1. Meet Zeehaak AP
Zeehaak Admin Panel Framework v1.1.0 is a reusable PHP-rendered UI foundation. It combines an original responsive workspace, native browser interactions, SVG charts and replaceable demo data. It is not an identity service, ERP, database application or payment processor.
2. Installation & running locally
Copy the entire Zeehaak-AP directory into a PHP-capable web root. No Composer, npm, database or internet connection is needed. Use a maintained PHP runtime for deployments. The source avoids PHP 8-only syntax and can be demonstrated on PHP 7.4.
cd Zeehaak-AP
php -S 127.0.0.1:8088 -t .
# Open http://127.0.0.1:8088/index.phpWith XAMPP, start Apache and open the folder's index.php through localhost. Opening PHP files directly with file:// will not work. The development server is for local previews only.
3. Folder structure
assets/css/ Shared CSS tokens, responsive styles, generated theme CSS
assets/js/ Theme, core behaviors, table and chart modules
assets/images/ Original SVG logo
components/ PHP helpers and shared dialogs
config/ Branding, version, page registry, menu and role policy
layouts/ Shared workspace, authentication and error shells
pages/ Showcase pages and example screens
examples/ Replaceable data and starter page
docs/ This guide, dependency inventory and acceptance map
tests/ Reproducible local acceptance checks
index.php Allowlisted front controller
CHANGELOG.md Release history
Default and compact layouts share one shell; the compact variant is controlled by appearance preferences. Authentication and error pages use standalone shells. A blank content template is provided in examples/starter.php. Shared rendering functions avoid duplicate UI markup.
4. Create a page
Copy examples/starter.php to pages/projects.php. Add an explicit entry to config/pages.php; the tuple is title, subtitle, filename and required permission. Page names are allowlisted. Never turn a user query value into a filesystem path.
'projects' => ['Projects', 'A home for your projects.', 'projects.php', 'projects.view'],Grant projects.view to suitable roles in config/permissions.php, then visit index.php?page=projects. Every page receives the shared layout, scripts and dialogs automatically. Escape text with e() and generate internal links with url().
5. Top modules & context sidebar
Version 1.1.0 uses config/menu.php as the single registry for top modules, sidebar items, icons, page ownership and permissions. Only the current module's permitted menus appear in the sidebar. Direct URLs, refresh and browser history resolve active state on the server. Existing showcase routes continue to work under their configured modules.
'projects' => [
'label' => 'Projects', 'icon' => 'layers', 'permission' => 'projects.view',
'menus' => [
['projects', 'Overview', 'grid', 'projects.view', 'projects.php'],
['projects-add', 'Add project', 'plus', 'projects.create', 'project-form.php'],
],
'groups' => ['Archive' => [['projects-history', 'History', 'clock']]],
],Item order is stable page key, label, icon, optional permission, optional PHP view. Existing registered pages keep their views; new items default to an explicitly labelled integration page until you supply a view. Modules with no allowed pages disappear; others open their first permitted page. Labels can be translated without changing URLs. See docs/NAVIGATION.md for the full integration contract, existing-path adaptation and test instructions.
6. Cards, charts & statistics
<section class="card">
<div class="card-header"><h2>Revenue</h2></div>
<?php kpi('Revenue', '$12,300', '8.2%', 'wallet', [10,12,9,20]); ?>
<?php chart('line', 'Monthly revenue', [10,12,9,20]); ?>
</section>Chart types: line, bar, area, donut, pie, mixed and sparkline. Pass nonnegative numeric arrays. Supply a descriptive label including units and period. Color tokens adapt automatically to dark mode. Charts are illustrative SVG renderers, not a full plotting library; series comparisons on the dashboard use documented demo values.
7. Tables
The Orders page demonstrates search, status/date filters, sortable columns, page sizes, row selection, bulk confirmation, column visibility, compact/bordered/striped styles, sticky headers, horizontal scrolling, loading and empty states. Export uses filtered rows and visible columns; print temporarily renders all matching rows. Formula-like CSV values are neutralized before export.
For a new table, follow pages/tables.php and table.js. The six-column order schema is an example adapter. Refactor its columns and row mapping for your dataset, or use the shared table CSS for a plain table. Render untrusted strings as textContent, not innerHTML. Production datasets should be paginated and scoped on the server. Selection resets when filters change; page changes preserve selection until cleared. Demo mutations are in memory and reset on refresh.
8. Forms & validation
Use labels around inputs, .form-grid for two-column sections, .check for toggles and .field-group for prefixes/password controls. Forms marked data-demo-form are intercepted: no requests or credentials are sent. Native constraints plus inline messages validate required fields, email, numeric ranges, matching passwords and date order. Successful validation disables repeat submission until a field changes. Uploads preview locally, allow PNG/JPEG/WebP up to 5 MB and do not write files.
<form data-demo-form novalidate>
<div class="form-result" role="status" hidden></div>
<label>Name<input name="name" required maxlength="100"></label>
<button type="submit" class="button primary">Validate</button>
</form>To connect real writes, remove the demo handler and implement a server endpoint with CSRF protection, server validation, authorization and idempotency. Never treat browser validation as an authorization or storage guarantee. Handle file signatures, size, storage names and access rights server-side.
9. Modals, drawers & confirmation
Use a native dialog with an accessible heading, data-open on its trigger and data-close on dismissal buttons. Zeehaak.open(id) restores focus to the trigger on close; native dialog handles focus containment and Escape. Add .drawer for an off-canvas variant.
<button data-open="project-dialog">Open</button>
<dialog id="project-dialog" aria-labelledby="project-title">
<div class="dialog-header"><h2 id="project-title">Project</h2></div>
<div class="dialog-body">Content</div>
<div class="dialog-footer"><button data-close>Close</button></div>
</dialog>
Zeehaak.confirm('Continue?', () => { /* authorized action */ });
Zeehaak.toast('Saved after your backend confirms success.');
10. Other components
Use badge(text, tone), icon(name), .button, .button-group, .alert, .progress, .empty-state, .skeleton and .spinner. The showcase pages demonstrate markup. Tabs use role=tablist, role=tab, aria-controls and keyboard arrow navigation. Native details elements provide accordions and dropdowns. The popover example uses the browser Popover API. Every icon-only action needs an accessible label. Keep loading/status text available to screen readers.
11. Branding & themes
Edit config/app.php for application name, short name, company, logo, favicon, login tagline, footer, copyright, version, locale and default direction. Keep logo paths relative to index.php. The supplied logo is assets/images/logo.svg. Configure primary, secondary and accent as six-digit hex colors. Sidebar styles are dark or light; navbar styles are surface or tinted.
Theme CSS is generated from configuration without inline styles. The Brand default setting uses your configured primary color (the stored key remains violet for compatibility). Appearance overrides are stored under zeehaak.ap.appearance in localStorage. Reset appearance to return to defaults after changing configuration. The secondary token drives the sidebar and the accent token is available for your custom components.
12. Dark, light & system modes
Open Appearance in the navbar or call ZeehaakTheme.set('mode', 'dark'). Values are light, dark and system. System mode observes OS preference changes. Storage failures do not prevent rendering. Choose a theme before first paint using theme.js. Respect reduced motion; do not add animation that ignores the existing media query.
13. RTL & layout variants
Set direction to rtl in app.php for the default, or ZeehaakTheme.set('direction', 'rtl') for a browser preference. Logical margins, paddings and positioning move the sidebar, drawers and data alignment. Set locale to ur or ar when the actual interface is translated. Number/date/currency formatting is a replaceable integration detail; the demo table uses USD and ISO dates.
ZeehaakTheme.set('compact', true);
ZeehaakTheme.set('mini', true);
ZeehaakTheme.set('wide', true);
ZeehaakTheme.set('fixed', true);The desktop sidebar can collapse to a mini rail. On mobile it becomes a drawer; Escape and the backdrop close it. Fixed mode keeps scrolling inside the main viewport. Full width removes the maximum content width.
14. Permissions & safe integration
config/permissions.php includes Super Admin, Admin, Manager, Staff, Data Entry, Viewer and Custom examples. can() gates registered routes, menu items and example actions on the server. Resolve roles from a trusted authenticated session when integrating. The demo_role value is developer configuration, not authentication; the demo must not protect sensitive data.
For real applications: authenticate every protected request, deny by default, authorize every action and scope all reads/writes by trusted tenant and ownership identifiers. Use parameterized queries, CSRF tokens for writes, unique constraints where business rules permit and a transaction for related writes. Assign an idempotency key per logical operation, bind it to the authenticated scope and store the final result atomically. Retrying the same key should return the prior committed result. Disable duplicate submission while pending and only display success after commit.
No database schema or migrations ship with this UI release. Do not use the demo login, role config or JavaScript visibility as a production security boundary. Do not store real passwords in browser storage. Replace demo social login, recovery, verification and logout with your identity provider.
15. Add components & create client projects
Copy the framework into the new project, replace configuration and demo data, register your pages and integrate backend routes. Keep common PHP helpers in components/, page-specific markup in pages/ and script modules under assets/js/. Load page-specific scripts only where needed. New components should work in dark/light, RTL, compact and mobile modes. Avoid adding a dependency when native browser features cover the requirement.
16. Updating Zeehaak AP
Keep a versioned copy of your integration. Back up config, custom pages, assets and any external application database before updating. Compare CHANGELOG.md and review changes in shared components before merging. Re-run your authorization, data isolation, duplicate submission and UI checks after an update. Never overwrite project configuration or stored data with demo fixtures.
17. Dependencies & commercial reuse
No third-party CSS, JavaScript, font, icon or image assets are bundled in the runtime. The SVG logo, icon markup, theme, components and example scripts were authored for this project. System fonts are requested by name and are not redistributed. PHP and the browser are execution requirements, not included software. Local acceptance tests can use a separately installed Playwright; it is not shipped as a runtime dependency.
See docs/DEPENDENCIES.md for the inventory and docs/COMMERCIAL_REUSE.md for packaging guidance. Preserve this inventory when adding third-party assets and review their actual distribution terms. The project includes no third-party licensing promises and no assertion that a product name is trademark-cleared.
18. Troubleshooting
- PHP code appears as text: open through a PHP server, not the filesystem.
- Styles are missing: confirm assets/css/theme.php and zeehaak.css return successfully. Keep the folder structure intact.
- Old appearance remains: use Reset appearance or clear the zeehaak.ap.appearance key.
- A menu is missing or a page is denied: inspect demo_role, role grants and the page's required permission.
- A form does not save: all shipped forms are local validation demonstrations. Add a backend to persist records.
- A table is empty: clear search, date and status filters. From must not exceed To.
- Popover or dialog behavior differs: use a modern browser with native dialog, inert and Popover API support.
- Real mail, OTP and social sign-in do not work: these are explicit UI placeholders.
19. Accessibility & testing
The framework includes a skip link, visible focus, semantic controls, accessible labels, live status messages, keyboard tabs, native dialog focus management, mobile sidebar focus containment and reduced-motion support. These measures are not a formal accessibility certification. Run the included acceptance checks and review your actual content with assistive technology before release.
tests/acceptance.cjs accepts BASE_URL, PLAYWRIGHT_MODULE and optional BROWSER_EXECUTABLE environment variables. It checks pages, controls, viewports, dark mode, RTL, navigation and assets. The checked-in TEST_REPORT.md records the tested environment and any limits. After connecting a backend, add integration tests for retries, database uniqueness, ownership and tenant isolation.