Add Franchise and Newsletter management features

- Implemented FranchiseController with CRUD operations and data handling.
- Created NewsletterController for managing newsletter subscriptions.
- Added routes for Franchise and Newsletter resources in web.php.
- Developed views for Franchise and Newsletter management including index, create, edit, and datatable actions.
- Introduced form handling and validation for Franchise and Newsletter submissions.
- Created database migrations for franchises and newsletters tables.
- Updated sidebar configuration to include Franchise and Newsletter sections.
- Enhanced client-side forms with AJAX submission for Franchise and Newsletter.
This commit is contained in:
2025-08-21 23:23:38 +05:45
parent 7f9d6bc8ec
commit d29b3ba489
23 changed files with 843 additions and 79 deletions

View File

@@ -219,6 +219,86 @@
});
</script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('franchise-form');
const submitBtn = document.getElementById('franchise-submit');
const url = form.action;
form.addEventListener('submit', async (e) => {
e.preventDefault();
submitBtn.disabled = true;
submitBtn.textContent = 'Submitting…';
const formData = new FormData(form);
try {
const res = await fetch(url, {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')
.content
},
body: formData
});
const data = await res.json();
if (res.ok) {
form.reset();
window.location.href =
"{{ route('thankyou') }}"; // ✅ redirect instead of toastr
} else if (data.errors && data.errors.email) {
data.errors.email.forEach(msg => toastr.error(msg));
} else {
toastr.error('Submission failed. Please try again.');
}
} catch (err) {
console.error(err);
toastr.error('Something went wrong. Please try again.');
} finally {
submitBtn.disabled = false;
submitBtn.textContent = 'Submit';
}
});
});
</script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('newsletter-form');
const submitBtn = document.getElementById('newsletter-submit');
const url = form.action;
form.addEventListener('submit', async (e) => {
e.preventDefault();
submitBtn.disabled = true;
submitBtn.textContent = 'Submitting…';
const formData = new FormData(form);
try {
const res = await fetch(url, {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')
.content
},
body: formData
});
const data = await res.json();
if (res.ok) {
form.reset();
window.location.href =
"{{ route('thankyou') }}"; // ✅ redirect instead of toastr
} else if (data.errors && data.errors.email) {
data.errors.email.forEach(msg => toastr.error(msg));
} else {
toastr.error('Submission failed. Please try again.');
}
} catch (err) {
console.error(err);
toastr.error('Something went wrong. Please try again.');
} finally {
submitBtn.disabled = false;
submitBtn.textContent = 'Submit';
}
});
});
</script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('counselor-form');

View File

@@ -61,10 +61,12 @@
<a href="{{ setting('whatsapp') }}" target="blank"> <i
class="fa-brands fa-square-whatsapp"></i></a>
</div>
<form class="flex" action="">
<form action="{{ route('newsletter.store') }}" method="post" id="newsletter-form">
@csrf
<input class=" border-0 w-80percent px-20 text-14 py-10 text-black" type="email"
name="email" id="email" placeholder="Enter your Email">
<button class="border-0 text-white p-10 text-12 ">Subscribe</button>
<button type="submit" id="newsletter-submit"
class="border-0 text-white p-10 text-12 newsletter-submit">Subscribe</button>
</form>
<div>
<iframe

View File

@@ -33,12 +33,10 @@
<div class="quote-mark">"</div>
<h2 class="heading">Your Trusted Study Abroad Partner.</h2>
<h2 class="heading">{{$page->short_description}}</h2>
<p class="message">
Were more than just a consultancy—were your ultimate study abroad ally! With years of
experience and a passion for helping students succeed, weve guided thousands of students to
their dream universities across the globe. Your dreams are our mission
{!! $page->description !!}
</p>
</div>
</div>

View File

