Skip to content

Commit 99d80d7

Browse files
Update App.tsx
1 parent 9f14fee commit 99d80d7

1 file changed

Lines changed: 33 additions & 8 deletions

File tree

App.tsx

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
import React, { useState, useEffect } from 'react';
33
import {
4-
ShieldCheck, Menu, ChevronLeft, BookOpen, MessageSquare, Settings, Activity, Zap, ChevronDown, ChevronRight, Flag, Award, Terminal as TerminalIcon, Layers, Lock, Sun, Moon, CheckCircle, Code, ArrowLeft, Send, Clipboard, X, HelpCircle, Book, Flame, MapPin, ToggleRight, ToggleLeft, FastForward, Key
4+
ShieldCheck, Menu, ChevronLeft, BookOpen, MessageSquare, Settings, Activity, Zap, ChevronDown, ChevronRight, Flag, Award, Terminal as TerminalIcon, Layers, Lock, Sun, Moon, CheckCircle, Code, ArrowLeft, Send, Clipboard, X, HelpCircle, Book, Flame, MapPin, ToggleRight, ToggleLeft, FastForward, Key, AlertTriangle, Check
55
} from 'lucide-react';
66
import ReactMarkdown from 'react-markdown';
77
import Terminal from './components/Terminal';
@@ -329,6 +329,16 @@ const App: React.FC = () => {
329329
setShowApiKeyModal(false);
330330
};
331331

