Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions frontend/components/questions/question-filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ interface QuestionFilterProps {
onCategoryChange: (search: string) => void;
complexity: string;
onComplexityChange: (complexity: string) => void;
search: string;
onSearchChange: (search: string) => void;
onReset: () => void;
}

Expand All @@ -26,6 +28,8 @@ const QuestionFilter: React.FC<QuestionFilterProps> = ({
onCategoryChange,
complexity,
onComplexityChange,
search,
onSearchChange,
onReset,
}) => {
return (
Expand All @@ -35,6 +39,17 @@ const QuestionFilter: React.FC<QuestionFilterProps> = ({
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<Label htmlFor="search">Search</Label>
<Input
id="search"
value={search}
onChange={(e) => onSearchChange(e.target.value)}
placeholder="Search questions"
className="mt-1"
autoFocus
/>
</div>
<div>
<Label htmlFor="category">Category</Label>
<Input
Expand Down
30 changes: 23 additions & 7 deletions frontend/components/questions/questions-listing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

import { useAuth } from "@/app/auth/auth-context";
import { useEffect, useState, ChangeEvent } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import useSWR from "swr";
import { Question, QuestionArraySchema } from "@/lib/schemas/question-schema";
import { useRouter, useSearchParams } from "next/navigation";

import QuestionTable from "@/components/questions/questions-table";
import LoadingScreen from "@/components/common/loading-screen";
import DeleteQuestionModal from "@/components/questions/delete-question-modal";
import QuestionTable from "@/components/questions/questions-table";
import QuestionFilter from "@/components/questions/question-filter";
import { Button } from "@/components/ui/button";
import { PlusIcon, Upload } from "lucide-react";
Expand Down Expand Up @@ -49,8 +48,11 @@ export default function QuestionListing() {
searchParams.get("complexity") || ""
);
const { toast } = useToast();

const [search, setSearch] = useState(searchParams.get("search") || "");

const { data, isLoading, mutate } = useSWR(
`http://localhost:8000/questions?category=${encodeURIComponent(category)}&complexity=${encodeURIComponent(complexity)}`,
`http://localhost:8000/questions?category=${encodeURIComponent(category)}&complexity=${encodeURIComponent(complexity)}&search=${encodeURIComponent(search)}`,
fetcher,
{
keepPreviousData: true,
Expand Down Expand Up @@ -79,8 +81,13 @@ export default function QuestionListing() {
} else {
params.delete("complexity");
}
if (search) {
params.set("search", search);
} else {
params.delete("search");
}
router.push(`?${params.toString()}`);
}, [category, complexity, router, searchParams]);
}, [category, complexity, search, router, searchParams]);

const handleView = (question: Question) => {
router.push(`/app/questions/${question.id}`);
Expand Down Expand Up @@ -212,18 +219,25 @@ export default function QuestionListing() {
}
};

const handleSearchChange = (newSearch: string) => {
const handleCategoryChange = (newSearch: string) => {
setCategory(newSearch);
};

const handleComplexityChange = (newComplexity: string) => {
if (newComplexity === "all") {
newComplexity = "";
}
setComplexity(newComplexity);
};

const handleSearchChange = (newSearch: string) => {
setSearch(newSearch);
};

const handleReset = () => {
setSearch("");
setCategory("");
setComplexity("");
router.push("");
};

Expand Down Expand Up @@ -258,9 +272,11 @@ export default function QuestionListing() {
)}
<QuestionFilter
category={category}
onCategoryChange={handleSearchChange}
onCategoryChange={handleCategoryChange}
complexity={complexity}
onComplexityChange={handleComplexityChange}
search={search}
onSearchChange={handleSearchChange}
onReset={handleReset}
/>
<QuestionTable
Expand Down
4 changes: 3 additions & 1 deletion question-service/app/crud/questions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ async def create_question(question: CreateQuestionModel):
new_question = await question_collection.insert_one(question.model_dump())
return await question_collection.find_one({"_id": new_question.inserted_id})

async def get_all_questions(category: str, complexity: str) -> QuestionCollection:
async def get_all_questions(category: str, complexity: str, search: str) -> QuestionCollection:
query = {}
if search:
query["title"] = {"$regex": search, "$options": "i"}
if category:
query["category"] = {"$regex": category, "$options": "i"}
if complexity:
Expand Down
4 changes: 2 additions & 2 deletions question-service/app/routers/questions.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ async def create(question: CreateQuestionModel):
return existing_question

@router.get("/", response_description="Get all questions", response_model=QuestionCollection)
async def get_all(category: str = None, complexity: str = None):
return await get_all_questions(category, complexity)
async def get_all(category: str = None, complexity: str = None, search: str = None):
return await get_all_questions(category, complexity, search)

@router.get("/{question_id}", response_description="Get question with specified id", response_model=QuestionModel)
async def get_question(question_id: str):
Expand Down