@@ -101,19 +101,20 @@
<div class="franchise-form bg-white">
<form action="">
<form action="{{ route('franchise.store') }}" method="post" id="franchise-form">
@csrf
<label class="text-16 pb-5" for="">Your Name <span
class="text-brand">(Required)</span></label>
<div class="flex gap-10 ">
<div class="w-full">
<label class="text-14 pb-5" for="">First</label>
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text" name=""
id="">
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text"
name="first_name" id="">
</div>
<div class="w-full">
<label class="text-14 pb-5" for="">Last</label>
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text" name=""
id="">
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text"
name="last_name" id="">
</div>
@@ -123,33 +124,33 @@
<label class="text-16 pb-5" for="">Your Email Address <span
class="text-brand">(Required)</span></label>
<input class="w-full mb-20 rounded-6 py-10 text-14 px-10" type="email" name=""
<input class="w-full mb-20 rounded-6 py-10 text-14 px-10" type="email" name="email"
id="">
<label class="text-16 pb-5" for="">Your Phone <span
class="text-brand">(Required)</span></label>
<input class="w-full mb-20 rounded-6 py-10 text-14 px-10" type="text" name=""
<input class="w-full mb-20 rounded-6 py-10 text-14 px-10" type="text" name="phone"
id="">
<label class="text-16 pb-5" for="">Your Address <span
class="text-brand">(Required)</span></label>
<input class="w-full mb-20 rounded-6 py-10 text-14 px-10" type="text" name=""
<input class="w-full mb-20 rounded-6 py-10 text-14 px-10" type="text" name="address"
id="">
<div class="flex gap-10 ">
<div class="w-full">
<label class="text-14 pb-5" for="">City</label>
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text"
name="" id="">
name="city" id="">
</div>
<div class="w-full">
<label class="text-14 pb-5" for="">State/Region/Province</label>
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text"
name="" id="">
name="state" id="">
</div>
@@ -161,7 +162,7 @@
<div class="sm:block flex gap-10 ">
<div class="w-full">
<label class="text-14 pb-5" for="">Level to Invest</label>
<select class="w-full py-5" name="" id="">
<select class="w-full py-5" name="invest_level" id="">
<option value="">Less than $20,000</option>
<option value="">Less than $30,000</option>
<option value="">Less than $40,000</option>
@@ -169,9 +170,9 @@
</select>
<!-- <select name="" id="franchise-invest">
<option value="" selected hidden> Less than $10,000</option>
<option value=""></option>
</select> -->
<option value="" selected hidden> Less than $10,000</option>
<option value=""></option>
</select> -->
</div>
@@ -179,7 +180,7 @@
<label class="text-14 pb-5" for="">Do you currently own a business?
(Yes/No)</label>
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text"
name="" id="">
name="own_business" id="">
</div>
@@ -192,26 +193,26 @@
business</label>
<textarea class="w-full mb-20 rounded-6 py-10 text-14 px-10" name="" id=""></textarea>
<textarea class="w-full mb-20 rounded-6 py-10 text-14 px-10" name="yes_own_des" id=""></textarea>
<div class="sm:block flex gap-10 ">
<div class="w-full">
<label class="text-14 pb-5" for="">Preferred Franchise Location</label>
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text"
name="" id="">
name="franchise_location" id="">
</div>
<div class="w-full">
<label class="text-14 pb-5" for="">Timeframe to Start</label>
<select class="w-full py-5" name="" id="">
<select class="w-full py-5" name="start_time_frame" id="">
<option value="">within 1 year</option>
<option value="">After 1 year</option>
</select>
<!-- <select name="" id="franchise-timeframe">
<option value="" selected hidden> within 6 months</option>
<option value=""></option>
</select> -->
<option value="" selected hidden> within 6 months</option>
<option value=""></option>
</select> -->
</div>
@@ -221,17 +222,18 @@
</div>
<div class="sm:w-full w-50percent">
<label class="text-14 pb-5" for="">Do u already have an office setup ?</label>
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text" name=""
id="">
<input class="w-full mb-30 rounded-6 py-10 text-14 px-10" type="text"
name="office_setup" id="">
</div>
<label class="text-14 pb-5" for=""> Please add your bussiness portfolio website ,and
let us know
if you have any questions?</label>
<textarea class="w-full mb-20 rounded-6 py-10 text-14 px-10" name="" id=""></textarea>
<textarea class="w-full mb-20 rounded-6 py-10 text-14 px-10" name="website" id=""></textarea>
<button class="button-hover px-20 py-10 bg-sec text-white text-16 border-0">Send
<button type="submit" id="franchise-submit"
class="button-hover px-20 py-10 bg-sec text-white text-16 border-0 franchise-submit">Send
Message</button>
</form>
</div>

