- Add NuxtLink on component/piece/product names in machine hierarchy
(using composantId, pieceId, product.id)
- Make site machine count badges clickable → /machines?sites={id}
- Add opt-in fixedLayout prop and minWidth to DataTable columns
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
87 lines
3.1 KiB
Vue
87 lines
3.1 KiB
Vue
<template>
|
|
<div
|
|
class="card site-card shadow-md hover:shadow-xl transition-shadow overflow-hidden"
|
|
:style="{
|
|
borderTop: site.color ? `4px solid ${site.color}` : '4px solid transparent',
|
|
background: site.color ? `linear-gradient(160deg, ${site.color}30 0%, ${site.color}08 40%, var(--color-base-100) 100%)` : undefined,
|
|
}"
|
|
>
|
|
<div class="card-body">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h3 class="card-title text-lg text-base-content">
|
|
{{ site.name }}
|
|
</h3>
|
|
<NuxtLink
|
|
:to="`/machines?sites=${site.id}`"
|
|
class="badge font-bold hover:opacity-80 transition-opacity"
|
|
:style="site.color ? { backgroundColor: site.color + '30', color: site.color, borderColor: site.color + '50' } : {}"
|
|
:class="!site.color ? 'badge-primary' : ''"
|
|
>
|
|
{{ machineCount }} machines
|
|
</NuxtLink>
|
|
</div>
|
|
|
|
<div class="space-y-3 text-sm">
|
|
<div class="flex items-center gap-2 text-base-content/80">
|
|
<IconLucideUser class="w-4 h-4 text-primary" aria-hidden="true" />
|
|
<span class="font-medium">{{ site.contactName }}</span>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-2 text-base-content/60">
|
|
<IconLucidePhone class="w-4 h-4 text-secondary" aria-hidden="true" />
|
|
<span>{{ formattedContactPhone }}</span>
|
|
</div>
|
|
|
|
<div class="flex items-start gap-2 text-base-content/60">
|
|
<IconLucideMapPin class="w-4 h-4 text-accent mt-1" aria-hidden="true" />
|
|
<span>
|
|
{{ site.contactAddress }}<br>
|
|
{{ site.contactPostalCode }} {{ site.contactCity }}
|
|
</span>
|
|
</div>
|
|
|
|
<NuxtLink :to="`/machines?sites=${site.id}`" class="flex items-center gap-2 text-base-content/60 hover:text-primary transition-colors">
|
|
<IconLucideFactory class="w-4 h-4 text-blue-500" aria-hidden="true" />
|
|
<span>{{ machineCount }} machine(s)</span>
|
|
</NuxtLink>
|
|
</div>
|
|
|
|
<div class="card-actions justify-end mt-4">
|
|
<button class="btn btn-sm btn-outline" @click="emit('edit', site)">
|
|
{{ canEdit ? 'Modifier' : 'Consulter' }}
|
|
</button>
|
|
<button v-if="canEdit" class="btn btn-sm btn-error" @click="emit('delete', site)">
|
|
Supprimer
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue'
|
|
import IconLucideFactory from '~icons/lucide/factory'
|
|
import IconLucideMapPin from '~icons/lucide/map-pin'
|
|
import IconLucidePhone from '~icons/lucide/phone'
|
|
import IconLucideUser from '~icons/lucide/user'
|
|
import { formatPhone } from '~/utils/formatters/phone'
|
|
|
|
const { canEdit } = usePermissions()
|
|
|
|
const props = defineProps({
|
|
site: {
|
|
type: Object,
|
|
required: true
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(['edit', 'delete'])
|
|
|
|
const machineCount = computed(() => props.site?.machines?.length || 0)
|
|
const formattedContactPhone = computed(() => {
|
|
const value = props.site?.contactPhone ?? ''
|
|
const formatted = formatPhone(value)
|
|
return formatted || value || '—'
|
|
})
|
|
</script>
|