Skip to content

Commit cc96d18

Browse files
committed
Add filter context
1 parent aa6c5ba commit cc96d18

File tree

10 files changed

+85
-81
lines changed

10 files changed

+85
-81
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
**/.env
2-
.idea
2+
.idea
3+
*.log

matching-service-api/log/matching_service_api.log

Lines changed: 0 additions & 35 deletions
This file was deleted.

matching-service/log/matching_service.log

Lines changed: 0 additions & 8 deletions
This file was deleted.

peerprep/app/questions/page.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import React from "react";
22
import QuestionList from "@/components/questionpage/QuestionList";
33
import Matchmaking from "@/components/questionpage/Matchmaking";
4+
import { QuestionFilterProvider } from "@/contexts/QuestionFilterContext";
45

56
const QuestionsPage = () => {
67
return (
7-
<div>
8+
<QuestionFilterProvider>
89
<Matchmaking></Matchmaking>
910
<QuestionList></QuestionList>
10-
</div>
11+
</QuestionFilterProvider>
1112
);
1213
};
1314

peerprep/components/questionpage/Matchmaking.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,27 @@
22
import React from "react";
33
import { useRouter } from "next/navigation";
44
import PeerprepButton from "../shared/PeerprepButton";
5+
import { useQuestionFilter } from "@/contexts/QuestionFilterContext";
56

67
const Matchmaking = () => {
78
const router = useRouter();
9+
const { difficulty, topics } = useQuestionFilter();
10+
11+
const handleMatch = () => {
12+
console.log("Match attempted");
13+
console.log("Selected Difficulty:", difficulty);
14+
console.log("Selected Topics:", topics);
15+
// username as userid?
16+
// should probably just use the questionlist selections as params
17+
};
18+
819
return (
9-
<div className="p-4">
20+
// TODO: move this to some admin panel or something
21+
<div className="p-4 space-x-4">
1022
<PeerprepButton onClick={() => router.push(`questions/new`)}>
1123
Add Question
1224
</PeerprepButton>
25+
<PeerprepButton onClick={handleMatch}>Find Match</PeerprepButton>
1326
</div>
1427
);
1528
};

