Add contract management and invoice settings pages

- Created a new Blade view for managing brand contracts with forms for adding and editing contracts, including client and category selection.
- Implemented success message notifications for contract actions.
- Added a new Blade view for invoice settings, allowing customization of invoice number format, header branding, and default values for new invoices.
- Introduced a new PDF view for generating rate cards with customizable styles based on user profile settings.
- Developed a profile management page for rate cards, enabling users to update their identity, appearance, and visibility settings.
This commit is contained in:
I-Fun
2026-04-01 21:47:34 +07:00
parent d3c35ad730
commit 22f03ccca7
48 changed files with 2415 additions and 296 deletions

View File

@@ -6,8 +6,9 @@
@section('content')
<div class="max-w-2xl mx-auto">
<div class="cat-card p-4 lg:p-8">
<form action="{{ route('content.store') }}" method="POST" class="space-y-4">
@csrf
<form action="{{ route('content.store') }}" method="POST" class="space-y-4"
x-data="contractCheck('{{ route('contracts.check') }}')"
@submit.prevent="submitIfClear($el)">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div class="sm:col-span-2">
@@ -40,19 +41,38 @@
</div>
<div>
<label class="block text-sm font-semibold text-gray-700 mb-1">Client</label>
<select name="client_id" class="input-soft">
<select name="client_id" class="input-soft" x-model="clientId" @change="checkContract()">
<option value="">— None —</option>
@foreach($clients as $client)
<option value="{{ $client->id }}">{{ $client->name }}</option>
@endforeach
</select>
</div>
<div>
<label class="block text-sm font-semibold text-gray-700 mb-1">Category</label>
<select name="category_id" class="input-soft" x-model="categoryId" @change="checkContract()">
<option value="">— None —</option>
@foreach($categoryTree as $parent)
<option value="{{ $parent->id }}">{{ $parent->icon }} {{ $parent->name }}</option>
@foreach($parent->children as $child)
<option value="{{ $child->id }}">&nbsp;&nbsp;↳ {{ $child->name }}</option>
@endforeach
@endforeach
</select>
</div>
<div>
<label class="block text-sm font-semibold text-gray-700 mb-1">Target Date</label>
<input type="date" name="target_date" value="{{ old('target_date') }}" class="input-soft">
</div>
</div>
{{-- Contract warning --}}
<div x-show="contractWarning" x-transition
class="rounded-2xl bg-amber-50 border border-amber-200 px-4 py-3 text-sm" style="display:none">
<div class="font-semibold text-amber-700 mb-1">⚠️ Exclusive Contract Active</div>
<p class="text-amber-600 text-xs" x-text="contractMessage"></p>
</div>
{{-- Storyline Maker --}}
<div class="bg-pink-50 rounded-2xl p-4 space-y-3">
<h3 class="font-bold text-gray-700 flex items-center gap-2 text-sm">✍️ Storyline Maker</h3>
@@ -95,7 +115,8 @@
</div>
<div class="flex flex-col sm:flex-row gap-3 pt-1">
<button type="submit" class="btn-sakura flex-1 py-3">🎬 Create Brief</button>
<button type="submit" class="btn-sakura flex-1 py-3"
:class="{ 'opacity-50 cursor-not-allowed': contractWarning }">🎬 Create Brief</button>
<a href="{{ route('content.index') }}"
class="flex-1 py-3 text-center rounded-full border border-pink-200 text-gray-600 hover:bg-pink-50 font-semibold text-sm">
Cancel
@@ -104,4 +125,35 @@
</form>
</div>
</div>
@push('scripts')
<script>
function contractCheck(checkUrl) {
return {
categoryId: '',
clientId: '',
contractWarning: false,
contractMessage: '',
async checkContract() {
if (!this.categoryId) { this.contractWarning = false; return; }
const params = new URLSearchParams({ category_id: this.categoryId, client_id: this.clientId || '' });
const res = await fetch(checkUrl + '?' + params);
const data = await res.json();
if (data) {
this.contractWarning = true;
this.contractMessage = `"${data.title}" — ${data.client_name} holds exclusive rights in the ${data.category} category until ${data.end_date} (${data.days_left} days left).`;
} else {
this.contractWarning = false;
this.contractMessage = '';
}
},
submitIfClear(form) {
if (this.contractWarning) {
if (!confirm('⚠️ An exclusive contract is active for this category.\n\nAre you sure you want to proceed?')) return;
}
form.submit();
}
};
}
</script>
@endpush
@endsection