WS-3 session 1b-i Tier 1. Scope: src/components/**, src/pages/**, src/layouts/**, src/views/** restricted to *.vue files. Mechanical formatting only — predominantly vue/html-indent (506 fixes in CrowdListDetailPanel.vue alone), padding-line-between-statements, antfu/if-newline. Excludes (per session prompt): - apps/app/vite.config.ts (Tier 3) - apps/app/themeConfig.ts (Tier 3) - apps/app/vitest.config.ts (Tier 3) - All TypeScript-only files in src/composables, src/lib, src/stores, src/plugins, src/types (Tier 2 — separate commit) Includes session 1a layouts (PortalLayout.vue, PublicLayout.vue) where 2 'lines-around-comment' errors were flagged in the previous 1b-i pre-flight inspection. Tests + typecheck verified green post-fix: - apps/app vitest: 49 passed (unchanged) - apps/app vue-tsc: clean (unchanged) - apps/portal vitest: 113 passed (unchanged — not touched) - backend pest: 1486 passed (unchanged — not touched) Lint baseline progression: - Pre-Tier-1: 1451 problems - Post-Tier-1: 422 problems Visual smoke status: - NOT YET SMOKED — Bert to verify before merge. This Claude Code session has no UI access; cannot run pnpm dev and click through affected routes. The high-traffic candidates are CrowdListDetailPanel (506 fixes), AssignPersonDialog (44), ShiftDetailPanel (36), and the events / form-failures pages. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
72 lines
1.6 KiB
Vue
72 lines
1.6 KiB
Vue
<script setup lang="ts">
|
|
/**
|
|
* Standaard KPI-tegel: icon + waarde, titel, optionele ondertitel.
|
|
* Zelfde structuur als event-statistieken; kaart-chrome is altijd gelijk (geen gekleurde rand tenzij borderAccent).
|
|
*/
|
|
type BorderAccent = 'primary' | 'warning' | 'info' | 'success' | 'error'
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
icon: string
|
|
iconColor?: string
|
|
value: string | number
|
|
title: string
|
|
|
|
/** Ondertitel; ontbreekt er een, dan blijft één regelhoogte gereserveerd voor gelijke tegelhoogtes. */
|
|
subtitle?: string
|
|
clickable?: boolean
|
|
borderAccent?: BorderAccent
|
|
}>(),
|
|
{
|
|
iconColor: 'primary',
|
|
clickable: false,
|
|
},
|
|
)
|
|
|
|
const emit = defineEmits<{
|
|
click: []
|
|
}>()
|
|
|
|
function onClick() {
|
|
if (props.clickable)
|
|
emit('click')
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<VCard
|
|
class="flex-grow-1 w-100 d-flex flex-column"
|
|
:class="[
|
|
clickable ? 'cursor-pointer' : '',
|
|
borderAccent ? `card-border-shadow-${borderAccent}` : '',
|
|
]"
|
|
@click="onClick"
|
|
>
|
|
<VCardText class="flex-grow-1 d-flex flex-column">
|
|
<div class="d-flex align-center mb-1">
|
|
<VAvatar
|
|
:color="iconColor"
|
|
variant="tonal"
|
|
size="44"
|
|
rounded
|
|
class="me-4"
|
|
>
|
|
<VIcon
|
|
:icon="icon"
|
|
size="28"
|
|
/>
|
|
</VAvatar>
|
|
<h4 class="text-h4 mb-0">
|
|
{{ value }}
|
|
</h4>
|
|
</div>
|
|
<p class="mb-1">
|
|
{{ title }}
|
|
</p>
|
|
<p class="mb-0 text-body-secondary text-sm">
|
|
{{ subtitle ?? '\u00a0' }}
|
|
</p>
|
|
</VCardText>
|
|
</VCard>
|
|
</template>
|