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:
@@ -47,7 +47,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div class="price__area-item-btn">
|
||||
<button type="button" class="build_button apply-now-button" data-bs-toggle="modal" data-bs-target="#applicationModal" data-career-title="{{ $career->title }}" data-career-location="{{ $career->location }}" data-career-salary="{{ $career->salary_per_month }}" data-career-description="{{ $career->title_description }}" data-career-id="{{ $career->id }}">Apply Now<i class="flaticon-right-up"></i></button>
|
||||
<button type="button" class="build_button apply-now-button" data-bs-toggle="modal" data-bs-target="#applyInternshipModal" data-job-id="{{ $career->id }}" data-job-type="career" data-career-title="{{ $career->title }}" data-career-location="{{ $career->location }}" data-career-salary="{{ $career->salary_per_month }}" data-career-description="{{ $career->title_description }}">Apply Now<i class="flaticon-right-up"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
@@ -59,114 +59,77 @@
|
||||
</div>
|
||||
<!-- Pricing Plan Area End -->
|
||||
|
||||
<!-- Application Modal -->
|
||||
<div class="modal fade" id="applicationModal" tabindex="-1" aria-labelledby="applicationModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content rounded-3">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="applicationModalLabel">Apply for <span id="jobTitle"></span></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h6 id="jobLocation"></h6>
|
||||
<p id="jobSalary"></p>
|
||||
<p id="jobDescription"></p>
|
||||
<form id="applicationForm" enctype="multipart/form-data" action="{{ route('applications.store') }}" method="POST">
|
||||
@csrf
|
||||
<input type="hidden" name="career_id" id="careerId">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="name" class="form-label">Name <span> *</span></label>
|
||||
<input type="text" class="form-control" id="name" name="name" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="birthdate" class="form-label">Birthdate <span> *</span></label>
|
||||
<input type="date" class="form-control" id="birthdate" name="birthdate" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="email" class="form-label">Email <span> *</span></label>
|
||||
<input type="email" class="form-control" id="email" name="email" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="phone_number" class="form-label">Phone Number <span> *</span></label>
|
||||
<input type="text" class="form-control" id="phone_number" name="phone_number" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="resume_file" class="form-label">Resume (PDF, DOC, DOCX) <span> *</span></label>
|
||||
<input type="file" class="form-control" id="resume_file" name="resume_file" accept=".pdf,.doc,.docx" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="cover_letter" class="form-label">Cover Letter (Optional)</label>
|
||||
<textarea class="form-control" id="cover_letter" name="cover_letter" rows="5"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit Application</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
{{-- Application Modal --}}
|
||||
@include('web.components.application_modal', ['jobId' => null, 'jobType' => 'career']) {{-- jobId will be set by JS from button data attributes --}}
|
||||
|
||||
@push('footer-js')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var applicationModal = document.getElementById('applicationModal');
|
||||
applicationModal.addEventListener('show.bs.modal', function (event) {
|
||||
var button = event.relatedTarget;
|
||||
var careerTitle = button.getAttribute('data-career-title');
|
||||
var careerLocation = button.getAttribute('data-career-location');
|
||||
var careerSalary = button.getAttribute('data-career-salary');
|
||||
var careerDescription = button.getAttribute('data-career-description');
|
||||
var careerId = button.getAttribute('data-career-id');
|
||||
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 modalCareerId = applicationModal.querySelector('#careerId');
|
||||
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');
|
||||
|
||||
modalTitle.textContent = careerTitle;
|
||||
modalLocation.textContent = 'Location: ' + careerLocation;
|
||||
modalSalary.textContent = 'Salary: ' + careerSalary + ' / Per monthly';
|
||||
modalDescription.textContent = careerDescription;
|
||||
modalCareerId.value = careerId;
|
||||
});
|
||||
// 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;
|
||||
|
||||
// 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')
|
||||
// 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';
|
||||
}
|
||||
})
|
||||
.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.');
|
||||
});
|
||||
});
|
||||
|
||||
// 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