Skip to content

Commit 1eac237

Browse files
authored
Merge pull request #7 from pyKinsu/Quiz
Updated quiz features
2 parents c965d6e + 4259f5a commit 1eac237

15 files changed

Lines changed: 1399 additions & 674 deletions

File tree

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { signOut } from 'firebase/auth';
77
import { auth } from '@/lib/firebase';
88
import { useAuth } from '@/lib/authContext';
99
import { Button } from '@/components/ui/button';
10-
import { getUserProfile } from '@/lib/userService';
10+
import { getUserProfile, updateUserProfile } from '@/lib/userService';
1111
import { getUserQuizStats } from '@/lib/quizService';
12+
import { ensureDefaultAvatar } from '@/lib/userService';
1213
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
1314
import { Menu, X, LogOut, Settings, FileText, HelpCircle, User, Code, BookOpen, Zap, ChevronRight, Award, BarChart3 } from 'lucide-react';
15+
import PageLoader from '@/components/PageLoader';
1416

1517
export default function DashboardPage() {
1618
const router = useRouter();
@@ -20,7 +22,6 @@ export default function DashboardPage() {
2022
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
2123
const [dropdownOpen, setDropdownOpen] = useState(false);
2224

23-
// NEW: Quiz stats state
2425
const [quizStats, setQuizStats] = useState({
2526
totalAttempts: 0,
2627
totalQuestions: 0,
@@ -31,20 +32,24 @@ export default function DashboardPage() {
3132
});
3233
const [statsLoading, setStatsLoading] = useState(true);
3334

34-
// Redirect to login if not authenticated
3535
useEffect(() => {
3636
if (!loading && !user) {
3737
router.push('/login');
3838
}
3939
}, [user, loading, router]);
4040

41-
// Fetch user profile from Firestore
4241
useEffect(() => {
4342
if (user) {
4443
const fetchProfile = async () => {
4544
try {
4645
const profile = await getUserProfile(user.uid);
4746
setUserProfile(profile);
47+
48+
// Ensure default avatar is set
49+
if (profile) {
50+
await ensureDefaultAvatar(user.uid, profile.firstName, profile.lastName);
51+
}
52+
4853
setProfileLoading(false);
4954
} catch (error) {
5055
console.error('Error fetching profile:', error);
@@ -55,12 +60,14 @@ export default function DashboardPage() {
5560
}
5661
}, [user]);
5762

58-
// NEW: Fetch quiz statistics
5963
useEffect(() => {
6064
if (user) {
6165
const fetchQuizStats = async () => {
6266
try {
6367
const stats = await getUserQuizStats(user.uid);
68+
console.log('Quiz stats fetched:', stats);
69+
console.log('Average score value:', stats.averageScore);
70+
console.log('Type of averageScore:', typeof stats.averageScore);
6471
setQuizStats(stats);
6572
setStatsLoading(false);
6673
} catch (error) {
@@ -81,31 +88,17 @@ export default function DashboardPage() {
8188
}
8289
};
8390

84-
const getInitials = (firstName?: string, lastName?: string) => {
85-
if (!firstName || !lastName) return 'U';
86-
return `${firstName.charAt(0)}${lastName.charAt(0)}`.toUpperCase();
87-
};
88-
8991
const getRoboHashUrl = (name: string) => {
9092
const hashString = name.replace(/\s+/g, '') || 'user';
9193
return `https://robohash.org/${hashString}?size=200x200&set=set1`;
9294
};
9395

9496
const avatarUrl = userProfile?.avatarUrl || getRoboHashUrl(`${userProfile?.firstName || 'User'} ${userProfile?.lastName || ''}`);
9597

96-
// Show loading state while checking authentication
9798
if (loading || profileLoading) {
98-
return (
99-
<div className="flex min-h-screen items-center justify-center bg-white">
100-
<div className="text-center">
101-
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-black mx-auto mb-4"></div>
102-
<p className="text-gray-600">Loading dashboard...</p>
103-
</div>
104-
</div>
105-
);
99+
return <PageLoader />;
106100
}
107101

108-
// Don't render if not authenticated
109102
if (!user) {
110103
return null;
111104
}
@@ -236,7 +229,7 @@ export default function DashboardPage() {
236229
<span className="text-sm font-medium">View Profile</span>
237230
</div>
238231
</Link>
239-
<Link href="/profile" onClick={() => setDropdownOpen(false)}>
232+
<Link href="/edit-profile" onClick={() => setDropdownOpen(false)}>
240233
<div className="flex items-center gap-3 px-5 py-3 text-gray-600 hover:bg-gray-100 hover:text-black cursor-pointer transition-colors">
241234
<Settings className="h-4 w-4" />
242235
<span className="text-sm font-medium">Edit Profile</span>
@@ -330,9 +323,9 @@ export default function DashboardPage() {
330323
</CardHeader>
331324
</Card>
332325

333-
{/* Profile Cards - NOW WITH REAL DATA */}
326+
{/* Profile Cards */}
334327
<div className="grid gap-3 sm:gap-4 grid-cols-2 sm:grid-cols-4 md:grid-cols-4 lg:grid-cols-8 mb-8">
335-
{/* Combined Quiz Attempts & Questions Card */}
328+
{/* Quiz Activity Card */}
336329
<Card className="border border-gray-200 bg-white shadow-sm hover:shadow-md transition-all duration-300 col-span-1 sm:col-span-2 md:col-span-2 lg:col-span-2">
337330
<CardHeader className="pb-2 pt-3 px-3 sm:pt-4 sm:px-4">
338331
<CardTitle className="text-sm sm:text-lg text-black">Quiz Activity</CardTitle>
@@ -355,7 +348,7 @@ export default function DashboardPage() {
355348
</CardContent>
356349
</Card>
357350

358-
{/* Stats Card - Correct and Wrong */}
351+
{/* Stats Card */}
359352
<Card className="border border-gray-200 bg-white shadow-sm hover:shadow-md transition-all duration-300 col-span-1 sm:col-span-2 md:col-span-2 lg:col-span-2">
360353
<CardHeader className="pb-2 pt-3 px-3 sm:pt-4 sm:px-4">
361354
<CardTitle className="text-sm sm:text-lg text-black">Stats</CardTitle>
@@ -376,7 +369,7 @@ export default function DashboardPage() {
376369
</CardContent>
377370
</Card>
378371

379-
{/* Correct & Wrong Answers Card */}
372+
{/* Answers Card */}
380373
<Card className="border border-gray-200 bg-white shadow-sm hover:shadow-md transition-all duration-300 col-span-1 sm:col-span-2 md:col-span-2 lg:col-span-2">
381374
<CardHeader className="pb-2 pt-3 px-3 sm:pt-4 sm:px-4">
382375
<CardTitle className="text-sm sm:text-lg text-black">Answers</CardTitle>
@@ -397,13 +390,12 @@ export default function DashboardPage() {
397390
</CardContent>
398391
</Card>
399392

400-
{/* Combined Profile & Account Card */}
393+
{/* Profile & Account Card */}
401394
<Card className="border border-gray-200 bg-white shadow-sm hover:shadow-md transition-all duration-300 col-span-1 sm:col-span-2 md:col-span-2 lg:col-span-2">
402395
<CardHeader className="pb-2 pt-3 px-3 sm:pt-4 sm:px-4">
403396
<CardTitle className="text-sm sm:text-lg text-black">Profile & Account</CardTitle>
404397
</CardHeader>
405398
<CardContent className="space-y-3 pt-0 pb-3 px-3 sm:pb-4 sm:px-4">
406-
{/* Profile Section */}
407399
<div>
408400
<div className="flex items-center gap-2 mb-3">
409401
<img
@@ -420,7 +412,6 @@ export default function DashboardPage() {
420412
</div>
421413
</div>
422414

423-
{/* Account Section */}
424415
<div className="space-y-1.5">
425416
<p className="text-xs text-gray-600 font-semibold">Member Since</p>
426417
<p className="text-2xl sm:text-3xl font-bold text-black">
@@ -430,7 +421,6 @@ export default function DashboardPage() {
430421
</p>
431422
</div>
432423

433-
{/* Status */}
434424
<div>
435425
<p className="text-xs text-gray-600 font-semibold mb-1">Status</p>
436426
<div className="inline-flex items-center gap-1.5 px-2 py-1 bg-green-100 text-green-700 rounded text-xs font-bold border border-green-300">
@@ -439,8 +429,7 @@ export default function DashboardPage() {
439429
</div>
440430
</div>
441431

442-
{/* Edit Button */}
443-
<Link href="/profile" className="block">
432+
<Link href="/edit-profile" className="block">
444433
<Button className="w-full bg-black hover:bg-gray-800 text-white text-xs py-1.5 sm:py-2 h-7 sm:h-8">
445434
<Settings className="h-3 w-3 mr-1" />
446435
Edit Profile

0 commit comments

Comments
 (0)