11import { redirect } from "next/navigation" ;
2+ import { revalidatePath } from "next/cache" ;
23import Link from "next/link" ;
34import { createClient as createServerClient } from "../../lib/supabase/server" ;
45import { Cinzel } from "next/font/google" ;
5- import checkUserCompletedQuizzes from "@/lib/checkUserCompletedQuizzes" ;
66import { ArrowBigLeft , ArrowBigDown , ArrowBigRight } from "lucide-react" ;
77
88const cinzel = Cinzel ( {
@@ -17,6 +17,36 @@ async function logout() {
1717 redirect ( "/" ) ;
1818}
1919
20+ async function resetQuestProgress ( ) {
21+ "use server" ;
22+ const supabase = await createServerClient ( ) ;
23+ const {
24+ data : { user } ,
25+ } = await supabase . auth . getUser ( ) ;
26+
27+ if ( ! user ) {
28+ return ;
29+ }
30+
31+ // Delete all quest completions for this user
32+ // The trigger will automatically update quests_completed count to 0
33+ const { error : deleteError } = await supabase
34+ . from ( "quest_completions" )
35+ . delete ( )
36+ . eq ( "user_id" , user . id ) ;
37+
38+ if ( deleteError ) {
39+ console . error ( "Error deleting quest completions:" , deleteError ) ;
40+ }
41+
42+ // Revalidate the dashboard and profile pages to refresh data
43+ revalidatePath ( "/dashboard" ) ;
44+ revalidatePath ( "/profile" ) ;
45+
46+ // Redirect to refresh the page
47+ redirect ( "/dashboard" ) ;
48+ }
49+
2050export default async function DashboardPage ( ) {
2151 const supabase = await createServerClient ( ) ;
2252 const {
@@ -25,19 +55,30 @@ export default async function DashboardPage() {
2555
2656 if ( ! user ) redirect ( "/login" ) ;
2757
28- // Completed quizzes
29- const completedQuizzes = await checkUserCompletedQuizzes ( ) ;
30-
31- const isHelloWorldComplete = completedQuizzes . has ( "hello-world" ) ;
32- const isVariablesComplete = completedQuizzes . has ( "variables" ) ;
33- const isUserInputComplete = completedQuizzes . has ( "user-input" ) ;
34- const isConditionalsComplete = completedQuizzes . has ( "conditionals" ) ;
35- const isLoopsComplete = completedQuizzes . has ( "loops" ) ;
36- const isMathComplete = completedQuizzes . has ( "math" ) ;
37- const isFunctionsComplete = completedQuizzes . has ( "functions" ) ;
38- const isListsArraysComplete = completedQuizzes . has ( "lists-arrays" ) ;
39- const isDictionaryComplete = completedQuizzes . has ( "dictionary" ) ;
40- const isRecursionComplete = completedQuizzes . has ( "recursion" ) ;
58+ // Fetch individual quest completions from quest_completions table
59+ const { data : questCompletions , error : completionsError } = await supabase
60+ . from ( "quest_completions" )
61+ . select ( "quest_id" )
62+ . eq ( "user_id" , user . id ) ;
63+
64+ if ( completionsError ) {
65+ console . error ( `Error fetching quest completions: ${ completionsError . message } ` ) ;
66+ }
67+
68+ // Create a Set of completed quest IDs for quick lookup
69+ const completedQuestIds = new Set ( questCompletions ?. map ( ( qc ) => qc . quest_id ) || [ ] ) ;
70+
71+ // Check individual quest completion status
72+ const isHelloWorldComplete = completedQuestIds . has ( "hello-world" ) ;
73+ const isVariablesComplete = completedQuestIds . has ( "variables" ) ;
74+ const isUserInputComplete = completedQuestIds . has ( "user-input" ) ;
75+ const isConditionalsComplete = completedQuestIds . has ( "conditionals" ) ;
76+ const isLoopsComplete = completedQuestIds . has ( "loops" ) ;
77+ const isMathComplete = completedQuestIds . has ( "math" ) ;
78+ const isFunctionsComplete = completedQuestIds . has ( "functions" ) ;
79+ const isListsArraysComplete = completedQuestIds . has ( "lists-arrays" ) ;
80+ const isDictionaryComplete = completedQuestIds . has ( "dictionary" ) ;
81+ const isRecursionComplete = completedQuestIds . has ( "recursion" ) ;
4182
4283 const celestialButtonClasses =
4384 "btn border-2 border-cyan-400 text-cyan-400 bg-transparent hover:bg-cyan-900/50 hover:border-cyan-200 hover:text-cyan-200 shadow-lg shadow-cyan-500/50 transition duration-300 ease-in-out w-full" ;
@@ -66,18 +107,23 @@ export default async function DashboardPage() {
66107 >
67108 < div className = "flex justify-between items-start w-full" >
68109 < div className = "flex flex-col gap-4 p-0 w-fit" >
69- < h1 className = "text-white text-5xl font-bold tracking-wider mb-4" > Dashboard</ h1 >
70- < div className = "flex flex-col gap-4 w-32" >
71- < Link href = "/" className = { celestialButtonClasses } >
72- < span > Home</ span >
73- </ Link >
74- </ div >
110+ < h1 className = "text-white text-6xl font-bold tracking-wider mb-4 drop-shadow-[0_0_15px_rgba(255,255,255,0.5)] hover:drop-shadow-[0_0_20px_rgba(255,255,255,0.7)] transition-all duration-300" >
111+ Dashboard
112+ </ h1 >
75113 </ div >
76114
77115 < div className = "flex items-center gap-4 p-0 w-fit" >
116+ < Link href = "/" className = { celestialButtonNoFullWidth } >
117+ < span > Home</ span >
118+ </ Link >
78119 < Link href = "/profile" className = { celestialButtonNoFullWidth } >
79120 < span > Profile</ span >
80121 </ Link >
122+ < form action = { resetQuestProgress } >
123+ < button type = "submit" className = { celestialButtonNoFullWidth } >
124+ < span > Reset Quests</ span >
125+ </ button >
126+ </ form >
81127 < form action = { logout } >
82128 < button type = "submit" className = { celestialButtonNoFullWidth } >
83129 < span > Log out</ span >
0 commit comments