DONE: fix issue email redirect to localhost, move action button in user to first column, update cicd

This commit is contained in:
2026-10-25 11:15:09 +08:00
parent 13fea33964
commit d314694773
4 changed files with 25 additions and 9 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
# Stage 1: Build Vue SPA # Stage 1: Build Vue SPA
FROM node:22 AS builder FROM node:22 AS builder
WORKDIR /app WORKDIR /app
COPY fe/package*.json fe/pnpm-lock.yaml fe/.npmrc ./ COPY fe/package*.json fe/pnpm-lock.yaml fe/.npmrc fe/pnpm-workspace.yaml ./
# Skip prepare (cypress install); rebuild esbuild only — required for Vite # Skip prepare (cypress install); rebuild esbuild only — required for Vite
RUN npm install -g pnpm && \ RUN npm install -g pnpm && \
pnpm install --frozen-lockfile --ignore-scripts && \ pnpm install --frozen-lockfile --ignore-scripts && \
+2
View File
@@ -0,0 +1,2 @@
allowBuilds:
esbuild: true
+2 -2
View File
@@ -317,6 +317,7 @@ async function confirmRestore() {
const headers: TableHeader[] = [ const headers: TableHeader[] = [
{ title: 'Bil.', key: '#', sortable: false }, { title: 'Bil.', key: '#', sortable: false },
{ title: 'Tindakan', key: 'actions', sortable: false },
{ title: 'Name', key: 'name', sortable: true }, { title: 'Name', key: 'name', sortable: true },
{ {
title: 'Unit', title: 'Unit',
@@ -345,12 +346,12 @@ const headers: TableHeader[] = [
exportValue: (item) => formatUserRoles(item.roles), exportValue: (item) => formatUserRoles(item.roles),
}, },
{ title: 'Status', key: 'status', sortable: true }, { title: 'Status', key: 'status', sortable: true },
{ title: 'Tindakan', key: 'actions', sortable: false },
] ]
// deleted users table headers // deleted users table headers
const deletedHeaders: TableHeader[] = [ const deletedHeaders: TableHeader[] = [
{ title: 'Bil.', key: '#', sortable: false }, { title: 'Bil.', key: '#', sortable: false },
{ title: 'Tindakan', key: 'actions', sortable: false },
{ title: 'Name', key: 'name', sortable: true }, { title: 'Name', key: 'name', sortable: true },
{ {
title: 'Unit', title: 'Unit',
@@ -368,7 +369,6 @@ const deletedHeaders: TableHeader[] = [
}, },
{ title: 'Status', key: 'status', sortable: true }, { title: 'Status', key: 'status', sortable: true },
{ title: 'Dipadam Pada', key: 'deleted_at', sortable: true }, { title: 'Dipadam Pada', key: 'deleted_at', sortable: true },
{ title: 'Tindakan', key: 'actions', sortable: false },
] ]
const { const {
+20 -6
View File
@@ -5,6 +5,7 @@ import { Box } from '@/components/ui/box'
import { Field, FieldGroup, FieldLabel } from '@/components/ui/field' import { Field, FieldGroup, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input' import { Input } from '@/components/ui/input'
import type { Address } from '@/modules/profile/types/address.types' import type { Address } from '@/modules/profile/types/address.types'
import type { Heir } from '@/modules/profile/types/heir.types'
import type { UserDetail } from '../types/user.types' import type { UserDetail } from '../types/user.types'
const props = defineProps<{ const props = defineProps<{
@@ -31,6 +32,8 @@ const statusLabel = computed(() => {
const roleNames = computed(() => props.user.roles?.map((role) => role.name).join(', ') || '-') const roleNames = computed(() => props.user.roles?.map((role) => role.name).join(', ') || '-')
const heirs = computed<Heir[]>(() => props.user.heirs ?? [])
function formatDate(value: string | null | undefined): string { function formatDate(value: string | null | undefined): string {
if (!value) return '-' if (!value) return '-'
return value.slice(0, 10) return value.slice(0, 10)
@@ -157,19 +160,30 @@ function formatAddressLine(address: Address) {
<Box raised="single" class="p-6"> <Box raised="single" class="p-6">
<div class="mb-6"> <div class="mb-6">
<h3 class="text-lg font-semibold text-slate-900">Penama</h3> <h3 class="text-lg font-semibold text-slate-900">Penama</h3>
<p class="mt-1 text-sm text-slate-500">Senarai penama pengguna.</p> <p class="mt-1 text-sm text-slate-500">Paparan maklumat penama anggota (baca sahaja).</p>
</div> </div>
<div v-if="user.heirs?.length" class="space-y-3"> <div v-if="heirs.length" class="space-y-3">
<div v-for="heir in user.heirs" :key="heir.id" class="rounded-lg border border-foreground/10 p-4"> <div v-for="heir in heirs" :key="heir.id" class="rounded-lg border border-foreground/10 p-4">
<div class="flex flex-wrap items-center gap-2"> <div class="flex flex-wrap items-center gap-2">
<span class="font-medium text-slate-900">{{ heir.name }}</span> <span class="font-medium text-slate-900">{{ heir.name }}</span>
<Badge v-if="heir.is_primary" class="bg-green-500 text-white">Utama</Badge> <Badge v-if="heir.is_primary" class="bg-green-500 text-white">Utama</Badge>
<Badge look="outline">{{ heir.relationship }}</Badge> <Badge look="outline">{{ heir.relationship }}</Badge>
</div> </div>
<p class="mt-1 text-sm text-slate-500">{{ heir.ic_number }}</p> <dl class="mt-3 grid grid-cols-1 gap-3 text-sm md:grid-cols-2">
<p class="mt-1 text-sm text-slate-500">{{ heir.phone_number }}</p> <div>
<p class="mt-1 text-sm text-slate-700">{{ heir.address }}</p> <dt class="text-slate-500">No. Kad Pengenalan</dt>
<dd class="text-slate-700">{{ heir.ic_number || '-' }}</dd>
</div>
<div>
<dt class="text-slate-500">No. Telefon</dt>
<dd class="text-slate-700">{{ heir.phone_number || '-' }}</dd>
</div>
<div class="md:col-span-2">
<dt class="text-slate-500">Alamat</dt>
<dd class="whitespace-pre-line text-slate-700">{{ heir.address || '-' }}</dd>
</div>
</dl>
</div> </div>
</div> </div>