@@ -10,7 +10,7 @@ import {
1010 useSandpack
1111} from "@codesandbox/sandpack-react" ;
1212import { Button } from "@/components/ui/button" ;
13- import { IconPlayerPlay , IconCheck , IconRotateClockwise , IconRobot } from "@tabler/icons-react" ;
13+ import { IconPlayerPlay , IconCheck , IconRotateClockwise } from "@tabler/icons-react" ;
1414import { toast } from "sonner" ;
1515import { useTranslations } from "next-intl" ;
1616import { createClient } from "@/lib/supabase/client" ;
@@ -31,8 +31,6 @@ const SubmitButton = ({ onComplete }: { onComplete: () => void }) => {
3131 const handleSubmit = async ( ) => {
3232 setLoading ( true ) ;
3333 try {
34- // In a real app, you'd send sandpack.files to an API to evaluate
35- // For now we simulate success after 2 seconds
3634 await new Promise ( r => setTimeout ( r , 2000 ) ) ;
3735 onComplete ( ) ;
3836 toast . success ( "Solution submitted and verified!" ) ;
@@ -64,13 +62,13 @@ export default function CodeChallengeWrapper({
6462 tenantId,
6563} : CodeChallengeWrapperProps ) {
6664 const [ isCompleted , setIsCompleted ] = useState ( initialCompleted ) ;
67- const tGamification = useTranslations ( "gamification" ) ;
65+ const tGamification = useTranslations ( "components. gamification" ) ;
6866 const supabase = createClient ( ) ;
6967
7068 const handleComplete = async ( ) => {
7169 setIsCompleted ( true ) ;
72- // Persist completion in Supabase
73- const { data : { session } } = await supabase . auth . getSession ( ) ; const user = session ?. user ;
70+ const { data : { session } } = await supabase . auth . getSession ( ) ;
71+ const user = session ?. user ;
7472 if ( user ) {
7573 await supabase . from ( 'exercise_completions' ) . insert ( {
7674 exercise_id : exerciseId ,
@@ -84,57 +82,92 @@ export default function CodeChallengeWrapper({
8482 }
8583
8684 return (
87- < div className = "space-y-4" >
88- < SandpackProvider
89- files = { files }
90- theme = "dark"
91- template = "react"
92- options = { {
93- activeFile : exercise . active_file || undefined ,
94- visibleFiles : exercise . visible_files || undefined ,
95- } }
96- >
97- < SandpackLayout className = "rounded-xl overflow-hidden border shadow-soft ring-1 ring-border/50" >
98- < SandpackFileExplorer className = "h-[600px] border-r bg-muted/50" />
99- < SandpackCodeEditor
100- className = "h-[600px]"
101- showLineNumbers
102- showTabs
103- closableTabs
104- />
105- < div className = "flex flex-col border-l h-[600px] bg-background" >
106- < div className = "p-3 border-b flex items-center justify-between bg-muted/30" >
107- < span className = "text-xs font-medium uppercase tracking-wider text-muted-foreground" > Output</ span >
108- < div className = "flex items-center gap-2" >
109- < SubmitButton onComplete = { handleComplete } />
85+ < >
86+ < style > { `
87+ .sp-challenge-wrapper .sp-layout {
88+ --sp-layout-height: clamp(400px, calc(100svh - 280px), 720px);
89+ width: 100%;
90+ }
91+ .sp-challenge-wrapper .sp-output-panel {
92+ height: clamp(400px, calc(100svh - 280px), 720px);
93+ min-height: 400px;
94+ }
95+ @media (max-width: 639px) {
96+ .sp-challenge-wrapper .sp-layout {
97+ --sp-layout-height: 350px;
98+ flex-direction: column !important;
99+ height: 610px !important;
100+ }
101+ .sp-challenge-wrapper .sp-file-explorer {
102+ display: none !important;
103+ }
104+ .sp-challenge-wrapper .sp-editor {
105+ flex: 0 0 350px !important;
106+ height: 350px !important;
107+ width: 100% !important;
108+ }
109+ .sp-challenge-wrapper .sp-output-panel {
110+ flex: 0 0 250px !important;
111+ height: 250px !important;
112+ min-height: 0 !important;
113+ width: 100% !important;
114+ border-top: 1px solid hsl(var(--border));
115+ border-left: none !important;
116+ }
117+ }
118+ ` } </ style >
119+
120+ < div className = "space-y-4 sp-challenge-wrapper" >
121+ < SandpackProvider
122+ files = { files }
123+ theme = "dark"
124+ template = "react"
125+ options = { {
126+ activeFile : exercise . active_file || undefined ,
127+ visibleFiles : exercise . visible_files || undefined ,
128+ } }
129+ >
130+ < SandpackLayout className = "rounded-xl overflow-hidden border shadow-soft ring-1 ring-border/50" >
131+ < SandpackFileExplorer className = "border-r bg-muted/50" />
132+ < SandpackCodeEditor
133+ showLineNumbers
134+ showTabs
135+ closableTabs
136+ />
137+ < div className = "sp-output-panel flex flex-col border-l bg-background" >
138+ < div className = "p-3 border-b flex items-center justify-between bg-muted/30 shrink-0" >
139+ < span className = "text-xs font-medium uppercase tracking-wider text-muted-foreground" > Output</ span >
140+ < div className = "flex items-center gap-2" >
141+ < SubmitButton onComplete = { handleComplete } />
142+ </ div >
110143 </ div >
144+ < SandpackPreview
145+ className = "flex-1 min-h-0"
146+ showNavigator = { false }
147+ showRefreshButton = { true }
148+ />
111149 </ div >
112- < SandpackPreview
113- className = "flex-1"
114- showNavigator = { false }
115- showRefreshButton = { true }
116- />
117- </ div >
118- </ SandpackLayout >
119- </ SandpackProvider >
150+ </ SandpackLayout >
151+ </ SandpackProvider >
120152
121- { isCompleted && (
122- < div className = "p-4 bg-green-50 border border-green-100 rounded-xl flex items-center justify-between animate-in fade-in slide-in-from-bottom-2" >
123- < div className = "flex items-center gap-3" >
124- < div className = "h-10 w-10 bg-green-100 text-green-600 rounded-full flex items-center justify-center" >
125- < IconCheck size = { 24 } />
126- </ div >
127- < div >
128- < h4 className = "font-semibold text-green-900" > Challenge Completed!</ h4 >
129- < p className = "text-sm text-green-700" > Excellent work. You've successfully solved this coding challenge.</ p >
153+ { isCompleted && (
154+ < div className = "p-4 my-2 bg-green-50 border border-green-100 rounded-xl flex items-center justify-between animate-in fade-in slide-in-from-bottom-2" >
155+ < div className = "flex items-center gap-3" >
156+ < div className = "h-10 w-10 bg-green-100 text-green-600 rounded-full flex items-center justify-center shrink-0" >
157+ < IconCheck size = { 24 } />
158+ </ div >
159+ < div >
160+ < h4 className = "font-semibold text-green-900" > Challenge Completed!</ h4 >
161+ < p className = "text-sm text-green-700" > Excellent work. You've successfully solved this coding challenge.</ p >
162+ </ div >
130163 </ div >
164+ < Button variant = "outline" className = "text-green-700 border-green-200 hover:bg-green-100 gap-2 shrink-0 ml-4" >
165+ < IconRotateClockwise size = { 18 } />
166+ Next Activity
167+ </ Button >
131168 </ div >
132- < Button variant = "outline" className = "text-green-700 border-green-200 hover:bg-green-100 gap-2" >
133- < IconRotateClockwise size = { 18 } />
134- Next Activity
135- </ Button >
136- </ div >
137- ) }
138- </ div >
169+ ) }
170+ </ div >
171+ </ >
139172 ) ;
140173}
0 commit comments