Skip to content

Commit e04ac09

Browse files
author
Lasim
committed
feat(frontend): update account sidebar navigation with settings menu
1 parent 5049c9f commit e04ac09

File tree

3 files changed

+162
-199
lines changed

3 files changed

+162
-199
lines changed
Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
<script setup lang="ts">
2-
import { computed } from 'vue'
3-
import { useRoute, RouterLink } from 'vue-router'
4-
import { cn } from '@/lib/utils'
5-
import { Button } from '@/components/ui/button'
6-
7-
export interface AccountSection {
8-
id: string
9-
name: string
10-
href: string
11-
}
2+
import { useRoute } from 'vue-router'
3+
import { useI18n } from 'vue-i18n'
4+
import {
5+
SettingsMenu,
6+
SettingsMenuGroup,
7+
SettingsMenuItem,
8+
} from '@/components/ui/settings-menu'
129
1310
interface Props {
1411
canChangePassword?: boolean
@@ -18,45 +15,26 @@ const props = withDefaults(defineProps<Props>(), {
1815
canChangePassword: true
1916
})
2017
18+
const { t } = useI18n()
2119
const route = useRoute()
22-
23-
const accountSections = computed((): AccountSection[] => {
24-
const sections = [
25-
{
26-
id: 'profile',
27-
name: 'Profile',
28-
href: '/user/profile',
29-
},
30-
]
31-
32-
// Only show Security section for users who can change password
33-
if (props.canChangePassword) {
34-
sections.push({
35-
id: 'security',
36-
name: 'Security',
37-
href: '/user/security',
38-
})
39-
}
40-
41-
return sections
42-
})
4320
</script>
4421

4522
<template>
46-
<nav class="flex space-x-2 lg:flex-col lg:space-x-0 lg:space-y-1">
47-
<Button
48-
v-for="section in accountSections"
49-
:key="section.id"
50-
as-child
51-
variant="ghost"
52-
:class="cn(
53-
'w-full text-left justify-start',
54-
route.path === section.href && 'bg-muted hover:bg-muted',
55-
)"
56-
>
57-
<RouterLink :to="section.href">
58-
{{ section.name }}
59-
</RouterLink>
60-
</Button>
61-
</nav>
23+
<SettingsMenu>
24+
<SettingsMenuGroup>
25+
<SettingsMenuItem
26+
to="/user/profile"
27+
:active="route.path === '/user/profile'"
28+
>
29+
{{ t('userAccount.navigation.profile') }}
30+
</SettingsMenuItem>
31+
<SettingsMenuItem
32+
v-if="canChangePassword"
33+
to="/user/security"
34+
:active="route.path === '/user/security'"
35+
>
36+
{{ t('userAccount.navigation.security') }}
37+
</SettingsMenuItem>
38+
</SettingsMenuGroup>
39+
</SettingsMenu>
6240
</template>

services/frontend/src/views/user/Profile.vue

