toastr error fixed and document workable with other minor error fixes

This commit is contained in:
2025-09-02 16:22:25 +05:45
parent f8f496077b
commit 5b5e19f919
10 changed files with 149 additions and 65 deletions

View File

@@ -49,7 +49,7 @@ class NewsletterController extends Controller
{
try {
$rules = [
'email' => 'required|email',
'email' => 'required|email|unique:newsletters,email',
];
if (setting('enable_reCaptcha') == 1) {
@@ -57,7 +57,7 @@ class NewsletterController extends Controller
}
$messages = [
'email.email' => 'Must be a valid email address.',
'email.email' => 'Must be a valid and unique email address.',
'g-recaptcha-response.required' => 'Please complete reCAPTCHA validation.',
'g-recaptcha-response' => 'Invalid reCAPTCHA.',
];

View File

@@ -19,12 +19,10 @@ class Partner extends Model
protected $fillable = [
'title',
'slug',
'link',
'image',
'status',
'linka',
'order',
'createdby',
'updatedby',
];

View File

@@ -29,7 +29,7 @@
],
['title' => 'Image', 'data' => 'image', 'name' => 'image'],
['title' => 'Name', 'data' => 'title', 'name' => 'title'],
['title' => 'Link', 'data' => 'link', 'name' => 'link'],
['title' => 'Link', 'data' => 'linka', 'name' => 'linka'],
['title' => 'Status', 'data' => 'status', 'name' => 'status'],
[
'title' => 'Action',

View File

@@ -3,6 +3,7 @@
namespace Modules\Document\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Modules\CCMS\Models\Country;
@@ -13,6 +14,7 @@ use Modules\Document\Services\DocumentService;
use Yajra\DataTables\Facades\DataTables;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\DB;
class DocumentController extends Controller
@@ -26,14 +28,66 @@ class DocumentController extends Controller
public function index()
{
$title = 'Upload Documents';
$title = "Upload Document";
$countryOptions = Country::whereNull('parent_id')->pluck('title', 'id')->mapWithKeys(fn($title, $id) => ["Country:$id" => "Country - $title"]);
$serviceOptions = Service::whereNull('parent_id')->pluck('title', 'id')->mapWithKeys(fn($title, $id) => ["Service:$id" => "Service - $title"]);
$testOptions = Test::whereNull('parent_id')->pluck('title', 'id')->mapWithKeys(fn($title, $id) => ["Test:$id" => "Test - $title"]);
$modelOptions = $countryOptions->merge($serviceOptions)->merge($testOptions);
return view('document::document.index', compact('modelOptions', 'title'));
if (request()->ajax()) {
$model = Document::query()->latest();
return DataTables::eloquent($model)
->setRowClass('tableRow')
->addColumn('name', function (Document $document) {
$extension = $document->getExtension();
$assetUrl = $document->getUrl();
$html = $document->isImageFile()
? "<div class='flex-shrink-0'>
<div class='avatar-sm bg-light rounded p-1'>
<a href='{$assetUrl}' data-fancybox='gallery' data-caption='{$document->title}'>
<img src='{$assetUrl}' alt='' class='avatar-sm img-fluid d-block'>
</a>
</div>
</div>"
: "<div class='flex-shrink-0'>
<div class='avatar-sm'>
<a href='{$assetUrl}' data-fancybox='gallery' data-caption='{$document->title}'>
<div class='avatar-title bg-" . getFileIcon($extension)[1] . "-subtle text-" . getFileIcon($extension)[1] . " fs-20 material-shadow rounded'>
<i class='" . getFileIcon($extension)[0] . "'></i>
</div>
</a>
</div>
</div>";
return "<div class='d-flex align-items-center'>
{$html} <div class='flex-grow-1 ms-3'>
<h6 class='fs-12 mb-0'>{$document->title}</h6>
</div>
</div>";
})
->addColumn('type', function (Document $document) {
return $document->getExtension();
})
->addColumn('size', function (Document $document) {
return $document->getSize();
})
->editColumn('created_at', function (Document $document) {
return getFormatted($document->created_at);
})
->addColumn('action', function (Document $document) {
return view('document::document.partials.action', ['document' => $document]);
})
->rawColumns(['action', 'name', 'size'])
->toJson();
}
return view('document::document.index', [
'title' => $title,
'countryOptions' => $countryOptions,
'serviceOptions' => $serviceOptions,
'testOptions' => $testOptions,
'modelOptions' => $modelOptions,
]);
}
@@ -48,7 +102,7 @@ class DocumentController extends Controller
$document->delete();
session()->flash('Document Deleted');
return response()->json(['status' => true, 'msg' => 'Document Deleted']);
return response()->json(['status' => 200, 'message' => 'Document Deleted Successfully']);
} catch (\Throwable $th) {
session()->flash('error', $th->getMessage());
}
@@ -122,21 +176,27 @@ class DocumentController extends Controller
public function getAllDocuments()
{
$model = Document::query()->latest();
return DataTables::eloquent($model)
->setRowClass('tableRow')
->addColumn('name', function (Document $document) {
$extension = $document->getExtension();
$assetUrl = $document->getUrl();
$html = $document->isImageFile()
? "<div class='flex-shrink-0'>
$countryOptions = Country::whereNull('parent_id')->pluck('title', 'id')->mapWithKeys(fn($title, $id) => ["Country:$id" => "Country - $title"]);
$serviceOptions = Service::whereNull('parent_id')->pluck('title', 'id')->mapWithKeys(fn($title, $id) => ["Service:$id" => "Service - $title"]);
$testOptions = Test::whereNull('parent_id')->pluck('title', 'id')->mapWithKeys(fn($title, $id) => ["Test:$id" => "Test - $title"]);
$modelOptions = $countryOptions->merge($serviceOptions)->merge($testOptions);
if (request()->ajax()) {
$model = Document::query()->latest();
return DataTables::eloquent($model)
->setRowClass('tableRow')
->addColumn('name', function (Document $document) {
$extension = $document->getExtension();
$assetUrl = $document->getUrl();
$html = $document->isImageFile()
? "<div class='flex-shrink-0'>
<div class='avatar-sm bg-light rounded p-1'>
<a href='{$assetUrl}' data-fancybox='gallery' data-caption='{$document->title}'>
<img src='{$assetUrl}' alt='' class='avatar-sm img-fluid d-block'>
</a>
</div>
</div>"
: "<div class='flex-shrink-0'>
: "<div class='flex-shrink-0'>
<div class='avatar-sm'>
<a href='{$assetUrl}' data-fancybox='gallery' data-caption='{$document->title}'>
<div class='avatar-title bg-" . getFileIcon($extension)[1] . "-subtle text-" . getFileIcon($extension)[1] . " fs-20 material-shadow rounded'>
@@ -146,40 +206,47 @@ class DocumentController extends Controller
</div>
</div>";
return "<div class='d-flex align-items-center'>
return "<div class='d-flex align-items-center'>
{$html} <div class='flex-grow-1 ms-3'>
<h6 class='fs-12 mb-0'>{$document->title}</h6>
</div>
</div>";
})
->addColumn('type', function (Document $document) {
return $document->getExtension();
})
->addColumn('size', function (Document $document) {
return $document->getSize();
})
->editColumn('created_at', function (Document $document) {
return getFormatted($document->created_at);
})
->addColumn('action', function (Document $document) {
return view('document::document.partials.action', ['document' => $document]);
})
->rawColumns(['action', 'name', 'size'])
->toJson();
})
->addColumn('type', function (Document $document) {
return $document->getExtension();
})
->addColumn('size', function (Document $document) {
return $document->getSize();
})
->editColumn('created_at', function (Document $document) {
return getFormatted($document->created_at);
})
->addColumn('action', function (Document $document) {
return view('document::document.partials.action', ['document' => $document]);
})
->rawColumns(['action', 'name', 'size'])
->toJson();
}
return view('document::document.index', [
'countryOptions' => $countryOptions,
'serviceOptions' => $serviceOptions,
'testOptions' => $testOptions,
'modelOptions' => $modelOptions,
]);
}
public function reorder(Request $request)
{
Document::chunkById(100, function (Collection $documents) use ($request) {
foreach ($documents as $document) {
foreach ($request->order as $order) {
if ($order['id'] == $document->id) {
$document->update(['order' => $order['position']]);
}
$partners = Document::all();
foreach ($partners as $partner) {
foreach ($request->order as $order) {
if ($order['id'] == $partner->id) {
$partner->update(['order' => $order['position']]);
}
}
});
}
return response(['status' => true, 'message' => 'Reordered successfully'], 200);
}
}

View File

@@ -32,7 +32,7 @@
];
@endphp
<x-data-table-script :route="route('documents.getAllDocuments')" :columns="$columns" id="documents-table" :reorder="route('documents.reorder')" />
<x-data-table-script :route="route('documents.index')" :columns="$columns" :reorder="route('documents.reorder')" />
</div>
</div>

View File

@@ -1,7 +1,5 @@
<div class="hstack flex-wrap gap-3 align-items-center">
<a href="{{ $document->getUrl() }}" class="link-primary fs-15" download><i class="ri-download-2-line"></i></a>
@can('documents.destroy')
<a href="javascript:void(0);" data-link="{{ route('documents.destroy', $document->id) }}"
class="link-danger fs-15 remove-item"><i class="ri-delete-bin-line"></i></a>
@endcan
<a href="javascript:void(0);" data-link="{{ route('documents.destroy', $document->id) }}"
class="link-danger fs-15 remove-item"><i class="ri-delete-bin-line"></i></a>
</div>

View File

@@ -11,7 +11,6 @@ trait AddToDocumentCollection
{
public function addToDocumentCollection(string $collectionName = 'uploads', string $file, ?string $documentName = null, ?int $referenceDocumentId = null)
{
dd($documentName);
if (!Storage::disk('public')->exists($collectionName)) {
Storage::disk('public')->makeDirectory($collectionName);
}

View File

@@ -46,7 +46,7 @@
<!-- for select2 -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
@stack('css')
@@ -264,11 +264,13 @@
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',
@@ -278,16 +280,19 @@
},
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));
window.location.href = "{{ route('thankyou') }}";
} else if (data.errors) {
toastr.error(data.errors.email ? data.errors.email[0] :
'Submission failed. Please try again.');
} else {
toastr.error('Submission failed. Please try again.');
}
} catch (err) {
console.error(err);
toastr.error('Something went wrong. Please try again.');
@@ -303,12 +308,23 @@
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('counselor-form');
const submitBtn = document.getElementById('counselor-submit-btn');
const termsCheckbox = document.getElementById('terms');
const url = form.action;
form.addEventListener('submit', async (e) => {
e.preventDefault();
// ✅ Check if terms are ticked
if (!termsCheckbox.checked) {
toastr.error('You must agree to the terms and conditions.');
return; // stop submission
}
submitBtn.disabled = true;
submitBtn.textContent = 'Submitting…';
const formData = new FormData(form);
try {
const res = await fetch(url, {
method: 'POST',
@@ -318,16 +334,21 @@
},
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));
window.location.href = "{{ route('thankyou') }}"; // redirect on success
} else if (data.errors) {
// ✅ Loop through all errors, not just email
Object.values(data.errors).forEach(fieldErrors => {
fieldErrors.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.');
@@ -339,6 +360,7 @@
});
</script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('vacancy-form');

View File

@@ -27,13 +27,13 @@
<h4 class="text-ter text-36">
Get in <span class="text-brand">touch</span>
</h4>
<h5 class="font-medium text-16">Book your <span class="font-bold">FREE
<h5 class="font-medium text-16">Book your <span cl` ass="font-bold">FREE
consultation </span>with Certified Counsellors</h5>
</div>
<form action="{{ route('counselor.store') }}" method="POST" id="counselor-form">
@csrf
<div class="flex justify-between items-center gap-5">
<div class="flex justify-between items-center gap-5">
<input class="w-full mb-10 rounded-6 py-10 text-14 px-10 border-bottom"
type="text" name="name" id="name" placeholder=" Name" required>
<input class="w-full mb-10 rounded-6 py-10 text-14 px-10 border-bottom"
@@ -54,7 +54,7 @@
<input class="w-full mb-20 rounded-6 py-10 text-14 px-10" type="text"
name="qualification" id="qualification" placeholder="Recent Education Qualification"
required>
<input class="mb-20" type="checkbox" id=terms>
<input class="mb-20" type="checkbox" id=terms required>
<label class="text-14 mb-20" for="terms">I accept the terms & conditions</label>
<button type="submit" id="counselor-submit-btn"
class=" w-full py-10 bg-sec text-white rounded-10 text-16 border-0 button-hover">

View File

@@ -55,7 +55,7 @@
</button>
</div>
<div class="dropdown topbar-head-dropdown ms-1 header-item" id="notificationDropdown">
{{-- <div class="dropdown topbar-head-dropdown ms-1 header-item" id="notificationDropdown">
<button type="button" class="btn btn-icon btn-topbar btn-ghost-secondary rounded-circle"
id="page-header-notifications-dropdown" data-bs-toggle="dropdown" data-bs-auto-close="outside"
aria-haspopup="true" aria-expanded="false">
@@ -88,12 +88,12 @@
All (4)
</a>
</li>
{{-- <li class="nav-item waves-effect waves-light">
<li class="nav-item waves-effect waves-light">
<a class="nav-link" data-bs-toggle="tab" href="#messages-tab" role="tab"
aria-selected="false">
Messages
</a>
</li> --}}
</li>
</ul>
</div>
@@ -147,7 +147,7 @@
</div>
</div>
</div>
</div>
</div> --}}
<div class="dropdown ms-sm-3 header-item topbar-user">
<button type="button" class="btn" id="page-header-user-dropdown" data-bs-toggle="dropdown"