Skip to content

Commit 80bf5ad

Browse files
committed
Merge branch 'main' of https://github.com/TyrinH/code-racer into result-page-toast-for-guest
2 parents 0101c8c + b551cfd commit 80bf5ad

32 files changed

+1292
-1118
lines changed

package-lock.json

Lines changed: 39 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
},
1919
"dependencies": {
2020
"@auth/prisma-adapter": "^1.0.0",
21+
"@hookform/resolvers": "^3.1.1",
2122
"@next-auth/prisma-adapter": "^1.0.7",
2223
"@prisma/client": "^5.0.0",
2324
"@radix-ui/react-dialog": "^1.0.4",
@@ -40,12 +41,14 @@
4041
"lucide-react": "^0.259.0",
4142
"next": "13.4.9",
4243
"next-auth": "^4.22.1",
44+
"next-safe-action": "^3.0.1",
4345
"next-themes": "^0.2.1",
4446
"nextjs-toploader": "^1.4.2",
4547
"postcss": "8.4.25",
4648
"react": "18.2.0",
4749
"react-confetti": "^6.1.0",
4850
"react-dom": "18.2.0",
51+
"react-hook-form": "^7.45.1",
4952
"react-share": "^4.4.1",
5053
"react-use": "^17.4.0",
5154
"recharts": "^2.7.2",
@@ -54,7 +57,6 @@
5457
"tailwindcss": "3.3.2",
5558
"tailwindcss-animate": "^1.0.6",
5659
"unstyled-table": "^0.0.3-alpha-3",
57-
"zact": "^0.0.2",
5860
"zod": "^3.21.4"
5961
},
6062
"devDependencies": {

prisma/schema.prisma

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ model User {
3030
results Result[]
3131
achievements UserAchievement[]
3232
33+
averageAccuracy Decimal @default(0) @db.Decimal(5, 2)
34+
averageCpm Decimal @default(0) @db.Decimal(6, 2)
35+
3336
role UserRole @default(USER)
3437
3538
snippets Snippet[]
Lines changed: 86 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,100 @@
11
"use client";
22

3-
import { FormEvent, useRef } from "react";
4-
import { Controls, EditableInput } from "@/components/ui/editable-input";
3+
import { Button } from "@/components/ui/button";
4+
import {
5+
Form,
6+
FormControl,
7+
FormField,
8+
FormItem
9+
} from "@/components/ui/form";
10+
import { Input } from "@/components/ui/input";
11+
import { useToast } from "@/components/ui/use-toast";
12+
import { catchError } from "@/lib/utils";
13+
import { zodResolver } from "@hookform/resolvers/zod";
514
import { useSession } from "next-auth/react";
615
import { useRouter } from "next/navigation";
16+
import React from "react";
17+
import { useForm } from "react-hook-form";
18+
import { z } from "zod";
719
import { updateUserAction } from "../../../_actions/user";
8-
import { useToast } from "@/components/ui/use-toast";
9-
import { catchError } from "@/lib/utils";
20+
21+
const updateUserSchema = z.object({
22+
name: z
23+
.string({
24+
required_error: "Please enter a username",
25+
})
26+
.nonempty("Please enter a username"),
27+
});
28+
29+
type UpdateUser = z.infer<typeof updateUserSchema>;
1030

1131
export default function ChangeNameForm({
12-
displayName,
32+
displayName,
1333
}: {
14-
displayName: string | null | undefined;
34+
displayName: string | null | undefined;
1535
}) {
16-
const router = useRouter();
17-
const session = useSession();
18-
const controlsRef = useRef<Controls>({
19-
setEdit: () => undefined,
20-
});
21-
const inputRef = useRef<HTMLInputElement>(null);
22-
const { toast } = useToast();
23-
24-
async function handleSubmit(e: FormEvent) {
25-
e.preventDefault();
26-
const newName = inputRef.current?.value as string;
27-
28-
if (newName === displayName) {
29-
controlsRef.current.setEdit(false);
30-
return;
31-
}
36+
const router = useRouter();
37+
const session = useSession();
38+
const form = useForm<UpdateUser>({
39+
resolver: zodResolver(updateUserSchema),
40+
mode: "onSubmit",
41+
defaultValues: {
42+
name: displayName ?? "",
43+
},
44+
});
45+
46+
const [isEditing, setIsEditing] = React.useState(false)
47+
48+
const { toast } = useToast();
3249

33-
controlsRef.current.setEdit(false);
34-
try {
35-
await updateUserAction({ name: newName });
50+
async function onSubmit(data: UpdateUser) {
51+
try {
52+
await updateUserAction({ name: data.name });
3653

37-
toast({
38-
title: "Username successfully updated.",
39-
description: "Your username has been successfully updated.",
40-
variant: "default",
41-
});
54+
toast({
55+
title: "Username successfully updated.",
56+
description: "Your username has been successfully updated.",
57+
variant: "default",
58+
});
4259

43-
await session.update({ name: newName });
44-
router.refresh();
45-
} catch (err) {
46-
catchError(err);
60+
await session.update({ name: data.name });
61+
62+
router.refresh();
63+
} catch (error) {
64+
catchError(error);
65+
}
4766
}
48-
}
49-
50-
return (
51-
<form
52-
onSubmit={handleSubmit}
53-
className="w-[75%] text-center mb-4 hover:border-dashed border hover:border-white"
54-
>
55-
<EditableInput
56-
controls={controlsRef}
57-
value={displayName as string}
58-
ref={inputRef}
59-
className="text-2xl font-bold"
60-
/>
61-
</form>
62-
);
67+
68+
return (
69+
<Form {...form}>
70+
<form
71+
onSubmit={form.handleSubmit(onSubmit)}
72+
className="w-[75%] text-center mb-4"
73+
>
74+
<FormField
75+
control={form.control}
76+
name="name"
77+
render={({ field }) => (
78+
<FormItem>
79+
<FormControl>
80+
<>
81+
<Input
82+
className="text-2xl font-bold hover:border-dashed border hover:border-white"
83+
onFocus={() => setIsEditing(true)}
84+
{...field}
85+
/>
86+
{isEditing && (
87+
<div className="flex items-center gap-2">
88+
<Button type="reset" className="w-full" onClick={() => setIsEditing(false)}>Cancel</Button>
89+
<Button type="submit" className="w-full">Submit</Button>
90+
</div>
91+
)}
92+
</>
93+
</FormControl>
94+
</FormItem>
95+
)}
96+
/>
97+
</form>
98+
</Form>
99+
);
63100
}

src/app/(profile-related)/profile/_components/confirmation.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default function DeleteConfirmation({
3333
setIsLoading(true);
3434
e.preventDefault();
3535
try {
36-
await deleteUserAction();
36+
await deleteUserAction({});
3737
await signOut({
3838
callbackUrl: "/",
3939
});

src/app/(user)/[userId]/page.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Heading } from "@/components/ui/heading";
22
import { prisma } from "@/lib/prisma";
33

4-
54
interface PageProps {
65
params: {
76
userId: string;
@@ -20,7 +19,10 @@ const page = async ({ params }: PageProps) => {
2019
title="Hello, Welcome to my profile"
2120
description="Here you can find information about the user"
2221
/>
23-
<h1>If anyone works on the design of this page let me know discord @trace2798</h1>
22+
<h1>
23+
If anyone works on the design of this page let me know discord
24+
@trace2798
25+
</h1>
2426
{/* <h1>Account Created:{formatTime}</h1> */}
2527
<h1>My Id is: {user?.id}</h1>
2628
<h2>Name: {user?.name}</h2>

0 commit comments

Comments
 (0)