Add todo frontend

This commit is contained in:
2021-11-10 21:23:02 +01:00
parent b7a57461a9
commit f2e9fc67b7
15 changed files with 215 additions and 5 deletions

View File

@@ -0,0 +1,9 @@
import { FC } from "react";
interface PageHeadingProps {
title: string;
}
export const PageHeading: FC<PageHeadingProps> = ({ title }) => (
<h3 className="font-bold text-xl tracking-wide">{title}</h3>
);

View File

@@ -0,0 +1,3 @@
export const ProjectsHeading = (props: { title: string }) => (
<h5 className="text-sm font-bold">{props.title}</h5>
);

View File

@@ -0,0 +1,25 @@
import { useState } from "react";
import { CollapsedAddTodo } from "@src/components/todos/collapsed/collapsedAddTodo";
import { AddTodoForm } from "@src/components/todos/collapsed/addTodoForm";
import { CollapsedState } from "@src/components/todos/collapsed/collapsedState";
export function AddTodo() {
const [collapsed, setCollapsed] = useState<CollapsedState>(
CollapsedState.collapsed
);
if (collapsed === CollapsedState.collapsed) {
return (
<CollapsedAddTodo
onClick={() => setCollapsed(CollapsedState.notCollapsed)}
/>
);
}
return (
<AddTodoForm
onAdd={(todoName) => {}}
onClose={() => setCollapsed(CollapsedState.collapsed)}
/>
);
}

View File

@@ -0,0 +1,35 @@
import { FC, useState } from "react";
export const AddTodoForm: FC<{
onAdd: (todoName: string) => void;
onClose: () => void;
}> = ({ onAdd, onClose }) => {
const [todoName, setTodoName] = useState("");
return (
<div className="p-2 space-y-1">
<div className="todo-input-form py-2 px-4 bg-gray-900 border border-gray-600">
<input
type="text"
placeholder="Todo name"
className="text-sm"
value={todoName}
onChange={(e) => setTodoName(e.target.value)}
/>
</div>
<div className="space-x-2">
<button
disabled={!todoName}
onClick={() => {
onAdd(todoName);
setTodoName("");
}}
className="disabled:text-gray-800 transition"
>
Add todo
</button>
<button onClick={onClose}>Cancel</button>
</div>
</div>
);
};

View File

@@ -0,0 +1,5 @@
import { FC } from "react";
export const CollapsedAddTodo: FC<{ onClick: () => void }> = ({ onClick }) => {
return <div onClick={onClick}>Add todo</div>;
};

View File

@@ -0,0 +1,12 @@
type Collapsed = true;
type NotCollapsed = false;
export type CollapsedState = Collapsed | NotCollapsed;
export const CollapsedState: {
collapsed: Collapsed;
notCollapsed: NotCollapsed;
} = {
collapsed: true,
notCollapsed: false,
};

View File

@@ -0,0 +1,2 @@
export * from "./todoItem";
export * from "./todoList";

View File

@@ -0,0 +1,20 @@
import { StatusState, Todo } from "@src/core/entities/todo";
import { FC } from "react";
interface TodoCheckmarkProps {
updateTodo: (todo: Todo) => void;
todo: Todo;
}
export const TodoCheckmark: FC<TodoCheckmarkProps> = (props) => (
<div
onClick={() =>
props.updateTodo({ ...props.todo, status: !props.todo.status })
}
className={`h-5 w-5 rounded-full border dark:border-gray-700 ${
props.todo.status === StatusState.done
? "dark:bg-gray-700"
: "hover:dark:bg-gray-600"
}`}
/>
);

View File

@@ -0,0 +1,17 @@
import { Todo } from "@src/core/entities/todo";
import { FC } from "react";
import { TodoCheckmark } from "@src/components/todos/todoCheckmark";
interface TodoItemProps {
todo: Todo;
updateTodo: (todo: Todo) => void;
}
export const TodoItem: FC<TodoItemProps> = (props) => (
<div className="py-3 border-b border-gray-300 dark:border-gray-700">
<div className="flex items-center space-x-4">
<TodoCheckmark {...props} />
<span className="pb-1">{props.todo.name}</span>
</div>
</div>
);

View File

@@ -0,0 +1,21 @@
import { Todo } from "@src/core/entities/todo";
import { TodoItem } from "@src/components/todos/todoItem";
import { AddTodo } from "@src/components/todos/addTodo";
export const TodoList = (props: { todos: Todo[] }) => (
<>
<ul id="inbox">
{props.todos.map((t, i) => (
<li key={i}>
<TodoItem
todo={t}
updateTodo={(todo) => {
console.log(todo);
}}
/>
</li>
))}
</ul>
<AddTodo />
</>
);