feat: implement inventory and pantry management views with CRUD functionality and user-friendly interfaces

This commit is contained in:
Nils-Johan Gynther
2026-04-21 14:43:18 +02:00
parent 82c3dc3fee
commit 81b63b3fdb
14 changed files with 352 additions and 59 deletions
+51 -45
View File
@@ -1,71 +1,77 @@
'use client';
import { useState } from 'react';
import MergePreviewForm from '../../admin/products/MergePreviewForm';
import AdminProductList from '../../admin/products/AdminProductList';
import ExpandableCreateProductSection from '../../admin/products/ExpandableCreateProductSection';
import ResetProductsButton from '../../admin/products/ResetProductsButton';
import DeletedProductsView from '../../admin/products/DeletedProductsView';
import { useSession } from 'next-auth/react';
import ProductsView from './views/ProductsView';
import InventoryView from './views/InventoryView';
import PantryView from './views/PantryView';
const subTabs = [
{ id: 'varor', label: '📦 Varor' },
{ id: 'skapa-merge', label: ' Skapa / Slå ihop' },
{ id: 'papperskorg', label: '🗑️ Papperskorg' },
] as const;
type TableId = 'inventory' | 'pantry' | 'products';
type SubTabId = typeof subTabs[number]['id'];
type TableDef = {
id: TableId;
label: string;
adminOnly: boolean;
};
const TABLES: TableDef[] = [
{ id: 'inventory', label: '🏠 Inventarie', adminOnly: false },
{ id: 'pantry', label: '📦 Baslager', adminOnly: false },
{ id: 'products', label: '🗄️ Produkter', adminOnly: true },
];
const tabStyle = (active: boolean): React.CSSProperties => ({
padding: '0.4rem 1rem',
padding: '0.5rem 1.1rem',
border: 'none',
borderBottom: active ? '2.5px solid #333' : '2.5px solid transparent',
background: 'none',
borderBottom: active ? '2.5px solid #2563eb' : '2.5px solid transparent',
background: active ? '#eff6ff' : 'none',
cursor: 'pointer',
fontWeight: active ? 600 : 400,
color: active ? '#111' : '#666',
color: active ? '#2563eb' : '#555',
fontSize: '0.95rem',
transition: 'color 0.15s, border-color 0.15s',
borderRadius: '4px 4px 0 0',
transition: 'color 0.15s, border-color 0.15s, background 0.15s',
});
export default function DatabsTab() {
const [activeSubTab, setActiveSubTab] = useState<SubTabId>('varor');
const { data: session } = useSession();
const isAdmin = (session?.user as any)?.role === 'admin';
const visibleTables = TABLES.filter((t) => !t.adminOnly || isAdmin);
const [activeTable, setActiveTable] = useState<TableId>('inventory');
// Om vald tabell inte är tillgänglig för rollen, fall tillbaka på första
const safeActive = visibleTables.find((t) => t.id === activeTable)
? activeTable
: visibleTables[0]?.id ?? 'inventory';
return (
<div>
{/* Undertabbar */}
<div style={{ display: 'flex', gap: '0.25rem', borderBottom: '1px solid #ddd', marginBottom: '1.5rem' }}>
{subTabs.map((tab) => (
{/* Tabellväljare */}
<div
style={{
display: 'flex',
gap: '0.25rem',
borderBottom: '1px solid #ddd',
marginBottom: '1.75rem',
}}
>
{visibleTables.map((table) => (
<button
key={tab.id}
style={tabStyle(activeSubTab === tab.id)}
onClick={() => setActiveSubTab(tab.id)}
key={table.id}
style={tabStyle(safeActive === table.id)}
onClick={() => setActiveTable(table.id)}
>
{tab.label}
{table.label}
</button>
))}
</div>
{activeSubTab === 'varor' && (
<div>
<p style={{ color: '#555', marginBottom: '1rem' }}>
Granska och standardisera produktnamn samt hantera kategorier.
</p>
<AdminProductList />
</div>
)}
{activeSubTab === 'skapa-merge' && (
<div>
<p style={{ color: '#555', marginBottom: '1rem' }}>
Skapa ny produkt, återställ produktdatabas eller slå ihop dubbletter.
</p>
<ExpandableCreateProductSection />
<ResetProductsButton />
<MergePreviewForm />
</div>
)}
{activeSubTab === 'papperskorg' && <DeletedProductsView />}
{safeActive === 'inventory' && <InventoryView />}
{safeActive === 'pantry' && <PantryView />}
{safeActive === 'products' && isAdmin && <ProductsView />}
</div>
);
}