From e0cc88ad453f56740a2c1c4143ae7b1fd32ea9f9 Mon Sep 17 00:00:00 2001 From: chyoo Date: Thu, 9 Jul 2026 11:20:17 +0900 Subject: [PATCH] add avatar user list --- src/pages/operations/UserSessionsPage.tsx | 58 ++++++++++++++++++----- src/pages/operations/operations-api.ts | 1 + 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/pages/operations/UserSessionsPage.tsx b/src/pages/operations/UserSessionsPage.tsx index 9213adf..98eb8e7 100644 --- a/src/pages/operations/UserSessionsPage.tsx +++ b/src/pages/operations/UserSessionsPage.tsx @@ -3,6 +3,7 @@ import { useEffect, useMemo, useState } from 'react'; import { DataTableCard, type DataTableColumn, type DataTableFilter } from '../../components/data-table'; import { Button, Modal } from '../../components/ui'; import { PageTitle } from '../../layout/AppLayout'; +import { cn } from '../../lib/utils'; import { loadUserSessions, lockUser, terminateUserSession, unlockUser, type UserSession } from './operations-api'; import { formatDateTime, LoadingModal, StatusBadge, useMinimumLoading } from './operation-utils'; @@ -56,11 +57,14 @@ export function UserSessionsPage() { { key: 'user', header: '사용자', - className: 'w-[240px] px-5 py-3 font-medium', + className: 'w-[280px] px-5 py-3 font-medium', cell: (row) => ( -
-

{row.user}

- {row.email ?

{row.email}

: null} +
+ +
+

{row.user}

+ {row.email ?

{row.email}

: null} +
) }, @@ -174,13 +178,16 @@ export function UserSessionsPage() { {detailSession ? (
-
-

{detailSession.user}

-

{detailSession.email ?? '-'}

+
+ +
+

{detailSession.user}

+

{detailSession.email ?? '-'}

+
-
+
@@ -212,11 +219,36 @@ function organizationTypeLabel(type?: string | null) { return type ? labels[type] ?? type : '-'; } -function DetailItem({ label, value, mono = false }: { label: string; value: string; mono?: boolean }) { +function UserAvatar({ session, size = 'sm' }: { session: UserSession; size?: 'sm' | 'lg' }) { + const [failed, setFailed] = useState(false); + const initial = (session.user || session.email || '?').trim().charAt(0).toUpperCase() || '?'; + const sizeClassName = size === 'lg' ? 'size-14 text-lg' : 'size-9 text-sm'; + + if (session.avatarUrl && !failed) { + return ( + setFailed(true)} + /> + ); + } + return ( -
-

{label}

-

{value || '-'}

-
+ + {initial} + + ); +} + +function DetailItem({ label, value, mono = false }: { label: string; value: string; mono?: boolean }) { + return ( + ); } diff --git a/src/pages/operations/operations-api.ts b/src/pages/operations/operations-api.ts index aacd477..57da397 100644 --- a/src/pages/operations/operations-api.ts +++ b/src/pages/operations/operations-api.ts @@ -39,6 +39,7 @@ export type UserSession = { sessionId?: string | null; user: string; email?: string; + avatarUrl?: string | null; role: string; session: string; expiresAt?: string | null;