Moved to lazy loading modules and configured build chunking
modified: package-lock.json modified: package.json modified: src/App.tsx modified: src/screens/ActivePickListScreen.test.tsx modified: src/screens/ActivePickListScreen.tsx modified: src/screens/BarcodeScannerScreen.tsx modified: src/screens/HomeScreen.tsx modified: src/screens/ImportExportScreen.tsx modified: src/screens/ManageAreasScreen.test.tsx modified: src/screens/ManageAreasScreen.tsx modified: src/screens/ManageCategoriesScreen.test.tsx modified: src/screens/ManageCategoriesScreen.tsx modified: src/screens/ManageProductsScreen.test.tsx modified: src/screens/ManageProductsScreen.tsx modified: src/screens/PickListsScreen.test.tsx modified: src/screens/PickListsScreen.tsx modified: src/screens/StartPickListScreen.test.tsx modified: src/screens/StartPickListScreen.tsx modified: tsconfig.json modified: vite.config.ts
This commit is contained in:
Generated
+112
@@ -42,6 +42,7 @@
|
|||||||
"eslint-plugin-react-refresh": "^0.4.24",
|
"eslint-plugin-react-refresh": "^0.4.24",
|
||||||
"jsdom": "^27.2.0",
|
"jsdom": "^27.2.0",
|
||||||
"msw": "^2.12.3",
|
"msw": "^2.12.3",
|
||||||
|
"rollup-plugin-visualizer": "^6.0.5",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.47.0",
|
"typescript-eslint": "^8.47.0",
|
||||||
"vite": "^7.2.4",
|
"vite": "^7.2.4",
|
||||||
@@ -3425,6 +3426,16 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/define-lazy-prop": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dequal": {
|
"node_modules/dequal": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||||
@@ -4256,6 +4267,22 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-docker": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"is-docker": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-extglob": {
|
"node_modules/is-extglob": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
@@ -4313,6 +4340,19 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/is-wsl": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-docker": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/isarray": {
|
"node_modules/isarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
@@ -4806,6 +4846,24 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/open": {
|
||||||
|
"version": "8.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
|
||||||
|
"integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"define-lazy-prop": "^2.0.0",
|
||||||
|
"is-docker": "^2.1.1",
|
||||||
|
"is-wsl": "^2.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/optionator": {
|
"node_modules/optionator": {
|
||||||
"version": "0.9.4",
|
"version": "0.9.4",
|
||||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||||
@@ -5393,6 +5451,60 @@
|
|||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rollup-plugin-visualizer": {
|
||||||
|
"version": "6.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-6.0.5.tgz",
|
||||||
|
"integrity": "sha512-9+HlNgKCVbJDs8tVtjQ43US12eqaiHyyiLMdBwQ7vSZPiHMysGNo2E88TAp1si5wx8NAoYriI2A5kuKfIakmJg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"open": "^8.0.0",
|
||||||
|
"picomatch": "^4.0.2",
|
||||||
|
"source-map": "^0.7.4",
|
||||||
|
"yargs": "^17.5.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"rollup-plugin-visualizer": "dist/bin/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rolldown": "1.x || ^1.0.0-beta",
|
||||||
|
"rollup": "2.x || 3.x || 4.x"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"rolldown": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"rollup": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/rollup-plugin-visualizer/node_modules/picomatch": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/rollup-plugin-visualizer/node_modules/source-map": {
|
||||||
|
"version": "0.7.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
|
||||||
|
"integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/run-parallel": {
|
"node_modules/run-parallel": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
"eslint-plugin-react-refresh": "^0.4.24",
|
"eslint-plugin-react-refresh": "^0.4.24",
|
||||||
"jsdom": "^27.2.0",
|
"jsdom": "^27.2.0",
|
||||||
"msw": "^2.12.3",
|
"msw": "^2.12.3",
|
||||||
|
"rollup-plugin-visualizer": "^6.0.5",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.47.0",
|
"typescript-eslint": "^8.47.0",
|
||||||
"vite": "^7.2.4",
|
"vite": "^7.2.4",
|
||||||
|
|||||||
+26
-22
@@ -2,16 +2,18 @@ import { CssBaseline, ThemeProvider, createTheme } from '@mui/material';
|
|||||||
import { BrowserRouter, Route, Routes } from 'react-router-dom';
|
import { BrowserRouter, Route, Routes } from 'react-router-dom';
|
||||||
import { DBProvider } from './context/DBProvider';
|
import { DBProvider } from './context/DBProvider';
|
||||||
import { AppLayout } from './components/AppLayout';
|
import { AppLayout } from './components/AppLayout';
|
||||||
import { HomeScreen } from './screens/HomeScreen';
|
import React, { Suspense, lazy } from 'react';
|
||||||
import { StartPickListScreen } from './screens/StartPickListScreen';
|
|
||||||
import { PickListsScreen } from './screens/PickListsScreen';
|
|
||||||
import { ActivePickListScreen } from './screens/ActivePickListScreen';
|
|
||||||
import { ManageProductsScreen } from './screens/ManageProductsScreen';
|
|
||||||
import { ManageAreasScreen } from './screens/ManageAreasScreen';
|
|
||||||
import { ManageCategoriesScreen } from './screens/ManageCategoriesScreen';
|
|
||||||
import { BarcodeScannerScreen } from './screens/BarcodeScannerScreen';
|
|
||||||
import { useServiceWorker } from './hooks/useServiceWorker';
|
import { useServiceWorker } from './hooks/useServiceWorker';
|
||||||
import { ImportExportScreen } from './screens/ImportExportScreen';
|
|
||||||
|
const HomeScreen = lazy(() => import('./screens/HomeScreen'));
|
||||||
|
const StartPickListScreen = lazy(() => import('./screens/StartPickListScreen'));
|
||||||
|
const PickListsScreen = lazy(() => import('./screens/PickListsScreen'));
|
||||||
|
const ActivePickListScreen = lazy(() => import('./screens/ActivePickListScreen'));
|
||||||
|
const ManageProductsScreen = lazy(() => import('./screens/ManageProductsScreen'));
|
||||||
|
const ManageAreasScreen = lazy(() => import('./screens/ManageAreasScreen'));
|
||||||
|
const ManageCategoriesScreen = lazy(() => import('./screens/ManageCategoriesScreen'));
|
||||||
|
const BarcodeScannerScreen = lazy(() => import('./screens/BarcodeScannerScreen'));
|
||||||
|
const ImportExportScreen = lazy(() => import('./screens/ImportExportScreen'));
|
||||||
|
|
||||||
const theme = createTheme({
|
const theme = createTheme({
|
||||||
palette: {
|
palette: {
|
||||||
@@ -25,19 +27,21 @@ const theme = createTheme({
|
|||||||
const AppRoutes = () => {
|
const AppRoutes = () => {
|
||||||
useServiceWorker();
|
useServiceWorker();
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<Suspense fallback={<div>Loading…</div>}>
|
||||||
<Route element={<AppLayout />}>
|
<Routes>
|
||||||
<Route path="/" element={<HomeScreen />} />
|
<Route element={<AppLayout />}>
|
||||||
<Route path="/start" element={<StartPickListScreen />} />
|
<Route path="/" element={<HomeScreen />} />
|
||||||
<Route path="/pick-lists" element={<PickListsScreen />} />
|
<Route path="/start" element={<StartPickListScreen />} />
|
||||||
<Route path="/pick-lists/:id" element={<ActivePickListScreen />} />
|
<Route path="/pick-lists" element={<PickListsScreen />} />
|
||||||
<Route path="/products" element={<ManageProductsScreen />} />
|
<Route path="/pick-lists/:id" element={<ActivePickListScreen />} />
|
||||||
<Route path="/categories" element={<ManageCategoriesScreen />} />
|
<Route path="/products" element={<ManageProductsScreen />} />
|
||||||
<Route path="/areas" element={<ManageAreasScreen />} />
|
<Route path="/categories" element={<ManageCategoriesScreen />} />
|
||||||
<Route path="/scan" element={<BarcodeScannerScreen />} />
|
<Route path="/areas" element={<ManageAreasScreen />} />
|
||||||
<Route path="/data" element={<ImportExportScreen />} />
|
<Route path="/scan" element={<BarcodeScannerScreen />} />
|
||||||
</Route>
|
<Route path="/data" element={<ImportExportScreen />} />
|
||||||
</Routes>
|
</Route>
|
||||||
|
</Routes>
|
||||||
|
</Suspense>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
|||||||
import { render, screen, within } from '@testing-library/react';
|
import { render, screen, within } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { describe, expect, it, vi, beforeEach } from 'vitest';
|
import { describe, expect, it, vi, beforeEach } from 'vitest';
|
||||||
import { ActivePickListScreen } from './ActivePickListScreen';
|
import ActivePickListScreen from './ActivePickListScreen';
|
||||||
import { PickItem } from '../models/PickItem';
|
import { PickItem } from '../models/PickItem';
|
||||||
import { Product } from '../models/Product';
|
import { Product } from '../models/Product';
|
||||||
|
|
||||||
|
//const ActivePickListScreen = lazy(() => import('./screens/ActivePickListScreen'));
|
||||||
const addMock = vi.fn();
|
const addMock = vi.fn();
|
||||||
const updateMock = vi.fn();
|
const updateMock = vi.fn();
|
||||||
const pickItemsMock = vi.fn<() => PickItem[]>();
|
const pickItemsMock = vi.fn<() => PickItem[]>();
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import { ProductAutocomplete } from '../components/ProductAutocomplete';
|
|||||||
|
|
||||||
const normalizeName = (name: string) => name.trim().toLowerCase();
|
const normalizeName = (name: string) => name.trim().toLowerCase();
|
||||||
|
|
||||||
export const ActivePickListScreen = () => {
|
const ActivePickListScreen = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const pickList = usePickList(id);
|
const pickList = usePickList(id);
|
||||||
const items = usePickItems(id);
|
const items = usePickItems(id);
|
||||||
@@ -558,3 +558,5 @@ export const ActivePickListScreen = () => {
|
|||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default ActivePickListScreen
|
||||||
@@ -26,7 +26,7 @@ interface ProductLookup {
|
|||||||
pickLists: { list: PickList; area?: Area }[];
|
pickLists: { list: PickList; area?: Area }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BarcodeScannerScreen = () => {
|
const BarcodeScannerScreen = () => {
|
||||||
const db = useDatabase();
|
const db = useDatabase();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [lastCode, setLastCode] = useState('');
|
const [lastCode, setLastCode] = useState('');
|
||||||
@@ -193,3 +193,5 @@ export const BarcodeScannerScreen = () => {
|
|||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default BarcodeScannerScreen
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Button, Container, Stack, Typography } from '@mui/material';
|
import { Button, Container, Stack, Typography } from '@mui/material';
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
import { Link as RouterLink } from 'react-router-dom';
|
||||||
|
|
||||||
export const HomeScreen = () => (
|
const HomeScreen = () => (
|
||||||
<Container sx={{ py: 4 }}>
|
<Container sx={{ py: 4 }}>
|
||||||
<Typography variant="h4" gutterBottom>
|
<Typography variant="h4" gutterBottom>
|
||||||
StockFill
|
StockFill
|
||||||
@@ -28,3 +28,5 @@ export const HomeScreen = () => (
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export default HomeScreen;
|
||||||
@@ -19,7 +19,7 @@ import { ImportExportLog } from '../models/ImportExportLog';
|
|||||||
|
|
||||||
const templateFiles: { label: string; file: string }[] = [{ label: 'Products', file: 'products_template.csv' }];
|
const templateFiles: { label: string; file: string }[] = [{ label: 'Products', file: 'products_template.csv' }];
|
||||||
|
|
||||||
export const ImportExportScreen = () => {
|
const ImportExportScreen = () => {
|
||||||
const db = useDatabase();
|
const db = useDatabase();
|
||||||
const [logLines, setLogLines] = useState<string[]>([]);
|
const [logLines, setLogLines] = useState<string[]>([]);
|
||||||
const [history, setHistory] = useState<ImportExportLog[]>([]);
|
const [history, setHistory] = useState<ImportExportLog[]>([]);
|
||||||
@@ -176,3 +176,5 @@ export const ImportExportScreen = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default ImportExportScreen
|
||||||
@@ -2,7 +2,7 @@ import { MemoryRouter } from 'react-router-dom';
|
|||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { describe, expect, it, vi } from 'vitest';
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
import { ManageAreasScreen } from './ManageAreasScreen';
|
import ManageAreasScreen from './ManageAreasScreen';
|
||||||
|
|
||||||
const areasMock = [{ id: 'area-1', name: 'Front Counter', created_at: 0, updated_at: 0 }];
|
const areasMock = [{ id: 'area-1', name: 'Front Counter', created_at: 0, updated_at: 0 }];
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import { useAreas } from '../hooks/dataHooks';
|
import { useAreas } from '../hooks/dataHooks';
|
||||||
import { useDatabase } from '../context/DBProvider';
|
import { useDatabase } from '../context/DBProvider';
|
||||||
|
|
||||||
export const ManageAreasScreen = () => {
|
const ManageAreasScreen = () => {
|
||||||
const db = useDatabase();
|
const db = useDatabase();
|
||||||
const areas = useAreas();
|
const areas = useAreas();
|
||||||
const [name, setName] = useState('');
|
const [name, setName] = useState('');
|
||||||
@@ -128,3 +128,5 @@ export const ManageAreasScreen = () => {
|
|||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default ManageAreasScreen
|
||||||
@@ -2,7 +2,7 @@ import { MemoryRouter } from 'react-router-dom';
|
|||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import { ManageCategoriesScreen } from './ManageCategoriesScreen';
|
import ManageCategoriesScreen from './ManageCategoriesScreen';
|
||||||
|
|
||||||
const categoriesMock = [{ id: 'cat-1', name: 'Snacks', created_at: 0, updated_at: 0 }];
|
const categoriesMock = [{ id: 'cat-1', name: 'Snacks', created_at: 0, updated_at: 0 }];
|
||||||
const productsMock = [
|
const productsMock = [
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import { useDatabase } from '../context/DBProvider';
|
import { useDatabase } from '../context/DBProvider';
|
||||||
import { useCategories, useProducts } from '../hooks/dataHooks';
|
import { useCategories, useProducts } from '../hooks/dataHooks';
|
||||||
|
|
||||||
export const ManageCategoriesScreen = () => {
|
const ManageCategoriesScreen = () => {
|
||||||
const db = useDatabase();
|
const db = useDatabase();
|
||||||
const categories = useCategories();
|
const categories = useCategories();
|
||||||
const products = useProducts();
|
const products = useProducts();
|
||||||
@@ -198,3 +198,5 @@ const deleteCategory = async (categoryId: string, categoryName: string) => {
|
|||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default ManageCategoriesScreen
|
||||||
@@ -4,7 +4,7 @@ import { MemoryRouter } from 'react-router-dom';
|
|||||||
import { fireEvent, render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
|
import { fireEvent, render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import { ManageProductsScreen } from './ManageProductsScreen';
|
import ManageProductsScreen from './ManageProductsScreen';
|
||||||
|
|
||||||
let mockScannedBarcode = '123456';
|
let mockScannedBarcode = '123456';
|
||||||
const mockUseProducts = vi.fn();
|
const mockUseProducts = vi.fn();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { BarcodeScannerView } from '../components/BarcodeScannerView';
|
|||||||
import { ExternalProductInfo, fetchProductFromOFF } from '../modules/openFoodFacts';
|
import { ExternalProductInfo, fetchProductFromOFF } from '../modules/openFoodFacts';
|
||||||
import { DEFAULT_BULK_NAME, DEFAULT_UNIT_TYPE, Product } from '../models/Product';
|
import { DEFAULT_BULK_NAME, DEFAULT_UNIT_TYPE, Product } from '../models/Product';
|
||||||
|
|
||||||
export const ManageProductsScreen = () => {
|
const ManageProductsScreen = () => {
|
||||||
const db = useDatabase();
|
const db = useDatabase();
|
||||||
const products = useProducts();
|
const products = useProducts();
|
||||||
const categories = useCategories();
|
const categories = useCategories();
|
||||||
@@ -505,3 +505,5 @@ export const ManageProductsScreen = () => {
|
|||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default ManageProductsScreen
|
||||||
@@ -2,7 +2,7 @@ import { MemoryRouter } from 'react-router-dom';
|
|||||||
import { render, screen, within } from '@testing-library/react';
|
import { render, screen, within } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import { PickListsScreen } from './PickListsScreen';
|
import PickListsScreen from './PickListsScreen';
|
||||||
|
|
||||||
let areasMock = [
|
let areasMock = [
|
||||||
{ id: 'area-1', name: 'Front Counter', created_at: 0, updated_at: 0 },
|
{ id: 'area-1', name: 'Front Counter', created_at: 0, updated_at: 0 },
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { usePickLists, useAreas } from '../hooks/dataHooks';
|
|||||||
import { useDatabase } from '../context/DBProvider';
|
import { useDatabase } from '../context/DBProvider';
|
||||||
import { PickList } from '../models/PickList';
|
import { PickList } from '../models/PickList';
|
||||||
|
|
||||||
export const PickListsScreen = () => {
|
const PickListsScreen = () => {
|
||||||
const lists = usePickLists();
|
const lists = usePickLists();
|
||||||
const areas = useAreas();
|
const areas = useAreas();
|
||||||
const db = useDatabase();
|
const db = useDatabase();
|
||||||
@@ -176,3 +176,5 @@ export const PickListsScreen = () => {
|
|||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default PickListsScreen
|
||||||
@@ -2,7 +2,7 @@ import { MemoryRouter } from 'react-router-dom';
|
|||||||
import { render, screen, waitFor } from '@testing-library/react';
|
import { render, screen, waitFor } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import { StartPickListScreen } from './StartPickListScreen';
|
import StartPickListScreen from './StartPickListScreen';
|
||||||
|
|
||||||
const navigateMock = vi.fn();
|
const navigateMock = vi.fn();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import { useAreas, useCategories } from '../hooks/dataHooks';
|
import { useAreas, useCategories } from '../hooks/dataHooks';
|
||||||
import { useDatabase } from '../context/DBProvider';
|
import { useDatabase } from '../context/DBProvider';
|
||||||
|
|
||||||
export const StartPickListScreen = () => {
|
const StartPickListScreen = () => {
|
||||||
const areas = useAreas();
|
const areas = useAreas();
|
||||||
const categories = useCategories();
|
const categories = useCategories();
|
||||||
const db = useDatabase();
|
const db = useDatabase();
|
||||||
@@ -175,3 +175,5 @@ export const StartPickListScreen = () => {
|
|||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default StartPickListScreen
|
||||||
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"types": ["vite/client", "vitest/globals"]
|
"types": ["vite/client", "vitest/globals", "vitest"]
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
"references": [{ "path": "./tsconfig.node.json" }]
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
|
|||||||
+45
-1
@@ -1,13 +1,57 @@
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
|
|
||||||
|
function packageNameFromId(id: string) {
|
||||||
|
// Extract the package name from a node_modules path, including scoped packages.
|
||||||
|
const match = id.match(/node_modules\/((?:@[^/]+\/)?[^/]+)/);
|
||||||
|
return match ? match[1] : null;
|
||||||
|
}
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react(), visualizer({ filename: 'dist/stats.html', open: true })],
|
||||||
server: {
|
server: {
|
||||||
port: 5173,
|
port: 5173,
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
outDir: 'dist',
|
outDir: 'dist',
|
||||||
|
minify: 'esbuild', // fast minifier
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks(id: string) {
|
||||||
|
if (!id) return;
|
||||||
|
if (id.includes('node_modules')) {
|
||||||
|
// Always group react + router into one chunk
|
||||||
|
if (id.includes('react') || id.includes('react-dom') || id.includes('react-router-dom')) {
|
||||||
|
return 'react-vendor';
|
||||||
|
}
|
||||||
|
|
||||||
|
// MUI splits: specific first, generic later
|
||||||
|
if (id.includes('@mui/icons-material')) return 'mui-icons';
|
||||||
|
if (id.includes('@mui/material/esm/styles') || id.includes('@mui/material/styles')) return 'mui-styles';
|
||||||
|
// remaining @mui material code -> mui-core (covers components, utils, etc.)
|
||||||
|
if (id.includes('@mui/material') || id.includes('@mui/base')) return 'mui-core';
|
||||||
|
// emotion / styled engine split
|
||||||
|
if (id.includes('@emotion') || id.includes('@mui/styled-engine')) return 'mui-styled';
|
||||||
|
|
||||||
|
|
||||||
|
// Keep large libs in their own chunk to avoid a huge 'vendor'
|
||||||
|
if (id.includes('jszip')) return 'jszip';
|
||||||
|
if (id.includes('papaparse')) return 'papaparse';
|
||||||
|
if (id.includes('dexie')) return 'dexie';
|
||||||
|
if (id.includes('@zxing')) return 'zxing';
|
||||||
|
|
||||||
|
// Default: create a per-package chunk name so vendor is split up.
|
||||||
|
const pkg = packageNameFromId(id);
|
||||||
|
if (pkg) {
|
||||||
|
// normalize '@' from scoped packages (can't use '/' in filenames)
|
||||||
|
return `npm.${pkg.replace('/', '__').replace('@', '')}`;
|
||||||
|
}
|
||||||
|
return 'vendor';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
test: {
|
test: {
|
||||||
include: ['src/**/*.{test,spec}.{ts,tsx}'],
|
include: ['src/**/*.{test,spec}.{ts,tsx}'],
|
||||||
|
|||||||
Reference in New Issue
Block a user