Add all files
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
<?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 Paymenter\Extensions\Others\SocialBase\Models\Conversation;
|
||||
use Paymenter\Extensions\Others\SocialBase\Admin\Clusters\MessagingCluster;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class ConversationResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Conversation::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-chat';
|
||||
protected static ?string $navigationLabel = 'Conversations';
|
||||
protected static ?string $cluster = MessagingCluster::class;
|
||||
protected static ?int $navigationSort = 3;
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form->schema([
|
||||
Forms\Components\TextInput::make('id')
|
||||
->label('Conversation ID')
|
||||
->disabled(),
|
||||
|
||||
Forms\Components\TextInput::make('type')
|
||||
->label('Type')
|
||||
->afterStateHydrated(function ($component, $state, $record) {
|
||||
if ($record) {
|
||||
$component->state(ucfirst($record->type));
|
||||
}
|
||||
})
|
||||
->disabled(),
|
||||
|
||||
Forms\Components\TextInput::make('subject')
|
||||
->label('Subject')
|
||||
->disabled(),
|
||||
|
||||
Forms\Components\Textarea::make('participants_list')
|
||||
->label('Participants')
|
||||
->afterStateHydrated(function ($component, $state, $record) {
|
||||
if (!$record) {
|
||||
$component->state('—');
|
||||
return;
|
||||
}
|
||||
|
||||
$participants = $record->participants()->get();
|
||||
$names = $participants->map(fn($p) => $p->name . ' (' . $p->email . ')')->join("\n");
|
||||
$component->state($names);
|
||||
})
|
||||
->disabled()
|
||||
->rows(3),
|
||||
|
||||
Forms\Components\TextInput::make('created_at')
|
||||
->label('Created At')
|
||||
->afterStateHydrated(function ($component, $state, $record) {
|
||||
if ($record) {
|
||||
$component->state($record->created_at->format('M j, Y g:i A'));
|
||||
}
|
||||
})
|
||||
->disabled(),
|
||||
|
||||
Forms\Components\TextInput::make('last_message_at')
|
||||
->label('Last Message')
|
||||
->afterStateHydrated(function ($component, $state, $record) {
|
||||
if ($record && $record->last_message_at) {
|
||||
$component->state($record->last_message_at->format('M j, Y g:i A'));
|
||||
} else {
|
||||
$component->state('—');
|
||||
}
|
||||
})
|
||||
->disabled(),
|
||||
|
||||
Forms\Components\TextInput::make('messages_count')
|
||||
->label('Total Messages')
|
||||
->afterStateHydrated(function ($component, $record) {
|
||||
if ($record) {
|
||||
$component->state($record->messages()->count());
|
||||
}
|
||||
})
|
||||
->disabled(),
|
||||
|
||||
Forms\Components\Placeholder::make('view_messages_link')
|
||||
->label('View Messages')
|
||||
->content(function ($record) {
|
||||
if (!$record) return '—';
|
||||
|
||||
$baseUrl = \Paymenter\Extensions\Others\SocialBase\Admin\Resources\MessageModerationResource::getUrl('index');
|
||||
$url = $baseUrl . '?filters[conversation_id][value]=' . $record->id;
|
||||
|
||||
return new HtmlString(
|
||||
'<a href="' . e($url) . '" class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors">' .
|
||||
'<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">' .
|
||||
'<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path>' .
|
||||
'</svg>' .
|
||||
'View All ' . $record->messages()->count() . ' Messages' .
|
||||
'</a>'
|
||||
);
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')
|
||||
->label('ID')
|
||||
->sortable()
|
||||
->searchable(),
|
||||
|
||||
Tables\Columns\TextColumn::make('type')
|
||||
->label('Type')
|
||||
->badge()
|
||||
->color(fn(string $state): string => match ($state) {
|
||||
'direct' => 'success',
|
||||
'system' => 'info',
|
||||
default => 'gray',
|
||||
})
|
||||
->formatStateUsing(fn(string $state): string => ucfirst($state))
|
||||
->sortable(),
|
||||
|
||||
Tables\Columns\TextColumn::make('participants_names')
|
||||
->label('Participants')
|
||||
->getStateUsing(function ($record) {
|
||||
$participants = $record->participants()->get();
|
||||
return $participants->map(fn($p) => $p->name)->join(', ');
|
||||
})
|
||||
->searchable()
|
||||
->wrap(),
|
||||
|
||||
Tables\Columns\TextColumn::make('messages_count')
|
||||
->label('Messages')
|
||||
->counts('messages')
|
||||
->sortable(),
|
||||
|
||||
Tables\Columns\TextColumn::make('flagged_messages_count')
|
||||
->label('Flagged')
|
||||
->getStateUsing(function ($record) {
|
||||
return $record->messages()->where('moderation_status', 'flagged')->count();
|
||||
})
|
||||
->badge()
|
||||
->color(fn($state) => $state > 0 ? 'danger' : 'success')
|
||||
->sortable(),
|
||||
|
||||
Tables\Columns\TextColumn::make('last_message_at')
|
||||
->label('Last Message')
|
||||
->dateTime('M j, Y g:i A')
|
||||
->sortable()
|
||||
->default('—'),
|
||||
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->label('Created')
|
||||
->dateTime('M j, Y')
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('type')
|
||||
->label('Type')
|
||||
->options([
|
||||
'direct' => 'Direct',
|
||||
'system' => 'System',
|
||||
]),
|
||||
Tables\Filters\Filter::make('has_messages')
|
||||
->label('Has Messages')
|
||||
->query(fn($query) => $query->has('messages')),
|
||||
Tables\Filters\Filter::make('has_flagged_messages')
|
||||
->label('Has Flagged Messages')
|
||||
->query(fn($query) => $query->whereHas('messages', function ($q) {
|
||||
$q->where('moderation_status', 'flagged');
|
||||
})),
|
||||
Tables\Filters\Filter::make('recent_activity')
|
||||
->label('Recent Activity (24h)')
|
||||
->query(fn($query) => $query->where('last_message_at', '>=', now()->subDay())),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make()
|
||||
->before(function ($record) {
|
||||
$record->messages()->delete();
|
||||
$record->participants()->detach();
|
||||
})
|
||||
->successNotificationTitle('Conversation deleted'),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\DeleteBulkAction::make()
|
||||
->before(function ($records) {
|
||||
foreach ($records as $record) {
|
||||
$record->messages()->delete();
|
||||
$record->participants()->detach();
|
||||
}
|
||||
})
|
||||
->successNotificationTitle('Conversations deleted'),
|
||||
])
|
||||
->defaultSort('last_message_at', 'desc')
|
||||
->poll('30s');
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => \Paymenter\Extensions\Others\SocialBase\Admin\Resources\ConversationResource\Pages\ListConversations::route('/'),
|
||||
'view' => \Paymenter\Extensions\Others\SocialBase\Admin\Resources\ConversationResource\Pages\ViewConversation::route('/{record}'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canCreate(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function canEdit($record): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getNavigationBadge(): ?string
|
||||
{
|
||||
$count = static::getModel()::whereHas('messages', function ($query) {
|
||||
$query->where('moderation_status', 'flagged');
|
||||
})->count();
|
||||
|
||||
return $count > 0 ? (string)$count : null;
|
||||
}
|
||||
|
||||
public static function getNavigationBadgeColor(): ?string
|
||||
{
|
||||
$count = static::getModel()::whereHas('messages', function ($query) {
|
||||
$query->where('moderation_status', 'flagged');
|
||||
})->count();
|
||||
|
||||
return $count > 3 ? 'danger' : ($count > 0 ? 'warning' : null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user