You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
11 KiB
175 lines
11 KiB
@use(App\Domains\System\Support\ValueObjects\Money)
|
|
|
|
<div>
|
|
<div class="row g-3 g-lg-4">
|
|
<!-- Left Column: Admission Schedule Info Card -->
|
|
<div class="col-12 col-lg-4">
|
|
<x-card :title="__('domains/admission/field.admission_schedule_detail.schedule_detail')">
|
|
<div class="d-flex flex-column gap-3">
|
|
<!-- Track Name -->
|
|
<div class="p-3 rounded-3 bg-body-tertiary border border-body-tertiary">
|
|
<small class="text-body-secondary fw-semibold text-uppercase d-block mb-1 fs-7">
|
|
{{ __('domains/admission/field.admission_schedule.track_name') }}
|
|
</small>
|
|
<span class="fw-bold text-body fs-6">
|
|
{{ $this->admissionSchedule->admissionTrack->name }}
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Term Name -->
|
|
<div class="p-3 rounded-3 bg-body-tertiary border border-body-tertiary">
|
|
<small class="text-body-secondary fw-semibold text-uppercase d-block mb-1 fs-7">
|
|
{{ __('domains/admission/field.admission_schedule.term_name') }}
|
|
</small>
|
|
<span class="fw-bold text-body">
|
|
{{ $this->admissionSchedule->term->name }}
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Admission Period -->
|
|
<div class="p-3 rounded-3 bg-body-tertiary border border-body-tertiary">
|
|
<small class="text-body-secondary fw-semibold text-uppercase d-block mb-2 fs-7">
|
|
{{ __('domains/admission/field.admission_schedule_detail.admission_period') }}
|
|
</small>
|
|
<div class="d-flex align-items-center justify-content-between gap-2">
|
|
<div>
|
|
<small class="text-body-secondary fs-7 d-block">{{ __('domains/admission/field.admission_schedule.date_start') }}</small>
|
|
<span class="fw-bold text-body font-monospace">{{ $this->admissionSchedule->date_start->format('d M Y') }}</span>
|
|
</div>
|
|
<x-tabler-arrow-right class="text-body-tertiary flex-shrink-0" width="16" height="16" />
|
|
<div class="text-end">
|
|
<small class="text-body-secondary fs-7 d-block">{{ __('domains/admission/field.admission_schedule.date_end') }}</small>
|
|
<span class="fw-bold text-body font-monospace">{{ $this->admissionSchedule->date_end->format('d M Y') }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Re-registration Period -->
|
|
<div class="p-3 rounded-3 bg-body-tertiary border border-body-tertiary">
|
|
<small class="text-body-secondary fw-semibold text-uppercase d-block mb-2 fs-7">
|
|
{{ __('domains/admission/field.admission_schedule_detail.re_registration_period') }}
|
|
</small>
|
|
<div class="d-flex align-items-center justify-content-between gap-2">
|
|
<div>
|
|
<small class="text-body-secondary fs-7 d-block">{{ __('domains/admission/field.admission_schedule.re_registration_date_start') }}</small>
|
|
<span class="fw-bold text-body font-monospace">{{ $this->admissionSchedule->re_registration_date_start->format('d M Y') }}</span>
|
|
</div>
|
|
<x-tabler-arrow-right class="text-body-tertiary flex-shrink-0" width="16" height="16" />
|
|
<div class="text-end">
|
|
<small class="text-body-secondary fs-7 d-block">{{ __('domains/admission/field.admission_schedule.re_registration_date_end') }}</small>
|
|
<span class="fw-bold text-body font-monospace">{{ $this->admissionSchedule->re_registration_date_end->format('d M Y') }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</x-card>
|
|
</div>
|
|
|
|
<!-- Right Column: Fee Structure Accordion -->
|
|
<div class="col-12 col-lg-8">
|
|
<x-card :title="__('domains/admission/field.admission_schedule_detail.fee_detail')">
|
|
<x-slot:actions>
|
|
<x-button type="button" theme="primary" size="sm" icon="tabler-stack-pull" :label="__('ui/button.publish')" class="px-3 fw-medium" />
|
|
</x-slot:actions>
|
|
|
|
<x-container.accordion id="fee-detail">
|
|
@foreach ($this->studyPrograms as $study)
|
|
<x-container.accordion-item item-id="study-{{ $study->ulid }}" wire:key="study-item-{{ $study->id }}">
|
|
<x-slot:header class="d-flex align-items-center gap-2">
|
|
<x-dynamic-component
|
|
component="badge"
|
|
:attributes="new Illuminate\View\ComponentAttributeBag($this->setStudyProgramBadgeAttribute($study->id))"
|
|
/>
|
|
<span class="fw-bold text-body fs-6">{{ $study->name }}</span>
|
|
</x-slot:header>
|
|
|
|
<!-- Scrollable Fee Table -->
|
|
<x-slot:content>
|
|
<div class="table-responsive" style="max-height: 450px;">
|
|
<table class="table table-hover align-middle mb-0 text-nowrap small" style="table-layout: fixed; min-width: {{ 200 + ($this->feeTypes->count() * 160) }}px;">
|
|
<thead class="position-sticky top-0 z-2 shadow-sm">
|
|
<tr>
|
|
<!-- Fixed Column Header -->
|
|
<th class="ps-3 py-2.5 text-uppercase fs-7 fw-semibold text-truncate text-body-secondary position-sticky start-0 border-end z-3" style="width: 200px;">
|
|
<span title="{{ __('domains/admission/field.academic_program.name') }}">
|
|
{{ __('domains/admission/field.academic_program.name') }}
|
|
</span>
|
|
<!-- Dynamic Fee Columns -->
|
|
@foreach ($this->feeTypes as $fee)
|
|
<th class="text-end py-2.5 text-uppercase fs-7 fw-semibold text-body-secondary pe-3" style="width: 160px;">
|
|
<span class="d-block text-truncate" title="{{ $fee->name }}">{{ $fee->name }}</span>
|
|
</th>
|
|
@endforeach
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach ($this->academicPrograms as $program)
|
|
<tr>
|
|
<!-- Fixed First Column Body Cell -->
|
|
<td class="ps-3 py-2 fw-semibold text-body text-truncate position-sticky start-0 bg-body border-end z-1 shadow-sm" style="max-width: 200px;" title="{{ $program->name }}">
|
|
{{ $program->name }}
|
|
</td>
|
|
@foreach ($this->feeTypes as $fee)
|
|
@php($lookupKey = "{$study->id}_{$program->id}_{$fee->id}")
|
|
@php($feeRate = isset($this->feeRates[$lookupKey]) ? $this->feeRates[$lookupKey] : new Money(0))
|
|
<td wire:key="cell-{{ $lookupKey }}" class="text-end pe-3 py-2">
|
|
<x-badge
|
|
data-fee-type-id="{{ $fee->ulid }}"
|
|
data-program-id="{{ $program->ulid }}"
|
|
data-study-program-id="{{ $study->ulid }}"
|
|
data-fee-type="{{ $feeRate->toFloat() }}"
|
|
class="cursor-pointer px-3 py-1.5 font-monospace w-100 text-end justify-content-end border shadow-2xs transition-all hover-opacity-80"
|
|
x-on:click="$js.ask"
|
|
:label="$feeRate"
|
|
:variant="$this->setBadgeVariant($feeRate)"
|
|
/>
|
|
</td>
|
|
@endforeach
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</x-slot:content>
|
|
</x-container.accordion-item>
|
|
@endforeach
|
|
</x-container.accordion>
|
|
</x-card>
|
|
</div>
|
|
</div>
|
|
|
|
@script
|
|
<script>
|
|
$js.ask = function (self) {
|
|
var btn = self.target.closest('[data-fee-type-id]');
|
|
var dataset = btn ? btn.dataset : self.target.dataset;
|
|
|
|
window.Swal.fire({
|
|
title: '{{ __("domains/admission/field.admission_schedule_detail.update_fee_rate") }}',
|
|
text: '{{ __("domains/admission/field.admission_schedule_detail.enter_new_fee") }}',
|
|
input: 'text',
|
|
inputValue: dataset.feeType.trim(),
|
|
showCancelButton: true,
|
|
confirmButtonText: '{{ __("ui/button.save") }}',
|
|
cancelButtonText: '{{ __("ui/button.cancel") }}',
|
|
customClass: {
|
|
confirmButton: 'btn btn-primary me-2',
|
|
cancelButton: 'btn btn-secondary'
|
|
},
|
|
buttonsStyling: false,
|
|
inputValidator: (value) => {
|
|
if (!value) {
|
|
return '{{ __("domains/admission/field.admission_schedule_detail.amount_required") }}';
|
|
}
|
|
},
|
|
preConfirm: (value) => {
|
|
return new Promise((resolve) => {
|
|
$wire.updateFee(dataset.feeTypeId, dataset.programId, dataset.studyProgramId, value);
|
|
resolve();
|
|
});
|
|
},
|
|
});
|
|
};
|
|
</script>
|
|
@endscript
|
|
</div>
|
|
|