diff --git a/src/components/AdminShell.tsx b/src/components/AdminShell.tsx
index e69f188..3d2ea04 100644
--- a/src/components/AdminShell.tsx
+++ b/src/components/AdminShell.tsx
@@ -12,6 +12,7 @@ const TAB_SETS: Array<{ prefixes: string[]; tabs: Tab[] }> = [
tabs: [
{ href: '/admin/roles', label: 'Internal Roles', exact: true },
{ href: '/admin/roles/create', label: 'Create Role' },
+ { href: '/admin/roles/templates', label: 'Role Templates' },
],
},
{
@@ -50,6 +51,14 @@ const TAB_SETS: Array<{ prefixes: string[]; tabs: Tab[] }> = [
];
const PAGE_TITLES: Array<{ prefix: string; title: string }> = [
+ { prefix: '/admin/workspace', title: 'Dashboard Workspace' },
+ { prefix: '/admin/settings', title: 'Settings' },
+ { prefix: '/admin/role-modules', title: 'Role Modules' },
+ { prefix: '/admin/modules', title: 'Module Management' },
+ { prefix: '/admin/responses', title: 'Lead Responses' },
+ { prefix: '/admin/applications', title: 'Applications' },
+ { prefix: '/admin/financial', title: 'Financial Management' },
+ { prefix: '/admin/help', title: 'Support Management' },
{ prefix: '/admin/verification-status', title: 'Verification Status' },
{ prefix: '/admin/verification', title: 'Verification Review' },
{ prefix: '/admin/approval', title: 'Approval Management' },
@@ -69,7 +78,10 @@ const PAGE_TITLES: Array<{ prefix: string; title: string }> = [
{ prefix: '/admin/ledger', title: 'Ledger Management' },
{ prefix: '/admin/report', title: 'Report Management' },
{ prefix: '/admin/roles', title: 'Internal Role Management' },
+ { prefix: '/admin/external-role-management', title: 'External Role Management' },
+ { prefix: '/admin/internal-role-management', title: 'Internal Role Management' },
{ prefix: '/admin/runtime-roles', title: 'External Role Management' },
+ { prefix: '/admin/onboarding-management', title: 'Onboarding Management' },
{ prefix: '/admin/onboarding-schemas', title: 'Onboarding Management' },
{ prefix: '/admin', title: 'Dashboard' },
];
diff --git a/src/routes/admin/applications.tsx b/src/routes/admin/applications.tsx
new file mode 100644
index 0000000..d756c2a
--- /dev/null
+++ b/src/routes/admin/applications.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function ApplicationsAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/jobs', { replace: true }));
+ return Redirecting to jobs management...
;
+}
diff --git a/src/routes/admin/company.tsx b/src/routes/admin/company.tsx
index 2ffcc94..bb1b926 100644
--- a/src/routes/admin/company.tsx
+++ b/src/routes/admin/company.tsx
@@ -77,6 +77,7 @@ export default function CompanyPage() {
Company Management
Manage all company accounts on the platform.
+ Create Company
diff --git a/src/routes/admin/company/[id].tsx b/src/routes/admin/company/[id].tsx
new file mode 100644
index 0000000..f5fd66d
--- /dev/null
+++ b/src/routes/admin/company/[id].tsx
@@ -0,0 +1,101 @@
+import { A, useParams } from '@solidjs/router';
+import { createMemo, createResource, Show } from 'solid-js';
+import AdminShell from '~/components/AdminShell';
+
+const API = '/api/gateway';
+
+type CompanyDetail = {
+ id: string;
+ company_name?: string;
+ companyName?: string;
+ company_id?: string;
+ companyId?: string;
+ industry?: string;
+ email?: string;
+ phone?: string;
+ website_url?: string;
+ websiteUrl?: string;
+ city?: string;
+ state?: string;
+ address?: string;
+ status?: string;
+ is_verified?: boolean;
+ isVerified?: boolean;
+ description?: string;
+ pan?: string;
+ gst?: string;
+ tan?: string;
+};
+
+async function fetchCompany(id: string): Promise {
+ try {
+ const res = await fetch(`${API}/api/admin/companies/${id}`);
+ if (!res.ok) return null;
+ const data = await res.json();
+ return data.company || data;
+ } catch {
+ return null;
+ }
+}
+
+export default function CompanyDetailPage() {
+ const params = useParams();
+ const [company] = createResource(() => params.id, fetchCompany);
+
+ const name = createMemo(() => company()?.company_name || company()?.companyName || 'Company');
+ const cid = createMemo(() => company()?.company_id || company()?.companyId || company()?.id || '—');
+ const website = createMemo(() => company()?.website_url || company()?.websiteUrl || '');
+ const isVerified = createMemo(() => Boolean(company()?.is_verified ?? company()?.isVerified));
+
+ return (
+
+
+
+
Company Detail
+
Review company profile, contact details, and verification readiness.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Company
+ Name: {name()}
+ Company ID: {cid()}
+ Industry: {company()!.industry || '—'}
+ Status: {company()!.status || '—'}
+ Verification: {isVerified() ? 'Verified' : 'Not Verified'}
+
+
+ Contact
+ Email: {company()!.email || '—'}
+ Phone: {company()!.phone || '—'}
+ City/State: {[company()!.city, company()!.state].filter(Boolean).join(', ') || '—'}
+ Address: {company()!.address || '—'}
+ Website: {website() ? {website()} : '—'}
+
+
+
+
+ Compliance
+
+
PAN: {company()!.pan || '—'}
+
GST: {company()!.gst || '—'}
+
TAN: {company()!.tan || '—'}
+
+
+
+
+ );
+}
diff --git a/src/routes/admin/company/create.tsx b/src/routes/admin/company/create.tsx
new file mode 100644
index 0000000..f92546a
--- /dev/null
+++ b/src/routes/admin/company/create.tsx
@@ -0,0 +1,111 @@
+import { A, useNavigate } from '@solidjs/router';
+import { createSignal, Show } from 'solid-js';
+import AdminShell from '~/components/AdminShell';
+
+const API = '/api/gateway';
+
+export default function CreateCompanyPage() {
+ const navigate = useNavigate();
+ const [saving, setSaving] = createSignal(false);
+ const [error, setError] = createSignal('');
+ const [form, setForm] = createSignal({
+ companyName: '',
+ companyId: '',
+ address: '',
+ email: '',
+ phone: '',
+ industry: 'TECHNOLOGY',
+ description: '',
+ websiteUrl: '',
+ });
+
+ const setField = (k: keyof ReturnType, v: string) => {
+ setForm((prev) => ({ ...prev, [k]: v }));
+ };
+
+ const submit = async (e: Event) => {
+ e.preventDefault();
+ const f = form();
+ if (!f.companyName.trim() || !f.companyId.trim() || !f.address.trim() || !f.email.trim() || !f.phone.trim()) {
+ setError('Please fill all required fields.');
+ return;
+ }
+ try {
+ setSaving(true);
+ setError('');
+ const res = await fetch(`${API}/api/admin/companies`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(f),
+ });
+ if (!res.ok) {
+ const payload = await res.json().catch(() => ({}));
+ throw new Error(payload.message || 'Failed to create company');
+ }
+ navigate('/admin/company');
+ } catch (err: any) {
+ setError(err.message || 'Failed to create company');
+ } finally {
+ setSaving(false);
+ }
+ };
+
+ return (
+
+
+
+
Create Company
+
Add a new organization profile to the admin company catalog.
+
+
Back to Companies
+
+
+
+ {error()}
+
+
+
+
+ );
+}
diff --git a/src/routes/admin/employees.tsx b/src/routes/admin/employees.tsx
index 259f13d..80fee41 100644
--- a/src/routes/admin/employees.tsx
+++ b/src/routes/admin/employees.tsx
@@ -1,5 +1,5 @@
-import { A, useNavigate } from '@solidjs/router';
-import { createResource, createSignal, Show, For } from 'solid-js';
+import { A, useNavigate, useSearchParams } from '@solidjs/router';
+import { createResource, createSignal, Show, For, onMount } from 'solid-js';
import AdminShell from '~/components/AdminShell';
const API = '/api/gateway';
@@ -60,6 +60,7 @@ function isActive(e: Employee): boolean {
export default function EmployeesPage() {
const navigate = useNavigate();
+ const [searchParams] = useSearchParams();
const [employees, { refetch }] = createResource(loadEmployees);
const [roles] = createResource(loadRoles);
@@ -67,6 +68,12 @@ export default function EmployeesPage() {
// tabs: list | create
const [view, setView] = createSignal<'list' | 'create'>('list');
+ onMount(() => {
+ if (searchParams.tab === 'create') {
+ setView('create');
+ }
+ });
+
// create form fields
const [formName, setFormName] = createSignal('');
const [formEmail, setFormEmail] = createSignal('');
diff --git a/src/routes/admin/employees/[id]/edit.tsx b/src/routes/admin/employees/[id]/edit.tsx
new file mode 100644
index 0000000..d7c94b4
--- /dev/null
+++ b/src/routes/admin/employees/[id]/edit.tsx
@@ -0,0 +1,132 @@
+import { A, useNavigate, useParams } from '@solidjs/router';
+import { createMemo, createResource, createSignal, Show } from 'solid-js';
+import AdminShell from '~/components/AdminShell';
+
+const API = '/api/gateway';
+
+type Role = { id: string; name: string };
+type Employee = { id: string; name?: string; full_name?: string; email: string; role_id?: string; role?: { id?: string } };
+
+async function fetchEmployee(id: string): Promise {
+ try {
+ const res = await fetch(`${API}/api/admin/employees/${id}`);
+ if (!res.ok) return null;
+ return res.json();
+ } catch {
+ return null;
+ }
+}
+
+async function fetchRoles(): Promise {
+ try {
+ const res = await fetch(`${API}/api/admin/roles?audience=INTERNAL`);
+ if (!res.ok) return [];
+ const data = await res.json();
+ return Array.isArray(data) ? data : (data.roles || []);
+ } catch {
+ return [];
+ }
+}
+
+export default function EditEmployeePage() {
+ const params = useParams();
+ const navigate = useNavigate();
+ const [employee] = createResource(() => params.id, fetchEmployee);
+ const [roles] = createResource(fetchRoles);
+
+ const [name, setName] = createSignal('');
+ const [email, setEmail] = createSignal('');
+ const [roleId, setRoleId] = createSignal('');
+ const [saving, setSaving] = createSignal(false);
+ const [error, setError] = createSignal('');
+
+ createMemo(() => {
+ const e = employee();
+ if (!e) return null;
+ setName(e.name || e.full_name || '');
+ setEmail(e.email || '');
+ setRoleId(e.role_id || e.role?.id || '');
+ return null;
+ });
+
+ const submit = async (e: Event) => {
+ e.preventDefault();
+ if (!name().trim() || !email().trim() || !roleId()) {
+ setError('Name, email, and role are required.');
+ return;
+ }
+ try {
+ setSaving(true);
+ setError('');
+ const res = await fetch(`${API}/api/admin/employees/${params.id}`, {
+ method: 'PATCH',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ name: name().trim(), email: email().trim(), role_id: roleId() }),
+ });
+ if (!res.ok) {
+ const payload = await res.json().catch(() => ({}));
+ throw new Error(payload.message || 'Failed to update employee');
+ }
+ navigate('/admin/employees');
+ } catch (err: any) {
+ setError(err.message || 'Failed to update employee');
+ } finally {
+ setSaving(false);
+ }
+ };
+
+ return (
+
+
+
+
Edit Employee
+
Update internal employee profile and role assignment.
+
+
Back to Employees
+
+
+
+ {error()}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/routes/admin/employees/create.tsx b/src/routes/admin/employees/create.tsx
new file mode 100644
index 0000000..e042261
--- /dev/null
+++ b/src/routes/admin/employees/create.tsx
@@ -0,0 +1,19 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function CreateEmployeeAliasPage() {
+ const navigate = useNavigate();
+
+ onMount(() => {
+ navigate('/admin/employees?tab=create', { replace: true });
+ });
+
+ return (
+
+
+
Redirecting to employee create form...
+
+
+ );
+}
diff --git a/src/routes/admin/external-role-management.tsx b/src/routes/admin/external-role-management.tsx
new file mode 100644
index 0000000..05bb13a
--- /dev/null
+++ b/src/routes/admin/external-role-management.tsx
@@ -0,0 +1,13 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function ExternalRoleManagementAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/runtime-roles', { replace: true }));
+ return (
+
+ Redirecting to external role management...
+
+ );
+}
diff --git a/src/routes/admin/financial/adjust-credit.tsx b/src/routes/admin/financial/adjust-credit.tsx
new file mode 100644
index 0000000..394642d
--- /dev/null
+++ b/src/routes/admin/financial/adjust-credit.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function AdjustCreditAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/credit', { replace: true }));
+ return Redirecting to credit management...
;
+}
diff --git a/src/routes/admin/financial/reconcile.tsx b/src/routes/admin/financial/reconcile.tsx
new file mode 100644
index 0000000..c8d6fe8
--- /dev/null
+++ b/src/routes/admin/financial/reconcile.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function ReconcileAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/ledger', { replace: true }));
+ return Redirecting to ledger management...
;
+}
diff --git a/src/routes/admin/help.tsx b/src/routes/admin/help.tsx
new file mode 100644
index 0000000..2caa6cc
--- /dev/null
+++ b/src/routes/admin/help.tsx
@@ -0,0 +1,13 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function HelpAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/support', { replace: true }));
+ return (
+
+ Redirecting to support management...
+
+ );
+}
diff --git a/src/routes/admin/help/[id].tsx b/src/routes/admin/help/[id].tsx
new file mode 100644
index 0000000..151b4ed
--- /dev/null
+++ b/src/routes/admin/help/[id].tsx
@@ -0,0 +1,25 @@
+import { A, useParams } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function HelpArticlePage() {
+ const params = useParams();
+ return (
+
+
+
+
Help Article
+
Legacy help article route preserved for migration compatibility.
+
+
Back to Support
+
+
+
+ Article ID: {params.id}
+
+
+ Detailed knowledge base article rendering is handled in the support/KB modules during this migration phase.
+
+
+
+ );
+}
diff --git a/src/routes/admin/help/support-bridge.tsx b/src/routes/admin/help/support-bridge.tsx
new file mode 100644
index 0000000..735a2ce
--- /dev/null
+++ b/src/routes/admin/help/support-bridge.tsx
@@ -0,0 +1,20 @@
+import { A } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function HelpSupportBridgePage() {
+ return (
+
+
+
Support Bridge
+
+ This legacy help bridge now routes through the unified Support Management module.
+
+
+
+
+ );
+}
diff --git a/src/routes/admin/internal-role-management.tsx b/src/routes/admin/internal-role-management.tsx
new file mode 100644
index 0000000..65b41fe
--- /dev/null
+++ b/src/routes/admin/internal-role-management.tsx
@@ -0,0 +1,13 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function InternalRoleManagementAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/roles', { replace: true }));
+ return (
+
+ Redirecting to internal role management...
+
+ );
+}
diff --git a/src/routes/admin/kb/articles.tsx b/src/routes/admin/kb/articles.tsx
new file mode 100644
index 0000000..d2195ad
--- /dev/null
+++ b/src/routes/admin/kb/articles.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function KbArticlesAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/kb', { replace: true }));
+ return Redirecting to knowledge base...
;
+}
diff --git a/src/routes/admin/kb/articles/[id].tsx b/src/routes/admin/kb/articles/[id].tsx
new file mode 100644
index 0000000..18b61c3
--- /dev/null
+++ b/src/routes/admin/kb/articles/[id].tsx
@@ -0,0 +1,17 @@
+import { onMount } from 'solid-js';
+import { A, useNavigate, useParams } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function KbArticleAliasPage() {
+ const navigate = useNavigate();
+ const params = useParams();
+ onMount(() => navigate('/admin/kb', { replace: true }));
+ return (
+
+
+
Redirecting article {params.id} to knowledge base module...
+
+
+
+ );
+}
diff --git a/src/routes/admin/kb/articles/[id]/edit.tsx b/src/routes/admin/kb/articles/[id]/edit.tsx
new file mode 100644
index 0000000..ad7dc5e
--- /dev/null
+++ b/src/routes/admin/kb/articles/[id]/edit.tsx
@@ -0,0 +1,17 @@
+import { onMount } from 'solid-js';
+import { A, useNavigate, useParams } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function KbArticleEditAliasPage() {
+ const navigate = useNavigate();
+ const params = useParams();
+ onMount(() => navigate('/admin/kb', { replace: true }));
+ return (
+
+
+
Redirecting article edit {params.id} to knowledge base module...
+
+
+
+ );
+}
diff --git a/src/routes/admin/kb/articles/new.tsx b/src/routes/admin/kb/articles/new.tsx
new file mode 100644
index 0000000..80a99b5
--- /dev/null
+++ b/src/routes/admin/kb/articles/new.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function KbArticleNewAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/kb', { replace: true }));
+ return Redirecting to knowledge base editor...
;
+}
diff --git a/src/routes/admin/kb/categories.tsx b/src/routes/admin/kb/categories.tsx
new file mode 100644
index 0000000..d61d9c5
--- /dev/null
+++ b/src/routes/admin/kb/categories.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function KbCategoriesAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/kb', { replace: true }));
+ return Redirecting to knowledge base categories...
;
+}
diff --git a/src/routes/admin/leads/[id].tsx b/src/routes/admin/leads/[id].tsx
new file mode 100644
index 0000000..b0790ff
--- /dev/null
+++ b/src/routes/admin/leads/[id].tsx
@@ -0,0 +1,82 @@
+import { A, useParams } from '@solidjs/router';
+import { createMemo, createResource, Show } from 'solid-js';
+import AdminShell from '~/components/AdminShell';
+
+const API = '/api/gateway';
+
+type Lead = {
+ id: string;
+ requirementId?: string;
+ requirement_id?: string;
+ profession?: string;
+ customerId?: string;
+ customer_id?: string;
+ professionalId?: string;
+ professional_id?: string;
+ status?: string;
+ createdAt?: string;
+ created_at?: string;
+ updatedAt?: string;
+ updated_at?: string;
+};
+
+async function fetchLead(id: string): Promise {
+ try {
+ const res = await fetch(`${API}/api/leads/${id}`);
+ if (!res.ok) return null;
+ const data = await res.json();
+ return data.lead || data;
+ } catch {
+ return null;
+ }
+}
+
+export default function LeadDetailPage() {
+ const params = useParams();
+ const [lead] = createResource(() => params.id, fetchLead);
+
+ const requirementId = createMemo(() => lead()?.requirementId || lead()?.requirement_id || '');
+ const customerId = createMemo(() => lead()?.customerId || lead()?.customer_id || '');
+ const professionalId = createMemo(() => lead()?.professionalId || lead()?.professional_id || '');
+ const createdAt = createMemo(() => lead()?.createdAt || lead()?.created_at || '');
+ const updatedAt = createMemo(() => lead()?.updatedAt || lead()?.updated_at || '');
+
+ return (
+
+
+
+
Lead Detail
+
Review one lead and its linked requirement identifiers.
+
+
Back to Leads
+
+
+
+
+
+
+
+
+
+
+
+
+
Lead ID: {lead()!.id}
+
Status: {lead()!.status || '—'}
+
Profession: {lead()!.profession || '—'}
+
Requirement ID: {requirementId() || '—'}
+
Customer ID: {customerId() || '—'}
+
Professional ID: {professionalId() || 'Unassigned'}
+
Created: {createdAt() ? new Date(createdAt()).toLocaleString() : '—'}
+
Updated: {updatedAt() ? new Date(updatedAt()).toLocaleString() : '—'}
+
+
+
+
+
+ );
+}
diff --git a/src/routes/admin/modules.tsx b/src/routes/admin/modules.tsx
new file mode 100644
index 0000000..e044420
--- /dev/null
+++ b/src/routes/admin/modules.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function ModulesAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/internal-dashboard-management', { replace: true }));
+ return Redirecting to dashboard module configuration...
;
+}
diff --git a/src/routes/admin/onboarding-management.tsx b/src/routes/admin/onboarding-management.tsx
new file mode 100644
index 0000000..4d59547
--- /dev/null
+++ b/src/routes/admin/onboarding-management.tsx
@@ -0,0 +1,13 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function OnboardingManagementAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/onboarding-schemas', { replace: true }));
+ return (
+
+ Redirecting to onboarding management...
+
+ );
+}
diff --git a/src/routes/admin/photographer.tsx b/src/routes/admin/photographer.tsx
index dfb25dc..2fe8eb2 100644
--- a/src/routes/admin/photographer.tsx
+++ b/src/routes/admin/photographer.tsx
@@ -108,7 +108,7 @@ export default function PhotographerPage() {
|
diff --git a/src/routes/admin/photographer/[id].tsx b/src/routes/admin/photographer/[id].tsx
new file mode 100644
index 0000000..dd1ba67
--- /dev/null
+++ b/src/routes/admin/photographer/[id].tsx
@@ -0,0 +1,77 @@
+import { A, useParams } from '@solidjs/router';
+import { createMemo, createResource, Show } from 'solid-js';
+import AdminShell from '~/components/AdminShell';
+
+const API = '/api/gateway';
+
+type Photographer = {
+ id: string;
+ name?: string;
+ full_name?: string;
+ email?: string;
+ phone?: string;
+ status?: string;
+ created_at?: string;
+ createdAt?: string;
+ city?: string;
+ state?: string;
+ experience?: string;
+ portfolio_url?: string;
+};
+
+async function fetchPhotographer(id: string): Promise {
+ try {
+ const res = await fetch(`${API}/api/admin/users/${id}`);
+ if (res.ok) return res.json();
+ const fallback = await fetch(`${API}/api/users/${id}`);
+ if (!fallback.ok) return null;
+ return fallback.json();
+ } catch {
+ return null;
+ }
+}
+
+export default function PhotographerDetailPage() {
+ const params = useParams();
+ const [profile] = createResource(() => params.id, fetchPhotographer);
+
+ const name = createMemo(() => profile()?.name || profile()?.full_name || 'Photographer');
+ const created = createMemo(() => profile()?.createdAt || profile()?.created_at || '');
+
+ return (
+
+
+
+
Photographer Detail
+
View profile snapshot and account metadata for one photographer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Name: {name()}
+
Email: {profile()!.email || '—'}
+
Phone: {profile()!.phone || '—'}
+
Status: {profile()!.status || '—'}
+
City/State: {[profile()!.city, profile()!.state].filter(Boolean).join(', ') || '—'}
+
Experience: {profile()!.experience || '—'}
+
Created: {created() ? new Date(created()).toLocaleString() : '—'}
+
Portfolio: {profile()!.portfolio_url || '—'}
+
+
+
+
+ );
+}
diff --git a/src/routes/admin/profile/[id].tsx b/src/routes/admin/profile/[id].tsx
new file mode 100644
index 0000000..93232d4
--- /dev/null
+++ b/src/routes/admin/profile/[id].tsx
@@ -0,0 +1,10 @@
+import { onMount } from 'solid-js';
+import { useNavigate, useParams } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function ProfileAliasPage() {
+ const navigate = useNavigate();
+ const params = useParams();
+ onMount(() => navigate(`/admin/users/details/${params.id}`, { replace: true }));
+ return Redirecting to user profile detail...
;
+}
diff --git a/src/routes/admin/responses.tsx b/src/routes/admin/responses.tsx
new file mode 100644
index 0000000..08e6f3d
--- /dev/null
+++ b/src/routes/admin/responses.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function ResponsesAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/leads', { replace: true }));
+ return Redirecting to lead responses management...
;
+}
diff --git a/src/routes/admin/role-modules.tsx b/src/routes/admin/role-modules.tsx
new file mode 100644
index 0000000..f471fa6
--- /dev/null
+++ b/src/routes/admin/role-modules.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function RoleModulesAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/role-ui-configs', { replace: true }));
+ return Redirecting to role module configuration...
;
+}
diff --git a/src/routes/admin/roles/templates.tsx b/src/routes/admin/roles/templates.tsx
new file mode 100644
index 0000000..624ad49
--- /dev/null
+++ b/src/routes/admin/roles/templates.tsx
@@ -0,0 +1,92 @@
+import { A } from '@solidjs/router';
+import { createMemo, createResource, For, Show } from 'solid-js';
+import AdminShell from '~/components/AdminShell';
+
+const API = '/api/gateway';
+
+type RoleTemplate = {
+ id: string;
+ name: string;
+ description?: string;
+ code?: string;
+ audience?: string;
+};
+
+async function fetchTemplates(): Promise {
+ try {
+ const res = await fetch(`${API}/api/admin/roles?audience=INTERNAL`);
+ if (!res.ok) return [];
+ const data = await res.json();
+ const rows = Array.isArray(data) ? data : (data.roles || []);
+ return rows.map((r: any) => ({
+ id: r.id,
+ name: r.name,
+ description: r.description || '',
+ code: r.code || r.key || '',
+ audience: r.audience || 'INTERNAL',
+ }));
+ } catch {
+ return [];
+ }
+}
+
+export default function RoleTemplatesPage() {
+ const [templates] = createResource(fetchTemplates);
+ const count = createMemo(() => (templates() || []).length);
+
+ return (
+
+
+
+
Role Templates
+
Starter role presets for faster internal role creation and cloning.
+
+
Create Internal Role
+
+
+
+
+
Available Templates
+ {count()} template{count() !== 1 ? 's' : ''}
+
+
+
+
+
+ | Name |
+ Description |
+ Code |
+ Actions |
+
+
+
+
+ | Loading templates... |
+
+
+ | No templates available yet. |
+
+ 0}>
+
+ {(item) => (
+
+ | {item.name} |
+ {item.description || '—'} |
+ {item.code || '—'} |
+
+
+ |
+
+ )}
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/routes/admin/settings.tsx b/src/routes/admin/settings.tsx
new file mode 100644
index 0000000..9d25bee
--- /dev/null
+++ b/src/routes/admin/settings.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function SettingsAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin/internal-dashboard-management', { replace: true }));
+ return Redirecting to settings/configuration...
;
+}
diff --git a/src/routes/admin/workspace.tsx b/src/routes/admin/workspace.tsx
new file mode 100644
index 0000000..646b64a
--- /dev/null
+++ b/src/routes/admin/workspace.tsx
@@ -0,0 +1,9 @@
+import { onMount } from 'solid-js';
+import { useNavigate } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function WorkspaceAliasPage() {
+ const navigate = useNavigate();
+ onMount(() => navigate('/admin', { replace: true }));
+ return Redirecting to dashboard workspace...
;
+}
diff --git a/src/routes/admin/workspace/[menuId].tsx b/src/routes/admin/workspace/[menuId].tsx
new file mode 100644
index 0000000..b02e9f0
--- /dev/null
+++ b/src/routes/admin/workspace/[menuId].tsx
@@ -0,0 +1,16 @@
+import { onMount } from 'solid-js';
+import { useNavigate, useParams } from '@solidjs/router';
+import AdminShell from '~/components/AdminShell';
+
+export default function WorkspaceMenuAliasPage() {
+ const navigate = useNavigate();
+ const params = useParams();
+ onMount(() => navigate('/admin', { replace: true }));
+ return (
+
+
+
Redirecting workspace menu {params.menuId} to dashboard...
+
+
+ );
+}