135 lines
3.3 KiB
TypeScript
135 lines
3.3 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, Addon } from './types';
|
||
import { fetchItems, fetchOfferings, fetchAddons } from '../../lib/db';
|
||
import ItemGrid from './ItemGrid';
|
||
import OfferingGrid from './OfferingGrid';
|
||
import AddonGrid from './AddonGrid';
|
||
|
||
type Tab = 'items' | 'offerings' | 'addons';
|
||
|
||
export default function ItemsPage() {
|
||
const store = useInventoryStore();
|
||
|
||
const [tab, setTab] = useState<Tab>('items');
|
||
const [items, setItems] = useState<Item[]>([]);
|
||
const [offerings, setOfferings] = useState<Offering[]>([]);
|
||
const [addons, setAddons] = useState<Addon[]>([]);
|
||
|
||
const [randMin, setRandMin] = useState(50);
|
||
const [randMax, setRandMax] = useState(200);
|
||
|
||
useEffect(() => {
|
||
Promise.all([fetchItems(), fetchOfferings(), fetchAddons()]).then(
|
||
([i, o, a]) => {
|
||
setItems(i);
|
||
setOfferings(o);
|
||
setAddons(a);
|
||
}
|
||
);
|
||
}, []);
|
||
|
||
const handleClearAll = () => {
|
||
store.clearCategory('items');
|
||
store.clearCategory('offerings');
|
||
store.clearCategory('addons');
|
||
};
|
||
|
||
const activeItems = Object.values(store.items).filter((q) => q > 0).length;
|
||
const activeOfferings = Object.values(store.offerings).filter(
|
||
(q) => q > 0
|
||
).length;
|
||
const activeAddons = Object.values(store.addons).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} items · {activeOfferings} offerings · {activeAddons}{' '}
|
||
addons
|
||
</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', 'addons'] 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}
|
||
/>
|
||
)}
|
||
|
||
{tab === 'addons' && (
|
||
<AddonGrid
|
||
addons={addons}
|
||
quantities={store.addons}
|
||
randMin={randMin}
|
||
randMax={randMax}
|
||
onSetQty={store.setAddonQuantity}
|
||
/>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|