mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-06 14:42:05 +00:00
269 lines
11 KiB
JavaScript
269 lines
11 KiB
JavaScript
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.");
|