feat(ui): display user ID on dashboard and profile settings pages

This commit is contained in:
dongmucat 2026-04-27 14:54:39 +08:00
parent 1591ee02b5
commit c330db0bf3
5 changed files with 56 additions and 4 deletions

View file

@ -0,0 +1,42 @@
import { expect, test } from '@playwright/test'
import { setEnglishLocale } from './helpers/auth-fixtures'
import { registerSession } from './helpers/session'
test.describe('User ID Display', () => {
test.beforeEach(async ({ page }, testInfo) => {
await setEnglishLocale(page)
await registerSession(page, testInfo)
})
test('shows user ID in dashboard account card', async ({ page }) => {
await page.goto('/dashboard')
await expect(page.getByText('Account Information')).toBeVisible()
const userIdText = page.getByText('User ID', { exact: false })
await expect(userIdText).toBeVisible()
// The dashboard renders "User ID: <value>" in a single element.
// Verify the value is not empty by checking the text content is longer than just the label.
const content = await userIdText.textContent()
const valueAfterLabel = content?.replace(/^.*User ID[:\s]*/i, '').trim() ?? ''
expect(valueAfterLabel.length).toBeGreaterThan(0)
})
test('shows user ID on profile settings page', async ({ page }) => {
await page.goto('/settings/profile')
await expect(page.getByRole('heading', { name: 'Profile Settings' })).toBeVisible()
const label = page.getByText('User ID', { exact: true })
await expect(label).toBeVisible()
// The value is rendered in a sibling <p> element right after the label.
// Locate the value paragraph within the same container.
const container = page.locator('.space-y-2', { has: label })
const value = container.locator('p')
await expect(value).toBeVisible()
const text = await value.textContent()
expect(text?.trim()).not.toBe('')
expect(text?.trim()).not.toBe('-')
})
})

View file

@ -326,7 +326,8 @@
"reportsTitle": "Report Management",
"viewReports": "View skill reports",
"previewMore": "...",
"previewMoreLabel": "View All"
"previewMoreLabel": "View All",
"userId": "User ID"
},
"mySkills": {
"title": "My Skills",
@ -699,7 +700,8 @@
"reviewHint": "Some changes require admin review before taking effect.",
"partiallyAppliedTitle": "Partially Applied",
"partiallyAppliedDescription": "Some changes were applied immediately. Others are pending admin review.",
"noChanges": "No changes to save."
"noChanges": "No changes to save.",
"userId": "User ID"
},
"security": {
"title": "Security Settings",

View file

@ -326,7 +326,8 @@
"reportsTitle": "举报管理",
"viewReports": "查看技能举报",
"previewMore": "...",
"previewMoreLabel": "查看全部"
"previewMoreLabel": "查看全部",
"userId": "用户 ID"
},
"mySkills": {
"title": "我的技能",
@ -699,7 +700,8 @@
"reviewHint": "部分修改需要管理员审核后生效。",
"partiallyAppliedTitle": "部分已生效",
"partiallyAppliedDescription": "部分修改已立即生效,其余修改正在等待管理员审核。",
"noChanges": "没有需要保存的修改。"
"noChanges": "没有需要保存的修改。",
"userId": "用户 ID"
},
"security": {
"title": "安全设置",

View file

@ -52,6 +52,7 @@ export function DashboardPage() {
<div className="space-y-1.5">
<div className="text-xl font-semibold font-heading">{user?.displayName}</div>
<div className="text-sm text-muted-foreground">{user?.email}</div>
<div className="text-sm text-muted-foreground">{t('dashboard.userId')}: {user?.userId}</div>
<div className="text-xs text-muted-foreground flex items-center gap-2">
<span className="w-2 h-2 rounded-full bg-emerald-500" />
{t('dashboard.loginVia', { provider: user?.oauthProvider })}

View file

@ -207,6 +207,11 @@ export function ProfileSettingsPage() {
</div>
) : null}
<div className="space-y-2">
<label className="text-sm font-medium">{t('profile.userId')}</label>
<p className="text-sm text-muted-foreground">{user?.userId || '-'}</p>
</div>
<form className="space-y-4" onSubmit={handleSubmit}>
{/* Dynamic fields */}
{Object.entries(fieldPolicies).map(([field, policy]) => {