peerprep/components/questionpage/QuestionList.tsx

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ import QuestionCard from "./QuestionCard";
44
import { Question, StatusBody, Difficulty, isError } from "@/api/structs";
55
import PeerprepDropdown from "../shared/PeerprepDropdown";
66
import PeerprepSearchBar from "../shared/PeerprepSearchBar";
7-
7+
import { useQuestionFilter } from "@/contexts/QuestionFilterContext";
8+
// TODO make multiple select for topics at least
89
const QuestionList: React.FC = () => {
910
const [questions, setQuestions] = useState<Question[]>([]);
1011
const [loading, setLoading] = useState(true);
11-
const [difficultyFilter, setDifficultyFilter] = useState<string>(
12-
Difficulty.All
13-
);
14-
const [topicFilter, setTopicFilter] = useState<string>("all");
1512
const [searchFilter, setSearchFilter] = useState<string>("");
16-
const [topics, setTopics] = useState<string[]>(["all"]);
13+
const [topicsList, setTopicsList] = useState<string[]>(["all"]);
14+
15+
const { difficulty, setDifficulty, topics, setTopics } = useQuestionFilter();
1716

1817
useEffect(() => {
1918
const fetchQuestions = async () => {
@@ -34,19 +33,18 @@ const QuestionList: React.FC = () => {
3433
const uniqueTopics = Array.from(
3534
new Set(data.flatMap((question) => question.topicTags))
3635
);
37-
setTopics(["all", ...uniqueTopics]);
36+
setTopicsList(["all", ...uniqueTopics]);
3837
};
3938

4039
fetchQuestions();
4140
}, []);
4241

4342
const filteredQuestions = questions.filter((question) => {
4443
const matchesDifficulty =
45-
difficultyFilter === Difficulty.All ||
46-
Difficulty[question.difficulty] === difficultyFilter;
44+
difficulty === Difficulty.All ||
45+
Difficulty[question.difficulty] === difficulty;
4746
const matchesTopic =
48-
topicFilter === topics[0] ||
49-
(question.topicTags ?? []).includes(topicFilter);
47+
topics[0] === "all" || (question.topicTags ?? []).includes(topics[0]);
5048
const matchesSearch =
5149
searchFilter === "" ||
5250
(question.title ?? "").toLowerCase().includes(searchFilter.toLowerCase());
@@ -66,15 +64,15 @@ const QuestionList: React.FC = () => {
6664
/>
6765
<PeerprepDropdown
6866
label="Difficulty"
69-
value={difficultyFilter}
70-
onChange={(e) => setDifficultyFilter(e.target.value)}
67+
value={difficulty}
68+
onChange={(e) => setDifficulty(e.target.value)}
7169
options={Object.keys(Difficulty).filter((key) => isNaN(Number(key)))}
7270
/>
7371
<PeerprepDropdown
7472
label="Topics"
75-
value={topicFilter}
76-
onChange={(e) => setTopicFilter(e.target.value)}
77-
options={topics}
73+
value={topics[0]}
74+
onChange={(e) => setTopics([e.target.value])}
75+
options={topicsList}
7876
/>
7977
</div>
8078

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"use client";
2+
import { Difficulty } from "@/api/structs";
3+
import React, { createContext, useContext, useState, ReactNode } from "react";
4+
5+
interface QuestionFilterContextType {
6+
difficulty: string;
7+
setDifficulty: (difficulty: string) => void;
8+
topics: string[];
9+
setTopics: (topics: string[]) => void;
10+
}
11+
12+
const QuestionFilterContext = createContext<
13+
QuestionFilterContextType | undefined
14+
>(undefined);
15+
16+
export const QuestionFilterProvider: React.FC<{ children: ReactNode }> = ({
17+
children,
18+
}) => {
19+
const [difficulty, setDifficulty] = useState<string>(Difficulty.All); // default to all
20+
const [topics, setTopics] = useState<string[]>(["all"]); // I guess default set this too the whole list of topics from questionlist
21+
22+
return (
23+
<QuestionFilterContext.Provider
24+
value={{ difficulty, setDifficulty, topics, setTopics }}
25+
>
26+
{children}
27+
</QuestionFilterContext.Provider>
28+
);
29+
};
30+
31+
export const useQuestionFilter = (): QuestionFilterContextType => {
32+
const context = useContext(QuestionFilterContext);
33+
if (!context) {
34+
throw new Error(
35+
"useQuestionFilter must be used within a QuestionFilterProvider"
36+
);
37+
}
38+
return context;
39+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// maybe store SAFE user info and wrap the whole damn app in it

peerprep/middleware.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1-
import { cookies } from 'next/headers'
2-
import { NextResponse } from 'next/server'
3-
import type { NextRequest } from 'next/server'
1+
import { cookies } from "next/headers";
2+
import { NextResponse } from "next/server";
3+
import type { NextRequest } from "next/server";
44

55
function isNoSession(request: NextRequest): boolean {
6-
return request.nextUrl.pathname.startsWith('/auth') && cookies().has("session");
6+
return (
7+
request.nextUrl.pathname.startsWith("/auth") && cookies().has("session")
8+
);
79
}
810

911
function isSession(request: NextRequest): boolean {
10-
return !request.nextUrl.pathname.startsWith('/auth') && !cookies().has("session");
12+
return (
13+
!request.nextUrl.pathname.startsWith("/auth") && !cookies().has("session")
14+
);
1115
}
1216

1317
export function middleware(request: NextRequest) {
1418
if (isNoSession(request)) {
1519
return NextResponse.redirect(new URL("/questions", request.url));
1620
}
17-
21+
1822
if (isSession(request)) {
1923
return NextResponse.redirect(new URL("/auth/login", request.url));
2024
}
@@ -30,6 +34,6 @@ export const config = {
3034
* - _next/image (image optimization files)
3135
* - favicon.ico, sitemap.xml, robots.txt (metadata files)
3236
*/
33-
'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
37+
"/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
3438
],
35-
}
39+
};

storage-blob-api/log/matching_service_api.log

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)