chore: import codes

This commit is contained in:
2026-04-12 12:50:14 -04:00
parent 4bcb4898e8
commit 65ae3c6788
241 changed files with 48834 additions and 1 deletions
+135
View File
@@ -0,0 +1,135 @@
/**
* Admin Page - Server Component Wrapper for Next.js App Router
*
* This is a complete server component that handles all admin routes.
* Users can simply re-export this in their app/admin/[...admin]/page.js:
*
* ```javascript
* export { default } from '@hykocx/zen/admin/page';
* ```
*
* This eliminates the need to manually import and pass all actions and props.
*/
import { AdminPagesLayout, AdminPagesClient } from '@hykocx/zen/admin/pages';
import { protectAdmin } from '@hykocx/zen/admin';
import { buildNavigationSections } from '@hykocx/zen/admin/navigation';
import { getDashboardStats, getModuleDashboardStats } from '@hykocx/zen/admin/actions';
import { logoutAction } from '@hykocx/zen/auth/actions';
import { getAppName, getModulesConfig, getAppConfig, moduleSystem } from '@hykocx/zen';
const { getAdminPage } = moduleSystem;
/**
* Parse admin route params and build the module path
* Handles nested paths like /admin/invoice/clients/edit/123
*
* @param {Object} params - Next.js route params
* @returns {Object} Parsed info with path, action, and id
*/
function parseAdminRoute(params) {
const parts = params?.admin || [];
if (parts.length === 0) {
return { path: '/admin/dashboard', action: null, id: null, isCorePage: true };
}
// Check for core pages first
const corePages = ['dashboard', 'users', 'profile'];
if (corePages.includes(parts[0])) {
// Users: support /admin/users/edit/:id
if (parts[0] === 'users' && parts[1] === 'edit' && parts[2]) {
return { path: '/admin/users', action: 'edit', id: parts[2], isCorePage: true };
}
return { path: `/admin/${parts[0]}`, action: null, id: null, isCorePage: true };
}
// Build module path
// Look for 'new', 'create', or 'edit' to determine action
const actionKeywords = ['new', 'create', 'edit'];
let pathParts = [];
let action = null;
let id = null;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (actionKeywords.includes(part)) {
action = part === 'create' ? 'new' : part;
// If it's 'edit', the next part is the ID
if (action === 'edit' && i + 1 < parts.length) {
id = parts[i + 1];
}
break;
}
pathParts.push(part);
}
// Build the full path
let fullPath = '/admin/' + pathParts.join('/');
if (action) {
fullPath += '/' + action;
}
return { path: fullPath, action, id, isCorePage: false };
}
/**
* Check if a path is a module page
* @param {string} fullPath - Full admin path
* @returns {Object|null} Module info if it's a module page, null otherwise
*/
function getModulePageInfo(fullPath) {
const modulePage = getAdminPage(fullPath);
if (modulePage) {
return {
module: modulePage.module,
path: fullPath
};
}
return null;
}
export default async function AdminPage({ params }) {
const resolvedParams = await params;
const session = await protectAdmin();
const appName = getAppName();
const enabledModules = getModulesConfig();
const config = getAppConfig();
const statsResult = await getDashboardStats();
const dashboardStats = statsResult.success ? statsResult.stats : null;
// Fetch module dashboard stats for widgets
const moduleStats = await getModuleDashboardStats();
// Build navigation on server where module registry is available
const navigationSections = buildNavigationSections('/', enabledModules);
// Parse route and build path
const { path, action, id, isCorePage } = parseAdminRoute(resolvedParams);
// Check if this is a module page (just check existence, don't load)
const modulePageInfo = isCorePage ? null : getModulePageInfo(path);
return (
<AdminPagesLayout
user={session.user}
onLogout={logoutAction}
appName={appName}
enabledModules={enabledModules}
navigationSections={navigationSections}
>
<AdminPagesClient
params={resolvedParams}
user={session.user}
dashboardStats={dashboardStats}
moduleStats={moduleStats}
modulePageInfo={modulePageInfo}
routeInfo={{ path, action, id }}
enabledModules={enabledModules}
/>
</AdminPagesLayout>
);
}