feat(profile): role-aware nav + avatar menu + full editable profile
Build backend images / build content-svc (push) Failing after 1m59s
Build backend images / build file-svc (push) Failing after 3m18s
Build backend images / build gateway (push) Failing after 3m28s
Build backend images / build identity-svc (push) Failing after 2m1s
Build backend images / build notification-svc (push) Failing after 4m45s
Build backend images / build render-svc (push) Failing after 5m18s
Build backend images / build studio-svc (push) Failing after 2m12s
Build backend images / build content-svc (push) Failing after 1m59s
Build backend images / build file-svc (push) Failing after 3m18s
Build backend images / build gateway (push) Failing after 3m28s
Build backend images / build identity-svc (push) Failing after 2m1s
Build backend images / build notification-svc (push) Failing after 4m45s
Build backend images / build render-svc (push) Failing after 5m18s
Build backend images / build studio-svc (push) Failing after 2m12s
Navigation: - UserMenu (avatar + role-aware dropdown: Dashboard, Admin Panel for admins, Profile, Sign out) replaces Sign In/Try Free when logged in (desktop + mobile). - Real avatars in dashboard sidebar + a new admin-shell profile section. - Shared Avatar primitive (image with initials fallback). SiteChrome excludes /admin. Profile (data-collection surface for future AI video generation): - SettingsProfile rebuilt: avatar upload + slogan, about, company, website, country, national code, birthdate, gender. No resume builder (per scope change). - /api/profile forwards all fields; new user-scoped /api/profile/upload (avatar → MinIO via file-svc, sets avatar). Identity UpdateUserRequest/UserResponse widened (country/national/method); no DB migration (columns already exist). - fa+en strings; verified GET/PATCH round-trip + logged-in SSR render. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ export default async function DashboardLayout({
|
||||
userEmail={user.email ?? ""}
|
||||
userName={user.full_name ?? null}
|
||||
userId={user.id}
|
||||
avatarUrl={(user.avatar_url as string | null) ?? null}
|
||||
>
|
||||
{children}
|
||||
</DashboardShell>
|
||||
|
||||
@@ -23,8 +23,20 @@ export default async function DashboardSettingsPage() {
|
||||
const user = await getCurrentUser();
|
||||
|
||||
const email = user?.email ?? "";
|
||||
const displayName =
|
||||
typeof user?.full_name === "string" ? user.full_name : null;
|
||||
const u = (user ?? {}) as Record<string, unknown>;
|
||||
const str = (v: unknown) => (typeof v === "string" ? v : "");
|
||||
const initialProfile = {
|
||||
full_name: str(u.full_name),
|
||||
avatar_url: typeof u.avatar_url === "string" ? u.avatar_url : null,
|
||||
slogan: str(u.slogan),
|
||||
about_me: str(u.about_me),
|
||||
company_name: str(u.company_name),
|
||||
website_name: str(u.website_name),
|
||||
country_code: str(u.country_code),
|
||||
national_code: str(u.national_code),
|
||||
birth_date: str(u.birth_date),
|
||||
gender: str(u.gender),
|
||||
};
|
||||
|
||||
const profile = user ? await getUserProfile(user.id) : null;
|
||||
const plan = profile?.plan ?? "free";
|
||||
@@ -42,7 +54,7 @@ export default async function DashboardSettingsPage() {
|
||||
{/* Content */}
|
||||
<div className="flex-1 p-6">
|
||||
<div className="mx-auto max-w-2xl space-y-6">
|
||||
<SettingsProfile email={email} displayName={displayName} />
|
||||
<SettingsProfile email={email} initial={initialProfile} />
|
||||
<SettingsSecurity />
|
||||
<SettingsBilling plan={plan} />
|
||||
<SettingsNotifications />
|
||||
|
||||
Reference in New Issue
Block a user