-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'enhancement/question-cat-enum' of github.com:CS3219-AY2…
…425S1/cs3219-ay2425s1-project-g50 into enhancement/question-cat-enum
- Loading branch information
Showing
15 changed files
with
387 additions
and
220 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import AuthPageWrapper from "@/components/auth/auth-page-wrapper"; | ||
import FindMatch from "@/components/matching/find-match"; | ||
import { Suspense } from "react"; | ||
|
||
export default function MatchingPage() { | ||
return ( | ||
<AuthPageWrapper requireLoggedIn> | ||
<Suspense> | ||
<FindMatch /> | ||
</Suspense> | ||
</AuthPageWrapper> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
"use client"; | ||
import React, { useState, useEffect } from "react"; | ||
import { MatchForm } from "@/components/matching/matching-form"; | ||
import { SearchProgress } from "@/components/matching/search-progress"; | ||
import { SelectionSummary } from "@/components/matching/selection-summary"; | ||
import { useToast } from "@/components/hooks/use-toast"; | ||
|
||
export default function FindMatch() { | ||
const [selectedDifficulty, setSelectedDifficulty] = useState<string>(""); | ||
const [selectedTopic, setSelectedTopic] = useState<string>(""); | ||
const [isSearching, setIsSearching] = useState<boolean>(false); | ||
const [waitTime, setWaitTime] = useState<number>(0); | ||
const { toast } = useToast(); | ||
|
||
useEffect(() => { | ||
let interval: NodeJS.Timeout | undefined; | ||
if (isSearching) { | ||
interval = setInterval(() => { | ||
setWaitTime((prevTime) => prevTime + 1); | ||
}, 1000); | ||
} else { | ||
setWaitTime(0); | ||
} | ||
return () => clearInterval(interval); | ||
}, [isSearching]); | ||
|
||
const handleSearch = () => { | ||
if (selectedDifficulty && selectedTopic) { | ||
setIsSearching(true); | ||
} else { | ||
toast({ | ||
title: "Invalid Selection", | ||
description: "Please select both a difficulty level and a topic", | ||
variant: "destructive", | ||
}); | ||
} | ||
}; | ||
|
||
const handleCancel = () => { | ||
setIsSearching(false); | ||
setWaitTime(0); | ||
}; | ||
|
||
return ( | ||
<div className="container mx-auto p-4"> | ||
<MatchForm | ||
selectedDifficulty={selectedDifficulty} | ||
setSelectedDifficulty={setSelectedDifficulty} | ||
selectedTopic={selectedTopic} | ||
setSelectedTopic={setSelectedTopic} | ||
handleSearch={handleSearch} | ||
isSearching={isSearching} | ||
handleCancel={handleCancel} | ||
/> | ||
|
||
{isSearching && <SearchProgress waitTime={waitTime} />} | ||
|
||
{!isSearching && (selectedDifficulty || selectedTopic) && ( | ||
<SelectionSummary | ||
selectedDifficulty={selectedDifficulty} | ||
selectedTopic={selectedTopic} | ||
/> | ||
)} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import React from "react"; | ||
import { Button } from "@/components/ui/button"; | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardFooter, | ||
CardHeader, | ||
CardTitle, | ||
} from "@/components/ui/card"; | ||
import { | ||
Select, | ||
SelectContent, | ||
SelectItem, | ||
SelectTrigger, | ||
SelectValue, | ||
} from "@/components/ui/select"; | ||
import { Label } from "@/components/ui/label"; | ||
|
||
const difficulties: string[] = ["Easy", "Medium", "Hard"]; | ||
const topics: string[] = [ | ||
"Arrays", | ||
"Strings", | ||
"Linked Lists", | ||
"Trees", | ||
"Graphs", | ||
"Dynamic Programming", | ||
]; | ||
|
||
interface MatchFormProps { | ||
selectedDifficulty: string; | ||
setSelectedDifficulty: (difficulty: string) => void; | ||
selectedTopic: string; | ||
setSelectedTopic: (topic: string) => void; | ||
handleSearch: () => void; | ||
isSearching: boolean; | ||
handleCancel: () => void; | ||
} | ||
|
||
export function MatchForm({ | ||
selectedDifficulty, | ||
setSelectedDifficulty, | ||
selectedTopic, | ||
setSelectedTopic, | ||
handleSearch, | ||
isSearching, | ||
handleCancel, | ||
}: MatchFormProps) { | ||
return ( | ||
<Card className="w-full max-w-2xl mx-auto"> | ||
<CardHeader> | ||
<CardTitle>Find a Match</CardTitle> | ||
<CardDescription> | ||
Select your preferred difficulty level and topic to find a match. | ||
</CardDescription> | ||
</CardHeader> | ||
<CardContent> | ||
<div className="space-y-6"> | ||
<div> | ||
<Label | ||
htmlFor="difficulty-select" | ||
className="text-lg font-medium mb-2 block" | ||
> | ||
Difficulty Level | ||
</Label> | ||
<Select | ||
value={selectedDifficulty} | ||
onValueChange={setSelectedDifficulty} | ||
> | ||
<SelectTrigger id="difficulty-select"> | ||
<SelectValue placeholder="Select difficulty" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
{difficulties.map((difficulty) => ( | ||
<SelectItem key={difficulty} value={difficulty}> | ||
{difficulty} | ||
</SelectItem> | ||
))} | ||
</SelectContent> | ||
</Select> | ||
</div> | ||
<div> | ||
<Label | ||
htmlFor="topic-select" | ||
className="text-lg font-medium mb-2 block" | ||
> | ||
Topic | ||
</Label> | ||
<Select value={selectedTopic} onValueChange={setSelectedTopic}> | ||
<SelectTrigger id="topic-select"> | ||
<SelectValue placeholder="Select topic" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
{topics.map((topic) => ( | ||
<SelectItem key={topic} value={topic}> | ||
{topic} | ||
</SelectItem> | ||
))} | ||
</SelectContent> | ||
</Select> | ||
</div> | ||
</div> | ||
</CardContent> | ||
<CardFooter className="flex justify-between"> | ||
{!isSearching ? ( | ||
<Button onClick={handleSearch}>Find Match</Button> | ||
) : ( | ||
<Button variant="destructive" onClick={handleCancel}> | ||
Cancel Search | ||
</Button> | ||
)} | ||
</CardFooter> | ||
</Card> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React from "react"; | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardHeader, | ||
CardTitle, | ||
} from "@/components/ui/card"; | ||
import { Progress } from "@/components/ui/progress"; | ||
import { Clock } from "lucide-react"; | ||
|
||
interface SearchProgressProps { | ||
waitTime: number; | ||
} | ||
|
||
export function SearchProgress({ waitTime }: SearchProgressProps) { | ||
return ( | ||
<Card className="w-full max-w-2xl mx-auto mt-4"> | ||
<CardHeader> | ||
<CardTitle>Searching for Match</CardTitle> | ||
<CardDescription> | ||
Please wait while we find a suitable match for you. | ||
</CardDescription> | ||
</CardHeader> | ||
<CardContent> | ||
<div className="space-y-4"> | ||
<Progress className="w-full" indeterminate /> | ||
<div className="flex items-center justify-between"> | ||
<div className="flex items-center space-x-2"> | ||
<Clock className="h-4 w-4" /> | ||
<span> | ||
Wait Time: {Math.floor(waitTime / 60)}: | ||
{(waitTime % 60).toString().padStart(2, "0")} | ||
</span> | ||
</div> | ||
<span>Searching...</span> | ||
</div> | ||
</div> | ||
</CardContent> | ||
</Card> | ||
); | ||
} |
Oops, something went wrong.