schema([ Forms\Components\TextInput::make('mobile_number') ->label('Mobile Number') ->length(10) ->reactive() ->extraInputAttributes([ 'oninput' => 'this.value = this.value.replace(/[^0-9]/g, "").slice(0, 10)', // blocks non-numbers + limits to 10 chars 'maxlength' => 10, ]) ->required() ->extraAttributes([ 'id' => 'mobile_number_input', 'x-data' => '{ value: "" }', 'x-model' => 'value', 'wire:keydown.enter.prevent' => 'processMobile(value)', ]), Forms\Components\TextInput::make('name') ->label('Name') ->required() ->reactive() ->extraInputAttributes([ 'oninput' => 'this.value = this.value.replace(/[^a-zA-Z\s]/g, "")', ]), Forms\Components\Select::make('type') ->label('Type') ->reactive() ->options([ 'Student' => 'Student', 'Consultant' => 'Consultant', 'Vendor' => 'Vendor', 'Other' => 'Other', ]) ->required() ->dehydrateStateUsing(function ($state, callable $get) { return $state == 'Other' ? $get('other_type') : $state; }), Forms\Components\TextInput::make('other_type') ->label('Specify Type') ->reactive() ->visible(fn (callable $get) => $get('type') == 'Other') ->required(fn (callable $get) => $get('type') == 'Other') ->dehydrated(false), Forms\Components\TextInput::make('company') ->label('Company') ->required(), Forms\Components\Select::make('department') ->label('Employee Department') ->options( \App\Models\EmployeeMaster::distinct() ->pluck('department', 'department') ) ->required() ->reactive() ->afterStateUpdated(function (callable $set) { $set('employee_master_id', null); $set('code', null); }), // Forms\Components\Select::make('employee_master_id') // ->label('Recipient Employee') // ->required() // ->options(function (callable $get) { // $department = $get('department'); // if (!$department) { // return []; // } // return \App\Models\EmployeeMaster::where('department', $department) // ->pluck('name', 'id'); // }) // ->reactive() // ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { // $department = $get('department'); // $employee = \App\Models\EmployeeMaster::where('id', $state) // ->where('department', $department) // ->first(); // $set('code', $employee ? $employee->code : ''); // }), Forms\Components\Select::make('employee_master_id') ->label('Recipient Employee') ->required() ->options(function (callable $get) { $department = $get('department'); // Always load ALL employees, filter by department if set if ($department) { return \App\Models\EmployeeMaster::where('department', $department) ->pluck('name', 'id'); } // Fallback: load all so fill() can always match the ID return \App\Models\EmployeeMaster::pluck('name', 'id'); }) ->reactive() ->afterStateUpdated(function (callable $set, ?string $state) { $employee = \App\Models\EmployeeMaster::find($state); $set('code', $employee?->code ?? ''); }), Forms\Components\TextInput::make('code') ->label('Employee Code') ->readOnly(), Forms\Components\Textarea::make('purpose_of_visit') ->label('Purpose of Visit') ->required(), Forms\Components\TextInput::make('number_of_person') ->numeric() ->default(1) ->required(), Forms\Components\DateTimePicker::make('in_time') ->label('In Time'), Forms\Components\DateTimePicker::make('out_time') ->label('Out Time'), Forms\Components\View::make('components.webcam-field') ->columnSpanFull(), Forms\Components\Hidden::make('photo'), Forms\Components\Hidden::make('created_by') ->label('created_by') ->default(Filament::auth()->user()?->name), Forms\Components\Hidden::make('updated_by') ->label('updated_by') ->default(Filament::auth()->user()?->name), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('No.') ->label('NO') ->alignCenter() ->getStateUsing(function ($record, $livewire, $column, $rowLoop) { $paginator = $livewire->getTableRecords(); $perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10; $currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1; return ($currentPage - 1) * $perPage + $rowLoop->iteration; }), Tables\Columns\ImageColumn::make('photo') ->label('Photo') ->disk('public') ->height(50) ->width(50) ->defaultImageUrl('https://ui-avatars.com/api/?name=Visitor&background=555&color=fff') ->alignCenter() ->extraImgAttributes(['style' => 'border-radius: 6px; object-fit: cover;']), Tables\Columns\TextColumn::make('type') ->label('Visitor Type') ->alignCenter() ->sortable(), Tables\Columns\TextColumn::make('name') ->label('Visitor Name') ->sortable() ->alignCenter() ->searchable(), Tables\Columns\TextColumn::make('mobile_number') ->label('Visitor Mobile Number') ->alignCenter() ->sortable(), Tables\Columns\TextColumn::make('employeeMaster.name') ->label('Recipient Name') ->alignCenter() ->sortable(), Tables\Columns\TextColumn::make('employeeMaster.code') ->label('Receipient ID') ->alignCenter() ->sortable(), Tables\Columns\TextColumn::make('employeeMaster.department') ->label('Receipient Department') ->alignCenter() ->sortable(), Tables\Columns\TextColumn::make('number_of_person') ->label('Number of Person') ->numeric() ->alignCenter() ->sortable(), Tables\Columns\TextColumn::make('in_time') ->label('In Time') ->dateTime() ->sortable() ->alignCenter(), Tables\Columns\TextColumn::make('out_time') ->label('Out Time') ->dateTime() ->sortable() ->alignCenter(), Tables\Columns\TextColumn::make('created_at') ->label('Created At') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true) ->alignCenter(), Tables\Columns\TextColumn::make('updated_at') ->label('Updated At') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true) ->alignCenter(), Tables\Columns\TextColumn::make('deleted_at') ->label('Deleted At') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true) ->alignCenter(), ]) ->filters([ Tables\Filters\TrashedFilter::make(), ]) ->actions([ Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), Tables\Actions\ForceDeleteBulkAction::make(), Tables\Actions\RestoreBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListVisitorEntries::route('/'), 'create' => Pages\CreateVisitorEntry::route('/create'), 'view' => Pages\ViewVisitorEntry::route('/{record}'), 'edit' => Pages\EditVisitorEntry::route('/{record}/edit'), ]; } public static function getEloquentQuery(): Builder { return parent::getEloquentQuery() ->withoutGlobalScopes([ SoftDeletingScope::class, ]); } }