diff --git a/app/(auth)/sign-in/page.tsx b/app/(auth)/sign-in/page.tsx index 0a44248..bff80f9 100644 --- a/app/(auth)/sign-in/page.tsx +++ b/app/(auth)/sign-in/page.tsx @@ -1,6 +1,7 @@ 'use client'; import { useState } from 'react'; +import { Loader } from 'lucide-react'; import Link from 'next/link'; import { Button } from '../../_components/ui/button'; @@ -18,16 +19,20 @@ import { signIn } from '../actions'; export default function SignIn() { const [error, setError] = useState(); + const [loading, setLoading] = useState(false); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); + if (loading) return; const formData = new FormData(event.currentTarget); + setLoading(true); const res = await signIn(formData); if (res && res.error) { setError(res.error); } + setLoading(false); }; return ( @@ -57,8 +62,8 @@ export default function SignIn() { -
diff --git a/app/(auth)/sign-up/page.tsx b/app/(auth)/sign-up/page.tsx index 1ffac4d..198446b 100644 --- a/app/(auth)/sign-up/page.tsx +++ b/app/(auth)/sign-up/page.tsx @@ -15,12 +15,15 @@ import { Input } from '../../_components/ui/input'; import { Label } from '../../_components/ui/label'; import { Separator } from '../../_components/ui/separator'; import { signUp } from '../actions'; +import { Loader } from 'lucide-react'; export default function SignUp() { const [error, setError] = useState(); + const [loading, setLoading] = useState(false); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); + if (loading) return; const formData = new FormData(event.currentTarget); @@ -32,10 +35,12 @@ export default function SignUp() { return; } + setLoading(true); const res = await signUp(formData); if (res && res.error) { setError(res.error); } + setLoading(false); }; return ( @@ -74,8 +79,12 @@ export default function SignUp() { required />
-
diff --git a/app/add-todo.tsx b/app/add-todo.tsx index 696ea01..0339e50 100644 --- a/app/add-todo.tsx +++ b/app/add-todo.tsx @@ -1,7 +1,7 @@ 'use client'; -import { Plus } from 'lucide-react'; -import { useRef } from 'react'; +import { Loader, Plus } from 'lucide-react'; +import { useRef, useState } from 'react'; import { toast } from 'sonner'; import { Button } from './_components/ui/button'; @@ -10,11 +10,15 @@ import { createTodo } from './actions'; export function CreateTodo() { const inputRef = useRef(null); + const [loading, setLoading] = useState(false); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); + if (loading) return; const formData = new FormData(event.currentTarget); + + setLoading(true); const res = await createTodo(formData); if (res) { @@ -28,6 +32,7 @@ export function CreateTodo() { } } } + setLoading(false); }; return ( @@ -38,8 +43,8 @@ export function CreateTodo() { className="flex-1" placeholder="Take out trash" /> - ); diff --git a/app/todos.tsx b/app/todos.tsx index 45726e0..45a37aa 100644 --- a/app/todos.tsx +++ b/app/todos.tsx @@ -1,7 +1,7 @@ 'use client'; import { useCallback, useState } from 'react'; -import { Trash } from 'lucide-react'; +import { Loader, Trash } from 'lucide-react'; import { toast } from 'sonner'; import { Checkbox } from './_components/ui/checkbox'; @@ -15,6 +15,7 @@ export function Todos({ todos }: { todos: Todo[] }) { const [bulkMode, setBulkMode] = useState(false); const [dirty, setDirty] = useState([]); const [deleted, setDeleted] = useState([]); + const [loading, setLoading] = useState(false); const handleToggle = useCallback( async (id: number) => { @@ -63,7 +64,9 @@ export function Todos({ todos }: { todos: Todo[] }) { ); const updateAll = async () => { + setLoading(true); const res = await bulkUpdate(dirty, deleted); + setLoading(false); setBulkMode(false); setDirty([]); setDeleted([]); @@ -126,7 +129,9 @@ export function Todos({ todos }: { todos: Todo[] }) { {bulkMode ? (
- +