From 711ae9caf91225fad0acea0d23245a2cd0883515 Mon Sep 17 00:00:00 2001 From: Subash Date: Fri, 22 Aug 2025 11:03:10 +0545 Subject: [PATCH] feat: Implement Event management features including CRUD operations and routing --- .../app/Http/Controllers/EventController.php | 147 +++++++++++++ Modules/CCMS/app/Models/Event.php | 113 ++++++++++ .../2025_08_22_044129_create_events_table.php | 58 ++++++ .../resources/views/event/create.blade.php | 16 ++ .../views/event/datatable/action.blade.php | 12 ++ .../CCMS/resources/views/event/edit.blade.php | 16 ++ .../resources/views/event/index.blade.php | 50 +++++ .../views/event/partials/_form.blade.php | 196 ++++++++++++++++++ Modules/CCMS/routes/web.php | 7 +- Modules/Meeting/routes/web.php | 3 +- config/sidebar.php | 12 +- 11 files changed, 625 insertions(+), 5 deletions(-) create mode 100644 Modules/CCMS/app/Http/Controllers/EventController.php create mode 100644 Modules/CCMS/app/Models/Event.php create mode 100644 Modules/CCMS/database/migrations/2025_08_22_044129_create_events_table.php create mode 100644 Modules/CCMS/resources/views/event/create.blade.php create mode 100644 Modules/CCMS/resources/views/event/datatable/action.blade.php create mode 100644 Modules/CCMS/resources/views/event/edit.blade.php create mode 100644 Modules/CCMS/resources/views/event/index.blade.php create mode 100644 Modules/CCMS/resources/views/event/partials/_form.blade.php diff --git a/Modules/CCMS/app/Http/Controllers/EventController.php b/Modules/CCMS/app/Http/Controllers/EventController.php new file mode 100644 index 0000000..fca8958 --- /dev/null +++ b/Modules/CCMS/app/Http/Controllers/EventController.php @@ -0,0 +1,147 @@ +ajax()) { + $model = Event::query()->orderBy('order'); + return DataTables::eloquent($model) + ->addIndexColumn() + ->setRowClass('tableRow') + ->editColumn('image', function (Event $event) { + return $event->getRawOriginal('image') ? "{$event->title}" : '-'; + }) + ->editColumn('parent_id', function (Event $event) { + return $event->parent ? "{$event->parent?->title}" : '-'; + }) + ->editColumn('status', function (Event $event) { + $status = $event->status ? 'Published' : 'Draft'; + $color = $event->status ? 'text-success' : 'text-danger'; + return "

{$status}

"; + }) + ->addColumn('action', 'ccms::event.datatable.action') + ->rawColumns(['parent_id', 'image', 'status', 'action']) + ->toJson(); + } + + return view('ccms::event.index', [ + 'title' => 'Event List', + ]); + } + + /** + * Show the form for creating a new resource. + */ + public function create() + { + $eventOptions = Event::where('status', 1)->pluck('title', 'id'); + return view('ccms::event.create', [ + 'title' => 'Create Event', + 'editable' => false, + 'eventOptions' => $eventOptions + ]); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + $maxOrder = Event::max('order'); + $order = $maxOrder ? ++$maxOrder : 1; + + $request->mergeIfMissing([ + 'slug' => Str::slug($request->title), + 'order' => $order, + ]); + + + + $validated = $request->validate([ + 'title' => 'required', + ]); + Event::create($request->all()); + flash()->success("Event has been created!"); + return redirect()->route('event.index'); + } + + /** + * Show the specified resource. + */ + public function show($id) + { + return view('ccms::show'); + } + + /** + * Show the form for editing the specified resource. + */ + public function edit($id) + { + $eventOptions = Event::where('status', 1)->pluck('title', 'id'); + $event = Event::findOrFail($id); + return view('ccms::event.edit', [ + 'title' => 'Edit Event', + 'editable' => true, + 'event' => $event, + 'eventOptions' => $eventOptions + ]); + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, $id) + { + $request->merge([ + 'slug' => Str::slug($request->title), + ]); + $validated = $request->validate([]); + $event = Event::findOrFail($id); + $event->update($request->all()); + flash()->success("Event has been updated."); + return redirect()->back(); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy($id) + { + $event = Event::findOrFail($id); + $event->delete(); + return response()->json(['status' => 200, 'message' => "Event has been deleted."], 200); + } + + public function reorder(Request $request) + { + $events = Event::all(); + foreach ($events as $event) { + foreach ($request->order as $order) { + if ($order['id'] == $event->id) { + $event->update(['order' => $order['position']]); + } + } + } + return response(['status' => true, 'message' => 'Reordered successfully'], 200); + } + + public function toggle($id) + { + $event = Event::findOrFail($id); + $event->update(['status' => !$event->status]); + return response(['status' => 200, 'message' => 'Toggled successfully'], 200); + } +} diff --git a/Modules/CCMS/app/Models/Event.php b/Modules/CCMS/app/Models/Event.php new file mode 100644 index 0000000..cb3322b --- /dev/null +++ b/Modules/CCMS/app/Models/Event.php @@ -0,0 +1,113 @@ + 'array', + ]; + } + + protected function images(): Attribute + { + return Attribute::make( + get: function ($value) { + if (empty($value)) { + return []; + } + + $parts = explode(',', $value); + return array_map(fn($part) => asset(trim($part)), $parts); + } + ); + } + + protected function image(): Attribute + { + return Attribute::make( + get: fn($value) => asset($value), + ); + } + + protected function banner(): Attribute + { + return Attribute::make( + get: fn($value) => asset($value), + ); + } + + protected function sidebarImage(): Attribute + { + return Attribute::make( + get: fn($value) => asset($value), + ); + } + + protected function iconImage(): Attribute + { + return Attribute::make( + get: fn($value) => asset($value), + ); + } + + public function children() + { + return $this->hasMany(Event::class, 'parent_id'); + } + + public function parent() + { + return $this->belongsTo(Event::class, 'parent_id'); + } + + public function documents() + { + return $this->morphMany(Document::class, 'documentable'); + } +} diff --git a/Modules/CCMS/database/migrations/2025_08_22_044129_create_events_table.php b/Modules/CCMS/database/migrations/2025_08_22_044129_create_events_table.php new file mode 100644 index 0000000..3f69e09 --- /dev/null +++ b/Modules/CCMS/database/migrations/2025_08_22_044129_create_events_table.php @@ -0,0 +1,58 @@ +id(); + $table->text('title'); + $table->text('slug')->nullable(); + $table->text('short_description')->nullable(); + $table->longText('description')->nullable(); + $table->json('custom')->nullable(); + $table->integer('parent_id')->unsigned()->nullable(); + + $table->string('image')->nullable(); + $table->string('banner')->nullable(); + + $table->text('images')->nullable(); + $table->date('start_date')->nullable(); + $table->date('end_date')->nullable(); + $table->text('meta_title')->nullable(); + $table->text('meta_description')->nullable(); + $table->text('meta_keywords')->nullable(); + + $table->text('sidebar_title')->nullable(); + $table->mediumText('sidebar_content')->nullable(); + $table->string('sidebar_image')->nullable(); + + $table->string('button_text')->nullable(); + $table->string('button_url')->nullable(); + $table->string('button_target')->nullable(); + + $table->integer('status')->default(1); + $table->string('icon_class')->nullable(); + $table->string('icon_image')->nullable(); + $table->integer('createdby')->unsigned()->nullable(); + $table->integer('updatedby')->unsigned()->nullable(); + $table->integer('order')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('events'); + } +}; diff --git a/Modules/CCMS/resources/views/event/create.blade.php b/Modules/CCMS/resources/views/event/create.blade.php new file mode 100644 index 0000000..a5faed8 --- /dev/null +++ b/Modules/CCMS/resources/views/event/create.blade.php @@ -0,0 +1,16 @@ +@extends('layouts.app') +@section('content') + +
+ @if ($errors->any()) + + @endif +
+
+ {{ html()->form('POST')->route('event.store')->class('needs-validation')->attributes(['novalidate'])->open() }} + @include('ccms::event.partials._form') + {{ html()->form()->close() }} +
+
+
+@endsection diff --git a/Modules/CCMS/resources/views/event/datatable/action.blade.php b/Modules/CCMS/resources/views/event/datatable/action.blade.php new file mode 100644 index 0000000..0d3ddd6 --- /dev/null +++ b/Modules/CCMS/resources/views/event/datatable/action.blade.php @@ -0,0 +1,12 @@ +
+ + + + + + +
diff --git a/Modules/CCMS/resources/views/event/edit.blade.php b/Modules/CCMS/resources/views/event/edit.blade.php new file mode 100644 index 0000000..4716a97 --- /dev/null +++ b/Modules/CCMS/resources/views/event/edit.blade.php @@ -0,0 +1,16 @@ +@extends('layouts.app') +@section('content') + +
+ @if ($errors->any()) + + @endif +
+
+ {{ html()->modelForm($event, 'PUT')->route('event.update', $event->id)->class('needs-validation')->attributes(['novalidate'])->open() }} + @include('ccms::event.partials._form') + {{ html()->closeModelForm() }} +
+
+
+@endsection diff --git a/Modules/CCMS/resources/views/event/index.blade.php b/Modules/CCMS/resources/views/event/index.blade.php new file mode 100644 index 0000000..a2a19fc --- /dev/null +++ b/Modules/CCMS/resources/views/event/index.blade.php @@ -0,0 +1,50 @@ +@extends('layouts.app') + +@section('content') +
+ + @if ($errors->any()) + + @endif + +
+
+
+
+
{{ $title }}
+ Create +
+
+ @php + $columns = [ + [ + 'title' => 'S.N', + 'data' => 'DT_RowIndex', + 'name' => 'DT_RowIndex', + 'orderable' => false, + 'searchable' => false, + 'sortable' => false, + ], + ['title' => 'Image', 'data' => 'image', 'name' => 'image'], + ['title' => 'Parent', 'data' => 'parent_id', 'name' => 'parent_ids'], + ['title' => 'Title', 'data' => 'title', 'name' => 'title'], + ['title' => 'Start Date', 'data' => 'start_date', 'name' => 'start_date'], + ['title' => 'End Date', 'data' => 'end_date', 'name' => 'end_date'], + ['title' => 'Slug', 'data' => 'slug', 'name' => 'slug'], + ['title' => 'Status', 'data' => 'status', 'name' => 'status'], + [ + 'title' => 'Action', + 'data' => 'action', + 'orderable' => false, + 'searchable' => false, + ], + ]; + @endphp + +
+
+
+
+
+@endsection diff --git a/Modules/CCMS/resources/views/event/partials/_form.blade.php b/Modules/CCMS/resources/views/event/partials/_form.blade.php new file mode 100644 index 0000000..292fda3 --- /dev/null +++ b/Modules/CCMS/resources/views/event/partials/_form.blade.php @@ -0,0 +1,196 @@ +
+
+
+
+
+
+ {{ html()->label('Title')->class('form-label')->for('title') }} + {{ html()->span('*')->class('text-danger') }} + {{ html()->text('title')->class('form-control')->placeholder('Enter Event Title')->required(true) }} +
+ +
+ {{ html()->label('Start Date')->class('form-label') }} +
+ {{ html()->text('start_date')->class('form-control')->id('event-start-date')->placeholder('Event Start Date')->attributes([ + 'data-provider' => 'flatpickr', + 'data-date-format' => 'Y-m-d', + 'data-enable-time' => '', + ])->required() }} + +
+
+ +
+ {{ html()->label('End Date')->class('form-label') }} +
+ {{ html()->text('end_date')->class('form-control')->id('event-end-date')->placeholder('Event End Date')->attributes([ + 'data-provider' => 'flatpickr', + 'data-date-format' => 'Y-m-d', + 'data-enable-time' => '', + ]) }} + +
+
+ +
+ {{ html()->label('Description (Short)')->class('form-label')->for('short_description') }} + {{ html()->textarea('short_description')->class('form-control')->placeholder('Enter Description (Short)')->rows(5) }} +
+ +
+ {{ html()->label('Description')->class('form-label')->for('description') }} + {{ html()->textarea('description')->class('form-control ckeditor-classic')->placeholder('Enter Description') }} +
+
+
+
+ + + +
+
+
Meta
+
+
+
+
+ {{ html()->label('Meta Title')->class('form-label')->for('meta_title') }} + {{ html()->text('meta_title')->class('form-control mb-3')->placeholder('Meta Title') }} +
+
+ {{ html()->label('Meta Keywords')->class('form-label')->for('meta_keywords') }} + {{ html()->textarea('meta_keywords')->class('form-control mb-3')->placeholder('Meta Keywords') }} +
+ +
+ {{ html()->label('Meta Description')->class('form-label')->for('meta_description') }} + {{ html()->textarea('meta_description')->class('form-control mb-3')->placeholder('Meta wire:Description')->rows(3) }} +
+
+
+
+
+ +
+
+
+
+ Published +
+
+
+ {{ html()->label('Status')->class('form-label visually-hidden')->for('status') }} + {{ html()->select('status', config('constants.page_status_options'))->class('form-select choices-select') }} +
+ + +
+ +
+
+
+ Page Attributes +
+
+
+ {{ html()->label('Parent Event')->class('form-label')->for('parent_id') }} + {{ html()->select('parent_id', $eventOptions ?? [])->value($event->parent_id ?? old('parent_id'))->class('form-select choices-select')->placeholder('Select') }} +
+
+ + + + + + + + + + +
+
+
Button
+
+
+
+
+ {{ html()->label('Text')->class('form-label')->for('button_text') }} + {{ html()->text('button_text')->class('form-control') }} +
+
+ {{ html()->label('Link')->class('form-label')->for('button_url') }} + {{ html()->text('button_url')->class('form-control')->placeholder('Button Link') }} +
+ +
+ {{ html()->label('Target')->class('form-label')->for('button_target') }} + {{ html()->select('button_target', config('constants.redirect_options'))->class('form-select choices-select') }} +
+
+
+
+
+
diff --git a/Modules/CCMS/routes/web.php b/Modules/CCMS/routes/web.php index e25e4f3..a17b0e4 100644 --- a/Modules/CCMS/routes/web.php +++ b/Modules/CCMS/routes/web.php @@ -8,6 +8,7 @@ use Modules\CCMS\Http\Controllers\CounselorController; use Modules\CCMS\Http\Controllers\CounterController; use Modules\CCMS\Http\Controllers\CountryController; use Modules\CCMS\Http\Controllers\EnquiryController; +use Modules\CCMS\Http\Controllers\EventController; use Modules\CCMS\Http\Controllers\FaqCategoryController; use Modules\CCMS\Http\Controllers\FaqController; use Modules\CCMS\Http\Controllers\FranchiseController; @@ -33,7 +34,7 @@ use Modules\CCMS\Http\Controllers\TestimonialController; | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! -| +|Eventcontr */ Route::group(['middleware' => ['web', 'auth', 'permission'], 'prefix' => 'admin/'], function () { @@ -85,6 +86,10 @@ Route::group(['middleware' => ['web', 'auth', 'permission'], 'prefix' => 'admin/ Route::get('service/toggle/{id}', [ServiceController::class, 'toggle'])->name('service.toggle'); Route::resource('service', ServiceController::class)->names('service'); + Route::post('event/reorder', [EventController::class, 'reorder'])->name('event.reorder'); + Route::get('event/toggle/{id}', [EventController::class, 'toggle'])->name('event.toggle'); + Route::resource('event', EventController::class)->names('event'); + Route::post('branch/reorder', [BranchController::class, 'reorder'])->name('branch.reorder'); Route::get('branch/toggle/{id}', [BranchController::class, 'toggle'])->name('branch.toggle'); Route::resource('branch', BranchController::class)->names('branch'); diff --git a/Modules/Meeting/routes/web.php b/Modules/Meeting/routes/web.php index 2172583..3001e42 100644 --- a/Modules/Meeting/routes/web.php +++ b/Modules/Meeting/routes/web.php @@ -16,10 +16,9 @@ use Modules\Meeting\Http\Controllers\MeetingController; */ Route::group(['middleware' => ['web', 'auth', 'permission'], 'prefix' => 'admin/'], function () { - Route::resource('event', EventController::class)->names('event'); + // Route::resource('event', EventController::class)->names('event'); Route::post('meeting/sub-task', [MeetingController::class, 'storeSubTask'])->name('meeting.storeSubTask'); Route::resource('meeting', MeetingController::class)->names('meeting'); Route::get('meeting/{id}/send-email', [MeetingController::class, 'sendEmail'])->name('meeting.sendmail'); - }); diff --git a/config/sidebar.php b/config/sidebar.php index 3afc673..020d954 100644 --- a/config/sidebar.php +++ b/config/sidebar.php @@ -66,13 +66,13 @@ return [ [ 'text' => 'Franchise Request', 'url' => 'admin/franchise', - // 'can' => ['franchise.index'], + 'can' => ['franchise.index'], ], [ 'text' => 'Newsletter', 'url' => 'admin/newsletter', - // 'can' => ['newsletter.index'], + 'can' => ['newsletter.index'], ], ], ], @@ -133,6 +133,14 @@ return [ 'can' => ['service.index'], ], + [ + 'text' => 'Events', + 'url' => 'admin/event', + 'icon' => 'ri-feedback-line', + 'module' => 'CCMS', + 'can' => ['event.index'], + ], + [ 'text' => 'Team', 'url' => 'admin/team',