Add src/app/quiz/page.tsx

This commit is contained in:
2026-03-09 06:09:05 +00:00
parent 2e9ac9d9d3
commit 11c38b352b

381
src/app/quiz/page.tsx Normal file
View File

@@ -0,0 +1,381 @@
"use client";
import { useState, useEffect } from "react";
import { ArrowRight, CheckCircle, XCircle, RotateCcw } from "lucide-react";
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
interface QuizQuestion {
id: string;
question: string;
options: string[];
correctAnswer: number;
explanation: string;
}
const quizzes: Record<string, { title: string; questions: QuizQuestion[] }> = {
"password-security": {
title: "Password Security Quiz", questions: [
{
id: "1", question: "What is the minimum recommended password length?", options: ["8 characters", "10 characters", "12 characters", "6 characters"],
correctAnswer: 2,
explanation: "Security experts recommend at least 12 characters for strong passwords to resist brute force attacks."},
{
id: "2", question: "Which of these is the strongest password?", options: [
"Password123", "MyDog2024!", "X9#kL@mP2$wQ", "1234567890"],
correctAnswer: 2,
explanation: "Random combinations of letters, numbers, and special characters are strongest. Predictable patterns and personal information make passwords vulnerable."},
{
id: "3", question: "What does Two-Factor Authentication (2FA) add to your account security?", options: [
"A longer password", "A second layer of verification", "Password encryption", "Automatic password changes"],
correctAnswer: 1,
explanation: "2FA requires a second verification method (like a code from your phone) after entering your password, significantly increasing security."},
{
id: "4", question: "Should you use the same password for multiple accounts?", options: [
"Yes, it's easier to remember", "No, use unique passwords for each account", "Only for unimportant accounts", "Yes, with slight variations"],
correctAnswer: 1,
explanation: "Using unique passwords for each account means if one is compromised, others remain secure. Use a password manager to help manage them."},
{
id: "5", question: "How often should you change your passwords?", options: [
"Every day", "Every month", "Every year", "When compromised or every 90 days"],
correctAnswer: 3,
explanation: "Change passwords immediately if compromised. For regular maintenance, change every 90 days. More frequent changes can lead to weaker passwords."},
],
},
"phishing-detection": {
title: "Phishing Detection Quiz", questions: [
{
id: "1", question: "What is a red flag for phishing emails?", options: [
"Professional formatting", "Request for personal information", "Official company logo", "Clear sender address"],
correctAnswer: 1,
explanation: "Phishing emails often ask for passwords, social security numbers, or bank details. Legitimate companies never ask for sensitive info via email."},
{
id: "2", question: "How should you verify suspicious email links?", options: [
"Click and see if it's legitimate", "Hover over the link to see the actual URL", "Ask friends if they received it", "Contact the company through the email"],
correctAnswer: 1,
explanation: "Always hover over links to see their true destination before clicking. This reveals if the link actually goes where it claims to go."},
{
id: "3", question: "What common technique do phishers use?", options: [
"Formal business language", "Creating urgency or fear", "Providing too much information", "Using official company names"],
correctAnswer: 1,
explanation: "Phishing emails create artificial urgency (account locked, limited time) to make you act without thinking carefully."},
{
id: "4", question: "How can poor grammar indicate a phishing email?", options: [
"It doesn't matter", "Legitimate companies always have typos", "Professional emails are carefully proofread", "Grammar is unrelated to security"],
correctAnswer: 2,
explanation: "Legitimate companies proofread communications carefully. Numerous errors, awkward phrasing, or grammatical mistakes are phishing warning signs."},
{
id: "5", question: "What should you do if you suspect a phishing email?", options: [
"Reply asking them to stop", "Report it and don't click links", "Forward it to friends", "Click to check if it's real"],
correctAnswer: 1,
explanation: "Report phishing emails to your email provider and the company being impersonated. Never click links or provide information."},
],
},
"social-media-safety": {
title: "Social Media Safety Quiz", questions: [
{
id: "1", question: "What personal information should you never post on social media?", options: [
"Your hobbies", "Your exact location and home address", "Your favorite movies", "Your name"],
correctAnswer: 1,
explanation: "Never share your home address, phone number, or location. This information can be used for stalking, theft, or identity theft."},
{
id: "2", question: "How often should you review your privacy settings?", options: [
"Never", "Once a year", "Every few months", "Social media platforms never change them"],
correctAnswer: 2,
explanation: "Social media platforms frequently update privacy settings. Review yours every few months to ensure your information is protected."},
{
id: "3", question: "Is it safe to accept friend requests from strangers?", options: [
"Yes, more friends is better", "No, they could be scammers or stalkers", "Only if they have a profile picture", "Yes, if they have mutual friends"],
correctAnswer: 1,
explanation: "Strangers could be scammers, stalkers, or hackers. Always verify who you're connecting with before accepting requests."},
{
id: "4", question: "Before posting something, what should you think about?", options: [
"How many likes it will get", "If your future employer might see it", "If your parents will be proud", "How quickly you can post it"],
correctAnswer: 1,
explanation: "Employers, colleges, and others research social media profiles. Once posted, content is permanent and can affect your future."},
{
id: "5", question: "What is cyberbullying?", options: [
"Making friends online", "Harassment, threats, or humiliation online", "Following your friends", "Commenting on posts"],
correctAnswer: 1,
explanation: "Cyberbullying includes harassment, threats, and humiliation online. If you experience it, report it and reach out to trusted adults."},
],
},
};
export default function QuizPage() {
const [currentQuestion, setCurrentQuestion] = useState(0);
const [score, setScore] = useState(0);
const [selectedAnswer, setSelectedAnswer] = useState<number | null>(null);
const [showResult, setShowResult] = useState(false);
const [quizComplete, setQuizComplete] = useState(false);
const [questions, setQuestions] = useState<QuizQuestion[]>([]);
const [quizTitle, setQuizTitle] = useState("");
useEffect(() => {
// Select a random quiz for demo
const quizKeys = Object.keys(quizzes);
const randomKey = quizKeys[Math.floor(Math.random() * quizKeys.length)];
const quiz = quizzes[randomKey];
setQuestions(quiz.questions);
setQuizTitle(quiz.title);
}, []);
if (questions.length === 0) return null;
const handleAnswerSelect = (answerIndex: number) => {
if (!showResult) {
setSelectedAnswer(answerIndex);
setShowResult(true);
if (answerIndex === questions[currentQuestion].correctAnswer) {
setScore(score + 1);
}
}
};
const handleNextQuestion = () => {
if (currentQuestion + 1 < questions.length) {
setCurrentQuestion(currentQuestion + 1);
setSelectedAnswer(null);
setShowResult(false);
} else {
setQuizComplete(true);
}
};
const handleRestartQuiz = () => {
setCurrentQuestion(0);
setScore(0);
setSelectedAnswer(null);
setShowResult(false);
setQuizComplete(false);
};
const percentage = Math.round((score / questions.length) * 100);
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="entrance-slide"
borderRadius="pill"
contentWidth="compact"
sizing="largeSmall"
background="noise"
cardStyle="outline"
primaryButtonStyle="flat"
secondaryButtonStyle="radial-glow"
headingFontWeight="light"
>
<div id="nav" data-section="nav">
<NavbarStyleFullscreen
brandName="CyberSafe"
navItems={[
{ name: "Home", id: "/" },
{ name: "About", id: "#about" },
{ name: "Resources", id: "#features" },
{ name: "Learn", id: "#metrics" },
{ name: "Quiz", id: "/quiz" },
{ name: "Contact", id: "#contact" },
]}
bottomLeftText="Student Safety First"
bottomRightText="cybersafe@education.org"
/>
</div>
<div id="quiz" data-section="quiz" className="min-h-screen py-20 px-4 sm:px-6 lg:px-8">
<div className="max-w-2xl mx-auto">
{!quizComplete ? (
<div className="space-y-8">
{/* Header */}
<div className="text-center space-y-2">
<h1 className="text-4xl font-bold">{quizTitle}</h1>
<p className="text-lg text-foreground/70">
Question {currentQuestion + 1} of {questions.length}
</p>
</div>
{/* Progress Bar */}
<div className="w-full bg-background-accent rounded-pill h-2">
<div
className="bg-primary-cta h-2 rounded-pill transition-all duration-300"
style={{
width: `${((currentQuestion + 1) / questions.length) * 100}%`,
}}
/>
</div>
{/* Question */}
<div className="bg-card rounded-pill p-8 border border-background-accent">
<h2 className="text-2xl font-semibold mb-6">
{questions[currentQuestion].question}
</h2>
{/* Options */}
<div className="space-y-3">
{questions[currentQuestion].options.map((option, index) => (
<button
key={index}
onClick={() => handleAnswerSelect(index)}
disabled={showResult}
className={`w-full p-4 text-left rounded-pill border-2 transition-all ${
selectedAnswer === index
? index === questions[currentQuestion].correctAnswer
? "border-green-500 bg-green-500/10"
: "border-red-500 bg-red-500/10"
: showResult &&
index === questions[currentQuestion].correctAnswer
? "border-green-500 bg-green-500/10"
: "border-background-accent hover:border-primary-cta"
}`}
>
<div className="flex items-center justify-between">
<span className="font-medium">{option}</span>
{selectedAnswer === index && showResult && (
index === questions[currentQuestion].correctAnswer ? (
<CheckCircle className="w-5 h-5 text-green-500" />
) : (
<XCircle className="w-5 h-5 text-red-500" />
)
)}
{showResult &&
index === questions[currentQuestion].correctAnswer &&
selectedAnswer !== index && (
<CheckCircle className="w-5 h-5 text-green-500" />
)}
</div>
</button>
))}
</div>
{/* Explanation */}
{showResult && (
<div className="mt-6 p-4 bg-background-accent rounded-pill border border-primary-cta/30">
<p className="text-sm font-semibold text-primary-cta mb-2">Explanation:</p>
<p className="text-foreground/80">
{questions[currentQuestion].explanation}
</p>
</div>
)}
</div>
{/* Next Button */}
{showResult && (
<button
onClick={handleNextQuestion}
className="w-full py-3 px-6 bg-primary-cta text-background rounded-pill font-semibold flex items-center justify-center gap-2 hover:opacity-90 transition-opacity"
>
{currentQuestion + 1 === questions.length ? "See Results" : "Next Question"}
<ArrowRight className="w-5 h-5" />
</button>
)}
</div>
) : (
/* Results Screen */
<div className="space-y-8 text-center">
<div>
<h1 className="text-4xl font-bold mb-4">Quiz Complete!</h1>
<div className="w-32 h-32 mx-auto mb-6 rounded-full bg-primary-cta/10 flex items-center justify-center">
<div className="text-center">
<p className="text-5xl font-bold text-primary-cta">{percentage}%</p>
<p className="text-lg font-semibold text-foreground">
{score}/{questions.length}
</p>
</div>
</div>
</div>
{/* Result Message */}
<div className="bg-card rounded-pill p-8 border border-background-accent">
{percentage >= 80 ? (
<div className="space-y-2">
<p className="text-2xl font-bold text-green-600">Excellent!</p>
<p className="text-foreground/80">
You demonstrated strong cyber safety knowledge. Keep practicing to
maintain your skills!
</p>
</div>
) : percentage >= 60 ? (
<div className="space-y-2">
<p className="text-2xl font-bold text-yellow-600">Good Job!</p>
<p className="text-foreground/80">
You're on the right track! Review the explanations and try again to
improve your score.
</p>
</div>
) : (
<div className="space-y-2">
<p className="text-2xl font-bold text-red-600">Keep Learning!</p>
<p className="text-foreground/80">
Take time to review the core modules and try the quiz again to
strengthen your cyber safety knowledge.
</p>
</div>
)}
</div>
{/* Action Buttons */}
<div className="flex gap-4 justify-center">
<button
onClick={handleRestartQuiz}
className="py-3 px-8 bg-secondary-cta text-foreground rounded-pill font-semibold flex items-center gap-2 hover:opacity-90 transition-opacity"
>
<RotateCcw className="w-5 h-5" />
Try Again
</button>
<a
href="/#quiz"
className="py-3 px-8 bg-primary-cta text-background rounded-pill font-semibold flex items-center gap-2 hover:opacity-90 transition-opacity"
>
<ArrowRight className="w-5 h-5" />
More Quizzes
</a>
</div>
</div>
)}
</div>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="CyberSafe"
columns={[
{
title: "Learning", items: [
{ label: "Core Modules", href: "/#features" },
{ label: "Threat Awareness", href: "/#metrics" },
{ label: "Best Practices", href: "/#features" },
{ label: "FAQ", href: "/#faq" },
],
},
{
title: "Resources", items: [
{ label: "Blog", href: "#" },
{ label: "Webinars", href: "#" },
{ label: "Tools & Guides", href: "#" },
{ label: "Community", href: "#" },
],
},
{
title: "Support", items: [
{ label: "Contact Us", href: "/#contact" },
{ label: "Report Issues", href: "#" },
{ label: "Help Center", href: "#" },
{ label: "Feedback", href: "#" },
],
},
{
title: "Organization", items: [
{ label: "About Us", href: "/#about" },
{ label: "Our Mission", href: "/#about" },
{ label: "Partnerships", href: "#" },
{ label: "Careers", href: "#" },
],
},
]}
copyrightText="© 2025 CyberSafe. Empowering students with cyber safety knowledge."
/>
</div>
</ThemeProvider>
);
}