diff --git a/inventory/package-lock.json b/inventory/package-lock.json
index 6a2303f..546df48 100644
--- a/inventory/package-lock.json
+++ b/inventory/package-lock.json
@@ -36,6 +36,7 @@
"cmdk": "^1.0.0",
"date-fns": "^3.6.0",
"lucide-react": "^0.469.0",
+ "motion": "^11.18.0",
"next-themes": "^0.4.4",
"react": "^18.3.1",
"react-chartjs-2": "^5.3.0",
@@ -4606,6 +4607,33 @@
"url": "https://github.com/sponsors/rawify"
}
},
+ "node_modules/framer-motion": {
+ "version": "11.18.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.0.tgz",
+ "integrity": "sha512-Vmjl5Al7XqKHzDFnVqzi1H9hzn5w4eN/bdqXTymVpU2UuMQuz9w6UPdsL9dFBeH7loBlnu4qcEXME+nvbkcIOw==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^11.16.4",
+ "motion-utils": "^11.16.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/fs-extra": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
@@ -5270,6 +5298,47 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/motion": {
+ "version": "11.18.0",
+ "resolved": "https://registry.npmjs.org/motion/-/motion-11.18.0.tgz",
+ "integrity": "sha512-uJ4zNXh/4K9C5wftxHKlXLHC0Rc9dHSHPyO1P6T9XE2bTn2z8C2lOZX/M8vAmFp0gtJTJ3aYkv44lTtJSfv6+A==",
+ "license": "MIT",
+ "dependencies": {
+ "framer-motion": "^11.18.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "11.16.4",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.16.4.tgz",
+ "integrity": "sha512-2wuCie206pCiP2K23uvwJeci4pMFfyQKpWI0Vy6HrCTDzDCer4TsYtT7IVnuGbDeoIV37UuZiUr6SZMHEc1Vww==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^11.16.0"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "11.16.0",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.16.0.tgz",
+ "integrity": "sha512-ngdWPjg31rD4WGXFi0eZ00DQQqKKu04QExyv/ymlC+3k+WIgYVFbt6gS5JsFPbJODTF/r8XiE/X+SsoT9c0ocw==",
+ "license": "MIT"
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
diff --git a/inventory/package.json b/inventory/package.json
index d8eb2cd..51a702e 100644
--- a/inventory/package.json
+++ b/inventory/package.json
@@ -38,6 +38,7 @@
"cmdk": "^1.0.0",
"date-fns": "^3.6.0",
"lucide-react": "^0.469.0",
+ "motion": "^11.18.0",
"next-themes": "^0.4.4",
"react": "^18.3.1",
"react-chartjs-2": "^5.3.0",
diff --git a/inventory/src/App.tsx b/inventory/src/App.tsx
index bae9526..6d9189b 100644
--- a/inventory/src/App.tsx
+++ b/inventory/src/App.tsx
@@ -2,7 +2,6 @@ import { Routes, Route, useNavigate, Navigate } from 'react-router-dom';
import { MainLayout } from './components/layout/MainLayout';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Products } from './pages/Products';
-import { Import } from './pages/Import';
import { Dashboard } from './pages/Dashboard';
import { Orders } from './pages/Orders';
import { Settings } from './pages/Settings';
@@ -55,7 +54,6 @@ function App() {
}>
} />
} />
- } />
} />
} />
} />
diff --git a/inventory/src/components/layout/MainLayout.tsx b/inventory/src/components/layout/MainLayout.tsx
index be1f815..71fdaa7 100644
--- a/inventory/src/components/layout/MainLayout.tsx
+++ b/inventory/src/components/layout/MainLayout.tsx
@@ -1,21 +1,24 @@
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
import { AppSidebar } from "./AppSidebar";
import { Outlet } from "react-router-dom";
+import { motion } from "motion/react";
export function MainLayout() {
return (
-
-
-
+
+
+
+
+
);
-}
\ No newline at end of file
+}
diff --git a/inventory/src/pages/Analytics.tsx b/inventory/src/pages/Analytics.tsx
index 13baf16..bb21e04 100644
--- a/inventory/src/pages/Analytics.tsx
+++ b/inventory/src/pages/Analytics.tsx
@@ -7,6 +7,7 @@ import { StockAnalysis } from '../components/analytics/StockAnalysis';
import { PriceAnalysis } from '../components/analytics/PriceAnalysis';
import { CategoryPerformance } from '../components/analytics/CategoryPerformance';
import config from '../config';
+import { motion } from 'motion/react';
interface AnalyticsStats {
profitMargin: number;
@@ -34,7 +35,7 @@ export function Analytics() {
}
return (
-
+
Analytics
@@ -107,6 +108,6 @@ export function Analytics() {
-
+
);
}
\ No newline at end of file
diff --git a/inventory/src/pages/Dashboard.tsx b/inventory/src/pages/Dashboard.tsx
index d1d5ee7..c69a6d9 100644
--- a/inventory/src/pages/Dashboard.tsx
+++ b/inventory/src/pages/Dashboard.tsx
@@ -4,10 +4,10 @@ import { LowStockAlerts } from "@/components/dashboard/LowStockAlerts"
import { TrendingProducts } from "@/components/dashboard/TrendingProducts"
import { VendorPerformance } from "@/components/dashboard/VendorPerformance"
import { KeyMetricsCharts } from "@/components/dashboard/KeyMetricsCharts"
-
+import { motion } from "motion/react"
export function Dashboard() {
return (
-
+
Dashboard
@@ -30,7 +30,7 @@ export function Dashboard() {
-
+
)
}
diff --git a/inventory/src/pages/Import.tsx b/inventory/src/pages/Import.tsx
deleted file mode 100644
index 9200177..0000000
--- a/inventory/src/pages/Import.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import { useState } from 'react';
-import { useMutation } from '@tanstack/react-query';
-import config from '../config';
-
-export function Import() {
- const [file, setFile] = useState(null);
-
- const importMutation = useMutation({
- mutationFn: async (formData: FormData) => {
- const response = await fetch(`${config.apiUrl}/products/import`, {
- method: 'POST',
- body: formData,
- });
- if (!response.ok) {
- throw new Error('Import failed');
- }
- return response.json();
- },
- });
-
- const handleFileChange = (e: React.ChangeEvent) => {
- if (e.target.files?.[0]) {
- setFile(e.target.files[0]);
- }
- };
-
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault();
- if (!file) return;
-
- const formData = new FormData();
- formData.append('file', file);
- importMutation.mutate(formData);
- };
-
- return (
-
- );
-}
\ No newline at end of file
diff --git a/inventory/src/pages/Login.tsx b/inventory/src/pages/Login.tsx
index 8cb56ff..74f18ff 100644
--- a/inventory/src/pages/Login.tsx
+++ b/inventory/src/pages/Login.tsx
@@ -1,22 +1,18 @@
-import { useState } from 'react';
-import { useNavigate } from 'react-router-dom';
-import { Button } from '@/components/ui/button';
-import {
- Card,
- CardContent,
- CardHeader,
- CardTitle,
-} from '@/components/ui/card';
-import { Input } from '@/components/ui/input';
-import { toast } from 'sonner';
-import config from '../config';
-import { Loader2, Box } from 'lucide-react';
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { Button } from "@/components/ui/button";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { Input } from "@/components/ui/input";
+import { toast } from "sonner";
+import config from "../config";
+import { Loader2, Box } from "lucide-react";
+import { motion } from "motion/react";
-const isDev = process.env.NODE_ENV === 'development';
+const isDev = process.env.NODE_ENV === "development";
export function Login() {
- const [username, setUsername] = useState('');
- const [password, setPassword] = useState('');
+ const [username, setUsername] = useState("");
+ const [password, setPassword] = useState("");
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
@@ -26,46 +22,46 @@ export function Login() {
try {
const url = isDev ? "/auth-inv/login" : `${config.authUrl}/login`;
- console.log('Making login request:', {
+ console.log("Making login request:", {
url,
- method: 'POST',
+ method: "POST",
headers: {
- 'Content-Type': 'application/json',
+ "Content-Type": "application/json",
},
body: { username, password },
- config
+ config,
});
const response = await fetch(url, {
- method: 'POST',
+ method: "POST",
headers: {
- 'Content-Type': 'application/json',
+ "Content-Type": "application/json",
},
body: JSON.stringify({ username, password }),
- credentials: 'include'
+ credentials: "include",
});
- console.log('Login response status:', response.status);
-
+ console.log("Login response status:", response.status);
+
if (!response.ok) {
- const data = await response.json().catch(() => ({ error: 'Failed to parse error response' }));
- console.error('Login failed:', data);
- throw new Error(data.error || 'Login failed');
+ const data = await response
+ .json()
+ .catch(() => ({ error: "Failed to parse error response" }));
+ console.error("Login failed:", data);
+ throw new Error(data.error || "Login failed");
}
const data = await response.json();
- console.log('Login successful:', data);
-
- sessionStorage.setItem('token', data.token);
- sessionStorage.setItem('isLoggedIn', 'true');
- toast.success('Successfully logged in');
- navigate('/');
+ console.log("Login successful:", data);
+
+ sessionStorage.setItem("token", data.token);
+ sessionStorage.setItem("isLoggedIn", "true");
+ toast.success("Successfully logged in");
+ navigate("/", { replace: true });
} catch (error) {
- console.error('Login error:', error);
+ console.error("Login error:", error);
toast.error(
- error instanceof Error
- ? error.message
- : 'An unexpected error occurred',
+ error instanceof Error ? error.message : "An unexpected error occurred"
);
} finally {
setIsLoading(false);
@@ -73,23 +69,33 @@ export function Login() {
};
return (
-
-
-
+
+
-
+
- Log in to continue
+
+ Log in to continue
+
-
-
+
+
);
-}
\ No newline at end of file
+}
diff --git a/inventory/src/pages/Orders.tsx b/inventory/src/pages/Orders.tsx
index f48efa6..9bc13f7 100644
--- a/inventory/src/pages/Orders.tsx
+++ b/inventory/src/pages/Orders.tsx
@@ -33,7 +33,7 @@ import { ArrowUpDown, Search } from "lucide-react";
import debounce from 'lodash/debounce';
import config from '../config';
import { DateRange } from 'react-day-picker';
-
+import { motion } from 'motion/react';
interface Order {
order_number: string;
customer: string;
@@ -130,7 +130,7 @@ export function Orders() {
);
return (
-
+
Orders
@@ -317,6 +317,6 @@ export function Orders() {
)}
-
+
);
}
\ No newline at end of file
diff --git a/inventory/src/pages/Products.tsx b/inventory/src/pages/Products.tsx
index 8bf9159..61ef3fe 100644
--- a/inventory/src/pages/Products.tsx
+++ b/inventory/src/pages/Products.tsx
@@ -23,7 +23,7 @@ import {
import { Button } from "@/components/ui/button";
import { Settings2 } from "lucide-react";
import config from '../config';
-
+import { motion } from 'motion/react';
// Enhanced Product interface with all possible fields
interface Product {
// Basic product info (from products table)
@@ -309,10 +309,11 @@ export function Products() {
);
return (
-
-
-
-
+
+
+ handlePageChange(Math.max(1, page - 1))}
@@ -371,11 +372,12 @@ export function Products() {
+
);
};
return (
-
+
Products
@@ -451,6 +453,6 @@ export function Products() {
productId={selectedProductId}
onClose={() => setSelectedProductId(null)}
/>
-
+
);
}
\ No newline at end of file
diff --git a/inventory/src/pages/PurchaseOrders.tsx b/inventory/src/pages/PurchaseOrders.tsx
index 9c69c24..cb42db4 100644
--- a/inventory/src/pages/PurchaseOrders.tsx
+++ b/inventory/src/pages/PurchaseOrders.tsx
@@ -19,6 +19,7 @@ import {
PaginationNext,
PaginationPrevious,
} from '../components/ui/pagination';
+import { motion } from 'motion/react';
interface PurchaseOrder {
id: number;
@@ -205,7 +206,7 @@ export default function PurchaseOrders() {
}
return (
-
+
Purchase Orders
{/* Metrics Overview */}
@@ -453,6 +454,6 @@ export default function PurchaseOrders() {
-
+
);
}
\ No newline at end of file
diff --git a/inventory/src/pages/Settings.tsx b/inventory/src/pages/Settings.tsx
index 8e2124e..cfc7a58 100644
--- a/inventory/src/pages/Settings.tsx
+++ b/inventory/src/pages/Settings.tsx
@@ -3,10 +3,11 @@ import { DataManagement } from "@/components/settings/DataManagement";
import { StockManagement } from "@/components/settings/StockManagement";
import { PerformanceMetrics } from "@/components/settings/PerformanceMetrics";
import { CalculationSettings } from "@/components/settings/CalculationSettings";
+import { motion } from 'motion/react';
export function Settings() {
return (
-
+
Settings
@@ -39,6 +40,6 @@ export function Settings() {
-
+
);
}