Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
6d51834a
Commit
6d51834a
authored
Apr 22, 2026
by
IanShaw027
Browse files
refactor(profile): simplify profile page flow
parent
863258d7
Changes
3
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/user/profile/ProfileInfoCard.vue
View file @
6d51834a
...
...
@@ -98,7 +98,7 @@
</div>
</section>
<div
class=
"
grid gap-6 xl:grid-cols-[minmax(0,1.15fr)_320px]
"
>
<div
class=
"
space-y-6
"
>
<div
data-testid=
"profile-main-column"
class=
"space-y-6"
>
<section
data-testid=
"profile-basics-panel"
...
...
@@ -115,7 +115,7 @@
</div>
</div>
<div
class=
"grid gap-6
lg
:grid-cols-
[minmax(0,0.8fr)_minmax(0,1.2fr)]
"
>
<div
class=
"grid gap-6
sm
:grid-cols-
1 md:grid-cols-2
"
>
<div
class=
"rounded-3xl border border-gray-100 bg-gray-50/80 p-5 dark:border-dark-700 dark:bg-dark-900/30"
>
<ProfileAvatarCard
:user=
"user"
...
...
@@ -150,35 +150,7 @@
</section>
</div>
<aside
data-testid=
"profile-side-column"
class=
"space-y-6"
>
<section
class=
"card border border-gray-100 bg-white/90 p-6 dark:border-dark-700 dark:bg-dark-900/50"
>
<h3
class=
"text-lg font-semibold text-gray-900 dark:text-white"
>
{{
t
(
'
profile.overviewTitle
'
)
}}
</h3>
<p
class=
"mt-1 text-sm text-gray-500 dark:text-gray-400"
>
{{
t
(
'
profile.overviewDescription
'
)
}}
</p>
<div
class=
"mt-5 grid gap-3"
>
<div
class=
"rounded-2xl border border-gray-100 bg-gray-50/80 px-4 py-3 dark:border-dark-700 dark:bg-dark-900/30"
>
<p
class=
"text-xs font-medium uppercase tracking-[0.16em] text-gray-400 dark:text-gray-500"
>
{{
t
(
'
profile.username
'
)
}}
</p>
<p
class=
"mt-1 text-sm font-semibold text-gray-900 dark:text-white"
>
{{
user
?.
username
||
displayName
}}
</p>
</div>
<div
class=
"rounded-2xl border border-gray-100 bg-gray-50/80 px-4 py-3 dark:border-dark-700 dark:bg-dark-900/30"
>
<p
class=
"text-xs font-medium uppercase tracking-[0.16em] text-gray-400 dark:text-gray-500"
>
{{
t
(
'
profile.email
'
)
}}
</p>
<p
class=
"mt-1 text-sm font-semibold text-gray-900 dark:text-white"
>
{{
user
?.
email
||
'
-
'
}}
</p>
</div>
</div>
</section>
<div
data-testid=
"profile-side-column"
class=
"space-y-6"
>
<section
v-if=
"sourceHints.length"
class=
"card border border-gray-100 bg-white/90 p-6 dark:border-dark-700 dark:bg-dark-900/50"
...
...
@@ -201,7 +173,7 @@
</div>
</div>
</section>
</
aside
>
</
div
>
</div>
</div>
</
template
>
...
...
frontend/src/views/user/ProfileView.vue
View file @
6d51834a
...
...
@@ -2,59 +2,47 @@
<AppLayout>
<div
data-testid=
"profile-shell"
class=
"mx-auto max-w-
6xl
space-y-6"
class=
"mx-auto max-w-
[950px]
space-y-6"
>
<div
class=
"grid gap-6 xl:grid-cols-[minmax(0,1.35fr)_360px]"
>
<div
data-testid=
"profile-primary-column"
class=
"space-y-6"
>
<ProfileInfoCard
:user=
"user"
:linuxdo-enabled=
"linuxdoOAuthEnabled"
:oidc-enabled=
"oidcOAuthEnabled"
:oidc-provider-name=
"oidcOAuthProviderName"
:wechat-enabled=
"wechatOAuthEnabled"
:wechat-open-enabled=
"wechatOAuthOpenEnabled"
:wechat-mp-enabled=
"wechatOAuthMPEnabled"
/>
</div>
<ProfileInfoCard
:user=
"user"
:linuxdo-enabled=
"linuxdoOAuthEnabled"
:oidc-enabled=
"oidcOAuthEnabled"
:oidc-provider-name=
"oidcOAuthProviderName"
:wechat-enabled=
"wechatOAuthEnabled"
:wechat-open-enabled=
"wechatOAuthOpenEnabled"
:wechat-mp-enabled=
"wechatOAuthMPEnabled"
/>
<aside
data-testid=
"profile-secondary-column"
class=
"space-y-6"
>
<div
v-if=
"contactInfo"
class=
"card border-primary-200 bg-primary-50 p-6 dark:bg-primary-900/20"
>
<div
class=
"flex items-center gap-4"
>
<div
class=
"rounded-xl bg-primary-100 p-3 text-primary-600"
>
<Icon
name=
"chat"
size=
"lg"
/>
</div>
<div>
<h3
class=
"font-semibold text-primary-800 dark:text-primary-200"
>
{{
t
(
'
common.contactSupport
'
)
}}
</h3>
<p
class=
"text-sm font-medium"
>
{{
contactInfo
}}
</p>
</div>
</div>
<div
v-if=
"contactInfo"
class=
"card border-primary-200 bg-primary-50 p-6 dark:bg-primary-900/20"
>
<div
class=
"flex items-center gap-4"
>
<div
class=
"rounded-xl bg-primary-100 p-3 text-primary-600"
>
<Icon
name=
"chat"
size=
"lg"
/>
</div>
<div>
<h3
class=
"font-semibold text-primary-800 dark:text-primary-200"
>
{{
t
(
'
common.contactSupport
'
)
}}
</h3>
<p
class=
"text-sm font-medium"
>
{{
contactInfo
}}
</p>
</div>
</div>
</div>
<ProfilePasswordForm
/>
<ProfilePasswordForm
/>
<ProfileBalanceNotifyCard
v-if=
"user && balanceLowNotifyEnabled"
:enabled=
"user.balance_notify_enabled ?? true"
:threshold=
"user.balance_notify_threshold"
:extra-emails=
"user.balance_notify_extra_emails ?? []"
:system-default-threshold=
"systemDefaultThreshold"
:user-email=
"user.email"
/>
<ProfileBalanceNotifyCard
v-if=
"user && balanceLowNotifyEnabled"
:enabled=
"user.balance_notify_enabled ?? true"
:threshold=
"user.balance_notify_threshold"
:extra-emails=
"user.balance_notify_extra_emails ?? []"
:system-default-threshold=
"systemDefaultThreshold"
:user-email=
"user.email"
/>
<ProfileTotpCard
/>
</aside>
</div>
<ProfileTotpCard
/>
</div>
</AppLayout>
</
template
>
...
...
frontend/src/views/user/__tests__/ProfileView.spec.ts
View file @
6d51834a
...
...
@@ -73,7 +73,7 @@ describe('ProfileView', () => {
})
})
it
(
'
renders the
approved two
-column profile shell without separate stat cards
'
,
async
()
=>
{
it
(
'
renders the
simplified single
-column profile shell without separate stat cards
'
,
async
()
=>
{
const
wrapper
=
mount
(
ProfileView
,
{
global
:
{
stubs
:
{
...
...
@@ -92,10 +92,8 @@ describe('ProfileView', () => {
expect
(
wrapper
.
findAll
(
'
.stat-card
'
)).
toHaveLength
(
0
)
expect
(
wrapper
.
get
(
'
[data-testid="profile-shell"]
'
).
exists
()).
toBe
(
true
)
expect
(
wrapper
.
get
(
'
[data-testid="profile-primary-column"]
'
).
exists
()).
toBe
(
true
)
expect
(
wrapper
.
get
(
'
[data-testid="profile-secondary-column"]
'
).
exists
()).
toBe
(
true
)
expect
(
wrapper
.
get
(
'
[data-testid="profile-primary-column"]
'
).
html
()).
toContain
(
'
profile-info-card
'
)
expect
(
wrapper
.
get
(
'
[data-testid="profile-secondary-column"]
'
).
html
()).
toContain
(
'
profile-password-form
'
)
expect
(
wrapper
.
get
(
'
[data-testid="profile-secondary-column"]
'
).
html
()).
toContain
(
'
profile-totp-card
'
)
expect
(
wrapper
.
get
(
'
[data-testid="profile-shell"]
'
).
html
()).
toContain
(
'
profile-info-card
'
)
expect
(
wrapper
.
get
(
'
[data-testid="profile-shell"]
'
).
html
()).
toContain
(
'
profile-password-form
'
)
expect
(
wrapper
.
get
(
'
[data-testid="profile-shell"]
'
).
html
()).
toContain
(
'
profile-totp-card
'
)
})
})
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment