schema([ Forms\Components\FileUpload::make('path') ->required() ->image() ->imageEditor() ->columnSpanFull() ->helperText(function (Forms\Get $get) { $path = $get('path'); if (blank($path)) { return 'Rekomendasi dimensi: 1920├ù1080 px (16:9)'; } $file = is_array($path) ? ($path[0] ?? null) : $path; if (! is_string($file)) { return 'Rekomendasi dimensi: 1920├ù1080 px (16:9)'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi dimensi: 1920├ù1080 px (16:9)'; }), Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\TextInput::make('redirect') ->label('Redirect URL') ->url() ->maxLength(255), ]); } public static function table(Table $table): Table { return $table ->reorderable('sort') ->columns([ Tables\Columns\ImageColumn::make('path') ->label('Image'), Tables\Columns\TextColumn::make('name') ->searchable(), Tables\Columns\TextColumn::make('redirect') ->label('Redirect URL') ->default('Redirect Disabled') ->searchable(), Tables\Columns\TextColumn::make('created_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('updated_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->defaultSort('sort') ->filters([ // ]) ->actions([ Tables\Actions\ActionGroup::make([ Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make(), ]), ]) ->headerActions([ Tables\Actions\CreateAction::make() ->label('Create Banner'), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListBanners::route('/'), // 'create' => Pages\CreateBanner::route('/create'), // 'edit' => Pages\EditBanner::route('/{record}/edit'), ]; } } schema([ Section::make('Event Banner') ->schema([ Forms\Components\FileUpload::make('cover') ->label('Upload Event Banner') ->required() ->image() ->imageEditor() ->columnSpanFull() ->helperText(function (Forms\Get $get) { $path = $get('cover'); if (blank($path)) { return 'Rekomendasi dimensi: 1920├ù1080 px (16:9)'; } $file = is_array($path) ? ($path[0] ?? null) : $path; if (! is_string($file)) { return 'Rekomendasi dimensi: 1920├ù1080 px (16:9)'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi dimensi: 1920├ù1080 px (16:9)'; }), ]), Section::make('Event Information')->schema([ Forms\Components\TextInput::make('name') ->label('Event Name') ->required() ->maxLength(255) ->live(onBlur: true) ->afterStateUpdated(function (Set $set, $state) { $set('slug', Str::slug($state)); }), Forms\Components\TextInput::make('location') ->label('Event Location') ->placeholder('Venue Name, City, Country') ->required(), Forms\Components\RichEditor::make('description') ->required() ->columnSpanFull(), Forms\Components\DatePicker::make('startDate') ->label('Event Start Date') ->native(false), Forms\Components\DatePicker::make('endDate') ->label('Event End Date') ->native(false), Forms\Components\TextInput::make('coordinates') ->label('Map Coordinates') ->placeholder('0.000000, 0.000000') ->required(), Forms\Components\Select::make('category_id') ->label('Event Category') ->relationship(name: 'category', titleAttribute: 'name') ->createOptionForm([ Forms\Components\TextInput::make('name') ->label('Category Name') ->required() ->live(onBlur: true) ->afterStateUpdated(function (Set $set, $state) { $set('slug', Str::slug($state)); }), Forms\Components\TextInput::make('slug') ->required(), ]) ->preload() ->searchable() ->selectablePlaceholder(false) ->loadingMessage('Loading categories...') ->noSearchResultsMessage('No categories found.') ->searchPrompt('Search Event Categories') ->placeholder('') ->native(false), Forms\Components\TextInput::make('slug') ->required() ->maxLength(255), ]), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\ImageColumn::make('cover') ->label('Event Banner'), Tables\Columns\TextColumn::make('name') ->sortable() ->searchable(), Tables\Columns\TextColumn::make('description') ->limit(50) ->html() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('category.name') ->label('Event Category') ->searchable() ->sortable(), Tables\Columns\TextColumn::make('startDate') ->date() ->sortable(), Tables\Columns\TextColumn::make('endDate') ->date() ->sortable(), Tables\Columns\ToggleColumn::make('isAvailable') ->label('Availability') ->alignment(Alignment::Center), Tables\Columns\TextColumn::make('slug') ->searchable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('created_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('updated_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->defaultSort('name') ->filters([ SelectFilter::make('category.name') ->relationship(name: 'category', titleAttribute: 'name') ->searchable() ->preload() ->native(false), Tables\Filters\Filter::make('startDate') ->form([ Forms\Components\DatePicker::make('startDate')->native(false)->label('Started From'), ]) ->query(function (Builder $query, array $data): Builder { return $query ->when( $data['startDate'], fn (Builder $query, $date): Builder => $query->whereDate('startDate', '>=', $date), ); }) ->indicateUsing(function (array $data): array { $indicators = []; if ($data['startDate'] ?? null) { $indicators[] = Indicator::make('Created from '.Carbon::parse($data['startDate'])->toFormattedDateString()) ->removeField('startDate'); } return $indicators; }), Tables\Filters\Filter::make('endDate') ->form([ Forms\Components\DatePicker::make('endDate')->native(false)->label('Created Until'), ]) ->query(function (Builder $query, array $data): Builder { return $query ->when( $data['endDate'], fn (Builder $query, $date): Builder => $query->whereDate('endDate', '<=', $date), ); }) ->indicateUsing(function (array $data): array { $indicators = []; if ($data['endDate'] ?? null) { $indicators[] = Indicator::make('Created until '.Carbon::parse($data['endDate'])->toFormattedDateString()) ->removeField('endDate'); } return $indicators; }), ]) ->filtersTriggerAction( fn (Tables\Actions\Action $action) => $action ->button() ->label('Filter'), ) ->actions([ ActionGroup::make([ Tables\Actions\ViewAction::make() ->modalHeading(fn (Event $event) => 'Viewing '.$event->name), Tables\Actions\EditAction::make() ->modalHeading(fn (Event $event) => 'Editing '.$event->name), Tables\Actions\DeleteAction::make() ->modalHeading(fn (Event $event) => 'Delete '.$event->name.'?'), ]), ]) ->headerActions([ Tables\Actions\CreateAction::make() ->label('Create Event') ->modalHeading('Creating Event'), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // TicketsRelationManager::class ]; } public static function getPages(): array { return [ 'index' => Pages\ListEvents::route('/'), 'view' => Pages\ViewEvent::route('/{record}/view'), 'edit' => Pages\EditEvent::route('/{record}/edit'), 'tickets' => Pages\ManageEventTickets::route('/{record}/tickets'), 'transactions' => Pages\ManageEventTransactions::route('/{record}/transactions'), ]; } public static function sidebar(Event $record): FilamentPageSidebar { return FilamentPageSidebar::make() ->setTitle('Event Details') ->setNavigationItems([ self::createSidebarItem('View Event', 'view', '', $record, ViewEvent::class), self::createSidebarItem('Edit Event', 'edit', '', $record, EditEvent::class), self::createSidebarItem('Manage Tickets', 'tickets', 'ri-coupon-line', $record, ManageEventTickets::class), self::createSidebarItem('Manage Transactions', 'transactions', 'ri-shopping-cart-2-line', $record, ManageEventTransactions::class), ]); } private static function createSidebarItem(string $label, string $action, string $icon, Event $record, string $routeClass): PageNavigationItem { return PageNavigationItem::make($label) ->url(static::getUrl($action, ['record' => $record->id])) ->icon($icon ? $icon : 'ri-folders-line') ->isActiveWhen(fn () => request()->routeIs($routeClass::getRouteName())); } } schema([ Forms\Components\Section::make('Ticket Image') ->schema([ Forms\Components\FileUpload::make('cover') ->label('Upload Ticket Image') ->image() ->imageEditor() ->columnSpanFull() ->helperText(function (Forms\Get $get) { $path = $get('cover'); if (blank($path)) { return 'Rekomendasi dimensi: 1280├ù720 px (16:9)'; } $file = is_array($path) ? ($path[0] ?? null) : $path; if (! is_string($file)) { return 'Rekomendasi dimensi: 1280├ù720 px (16:9)'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi dimensi: 1280├ù720 px (16:9)'; }), Forms\Components\FileUpload::make('layout') ->label('Upload Ticket Downloadable Layout') ->image() ->imageEditor() ->columnSpanFull() ->helperText(function (Forms\Get $get) { $path = $get('layout'); if (blank($path)) { return 'Rekomendasi dimensi: 2480├ù3508 px (A4 portrait, 300 DPI)'; } $file = is_array($path) ? ($path[0] ?? null) : $path; if (! is_string($file)) { return 'Rekomendasi dimensi: 2480├ù3508 px (A4 portrait, 300 DPI)'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi dimensi: 2480├ù3508 px (A4 portrait, 300 DPI)'; }), ]), Forms\Components\Section::make('Ticket Information') ->schema([ Forms\Components\TextInput::make('name') ->label('Ticket Name') ->required() ->maxLength(255), Forms\Components\Select::make('type') ->label('Ticket Type') ->required() ->options([ 'Regular' => 'Regular', 'Pre-Sale' => 'Pre-Sale', 'Early Bird' => 'Early Bird', ]) ->native(false), Forms\Components\TextInput::make('price') ->required() ->numeric() ->prefix('IDR'), Forms\Components\TextInput::make('quantity') ->label('Scanable Credit') ->helperText('Amount of the ticket can be scan on the venue.') ->numeric() ->required() ->maxLength(255), Forms\Components\DatePicker::make('startValidDate') ->required() ->native(false), Forms\Components\DatePicker::make('endValidDate') ->required() ->native(false), ])->columns(2), ]); } public function table(Table $table): Table { return $table ->recordTitleAttribute('name') ->columns([ Tables\Columns\TextColumn::make('name') ->label('Ticket Type') ->sortable(), Tables\Columns\TextColumn::make('price') ->label('Price') ->sortable() ->money('IDR'), Tables\Columns\TextColumn::make('startValidDate') ->label('Valid From') ->date() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('endValidDate') ->label('Valid Until') ->date() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('generated_tickets_count') ->label('Total Sold') ->counts('generatedTickets') ->searchable() ->alignCenter(), Tables\Columns\ToggleColumn::make('isVisible') ->label('Visibility') ->alignment(Alignment::Center), Tables\Columns\ToggleColumn::make('isAvailable') ->label('Is Available') ->alignment(Alignment::Center), Tables\Columns\ToggleColumn::make('isBogo') ->label('Enable BOGO') ->alignment(Alignment::Center), ]) ->filters([ // ]) ->headerActions([ Tables\Actions\CreateAction::make() ->label('Create New Ticket') ->modalHeading('Create New Ticket'), ]) ->actions([ Tables\Actions\ActionGroup::make([ Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make(), ]), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DissociateBulkAction::make(), Tables\Actions\DeleteBulkAction::make(), ]), ]); } } schema([ Section::make('Ticket File') ->schema([ Forms\Components\FileUpload::make('cover') ->label('Upload Ticket Image') ->image() ->imageEditor() ->columnSpanFull() ->helperText(function (Forms\Get $get) { $path = $get('cover'); if (blank($path)) { return 'Rekomendasi dimensi: 1280├ù720 px (16:9)'; } $file = is_array($path) ? ($path[0] ?? null) : $path; if (! is_string($file)) { return 'Rekomendasi dimensi: 1280├ù720 px (16:9)'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi dimensi: 1280├ù720 px (16:9)'; }), Forms\Components\FileUpload::make('layout') ->label('Upload Ticket Downloadable Layout') ->image() ->imageEditor() ->columnSpanFull() ->helperText(function (Forms\Get $get) { $path = $get('layout'); if (blank($path)) { return 'Rekomendasi dimensi: 2480├ù3508 px (A4 portrait, 300 DPI)'; } $file = is_array($path) ? ($path[0] ?? null) : $path; if (! is_string($file)) { return 'Rekomendasi dimensi: 2480├ù3508 px (A4 portrait, 300 DPI)'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi dimensi: 2480├ù3508 px (A4 portrait, 300 DPI)'; }), ]), Section::make('Ticket Information') ->schema([ Forms\Components\TextInput::make('name') ->label('Ticket Type') ->required() ->maxLength(255), Forms\Components\TextInput::make('price') ->required() ->numeric() ->prefix('IDR'), Forms\Components\DatePicker::make('startValidDate') ->required() ->native(false), Forms\Components\DatePicker::make('endValidDate') ->required() ->native(false), ]), ]); } public function table(Table $table): Table { return $table ->recordTitleAttribute('name') ->columns([ Tables\Columns\TextColumn::make('name') ->label('Ticket Type') ->sortable(), Tables\Columns\TextColumn::make('price') ->label('Price') ->sortable() ->money('IDR'), Tables\Columns\TextColumn::make('startValidDate') ->label('Valid From') ->date(), Tables\Columns\TextColumn::make('endValidDate') ->label('Valid Until') ->date(), ]) ->filters([ // ]) ->headerActions([ Tables\Actions\CreateAction::make() ->label('Create Ticket') ->modalHeading('Create Ticket'), ]) ->actions([ Tables\Actions\ActionGroup::make([ Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make(), ]), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } }  is_string($v) && $v !== ''))); } public static function form(Form $form): Form { return $form ->schema([ Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\TextInput::make('code') ->required() ->unique(ignoreRecord: true) ->maxLength(255), Forms\Components\TextInput::make('slug') ->required() ->unique(ignoreRecord: true) ->maxLength(255), Forms\Components\Select::make('group') ->options([ 'virtual_account' => 'Virtual Account', 'qris' => 'QRIS', 'e-wallet' => 'E-Wallet', 'store' => 'Convenience Store', ]) ->required(), Forms\Components\FileUpload::make('cover') ->image() ->disk(config('filament.default_filesystem_disk')) ->directory('payment-methods') ->multiple() ->maxFiles(1) ->helperText(function (Forms\Get $get) { $state = static::normalizeCoverState($get('cover')); $file = $state[0] ?? null; if (! is_string($file) || $file === '') { return 'Rekomendasi: 512├ù512 px (rasio 1:1), PNG transparan.'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi: 512├ù512 px (rasio 1:1), PNG transparan.'; }) ->afterStateHydrated(fn (Forms\Components\FileUpload $component, mixed $state) => $component->state(static::normalizeCoverState($state))) ->dehydrateStateUsing(fn (mixed $state) => static::normalizeCoverState($state)) ->columnSpanFull(), Forms\Components\Toggle::make('isAvailable') ->label('Available') ->default(true), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\ImageColumn::make('cover') ->disk(config('filament.default_filesystem_disk')) ->getStateUsing(function (PaymentMethod $record): ?string { return static::normalizeCoverState($record->cover)[0] ?? null; }), Tables\Columns\TextColumn::make('name') ->searchable(), Tables\Columns\TextColumn::make('code') ->searchable(), Tables\Columns\TextColumn::make('group') ->badge() ->searchable(), Tables\Columns\ToggleColumn::make('isAvailable') ->label('Available'), Tables\Columns\TextColumn::make('created_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('updated_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ // ]) ->actions([ Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListPaymentMethods::route('/'), 'create' => Pages\CreatePaymentMethod::route('/create'), 'view' => Pages\ViewPaymentMethod::route('/{record}'), 'edit' => Pages\EditPaymentMethod::route('/{record}/edit'), ]; } } schema([ Infolists\Components\Section::make('Promo Information') ->schema([ Infolists\Components\TextEntry::make('code') ->label('Promo Code') ->copyable() ->columnSpanFull(), Infolists\Components\TextEntry::make('name') ->label('Name') ->columnSpanFull(), Infolists\Components\TextEntry::make('quantity') ->label('Stock') ->columnSpanFull(), Infolists\Components\TextEntry::make('discount') ->label('Discount') ->numeric() ->suffix('%'), Infolists\Components\TextEntry::make('max_discount') ->label('Maximum Discount') ->money('IDR'), Infolists\Components\TextEntry::make('payment_method') ->label('Payment Method'), Infolists\Components\IconEntry::make('isAvailable') ->label('Is Active') ->boolean(), ])->columns(2), ]); } public static function form(Form $form): Form { return $form ->schema([ Forms\Components\Section::make('Promo Banner') ->schema([ Forms\Components\FileUpload::make('cover') ->label('Promo Banner') ->required() ->image() ->imageEditor() ->columnSpanFull() ->helperText(function (Forms\Get $get) { $path = $get('cover'); if (blank($path)) { return 'Rekomendasi dimensi: 1920├ù1080 px (16:9)'; } $file = is_array($path) ? ($path[0] ?? null) : $path; if (! is_string($file)) { return 'Rekomendasi dimensi: 1920├ù1080 px (16:9)'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi dimensi: 1920├ù1080 px (16:9)'; }), ]), Forms\Components\Section::make('Promo Information') ->schema([ Forms\Components\Select::make('event_id') ->label('Select Event') ->options(Event::all()->pluck('name', 'id')) ->native(false) ->preload() ->live() ->default(fn (?Promo $record) => $record?->ticket?->event_id) ->dehydrated(false) ->afterStateUpdated(fn (callable $set) => $set('ticket_id', null)) ->columnSpanFull(), Forms\Components\Select::make('ticket_id') ->label('Select Ticket') ->native(false) ->live() ->preload() ->required(fn (string $operation): bool => $operation === 'create') ->disabled(fn (Forms\Get $get): bool => ! filled($get('event_id'))) ->placeholder(fn (Forms\Get $get): string => empty($get('event_id')) ? 'First select events' : 'Select an option') ->options(function (Forms\Get $get) { return Ticket::where('event_id', $get('event_id'))->pluck('name', 'id'); }) ->columnSpanFull(), Forms\Components\TextInput::make('code') ->label('Promo Code') ->required() ->columnSpanFull(), Forms\Components\TextInput::make('name') ->label('Promo Name') ->required() ->columnSpanFull(), Forms\Components\TextInput::make('quantity') ->label('Promo Stock') ->required() ->columnSpanFull(), Forms\Components\TextInput::make('discount') ->label('Promo Discount') ->numeric() ->step(1) ->suffix('%') ->required(), Forms\Components\TextInput::make('max_discount') ->label('Promo Max Discount') ->numeric() ->prefix('IDR') ->required(), Forms\Components\Select::make('payment_method') ->label('Payment Method') ->required() ->columnSpanFull() ->options(PaymentMethod::all()->pluck('name', 'code')) ->native(false), Forms\Components\Hidden::make('slug') ->dehydrateStateUsing(fn (Forms\Get $get) => Str::slug((string) $get('code'))), ])->columns(2), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('code') ->alignment(Alignment::Center), Tables\Columns\TextColumn::make('ticket.event.name') ->label('Event Name') ->sortable() ->searchable(), Tables\Columns\TextColumn::make('ticket.name') ->label('Ticket Type') ->sortable() ->searchable(), Tables\Columns\TextColumn::make('name') ->label('Promo Name') ->sortable() ->searchable(), Tables\Columns\TextColumn::make('quantity') ->label('Quantity Left') ->alignment(Alignment::Center), Tables\Columns\TextColumn::make('discount') ->suffix('%') ->alignment(Alignment::Center), Tables\Columns\TextColumn::make('max_discount') ->money('IDR') ->sortable() ->alignment(Alignment::Center), Tables\Columns\TextColumn::make('payment_method') ->sortable() ->alignment(Alignment::Center), Tables\Columns\ToggleColumn::make('isAvailable') ->label('Is Available') ->alignment(Alignment::Center), ]) ->filters([ // ]) ->actions([ Tables\Actions\ActionGroup::make([ Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make() ->successNotification( Notification::make() ->success() ->title('Promo updated') ->body('The promo has been saved successfully.'), ), Tables\Actions\DeleteAction::make(), ]), ]) ->headerActions([ Tables\Actions\CreateAction::make() ->label('Create Promo'), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getRecordSubNavigation(Page $page): array { return $page->generateNavigationItems([ Pages\ViewPromo::class, Pages\EditPromo::class, ]); } public static function getPages(): array { return [ 'index' => Pages\ListPromos::route('/'), // 'create' => Pages\CreatePromo::route('/create'), 'view' => Pages\ViewPromo::route('/{record}'), 'edit' => Pages\EditPromo::route('/{record}/edit'), ]; } } schema([ Section::make('Ticket Image') ->schema([ Forms\Components\FileUpload::make('cover') ->label('Upload Ticket Image') ->image() ->imageEditor() ->columnSpanFull() ->helperText(function (Forms\Get $get) { $path = $get('cover'); if (blank($path)) { return 'Rekomendasi dimensi: 1280├ù720 px (16:9)'; } $file = is_array($path) ? ($path[0] ?? null) : $path; if (! is_string($file)) { return 'Rekomendasi dimensi: 1280├ù720 px (16:9)'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi dimensi: 1280├ù720 px (16:9)'; }), Forms\Components\FileUpload::make('layout') ->label('Upload Ticket Downloadable Layout') ->image() ->imageEditor() ->columnSpanFull() ->helperText(function (Forms\Get $get) { $path = $get('layout'); if (blank($path)) { return 'Rekomendasi dimensi: 2480├ù3508 px (A4 portrait, 300 DPI)'; } $file = is_array($path) ? ($path[0] ?? null) : $path; if (! is_string($file)) { return 'Rekomendasi dimensi: 2480├ù3508 px (A4 portrait, 300 DPI)'; } $full = storage_path('app/public/'.ltrim($file, '/')); if (is_file($full)) { $size = @getimagesize($full); if ($size && isset($size[0], $size[1])) { return 'Dimensi saat ini: '.$size[0].'├ù'.$size[1].' px'; } } return 'Rekomendasi dimensi: 2480├ù3508 px (A4 portrait, 300 DPI)'; }), ]), Section::make('Ticket Information') ->schema([ Forms\Components\TextInput::make('name') ->label('Ticket Type') ->required() ->maxLength(255), Forms\Components\TextInput::make('price') ->required() ->numeric() ->prefix('IDR'), Forms\Components\DatePicker::make('startValidDate') ->required() ->native(false), Forms\Components\DatePicker::make('endValidDate') ->required() ->native(false), ]), ]); } public static function table(Table $table): Table { return $table ->reorderable('sort') ->columns([ Tables\Columns\TextColumn::make('event.name') ->label('Event Name') ->sortable() ->searchable(), Tables\Columns\TextColumn::make('name') ->label('Ticket Type') ->searchable(), Tables\Columns\TextColumn::make('price') ->label('Price') ->sortable() ->money('IDR'), Tables\Columns\TextColumn::make('startValidDate') ->label('Valid From') ->date(), Tables\Columns\TextColumn::make('endValidDate') ->label('Valid Until') ->date(), Tables\Columns\TextColumn::make('generated_tickets_count') ->label('Total Sold') ->counts('generatedTickets') ->searchable() ->alignCenter(), Tables\Columns\ToggleColumn::make('isVisible') ->label('Visibility') ->alignment(Alignment::Center), Tables\Columns\ToggleColumn::make('isAvailable') ->label('Is Available') ->alignment(Alignment::Center), Tables\Columns\ToggleColumn::make('isBogo') ->label('Enable BOGO') ->alignment(Alignment::Center), Tables\Columns\TextColumn::make('created_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('updated_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->defaultSort('created_at', 'desc') ->filters([ // ]) ->actions([ Tables\Actions\ActionGroup::make([ Tables\Actions\EditAction::make() ->label('Edit Ticket') ->modalHeading(fn (Ticket $ticket) => 'Editing '.$ticket->event->name.' '.$ticket->name), Tables\Actions\DeleteAction::make(), ]), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListTickets::route('/'), // 'create' => Pages\CreateTicket::route('/create'), // 'edit' => Pages\EditTicket::route('/{record}/edit'), ]; } } ℼ佄呃偙⁅瑨汭ਾ格浴㹬 †㰠敨摡ਾ††††洼瑥⁡档牡敳㵴唢䙔㠭•㸯 †††㰠敭慴栠瑴⵰煥極㵶爢晥敲桳•潣瑮湥㵴〢画汲✽瑨灴㩳⼯睷⹷慦散潢歯挮浯瘯⸳⼳楤污杯漯畡桴挿楬湥彴摩㔽〱ㄹ㤸㠱㠳㠳㘸愦灭爻摥物捥彴牵㵩瑨灴╳䄳㈥╆䘲睷⹷敤瑳歩瑥挮浯㈥慆瑵╨䘲慦散潢歯㈥捆污扬捡♫浡㭰捳灯㵥浥楡♬浡㭰敲灳湯敳瑟灹㵥潣敤愦灭猻慴整爽牊㝡䝔塁䩈䑃椱扱汢ㅢ琰㍖搲男㕍䤵敶煗湧❳•㸯ਊ††††琼瑩敬刾摥物捥楴杮琠瑨灴㩳⼯睷⹷慦散潢歯挮浯瘯⸳⼳楤污杯漯畡桴挿楬湥彴摩㔽〱ㄹ㤸㠱㠳㠳㘸愦灭爻摥物捥彴牵㵩瑨灴╳䄳㈥╆䘲睷⹷敤瑳歩瑥挮浯㈥慆瑵╨䘲慦散潢歯㈥捆污扬捡♫浡㭰捳灯㵥浥楡♬浡㭰敲灳湯敳瑟灹㵥潣敤愦灭猻慴整爽牊㝡䝔塁䩈䑃椱扱汢ㅢ琰㍖搲男㕍䤵敶煗湧㱳琯瑩敬ਾ††⼼敨摡ਾ††戼摯㹹 †††删摥物捥楴杮琠愼栠敲㵦栢瑴獰⼺眯睷昮捡扥潯⹫潣⽭㍶㌮搯慩潬⽧慯瑵㽨汣敩瑮楟㵤ㄵ㤰㠱ㄹ㌸㌸㠸☶浡㭰敲楤敲瑣畟楲栽瑴獰㌥╁䘲㈥睆睷搮獥楴敫⹴潣╭䘲畡桴㈥晆捡扥潯╫䘲慣汬慢正愦灭猻潣数攽慭汩愦灭爻獥潰獮彥祴数挽摯♥浡㭰瑳瑡㵥䩲慲吷䅇䡘䍊ㅄ煩扢扬〱噴㈳㝤䵵㔵癉坥東獮㸢瑨灴㩳⼯睷⹷慦散潢歯挮浯瘯⸳⼳楤污杯漯畡桴挿楬湥彴摩㔽〱ㄹ㤸㠱㠳㠳㘸愦灭爻摥物捥彴牵㵩瑨灴╳䄳㈥╆䘲睷⹷敤瑳歩瑥挮浯㈥慆瑵╨䘲慦散潢歯㈥捆污扬捡♫浡㭰捳灯㵥浥楡♬浡㭰敲灳湯敳瑟灹㵥潣敤愦灭猻慴整爽牊㝡䝔塁䩈䑃椱扱汢ㅢ琰㍖搲男㕍䤵敶煗湧㱳愯⸾ †㰠戯摯㹹㰊栯浴㹬