diff --git a/.env.example b/.env.example index 1b5466fe..296fbba7 100644 --- a/.env.example +++ b/.env.example @@ -23,6 +23,7 @@ DB_LOWER_STRING_LENGTH=false BROADCAST_DRIVER=log CACHE_DRIVER=file +FILESYSTEM_DISK=local SESSION_DRIVER=file SESSION_LIFETIME=120 QUEUE_CONNECTION=sync @@ -91,3 +92,5 @@ IGNITION_EDITOR=vscode IGNITION_THEME=auto IGNITION_REMOTE_SITES_PATH= IGNITION_LOCAL_SITES_PATH= + +FILAMENT_FILESYSTEM_DRIVER=public diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 0652bdb0..0dd4afc8 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -29,6 +29,8 @@ protected function schedule(Schedule $schedule) $schedule->command('activitylog:clean')->daily(); + $schedule->command('model:prune'); + if (config('telescope.enabled')) { $schedule->command('telescope:prune')->daily(); } diff --git a/app/Events/FileCreated.php b/app/Events/FileCreated.php new file mode 100644 index 00000000..015cb333 --- /dev/null +++ b/app/Events/FileCreated.php @@ -0,0 +1,39 @@ + $record->icao, + 'IATA' => $record->iata, + ]; + } + + public static function form(Form $form): Form + { + return $form + ->schema([ + Forms\Components\TextInput::make('icao') + ->label('ICAO') + ->required() + ->unique() + ->maxLength(255), + Forms\Components\TextInput::make('iata') + ->label('IATA') + ->required() + ->unique() + ->maxLength(255), + Forms\Components\TextInput::make('name') + ->required() + ->maxLength(255), + Forms\Components\TextInput::make('latitude'), + Forms\Components\TextInput::make('longitude'), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('icao')->label('ICAO')->sortable(), + Tables\Columns\TextColumn::make('iata')->label('IATA')->sortable(), + Tables\Columns\TextColumn::make('name')->sortable(), + ]) + ->defaultSort('icao') + ->filters([ + // + ]) + ->pushHeaderActions([ + ButtonAction::make('delete-unused-airports') + ->action(function () { + Airport::whereDoesntHave('flightsDep') + ->whereDoesntHave('flightsArr') + ->whereDoesntHave('eventDep') + ->whereDoesntHave('eventArr') + ->delete(); + }) + ->requiresConfirmation() + ->color('danger') + ->icon('heroicon-o-trash') + ]); + } + + public static function getRelations(): array + { + return [ + RelationManagers\LinksRelationManager::class, + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListAirports::route('/'), + 'create' => Pages\CreateAirport::route('/create'), + 'edit' => Pages\EditAirport::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/AirportResource/Pages/CreateAirport.php b/app/Filament/Resources/AirportResource/Pages/CreateAirport.php new file mode 100644 index 00000000..416f41cc --- /dev/null +++ b/app/Filament/Resources/AirportResource/Pages/CreateAirport.php @@ -0,0 +1,11 @@ +schema([ + Forms\Components\Select::make('airportLinkType_id') + ->label('Type') + ->required() + ->options(AirportLinkType::all(['id', 'name'])->pluck('name', 'id')), + Forms\Components\TextInput::make('name') + ->helperText('If left empty, type will be used as name') + ->minLength(5) + ->maxLength(255), + Forms\Components\TextInput::make('url') + ->required() + ->url() + ->maxLength(255), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('type.name')->sortable(), + Tables\Columns\TextColumn::make('name')->sortable(), + Tables\Columns\TextColumn::make('url')->sortable(), + ]) + ->filters([ + // + ]); + } +} diff --git a/app/Filament/Resources/EventResource.php b/app/Filament/Resources/EventResource.php new file mode 100644 index 00000000..ce15e09f --- /dev/null +++ b/app/Filament/Resources/EventResource.php @@ -0,0 +1,130 @@ + $record->type->name, + 'Date' => $record->startEvent->format('M j, Y') + ]; + } + + protected static function getGlobalSearchEloquentQuery(): Builder + { + return parent::getGlobalSearchEloquentQuery() + ->orderBy('startEvent') + ->with(['type']); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('name'), + Tables\Columns\TextColumn::make('type.name'), + Tables\Columns\TextColumn::make('startEvent') + ->dateTime('M j, Y Hi\z')->sortable(), + ])->defaultSort('startEvent') + ->filters([ + Filter::make('active')->query(fn (Builder $query): Builder => $query->where('endEvent', '>', now()))->default(), + Filter::make('expired')->query(fn (Builder $query): Builder => $query->where('endEvent', '<', now())), + SelectFilter::make('event_type_id') + ->label('Type') + ->options(ModelsEventType::all(['id', 'name'])->pluck('name', 'id')), + ]) + ->prependActions([ + ButtonAction::make('import-bookings') + ->url(fn (Event $record): string => route('filament.resources.events.import-bookings', $record)) + ->icon('heroicon-o-upload') + ->visible(fn (Event $record): bool => auth()->user()->can('update', $record)), + ButtonAction::make('assign-routes') + ->url(fn (Event $record): string => route('filament.resources.events.assign-routes', $record)) + ->icon('heroicon-o-upload') + ->visible(fn (Event $record): bool => auth()->user()->can('update', $record) && $record->event_type_id == EventType::MULTIFLIGHTS()->value), + ButtonAction::make('send-email') + ->url(fn (Event $record): string => route('filament.resources.events.send-email', $record)) + ->icon('heroicon-o-mail'), + ButtonAction::make('export') + ->action(function (Event $record): BinaryFileResponse { + activity() + ->by(auth()->user()) + ->on($record) + ->log('Export triggered'); + + return (new BookingsExport($record, false))->download('bookings.csv'); + }) + ->icon('heroicon-o-download') + ->modalButton('Start export') + ->requiresConfirmation() + ->hidden(fn (Event $record): bool => $record->event_type_id == EventType::MULTIFLIGHTS()->value), + ButtonAction::make('export_multiflights') + ->label('Export') + ->action(function (Event $record, array $data): BinaryFileResponse { + activity() + ->by(auth()->user()) + ->on($record) + ->log('Export triggered'); + + return (new BookingsExport($record, $data['with_emails']))->download('bookings.csv'); + }) + ->icon('heroicon-o-download') + ->modalButton('Start export') + ->form([ + Toggle::make('with_emails') + ->default(false) + ]) + ->visible(fn (Event $record): bool => $record->event_type_id == EventType::MULTIFLIGHTS()->value), + ]); + } + + public static function getRelations(): array + { + return [ + RelationManagers\BookingsRelationManager::class, + RelationManagers\LinksRelationManager::class, + RelationManagers\FaqsRelationManager::class, + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListEvents::route('/'), + 'create' => Pages\CreateEvent::route('/create'), + 'view' => Pages\ViewEvent::route('/{record}'), + 'edit' => Pages\EditEvent::route('/{record}/edit'), + 'import-bookings' => Pages\ImportBookings::route('{record}/import-bookings'), + 'assign-routes' => Pages\AssignRoutes::route('{record}/assign-routes'), + 'send-email' => Pages\SendEmail::route('{record}/send-email') + ]; + } +} diff --git a/app/Filament/Resources/EventResource/Pages/AssignRoutes.php b/app/Filament/Resources/EventResource/Pages/AssignRoutes.php new file mode 100644 index 00000000..034485f4 --- /dev/null +++ b/app/Filament/Resources/EventResource/Pages/AssignRoutes.php @@ -0,0 +1,62 @@ +event = $record; + $this->form->fill(); + } + + protected function getFormSchema(): array + { + return [ + FileUpload::make('file') + ->helperText('Headers in **bold** are mandatory
**From** | **To** | **Route** | Notes') + ->required() + ->directory('imports') + ->visibility('private'), + ]; + } + + protected function getFormModel(): Model|string|null + { + return $this->event; + } + + public function submit(): void + { + activity() + ->by(auth()->user()) + ->on($this->event) + ->log('Import triggered'); + + $this->event->files()->create([ + 'path' => $this->form->getState()['file'], + 'disk' => config('filament.default_filesystem_disk'), + 'type' => FlightRouteAssign::class, + ]); + + $this->notify('success', 'Import triggered', true); + $this->redirectRoute('filament.resources.events.index'); + } +} diff --git a/app/Filament/Resources/EventResource/Pages/CreateEvent.php b/app/Filament/Resources/EventResource/Pages/CreateEvent.php new file mode 100644 index 00000000..c1031e9e --- /dev/null +++ b/app/Filament/Resources/EventResource/Pages/CreateEvent.php @@ -0,0 +1,11 @@ +event = $record; + $this->form->fill(); + } + + protected function getFormSchema(): array + { + $helperText = 'Headers in **bold** are mandatory
'; + switch ($this->event->event_type_id) { + case EventType::MULTIFLIGHTS()->value: + $helperText .= '**CTOT 1** - **Airport 1** - **CTOT 2** - **Airport 2** - **Airport 3**'; + break; + default: + $helperText .= 'Call Sign | **Origin** | **Destination** | CTOT | ETA | Aircraft Type | Route | Notes | Track | FL'; + } + return [ + FileUpload::make('file') + ->helperText($helperText) + ->required() + ->directory('imports') + ->visibility('private'), + ]; + } + + protected function getFormModel(): Model|string|null + { + return $this->event; + } + + public function submit(): void + { + activity() + ->by(auth()->user()) + ->on($this->event) + ->log('Import triggered'); + + $this->event->files()->create([ + 'path' => $this->form->getState()['file'], + 'disk' => config('filament.default_filesystem_disk'), + 'type' => BookingsImport::class, + ]); + + $this->notify('success', 'Import triggered', true); + $this->redirectRoute('filament.resources.events.index'); + } +} diff --git a/app/Filament/Resources/EventResource/Pages/ListEvents.php b/app/Filament/Resources/EventResource/Pages/ListEvents.php new file mode 100644 index 00000000..1c98cbcb --- /dev/null +++ b/app/Filament/Resources/EventResource/Pages/ListEvents.php @@ -0,0 +1,11 @@ +event = $record; + $this->finalInformationEmailForm->fill(); + $this->emailForm->fill(); + } + + protected function getFinalInformationEmailSchema(): array + { + return [ + Toggle::make('test_mode_final') + ->label('Test mode') + ->helperText('Send a random **Final Information E-mail** to yourself'), + Toggle::make('force_send') + ->helperText('Send to all particpants, even though they already received it (and no edit was made)'), + + ]; + } + + protected function getEmailSchema(): array + { + return [ + TextInput::make('subject') + ->prefix($this->event->name . ':'), + RichEditor::make('message') + ->helperText('Salutation and closing are already included') + ->disableToolbarButtons([ + 'attachFiles', + 'codeBlock', + ]), + Toggle::make('test_mode') + ->helperText('Send a random **E-mail** to yourself'), + ]; + } + + protected function getForms(): array + { + return [ + 'finalInformationEmailForm' => $this->makeForm() + ->schema($this->getFinalInformationEmailSchema()) + ->model($this->event), + 'emailForm' => $this->makeForm() + ->schema($this->getEmailSchema()) + ->model($this->event), + ]; + } + + public function sendFinalInformationEmail(): void + { + $state = $this->finalInformationEmailForm->getState(); + + $bookings = $this->event->bookings() + ->with(['user', 'flights']) + ->where('status', BookingStatus::BOOKED) + ->get(); + + if ($state['test_mode_final']) { + EventFinalInformation::dispatch($bookings->random(), auth()->user()); + $this->notify('primary', 'Email has been sent to yourself'); + return; + } + + $count = $bookings->count(); + $countSkipped = 0; + foreach ($bookings as $booking) { + if (!$booking->has_received_final_information_email || $state['force_send']) { + EventFinalInformation::dispatch($booking); + } else { + $count--; + $countSkipped++; + } + } + + $message = "Final Information has been sent to {$count} people!"; + if ($countSkipped != 0) { + $message .= " However, {$countSkipped} where skipped, because they already received one"; + } + + activity() + ->by(auth()->user()) + ->on($this->event) + ->withProperties([ + 'count' => $count, + 'countSkipped', $countSkipped + ]) + ->log('Final Information E-mail'); + + $this->notify('success', $message, true); + $this->redirectRoute('filament.resources.events.index'); + } + + public function sendEmail(): void + { + $state = $this->emailForm->getState(); + + if ($state['test_mode']) { + EventBulkEmail::dispatch($this->event, $state, collect([auth()->user()])); + $this->notify('primary', 'Email has been sent to yourself'); + return; + } + + $users = User::whereHas('bookings', function (Builder $query) { + $query->where('event_id', $this->event->id); + $query->where('status', BookingStatus::BOOKED); + })->get(); + + EventBulkEmail::dispatch($this->event, $state, $users); + $this->notify('success', "Bulk E-mail has been sent to {$users->count()} people!", true); + $this->redirectRoute('filament.resources.events.index'); + } +} diff --git a/app/Filament/Resources/EventResource/Pages/ViewEvent.php b/app/Filament/Resources/EventResource/Pages/ViewEvent.php new file mode 100644 index 00000000..9d8040f9 --- /dev/null +++ b/app/Filament/Resources/EventResource/Pages/ViewEvent.php @@ -0,0 +1,11 @@ +ownerRecord->event_type_id == EventType::MULTIFLIGHTS) { + return false; + } + + return parent::canCreate(); + } + + public static function form(Form $form): Form + { + return $form + ->schema([ + Forms\Components\Toggle::make('is_editable') + ->columnSpan('full') + ->label('Editable?') + ->helperText("Choose if you want the booking to be editable (Callsign and Aircraft Code only) by users. This is useful when using 'import only', but want to add extra slots") + ->required(), + Forms\Components\TextInput::make('callsign') + ->maxLength(7), + Forms\Components\TextInput::make('acType') + ->label('Aircraft code') + ->maxLength(4), + Forms\Components\HasManyRepeater::make('flights') + ->relationship('flights') + ->label(__('Flight')) + ->columnSpan('full') + ->columns(2) + ->disableItemCreation() + ->disableItemDeletion() + ->disableItemMovement() + ->schema([ + Forms\Components\Select::make('dep') + ->label('Departure airport') + ->required() + ->searchable() + ->getSearchResultsUsing(fn (string $query) => Airport::where('icao', 'like', "%{$query}%") + ->orWhere('iata', 'like', "%{$query}%")->orWhere('name', 'like', "%{$query}%") + ->limit(50)->get()->mapWithKeys(fn (Airport $airport) => [$airport->id => "$airport->icao | $airport->iata | $airport->name"])) + ->getOptionLabelUsing(function (?string $value) { + $airport = Airport::find($value); + return $airport ? "{$airport?->icao} | {$airport?->iata} | {$airport?->name}" : ''; + }), + Forms\Components\Select::make('arr') + ->label('Arrival airport') + ->required() + ->searchable() + ->getSearchResultsUsing(fn (string $query) => Airport::where('icao', 'like', "%{$query}%") + ->orWhere('iata', 'like', "%{$query}%")->orWhere('name', 'like', "%{$query}%") + ->limit(50)->get()->mapWithKeys(fn (Airport $airport) => [$airport->id => "$airport->icao | $airport->iata | $airport->name"])) + ->getOptionLabelUsing(function (?string $value) { + $airport = Airport::find($value); + return $airport ? "{$airport?->icao} | {$airport?->iata} | {$airport?->name}" : ''; + }), + Forms\Components\TimePicker::make('ctot')->label('CTOT (UTC)')->withoutSeconds(), + Forms\Components\TimePicker::make('eta')->label('ETA (UTC)')->withoutSeconds(), + Forms\Components\TextInput::make('oceanicFL') + ->label('Cruise FL') + ->prefix('FL') + ->numeric() + ->step(10) + ->minLength(0) + ->maxLength(660), + Forms\Components\Textarea::make('route')->columnSpan('full'), + Forms\Components\Textarea::make('notes')->columnSpan('full'), + ]) + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('firstFlight.ctot')->label('CTOT')->time('Hi\z'), + Tables\Columns\TextColumn::make('firstFlight.eta')->label('ETA')->time('Hi\z'), + Tables\Columns\TextColumn::make('firstFlight.airportDep.icao')->label('DEP'), + Tables\Columns\TextColumn::make('firstFlight.airportArr.icao')->label('ARR'), + Tables\Columns\TextColumn::make('callsign'), + Tables\Columns\TextColumn::make('acType')->label('Aircraft type'), + Tables\Columns\BadgeColumn::make('status') + ->enum([ + BookingStatus::UNASSIGNED()->value => 'Unassigned', + BookingStatus::RESERVED()->value => 'Reserved', + BookingStatus::BOOKED()->value => 'Booked', + ]) + ->colors([ + 'warning' => BookingStatus::RESERVED()->value, + 'success' => BookingStatus::BOOKED()->value, + ]), + Tables\Columns\TextColumn::make('user.pic')->label('PIC'), + ]) + ->filters([ + // + ]); + } +} diff --git a/app/Filament/Resources/EventResource/RelationManagers/FaqsRelationManager.php b/app/Filament/Resources/EventResource/RelationManagers/FaqsRelationManager.php new file mode 100644 index 00000000..3257dd76 --- /dev/null +++ b/app/Filament/Resources/EventResource/RelationManagers/FaqsRelationManager.php @@ -0,0 +1,45 @@ +columns(1) + ->schema([ + Forms\Components\Toggle::make('is_online') + ->label('Show online?') + ->default(true) + ->required(), + Forms\Components\TextInput::make('question') + ->required() + ->maxLength(255), + Forms\Components\RichEditor::make('answer') + ->required(), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('question'), + Tables\Columns\BooleanColumn::make('is_online')->label('Show online?'), + ]) + ->filters([ + // + ]); + } +} diff --git a/app/Filament/Resources/EventResource/RelationManagers/LinksRelationManager.php b/app/Filament/Resources/EventResource/RelationManagers/LinksRelationManager.php new file mode 100644 index 00000000..13bfb06a --- /dev/null +++ b/app/Filament/Resources/EventResource/RelationManagers/LinksRelationManager.php @@ -0,0 +1,48 @@ +schema([ + Forms\Components\Select::make('event_link_type_id') + ->label('Type') + ->required() + ->options(AirportLinkType::all(['id', 'name'])->pluck('name', 'id')), + Forms\Components\TextInput::make('name') + ->minLength(5) + ->maxLength(255), + Forms\Components\TextInput::make('url') + ->required() + ->url() + ->maxLength(255), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('type.name')->sortable(), + Tables\Columns\TextColumn::make('name')->sortable(), + Tables\Columns\TextColumn::make('url')->sortable(), + ]) + ->filters([ + // + ]); + } +} diff --git a/app/Filament/Resources/EventResource/Traits/EventForm.php b/app/Filament/Resources/EventResource/Traits/EventForm.php new file mode 100644 index 00000000..ccf5c462 --- /dev/null +++ b/app/Filament/Resources/EventResource/Traits/EventForm.php @@ -0,0 +1,106 @@ +schema([ + Toggle::make('is_online') + ->label('Show online?') + ->default(true) + ->helperText("Choose here if you want the event to be reachable by it's generated url") + ->required(), + Toggle::make('show_on_homepage') + ->label('Show on homepage?') + ->default(true) + ->helperText("Choose here if you want to show the event on the homepage. If turned off, the event can only be reached by the url. NOTE: If 'Show Online' is off, the event won't be shown at all") + ->required(), + Toggle::make('import_only') + ->label('Only import?') + ->helperText('If enabled, only admins can fill in details via import script') + ->required(), + Toggle::make('uses_times') + ->label('Show times?') + ->helperText('If enabled, CTOT and ETA (if set in booking) will be shown') + ->required(), + Toggle::make('multiple_bookings_allowed') + ->label('Multiple bookings allowed?') + ->helperText('If enabled, a user is allowed to book multiple flights for this event') + ->required(), + Toggle::make('is_oceanic_event') + ->label('Oceanic event?') + ->helperText('If enabled, users can fill in a SELCAL code') + ->required(), + TextInput::make('name') + ->required() + ->maxLength(255), + Select::make('event_type_id') + ->label('Event type') + ->options(EventType::all(['id', 'name'])->pluck('name', 'id')) + ->required(), + Select::make('dep') + ->label('Departure airport') + ->required() + ->searchable() + ->getSearchResultsUsing(fn (string $query) => Airport::where('icao', 'like', "%{$query}%") + ->orWhere('iata', 'like', "%{$query}%")->orWhere('name', 'like', "%{$query}%") + ->limit(50)->get()->mapWithKeys(fn (Airport $airport) => [$airport->id => "$airport->icao | $airport->iata | $airport->name"])) + ->getOptionLabelUsing(function (?string $value) { + $airport = Airport::find($value); + return $airport ? "{$airport?->icao} | {$airport?->iata} | {$airport?->name}" : ''; + }), + Select::make('arr') + ->label('Arrival airport') + ->required() + ->searchable() + ->getSearchResultsUsing(fn (string $query) => Airport::where('icao', 'like', "%{$query}%") + ->orWhere('iata', 'like', "%{$query}%")->orWhere('name', 'like', "%{$query}%") + ->limit(50)->get()->mapWithKeys(fn (Airport $airport) => [$airport->id => "$airport->icao | $airport->iata | $airport->name"])) + ->getOptionLabelUsing(function (?string $value) { + $airport = Airport::find($value); + return $airport ? "{$airport?->icao} | {$airport?->iata} | {$airport?->name}" : ''; + }), + DateTimePicker::make('startEvent') + ->label('Start event (UTC)') + ->default(now()->addDay()->startOfHour()) + ->withoutSeconds() + ->required(), + DateTimePicker::make('endEvent') + ->label('End event (UTC)') + ->default(now()->addDay()->addHours(4)->startOfHour()) + ->withoutSeconds() + ->required() + ->after('startEvent'), + DateTimePicker::make('startBooking') + ->label('Start booking (UTC)') + ->default(now()->startOfHour()) + ->withoutSeconds() + ->required(), + DateTimePicker::make('endBooking') + ->label('End booking (UTC)') + ->default(now()->addDay()->addHours(4)->startOfHour()) + ->withoutSeconds() + ->required() + ->after('startBooking') + ->beforeOrEqual('endEvent'), + TextInput::make('image_url') + ->label('Image URL') + ->maxLength(255) + ->url(), + RichEditor::make('description') + ->columnSpan('full'), + ]); + } +} diff --git a/app/Filament/Resources/FaqResource.php b/app/Filament/Resources/FaqResource.php new file mode 100644 index 00000000..7420f36f --- /dev/null +++ b/app/Filament/Resources/FaqResource.php @@ -0,0 +1,65 @@ +columns(1) + ->schema([ + Forms\Components\Toggle::make('is_online') + ->label('Show online?') + ->default(true) + ->required(), + Forms\Components\TextInput::make('question') + ->required() + ->maxLength(255), + Forms\Components\RichEditor::make('answer') + ->required(), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('question'), + Tables\Columns\BooleanColumn::make('is_online')->label('Show online?'), + Tables\Columns\BooleanColumn::make('events_count')->label('Linked to event(s)?')->counts('events'), + ]) + ->filters([ + // + ]); + } + + public static function getRelations(): array + { + return [ + RelationManagers\EventsRelationManager::class, + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListFaqs::route('/'), + 'create' => Pages\CreateFaq::route('/create'), + 'edit' => Pages\EditFaq::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/FaqResource/Pages/CreateFaq.php b/app/Filament/Resources/FaqResource/Pages/CreateFaq.php new file mode 100644 index 00000000..ef41d093 --- /dev/null +++ b/app/Filament/Resources/FaqResource/Pages/CreateFaq.php @@ -0,0 +1,11 @@ +schema([ + Select::make('recordId') + ->label('Event') + ->options(Event::where('endEvent', '>', now()) + ->orderBy('startEvent')->get()->mapWithKeys(fn (Event $event) => [$event->id => $event->name_date])) + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('nameDate')->label('Name') + ]) + ->filters([ + // + ]); + } +} diff --git a/app/Http/Controllers/Airport/AirportAdminController.php b/app/Http/Controllers/Airport/AirportAdminController.php deleted file mode 100644 index 93883bee..00000000 --- a/app/Http/Controllers/Airport/AirportAdminController.php +++ /dev/null @@ -1,88 +0,0 @@ -authorizeResource(AirportPolicy::class, 'airport'); - } - - public function index(): View - { - $airports = Airport::with(['flightsDep', 'flightsArr', 'eventDep', 'eventArr']) - ->paginate(100); - return view('airport.admin.overview', compact('airports')); - } - - public function create(): View - { - return view('airport.admin.form', ['airport' => new Airport()]); - } - - public function store(StoreAirport $request): RedirectResponse - { - $airport = Airport::create($request->validated()); - flashMessage('success', __('Done'), __(':airport has been added!', ['airport' => "$airport->name [$airport->icao | $airport->iata]"])); - return to_route('admin.airports.index'); - } - - public function show(Airport $airport): View - { - return view('airport.admin.show', compact('airport')); - } - - public function edit(Airport $airport): View - { - return view('airport.admin.form', compact('airport')); - } - - public function update(UpdateAirport $request, Airport $airport): RedirectResponse - { - $airport->update($request->validated()); - flashMessage('success', __('Done'), __(':airport has been updated!', ['airport' => "$airport->name [$airport->icao | $airport->iata]"])); - - return to_route('admin.airports.index'); - } - - public function destroy(Airport $airport): RedirectResponse - { - if ($airport->flightsDep->isEmpty() && $airport->flightsArr->isEmpty()) { - $airport->delete(); - flashMessage('success', __('Done'), __(':airport has been deleted!', ['airport' => "$airport->name [$airport->icao | $airport->iata]"])); - - return redirect()->back(); - } else { - flashMessage( - 'danger', - __('Warning'), - __(':airport could not be deleted! It\'s linked to another event', ['airport' => "$airport->name [$airport->icao | $airport->iata]"]) - ); - return redirect()->back(); - } - } - - public function destroyUnused() - { - $this->authorize('destroy', Airport::class); - Airport::whereDoesntHave('flightsDep') - ->whereDoesntHave('flightsArr') - ->whereDoesntHave('eventDep') - ->whereDoesntHave('eventArr') - ->delete(); - - flashMessage('success', __('Done'), __('Unused airport have been deleted!')); - - return to_route('admin.airports.index'); - } -} diff --git a/app/Http/Controllers/AirportLink/AirportLinkAdminController.php b/app/Http/Controllers/AirportLink/AirportLinkAdminController.php deleted file mode 100644 index 5dbfb6e5..00000000 --- a/app/Http/Controllers/AirportLink/AirportLinkAdminController.php +++ /dev/null @@ -1,73 +0,0 @@ -authorizeResource(AirportLinkPolicy::class, 'airportLink'); - } - - public function index(): View - { - $airportLinks = AirportLink::orderBy('airport_id', 'asc') - ->with(['airport', 'type']) - ->paginate(); - return view('airportLink.admin.overview', compact('airportLinks')); - } - - public function create(): View - { - $airportLink = new AirportLink(); - $airportLinkTypes = AirportLinkType::all(['id', 'name'])->pluck('name', 'id'); - $airports = Airport::all(['id', 'icao', 'iata', 'name'])->keyBy('id') - ->map(function ($airport) { - /** @var Airport $airport */ - return "$airport->icao | $airport->name | $airport->iata"; - }); - return view('airportLink.admin.form', compact('airportLink', 'airportLinkTypes', 'airports')); - } - - public function store(StoreAirportLink $request): RedirectResponse - { - $airportLink = AirportLink::create($request->validated()); - flashMessage( - 'success', - __('Done'), - __(':Type item has been added for :airport', ['Type' => $airportLink->type->name, 'airport' => "{$airportLink->airport->name} [{$airportLink->airport->icao} | {$airportLink->airport->iata}]"]) - ); - return to_route('admin.airports.index'); - } - - public function edit(AirportLink $airportLink): View - { - $airportLinkTypes = AirportLinkType::all(['id', 'name'])->pluck('name', 'id'); - - return view('airportLink.admin.form', compact('airportLink', 'airportLinkTypes')); - } - - public function update(UpdateAirportLink $request, AirportLink $airportLink): RedirectResponse - { - $airportLink->update($request->validated()); - flashMessage('success', __('Done'), __('Airport Link has been updated')); - return to_route('admin.airportLinks.index'); - } - - public function destroy(AirportLink $airportLink): RedirectResponse - { - $airportLink->delete(); - flashMessage('success', __('Airport link deleted'), __('Airport link has been deleted')); - return back(); - } -} diff --git a/app/Http/Controllers/Booking/BookingAdminController.php b/app/Http/Controllers/Booking/BookingAdminController.php index 86a10edb..c824d9fb 100644 --- a/app/Http/Controllers/Booking/BookingAdminController.php +++ b/app/Http/Controllers/Booking/BookingAdminController.php @@ -23,7 +23,6 @@ use App\Http\Requests\Booking\Admin\RouteAssign; use App\Http\Requests\Booking\Admin\StoreBooking; use App\Http\Requests\Booking\Admin\UpdateBooking; -use App\Http\Requests\Booking\Admin\ImportBookings; use Symfony\Component\HttpFoundation\BinaryFileResponse; class BookingAdminController extends AdminController @@ -221,34 +220,6 @@ public function destroy(Booking $booking): RedirectResponse return back(); } - public function export(Event $event, Request $request): BinaryFileResponse - { - activity() - ->by(auth()->user()) - ->on($event) - ->log('Export triggered'); - - return (new BookingsExport($event, $request->vacc))->download('bookings.csv'); - } - - public function importForm(Event $event) - { - return view('event.admin.import', compact('event')); - } - - public function import(ImportBookings $request, Event $event): RedirectResponse - { - activity() - ->by(auth()->user()) - ->on($event) - ->log('Import triggered'); - $file = $request->file('file'); - (new BookingsImport($event))->import($file); - Storage::delete($file->getRealPath()); - flashMessage('success', __('Flights imported'), __('Flights have been imported')); - return to_route('bookings.event.index', $event); - } - public function adminAutoAssignForm(Event $event): View { return view('event.admin.autoAssign', compact('event')); diff --git a/app/Http/Controllers/Event/EventAdminController.php b/app/Http/Controllers/Event/EventAdminController.php deleted file mode 100644 index c7739706..00000000 --- a/app/Http/Controllers/Event/EventAdminController.php +++ /dev/null @@ -1,208 +0,0 @@ -authorizeResource(EventPolicy::class, 'event'); - } - - public function index(): View - { - $events = Event::orderByDesc('startEvent') - ->with('type') - ->paginate(); - return view('event.admin.overview', compact('events')); - } - - public function create(): View - { - $event = new Event(); - $airports = Airport::all(['id', 'icao', 'iata', 'name'])->keyBy('id') - ->map(function ($airport) { - /** @var Airport $airport */ - return "$airport->icao | $airport->name | $airport->iata"; - }); - $eventTypes = EventType::all()->pluck('name', 'id'); - return view('event.admin.form', compact('event', 'airports', 'eventTypes')); - } - - public function store(StoreEvent $request): RedirectResponse - { - $event = new Event(); - $event->fill($request->only( - 'is_online', - 'show_on_homepage', - 'name', - 'event_type_id', - 'import_only', - 'uses_times', - 'multiple_bookings_allowed', - 'is_oceanic_event', - 'dep', - 'arr', - 'image_url', - 'description' - )); - $event->fill([ - 'startEvent' => $request->date('startEvent'), - 'endEvent' => $request->date('endEvent'), - 'startBooking' => $request->date('startBooking'), - 'endBooking' => $request->date('endBooking'), - ])->save(); - - flashMessage('success', __('Done'), __('Event has been created!')); - return to_route('admin.events.index'); - } - - public function show(Event $event): View - { - return view('event.admin.show', compact('event')); - } - - public function edit(Event $event): View - { - $airports = Airport::all(['id', 'icao', 'iata', 'name'])->keyBy('id') - ->map(function ($airport) { - /** @var Airport $airport */ - return "$airport->icao | $airport->name | $airport->iata"; - }); - $eventTypes = EventType::all()->pluck('name', 'id'); - return view('event.admin.form', compact('event', 'airports', 'eventTypes')); - } - - public function update(UpdateEvent $request, Event $event): RedirectResponse - { - $event->fill($request->only( - 'is_online', - 'show_on_homepage', - 'name', - 'event_type_id', - 'import_only', - 'uses_times', - 'multiple_bookings_allowed', - 'is_oceanic_event', - 'dep', - 'arr', - 'image_url', - 'description' - )); - $event->fill([ - 'startEvent' => $request->date('startEvent'), - 'endEvent' => $request->date('endEvent'), - 'startBooking' => $request->date('startBooking'), - 'endBooking' => $request->date('endBooking'), - ])->save(); - flashMessage('success', __('Done'), __('Event has been updated!')); - return to_route('admin.events.index'); - } - - public function destroy(Event $event): RedirectResponse - { - if ($event->startEvent > now()) { - $event->delete(); - flashMessage('success', __('Done'), __(':event has been deleted!', ['event' => $event->name])); - return redirect()->back(); - } else { - flashMessage('danger', __('Danger'), __('Event can no longer be deleted!')); - return redirect()->back(); - } - } - - public function sendEmailForm(Event $event): View - { - return view('event.admin.sendEmail', compact('event')); - } - - public function sendEmail(SendEmail $request, Event $event): JsonResponse|RedirectResponse - { - if ($request->testmode) { - event(new EventBulkEmail($event, $request->all(), collect([auth()->user()]))); - return response()->json(['success' => __('Email has been sent to yourself')]); - } else { - /* @var User $users */ - $users = User::whereHas('bookings', function (Builder $query) use ($event) { - $query->where('event_id', $event->id); - $query->where('status', BookingStatus::BOOKED); - })->get(); - event(new EventBulkEmail($event, $request->all(), $users)); - flashMessage('success', __('Done'), __('Bulk E-mail has been sent to :count people!', ['count' => $users->count()])); - return to_route('admin.events.index'); - } - } - - public function sendFinalInformationMail(Request $request, Event $event): RedirectResponse|JsonResponse - { - $bookings = $event->bookings() - ->with(['user', 'flights']) - ->where('status', BookingStatus::BOOKED) - ->get(); - - if ($request->testmode) { - event(new EventFinalInformation($bookings->random(), $request->user())); - - return response()->json(['success' => __('Email has been sent to yourself')]); - } else { - $count = $bookings->count(); - $countSkipped = 0; - foreach ($bookings as $booking) { - if (!$booking->has_received_final_information_email || $request->forceSend) { - event(new EventFinalInformation($booking)); - } else { - $count--; - $countSkipped++; - } - } - $message = __('Final Information has been sent to :count people!', ['count' => $count]); - if ($countSkipped != 0) { - $message .= ' ' . __('However, :count where skipped, because they already received one', ['count' => $count]); - } - flashMessage('success', __('Done'), $message); - activity() - ->by(auth()->user()) - ->on($event) - ->withProperty('count', $count) - ->log('Final Information E-mail'); - } - - return to_route('admin.events.index'); - } - - public function deleteAllBookings(Request $request, Event $event): RedirectResponse - { - activity() - ->by(auth()->user()) - ->on($event) - ->log('Delete all bookings'); - - if ($event->endEvent <= now()) { - flashMessage('danger', __('Danger'), __('Booking can no longer be deleted')); - return back(); - } - - $event->bookings()->delete(); - flashMessage('success', __('Bookings deleted'), __('All bookings have been deleted')); - return to_route('admin.events.index'); - } -} diff --git a/app/Http/Controllers/EventLink/EventLinkAdminController.php b/app/Http/Controllers/EventLink/EventLinkAdminController.php deleted file mode 100644 index cc914418..00000000 --- a/app/Http/Controllers/EventLink/EventLinkAdminController.php +++ /dev/null @@ -1,75 +0,0 @@ -authorizeResource(EventLinkPolicy::class, 'eventLink'); - } - - public function index(): View - { - $eventLinks = EventLink::orderBy('event_id', 'asc') - ->with(['event', 'type']) - ->paginate(); - return view('eventLink.admin.overview', compact('eventLinks')); - } - - public function create(Event $event): View - { - $eventLink = new EventLink(); - $eventLinkTypes = AirportLinkType::all(['id', 'name'])->pluck('name', 'id'); - $events = Event::where('endEvent', '>', now()) - ->orderBy('startEvent') - ->get(['id', 'name', 'startEvent']) - ->keyBy('id') - ->map(function ($event) { - /** @var Event $event */ - return "$event->name [{$event->startEvent->format('d-m-Y')}]"; - }); - return view('eventLink.admin.form', compact('eventLink', 'eventLinkTypes', 'events')); - } - - public function store(StoreEventLink $request): RedirectResponse - { - $eventLink = EventLink::create($request->validated()); - flashMessage( - 'success', - __('Done'), - __(':Type item has been added for :event', ['Type' => $eventLink->type->name, 'event' => $eventLink->event->name]) - ); - return to_route('admin.eventLinks.index'); - } - - public function edit(EventLink $eventLink): View - { - $eventLinkTypes = AirportLinkType::all(['id', 'name'])->pluck('name', 'id'); - return view('eventLink.admin.form', compact('eventLink', 'eventLinkTypes')); - } - - public function update(UpdateEventLink $request, EventLink $eventLink): RedirectResponse - { - $eventLink->update($request->validated()); - flashMessage('success', __('Done'), __('Link has been updated')); - return to_route('admin.eventLinks.index'); - } - - public function destroy(EventLink $eventLink): RedirectResponse - { - $eventLink->delete(); - flashMessage('success', __('Event link deleted'), __('Event link has been deleted')); - return back(); - } -} diff --git a/app/Http/Controllers/Faq/FaqAdminController.php b/app/Http/Controllers/Faq/FaqAdminController.php deleted file mode 100644 index b91324be..00000000 --- a/app/Http/Controllers/Faq/FaqAdminController.php +++ /dev/null @@ -1,74 +0,0 @@ -authorizeResource(FaqPolicy::class, 'faq'); - } - - public function index(): View - { - $faqs = Faq::withCount('events')->paginate(); - return view('faq.admin.overview', compact('faqs')); - } - - public function create(): View - { - $faq = new Faq(); - return view('faq.admin.form', compact('faq')); - } - - public function store(StoreFaq $request): RedirectResponse - { - $faq = Faq::create($request->validated()); - flashMessage('success', __('Done'), __('FAQ has been added!')); - return to_route('admin.faq.edit', $faq); - } - - public function edit(Faq $faq): View - { - $events = Event::where('endEvent', '>', now()) - ->orderBy('startEvent', 'desc') - ->get(); - - return view('faq.admin.form', compact('faq', 'events')); - } - - public function update(UpdateFaq $request, Faq $faq): RedirectResponse - { - $faq->update($request->validated()); - flashMessage('success', __('Done'), __('FAQ has been updated!')); - return to_route('admin.faq.edit', $faq); - } - - public function destroy(Faq $faq): RedirectResponse - { - $faq->delete(); - flashMessage('success', __('Done'), 'Question has been removed!'); - return to_route(route('admin.faq.index')); - } - - public function toggleEvent(Faq $faq, Event $event): RedirectResponse - { - if ($faq->events()->where('event_id', $event->id)->first()) { - $faq->events()->detach($event->id); - flashMessage('success', __('Event unlinked'), __('Event has been unlinked to this FAQ')); - } else { - $faq->events()->attach($event->id); - flashMessage('success', __('Event linked'), __('Event has been linked to this FAQ')); - } - return back(); - } -} diff --git a/app/Http/Requests/Airport/Admin/StoreAirport.php b/app/Http/Requests/Airport/Admin/StoreAirport.php deleted file mode 100644 index 986dd985..00000000 --- a/app/Http/Requests/Airport/Admin/StoreAirport.php +++ /dev/null @@ -1,40 +0,0 @@ - 'required:string|unique:airports|size:4', - 'iata' => 'required:string|unique:airports,iata|size:3', - 'name' => 'required:string', - 'latitude' => ['required', 'regex:/^[-]?((([0-8]?[0-9])(\.(\d{1,10}))?)|(90(\.0+)?))$/'], - 'longitude' => ['required', 'regex:/^[-]?((((1[0-7][0-9])|([0-9]?[0-9]))(\.(\d{1,10}))?)|180(\.0+)?)/'], - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'icao' => __('ICAO'), - 'iata' => __('IATA'), - 'name' => __('Name'), - 'latitude' => __('Latitude'), - 'longitude' => __('Longitude'), - ]; - } -} diff --git a/app/Http/Requests/Airport/Admin/UpdateAirport.php b/app/Http/Requests/Airport/Admin/UpdateAirport.php deleted file mode 100644 index de0ce63e..00000000 --- a/app/Http/Requests/Airport/Admin/UpdateAirport.php +++ /dev/null @@ -1,40 +0,0 @@ - 'required:string|between:4,4', - 'iata' => 'required:string|between:3,3', - 'name' => 'required:string', - 'latitude' => ['required', 'regex:/^[-]?((([0-8]?[0-9])(\.(\d{1,10}))?)|(90(\.0+)?))$/'], - 'longitude' => ['required', 'regex:/^[-]?((((1[0-7][0-9])|([0-9]?[0-9]))(\.(\d{1,10}))?)|180(\.0+)?)/'], - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'icao' => __('ICAO'), - 'iata' => __('IATA'), - 'name' => __('Name'), - 'latitude' => __('Latitude'), - 'longitude' => __('Longitude'), - ]; - } -} diff --git a/app/Http/Requests/AirportLink/Admin/StoreAirportLink.php b/app/Http/Requests/AirportLink/Admin/StoreAirportLink.php deleted file mode 100644 index f398b1c9..00000000 --- a/app/Http/Requests/AirportLink/Admin/StoreAirportLink.php +++ /dev/null @@ -1,38 +0,0 @@ - 'required|exists:airport_link_types,id', - 'airport_id' => 'required|exists:airports,id', - 'name' => 'nullable|string', - 'url' => 'required|url', - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'airportLinkType_id' => __('Type'), - 'airport_id' => __('Airport'), - 'name' => __('Name'), - 'url' => __('URL'), - ]; - } -} diff --git a/app/Http/Requests/AirportLink/Admin/UpdateAirportLink.php b/app/Http/Requests/AirportLink/Admin/UpdateAirportLink.php deleted file mode 100644 index 00fb647c..00000000 --- a/app/Http/Requests/AirportLink/Admin/UpdateAirportLink.php +++ /dev/null @@ -1,36 +0,0 @@ - 'required|exists:airport_link_types,id', - 'name' => 'nullable|string', - 'url' => 'required|url', - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'airportLinkType_id' => __('Type'), - 'name' => __('Name'), - 'url' => __('URL'), - ]; - } -} diff --git a/app/Http/Requests/Event/Admin/SendEmail.php b/app/Http/Requests/Event/Admin/SendEmail.php deleted file mode 100644 index 53ff145f..00000000 --- a/app/Http/Requests/Event/Admin/SendEmail.php +++ /dev/null @@ -1,36 +0,0 @@ - 'bail|required:string', - 'message' => 'required:string', - 'testmode' => 'boolean' - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'subject' => __('Subject'), - 'message' => __('Message'), - 'testmode' => __('Test mode'), - ]; - } -} diff --git a/app/Http/Requests/Event/Admin/StoreEvent.php b/app/Http/Requests/Event/Admin/StoreEvent.php deleted file mode 100644 index 0e261783..00000000 --- a/app/Http/Requests/Event/Admin/StoreEvent.php +++ /dev/null @@ -1,62 +0,0 @@ - 'required|boolean', - 'show_on_homepage' => 'required|boolean', - 'name' => 'bail|required:string', - 'event_type_id' => 'exists:event_types,id|required', - 'import_only' => 'required|boolean', - 'uses_times' => 'required|boolean', - 'multiple_bookings_allowed' => 'required|boolean', - 'is_oceanic_event' => 'required|boolean', - 'dep' => 'exists:airports,id|required', - 'arr' => 'exists:airports,id|required', - 'startEvent' => 'required|date', - 'endEvent' => 'required|date|after_or_equal:startEvent', - 'startBooking' => 'required|date', - 'endBooking' => 'required|date|after_or_equal:startBooking', - 'image_url' => 'nullable|url', - 'description' => 'required:string', - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'is_online' => __('Show online?'), - 'show_on_homepage' => __('Show on homepage?'), - 'name' => __('Name'), - 'event_type_id' => __('Event type'), - 'import_only' => __('Only import?'), - 'uses_times' => __('Show times?'), - 'multiple_bookings_allowed' => __('Multiple bookings allowed?'), - 'is_oceanic_event' => __('Oceanic event?'), - 'dep' => __('Departure airport'), - 'arr' => __('Arrival airport'), - 'startEvent' => __('Start event'), - 'endEvent' => __('End event'), - 'startBooking' => __('Start booking'), - 'endBooking' => __('End booking'), - 'image_url' => __('Image URL'), - 'description' => __('Description'), - ]; - } -} diff --git a/app/Http/Requests/Event/Admin/UpdateEvent.php b/app/Http/Requests/Event/Admin/UpdateEvent.php deleted file mode 100644 index 536aec78..00000000 --- a/app/Http/Requests/Event/Admin/UpdateEvent.php +++ /dev/null @@ -1,62 +0,0 @@ - 'required|boolean', - 'show_on_homepage' => 'required|boolean', - 'name' => 'bail|required:string', - 'event_type_id' => 'exists:event_types,id|required', - 'import_only' => 'required|boolean', - 'uses_times' => 'required|boolean', - 'multiple_bookings_allowed' => 'required|boolean', - 'is_oceanic_event' => 'required|boolean', - 'dep' => 'exists:airports,id|required', - 'arr' => 'exists:airports,id|required', - 'startEvent' => 'required|date', - 'endEvent' => 'required|date|after_or_equal:startEvent', - 'startBooking' => 'required|date', - 'endBooking' => 'required|date|after_or_equal:startBooking', - 'image_url' => 'nullable|url', - 'description' => 'required:string', - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'is_online' => __('Show online?'), - 'show_on_homepage' => __('Show on homepage?'), - 'name' => __('Name'), - 'event_type_id' => __('Event type'), - 'import_only' => __('Only import?'), - 'uses_times' => __('Show times?'), - 'multiple_bookings_allowed' => __('Multiple bookings allowed?'), - 'is_oceanic_event' => __('Oceanic event?'), - 'dep' => __('Departure airport'), - 'arr' => __('Arrival airport'), - 'startEvent' => __('Start event'), - 'endEvent' => __('End event'), - 'startBooking' => __('Start booking'), - 'endBooking' => __('End booking'), - 'image_url' => __('Image URL'), - 'description' => __('Description'), - ]; - } -} diff --git a/app/Http/Requests/EventLink/Admin/StoreEventLink.php b/app/Http/Requests/EventLink/Admin/StoreEventLink.php deleted file mode 100644 index 8adf251a..00000000 --- a/app/Http/Requests/EventLink/Admin/StoreEventLink.php +++ /dev/null @@ -1,38 +0,0 @@ - 'required|exists:airport_link_types,id', - 'event_id' => 'required|exists:events,id', - 'name' => 'nullable|string', - 'url' => 'required|url', - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'event_link_type_id' => __('Type'), - 'event_id' => __('Event'), - 'name' => __('Name'), - 'url' => __('URL'), - ]; - } -} diff --git a/app/Http/Requests/EventLink/Admin/UpdateEventLink.php b/app/Http/Requests/EventLink/Admin/UpdateEventLink.php deleted file mode 100644 index 8bcfd0d6..00000000 --- a/app/Http/Requests/EventLink/Admin/UpdateEventLink.php +++ /dev/null @@ -1,36 +0,0 @@ - 'required|exists:airport_link_types,id', - 'name' => 'nullable|string', - 'url' => 'required|url', - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'event_link_type_id' => __('Type'), - 'name' => __('Name'), - 'url' => __('URL'), - ]; - } -} diff --git a/app/Http/Requests/Faq/Admin/StoreFaq.php b/app/Http/Requests/Faq/Admin/StoreFaq.php deleted file mode 100644 index 16eda1da..00000000 --- a/app/Http/Requests/Faq/Admin/StoreFaq.php +++ /dev/null @@ -1,36 +0,0 @@ - 'required:boolean', - 'question' => 'required:string', - 'answer' => 'required:string' - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'is_online' => __('Is online'), - 'question' => __('Question'), - 'answer' => __('Answer'), - ]; - } -} diff --git a/app/Http/Requests/Faq/Admin/UpdateFaq.php b/app/Http/Requests/Faq/Admin/UpdateFaq.php deleted file mode 100644 index 24e81276..00000000 --- a/app/Http/Requests/Faq/Admin/UpdateFaq.php +++ /dev/null @@ -1,36 +0,0 @@ - 'required:boolean', - 'question' => 'required:string', - 'answer' => 'required:string' - ]; - } - - /** - * Get custom attributes for validator errors. - * - * @return array - */ - public function attributes() - { - return [ - 'is_online' => __('Is online'), - 'question' => __('Question'), - 'answer' => __('Answer'), - ]; - } -} diff --git a/app/Imports/BookingsImport.php b/app/Imports/BookingsImport.php index 7b703e74..562460fd 100644 --- a/app/Imports/BookingsImport.php +++ b/app/Imports/BookingsImport.php @@ -6,15 +6,17 @@ use App\Models\Event; use App\Models\Airport; use App\Models\Booking; +use Illuminate\Contracts\Queue\ShouldQueue; use Maatwebsite\Excel\Concerns\ToModel; use PhpOffice\PhpSpreadsheet\Shared\Date; use Maatwebsite\Excel\Concerns\Importable; +use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\WithHeadingRow; use Maatwebsite\Excel\Concerns\WithValidation; use Maatwebsite\Excel\Concerns\WithBatchInserts; use Maatwebsite\Excel\Concerns\WithChunkReading; -class BookingsImport implements ToModel, WithHeadingRow, WithBatchInserts, WithChunkReading, WithValidation +class BookingsImport implements ToModel, WithHeadingRow, WithBatchInserts, WithChunkReading, WithValidation, ShouldQueue, SkipsEmptyRows { use Importable; @@ -97,17 +99,17 @@ public function rules(): array ]; } return [ - 'origin' => 'exists:airports,icao', - 'destination' => 'exists:airports,icao', - 'track' => 'sometimes|nullable', - 'oceanicFL' => 'sometimes|nullable|integer:3', - 'aircraft_type' => 'sometimes|nullable|max:4', + 'origin' => ['exists:airports,icao'], + 'destination' => ['exists:airports,icao'], + 'track' => ['sometimes', 'nullable'], + 'oceanicFL' => ['sometimes', 'nullable', 'integer:3'], + 'aircraft_type' => ['sometimes', 'nullable', 'max:4'], ]; } private function getAirport($icao): int { - return Airport::whereIcao($icao)->first()->id; + return Airport::whereIcao(strtoupper($icao))->first()->id; } private function getTime($time) diff --git a/app/Imports/FlightRouteAssign.php b/app/Imports/FlightRouteAssign.php index 09e14f06..55981eae 100644 --- a/app/Imports/FlightRouteAssign.php +++ b/app/Imports/FlightRouteAssign.php @@ -6,11 +6,15 @@ use App\Models\Airport; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\Importable; +use Illuminate\Contracts\Queue\ShouldQueue; use Maatwebsite\Excel\Concerns\ToCollection; +use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\WithHeadingRow; use Maatwebsite\Excel\Concerns\WithValidation; +use Maatwebsite\Excel\Concerns\WithBatchInserts; +use Maatwebsite\Excel\Concerns\WithChunkReading; -class FlightRouteAssign implements ToCollection, WithHeadingRow, WithValidation +class FlightRouteAssign implements ToCollection, WithHeadingRow, WithBatchInserts, WithChunkReading, WithValidation, ShouldQueue, SkipsEmptyRows { use Importable; @@ -28,6 +32,16 @@ public function collection(Collection $rows) } } + public function batchSize(): int + { + return 250; + } + + public function chunkSize(): int + { + return 250; + } + public function rules(): array { return [ diff --git a/app/Listeners/AssignRoutes.php b/app/Listeners/AssignRoutes.php new file mode 100644 index 00000000..018e18d8 --- /dev/null +++ b/app/Listeners/AssignRoutes.php @@ -0,0 +1,39 @@ +file->type != FlightRouteAssign::class) { + return; + } + + (new FlightRouteAssign($event->file->fileable)) + ->queue($event->file->path, $event->file->disk); + } +} diff --git a/app/Listeners/ImportBookings.php b/app/Listeners/ImportBookings.php new file mode 100644 index 00000000..02e307a0 --- /dev/null +++ b/app/Listeners/ImportBookings.php @@ -0,0 +1,40 @@ +file->type != BookingsImport::class) { + return; + } + + (new BookingsImport($event->file->fileable)) + ->queue($event->file->path, $event->file->disk); + } +} diff --git a/app/Listeners/SendEventBulkEmailNotification.php b/app/Listeners/SendEventBulkEmailNotification.php index 1e3106f7..b02d3c18 100644 --- a/app/Listeners/SendEventBulkEmailNotification.php +++ b/app/Listeners/SendEventBulkEmailNotification.php @@ -27,7 +27,7 @@ public function __construct() */ public function handle(EventBulkEmail $event) { - if (isset($event->request['testmode'])) { + if (isset($event->request['test_mode'])) { $log = 'Bulk E-mail test performed'; } else { $log = 'Bulk E-mail'; diff --git a/app/Models/Airport.php b/app/Models/Airport.php index 1ee253fc..8d389b05 100644 --- a/app/Models/Airport.php +++ b/app/Models/Airport.php @@ -17,6 +17,8 @@ * @property string $icao * @property string $iata * @property string $name + * @property float|null $latitude + * @property float|null $longitude * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \Illuminate\Database\Eloquent\Collection|\Spatie\Activitylog\Models\Activity[] $activities @@ -40,6 +42,8 @@ * @method static Builder|Airport whereIata($value) * @method static Builder|Airport whereIcao($value) * @method static Builder|Airport whereId($value) + * @method static Builder|Airport whereLatitude($value) + * @method static Builder|Airport whereLongitude($value) * @method static Builder|Airport whereName($value) * @method static Builder|Airport whereUpdatedAt($value) * @mixin \Eloquent diff --git a/app/Models/AirportLinkType.php b/app/Models/AirportLinkType.php index e1cb0032..1a2066a6 100644 --- a/app/Models/AirportLinkType.php +++ b/app/Models/AirportLinkType.php @@ -20,7 +20,7 @@ * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \Illuminate\Database\Eloquent\Collection|\Spatie\Activitylog\Models\Activity[] $activities * @property-read int|null $activities_count - * @property-read AirportLink $links + * @property-read AirportLink|null $links * @method static Builder|AirportLinkType newModelQuery() * @method static Builder|AirportLinkType newQuery() * @method static Builder|AirportLinkType query() diff --git a/app/Models/Booking.php b/app/Models/Booking.php index 7000ac80..a555ff6c 100644 --- a/app/Models/Booking.php +++ b/app/Models/Booking.php @@ -15,6 +15,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\HasOneThrough; /** * App\Models\Booking @@ -33,15 +34,15 @@ * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \Illuminate\Database\Eloquent\Collection|\Spatie\Activitylog\Models\Activity[] $activities * @property-read int|null $activities_count - * @property-read Airport|null $airportArr - * @property-read Airport|null $airportDep * @property-read Event $event + * @property-read Flight|null $firstFlight * @property-read \Illuminate\Database\Eloquent\Collection|Flight[] $flights * @property-read int|null $flights_count * @property-read string $formatted_actype * @property-read string $formatted_callsign * @property-read string $formatted_selcal * @property-read bool $has_received_final_information_email + * @property-read Flight|null $lastFlight * @property-write mixed $actype * @property-read User|null $user * @method static \Database\Factories\BookingFactory factory(...$parameters) @@ -136,16 +137,6 @@ public function setSelcalAttribute($value): void $this->attributes['selcal'] = !empty($value) ? strtoupper($value) : null; } - public function airportDep(): HasOne - { - return $this->hasOne(Airport::class, 'id', 'dep'); - } - - public function airportArr(): HasOne - { - return $this->hasOne(Airport::class, 'id', 'arr'); - } - public function event(): BelongsTo { return $this->belongsTo(Event::class); @@ -161,6 +152,16 @@ public function flights(): HasMany return $this->hasMany(Flight::class)->orderBy('order_by'); } + public function firstFlight(): HasOne + { + return $this->hasOne(Flight::class)->ofMany('order_by', 'min'); + } + + public function lastFlight(): HasOne + { + return $this->hasOne(Flight::class)->ofMany('order_by', 'max'); + } + public function airportCtot($orderBy, $withAbbr = true): string { if ($flight = $this->flights->where('order_by', $orderBy)->first()) { diff --git a/app/Models/Event.php b/app/Models/Event.php index 6e80b688..f7cb914c 100644 --- a/app/Models/Event.php +++ b/app/Models/Event.php @@ -6,11 +6,13 @@ use Spatie\Activitylog\LogOptions; use Illuminate\Database\Eloquent\Model; use Cviebrock\EloquentSluggable\Sluggable; +use Illuminate\Database\Eloquent\Casts\Attribute; use Spatie\Activitylog\Traits\LogsActivity; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Database\Eloquent\Relations\MorphMany; /** * App\Models\Event @@ -43,6 +45,8 @@ * @property-read int|null $bookings_count * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Faq[] $faqs * @property-read int|null $faqs_count + * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\File[] $files + * @property-read int|null $files_count * @property-read \Illuminate\Database\Eloquent\Collection|EventLink[] $links * @property-read int|null $links_count * @property-read \App\Models\EventType|null $type @@ -150,6 +154,11 @@ public function faqs(): BelongsToMany return $this->belongsToMany(Faq::class); } + public function files(): MorphMany + { + return $this->morphMany(File::class, 'fileable'); + } + public function sluggable(): array { return [ @@ -171,4 +180,11 @@ public function hasOrderButtons(): bool \App\Enums\EventType::GROUPFLIGHT ]); } + + protected function nameDate(): Attribute + { + return new Attribute( + get: fn () => "{$this->name} [{$this->startEvent->format('M j, Y')}]", + ); + } } diff --git a/app/Models/EventType.php b/app/Models/EventType.php index 741d36d7..a8d9078a 100644 --- a/app/Models/EventType.php +++ b/app/Models/EventType.php @@ -16,7 +16,7 @@ * @property string $name * @property-read \Illuminate\Database\Eloquent\Collection|\Spatie\Activitylog\Models\Activity[] $activities * @property-read int|null $activities_count - * @property-read Event $events + * @property-read Event|null $events * @method static Builder|EventType newModelQuery() * @method static Builder|EventType newQuery() * @method static Builder|EventType query() diff --git a/app/Models/File.php b/app/Models/File.php new file mode 100644 index 00000000..9e568425 --- /dev/null +++ b/app/Models/File.php @@ -0,0 +1,64 @@ + FileCreated::class, + ]; + + public function prunable() + { + return static::where('created_at', '<=', now()->subDay()); + } + + public function fileable(): MorphTo + { + return $this->morphTo(); + } + + protected function pruning() + { + Storage::disk($this->disk) + ->delete($this->path); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index add48045..db6072b8 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -6,6 +6,8 @@ use Spatie\Activitylog\LogOptions; use Illuminate\Notifications\Notifiable; use App\Http\Controllers\OAuthController; +use Filament\Models\Contracts\FilamentUser; +use Filament\Models\Contracts\HasName; use League\OAuth2\Client\Token\AccessToken; use Spatie\Activitylog\Traits\LogsActivity; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -56,7 +58,7 @@ * @method static \Illuminate\Database\Eloquent\Builder|User whereUseMonospaceFont($value) * @mixin \Eloquent */ -class User extends Authenticatable +class User extends Authenticatable implements FilamentUser, HasName { use HasFactory; use LogsActivity; @@ -83,6 +85,16 @@ class User extends Authenticatable 'use_monospace_font' => 'boolean', ]; + public function canAccessFilament(): bool + { + return $this->isAdmin; + } + + public function getFilamentName(): string + { + return $this->full_name; + } + public function getActivitylogOptions(): LogOptions { return LogOptions::defaults()->logOnlyDirty(); diff --git a/app/Policies/AirportLinkPolicy.php b/app/Policies/AirportLinkPolicy.php index 60e6ac28..1d551897 100644 --- a/app/Policies/AirportLinkPolicy.php +++ b/app/Policies/AirportLinkPolicy.php @@ -10,6 +10,13 @@ class AirportLinkPolicy { use HandlesAuthorization; + public function before(User $user, $ability) + { + if ($user->isAdmin) { + return true; + } + } + /** * Determine whether the user can view the airport link. * diff --git a/app/Policies/AirportPolicy.php b/app/Policies/AirportPolicy.php index 21aa7d61..a3cf52ed 100644 --- a/app/Policies/AirportPolicy.php +++ b/app/Policies/AirportPolicy.php @@ -10,6 +10,13 @@ class AirportPolicy { use HandlesAuthorization; + public function before(User $user, $ability) + { + if ($user->isAdmin && $ability != 'delete') { + return true; + } + } + /** * Determine whether the user can view the airport. * @@ -54,7 +61,7 @@ public function update(User $user, Airport $airport) */ public function delete(User $user, Airport $airport) { - return false; + return $user->isAdmin && $airport->flightsDep->isEmpty() && $airport->flightsArr->isEmpty(); } /** diff --git a/app/Policies/BookingPolicy.php b/app/Policies/BookingPolicy.php index a8f44444..ff735f46 100644 --- a/app/Policies/BookingPolicy.php +++ b/app/Policies/BookingPolicy.php @@ -10,6 +10,13 @@ class BookingPolicy { use HandlesAuthorization; + public function before(User $user, $ability) + { + if ($user->isAdmin) { + return true; + } + } + /** * Determine whether the user can view the booking. * diff --git a/app/Policies/EventLinkPolicy.php b/app/Policies/EventLinkPolicy.php index 0be6b145..ae82cd3e 100644 --- a/app/Policies/EventLinkPolicy.php +++ b/app/Policies/EventLinkPolicy.php @@ -10,6 +10,13 @@ class EventLinkPolicy { use HandlesAuthorization; + public function before(User $user, $ability) + { + if ($user->isAdmin) { + return true; + } + } + /** * Determine whether the user can view any models. * diff --git a/app/Policies/EventPolicy.php b/app/Policies/EventPolicy.php index c7386ad5..6123e979 100644 --- a/app/Policies/EventPolicy.php +++ b/app/Policies/EventPolicy.php @@ -10,6 +10,13 @@ class EventPolicy { use HandlesAuthorization; + public function before(User $user, $ability) + { + // if ($user->isAdmin && $ability != 'delete') { + // return true; + // } + } + /** * Determine whether the user can view the event. * @@ -19,7 +26,7 @@ class EventPolicy */ public function view(?User $user, Event $event) { - return true; + return $user->isAdmin || $event->is_online; } /** @@ -30,7 +37,7 @@ public function view(?User $user, Event $event) */ public function create(User $user) { - return false; + return $user->isAdmin; } /** @@ -42,7 +49,7 @@ public function create(User $user) */ public function update(User $user, Event $event) { - return false; + return $user->isAdmin && $event->startEvent->gt(now()); } /** @@ -54,7 +61,7 @@ public function update(User $user, Event $event) */ public function delete(User $user, Event $event) { - return false; + return $user->isAdmin && $event->startEvent->gt(now()); } /** diff --git a/app/Policies/FaqPolicy.php b/app/Policies/FaqPolicy.php index 967b3a12..1d8f0f72 100644 --- a/app/Policies/FaqPolicy.php +++ b/app/Policies/FaqPolicy.php @@ -10,6 +10,13 @@ class FaqPolicy { use HandlesAuthorization; + public function before(User $user, $ability) + { + if ($user->isAdmin) { + return true; + } + } + /** * Determine whether the user can view the faq. * diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index e32e5135..f05e9317 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -12,7 +12,6 @@ use App\Policies\BookingPolicy; use App\Policies\EventPolicy; use App\Policies\FaqPolicy; -use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider @@ -38,11 +37,5 @@ class AuthServiceProvider extends ServiceProvider public function boot() { $this->registerPolicies(); - - Gate::before(function ($user, $ability) { - if ($user->isAdmin) { - return true; - } - }); } } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 4b1c3b8e..ebe649cb 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -12,26 +12,7 @@ class EventServiceProvider extends ServiceProvider * * @var array */ - protected $listen = [ - 'App\Events\BookingConfirmed' => [ - 'App\Listeners\SendBookingConfirmedNotification', - ], - 'App\Events\BookingCancelled' => [ - 'App\Listeners\SendBookingCancelledNotification', - ], - 'App\Events\BookingChanged' => [ - 'App\Listeners\SendBookingChangedNotification', - ], - 'App\Events\BookingDeleted' => [ - 'App\Listeners\SendBookingDeletedNotification', - ], - 'App\Events\EventBulkEmail' => [ - 'App\Listeners\SendEventBulkEmailNotification', - ], - 'App\Events\EventFinalInformation' => [ - 'App\Listeners\SendEventFinalInformationNotification', - ] - ]; + protected $listen = []; /** * Register any events for your application. @@ -44,4 +25,14 @@ public function boot() // } + + /** + * Determine if events and listeners should be automatically discovered. + * + * @return bool + */ + public function shouldDiscoverEvents() + { + return true; + } } diff --git a/app/View/Components/FlatPickr.php b/app/View/Components/FlatPickr.php deleted file mode 100644 index 6ea28ef9..00000000 --- a/app/View/Components/FlatPickr.php +++ /dev/null @@ -1,15 +0,0 @@ - true, - 'altFormat' => 'F j, Y H:i\\z', - 'ariaDateFormat' => 'F j, Y H:i' - ], parent::options()); - } -} diff --git a/composer.json b/composer.json index fc964e52..10de79f0 100644 --- a/composer.json +++ b/composer.json @@ -11,10 +11,10 @@ "php": "^8.1", "aws/aws-sdk-php": "^3.209", "bensampo/laravel-enum": "^5.0", - "blade-ui-kit/blade-ui-kit": "^0.3.3", "bugsnag/bugsnag-laravel": "^2.22", "cviebrock/eloquent-sluggable": "^9.0", "doctrine/dbal": "^3.3", + "filament/filament": "^2.13", "laravel/framework": "^9.0", "laravel/horizon": "^5.8", "laravel/telescope": "^4.7", @@ -78,7 +78,8 @@ "php artisan ide-helper:generate", "php artisan ide-helper:meta", "@php artisan telescope:publish --ansi", - "@php artisan horizon:publish --ansi" + "@php artisan horizon:publish --ansi", + "@php artisan filament:upgrade" ] }, "config": { diff --git a/composer.lock b/composer.lock index 4fbdcec0..27cd1c35 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,76 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f85bdd783395128c8d0055121d97841a", + "content-hash": "9d7660632990a6e10a2d4c63e7714ee2", "packages": [ + { + "name": "akaunting/laravel-money", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/akaunting/laravel-money.git", + "reference": "22336631239eb008e26d322faa208cbc50757a38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/akaunting/laravel-money/zipball/22336631239eb008e26d322faa208cbc50757a38", + "reference": "22336631239eb008e26d322faa208cbc50757a38", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.67|^9.0", + "illuminate/support": "^8.67|^9.0", + "illuminate/view": "^8.67|^9.0", + "php": "^8.0", + "vlucas/phpdotenv": "^5.4.1" + }, + "require-dev": { + "orchestra/testbench": "^6.23|^7.4", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.23" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Akaunting\\Money\\Provider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Akaunting\\Money\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Duliçi", + "email": "info@akaunting.com", + "homepage": "https://akaunting.com", + "role": "Developer" + } + ], + "description": "Currency formatting and conversion package for Laravel", + "keywords": [ + "convert", + "currency", + "format", + "laravel", + "money" + ], + "support": { + "issues": "https://github.com/akaunting/laravel-money/issues", + "source": "https://github.com/akaunting/laravel-money/tree/3.0.1" + }, + "time": "2022-05-11T06:34:38+00:00" + }, { "name": "aws/aws-crt-php", "version": "v1.0.2", @@ -235,50 +303,119 @@ "time": "2022-06-22T08:35:50+00:00" }, { - "name": "blade-ui-kit/blade-ui-kit", - "version": "0.3.4", + "name": "blade-ui-kit/blade-heroicons", + "version": "1.3.1", "source": { "type": "git", - "url": "https://github.com/blade-ui-kit/blade-ui-kit.git", - "reference": "139f387d219bceb647c02d18c6b74cebb4c8dae6" + "url": "https://github.com/blade-ui-kit/blade-heroicons.git", + "reference": "a2749abc7b8eb6149ff643ffa99a3d33a2de7961" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/blade-ui-kit/blade-ui-kit/zipball/139f387d219bceb647c02d18c6b74cebb4c8dae6", - "reference": "139f387d219bceb647c02d18c6b74cebb4c8dae6", + "url": "https://api.github.com/repos/blade-ui-kit/blade-heroicons/zipball/a2749abc7b8eb6149ff643ffa99a3d33a2de7961", + "reference": "a2749abc7b8eb6149ff643ffa99a3d33a2de7961", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/filesystem": "^7.0|^8.0|^9.0", - "illuminate/support": "^7.0|^8.0|^9.0", - "illuminate/view": "^7.0|^8.0|^9.0", - "nesbot/carbon": "^2.38", - "php": "^7.3|^8.0" + "blade-ui-kit/blade-icons": "^1.1", + "illuminate/support": "^8.0|^9.0", + "php": "^7.4|^8.0" }, "require-dev": { - "gajus/dindent": "^2.0", - "guzzlehttp/guzzle": "^7.4", - "league/commonmark": "^1.4|^2.0", - "lorisleiva/cron-translator": "^0.1.1", - "orchestra/testbench": "^5.0|^6.0|^7.1", + "orchestra/testbench": "^6.0|^7.0", "phpunit/phpunit": "^9.0" }, - "suggest": { - "league/commonmark": "Required to use the markdown component (^1.4).", - "lorisleiva/cron-translator": "Required to use the cron component (^0.1.1)." + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BladeUI\\Heroicons\\BladeHeroiconsServiceProvider" + ] + } }, + "autoload": { + "psr-4": { + "BladeUI\\Heroicons\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dries Vints", + "homepage": "https://driesvints.com" + } + ], + "description": "A package to easily make use of Heroicons in your Laravel Blade views.", + "homepage": "https://github.com/blade-ui-kit/blade-heroicons", + "keywords": [ + "Heroicons", + "blade", + "laravel" + ], + "support": { + "issues": "https://github.com/blade-ui-kit/blade-heroicons/issues", + "source": "https://github.com/blade-ui-kit/blade-heroicons/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/caneco", + "type": "github" + }, + { + "url": "https://github.com/driesvints", + "type": "github" + } + ], + "time": "2022-03-02T11:50:13+00:00" + }, + { + "name": "blade-ui-kit/blade-icons", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/blade-ui-kit/blade-icons.git", + "reference": "57a7c41e1e79e38aed029d3e6ae690b04344c99e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/57a7c41e1e79e38aed029d3e6ae690b04344c99e", + "reference": "57a7c41e1e79e38aed029d3e6ae690b04344c99e", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.0|^9.0", + "illuminate/filesystem": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "illuminate/view": "^8.0|^9.0", + "php": "^7.4|^8.0", + "symfony/console": "^5.3|^6.0", + "symfony/finder": "^5.3|^6.0" + }, + "require-dev": { + "mockery/mockery": "^1.3", + "orchestra/testbench": "^6.0|^7.0", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/blade-icons-generate" + ], "type": "library", "extra": { "laravel": { "providers": [ - "BladeUIKit\\BladeUIKitServiceProvider" + "BladeUI\\Icons\\BladeIconsServiceProvider" ] } }, "autoload": { + "files": [ + "src/helpers.php" + ], "psr-4": { - "BladeUIKit\\": "src" + "BladeUI\\Icons\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -291,16 +428,17 @@ "homepage": "https://driesvints.com" } ], - "description": "A set of renderless components to utilise in your Laravel Blade views.", - "homepage": "https://github.com/blade-ui-kit/blade-ui-kit", + "description": "A package to easily make use of icons in your Laravel Blade views.", + "homepage": "https://github.com/blade-ui-kit/blade-icons", "keywords": [ "blade", + "icons", "laravel", - "ui" + "svg" ], "support": { - "issues": "https://github.com/blade-ui-kit/blade-ui-kit/issues", - "source": "https://github.com/blade-ui-kit/blade-ui-kit" + "issues": "https://github.com/blade-ui-kit/blade-icons/issues", + "source": "https://github.com/blade-ui-kit/blade-icons" }, "funding": [ { @@ -312,7 +450,7 @@ "type": "github" } ], - "time": "2022-04-17T13:03:05+00:00" + "time": "2022-05-11T12:38:11+00:00" }, { "name": "brick/math", @@ -1323,6 +1461,111 @@ ], "time": "2022-01-25T02:55:58+00:00" }, + { + "name": "danharrin/date-format-converter", + "version": "v0.2.0", + "source": { + "type": "git", + "url": "https://github.com/danharrin/date-format-converter.git", + "reference": "ee448ab0cbe2ea36edb886a01670fc760e388f19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/danharrin/date-format-converter/zipball/ee448ab0cbe2ea36edb886a01670fc760e388f19", + "reference": "ee448ab0cbe2ea36edb886a01670fc760e388f19", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/helpers.php", + "src/standards.php" + ], + "psr-4": { + "DanHarrin\\DateFormatConverter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dan Harrin", + "email": "dan@danharrin.com" + } + ], + "description": "Convert token-based date formats between standards.", + "homepage": "https://github.com/danharrin/date-format-converter", + "support": { + "issues": "https://github.com/danharrin/date-format-converter/issues", + "source": "https://github.com/danharrin/date-format-converter" + }, + "funding": [ + { + "url": "https://github.com/danharrin", + "type": "github" + } + ], + "time": "2021-02-10T23:58:47+00:00" + }, + { + "name": "danharrin/livewire-rate-limiting", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/danharrin/livewire-rate-limiting.git", + "reference": "b99facf5b607fb0cde92a6f254f437295339f7de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/danharrin/livewire-rate-limiting/zipball/b99facf5b607fb0cde92a6f254f437295339f7de", + "reference": "b99facf5b607fb0cde92a6f254f437295339f7de", + "shasum": "" + }, + "require": { + "illuminate/support": "^8.0|^9.0", + "php": "^8.0" + }, + "require-dev": { + "livewire/livewire": "^2.3", + "orchestra/testbench": "^6.2|^7.0", + "phpunit/phpunit": "^9.4", + "symplify/monorepo-builder": "^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "DanHarrin\\LivewireRateLimiting\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dan Harrin", + "email": "dan@danharrin.com" + } + ], + "description": "Apply rate limiters to Laravel Livewire actions.", + "homepage": "https://github.com/danharrin/livewire-rate-limiting", + "support": { + "issues": "https://github.com/danharrin/livewire-rate-limiting/issues", + "source": "https://github.com/danharrin/livewire-rate-limiting" + }, + "funding": [ + { + "url": "https://github.com/danharrin", + "type": "github" + } + ], + "time": "2022-01-21T11:26:58+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.1", @@ -2086,6 +2329,227 @@ }, "time": "2021-12-25T01:21:49+00:00" }, + { + "name": "filament/filament", + "version": "v2.13.14", + "source": { + "type": "git", + "url": "https://github.com/filamentphp/admin.git", + "reference": "88324f6375c1af1ede797b48ad6f25ddeecbc632" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filamentphp/admin/zipball/88324f6375c1af1ede797b48ad6f25ddeecbc632", + "reference": "88324f6375c1af1ede797b48ad6f25ddeecbc632", + "shasum": "" + }, + "require": { + "danharrin/livewire-rate-limiting": "^0.3|^1.0", + "filament/forms": "self.version", + "filament/support": "self.version", + "filament/tables": "self.version", + "illuminate/auth": "^8.6|^9.0", + "illuminate/console": "^8.6|^9.0", + "illuminate/contracts": "^8.6|^9.0", + "illuminate/cookie": "^8.6|^9.0", + "illuminate/database": "^8.6|^9.0", + "illuminate/http": "^8.6|^9.0", + "illuminate/routing": "^8.6|^9.0", + "illuminate/session": "^8.6|^9.0", + "illuminate/support": "^8.6|^9.0", + "illuminate/view": "^8.6|^9.0", + "livewire/livewire": "^2.6", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.9" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Filament\\FilamentServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Filament\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Effortlessly build TALL-powered admin panels.", + "homepage": "https://github.com/filamentphp/filament", + "support": { + "issues": "https://github.com/filamentphp/filament/issues", + "source": "https://github.com/filamentphp/filament" + }, + "time": "2022-06-30T11:55:54+00:00" + }, + { + "name": "filament/forms", + "version": "v2.13.14", + "source": { + "type": "git", + "url": "https://github.com/filamentphp/forms.git", + "reference": "c40a067644b8b0bf40a17b236b22d2ef31489a8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/c40a067644b8b0bf40a17b236b22d2ef31489a8d", + "reference": "c40a067644b8b0bf40a17b236b22d2ef31489a8d", + "shasum": "" + }, + "require": { + "blade-ui-kit/blade-heroicons": "^1.2", + "danharrin/date-format-converter": "^0.2", + "filament/support": "self.version", + "illuminate/console": "^8.6|^9.0", + "illuminate/contracts": "^8.6|^9.0", + "illuminate/database": "^8.6|^9.0", + "illuminate/filesystem": "^8.6|^9.0", + "illuminate/support": "^8.6|^9.0", + "illuminate/validation": "^8.6|^9.0", + "illuminate/view": "^8.6|^9.0", + "livewire/livewire": "^2.6", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.9" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Filament\\Forms\\FormsServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Filament\\Forms\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Effortlessly build TALL-powered forms.", + "homepage": "https://github.com/filamentphp/filament", + "support": { + "issues": "https://github.com/filamentphp/filament/issues", + "source": "https://github.com/filamentphp/filament" + }, + "time": "2022-06-30T11:56:23+00:00" + }, + { + "name": "filament/support", + "version": "v2.13.14", + "source": { + "type": "git", + "url": "https://github.com/filamentphp/support.git", + "reference": "7ede0b21503000d11aed71e088f5f1b268bab0e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filamentphp/support/zipball/7ede0b21503000d11aed71e088f5f1b268bab0e5", + "reference": "7ede0b21503000d11aed71e088f5f1b268bab0e5", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.6|^9.0", + "illuminate/support": "^8.6|^9.0", + "illuminate/view": "^8.6|^9.0", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.9" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Filament\\Support\\SupportServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Filament\\Support\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Associated helper methods and foundation code for Filament packages.", + "homepage": "https://github.com/filamentphp/filament", + "support": { + "issues": "https://github.com/filamentphp/filament/issues", + "source": "https://github.com/filamentphp/filament" + }, + "time": "2022-06-29T21:09:03+00:00" + }, + { + "name": "filament/tables", + "version": "v2.13.14", + "source": { + "type": "git", + "url": "https://github.com/filamentphp/tables.git", + "reference": "3d60211628dc237d98727c4deb157b0897a936fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/3d60211628dc237d98727c4deb157b0897a936fb", + "reference": "3d60211628dc237d98727c4deb157b0897a936fb", + "shasum": "" + }, + "require": { + "akaunting/laravel-money": "^1.2|^2.0|^3.0", + "blade-ui-kit/blade-heroicons": "^1.2", + "filament/forms": "self.version", + "filament/support": "self.version", + "illuminate/console": "^8.6|^9.0", + "illuminate/contracts": "^8.6|^9.0", + "illuminate/database": "^8.6|^9.0", + "illuminate/filesystem": "^8.6|^9.0", + "illuminate/support": "^8.6|^9.0", + "illuminate/view": "^8.6|^9.0", + "livewire/livewire": "^2.6", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.9" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Filament\\Tables\\TablesServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Filament\\Tables\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Effortlessly build TALL-powered tables.", + "homepage": "https://github.com/filamentphp/filament", + "support": { + "issues": "https://github.com/filamentphp/filament/issues", + "source": "https://github.com/filamentphp/filament" + }, + "time": "2022-06-30T11:55:52+00:00" + }, { "name": "fruitcake/php-cors", "version": "v1.2.0", diff --git a/config/blade-ui-kit.php b/config/blade-ui-kit.php deleted file mode 100644 index 0a18797c..00000000 --- a/config/blade-ui-kit.php +++ /dev/null @@ -1,132 +0,0 @@ - [ - // 'alert' => Components\Alerts\Alert::class, - // 'avatar' => Components\Support\Avatar::class, - // 'carbon' => Components\DateTime\Carbon::class, - // 'checkbox' => Components\Forms\Inputs\Checkbox::class, - // 'color-picker' => Components\Forms\Inputs\ColorPicker::class, - // 'countdown' => Components\DateTime\Countdown::class, - // 'cron' => Components\Support\Cron::class, - // 'dropdown' => Components\Navigation\Dropdown::class, - // 'easy-mde' => Components\Editors\EasyMDE::class, - // 'email' => Components\Forms\Inputs\Email::class, - // 'error' => Components\Forms\Error::class, - 'flat-pickr' => FlatPickr::class, - // 'form' => Components\Forms\Form::class, - // 'form-button' => Components\Buttons\FormButton::class, - // 'html' => Components\Layouts\Html::class, - // 'input' => Components\Forms\Inputs\Input::class, - // 'label' => Components\Forms\Label::class, - // 'logout' => Components\Buttons\Logout::class, - // 'mapbox' => Components\Maps\Mapbox::class, - // 'markdown' => Components\Markdown\Markdown::class, - // 'password' => Components\Forms\Inputs\Password::class, - // 'pikaday' => Components\Forms\Inputs\Pikaday::class, - // 'social-meta' => Components\Layouts\SocialMeta::class, - // 'textarea' => Components\Forms\Inputs\Textarea::class, - // 'toc' => Components\Markdown\ToC::class, - // 'trix' => Components\Editors\Trix::class, - // 'unsplash' => Components\Support\Unsplash::class, - ], - - /* - |-------------------------------------------------------------------------- - | Livewire Components - |-------------------------------------------------------------------------- - | - | Below you reference all the Livewire components that should be loaded - | for your app. By default all components from Blade UI Kit are loaded in. - | - */ - - 'livewire' => [ - // - ], - - /* - |-------------------------------------------------------------------------- - | Components Prefix - |-------------------------------------------------------------------------- - | - | This value will set a prefix for all Blade UI Kit components. - | By default it's empty. This is useful if you want to avoid - | collision with components from other libraries. - | - | If set with "buk", for example, you can reference components like: - | - | - | - */ - - 'prefix' => '', - - /* - |-------------------------------------------------------------------------- - | Third Party Asset Libraries - |-------------------------------------------------------------------------- - | - | These settings hold reference to all third party libraries and their - | asset files served through a CDN. Individual components can require - | these asset files through their static `$assets` property. - | - */ - - 'assets' => [ - - 'alpine' => 'https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.3.5/dist/alpine.min.js', - - 'easy-mde' => [ - 'https://unpkg.com/easymde/dist/easymde.min.css', - 'https://unpkg.com/easymde/dist/easymde.min.js', - ], - - 'flat-pickr' => [ - 'https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css', - 'https://cdn.jsdelivr.net/npm/flatpickr@4.6.9/dist/flatpickr.min.js', - ], - - 'mapbox' => [ - 'https://api.mapbox.com/mapbox-gl-js/v1.8.1/mapbox-gl.css', - 'https://api.mapbox.com/mapbox-gl-js/v1.8.1/mapbox-gl.js', - ], - - 'moment' => [ - 'https://cdn.jsdelivr.net/npm/moment@2.26.0/moment.min.js', - 'https://cdn.jsdelivr.net/npm/moment-timezone@0.5.31/builds/moment-timezone-with-data.min.js', - ], - - 'pickr' => [ - 'https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/classic.min.css', - 'https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js', - ], - - 'pikaday' => [ - 'https://cdn.jsdelivr.net/npm/pikaday/css/pikaday.css', - 'https://cdn.jsdelivr.net/npm/pikaday/pikaday.js', - ], - - 'trix' => [ - 'https://unpkg.com/trix@1.2.3/dist/trix.css', - 'https://unpkg.com/trix@1.2.3/dist/trix.js', - ], - - ], - -]; diff --git a/config/filament.php b/config/filament.php new file mode 100644 index 00000000..035edc3a --- /dev/null +++ b/config/filament.php @@ -0,0 +1,254 @@ + env('FILAMENT_PATH', 'admin'), + + /* + |-------------------------------------------------------------------------- + | Filament Domain + |-------------------------------------------------------------------------- + | + | You may change the domain where Filament should be active. If the domain + | is empty, all domains will be valid. + | + */ + + 'domain' => env('FILAMENT_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | Homepage URL + |-------------------------------------------------------------------------- + | + | This is the URL that Filament will redirect the user to when they click + | on the sidebar's header. + | + */ + + 'home_url' => '/', + + /* + |-------------------------------------------------------------------------- + | Brand Name + |-------------------------------------------------------------------------- + | + | This will be displayed on the login page and in the sidebar's header. + | + */ + + 'brand' => env('APP_NAME'), + + /* + |-------------------------------------------------------------------------- + | Auth + |-------------------------------------------------------------------------- + | + | This is the configuration that Filament will use to handle authentication + | into the admin panel. + | + */ + + 'auth' => [ + 'guard' => env('FILAMENT_AUTH_GUARD', 'web'), + 'pages' => [ + 'login' => \Filament\Http\Livewire\Auth\Login::class, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Pages + |-------------------------------------------------------------------------- + | + | This is the namespace and directory that Filament will automatically + | register pages from. You may also register pages here. + | + */ + + 'pages' => [ + 'namespace' => 'App\\Filament\\Pages', + 'path' => app_path('Filament/Pages'), + 'register' => [ + Pages\Dashboard::class, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Resources + |-------------------------------------------------------------------------- + | + | This is the namespace and directory that Filament will automatically + | register resources from. You may also register resources here. + | + */ + + 'resources' => [ + 'namespace' => 'App\\Filament\\Resources', + 'path' => app_path('Filament/Resources'), + 'register' => [], + ], + + /* + |-------------------------------------------------------------------------- + | Widgets + |-------------------------------------------------------------------------- + | + | This is the namespace and directory that Filament will automatically + | register dashboard widgets from. You may also register widgets here. + | + */ + + 'widgets' => [ + 'namespace' => 'App\\Filament\\Widgets', + 'path' => app_path('Filament/Widgets'), + 'register' => [ + Widgets\AccountWidget::class, + Widgets\FilamentInfoWidget::class, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Livewire + |-------------------------------------------------------------------------- + | + | This is the namespace and directory that Filament will automatically + | register Livewire components inside. + | + */ + + 'livewire' => [ + 'namespace' => 'App\\Filament', + 'path' => app_path('Filament'), + ], + + /* + |-------------------------------------------------------------------------- + | Dark mode + |-------------------------------------------------------------------------- + | + | By enabling this feature, your users are able to select between a light + | and dark appearance for the admin panel, or let their system decide. + | + */ + + 'dark_mode' => true, + + /* + |-------------------------------------------------------------------------- + | Layout + |-------------------------------------------------------------------------- + | + | This is the configuration for the general layout of the admin panel. + | + | You may configure the max content width from `xl` to `7xl`, or `full` + | for no max width. + | + */ + + 'layout' => [ + 'forms' => [ + 'actions' => [ + 'alignment' => 'left', + ], + ], + 'footer' => [ + 'should_show_logo' => true, + ], + 'max_content_width' => null, + 'tables' => [ + 'actions' => [ + 'type' => \Filament\Tables\Actions\LinkAction::class, + ], + ], + ], + + /* + |-------------------------------------------------------------------------- + | Favicon + |-------------------------------------------------------------------------- + | + | This is the path to the favicon used for pages in the admin panel. + | + */ + + 'favicon' => null, + + /* + |-------------------------------------------------------------------------- + | Default Avatar Provider + |-------------------------------------------------------------------------- + | + | This is the service that will be used to retrieve default avatars if one + | has not been uploaded. + | + */ + + 'default_avatar_provider' => \Filament\AvatarProviders\UiAvatarsProvider::class, + + /* + |-------------------------------------------------------------------------- + | Default Filesystem Disk + |-------------------------------------------------------------------------- + | + | This is the storage disk Filament will use to put media. You may use any + | of the disks defined in the `config/filesystems.php`. + | + */ + + 'default_filesystem_disk' => env('FILAMENT_FILESYSTEM_DRIVER', 'public'), + + /* + |-------------------------------------------------------------------------- + | Middleware + |-------------------------------------------------------------------------- + | + | You may customise the middleware stack that Filament uses to handle + | requests. + | + */ + + 'middleware' => [ + 'auth' => [ + Authenticate::class, + ], + 'base' => [ + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, + AuthenticateSession::class, + ShareErrorsFromSession::class, + VerifyCsrfToken::class, + SubstituteBindings::class, + DispatchServingFilamentEvent::class, + MirrorConfigToSubpackages::class, + ], + ], + +]; diff --git a/database/migrations/2022_02_25_212605_create_files_table.php b/database/migrations/2022_02_25_212605_create_files_table.php new file mode 100644 index 00000000..827fc79b --- /dev/null +++ b/database/migrations/2022_02_25_212605_create_files_table.php @@ -0,0 +1,34 @@ +id(); + $table->morphs('fileable'); + $table->string('path'); + $table->string('disk'); + $table->string('type'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('files'); + } +}; diff --git a/package-lock.json b/package-lock.json index fcc62069..9b3717a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,6 @@ "dependencies": { "alpinejs": "^3.10.2", "bootswatch": "^4.6.1", - "flatpickr": "^4.6.13", "sweetalert2": "^11.4.19" }, "devDependencies": { @@ -39,8 +38,7 @@ "resolve-url-loader": "^5.0.0", "sass": "^1.53.0", "sass-loader": "^13.0.2", - "semantic-release": "^19.0.3", - "tinymce": "^6.1.0" + "semantic-release": "^19.0.3" } }, "node_modules/@ampproject/remapping": { @@ -7069,11 +7067,6 @@ "node": ">= 8" } }, - "node_modules/flatpickr": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz", - "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==" - }, "node_modules/follow-redirects": { "version": "1.14.9", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", @@ -15933,12 +15926,6 @@ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, - "node_modules/tinymce": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.1.0.tgz", - "integrity": "sha512-IdSdMlmuyhpEpUuabhBUaRC2NzZZxP2/CO/F+/54kTaAifB1Et5mKEty03pJYZxl6GBdFgclKRA2UU5JKJtJbA==", - "dev": true - }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -22498,11 +22485,6 @@ "resolve-dir": "^1.0.1" } }, - "flatpickr": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz", - "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==" - }, "follow-redirects": { "version": "1.14.9", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", @@ -29063,12 +29045,6 @@ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, - "tinymce": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.1.0.tgz", - "integrity": "sha512-IdSdMlmuyhpEpUuabhBUaRC2NzZZxP2/CO/F+/54kTaAifB1Et5mKEty03pJYZxl6GBdFgclKRA2UU5JKJtJbA==", - "dev": true - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index 5a778e78..5e49f6d3 100644 --- a/package.json +++ b/package.json @@ -47,13 +47,11 @@ "resolve-url-loader": "^5.0.0", "sass": "^1.53.0", "sass-loader": "^13.0.2", - "semantic-release": "^19.0.3", - "tinymce": "^6.1.0" + "semantic-release": "^19.0.3" }, "dependencies": { "alpinejs": "^3.10.2", "bootswatch": "^4.6.1", - "flatpickr": "^4.6.13", "sweetalert2": "^11.4.19" }, "release": { diff --git a/resources/js/alpine.js b/resources/js/alpine.js index 91c700cd..df80acc4 100644 --- a/resources/js/alpine.js +++ b/resources/js/alpine.js @@ -3,7 +3,3 @@ import Alpine from 'alpinejs'; window.Alpine = Alpine; Alpine.start(); - - -import flatpickr from 'flatpickr'; -window.flatPickr = flatpickr; diff --git a/resources/js/tinymce.js b/resources/js/tinymce.js deleted file mode 100644 index b25f5ba3..00000000 --- a/resources/js/tinymce.js +++ /dev/null @@ -1,9 +0,0 @@ -// TinyMCE -import tinymce from 'tinymce'; -import 'tinymce/plugins/code'; -import 'tinymce/plugins/link'; - -tinymce.init({ - selector: 'textarea.tinymce', - plugins: ['code', 'link'] -}); diff --git a/resources/sass/app.scss b/resources/sass/app.scss index e0c9b5fd..b1023ebb 100644 --- a/resources/sass/app.scss +++ b/resources/sass/app.scss @@ -1,6 +1,3 @@ -// Flatpickr -@import "flatpickr/dist/flatpickr.min.css"; - // Bootswatch Flatly variables @import 'bootswatch/dist/flatly/variables'; diff --git a/resources/views/airport/admin/form.blade.php b/resources/views/airport/admin/form.blade.php deleted file mode 100644 index d926cd41..00000000 --- a/resources/views/airport/admin/form.blade.php +++ /dev/null @@ -1,35 +0,0 @@ -@extends('layouts.app') - -@section('content') - -
-
-
-
{{ $airport->id ? __('Edit') : __('Add new') }} {{ __('Airport') }}
- -
- - - @bind($airport) - - - - - - - - @if ($airport->id) - {{ __('Edit') }} - @else - {{ __('Add') }} - @endif - - @endbind - -
-
-
-
-@endsection diff --git a/resources/views/airport/admin/overview.blade.php b/resources/views/airport/admin/overview.blade.php deleted file mode 100644 index 2c86f7d2..00000000 --- a/resources/views/airport/admin/overview.blade.php +++ /dev/null @@ -1,92 +0,0 @@ -@extends('layouts.app') - -@section('content') -

Airports Overview

-
- @include('layouts.alert') - @push('scripts') - - @endpush -
- Add new - Airport - Add - new - Airport - Link - -
- - - - - - - - - - @foreach ($airports as $airport) - - - - - - - - @endforeach - {{ $airports->links() }} -
ICAOIATANameActions
{{ $airport->icao }}{{ $airport->iata }}{{ $airport->name }} - - - - - @if ($airport->flightsDep->isEmpty() && $airport->flightsArr->isEmpty() && $airport->eventDep->isEmpty() && $airport->eventArr->isEmpty()) -
- @method('DELETE') - - @csrf -
- @else - - @endif -
- {{ $airports->links() }} - -@endsection diff --git a/resources/views/airport/admin/show.blade.php b/resources/views/airport/admin/show.blade.php deleted file mode 100644 index 421f9eb6..00000000 --- a/resources/views/airport/admin/show.blade.php +++ /dev/null @@ -1,27 +0,0 @@ -@extends('layouts.app') - -@section('content') - -
-
-
-
{{ $airport->name }} [{{ $airport->icao }} | {{ $airport->iata }}]
- -
- @foreach($airport->links as $link) -
- - -
- -
-
- @endforeach -
-
-
-
-@endsection diff --git a/resources/views/airportLink/admin/form.blade.php b/resources/views/airportLink/admin/form.blade.php deleted file mode 100644 index dc42370b..00000000 --- a/resources/views/airportLink/admin/form.blade.php +++ /dev/null @@ -1,44 +0,0 @@ -@extends('layouts.app') - -@section('content') - -
-
-
-
{{ $airportLink->id ? __('Edit') : __('Add new') }} {{ __('Airport Link') }} -
- -
- - - @bind($airportLink) - - @if ($airportLink->id) - - {{ $airportLink->airport->icao }} [{{ $airportLink->airport->name }} - ({{ $airportLink->airport->iata }})] - - @else - - @endif - - - - - @if ($airportLink->id) - {{ __('Edit') }} - @else - {{ __('Add') }} - @endif - - @endbind - -
-
-
-
-@endsection diff --git a/resources/views/airportLink/admin/overview.blade.php b/resources/views/airportLink/admin/overview.blade.php deleted file mode 100644 index f6cb4c0d..00000000 --- a/resources/views/airportLink/admin/overview.blade.php +++ /dev/null @@ -1,66 +0,0 @@ -@extends('layouts.app') - -@section('content') -

Airport Links Overview

- @include('layouts.alert') - @push('scripts') - - @endpush -

- Add new - Airport - Link -

- - - - - - - - - @foreach ($airportLinks as $airportLink) - - - - - - - @endforeach - {{ $airportLinks->links() }} -
AirportType / NameActions
- {{ $airportLink->airport->name }} - [{{ $airportLink->airport->icao }} | {{ $airportLink->airport->iata }}] - {{ $airportLink->name ?? $airportLink->type->name }} - - - - -
- @method('DELETE') - - @csrf -
-
- {{ $airportLinks->links() }} -@endsection diff --git a/resources/views/booking/overview/default.blade.php b/resources/views/booking/overview/default.blade.php index 0a4ade1c..dd695bb7 100644 --- a/resources/views/booking/overview/default.blade.php +++ b/resources/views/booking/overview/default.blade.php @@ -9,9 +9,6 @@ Callsign Aircraft Book | Available until {{ $event->endBooking->format('d-m-Y H:i') }}z - @if (auth()->check() && auth()->user()->isAdmin && $event->endEvent >= now()) - Admin actions - @endif @foreach ($bookings as $booking) @@ -62,7 +59,7 @@ @else + @endcan @else @if (auth()->check()) @@ -87,28 +84,6 @@ @endif @endif - @if (auth()->check() && auth()->user()->isAdmin && $event->endEvent >= now()) - Edit - - -
- @csrf - @method('DELETE') - -
- - - @if ($booking->user_id) - - - - @endif - - @endif @endif @endforeach diff --git a/resources/views/booking/overview/multiflights.blade.php b/resources/views/booking/overview/multiflights.blade.php index c153c916..0fd6cc05 100644 --- a/resources/views/booking/overview/multiflights.blade.php +++ b/resources/views/booking/overview/multiflights.blade.php @@ -5,9 +5,6 @@ Callsign Aircraft Book | Available until {{ $event->endBooking->format('d-m-Y H:i') }}z - @if (auth()->check() && auth()->user()->isAdmin && $event->endEvent >= now()) - Admin actions - @endif @foreach ($bookings as $booking) @@ -45,7 +42,7 @@ @else + @endcan @else @if (auth()->check()) @@ -70,27 +67,5 @@ @endif @endif - @if (auth()->check() && auth()->user()->isAdmin && $event->endEvent >= now()) - Edit - - -
- @csrf - @method('DELETE') - -
- - - @if ($booking->user_id) - - - - @endif - - @endif @endforeach diff --git a/resources/views/event/admin/form.blade.php b/resources/views/event/admin/form.blade.php deleted file mode 100644 index c33212e0..00000000 --- a/resources/views/event/admin/form.blade.php +++ /dev/null @@ -1,120 +0,0 @@ -@extends('layouts.app') - -@section('content') - -
-
-
-
{{ $event->id ? 'Edit' : 'Add new' }} Event
- -
- - @bind($event) - - - - - @slot('help') - - {{ __("Choose here if you want the event to be reachable by it's generated url") }} - - @endslot - - - - - - @slot('help') - - {{ __("Choose here if you want to show the event on the homepage. If turned off, the event can only be reached by the url. NOTE: If 'Show Online' is off, the event won't be shown at all") }} - - @endslot - - - - - - - - - - @slot('help') - - {{ __('If enabled, only admins can fill in details via import script') }} - - @endslot - - - - - - @slot('help') - - {{ __('If enabled, CTOT and ETA (if set in booking) will be shown') }} - - @endslot - - - - - - @slot('help') - - {{ __('If enabled, a user is allowed to book multiple flights for this event') }} - - @endslot - - - - - - @slot('help') - - {{ __('If enabled, users can fill in a SELCAL code') }} - - @endslot - - - - - - - - - - - - - - - - - - - - - - - - - - - - @if ($event->id) - {{ __('Edit') }} - @else - {{ __('Add') }} - @endif - - - @endbind - -
-
-
-
-@endsection diff --git a/resources/views/eventLink/admin/form.blade.php b/resources/views/eventLink/admin/form.blade.php deleted file mode 100644 index 4a20ce7d..00000000 --- a/resources/views/eventLink/admin/form.blade.php +++ /dev/null @@ -1,42 +0,0 @@ -@extends('layouts.app') - -@section('content') - -
-
-
-
{{ $eventLink->id ? 'Edit' : 'Add new' }} Event Link
- -
- - - @bind($eventLink) - - @if ($eventLink->id) - - {{ $eventLink->event->name }} [{{ $eventLink->event->startEvent->format('d-m-Y') }}] - - @else - - @endif - - - - - @if ($eventLink->id) - {{ __('Edit') }} - @else - {{ __('Add') }} - @endif - - @endbind - -
-
-
-
-@endsection diff --git a/resources/views/eventLink/admin/overview.blade.php b/resources/views/eventLink/admin/overview.blade.php deleted file mode 100644 index 74c0b168..00000000 --- a/resources/views/eventLink/admin/overview.blade.php +++ /dev/null @@ -1,65 +0,0 @@ -@extends('layouts.app') - -@section('content') -

Event Links Overview

- @include('layouts.alert') - @push('scripts') - - @endpush -

- Add new - Event - Link -

- - - - - - - - - @foreach ($eventLinks as $eventLink) - - - - - - - @endforeach - {{ $eventLinks->links() }} -
EventType / NameActions
- {{ $eventLink->event->name }} - {{ $eventLink->name ?? $eventLink->type->name }} - - - - -
- @method('DELETE') - - @csrf -
-
- {{ $eventLinks->links() }} -@endsection diff --git a/resources/views/filament/resources/event-resource/pages/assign-routes.blade.php b/resources/views/filament/resources/event-resource/pages/assign-routes.blade.php new file mode 100644 index 00000000..0ce51173 --- /dev/null +++ b/resources/views/filament/resources/event-resource/pages/assign-routes.blade.php @@ -0,0 +1,16 @@ + + + {{ $this->form }} + +
+ + Submit + + + Download template + +
+ +
+
diff --git a/resources/views/filament/resources/event-resource/pages/import-bookings.blade.php b/resources/views/filament/resources/event-resource/pages/import-bookings.blade.php new file mode 100644 index 00000000..82299ae4 --- /dev/null +++ b/resources/views/filament/resources/event-resource/pages/import-bookings.blade.php @@ -0,0 +1,16 @@ + + + {{ $this->form }} + +
+ + Submit + + + Download template + +
+ +
+
diff --git a/resources/views/filament/resources/event-resource/pages/send-email.blade.php b/resources/views/filament/resources/event-resource/pages/send-email.blade.php new file mode 100644 index 00000000..9abb4bf1 --- /dev/null +++ b/resources/views/filament/resources/event-resource/pages/send-email.blade.php @@ -0,0 +1,21 @@ + + + {{ $this->finalInformationEmailForm }} + + + Send Final Information E-mail + + + + +
+ + + {{ $this->emailForm }} + + + Send E-mail + + + +
diff --git a/resources/views/layouts/navbar.blade.php b/resources/views/layouts/navbar.blade.php index 4714b522..a197ac9f 100644 --- a/resources/views/layouts/navbar.blade.php +++ b/resources/views/layouts/navbar.blade.php @@ -60,26 +60,9 @@ class="fas fa-chevron-right"> {{ $bookings->count() > 1 ? $booking->cal @auth @if (auth()->user()->isAdmin) - @endif @endauth diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index b5b4c5d9..43050cdf 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -5,102 +5,6 @@ $trail->push('Home', route('home')); }); -// Home > Admin -Breadcrumbs::for('admin', function ($trail) { - $trail->parent('home'); - $trail->push('Admin'); -}); - -// Home > Admin > Airports -Breadcrumbs::for('admin.airports.index', function ($trail) { - $trail->parent('admin'); - $trail->push('Airports', route('admin.airports.index')); -}); - -// Home > Admin > Airports > New -Breadcrumbs::for('admin.airports.create', function ($trail) { - $trail->parent('admin.airports.index'); - $trail->push('New', route('admin.airports.create')); -}); - -// Home > Admin > Airports > [Airport] -Breadcrumbs::for('admin.airports.show', function ($trail, $airport) { - $trail->parent('admin.airports.index'); - $trail->push($airport->name . ' [' . $airport->icao . ' | ' . $airport->iata . ']', route('admin.airports.show', $airport)); -}); - -// Home > Admin > Airports > [Airport] > Edit Airport -Breadcrumbs::for('admin.airports.edit', function ($trail, $airport) { - $trail->parent('admin.airports.show', $airport); - $trail->push('Edit Airport', route('admin.airports.edit', $airport)); -}); - -// Home > Admin > Airport Links -Breadcrumbs::for('admin.airportLinks.index', function ($trail) { - $trail->parent('admin'); - $trail->push('Airport Links', route('admin.airportLinks.index')); -}); - -// Home > Admin > Airport Links > New -Breadcrumbs::for('admin.airportLinks.create', function ($trail) { - $trail->parent('admin.airportLinks.index'); - $trail->push('New', route('admin.airportLinks.create')); -}); - -// Home > Admin > Airports > [Airport] > [Airport Link] > Edit Airport Link -Breadcrumbs::for('admin.airportLinks.edit', function ($trail, $airportLink) { - $trail->parent('admin.airports.show', $airportLink->airport); - $trail->push('Edit Airport Link', route('admin.airportLinks.edit', $airportLink)); -}); - -// Home > Admin > Event Links -Breadcrumbs::for('admin.eventLinks.index', function ($trail) { - $trail->parent('admin'); - $trail->push('Event Links', route('admin.eventLinks.index')); -}); - -// Home > Admin > Event Links > New -Breadcrumbs::for('admin.eventLinks.create', function ($trail) { - $trail->parent('admin.eventLinks.index'); - $trail->push('New', route('admin.eventLinks.create')); -}); - -// Home > Admin > Events > [Event] > [Event Link] > Edit Event Link -Breadcrumbs::for('admin.eventLinks.edit', function ($trail, $eventLink) { - $trail->parent('admin.events.show', $eventLink->event); - $trail->push('Edit Airport Link', route('admin.eventLinks.edit', $eventLink)); -}); - -// Home > Admin > Events -Breadcrumbs::for('admin.events.index', function ($trail) { - $trail->parent('admin'); - $trail->push('Events', route('admin.events.index')); -}); - -// Home > Admin > Events > [Event] > Edit event -Breadcrumbs::for('admin.events.edit', function ($trail, $event) { - $trail->parent('admin.events.show', $event); - $trail->push('Edit Event', route('admin.events.edit', $event)); -}); - -// Home > Admin > Events > New -Breadcrumbs::for('admin.events.create', function ($trail) { - $trail->parent('admin.events.index'); - $trail->push('New', route('admin.events.create')); -}); - -// Home > Admin > Events > [Event] -Breadcrumbs::for('admin.events.show', function ($trail, $event) { - $trail->parent('admin.events.index'); - $trail->push($event->name . ' [' . $event->startEvent->toFormattedDateString() . ']', route('admin.events.show', $event)); -}); - -// Home > Admin > Events > [Event] > Send E-mail -Breadcrumbs::for('admin.events.email.form', function ($trail, $event) { - $trail->parent('admin.events.show', $event); - $trail->push('Send E-mail', route('admin.events.email.form', $event)); -}); - // Home (no event found) Breadcrumbs::for('bookings.index', function ($trail) { $trail->parent('home'); @@ -130,66 +34,12 @@ $trail->push('My Booking', route('bookings.show', $booking)); }); -// Home > Admin > [Event] > Add Slot -Breadcrumbs::for('admin.bookings.create', function ($trail, $event) { - $trail->parent('admin.events.show', $event); - $trail->push('Add Slot(s)', route('admin.bookings.create', $event)); -}); - -// Home > Admin > [Event] > Import -Breadcrumbs::for('admin.bookings.importForm', function ($trail, $event) { - $trail->parent('admin.events.show', $event); - $trail->push('Import', route('admin.bookings.importForm', $event)); -}); - -// Home > Admin > [Event] > Booking -Breadcrumbs::for('admin.bookings.edit', function ($trail, $booking) { - $trail->parent('admin.events.show', $booking->event); - $trail->push('Edit Booking', route('admin.bookings.edit', $booking)); -}); - -// Home > Admin > [Event] > Auto-Assign FL / Route -Breadcrumbs::for('admin.bookings.autoAssignForm', function ($trail, $event) { - $trail->parent('admin.events.show', $event); - $trail->push('Auto-Assign FL / Route', route('admin.bookings.autoAssignForm', $event)); -}); - -// Home > Admin > [Event] > Route assign -Breadcrumbs::for('admin.bookings.routeAssignForm', function ($trail, $event) { - $trail->parent('admin.events.show', $event); - $trail->push('Route assign', route('admin.bookings.routeAssignForm', $event)); -}); - // Home > FAQ Breadcrumbs::for('faq', function ($trail) { $trail->parent('home'); $trail->push('FAQ', route('faq')); }); -// Home > Admin > FAQ -Breadcrumbs::for('admin.faq.index', function ($trail) { - $trail->parent('admin'); - $trail->push('FAQ', route('admin.faq.index')); -}); - -// Home > Admin > FAQ > New -Breadcrumbs::for('admin.faq.create', function ($trail) { - $trail->parent('admin.faq.index'); - $trail->push('New', route('admin.faq.create')); -}); - -// Home > Admin > FAQ > [FAQ] -Breadcrumbs::for('admin.faq.show', function ($trail, $faq) { - $trail->parent('admin.faq.index'); - $trail->push('[' . $faq->id . '] ' . $faq->question); -}); - -// Home > Admin > FAQ > [FAQ] > Edit FAQ -Breadcrumbs::for('admin.faq.edit', function ($trail, $faq) { - $trail->parent('admin.faq.show', $faq); - $trail->push('Edit FAQ', route('admin.faq.edit', $faq)); -}); - // Home > My settings Breadcrumbs::for('user.settings', function ($trail) { $trail->parent('home'); diff --git a/routes/web.php b/routes/web.php index ce870118..88fc688f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -5,13 +5,8 @@ use App\Http\Controllers\User\UserController; use App\Http\Controllers\Auth\LoginController; use App\Http\Controllers\Event\EventController; -use App\Http\Controllers\Faq\FaqAdminController; use App\Http\Controllers\Booking\BookingController; -use App\Http\Controllers\Event\EventAdminController; -use App\Http\Controllers\Airport\AirportAdminController; use App\Http\Controllers\Booking\BookingAdminController; -use App\Http\Controllers\AirportLink\AirportLinkAdminController; -use App\Http\Controllers\EventLink\EventLinkAdminController; /* |-------------------------------------------------------------------------- @@ -29,35 +24,15 @@ Route::get('/login', [LoginController::class, 'login'])->name('login'); Route::get('/logout', [LoginController::class, 'logout'])->name('logout'); +Route::get('admin/login', function () { + // Just redirect to login, we don't work with passwords + return to_route('login'); +})->name('filament.auth.login'); + // Admin routes Route::group(['as' => 'admin.', 'prefix' => 'admin', 'middleware' => 'auth.isAdmin'], function () { - // Airports - Route::post('airports/destroy-unused', [AirportAdminController::class, 'destroyUnused'])->name('airports.destroyUnused'); - Route::resource('airports', AirportAdminController::class); - - // AirportLinks - Route::resource('airportLinks', AirportLinkAdminController::class)->except(['show']); - - // EventLinks - Route::resource('eventLinks', EventLinkAdminController::class)->except(['show']); - - // Faq - Route::resource('faq', FaqAdminController::class)->except('show'); - Route::patch('faq/{faq}/toggle-event/{event}', [FaqAdminController::class, 'toggleEvent'])->name('faq.toggleEvent'); - - // Event - Route::delete('events/{event}/delete-bookings', [EventAdminController::class, 'deleteAllBookings'])->name('events.delete-bookings'); - Route::resource('events', EventAdminController::class); - Route::get('{event}/email', [EventAdminController::class, 'sendEmailForm'])->name('events.email.form'); - Route::patch('{event}/email', [EventAdminController::class, 'sendEmail'])->name('events.email'); - Route::patch( - '{event}/email_final', - [EventAdminController::class, 'sendFinalInformationMail'] - )->name('events.email.final'); - // Booking Route::resource('bookings', BookingAdminController::class)->except(['index', 'create', 'show']); - Route::get('{event}/bookings/export/{vacc?}', [BookingAdminController::class, 'export'])->name('bookings.export'); Route::get('{event}/bookings/create/{bulk?}', [BookingAdminController::class, 'create'])->name('bookings.create'); Route::get('{event}/bookings/import', [BookingAdminController::class, 'importForm'])->name('bookings.importForm'); Route::post('{event}/bookings/import', [BookingAdminController::class, 'import'])->name('bookings.import'); diff --git a/webpack.mix.js b/webpack.mix.js index 2ee9411a..6179e70f 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -17,22 +17,14 @@ require('dotenv').config(); mix.js('resources/js/app.js', 'public/js') .js('resources/js/alpine.js', 'public/js') - .js('resources/js/tinymce.js', 'public/js') .sass('resources/sass/app.scss', 'public/css', { additionalData: '$envColorPrimary: ' + (process.env.BOOTSTRAP_COLOR_PRIMARY || '#2C3E50') + '; $envColorSecondary: ' + (process.env.BOOTSTRAP_COLOR_SECONDARY || '#95a5a6') + '; $envColorTertiary: ' + (process.env.BOOTSTRAP_COLOR_TERTIARY || '#18BC9C') + '; $envColorSuccess: ' + (process.env.BOOTSTRAP_COLOR_SUCCESS || '#18BC9C') + '; $envColorWarning: ' + (process.env.BOOTSTRAP_COLOR_WARNING || '#F39C12') + '; $envColorDanger: ' + (process.env.BOOTSTRAP_COLOR_DANGER || '#E74C3C') + ';' }) .purgeCss({ extend: { content: [path.join(__dirname, 'vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*bootstrap-4.blade.php')], - safelist: { - deep: [/\b(ui|flatpickr)-\S*$/] - } }, }) - .copyDirectory('node_modules/tinymce/icons', 'public/js/icons') - .copyDirectory('node_modules/tinymce/models', 'public/js/models') - .copyDirectory('node_modules/tinymce/themes', 'public/js/themes') - .copyDirectory('node_modules/tinymce/skins', 'public/js/skins') .extract(); if (mix.inProduction()) {