218 lines
12 KiB
PHP
218 lines
12 KiB
PHP
@extends('layouts.app')
|
||
@section('title', 'Brand Contracts')
|
||
@section('page-title', '📋 Brand Contracts')
|
||
@section('page-subtitle', 'Manage exclusive brand agreements per category')
|
||
|
||
@section('content')
|
||
<div class="max-w-4xl mx-auto space-y-5">
|
||
|
||
@if(session('success'))
|
||
<div x-data="{ show: true }" x-show="show" x-init="setTimeout(() => show = false, 4000)"
|
||
class="flex items-center justify-between gap-3 bg-green-50 border border-green-200 rounded-2xl px-4 py-3 text-sm text-green-700">
|
||
<span>{{ session('success') }}</span>
|
||
<button @click="show = false" class="text-green-500 hover:text-green-700 text-lg leading-none">✕</button>
|
||
</div>
|
||
@endif
|
||
|
||
{{-- Add Contract --}}
|
||
<div class="cat-card overflow-hidden" x-data="{ open: {{ $errors->any() ? 'true' : 'false' }} }">
|
||
<div class="flex items-center gap-3 px-5 py-4 border-b border-pink-50">
|
||
<button type="button" @click="open = !open"
|
||
class="btn-sakura text-xs"
|
||
x-text="open ? '✕ Close' : '+ Add New Contract'">
|
||
</button>
|
||
</div>
|
||
|
||
<div x-show="open" x-transition style="display:none">
|
||
<form action="{{ route('contracts.store') }}" method="POST"
|
||
class="p-5 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 border-b border-pink-50">
|
||
@csrf
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Contract Title <span class="text-pink-400">*</span></label>
|
||
<input type="text" name="title" required maxlength="255"
|
||
placeholder="e.g. Exclusive – Susu Formula 2026"
|
||
class="input-soft" value="{{ old('title') }}">
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Brand / Client</label>
|
||
<select name="client_id" class="input-soft">
|
||
<option value="">— No specific client —</option>
|
||
@foreach($clients as $c)
|
||
<option value="{{ $c->id }}" {{ old('client_id') == $c->id ? 'selected' : '' }}>
|
||
{{ $c->name }}
|
||
</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Category (exclusive) <span class="text-pink-400">*</span></label>
|
||
<select name="category_id" required class="input-soft">
|
||
<option value="">— Select category —</option>
|
||
@foreach($categoryTree as $parent)
|
||
<option value="{{ $parent->id }}" {{ old('category_id') == $parent->id ? 'selected' : '' }}>
|
||
{{ $parent->icon }} {{ $parent->name }}
|
||
</option>
|
||
@foreach($parent->children as $child)
|
||
<option value="{{ $child->id }}" {{ old('category_id') == $child->id ? 'selected' : '' }}>
|
||
↳ {{ $child->name }}
|
||
</option>
|
||
@endforeach
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Start Date <span class="text-pink-400">*</span></label>
|
||
<input type="date" name="start_date" required class="input-soft"
|
||
value="{{ old('start_date', today()->toDateString()) }}">
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">End Date <span class="text-pink-400">*</span></label>
|
||
<input type="date" name="end_date" required class="input-soft"
|
||
value="{{ old('end_date') }}">
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Notes</label>
|
||
<input type="text" name="notes" maxlength="500" placeholder="Optional notes…"
|
||
class="input-soft" value="{{ old('notes') }}">
|
||
</div>
|
||
<div class="sm:col-span-2 lg:col-span-3 flex justify-end pt-1">
|
||
<button type="submit" class="btn-sakura px-6 py-2.5">📋 Add Contract</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Contracts List --}}
|
||
<div class="cat-card overflow-hidden">
|
||
<div class="flex items-center gap-3 px-5 py-4 border-b border-pink-50">
|
||
<span class="text-xl">📋</span>
|
||
<h2 class="font-bold text-gray-700">All Contracts</h2>
|
||
<span class="ml-auto text-xs bg-pink-100 text-pink-600 font-semibold px-2.5 py-0.5 rounded-full">
|
||
{{ $contracts->count() }} total
|
||
</span>
|
||
</div>
|
||
|
||
@forelse($contracts as $contract)
|
||
<div x-data="{ editing: false }" class="border-b border-pink-50 last:border-0">
|
||
<div class="flex items-center gap-3 px-5 py-3 hover:bg-pink-50/30 transition-colors">
|
||
<span class="badge {{ $contract->statusColor }} shrink-0">{{ $contract->statusLabel }}</span>
|
||
<div class="flex-1 min-w-0">
|
||
<div class="font-semibold text-gray-700 text-sm truncate">{{ $contract->title }}</div>
|
||
<div class="text-xs text-gray-400 flex flex-wrap gap-x-3 mt-0.5">
|
||
@if($contract->client)<span>👤 {{ $contract->client->name }}</span>@endif
|
||
@if($contract->category)<span>🏷️ {{ $contract->category->fullName }}</span>@endif
|
||
<span>📅 {{ $contract->start_date->format('d M Y') }} – {{ $contract->end_date->format('d M Y') }}</span>
|
||
@if($contract->isCurrentlyActive())
|
||
<span class="text-pink-500 font-medium">{{ $contract->days_remaining }}d left</span>
|
||
@endif
|
||
</div>
|
||
@if($contract->notes)
|
||
<div class="text-xs text-gray-400 mt-0.5 italic truncate">{{ $contract->notes }}</div>
|
||
@endif
|
||
</div>
|
||
<div class="flex gap-1.5 shrink-0">
|
||
<form action="{{ route('contracts.toggle', $contract) }}" method="POST">
|
||
@csrf @method('PATCH')
|
||
<button class="text-xs px-2.5 py-1.5 rounded-full border
|
||
{{ $contract->is_active ? 'border-amber-200 text-amber-500 hover:bg-amber-50' : 'border-green-200 text-green-500 hover:bg-green-50' }}"
|
||
title="{{ $contract->is_active ? 'Pause' : 'Activate' }}">
|
||
{{ $contract->is_active ? '⏸️' : '▶️' }}
|
||
</button>
|
||
</form>
|
||
<button @click="editing = !editing"
|
||
class="text-xs px-2.5 py-1.5 rounded-full border border-blue-200 text-blue-500 hover:bg-blue-50">
|
||
✏️
|
||
</button>
|
||
<form action="{{ route('contracts.destroy', $contract) }}" method="POST"
|
||
onsubmit="return confirm('Delete this contract?')">
|
||
@csrf @method('DELETE')
|
||
<button class="text-xs px-2.5 py-1.5 rounded-full border border-red-100 text-red-400 hover:bg-red-50">
|
||
🗑️
|
||
</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div x-show="editing" x-transition style="display:none"
|
||
class="px-5 pb-5 pt-3 bg-pink-50/20 border-t border-pink-50">
|
||
<form action="{{ route('contracts.update', $contract) }}" method="POST"
|
||
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
|
||
@csrf @method('PUT')
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Title</label>
|
||
<input type="text" name="title" required value="{{ $contract->title }}" class="input-soft">
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Brand / Client</label>
|
||
<select name="client_id" class="input-soft">
|
||
<option value="">— No specific client —</option>
|
||
@foreach($clients as $c)
|
||
<option value="{{ $c->id }}" {{ $contract->client_id == $c->id ? 'selected' : '' }}>{{ $c->name }}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Category</label>
|
||
<select name="category_id" required class="input-soft">
|
||
<option value="">— Select —</option>
|
||
@foreach($categoryTree as $parent)
|
||
<option value="{{ $parent->id }}" {{ $contract->category_id == $parent->id ? 'selected' : '' }}>
|
||
{{ $parent->icon }} {{ $parent->name }}
|
||
</option>
|
||
@foreach($parent->children as $child)
|
||
<option value="{{ $child->id }}" {{ $contract->category_id == $child->id ? 'selected' : '' }}>
|
||
↳ {{ $child->name }}
|
||
</option>
|
||
@endforeach
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Start Date</label>
|
||
<input type="date" name="start_date" required value="{{ $contract->start_date->toDateString() }}" class="input-soft">
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">End Date</label>
|
||
<input type="date" name="end_date" required value="{{ $contract->end_date->toDateString() }}" class="input-soft">
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-semibold text-gray-600 mb-1">Notes</label>
|
||
<input type="text" name="notes" value="{{ $contract->notes }}" class="input-soft">
|
||
</div>
|
||
<div class="flex items-center gap-4 sm:col-span-2 lg:col-span-3">
|
||
<label class="flex items-center gap-2 cursor-pointer">
|
||
<input type="checkbox" name="is_active" value="1"
|
||
class="w-4 h-4 accent-pink-400 rounded"
|
||
{{ $contract->is_active ? 'checked' : '' }}>
|
||
<span class="text-sm text-gray-600">Active</span>
|
||
</label>
|
||
<button type="submit" class="btn-sakura px-5 py-2 text-sm ml-auto">💾 Save</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
@empty
|
||
<div class="text-center py-14 text-gray-400">
|
||
<div class="text-4xl mb-2">📋</div>
|
||
<p class="text-sm">No contracts yet. Add your first exclusive agreement above.</p>
|
||
</div>
|
||
@endforelse
|
||
</div>
|
||
|
||
{{-- How it works --}}
|
||
<div class="cat-card overflow-hidden border-blue-100 bg-blue-50/30">
|
||
<div class="flex items-center gap-3 px-5 py-3 border-b border-blue-100">
|
||
<span class="text-xl">💡</span>
|
||
<h2 class="font-semibold text-gray-600 text-sm">How Brand Contracts Work</h2>
|
||
</div>
|
||
<ul class="text-xs text-gray-500 space-y-1.5 px-5 py-4">
|
||
<li>🔒 When a contract is <strong>Active</strong>, creating schedules or content for a competing brand in the same category will show a warning.</li>
|
||
<li>✅ The contracted brand itself is always allowed — no warning shown.</li>
|
||
<li>🏷️ Blocking a <strong>parent category</strong> also blocks all its subcategories.</li>
|
||
<li>📅 Contracts only block during their active date range. Expired contracts are ignored automatically.</li>
|
||
</ul>
|
||
</div>
|
||
|
||
</div>
|
||
@endsection
|