From 7db1f648bf49c36c1baf1d482137d2bb44f6c0ec Mon Sep 17 00:00:00 2001 From: Z8MB1E Date: Sun, 16 Aug 2026 23:27:51 -0400 Subject: [PATCH] style(app): format app routes, pages, and server actions --- src/app/(frontend)/helpdesk/actions.ts | 29 +- .../intelligence/campaigns/[id]/page.tsx | 3 +- .../intelligence/factions/[id]/page.tsx | 4 +- .../(frontend)/intelligence/factions/page.tsx | 4 +- .../intelligence/missions/[id]/page.tsx | 27 +- .../intelligence/missions/actions.ts | 2 +- .../(frontend)/intelligence/missions/page.tsx | 2 +- src/app/(frontend)/intelligence/page.tsx | 26 +- src/app/(frontend)/locker/actions.ts | 113 +++++--- .../logistics/banking/[id]/page.tsx | 5 +- .../logistics/game-vehicles/[id]/page.tsx | 103 +++---- .../logistics/game-vehicles/page.tsx | 23 +- .../(frontend)/logistics/market/actions.ts | 76 +++-- src/app/(frontend)/logistics/market/page.tsx | 13 +- src/app/(frontend)/logistics/page.tsx | 8 +- .../logistics/resources/[id]/page.tsx | 21 +- .../(frontend)/logistics/resources/page.tsx | 4 +- .../logistics/shipments/[id]/page.tsx | 114 ++------ .../(frontend)/logistics/shipments/actions.ts | 93 ++---- .../(frontend)/logistics/shipments/page.tsx | 2 +- .../logistics/structures/[id]/page.tsx | 34 ++- .../logistics/structures/actions.ts | 267 ++++++++++++------ .../logistics/vehicles/VehiclesList.tsx | 19 +- .../logistics/vehicles/[id]/page.tsx | 35 +-- src/app/(frontend)/page.tsx | 2 +- .../(frontend)/profile/[username]/page.tsx | 26 +- src/app/(frontend)/roster/page.tsx | 15 +- .../(payload)/api/graphql-playground/route.ts | 6 +- src/app/(payload)/api/graphql/route.ts | 4 +- src/app/api/realtime/route.ts | 6 +- src/app/api/version/route.ts | 7 +- src/app/login/page.tsx | 3 +- 32 files changed, 517 insertions(+), 579 deletions(-) diff --git a/src/app/(frontend)/helpdesk/actions.ts b/src/app/(frontend)/helpdesk/actions.ts index ac9dec4..81f09ed 100644 --- a/src/app/(frontend)/helpdesk/actions.ts +++ b/src/app/(frontend)/helpdesk/actions.ts @@ -9,12 +9,8 @@ import { EventTypes } from "@/utils/event-log/eventTypes"; import { notifyUser } from "@/lib/notifications"; import { plaintextToLexical } from "@/lib/tickets/lexical"; import { getStaffUserIds } from "@/lib/tickets/staff"; -import { - CLOSING_STATUSES, - STATUS_LABEL, - TICKET_STATUSES, -} from "@/lib/tickets/ticketMeta"; import type { TicketCategory, TicketPriority, TicketStatus } from "@/lib/tickets/ticketMeta"; +import { CLOSING_STATUSES, STATUS_LABEL, TICKET_STATUSES } from "@/lib/tickets/ticketMeta"; export interface ActionResult { success: boolean; @@ -36,7 +32,10 @@ async function authenticate() { return { payload, user }; } -function displayNameOf(user: { payloadDisplayName?: string | null; username?: string | null }): string { +function displayNameOf(user: { + payloadDisplayName?: string | null; + username?: string | null; +}): string { return user.payloadDisplayName || user.username || "A member"; } @@ -169,9 +168,7 @@ export async function replyToTicket(ticketId: number, content: string): Promise< await payload.update({ collection: "tickets", id: ticketId, - data: reopen - ? { activity: newActivity, status: "open" } - : { activity: newActivity }, + data: reopen ? { activity: newActivity, status: "open" } : { activity: newActivity }, overrideAccess: true, depth: 0, }); @@ -229,7 +226,10 @@ export async function replyToTicket(ticketId: number, content: string): Promise< } } -export async function updateTicketStatus(ticketId: number, status: TicketStatus): Promise { +export async function updateTicketStatus( + ticketId: number, + status: TicketStatus, +): Promise { try { const { payload, user } = await authenticate(); const userId = user.id as number; @@ -245,9 +245,7 @@ export async function updateTicketStatus(ticketId: number, status: TicketStatus) const reporterId = reporterIdOf(ticket); if (!isStaff) { const reporterCancel = - reporterId === userId && - status === "canceled" && - !CLOSING_STATUSES.includes(ticket.status); + reporterId === userId && status === "canceled" && !CLOSING_STATUSES.includes(ticket.status); if (!reporterCancel) throw new Error("Only staff can change ticket status."); } @@ -293,7 +291,10 @@ export async function updateTicketStatus(ticketId: number, status: TicketStatus) } } -export async function assignTicket(ticketId: number, assigneeId: number | null): Promise { +export async function assignTicket( + ticketId: number, + assigneeId: number | null, +): Promise { try { const { payload, user } = await authenticate(); const userId = user.id as number; diff --git a/src/app/(frontend)/intelligence/campaigns/[id]/page.tsx b/src/app/(frontend)/intelligence/campaigns/[id]/page.tsx index f1d14c8..5911626 100644 --- a/src/app/(frontend)/intelligence/campaigns/[id]/page.tsx +++ b/src/app/(frontend)/intelligence/campaigns/[id]/page.tsx @@ -2,13 +2,12 @@ import config from "@payload-config"; import { getPayload } from "payload"; import { notFound } from "next/navigation"; import Link from "next/link"; -import type { Campaign, Faction, Media, Mission } from "@/payload-types"; +import type { Faction, Media, Mission } from "@/payload-types"; import { RichText } from "@payloadcms/richtext-lexical/react"; import { ArrowLeftIcon, CalendarDaysIcon, ChevronRightIcon, - CrosshairIcon, ShieldIcon, TargetIcon, UsersIcon, diff --git a/src/app/(frontend)/intelligence/factions/[id]/page.tsx b/src/app/(frontend)/intelligence/factions/[id]/page.tsx index 5006eb9..1f34d37 100644 --- a/src/app/(frontend)/intelligence/factions/[id]/page.tsx +++ b/src/app/(frontend)/intelligence/factions/[id]/page.tsx @@ -2,7 +2,7 @@ import config from "@payload-config"; import { getPayload } from "payload"; import { notFound } from "next/navigation"; import Link from "next/link"; -import type { Faction, Media, Mission, BankAccount, Resource, Campaign } from "@/payload-types"; +import type { BankAccount, Campaign, Faction, Media, Mission, Resource } from "@/payload-types"; import { RichText } from "@payloadcms/richtext-lexical/react"; import { convertLexicalToPlaintext } from "@payloadcms/richtext-lexical/plaintext"; import { @@ -10,8 +10,8 @@ import { ChevronRightIcon, FlagIcon, LandmarkIcon, - ShieldIcon, ScaleIcon, + ShieldIcon, } from "lucide-react"; import { Item, ItemContent, ItemHeader, ItemTitle } from "@/components/ui/item"; import { formatAmount } from "@/lib/banking/format"; diff --git a/src/app/(frontend)/intelligence/factions/page.tsx b/src/app/(frontend)/intelligence/factions/page.tsx index af74cff..7b81400 100644 --- a/src/app/(frontend)/intelligence/factions/page.tsx +++ b/src/app/(frontend)/intelligence/factions/page.tsx @@ -37,8 +37,8 @@ export default async function FactionsPage() {

Factions

- {factions.length} faction{factions.length !== 1 ? "s" : ""} tracked in - the theater of operations. + {factions.length} faction{factions.length !== 1 ? "s" : ""} tracked in the theater of + operations.

diff --git a/src/app/(frontend)/intelligence/missions/[id]/page.tsx b/src/app/(frontend)/intelligence/missions/[id]/page.tsx index 3f8183d..66db88e 100644 --- a/src/app/(frontend)/intelligence/missions/[id]/page.tsx +++ b/src/app/(frontend)/intelligence/missions/[id]/page.tsx @@ -3,35 +3,18 @@ import { getPayload } from "payload"; import { notFound } from "next/navigation"; import Link from "next/link"; import { headers as nextHeaders } from "next/headers"; -import type { - Mission, - Campaign, - Map, - User, - Faction, - Qualification, - Rank, - Media, -} from "@/payload-types"; +import type { Campaign, Map, Media, Mission } from "@/payload-types"; import { ArrowLeftIcon, - ArrowRightIcon, CalendarDaysIcon, ChevronRightIcon, ClockIcon, - MapPinIcon, CrosshairIcon, - ServerIcon, FlagIcon, + MapPinIcon, + ServerIcon, } from "lucide-react"; -import { - Item, - ItemContent, - ItemDescription, - ItemHeader, - ItemMedia, - ItemTitle, -} from "@/components/ui/item"; +import { Item, ItemContent, ItemHeader, ItemTitle } from "@/components/ui/item"; import { MissionBriefingSection } from "@/components/frontend/intelligence/MissionBriefingSection"; import { MissionObjectives } from "@/components/frontend/intelligence/MissionObjectives"; import { MissionFactions } from "@/components/frontend/intelligence/MissionFactions"; @@ -40,10 +23,10 @@ import { MissionLogistics } from "@/components/frontend/intelligence/MissionLogi import { MissionComms } from "@/components/frontend/intelligence/MissionComms"; import { MissionAttendance } from "@/components/frontend/intelligence/MissionAttendance"; import { + type AttendanceResponse, getMissionAttendance, getUserAttendance, isMissionPast, - type AttendanceResponse, } from "@/lib/attendance"; interface MissionDetailPageProps { diff --git a/src/app/(frontend)/intelligence/missions/actions.ts b/src/app/(frontend)/intelligence/missions/actions.ts index ea6b42e..0b133d0 100644 --- a/src/app/(frontend)/intelligence/missions/actions.ts +++ b/src/app/(frontend)/intelligence/missions/actions.ts @@ -2,8 +2,8 @@ import config from "@payload-config"; import { getPayload } from "payload"; -import { setMissionAttendance as setAttendance } from "@/lib/attendance"; import type { AttendanceResponse } from "@/lib/attendance"; +import { setMissionAttendance as setAttendance } from "@/lib/attendance"; export interface ActionResult { success: boolean; diff --git a/src/app/(frontend)/intelligence/missions/page.tsx b/src/app/(frontend)/intelligence/missions/page.tsx index 9cd29d1..ace55eb 100644 --- a/src/app/(frontend)/intelligence/missions/page.tsx +++ b/src/app/(frontend)/intelligence/missions/page.tsx @@ -1,6 +1,6 @@ import config from "@payload-config"; import { getPayload } from "payload"; -import type { Mission, Campaign, Map } from "@/payload-types"; +import type { Campaign, Mission } from "@/payload-types"; import { CrosshairIcon } from "lucide-react"; import { MissionsList } from "@/components/frontend/intelligence/MissionsList"; diff --git a/src/app/(frontend)/intelligence/page.tsx b/src/app/(frontend)/intelligence/page.tsx index 91ec18a..99f63be 100644 --- a/src/app/(frontend)/intelligence/page.tsx +++ b/src/app/(frontend)/intelligence/page.tsx @@ -3,16 +3,10 @@ import { getPayload } from "payload"; import { headers as nextHeaders } from "next/headers"; import { redirect } from "next/navigation"; import Link from "next/link"; -import type { Campaign, Mission, Faction } from "@/payload-types"; +import type { Campaign, Faction } from "@/payload-types"; import { hasIntelligenceQualification } from "@/utils/access-control/hasIntelligenceQualification"; -import { CrosshairIcon, ArrowRightIcon } from "lucide-react"; -import { - Item, - ItemContent, - ItemDescription, - ItemHeader, - ItemTitle, -} from "@/components/ui/item"; +import { ArrowRightIcon, CrosshairIcon } from "lucide-react"; +import { Item, ItemContent, ItemDescription, ItemHeader, ItemTitle } from "@/components/ui/item"; import { CampaignCard } from "@/components/frontend/intelligence/CampaignCard"; export const metadata = { @@ -55,8 +49,7 @@ export default async function IntelligenceOverviewPage() {

Intelligence

- Campaigns, missions, and faction intelligence for the theater of - operations. + Campaigns, missions, and faction intelligence for the theater of operations.

@@ -71,9 +64,7 @@ export default async function IntelligenceOverviewPage() { - - Active and completed campaigns across all theaters. - + Active and completed campaigns across all theaters. @@ -87,9 +78,7 @@ export default async function IntelligenceOverviewPage() { - - Operation briefings, objectives, and schedules. - + Operation briefings, objectives, and schedules. @@ -104,8 +93,7 @@ export default async function IntelligenceOverviewPage() { - {factions.length} faction{factions.length !== 1 ? "s" : ""}{" "} - tracked in the AO. + {factions.length} faction{factions.length !== 1 ? "s" : ""} tracked in the AO. diff --git a/src/app/(frontend)/locker/actions.ts b/src/app/(frontend)/locker/actions.ts index c774341..396fbbe 100644 --- a/src/app/(frontend)/locker/actions.ts +++ b/src/app/(frontend)/locker/actions.ts @@ -11,9 +11,9 @@ import { autoArrangeLockerItems, ensureLockerStorage, findLockerEmptySpot, + getLoadoutSlot, getLockerGridDimensions, getLockerItemFootprint, - getLoadoutSlot, isAttachmentCompatible, isLockerPlacementValid, isSkinAsset, @@ -23,7 +23,6 @@ import { resolveAssetId, skinAppliesTo, toLockerGridItems, - type LockerGridItem, } from "@/lib/locker"; export interface ActionResult { @@ -219,7 +218,8 @@ export async function removeLockerItem(entryId: string): Promise { const removed = items[idx]; const asset = removed.asset as Asset; - const removedName = typeof asset === "object" && asset ? asset.name : `asset #${resolveAssetId(removed.asset)}`; + const removedName = + typeof asset === "object" && asset ? asset.name : `asset #${resolveAssetId(removed.asset)}`; items.splice(idx, 1); await payload.update({ @@ -236,7 +236,12 @@ export async function removeLockerItem(entryId: string): Promise { actor: user.id, targetCollection: "locker-storages", targetId: locker.id, - data: { entryId, assetId: resolveAssetId(removed.asset), assetName: removedName, quantity: removed.quantity }, + data: { + entryId, + assetId: resolveAssetId(removed.asset), + assetName: removedName, + quantity: removed.quantity, + }, }); return { success: true }; @@ -269,19 +274,33 @@ export async function moveLockerItem( const effectiveRotated = rotated ?? entry.rotated ?? false; const fp = getLockerItemFootprint(asset, effectiveRotated); - if (gridX < 0 || gridY < 0 || gridX + fp.width > grid.width || gridY + fp.height > grid.height) { + if ( + gridX < 0 || + gridY < 0 || + gridX + fp.width > grid.width || + gridY + fp.height > grid.height + ) { return { success: false, error: "Placement is outside grid bounds." }; } const gridItems = toLockerGridItems(items); - if (!isLockerPlacementValid(gridItems, entryId, gridX, gridY, fp.width, fp.height, grid.width, grid.height)) { + if ( + !isLockerPlacementValid( + gridItems, + entryId, + gridX, + gridY, + fp.width, + fp.height, + grid.width, + grid.height, + ) + ) { return { success: false, error: "Cannot move here — overlaps with another item." }; } items[idx] = - rotated !== undefined - ? { ...entry, gridX, gridY, rotated } - : { ...entry, gridX, gridY }; + rotated !== undefined ? { ...entry, gridX, gridY, rotated } : { ...entry, gridX, gridY }; await payload.update({ collection: "locker-storages", @@ -297,7 +316,14 @@ export async function moveLockerItem( actor: user.id, targetCollection: "locker-storages", targetId: locker.id, - data: { entryId, assetId: asset.id, assetName: asset.name, gridX, gridY, rotated: effectiveRotated }, + data: { + entryId, + assetId: asset.id, + assetName: asset.name, + gridX, + gridY, + rotated: effectiveRotated, + }, }); return { success: true }; @@ -321,7 +347,8 @@ export async function rotateLockerItem(entryId: string): Promise { const entry = items[idx]; const asset = entry.asset as Asset; if (!asset || typeof asset === "number") return { success: false, error: "Invalid asset." }; - if (!lockerIsRotatable(asset)) return { success: false, error: "This asset cannot be rotated." }; + if (!lockerIsRotatable(asset)) + return { success: false, error: "This asset cannot be rotated." }; const newRotated = !(entry.rotated ?? false); const fp = getLockerItemFootprint(asset, newRotated); @@ -331,7 +358,18 @@ export async function rotateLockerItem(entryId: string): Promise { } const gridItems = toLockerGridItems(items); - if (!isLockerPlacementValid(gridItems, entryId, entry.gridX, entry.gridY, fp.width, fp.height, grid.width, grid.height)) { + if ( + !isLockerPlacementValid( + gridItems, + entryId, + entry.gridX, + entry.gridY, + fp.width, + fp.height, + grid.width, + grid.height, + ) + ) { return { success: false, error: "Rotation would overlap with another item." }; } @@ -362,10 +400,7 @@ export async function rotateLockerItem(entryId: string): Promise { } } -export async function mergeLockerStacks( - sourceId: string, - targetId: string, -): Promise { +export async function mergeLockerStacks(sourceId: string, targetId: string): Promise { try { const { payload, user } = await authenticate(); const locker = await getLockerWithItems(payload, user.id as number); @@ -385,7 +420,8 @@ export async function mergeLockerStacks( if (srcAsset.id !== tgtAsset.id) { return { success: false, error: "Cannot merge different asset types." }; } - if (!lockerIsStackable(tgtAsset)) return { success: false, error: "This asset cannot be stacked." }; + if (!lockerIsStackable(tgtAsset)) + return { success: false, error: "This asset cannot be stacked." }; const maxStack = lockerMaxStack(tgtAsset); const spaceInTarget = maxStack === Infinity ? Infinity : Math.max(0, maxStack - tgt.quantity); @@ -426,7 +462,10 @@ export async function mergeLockerStacks( } } -export async function splitLockerStack(entryId: string, splitAmount: number): Promise { +export async function splitLockerStack( + entryId: string, + splitAmount: number, +): Promise { try { const { payload, user } = await authenticate(); if (!Number.isInteger(splitAmount) || splitAmount <= 0) { @@ -445,7 +484,8 @@ export async function splitLockerStack(entryId: string, splitAmount: number): Pr } const asset = entry.asset as Asset; if (!asset || typeof asset === "number") return { success: false, error: "Invalid asset." }; - if (!lockerIsStackable(asset)) return { success: false, error: "This asset cannot be stacked." }; + if (!lockerIsStackable(asset)) + return { success: false, error: "This asset cannot be stacked." }; const gridItems = toLockerGridItems(items); const fp = getLockerItemFootprint(asset, entry.rotated ?? false); @@ -475,7 +515,13 @@ export async function splitLockerStack(entryId: string, splitAmount: number): Pr actor: user.id, targetCollection: "locker-storages", targetId: locker.id, - data: { entryId, assetId: asset.id, assetName: asset.name, splitAmount, remainingAmount: entry.quantity - splitAmount }, + data: { + entryId, + assetId: asset.id, + assetName: asset.name, + splitAmount, + remainingAmount: entry.quantity - splitAmount, + }, }); return { success: true }; @@ -674,7 +720,7 @@ export async function setLoadoutSlot( }); const equippedName = assetId - ? (await getAssetOrThrow(payload, assetId).catch(() => null))?.name ?? `asset #${assetId}` + ? ((await getAssetOrThrow(payload, assetId).catch(() => null))?.name ?? `asset #${assetId}`) : null; await emitGameEvent(payload, { @@ -778,10 +824,7 @@ export async function equipLoadout(loadoutId: number, equipped = true): Promise< // --- Equipment customization (attachments & skins) --- -export async function setItemAttachment( - entryId: string, - assetId: number, -): Promise { +export async function setItemAttachment(entryId: string, assetId: number): Promise { try { const { payload, user } = await authenticate(); const locker = await getLockerWithItems(payload, user.id as number); @@ -954,7 +997,8 @@ export async function setItemSkin(entryId: string, assetId: number): Promise { const skin = await getAssetOrThrow(payload, skinId); const fp = getLockerItemFootprint(skin, false); - const spot = findLockerEmptySpot(toLockerGridItems(items), fp.width, fp.height, grid.width, grid.height); + const spot = findLockerEmptySpot( + toLockerGridItems(items), + fp.width, + fp.height, + grid.width, + grid.height, + ); if (!spot) return { success: false, error: `No space in locker to return ${skin.name}.` }; const updatedItems = [...items]; @@ -1092,10 +1142,7 @@ export async function removeItemSkin(entryId: string): Promise { } } -export async function renameLockerItem( - entryId: string, - customName: string, -): Promise { +export async function renameLockerItem(entryId: string, customName: string): Promise { try { const { payload, user } = await authenticate(); const locker = await getLockerWithItems(payload, user.id as number); @@ -1121,9 +1168,7 @@ export async function renameLockerItem( await emitGameEvent(payload, { type: EventTypes.LockerItemRename, - message: name - ? `Renamed ${asset.name} to "${name}"` - : `Cleared custom name on ${asset.name}`, + message: name ? `Renamed ${asset.name} to "${name}"` : `Cleared custom name on ${asset.name}`, actor: user.id, targetCollection: "locker-storages", targetId: locker.id, diff --git a/src/app/(frontend)/logistics/banking/[id]/page.tsx b/src/app/(frontend)/logistics/banking/[id]/page.tsx index a005eb2..c9f9b5e 100644 --- a/src/app/(frontend)/logistics/banking/[id]/page.tsx +++ b/src/app/(frontend)/logistics/banking/[id]/page.tsx @@ -47,10 +47,7 @@ export default async function AccountPage({ params }: AccountPageProps) { ? typedAccount.ownerUser?.id : typedAccount.ownerUser; - const isOwner = - typedAccount.accountType === "personal" && - user !== null && - ownerId === user.id; + const isOwner = typedAccount.accountType === "personal" && user !== null && ownerId === user.id; if (!isManager && !isOwner) { notFound(); diff --git a/src/app/(frontend)/logistics/game-vehicles/[id]/page.tsx b/src/app/(frontend)/logistics/game-vehicles/[id]/page.tsx index dd4cc2b..336897a 100644 --- a/src/app/(frontend)/logistics/game-vehicles/[id]/page.tsx +++ b/src/app/(frontend)/logistics/game-vehicles/[id]/page.tsx @@ -2,13 +2,7 @@ import config from "@payload-config"; import { getPayload } from "payload"; import { notFound } from "next/navigation"; import Link from "next/link"; -import type { - GameVehicle, - Vehicle, - GameStructure, - Structure, - Resource, -} from "@/payload-types"; +import type { GameStructure, GameVehicle, Resource, Structure, Vehicle } from "@/payload-types"; import { ArrowLeftIcon, FuelIcon, @@ -38,9 +32,7 @@ const statusColors: Record = { destroyed: "bg-red-500/20 text-red-400", }; -export default async function GameVehicleDetailPage({ - params, -}: GameVehicleDetailPageProps) { +export default async function GameVehicleDetailPage({ params }: GameVehicleDetailPageProps) { const { id } = await params; const payload = await getPayload({ config }); @@ -59,11 +51,9 @@ export default async function GameVehicleDetailPage({ const vehicleData = vehicle as unknown as GameVehicle & { type: Vehicle; }; - const vehicleType = - typeof vehicleData.type === "object" ? vehicleData.type : null; + const vehicleType = typeof vehicleData.type === "object" ? vehicleData.type : null; const deployedAt = - typeof vehicleData.deployedAt === "object" && - vehicleData.deployedAt !== null + typeof vehicleData.deployedAt === "object" && vehicleData.deployedAt !== null ? (vehicleData.deployedAt as GameStructure & { type: Structure }) : null; const faction = @@ -100,8 +90,7 @@ export default async function GameVehicleDetailPage({ > {vehicleData.status === "in_transit" ? "In Transit" - : vehicleData.status.charAt(0).toUpperCase() + - vehicleData.status.slice(1)} + : vehicleData.status.charAt(0).toUpperCase() + vehicleData.status.slice(1)} {vehicleType?.name ?? "Unknown type"} @@ -118,8 +107,7 @@ export default async function GameVehicleDetailPage({ Fuel - {vehicleData.currentFuel?.toFixed(1)} /{" "} - {vehicleType?.fuel?.fuelCapacity ?? "?"} + {vehicleData.currentFuel?.toFixed(1)} / {vehicleType?.fuel?.fuelCapacity ?? "?"} @@ -129,9 +117,7 @@ export default async function GameVehicleDetailPage({ Health - - {vehicleData.currentHealth} - + {vehicleData.currentHealth} @@ -140,9 +126,7 @@ export default async function GameVehicleDetailPage({ Location - - {deployedAt?.name ?? "In transit"} - + {deployedAt?.name ?? "In transit"} @@ -151,9 +135,7 @@ export default async function GameVehicleDetailPage({ Faction - - {faction?.name ?? "Unassigned"} - + {faction?.name ?? "Unassigned"} @@ -180,25 +162,18 @@ export default async function GameVehicleDetailPage({ }} /> - - {fuelPercent.toFixed(0)}% - + {fuelPercent.toFixed(0)}%
- - {vehicleData.currentFuel?.toFixed(1)} units remaining - - - Capacity: {vehicleType?.fuel?.fuelCapacity ?? "?"} units - + {vehicleData.currentFuel?.toFixed(1)} units remaining + Capacity: {vehicleType?.fuel?.fuelCapacity ?? "?"} units
- {vehicleType?.fuel?.fuelType && - typeof vehicleType.fuel.fuelType === "object" && ( -
- Fuel type: {vehicleType.fuel.fuelType.name} · Consumption - rate: {vehicleType.fuel.fuelConsumptionRate}/unit -
- )} + {vehicleType?.fuel?.fuelType && typeof vehicleType.fuel.fuelType === "object" && ( +
+ Fuel type: {vehicleType.fuel.fuelType.name} · Consumption rate:{" "} + {vehicleType.fuel.fuelConsumptionRate}/unit +
+ )} @@ -227,14 +202,9 @@ export default async function GameVehicleDetailPage({ {storedResources.map((entry, index) => { const resource = - typeof entry.resource === "object" - ? (entry.resource as Resource) - : null; + typeof entry.resource === "object" ? (entry.resource as Resource) : null; return ( - + {resource?.name ?? `Resource #${entry.resource}`} @@ -248,9 +218,7 @@ export default async function GameVehicleDetailPage({ ) : ( -

- Vehicle cargo is empty. -

+

Vehicle cargo is empty.

)} @@ -266,28 +234,25 @@ export default async function GameVehicleDetailPage({
-

- {vehicleType?.name ?? "Unknown"} -

+

{vehicleType?.name ?? "Unknown"}

{vehicleType?.classname && (

{vehicleType.classname}

)}
- {vehicleType?.category && - vehicleType.category.length > 0 && ( -
- {vehicleType.category.map((cat) => ( - - {cat} - - ))} -
- )} + {vehicleType?.category && vehicleType.category.length > 0 && ( +
+ {vehicleType.category.map((cat) => ( + + {cat} + + ))} +
+ )}
diff --git a/src/app/(frontend)/logistics/game-vehicles/page.tsx b/src/app/(frontend)/logistics/game-vehicles/page.tsx index 92c6584..5d5286b 100644 --- a/src/app/(frontend)/logistics/game-vehicles/page.tsx +++ b/src/app/(frontend)/logistics/game-vehicles/page.tsx @@ -52,17 +52,13 @@ export default async function GameVehiclesPage() { {vehicles.length > 0 ? (
{vehicles.map((vehicle) => { - const vehicleType = - typeof vehicle.type === "object" ? vehicle.type : null; + const vehicleType = typeof vehicle.type === "object" ? vehicle.type : null; const fuelPercent = vehicleType?.fuel?.fuelCapacity ? (vehicle.currentFuel / vehicleType.fuel.fuelCapacity) * 100 : 0; return ( - + {vehicle.status === "in_transit" ? "In Transit" - : vehicle.status.charAt(0).toUpperCase() + - vehicle.status.slice(1)} + : vehicle.status.charAt(0).toUpperCase() + vehicle.status.slice(1)} @@ -94,9 +89,7 @@ export default async function GameVehiclesPage() {
20 - ? "bg-green-500" - : "bg-red-500" + fuelPercent > 20 ? "bg-green-500" : "bg-red-500" }`} style={{ width: `${Math.min(100, fuelPercent)}%`, @@ -112,16 +105,12 @@ export default async function GameVehiclesPage() { HP: {vehicle.currentHealth} {vehicleType?.fuel?.fuelType && typeof vehicleType.fuel.fuelType === "object" && ( - - {vehicleType.fuel.fuelType.name} - + {vehicleType.fuel.fuelType.name} )}
- - {vehicleType?.name ?? "Unknown type"} - + {vehicleType?.name ?? "Unknown type"}
); diff --git a/src/app/(frontend)/logistics/market/actions.ts b/src/app/(frontend)/logistics/market/actions.ts index 6e63958..3b3b956 100644 --- a/src/app/(frontend)/logistics/market/actions.ts +++ b/src/app/(frontend)/logistics/market/actions.ts @@ -7,17 +7,22 @@ import hasRoles from "@/utils/access-control/hasRoles"; import { emitGameEvent } from "@/utils/event-log/emit"; import { EventTypes } from "@/utils/event-log/eventTypes"; import { + buyListing, countCleanQuantity, creditLockerQuantity, deductLockerQuantity, - buyListing, negotiationRange, USER_LISTING_DURATION_MS, } from "@/lib/market"; import { ensureLockerStorage, resolveAssetId } from "@/lib/locker"; import { getMainCurrencyId } from "@/lib/banking"; import { notifyUser } from "@/lib/notifications"; -import { expireNegotiationsForListing, npcDialogue, npcResponseToOffer, type NpcState } from "@/lib/market/negotiations"; +import { + expireNegotiationsForListing, + npcDialogue, + npcResponseToOffer, + type NpcState, +} from "@/lib/market/negotiations"; export interface ActionResult { success: boolean; @@ -86,7 +91,9 @@ async function getListingOrThrow( function assetNameOf(listing: MarketListing): string { const asset = listing.asset as Asset; - return typeof asset === "object" && asset ? asset.name : `asset #${resolveAssetId(listing.asset)}`; + return typeof asset === "object" && asset + ? asset.name + : `asset #${resolveAssetId(listing.asset)}`; } async function getNegotiationOrThrow( @@ -94,7 +101,12 @@ async function getNegotiationOrThrow( negotiationId: number, ): Promise { const negotiation = (await payload - .findByID({ collection: "market-negotiations", id: negotiationId, depth: 2, overrideAccess: true }) + .findByID({ + collection: "market-negotiations", + id: negotiationId, + depth: 2, + overrideAccess: true, + }) .catch(() => null)) as unknown as MarketNegotiation | null; if (!negotiation) throw new Error("Negotiation not found."); return negotiation; @@ -146,10 +158,7 @@ function enforceHigherBuyerOffer(negotiation: MarketNegotiation, amount: number) } /** Role of the acting user in a negotiation: "buyer", "seller", or null. */ -function partyRoleOf( - negotiation: MarketNegotiation, - userId: number, -): "buyer" | "seller" | null { +function partyRoleOf(negotiation: MarketNegotiation, userId: number): "buyer" | "seller" | null { if (negotiationBuyerId(negotiation) === userId) return "buyer"; const listing = negotiationListing(negotiation); if (typeof listing === "object" && listing) { @@ -175,7 +184,7 @@ async function finalizeNegotiation( const buyerId = buyer.id as number; const sellerId = sellerIdOf(listing); const assetName = assetNameOf(listing); - const quantity = negotiation.quantity ?? (listing.quantity ?? 1); + const quantity = negotiation.quantity ?? listing.quantity ?? 1; const total = agreedPrice * quantity; const result = await buyListing(payload, listing, buyer, { unitPrice: agreedPrice, quantity }); @@ -319,7 +328,7 @@ async function resolveNpcOffer( targetId: negotiation.id, data: { listingId: listing.id, - quantity: negotiation.quantity ?? (listing.quantity ?? 1), + quantity: negotiation.quantity ?? listing.quantity ?? 1, amount, counter: response.amount, patience: response.patience, @@ -343,7 +352,7 @@ async function resolveNpcOffer( targetId: negotiation.id, data: { listingId: listing.id, - quantity: negotiation.quantity ?? (listing.quantity ?? 1), + quantity: negotiation.quantity ?? listing.quantity ?? 1, amount, counter: response.amount, patience: response.patience, @@ -472,7 +481,12 @@ export async function cancelMarketListing(listingId: number): Promise (listing.quantity ?? 1)) { return { success: false, error: `Quantity must be between 1 and ${listing.quantity}.` }; } @@ -580,7 +594,7 @@ export async function makeMarketOffer( return { success: false, error: "Offer must be greater than zero." }; } - const qty = quantity ?? (listing.quantity ?? 1); + const qty = quantity ?? listing.quantity ?? 1; if (!Number.isInteger(qty) || qty <= 0 || qty > (listing.quantity ?? 1)) { return { success: false, error: `Quantity must be between 1 and ${listing.quantity}.` }; } @@ -642,7 +656,9 @@ export async function makeMarketOffer( amount, proposedBy: "buyer", quantity: qty, - history: [{ amount, from: "buyer", note: "Initial offer", at: new Date().toISOString() }], + history: [ + { amount, from: "buyer", note: "Initial offer", at: new Date().toISOString() }, + ], }, overrideAccess: true, depth: 1, @@ -728,7 +744,9 @@ export async function makeMarketOffer( * buyer accepts the seller's counteroffer). Completes the sale at the * agreed price. */ -export async function acceptMarketOffer(negotiationId: number): Promise> { +export async function acceptMarketOffer( + negotiationId: number, +): Promise> { try { const { payload, user } = await authenticate(); const userId = user.id as number; @@ -789,8 +807,12 @@ export async function rejectMarketOffer(negotiationId: number): Promise), - ]; + const history = [...((negotiation.history ?? []) as NonNullable)]; history.push({ amount, from: role, note: "Counteroffer", at: new Date().toISOString() }); const updated = (await payload.update({ @@ -900,7 +920,8 @@ export async function counterMarketOffer( return { success: true, data: refreshed }; } - const counterpartyId = role === "buyer" ? sellerId : (negotiationBuyerId(negotiation) as number); + const counterpartyId = + role === "buyer" ? sellerId : (negotiationBuyerId(negotiation) as number); await notifyUser(payload, { userId: counterpartyId, type: "market:counter", @@ -933,9 +954,14 @@ export async function cancelMarketOffer(negotiationId: number): Promise { const sellerId = - typeof l.seller === "object" && l.seller ? (l.seller as { id: number }).id : (l.seller as number | null); + typeof l.seller === "object" && l.seller + ? (l.seller as { id: number }).id + : (l.seller as number | null); return sellerId === userId; }); @@ -62,7 +61,9 @@ export default async function MarketPage() { }); const negotiations = (negotiationsRes.docs as unknown as MarketNegotiation[]).filter((n) => { const buyerId = - typeof n.buyer === "object" && n.buyer ? (n.buyer as { id: number }).id : (n.buyer as number | null); + typeof n.buyer === "object" && n.buyer + ? (n.buyer as { id: number }).id + : (n.buyer as number | null); if (buyerId === userId) return true; const listing = n.listing as unknown as MarketListing | number | null; if (typeof listing === "object" && listing) { diff --git a/src/app/(frontend)/logistics/page.tsx b/src/app/(frontend)/logistics/page.tsx index 757ae9e..eeab73f 100644 --- a/src/app/(frontend)/logistics/page.tsx +++ b/src/app/(frontend)/logistics/page.tsx @@ -1,6 +1,6 @@ import config from "@payload-config"; import { getPayload } from "payload"; -import { GameStructure, Faction, Structure } from "@/payload-types"; +import { Faction, GameStructure, Structure } from "@/payload-types"; import { StorageGrid } from "@/components/frontend/storage/StorageGrid"; import { Building2Icon } from "lucide-react"; @@ -40,11 +40,7 @@ export default async function LogisticsPage() { Overview of all structures and their stored resources across the theater of operations.

- + ); } diff --git a/src/app/(frontend)/logistics/resources/[id]/page.tsx b/src/app/(frontend)/logistics/resources/[id]/page.tsx index da44c11..7cee79c 100644 --- a/src/app/(frontend)/logistics/resources/[id]/page.tsx +++ b/src/app/(frontend)/logistics/resources/[id]/page.tsx @@ -2,7 +2,7 @@ import config from "@payload-config"; import { getPayload } from "payload"; import { notFound } from "next/navigation"; import Link from "next/link"; -import type { Resource, Structure, Asset } from "@/payload-types"; +import type { Asset, Structure } from "@/payload-types"; import { RichText } from "@payloadcms/richtext-lexical/react"; import { convertLexicalToPlaintext } from "@payloadcms/richtext-lexical/plaintext"; import { @@ -12,7 +12,6 @@ import { CoinsIcon, Grid3x3Icon, LayersIcon, - MoveIcon, RotateCcwIcon, ScaleIcon, TagIcon, @@ -48,9 +47,7 @@ const typeColors: Record = { abstract: "bg-purple-500/20 text-purple-400", }; -export default async function ResourceDetailPage({ - params, -}: ResourceDetailPageProps) { +export default async function ResourceDetailPage({ params }: ResourceDetailPageProps) { const { id } = await params; const payload = await getPayload({ config }); @@ -105,9 +102,7 @@ export default async function ResourceDetailPage({ const allRelatedStructures = [ ...producers, - ...autoGenStructures.filter( - (s) => !producers.some((p) => p.id === s.id), - ), + ...autoGenStructures.filter((s) => !producers.some((p) => p.id === s.id)), ]; return ( @@ -124,10 +119,7 @@ export default async function ResourceDetailPage({
{resource.color ? ( -
+
) : ( )} @@ -243,10 +235,7 @@ export default async function ResourceDetailPage({
{allRelatedStructures.map((structure) => ( - + ) : ( -

- No resources available. -

+

No resources available.

)}
); diff --git a/src/app/(frontend)/logistics/shipments/[id]/page.tsx b/src/app/(frontend)/logistics/shipments/[id]/page.tsx index 0a1f584..6877b1a 100644 --- a/src/app/(frontend)/logistics/shipments/[id]/page.tsx +++ b/src/app/(frontend)/logistics/shipments/[id]/page.tsx @@ -2,30 +2,16 @@ import config from "@payload-config"; import { getPayload } from "payload"; import { notFound } from "next/navigation"; import Link from "next/link"; -import type { - Shipment, - GameStructure, - GameVehicle, - Vehicle, - Resource, -} from "@/payload-types"; +import type { GameStructure, GameVehicle, Vehicle } from "@/payload-types"; import { ArrowLeftIcon, ArrowRightIcon, ClockIcon, FuelIcon, - MapPinIcon, PackageIcon, TruckIcon, } from "lucide-react"; -import { - Item, - ItemContent, - ItemDescription, - ItemHeader, - ItemMedia, - ItemTitle, -} from "@/components/ui/item"; +import { Item, ItemContent, ItemHeader, ItemTitle } from "@/components/ui/item"; import { ShipmentActions } from "@/components/frontend/logistics/ShipmentActions"; import { ShipmentProgressBar } from "@/components/frontend/logistics/ShipmentProgressBar"; @@ -44,9 +30,7 @@ const statusColors: Record = { stranded: "bg-red-500/20 text-red-400", }; -export default async function ShipmentDetailPage({ - params, -}: ShipmentDetailPageProps) { +export default async function ShipmentDetailPage({ params }: ShipmentDetailPageProps) { const { id } = await params; const payload = await getPayload({ config }); @@ -71,31 +55,20 @@ export default async function ShipmentDetailPage({ ? (shipment.destination as GameStructure) : null; const vehicle = - typeof shipment.transportVehicle === "object" && - shipment.transportVehicle !== null + typeof shipment.transportVehicle === "object" && shipment.transportVehicle !== null ? (shipment.transportVehicle as GameVehicle & { type: Vehicle }) : null; - const vehicleType = - vehicle && typeof vehicle.type === "object" ? vehicle.type : null; + const vehicleType = vehicle && typeof vehicle.type === "object" ? vehicle.type : null; - const dispatchedAt = shipment.dispatchedAt - ? new Date(shipment.dispatchedAt) - : null; - const estimatedArrival = shipment.estimatedArrival - ? new Date(shipment.estimatedArrival) - : null; - const completedAt = shipment.completedAt - ? new Date(shipment.completedAt) - : null; + const dispatchedAt = shipment.dispatchedAt ? new Date(shipment.dispatchedAt) : null; + const estimatedArrival = shipment.estimatedArrival ? new Date(shipment.estimatedArrival) : null; + const completedAt = shipment.completedAt ? new Date(shipment.completedAt) : null; const now = new Date(); - const isActive = - shipment.status === "dispatched" || shipment.status === "in_transit"; + const isActive = shipment.status === "dispatched" || shipment.status === "in_transit"; const fuelPercent = - shipment.fuelCost > 0 - ? ((shipment.fuelConsumed ?? 0) / shipment.fuelCost) * 100 - : 0; + shipment.fuelCost > 0 ? ((shipment.fuelConsumed ?? 0) / shipment.fuelCost) * 100 : 0; return (
@@ -111,9 +84,7 @@ export default async function ShipmentDetailPage({
-

- {shipment.name ?? `SHP-${shipment.id}`} -

+

{shipment.name ?? `SHP-${shipment.id}`}

{shipment.status === "in_transit" ? "In Transit" - : shipment.status.charAt(0).toUpperCase() + - shipment.status.slice(1)} + : shipment.status.charAt(0).toUpperCase() + shipment.status.slice(1)} {shipment.distance?.toFixed(1)} units distance @@ -143,9 +113,7 @@ export default async function ShipmentDetailPage({
-

- {origin?.name ?? "Unknown"} -

+

{origin?.name ?? "Unknown"}

Origin

@@ -155,9 +123,7 @@ export default async function ShipmentDetailPage({
-

- {destination?.name ?? "Unknown"} -

+

{destination?.name ?? "Unknown"}

Destination

@@ -220,23 +186,14 @@ export default async function ShipmentDetailPage({ value: number | { name?: string }; }; itemType = polymorphic.relationTo; - if ( - typeof polymorphic.value === "object" && - polymorphic.value !== null - ) { - itemName = - polymorphic.value.name ?? "Unknown"; + if (typeof polymorphic.value === "object" && polymorphic.value !== null) { + itemName = polymorphic.value.name ?? "Unknown"; } } return ( - - - {itemName} - + + {itemName} {itemType} @@ -250,9 +207,7 @@ export default async function ShipmentDetailPage({
) : ( -

- No cargo on this shipment. -

+

No cargo on this shipment.

)} @@ -271,9 +226,7 @@ export default async function ShipmentDetailPage({
-

- {vehicle?.name ?? "Unknown"} -

+

{vehicle?.name ?? "Unknown"}

{vehicleType?.name ?? "Unknown type"}

@@ -283,24 +236,19 @@ export default async function ShipmentDetailPage({
Fuel - {vehicle.currentFuel?.toFixed(1)} /{" "} - {vehicleType?.fuel?.fuelCapacity ?? "?"} + {vehicle.currentFuel?.toFixed(1)} / {vehicleType?.fuel?.fuelCapacity ?? "?"}
0 - ? "bg-green-500" - : "bg-red-500" + vehicle.currentFuel > 0 ? "bg-green-500" : "bg-red-500" }`} style={{ width: `${Math.min( 100, vehicleType?.fuel?.fuelCapacity - ? (vehicle.currentFuel / - vehicleType.fuel.fuelCapacity) * - 100 + ? (vehicle.currentFuel / vehicleType.fuel.fuelCapacity) * 100 : 0, )}%`, }} @@ -308,9 +256,7 @@ export default async function ShipmentDetailPage({
Health - - {vehicle.currentHealth} - + {vehicle.currentHealth}
)} @@ -334,9 +280,7 @@ export default async function ShipmentDetailPage({
Consumed - - {(shipment.fuelConsumed ?? 0).toFixed(1)} - + {(shipment.fuelConsumed ?? 0).toFixed(1)}
- {shipment.status === "completed" - ? "Arrived" - : "Est. Arrival"} + {shipment.status === "completed" ? "Arrived" : "Est. Arrival"} {estimatedArrival.toLocaleDateString()}{" "} @@ -411,9 +353,7 @@ export default async function ShipmentDetailPage({ Failure Reason -

- {shipment.failureReason} -

+

{shipment.failureReason}

)} diff --git a/src/app/(frontend)/logistics/shipments/actions.ts b/src/app/(frontend)/logistics/shipments/actions.ts index 7650491..ff716e1 100644 --- a/src/app/(frontend)/logistics/shipments/actions.ts +++ b/src/app/(frontend)/logistics/shipments/actions.ts @@ -2,27 +2,13 @@ import config from "@payload-config"; import { getPayload } from "payload"; -import type { - GameStructure, - GameVehicle, - Structure, - Vehicle, - Resource, -} from "@/payload-types"; +import type { GameStructure, GameVehicle, Resource, Structure, Vehicle } from "@/payload-types"; import hasRoles from "@/utils/access-control/hasRoles"; import { emitGameEvent } from "@/utils/event-log/emit"; import { EventTypes } from "@/utils/event-log/eventTypes"; import { calculateDistance } from "@/lib/distance"; -import { - calculateFuelCost, - calculateTransitTime, - getVehicleEffectiveSpeed, -} from "@/lib/shipping"; -import { processShipmentTick } from "@/scripts/processShipmentTick"; -import { - checkStorageDeposit, - storageViolationMessage, -} from "@/lib/storageRules"; +import { calculateFuelCost, calculateTransitTime, getVehicleEffectiveSpeed } from "@/lib/shipping"; +import { checkStorageDeposit, storageViolationMessage } from "@/lib/storageRules"; interface ActionResult { success: boolean; @@ -105,8 +91,7 @@ export async function createShipment(params: { if (!originCoords || !destCoords) { return { success: false, - error: - "Both origin and destination must have coordinates set.", + error: "Both origin and destination must have coordinates set.", }; } @@ -146,9 +131,7 @@ export async function createShipment(params: { } const vehicleAtId = - typeof vehicle.deployedAt === "object" - ? vehicle.deployedAt?.id - : vehicle.deployedAt; + typeof vehicle.deployedAt === "object" ? vehicle.deployedAt?.id : vehicle.deployedAt; if (vehicleAtId !== originId) { return { @@ -158,8 +141,7 @@ export async function createShipment(params: { } // Get vehicle type details - const vehicleType = - typeof vehicle.type === "object" ? vehicle.type : null; + const vehicleType = typeof vehicle.type === "object" ? vehicle.type : null; if (!vehicleType) { return { success: false, error: "Vehicle type not found." }; } @@ -182,8 +164,7 @@ export async function createShipment(params: { if (cargoItem.relationTo === "resources") { const available = storedResources .filter((r) => { - const resId = - typeof r.resource === "object" ? r.resource.id : r.resource; + const resId = typeof r.resource === "object" ? r.resource.id : r.resource; return resId === cargoItem.value; }) .reduce((sum, r) => sum + r.amount, 0); @@ -191,18 +172,12 @@ export async function createShipment(params: { if (available < cargoItem.amount) { const resName = typeof storedResources.find((r) => { - const resId = - typeof r.resource === "object" - ? r.resource.id - : r.resource; + const resId = typeof r.resource === "object" ? r.resource.id : r.resource; return resId === cargoItem.value; })?.resource === "object" ? ( storedResources.find((r) => { - const resId = - typeof r.resource === "object" - ? r.resource.id - : r.resource; + const resId = typeof r.resource === "object" ? r.resource.id : r.resource; return resId === cargoItem.value; })?.resource as Resource ).name @@ -217,8 +192,7 @@ export async function createShipment(params: { } // Validate destination can accept the cargo (storage rules + mass capacity) - const destType = - typeof destination.type === "object" ? destination.type : null; + const destType = typeof destination.type === "object" ? destination.type : null; if (destType) { const destStored = destination.storedResources ?? []; const destVoid = (destination as GameStructure).voidStorage ?? []; @@ -233,8 +207,7 @@ export async function createShipment(params: { itemId: number, ) => entries.reduce((sum, r) => { - const resId = - typeof r.resource === "object" ? r.resource.id : r.resource; + const resId = typeof r.resource === "object" ? r.resource.id : r.resource; return sum + (resId === itemId ? r.amount : 0); }, 0); @@ -257,8 +230,7 @@ export async function createShipment(params: { } const currentStored = - storedAmountIn(destStored, cargoItem.value) + - storedAmountIn(destVoid, cargoItem.value); + storedAmountIn(destStored, cargoItem.value) + storedAmountIn(destVoid, cargoItem.value); const ruleCheck = checkStorageDeposit( destType, @@ -278,10 +250,7 @@ export async function createShipment(params: { } destMass += (resource.massPerUnit ?? 0) * cargoItem.amount; - if ( - destType.maxCapacityMass && - destMass > destType.maxCapacityMass - ) { + if (destType.maxCapacityMass && destMass > destType.maxCapacityMass) { return { success: false, error: `Destination "${destination.name}" would exceed its mass capacity of ${destType.maxCapacityMass.toLocaleString()} kg.`, @@ -327,8 +296,7 @@ export async function createShipment(params: { let remaining = cargoItem.amount; updatedResources = updatedResources .map((r) => { - const resId = - typeof r.resource === "object" ? r.resource.id : r.resource; + const resId = typeof r.resource === "object" ? r.resource.id : r.resource; if (resId === cargoItem.value && remaining > 0) { const deduct = Math.min(r.amount, remaining); remaining -= deduct; @@ -377,9 +345,7 @@ export async function createShipment(params: { fuelConsumed: 0, status: "dispatched", dispatchedAt: now.toISOString(), - estimatedArrival: new Date( - now.getTime() + transitTimeMs, - ).toISOString(), + estimatedArrival: new Date(now.getTime() + transitTimeMs).toISOString(), autoReturn: false, createdBy: user.id, }, @@ -402,8 +368,7 @@ export async function createShipment(params: { return { success: true, data: shipment }; } catch (error) { - const message = - error instanceof Error ? error.message : "Unknown error"; + const message = error instanceof Error ? error.message : "Unknown error"; if (message === "Unauthorized") { return { success: false, error: "You must be logged in." }; } @@ -411,9 +376,7 @@ export async function createShipment(params: { } } -export async function cancelShipment( - shipmentId: number, -): Promise { +export async function cancelShipment(shipmentId: number): Promise { try { const { payload, user } = await authenticate(); @@ -433,10 +396,7 @@ export async function cancelShipment( return { success: false, error: "Shipment not found." }; } - if ( - shipment.status !== "dispatched" && - shipment.status !== "in_transit" - ) { + if (shipment.status !== "dispatched" && shipment.status !== "in_transit") { return { success: false, error: `Cannot cancel shipment with status "${shipment.status}".`, @@ -444,9 +404,7 @@ export async function cancelShipment( } const originId = - typeof shipment.origin === "object" - ? shipment.origin.id - : (shipment.origin as number); + typeof shipment.origin === "object" ? shipment.origin.id : (shipment.origin as number); const vehicleId = typeof shipment.transportVehicle === "object" ? shipment.transportVehicle.id @@ -464,9 +422,7 @@ export async function cancelShipment( if (polymorphic.relationTo !== "resources") continue; const itemId = - typeof polymorphic.value === "object" - ? polymorphic.value.id - : polymorphic.value; + typeof polymorphic.value === "object" ? polymorphic.value.id : polymorphic.value; const origin = await payload.findByID({ collection: "game-structures", @@ -476,8 +432,7 @@ export async function cancelShipment( const existingResources = origin.storedResources ?? []; const existingEntry = existingResources.find((r) => { - const resId = - typeof r.resource === "object" ? r.resource.id : r.resource; + const resId = typeof r.resource === "object" ? r.resource.id : r.resource; return resId === itemId; }); @@ -531,8 +486,7 @@ export async function cancelShipment( return { success: true }; } catch (error) { - const message = - error instanceof Error ? error.message : "Unknown error"; + const message = error instanceof Error ? error.message : "Unknown error"; if (message === "Unauthorized") { return { success: false, error: "You must be logged in." }; } @@ -574,8 +528,7 @@ export async function toggleAutoReturn( return { success: true }; } catch (error) { - const message = - error instanceof Error ? error.message : "Unknown error"; + const message = error instanceof Error ? error.message : "Unknown error"; return { success: false, error: message }; } } diff --git a/src/app/(frontend)/logistics/shipments/page.tsx b/src/app/(frontend)/logistics/shipments/page.tsx index a478420..a9f26f3 100644 --- a/src/app/(frontend)/logistics/shipments/page.tsx +++ b/src/app/(frontend)/logistics/shipments/page.tsx @@ -1,6 +1,6 @@ import config from "@payload-config"; import { getPayload } from "payload"; -import type { Shipment, GameStructure, GameVehicle, Vehicle } from "@/payload-types"; +import type { Shipment } from "@/payload-types"; import { TruckIcon } from "lucide-react"; import { ShipmentsList } from "@/components/frontend/logistics/ShipmentsList"; diff --git a/src/app/(frontend)/logistics/structures/[id]/page.tsx b/src/app/(frontend)/logistics/structures/[id]/page.tsx index 3bf8179..ffcafb1 100644 --- a/src/app/(frontend)/logistics/structures/[id]/page.tsx +++ b/src/app/(frontend)/logistics/structures/[id]/page.tsx @@ -3,7 +3,7 @@ import { getPayload } from "payload"; import { notFound } from "next/navigation"; import { headers as nextHeaders } from "next/headers"; import Link from "next/link"; -import { GameStructure, Structure, Faction, Resource } from "@/payload-types"; +import { Faction, GameStructure, Resource, Structure } from "@/payload-types"; import { convertLexicalToPlaintext } from "@payloadcms/richtext-lexical/plaintext"; import { CapacityBar } from "@/components/frontend/storage/CapacityBar"; import { StorageRules } from "@/components/frontend/storage/StorageRules"; @@ -45,11 +45,13 @@ export default async function StructureDetailPage({ params }: StructureDetailPag const headers = await nextHeaders(); const { user } = await payload.auth({ headers, canSetHeaders: false }); - const structureRes = await payload.findByID({ - collection: "game-structures", - id: Number(id), - depth: 2, - }).catch(() => null); + const structureRes = await payload + .findByID({ + collection: "game-structures", + id: Number(id), + depth: 2, + }) + .catch(() => null); if (!structureRes) { notFound(); @@ -116,9 +118,7 @@ export default async function StructureDetailPage({ params }: StructureDetailPag
- {description && ( -

{description}

- )} + {description &&

{description}

}
@@ -187,7 +187,9 @@ export default async function StructureDetailPage({ params }: StructureDetailPag Max Capacity - {structureType.maxCapacityMass.toLocaleString()} kg (mass) + + {structureType.maxCapacityMass.toLocaleString()} kg (mass) + )} @@ -204,9 +206,7 @@ export default async function StructureDetailPage({ params }: StructureDetailPag )}
- + - {resource.name}: {upkeep.amount?.toLocaleString()} {pluralize(upkeep.amount ?? 0, resource.unitOfMeasure)}/tick + + {resource.name}: {upkeep.amount?.toLocaleString()}{" "} + {pluralize(upkeep.amount ?? 0, resource.unitOfMeasure)}/tick ); })} diff --git a/src/app/(frontend)/logistics/structures/actions.ts b/src/app/(frontend)/logistics/structures/actions.ts index 258ce91..226bd39 100644 --- a/src/app/(frontend)/logistics/structures/actions.ts +++ b/src/app/(frontend)/logistics/structures/actions.ts @@ -6,10 +6,7 @@ import { GameStructure, Resource, Structure } from "@/payload-types"; import hasRoles from "@/utils/access-control/hasRoles"; import { emitGameEvent } from "@/utils/event-log/emit"; import { EventTypes } from "@/utils/event-log/eventTypes"; -import { - checkStorageDeposit, - storageViolationMessage, -} from "@/lib/storageRules"; +import { checkStorageDeposit, storageViolationMessage } from "@/lib/storageRules"; interface ActionResult { success: boolean; @@ -32,11 +29,13 @@ async function authenticate() { } async function getStructure(payload: Awaited>, id: number) { - const structure = await payload.findByID({ - collection: "game-structures", - id, - depth: 2, - }).catch(() => null); + const structure = await payload + .findByID({ + collection: "game-structures", + id, + depth: 2, + }) + .catch(() => null); if (!structure) { throw new Error("Structure not found"); @@ -45,7 +44,10 @@ async function getStructure(payload: Awaited>, id: return structure as unknown as GameStructure & { type: Structure }; } -function getStoredAmount(storedResources: GameStructure["storedResources"], resourceId: number): number { +function getStoredAmount( + storedResources: GameStructure["storedResources"], + resourceId: number, +): number { if (!storedResources) return 0; const entry = storedResources.find((e) => { const res = e.resource; @@ -73,7 +75,10 @@ export async function addResource( try { const { payload, user } = await authenticate(); if (!hasRoles(["admin"], user)) { - return { success: false, error: "Insufficient permissions. Admin or Developer role required for deposit." }; + return { + success: false, + error: "Insufficient permissions. Admin or Developer role required for deposit.", + }; } if (amount <= 0) { @@ -84,11 +89,13 @@ export async function addResource( const structureType = structure.type; // Fetch the resource to check rules + mass - const resource = await payload.findByID({ - collection: "resources", - id: resourceId, - depth: 0, - }).catch(() => null); + const resource = await payload + .findByID({ + collection: "resources", + id: resourceId, + depth: 0, + }) + .catch(() => null); if (!resource) { return { success: false, error: "Resource not found." }; @@ -99,12 +106,7 @@ export async function addResource( getStoredAmount(structure.storedResources, resourceId) + getStoredAmount(structure.voidStorage ?? [], resourceId); - const ruleCheck = checkStorageDeposit( - structureType, - resourceId, - amount, - currentStored, - ); + const ruleCheck = checkStorageDeposit(structureType, resourceId, amount, currentStored); if (!ruleCheck.allowed) { return { @@ -136,9 +138,7 @@ export async function addResource( const resH = resource.gridHeight ?? 1; const ew = resW; const eh = resH; - const maxStack = resource.stackable === false - ? 1 - : resource.maxStackSize ?? Infinity; + const maxStack = resource.stackable === false ? 1 : (resource.maxStackSize ?? Infinity); // 1. Fill existing stacks of the same resource that have space let remaining = amount; @@ -151,9 +151,8 @@ export async function addResource( for (const entry of sameType) { if (remaining <= 0) break; - const space = maxStack === Infinity - ? remaining - : Math.min(maxStack - entry.amount, remaining); + const space = + maxStack === Infinity ? remaining : Math.min(maxStack - entry.amount, remaining); if (space <= 0) continue; const idx = existing.findIndex((e) => e.id === entry.id); if (idx >= 0) { @@ -204,7 +203,13 @@ export async function addResource( } const stackAmount = Math.min(remaining, maxStack === Infinity ? remaining : maxStack); - existing.push({ resource: resourceId, amount: stackAmount, gridX: spot.x, gridY: spot.y, rotated: false }); + existing.push({ + resource: resourceId, + amount: stackAmount, + gridX: spot.x, + gridY: spot.y, + rotated: false, + }); remaining -= stackAmount; } } else { @@ -260,7 +265,10 @@ export async function removeResource( try { const { payload, user } = await authenticate(); if (!hasRoles(["admin"], user)) { - return { success: false, error: "Insufficient permissions. Admin or Developer role required for withdrawal." }; + return { + success: false, + error: "Insufficient permissions. Admin or Developer role required for withdrawal.", + }; } if (amount <= 0) { @@ -331,7 +339,12 @@ export async function removeResource( data: { storedResources, voidStorage }, }); - const resName = (await payload.findByID({ collection: "resources", id: resourceId, depth: 0 }).catch(() => null))?.name ?? `resource #${resourceId}`; + const resName = + ( + await payload + .findByID({ collection: "resources", id: resourceId, depth: 0 }) + .catch(() => null) + )?.name ?? `resource #${resourceId}`; await emitGameEvent(payload, { type: EventTypes.StorageWithdraw, message: `Withdrew ${amount.toLocaleString()}× ${resName} from "${structure.name}"`, @@ -361,7 +374,10 @@ export async function transferResource( try { const { payload, user } = await authenticate(); if (!hasRoles(["admin"], user) && !hasRoles(["user"], user)) { - return { success: false, error: "Insufficient permissions. User, Admin, or Developer role required for transfer." }; + return { + success: false, + error: "Insufficient permissions. User, Admin, or Developer role required for transfer.", + }; } if (amount <= 0) { @@ -405,11 +421,13 @@ export async function transferResource( } // Fetch the resource for rule + capacity checks - const resource = await payload.findByID({ - collection: "resources", - id: resourceId, - depth: 0, - }).catch(() => null); + const resource = await payload + .findByID({ + collection: "resources", + id: resourceId, + depth: 0, + }) + .catch(() => null); if (!resource) { return { success: false, error: "Resource not found." }; @@ -468,7 +486,15 @@ export async function transferResource( structure: toStructureId, targetCollection: "game-structures", targetId: toStructureId, - data: { resourceId, amount, resourceName: resName, fromStructureId, toStructureId, fromStructureName: fromStructure.name, toStructureName: toStructure.name }, + data: { + resourceId, + amount, + resourceName: resName, + fromStructureId, + toStructureId, + fromStructureName: fromStructure.name, + toStructureName: toStructure.name, + }, }); return { success: true, data: addResult.data }; @@ -499,7 +525,10 @@ export async function placeResourceOnGrid( try { const { payload, user } = await authenticate(); if (!hasRoles(["admin"], user)) { - return { success: false, error: "Insufficient permissions. Admin or Developer role required for placement." }; + return { + success: false, + error: "Insufficient permissions. Admin or Developer role required for placement.", + }; } if (amount <= 0) return { success: false, error: "Amount must be greater than zero." }; @@ -507,7 +536,9 @@ export async function placeResourceOnGrid( const structure = await getStructure(payload, structureId); const structureType = structure.type; - const resource = await payload.findByID({ collection: "resources", id: resourceId, depth: 0 }).catch(() => null); + const resource = await payload + .findByID({ collection: "resources", id: resourceId, depth: 0 }) + .catch(() => null); if (!resource) return { success: false, error: "Resource not found." }; // Check storage rules (prohibited → whitelist → per-item cap) @@ -515,12 +546,7 @@ export async function placeResourceOnGrid( getStoredAmount(structure.storedResources, resourceId) + getStoredAmount(structure.voidStorage ?? [], resourceId); - const ruleCheck = checkStorageDeposit( - structureType, - resourceId, - amount, - currentStored, - ); + const ruleCheck = checkStorageDeposit(structureType, resourceId, amount, currentStored); if (!ruleCheck.allowed) { return { success: false, error: storageViolationMessage(resource.name, ruleCheck) }; @@ -534,7 +560,10 @@ export async function placeResourceOnGrid( const addedMass = (resource.massPerUnit ?? 0) * amount; const maxMass = structureType.maxCapacityMass; if (maxMass && currentMass + addedMass > maxMass) { - return { success: false, error: `Exceeds mass capacity. Available: ${(maxMass - currentMass).toLocaleString()} kg.` }; + return { + success: false, + error: `Exceeds mass capacity. Available: ${(maxMass - currentMass).toLocaleString()} kg.`, + }; } const gridW = structureType.xSize ?? 0; @@ -543,8 +572,8 @@ export async function placeResourceOnGrid( return { success: false, error: "This structure does not have grid dimensions configured." }; } - const resW = (resource.gridWidth ?? 1); - const resH = (resource.gridHeight ?? 1); + const resW = resource.gridWidth ?? 1; + const resH = resource.gridHeight ?? 1; const effectiveW = rotated ? resH : resW; const effectiveH = rotated ? resW : resH; @@ -578,7 +607,11 @@ export async function placeResourceOnGrid( existing.push({ resource: resourceId, amount, gridX, gridY, rotated }); - await payload.update({ collection: "game-structures", id: structureId, data: { storedResources: existing } }); + await payload.update({ + collection: "game-structures", + id: structureId, + data: { storedResources: existing }, + }); await emitGameEvent(payload, { type: EventTypes.GridPlace, @@ -609,7 +642,10 @@ export async function moveGridItem( try { const { payload, user } = await authenticate(); if (!hasRoles(["admin"], user) && !hasRoles(["user"], user)) { - return { success: false, error: "Insufficient permissions. User, Admin, or Developer role required." }; + return { + success: false, + error: "Insufficient permissions. User, Admin, or Developer role required.", + }; } const structure = await getStructure(payload, structureId); const existing = [...(structure.storedResources ?? [])]; @@ -653,10 +689,13 @@ export async function moveGridItem( } } - existing[idx] = rotated !== undefined - ? { ...entry, gridX, gridY, rotated } - : { ...entry, gridX, gridY }; - await payload.update({ collection: "game-structures", id: structureId, data: { storedResources: existing } }); + existing[idx] = + rotated !== undefined ? { ...entry, gridX, gridY, rotated } : { ...entry, gridX, gridY }; + await payload.update({ + collection: "game-structures", + id: structureId, + data: { storedResources: existing }, + }); await emitGameEvent(payload, { type: EventTypes.GridMove, @@ -665,7 +704,14 @@ export async function moveGridItem( structure: structureId, targetCollection: "game-structures", targetId: structureId, - data: { entryId, resourceId: (typeof res === "object" ? res.id : res), resourceName: res.name, gridX, gridY, rotated }, + data: { + entryId, + resourceId: typeof res === "object" ? res.id : res, + resourceName: res.name, + gridX, + gridY, + rotated, + }, }); return { success: true }; @@ -685,7 +731,10 @@ export async function mergeGridStacks( try { const { payload, user } = await authenticate(); if (!hasRoles(["admin"], user) && !hasRoles(["user"], user)) { - return { success: false, error: "Insufficient permissions. User, Admin, or Developer role required." }; + return { + success: false, + error: "Insufficient permissions. User, Admin, or Developer role required.", + }; } const structure = await getStructure(payload, structureId); const existing = [...(structure.storedResources ?? [])]; @@ -705,9 +754,11 @@ export async function mergeGridStacks( const srcResId = typeof srcRes === "object" ? srcRes.id : srcRes; const tgtResId = typeof tgtRes === "object" ? tgtRes.id : tgtRes; - if (srcResId !== tgtResId) return { success: false, error: "Cannot merge different resource types." }; + if (srcResId !== tgtResId) + return { success: false, error: "Cannot merge different resource types." }; - if (tgtRes.stackable === false) return { success: false, error: "This resource cannot be stacked." }; + if (tgtRes.stackable === false) + return { success: false, error: "This resource cannot be stacked." }; const maxStack = tgtRes.maxStackSize; const spaceInTarget = maxStack ? maxStack - tgt.amount : Infinity; @@ -723,7 +774,11 @@ export async function mergeGridStacks( existing[srcIdx] = { ...src, amount: src.amount - transferAmount }; } - await payload.update({ collection: "game-structures", id: structureId, data: { storedResources: existing } }); + await payload.update({ + collection: "game-structures", + id: structureId, + data: { storedResources: existing }, + }); const mergeResName = typeof srcRes === "object" ? srcRes.name : `resource #${srcResId}`; await emitGameEvent(payload, { @@ -733,7 +788,13 @@ export async function mergeGridStacks( structure: structureId, targetCollection: "game-structures", targetId: structureId, - data: { sourceId, targetId, resourceId: srcResId, resourceName: mergeResName, transferAmount }, + data: { + sourceId, + targetId, + resourceId: srcResId, + resourceName: mergeResName, + transferAmount, + }, }); return { success: true }; @@ -752,7 +813,10 @@ export async function rotateGridItem( try { const { payload, user } = await authenticate(); if (!hasRoles(["admin"], user) && !hasRoles(["user"], user)) { - return { success: false, error: "Insufficient permissions. User, Admin, or Developer role required." }; + return { + success: false, + error: "Insufficient permissions. User, Admin, or Developer role required.", + }; } const structure = await getStructure(payload, structureId); const existing = [...(structure.storedResources ?? [])]; @@ -762,7 +826,8 @@ export async function rotateGridItem( const entry = existing[idx]; const res = entry.resource as Resource; if (!res || typeof res === "number") return { success: false, error: "Invalid resource." }; - if (res.rotatable === false) return { success: false, error: "This resource cannot be rotated." }; + if (res.rotatable === false) + return { success: false, error: "This resource cannot be rotated." }; const newRotated = !(entry.rotated ?? false); const ew = newRotated ? (res.gridHeight ?? 1) : (res.gridWidth ?? 1); @@ -798,7 +863,11 @@ export async function rotateGridItem( } existing[idx] = { ...entry, rotated: newRotated }; - await payload.update({ collection: "game-structures", id: structureId, data: { storedResources: existing } }); + await payload.update({ + collection: "game-structures", + id: structureId, + data: { storedResources: existing }, + }); await emitGameEvent(payload, { type: EventTypes.GridRotate, @@ -807,7 +876,12 @@ export async function rotateGridItem( structure: structureId, targetCollection: "game-structures", targetId: structureId, - data: { entryId, resourceId: (typeof res === "object" ? res.id : res), resourceName: res.name, rotated: newRotated }, + data: { + entryId, + resourceId: typeof res === "object" ? res.id : res, + resourceName: res.name, + rotated: newRotated, + }, }); return { success: true }; @@ -826,7 +900,10 @@ export async function removeGridItem( try { const { payload, user } = await authenticate(); if (!hasRoles(["admin"], user)) { - return { success: false, error: "Insufficient permissions. Admin or Developer role required for removal." }; + return { + success: false, + error: "Insufficient permissions. Admin or Developer role required for removal.", + }; } const structure = await getStructure(payload, structureId); const existing = [...(structure.storedResources ?? [])]; @@ -836,9 +913,15 @@ export async function removeGridItem( const removedEntry = existing[idx]; const removedRes = removedEntry.resource as Resource; existing.splice(idx, 1); - await payload.update({ collection: "game-structures", id: structureId, data: { storedResources: existing } }); + await payload.update({ + collection: "game-structures", + id: structureId, + data: { storedResources: existing }, + }); - const removedName = removedRes?.name ?? `resource #${typeof removedRes === "object" ? removedRes.id : removedRes}`; + const removedName = + removedRes?.name ?? + `resource #${typeof removedRes === "object" ? removedRes.id : removedRes}`; await emitGameEvent(payload, { type: EventTypes.StorageWithdraw, message: `Removed ${removedEntry.amount}× ${removedName} from "${structure.name}"`, @@ -846,7 +929,12 @@ export async function removeGridItem( structure: structureId, targetCollection: "game-structures", targetId: structureId, - data: { entryId, resourceId: typeof removedRes === "object" ? removedRes.id : removedRes, resourceName: removedName, amount: removedEntry.amount }, + data: { + entryId, + resourceId: typeof removedRes === "object" ? removedRes.id : removedRes, + resourceName: removedName, + amount: removedEntry.amount, + }, }); return { success: true }; @@ -866,7 +954,10 @@ export async function splitGridStack( try { const { payload, user } = await authenticate(); if (!hasRoles(["admin"], user) && !hasRoles(["user"], user)) { - return { success: false, error: "Insufficient permissions. User, Admin, or Developer role required." }; + return { + success: false, + error: "Insufficient permissions. User, Admin, or Developer role required.", + }; } if (splitAmount <= 0) return { success: false, error: "Split amount must be positive." }; @@ -877,7 +968,8 @@ export async function splitGridStack( if (idx < 0) return { success: false, error: "Item not found in grid." }; const entry = existing[idx]; - if (splitAmount >= entry.amount) return { success: false, error: "Split amount must be less than the stack size." }; + if (splitAmount >= entry.amount) + return { success: false, error: "Split amount must be less than the stack size." }; const res = entry.resource as Resource; if (!res || typeof res === "number") return { success: false, error: "Invalid resource." }; @@ -934,7 +1026,11 @@ export async function splitGridStack( if (!placed) return { success: false, error: "No empty spot available for the split stack." }; - await payload.update({ collection: "game-structures", id: structureId, data: { storedResources: existing } }); + await payload.update({ + collection: "game-structures", + id: structureId, + data: { storedResources: existing }, + }); const splitResName = typeof res === "object" ? res.name : `resource #${res}`; await emitGameEvent(payload, { @@ -944,7 +1040,13 @@ export async function splitGridStack( structure: structureId, targetCollection: "game-structures", targetId: structureId, - data: { entryId, resourceId: typeof res === "object" ? res.id : res, resourceName: splitResName, splitAmount, remainingAmount: entry.amount - splitAmount }, + data: { + entryId, + resourceId: typeof res === "object" ? res.id : res, + resourceName: splitResName, + splitAmount, + remainingAmount: entry.amount - splitAmount, + }, }); return { success: true }; @@ -1029,9 +1131,10 @@ export async function retrieveFromVoid(structureId: number): Promise 0 - ? `Retrieved ${recovered} item(s) from void in "${structure.name}"` - : `No void items could be recovered in "${structure.name}" — grid full`, + message: + recovered > 0 + ? `Retrieved ${recovered} item(s) from void in "${structure.name}"` + : `No void items could be recovered in "${structure.name}" — grid full`, actor: user.id, structure: structureId, targetCollection: "game-structures", @@ -1040,9 +1143,10 @@ export async function retrieveFromVoid(structureId: number): Promise 0 - ? `${recovered} item(s) retrieved from void storage.` - : "No items could be retrieved — grid is full.", + error: + recovered > 0 + ? `${recovered} item(s) retrieved from void storage.` + : "No items could be retrieved — grid is full.", }; } catch (error) { const message = error instanceof Error ? error.message : "Unknown error"; @@ -1056,7 +1160,10 @@ export async function autoArrangeGrid(structureId: number): Promise(null); const filtered = useMemo(() => { if (!selectedCategory) return vehicles; - return vehicles.filter( - (v) => v.category?.includes(selectedCategory as NonNullable[number]), + return vehicles.filter((v) => + v.category?.includes(selectedCategory as NonNullable[number]), ); }, [vehicles, selectedCategory]); return ( <> - + {filtered.length > 0 ? (
{filtered.map((vehicle) => ( diff --git a/src/app/(frontend)/logistics/vehicles/[id]/page.tsx b/src/app/(frontend)/logistics/vehicles/[id]/page.tsx index 97d9518..bd965f9 100644 --- a/src/app/(frontend)/logistics/vehicles/[id]/page.tsx +++ b/src/app/(frontend)/logistics/vehicles/[id]/page.tsx @@ -2,7 +2,7 @@ import config from "@payload-config"; import { getPayload } from "payload"; import { notFound } from "next/navigation"; import Link from "next/link"; -import type { Vehicle, Resource, Technology, Structure } from "@/payload-types"; +import type { Resource, Structure, Technology } from "@/payload-types"; import { RichText } from "@payloadcms/richtext-lexical/react"; import { convertLexicalToPlaintext } from "@payloadcms/richtext-lexical/plaintext"; import { @@ -10,7 +10,6 @@ import { BoxIcon, Building2Icon, ClockIcon, - CrosshairIcon, GaugeIcon, HeartIcon, ShieldIcon, @@ -46,9 +45,7 @@ const armorColors: Record = { composite: "bg-purple-500/20 text-purple-400", }; -export default async function VehicleDetailPage({ - params, -}: VehicleDetailPageProps) { +export default async function VehicleDetailPage({ params }: VehicleDetailPageProps) { const { id } = await params; const payload = await getPayload({ config }); @@ -144,10 +141,7 @@ export default async function VehicleDetailPage({
{materials.map((mat, index) => ( - + {mat.resource.name}: {mat.amount.toLocaleString()} ))} @@ -203,9 +197,7 @@ export default async function VehicleDetailPage({ Armor Rating - - {vehicle.armorRating} - + {vehicle.armorRating} )} @@ -319,15 +311,10 @@ export default async function VehicleDetailPage({
{scrapReturns.map((scrap, index) => ( - + {scrap.resource.name}: {scrap.amount.toLocaleString()} {scrap.chance < 100 && ( - - ({scrap.chance}%) - + ({scrap.chance}%) )} ))} @@ -348,10 +335,7 @@ export default async function VehicleDetailPage({
{upkeepCosts.map((upkeep, index) => ( - + {upkeep.resource.name}: {upkeep.amount.toLocaleString()}/tick ))} @@ -369,10 +353,7 @@ export default async function VehicleDetailPage({
{producingStructures.map((structure) => ( - + Unit Roster

- {members.length} operator{members.length !== 1 ? "s" : ""} across{" "} - {assignments.length} assignment{assignments.length !== 1 ? "s" : ""} + {members.length} operator{members.length !== 1 ? "s" : ""} across {assignments.length}{" "} + assignment{assignments.length !== 1 ? "s" : ""}

- +
); } diff --git a/src/app/(payload)/api/graphql-playground/route.ts b/src/app/(payload)/api/graphql-playground/route.ts index 8990e21..b186295 100644 --- a/src/app/(payload)/api/graphql-playground/route.ts +++ b/src/app/(payload)/api/graphql-playground/route.ts @@ -1,7 +1,7 @@ /* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */ /* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */ -import config from '@payload-config' -import '@payloadcms/next/css' -import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes' +import config from "@payload-config"; +import "@payloadcms/next/css"; +import { GRAPHQL_PLAYGROUND_GET } from "@payloadcms/next/routes"; export const GET = GRAPHQL_PLAYGROUND_GET(config); diff --git a/src/app/(payload)/api/graphql/route.ts b/src/app/(payload)/api/graphql/route.ts index 4534269..df3994b 100644 --- a/src/app/(payload)/api/graphql/route.ts +++ b/src/app/(payload)/api/graphql/route.ts @@ -1,7 +1,7 @@ /* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */ /* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */ -import config from '@payload-config' -import { GRAPHQL_POST, REST_OPTIONS } from '@payloadcms/next/routes' +import config from "@payload-config"; +import { GRAPHQL_POST, REST_OPTIONS } from "@payloadcms/next/routes"; export const POST = GRAPHQL_POST(config); diff --git a/src/app/api/realtime/route.ts b/src/app/api/realtime/route.ts index c280ef8..e170859 100644 --- a/src/app/api/realtime/route.ts +++ b/src/app/api/realtime/route.ts @@ -1,9 +1,5 @@ import { NextRequest } from "next/server"; -import { - subscribe, - unsubscribe, - type SSEEventClient, -} from "@/lib/realtime/bus"; +import { type SSEEventClient, subscribe, unsubscribe } from "@/lib/realtime/bus"; export const dynamic = "force-dynamic"; export const runtime = "nodejs"; diff --git a/src/app/api/version/route.ts b/src/app/api/version/route.ts index 29749ae..838c94a 100644 --- a/src/app/api/version/route.ts +++ b/src/app/api/version/route.ts @@ -5,12 +5,7 @@ import type { VersionInfo } from "@/lib/versionInfo"; export const dynamic = "force-dynamic"; export const runtime = "nodejs"; -const VERSION_INFO_PATH = path.join( - process.cwd(), - "src", - "generated", - "versionInfo.json", -); +const VERSION_INFO_PATH = path.join(process.cwd(), "src", "generated", "versionInfo.json"); const EMPTY: VersionInfo = { version: null, diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 3d3a018..4cfa177 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -24,8 +24,7 @@ export default async function LoginPage() {

- Log in to access the operations dashboard, intelligence, and - logistics. + Log in to access the operations dashboard, intelligence, and logistics.