This repository has been archived on 2026-08-11. You can view files and clone it, but cannot push or open issues or pull requests.
Gishen-Admin/src/pages/stock/StockPage.tsx
kirukib c2fd9d6431 first commit
Scaffold Gishen Admin: React/Vite shadcn console with role modules, EN/AM i18n, mocks, and backend spec.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 18:01:56 +03:00

134 lines
5.3 KiB
TypeScript

import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { PageShell } from '@/layouts/PageShell'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { branches, stockRows } from '@/mocks/data'
export function StockPage() {
const { t } = useTranslation()
const [entry, setEntry] = useState('')
const [rows, setRows] = useState(stockRows)
const duplicates = entry.length > 2
? rows.filter((r) => r.name.toLowerCase().includes(entry.toLowerCase()) || r.sku.toLowerCase().includes(entry.toLowerCase()))
: []
const resolve = (sku: string) => {
setRows((prev) => prev.map((r) => (r.sku === sku ? { ...r, qty: r.erpQty } : r)))
toast.success(`Discrepancy resolved for ${sku}`)
}
return (
<PageShell title={t('stock.title')} subtitle={t('stock.subtitle')}>
<Tabs defaultValue="inventory">
<TabsList>
<TabsTrigger value="inventory">Inventory</TabsTrigger>
<TabsTrigger value="erp">ERP sync</TabsTrigger>
<TabsTrigger value="entry">AI-assisted entry</TabsTrigger>
<TabsTrigger value="transfers">Transfers</TabsTrigger>
</TabsList>
<TabsContent value="inventory">
<Card>
<CardContent className="p-4">
<Table>
<TableHeader>
<TableRow>
<TableHead>SKU</TableHead>
<TableHead>Name</TableHead>
<TableHead>Branch</TableHead>
<TableHead>Qty</TableHead>
<TableHead>Batch</TableHead>
<TableHead>Expiry</TableHead>
<TableHead>Alert</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{rows.map((r) => (
<TableRow key={`${r.sku}-${r.branchId}`}>
<TableCell className="font-medium">{r.sku}</TableCell>
<TableCell>{r.name}</TableCell>
<TableCell>{branches.find((b) => b.id === r.branchId)?.name}</TableCell>
<TableCell>{r.qty}</TableCell>
<TableCell>{r.batch}</TableCell>
<TableCell>{r.expiry}</TableCell>
<TableCell>
{r.qty < 20 ? <Badge variant="warning">low stock</Badge> : <Badge variant="success">ok</Badge>}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="erp">
<Card>
<CardHeader>
<CardTitle>Platform vs ERP discrepancies</CardTitle>
</CardHeader>
<CardContent className="space-y-3 p-4 pt-0">
{rows
.filter((r) => r.qty !== r.erpQty)
.map((r) => (
<div key={r.sku} className="flex items-center justify-between rounded-xl border p-3">
<div>
<p className="font-medium">{r.sku}</p>
<p className="text-xs text-muted-foreground">
Platform {r.qty} · ERP {r.erpQty}
</p>
</div>
<Button size="sm" onClick={() => resolve(r.sku)}>
Resolve to ERP
</Button>
</div>
))}
{rows.every((r) => r.qty === r.erpQty) && (
<p className="text-sm text-muted-foreground">No open discrepancies</p>
)}
</CardContent>
</Card>
</TabsContent>
<TabsContent value="entry">
<Card>
<CardHeader>
<CardTitle>Duplicate detection while typing</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<Input
placeholder="Name, barcode, or SKU…"
value={entry}
onChange={(e) => setEntry(e.target.value)}
/>
{duplicates.map((d) => (
<div key={d.sku} className="rounded-xl border border-orange/30 bg-orange/5 p-3 text-sm">
Possible match: <strong>{d.name}</strong> ({d.sku}) — merge requires human approval
</div>
))}
</CardContent>
</Card>
</TabsContent>
<TabsContent value="transfers">
<Card>
<CardContent className="space-y-3 p-5">
<p className="text-sm text-muted-foreground">
Stock Manager owns inter-branch transfers. Suggest move of Vitamin C from Bole → CMC (fast mover).
</p>
<Button
onClick={() => toast.success('Transfer draft created (mock)')}
>
Create transfer suggestion
</Button>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</PageShell>
)
}