Add price list management across the API, store, services, routes, navigation, and sales views. Support quotes for either a client or a client group, including PDF download and nullable client validation for group-based recipients. Extend client groups to manage assigned clients directly from the form and detail views, and refresh supplier, intervention, stock, and order screens with updated interactions and layouts.
78 lines
3.8 KiB
Vue
78 lines
3.8 KiB
Vue
<template>
|
|
<nav class="tab-nav">
|
|
<button
|
|
v-for="tab in tabs"
|
|
:key="tab.id"
|
|
class="tab-item"
|
|
:class="{ active: activeTab === tab.id }"
|
|
@click="$emit('change-tab', tab.id)"
|
|
>
|
|
<span class="tab-icon" v-html="tab.icon"></span>
|
|
<span class="tab-label">{{ tab.label }}</span>
|
|
<span v-if="tab.id === 'team' && teamCount > 0" class="tab-badge">{{ teamCount }}</span>
|
|
<span v-if="tab.id === 'documents' && documentsCount > 0" class="tab-badge">{{ documentsCount }}</span>
|
|
</button>
|
|
</nav>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { defineProps, defineEmits } from 'vue';
|
|
|
|
defineProps({
|
|
activeTab: { type: String, required: true },
|
|
teamCount: { type: Number, default: 0 },
|
|
documentsCount:{ type: Number, default: 0 },
|
|
});
|
|
defineEmits(['change-tab']);
|
|
|
|
const tabs = [
|
|
{ id:'overview', label:"Vue d'ensemble", icon:`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>` },
|
|
{ id:'details', label:'Détails', icon:`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg>` },
|
|
{ id:'team', label:'Équipe', icon:`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>` },
|
|
{ id:'documents', label:'Documents', icon:`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>` },
|
|
{ id:'quote', label:'Devis', icon:`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>` },
|
|
{ id:'history', label:'Historique', icon:`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 .49-4.5"/></svg>` },
|
|
];
|
|
</script>
|
|
|
|
<style scoped>
|
|
.tab-nav {
|
|
--brand: #4f46e5;
|
|
--brand-lt: #eef2ff;
|
|
--brand-dk: #3730a3;
|
|
--surface-2:#f8fafc;
|
|
--border-lt:#f1f5f9;
|
|
--text-1: #0f172a;
|
|
--text-2: #64748b;
|
|
--text-3: #94a3b8;
|
|
--r-sm: 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
font-family: 'Inter', system-ui, sans-serif;
|
|
}
|
|
|
|
.tab-item {
|
|
display: flex; align-items: center; gap: 9px;
|
|
padding: 8px 11px; border-radius: var(--r-sm);
|
|
border: none; background: transparent; cursor: pointer;
|
|
width: 100%; text-align: left;
|
|
font-size: 13.5px; font-weight: 500; color: var(--text-2);
|
|
transition: background .12s, color .12s;
|
|
}
|
|
.tab-item:hover { background: var(--surface-2); color: var(--text-1); }
|
|
.tab-item.active { background: var(--brand-lt); color: var(--brand); font-weight: 600; }
|
|
|
|
.tab-icon { flex-shrink: 0; display: flex; color: var(--text-3); }
|
|
.tab-item.active .tab-icon { color: var(--brand); }
|
|
.tab-label { flex: 1; }
|
|
|
|
.tab-badge {
|
|
min-width: 19px; height: 19px; padding: 0 5px; border-radius: 10px;
|
|
background: var(--brand); color: white;
|
|
font-size: 10.5px; font-weight: 700;
|
|
display: flex; align-items: center; justify-content: center;
|
|
}
|
|
.tab-item.active .tab-badge { background: var(--brand-dk); }
|
|
</style>
|