schema([ TextInput::make('rating') ->label('Rating') ->disabled(), TextInput::make('title') ->label('Title') ->disabled(), Textarea::make('body') ->label('Body') ->disabled() ->columnSpanFull(), Group::make([ TextInput::make('reviewer_name') ->label('Reviewer name') ->disabled(), TextInput::make('reviewer_email') ->label('Reviewer email') ->disabled(), ])->columns(2), Group::make([ TextInput::make('location') ->label('Location') ->disabled(), TextInput::make('source') ->label('Source') ->disabled(), ])->columns(2), Group::make([ TextInput::make('reviewed_at') ->label('Reviewed at') ->disabled(), TextInput::make('replied_at') ->label('Replied at') ->disabled(), ])->columns(2), Textarea::make('reply') ->label('Reply') ->disabled() ->columnSpanFull(), Placeholder::make('images') ->label('Images') ->content(function (?ProductReview $record) { if (! $record) { return null; } $media = $record->getMedia(ProductReview::IMAGES_COLLECTION); if ($media->isEmpty()) { return 'No images'; } $tags = $media->map(fn ($item) => sprintf( '', $item->getUrl(), ))->implode(''); return new HtmlString($tags); }) ->columnSpanFull(), ]); } public function table(Table $table): Table { return $table ->recordTitleAttribute('title') ->columns([ TextColumn::make('rating') ->label('Rating') ->formatStateUsing(fn (int $state) => str_repeat('★', $state).str_repeat('☆', 5 - $state)) ->sortable(), TextColumn::make('title') ->label('Title') ->limit(40) ->searchable(), TextColumn::make('reviewer_name') ->label('Reviewer') ->searchable(), ]) ->defaultSort('reviewed_at', 'desc') ->filters([ // ]) ->actions([ ViewAction::make(), Action::make('reply') ->label(fn (ProductReview $record) => $record->reply ? 'Edit reply' : 'Reply') ->icon('heroicon-o-chat-bubble-left-right') ->form([ Textarea::make('reply') ->label('Reply') ->required(), ]) ->fillForm(fn (ProductReview $record) => ['reply' => $record->reply]) ->action(function (ProductReview $record, array $data) { $record->update([ 'reply' => $data['reply'], 'replied_at' => Carbon::now(), ]); }), DeleteAction::make(), ]) ->bulkActions([ DeleteBulkAction::make(), ]); } }