Enhance internship application process: update InternshipsPageController to retrieve internships and validate application submissions, modify Internship model to include relationships, and implement dynamic application modals in views for internships and careers. Update Livewire configuration for improved file upload handling.
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
@extends('web.layouts.app')
|
||||
|
||||
@push('header-css')
|
||||
<style>
|
||||
#applicationForm > label > span {
|
||||
color: var(--gujurly-primary);
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<!-- Breadcrumb Area Start -->
|
||||
<div class="breadcrumb__area" style="background-image: url('/web/assets/img/page/breadcrumb.jpg');">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="breadcrumb__area-content">
|
||||
<h2>Internships</h2>
|
||||
<ul>
|
||||
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
|
||||
<li>Internships</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Breadcrumb Area End -->
|
||||
<!-- Pricing Plan Area Start -->
|
||||
<div class="price__area section-padding">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xl-4 col-md-6 xl-mb-25 wow fadeInUp" data-wow-delay=".4s">
|
||||
@forelse ($internships as $internship)
|
||||
<div class="price__area-item">
|
||||
<div class="price__area-item-price">
|
||||
<span>{{ $internship->title }}</span>
|
||||
<h3>{{ $internship->location }}</h3>
|
||||
<h2>{{ $internship->salary_per_month }} {{ $internship->salary_currency }}</h2>
|
||||
<span>Per monthly</span>
|
||||
</div>
|
||||
<div class="price__area-item-list">
|
||||
<ul>
|
||||
@foreach($internship->bullets as $bullet)
|
||||
<li><i class="flaticon-checked"></i>{{ $bullet['bullet'] ?? '' }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
<div class="price__area-item-btn">
|
||||
<button type="button" class="build_button apply-now-button" data-bs-toggle="modal" data-bs-target="#applyInternshipModal" data-job-id="{{ $internship->id }}" data-job-type="internship" data-internship-title="{{ $internship->title }}" data-internship-location="{{ $internship->location }}" data-internship-salary="{{ $internship->salary_per_month }}" data-internship-description="{{ $internship->title_description }}">Apply Now<i class="flaticon-right-up"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<span>No internships found...</span>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pricing Plan Area End -->
|
||||
|
||||
{{-- Application Modal --}}
|
||||
@include('web.components.application_modal', ['jobId' => null, 'jobType' => 'internship']) {{-- jobId will be set by JS from button data attributes --}}
|
||||
|
||||
@endsection
|
||||
|
||||
@push('footer-js')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var applicationModal = document.getElementById('applyInternshipModal');
|
||||
if (applicationModal) {
|
||||
applicationModal.addEventListener('show.bs.modal', function (event) {
|
||||
var button = event.relatedTarget; // Button that triggered the modal
|
||||
var jobId = button.getAttribute('data-job-id'); // Generic attribute for job ID
|
||||
var jobType = button.getAttribute('data-job-type'); // Generic attribute for job type
|
||||
|
||||
var modalTitle = applicationModal.querySelector('#jobTitle');
|
||||
var modalLocation = applicationModal.querySelector('#jobLocation');
|
||||
var modalSalary = applicationModal.querySelector('#jobSalary');
|
||||
var modalDescription = applicationModal.querySelector('#jobDescription');
|
||||
var jobIdInput = applicationModal.querySelector('#jobIdInput');
|
||||
var applicationForm = applicationModal.querySelector('#applicationForm');
|
||||
|
||||
// Set dynamic values
|
||||
modalTitle.textContent = button.getAttribute('data-' + jobType + '-title');
|
||||
modalLocation.textContent = 'Location: ' + button.getAttribute('data-' + jobType + '-location');
|
||||
modalSalary.textContent = 'Salary: ' + button.getAttribute('data-' + jobType + '-salary') + ' / Per monthly';
|
||||
modalDescription.textContent = button.getAttribute('data-' + jobType + '-description');
|
||||
jobIdInput.value = jobId;
|
||||
|
||||
// Set form action dynamically
|
||||
if (jobType === 'internship') {
|
||||
applicationForm.action = '{{ route('internship.store') }}';
|
||||
jobIdInput.name = 'internship_id';
|
||||
} else if (jobType === 'career') {
|
||||
applicationForm.action = '{{ route('applications.store') }}'; // Assuming careers still use applications.store
|
||||
jobIdInput.name = 'career_id';
|
||||
}
|
||||
});
|
||||
|
||||
// Handle form submission with AJAX
|
||||
document.getElementById('applicationForm').addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
let form = e.target;
|
||||
let formData = new FormData(form);
|
||||
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.message) {
|
||||
alert(data.message);
|
||||
var modal = bootstrap.Modal.getInstance(applicationModal);
|
||||
modal.hide();
|
||||
form.reset();
|
||||
} else {
|
||||
alert('Error: ' + data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('An error occurred. Please try again.');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
Reference in New Issue
Block a user