332+
const handleCertificateAccess = () => {
333+
if (userProfile?.isCertified) {
334+
setAppState(AppState.CERTIFICATE);
335+
} else {
336+
alert("Access Denied: You must pass the Final Certification Exam first.");
337+
}
338+
setMobileMenuOpen(false);
339+
setActiveMobileTab('learn');
340+
};
341+
332342
const getDifficultyColor = (diff: string) => {
333343
switch(diff) {
334344
case 'Beginner': return 'bg-gray-800 text-gray-400 border-gray-700';
@@ -361,9 +371,9 @@ const App: React.FC = () => {
361371
<ShieldCheck size={16} className={userProfile?.isCertified ? "text-green-500" : "text-gray-400"} />
362372
Certification
363373
</button>
364-
<button onClick={() => {setAppState(AppState.CERTIFICATE); setMobileMenuOpen(false); setActiveMobileTab('learn');}} className={`w-full flex items-center gap-3 px-3 py-2 rounded-md text-xs font-medium transition-colors ${appState === AppState.CERTIFICATE ? 'bg-brand/10 text-brand' : 'text-gray-400 hover:bg-[#111]'}`}>
374+
<button onClick={handleCertificateAccess} className={`w-full flex items-center gap-3 px-3 py-2 rounded-md text-xs font-medium transition-colors ${appState === AppState.CERTIFICATE ? 'bg-brand/10 text-brand' : 'text-gray-400 hover:bg-[#111]'}`}>
365375
<Award size={16} className={userProfile?.isCertified ? "text-brand" : "text-gray-400"} />
366-
My Credential
376+
My Credential {userProfile?.isCertified ? "" : "(Locked)"}
367377
</button>
368378
<button onClick={() => setShowApiKeyModal(true)} className="w-full flex items-center gap-3 px-3 py-2 rounded-md text-xs font-medium text-gray-400 hover:bg-[#111] transition-colors">
369379
<Key size={16} /> API Key
@@ -444,11 +454,11 @@ const App: React.FC = () => {
444454
{isDarkMode ? <Sun size={18} /> : <Moon size={18} />}
445455
</button>
446456

447-
<div className="flex items-center gap-2 px-3 py-1 bg-gray-100 dark:bg-[#111] rounded border border-gray-200 dark:border-[#27272a]">
457+
<div className="flex items-center gap-2 px-3 py-1 bg-gray-100 dark:bg-[#111] rounded border border-gray-200 dark:border-gray-700">
448458
<Flame size={12} className="text-orange-500 fill-orange-500" />
449459
<span className="text-xs font-bold text-gray-700 dark:text-gray-300">{userProfile?.streak || 1}</span>
450460
</div>
451-
<div className="flex items-center gap-2 px-3 py-1 bg-gray-100 dark:bg-[#111] rounded border border-gray-200 dark:border-[#27272a]">
461+
<div className="flex items-center gap-2 px-3 py-1 bg-gray-100 dark:bg-[#111] rounded border border-gray-200 dark:border-gray-700">
452462
<Zap size={12} className="text-brand fill-brand" />
453463
<span className="text-xs font-bold text-gray-700 dark:text-gray-300">{userProfile?.xp || 0} XP</span>
454464
</div>
@@ -514,7 +524,15 @@ const App: React.FC = () => {
514524
</div>
515525

516526
<div className="p-4 border border-gray-200 dark:border-[#27272a] rounded-lg bg-gray-50 dark:bg-[#050505]">
517-
<div className="flex gap-2"><input type="text" value={flagInput} onChange={(e) => setFlagInput(e.target.value)} placeholder="CIPHER-CTF{...}" className="flex-1 bg-white dark:bg-[#0a0a0a] border border-gray-300 dark:border-[#27272a] rounded px-3 py-2 text-gray-900 dark:text-white font-mono text-sm focus:border-brand outline-none" /><button onClick={handleFlagSubmit} className="bg-gray-900 dark:bg-white text-white dark:text-black font-bold px-4 py-2 rounded text-sm hover:opacity-90">Submit</button></div>
527+
<div className="flex gap-2 items-center">
528+
<input type="text" value={flagInput} onChange={(e) => setFlagInput(e.target.value)} placeholder="CIPHER-CTF{...}" className={`flex-1 bg-white dark:bg-[#0a0a0a] border rounded px-3 py-2 text-gray-900 dark:text-white font-mono text-sm outline-none transition-all ${flagStatus === 'error' ? 'border-red-500 ring-1 ring-red-500 animate-pulse' : 'border-gray-300 dark:border-[#27272a] focus:border-brand'}`} />
529+
<button onClick={handleFlagSubmit} className="bg-gray-900 dark:bg-white text-white dark:text-black font-bold px-4 py-2 rounded text-sm hover:opacity-90 flex items-center gap-2">
530+
{flagStatus === 'success' ? <Check size={16} className="text-green-500" /> : flagStatus === 'error' ? <AlertTriangle size={16} className="text-red-500" /> : <Send size={16} />}
531+
{flagStatus === 'success' ? "CAPTURED" : "Submit"}
532+
</button>
533+
</div>
534+
{flagStatus === 'success' && <p className="text-green-500 text-xs mt-2 font-bold animate-bounce">Access Granted! +{activeCTF.xpReward} XP</p>}
535+
{flagStatus === 'error' && <p className="text-red-500 text-xs mt-2 font-bold">Incorrect Flag. Try again.</p>}
518536
</div>
519537
</div>
520538
</div>
@@ -597,8 +615,15 @@ const App: React.FC = () => {
597615
<div className="prose prose-sm max-w-none mb-6 break-words text-gray-700 dark:text-gray-400 leading-relaxed dark:prose-invert">
598616
<ReactMarkdown components={MarkdownComponents}>{activeCTF.description}</ReactMarkdown>
599617
</div>
600-
<div className="mb-6">
601-
<div className="flex gap-2"><input type="text" value={flagInput} onChange={(e) => setFlagInput(e.target.value)} placeholder="CIPHER-CTF{...}" className="flex-1 border rounded px-3 py-2 text-sm bg-white dark:bg-[#0a0a0a] text-gray-900 dark:text-white border-gray-300 dark:border-[#27272a] font-mono outline-none focus:border-brand" /><button onClick={handleFlagSubmit} className="bg-gray-900 dark:bg-white text-white dark:text-black px-4 rounded font-bold text-sm"><Send size={16}/></button></div>
618+
<div className="mb-6 p-4 rounded-lg bg-gray-50 dark:bg-[#050505] border border-gray-200 dark:border-[#27272a]">
619+
<div className="flex gap-2 items-center">
620+
<input type="text" value={flagInput} onChange={(e) => setFlagInput(e.target.value)} placeholder="CIPHER-CTF{...}" className={`flex-1 border rounded px-3 py-2 text-sm bg-white dark:bg-[#0a0a0a] text-gray-900 dark:text-white font-mono outline-none transition-all ${flagStatus === 'error' ? 'border-red-500 ring-1 ring-red-500' : 'border-gray-300 dark:border-[#27272a] focus:border-brand'}`} />
621+
<button onClick={handleFlagSubmit} className="bg-gray-900 dark:bg-white text-white dark:text-black px-4 rounded font-bold text-sm h-[38px] flex items-center justify-center min-w-[50px]">
622+
{flagStatus === 'success' ? <Check size={16} className="text-green-500" /> : <Send size={16} />}
623+
</button>
624+
</div>
625+
{flagStatus === 'success' && <p className="text-green-500 text-xs mt-2 font-bold text-center">Correct! +{activeCTF.xpReward} XP</p>}
626+
{flagStatus === 'error' && <p className="text-red-500 text-xs mt-2 font-bold text-center">Incorrect Flag</p>}
602627
</div>
603628
</div>
604629
)}

0 commit comments

Comments
 (0)