import "preact/debug"; import { get, post } from 'axios'; import { Component, render, Fragment, h } from 'preact'; import strftime from 'strftime'; import { ConfigView, Config } from './config.jsx' /** @jsx h */ /** @jsxFrag Fragment */ /* naive. assumes: year = 365 days, day = 24 hrs, hr = 60 mins, min = 60 secs */ function format_relative_naive(date) { const sec = 1000; const min = 60 * sec; const hr = 60 * min; const day = 24 * hr; let now = new Date(); let ms_diff = date - now; if (Math.abs(ms_diff) < 2 * min) { return `${Math.round(ms_diff / sec)}s`; } else if (Math.abs(ms_diff) < 2 * hr) { return `${Math.round(ms_diff / min)}m`; } else if (Math.abs(ms_diff) < 2 * day) { return `${Math.round(ms_diff / hr)}h`; } else { return `${Math.round(ms_diff / day)}d`; } } class TodoList extends Component { constructor() { super(); this.state = { todos: [] }; } componentWillMount() { get("/api/todos").then(resp => { let todos = resp.data.todos; todos.sort((todo1, todo2) => { return todo1.expires - todo2.expires; }) this.setState({ todos: resp.data.todos }) }) } render({ config }, { todos }) { let { datefmt, timezoneOffset } = config; return {todos.map(todo => { return strftime("%H:%M", date)} done={todo.done} desc={todo.desc} display_date={new Date(todo.expires)} key={`todo-${todo.id}`} id={todo.id} /> })}
what when left
; } } class TodoRow extends Component { constructor(props) { super(props); this.state = { id: props.id } } deleteTodo(event) { post("/api/delete-todo", { id: this.state.id }) .then(resp => { console.log(resp); window.location.reload(); }); } render({ dateFormatter, done, desc, display_date, key }, { }) { let status = done ? DONE : TODO return {status} {desc} {dateFormatter(display_date)} {format_relative_naive(display_date)} } } class PostForm extends Component { constructor({ notify_list, config }) { super(); this.state = { notify_list: notify_list, desc: "", date: config.getDefaultDate() }; } postTodo(event) { if (this.state.desc.length == 0) { return; } post( "/api/new-todo", { desc: this.state.desc, expires: new Date(this.state.date).getTime(), done: false } ) .then((resp) => { console.log(resp.data); window.location.reload(); }).catch((err) => { console.log("err: "); console.log(err); }); } render(props, state) { let isEmpty = state.desc.length == 0; const noop = _ => {}; let aClasslist = `a-button ${isEmpty ? "a-button-disabled" : ""}` return <> this.setState({ desc: e.target.value })} /> this.setState({ date: e.target.value })} value={this.state.date} /> post } } class App extends Component { constructor() { super(); this.state = { config: new Config() }; } changeConfig(newConfig) { this.setState({ config: newConfig }); } render({}, { config }) { return

|

} } render(, document.getElementById("root"));