diff --git a/Modules/CostCalculator/app/Http/Controllers/StayTypeController.php b/Modules/CostCalculator/app/Http/Controllers/StayTypeController.php new file mode 100644 index 0000000..96fe2a9 --- /dev/null +++ b/Modules/CostCalculator/app/Http/Controllers/StayTypeController.php @@ -0,0 +1,153 @@ +stayTypeService = $stayTypeService; + } + + /** + * Display a listing of the resource. + */ + public function index(?int $id = null) + { + $isEditing = !is_null($id); + $stay = $isEditing ? $this->stayTypeService->getStayTypeById($id) : null; + + if (request()->ajax()) { + $model = StayType::query()->orderBy('order'); + + return DataTables::eloquent($model) + ->addIndexColumn() + ->setRowClass('tableRow') + ->editColumn('status', function (StayType $stay) { + $status = $stay->status ? 'Published' : 'Draft'; + $color = $stay->status ? 'text-success' : 'text-danger'; + return "

{$status}

"; + }) + ->addColumn('action', 'costcalculator::staytype.datatable.action') + ->rawColumns(['action', 'status']) + ->toJson(); + } + + return view('costcalculator::staytype.index', [ + 'stay' => $stay, + 'editable' => $isEditing ? true : false, + 'title' => $isEditing ? 'Edit Stay Type' : 'Add Stay Type', + ]); + } + + /** + * Show the form for creating a new resource. + */ + public function create() + { + // + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + $isEditing = $request->has('id'); + + $request->merge([ + 'slug' => Str::slug($request->title), + ]); + + if ($isEditing) { + $validated = $request->validate([ + 'title' => ['required', 'string', 'max:255'], + 'slug' => ['required', 'string'], + ]); + + $stay = $this->stayTypeService->updateStayType($request->id, partnerData: $validated); + flash()->success("stay type for {$stay->title} has been updated."); + return to_route('stay.index'); + } + + $maxOrder = StayType::max('order'); + $order = $maxOrder ? ++$maxOrder : 1; + + $request->mergeIfMissing([ + 'order' => $order, + ]); + + $validated = $request->validate([ + 'title' => ['required', 'string'], + 'slug' => ['required', 'string'], + 'order' => ['integer'], + ]); + + $stay = $this->stayTypeService->storeStayType($validated); + flash()->success("Stay for {$stay->title} has been created."); + return to_route('stay.index'); + } + + /** + * Show the specified resource. + */ + public function show($id) + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit($id) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, $id) + { + // + } + + /** + * Remove the specified resource from storage. + */ + public function destroy($id) + { + $partner = $this->stayTypeService->deleteStayType($id); + return response()->json(['status' => 200, 'message' => "Stay Type has been deleted."], 200); + } + + public function reorder(Request $request) + { + $stays = $this->stayTypeService->getAllCategories(); + + foreach ($stays 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); + } + + public function toggle($id) + { + $partner = StayType::findOrFail($id); + $partner->update(['status' => !$partner->status]); + return response(['status' => 200, 'message' => 'Toggled successfully'], 200); + } +} diff --git a/Modules/CostCalculator/app/Models/StayType.php b/Modules/CostCalculator/app/Models/StayType.php new file mode 100644 index 0000000..7fe069f --- /dev/null +++ b/Modules/CostCalculator/app/Models/StayType.php @@ -0,0 +1,30 @@ + 'array', + ]; + } + +} diff --git a/Modules/CostCalculator/app/Services/StayTypeService.php b/Modules/CostCalculator/app/Services/StayTypeService.php new file mode 100644 index 0000000..be13386 --- /dev/null +++ b/Modules/CostCalculator/app/Services/StayTypeService.php @@ -0,0 +1,49 @@ +get(); + } + + public function storeStayType(array $partnerData): StayType + { + return DB::transaction(function () use ($partnerData) { + $partner = StayType::create($partnerData); + + return $partner; + }); + } + + public function getStayTypeById(int $id) + { + return StayType::findOrFail($id); + } + + public function updateStayType(int $id, array $partnerData) + { + $partner = $this->getStayTypeById($id); + + return DB::transaction(function () use ($partner, $partnerData) { + $partner->update($partnerData); + return $partner; + }); + } + + public function deleteStayType(int $id) + { + return DB::transaction(function () use ($id) { + $partner = $this->getStayTypeById($id); + $partner->delete(); + return true; + }); + } +} diff --git a/Modules/CostCalculator/database/migrations/2025_08_14_103942_create_stay_types_table.php b/Modules/CostCalculator/database/migrations/2025_08_14_103942_create_stay_types_table.php new file mode 100644 index 0000000..d8b26c9 --- /dev/null +++ b/Modules/CostCalculator/database/migrations/2025_08_14_103942_create_stay_types_table.php @@ -0,0 +1,33 @@ +id(); + $table->text('title'); + $table->text('slug')->nullable(); + $table->integer('status')->default(1); + $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('stay_types'); + } +}; diff --git a/Modules/CostCalculator/resources/views/staytype/add-stay-type-form.blade.php b/Modules/CostCalculator/resources/views/staytype/add-stay-type-form.blade.php new file mode 100644 index 0000000..7b2f091 --- /dev/null +++ b/Modules/CostCalculator/resources/views/staytype/add-stay-type-form.blade.php @@ -0,0 +1,22 @@ +{{ html()->form('POST', route('stay.store'))->class('needs-validation')->attributes(['novalidate'])->open() }} + +@isset($stay) + {{ html()->hidden('id', $stay->id) }} +@endisset + +
+
+
+
+ {{ html()->label('Title')->for('title') }} + {{ html()->span('*')->class('text-danger') }} + {{ html()->text('title')->value($stay->title ?? old('title'))->class('form-control')->placeholder('Enter Title')->required() }} + {{ html()->div('Please enter a title.')->class('invalid-feedback') }} +
+ +
+ + +
+
+{{ html()->form()->close() }} diff --git a/Modules/CostCalculator/resources/views/staytype/datatable/action.blade.php b/Modules/CostCalculator/resources/views/staytype/datatable/action.blade.php new file mode 100644 index 0000000..68ba592 --- /dev/null +++ b/Modules/CostCalculator/resources/views/staytype/datatable/action.blade.php @@ -0,0 +1,11 @@ +
+ + + + + + +
diff --git a/Modules/CostCalculator/resources/views/staytype/index.blade.php b/Modules/CostCalculator/resources/views/staytype/index.blade.php new file mode 100644 index 0000000..09dbb42 --- /dev/null +++ b/Modules/CostCalculator/resources/views/staytype/index.blade.php @@ -0,0 +1,47 @@ +@extends('layouts.app') + +@section('content') +
+ + @if ($errors->any()) + + @endif + +
+
+
+ @include('costcalculator::staytype.add-stay-type-form') +
+
+ +
+
+
+ @php + $columns = [ + [ + 'title' => 'S.N', + 'data' => 'DT_RowIndex', + 'name' => 'DT_RowIndex', + 'orderable' => false, + 'searchable' => false, + 'sortable' => false, + ], + ['title' => 'Name', 'data' => 'title', 'name' => 'title'], + ['title' => 'Status', 'data' => 'status', 'name' => 'status'], + [ + 'title' => 'Action', + 'data' => 'action', + 'orderable' => false, + 'searchable' => false, + ], + ]; + @endphp + + +
+
+
+
+
+@endsection diff --git a/Modules/CostCalculator/routes/web.php b/Modules/CostCalculator/routes/web.php index 3ec9778..30413f3 100644 --- a/Modules/CostCalculator/routes/web.php +++ b/Modules/CostCalculator/routes/web.php @@ -2,6 +2,7 @@ use Illuminate\Support\Facades\Route; use Modules\CostCalculator\Http\Controllers\CostCalculatorController; +use Modules\CostCalculator\Http\Controllers\StayTypeController; /* |-------------------------------------------------------------------------- @@ -16,4 +17,9 @@ use Modules\CostCalculator\Http\Controllers\CostCalculatorController; Route::group(['middleware' => ['web', 'auth', 'permission'], 'prefix' => 'admin/'], function () { Route::resource('cost-calculator', CostCalculatorController::class)->names('cost'); + + Route::post('stay/reorder', [StayTypeController::class, 'reorder'])->name('stay.reorder'); + Route::get('stay/toggle/{id}', [StayTypeController::class, 'toggle'])->name('stay.toggle'); + Route::get('stay/{id?}', [StayTypeController::class, 'index'])->name('stay.index'); + Route::resource('stay-type', StayTypeController::class)->names('stay')->only(['store', 'edit', 'destroy']); }); diff --git a/config/sidebar.php b/config/sidebar.php index 810aa27..a956bac 100644 --- a/config/sidebar.php +++ b/config/sidebar.php @@ -226,6 +226,24 @@ return [ ], ], + [ + 'text' => 'Cost Calculator', + 'icon' => 'ri-newspaper-line', + 'module' => 'CostCalculator', + 'submenu' => [ + [ + 'url' => 'admin/stay', + 'text' => 'Stay Type', + 'can' => ['stay.index'], + ], + [ + 'url' => 'admin/cost-calculator', + 'text' => 'Cost Calculation', + 'can' => ['cost.index'], + ], + ], + ], + [ 'text' => 'Documents', 'url' => 'admin/documents',