Added date filter to code list

This commit is contained in:
Joao Ramos
2024-06-20 22:57:34 +01:00
parent ce6708be6e
commit f6741dd80e

View File

@@ -14,9 +14,11 @@ import {
} from "@tanstack/react-table"; } from "@tanstack/react-table";
import axios from "axios"; import axios from "axios";
import moment from "moment"; import moment from "moment";
import { useEffect, useState } from "react"; import { useEffect, useState, useMemo } from "react";
import { BsTrash } from "react-icons/bs"; import { BsTrash } from "react-icons/bs";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import ReactDatePicker from "react-datepicker";
import clsx from "clsx";
const columnHelper = createColumnHelper<Code>(); const columnHelper = createColumnHelper<Code>();
@@ -41,41 +43,51 @@ export default function CodeList({ user }: { user: User }) {
const [selectedCodes, setSelectedCodes] = useState<string[]>([]); const [selectedCodes, setSelectedCodes] = useState<string[]>([]);
const [filteredCorporate, setFilteredCorporate] = useState<User | undefined>( const [filteredCorporate, setFilteredCorporate] = useState<User | undefined>(
user?.type === "corporate" ? user : undefined, user?.type === "corporate" ? user : undefined
); );
const [filterAvailability, setFilterAvailability] = useState< const [filterAvailability, setFilterAvailability] = useState<
"in-use" | "unused" "in-use" | "unused"
>(); >();
const [filteredCodes, setFilteredCodes] = useState<Code[]>([]); // const [filteredCodes, setFilteredCodes] = useState<Code[]>([]);
const { users } = useUsers(); const { users } = useUsers();
const { codes, reload } = useCodes( const { codes, reload } = useCodes(
user?.type === "corporate" ? user?.id : undefined, user?.type === "corporate" ? user?.id : undefined
); );
useEffect(() => { const [startDate, setStartDate] = useState<Date | null>(moment("01/01/2023").toDate());
let result = [...codes]; const [endDate, setEndDate] = useState<Date | null>(moment().endOf("day").toDate());
if (filteredCorporate) const filteredCodes = useMemo(() => {
result = result.filter((x) => x.creator === filteredCorporate.id); return codes.filter((x) => {
if (filterAvailability) // TODO: if the expiry date is missing, it does not make sense to filter by date
result = result.filter((x) => // so we need to find a way to handle this edge case
filterAvailability === "in-use" ? !!x.userId : !x.userId, if(startDate && endDate && x.expiryDate) {
); const date = moment(x.expiryDate);
if(date.isBefore(startDate) || date.isAfter(endDate)) {
return false;
}
}
if (filteredCorporate && x.creator !== filteredCorporate.id) return false;
if (filterAvailability) {
if (filterAvailability === "in-use" && !x.userId) return false;
if (filterAvailability === "unused" && x.userId) return false;
}
setFilteredCodes(result); return true;
}, [codes, filteredCorporate, filterAvailability]); });
}, [codes, startDate, endDate, filteredCorporate, filterAvailability]);
const toggleCode = (id: string) => { const toggleCode = (id: string) => {
setSelectedCodes((prev) => setSelectedCodes((prev) =>
prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id], prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]
); );
}; };
const toggleAllCodes = (checked: boolean) => { const toggleAllCodes = (checked: boolean) => {
if (checked) if (checked)
return setSelectedCodes( return setSelectedCodes(
filteredCodes.filter((x) => !x.userId).map((x) => x.code), filteredCodes.filter((x) => !x.userId).map((x) => x.code)
); );
return setSelectedCodes([]); return setSelectedCodes([]);
@@ -242,18 +254,20 @@ export default function CodeList({ user }: { user: User }) {
} }
options={users options={users
.filter((x) => .filter((x) =>
["admin", "developer", "corporate"].includes(x.type), ["admin", "developer", "corporate"].includes(x.type)
) )
.map((x) => ({ .map((x) => ({
label: `${x.type === "corporate" ? x.corporateInformation?.companyInformation?.name || x.name : x.name} (${ label: `${
USER_TYPE_LABELS[x.type] x.type === "corporate"
})`, ? x.corporateInformation?.companyInformation?.name || x.name
: x.name
} (${USER_TYPE_LABELS[x.type]})`,
value: x.id, value: x.id,
user: x, user: x,
}))} }))}
onChange={(value) => onChange={(value) =>
setFilteredCorporate( setFilteredCorporate(
value ? users.find((x) => x.id === value?.value) : undefined, value ? users.find((x) => x.id === value?.value) : undefined
) )
} }
/> />
@@ -267,10 +281,32 @@ export default function CodeList({ user }: { user: User }) {
]} ]}
onChange={(value) => onChange={(value) =>
setFilterAvailability( setFilterAvailability(
value ? (value.value as typeof filterAvailability) : undefined, value ? (value.value as typeof filterAvailability) : undefined
) )
} }
/> />
<ReactDatePicker
dateFormat="dd/MM/yyyy"
className="px-4 py-6 w-full text-sm text-center font-normal placeholder:text-mti-gray-cool disabled:bg-mti-gray-platinum/40 disabled:text-mti-gray-dim disabled:cursor-not-allowed rounded-full border border-mti-gray-platinum focus:outline-none"
selected={startDate}
startDate={startDate}
endDate={endDate}
selectsRange
showMonthDropdown
filterDate={(date: Date) =>
moment(date).isSameOrBefore(moment(new Date()))
}
onChange={([initialDate, finalDate]: [Date, Date]) => {
setStartDate(initialDate ?? moment("01/01/2023").toDate());
if (finalDate) {
// basicly selecting a final day works as if I'm selecting the first
// minute of that day. this way it covers the whole day
setEndDate(moment(finalDate).endOf("day").toDate());
return;
}
setEndDate(null);
}}
/>
</div> </div>
<div className="flex gap-4 items-center"> <div className="flex gap-4 items-center">
<span>{selectedCodes.length} code(s) selected</span> <span>{selectedCodes.length} code(s) selected</span>
@@ -295,7 +331,7 @@ export default function CodeList({ user }: { user: User }) {
? null ? null
: flexRender( : flexRender(
header.column.columnDef.header, header.column.columnDef.header,
header.getContext(), header.getContext()
)} )}
</th> </th>
))} ))}