Files
Kol-Manager/resources/views/contracts/index.blade.php
I-Fun 1b90f730a6 feat: add notes management feature with CRUD operations
- Created Note model and controller for handling notes.
- Added routes for notes CRUD operations.
- Implemented notes index view with search and pinning functionality.
- Created migration for notes table with necessary fields.
- Developed event creation form with client and contract options.
2026-04-02 23:24:38 +07:00

218 lines
12 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@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 – Energy Drinks 2025"
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' : '' }}>
&nbsp;&nbsp;↳ {{ $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' : '' }}>
&nbsp;&nbsp;↳ {{ $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