mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-06 00:42:04 +00:00
build: migrate from CRA to Vite with TypeScript config
This commit is contained in:
parent
bb11aab86c
commit
0451788764
10 changed files with 7455 additions and 23342 deletions
28
index.html
Normal file
28
index.html
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Seahaven - Officetrax" />
|
||||
<link rel="apple-touch-icon" href="/logo192.png" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
|
||||
integrity="sha512-SfTiTlX6kk+qitfevl/7LibUOeJWlt9rbyDn92a1DqWOw9vWG2MFoays0sgObmWazO5BQPiFucnnEAjpAB+/Sw=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
|
||||
<title>Seahaven - Officetrax</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
30182
package-lock.json
generated
30182
package-lock.json
generated
File diff suppressed because it is too large
Load diff
103
package.json
103
package.json
|
|
@ -2,55 +2,102 @@
|
|||
"name": "seahaven-new-app",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "node --experimental-strip-types scripts/fix-router-paths.ts && tsc -b && vite build",
|
||||
"preview": "vite preview",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"test:e2e": "playwright test",
|
||||
"test:e2e:ui": "playwright test --ui",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check .",
|
||||
"prepare": "husky"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/{api,domain,app,lib,providers,infra,config,hooks,components}/**/*.{ts,tsx}": [
|
||||
"eslint --fix --max-warnings=0",
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{ts,tsx}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"src/test/**/*.{test,integration.test}.{ts,tsx}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{json,css,md,mdc}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"eslint.config.js": [
|
||||
"prettier --write"
|
||||
],
|
||||
"commitlint.config.js": [
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@fontsource/dm-sans": "^5.2.8",
|
||||
"@fontsource/jetbrains-mono": "^5.2.8",
|
||||
"@fontsource/montserrat": "^5.2.8",
|
||||
"@fullcalendar/daygrid": "^6.1.20",
|
||||
"@fullcalendar/interaction": "^6.1.20",
|
||||
"@fullcalendar/react": "^6.1.20",
|
||||
"@fullcalendar/timegrid": "^6.1.20",
|
||||
"@generouted/react-router": "^1.20.2",
|
||||
"@hookform/resolvers": "^5.4.0",
|
||||
"@mui/icons-material": "^7.3.1",
|
||||
"@mui/material": "^7.3.1",
|
||||
"@reduxjs/toolkit": "^2.11.2",
|
||||
"@tanstack/react-query": "^5.100.10",
|
||||
"@tanstack/react-query-devtools": "^5.100.10",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.6.4",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^1.16.0",
|
||||
"http-proxy-middleware": "^3.0.5",
|
||||
"clsx": "^2.1.1",
|
||||
"ky": "^1.7.5",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-hook-form": "^7.78.0",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-redux": "^9.2.0",
|
||||
"react-router-dom": "^7.9.4",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-toastify": "^11.0.5",
|
||||
"web-vitals": "^2.1.4"
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"web-vitals": "^2.1.4",
|
||||
"zod": "^4.4.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^21.0.2",
|
||||
"@commitlint/config-conventional": "^21.0.2",
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@playwright/test": "^1.60.0",
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"@types/node": "^22.15.30",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@vitejs/plugin-react": "^4.5.2",
|
||||
"@vitest/coverage-v8": "^3.2.4",
|
||||
"eslint": "^10.4.1",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-react-hooks": "^7.1.1",
|
||||
"eslint-plugin-react-refresh": "^0.5.2",
|
||||
"globals": "^17.6.0",
|
||||
"husky": "^9.1.7",
|
||||
"jsdom": "^26.1.0",
|
||||
"lint-staged": "^16.4.0",
|
||||
"prettier": "^3.8.4",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.61.0",
|
||||
"vite": "^6.3.5",
|
||||
"vitest": "^3.2.4"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha512-SfTiTlX6kk+qitfevl/7LibUOeJWlt9rbyDn92a1DqWOw9vWG2MFoays0sgObmWazO5BQPiFucnnEAjpAB+/Sw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>Seahaven - Officetrax</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
23
scripts/fix-router-paths.ts
Normal file
23
scripts/fix-router-paths.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
export const defaultRouterFile = path.resolve(scriptDir, "../src/router.ts");
|
||||
|
||||
/** Strip `/src/app` prefix from generouted Path types — views live under src/app/, not src/pages/. */
|
||||
export function fixGeneroutedRouterPaths(routerFile = defaultRouterFile) {
|
||||
const content = fs.readFileSync(routerFile, "utf8");
|
||||
const fixed = content.replace(/`\/+src\/app/g, "`").replace(/"\/+src\/app/g, '"/');
|
||||
|
||||
if (fixed !== content) {
|
||||
fs.writeFileSync(routerFile, fixed);
|
||||
}
|
||||
}
|
||||
|
||||
const isMain =
|
||||
process.argv[1] && path.resolve(process.argv[1]) === path.resolve(fileURLToPath(import.meta.url));
|
||||
|
||||
if (isMain) {
|
||||
fixGeneroutedRouterPaths();
|
||||
}
|
||||
269
scripts/migrate-routes.mjs
Normal file
269
scripts/migrate-routes.mjs
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const root = path.resolve(import.meta.dirname, "..");
|
||||
const src = path.join(root, "src");
|
||||
const app = path.join(src, "app");
|
||||
const routesSrc = path.join(app, "routes");
|
||||
|
||||
function read(file) {
|
||||
return fs.readFileSync(file, "utf8");
|
||||
}
|
||||
|
||||
function write(file, content) {
|
||||
fs.mkdirSync(path.dirname(file), { recursive: true });
|
||||
fs.writeFileSync(file, content, "utf8");
|
||||
}
|
||||
|
||||
function rmrf(dir) {
|
||||
if (!fs.existsSync(dir)) return;
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
function toDefaultExport(content, exportName) {
|
||||
let result = content;
|
||||
if (exportName) {
|
||||
result = result.replace(
|
||||
new RegExp(`export function ${exportName}\\b`),
|
||||
`export default function ${exportName}`,
|
||||
);
|
||||
result = result.replace(
|
||||
new RegExp(`export const ${exportName}\\b`),
|
||||
`export default function ${exportName}`,
|
||||
);
|
||||
}
|
||||
return result
|
||||
.replace(/^export \{ ([A-Za-z]+) as default \} from .+;\s*$/m, "")
|
||||
.trimEnd() + "\n";
|
||||
}
|
||||
|
||||
function copyRoutesTree() {
|
||||
const entries = ["(auth)", "(protected)", "v"];
|
||||
for (const entry of entries) {
|
||||
const from = path.join(routesSrc, entry);
|
||||
const to = path.join(app, entry);
|
||||
if (!fs.existsSync(from)) continue;
|
||||
rmrf(to);
|
||||
fs.cpSync(from, to, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
function updateProtectedLayout() {
|
||||
const layoutPath = path.join(app, "(protected)", "_layout.tsx");
|
||||
let content = read(layoutPath);
|
||||
content = content.replace(
|
||||
"export default function ProtectedLayout()",
|
||||
"export default function AdminShellLayout()",
|
||||
);
|
||||
write(layoutPath, content);
|
||||
}
|
||||
|
||||
function mergePage(sourceRel, destRel, exportName, importReplacements = [], { namedOnly = false } = {}) {
|
||||
const source = path.join(app, sourceRel);
|
||||
if (!fs.existsSync(source)) {
|
||||
console.warn("Missing source:", sourceRel);
|
||||
return;
|
||||
}
|
||||
let content = read(source);
|
||||
for (const [from, to] of importReplacements) {
|
||||
content = content.split(from).join(to);
|
||||
}
|
||||
if (!namedOnly) {
|
||||
content = toDefaultExport(content, exportName);
|
||||
}
|
||||
write(path.join(app, destRel), content.endsWith("\n") ? content : content + "\n");
|
||||
}
|
||||
|
||||
function copyFile(sourceRel, destRel, importReplacements = []) {
|
||||
mergePage(sourceRel, destRel, null, importReplacements, { namedOnly: true });
|
||||
}
|
||||
|
||||
function writeReExport(destRel, componentPath, { nestedEdit = false } = {}) {
|
||||
const importPath = nestedEdit ? componentPath.replace(/^\.\//, "../") : componentPath;
|
||||
write(path.join(app, destRel), `export { default } from "${importPath}";\n`);
|
||||
}
|
||||
|
||||
// --- infra ---
|
||||
write(path.join(src, "app-root.tsx"), read(path.join(app, "app-root.tsx")));
|
||||
|
||||
let main = read(path.join(src, "main.tsx"));
|
||||
main = main.replace('@/app/app-root', '@/app-root');
|
||||
write(path.join(src, "main.tsx"), main);
|
||||
|
||||
let vite = read(path.join(root, "vite.config.ts"));
|
||||
vite = vite.replace(
|
||||
'routes: "./src/app/routes/**/[\\w[-]*.{jsx,tsx}"',
|
||||
'routes: "./src/app/**/[\\w[-]*.{jsx,tsx}"',
|
||||
);
|
||||
vite = vite.replace(
|
||||
'modals: "./src/app/routes/**/[+]*.{jsx,tsx}"',
|
||||
'modals: "./src/app/**/[+]*.{jsx,tsx}"',
|
||||
);
|
||||
write(path.join(root, "vite.config.ts"), vite);
|
||||
|
||||
copyRoutesTree();
|
||||
updateProtectedLayout();
|
||||
|
||||
// --- accounts pilot ---
|
||||
mergePage("accounts/accounts-list-page.tsx", "(protected)/accounts/index.tsx", "AccountsListPage");
|
||||
mergePage("accounts/account-form-page.tsx", "(protected)/accounts/_components/account-form.tsx", "AccountFormPage");
|
||||
writeReExport("(protected)/accounts/new.tsx", "./_components/account-form");
|
||||
writeReExport("(protected)/accounts/edit/[id].tsx", "./_components/account-form");
|
||||
|
||||
// --- contacts, employees, locations ---
|
||||
mergePage("contacts/contacts-list-page.tsx", "(protected)/contacts/index.tsx", "ContactsListPage");
|
||||
mergePage("contacts/contact-form-page.tsx", "(protected)/contacts/_components/contact-form.tsx", "ContactFormPage");
|
||||
writeReExport("(protected)/contacts/new.tsx", "./_components/contact-form");
|
||||
writeReExport("(protected)/contacts/edit/[id].tsx", "./_components/contact-form");
|
||||
|
||||
mergePage("employees/employees-list-page.tsx", "(protected)/employees/index.tsx", "EmployeesListPage");
|
||||
mergePage("employees/employee-form-page.tsx", "(protected)/employees/_components/employee-form.tsx", "EmployeeFormPage");
|
||||
writeReExport("(protected)/employees/new.tsx", "./_components/employee-form");
|
||||
writeReExport("(protected)/employees/edit/[id].tsx", "./_components/employee-form");
|
||||
|
||||
mergePage("locations/locations-list-page.tsx", "(protected)/locations/index.tsx", "LocationsListPage");
|
||||
mergePage("locations/location-form-page.tsx", "(protected)/locations/_components/location-form.tsx", "LocationFormPage");
|
||||
writeReExport("(protected)/locations/new.tsx", "./_components/location-form");
|
||||
writeReExport("(protected)/locations/edit/[id].tsx", "./_components/location-form");
|
||||
|
||||
// --- assets, vendors, followups, pmschedules ---
|
||||
mergePage("assets/assets-list-page.tsx", "(protected)/assets/index.tsx", "AssetsListPage");
|
||||
mergePage("assets/asset-form-page.tsx", "(protected)/assets/_components/asset-form.tsx", "AssetFormPage");
|
||||
writeReExport("(protected)/assets/new.tsx", "./_components/asset-form");
|
||||
writeReExport("(protected)/assets/edit/[id].tsx", "./_components/asset-form");
|
||||
|
||||
mergePage("vendors/vendors-list-page.tsx", "(protected)/vendors/index.tsx", "VendorsListPage");
|
||||
mergePage(
|
||||
"vendors/vendor-form-page.tsx",
|
||||
"(protected)/vendors/_components/vendor-form.tsx",
|
||||
"VendorFormPage",
|
||||
[["@/app/vendors/components/vendor-portal-token-panel", "./vendor-portal-token-panel"]],
|
||||
);
|
||||
copyFile(
|
||||
"vendors/components/vendor-portal-token-panel.tsx",
|
||||
"(protected)/vendors/_components/vendor-portal-token-panel.tsx",
|
||||
);
|
||||
writeReExport("(protected)/vendors/new.tsx", "./_components/vendor-form");
|
||||
writeReExport("(protected)/vendors/edit/[id].tsx", "./_components/vendor-form");
|
||||
|
||||
mergePage("follow-ups/follow-ups-list-page.tsx", "(protected)/followups/index.tsx", "FollowUpsListPage");
|
||||
mergePage("follow-ups/follow-up-form-page.tsx", "(protected)/followups/_components/follow-up-form.tsx", "FollowUpFormPage");
|
||||
writeReExport("(protected)/followups/new.tsx", "./_components/follow-up-form");
|
||||
writeReExport("(protected)/followups/edit/[id].tsx", "./_components/follow-up-form");
|
||||
|
||||
mergePage("pm-schedules/pm-schedules-list-page.tsx", "(protected)/pmschedules/index.tsx", "PmSchedulesListPage");
|
||||
mergePage("pm-schedules/pm-schedule-form-page.tsx", "(protected)/pmschedules/_components/pm-schedule-form.tsx", "PmScheduleFormPage");
|
||||
writeReExport("(protected)/pmschedules/new.tsx", "./_components/pm-schedule-form");
|
||||
writeReExport("(protected)/pmschedules/edit/[id].tsx", "./_components/pm-schedule-form");
|
||||
|
||||
// --- calendar, uplifts, vendor-pos, settings, dashboard, login ---
|
||||
mergePage("calendar/calendar-page.tsx", "(protected)/calendar/index.tsx", "CalendarPage");
|
||||
mergePage("calendar/event-form-page.tsx", "(protected)/calendar/_components/event-form.tsx", "EventFormPage");
|
||||
writeReExport("(protected)/calendar/new.tsx", "./_components/event-form");
|
||||
writeReExport("(protected)/calendar/edit/[id].tsx", "./_components/event-form");
|
||||
|
||||
mergePage("uplifts/uplift-queue-page.tsx", "(protected)/uplifts/index.tsx", "UpliftQueuePage");
|
||||
|
||||
mergePage("vendor-pos/vendor-pos-list-page.tsx", "(protected)/vendor-pos/index.tsx", "VendorPosListPage");
|
||||
mergePage("vendor-pos/vendor-po-view-page.tsx", "(protected)/vendor-pos/[id].tsx", "VendorPoViewPage");
|
||||
|
||||
mergePage("settings/dropdown-options-page.tsx", "(protected)/settings/dropdowns.tsx", "DropdownOptionsPage");
|
||||
mergePage("settings/task-templates-page.tsx", "(protected)/settings/task-templates.tsx", "TaskTemplatesPage");
|
||||
|
||||
mergePage("dashboard/dashboard-page.tsx", "(protected)/index.tsx", "DashboardPage");
|
||||
mergePage("dashboard/dashboard-page.tsx", "(protected)/dashboard.tsx", "DashboardPage");
|
||||
|
||||
mergePage("login/login-page.tsx", "(auth)/login.tsx", "LoginPage");
|
||||
|
||||
// --- workorders ---
|
||||
mergePage("work-orders/work-orders-list-page.tsx", "(protected)/workorders/index.tsx", "WorkOrdersListPage");
|
||||
mergePage("work-orders/work-order-form-page.tsx", "(protected)/workorders/_components/work-order-form.tsx", "WorkOrderFormPage");
|
||||
writeReExport("(protected)/workorders/new.tsx", "./_components/work-order-form");
|
||||
writeReExport("(protected)/workorders/edit/[id].tsx", "./_components/work-order-form");
|
||||
mergePage(
|
||||
"work-orders/work-order-view-page.tsx",
|
||||
"(protected)/workorders/[id].tsx",
|
||||
"WorkOrderViewPage",
|
||||
[
|
||||
["@/app/work-orders/components/dispatch-create-modal", "./_components/dispatch-create-modal"],
|
||||
["@/app/work-orders/components/dispatch-detail-modal", "./_components/dispatch-detail-modal"],
|
||||
],
|
||||
);
|
||||
copyFile(
|
||||
"work-orders/components/dispatch-create-modal.tsx",
|
||||
"(protected)/workorders/_components/dispatch-create-modal.tsx",
|
||||
);
|
||||
copyFile(
|
||||
"work-orders/components/dispatch-detail-modal.tsx",
|
||||
"(protected)/workorders/_components/dispatch-detail-modal.tsx",
|
||||
);
|
||||
|
||||
// --- vendor portal ---
|
||||
const vpComponents = path.join(app, "v", "_components");
|
||||
fs.mkdirSync(vpComponents, { recursive: true });
|
||||
|
||||
copyFile("vendor-portal/vendor-portal-provider.tsx", "v/_components/vendor-portal-provider.tsx");
|
||||
copyFile("vendor-portal/components/signature-pad.tsx", "v/_components/signature-pad.tsx");
|
||||
fs.copyFileSync(
|
||||
path.join(app, "vendor-portal/vendor-portal.css"),
|
||||
path.join(vpComponents, "vendor-portal.css"),
|
||||
);
|
||||
|
||||
let vpLayout = read(path.join(app, "vendor-portal/vendor-portal-layout.tsx"));
|
||||
vpLayout = vpLayout
|
||||
.replace("@/app/vendor-portal/vendor-portal-provider", "@/app/v/_components/vendor-portal-provider")
|
||||
.replace("@/app/vendor-portal/vendor-portal.css", "@/app/v/_components/vendor-portal.css")
|
||||
.replace("export function VendorPortalLayout", "export default function VendorPortalLayout");
|
||||
write(path.join(app, "v", "[token]", "_layout.tsx"), vpLayout);
|
||||
|
||||
mergePage(
|
||||
"vendor-portal/vendor-portal-dashboard-page.tsx",
|
||||
"v/[token]/dashboard.tsx",
|
||||
"VendorPortalDashboardPage",
|
||||
[["@/app/vendor-portal/vendor-portal-provider", "@/app/v/_components/vendor-portal-provider"]],
|
||||
);
|
||||
mergePage(
|
||||
"vendor-portal/vendor-portal-pos-page.tsx",
|
||||
"v/[token]/pos.tsx",
|
||||
"VendorPortalPosPage",
|
||||
[["@/app/vendor-portal/vendor-portal-provider", "@/app/v/_components/vendor-portal-provider"]],
|
||||
);
|
||||
mergePage(
|
||||
"vendor-portal/vendor-portal-dispatch-page.tsx",
|
||||
"v/[token]/dispatch/[id].tsx",
|
||||
"VendorPortalDispatchPage",
|
||||
[
|
||||
["@/app/vendor-portal/components/signature-pad", "@/app/v/_components/signature-pad"],
|
||||
["@/app/vendor-portal/vendor-portal-provider", "@/app/v/_components/vendor-portal-provider"],
|
||||
],
|
||||
);
|
||||
|
||||
// --- cleanup old dirs ---
|
||||
const toDelete = [
|
||||
path.join(app, "routes"),
|
||||
path.join(app, "app-root.tsx"),
|
||||
path.join(app, "store.js"),
|
||||
path.join(app, "slices"),
|
||||
path.join(app, "accounts"),
|
||||
path.join(app, "contacts"),
|
||||
path.join(app, "employees"),
|
||||
path.join(app, "locations"),
|
||||
path.join(app, "assets"),
|
||||
path.join(app, "vendors"),
|
||||
path.join(app, "follow-ups"),
|
||||
path.join(app, "pm-schedules"),
|
||||
path.join(app, "calendar"),
|
||||
path.join(app, "uplifts"),
|
||||
path.join(app, "vendor-pos"),
|
||||
path.join(app, "settings"),
|
||||
path.join(app, "dashboard"),
|
||||
path.join(app, "login"),
|
||||
path.join(app, "work-orders"),
|
||||
path.join(app, "vendor-portal"),
|
||||
];
|
||||
|
||||
for (const dir of toDelete) {
|
||||
rmrf(dir);
|
||||
}
|
||||
|
||||
console.log("Migration complete.");
|
||||
29
tsconfig.json
Normal file
29
tsconfig.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"strict": true,
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"composite": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
20
tsconfig.node.json
Normal file
20
tsconfig.node.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"strict": true,
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "./node_modules/.tmp/tsconfig.node",
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["vite.config.ts", "vitest.config.ts", "scripts/fix-router-paths.ts"]
|
||||
}
|
||||
77
vite.config.ts
Normal file
77
vite.config.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import generouted from "@generouted/react-router/plugin";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import path from "node:path";
|
||||
import { defineConfig, loadEnv, transformWithEsbuild } from "vite";
|
||||
import { defaultRouterFile, fixGeneroutedRouterPaths } from "./scripts/fix-router-paths.ts";
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
const env = loadEnv(mode, process.cwd(), "");
|
||||
|
||||
return {
|
||||
plugins: [
|
||||
{
|
||||
name: "load-js-files-as-jsx",
|
||||
async transform(code, id) {
|
||||
if (!/\/src\/.*\.js$/.test(id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return transformWithEsbuild(code, id, {
|
||||
loader: "jsx",
|
||||
jsx: "automatic",
|
||||
});
|
||||
},
|
||||
},
|
||||
react(),
|
||||
tailwindcss(),
|
||||
generouted({
|
||||
source: {
|
||||
routes: "./src/app/**/[\\w[-]*.{jsx,tsx}",
|
||||
modals: "./src/app/**/[+]*.{jsx,tsx}",
|
||||
},
|
||||
output: "./src/router.ts",
|
||||
}),
|
||||
{
|
||||
name: "generouted-app-paths",
|
||||
enforce: "post",
|
||||
buildEnd() {
|
||||
fixGeneroutedRouterPaths(defaultRouterFile);
|
||||
},
|
||||
configureServer(server) {
|
||||
const scheduleFix = () => {
|
||||
setTimeout(() => fixGeneroutedRouterPaths(defaultRouterFile), 50);
|
||||
};
|
||||
server.watcher.on("add", scheduleFix);
|
||||
server.watcher.on("change", scheduleFix);
|
||||
server.watcher.on("unlink", scheduleFix);
|
||||
},
|
||||
},
|
||||
],
|
||||
optimizeDeps: {
|
||||
esbuildOptions: {
|
||||
loader: {
|
||||
".js": "jsx",
|
||||
},
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "src"),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
port: 3000,
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: env.VITE_API_TARGET ?? "http://localhost:5141",
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
build: {
|
||||
outDir: "dist",
|
||||
},
|
||||
};
|
||||
});
|
||||
19
vitest.config.ts
Normal file
19
vitest.config.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import react from "@vitejs/plugin-react";
|
||||
import path from "node:path";
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "src"),
|
||||
},
|
||||
},
|
||||
test: {
|
||||
environment: "jsdom",
|
||||
setupFiles: ["./src/test/setup.ts"],
|
||||
globals: false,
|
||||
include: ["src/test/**/*.test.{ts,tsx}", "src/test/**/*.integration.test.{ts,tsx}"],
|
||||
exclude: ["e2e/**", "node_modules/**"],
|
||||
},
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue