Skip to content

Commit 807dff0

Browse files
committed
Merge branch 'staging' into delete-button
2 parents c9029c4 + 074d970 commit 807dff0

File tree

5 files changed

+137
-46
lines changed

5 files changed

+137
-46
lines changed

apps/question-service/src/app/page.tsx

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ import {
3535
/**
3636
* defines the State of the page whe a user is deleing an object. Has 3 general states:
3737
* - {}: user is not deleting anything. The page's normal state
38-
* - {index: number, deleteConfirmed: false}: Modal popup asking whether to delete the question, pending user's decision to confirm or cancel
39-
* - {index: number, deleteConfirmed: true}: Currently deleting the question and reloading the database
38+
* - {index: docref string, deleteConfirmed: false}: Modal popup asking whether to delete the question, pending user's decision to confirm or cancel
39+
* - {index: docref string, deleteConfirmed: true}: Currently deleting the question and reloading the database
4040
*/
41-
type DeletionStage = {} | {index: number, deleteConfirmed: boolean}
41+
type DeletionStage = {} | {index: Question, deleteConfirmed: boolean}
4242

4343
function DeleteModal({isDeleting, questionTitle, okHandler, cancelHandler}: {questionTitle: string, okHandler: () => void, cancelHandler: () => void, isDeleting: boolean }) {
4444
const title: string = `Delete Question \"${questionTitle}\"?`
@@ -65,12 +65,15 @@ export default function Home() {
6565
const [questions, setQuestions] = useState<Question[] | undefined>(undefined); // Store the questions
6666
const [totalCount, setTotalCount] = useState<number | undefined>(undefined); // Store the total count of questions
6767
const [totalPages, setTotalPages] = useState<number | undefined>(undefined); // Store the total number of pages
68-
const [currentPage, setCurrentPage] = useState<number | undefined>(undefined); // Store the current page
69-
const [limit, setLimit] = useState<number | undefined>(10); // Store the quantity of questions to be displayed
68+
const [currentPage, setCurrentPage] = useState<number>(1); // Store the current page
69+
const [limit, setLimit] = useState<number>(10); // Store the quantity of questions to be displayed
7070
const [isLoading, setIsLoading] = useState<boolean>(true); // Store the states related to table's loading
7171

7272
// Filtering States
7373
const [search, setSearch] = useState<string | undefined>(undefined); // Store the search
74+
const [delayedSearch, setDelayedSearch] = useState<string | undefined>(
75+
undefined
76+
); // Store the delayed search value
7477
const [categories, setCategories] = useState<string[]>([]); // Store the selected filter categories
7578
const [difficulty, setDifficulty] = useState<string[]>([]); // Store the selected difficulty level
7679
const [sortBy, setSortBy] = useState<string | undefined>(undefined); // Store the selected sorting parameter
@@ -104,7 +107,7 @@ export default function Home() {
104107
setIsLoading(true);
105108
}
106109

107-
let data = await GetQuestions(currentPage, limit);
110+
let data = await GetQuestions(currentPage, limit, sortBy, difficulty, delayedSearch);
108111
setQuestions(data.questions);
109112
setTotalCount(data.totalCount);
110113
setTotalPages(data.totalPages);
@@ -113,7 +116,7 @@ export default function Home() {
113116
setIsLoading(false);
114117
}
115118

116-
useEffect(() => {loadQuestions()}, [limit, currentPage]);
119+
useEffect(() => {loadQuestions()}, [limit, currentPage, sortBy, difficulty, delayedSearch]);
117120

118121
// Table column specification
119122
const columns: TableProps<Question>["columns"] = [
@@ -156,7 +159,7 @@ export default function Home() {
156159
title: "Actions",
157160
key: "actions",
158161
dataIndex: "id",
159-
render: (id: number) => (
162+
render: (_: number, question: Question) => (
160163
<div>
161164
{/* TODO (Sean): Include Logic to handle retrieving of editable data here and display in a modal component */}
162165
<Button className="edit-button" icon={<EditOutlined />}></Button>
@@ -166,15 +169,7 @@ export default function Home() {
166169
danger
167170
icon={<DeleteOutlined />}
168171
onClick={() => {
169-
if (questions === undefined) {
170-
throw new Error("questions is undefined")
171-
}
172-
let toDelete = questions.findIndex(row => row.id === id)
173-
if (toDelete === -1) {
174-
error("Could not find id");
175-
return;
176-
}
177-
setDeletionStage({index: toDelete, deleteConfirmed: false})}
172+
setDeletionStage({index: question, deleteConfirmed: false})}
178173
}
179174
></Button>
180175
</div>
@@ -185,6 +180,7 @@ export default function Home() {
185180
// Handler for change in multi-select categories option
186181
const handleCategoriesChange = (value: string[]) => {
187182
setCategories(value);
183+
setCurrentPage(1); // Reset the current page
188184
};
189185

190186
// Handler for clearing the filtering options
@@ -196,17 +192,15 @@ export default function Home() {
196192
};
197193

198194
// Handler for filtering (TODO)
199-
const handleFilter = async () => {
200-
success("Filtered Successfully!");
201-
};
195+
// const handleFilter = async () => {
196+
// success("Filtered Successfully!");
197+
// };
202198

203199
// Handler for show size change for pagination
204200
const onShowSizeChange: PaginationProps["onShowSizeChange"] = (
205201
current,
206202
pageSize
207203
) => {
208-
console.log(current);
209-
console.log(pageSize);
210204
setCurrentPage(current);
211205
setLimit(pageSize);
212206
};
@@ -225,18 +219,16 @@ export default function Home() {
225219
error("Cannot delete: questions does not exist");
226220
return;
227221
}
228-
if (currentPage == undefined) {
229-
error("Cannot delete: currentPage does not exist");
230-
return;
231-
}
232222

233223
setDeletionStage({ index: deletionStage.index, deleteConfirmed: true });
234-
await DeleteQuestionByDocref(questions[deletionStage.index].docRefId);
224+
await DeleteQuestionByDocref(deletionStage.index.docRefId);
235225
if (questions.length == 1 && currentPage > 1) {
236226
setCurrentPage(currentPage - 1);
227+
success("Question deleted successfully");
237228
} else {
238229
try {
239230
await loadQuestions();
231+
success("Question deleted successfully");
240232
} catch (err) {
241233
if (typeof err == 'string') {
242234
error(err);
@@ -271,6 +263,7 @@ export default function Home() {
271263
prefix={<SearchOutlined />}
272264
onChange={(e) => setSearch(e.target.value)}
273265
value={search}
266+
allowClear
274267
/>
275268
</Col>
276269
<Col span={6}>
@@ -284,12 +277,15 @@ export default function Home() {
284277
value={categories}
285278
/>
286279
</Col>
287-
<Col span={4}>
280+
<Col span={6}>
288281
<Select
289282
mode="multiple"
290283
allowClear
291284
placeholder="Difficulty"
292-
onChange={(value: string[]) => setDifficulty(value)}
285+
onChange={(value: string[]) => {
286+
setDifficulty(value);
287+
setCurrentPage(1); //Reset the currentpage since filter params changed
288+
}}
293289
options={DifficultyOption}
294290
className="difficulty-select"
295291
value={difficulty}
@@ -305,15 +301,17 @@ export default function Home() {
305301
value={sortBy}
306302
/>
307303
</Col>
308-
<Col span={4}>
309-
<Button onClick={handleClear}>Clear</Button>
310-
<Button
304+
<Col span={2}>
305+
<Button onClick={handleClear} className="clear-button">
306+
Clear
307+
</Button>
308+
{/* <Button
311309
type="primary"
312310
className="filter-button"
313311
onClick={handleFilter}
314312
>
315313
Filter
316-
</Button>
314+
</Button> */}
317315
</Col>
318316
</Row>
319317
</div>
@@ -323,6 +321,7 @@ export default function Home() {
323321
columns={columns}
324322
loading={isLoading}
325323
pagination={{
324+
current: currentPage,
326325
total: totalCount,
327326
showSizeChanger: true,
328327
onShowSizeChange: onShowSizeChange,
@@ -337,7 +336,7 @@ export default function Home() {
337336
{("index" in deletionStage && questions != undefined) && <DeleteModal
338337
okHandler={confirmDeleteHandler}
339338
cancelHandler={() => setDeletionStage({})}
340-
questionTitle={questions[deletionStage.index].title}
339+
questionTitle={deletionStage.index.title}
341340
isDeleting={deletionStage.deleteConfirmed}/>}
342341
</div>
343342
);

apps/question-service/src/app/services/question.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ export interface QuestionListResponse {
2424
// GET request to fetch all the questions (TODO: Ben --> Fetch with filtering/sorting etc)
2525
export const GetQuestions = async (
2626
currentPage?: number,
27-
limit?: number
27+
limit?: number,
28+
sortBy?: string,
29+
difficulty?: string[],
30+
title?: string
2831
): Promise<QuestionListResponse> => {
2932
let query_url = `${process.env.NEXT_PUBLIC_API_URL}questions`;
3033
let query_params = "";
@@ -37,6 +40,27 @@ export const GetQuestions = async (
3740
query_params += `${query_params.length > 0 ? "&" : "?"}limit=${limit}`;
3841
}
3942

43+
if (sortBy) {
44+
const [field, order] = sortBy.split(" ");
45+
query_params += `${
46+
query_params.length > 0 ? "&" : "?"
47+
}sortField=${field}&sortValue=${order}`;
48+
}
49+
50+
if (difficulty && difficulty.length > 0) {
51+
const value = difficulty.join(","); // Change them from ["easy", "medium"] to "easy,medium"
52+
query_params += `${query_params.length > 0 ? "&" : "?"}complexity=${value}`;
53+
}
54+
55+
if (title && title != "") {
56+
const urlEncodedTitle = encodeURIComponent(title);
57+
query_params += `${
58+
query_params.length > 0 ? "&" : "?"
59+
}title=${urlEncodedTitle}`;
60+
}
61+
62+
// TODO: (Ryan) Filtering via categories
63+
4064
query_url += query_params;
4165
const response = await fetch(query_url);
4266
const data = await response.json();

apps/question-service/src/app/styles.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.02) !important;
4545
}
4646

47+
.clear-button {
48+
width: 100%;
49+
}
50+
4751
.categories-multi-select,
4852
.difficulty-select,
4953
.order-select {

apps/question-service/src/app/utils/SelectOptions.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,49 +78,49 @@ export const CategoriesOption = [
7878
export const DifficultyOption = [
7979
{
8080
label: "Easy",
81-
value: "Easy",
81+
value: "easy",
8282
},
8383
{
8484
label: "Medium",
85-
value: "Medium",
85+
value: "medium",
8686
},
8787
{
8888
label: "Hard",
89-
value: "Hard",
89+
value: "hard",
9090
},
9191
];
9292

9393
export const OrderOption = [
9494
{
9595
label: "Id (ASC)",
96-
value: "Id (ASC)",
96+
value: "id asc",
9797
},
9898
{
9999
label: "Id (DESC)",
100-
value: "Id (DESC)",
100+
value: "id desc",
101101
},
102102
{
103103
label: "Most Recent",
104-
value: "Most Recent",
104+
value: "createdAt desc",
105105
},
106106
{
107107
label: "Oldest",
108-
value: "Oldest",
108+
value: "createdAt asc",
109109
},
110110
{
111111
label: "Alphabetical (A-Z)",
112-
value: "Alphabetical (A-Z)", // TODO: Edit the values based on backend in the future
112+
value: "title asc",
113113
},
114114
{
115115
label: "Alphabetical (Z-A)",
116-
value: "Alphabetical (Z-A)", // TODO: Edit the values based on backend in the future
116+
value: "title desc",
117117
},
118118
{
119119
label: "Difficulty (ASC)",
120-
value: "Difficulty (ASC)",
120+
value: "complexity asc",
121121
},
122122
{
123123
label: "Difficulty (DESC)",
124-
value: "Difficulty (DESC)",
124+
value: "complexity desc",
125125
},
126126
];

0 commit comments

Comments
 (0)