110 lines
3.7 KiB
TypeScript
110 lines
3.7 KiB
TypeScript
'use client';
|
||
|
||
import { useState, useEffect } from 'react';
|
||
import { useInventoryStore } from '@/store/useInventoryStore';
|
||
|
||
import shared from '../../styles/shared.module.css';
|
||
import styles from '../../styles/Items.module.css';
|
||
|
||
import { Item, Offering } from './types';
|
||
import ItemGrid from './ItemGrid';
|
||
import OfferingGrid from './OfferingGrid';
|
||
|
||
type Tab = 'items' | 'offerings';
|
||
|
||
export default function ItemsPage() {
|
||
const store = useInventoryStore();
|
||
|
||
const [tab, setTab] = useState<Tab>('items');
|
||
const [items, setItems] = useState<Item[]>([]);
|
||
const [offerings, setOfferings] = useState<Offering[]>([]);
|
||
|
||
const [randMin, setRandMin] = useState(50);
|
||
const [randMax, setRandMax] = useState(200);
|
||
|
||
useEffect(() => {
|
||
Promise.all([
|
||
fetch('/data/items.json').then(r => r.json()).catch(() => []),
|
||
fetch('/data/offerings.json').then(r => r.json()).catch(() => []),
|
||
]).then(([i, o]) => {
|
||
setItems(i);
|
||
setOfferings(o);
|
||
});
|
||
}, []);
|
||
|
||
const handleClearAll = () => {
|
||
store.clearCategory('items');
|
||
store.clearCategory('offerings');
|
||
};
|
||
|
||
const activeItems = Object.values(store.items).filter(q => q > 0).length;
|
||
const activeOfferings = Object.values(store.offerings).filter(q => q > 0).length;
|
||
|
||
return (
|
||
<div className={shared.container}>
|
||
<header className={shared.header}>
|
||
<div>
|
||
<h1 className={shared.title}>Items & Offerings</h1>
|
||
<p className={shared.subtitle}>
|
||
{activeItems} active items · {activeOfferings} active offerings
|
||
</p>
|
||
</div>
|
||
|
||
<div className={styles.rangeGroup}>
|
||
<span className={styles.rangeLabel}>Rand range</span>
|
||
<input
|
||
className={styles.rangeInput}
|
||
type="number"
|
||
value={randMin}
|
||
min={0}
|
||
max={5000}
|
||
onChange={e => setRandMin(Math.max(0, parseInt(e.target.value) || 0))}
|
||
/>
|
||
<span className={styles.rangeSep}>–</span>
|
||
<input
|
||
className={styles.rangeInput}
|
||
type="number"
|
||
value={randMax}
|
||
min={0}
|
||
max={5000}
|
||
onChange={e => setRandMax(Math.min(5000, parseInt(e.target.value) || 0))}
|
||
/>
|
||
</div>
|
||
|
||
<button className={shared.clearBtn} onClick={handleClearAll}>Clear All</button>
|
||
</header>
|
||
|
||
<div className={styles.tabs}>
|
||
{(['items', 'offerings'] as Tab[]).map(t => (
|
||
<button
|
||
key={t}
|
||
className={`${styles.tab} ${tab === t ? styles.tabActive : ''}`}
|
||
onClick={() => setTab(t)}
|
||
>
|
||
{t}
|
||
</button>
|
||
))}
|
||
</div>
|
||
|
||
{tab === 'items' && (
|
||
<ItemGrid
|
||
items={items}
|
||
quantities={store.items}
|
||
randMin={randMin}
|
||
randMax={randMax}
|
||
onSetQty={store.setItemQuantity}
|
||
/>
|
||
)}
|
||
|
||
{tab === 'offerings' && (
|
||
<OfferingGrid
|
||
offerings={offerings}
|
||
quantities={store.offerings}
|
||
randMin={randMin}
|
||
randMax={randMax}
|
||
onSetQty={store.setOfferingQuantity}
|
||
/>
|
||
)}
|
||
</div>
|
||
);
|
||
} |