-
-
Notifications
You must be signed in to change notification settings - Fork 9
feat(app): add filtering questions #407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
b8a3053
0d7d01f
80c7bea
179b23e
b6cbccd
aa738c2
a583cbc
2fde7d1
e4862a8
46452d6
febfd35
1c9a4c0
069e7e5
9ea666e
cdd3ccd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
"use client"; | ||
|
||
import { ChangeEvent } from "react"; | ||
import { DEFAULT_ORDER_QUERY } from "../../lib/order"; | ||
import { technologiesLabel, Technology } from "../../lib/technologies"; | ||
import { pluralize } from "../../utils/intl"; | ||
import { Select } from "../Select/Select"; | ||
import { useQuestionsOrderBy } from "../../hooks/useQuestionsOrderBy"; | ||
|
||
const questionsPluralize = pluralize("pytanie", "pytania", "pytań"); | ||
|
||
type QuestionsHeaderProps = Readonly<{ | ||
technology: Technology; | ||
total: number; | ||
}>; | ||
|
||
export const QuestionsHeader = ({ technology, total }: QuestionsHeaderProps) => { | ||
const { setOrderBy } = useQuestionsOrderBy(); | ||
|
||
const handleSelectChange = (event: ChangeEvent<HTMLSelectElement>) => { | ||
event.preventDefault(); | ||
setOrderBy(event.target.value); | ||
}; | ||
|
||
return ( | ||
<header className="flex justify-between text-neutral-400"> | ||
<output> | ||
<strong>{technologiesLabel[technology]}: </strong> | ||
{total} {questionsPluralize(total)} | ||
</output> | ||
<label> | ||
Sortuj według: | ||
<Select | ||
variant="default" | ||
defaultValue={DEFAULT_ORDER_QUERY} | ||
onChange={handleSelectChange} | ||
className="ml-3" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Brakuje |
||
> | ||
<option value="acceptedAt*desc">od najnowszych</option> | ||
<option value="acceptedAt*asc">od najstarszych</option> | ||
<option value="votesCount*asc">od najmniej popularnych</option> | ||
<option value="votesCount*desc">od najpopularniejszych</option> | ||
</Select> | ||
</label> | ||
</header> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { useSearchParams } from "next/navigation"; | ||
|
||
export const useDevFAQRouter = () => { | ||
const searchParams = useSearchParams(); | ||
|
||
const mergeQueryParams = (data: Record<string, string>) => { | ||
const params = { ...Object.fromEntries(searchParams.entries()), ...data }; | ||
|
||
return new URLSearchParams(params).toString(); | ||
}; | ||
|
||
return { mergeQueryParams }; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { usePathname, useRouter } from "next/navigation"; | ||
import { useDevFAQRouter } from "./useDevFAQRouter"; | ||
|
||
export const useQuestionsOrderBy = () => { | ||
const pathname = usePathname(); | ||
const router = useRouter(); | ||
const { mergeQueryParams } = useDevFAQRouter(); | ||
|
||
const setOrderBy = (order: string) => { | ||
if (pathname) { | ||
router.push(`${pathname}?${mergeQueryParams({ sortBy: order })}`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Czemu tego wszystkiego nie robi There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A gdzie walidacja tego |
||
} | ||
}; | ||
|
||
return { setOrderBy }; | ||
}; |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,12 @@ | ||||||
const orderBy = ["acceptedAt", "level", "votesCount"] as const; | ||||||
const order = ["asc", "desc"] as const; | ||||||
|
||||||
export const DEFAULT_ORDER_QUERY = "acceptedAt*desc"; | ||||||
|
||||||
export const validateOrderBy = (data: unknown): data is typeof orderBy[number] => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
return orderBy.includes(data); | ||||||
}; | ||||||
|
||||||
export const validateOrder = (data: unknown): data is typeof order[number] => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
return order.includes(data); | ||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,12 @@ | ||
export const technologies = ["html", "css", "js", "angular", "react", "git", "other"] as const; | ||
export type Technology = typeof technologies[number]; | ||
|
||
export const technologiesLabel: Record<Technology, string> = { | ||
html: "HTML5", | ||
css: "CSS3", | ||
js: "JS", | ||
angular: "Angular", | ||
react: "React", | ||
git: "Git", | ||
other: "Inne", | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To i walidacja nie powinny być w komponencie.