Projects/3BIT/winter-semester/IIS/xnecasr00/resources/views/vineyard/map/edit.blade.php
2026-04-14 19:28:46 +02:00

410 lines
12 KiB
PHP

@extends('layouts.winemaker')
@section('title', 'Edit Vineyard Map')
@push('styles')
<style>
.map-edit-layout {
display: grid;
grid-template-columns: 260px 1fr;
gap: 2rem;
min-height: 70vh;
}
.editor-sidebar {
background: #ffffff;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.edit-panel {
background: #ffffff;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
display: flex;
flex-direction: column;
gap: 1rem;
}
.map-canvas-wrapper {
position: relative;
border: 1px dashed #cbd5e1;
border-radius: 12px;
min-height: 520px;
overflow: auto;
background: repeating-linear-gradient(90deg, rgba(99, 102, 241, 0.06) 0, rgba(99, 102, 241, 0.06) 1px, transparent 1px, transparent 96px),
repeating-linear-gradient(180deg, rgba(99, 102, 241, 0.06) 0, rgba(99, 102, 241, 0.06) 1px, transparent 1px, transparent 96px);
}
.vineyard-map-grid {
position: absolute;
top: 0;
left: 0;
transform-origin: top left;
}
.map-cell {
position: absolute;
border-radius: 12px;
border: 1px solid rgba(79, 70, 229, 0.35);
background: rgba(99, 102, 241, 0.18);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.35rem;
color: #1a365d;
box-shadow: 0 10px 20px rgba(15, 23, 42, 0.08);
transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.2s ease, border-color 0.2s ease;
cursor: pointer;
user-select: none;
}
.map-cell::after {
content: '';
position: absolute;
inset: 6px;
border-radius: 8px;
border: 1px dashed rgba(79, 70, 229, 0.2);
pointer-events: none;
}
.map-cell-count {
font-size: 1.05rem;
font-weight: 700;
}
.map-cell-variety {
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.04em;
opacity: 0.8;
}
.map-cell.selected {
background: rgba(59, 130, 246, 0.35);
border-color: rgba(37, 99, 235, 0.9);
box-shadow: 0 14px 26px rgba(37, 99, 235, 0.35);
}
.map-cell.remove-selected {
outline: 3px solid rgba(239, 68, 68, 0.65);
outline-offset: 2px;
}
.map-cell.status-inactive {
background: rgba(148, 163, 184, 0.18);
border-color: rgba(148, 163, 184, 0.7);
}
.map-cell.status-discarded {
background: rgba(239, 68, 68, 0.25);
border-color: rgba(239, 68, 68, 0.6);
}
.map-cell.status-harvested {
background: rgba(16, 185, 129, 0.22);
border-color: rgba(5, 150, 105, 0.6);
}
.map-secondary-nav {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
margin-bottom: 1rem;
}
.map-secondary-nav a {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.45rem 0.85rem;
border-radius: 999px;
background: rgba(148, 163, 184, 0.2);
color: #1e293b;
text-decoration: none;
font-size: 0.8rem;
font-weight: 600;
transition: background 0.2s ease, color 0.2s ease;
}
.map-secondary-nav a:hover {
background: rgba(37, 99, 235, 0.18);
color: #1d4ed8;
}
.map-secondary-nav a.active {
background: rgba(37, 99, 235, 0.28);
color: #1d4ed8;
}
.pending-cell {
position: absolute;
border: 2px dashed rgba(37, 99, 235, 0.85);
border-radius: 12px;
background: rgba(59, 130, 246, 0.18);
pointer-events: none;
box-shadow: inset 0 0 0 2px rgba(59, 130, 246, 0.25);
display: none;
transition: opacity 0.15s ease;
opacity: 0.85;
}
.mode-switch {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.mode-switch button {
border: 1px solid #dce5f3;
border-radius: 10px;
padding: 0.85rem 1rem;
background: #f4f7fb;
color: #1a365d;
font-weight: 600;
text-align: left;
transition: all 0.2s ease;
cursor: pointer;
}
.mode-switch button:hover,
.mode-switch button.active {
background: linear-gradient(135deg, #7fb4e0 0%, #9dcaeb 100%);
color: #ffffff;
border-color: transparent;
}
.mode-panels {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.mode-panel {
display: none;
flex-direction: column;
gap: 0.85rem;
}
.mode-panel.active {
display: flex;
}
.mode-panel form,
.mode-panel .panel-body {
display: flex;
flex-direction: column;
gap: 0.85rem;
}
.editor-sidebar label {
font-weight: 600;
color: #1a365d;
font-size: 0.9rem;
}
.editor-sidebar input,
.editor-sidebar select,
.editor-sidebar textarea {
width: 100%;
border-radius: 8px;
border: 1px solid #cbd5e1;
padding: 0.6rem 0.75rem;
font-size: 0.95rem;
}
.editor-sidebar button {
border: none;
border-radius: 8px;
padding: 0.7rem 1rem;
font-weight: 600;
cursor: pointer;
}
.btn-primary {
background: #2563eb;
color: #ffffff;
}
.btn-danger {
background: #ef4444;
color: #ffffff;
}
.btn-secondary {
background: #1e293b;
color: #ffffff;
}
.info-card {
margin-bottom: 1.5rem;
background: #f1f5f9;
border-radius: 10px;
padding: 1rem;
color: #475569;
}
.map-legend {
display: flex;
gap: 1rem;
font-size: 0.85rem;
color: #475569;
}
.map-feedback {
margin-top: 0.75rem;
font-size: 0.9rem;
color: #475569;
}
.map-feedback.feedback-success {
color: #0f766e;
}
.map-feedback.feedback-error {
color: #dc2626;
}
.map-feedback.feedback-info {
color: #475569;
}
.mode-actions {
display: flex;
gap: 0.5rem;
}
.mode-panel-divider {
height: 1px;
background: #e2e8f0;
}
.map-selection-layer {
position: absolute;
inset: 0;
pointer-events: none;
user-select: none;
}
.selection-box {
position: absolute;
border: 1px solid rgba(37, 99, 235, 0.85);
background: rgba(59, 130, 246, 0.2);
border-radius: 10px;
box-shadow: 0 0 0 1px rgba(37, 99, 235, 0.35);
pointer-events: none;
}
.add-marker {
position: absolute;
border: 2px dashed rgba(16, 185, 129, 0.8);
border-radius: 12px;
background: rgba(110, 231, 183, 0.2);
box-shadow: inset 0 0 0 2px rgba(16, 185, 129, 0.2);
pointer-events: none;
}
.selection-summary {
font-size: 0.85rem;
color: #64748b;
line-height: 1.4;
}
</style>
@endpush
@section('content')
<div class="map-edit-layout" data-page="vineyard-map-edit">
<aside class="editor-sidebar">
<div>
<h2 style="font-size:1.4rem; color:#1a365d; margin:0;">Map actions</h2>
<p style="font-size:0.9rem; color:#475569; margin:0.5rem 0 0;">Choose what you want to do, then use the map on the right.</p>
</div>
<div class="mode-switch" data-role="mode-switch">
<button type="button" data-mode="edit" class="active">Edit rows</button>
<button type="button" data-mode="add">Add rows</button>
<button type="button" data-mode="remove">Remove rows</button>
</div>
<div class="mode-panels">
<div class="mode-panel active" data-mode-panel="edit">
<form data-role="row-form">
<input type="hidden" name="row_id">
<label>Current location
<input type="text" name="location" readonly>
</label>
<label>Head count
<input type="number" name="vine_count" min="0" step="1" required>
</label>
<p style="font-size:0.85rem; color:#64748b;">Click an empty cell to stage a new location. Pending: <span data-role="relocation-target">None</span></p>
<button type="button" class="btn-secondary" data-control="clear-relocation" style="align-self:flex-start;">Clear staged move</button>
<div style="display:flex; gap:0.5rem;">
<button type="submit" class="btn-primary" style="flex:1;" disabled>Save row</button>
<button type="button" class="btn-danger" data-control="delete-row" disabled>Remove</button>
</div>
</form>
</div>
<div class="mode-panel" data-mode-panel="add">
<div class="panel-body">
<h3 style="margin:0; color:#1a365d;">Add rows</h3>
<p style="font-size:0.9rem; color:#475569;">Click empty squares to stage new rows. Hold Shift or drag to select multiple locations.</p>
<div class="mode-panel-divider"></div>
<label>Head count per row
<input type="number" name="add_vine_count" min="0" step="1" value="0">
</label>
<div class="mode-actions">
<button type="button" class="btn-primary" data-control="commit-add-selection" disabled>Create rows</button>
<button type="button" class="btn-secondary" data-control="clear-add-selection" disabled>Clear selection</button>
</div>
<p class="selection-summary">Selected squares: <span data-role="add-selection-count">0</span></p>
</div>
</div>
<div class="mode-panel" data-mode-panel="remove">
<div class="panel-body">
<h3 style="margin:0; color:#1a365d;">Remove rows</h3>
<p style="font-size:0.9rem; color:#475569;">Click rows to mark them for deletion. Hold Shift or drag to select multiple.</p>
<div class="mode-actions">
<button type="button" class="btn-danger" data-control="commit-remove-selection" disabled>Delete selected</button>
<button type="button" class="btn-secondary" data-control="clear-remove-selection" disabled>Clear selection</button>
</div>
<p class="selection-summary">Selected rows: <span data-role="remove-selection-count">0</span></p>
</div>
</div>
</div>
</aside>
<section class="edit-panel">
<div class="info-card">
<strong>Map editor:</strong> Choose an action on the left, then work directly on the grid.
<p class="map-feedback feedback-info" data-role="map-feedback" aria-live="polite">Select a row to edit or click an empty cell to stage a new location.</p>
</div>
<div class="map-secondary-nav" aria-label="Related vineyard navigation">
<a href="{{ route('vineyard.map') }}">Map Overview</a>
<a href="{{ route('vineyard.map.edit') }}" class="active" aria-current="page">Map Editor</a>
<a href="{{ route('vineyard-rows.index') }}">Row Directory</a>
</div>
<div class="map-canvas-wrapper" data-role="map-container"></div>
</section>
</div>
@php
$vineyardEditRoutes = [
'update' => route('vineyard.updateHeadCount'),
'add' => route('vineyard.addRows'),
'destroy' => route('vineyard.rows.destroy', ['vineyardRow' => '__ROW__']),
'remove' => route('vineyard.rows.destroyMany'),
];
@endphp
<script type="application/json" id="vineyard-edit-rows">@json($rows)</script>
<script type="application/json" id="vineyard-edit-routes">@json($vineyardEditRoutes)</script>
@endsection