View File

@@ -7,23 +7,25 @@
</div>
<section class="container py-30 free-resources">
<div class="row">
<div class="col col-md-3"></div>
<div class="col col-md-9">
<div class="flex justify-between items-center ">
<div>
<div class="row">
<div class="col col-md-3"></div>
<div class="col col-md-9">
<div class="flex justify-between items-center ">
<div>
<h2 class="md:text-30 text-60 text-sec"> {{ $page->title }}</h2>
<div class="title-line "></div>
<h2 class="md:text-30 text-60 text-sec"> {{ $page->title }}</h2>
<div class="title-line "></div>
</div>
<button class="review-button"><p>Review</p></button>
</div>
<button class="review-button">
<p>Review</p>
</button>
</div>
</div>
</div>
</div>
@if ($page->children)
<section class="free-resources-content tab-container">
@@ -82,49 +84,61 @@
@php
$accordionId = "accordion-questions-{$index}";
@endphp
<div class="py-40">
<h3 class="text-20 text-brand">
{{ $page->title }} FAQ's
Frequently Asked Questions
</h3>
<div class="accordion accordion-title-underlined accordion-sm pt-20"
id="accordion-questions" role="tablist" aria-multiselectable="true">
@foreach ($page->custom as $key => $value)
<div class="accordion accordion-title-underlined accordion-sm pt-20"
id="{{ $accordionId }}" role="tablist" aria-multiselectable="true">
@foreach ($child->custom as $key => $item)
@php
$headingId = "heading-{$index}-{$key}";
$collapseId = "collapse-{$index}-{$key}";
@endphp
<div class="accordion-item panel mb-10">
<div class="accordion-heading" role="tab"
id="heading-question-{{ $key + 1 }}">
id="{{ $headingId }}">
<h4 class="accordion-title">
<a class="collapsed text-17 font-bold" role="button"
data-bs-toggle="collapse"
data-bs-parent="#accordion-questions"
href="index.php#collapse-question-item-{{ $key + 1 }}"
aria-expanded="false"
aria-controls="collapse-question-item-{{ $key + 1 }}">
<span
class="accordion-expander text-16 text-black"><i
href="#{{ $collapseId }}"
aria-expanded="{{ $loop->first ? 'true' : 'false' }}"
aria-controls="{{ $collapseId }}">
<span class="accordion-expander text-16 text-black">
<i
class="lqd-icn-ess icon-ion-ios-arrow-forward"></i>
<i
class="lqd-icn-ess icon-ion-ios-arrow-forward"></i></span><span
class="accordion-title-txt">{{ $value['icon'] ?? '' }}</span>
class="lqd-icn-ess icon-ion-ios-arrow-forward"></i>
</span>
<span
class="accordion-title-txt">{{ $item['icon'] ?? '' }}</span>
</a>
</h4>
</div>
<div id="collapse-question-item-{{ $key + 1 }}"
class="accordion-collapse collapse"
data-bs-parent="#accordion-questions" role="tabpanel"
aria-labelledby="heading-question-{{ $key + 1 }}">
<div id="{{ $collapseId }}"
class="accordion-collapse collapse {{ $loop->first ? 'show' : '' }}"
data-bs-parent="#{{ $accordionId }}" role="tabpanel"
aria-labelledby="{{ $headingId }}">
<div
class="accordion-content text-14 leading-20 text-black">
<p>{{ $value['key'] ?? '' }}</p>
<p>{{ $item['key'] ?? '' }}</p>
</div>
</div>
</div>
@endforeach
</div>
</div>
<!-- blog -->
<div class="lqd-section blog pt-20" id="blog" data-custom-animations="true"
{{-- <div class="lqd-section blog pt-20" id="blog" data-custom-animations="true"
data-ca-options='{"animationTarget": ".btn, .animation-element", "ease": "power4.out", "initValues":{"x": "-10px", "y": "10px", "opacity":0} , "animations":{"x": "0px", "y": "0px", "opacity":1}}'>
<div class="container">
<div class="row">
@@ -174,7 +188,7 @@
</div>
</div>
</div>
</div>
</div> --}}
</div>
</div>
</div>