diff --git a/inventory/src/components/ui/alert.tsx b/inventory/src/components/ui/alert.tsx new file mode 100644 index 0000000..5afd41d --- /dev/null +++ b/inventory/src/components/ui/alert.tsx @@ -0,0 +1,59 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const alertVariants = cva( + "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7", + { + variants: { + variant: { + default: "bg-background text-foreground", + destructive: + "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +const Alert = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
+)) +Alert.displayName = "Alert" + +const AlertTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertTitle.displayName = "AlertTitle" + +const AlertDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertDescription.displayName = "AlertDescription" + +export { Alert, AlertTitle, AlertDescription } diff --git a/inventory/src/pages/Settings.tsx b/inventory/src/pages/Settings.tsx index 5410901..24f83d6 100644 --- a/inventory/src/pages/Settings.tsx +++ b/inventory/src/pages/Settings.tsx @@ -4,7 +4,9 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com import { Progress } from "@/components/ui/progress"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; +import { Alert, AlertDescription } from "@/components/ui/alert"; import { Loader2, RefreshCw, Upload, X } from "lucide-react"; +import { Separator } from "@/components/ui/separator"; import config from '../config'; interface ImportProgress { @@ -350,9 +352,11 @@ export function Settings() { )} {progress.error && ( -
- Error: {progress.error} -
+ + + {progress.error} + + )}
); @@ -364,114 +368,136 @@ export function Settings() {

Settings

-
+
+ {/* Update CSV Card */} - Data Management - Update and import CSV data files + Update CSV Files + Download the latest CSV data files - -
-
-
- - setLimits(prev => ({ ...prev, products: parseInt(e.target.value) || 0 }))} - disabled={isUpdating || isImporting} - /> -
- -
- - setLimits(prev => ({ ...prev, orders: parseInt(e.target.value) || 0 }))} - disabled={isUpdating || isImporting} - /> -
- -
- - setLimits(prev => ({ ...prev, purchaseOrders: parseInt(e.target.value) || 0 }))} - disabled={isUpdating || isImporting} - /> -
-
- -
- - - {isUpdating && ( - + +
+
+ -
- - - {isImporting && ( - - )} -
- - {(isUpdating || isImporting || progress) && renderProgress()} + )}
+ + {isUpdating && renderProgress()} + + {/* Import Data Card */} + + + Import Data + Import current CSV files into database. Set limits to 0 to import all records. + + +
+
+ + setLimits(prev => ({ ...prev, products: parseInt(e.target.value) || 0 }))} + disabled={isUpdating || isImporting} + className="[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" + placeholder="0 for no limit" + /> +
+
+ + setLimits(prev => ({ ...prev, orders: parseInt(e.target.value) || 0 }))} + disabled={isUpdating || isImporting} + className="[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" + placeholder="0 for no limit" + /> +
+
+ + setLimits(prev => ({ ...prev, purchaseOrders: parseInt(e.target.value) || 0 }))} + disabled={isUpdating || isImporting} + className="[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" + placeholder="0 for no limit" + /> +
+
+ +
+ + + {isImporting && ( + + )} +
+ + {isImporting && renderProgress()} + + + {/* Show progress outside cards if neither operation is running but we have progress state */} + {!isUpdating && !isImporting && progress && ( + <> + {renderProgress()} + + )} +
+
);