redesign the homepage
Build & Deploy / Build & Push Docker Image (push) Failing after 47s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m4s
Test / Marketplace Unit Tests (push) Failing after 4m55s
Test / Admin Unit Tests (push) Successful in 9m37s
Test / Dashboard Unit Tests (push) Successful in 9m37s
Test / API Integration Tests (push) Successful in 9m54s
Build & Deploy / Build & Push Docker Image (push) Failing after 47s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m4s
Test / Marketplace Unit Tests (push) Failing after 4m55s
Test / Admin Unit Tests (push) Successful in 9m37s
Test / Dashboard Unit Tests (push) Successful in 9m37s
Test / API Integration Tests (push) Successful in 9m54s
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
import { readFile, readdir, stat } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const errors = [];
|
||||
|
||||
async function exists(target) {
|
||||
try { await stat(target); return true; } catch { return false; }
|
||||
}
|
||||
|
||||
async function walk(directory) {
|
||||
const files = [];
|
||||
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
||||
if (['node_modules', '.next', '.turbo', 'dist', 'coverage'].includes(entry.name)) continue;
|
||||
const target = path.join(directory, entry.name);
|
||||
if (entry.isDirectory()) files.push(...(await walk(target)));
|
||||
else files.push(target);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
function requireText(contents, required, label) {
|
||||
for (const marker of required) {
|
||||
if (!contents.includes(marker)) errors.push(`${label}: missing ${marker}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const app of ['admin', 'api', 'dashboard', 'homepage', 'storefront']) {
|
||||
if (!(await exists(path.join(root, app)))) errors.push(`missing application directory: ${app}`);
|
||||
if (!(await exists(path.join(root, app, 'package.json')))) errors.push(`${app}: missing package.json`);
|
||||
}
|
||||
|
||||
for (const app of ['admin', 'dashboard']) {
|
||||
const tokenPath = path.join(root, app, 'src/styles/phase16-tokens.css');
|
||||
const globalsPath = path.join(root, app, 'src/app/globals.css');
|
||||
if (!(await exists(tokenPath))) errors.push(`${app}: missing Phase 16 token file`);
|
||||
if (!(await exists(globalsPath))) errors.push(`${app}: missing globals.css`);
|
||||
|
||||
const tokens = await readFile(tokenPath, 'utf8');
|
||||
requireText(tokens, [
|
||||
'--rdg-blue-700', '--rdg-orange-600', '--rdg-sidebar-size',
|
||||
'--rdg-header-size', '--rdg-radius-lg', '--rdg-shadow-card',
|
||||
], `${app} tokens`);
|
||||
|
||||
const globals = await readFile(globalsPath, 'utf8');
|
||||
requireText(globals, [
|
||||
'phase16-tokens.css', '.rdg-app-shell', '.rdg-sidebar', '.rdg-topbar',
|
||||
'.rdg-page-hero', '.rdg-page-heading', '.btn-primary', '.btn-conversion',
|
||||
'.panel', '.field', '@media (forced-colors: active)',
|
||||
], `${app} globals`);
|
||||
|
||||
const withoutComments = globals.replace(/\/\*[\s\S]*?\*\//g, '');
|
||||
const balance = [...withoutComments].reduce((value, character) =>
|
||||
character === '{' ? value + 1 : character === '}' ? value - 1 : value, 0);
|
||||
if (balance !== 0) errors.push(`${app}: unbalanced CSS braces (${balance})`);
|
||||
}
|
||||
|
||||
const dashboardLayout = await readFile(path.join(root, 'dashboard/src/app/(dashboard)/layout.tsx'), 'utf8');
|
||||
requireText(dashboardLayout, ['rdg-app-shell', 'rdg-workspace', 'rdg-app-main', 'rdg-app-content'], 'dashboard shell');
|
||||
|
||||
const dashboardSidebar = await readFile(path.join(root, 'dashboard/src/components/layout/Sidebar.tsx'), 'utf8');
|
||||
requireText(dashboardSidebar, ['rdg-sidebar', 'rdg-nav-item', 'aria-current', 'RentalDriveGo'], 'dashboard sidebar');
|
||||
|
||||
const dashboardTopbar = await readFile(path.join(root, 'dashboard/src/components/layout/TopBar.tsx'), 'utf8');
|
||||
requireText(dashboardTopbar, ['rdg-topbar', 'rdg-system-status', 'rdg-search-field'], 'dashboard topbar');
|
||||
|
||||
const adminLayout = await readFile(path.join(root, 'admin/src/app/dashboard/layout.tsx'), 'utf8');
|
||||
requireText(adminLayout, [
|
||||
'rdg-app-shell', 'rdg-sidebar', 'rdg-nav-item', 'rdg-topbar',
|
||||
'rdg-system-status', 'aria-current', 'RentalDriveGo',
|
||||
], 'admin shell');
|
||||
|
||||
const routeRoots = [
|
||||
path.join(root, 'admin/src/app/dashboard'),
|
||||
path.join(root, 'dashboard/src/app/(dashboard)'),
|
||||
];
|
||||
for (const routeRoot of routeRoots) {
|
||||
const pages = (await walk(routeRoot)).filter((file) => file.endsWith('page.tsx'));
|
||||
for (const page of pages) {
|
||||
const contents = await readFile(page, 'utf8');
|
||||
if (!['rdg-page-heading', 'rdg-page-hero'].some((marker) => contents.includes(marker))) {
|
||||
errors.push(`${path.relative(root, page)}: missing Phase 16 page heading or hero`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const app of ['admin', 'dashboard']) {
|
||||
for (const file of await walk(path.join(root, app, 'src'))) {
|
||||
if (!/\.(ts|tsx|css|json)$/.test(file)) continue;
|
||||
const contents = await readFile(file, 'utf8');
|
||||
if (/RentalDriveGo/i.test(contents)) errors.push(`${path.relative(root, file)}: retired RentalDriveGo brand remains`);
|
||||
}
|
||||
}
|
||||
|
||||
const authChecks = [
|
||||
'dashboard/src/app/sign-in/[[...sign-in]]/SignInPageClient.tsx',
|
||||
'dashboard/src/app/sign-up/[[...sign-up]]/SignUpForm.tsx',
|
||||
];
|
||||
for (const relative of authChecks) {
|
||||
const contents = await readFile(path.join(root, relative), 'utf8');
|
||||
if (!contents.includes('PublicPageLayout')) errors.push(`${relative}: shared public layout not applied`);
|
||||
}
|
||||
|
||||
for (const relative of [
|
||||
'storefront/src/components/public/SiteNavbar.tsx',
|
||||
'storefront/src/components/public/SiteFooter.tsx',
|
||||
'storefront/src/components/public/SitePageLayout.tsx',
|
||||
]) {
|
||||
if (!(await exists(path.join(root, relative)))) errors.push(`missing shared storefront component: ${relative}`);
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
console.error(errors.join('\n'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Phase 16 dashboard/admin design checks passed.');
|
||||
Reference in New Issue
Block a user