Files
Virtnet.bond/extensions/Others/SocialBase/Admin/Resources/ProfileCommentResource.php
2025-11-30 11:57:22 +01:00

209 lines
8.0 KiB
PHP

<?php
namespace Paymenter\Extensions\Others\SocialBase\Admin\Resources;
use Filament\Resources\Resource;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Paymenter\Extensions\Others\SocialBase\Models\ProfileComment;
use Paymenter\Extensions\Others\SocialBase\Admin\Clusters\ProfilesCluster;
use Illuminate\Support\Facades\Auth;
use Filament\Tables\Actions;
use Filament\Notifications\Notification;
class ProfileCommentResource extends Resource
{
protected static ?string $model = ProfileComment::class;
protected static ?string $navigationIcon = 'heroicon-o-chat-bubble-left-right';
protected static ?string $navigationLabel = 'Profile Comments';
protected static ?string $cluster = ProfilesCluster::class;
protected static ?int $navigationSort = 20;
public static function form(Form $form): Form
{
return $form->schema([
Forms\Components\TextInput::make('commenter_name')
->label('Commenter')
->afterStateHydrated(function ($component, $state, $record) {
if ($record && $record->user) {
$component->state($record->user->name . ' (' . $record->user->email . ')');
} else {
$component->state('Unknown User');
}
})
->disabled(),
Forms\Components\TextInput::make('profile_owner')
->label('Profile Owner')
->afterStateHydrated(function ($component, $state, $record) {
if ($record && $record->profile && $record->profile->user) {
$component->state($record->profile->user->name . ' (@' . $record->profile->display_name . ')');
} else {
$component->state('Unknown Profile');
}
})
->disabled(),
Forms\Components\Textarea::make('content')
->label('Comment Content')
->rows(4)
->required()
->maxLength(1000),
Forms\Components\Toggle::make('approved')
->label('Approved')
->default(false)
->helperText('Whether this comment is visible on the profile'),
Forms\Components\TextInput::make('parent_comment')
->label('Parent Comment')
->afterStateHydrated(function ($component, $state, $record) {
if ($record && $record->parent_id) {
$parent = $record->parent;
$component->state($parent ? 'Reply to: ' . substr($parent->content, 0, 50) . '...' : 'Reply (parent deleted)');
} else {
$component->state('Top-level comment');
}
})
->disabled(),
Forms\Components\Placeholder::make('reactions_count')
->label('Total Reactions')
->content(function ($record) {
return $record ? $record->reactions()->count() : '0';
}),
Forms\Components\DateTimePicker::make('created_at')
->label('Created At')
->disabled(),
Forms\Components\DateTimePicker::make('updated_at')
->label('Last Updated')
->disabled(),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('id')
->label('ID')
->sortable(),
Tables\Columns\TextColumn::make('user.name')
->label('Commenter')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('profile.user.name')
->label('Profile Owner')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('content')
->label('Comment')
->limit(50)
->searchable(),
Tables\Columns\IconColumn::make('parent_id')
->label('Reply')
->boolean()
->trueIcon('heroicon-o-reply')
->falseIcon('heroicon-o-chat-bubble-left')
->getStateUsing(fn ($record) => $record->parent_id !== null),
Tables\Columns\BadgeColumn::make('approved')
->label('Status')
->formatStateUsing(fn ($state) => $state ? 'Approved' : 'Pending')
->colors([
'success' => true,
'warning' => false,
]),
Tables\Columns\TextColumn::make('reactions_count')
->label('Reactions')
->counts('reactions')
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Posted')
->dateTime()
->sortable(),
])
->filters([
Tables\Filters\TernaryFilter::make('approved')
->label('Approval Status')
->placeholder('All comments')
->trueLabel('Approved only')
->falseLabel('Pending only'),
Tables\Filters\TernaryFilter::make('parent_id')
->label('Comment Type')
->placeholder('All comments')
->trueLabel('Replies only')
->falseLabel('Top-level only')
->queries(
true: fn (Builder $query) => $query->whereNotNull('parent_id'),
false: fn (Builder $query) => $query->whereNull('parent_id'),
),
Tables\Filters\Filter::make('pending')
->query(fn (Builder $query): Builder => $query->where('approved', false))
->label('Pending Approval')
->default(),
])
->defaultSort('created_at', 'desc')
->actions([
Actions\EditAction::make(),
Actions\DeleteAction::make()
->successNotificationTitle('Comment deleted')
->before(function ($record) {
$record->reactions()->delete();
$record->replies()->delete();
}),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make()
->successNotificationTitle('Comments deleted')
->before(function ($records) {
foreach ($records as $record) {
$record->reactions()->delete();
$record->replies()->delete();
}
}),
]);
}
public static function getPages(): array
{
return [
'index' => \Paymenter\Extensions\Others\SocialBase\Admin\Resources\ProfileCommentResource\Pages\ListProfileComments::route('/'),
'view' => \Paymenter\Extensions\Others\SocialBase\Admin\Resources\ProfileCommentResource\Pages\ViewProfileComment::route('/{record}'),
'edit' => \Paymenter\Extensions\Others\SocialBase\Admin\Resources\ProfileCommentResource\Pages\EditProfileComment::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->with(['user', 'profile.user', 'parent']);
}
public static function getNavigationBadge(): ?string
{
$count = static::getModel()::where('approved', false)->count();
return $count > 0 ? (string) $count : null;
}
public static function canViewAny(): bool
{
$user = Auth::user();
return $user && $user->hasPermission('socialbase.comments.view');
}
}