mirror of
https://github.com/sanidhyy/duolingo-clone.git
synced 2025-05-17 13:55:52 +08:00
89 lines
2.3 KiB
TypeScript
89 lines
2.3 KiB
TypeScript
"use server";
|
|
|
|
import { auth } from "@clerk/nextjs";
|
|
import { and, eq } from "drizzle-orm";
|
|
import { revalidatePath } from "next/cache";
|
|
|
|
import { MAX_HEARTS } from "@/constants";
|
|
import db from "@/db/drizzle";
|
|
import { getUserProgress, getUserSubscription } from "@/db/queries";
|
|
import { challengeProgress, challenges, userProgress } from "@/db/schema";
|
|
|
|
export const upsertChallengeProgress = async (challengeId: number) => {
|
|
const { userId } = auth();
|
|
|
|
if (!userId) throw new Error("Unauthorized.");
|
|
|
|
const currentUserProgress = await getUserProgress();
|
|
const userSubscription = await getUserSubscription();
|
|
|
|
if (!currentUserProgress) throw new Error("User progress not found.");
|
|
|
|
const challenge = await db.query.challenges.findFirst({
|
|
where: eq(challenges.id, challengeId),
|
|
});
|
|
|
|
if (!challenge) throw new Error("Challenge not found.");
|
|
|
|
const lessonId = challenge.lessonId;
|
|
|
|
const existingChallengeProgress = await db.query.challengeProgress.findFirst({
|
|
where: and(
|
|
eq(challengeProgress.userId, userId),
|
|
eq(challengeProgress.challengeId, challengeId)
|
|
),
|
|
});
|
|
|
|
const isPractice = !!existingChallengeProgress;
|
|
|
|
if (
|
|
currentUserProgress.hearts === 0 &&
|
|
!isPractice &&
|
|
!userSubscription?.isActive
|
|
)
|
|
return { error: "hearts" };
|
|
|
|
if (isPractice) {
|
|
await db
|
|
.update(challengeProgress)
|
|
.set({
|
|
completed: true,
|
|
})
|
|
.where(eq(challengeProgress.id, existingChallengeProgress.id));
|
|
|
|
await db
|
|
.update(userProgress)
|
|
.set({
|
|
hearts: Math.min(currentUserProgress.hearts + 1, MAX_HEARTS),
|
|
points: currentUserProgress.points + 10,
|
|
})
|
|
.where(eq(userProgress.userId, userId));
|
|
|
|
revalidatePath("/learn");
|
|
revalidatePath("/lesson");
|
|
revalidatePath("/quests");
|
|
revalidatePath("/leaderboard");
|
|
revalidatePath(`/lesson/${lessonId}`);
|
|
return;
|
|
}
|
|
|
|
await db.insert(challengeProgress).values({
|
|
challengeId,
|
|
userId,
|
|
completed: true,
|
|
});
|
|
|
|
await db
|
|
.update(userProgress)
|
|
.set({
|
|
points: currentUserProgress.points + 10,
|
|
})
|
|
.where(eq(userProgress.userId, userId));
|
|
|
|
revalidatePath("/learn");
|
|
revalidatePath("/lesson");
|
|
revalidatePath("/quests");
|
|
revalidatePath("/leaderboard");
|
|
revalidatePath(`/lesson/${lessonId}`);
|
|
};
|