Lines changed: 67 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,8 @@ import { useBreadcrumbs } from '@/composables/useBreadcrumbs'
55
import { toast } from 'vue-sonner'
66
import AccountSidebarNav from '@/components/account/AccountSidebarNav.vue'
77
import NavbarLayout from '@/components/NavbarLayout.vue'
8-
import {
9-
Card,
10-
CardContent,
11-
CardDescription,
12-
CardHeader,
13-
CardTitle,
14-
} from '@/components/ui/card'
8+
import { DsCard } from '@/components/ui/ds-card'
9+
import { DsPageHeading } from '@/components/ui/ds-page-heading'
1510
import { Button } from '@/components/ui/button'
1611
import { Spinner } from '@/components/ui/spinner'
1712
import { Input } from '@/components/ui/input'
@@ -130,6 +125,8 @@ async function handleProfileSubmit(event: Event) {
130125

131126
<template>
132127
<NavbarLayout>
128+
<DsPageHeading :title="t('userAccount.title')" />
129+
133130
<!-- Mobile Navigation - Show tabs on small screens -->
134131
<div class="block md:hidden mb-6">
135132
<nav class="flex space-x-1 p-1 bg-muted/50 rounded-lg">
@@ -172,72 +169,70 @@ async function handleProfileSubmit(event: Event) {
172169

173170
<!-- Profile Section -->
174171
<div v-else class="space-y-6">
175-
<Card>
176-
<CardHeader>
177-
<CardTitle>{{ t('userAccount.profile.title') }}</CardTitle>
178-
<CardDescription>
179-
{{ t('userAccount.profile.description') }}
180-
</CardDescription>
181-
</CardHeader>
182-
<CardContent>
183-
<form class="space-y-6" @submit="handleProfileSubmit">
184-
<div class="space-y-2">
185-
<Label for="first_name">{{ t('userAccount.profile.form.firstName.label') }}</Label>
186-
<Input
187-
id="first_name"
188-
type="text"
189-
v-model="profileForm.first_name"
190-
class="w-full"
191-
:disabled="isSubmittingProfile"
192-
/>
193-
</div>
194-
195-
<div class="space-y-2">
196-
<Label for="last_name">{{ t('userAccount.profile.form.lastName.label') }}</Label>
197-
<Input
198-
id="last_name"
199-
type="text"
200-
v-model="profileForm.last_name"
201-
class="w-full"
202-
:disabled="isSubmittingProfile"
203-
/>
204-
</div>
205-
206-
<div class="space-y-2">
207-
<Label for="username">{{ t('userAccount.profile.form.username.label') }}</Label>
208-
<Input
209-
id="username"
210-
type="text"
211-
v-model="profileForm.username"
212-
class="w-full"
213-
:disabled="!canChangeUsername || isSubmittingProfile"
214-
/>
215-
<p v-if="!canChangeUsername" class="text-xs text-muted-foreground">
216-
{{ t('userAccount.profile.form.username.disabledHelp', { authType: authTypeDisplayName }) }}
217-
</p>
218-
</div>
219-
220-
<div class="space-y-2">
221-
<Label for="email">{{ t('userAccount.profile.form.email.label') }}</Label>
222-
<Input
223-
id="email"
224-
type="email"
225-
v-model="profileForm.email"
226-
class="w-full"
227-
:disabled="isSubmittingProfile"
228-
/>
229-
</div>
230-
231-
<Button
232-
type="submit"
172+
<DsCard :title="t('userAccount.profile.title')">
173+
<p class="text-sm text-muted-foreground mb-6">
174+
{{ t('userAccount.profile.description') }}
175+
</p>
176+
<form id="profile-form" class="space-y-6" @submit="handleProfileSubmit">
177+
<div class="space-y-2">
178+
<Label for="first_name">{{ t('userAccount.profile.form.firstName.label') }}</Label>
179+
<Input
180+
id="first_name"
181+
type="text"
182+
v-model="profileForm.first_name"
183+
class="w-full"
184+
:disabled="isSubmittingProfile"
185+
/>
186+
</div>
187+
188+
<div class="space-y-2">
189+
<Label for="last_name">{{ t('userAccount.profile.form.lastName.label') }}</Label>
190+
<Input
191+
id="last_name"
192+
type="text"
193+
v-model="profileForm.last_name"
194+
class="w-full"
195+
:disabled="isSubmittingProfile"
196+
/>
197+
</div>
198+
199+
<div class="space-y-2">
200+
<Label for="username">{{ t('userAccount.profile.form.username.label') }}</Label>
201+
<Input
202+
id="username"
203+
type="text"
204+
v-model="profileForm.username"
205+
class="w-full"
206+
:disabled="!canChangeUsername || isSubmittingProfile"
207+
/>
208+
<p v-if="!canChangeUsername" class="text-xs text-muted-foreground">
209+
{{ t('userAccount.profile.form.username.disabledHelp', { authType: authTypeDisplayName }) }}
210+
</p>
211+
</div>
212+
213+
<div class="space-y-2">
214+
<Label for="email">{{ t('userAccount.profile.form.email.label') }}</Label>
215+
<Input
216+
id="email"
217+
type="email"
218+
v-model="profileForm.email"
219+
class="w-full"
233220
:disabled="isSubmittingProfile"
234-
>
235-
<Spinner v-if="isSubmittingProfile" class="mr-2" />
236-
{{ t('userAccount.profile.form.saveButton') }}
237-
</Button>
238-
</form>
239-
</CardContent>
240-
</Card>
221+
/>
222+
</div>
223+
</form>
224+
225+
<template #footer-actions>
226+
<Button
227+
type="submit"
228+
form="profile-form"
229+
:disabled="isSubmittingProfile"
230+
>
231+
<Spinner v-if="isSubmittingProfile" class="mr-2" />
232+
{{ t('userAccount.profile.form.saveButton') }}
233+
</Button>
234+
</template>
235+
</DsCard>
241236
</div>
242237
</div>
243238
</div>

0 commit comments

Comments
 (0)