Files
riksdagen-app/app/Livewire/Party/Show.php
Oskar-Mikael 1576048402
All checks were successful
Deploy App / deploy (push) Successful in 10s
Add party page
2025-12-27 17:15:59 +01:00

230 lines
5.9 KiB
PHP

<?php
namespace App\Livewire\Party;
use App\Enums\Parties as PartyEnum;
use App\Services\RiksdagenService;
use Asantibanez\LivewireCharts\Models\ColumnChartModel;
use Asantibanez\LivewireCharts\Models\PieChartModel;
use Illuminate\Support\Facades\Cache;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Lazy;
use Livewire\Component;
#[Lazy()]
class Show extends Component
{
public $partyCode;
public $party;
public $motions = [];
public $members = [];
public $votes = [];
public $selectedYear = '';
private RiksdagenService $service;
public function mount($partyCode)
{
$this->partyCode = strtoupper($partyCode);
$this->service = app(RiksdagenService::class);
// Find party info
$this->party = collect(PartyEnum::cases())
->firstWhere('value', $this->partyCode);
if (! $this->party) {
abort(404);
}
$this->loadPartyData();
}
public function loadPartyData()
{
// Load party motions
$this->loadMotions();
// Load party members
$this->loadMembers();
// Load voting data for members
$this->loadVotingData();
}
public function loadMotions()
{
$result = Cache::remember('party_motions_'.$this->partyCode, 60 * 30, function () {
return $this->service->getPartyMotions($this->partyCode);
});
$this->motions = $result->original->dokumentlista->dokument ?? [];
// Set default selected year if motions exist
if (! empty($this->motions)) {
$years = collect($this->motions)->pluck('rm')->unique()->sort()->reverse();
$this->selectedYear = $years->first();
}
}
public function loadMembers()
{
$result = Cache::remember('party_members_'.$this->partyCode, 24 * 60 * 60, function () {
return $this->service->searchPerson(party: $this->partyCode);
});
$this->members = $result->original->personlista->person ?? [];
}
public function loadVotingData()
{
// For now, load voting data for a sample of members due to API limitations
$sampleMembers = collect($this->members)->take(5);
foreach ($sampleMembers as $member) {
$memberVotes = Cache::remember('member_votes_'.$member->intressent_id, 60 * 60, function () use ($member) {
return $this->service->searchVotes(mp_id: $member->intressent_id);
});
$votes = $memberVotes->original->voteringlista->votering ?? [];
$this->votes = array_merge($this->votes, is_array($votes) ? $votes : [$votes]);
}
}
public function selectYear($year)
{
$this->selectedYear = $year;
}
#[Computed()]
public function motionsByYear()
{
$grouped = [];
foreach ($this->motions as $motion) {
$rm = $motion->rm;
if (! isset($grouped[$rm])) {
$grouped[$rm] = [];
}
$grouped[$rm][] = $motion;
}
return $grouped;
}
#[Computed()]
public function motionStatistics()
{
$stats = [
'total' => count($this->motions),
'by_year' => [],
'by_type' => [],
];
foreach ($this->motions as $motion) {
// By year
$year = $motion->rm;
$stats['by_year'][$year] = ($stats['by_year'][$year] ?? 0) + 1;
// By type
$type = $motion->subtyp ?? 'Okänd';
$stats['by_type'][$type] = ($stats['by_type'][$type] ?? 0) + 1;
}
return $stats;
}
#[Computed()]
public function votingStatistics()
{
$stats = [];
foreach ($this->votes as $vote) {
$voteType = $vote->rost ?? 'Okänd';
$stats[$voteType] = ($stats[$voteType] ?? 0) + 1;
}
return $stats;
}
#[Computed()]
public function motionsColumnChart()
{
$motionStats = $this->motionStatistics;
$chart = (new ColumnChartModel)
->setTitle('Motioner per år')
->setAnimated(true)
->withDataLabels();
$colors = ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6'];
$colorIndex = 0;
foreach ($motionStats['by_year'] as $year => $count) {
$chart->addColumn($year, $count, $colors[$colorIndex % count($colors)]);
$colorIndex++;
}
return $chart;
}
#[Computed()]
public function motionTypePieChart()
{
$motionStats = $this->motionStatistics;
$chart = (new PieChartModel)
->setTitle('Motioner per typ')
->setAnimated(true)
->withDataLabels();
$colors = ['#3B82F6', '#10B981', '#F59E0B', '#EF4444'];
$colorIndex = 0;
foreach ($motionStats['by_type'] as $type => $count) {
$chart->addSlice($type, $count, $colors[$colorIndex % count($colors)]);
$colorIndex++;
}
return $chart;
}
#[Computed()]
public function votingPieChart()
{
$votingStats = $this->votingStatistics;
$chart = (new PieChartModel)
->setTitle('Röstfördelning (urval av ledamöter)')
->setAnimated(true)
->withDataLabels();
$colors = [
'Ja' => '#10b981',
'Nej' => '#ef4444',
'Frånvarande' => '#6b7280',
'Avstår' => '#f59e0b',
];
foreach ($votingStats as $voteType => $count) {
$color = $colors[$voteType] ?? '#8b5cf6';
$chart->addSlice($voteType, $count, $color);
}
return $chart;
}
public function placeholder()
{
return view('livewire.person.show-skeleton');
}
public function render()
{
return view('livewire.party.show')
->title($this->party->label().' - Riksdagen App');
}
}