Files
crewli/apps/app/src/components/AppKpiCard.vue
bert.hausmans 47bd533179 style(app): apply eslint --fix to Tier 1 (Vue templates)
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>
2026-04-29 11:04:46 +02:00

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>