Layout tweaksÏ
This commit is contained in:
@@ -66,7 +66,7 @@ export function CalculationSettings() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="max-w-[700px] space-y-4">
|
||||
{/* Sales Velocity Configuration Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
|
||||
@@ -1,630 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { toast } from "sonner";
|
||||
import config from '../../config';
|
||||
|
||||
interface StockThreshold {
|
||||
id: number;
|
||||
category_id: number | null;
|
||||
vendor: string | null;
|
||||
critical_days: number;
|
||||
reorder_days: number;
|
||||
overstock_days: number;
|
||||
low_stock_threshold: number;
|
||||
min_reorder_quantity: number;
|
||||
category_name?: string;
|
||||
threshold_scope?: string;
|
||||
}
|
||||
|
||||
interface LeadTimeThreshold {
|
||||
id: number;
|
||||
category_id: number | null;
|
||||
vendor: string | null;
|
||||
target_days: number;
|
||||
warning_days: number;
|
||||
critical_days: number;
|
||||
}
|
||||
|
||||
interface SalesVelocityConfig {
|
||||
id: number;
|
||||
category_id: number | null;
|
||||
vendor: string | null;
|
||||
daily_window_days: number;
|
||||
weekly_window_days: number;
|
||||
monthly_window_days: number;
|
||||
}
|
||||
|
||||
interface ABCClassificationConfig {
|
||||
id: number;
|
||||
a_threshold: number;
|
||||
b_threshold: number;
|
||||
classification_period_days: number;
|
||||
}
|
||||
|
||||
interface SafetyStockConfig {
|
||||
id: number;
|
||||
category_id: number | null;
|
||||
vendor: string | null;
|
||||
coverage_days: number;
|
||||
service_level: number;
|
||||
}
|
||||
|
||||
interface TurnoverConfig {
|
||||
id: number;
|
||||
category_id: number | null;
|
||||
vendor: string | null;
|
||||
calculation_period_days: number;
|
||||
target_rate: number;
|
||||
}
|
||||
|
||||
export function Configuration() {
|
||||
const [stockThresholds, setStockThresholds] = useState<StockThreshold>({
|
||||
id: 1,
|
||||
category_id: null,
|
||||
vendor: null,
|
||||
critical_days: 7,
|
||||
reorder_days: 14,
|
||||
overstock_days: 90,
|
||||
low_stock_threshold: 5,
|
||||
min_reorder_quantity: 1
|
||||
});
|
||||
|
||||
const [leadTimeThresholds, setLeadTimeThresholds] = useState<LeadTimeThreshold>({
|
||||
id: 1,
|
||||
category_id: null,
|
||||
vendor: null,
|
||||
target_days: 14,
|
||||
warning_days: 21,
|
||||
critical_days: 30
|
||||
});
|
||||
|
||||
const [salesVelocityConfig, setSalesVelocityConfig] = useState<SalesVelocityConfig>({
|
||||
id: 1,
|
||||
category_id: null,
|
||||
vendor: null,
|
||||
daily_window_days: 30,
|
||||
weekly_window_days: 7,
|
||||
monthly_window_days: 90
|
||||
});
|
||||
|
||||
const [abcConfig, setAbcConfig] = useState<ABCClassificationConfig>({
|
||||
id: 1,
|
||||
a_threshold: 20.0,
|
||||
b_threshold: 50.0,
|
||||
classification_period_days: 90
|
||||
});
|
||||
|
||||
const [safetyStockConfig, setSafetyStockConfig] = useState<SafetyStockConfig>({
|
||||
id: 1,
|
||||
category_id: null,
|
||||
vendor: null,
|
||||
coverage_days: 14,
|
||||
service_level: 95.0
|
||||
});
|
||||
|
||||
const [turnoverConfig, setTurnoverConfig] = useState<TurnoverConfig>({
|
||||
id: 1,
|
||||
category_id: null,
|
||||
vendor: null,
|
||||
calculation_period_days: 30,
|
||||
target_rate: 1.0
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const loadConfig = async () => {
|
||||
try {
|
||||
const response = await fetch(`${config.apiUrl}/config`, {
|
||||
credentials: 'include'
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to load configuration');
|
||||
}
|
||||
const data = await response.json();
|
||||
setStockThresholds(data.stockThresholds);
|
||||
setLeadTimeThresholds(data.leadTimeThresholds);
|
||||
setSalesVelocityConfig(data.salesVelocityConfig);
|
||||
setAbcConfig(data.abcConfig);
|
||||
setSafetyStockConfig(data.safetyStockConfig);
|
||||
setTurnoverConfig(data.turnoverConfig);
|
||||
} catch (error) {
|
||||
toast.error(`Failed to load configuration: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
};
|
||||
loadConfig();
|
||||
}, []);
|
||||
|
||||
const handleUpdateStockThresholds = async () => {
|
||||
try {
|
||||
const response = await fetch(`${config.apiUrl}/config/stock-thresholds/1`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(stockThresholds)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
throw new Error(data.error || 'Failed to update stock thresholds');
|
||||
}
|
||||
|
||||
toast.success('Stock thresholds updated successfully');
|
||||
} catch (error) {
|
||||
toast.error(`Failed to update thresholds: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateLeadTimeThresholds = async () => {
|
||||
try {
|
||||
const response = await fetch(`${config.apiUrl}/config/lead-time-thresholds/1`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(leadTimeThresholds)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
throw new Error(data.error || 'Failed to update lead time thresholds');
|
||||
}
|
||||
|
||||
toast.success('Lead time thresholds updated successfully');
|
||||
} catch (error) {
|
||||
toast.error(`Failed to update thresholds: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateSalesVelocityConfig = async () => {
|
||||
try {
|
||||
const response = await fetch(`${config.apiUrl}/config/sales-velocity/1`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(salesVelocityConfig)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
throw new Error(data.error || 'Failed to update sales velocity configuration');
|
||||
}
|
||||
|
||||
toast.success('Sales velocity configuration updated successfully');
|
||||
} catch (error) {
|
||||
toast.error(`Failed to update configuration: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateABCConfig = async () => {
|
||||
try {
|
||||
const response = await fetch(`${config.apiUrl}/config/abc-classification/1`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(abcConfig)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
throw new Error(data.error || 'Failed to update ABC classification configuration');
|
||||
}
|
||||
|
||||
toast.success('ABC classification configuration updated successfully');
|
||||
} catch (error) {
|
||||
toast.error(`Failed to update configuration: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateSafetyStockConfig = async () => {
|
||||
try {
|
||||
const response = await fetch(`${config.apiUrl}/config/safety-stock/1`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(safetyStockConfig)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
throw new Error(data.error || 'Failed to update safety stock configuration');
|
||||
}
|
||||
|
||||
toast.success('Safety stock configuration updated successfully');
|
||||
} catch (error) {
|
||||
toast.error(`Failed to update configuration: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateTurnoverConfig = async () => {
|
||||
try {
|
||||
const response = await fetch(`${config.apiUrl}/config/turnover/1`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(turnoverConfig)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
throw new Error(data.error || 'Failed to update turnover configuration');
|
||||
}
|
||||
|
||||
toast.success('Turnover configuration updated successfully');
|
||||
} catch (error) {
|
||||
toast.error(`Failed to update configuration: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Tabs defaultValue="stock" className="w-full">
|
||||
<TabsList>
|
||||
<TabsTrigger value="stock">Stock Management</TabsTrigger>
|
||||
<TabsTrigger value="performance">Performance Metrics</TabsTrigger>
|
||||
<TabsTrigger value="calculation">Calculation Settings</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="stock" className="space-y-4">
|
||||
{/* Stock Thresholds Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Stock Thresholds</CardTitle>
|
||||
<CardDescription>Configure stock level thresholds for inventory management</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="critical-days">Critical Days</Label>
|
||||
<Input
|
||||
id="critical-days"
|
||||
type="number"
|
||||
min="1"
|
||||
value={stockThresholds.critical_days}
|
||||
onChange={(e) => setStockThresholds(prev => ({
|
||||
...prev,
|
||||
critical_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="reorder-days">Reorder Days</Label>
|
||||
<Input
|
||||
id="reorder-days"
|
||||
type="number"
|
||||
min="1"
|
||||
value={stockThresholds.reorder_days}
|
||||
onChange={(e) => setStockThresholds(prev => ({
|
||||
...prev,
|
||||
reorder_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="overstock-days">Overstock Days</Label>
|
||||
<Input
|
||||
id="overstock-days"
|
||||
type="number"
|
||||
min="1"
|
||||
value={stockThresholds.overstock_days}
|
||||
onChange={(e) => setStockThresholds(prev => ({
|
||||
...prev,
|
||||
overstock_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="low-stock-threshold">Low Stock Threshold</Label>
|
||||
<Input
|
||||
id="low-stock-threshold"
|
||||
type="number"
|
||||
min="0"
|
||||
value={stockThresholds.low_stock_threshold}
|
||||
onChange={(e) => setStockThresholds(prev => ({
|
||||
...prev,
|
||||
low_stock_threshold: parseInt(e.target.value) || 0
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="min-reorder-quantity">Minimum Reorder Quantity</Label>
|
||||
<Input
|
||||
id="min-reorder-quantity"
|
||||
type="number"
|
||||
min="1"
|
||||
value={stockThresholds.min_reorder_quantity}
|
||||
onChange={(e) => setStockThresholds(prev => ({
|
||||
...prev,
|
||||
min_reorder_quantity: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Button onClick={handleUpdateStockThresholds}>
|
||||
Update Stock Thresholds
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Safety Stock Configuration Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Safety Stock</CardTitle>
|
||||
<CardDescription>Configure safety stock parameters</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="coverage-days">Coverage Days</Label>
|
||||
<Input
|
||||
id="coverage-days"
|
||||
type="number"
|
||||
min="1"
|
||||
value={safetyStockConfig.coverage_days}
|
||||
onChange={(e) => setSafetyStockConfig(prev => ({
|
||||
...prev,
|
||||
coverage_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="service-level">Service Level (%)</Label>
|
||||
<Input
|
||||
id="service-level"
|
||||
type="number"
|
||||
min="0"
|
||||
max="100"
|
||||
step="0.1"
|
||||
value={safetyStockConfig.service_level}
|
||||
onChange={(e) => setSafetyStockConfig(prev => ({
|
||||
...prev,
|
||||
service_level: parseFloat(e.target.value) || 0
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Button onClick={handleUpdateSafetyStockConfig}>
|
||||
Update Safety Stock Configuration
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="performance" className="space-y-4">
|
||||
{/* Lead Time Thresholds Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Lead Time Thresholds</CardTitle>
|
||||
<CardDescription>Configure lead time thresholds for vendor performance</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="target-days">Target Days</Label>
|
||||
<Input
|
||||
id="target-days"
|
||||
type="number"
|
||||
min="1"
|
||||
value={leadTimeThresholds.target_days}
|
||||
onChange={(e) => setLeadTimeThresholds(prev => ({
|
||||
...prev,
|
||||
target_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="warning-days">Warning Days</Label>
|
||||
<Input
|
||||
id="warning-days"
|
||||
type="number"
|
||||
min="1"
|
||||
value={leadTimeThresholds.warning_days}
|
||||
onChange={(e) => setLeadTimeThresholds(prev => ({
|
||||
...prev,
|
||||
warning_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="critical-days-lead">Critical Days</Label>
|
||||
<Input
|
||||
id="critical-days-lead"
|
||||
type="number"
|
||||
min="1"
|
||||
value={leadTimeThresholds.critical_days}
|
||||
onChange={(e) => setLeadTimeThresholds(prev => ({
|
||||
...prev,
|
||||
critical_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Button onClick={handleUpdateLeadTimeThresholds}>
|
||||
Update Lead Time Thresholds
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* ABC Classification Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>ABC Classification</CardTitle>
|
||||
<CardDescription>Configure ABC classification parameters</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="a-threshold">A Threshold (%)</Label>
|
||||
<Input
|
||||
id="a-threshold"
|
||||
type="number"
|
||||
min="0"
|
||||
max="100"
|
||||
step="0.1"
|
||||
value={abcConfig.a_threshold}
|
||||
onChange={(e) => setAbcConfig(prev => ({
|
||||
...prev,
|
||||
a_threshold: parseFloat(e.target.value) || 0
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="b-threshold">B Threshold (%)</Label>
|
||||
<Input
|
||||
id="b-threshold"
|
||||
type="number"
|
||||
min="0"
|
||||
max="100"
|
||||
step="0.1"
|
||||
value={abcConfig.b_threshold}
|
||||
onChange={(e) => setAbcConfig(prev => ({
|
||||
...prev,
|
||||
b_threshold: parseFloat(e.target.value) || 0
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="classification-period">Classification Period (days)</Label>
|
||||
<Input
|
||||
id="classification-period"
|
||||
type="number"
|
||||
min="1"
|
||||
value={abcConfig.classification_period_days}
|
||||
onChange={(e) => setAbcConfig(prev => ({
|
||||
...prev,
|
||||
classification_period_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Button onClick={handleUpdateABCConfig}>
|
||||
Update ABC Classification
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Turnover Configuration Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Turnover Rate</CardTitle>
|
||||
<CardDescription>Configure turnover rate calculations</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="calculation-period">Calculation Period (days)</Label>
|
||||
<Input
|
||||
id="calculation-period"
|
||||
type="number"
|
||||
min="1"
|
||||
value={turnoverConfig.calculation_period_days}
|
||||
onChange={(e) => setTurnoverConfig(prev => ({
|
||||
...prev,
|
||||
calculation_period_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="target-rate">Target Rate</Label>
|
||||
<Input
|
||||
id="target-rate"
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.1"
|
||||
value={turnoverConfig.target_rate}
|
||||
onChange={(e) => setTurnoverConfig(prev => ({
|
||||
...prev,
|
||||
target_rate: parseFloat(e.target.value) || 0
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Button onClick={handleUpdateTurnoverConfig}>
|
||||
Update Turnover Configuration
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="calculation" className="space-y-4">
|
||||
{/* Sales Velocity Configuration Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Sales Velocity Windows</CardTitle>
|
||||
<CardDescription>Configure time windows for sales velocity calculations</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="daily-window">Daily Window (days)</Label>
|
||||
<Input
|
||||
id="daily-window"
|
||||
type="number"
|
||||
min="1"
|
||||
value={salesVelocityConfig.daily_window_days}
|
||||
onChange={(e) => setSalesVelocityConfig(prev => ({
|
||||
...prev,
|
||||
daily_window_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="weekly-window">Weekly Window (days)</Label>
|
||||
<Input
|
||||
id="weekly-window"
|
||||
type="number"
|
||||
min="1"
|
||||
value={salesVelocityConfig.weekly_window_days}
|
||||
onChange={(e) => setSalesVelocityConfig(prev => ({
|
||||
...prev,
|
||||
weekly_window_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="monthly-window">Monthly Window (days)</Label>
|
||||
<Input
|
||||
id="monthly-window"
|
||||
type="number"
|
||||
min="1"
|
||||
value={salesVelocityConfig.monthly_window_days}
|
||||
onChange={(e) => setSalesVelocityConfig(prev => ({
|
||||
...prev,
|
||||
monthly_window_days: parseInt(e.target.value) || 1
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Button onClick={handleUpdateSalesVelocityConfig}>
|
||||
Update Sales Velocity Windows
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
@@ -142,7 +142,7 @@ export function PerformanceMetrics() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="max-w-[700px] space-y-4">
|
||||
{/* Lead Time Thresholds Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
|
||||
@@ -109,7 +109,7 @@ export function StockManagement() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="max-w-[700px] space-y-4">
|
||||
{/* Stock Thresholds Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
|
||||
@@ -9,15 +9,18 @@ export function Settings() {
|
||||
<div className="container mx-auto py-6">
|
||||
<div className="mb-6">
|
||||
<h1 className="text-3xl font-bold">Settings</h1>
|
||||
<p className="text-muted-foreground">Manage your inventory system settings and configurations</p>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="data-management" className="space-y-4">
|
||||
<TabsList>
|
||||
<TabsTrigger value="data-management">Data Management</TabsTrigger>
|
||||
<TabsTrigger value="stock-management">Stock Management</TabsTrigger>
|
||||
<TabsTrigger value="performance-metrics">Performance Metrics</TabsTrigger>
|
||||
<TabsTrigger value="calculation-settings">Calculation Settings</TabsTrigger>
|
||||
<TabsTrigger value="performance-metrics">
|
||||
Performance Metrics
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="calculation-settings">
|
||||
Calculation Settings
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="data-management">
|
||||
|
||||
Reference in New Issue
Block a user