Output/Gemini1_0/JS/extracted_code/contextual_experiment/update/app.tsx (130 lines of code) (raw):
import React from "react";
import ReactDOM from "react-dom";
import { TodoModel } from "./todoModel";
import { TodoFooter } from "./footer";
import { TodoItem } from "./todoItem";
import { ALL_TODOS, ACTIVE_TODOS, COMPLETED_TODOS, ENTER_KEY } from "./constants";
const TodoApp = (props) => {
const [state, setState] = React.useState({
nowShowing: ALL_TODOS,
editing: null,
});
React.useEffect(() => {
const router = Router({
"/": () => setState({ nowShowing: ALL_TODOS }),
"/active": () => setState({ nowShowing: ACTIVE_TODOS }),
"/completed": () => setState({ nowShowing: COMPLETED_TODOS }),
});
router.init("/");
}, []);
const handleNewTodoKeyDown = (event) => {
if (event.keyCode !== ENTER_KEY) {
return;
}
event.preventDefault();
const val = (ReactDOM.findDOMNode(props.refs["newField"]) as HTMLInputElement).value.trim();
if (val) {
props.model.addTodo(val);
(ReactDOM.findDOMNode(props.refs["newField"]) as HTMLInputElement).value = "";
}
};
const toggleAll = (event) => {
const target = event.target as HTMLInputElement;
const checked = target.checked;
props.model.toggleAll(checked);
};
const toggle = (todoToToggle) => {
props.model.toggle(todoToToggle);
};
const destroy = (todo) => {
props.model.destroy(todo);
};
const edit = (todo) => {
setState({ editing: todo.id });
};
const save = (todoToSave, text) => {
props.model.save(todoToSave, text);
setState({ editing: null });
};
const cancel = () => {
setState({ editing: null });
};
const clearCompleted = () => {
props.model.clearCompleted();
};
const todos = props.model.todos;
const shownTodos = todos.filter((todo) => {
switch (state.nowShowing) {
case ACTIVE_TODOS:
return !todo.completed;
case COMPLETED_TODOS:
return todo.completed;
default:
return true;
}
});
const todoItems = shownTodos.map((todo) => {
return (
<TodoItem
key={todo.id}
todo={todo}
onToggle={() => toggle(todo)}
onDestroy={() => destroy(todo)}
onEdit={() => edit(todo)}
editing={state.editing === todo.id}
onSave={(text) => save(todo, text)}
onCancel={() => cancel()}
/>
);
});
let footer;
let main;
const activeTodoCount = todos.reduce((accum, todo) => {
return todo.completed ? accum : accum + 1;
}, 0);
const completedCount = todos.length - activeTodoCount;
if (activeTodoCount || completedCount) {
footer = (
<TodoFooter
count={activeTodoCount}
completedCount={completedCount}
nowShowing={state.nowShowing}
onClearCompleted={clearCompleted}
/>
);
}
if (todos.length) {
main = (
<section className="main">
<input
id="toggle-all"
className="toggle-all"
type="checkbox"
onChange={toggleAll}
checked={activeTodoCount === 0}
/>
<label htmlFor="toggle-all">Mark all as complete</label>
<ul className="todo-list">{todoItems}</ul>
</section>
);
}
return (
<div>
<header className="header">
<h1>todos</h1>
<input
ref="newField"
className="new-todo"
placeholder="What needs to be done?"
onKeyDown={handleNewTodoKeyDown}
autoFocus={true}
/>
</header>
{main}
{footer}
</div>
);
};
const model = new TodoModel("react-todos");
const render = () => {
ReactDOM.render(<TodoApp model={model} />, document.getElementsByClassName("todoapp")[0]);
};
model.subscribe(render);
render();