From f14e6b91f3d0677a4b2e949a18eae43214c3bce8 Mon Sep 17 00:00:00 2001 From: achmad Date: Fri, 29 May 2026 17:05:09 +0700 Subject: [PATCH] feat: add admin contracts and arsenal pages Co-Authored-By: Claude Opus 4.8 (1M context) --- backend/src/app/admin/arsenal/page.tsx | 57 ++++++++++++++++++++ backend/src/app/admin/contracts/page.tsx | 34 ++++++++++++ backend/src/app/api/admin/arsenal/route.ts | 10 ++++ backend/src/app/api/admin/contracts/route.ts | 8 +++ 4 files changed, 109 insertions(+) create mode 100644 backend/src/app/admin/arsenal/page.tsx create mode 100644 backend/src/app/admin/contracts/page.tsx create mode 100644 backend/src/app/api/admin/arsenal/route.ts create mode 100644 backend/src/app/api/admin/contracts/route.ts diff --git a/backend/src/app/admin/arsenal/page.tsx b/backend/src/app/admin/arsenal/page.tsx new file mode 100644 index 0000000..07988e5 --- /dev/null +++ b/backend/src/app/admin/arsenal/page.tsx @@ -0,0 +1,57 @@ +'use client'; +import { useEffect, useState } from 'react'; + +export default function ArsenalPage() { + const [data, setData] = useState({}); + + useEffect(() => { + fetch('/api/admin/arsenal').then(r => r.json()).then(setData); + }, []); + + return ( +
+

Arsenal

+
+
+

Inventory ({data.inventory?.length || 0})

+
+ {data.inventory?.map((i: any, idx: number) => ( +
+ {i.item_name} + [{i.quality}] +
{i.steam_id}
+
+ ))} + {!data.inventory?.length &&

None

} +
+
+
+

Loadouts ({data.loadouts?.length || 0})

+
+ {data.loadouts?.map((l: any, idx: number) => ( +
+ {l.steam_id} + {l.hero_name} +
{l.loadout}
+
+ ))} + {!data.loadouts?.length &&

None

} +
+
+
+

Active Listings ({data.listings?.length || 0})

+
+ {data.listings?.map((l: any, idx: number) => ( +
+ {l.item_name} + {l.price_free} free +
{l.steam_id}
+
+ ))} + {!data.listings?.length &&

None

} +
+
+
+
+ ); +} diff --git a/backend/src/app/admin/contracts/page.tsx b/backend/src/app/admin/contracts/page.tsx new file mode 100644 index 0000000..0298bdd --- /dev/null +++ b/backend/src/app/admin/contracts/page.tsx @@ -0,0 +1,34 @@ +'use client'; +import { useEffect, useState } from 'react'; + +export default function ContractsPage() { + const [contracts, setContracts] = useState([]); + + useEffect(() => { + fetch('/api/admin/contracts').then(r => r.json()).then(setContracts); + }, []); + + return ( +
+

Death Sentence Contracts

+
+ + + + + + + + {contracts.map((c: any) => ( + + + + + + ))} + +
Steam IDContract DataUpdated
{c.steam_id}{c.contracts}{c.updated_at}
+
+
+ ); +} diff --git a/backend/src/app/api/admin/arsenal/route.ts b/backend/src/app/api/admin/arsenal/route.ts new file mode 100644 index 0000000..1e9b82c --- /dev/null +++ b/backend/src/app/api/admin/arsenal/route.ts @@ -0,0 +1,10 @@ +import { NextResponse } from 'next/server'; +import { getDb } from '@/lib/db'; + +export async function GET() { + const db = getDb(); + const inventory = db.prepare('SELECT * FROM arsenal_inventory ORDER BY steam_id').all(); + const loadouts = db.prepare('SELECT * FROM arsenal_loadouts ORDER BY steam_id').all(); + const listings = db.prepare("SELECT * FROM arsenal_market_listings WHERE status = 'active' ORDER BY created_at DESC").all(); + return NextResponse.json({ inventory, loadouts, listings }); +} diff --git a/backend/src/app/api/admin/contracts/route.ts b/backend/src/app/api/admin/contracts/route.ts new file mode 100644 index 0000000..d84f40b --- /dev/null +++ b/backend/src/app/api/admin/contracts/route.ts @@ -0,0 +1,8 @@ +import { NextResponse } from 'next/server'; +import { getDb } from '@/lib/db'; + +export async function GET() { + const db = getDb(); + const contracts = db.prepare('SELECT * FROM death_sentence_contracts').all(); + return NextResponse.json(contracts); +}