From 873638db2071fe5da55f16a82f723c610c98e1ea Mon Sep 17 00:00:00 2001 From: chukwuemekarita Date: Tue, 20 Oct 2026 15:52:30 +0100 Subject: [PATCH] fix: credential verification, quiz timer, network badge, Module.content types - #507: Fix credential verification by handling both 'valid' and 'isValid' property names from API response - #500: Add getFreighterNetwork() to show actual Freighter network on connect button badge instead of hardcoded value - #499: Add client-side quiz timer enforcement with auto-submit on expiry and countdown display in quiz header - #498: Change Module.content to union type (string | VideoContent | InteractiveContent) with type guards and parseModuleContent helper --- src/app/(auth)/connect/page.tsx | 16 ++++- .../[courseId]/modules/[moduleId]/page.tsx | 22 +++++- src/components/course/quiz-interface.tsx | 71 +++++++++++++++++-- src/lib/api/credentials.ts | 3 + src/lib/hooks/use-credentials.ts | 10 ++- src/lib/stellar/wallet.ts | 15 ++++ src/types/course.ts | 34 ++++++++- 7 files changed, 160 insertions(+), 11 deletions(-) diff --git a/src/app/(auth)/connect/page.tsx b/src/app/(auth)/connect/page.tsx index cf1827c..ee2ce00 100644 --- a/src/app/(auth)/connect/page.tsx +++ b/src/app/(auth)/connect/page.tsx @@ -4,8 +4,8 @@ import { useRouter } from "next/navigation"; import { useAuth } from "@/lib/hooks/use-auth"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; -import { Wallet, Shield, ArrowRight, Loader2, AlertCircle } from "lucide-react"; -import { isFreighterInstalled } from "@/lib/stellar/wallet"; +import { Wallet, Shield, ArrowRight, Loader2, AlertCircle, Globe } from "lucide-react"; +import { isFreighterInstalled, getFreighterNetwork } from "@/lib/stellar/wallet"; import { useEffect, useState } from "react"; import { useToastContext } from "@/components/shared/toast"; @@ -16,9 +16,13 @@ export default function ConnectPage() { const [freighterInstalled, setFreighterInstalled] = useState( null ); + // #500 — Track actual Freighter network to show correct badge + const [freighterNetwork, setFreighterNetwork] = useState(null); useEffect(() => { isFreighterInstalled().then(setFreighterInstalled); + // #500 — Get actual network from Freighter + getFreighterNetwork().then(setFreighterNetwork).catch(() => setFreighterNetwork(null)); }, []); useEffect(() => { @@ -115,6 +119,14 @@ export default function ConnectPage() { )} + {/* #500 — Show actual Freighter network */} + {freighterNetwork && ( +
+ + Network: {freighterNetwork} +
+ )} +

diff --git a/src/app/courses/[courseId]/modules/[moduleId]/page.tsx b/src/app/courses/[courseId]/modules/[moduleId]/page.tsx index 6ba152c..e868921 100644 --- a/src/app/courses/[courseId]/modules/[moduleId]/page.tsx +++ b/src/app/courses/[courseId]/modules/[moduleId]/page.tsx @@ -16,6 +16,7 @@ import { } from "lucide-react"; import Link from "next/link"; import { useState } from "react"; +import { isTextContent, isVideoContent, isInteractiveContent } from "@/types/course"; export default function ModulePage({ params, @@ -102,8 +103,25 @@ export default function ModulePage({

{module.description}

- {/* Render module content. In production, use a proper MD renderer. */} -
+ {/* #498 — Render module content with proper type handling */} + {isTextContent(module.content) && ( +
+ )} + {isVideoContent(module.content) && ( +
+