diff --git a/src/client/src/components/common/headings/pageHeading.tsx b/src/client/src/components/common/headings/pageHeading.tsx new file mode 100644 index 0000000..8328545 --- /dev/null +++ b/src/client/src/components/common/headings/pageHeading.tsx @@ -0,0 +1,9 @@ +import { FC } from "react"; + +interface PageHeadingProps { + title: string; +} + +export const PageHeading: FC = ({ title }) => ( +

{title}

+); diff --git a/src/client/src/components/common/headings/projectsHeading.tsx b/src/client/src/components/common/headings/projectsHeading.tsx new file mode 100644 index 0000000..2b52c87 --- /dev/null +++ b/src/client/src/components/common/headings/projectsHeading.tsx @@ -0,0 +1,3 @@ +export const ProjectsHeading = (props: { title: string }) => ( +
{props.title}
+); diff --git a/src/client/src/components/todos/addTodo.tsx b/src/client/src/components/todos/addTodo.tsx new file mode 100644 index 0000000..823537c --- /dev/null +++ b/src/client/src/components/todos/addTodo.tsx @@ -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.collapsed + ); + + if (collapsed === CollapsedState.collapsed) { + return ( + setCollapsed(CollapsedState.notCollapsed)} + /> + ); + } + + return ( + {}} + onClose={() => setCollapsed(CollapsedState.collapsed)} + /> + ); +} diff --git a/src/client/src/components/todos/collapsed/addTodoForm.tsx b/src/client/src/components/todos/collapsed/addTodoForm.tsx new file mode 100644 index 0000000..edfdaa3 --- /dev/null +++ b/src/client/src/components/todos/collapsed/addTodoForm.tsx @@ -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 ( +
+
+ setTodoName(e.target.value)} + /> +
+
+ + +
+
+ ); +}; diff --git a/src/client/src/components/todos/collapsed/collapsedAddTodo.tsx b/src/client/src/components/todos/collapsed/collapsedAddTodo.tsx new file mode 100644 index 0000000..39a1ccf --- /dev/null +++ b/src/client/src/components/todos/collapsed/collapsedAddTodo.tsx @@ -0,0 +1,5 @@ +import { FC } from "react"; + +export const CollapsedAddTodo: FC<{ onClick: () => void }> = ({ onClick }) => { + return
Add todo
; +}; diff --git a/src/client/src/components/todos/collapsed/collapsedState.tsx b/src/client/src/components/todos/collapsed/collapsedState.tsx new file mode 100644 index 0000000..6477526 --- /dev/null +++ b/src/client/src/components/todos/collapsed/collapsedState.tsx @@ -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, +}; diff --git a/src/client/src/components/todos/index.ts b/src/client/src/components/todos/index.ts new file mode 100644 index 0000000..cb81900 --- /dev/null +++ b/src/client/src/components/todos/index.ts @@ -0,0 +1,2 @@ +export * from "./todoItem"; +export * from "./todoList"; diff --git a/src/client/src/components/todos/todoCheckmark.tsx b/src/client/src/components/todos/todoCheckmark.tsx new file mode 100644 index 0000000..004b992 --- /dev/null +++ b/src/client/src/components/todos/todoCheckmark.tsx @@ -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 = (props) => ( +
+ 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" + }`} + /> +); diff --git a/src/client/src/components/todos/todoItem.tsx b/src/client/src/components/todos/todoItem.tsx new file mode 100644 index 0000000..5a8361d --- /dev/null +++ b/src/client/src/components/todos/todoItem.tsx @@ -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 = (props) => ( +
+
+ + {props.todo.name} +
+
+); diff --git a/src/client/src/components/todos/todoList.tsx b/src/client/src/components/todos/todoList.tsx new file mode 100644 index 0000000..b620f1a --- /dev/null +++ b/src/client/src/components/todos/todoList.tsx @@ -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[] }) => ( + <> +
    + {props.todos.map((t, i) => ( +
  • + { + console.log(todo); + }} + /> +
  • + ))} +
+ + +); diff --git a/src/client/src/core/actions/todos.ts b/src/client/src/core/actions/todos.ts new file mode 100644 index 0000000..ee6050e --- /dev/null +++ b/src/client/src/core/actions/todos.ts @@ -0,0 +1,18 @@ +import { StatusState, Todo } from "@src/core/entities/todo"; + +export const createTodo = (name: string): Todo => ({ + name, + status: StatusState.notDone, +}); + +const createDoneTodo = (name: string) => ({ + ...createTodo(name), + status: true, +}); + +const todos: Todo[] = [ + createTodo("go to dentist"), + createTodo("Check e-Boks"), + createDoneTodo("Check and clean mail"), +]; +export const getInboxTodos = () => todos; diff --git a/src/client/src/core/entities/todo.tsx b/src/client/src/core/entities/todo.tsx new file mode 100644 index 0000000..3268c93 --- /dev/null +++ b/src/client/src/core/entities/todo.tsx @@ -0,0 +1,12 @@ +type NotDone = false; +type Done = true; +type StatusState = NotDone | Done; +export const StatusState: { done: Done; notDone: NotDone } = { + done: true, + notDone: false, +}; + +export interface Todo { + name: string; + status: StatusState; +} diff --git a/src/client/src/pages/index.tsx b/src/client/src/pages/index.tsx index 134394b..e0c4c4e 100644 --- a/src/client/src/pages/index.tsx +++ b/src/client/src/pages/index.tsx @@ -1,5 +1,18 @@ -export default function Home() { +import { useMemo } from "react"; +import { getInboxTodos } from "@src/core/actions/todos"; +import { PageHeading } from "@src/components/common/headings/pageHeading"; +import { TodoList } from "@src/components/todos"; + +const HomePage = () => { + const inboxTodos = useMemo(() => getInboxTodos(), []); + return ( -
Hello
- ) -} +
+
+ + +
+
+ ); +}; +export default HomePage; diff --git a/src/client/src/styles/tailwind.css b/src/client/src/styles/tailwind.css index b5c61c9..7d57195 100644 --- a/src/client/src/styles/tailwind.css +++ b/src/client/src/styles/tailwind.css @@ -1,3 +1,21 @@ @tailwind base; @tailwind components; + +input { + @apply shadow-none placeholder-gray-300 dark:placeholder-gray-700 border-none outline-none; + background: transparent; +} + +*:focus { + outline: none; +} + @tailwind utilities; + +* { + @apply dark:text-gray-100 +} + +body { + @apply h-screen dark:bg-black +} \ No newline at end of file diff --git a/src/client/tailwind.config.js b/src/client/tailwind.config.js index dd88c35..4245d45 100644 --- a/src/client/tailwind.config.js +++ b/src/client/tailwind.config.js @@ -3,7 +3,7 @@ module.exports = { purge: { content: ["./src/**/*.{ts,tsx}"], }, - darkMode: false, // or 'media' or 'class' + darkMode: "media", // or 'media' or 'class' theme: { extend: {}, },