This commit is contained in:
229
app/Livewire/Party/Show.php
Normal file
229
app/Livewire/Party/Show.php
Normal file
@@ -0,0 +1,229 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user