From a448fce756a10be693776ec233d67f7245c1b26c Mon Sep 17 00:00:00 2001 From: xayana Date: Mon, 26 Jan 2026 09:06:06 +0000 Subject: [PATCH] + availability --- RoomType::create([ | 8 + app/Http/Controllers/Admin/AuthController.php | 16 +- .../Admin/AvailabilityController.php | 46 +- .../Controllers/Admin/BookingController.php | 11 - .../Controllers/Admin/HotelController.php | 15 +- .../Controllers/Admin/RoomTypeController.php | 11 - app/Http/Controllers/BookingController.php | 129 ---- app/Http/Controllers/HotelController.php | 63 -- app/Http/Controllers/Orders.php | 10 - app/Http/Controllers/OrdersController.php | 34 - .../RoomAvailabilityController.php | 86 --- app/Http/Controllers/RoomTypeController.php | 75 --- app/Models/Availability.php | 31 + app/Models/Booking.php | 7 +- app/Models/Hotel.php | 2 +- app/Models/RoomType.php | 16 +- app/Providers/RouteServiceProvider.php | 19 +- cription' => 'С панорамным видом', | 628 ++++++++++++++++++ .../2025_12_30_222106_create_room_types.php | 8 +- ...025_12_30_231102_create_bookings_table.php | 33 +- ..._20_205127_create_availabilities_table.php | 26 + ...39_add_description_to_room_types_table.php | 22 + ...751_add_max_guests_to_room_types_table.php | 22 + ...33_modify_capacity_in_room_types_table.php | 23 + ..._modify_base_price_in_room_types_table.php | 23 + .../views/admin/hotels/_calendar.blade.php | 97 +++ resources/views/admin/hotels/create.blade.php | 4 +- resources/views/admin/hotels/edit.blade.php | 2 +- resources/views/admin/hotels/index.blade.php | 51 +- resources/views/admin/layout.blade.php | 65 +- resources/views/admin/login.blade.php | 11 +- resources/views/admin/logout.blade.php | 9 - routes/api.php | 13 +- routes/web.php | 51 +- 34 files changed, 1089 insertions(+), 578 deletions(-) create mode 100644 RoomType::create([ delete mode 100644 app/Http/Controllers/Admin/BookingController.php delete mode 100644 app/Http/Controllers/Admin/RoomTypeController.php delete mode 100644 app/Http/Controllers/BookingController.php delete mode 100644 app/Http/Controllers/HotelController.php delete mode 100644 app/Http/Controllers/Orders.php delete mode 100644 app/Http/Controllers/OrdersController.php delete mode 100644 app/Http/Controllers/RoomAvailabilityController.php delete mode 100644 app/Http/Controllers/RoomTypeController.php create mode 100644 app/Models/Availability.php create mode 100644 cription' => 'С панорамным видом', create mode 100644 database/migrations/2026_01_20_205127_create_availabilities_table.php create mode 100644 database/migrations/2026_01_23_215439_add_description_to_room_types_table.php create mode 100644 database/migrations/2026_01_23_222751_add_max_guests_to_room_types_table.php create mode 100644 database/migrations/2026_01_23_225033_modify_capacity_in_room_types_table.php create mode 100644 database/migrations/2026_01_23_225641_modify_base_price_in_room_types_table.php create mode 100644 resources/views/admin/hotels/_calendar.blade.php delete mode 100644 resources/views/admin/logout.blade.php diff --git a/RoomType::create([ b/RoomType::create([ new file mode 100644 index 0000000..9c52b4b --- /dev/null +++ b/RoomType::create([ @@ -0,0 +1,8 @@ += App\Models\Hotel {#5905 + name: "Mountain Lodge", + address: "Alpine Valley, Switzerland", + updated_at: "2026-01-23 22:51:26", + created_at: "2026-01-23 22:51:26", + id: 30, + } + diff --git a/app/Http/Controllers/Admin/AuthController.php b/app/Http/Controllers/Admin/AuthController.php index 7c9bb68..b62c0cc 100644 --- a/app/Http/Controllers/Admin/AuthController.php +++ b/app/Http/Controllers/Admin/AuthController.php @@ -25,20 +25,14 @@ class AuthController extends Controller return redirect()->route('admin.hotels.index'); } - return back()->withErrors([ - 'email' => 'Неверные данные.', - ])->onlyInput('email'); + return back()->withErrors(['email' => 'Неверные данные.']); } - /** - * Выход из системы. - */ public function logout(Request $request) { - Auth::logout(); - $request->session()->invalidate(); - $request->session()->regenerateToken(); - - return view('admin.logout'); + Auth::logout(); + $request->session()->invalidate(); + $request->session()->regenerateToken(); + return redirect()->route('admin.login.form')->with('success', 'Вы успешно вышли из системы.'); } } diff --git a/app/Http/Controllers/Admin/AvailabilityController.php b/app/Http/Controllers/Admin/AvailabilityController.php index deb3b4d..ee5adfb 100644 --- a/app/Http/Controllers/Admin/AvailabilityController.php +++ b/app/Http/Controllers/Admin/AvailabilityController.php @@ -3,9 +3,53 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; +use App\Models\RoomType; use Illuminate\Http\Request; class AvailabilityController extends Controller { - // + public function calendar(RoomType $roomType) + { + $roomType->load('availabilities'); + + if (request()->ajax()) { + return view('admin.availability._calendar', compact('roomType'))->render(); + } + + return view('admin.availability.calendar', compact('roomType')); + } + + public function store(Request $request, RoomType $roomType) + { + $validated = $request->validate([ + 'start_date' => 'required|date', + 'end_date' => 'required|date|after_or_equal:start_date', + 'is_available' => 'required|boolean', + 'price' => 'nullable|numeric|min=0', + ]); + + $roomType->availabilities() + ->where('start_date', '<=', $validated['end_date']) + ->where('end_date', '>=', $validated['start_date']) + ->delete(); + + $roomType->availabilities()->create($validated); + + if ($request->ajax()) { + return response()->json(['success' => true]); + } + + return redirect()->back()->with('success', 'Период сохранён.'); + } + + public function destroy(\App\Models\Availability $availability) + { + $availability->delete(); + + if (request()->ajax()) { + return response()->json(['success' => true]); + } + + return redirect()->back()->with('success', 'Период удалён.'); + } } diff --git a/app/Http/Controllers/Admin/BookingController.php b/app/Http/Controllers/Admin/BookingController.php deleted file mode 100644 index 71c955a..0000000 --- a/app/Http/Controllers/Admin/BookingController.php +++ /dev/null @@ -1,11 +0,0 @@ -with('availabilities')->get(); + + if ($request->ajax()) { + return view('admin.hotels._calendar', compact('hotel', 'roomTypes'))->render(); + } + + return view('admin.hotels.calendar', compact('hotel', 'roomTypes')); + } + public function store(Request $request) { $validated = $request->validate([ @@ -55,4 +68,4 @@ class HotelController extends Controller $hotel->delete(); return redirect()->route('admin.hotels.index')->with('success', 'Отель удалён.'); } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Admin/RoomTypeController.php b/app/Http/Controllers/Admin/RoomTypeController.php deleted file mode 100644 index 3317e6f..0000000 --- a/app/Http/Controllers/Admin/RoomTypeController.php +++ /dev/null @@ -1,11 +0,0 @@ -validate([ - 'room_type_id' => 'required|exists:room_types,id', - 'check_in' => 'required|date|after_or_equal:today', - 'check_out' => 'required|date|after:check_in', - 'guest_name' => 'required|string|max:255', - 'guest_email' => 'required|email', - 'guest_phone' => 'required|string', - 'confirmation_type' => 'required|in:auto,manual', - ]); - - $roomType = RoomType::findOrFail($validated['room_type_id']); - - $dates = []; - $currentDate = new \DateTime($validated['check_in']); - $endDate = new \DateTime($validated['check_out']); - - while ($currentDate < $endDate) { - $dates[] = $currentDate->format('Y-m-d'); - $currentDate->modify('+1 day'); - } - - $unavailableDates = RoomAvailability::where('room_type_id', $roomType->id) - ->whereIn('date', $dates) - ->where('is_available', false) - ->pluck('date') - ->toArray(); - - if (!empty($unavailableDates)) { - throw ValidationException::withMessages([ - 'check_in' => [ - 'The following dates are not available: ' . implode(', ', $unavailableDates) - ], - ]); - } - - DB::beginTransaction(); - - try { - $booking = Booking::create([ - 'room_type_id' => $validated['room_type_id'], - 'check_in' => $validated['check_in'], - 'check_out' => $validated['check_out'], - 'guest_name' => $validated['guest_name'], - 'guest_email' => $validated['guest_email'], - 'guest_phone' => $validated['guest_phone'], - 'status' => $validated['confirmation_type'] === 'auto' ? 'confirmed' : 'pending', - 'confirmed_at' => $validated['confirmation_type'] === 'auto' ? now() : null, - 'created_by_user_id' => $request->user()->id, // ← ID админа - ]); - - DB::commit(); - - return response()->json($booking, 201); - } catch (\Exception $e) { - DB::rollback(); - throw $e; - } - } - public function index(Request $request) -{ - $query = \App\Models\Booking::with(['roomType', 'roomType.hotel']); - - // Фильтр по статусу - if ($request->has('status')) { - $query->where('status', $request->status); - } - - // Фильтр по отелю - if ($request->has('hotel_id')) { - $query->whereHas('roomType.hotel', function ($q) use ($request) { - $q->where('id', $request->hotel_id); - }); - } - - // Фильтр по дате заезда (от) - if ($request->has('from')) { - $query->where('check_in', '>=', $request->from); - } - - $query->orderBy('created_at', 'desc'); - - return response()->json($query->paginate(10)); -} - public function confirm(Request $request, $id) - { - $booking = Booking::findOrFail($id); - - if ($booking->status !== 'pending') { - return response()->json(['error' => 'Booking is not in pending status'], 400); - } - - $booking->update([ - 'status' => 'confirmed', - 'confirmed_at' => now(), - ]); - - return response()->json($booking); - } - - public function cancel(Request $request, $id) - { - $booking = Booking::findOrFail($id); - - if ($booking->status === 'cancelled') { - return response()->json(['error' => 'Booking is already cancelled'], 400); - } - - $booking->update([ - 'status' => 'cancelled', - ]); - - return response()->json($booking); - } -} \ No newline at end of file diff --git a/app/Http/Controllers/HotelController.php b/app/Http/Controllers/HotelController.php deleted file mode 100644 index 37468a4..0000000 --- a/app/Http/Controllers/HotelController.php +++ /dev/null @@ -1,63 +0,0 @@ - -validate([ - 'name' => 'required|string|max:255', - 'address' => 'nullable|string', - ]); - - $hotel = Hotel::create($validated); - - return response()->json($hotel, 201); - } - - public function show($id) - { - $hotel = Hotel::findOrFail($id); - - return response()->json($hotel); - } - - public function update(Request $request, $id) - { - $hotel = Hotel::findOrFail($id); - - $validated = $request->validate([ - 'name' => 'required|string|max:255', - 'address' => 'nullable|string', - ]); - - $hotel->update($validated); - - return response()->json($hotel); - } - - public function destroy($id) - { - $hotel = Hotel::findOrFail($id); - - - //if ($hotel->bookings()->exists()) { - // return response()->json(['error' => 'Cannot delete hotel with bookings'], 400); - //} - - $hotel->delete(); - - return response()->json(['message' => 'Hotel deleted successfully']); - } -} \ No newline at end of file diff --git a/app/Http/Controllers/Orders.php b/app/Http/Controllers/Orders.php deleted file mode 100644 index 5fa8315..0000000 --- a/app/Http/Controllers/Orders.php +++ /dev/null @@ -1,10 +0,0 @@ -json(Orders::all()->toJson); - } -public function create(Request $request) -{ - $status = $request->get(key: 'status'); - $description = $request->get(key: 'description'); - - - - $order = new Order(); - $order ->status = $status; - $order ->description = $description; - - $order ->total = $request->get('total',0); - $order ->save(); - - - - return response()->json($order->toJson()); -} -} - diff --git a/app/Http/Controllers/RoomAvailabilityController.php b/app/Http/Controllers/RoomAvailabilityController.php deleted file mode 100644 index 778968b..0000000 --- a/app/Http/Controllers/RoomAvailabilityController.php +++ /dev/null @@ -1,86 +0,0 @@ -query('from'); - $to = $request->query('to'); - - if (!$from || !$to) { - throw ValidationException::withMessages([ - 'from' => ['The from date is required.'], - 'to' => ['The to date is required.'], - ]); - } - - $fromDate = \DateTime::createFromFormat('Y-m-d', $from); - $toDate = \DateTime::createFromFormat('Y-m-d', $to); - - if (!$fromDate || !$toDate) { - throw ValidationException::withMessages([ - 'from' => ['Invalid from date format. Use YYYY-MM-DD.'], - 'to' => ['Invalid to date format. Use YYYY-MM-DD.'], - ]); - } - - if ($fromDate > $toDate) { - throw ValidationException::withMessages([ - 'from' => ['From date must be before to date.'], - ]); - } - - $availabilities = RoomAvailability::where('room_type_id', $roomTypeId) - ->whereBetween('date', [$from, $to]) - ->orderBy('date') - ->get(); - - return response()->json($availabilities); - } - - public function bulkUpdate(Request $request, $roomTypeId) - { - $roomType = RoomType::findOrFail($roomTypeId); - - $validated = $request->validate([ - 'data' => 'required|array', - 'data.*.date' => 'required|date_format:Y-m-d|after_or_equal:today', - 'data.*.is_available' => 'required|boolean', - 'data.*.price_override' => 'nullable|numeric|min:0', - ]); - - DB::beginTransaction(); - - try { - foreach ($validated['data'] as $item) { - RoomAvailability::updateOrCreate( - [ - 'room_type_id' => $roomTypeId, - 'date' => $item['date'], - ], - [ - 'is_available' => $item['is_available'], - 'price_override' => $item['price_override'] ?? null, - ] - ); - } - - DB::commit(); - - return response()->json(['message' => 'Availability updated successfully']); - } catch (\Exception $e) { - DB::rollback(); - throw $e; - } - } -} \ No newline at end of file diff --git a/app/Http/Controllers/RoomTypeController.php b/app/Http/Controllers/RoomTypeController.php deleted file mode 100644 index f0b7ea7..0000000 --- a/app/Http/Controllers/RoomTypeController.php +++ /dev/null @@ -1,75 +0,0 @@ -validate([ - 'name' => 'required|string|max:255', - 'capacity' => 'required|integer|min:1', - 'base_price' => 'required|numeric|min:0', - ]); - - $roomType = $hotel->roomTypes()->create($validated); - - return response()->json($roomType, 201); - } - - public function update(Request $request, $id) - { - $roomType = RoomType::findOrFail($id); - - $validated = $request->validate([ - 'name' => 'required|string|max:255', - 'capacity' => 'required|integer|min:1', - 'base_price' => 'required|numeric|min:0', - ]); - - $roomType->update($validated); - - return response()->json($roomType); - } - - public function destroy($id) - { - $roomType = RoomType::findOrFail($id); - - - if ($roomType->bookings()->exists()) { - return response()->json(['error' => 'Cannot delete room type with active bookings'], 400); - } - - - if ($roomType->availabilities()->exists()) { - return response()->json(['error' => 'Cannot delete room type with availability records'], 400); - } - - $roomType->delete(); - - return response()->json(['message' => 'Room type deleted successfully']); - } - - public function hotel() -{ - return $this->belongsTo(Hotel::class); -} - -public function bookings() -{ - return $this->hasMany(Booking::class); -} - -public function availabilities() -{ - return $this->hasMany(RoomAvailability::class); -} -} \ No newline at end of file diff --git a/app/Models/Availability.php b/app/Models/Availability.php new file mode 100644 index 0000000..df28d4a --- /dev/null +++ b/app/Models/Availability.php @@ -0,0 +1,31 @@ + 'boolean', + 'start_date' => 'date', + 'end_date' => 'date', + 'price' => 'decimal:2', + ]; + + public function roomType() + { + return $this->belongsTo(RoomType::class); + } +} diff --git a/app/Models/Booking.php b/app/Models/Booking.php index 0b8f52a..5d74bc2 100644 --- a/app/Models/Booking.php +++ b/app/Models/Booking.php @@ -16,14 +16,15 @@ class Booking extends Model 'guest_name', 'guest_email', 'guest_phone', - 'status', - 'confirmed_at', + 'is_confirmed', + 'total_price', ]; protected $casts = [ 'check_in' => 'date', 'check_out' => 'date', - 'confirmed_at' => 'datetime', + 'is_confirmed' => 'boolean', + 'total_price' => 'decimal:2', ]; public function roomType() diff --git a/app/Models/Hotel.php b/app/Models/Hotel.php index 3d6f562..5b58be2 100644 --- a/app/Models/Hotel.php +++ b/app/Models/Hotel.php @@ -16,7 +16,7 @@ class Hotel extends Model public function roomTypes() { - return $this->hasMany(RoomType::class); + return $this->hasMany(\App\Models\RoomType::class); } //public function bookings() diff --git a/app/Models/RoomType.php b/app/Models/RoomType.php index f60a1eb..35fc0bd 100644 --- a/app/Models/RoomType.php +++ b/app/Models/RoomType.php @@ -12,8 +12,8 @@ class RoomType extends Model protected $fillable = [ 'hotel_id', 'name', - 'capacity', - 'base_price', + 'description', + 'max_guests', ]; public function hotel() @@ -21,13 +21,13 @@ class RoomType extends Model return $this->belongsTo(Hotel::class); } - public function bookings() - { - return $this->hasMany(Booking::class); - } - public function availabilities() { - return $this->hasMany(RoomAvailability::class); + return $this->hasMany(Availability::class); } + + public function bookings() +{ + return $this->hasMany(\App\Models\Booking::class); +} } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index ded4489..93f7e78 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -22,22 +22,19 @@ class RouteServiceProvider extends ServiceProvider * * @return void */ - public function boot() + public function boot() { $this->configureRateLimiting(); - //$this->routesPath = base_path('routes'); + $this->routes(function () { + Route::middleware('web') + ->group(base_path('routes/web.php')); - //$this->routes(function () { - //Route::middleware('web') - //->group($this->routesPath . '/web.php'); - - //Route::middleware(['web', 'auth']) - //->prefix('admin') - //->group($this->routesPath . '/admin.php'); - //}); + // Route::middleware(['web', 'auth']) +// ->prefix('admin') +// ->group(base_path('routes/admin.php')); + }); } - /** * Configure the rate limiters for the application. * diff --git a/cription' => 'С панорамным видом', b/cription' => 'С панорамным видом', new file mode 100644 index 0000000..f00c23a --- /dev/null +++ b/cription' => 'С панорамным видом', @@ -0,0 +1,628 @@ + + SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS + + Commands marked with * may be preceded by a number, _N. + Notes in parentheses indicate the behavior if _N is given. + A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. + + h H Display this help. + q :q Q :Q ZZ Exit. + --------------------------------------------------------------------------- + + MMOOVVIINNGG + + e ^E j ^N CR * Forward one line (or _N lines). + y ^Y k ^K ^P * Backward one line (or _N lines). + f ^F ^V SPACE * Forward one window (or _N lines). + b ^B ESC-v * Backward one window (or _N lines). + z * Forward one window (and set window to _N). + w * Backward one window (and set window to _N). + ESC-SPACE * Forward one window, but don't stop at end-of-file. + d ^D * Forward one half-window (and set half-window to _N). + u ^U * Backward one half-window (and set half-window to _N). + ESC-) RightArrow * Right one half screen width (or _N positions). + ESC-( LeftArrow * Left one half screen width (or _N positions). + ESC-} ^RightArrow Right to last column displayed. + ESC-{ ^LeftArrow Left to first column. + F Forward forever; like "tail -f". + ESC-F Like F but stop when search pattern is found. + r ^R ^L Repaint screen. + R Repaint screen, discarding buffered input. + --------------------------------------------------- + Default "window" is the screen height. + Default "half-window" is half of the screen height. + --------------------------------------------------------------------------- + + SSEEAARRCCHHIINNGG + + /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. + ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. + n * Repeat previous search (for _N-th occurrence). + N * Repeat previous search in reverse direction. + ESC-n * Repeat previous search, spanning files. + ESC-N * Repeat previous search, reverse dir. & spanning files. + ^O^N ^On * Search forward for (_N-th) OSC8 hyperlink. + ^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink. + ^O^L ^Ol Jump to the currently selected OSC8 hyperlink. + ESC-u Undo (toggle) search highlighting. + ESC-U Clear search highlighting. + &_p_a_t_t_e_r_n * Display only matching lines. + --------------------------------------------------- + A search pattern may begin with one or more of: + ^N or ! Search for NON-matching lines. + ^E or * Search multiple files (pass thru END OF FILE). + ^F or @ Start search at FIRST file (for /) or last file (for ?). + ^K Highlight matches, but don't move (KEEP position). + ^R Don't use REGULAR EXPRESSIONS. + ^S _n Search for match in _n-th parenthesized subpattern. + ^W WRAP search if no match found. + ^L Enter next character literally into pattern. + --------------------------------------------------------------------------- + + JJUUMMPPIINNGG + + g < ESC-< * Go to first line in file (or line _N). + G > ESC-> * Go to last line in file (or line _N). + p % * Go to beginning of file (or _N percent into file). + t * Go to the (_N-th) next tag. + T * Go to the (_N-th) previous tag. + { ( [ * Find close bracket } ) ]. + } ) ] * Find open bracket { ( [. + ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. + ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>. + --------------------------------------------------- + Each "find close bracket" command goes forward to the close bracket + matching the (_N-th) open bracket in the top line. + Each "find open bracket" command goes backward to the open bracket + matching the (_N-th) close bracket in the bottom line. + + m_<_l_e_t_t_e_r_> Mark the current top line with . + M_<_l_e_t_t_e_r_> Mark the current bottom line with . + '_<_l_e_t_t_e_r_> Go to a previously marked position. + '' Go to the previous position. + ^X^X Same as '. + ESC-m_<_l_e_t_t_e_r_> Clear a mark. + --------------------------------------------------- + A mark is any upper-case or lower-case letter. + Certain marks are predefined: + ^ means beginning of the file + $ means end of the file + --------------------------------------------------------------------------- + + CCHHAANNGGIINNGG FFIILLEESS + + :e [_f_i_l_e] Examine a new file. + ^X^V Same as :e. + :n * Examine the (_N-th) next file from the command line. + :p * Examine the (_N-th) previous file from the command line. + :x * Examine the first (or _N-th) file from the command line. + ^O^O Open the currently selected OSC8 hyperlink. + :d Delete the current file from the command line list. + = ^G :f Print current file name. + --------------------------------------------------------------------------- + + MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS + + -_<_f_l_a_g_> Toggle a command line option [see OPTIONS below]. + --_<_n_a_m_e_> Toggle a command line option, by name. + __<_f_l_a_g_> Display the setting of a command line option. + ___<_n_a_m_e_> Display the setting of an option, by name. + +_c_m_d Execute the less cmd each time a new file is examined. + + !_c_o_m_m_a_n_d Execute the shell command with $SHELL. + #_c_o_m_m_a_n_d Execute the shell command, expanded like a prompt. + |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. + s _f_i_l_e Save input to a file. + v Edit the current file with $VISUAL or $EDITOR. + V Print version number of "less". + --------------------------------------------------------------------------- + + OOPPTTIIOONNSS + + Most options may be changed either on the command line, + or from within less by using the - or -- command. + Options may be given in one of two forms: either a single + character preceded by a -, or a name preceded by --. + + -? ........ --help + Display help (from command line). + -a ........ --search-skip-screen + Search skips current screen. + -A ........ --SEARCH-SKIP-SCREEN + Search starts just after target line. + -b [_N] .... --buffers=[_N] + Number of buffers. + -B ........ --auto-buffers + Don't automatically allocate buffers for pipes. + -c ........ --clear-screen + Repaint by clearing rather than scrolling. + -d ........ --dumb + Dumb terminal. + -D xx_c_o_l_o_r . --color=xx_c_o_l_o_r + Set screen colors. + -e -E .... --quit-at-eof --QUIT-AT-EOF + Quit at end of file. + -f ........ --force + Force open non-regular files. + -F ........ --quit-if-one-screen + Quit if entire file fits on first screen. + -g ........ --hilite-search + Highlight only last match for searches. + -G ........ --HILITE-SEARCH + Don't highlight any matches for searches. + -h [_N] .... --max-back-scroll=[_N] + Backward scroll limit. + -i ........ --ignore-case + Ignore case in searches that do not contain uppercase. + -I ........ --IGNORE-CASE + Ignore case in all searches. + -j [_N] .... --jump-target=[_N] + Screen position of target lines. + -J ........ --status-column + Display a status column at left edge of screen. + -k _f_i_l_e ... --lesskey-file=_f_i_l_e + Use a compiled lesskey file. + -K ........ --quit-on-intr + Exit less in response to ctrl-C. + -L ........ --no-lessopen + Ignore the LESSOPEN environment variable. + -m -M .... --long-prompt --LONG-PROMPT + Set prompt style. + -n ......... --line-numbers + Suppress line numbers in prompts and messages. + -N ......... --LINE-NUMBERS + Display line number at start of each line. + -o [_f_i_l_e] .. --log-file=[_f_i_l_e] + Copy to log file (standard input only). + -O [_f_i_l_e] .. --LOG-FILE=[_f_i_l_e] + Copy to log file (unconditionally overwrite). + -p _p_a_t_t_e_r_n . --pattern=[_p_a_t_t_e_r_n] + Start at pattern (from command line). + -P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t] + Define new prompt. + -q -Q .... --quiet --QUIET --silent --SILENT + Quiet the terminal bell. + -r -R .... --raw-control-chars --RAW-CONTROL-CHARS + Output "raw" control characters. + -s ........ --squeeze-blank-lines + Squeeze multiple blank lines. + -S ........ --chop-long-lines + Chop (truncate) long lines rather than wrapping. + -t _t_a_g .... --tag=[_t_a_g] + Find a tag. + -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] + Use an alternate tags file. + -u -U .... --underline-special --UNDERLINE-SPECIAL + Change handling of backspaces, tabs and carriage returns. + -V ........ --version + Display the version number of "less". + -w ........ --hilite-unread + Highlight first new line after forward-screen. + -W ........ --HILITE-UNREAD + Highlight first new line after any forward movement. + -x [_N[,...]] --tabs=[_N[,...]] + Set tab stops. + -X ........ --no-init + Don't use termcap init/deinit strings. + -y [_N] .... --max-forw-scroll=[_N] + Forward scroll limit. + -z [_N] .... --window=[_N] + Set size of window. + -" [_c[_c]] . --quotes=[_c[_c]] + Set shell quote characters. + -~ ........ --tilde + Don't display tildes after end of file. + -# [_N] .... --shift=[_N] + Set horizontal scroll amount (0 = one half screen width). + + --exit-follow-on-close + Exit F command on a pipe when writer closes pipe. + --file-size + Automatically determine the size of the input file. + --follow-name + The F command changes files if the input file is renamed. + --header=[_L[,_C[,_N]]] + Use _L lines (starting at line _N) and _C columns as headers. + --incsearch + Search file as each pattern character is typed in. + --intr=[_C] + Use _C instead of ^X to interrupt a read. + --lesskey-context=_t_e_x_t + Use lesskey source file contents. + --lesskey-src=_f_i_l_e + Use a lesskey source file. + --line-num-width=[_N] + Set the width of the -N line number field to _N characters. + --match-shift=[_N] + Show at least _N characters to the left of a search match. + --modelines=[_N] + Read _N lines from the input file and look for vim modelines. + --mouse + Enable mouse input. + --no-keypad + Don't send termcap keypad init/deinit strings. + --no-histdups + Remove duplicates from command history. + --no-number-headers + Don't give line numbers to header lines. + --no-search-header-lines + Searches do not include header lines. + --no-search-header-columns + Searches do not include header columns. + --no-search-headers + Searches do not include header lines or columns. + --no-vbell + Disable the terminal's visual bell. + --redraw-on-quit + Redraw final screen when quitting. + --rscroll=[_C] + Set the character used to mark truncated lines. + --save-marks + Retain marks across invocations of less. + --search-options=[EFKNRW-] + Set default options for every search. + --show-preproc-errors + Display a message if preprocessor exits with an error status. + --proc-backspace + Process backspaces for bold/underline. + --PROC-BACKSPACE + Treat backspaces as control characters. + --proc-return + Delete carriage returns before newline. + --PROC-RETURN + Treat carriage returns as control characters. + --proc-tab + Expand tabs to spaces. + --PROC-TAB + Treat tabs as control characters. + --status-col-width=[_N] + Set the width of the -J status column to _N characters. + --status-line + Highlight or color the entire line containing a mark. + --use-backslash + Subsequent options use backslash as escape char. + --use-color + Enables colored text. + --wheel-lines=[_N] + Each click of the mouse wheel moves _N lines. + --wordwrap + Wrap lines at spaces. + + + --------------------------------------------------------------------------- + + LLIINNEE EEDDIITTIINNGG + + These keys can be used to edit text being entered + on the "command line" at the bottom of the screen. + + RightArrow ..................... ESC-l ... Move cursor right one character. + LeftArrow ...................... ESC-h ... Move cursor left one character. + ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word. + ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word. + HOME ........................... ESC-0 ... Move cursor to start of line. + END ............................ ESC-$ ... Move cursor to end of line. + BACKSPACE ................................ Delete char to left of cursor. + DELETE ......................... ESC-x ... Delete char under cursor. + ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor. + ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor. + ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line. + UpArrow ........................ ESC-k ... Retrieve previous command line. + DownArrow ...................... ESC-j ... Retrieve next command line. + TAB ...................................... Complete filename & cycle. + SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle. + ctrl-L ................................... Complete filename, list all. + + SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS + + Commands marked with * may be preceded by a number, _N. + Notes in parentheses indicate the behavior if _N is given. + A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. + + h H Display this help. + q :q Q :Q ZZ Exit. + --------------------------------------------------------------------------- + + MMOOVVIINNGG + + e ^E j ^N CR * Forward one line (or _N lines). + y ^Y k ^K ^P * Backward one line (or _N lines). + f ^F ^V SPACE * Forward one window (or _N lines). + b ^B ESC-v * Backward one window (or _N lines). + z * Forward one window (and set window to _N). + w * Backward one window (and set window to _N). + ESC-SPACE * Forward one window, but don't stop at end-of-file. + d ^D * Forward one half-window (and set half-window to _N). + u ^U * Backward one half-window (and set half-window to _N). + ESC-) RightArrow * Right one half screen width (or _N positions). + ESC-( LeftArrow * Left one half screen width (or _N positions). + ESC-} ^RightArrow Right to last column displayed. + ESC-{ ^LeftArrow Left to first column. + F Forward forever; like "tail -f". + ESC-F Like F but stop when search pattern is found. + r ^R ^L Repaint screen. + R Repaint screen, discarding buffered input. + --------------------------------------------------- + Default "window" is the screen height. + Default "half-window" is half of the screen height. + --------------------------------------------------------------------------- + + SSEEAARRCCHHIINNGG + + /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. + ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. + n * Repeat previous search (for _N-th occurrence). + N * Repeat previous search in reverse direction. + ESC-n * Repeat previous search, spanning files. + ESC-N * Repeat previous search, reverse dir. & spanning files. + ^O^N ^On * Search forward for (_N-th) OSC8 hyperlink. + ^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink. + ^O^L ^Ol Jump to the currently selected OSC8 hyperlink. + ESC-u Undo (toggle) search highlighting. + ESC-U Clear search highlighting. + &_p_a_t_t_e_r_n * Display only matching lines. + --------------------------------------------------- + A search pattern may begin with one or more of: + ^N or ! Search for NON-matching lines. + ^E or * Search multiple files (pass thru END OF FILE). + ^F or @ Start search at FIRST file (for /) or last file (for ?). + ^K Highlight matches, but don't move (KEEP position). + ^R Don't use REGULAR EXPRESSIONS. + ^S _n Search for match in _n-th parenthesized subpattern. + ^W WRAP search if no match found. + ^L Enter next character literally into pattern. + --------------------------------------------------------------------------- + + JJUUMMPPIINNGG + + g < ESC-< * Go to first line in file (or line _N). + G > ESC-> * Go to last line in file (or line _N). + p % * Go to beginning of file (or _N percent into file). + t * Go to the (_N-th) next tag. + T * Go to the (_N-th) previous tag. + { ( [ * Find close bracket } ) ]. + } ) ] * Find open bracket { ( [. + ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. + ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>. + --------------------------------------------------- + Each "find close bracket" command goes forward to the close bracket + matching the (_N-th) open bracket in the top line. + Each "find open bracket" command goes backward to the open bracket + matching the (_N-th) close bracket in the bottom line. + + m_<_l_e_t_t_e_r_> Mark the current top line with . + M_<_l_e_t_t_e_r_> Mark the current bottom line with . + '_<_l_e_t_t_e_r_> Go to a previously marked position. + '' Go to the previous position. + ^X^X Same as '. + ESC-m_<_l_e_t_t_e_r_> Clear a mark. + --------------------------------------------------- + A mark is any upper-case or lower-case letter. + Certain marks are predefined: + ^ means beginning of the file + $ means end of the file + --------------------------------------------------------------------------- + + CCHHAANNGGIINNGG FFIILLEESS + + :e [_f_i_l_e] Examine a new file. + ^X^V Same as :e. + :n * Examine the (_N-th) next file from the command line. + :p * Examine the (_N-th) previous file from the command line. + :x * Examine the first (or _N-th) file from the command line. + ^O^O Open the currently selected OSC8 hyperlink. + :d Delete the current file from the command line list. + = ^G :f Print current file name. + --------------------------------------------------------------------------- + + MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS + + -_<_f_l_a_g_> Toggle a command line option [see OPTIONS below]. + --_<_n_a_m_e_> Toggle a command line option, by name. + __<_f_l_a_g_> Display the setting of a command line option. + ___<_n_a_m_e_> Display the setting of an option, by name. + +_c_m_d Execute the less cmd each time a new file is examined. + + !_c_o_m_m_a_n_d Execute the shell command with $SHELL. + #_c_o_m_m_a_n_d Execute the shell command, expanded like a prompt. + |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. + s _f_i_l_e Save input to a file. + v Edit the current file with $VISUAL or $EDITOR. + V Print version number of "less". + --------------------------------------------------------------------------- + + OOPPTTIIOONNSS + + Most options may be changed either on the command line, + or from within less by using the - or -- command. + Options may be given in one of two forms: either a single + character preceded by a -, or a name preceded by --. + + -? ........ --help + Display help (from command line). + -a ........ --search-skip-screen + Search skips current screen. + -A ........ --SEARCH-SKIP-SCREEN + Search starts just after target line. + -b [_N] .... --buffers=[_N] + Number of buffers. + -B ........ --auto-buffers + Don't automatically allocate buffers for pipes. + -c ........ --clear-screen + Repaint by clearing rather than scrolling. + -d ........ --dumb + Dumb terminal. + -D xx_c_o_l_o_r . --color=xx_c_o_l_o_r + Set screen colors. + -e -E .... --quit-at-eof --QUIT-AT-EOF + Quit at end of file. + -f ........ --force + Force open non-regular files. + -F ........ --quit-if-one-screen + Quit if entire file fits on first screen. + -g ........ --hilite-search + Highlight only last match for searches. + -G ........ --HILITE-SEARCH + Don't highlight any matches for searches. + -h [_N] .... --max-back-scroll=[_N] + Backward scroll limit. + -i ........ --ignore-case + Ignore case in searches that do not contain uppercase. + -I ........ --IGNORE-CASE + Ignore case in all searches. + -j [_N] .... --jump-target=[_N] + Screen position of target lines. + -J ........ --status-column + Display a status column at left edge of screen. + -k _f_i_l_e ... --lesskey-file=_f_i_l_e + Use a compiled lesskey file. + -K ........ --quit-on-intr + Exit less in response to ctrl-C. + -L ........ --no-lessopen + Ignore the LESSOPEN environment variable. + -m -M .... --long-prompt --LONG-PROMPT + Set prompt style. + -n ......... --line-numbers + Suppress line numbers in prompts and messages. + -N ......... --LINE-NUMBERS + Display line number at start of each line. + -o [_f_i_l_e] .. --log-file=[_f_i_l_e] + Copy to log file (standard input only). + -O [_f_i_l_e] .. --LOG-FILE=[_f_i_l_e] + Copy to log file (unconditionally overwrite). + -p _p_a_t_t_e_r_n . --pattern=[_p_a_t_t_e_r_n] + Start at pattern (from command line). + -P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t] + Define new prompt. + -q -Q .... --quiet --QUIET --silent --SILENT + Quiet the terminal bell. + -r -R .... --raw-control-chars --RAW-CONTROL-CHARS + Output "raw" control characters. + -s ........ --squeeze-blank-lines + Squeeze multiple blank lines. + -S ........ --chop-long-lines + Chop (truncate) long lines rather than wrapping. + -t _t_a_g .... --tag=[_t_a_g] + Find a tag. + -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] + Use an alternate tags file. + -u -U .... --underline-special --UNDERLINE-SPECIAL + Change handling of backspaces, tabs and carriage returns. + -V ........ --version + Display the version number of "less". + -w ........ --hilite-unread + Highlight first new line after forward-screen. + -W ........ --HILITE-UNREAD + Highlight first new line after any forward movement. + -x [_N[,...]] --tabs=[_N[,...]] + Set tab stops. + -X ........ --no-init + Don't use termcap init/deinit strings. + -y [_N] .... --max-forw-scroll=[_N] + Forward scroll limit. + -z [_N] .... --window=[_N] + Set size of window. + -" [_c[_c]] . --quotes=[_c[_c]] + Set shell quote characters. + -~ ........ --tilde + Don't display tildes after end of file. + -# [_N] .... --shift=[_N] + Set horizontal scroll amount (0 = one half screen width). + + --exit-follow-on-close + Exit F command on a pipe when writer closes pipe. + --file-size + Automatically determine the size of the input file. + --follow-name + The F command changes files if the input file is renamed. + --header=[_L[,_C[,_N]]] + Use _L lines (starting at line _N) and _C columns as headers. + --incsearch + Search file as each pattern character is typed in. + --intr=[_C] + Use _C instead of ^X to interrupt a read. + --lesskey-context=_t_e_x_t + Use lesskey source file contents. + --lesskey-src=_f_i_l_e + Use a lesskey source file. + --line-num-width=[_N] + Set the width of the -N line number field to _N characters. + --match-shift=[_N] + Show at least _N characters to the left of a search match. + --modelines=[_N] + Read _N lines from the input file and look for vim modelines. + --mouse + Enable mouse input. + --no-keypad + Don't send termcap keypad init/deinit strings. + --no-histdups + Remove duplicates from command history. + --no-number-headers + Don't give line numbers to header lines. + --no-search-header-lines + Searches do not include header lines. + --no-search-header-columns + Searches do not include header columns. + --no-search-headers + Searches do not include header lines or columns. + --no-vbell + Disable the terminal's visual bell. + --redraw-on-quit + Redraw final screen when quitting. + --rscroll=[_C] + Set the character used to mark truncated lines. + --save-marks + Retain marks across invocations of less. + --search-options=[EFKNRW-] + Set default options for every search. + --show-preproc-errors + Display a message if preprocessor exits with an error status. + --proc-backspace + Process backspaces for bold/underline. + --PROC-BACKSPACE + Treat backspaces as control characters. + --proc-return + Delete carriage returns before newline. + --PROC-RETURN + Treat carriage returns as control characters. + --proc-tab + Expand tabs to spaces. + --PROC-TAB + Treat tabs as control characters. + --status-col-width=[_N] + Set the width of the -J status column to _N characters. + --status-line + Highlight or color the entire line containing a mark. + --use-backslash + Subsequent options use backslash as escape char. + --use-color + Enables colored text. + --wheel-lines=[_N] + Each click of the mouse wheel moves _N lines. + --wordwrap + Wrap lines at spaces. + + + --------------------------------------------------------------------------- + + LLIINNEE EEDDIITTIINNGG + + These keys can be used to edit text being entered + on the "command line" at the bottom of the screen. + + RightArrow ..................... ESC-l ... Move cursor right one character. + LeftArrow ...................... ESC-h ... Move cursor left one character. + ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word. + ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word. + HOME ........................... ESC-0 ... Move cursor to start of line. + END ............................ ESC-$ ... Move cursor to end of line. + BACKSPACE ................................ Delete char to left of cursor. + DELETE ......................... ESC-x ... Delete char under cursor. + ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor. + ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor. + ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line. + UpArrow ........................ ESC-k ... Retrieve previous command line. + DownArrow ...................... ESC-j ... Retrieve next command line. + TAB ...................................... Complete filename & cycle. + SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle. + ctrl-L ................................... Complete filename, list all. diff --git a/database/migrations/2025_12_30_222106_create_room_types.php b/database/migrations/2025_12_30_222106_create_room_types.php index 59fc158..554f7e5 100644 --- a/database/migrations/2025_12_30_222106_create_room_types.php +++ b/database/migrations/2025_12_30_222106_create_room_types.php @@ -15,7 +15,7 @@ return new class extends Migration $table->id(); $table->foreignId('hotel_id')->constrained()->onDelete('cascade'); $table->string('name'); - $table->integer('capacity'); + $table->integer('capacity')->nullable()->default(2)->change(); $table->decimal('base_price', 10, 2); $table->timestamps(); }); @@ -24,8 +24,10 @@ return new class extends Migration /** * Reverse the migrations. */ - public function down(): void + public function down() { - Schema::dropIfExists('room_types'); + Schema::table('room_types', function (Blueprint $table) { + $table->integer('capacity')->default(2)->change(); + }); } }; diff --git a/database/migrations/2025_12_30_231102_create_bookings_table.php b/database/migrations/2025_12_30_231102_create_bookings_table.php index 599ab67..51993fc 100644 --- a/database/migrations/2025_12_30_231102_create_bookings_table.php +++ b/database/migrations/2025_12_30_231102_create_bookings_table.php @@ -9,24 +9,21 @@ return new class extends Migration /** * Run the migrations. */ - public function up(): void - { - Schema::create('bookings', function (Blueprint $table) { - $table->id(); - $table->string('booking_number')->nullable(); - $table->foreignId('room_type_id')->constrained()->onDelete('cascade'); - $table->date('check_in'); - $table->date('check_out'); - $table->string('guest_name'); - $table->string('guest_email')->nullable(); - $table->string('guest_phone')->nullable(); - $table->enum('status', ['pending', 'confirmed', 'cancelled', 'completed'])->default('pending'); - $table->enum('confirmation_type', ['auto', 'manual'])->default('auto'); - $table->unsignedBigInteger('created_by_user_id')->nullable(); - $table->timestamp('confirmed_at')->nullable(); - $table->timestamps(); - }); - } + public function up() +{ + Schema::create('bookings', function (Blueprint $table) { + $table->id(); + $table->foreignId('room_type_id')->constrained()->onDelete('cascade'); + $table->date('check_in'); + $table->date('check_out'); + $table->string('guest_name'); + $table->string('guest_email'); + $table->string('guest_phone')->nullable(); + $table->boolean('is_confirmed')->default(false); + $table->decimal('total_price', 10, 2)->nullable(); + $table->timestamps(); + }); +} /** * Reverse the migrations. diff --git a/database/migrations/2026_01_20_205127_create_availabilities_table.php b/database/migrations/2026_01_20_205127_create_availabilities_table.php new file mode 100644 index 0000000..b4c3151 --- /dev/null +++ b/database/migrations/2026_01_20_205127_create_availabilities_table.php @@ -0,0 +1,26 @@ +id(); + $table->foreignId('room_type_id')->constrained()->onDelete('cascade'); + $table->date('start_date'); + $table->date('end_date'); + $table->boolean('is_available')->default(true); + $table->decimal('price', 8, 2)->nullable(); + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('availabilities'); + } +}; diff --git a/database/migrations/2026_01_23_215439_add_description_to_room_types_table.php b/database/migrations/2026_01_23_215439_add_description_to_room_types_table.php new file mode 100644 index 0000000..81c9b16 --- /dev/null +++ b/database/migrations/2026_01_23_215439_add_description_to_room_types_table.php @@ -0,0 +1,22 @@ +text('description')->nullable()->after('name'); + }); + } + + public function down() + { + Schema::table('room_types', function (Blueprint $table) { + $table->dropColumn('description'); + }); + } +}; \ No newline at end of file diff --git a/database/migrations/2026_01_23_222751_add_max_guests_to_room_types_table.php b/database/migrations/2026_01_23_222751_add_max_guests_to_room_types_table.php new file mode 100644 index 0000000..1ffbd37 --- /dev/null +++ b/database/migrations/2026_01_23_222751_add_max_guests_to_room_types_table.php @@ -0,0 +1,22 @@ +integer('max_guests')->default(2)->after('description'); + }); + } + + public function down() + { + Schema::table('room_types', function (Blueprint $table) { + $table->dropColumn('max_guests'); + }); + } +}; diff --git a/database/migrations/2026_01_23_225033_modify_capacity_in_room_types_table.php b/database/migrations/2026_01_23_225033_modify_capacity_in_room_types_table.php new file mode 100644 index 0000000..a29ca4a --- /dev/null +++ b/database/migrations/2026_01_23_225033_modify_capacity_in_room_types_table.php @@ -0,0 +1,23 @@ +integer('capacity')->nullable()->default(2)->change(); + }); + } + + public function down() + { + Schema::table('room_types', function (Blueprint $table) { + $table->integer('capacity')->default(2)->change(); + }); + } +}; diff --git a/database/migrations/2026_01_23_225641_modify_base_price_in_room_types_table.php b/database/migrations/2026_01_23_225641_modify_base_price_in_room_types_table.php new file mode 100644 index 0000000..44f9026 --- /dev/null +++ b/database/migrations/2026_01_23_225641_modify_base_price_in_room_types_table.php @@ -0,0 +1,23 @@ +decimal('base_price', 8, 2)->nullable()->default(5000.00)->change(); + }); + } + + public function down() + { + Schema::table('room_types', function (Blueprint $table) { + $table->decimal('base_price', 8, 2)->default(5000.00)->change(); + }); + } +}; \ No newline at end of file diff --git a/resources/views/admin/hotels/_calendar.blade.php b/resources/views/admin/hotels/_calendar.blade.php new file mode 100644 index 0000000..6be4d31 --- /dev/null +++ b/resources/views/admin/hotels/_calendar.blade.php @@ -0,0 +1,97 @@ +
+ @if($roomTypes->isEmpty()) +

Нет типов номеров. Создать тип номера

+ @else + @foreach($roomTypes as $type) +
+

{{ $type->name }}

+ + +
+ @csrf +
+ + +
+
+ +
+
+ +
+ +
+ + + @if($type->availabilities->isEmpty()) +

Нет периодов.

+ @else + + + + + + + + + + + + @foreach($type->availabilities as $period) + + + + + + + + @endforeach + +
СПоСтатусЦенаДействие
{{ $period->start_date }}{{ $period->end_date }} + @if($period->is_available) + Доступен + @else + Недоступен + @endif + {{ $period->price ? number_format($period->price, 2) : '-' }} +
+ @csrf + @method('DELETE') + +
+
+ @endif +
+ @endforeach + @endif +
+ + \ No newline at end of file diff --git a/resources/views/admin/hotels/create.blade.php b/resources/views/admin/hotels/create.blade.php index 0d6e015..9389d2d 100644 --- a/resources/views/admin/hotels/create.blade.php +++ b/resources/views/admin/hotels/create.blade.php @@ -26,7 +26,7 @@ - Отмена + Отмена -@endsection \ No newline at end of file +@endsections \ No newline at end of file diff --git a/resources/views/admin/hotels/edit.blade.php b/resources/views/admin/hotels/edit.blade.php index 8b2232d..c4a8714 100644 --- a/resources/views/admin/hotels/edit.blade.php +++ b/resources/views/admin/hotels/edit.blade.php @@ -27,7 +27,7 @@ - Отмена + Отмена @endsection \ No newline at end of file diff --git a/resources/views/admin/hotels/index.blade.php b/resources/views/admin/hotels/index.blade.php index b0f4899..cd4cdba 100644 --- a/resources/views/admin/hotels/index.blade.php +++ b/resources/views/admin/hotels/index.blade.php @@ -4,7 +4,7 @@

Отели

- Добавить отель + Добавить отель @if($hotels->isEmpty())

Нет отелей.

@@ -25,14 +25,20 @@ {{ $hotel->address ?? '-' }} {{ $hotel->phone ?? '-' }} - Редактировать + + Редактировать +
@csrf @method('DELETE') -
+ + @endforeach @@ -40,4 +46,43 @@ @endif
+ + + + + @endsection \ No newline at end of file diff --git a/resources/views/admin/layout.blade.php b/resources/views/admin/layout.blade.php index a08bfc9..22f16d7 100644 --- a/resources/views/admin/layout.blade.php +++ b/resources/views/admin/layout.blade.php @@ -17,7 +17,7 @@ padding: 20px; } header { - background-color: #4a4a4a; + background-color: #4a148c; color: white; padding: 15px 20px; display: flex; @@ -26,10 +26,6 @@ margin-bottom: 25px; border-radius: 6px; } - header h1 { - margin: 0; - font-size: 1.3rem; - } nav a { color: white; text-decoration: none; @@ -39,7 +35,7 @@ transition: background-color 0.2s; } nav a:hover { - background-color: #5a5a5a; + background-color: #6a1b9a; } main { background: white; @@ -47,13 +43,9 @@ border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); } - h1, h2, h3 { - color: #2d2d2d; - margin-top: 0; - } .btn { display: inline-block; - background-color: #6c757d; + background-color: #4a148c; color: white; padding: 8px 16px; text-decoration: none; @@ -63,37 +55,14 @@ font-size: 0.95rem; transition: background-color 0.2s; } - .btn:hover { - background-color: #5a6268; - } - table { - width: 100%; - border-collapse: collapse; - margin: 20px 0; - } - th, td { - padding: 12px 15px; - text-align: left; - border-bottom: 1px solid #eaeaea; - } - th { - background-color: #f1f1f1; - font-weight: 600; - color: #444; - } - tr:hover { - background-color: #fafafa; - } - .alert { - padding: 12px; - margin: 16px 0; - border-radius: 4px; - } - .alert-success { - background-color: #e0f0e0; - color: #2d5d2d; - border-left: 4px solid #4caf50; - } + .btn:hover { background-color: #6a1b9a; } + .btn-secondary { background-color: #7b1fa2; } + .btn-secondary:hover { background-color: #9c27b0; } + .btn-danger { background-color: #000000; } + .btn-danger:hover { background-color: #212121; } + table { width: 100%; border-collapse: collapse; margin: 20px 0; } + th, td { padding: 12px 15px; text-align: left; border-bottom: 1px solid #eaeaea; } + th { background-color: #f1f1f1; font-weight: 600; } @@ -102,17 +71,17 @@
@if(session('success')) -
{{ session('success') }}
+
+ {{ session('success') }} +
@endif @yield('content') diff --git a/resources/views/admin/login.blade.php b/resources/views/admin/login.blade.php index b350b4b..b2a5603 100644 --- a/resources/views/admin/login.blade.php +++ b/resources/views/admin/login.blade.php @@ -5,7 +5,7 @@

Вход в админку

@if ($errors->any()) -
+
Неверные данные.
@endif @@ -13,16 +13,15 @@
@csrf
- + + style="width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;" value="{{ old('email') }}">
- + + style="width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">
diff --git a/resources/views/admin/logout.blade.php b/resources/views/admin/logout.blade.php deleted file mode 100644 index 6b8721f..0000000 --- a/resources/views/admin/logout.blade.php +++ /dev/null @@ -1,9 +0,0 @@ -@extends('admin.layout') - -@section('content') -
-

Вы вышли из системы

-

До скорой встречи!

- Войти снова -
-@endsection diff --git a/routes/api.php b/routes/api.php index 4979a7b..88b0236 100644 --- a/routes/api.php +++ b/routes/api.php @@ -17,8 +17,8 @@ Route::middleware('auth:sanctum')->group(function () { Route::delete('/hotels/{id}', [HotelController::class, 'destroy']); }); -Route::middleware('auth:sanctum')->group(function () { - Route::post('/bookings/{id}/invoice', [InvoiceController::class, 'generate']); +Route::get('/hotels/{hotel}/room-types', function ($hotelId) { + return \App\Models\RoomType::where('hotel_id', $hotelId)->get(['id', 'name']); }); Route::post('/admin/login', [AdminAuthController::class, 'login']); @@ -34,11 +34,6 @@ Route::middleware('auth:sanctum')->group(function () { Route::get('/user', function (\Illuminate\Http\Request $request) { return $request->user(); }); - - Route::get('/orders', [OrdersController::class, 'index']); - Route::post('/orders', [OrdersController::class, 'create']); - - Route::get('/room_types', [RoomTypesController::class, 'index']); }); Route::middleware('auth:sanctum')->group(function () { @@ -53,6 +48,10 @@ Route::middleware('auth:sanctum')->group(function () { Route::post('/room-types/{id}/availability/bulk', [RoomAvailabilityController::class, 'bulkUpdate']); }); +Route::middleware('auth:sanctum')->group(function () { + Route::post('/bookings/{id}/invoice', [InvoiceController::class, 'generate']); +}); + Route::middleware('auth:sanctum')->group(function () { Route::post('/bookings', [BookingController::class, 'store']); }); diff --git a/routes/web.php b/routes/web.php index 57522c0..54ea6df 100644 --- a/routes/web.php +++ b/routes/web.php @@ -4,34 +4,33 @@ use Illuminate\Support\Facades\Route; use App\Http\Controllers\Admin\HotelController; use App\Http\Controllers\Admin\AuthController; -Route::get('/admin/login', [AuthController::class, 'showLoginForm'])->name('admin.login.form'); -Route::post('/admin/login', [AuthController::class, 'login'])->name('admin.login'); +// Вход +Route::get('/admin/login', [\App\Http\Controllers\Admin\AuthController::class, 'showLoginForm'])->name('admin.login.form'); +Route::post('/admin/login', [\App\Http\Controllers\Admin\AuthController::class, 'login'])->name('admin.login'); +// Админка (требует авторизации) Route::middleware('auth')->prefix('admin')->group(function () { - Route::get('/hotels', [HotelController::class, 'index'])->name('admin.hotels.index'); - Route::get('/hotels/create', [HotelController::class, 'create'])->name('admin.hotels.create'); - Route::post('/hotels', [HotelController::class, 'store'])->name('admin.hotels.store'); - Route::get('/hotels/{hotel}/edit', [HotelController::class, 'edit'])->name('admin.hotels.edit'); - Route::put('/hotels/{hotel}', [HotelController::class, 'update'])->name('admin.hotels.update'); - Route::delete('/hotels/{hotel}', [HotelController::class, 'destroy'])->name('admin.hotels.destroy'); + // Отели + Route::get('/hotels', [\App\Http\Controllers\Admin\HotelController::class, 'index'])->name('admin.hotels.index'); + Route::get('/hotels/create', [\App\Http\Controllers\Admin\HotelController::class, 'create'])->name('admin.hotels.create'); + Route::post('/hotels', [\App\Http\Controllers\Admin\HotelController::class, 'store'])->name('admin.hotels.store'); + Route::get('/hotels/{hotel}/edit', [\App\Http\Controllers\Admin\HotelController::class, 'edit'])->name('admin.hotels.edit'); + Route::put('/hotels/{hotel}', [\App\Http\Controllers\Admin\HotelController::class, 'update'])->name('admin.hotels.update'); + Route::delete('/hotels/{hotel}', [\App\Http\Controllers\Admin\HotelController::class, 'destroy'])->name('admin.hotels.destroy'); + // Шахматка для отеля + Route::get('/hotels/{hotelId}/calendar', [\App\Http\Controllers\Admin\HotelController::class, 'calendar'])->name('admin.hotels.calendar'); + // Сохранение периода + Route::post('/room-types/{roomType}/availability', [\App\Http\Controllers\Admin\AvailabilityController::class, 'store'])->name('admin.availability.store'); + // Удаление периода + Route::delete('/availability/{availability}', [\App\Http\Controllers\Admin\AvailabilityController::class, 'destroy'])->name('admin.availability.destroy'); + // Бронирования + Route::get('/bookings/create', [\App\Http\Controllers\Admin\BookingController::class, 'create'])->name('admin.bookings.create'); + Route::post('/bookings', [\App\Http\Controllers\Admin\BookingController::class, 'store'])->name('admin.bookings.store'); - Route::post('/logout', [AuthController::class, 'logout'])->name('admin.logout'); + // Выход + Route::post('/logout', [\App\Http\Controllers\Admin\AuthController::class, 'logout'])->name('admin.logout'); }); -// → форма входа -Route::get('/admin/login', [AuthController::class, 'showLoginForm'])->name('admin.login.form'); -Route::post('/admin/login', [AuthController::class, 'login'])->name('admin.login'); - -// → админка -Route::middleware('auth')->prefix('admin')->group(function () { - Route::get('/hotels', [HotelController::class, 'index'])->name('admin.hotels.index'); - Route::post('/logout', [AuthController::class, 'logout'])->name('admin.logout'); -}); - -Route::get('/', function () { - return view('welcome'); -}); - -Route::get('/{any?}', function () { - return view('app'); -})->where('any', '.*'); +// Вход +Route::get('/admin/login', [\App\Http\Controllers\Admin\AuthController::class, 'showLoginForm'])->name('admin.login.form'); +Route::post('/admin/login', [\App\Http\Controllers\Admin\AuthController::class, 'login'])->name('admin.login'); \ No newline at end of file