|
1 |
| -import './Main.css'; |
2 |
| -import React, { useEffect, FormEventHandler, FormEvent } from 'react'; |
3 |
| -import logout from '@wasp/auth/logout'; |
4 |
| -import useAuth from '@wasp/auth/useAuth'; |
5 |
| -import { useQuery } from '@wasp/queries'; // Wasp uses a thin wrapper around react-query |
6 |
| -import getTasks from '@wasp/queries/getTasks'; |
7 |
| -import createTask from '@wasp/actions/createTask'; |
8 |
| -import updateTask from '@wasp/actions/updateTask'; |
9 |
| -import waspLogo from './waspLogo.png'; |
10 |
| -import { Task } from './types' |
| 1 | +import React, { FormEventHandler, FormEvent } from "react"; |
| 2 | +import waspLogo from "./waspLogo.png"; |
11 | 3 |
|
12 |
| -export function MainPage() { |
13 |
| - const { data: user } = useAuth(); |
14 |
| - const { data: tasks, isLoading, error } = useQuery<unknown, Task[]>(getTasks); |
| 4 | +import "./Main.css"; |
| 5 | +// Wasp imports 🐝 = } |
| 6 | +import logout from "@wasp/auth/logout"; |
| 7 | +import { useQuery } from "@wasp/queries"; // Wasp uses a thin wrapper around react-query |
| 8 | +import getTasks from "@wasp/queries/getTasks"; |
| 9 | +import createTask from "@wasp/actions/createTask"; |
| 10 | +import updateTask from "@wasp/actions/updateTask"; |
| 11 | +import deleteTasks from "@wasp/actions/deleteTasks"; |
| 12 | +import type { Task, User } from "@wasp/entities"; |
15 | 13 |
|
16 |
| - useEffect(() => { |
17 |
| - console.log(user); |
18 |
| - }, [user]); |
| 14 | +export const MainPage = ({ user }: { user: User }) => { |
| 15 | + const { data: tasks, isLoading, error } = useQuery(getTasks); |
19 | 16 |
|
20 |
| - if (isLoading) return 'Loading...'; |
21 |
| - if (error) return 'Error: ' + error; |
| 17 | + if (isLoading) return "Loading..."; |
| 18 | + if (error) return "Error: " + error; |
| 19 | + |
| 20 | + const completed = tasks?.filter((task) => task.isDone).map((task) => task.id); |
22 | 21 |
|
23 | 22 | return (
|
24 | 23 | <main>
|
25 |
| - <img src={waspLogo} alt='wasp logo' /> |
26 |
| - <h1> |
27 |
| - {user.username} |
28 |
| - {`'s tasks :)`} |
29 |
| - </h1> |
| 24 | + <img src={waspLogo} alt="wasp logo" /> |
| 25 | + {user && ( |
| 26 | + <h1> |
| 27 | + {user.username} |
| 28 | + {`'s tasks :)`} |
| 29 | + </h1> |
| 30 | + )} |
30 | 31 | <NewTaskForm />
|
31 |
| - {tasks && <TasksList tasks={tasks} /> } |
32 |
| - <button onClick={logout}> Logout </button> |
| 32 | + {tasks && <TasksList tasks={tasks} />} |
| 33 | + <div className="buttons"> |
| 34 | + <button |
| 35 | + className="logout" |
| 36 | + onClick={() => void deleteTasks(completed ?? [])} |
| 37 | + > |
| 38 | + Delete completed |
| 39 | + </button> |
| 40 | + <button className="logout" onClick={logout}> |
| 41 | + Logout |
| 42 | + </button> |
| 43 | + </div> |
33 | 44 | </main>
|
34 | 45 | );
|
35 | 46 | };
|
36 | 47 |
|
37 | 48 | function Todo({ id, isDone, description }: Task) {
|
38 |
| - const handleIsDoneChange: FormEventHandler<HTMLInputElement> = async (event) => { |
| 49 | + const handleIsDoneChange: FormEventHandler<HTMLInputElement> = async ( |
| 50 | + event |
| 51 | + ) => { |
39 | 52 | try {
|
40 | 53 | await updateTask({
|
41 | 54 | id,
|
42 | 55 | isDone: event.currentTarget.checked,
|
43 | 56 | });
|
44 | 57 | } catch (err: any) {
|
45 |
| - window.alert('Error while updating task ' + err?.message); |
| 58 | + window.alert("Error while updating task " + err?.message); |
46 | 59 | }
|
47 |
| - } |
| 60 | + }; |
48 | 61 |
|
49 | 62 | return (
|
50 | 63 | <li>
|
51 |
| - <input type='checkbox' id={id.toString()} checked={isDone} onChange={handleIsDoneChange} /> |
52 |
| - <span>{description}</span> |
| 64 | + <span className="todo-item"> |
| 65 | + <input |
| 66 | + type="checkbox" |
| 67 | + id={id.toString()} |
| 68 | + checked={isDone} |
| 69 | + onChange={handleIsDoneChange} |
| 70 | + /> |
| 71 | + <span>{description}</span> |
| 72 | + <button onClick={() => void deleteTasks([id])}>Delete</button> |
| 73 | + </span> |
53 | 74 | </li>
|
54 | 75 | );
|
55 |
| -}; |
| 76 | +} |
56 | 77 |
|
57 |
| -function TasksList({tasks}: { tasks: Task[] }) { |
| 78 | +function TasksList({ tasks }: { tasks: Task[] }) { |
58 | 79 | if (tasks.length === 0) return <p>No tasks yet.</p>;
|
59 | 80 | return (
|
60 |
| - <ol className='tasklist'> |
| 81 | + <ol className="tasklist"> |
61 | 82 | {tasks.map((task, idx) => (
|
62 | 83 | <Todo {...task} key={idx} />
|
63 | 84 | ))}
|
64 | 85 | </ol>
|
65 | 86 | );
|
66 |
| -}; |
| 87 | +} |
67 | 88 |
|
68 | 89 | function NewTaskForm() {
|
69 | 90 | const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
|
70 | 91 | event.preventDefault();
|
71 |
| - |
| 92 | + |
72 | 93 | try {
|
73 | 94 | const description = event.currentTarget.description.value;
|
74 |
| - console.log(description) |
| 95 | + console.log(description); |
75 | 96 | event.currentTarget.reset();
|
76 | 97 | await createTask({ description });
|
77 | 98 | } catch (err: any) {
|
78 |
| - window.alert('Error: ' + err?.message); |
| 99 | + window.alert("Error: " + err?.message); |
79 | 100 | }
|
80 | 101 | };
|
81 | 102 |
|
82 | 103 | return (
|
83 | 104 | <form onSubmit={handleSubmit}>
|
84 |
| - <input name='description' type='text' defaultValue='' /> |
85 |
| - <input type='submit' value='Create task' /> |
| 105 | + <input name="description" type="text" defaultValue="" /> |
| 106 | + <input type="submit" value="Create task" /> |
86 | 107 | </form>
|
87 | 108 | );
|
88 |
| -}; |
| 109 | +} |
0 commit comments