From 0866b7a069e2b704dbcde6fc1d9f0919b4bc819c Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Sivakumar Date: Tue, 14 Jul 2026 21:24:02 +0530 Subject: [PATCH] fix(admin): add missing detail pages for 8 profession admin lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each of these profession admin list pages (makeup artist, tutor, developer, video editor, graphic designer, social media manager, fitness trainer, catering services) linked "View Profile" to /admin/{role}/{id}, but only Photographer and Company had a real [id].tsx route — every other role fell through to the legacy catch-all module and showed a placeholder instead of the applicant's actual profile. Converts each flat list route into a folder (index.tsx + [id].tsx) and adds a shared ProfessionDetailPage component, modeled on the working Photographer detail page. Co-Authored-By: Claude Sonnet 5 --- src/components/admin/ProfessionDetailPage.tsx | 163 ++++++++++++++++++ src/routes/admin/catering-services/[id].tsx | 12 ++ .../index.tsx} | 0 src/routes/admin/developers/[id].tsx | 12 ++ .../{developers.tsx => developers/index.tsx} | 0 src/routes/admin/fitness-trainers/[id].tsx | 12 ++ .../index.tsx} | 0 src/routes/admin/graphic-designers/[id].tsx | 12 ++ .../index.tsx} | 0 src/routes/admin/makeup-artist/[id].tsx | 12 ++ .../index.tsx} | 0 .../admin/social-media-managers/[id].tsx | 12 ++ .../index.tsx} | 0 src/routes/admin/tutors/[id].tsx | 12 ++ .../admin/{tutors.tsx => tutors/index.tsx} | 0 src/routes/admin/video-editors/[id].tsx | 12 ++ .../index.tsx} | 0 17 files changed, 259 insertions(+) create mode 100644 src/components/admin/ProfessionDetailPage.tsx create mode 100644 src/routes/admin/catering-services/[id].tsx rename src/routes/admin/{catering-services.tsx => catering-services/index.tsx} (100%) create mode 100644 src/routes/admin/developers/[id].tsx rename src/routes/admin/{developers.tsx => developers/index.tsx} (100%) create mode 100644 src/routes/admin/fitness-trainers/[id].tsx rename src/routes/admin/{fitness-trainers.tsx => fitness-trainers/index.tsx} (100%) create mode 100644 src/routes/admin/graphic-designers/[id].tsx rename src/routes/admin/{graphic-designers.tsx => graphic-designers/index.tsx} (100%) create mode 100644 src/routes/admin/makeup-artist/[id].tsx rename src/routes/admin/{makeup-artist.tsx => makeup-artist/index.tsx} (100%) create mode 100644 src/routes/admin/social-media-managers/[id].tsx rename src/routes/admin/{social-media-managers.tsx => social-media-managers/index.tsx} (100%) create mode 100644 src/routes/admin/tutors/[id].tsx rename src/routes/admin/{tutors.tsx => tutors/index.tsx} (100%) create mode 100644 src/routes/admin/video-editors/[id].tsx rename src/routes/admin/{video-editors.tsx => video-editors/index.tsx} (100%) diff --git a/src/components/admin/ProfessionDetailPage.tsx b/src/components/admin/ProfessionDetailPage.tsx new file mode 100644 index 0000000..cbc7cb0 --- /dev/null +++ b/src/components/admin/ProfessionDetailPage.tsx @@ -0,0 +1,163 @@ +import { A, useParams } from '@solidjs/router'; +import { For, createMemo, createResource, Show } from 'solid-js'; + +const API = ''; + +type ProfessionProfile = { + id: string; + name?: string; + full_name?: string; + first_name?: string; + last_name?: string; + email?: string; + phone?: string; + status?: string; + created_at?: string; + createdAt?: string; + city?: string; + state?: string; + experience?: string; + portfolio_url?: string; + phoneNumber?: string; + location?: string; + gender?: string; + availability?: string; + permanentAddress?: string; + hometown?: string; + pincode?: string; + languages?: Array<{ language?: string; proficiency?: string }>; +}; + +async function fetchProfile(id: string, apiSlug: 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 fallback.json(); + const roleRes = await fetch(`${API}/api/${apiSlug}/${id}`); + if (!roleRes.ok) return null; + return roleRes.json(); + } catch { + return null; + } +} + +/** + * Generic admin detail/drill-down page shared by every profession's "View Profile" + * link. Modeled on the Photographer detail page's fetch pattern (which already + * works via /api/admin/users/{id}) so each profession doesn't need its own + * bespoke backend endpoint just to render a read-only snapshot. + */ +export default function ProfessionDetailPage(props: { + roleLabel: string; + apiSlug: string; + backHref: string; + backLabel: string; +}) { + const params = useParams(); + const [profile] = createResource(() => params.id, (id) => fetchProfile(id, props.apiSlug)); + + const name = createMemo(() => { + const p = profile(); + if (!p) return props.roleLabel; + return ( + p.name || + p.full_name || + [p.first_name, p.last_name].filter(Boolean).join(' ') || + props.roleLabel + ); + }); + const created = createMemo(() => profile()?.createdAt || profile()?.created_at || ''); + + return ( +
+
+
+

{props.roleLabel} Detail

+

View profile snapshot and account metadata for one {props.roleLabel.toLowerCase()}.

+
+ +
+
+ +

Loading {props.roleLabel.toLowerCase()}...

+
+ +

{props.roleLabel} not found.

+
+ + +
+
+
+

Name

+

{name()}

+
+
+

Email

+

{profile()!.email || '—'}

+
+
+

Phone

+

{profile()!.phone || profile()!.phoneNumber || '—'}

+
+
+

Location

+

{profile()!.location || [profile()!.city, profile()!.state].filter(Boolean).join(', ') || '—'}

+
+
+

Gender

+

{profile()!.gender || '—'}

+
+
+

Experience

+

{profile()!.experience || '—'}

+
+
+

Availability

+

{profile()!.availability || '—'}

+
+
+

Permanent Address

+

{profile()!.permanentAddress || '—'}

+
+
+

Hometown

+

{profile()!.hometown || '—'}

+
+
+

Pincode

+

{profile()!.pincode || '—'}

+
+
+

Status

+

{profile()!.status || '—'}

+
+
+

Created

+

{created() ? new Date(created()).toLocaleString() : '—'}

+
+
+

Portfolio

+

{profile()!.portfolio_url || '—'}

+
+ 0}> +
+

Languages

+
    + + {(item) =>
  • {item.language || 'Unknown'} - {item.proficiency || 'N/A'}
  • } +
    +
+
+
+
+
+
+
+
+ ); +} diff --git a/src/routes/admin/catering-services/[id].tsx b/src/routes/admin/catering-services/[id].tsx new file mode 100644 index 0000000..8ed2899 --- /dev/null +++ b/src/routes/admin/catering-services/[id].tsx @@ -0,0 +1,12 @@ +import ProfessionDetailPage from '~/components/admin/ProfessionDetailPage'; + +export default function Page() { + return ( + + ); +} diff --git a/src/routes/admin/catering-services.tsx b/src/routes/admin/catering-services/index.tsx similarity index 100% rename from src/routes/admin/catering-services.tsx rename to src/routes/admin/catering-services/index.tsx diff --git a/src/routes/admin/developers/[id].tsx b/src/routes/admin/developers/[id].tsx new file mode 100644 index 0000000..1c114c1 --- /dev/null +++ b/src/routes/admin/developers/[id].tsx @@ -0,0 +1,12 @@ +import ProfessionDetailPage from '~/components/admin/ProfessionDetailPage'; + +export default function Page() { + return ( + + ); +} diff --git a/src/routes/admin/developers.tsx b/src/routes/admin/developers/index.tsx similarity index 100% rename from src/routes/admin/developers.tsx rename to src/routes/admin/developers/index.tsx diff --git a/src/routes/admin/fitness-trainers/[id].tsx b/src/routes/admin/fitness-trainers/[id].tsx new file mode 100644 index 0000000..2a298a1 --- /dev/null +++ b/src/routes/admin/fitness-trainers/[id].tsx @@ -0,0 +1,12 @@ +import ProfessionDetailPage from '~/components/admin/ProfessionDetailPage'; + +export default function Page() { + return ( + + ); +} diff --git a/src/routes/admin/fitness-trainers.tsx b/src/routes/admin/fitness-trainers/index.tsx similarity index 100% rename from src/routes/admin/fitness-trainers.tsx rename to src/routes/admin/fitness-trainers/index.tsx diff --git a/src/routes/admin/graphic-designers/[id].tsx b/src/routes/admin/graphic-designers/[id].tsx new file mode 100644 index 0000000..7d40418 --- /dev/null +++ b/src/routes/admin/graphic-designers/[id].tsx @@ -0,0 +1,12 @@ +import ProfessionDetailPage from '~/components/admin/ProfessionDetailPage'; + +export default function Page() { + return ( + + ); +} diff --git a/src/routes/admin/graphic-designers.tsx b/src/routes/admin/graphic-designers/index.tsx similarity index 100% rename from src/routes/admin/graphic-designers.tsx rename to src/routes/admin/graphic-designers/index.tsx diff --git a/src/routes/admin/makeup-artist/[id].tsx b/src/routes/admin/makeup-artist/[id].tsx new file mode 100644 index 0000000..948445d --- /dev/null +++ b/src/routes/admin/makeup-artist/[id].tsx @@ -0,0 +1,12 @@ +import ProfessionDetailPage from '~/components/admin/ProfessionDetailPage'; + +export default function Page() { + return ( + + ); +} diff --git a/src/routes/admin/makeup-artist.tsx b/src/routes/admin/makeup-artist/index.tsx similarity index 100% rename from src/routes/admin/makeup-artist.tsx rename to src/routes/admin/makeup-artist/index.tsx diff --git a/src/routes/admin/social-media-managers/[id].tsx b/src/routes/admin/social-media-managers/[id].tsx new file mode 100644 index 0000000..2dd116c --- /dev/null +++ b/src/routes/admin/social-media-managers/[id].tsx @@ -0,0 +1,12 @@ +import ProfessionDetailPage from '~/components/admin/ProfessionDetailPage'; + +export default function Page() { + return ( + + ); +} diff --git a/src/routes/admin/social-media-managers.tsx b/src/routes/admin/social-media-managers/index.tsx similarity index 100% rename from src/routes/admin/social-media-managers.tsx rename to src/routes/admin/social-media-managers/index.tsx diff --git a/src/routes/admin/tutors/[id].tsx b/src/routes/admin/tutors/[id].tsx new file mode 100644 index 0000000..025451a --- /dev/null +++ b/src/routes/admin/tutors/[id].tsx @@ -0,0 +1,12 @@ +import ProfessionDetailPage from '~/components/admin/ProfessionDetailPage'; + +export default function Page() { + return ( + + ); +} diff --git a/src/routes/admin/tutors.tsx b/src/routes/admin/tutors/index.tsx similarity index 100% rename from src/routes/admin/tutors.tsx rename to src/routes/admin/tutors/index.tsx diff --git a/src/routes/admin/video-editors/[id].tsx b/src/routes/admin/video-editors/[id].tsx new file mode 100644 index 0000000..4aaa700 --- /dev/null +++ b/src/routes/admin/video-editors/[id].tsx @@ -0,0 +1,12 @@ +import ProfessionDetailPage from '~/components/admin/ProfessionDetailPage'; + +export default function Page() { + return ( + + ); +} diff --git a/src/routes/admin/video-editors.tsx b/src/routes/admin/video-editors/index.tsx similarity index 100% rename from src/routes/admin/video-editors.tsx rename to src/routes/admin/video-editors/index.tsx