11"use client"
22
33import { useEffect , useMemo , useState } from "react"
4+ import { useRouter } from "next/navigation"
45import { ChevronDown } from "lucide-react"
56import { HeroSection } from "@/components/hero-section"
67import { VirtualizedProblemList } from "@/components/virtualized-problem-list"
78import { StreakWidget } from "@/components/streak-widget"
89import { StatsWidget } from "@/components/stats-widget"
10+ import {
11+ AlertDialog ,
12+ AlertDialogAction ,
13+ AlertDialogCancel ,
14+ AlertDialogContent ,
15+ AlertDialogDescription ,
16+ AlertDialogFooter ,
17+ AlertDialogHeader ,
18+ AlertDialogTitle ,
19+ } from "@/components/ui/alert-dialog"
920import { PageTransition } from "@/components/page-transition"
1021import { problems } from "@/lib/problems"
1122import { localizeCategory } from "@/lib/problems"
1223import type { Difficulty , Problem } from "@/lib/problems"
1324import {
25+ getApiSettings ,
1426 getSolvedProblemIds ,
1527 subscribeToProgressUpdates ,
1628} from "@/lib/local-progress"
29+ import { isMentorConfigured as resolveMentorConfigured } from "@/lib/mentor-access"
1730import { useAppLanguage } from "@/lib/use-app-language"
1831import { usePageEntryAnimation } from "@/lib/use-page-entry-animation"
1932import { useRestoreScroll } from "@/lib/use-restore-scroll"
@@ -49,6 +62,7 @@ function parseHomeViewState(value: unknown): HomeViewState | null {
4962}
5063
5164export default function HomePage ( ) {
65+ const router = useRouter ( )
5266 const { language, copy } = useAppLanguage ( )
5367 const shouldAnimateOnMount = usePageEntryAnimation ( )
5468 const [ viewState , setViewState ] = useRestoreScroll < HomeViewState > ( {
@@ -62,13 +76,23 @@ export default function HomePage() {
6276 } )
6377 const { selectedCategory, selectedDifficulty, sortBy } = viewState
6478 const [ solvedIds , setSolvedIds ] = useState < Set < string > > ( new Set ( ) )
79+ const [ isMentorReady , setIsMentorReady ] = useState ( false )
80+ const [ isMentorAlertOpen , setIsMentorAlertOpen ] = useState ( false )
6581
6682 useEffect ( ( ) => {
6783 const sync = ( ) => setSolvedIds ( getSolvedProblemIds ( ) )
6884 sync ( )
6985 return subscribeToProgressUpdates ( sync )
7086 } , [ ] )
7187
88+ useEffect ( ( ) => {
89+ const sync = ( ) => {
90+ setIsMentorReady ( resolveMentorConfigured ( getApiSettings ( ) ) )
91+ }
92+ sync ( )
93+ return subscribeToProgressUpdates ( sync )
94+ } , [ ] )
95+
7296 const categories = useMemo ( ( ) => {
7397 const map = new Map < string , number > ( )
7498 for ( const problem of problems ) {
@@ -87,7 +111,6 @@ export default function HomePage() {
87111 language === "ko" ? "난이도 오름차순" : "Difficulty Ascending"
88112 const sortDifficultyDescLabel =
89113 language === "ko" ? "난이도 내림차순" : "Difficulty Descending"
90-
91114 const difficultyRank : Record < Difficulty , number > = {
92115 Easy : 0 ,
93116 Medium : 1 ,
@@ -123,6 +146,14 @@ export default function HomePage() {
123146 return source . filter ( ( problem ) => problem . difficulty === difficulty ) . length
124147 }
125148
149+ const handleExternalFeedbackOpen = ( ) => {
150+ if ( ! isMentorReady ) {
151+ setIsMentorAlertOpen ( true )
152+ return
153+ }
154+ router . push ( "/external-feedback" )
155+ }
156+
126157 return (
127158 < PageTransition animateOnMount = { shouldAnimateOnMount } >
128159 < HeroSection />
@@ -204,10 +235,37 @@ export default function HomePage() {
204235 < div className = "sticky top-24 flex flex-col gap-4" >
205236 < StreakWidget />
206237 < StatsWidget />
238+ < section className = "rounded-2xl border border-border/70 bg-card p-4 shadow-sm" >
239+ < p className = "text-sm font-semibold text-foreground" > { copy . home . externalFeedbackTitle } </ p >
240+ < p className = "mt-1 text-xs text-muted-foreground" > { copy . home . externalFeedbackDescription } </ p >
241+ < button
242+ type = "button"
243+ onClick = { handleExternalFeedbackOpen }
244+ className = "mt-3 inline-flex w-full items-center justify-center rounded-full bg-[#3182F6] px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-[#2870d8]"
245+ >
246+ { copy . home . externalFeedbackAction }
247+ </ button >
248+ </ section >
207249 </ div >
208250 </ aside >
209251 </ div >
210252 </ main >
253+ < AlertDialog open = { isMentorAlertOpen } onOpenChange = { setIsMentorAlertOpen } >
254+ < AlertDialogContent overlayClassName = "bg-black/45" >
255+ < AlertDialogHeader >
256+ < AlertDialogTitle > { copy . problem . mentorSetupTitle } </ AlertDialogTitle >
257+ < AlertDialogDescription >
258+ { copy . problem . mentorSetupDescription }
259+ </ AlertDialogDescription >
260+ </ AlertDialogHeader >
261+ < AlertDialogFooter >
262+ < AlertDialogCancel > { copy . problem . mentorSetupCancel } </ AlertDialogCancel >
263+ < AlertDialogAction onClick = { ( ) => router . push ( "/settings" ) } >
264+ { copy . problem . mentorSetupGoToSettings }
265+ </ AlertDialogAction >
266+ </ AlertDialogFooter >
267+ </ AlertDialogContent >
268+ </ AlertDialog >
211269 </ PageTransition >
212270 )
213271}
0 commit comments