Skip to content

Commit

Permalink
feat: improve matricola search filter
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzocorallo committed Aug 22, 2024
1 parent 88dc2b1 commit 6ed470a
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/routes/viewer/CourseCombobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function CourseCombobox({ value, courses: c, onSelect }: Props) {

return (
<div className="flex items-center space-x-4">
<p className="text-muted-foreground text-sm">Corso</p>
<p className="text-sm">Corso</p>
{selectedCourse ? (
<Removable onRemove={() => handleSelect(absCourse.value)}>
{selectedCourse.label}
Expand Down
2 changes: 1 addition & 1 deletion src/routes/viewer/LocationSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function LocationsSelect(props: Props) {
if (locations.length === 0) return <></>;
return (
<div className="flex items-center space-x-4">
<p className="text-muted-foreground text-sm">Sede</p>
<p className="text-sm">Sede</p>
{locations.length >= 2 ? (
isMobile ? (
LocationCombobox(props)
Expand Down
2 changes: 1 addition & 1 deletion src/routes/viewer/PhaseSelect/GroupSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function GroupSelect(props: GroupSelectProps) {
const { groups, isCombobox, selectedGroup, groupOpen, onChange } = props;
return (
<div className="flex items-center space-x-4">
<p className="text-muted-foreground text-sm">Fase</p>
<p className="text-sm">Fase</p>
{groups.size >= 2 ? (
isCombobox ? (
<GroupCombobox
Expand Down
2 changes: 1 addition & 1 deletion src/routes/viewer/PhaseSelect/LangSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function LangSelect({

return (
<div className="flex items-center space-x-4">
<p className="text-muted-foreground text-sm">Lingua</p>
<p className="text-sm">Lingua</p>
{canChoose ? (
<Tabs
value={selectedLang}
Expand Down
2 changes: 1 addition & 1 deletion src/routes/viewer/PhaseSelect/RankingSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function RankingSelect(props: RankingSelectProps) {
const { phases, isCombobox, rankingOpen, selectedPhase, onChange } = props;
return (
<div className="flex items-center space-x-4">
<p className="text-muted-foreground text-sm">Graduatoria</p>
<p className="text-sm">Graduatoria</p>
{phases.length >= 2 ? (
isCombobox ? (
<RankingCombobox
Expand Down
4 changes: 1 addition & 3 deletions src/routes/viewer/Table/FilterBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,7 @@ export function FilterBtn<TData, TValue>({
>
<CheckIcon className={cn("h-4 w-4")} />
</div>
{option.icon && (
<option.icon className="text-muted-foreground mr-2 h-4 w-4" />
)}
{option.icon && <option.icon className="mr-2 h-4 w-4" />}
<span>{option.label}</span>
{facet && (
<span className="ml-auto flex h-4 w-4 items-center justify-center font-mono text-xs">
Expand Down
95 changes: 83 additions & 12 deletions src/routes/viewer/Table/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { enrollStatusOpts, enrollAllowedOpts } from "./columns";
import { StudentResultKeys } from ".";
import StudentResult from "@/utils/types/data/parsed/Ranking/StudentResult";
import { sha256 } from "@/utils/strings/crypto";
import { useState } from "react";
import { LuXCircle } from "react-icons/lu";
import { Removable } from "@/components/custom-ui/Removable";

type Props = {
has: Record<StudentResultKeys, boolean>;
Expand All @@ -17,21 +20,89 @@ type Props = {
export function Toolbar({ has, onCsvClick, table }: Props) {
const enrollStatusCol = table.getColumn("enrollStatus");
const enrollAllowedCol = table.getColumn("enrollAllowed");
const [matricolaFilter, setMatricolaFilter] = useState<string>("");
const [matricolaFilterSubmitted, setMatricolaFilterSubmitted] =
useState<boolean>(false);
const { rows: filteredRows } = table.getFilteredRowModel();

function clearMatricolaTableFilter() {
table.getColumn("id")?.setFilterValue(undefined);
}

function handleClearMatricolaFilter() {
setMatricolaFilter("");
clearMatricolaTableFilter();
setMatricolaFilterSubmitted(false);
}

function handleMatricolaFilterChange(
event: React.ChangeEvent<HTMLInputElement>,
) {
if (matricolaFilterSubmitted) clearMatricolaTableFilter();
const input = event.target.value;
setMatricolaFilter(input);
setMatricolaFilterSubmitted(false);
}

async function handleMatricolaFilterSubmit(
e: React.FormEvent<HTMLFormElement>,
) {
e.preventDefault();

if (matricolaFilter.length === 0) handleClearMatricolaFilter();
else {
const hash = await sha256(matricolaFilter);
table.getColumn("id")?.setFilterValue(hash);
setMatricolaFilterSubmitted(true);
}
}

return (
<div className="flex w-full flex-wrap items-center justify-start gap-4 max-sm:items-start max-2xs:flex-col">
<div className="flex w-full flex-wrap items-start justify-start gap-6 max-2xs:flex-col">
{table.getColumn("id") && (
<Input
className="w-full sm:max-w-[300px]"
placeholder="Filter per matricola..."
onChange={async (event) => {
const input = event.target.value;
const hash = await sha256(event.target.value);
table.getColumn("id")?.setFilterValue(input ? hash : undefined);
}}
/>
<div className="grid grid-cols-[auto_180px] grid-rows-[auto_auto] gap-x-4 gap-y-1">
<p className="self-center text-sm">Matricola</p>
{filteredRows.length > 0 && matricolaFilterSubmitted ? (
<Removable
onRemove={handleClearMatricolaFilter}
className="justify-between"
>
{matricolaFilter}
</Removable>
) : (
<>
<form
className="relative w-full"
onSubmit={handleMatricolaFilterSubmit}
>
<Input
placeholder="Inserisci la matricola..."
value={matricolaFilter}
onChange={handleMatricolaFilterChange}
/>
{matricolaFilter.length > 0 && (
<Button
type="button"
variant="ghost"
size="icon"
className="absolute right-1 top-1/2 h-7 w-7 -translate-y-1/2 text-gray-500 hover:bg-transparent hover:text-gray-900 dark:text-gray-400 dark:hover:bg-transparent dark:hover:text-gray-100"
onClick={handleClearMatricolaFilter}
>
<LuXCircle className="h-5 w-5" />
<span className="sr-only">Clear</span>
</Button>
)}
</form>
{matricolaFilterSubmitted && (
<p className="col-start-2 text-sm text-red-600 dark:text-red-400">
Matricola non trovata, ricontrolla.
</p>
)}
</>
)}
</div>
)}
<div className="flex flex-1 justify-start gap-4 max-xs:flex-wrap">
<div className="flex flex-1 justify-start gap-6 max-xs:flex-wrap">
{has.enrollAllowed && enrollAllowedCol && (
<FilterBtn
column={enrollAllowedCol}
Expand All @@ -47,7 +118,7 @@ export function Toolbar({ has, onCsvClick, table }: Props) {
/>
)}
</div>
<div className="flex justify-end ">
<div className="flex justify-end">
<Button
variant="outline"
className="whitespace-nowrap"
Expand Down
4 changes: 1 addition & 3 deletions src/routes/viewer/Table/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@ class Formatter {

return (
<div className="flex items-center justify-center">
{option.icon && (
<option.icon className="text-muted-foreground mr-2 h-4 w-4" />
)}
{option.icon && <option.icon className="mr-2 h-4 w-4" />}
<span>{option.label}</span>
</div>
);
Expand Down

0 comments on commit 6ed470a

Please sign in to comment.