feat(inspections): formulario y visor por grupos + comentarios + fotos
Parte 2 del bloque de plantillas/inspecciones: - Formulario de inspección (mapa): campos agrupados por sección, muestra la "pregunta" del campo (con la etiqueta como subtexto) y la ayuda; al final, apartado de Comentarios (notes) y subida de Fotos (media en la inspección). - ProjectMap: WithFileUploads + inspectionPhotos; saveInspection adjunta las fotos como media; Inspection gana relación media(). - Visor de inspección: datos agrupados por sección con pregunta/valor, comentarios y galería de fotos. Tests: InspectionFormTest (registra inspección con comentarios + foto). Suite 91 passing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Livewire\Projects;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\WithFileUploads;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Models\Project;
|
||||
use App\Models\Phase;
|
||||
@@ -15,6 +16,8 @@ use App\Models\Issue;
|
||||
|
||||
class ProjectMap extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public Project $project;
|
||||
public $phases;
|
||||
public $activeLayers = []; // Now stores Layer IDs (not Phase IDs)
|
||||
@@ -54,6 +57,7 @@ class ProjectMap extends Component
|
||||
// Inspection workflow
|
||||
public $inspectionResult = '';
|
||||
public $inspectionNotes = '';
|
||||
public $inspectionPhotos = [];
|
||||
|
||||
// Issues
|
||||
public $openIssuesCount = 0;
|
||||
@@ -247,6 +251,7 @@ class ProjectMap extends Component
|
||||
$this->inspectionFormData = [];
|
||||
$this->inspectionResult = '';
|
||||
$this->inspectionNotes = '';
|
||||
$this->inspectionPhotos = [];
|
||||
if ($this->selectedTemplateId) {
|
||||
$template = InspectionTemplate::find($this->selectedTemplateId);
|
||||
if ($template) {
|
||||
@@ -266,7 +271,10 @@ class ProjectMap extends Component
|
||||
$feature = Feature::with('layer.phase')->find($this->selectedFeature->id);
|
||||
if (!$feature || $feature->layer->phase->project_id !== $this->project->id) abort(403);
|
||||
|
||||
$this->validate(['selectedTemplateId' => 'required|exists:inspection_templates,id']);
|
||||
$this->validate([
|
||||
'selectedTemplateId' => 'required|exists:inspection_templates,id',
|
||||
'inspectionPhotos.*' => 'nullable|image|max:20480',
|
||||
]);
|
||||
|
||||
$template = InspectionTemplate::find($this->selectedTemplateId);
|
||||
foreach ($template->fields as $field) {
|
||||
@@ -290,6 +298,22 @@ class ProjectMap extends Component
|
||||
'data' => $this->inspectionFormData,
|
||||
]);
|
||||
|
||||
// Fotos adjuntas a la inspección
|
||||
foreach ($this->inspectionPhotos as $photo) {
|
||||
$mime = $photo->getMimeType();
|
||||
$path = $photo->store("uploads/inspections/{$inspection->id}", 'public');
|
||||
$inspection->media()->create([
|
||||
'name' => $photo->getClientOriginalName(),
|
||||
'file_path' => $path,
|
||||
'file_type' => $mime,
|
||||
'file_extension' => $photo->getClientOriginalExtension(),
|
||||
'file_size' => $photo->getSize(),
|
||||
'category' => str_starts_with($mime, 'image/') ? 'image' : 'document',
|
||||
'uploaded_by' => auth()->id(),
|
||||
'uuid' => (string) \Illuminate\Support\Str::uuid(),
|
||||
]);
|
||||
}
|
||||
|
||||
if ($this->inspectionResult === 'fail') {
|
||||
Issue::create([
|
||||
'project_id' => $this->project->id,
|
||||
@@ -363,7 +387,7 @@ class ProjectMap extends Component
|
||||
public function viewInspection($id)
|
||||
{
|
||||
$ins = Inspection::where('project_id', $this->project->id)
|
||||
->with(['feature.layer.phase', 'template', 'user'])
|
||||
->with(['feature.layer.phase', 'template', 'user', 'media'])
|
||||
->find($id);
|
||||
if (!$ins) return;
|
||||
$this->viewingInspection = [
|
||||
@@ -379,6 +403,7 @@ class ProjectMap extends Component
|
||||
'notes' => $ins->notes,
|
||||
'data' => $ins->data ?? [],
|
||||
'fields' => $ins->template?->fields ?? [],
|
||||
'photos' => $ins->media->map(fn ($m) => ['url' => $m->url, 'name' => $m->name])->values()->all(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user