From 42cd662e0f55cbd0344fcd0e8fb2b86829b1d508 Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Tue, 10 Oct 2023 03:02:55 +0100 Subject: [PATCH] desc mission history, add table filters --- app/data/missionInstances.server.ts | 2 +- app/routes/mission-board.history.tsx | 166 ++++++++++++++++++++++++--- 2 files changed, 151 insertions(+), 17 deletions(-) diff --git a/app/data/missionInstances.server.ts b/app/data/missionInstances.server.ts index 3ab1d44..cffd135 100644 --- a/app/data/missionInstances.server.ts +++ b/app/data/missionInstances.server.ts @@ -8,7 +8,7 @@ export async function getMissionHistory() { return await prisma.missionInstance.findMany({ where: { start: { gte: dayAgoString } }, orderBy: { - start: "asc", + start: "desc", }, }) } diff --git a/app/routes/mission-board.history.tsx b/app/routes/mission-board.history.tsx index c026818..02a1d05 100644 --- a/app/routes/mission-board.history.tsx +++ b/app/routes/mission-board.history.tsx @@ -1,4 +1,5 @@ -import { Link, useLoaderData } from "@remix-run/react" +import { Link, useLoaderData, useSearchParams } from "@remix-run/react" +import type { LoaderArgs } from "@remix-run/server-runtime" import { json } from "@remix-run/server-runtime" import { getMissionHistory } from "~/data/missionInstances.server" @@ -20,11 +21,76 @@ import { t } from "~/data/localization.server" import { Img } from "~/components/Img" import { Button } from "~/components/ui/button" import { sideObjectiveToType } from "~/components/Mission" +import { ChevronDown } from "lucide-react" +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuTrigger, +} from "~/components/ui/dropdown-menu" + +export async function loader({ request }: LoaderArgs) { + let searchParams = new URL(request.url).searchParams + let circumstanceFilter = searchParams.getAll("circumstance") + let sideMissionFilter = searchParams.getAll("sideMission") + let challengeFilter = searchParams.getAll("challenge") + let mapFilter = searchParams.getAll("map") -export async function loader() { let rawMissions = await getMissionHistory() - let missions = rawMissions.map((mission) => { + let circumstances = Array.from( + new Set(rawMissions.map((mission) => mission.circumstance)), + ) + .map((circumstance) => { + const template = CircumstanceTemplates[circumstance] + if (template) { + return { + value: circumstance, + label: t(template.display_name), + } + } + return false + }) + .filter(Boolean) + .sort((a, b) => (a.label > b.label ? 1 : -1)) + + let maps = Array.from(new Set(rawMissions.map((mission) => mission.map))) + .map((map) => { + const template = getMissionTemplate(map) + if (template) { + return { + value: map, + label: t(template.display_name), + } + } + return false + }) + .filter(Boolean) + .sort((a, b) => (a.label > b.label ? 1 : -1)) + + let filteredMissions = rawMissions + .filter((mission) => { + if ( + !circumstanceFilter.length && + !sideMissionFilter.length && + !mapFilter.length + ) + return true + + return ( + circumstanceFilter.includes(mission.circumstance) || + sideMissionFilter.includes( + sideObjectiveToType(mission.sideMission ?? ""), + ) || + mapFilter.includes(mission.map) + ) + }) + .filter((mission) => { + if (!challengeFilter.length) return true + return challengeFilter.includes(mission.challenge.toString()) + }) + + let missions = filteredMissions.map((mission) => { const circumstance = CircumstanceTemplates[mission.circumstance] const template = getMissionTemplate(mission.map) @@ -45,7 +111,7 @@ export async function loader() { } }) - return json({ missions }) + return json({ missions, circumstances, maps }) } type Column = (data: { @@ -59,15 +125,6 @@ type Column = (data: { sideMission: string | null }) => ReactNode -let headers = [ - "Difficulty", - "Map", - "Circumstance", - "Side objective", - "Started at", - "ID", -] - let columns: Column[] = [ ({ category, challenge }) => (
@@ -143,8 +200,85 @@ let columns: Column[] = [ ), ] +function SearchParamsDropdownMenu({ + label, + param, + items, +}: { + label: string + param: string + items: { label: string; value: string }[] +}) { + const [searchParams, setSearchParams] = useSearchParams() + + return ( + + + + + + {items.map((item) => { + return ( + { + if (checked) { + searchParams.append(param, item.value) + } else { + searchParams.delete(param, item.value) + } + setSearchParams(searchParams.toString()) + }} + > + {item.label} + + ) + })} + + + ) +} + export default function MissionHistory() { - const { missions } = useLoaderData() + const { missions, circumstances, maps } = useLoaderData() + + let headers = [ + , + , + , + , + "Started at", + "ID", + ] + return (
@@ -156,8 +290,8 @@ export default function MissionHistory() { - {headers.map((col) => ( - {col} + {headers.map((col, i) => ( + {col} ))}