135 lines
7.7 KiB
PHP
135 lines
7.7 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
<title>Lettura acqua - {{ $unita->stabile->denominazione ?? 'NetGescon' }}</title>
|
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
|
</head>
|
|
<body class="min-h-screen bg-slate-100 text-slate-900">
|
|
<div class="mx-auto max-w-3xl space-y-4 p-4 md:p-8">
|
|
<div>
|
|
<h1 class="text-2xl font-semibold">Invio lettura acqua</h1>
|
|
<p class="mt-1 text-sm text-slate-600">Compila la lettura attuale del contatore per l'unità indicata. La lettura resta il campo principale; le foto servono a fissare subito il dato del display.</p>
|
|
</div>
|
|
|
|
@if (session('success'))
|
|
<div class="rounded-lg border border-emerald-300 bg-emerald-50 p-3 text-sm text-emerald-700">{{ session('success') }}</div>
|
|
@endif
|
|
|
|
@if ($errors->any())
|
|
<div class="rounded-lg border border-red-300 bg-red-50 p-3 text-sm text-red-700">
|
|
<ul class="list-disc pl-5">
|
|
@foreach ($errors->all() as $error)
|
|
<li>{{ $error }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="rounded-lg bg-white p-4 shadow">
|
|
<div class="grid gap-3 md:grid-cols-2 text-sm">
|
|
<div><span class="font-medium">Stabile:</span> {{ $unita->stabile->codice_stabile ?? '' }} - {{ $unita->stabile->denominazione ?? '-' }}</div>
|
|
<div><span class="font-medium">Unità:</span> {{ $unita->codice_unita ?: ('UI #' . (int) $unita->id) }}</div>
|
|
<div><span class="font-medium">Servizio:</span> {{ $servizio->nome ?: 'Acqua' }}</div>
|
|
<div><span class="font-medium">Matricola:</span> {{ $servizio->contatore_matricola ?: '—' }}</div>
|
|
<div><span class="font-medium">Lettura precedente:</span> {{ $previous?->lettura_fine !== null ? number_format((float) $previous->lettura_fine, 3, ',', '.') : '—' }}</div>
|
|
<div><span class="font-medium">Ultima data nota:</span> {{ optional($previous?->periodo_al)->format('d/m/Y') ?: '—' }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="POST" action="{{ $submitUrl }}" enctype="multipart/form-data" class="space-y-4 rounded-lg bg-white p-4 shadow">
|
|
@csrf
|
|
|
|
<div class="rounded-xl border border-blue-100 bg-blue-50 p-4">
|
|
<label class="block text-sm">
|
|
<span class="mb-1 block text-sm font-semibold text-slate-900">Lettura attuale del contatore</span>
|
|
<input type="number" step="0.001" min="0" name="lettura_attuale" value="{{ old('lettura_attuale') }}" class="w-full rounded-md border-slate-300 text-lg font-semibold" required>
|
|
</label>
|
|
<div class="mt-2 text-xs text-slate-600">Inserisci solo il numero letto sul contatore. Se alleghi foto, il sistema conserva anche i metadati dello scatto.</div>
|
|
</div>
|
|
|
|
<div class="grid gap-4 md:grid-cols-2">
|
|
<label class="block text-sm">
|
|
<span class="mb-1 block font-medium">Chi sta inviando la lettura</span>
|
|
<input type="text" name="rilevatore_nome" value="{{ old('rilevatore_nome') }}" class="w-full rounded-md border-slate-300" required>
|
|
</label>
|
|
<label class="block text-sm">
|
|
<span class="mb-1 block font-medium">Contatto</span>
|
|
<input type="text" name="rilevatore_contatto" value="{{ old('rilevatore_contatto') }}" class="w-full rounded-md border-slate-300" placeholder="Telefono o email">
|
|
</label>
|
|
<label class="block text-sm">
|
|
<span class="mb-1 block font-medium">Data lettura</span>
|
|
<input type="date" name="data_lettura" value="{{ old('data_lettura', now()->toDateString()) }}" class="w-full rounded-md border-slate-300">
|
|
</label>
|
|
</div>
|
|
|
|
<div class="rounded-xl border border-slate-200 bg-slate-50 p-4">
|
|
<div class="mb-3 text-sm font-medium">Foto del contatore</div>
|
|
<div class="grid gap-4 md:grid-cols-2">
|
|
<label class="block text-sm">
|
|
<span class="mb-1 block font-medium">Foto contatore 1</span>
|
|
<input id="water-photo-1" type="file" name="foto_1" accept="image/*" capture="environment" class="w-full rounded-md border-slate-300">
|
|
</label>
|
|
<label class="block text-sm">
|
|
<span class="mb-1 block font-medium">Foto contatore 2</span>
|
|
<input id="water-photo-2" type="file" name="foto_2" accept="image/*" capture="environment" class="w-full rounded-md border-slate-300">
|
|
</label>
|
|
</div>
|
|
<div class="mt-4 grid gap-3 sm:grid-cols-2">
|
|
<div id="water-photo-preview-1" class="flex min-h-40 items-center justify-center rounded-xl border border-dashed border-slate-300 bg-white px-4 py-5 text-center text-sm text-slate-500">Nessuna foto 1 selezionata</div>
|
|
<div id="water-photo-preview-2" class="flex min-h-40 items-center justify-center rounded-xl border border-dashed border-slate-300 bg-white px-4 py-5 text-center text-sm text-slate-500">Nessuna foto 2 selezionata</div>
|
|
</div>
|
|
</div>
|
|
|
|
<label class="block text-sm">
|
|
<span class="mb-1 block font-medium">Note</span>
|
|
<textarea name="note" rows="3" class="w-full rounded-md border-slate-300">{{ old('note') }}</textarea>
|
|
</label>
|
|
|
|
<button type="submit" class="inline-flex items-center rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white">Invia lettura</button>
|
|
</form>
|
|
</div>
|
|
|
|
<script>
|
|
(() => {
|
|
const bindPreview = (inputId, previewId, emptyLabel) => {
|
|
const input = document.getElementById(inputId);
|
|
const preview = document.getElementById(previewId);
|
|
|
|
if (!input || !preview) {
|
|
return;
|
|
}
|
|
|
|
input.addEventListener('change', () => {
|
|
const [file] = Array.from(input.files || []);
|
|
preview.innerHTML = '';
|
|
|
|
if (!file) {
|
|
preview.textContent = emptyLabel;
|
|
preview.className = 'flex min-h-40 items-center justify-center rounded-xl border border-dashed border-slate-300 bg-white px-4 py-5 text-center text-sm text-slate-500';
|
|
return;
|
|
}
|
|
|
|
if (file.type.startsWith('image/')) {
|
|
const image = document.createElement('img');
|
|
image.src = URL.createObjectURL(file);
|
|
image.alt = file.name;
|
|
image.className = 'h-40 w-full rounded-xl object-cover';
|
|
preview.className = 'rounded-xl border border-slate-200 bg-white p-2';
|
|
preview.appendChild(image);
|
|
return;
|
|
}
|
|
|
|
preview.textContent = file.name;
|
|
preview.className = 'flex min-h-40 items-center justify-center rounded-xl border border-slate-200 bg-white px-4 py-5 text-center text-sm text-slate-500';
|
|
});
|
|
};
|
|
|
|
bindPreview('water-photo-1', 'water-photo-preview-1', 'Nessuna foto 1 selezionata');
|
|
bindPreview('water-photo-2', 'water-photo-preview-2', 'Nessuna foto 2 selezionata');
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html> |