big refactor
This commit is contained in:
110
app/components/back-office/KanbanTaskCard.vue
Normal file
110
app/components/back-office/KanbanTaskCard.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
task: any
|
||||
urgent?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
click: [task: any]
|
||||
}>()
|
||||
|
||||
const policyTypeColors: Record<string, string> = {
|
||||
car: 'bg-blue-100 text-blue-700',
|
||||
life: 'bg-violet-100 text-violet-700',
|
||||
fire: 'bg-amber-100 text-amber-700'
|
||||
}
|
||||
|
||||
function onClick() {
|
||||
emit('click', props.task)
|
||||
}
|
||||
|
||||
function daysInStage(createdAt: string): string {
|
||||
const days = Math.floor((Date.now() - new Date(createdAt).getTime()) / (1000 * 60 * 60 * 24))
|
||||
return days === 0 ? 'Today' : `${days}d`
|
||||
}
|
||||
|
||||
function formatDate(date: string, format: 'short' = 'short'): string {
|
||||
if (!date) return '—'
|
||||
const d = new Date(date)
|
||||
if (format === 'short') {
|
||||
return d.toLocaleDateString('es-PA', { month: 'short', day: 'numeric' })
|
||||
}
|
||||
return d.toLocaleDateString('es-PA', {
|
||||
day: '2-digit',
|
||||
month: 'short',
|
||||
year: 'numeric'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="kanban-task-card rounded-xl border px-3.5 py-3 shadow-sm ring-1 transition hover:shadow-md"
|
||||
:class="urgent
|
||||
? 'border-rose-300 bg-rose-50/50 ring-rose-100 hover:border-rose-400'
|
||||
: 'border-[var(--card-border)] bg-[var(--surface)] ring-[var(--surface)] hover:border-[var(--brand)]/30'"
|
||||
@click="onClick"
|
||||
>
|
||||
<!-- Header row: Application ID + Policy type badge -->
|
||||
<div class="flex items-start justify-between gap-1 mb-1">
|
||||
<p class="text-[13px] font-mono font-semibold leading-tight text-[var(--text-primary)] truncate">
|
||||
{{ task.application_id }}
|
||||
</p>
|
||||
<span
|
||||
class="ml-1 shrink-0 rounded-md px-1.5 py-0.5 text-[10px] font-semibold"
|
||||
:class="policyTypeColors[task.policy_type] || 'bg-gray-100 text-gray-700'"
|
||||
>
|
||||
{{ task.policy_type?.toUpperCase() }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Provider name -->
|
||||
<p class="text-[12px] text-[var(--text-muted)] truncate">
|
||||
{{ task.provider_name || 'Unknown Provider' }}
|
||||
</p>
|
||||
|
||||
<!-- Urgent flag -->
|
||||
<span v-if="urgent" class="mt-1.5 inline-flex items-center gap-1 rounded-full bg-rose-100 px-1.5 py-0.5 text-[9px] font-bold uppercase tracking-wide text-rose-600">
|
||||
<span class="h-1.5 w-1.5 rounded-full bg-rose-500" />
|
||||
Urgent
|
||||
</span>
|
||||
|
||||
<!-- Meta row -->
|
||||
<div class="mt-2.5 flex items-center justify-between border-t border-[var(--divider)] pt-2">
|
||||
<div class="flex items-center gap-1">
|
||||
<!-- Assignee -->
|
||||
<div v-if="task.assignee" class="flex items-center gap-1 text-[11px] text-[var(--text-muted)]">
|
||||
<UIcon name="i-heroicons-user" class="w-3 h-3" />
|
||||
<span class="truncate max-w-[60px]">{{ task.assignee.name }}</span>
|
||||
</div>
|
||||
<div v-else class="flex items-center gap-1 text-[11px] text-[var(--text-muted)] opacity-50">
|
||||
<UIcon name="i-heroicons-user-minus" class="w-3 h-3" />
|
||||
<span>Unassigned</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 text-[11px] text-[var(--text-muted)]">
|
||||
<!-- Due date if present -->
|
||||
<span v-if="task.due_date" class="truncate">
|
||||
Due: {{ formatDate(task.due_date, 'short') }}
|
||||
</span>
|
||||
<!-- Days in stage -->
|
||||
<span class="flex items-center gap-0.5">
|
||||
<UIcon name="i-heroicons-clock" class="w-3 h-3" />
|
||||
{{ daysInStage(task.created_at) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.kanban-task-card {
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
.kanban-task-card:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user