Files
roaauto/frontend/src/components/orders/OrderLineForm.vue
Marius Mutu ad41956ea1 feat(frontend): Dashboard + Orders UI + Vehicle Picker + Vehicles list
- Pinia stores: orders (CRUD, line management, totals recalc, stats) and vehicles (CRUD, search, marca/model cascade)
- useSync composable: auto-sync on window focus + periodic 60s interval
- VehiclePicker component: debounced autocomplete search by nr. inmatriculare or client name
- OrderLineForm component: manopera/material toggle with live total preview
- DashboardView: stats cards (orders, vehicles, revenue), recent orders list
- OrdersListView: filterable table (all/draft/validat/facturat), clickable rows
- OrderCreateView: vehicle picker + inline new vehicle form, tip deviz select, km/observatii
- OrderDetailView: order info, lines table with add/remove, totals, validate action
- VehiclesListView: searchable table, inline create form with marca/model cascade
- AppLayout: mobile hamburger menu with slide-in sidebar overlay

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 17:29:02 +02:00

133 lines
4.1 KiB
Vue

<template>
<div class="bg-gray-50 rounded-lg p-4 border border-gray-200">
<h4 class="text-sm font-medium text-gray-700 mb-3">Adauga linie</h4>
<form @submit.prevent="handleSubmit" class="space-y-3">
<!-- Tip -->
<div class="flex gap-3">
<label class="flex items-center gap-1.5 text-sm">
<input v-model="form.tip" type="radio" value="manopera" class="text-blue-600" />
Manopera
</label>
<label class="flex items-center gap-1.5 text-sm">
<input v-model="form.tip" type="radio" value="material" class="text-blue-600" />
Material
</label>
</div>
<!-- Descriere -->
<div>
<input
v-model="form.descriere"
type="text"
required
placeholder="Descriere operatiune / material"
class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<!-- Manopera fields -->
<div v-if="form.tip === 'manopera'" class="grid grid-cols-2 gap-3">
<div>
<label class="block text-xs text-gray-500 mb-1">Ore</label>
<input
v-model.number="form.ore"
type="number"
step="0.1"
min="0"
class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label class="block text-xs text-gray-500 mb-1">Pret/ora (RON)</label>
<input
v-model.number="form.pret_ora"
type="number"
step="0.01"
min="0"
class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
</div>
<!-- Material fields -->
<div v-if="form.tip === 'material'" class="grid grid-cols-3 gap-3">
<div>
<label class="block text-xs text-gray-500 mb-1">Cantitate</label>
<input
v-model.number="form.cantitate"
type="number"
step="0.01"
min="0"
class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label class="block text-xs text-gray-500 mb-1">Pret unitar (RON)</label>
<input
v-model.number="form.pret_unitar"
type="number"
step="0.01"
min="0"
class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label class="block text-xs text-gray-500 mb-1">UM</label>
<input
v-model="form.um"
type="text"
placeholder="buc"
class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
</div>
<!-- Total preview + submit -->
<div class="flex items-center justify-between pt-2">
<span class="text-sm text-gray-600">
Total: <strong>{{ computedTotal.toFixed(2) }} RON</strong>
</span>
<button
type="submit"
class="px-4 py-2 bg-blue-600 text-white text-sm rounded-md hover:bg-blue-700"
>
Adauga
</button>
</div>
</form>
</div>
</template>
<script setup>
import { reactive, computed } from 'vue'
const emit = defineEmits(['add'])
const form = reactive({
tip: 'manopera',
descriere: '',
ore: 0,
pret_ora: 0,
cantitate: 0,
pret_unitar: 0,
um: 'buc',
})
const computedTotal = computed(() => {
if (form.tip === 'manopera') return (form.ore || 0) * (form.pret_ora || 0)
return (form.cantitate || 0) * (form.pret_unitar || 0)
})
function handleSubmit() {
if (!form.descriere) return
emit('add', { ...form })
// Reset
form.descriere = ''
form.ore = 0
form.pret_ora = 0
form.cantitate = 0
form.pret_unitar = 0
form.um = 'buc'
}
</script>