Feature/phone register (#11)

Co-authored-by: ISMAIL MASSERAN <topaz@ISMAILs-Macbook.local>
Co-authored-by: ISMAIL MASSERAN <topaz@Mac.dlinkrouter.local>
Reviewed-on: #11
This commit was merged in pull request #11.
This commit is contained in:
2026-07-14 12:03:22 +08:00
parent 1e50e3d19f
commit b05e074456
160 changed files with 6497 additions and 759 deletions
+43
View File
@@ -20,6 +20,7 @@ import { Lucide } from '@/components/ui/lucide'
import DataTable from '@/components/ui/usage/DataTable.vue'
import type { TableHeader } from '@/components/ui/usage/DataTable.vue'
import { usePermissions } from '@/composables/usePermissions'
import { EMPLOYERS } from '@/constants/employers'
import { getApiErrorMessage } from '@/core/utils/getApiErrorMessage'
import { listRoles } from '@/modules/role/services/role.service'
import type { RoleListItem } from '@/modules/role/types/role.types'
@@ -48,6 +49,22 @@ const STATUS_FILTER_CHIPS: StatusFilterChip[] = [
{ label: 'Menunggu', value: 'pending', variant: 'pending' },
]
function getEmployerShortLabel(name: string): string {
const match = name.match(/\(([^)]+)\)/)
if (match?.[1]) return match[1]
if (name.startsWith('An-Nisa')) return "An-Nisa'"
if (name.startsWith('Kel Infra')) return 'Kel Infra'
return name
}
const UNIT_FILTER_CHIPS = [
{ label: 'Semua', value: '' },
...EMPLOYERS.map((employer) => ({
label: getEmployerShortLabel(employer.name),
value: employer.name,
})),
]
const router = useRouter()
const { hasPermission } = usePermissions()
@@ -163,6 +180,14 @@ function setStatusFilter(value: string) {
statusFilter.value = value
}
function isUnitFilterActive(value: string) {
return unitFilter.value === value
}
function setUnitFilter(value: string) {
unitFilter.value = value
}
function formatDeletedAt(value: string | null | undefined): string {
if (!value) return '-'
return dayjs(value).format('DD MMM YYYY, HH:mm')
@@ -356,6 +381,7 @@ const {
error,
search,
statusFilter,
unitFilter,
joinDateFrom,
joinDateTo,
leaveDateFrom,
@@ -540,6 +566,23 @@ onMounted(() => {
{{ chip.label }}
</Badge>
</div>
<div class="flex flex-wrap items-center gap-2">
<span class="text-sm opacity-70">Unit:</span>
<Badge
v-for="chip in UNIT_FILTER_CHIPS"
:key="chip.value || 'all-units'"
variant="ghost"
:look="isUnitFilterActive(chip.value) ? 'filled' : 'outline'"
role="button"
tabindex="0"
:title="chip.value || 'Semua unit'"
:aria-pressed="isUnitFilterActive(chip.value)"
@click="setUnitFilter(chip.value)"
@keydown.enter="setUnitFilter(chip.value)"
>
{{ chip.label }}
</Badge>
</div>
</div>
</template>