@@ -3,16 +3,8 @@ import { ref, onMounted, computed } from 'vue'
33import { useRoute , useRouter } from ' vue-router'
44import { useI18n } from ' vue-i18n'
55import { Button } from ' @/components/ui/button'
6- import {
7- Card ,
8- CardContent ,
9- CardDescription ,
10- CardHeader ,
11- CardTitle ,
12- } from ' @/components/ui/card'
13- import { Label } from ' @/components/ui/label'
146import { Badge } from ' @/components/ui/badge'
15- import { ArrowLeft , Mail , Github } from ' lucide-vue-next'
7+ import { ArrowLeft , Mail , Github , Shield } from ' lucide-vue-next'
168import DashboardLayout from ' @/components/DashboardLayout.vue'
179import { getEnv } from ' @/utils/env'
1810import type { User } from ' ./users/types'
@@ -75,7 +67,7 @@ const authTypeBadge = computed(() => {
7567 return {
7668 variant: (isEmail ? ' default' : ' secondary' ) as ' default' | ' secondary' ,
7769 icon: isEmail ? Mail : Github ,
78- text: isEmail ? ' Email ' : ' GitHub '
70+ text: isEmail ? t ( ' adminUsers.userDetail.values.email ' ) : t ( ' adminUsers.userDetail.values.github ' )
7971 }
8072})
8173
@@ -85,7 +77,7 @@ const goBack = () => {
8577 </script >
8678
8779<template >
88- <DashboardLayout :title =" `User: ${ user? .username || 'Loading...'}` " >
80+ <DashboardLayout :title =" user ? t('adminUsers.userDetail.title', { username: user.username }) : t('adminUsers.userDetail.titleLoading') " >
8981 <div class =" space-y-6" >
9082 <!-- Back Button -->
9183 <div >
@@ -95,112 +87,116 @@ const goBack = () => {
9587 class =" mb-4"
9688 >
9789 <ArrowLeft class =" h-4 w-4 mr-2" />
98- Back to Users
90+ {{ t('adminUsers.userDetail.backToUsers') }}
9991 </Button >
10092 </div >
10193
10294 <!-- Loading State -->
10395 <div v-if =" isLoading" class =" text-muted-foreground" >
104- Loading user details...
96+ {{ t('adminUsers.userDetail.loading') }}
10597 </div >
10698
10799 <!-- Error State -->
108100 <div v-else-if =" error" class =" text-red-500" >
109- Error loading user: {{ error }}
101+ {{ t('adminUsers.userDetail.errorLoading', { error }) }}
110102 </div >
111103
112104 <!-- User Details -->
113- <div v-else-if =" user" class =" space-y-6" >
114- <Card >
115- <CardHeader >
116- <CardTitle >Profile</CardTitle >
117- <CardDescription >
118- User information and account details.
119- </CardDescription >
120- </CardHeader >
121- <CardContent class =" space-y-6" >
122- <!-- Username -->
123- <div class =" space-y-2" >
124- <Label >Username</Label >
125- <div class =" text-sm font-medium" >{{ user.username }}</div >
126- </div >
127-
128- <!-- Email -->
129- <div class =" space-y-2" >
130- <Label >Email</Label >
131- <div class =" text-sm" >{{ user.email }}</div >
105+ <div v-else-if =" user" >
106+ <div class =" px-4 sm:px-0" >
107+ <h3 class =" text-base/7 font-semibold text-gray-900" >{{ t('adminUsers.userDetail.userInformation') }}</h3 >
108+ <p class =" mt-1 max-w-2xl text-sm/6 text-gray-500" >{{ t('adminUsers.userDetail.personalDetails') }}</p >
109+ </div >
110+ <div class =" mt-6 border-t border-gray-100" >
111+ <dl class =" divide-y divide-gray-100" >
112+ <!-- Full Name -->
113+ <div class =" px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0" >
114+ <dt class =" text-sm/6 font-medium text-gray-900" >{{ t('adminUsers.userDetail.fields.fullName') }}</dt >
115+ <dd class =" mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0" >
116+ {{ displayName === user.username ? t('adminUsers.userDetail.values.notProvided') : displayName }}
117+ </dd >
132118 </div >
133119
134- <!-- Full Name -->
135- <div class =" space-y-2" >
136- <Label >Full Name</Label >
137- <div class =" text-sm" >
138- {{ displayName === user.username ? 'Not provided' : displayName }}
139- </div >
120+ <!-- Username -->
121+ <div class =" px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0" >
122+ <dt class =" text-sm/6 font-medium text-gray-900" >{{ t('adminUsers.userDetail.fields.username') }}</dt >
123+ <dd class =" mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0" >{{ user.username }}</dd >
140124 </div >
141125
142- <!-- First Name -->
143- <div class =" space-y-2 " >
144- <Label >First Name</ Label >
145- <div class =" text-sm" >{{ user.first_name || 'Not provided' }}</div >
126+ <!-- Email -->
127+ <div class =" px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0 " >
128+ <dt class = " text-sm/6 font-medium text-gray-900 " >{{ t('adminUsers.userDetail.fields.emailAddress') }}</ dt >
129+ <dd class =" mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 " >{{ user.email }}</dd >
146130 </div >
147131
148- <!-- Last Name -->
149- <div class =" space-y-2" >
150- <Label >Last Name</Label >
151- <div class =" text-sm" >{{ user.last_name || 'Not provided' }}</div >
132+ <!-- Role -->
133+ <div class =" px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0" >
134+ <dt class =" text-sm/6 font-medium text-gray-900" >{{ t('adminUsers.userDetail.fields.role') }}</dt >
135+ <dd class =" mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0" >
136+ {{ user.role ? user.role.name : t('adminUsers.userDetail.values.noRoleAssigned') }}
137+ </dd >
152138 </div >
153139
154- <!-- Authentication Type -->
155- <div class =" space-y-2 " >
156- <Label >Registration Method</ Label >
157- <div v-if = " authTypeBadge " >
140+ <!-- Registration Method -->
141+ <div class =" px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0 " >
142+ <dt class = " text-sm/6 font-medium text-gray-900 " >{{ t('adminUsers.userDetail.fields.registrationMethod') }}</ dt >
143+ <dd class = " mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 " >
158144 <Badge
145+ v-if =" authTypeBadge"
159146 :variant =" authTypeBadge.variant"
160147 class =" flex items-center gap-1 w-fit"
161148 >
162149 <component :is =" authTypeBadge.icon" class =" h-3 w-3" />
163150 {{ authTypeBadge.text }}
164151 </Badge >
165- </div >
152+ </dd >
166153 </div >
167154
168155 <!-- GitHub ID (if applicable) -->
169- <div v-if =" user.github_id" class =" space-y-2" >
170- <Label >GitHub ID</Label >
171- <div class =" text-sm font-mono" >{{ user.github_id }}</div >
172- </div >
173-
174- <!-- Role -->
175- <div class =" space-y-2" >
176- <Label >Role</Label >
177- <div class =" text-sm" >
178- {{ user.role ? user.role.name : 'No role assigned' }}
179- </div >
156+ <div v-if =" user.github_id" class =" px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0" >
157+ <dt class =" text-sm/6 font-medium text-gray-900" >{{ t('adminUsers.userDetail.fields.githubId') }}</dt >
158+ <dd class =" mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0" >
159+ <span class =" font-mono" >{{ user.github_id }}</span >
160+ </dd >
180161 </div >
181162
182- <!-- Role Permissions (if role exists) -->
183- <div v-if =" user.role && user.role.permissions.length > 0" class =" space-y-2" >
184- <Label >Permissions</Label >
185- <div class =" flex flex-wrap gap-1" >
186- <Badge
187- v-for =" permission in user.role.permissions"
188- :key =" permission"
189- variant =" outline"
190- class =" text-xs"
191- >
192- {{ permission }}
193- </Badge >
194- </div >
163+ <!-- User Details -->
164+ <div class =" px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0" >
165+ <dt class =" text-sm/6 font-medium text-gray-900" >{{ t('adminUsers.userDetail.fields.accountDetails') }}</dt >
166+ <dd class =" mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0" >
167+ <div class =" space-y-2" >
168+ <div ><span class =" font-medium" >{{ t('adminUsers.userDetail.values.firstName') }}</span > {{ user.first_name || t('adminUsers.userDetail.values.notProvided') }}</div >
169+ <div ><span class =" font-medium" >{{ t('adminUsers.userDetail.values.lastName') }}</span > {{ user.last_name || t('adminUsers.userDetail.values.notProvided') }}</div >
170+ <div ><span class =" font-medium" >{{ t('adminUsers.userDetail.values.userId') }}</span > <span class =" font-mono text-xs" >{{ user.id }}</span ></div >
171+ </div >
172+ </dd >
195173 </div >
196174
197- <!-- User ID -->
198- <div class =" space-y-2" >
199- <Label >User ID</Label >
200- <div class =" text-sm font-mono text-muted-foreground" >{{ user.id }}</div >
175+ <!-- Permissions (if role exists) -->
176+ <div v-if =" user.role && user.role.permissions.length > 0" class =" px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0" >
177+ <dt class =" text-sm/6 font-medium text-gray-900" >{{ t('adminUsers.userDetail.fields.permissions') }}</dt >
178+ <dd class =" mt-2 text-sm text-gray-900 sm:col-span-2 sm:mt-0" >
179+ <ul role =" list" class =" divide-y divide-gray-100 rounded-md border border-gray-200" >
180+ <li
181+ v-for =" permission in user.role.permissions"
182+ :key =" permission"
183+ class =" flex items-center justify-between py-4 pr-5 pl-4 text-sm/6"
184+ >
185+ <div class =" flex w-0 flex-1 items-center" >
186+ <Shield class =" size-5 shrink-0 text-gray-400" aria-hidden =" true" />
187+ <div class =" ml-4 flex min-w-0 flex-1 gap-2" >
188+ <span class =" truncate font-medium" >{{ permission }}</span >
189+ </div >
190+ </div >
191+ <div class =" ml-4 shrink-0" >
192+ <Badge variant =" outline" class =" text-xs" >{{ t('adminUsers.userDetail.values.active') }}</Badge >
193+ </div >
194+ </li >
195+ </ul >
196+ </dd >
201197 </div >
202- </CardContent >
203- </Card >
198+ </dl >
199+ </div >
204200 </div >
205201 </div >
206202 </DashboardLayout >
0 commit comments