Skip to content

Commit 4096286

Browse files
committed
feat: ✨ messing around with revalidatePath and Tag
1 parent 8056471 commit 4096286

File tree

9 files changed

+80
-60
lines changed

9 files changed

+80
-60
lines changed

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "1.0.0",
44
"private": true,
55
"scripts": {
6-
"dev": "prisma generate && next dev --turbo",
6+
"dev": "prisma generate && next dev",
77
"dev:email": "email dev -p 9000",
88
"dev:content": "velite build --watch",
99
"build:content": "velite build --clean",
@@ -15,7 +15,6 @@
1515
},
1616
"dependencies": {
1717
"@hookform/resolvers": "^3.9.1",
18-
"@lucia-auth/adapter-prisma": "4.0.1",
1918
"@oslojs/crypto": "^1.0.1",
2019
"@oslojs/encoding": "^1.1.0",
2120
"@prisma/client": "^5.22.0",

pnpm-lock.yaml

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

src/actions/auth.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getCurrentSession, invalidateSession } from "~/lib/session";
99

1010
export async function logout() {
1111
const { session } = await getCurrentSession();
12+
1213
if (!session) {
1314
return {
1415
message: "Unauthorized",

src/app/[locale]/dashboard/settings/actions.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
"use server";
22

3-
import { revalidatePath } from "next/cache";
3+
import { revalidateTag } from "next/cache";
4+
import prisma from "~/lib/prisma";
45
import { utapi } from "~/lib/uploadthing-server";
56
import { getImageKeyFromUrl, isOurCdnUrl } from "~/lib/utils";
67
import { type payload } from "~/types";
7-
import prisma from "~/lib/prisma";
88

99
export const updateUser = async (id: string, payload: payload) => {
1010
await prisma.user.update({
1111
where: { id },
1212
data: { ...payload },
1313
});
1414

15-
revalidatePath("/dashboard/settings");
15+
revalidateTag("session");
1616
};
1717

1818
export async function removeUserOldImageFromCDN(
@@ -24,7 +24,6 @@ export async function removeUserOldImageFromCDN(
2424
const currentImageFileKey = getImageKeyFromUrl(currentImageUrl);
2525

2626
await utapi.deleteFiles(currentImageFileKey as string);
27-
revalidatePath("/dashboard/settings");
2827
}
2928
} catch (e) {
3029
console.error(e);

src/app/[locale]/dashboard/settings/settings-form.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ export default function SettingsForm({ currentUser }: { currentUser: User }) {
4040

4141
const form = useForm<SettingsValues>({
4242
resolver: zodResolver(settingsSchema),
43-
mode: "onChange",
4443
defaultValues: {
4544
name: currentUser.name ?? "",
4645
email: currentUser.email ?? "",
@@ -51,15 +50,22 @@ export default function SettingsForm({ currentUser }: { currentUser: User }) {
5150
const { formState, getFieldState, handleSubmit, reset, getValues } = form;
5251
const { isDirty: isImageChanged } = getFieldState("picture");
5352

53+
useEffect(() => {
54+
reset({
55+
name: currentUser.name ?? "",
56+
email: currentUser.email ?? "",
57+
picture: currentUser.picture ?? "",
58+
});
59+
// eslint-disable-next-line react-hooks/exhaustive-deps
60+
}, [currentUser]);
61+
5462
useEffect(() => {
5563
if (isImageChanged && currentUser.picture !== oldImage.current) {
5664
oldImage.current = currentUser.picture ?? "";
5765
}
5866
}, [currentUser.picture, isImageChanged]);
5967

6068
const onSubmit = handleSubmit((data: SettingsValues) => {
61-
if (!formState.isDirty) return;
62-
6369
startTransition(async () => {
6470
try {
6571
if (currentUser.picture && isImageChanged) {
@@ -68,7 +74,7 @@ export default function SettingsForm({ currentUser }: { currentUser: User }) {
6874
await updateUser(currentUser.id, data);
6975
toast({ title: "Updated successfully!" });
7076
} catch (error) {
71-
console.error(error);
77+
console.log(JSON.stringify(error));
7278
toast({ title: "Something went wrong.", variant: "destructive" });
7379
}
7480
});
@@ -90,8 +96,6 @@ export default function SettingsForm({ currentUser }: { currentUser: User }) {
9096
[formState.isSubmitting, isPending, formState.isDirty]
9197
);
9298

93-
console.log(formState.isSubmitting, isPending, !formState.isDirty);
94-
9599
return (
96100
<Form {...form}>
97101
<form

src/app/api/auth/login/github/callback/route.ts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { OAuth2RequestError } from "arctic";
1+
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
2+
import { ArcticFetchError, OAuth2RequestError } from "arctic";
3+
import { revalidatePath } from "next/cache";
24
import { cookies } from "next/headers";
35
import { sendWelcomeEmail } from "~/actions/mail";
46
import { setSessionTokenCookie } from "~/lib/cookies";
@@ -26,6 +28,7 @@ export const GET = async (request: Request) => {
2628
},
2729
});
2830
const githubUser: GitHubUser = await githubUserResponse.json();
31+
2932
if (!githubUser.email) {
3033
const githubEmailsResponse = await fetch(
3134
"https://api.github.com/user/emails",
@@ -46,17 +49,30 @@ export const GET = async (request: Request) => {
4649
if (verifiedEmail) githubUser.email = verifiedEmail.email;
4750
}
4851

49-
const existingUser = await prisma.user.findUnique({
52+
const existingUser = await prisma.user.findFirst({
5053
where: {
51-
githubId: githubUser.id,
54+
OR: [
55+
{
56+
githubId: githubUser.id,
57+
},
58+
{
59+
email: githubUser.email,
60+
},
61+
],
5262
},
5363
});
5464

5565
if (existingUser) {
5666
const sessionTokenCookie = generateSessionToken();
5767
const session = await createSession(sessionTokenCookie, existingUser.id);
58-
setSessionTokenCookie(sessionTokenCookie, session.expiresAt);
59-
return Response.redirect("/dashboard");
68+
await setSessionTokenCookie(sessionTokenCookie, session.expiresAt);
69+
revalidatePath("/dashboard", "layout");
70+
return new Response(null, {
71+
status: 302,
72+
headers: {
73+
Location: "/dashboard",
74+
},
75+
});
6076
}
6177

6278
const newUser = await prisma.user.create({
@@ -68,27 +84,44 @@ export const GET = async (request: Request) => {
6884
emailVerified: Boolean(githubUser.email),
6985
},
7086
});
87+
7188
if (githubUser.email) {
7289
sendWelcomeEmail({ toMail: newUser.email!, userName: newUser.name! });
7390
}
7491
const sessionTokenCookie = generateSessionToken();
7592
const session = await createSession(sessionTokenCookie, newUser.id);
7693
await setSessionTokenCookie(sessionTokenCookie, session.expiresAt);
94+
revalidatePath("/dashboard", "layout");
7795
return new Response(null, {
7896
status: 302,
7997
headers: {
8098
Location: "/dashboard",
8199
},
82100
});
83101
} catch (e) {
84-
console.log(e);
102+
console.log(JSON.stringify(e));
103+
85104
// the specific error message depends on the provider
86105
if (e instanceof OAuth2RequestError) {
87106
// invalid code
88-
return new Response(null, {
107+
return new Response(e.description, {
89108
status: 400,
90109
});
91110
}
111+
112+
if (e instanceof ArcticFetchError) {
113+
// invalid code
114+
return new Response(e.message, {
115+
status: 400,
116+
});
117+
}
118+
119+
if (e instanceof PrismaClientKnownRequestError) {
120+
return new Response(e.message, {
121+
status: 400,
122+
});
123+
}
124+
92125
return new Response("Internal Server Error", {
93126
status: 500,
94127
});

src/app/api/auth/login/verify-otp/route.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { revalidatePath } from "next/cache";
1+
import { revalidateTag } from "next/cache";
22
import { verifyVerificationCode } from "~/actions/auth";
33
import { setSessionTokenCookie } from "~/lib/cookies";
44
import prisma from "~/lib/prisma";
@@ -55,12 +55,9 @@ export const POST = async (req: Request, response: Response) => {
5555
const sessionToken = generateSessionToken();
5656
const session = await createSession(sessionToken, user.id);
5757
await setSessionTokenCookie(sessionToken, session.expiresAt);
58-
revalidatePath("/");
58+
revalidateTag("session");
5959
return new Response(null, {
6060
status: 200,
61-
headers: {
62-
Location: "/dashboard",
63-
},
6461
});
6562
} catch (error) {
6663
return new Response("Internal Server Error", {

src/components/layout/auth-form.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ export default function AuthForm() {
7474
});
7575
setCountdown(30);
7676
} catch (error) {
77+
const errorMessage =
78+
error instanceof Error ? error.message : "Something went wrong";
7779
toast({
7880
title: "Failed to send OTP",
79-
description: "Please try again later",
81+
description: errorMessage,
8082
variant: "destructive",
8183
});
8284
} finally {
@@ -98,12 +100,11 @@ export default function AuthForm() {
98100
throw new Error(await res.text());
99101
}
100102
setCountdown(0);
101-
103+
reset();
102104
toast({
103105
title: "Successfully verified!",
104106
});
105-
106-
router.push("/dashboard");
107+
window.location.href = "/dashboard";
107108
} catch (error) {
108109
const errorMessage =
109110
error instanceof Error ? error.message : "Something went wrong";
@@ -216,14 +217,14 @@ export default function AuthForm() {
216217
disabled={isVerifying || otp.length !== 6}
217218
className="mt-4"
218219
>
219-
{isLoading && (
220+
{isVerifying && (
220221
<Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
221222
)}
222223
Verify OTP
223224
</Button>
224225
</form>
225226
<div className="mt-4 flex items-center justify-between text-sm text-gray-600">
226-
<span>Didn&apos;t receive the code / expired?</span>
227+
<span>Didn&apos;t receive the code/expired?</span>
227228
{countdown > 0 ? (
228229
<span>Resend in {countdown}s</span>
229230
) : (
@@ -233,7 +234,7 @@ export default function AuthForm() {
233234
className="h-auto p-0"
234235
disabled={isLoading}
235236
>
236-
Resend OTP
237+
{isLoading ? "Resending..." : "Resend"}
237238
</Button>
238239
)}
239240
</div>

src/lib/session.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
} from "@oslojs/encoding";
66
import type { Session, User } from "@prisma/client";
77
import { cookies } from "next/headers";
8-
import { cache } from "react";
8+
// import { cache } from "react";
9+
import { unstable_cache as cache } from "next/cache";
910
import prisma from "./prisma";
1011

1112
export function generateSessionToken(): string {
@@ -65,18 +66,25 @@ export async function validateSessionToken(
6566
return { session, user };
6667
}
6768

68-
export const getCurrentSession = cache(
69-
async (): Promise<SessionValidationResult> => {
70-
const cookieStore = await cookies();
71-
const token = cookieStore.get("session")?.value ?? null;
69+
export const getSession = cache(
70+
async (token: string | null): Promise<SessionValidationResult> => {
7271
if (token === null) {
7372
return { session: null, user: null };
7473
}
75-
const result = await validateSessionToken(token);
76-
return result;
74+
return validateSessionToken(token);
75+
},
76+
["session"],
77+
{
78+
tags: ["session"],
7779
}
7880
);
7981

82+
export const getCurrentSession = async (): Promise<SessionValidationResult> => {
83+
const cookieStore = await cookies();
84+
const token = cookieStore.get("session")?.value ?? null;
85+
return getSession(token);
86+
};
87+
8088
export async function invalidateSession(sessionId: string): Promise<void> {
8189
await prisma.session.delete({ where: { id: sessionId } });
8290
}

0 commit comments

Comments
 (0)