From 3a456e56ddce817c1a8ca0bc87075dc6b8a3847d Mon Sep 17 00:00:00 2001 From: Kyle Pope Date: Mon, 2 Mar 2026 19:58:21 +0800 Subject: [PATCH] Show date of birth with calculated age in IAM user detail Adds date_of_birth to UserDetailResponse schema, AdminUserDetail TypeScript type, and the User Information card in UserDetailSection. Displays formatted date with age in parentheses (e.g. "3/02/2000 (26)"). Co-Authored-By: Claude Opus 4.6 --- backend/app/schemas/admin.py | 3 ++- frontend/src/components/admin/UserDetailSection.tsx | 10 ++++++++++ frontend/src/types/index.ts | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/backend/app/schemas/admin.py b/backend/app/schemas/admin.py index ca0c781..fa52d2a 100644 --- a/backend/app/schemas/admin.py +++ b/backend/app/schemas/admin.py @@ -5,7 +5,7 @@ All admin-facing request/response shapes live here to keep the admin router clean and testable in isolation. """ import re -from datetime import datetime +from datetime import date, datetime from typing import Optional, Literal from pydantic import BaseModel, ConfigDict, Field, field_validator @@ -42,6 +42,7 @@ class UserListResponse(BaseModel): class UserDetailResponse(UserListItem): preferred_name: Optional[str] = None + date_of_birth: Optional[date] = None must_change_password: bool = False locked_until: Optional[datetime] = None diff --git a/frontend/src/components/admin/UserDetailSection.tsx b/frontend/src/components/admin/UserDetailSection.tsx index 0f09563..83bdc7a 100644 --- a/frontend/src/components/admin/UserDetailSection.tsx +++ b/frontend/src/components/admin/UserDetailSection.tsx @@ -117,6 +117,16 @@ export default function UserDetailSection({ userId, onClose }: UserDetailSection + { + const dob = new Date(user.date_of_birth + 'T00:00:00'); + const now = new Date(); + let age = now.getFullYear() - dob.getFullYear(); + if (now.getMonth() < dob.getMonth() || (now.getMonth() === dob.getMonth() && now.getDate() < dob.getDate())) age--; + return `${dob.toLocaleDateString()} (${age})`; + })() : null} + />