Skip to content

Commit daa383b

Browse files
committed
adding spinners to buttons
1 parent 5ff2421 commit daa383b

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

app/(auth)/sign-in/page.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use client';
22

33
import { useState } from 'react';
4+
import { Loader } from 'lucide-react';
45

56
import Link from 'next/link';
67
import { Button } from '../../_components/ui/button';
@@ -18,16 +19,20 @@ import { signIn } from '../actions';
1819

1920
export default function SignIn() {
2021
const [error, setError] = useState<string>();
22+
const [loading, setLoading] = useState(false);
2123

2224
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
2325
event.preventDefault();
26+
if (loading) return;
2427

2528
const formData = new FormData(event.currentTarget);
2629

30+
setLoading(true);
2731
const res = await signIn(formData);
2832
if (res && res.error) {
2933
setError(res.error);
3034
}
35+
setLoading(false);
3136
};
3237

3338
return (
@@ -57,8 +62,8 @@ export default function SignIn() {
5762
<Label htmlFor="password">Password</Label>
5863
<Input id="password" type="password" name="password" required />
5964
</div>
60-
<Button type="submit" className="w-full">
61-
Login
65+
<Button type="submit" disabled={loading} className="w-full">
66+
{loading ? <Loader className="animate-spin" /> : 'Login'}
6267
</Button>
6368
</div>
6469
<div className="mt-4 text-center text-sm">

app/(auth)/sign-up/page.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@ import { Input } from '../../_components/ui/input';
1515
import { Label } from '../../_components/ui/label';
1616
import { Separator } from '../../_components/ui/separator';
1717
import { signUp } from '../actions';
18+
import { Loader } from 'lucide-react';
1819

1920
export default function SignUp() {
2021
const [error, setError] = useState<string>();
22+
const [loading, setLoading] = useState(false);
2123

2224
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
2325
event.preventDefault();
26+
if (loading) return;
2427

2528
const formData = new FormData(event.currentTarget);
2629

@@ -32,10 +35,12 @@ export default function SignUp() {
3235
return;
3336
}
3437

38+
setLoading(true);
3539
const res = await signUp(formData);
3640
if (res && res.error) {
3741
setError(res.error);
3842
}
43+
setLoading(false);
3944
};
4045

4146
return (
@@ -74,8 +79,12 @@ export default function SignUp() {
7479
required
7580
/>
7681
</div>
77-
<Button type="submit" className="w-full">
78-
Create an account
82+
<Button type="submit" disabled={loading} className="w-full">
83+
{loading ? (
84+
<Loader className="animate-spin" />
85+
) : (
86+
'Create an account'
87+
)}
7988
</Button>
8089
</div>
8190
<div className="mt-4 text-center text-sm">

app/add-todo.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

3-
import { Plus } from 'lucide-react';
4-
import { useRef } from 'react';
3+
import { Loader, Plus } from 'lucide-react';
4+
import { useRef, useState } from 'react';
55
import { toast } from 'sonner';
66

77
import { Button } from './_components/ui/button';
@@ -10,11 +10,15 @@ import { createTodo } from './actions';
1010

1111
export function CreateTodo() {
1212
const inputRef = useRef<HTMLInputElement>(null);
13+
const [loading, setLoading] = useState(false);
1314

1415
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
1516
event.preventDefault();
17+
if (loading) return;
1618

1719
const formData = new FormData(event.currentTarget);
20+
21+
setLoading(true);
1822
const res = await createTodo(formData);
1923

2024
if (res) {
@@ -28,6 +32,7 @@ export function CreateTodo() {
2832
}
2933
}
3034
}
35+
setLoading(false);
3136
};
3237

3338
return (
@@ -38,8 +43,8 @@ export function CreateTodo() {
3843
className="flex-1"
3944
placeholder="Take out trash"
4045
/>
41-
<Button size="icon" type="submit">
42-
<Plus />
46+
<Button size="icon" disabled={loading} type="submit">
47+
{loading ? <Loader className="animate-spin" /> : <Plus />}
4348
</Button>
4449
</form>
4550
);

app/todos.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

33
import { useCallback, useState } from 'react';
4-
import { Trash } from 'lucide-react';
4+
import { Loader, Trash } from 'lucide-react';
55
import { toast } from 'sonner';
66

77
import { Checkbox } from './_components/ui/checkbox';
@@ -15,6 +15,7 @@ export function Todos({ todos }: { todos: Todo[] }) {
1515
const [bulkMode, setBulkMode] = useState(false);
1616
const [dirty, setDirty] = useState<number[]>([]);
1717
const [deleted, setDeleted] = useState<number[]>([]);
18+
const [loading, setLoading] = useState(false);
1819

1920
const handleToggle = useCallback(
2021
async (id: number) => {
@@ -63,7 +64,9 @@ export function Todos({ todos }: { todos: Todo[] }) {
6364
);
6465

6566
const updateAll = async () => {
67+
setLoading(true);
6668
const res = await bulkUpdate(dirty, deleted);
69+
setLoading(false);
6770
setBulkMode(false);
6871
setDirty([]);
6972
setDeleted([]);
@@ -126,7 +129,9 @@ export function Todos({ todos }: { todos: Todo[] }) {
126129
</ul>
127130
{bulkMode ? (
128131
<div className="w-full grid grid-cols-2 gap-2">
129-
<Button onClick={updateAll}>Update all</Button>
132+
<Button disabled={loading} onClick={updateAll}>
133+
{loading ? <Loader className="animate-spin" /> : 'Update all'}
134+
</Button>
130135
<Button variant="secondary" onClick={() => setBulkMode(false)}>
131136
Cancel
132137
</Button>

0 commit comments

Comments
 (0)