label('Beri Suara') ->icon('heroicon-o-hand-raised') ->color('info') ->visible(fn () => $this->record->status === 'open' && ! $this->record->items()->where('user_id', auth()->id())->exists() && (! $this->record->deadline || $this->record->deadline->isFuture())) ->form([ \Filament\Forms\Components\Radio::make('choice') ->label('Pilihan Anda') ->options([ 'approve' => '✓ Setuju', 'reject' => '✗ Tidak Setuju', 'abstain' => '○ Abstain', ]) ->required(), ]) ->action(function (array $data): void { VoteItem::create([ 'vote_id' => $this->record->id, 'user_id' => auth()->id(), 'choice' => $data['choice'], ]); $this->refreshFormData([]); }), EditAction::make(), ]; } public function infolist(Schema $infolist): Schema { $record = $this->record; $total = $record->items()->count(); $approve = $record->items()->where('choice', 'approve')->count(); $reject = $record->items()->where('choice', 'reject')->count(); $abstain = $record->items()->where('choice', 'abstain')->count(); $quorum = $total > 0 && ($approve / $total) > 0.5 ? '✓ Mayoritas Setuju' : '✗ Belum Mayoritas'; return $infolist->schema([ Section::make('Detail Voting')->schema([ TextEntry::make('title')->label('Judul'), TextEntry::make('description')->label('Deskripsi'), TextEntry::make('type')->badge(), TextEntry::make('status')->badge() ->color(fn ($state) => $state === 'open' ? 'success' : 'gray'), TextEntry::make('deadline')->label('Batas Waktu')->dateTime('d M Y H:i'), TextEntry::make('creator.name')->label('Dibuat Oleh'), ])->columns(2), Section::make('Rekapitulasi Suara')->schema([ TextEntry::make('total')->label('Total Suara')->state($total), TextEntry::make('approve')->label('Setuju')->state($approve) ->color('success'), TextEntry::make('reject')->label('Tidak Setuju')->state($reject) ->color('danger'), TextEntry::make('abstain')->label('Abstain')->state($abstain) ->color('gray'), TextEntry::make('result')->label('Hasil')->state($total > 0 ? $quorum : '-') ->color($total > 0 && ($approve / max($total, 1)) > 0.5 ? 'success' : 'warning'), ])->columns(5), ]); } }