From 6c245d741d3d7ad85aa30412ff19d50b0043e56e Mon Sep 17 00:00:00 2001 From: Dan Reeves Date: Thu, 12 Oct 2023 01:09:24 +0100 Subject: [PATCH] Update inventory styles --- app/layout.tsx | 7 +- .../armoury.$character.inventory.$item.tsx | 450 +++++++++--------- app/routes/armoury.$character.inventory.tsx | 167 ++++--- app/routes/armoury.$character.tsx | 6 +- app/routes/armoury.tsx | 4 +- 5 files changed, 324 insertions(+), 310 deletions(-) diff --git a/app/layout.tsx b/app/layout.tsx index 7a66f98..654cf34 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -27,8 +27,11 @@ const userNavigation = [ export default function Layout({ user }: { user: User | null }) { return ( <> -
- +
+ {({ open }) => ( <>
diff --git a/app/routes/armoury.$character.inventory.$item.tsx b/app/routes/armoury.$character.inventory.$item.tsx index 1248283..0040ab5 100644 --- a/app/routes/armoury.$character.inventory.$item.tsx +++ b/app/routes/armoury.$character.inventory.$item.tsx @@ -1,225 +1,225 @@ -import { useLoaderData, useLocation } from "@remix-run/react" -import type { LoaderArgs } from "@remix-run/node" -import { redirect, json } from "@remix-run/node" -import { z } from "zod" -import { zx } from "zodix" -import { getAuthToken } from "~/data/authtoken.server" -import { getItems } from "~/data/items.server" -import { BlessingSchema, WeaponSchema } from "~/data/schemas.server" -import { authenticator } from "~/services/auth.server" -import { getAccountGear } from "~/services/darktide.server" -import { motion } from "framer-motion" -import { Img } from "~/components/Img" -import { ChevronDoubleUpIcon } from "@heroicons/react/24/outline" -import { t } from "~/data/localization.server" -import { getWeaponTemplate } from "~/data/weaponTemplates.server" -import { twMerge } from "tailwind-merge" - -export async function loader({ request, params }: LoaderArgs) { - let { character: characterId, item: itemId } = zx.parseParams(params, { - character: z.string(), - item: z.string(), - }) - - let user = await authenticator.isAuthenticated(request, { - failureRedirect: "/login", - }) - let auth = await getAuthToken(user.id) - let gear = await getAccountGear(auth) - - if (gear) { - let [weapons, blessings] = await Promise.all([ - getItems(WeaponSchema), - getItems(BlessingSchema), - ]) - - let [, item] = - Object.entries(gear) - .filter(([, item]) => { - return !item.characterId || item.characterId === characterId - }) - .find(([id]) => { - return id === itemId - }) ?? [] - - let weapon = weapons.find( - (wep) => item && wep.id === item.masterDataInstance.id, - ) - - let weaponTemplate = getWeaponTemplate(weapon?.baseName ?? "unknown") - - if (!item || !weapon || !weaponTemplate) { - return redirect(`/armoury/${characterId}/inventory`) - } - - let description = weapon.description - let rarity = item.masterDataInstance.overrides?.rarity ?? 1 - let baseItemLevel = item.masterDataInstance.overrides?.baseItemLevel - let itemLevel = item.masterDataInstance.overrides?.itemLevel - let previewImage = `${weapon.preview_image}.png` - let displayName = weapon.display_name - let traits = - item.masterDataInstance.overrides?.traits - ?.map((t) => { - let blessing = blessings.find((b) => b.id === t.id) - if (!blessing) return undefined - let [baseName] = t.id.match(/\w+$/) ?? [] - return { - baseName, - rarity: t.rarity, - displayName: blessing.display_name, - icon: `${blessing.icon}.png`, - } - }) - .filter(Boolean) ?? [] - let baseStats = (item.masterDataInstance.overrides?.base_stats ?? []) - .map((baseStat) => { - if (weaponTemplate) { - let baseStatConfig = weaponTemplate.base_stats[baseStat.name] - return { - displayName: t(baseStatConfig?.display_name ?? "unknown"), - value: baseStat.value, - } - } - return undefined - }) - .filter(Boolean) - - return json({ - displayName, - rarity, - previewImage, - baseItemLevel, - traits, - baseStats, - itemLevel, - description, - }) - } - - return json(null) -} - -let rarityBorder: Record = { - 1: "border-l-neutral-600 from-neutral-100", - 2: "border-l-green-600 from-green-50", - 3: "border-l-blue-600 from-blue-50", - 4: "border-l-purple-600 from-purple-50", - 5: "border-l-orange-600 from-orange-50", -} - -let rarityColor: Record = { - 1: "text-neutral-800", - 2: "text-green-800", - 3: "text-blue-800", - 4: "text-purple-800", - 5: "text-orange-800", -} - -export default function Item() { - let item = useLoaderData() - let { pathname } = useLocation() - - if (!item) return null - - return ( - -
-
-

- {item.displayName} -

- - - - -
- - -
- {item.baseStats.map((stat) => { - return ( -
-
{stat.displayName}
-
-
-
-
- {Math.round(stat.value * 100)}% -
-
-
-
- ) - })} -
-
-

{item.description}

-
- -
- - ) -} +// import { useLoaderData, useLocation } from "@remix-run/react" +// import type { LoaderArgs } from "@remix-run/node" +// import { redirect, json } from "@remix-run/node" +// import { z } from "zod" +// import { zx } from "zodix" +// import { getAuthToken } from "~/data/authtoken.server" +// import { getItems } from "~/data/items.server" +// import { BlessingSchema, WeaponSchema } from "~/data/schemas.server" +// import { authenticator } from "~/services/auth.server" +// import { getAccountGear } from "~/services/darktide.server" +// import { motion } from "framer-motion" +// import { Img } from "~/components/Img" +// import { ChevronDoubleUpIcon } from "@heroicons/react/24/outline" +// import { t } from "~/data/localization.server" +// import { getWeaponTemplate } from "~/data/weaponTemplates.server" +// import { twMerge } from "tailwind-merge" + +// export async function loader({ request, params }: LoaderArgs) { +// let { character: characterId, item: itemId } = zx.parseParams(params, { +// character: z.string(), +// item: z.string(), +// }) + +// let user = await authenticator.isAuthenticated(request, { +// failureRedirect: "/login", +// }) +// let auth = await getAuthToken(user.id) +// let gear = await getAccountGear(auth) + +// if (gear) { +// let [weapons, blessings] = await Promise.all([ +// getItems(WeaponSchema), +// getItems(BlessingSchema), +// ]) + +// let [, item] = +// Object.entries(gear) +// .filter(([, item]) => { +// return !item.characterId || item.characterId === characterId +// }) +// .find(([id]) => { +// return id === itemId +// }) ?? [] + +// let weapon = weapons.find( +// (wep) => item && wep.id === item.masterDataInstance.id, +// ) + +// let weaponTemplate = getWeaponTemplate(weapon?.baseName ?? "unknown") + +// if (!item || !weapon || !weaponTemplate) { +// return redirect(`/armoury/${characterId}/inventory`) +// } + +// let description = weapon.description +// let rarity = item.masterDataInstance.overrides?.rarity ?? 1 +// let baseItemLevel = item.masterDataInstance.overrides?.baseItemLevel +// let itemLevel = item.masterDataInstance.overrides?.itemLevel +// let previewImage = `${weapon.preview_image}.png` +// let displayName = weapon.display_name +// let traits = +// item.masterDataInstance.overrides?.traits +// ?.map((t) => { +// let blessing = blessings.find((b) => b.id === t.id) +// if (!blessing) return undefined +// let [baseName] = t.id.match(/\w+$/) ?? [] +// return { +// baseName, +// rarity: t.rarity, +// displayName: blessing.display_name, +// icon: `${blessing.icon}.png`, +// } +// }) +// .filter(Boolean) ?? [] +// let baseStats = (item.masterDataInstance.overrides?.base_stats ?? []) +// .map((baseStat) => { +// if (weaponTemplate) { +// let baseStatConfig = weaponTemplate.base_stats[baseStat.name] +// return { +// displayName: t(baseStatConfig?.display_name ?? "unknown"), +// value: baseStat.value, +// } +// } +// return undefined +// }) +// .filter(Boolean) + +// return json({ +// displayName, +// rarity, +// previewImage, +// baseItemLevel, +// traits, +// baseStats, +// itemLevel, +// description, +// }) +// } + +// return json(null) +// } + +// let rarityBorder: Record = { +// 1: "border-l-neutral-600 from-neutral-100", +// 2: "border-l-green-600 from-green-50", +// 3: "border-l-blue-600 from-blue-50", +// 4: "border-l-purple-600 from-purple-50", +// 5: "border-l-orange-600 from-orange-50", +// } + +// let rarityColor: Record = { +// 1: "text-neutral-800", +// 2: "text-green-800", +// 3: "text-blue-800", +// 4: "text-purple-800", +// 5: "text-orange-800", +// } + +// export default function Item() { +// let item = useLoaderData() +// let { pathname } = useLocation() + +// if (!item) return null + +// return ( +// +//
+//
+//

+// {item.displayName} +//

+// +// + +// +//
+// +// +//
+// {item.baseStats.map((stat) => { +// return ( +//
+//
{stat.displayName}
+//
+//
+//
+//
+// {Math.round(stat.value * 100)}% +//
+//
+//
+//
+// ) +// })} +//
+//
+//

{item.description}

+//
+// +//
+// +// ) +// } diff --git a/app/routes/armoury.$character.inventory.tsx b/app/routes/armoury.$character.inventory.tsx index ad6fbc3..23ed8d6 100644 --- a/app/routes/armoury.$character.inventory.tsx +++ b/app/routes/armoury.$character.inventory.tsx @@ -1,18 +1,14 @@ -import { ChevronDoubleUpIcon } from "@heroicons/react/24/outline" import { - Link, NavLink, useLoaderData, - useOutlet, useParams, useSearchParams, } from "@remix-run/react" -import type { LoaderArgs } from "@remix-run/node" -import { json } from "@remix-run/node" -import { AnimatePresence } from "framer-motion" +import type { LoaderArgs } from "@remix-run/server-runtime" +import { json } from "@remix-run/server-runtime" import { z } from "zod" import { zx } from "zodix" -import { Checkbox, Form, FormGroup, Select, TextInput } from "~/components/Form" +import { Form } from "~/components/Form" import { Img } from "~/components/Img" import { getAuthToken } from "~/data/authtoken.server" import { getItems } from "~/data/items.server" @@ -20,7 +16,21 @@ import { BlessingSchema, WeaponSchema } from "~/data/schemas.server" import { authenticator } from "~/services/auth.server" import { getAccountGear } from "~/services/darktide.server" import { getSearchParam } from "~/utils/getSearchParam" -import { twMerge } from "tailwind-merge" +import { cn } from "~/lib/utils" +import { Input } from "~/components/ui/input" +import { Label } from "~/components/ui/label" +import { ChevronsUp } from "lucide-react" +import { titleCase } from "~/utils/titleCase" +import { Checkbox } from "~/components/ui/checkbox" +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectTrigger, + SelectValue, +} from "~/components/ui/select" +import { filter, uniqBy } from "lodash-es" export async function loader({ request, params }: LoaderArgs) { let { character } = zx.parseParams(params, { character: z.string() }) @@ -32,13 +42,16 @@ export async function loader({ request, params }: LoaderArgs) { let searchName = url.searchParams.get("name") ?? "" let searchBlessing = url.searchParams.get("blessing") ?? "" + if (searchBlessing === "any") { + searchBlessing = "" + } + let user = await authenticator.isAuthenticated(request, { failureRedirect: "/login", }) - let auth = await getAuthToken(user.id) - let gear = await getAccountGear(auth) + if (gear) { let weapons = await getItems(WeaponSchema) let blessings = await getItems(BlessingSchema) @@ -63,6 +76,9 @@ export async function loader({ request, params }: LoaderArgs) { let blessing = blessings.find((b) => b.id === t.id) if (!blessing) return undefined let [baseName] = t.id.match(/\w+$/) ?? [] + + if (!baseName) return null + return { baseName, rarity: t.rarity, @@ -93,19 +109,10 @@ export async function loader({ request, params }: LoaderArgs) { : true), ) - let traitTable: Record = {} - for (let item of characterGear) { - for (let trait of item.traits) { - if (trait.baseName && trait.baseName in traitTable) { - traitTable[trait.baseName] = trait.displayName - } - } - } - - let traits = Object.entries(traitTable).map(([baseName, displayName]) => ({ - baseName, - displayName, - })) + let traits = uniqBy( + characterGear.map((item) => item.traits).flat(), + "baseName", + ) return json({ items, traits }) } @@ -114,15 +121,15 @@ export async function loader({ request, params }: LoaderArgs) { } let rarityBorder: Record = { - 1: "border-l-neutral-600 from-neutral-100", - 2: "border-l-green-600 from-green-50", - 3: "border-l-blue-600 from-blue-50", - 4: "border-l-purple-600 from-purple-50", - 5: "border-l-orange-600 from-orange-50", + 1: "border-l-foreground/75", + 2: "border-l-green-600", + 3: "border-l-blue-600", + 4: "border-l-purple-600", + 5: "border-l-orange-600", } let rarityColor: Record = { - 1: "text-neutral-800", + 1: "text-foreground/75", 2: "text-green-800", 3: "text-blue-800", 4: "text-purple-800", @@ -130,32 +137,63 @@ let rarityColor: Record = { } export default function Inventory() { - let outlet = useOutlet() let { items, traits } = useLoaderData() let { character } = useParams() - let [_searchParams] = useSearchParams() - let searchParams = _searchParams.toString() + return ( -
- +
+
+
+ + +
+ +
+ +
+ {["melee", "ranged"].map((kind) => ( +
+ + +
+ ))} +
+
+ +
+ + +
+
+ +
{items.map((item) => { return ( - - twMerge( - "from-1% relative h-full w-full basis-1/4 border-2 border-neutral-400 bg-white bg-gradient-to-r shadow transition", - rarityBorder[item.rarity], - outlet && !isActive && "opacity-50", - ) - } + className={cn( + "rounded-lg border bg-card text-card-foreground shadow-sm relative", + rarityBorder[item.rarity], + )} >
-
{item.traits.map((trait) => ( {`Tier
- +
) })} - -
-
- - - - - - - - -
- {outlet}
) } diff --git a/app/routes/armoury.$character.tsx b/app/routes/armoury.$character.tsx index 89806a3..3142018 100644 --- a/app/routes/armoury.$character.tsx +++ b/app/routes/armoury.$character.tsx @@ -1,9 +1,5 @@ import { Outlet } from "@remix-run/react" export default function Character() { - return ( -
- -
- ) + return } diff --git a/app/routes/armoury.tsx b/app/routes/armoury.tsx index ae720fa..f2b8ec7 100644 --- a/app/routes/armoury.tsx +++ b/app/routes/armoury.tsx @@ -63,8 +63,8 @@ export default function Armoury() { return ( <> -
-
+
+