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
|
what |
when |
left |
{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}
/>
})}
;
}
}
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"));