154 lines
5.8 KiB
Vue
154 lines
5.8 KiB
Vue
<script lang="ts" setup>
|
|
import { computed } from 'vue'
|
|
import { Badge } from '@/components/ui/badge'
|
|
import { Box } from '@/components/ui/box'
|
|
import { Field, FieldGroup, FieldLabel } from '@/components/ui/field'
|
|
import { Input } from '@/components/ui/input'
|
|
import type { Address } from '@/modules/profile/types/address.types'
|
|
import type { UserDetail } from '../types/user.types'
|
|
|
|
const props = defineProps<{
|
|
user: UserDetail
|
|
embedded?: boolean
|
|
}>()
|
|
|
|
const ADDRESS_TYPE_LABEL: Record<string, string> = {
|
|
home: 'Rumah',
|
|
office: 'Pejabat',
|
|
billing: 'Bil',
|
|
}
|
|
|
|
const displayValue = (value: string | number | null | undefined) => {
|
|
if (value === null || value === undefined || value === '') return '-'
|
|
return String(value).trim() || '-'
|
|
}
|
|
|
|
const statusLabel = computed(() => {
|
|
const status = props.user.status
|
|
if (!status) return '-'
|
|
return status.charAt(0).toUpperCase() + status.slice(1)
|
|
})
|
|
|
|
const roleNames = computed(() => props.user.roles?.map((role) => role.name).join(', ') || '-')
|
|
|
|
function formatDate(value: string | null | undefined): string {
|
|
if (!value) return '-'
|
|
return value.slice(0, 10)
|
|
}
|
|
|
|
function formatAddressLine(address: Address) {
|
|
return [address.address_line_1, address.address_line_2, address.postcode, address.city, address.state, address.country]
|
|
.filter((part) => part?.trim())
|
|
.join(', ')
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div :class="embedded ? 'space-y-8' : 'mt-5 space-y-8'">
|
|
<Box raised="single" class="p-6">
|
|
<div class="mb-6">
|
|
<h3 class="text-lg font-semibold text-slate-900">Maklumat Peribadi</h3>
|
|
<p class="mt-1 text-sm text-slate-500">Paparan maklumat pengguna (baca sahaja).</p>
|
|
</div>
|
|
|
|
<FieldGroup>
|
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
<Field>
|
|
<FieldLabel for="view-user-name">Nama</FieldLabel>
|
|
<Input id="view-user-name" :model-value="displayValue(user.name)" type="text" disabled />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-email">E-mel</FieldLabel>
|
|
<Input id="view-user-email" :model-value="displayValue(user.email)" type="email" disabled />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-ic">No. Kad Pengenalan</FieldLabel>
|
|
<Input id="view-user-ic" :model-value="displayValue(user.ic_number)" type="text" disabled />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-phone">No. Telefon</FieldLabel>
|
|
<Input id="view-user-phone" :model-value="displayValue(user.phone_number)" type="text" disabled />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-position">Jawatan</FieldLabel>
|
|
<Input id="view-user-position" :model-value="displayValue(user.position)" type="text" disabled />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-status">Status</FieldLabel>
|
|
<Input id="view-user-status" :model-value="statusLabel" type="text" disabled />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-gender">Jantina</FieldLabel>
|
|
<Input id="view-user-gender" :model-value="displayValue(user.gender)" type="text" disabled />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-marriage">Status Perkahwinan</FieldLabel>
|
|
<Input
|
|
id="view-user-marriage"
|
|
:model-value="displayValue(user.marriage_status)"
|
|
type="text"
|
|
disabled
|
|
/>
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-member-number">Nombor Anggota</FieldLabel>
|
|
<Input
|
|
id="view-user-member-number"
|
|
:model-value="displayValue(user.member_number)"
|
|
type="text"
|
|
disabled
|
|
/>
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-member-type">Jenis Anggota</FieldLabel>
|
|
<Input id="view-user-member-type" :model-value="displayValue(user.member_type)" type="text" disabled />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-join-date">Tarikh Sertai</FieldLabel>
|
|
<Input id="view-user-join-date" :model-value="formatDate(user.join_date)" type="text" disabled />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="view-user-birth-date">Tarikh Lahir</FieldLabel>
|
|
<Input id="view-user-birth-date" :model-value="formatDate(user.birth_date)" type="text" disabled />
|
|
</Field>
|
|
<Field class="md:col-span-2">
|
|
<FieldLabel for="view-user-birth-place">Tempat Lahir</FieldLabel>
|
|
<Input id="view-user-birth-place" :model-value="displayValue(user.birth_place)" type="text" disabled />
|
|
</Field>
|
|
<Field class="md:col-span-2">
|
|
<FieldLabel for="view-user-roles">Peranan</FieldLabel>
|
|
<Input id="view-user-roles" :model-value="roleNames" type="text" disabled />
|
|
</Field>
|
|
</div>
|
|
</FieldGroup>
|
|
</Box>
|
|
|
|
<Box raised="single" class="p-6">
|
|
<div class="mb-6">
|
|
<h3 class="text-lg font-semibold text-slate-900">Alamat</h3>
|
|
<p class="mt-1 text-sm text-slate-500">Senarai alamat pengguna.</p>
|
|
</div>
|
|
|
|
<div v-if="user.addresses?.length" class="space-y-3">
|
|
<div
|
|
v-for="address in user.addresses"
|
|
:key="address.id"
|
|
class="rounded-lg border border-foreground/10 p-4"
|
|
>
|
|
<Badge look="outline">
|
|
{{ ADDRESS_TYPE_LABEL[address.address_type] ?? address.address_type }}
|
|
</Badge>
|
|
<p class="mt-2 text-sm text-slate-700">{{ formatAddressLine(address) }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
v-else
|
|
class="rounded-lg border border-dashed border-foreground/15 p-6 text-center text-sm text-slate-500"
|
|
>
|
|
Tiada alamat direkodkan.
|
|
</div>
|
|
</Box>
|
|
</div>
|
|
</template>
|