171 lines
11 KiB
PHP
171 lines
11 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('content')
|
|
<div class="max-w-4xl mx-auto space-y-6">
|
|
<div class="flex items-center gap-4">
|
|
<a href="{{ route('payroll.index') }}" class="p-2 text-gray-500 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/></svg>
|
|
</a>
|
|
<h1 class="text-2xl font-bold text-gray-900">{{ __('payroll.new_entry') }}</h1>
|
|
</div>
|
|
|
|
<!-- Two modes: Manual entry and Auto-calculate -->
|
|
<div class="border-b border-gray-200">
|
|
<nav class="flex gap-6 -mb-px">
|
|
<button type="button" onclick="switchTab('manual')" id="tab-manual" class="tab-btn border-b-2 border-teal-500 text-teal-600 pb-3 text-sm font-medium">{{ __('payroll.manual_entry') }}</button>
|
|
<button type="button" onclick="switchTab('auto')" id="tab-auto" class="tab-btn border-b-2 border-transparent text-gray-500 hover:text-gray-700 pb-3 text-sm font-medium">{{ __('payroll.auto_calculate') }}</button>
|
|
</nav>
|
|
</div>
|
|
|
|
<!-- Manual Entry Tab -->
|
|
<div id="panel-manual">
|
|
<form method="POST" action="{{ route('payroll.store') }}" class="bg-white rounded-xl border border-gray-200 p-6 space-y-5">
|
|
@csrf
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
|
|
<div>
|
|
<label for="employee_id" class="block text-sm font-medium text-gray-700 mb-1">{{ __('payroll.employee') }} <span class="text-red-500">*</span></label>
|
|
<select id="employee_id" name="employee_id" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500" required>
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($employees as $emp)
|
|
<option value="{{ $emp->id }}">{{ $emp->first_name }} {{ $emp->last_name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label for="type" class="block text-sm font-medium text-gray-700 mb-1">{{ __('payroll.type') }} <span class="text-red-500">*</span></label>
|
|
<select id="type" name="type" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500" required>
|
|
@foreach(['salary', 'overtime', 'bonus', 'deduction', 'advance', 'allowance'] as $type)
|
|
<option value="{{ $type }}">{{ __('payroll.type_' . $type) }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label for="amount" class="block text-sm font-medium text-gray-700 mb-1">{{ __('payroll.amount') }} <span class="text-red-500">*</span></label>
|
|
<input type="number" id="amount" name="amount" step="1" min="0"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500" required>
|
|
</div>
|
|
<div>
|
|
<label for="currency_id" class="block text-sm font-medium text-gray-700 mb-1">{{ __('common.currency') }}</label>
|
|
<select id="currency_id" name="currency_id" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500">
|
|
@foreach($currencies as $currency)
|
|
<option value="{{ $currency->id }}" {{ $currency->is_default ? 'selected' : '' }}>{{ $currency->code }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label for="effective_date" class="block text-sm font-medium text-gray-700 mb-1">{{ __('payroll.effective_date') }} <span class="text-red-500">*</span></label>
|
|
<x-date-input name="effective_date" :value="now()->format('Y-m-d')" />
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500" required>
|
|
</div>
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<div>
|
|
<label for="month" class="block text-sm font-medium text-gray-700 mb-1">{{ __('payroll.month') }} <span class="text-red-500">*</span></label>
|
|
<select id="month" name="month" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500" required>
|
|
@foreach(range(1, 12) as $m)
|
|
<option value="{{ $m }}" {{ $m == $currentMonth ? 'selected' : '' }}>{{ $m }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label for="year" class="block text-sm font-medium text-gray-700 mb-1">{{ __('payroll.year') }} <span class="text-red-500">*</span></label>
|
|
<input type="number" id="year" name="year" value="{{ $currentYear }}" min="1400" max="1500"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500" required>
|
|
</div>
|
|
</div>
|
|
<div class="md:col-span-2">
|
|
<label for="description" class="block text-sm font-medium text-gray-700 mb-1">{{ __('common.description') }}</label>
|
|
<textarea id="description" name="description" rows="2"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500"></textarea>
|
|
</div>
|
|
<div class="md:col-span-2">
|
|
<label for="notes" class="block text-sm font-medium text-gray-700 mb-1">{{ __('payroll.notes') }}</label>
|
|
<textarea id="notes" name="notes" rows="2"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center justify-end gap-3 pt-4 border-t border-gray-200">
|
|
<a href="{{ route('payroll.index') }}" class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors">{{ __('common.cancel') }}</a>
|
|
<button type="submit" class="px-6 py-2 text-sm font-medium text-white bg-teal-600 rounded-lg hover:bg-teal-700 transition-colors">{{ __('common.create') }}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Auto Calculate Tab -->
|
|
<div id="panel-auto" class="hidden">
|
|
<form method="POST" action="{{ route('payroll.auto-calculate') }}" class="bg-white rounded-xl border border-gray-200 p-6 space-y-5">
|
|
@csrf
|
|
<div class="p-4 bg-teal-50 border border-teal-200 rounded-lg text-sm text-teal-800">
|
|
<strong>{{ __('payroll.auto_calculate_help_title') }}</strong><br>
|
|
{{ __('payroll.auto_calculate_help') }}
|
|
</div>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
|
|
<div>
|
|
<label for="auto_month" class="block text-sm font-medium text-gray-700 mb-1">{{ __('payroll.month') }} <span class="text-red-500">*</span></label>
|
|
<select id="auto_month" name="month" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500" required>
|
|
@foreach(range(1, 12) as $m)
|
|
<option value="{{ $m }}" {{ $m == $currentMonth ? 'selected' : '' }}>{{ $m }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label for="auto_year" class="block text-sm font-medium text-gray-700 mb-1">{{ __('payroll.year') }} <span class="text-red-500">*</span></label>
|
|
<input type="number" id="auto_year" name="year" value="{{ $currentYear }}" min="1400" max="1500"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500" required>
|
|
</div>
|
|
<div class="md:col-span-2">
|
|
<label class="flex items-center gap-2">
|
|
<input type="checkbox" name="include_worklogs" value="1" checked class="rounded border-gray-300 text-teal-600 focus:ring-teal-500">
|
|
<span class="text-sm font-medium text-gray-700">{{ __('payroll.include_worklogs') }}</span>
|
|
</label>
|
|
<p class="text-xs text-gray-500 mt-1">{{ __('payroll.include_worklogs_help') }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Employee Selection -->
|
|
<div>
|
|
<div class="flex items-center justify-between mb-2">
|
|
<label class="block text-sm font-medium text-gray-700">{{ __('payroll.select_employees') }}</label>
|
|
<button type="button" onclick="toggleAllEmployees()" class="text-xs text-teal-600 hover:text-teal-800 font-medium">{{ __('common.all') }} / {{ __('common.none') }}</button>
|
|
</div>
|
|
<div class="max-h-64 overflow-y-auto border border-gray-300 rounded-lg p-3 space-y-2">
|
|
@foreach($employees as $emp)
|
|
<label class="flex items-center gap-3 p-2 hover:bg-gray-50 rounded-lg cursor-pointer">
|
|
<input type="checkbox" name="employee_ids[]" value="{{ $emp->id }}" checked class="employee-checkbox rounded border-gray-300 text-teal-600 focus:ring-teal-500">
|
|
<div class="flex-1">
|
|
<span class="text-sm font-medium text-gray-900">{{ $emp->first_name }} {{ $emp->last_name }}</span>
|
|
<span class="text-xs text-gray-500 mr-2">{{ $emp->job_title ?? '' }}</span>
|
|
</div>
|
|
</label>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-center justify-end gap-3 pt-4 border-t border-gray-200">
|
|
<a href="{{ route('payroll.index') }}" class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors">{{ __('common.cancel') }}</a>
|
|
<button type="submit" class="px-6 py-2 text-sm font-medium text-white bg-teal-600 rounded-lg hover:bg-teal-700 transition-colors">{{ __('payroll.auto_calculate_btn') }}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function switchTab(tab) {
|
|
document.querySelectorAll('.tab-btn').forEach(btn => {
|
|
btn.classList.remove('border-teal-500', 'text-teal-600');
|
|
btn.classList.add('border-transparent', 'text-gray-500');
|
|
});
|
|
document.getElementById('tab-' + tab).classList.add('border-teal-500', 'text-teal-600');
|
|
document.getElementById('tab-' + tab).classList.remove('border-transparent', 'text-gray-500');
|
|
|
|
document.getElementById('panel-manual').classList.toggle('hidden', tab !== 'manual');
|
|
document.getElementById('panel-auto').classList.toggle('hidden', tab !== 'auto');
|
|
}
|
|
|
|
function toggleAllEmployees() {
|
|
const checkboxes = document.querySelectorAll('.employee-checkbox');
|
|
const allChecked = [...checkboxes].every(cb => cb.checked);
|
|
checkboxes.forEach(cb => cb.checked = !allChecked);
|
|
}
|
|
</script>
|
|
@endsection
|