false, 'showLog' => false, 'currentPubkey' => null, 'currentPleb' => null, 'events' => [], 'boardEvents' => [], 'election' => fn() => $election, 'plebs' => [], 'search' => '', 'signThisEvent' => '', 'isNotClosed' => true, ]); mount(function () { $this->plebs = \App\Models\EinundzwanzigPleb::query() ->with(['profile']) ->whereIn('association_status', [3, 4]) ->orderBy('association_status', 'desc') ->get() ->toArray(); $this->loadEvents(); $this->loadBoardEvents(); if ($this->election->end_time?->isPast() || !config('services.voting')) { $this->isNotClosed = false; } }); on([ 'nostrLoggedIn' => function ($pubkey) { $this->currentPubkey = $pubkey; $this->currentPleb = \App\Models\EinundzwanzigPleb::query()->where('pubkey', $pubkey)->first(); if ($this->currentPleb->association_status->value < 3) { return $this->js('alert("Du bist nicht berechtigt, an der Wahl teilzunehmen.")'); } $logPubkeys = [ '0adf67475ccc5ca456fd3022e46f5d526eb0af6284bf85494c0dd7847f3e5033', '430169631f2f0682c60cebb4f902d68f0c71c498fd1711fd982f052cf1fd4279', ]; if (in_array($this->currentPubkey, $logPubkeys, true)) { $this->showLog = true; } $this->isAllowed = true; }, 'echo:votes,.newVote' => function () { $this->loadEvents(); $this->loadBoardEvents(); }, 'nostrLoggedOut' => function () { $this->isAllowed = false; $this->currentPubkey = null; $this->currentPleb = null; }, ]); updated([ 'search' => function ($value) { $this->plebs = \App\Models\EinundzwanzigPleb::query() ->with(['profile']) ->whereIn('association_status', [3, 4]) ->where(fn($query) => $query ->where('pubkey', 'like', "%$value%") ->orWhereHas('profile', fn($query) => $query->where('name', 'ilike', "%$value%"))) ->orderBy('association_status', 'desc') ->get() ->toArray(); }, ]); $loadEvents = function () { $this->events = $this->loadNostrEvents([32122]); }; $loadBoardEvents = function () { $this->boardEvents = $this->loadNostrEvents([2121]); }; $loadNostrEvents = function ($kinds) { $subscription = new Subscription(); $subscriptionId = $subscription->setId(); $filter = new Filter(); $filter->setKinds($kinds); $requestMessage = new RequestMessage($subscriptionId, [$filter]); $relaySet = new RelaySet(); $relaySet->setRelays([new Relay(config('services.relay'))]); $request = new Request($relaySet, $requestMessage); $response = $request->send(); return collect($response[config('services.relay')]) ->map(fn($event) => [ 'id' => $event->event->id, 'kind' => $event->event->kind, 'content' => $event->event->content, 'pubkey' => $event->event->pubkey, 'tags' => $event->event->tags, 'created_at' => $event->event->created_at, ])->toArray(); }; $vote = function ($pubkey, $type, $board = false) { if ($this->election->end_time?->isPast()) { $this->isNotClosed = false; return; } $note = new NostrEvent(); $note->setKind($board ? 2121 : 32122); if (!$board) { $dTag = sprintf('%s,%s,%s', $this->currentPleb->pubkey, date('Y'), $type); $note->setTags([['d', $dTag]]); } $note->setContent("$pubkey,$type"); $this->signThisEvent = $note->toJson(); }; $checkElection = function () { if ($this->election->end_time?->isPast()) { $this->isNotClosed = false; } }; $signEvent = function ($event) { $note = new NostrEvent(); $note->setId($event['id']); $note->setSignature($event['sig']); $note->setKind($event['kind']); $note->setContent($event['content']); $note->setPublicKey($event['pubkey']); $note->setTags($event['tags']); $note->setCreatedAt($event['created_at']); $eventMessage = new EventMessage($note); $relay = new Relay(config('services.relay')); $relay->setMessage($eventMessage); $relay->send(); Broadcast::on('votes')->as('newVote')->sendNow(); }; ?> @volt
@if($isAllowed)
@php $positions = [ 'presidency' => ['icon' => 'fa-crown', 'title' => 'Präsidium'], 'board' => ['icon' => 'fa-users', 'title' => 'Vizepräsidium'], ]; $loadedEvents = collect($events) ->map(function($event) { $profile = \App\Models\Profile::query() ->where('pubkey', $event['pubkey']) ->first() ?->toArray(); $votedFor = \App\Models\Profile::query() ->where('pubkey', str($event['content'])->before(',')->toString()) ->first() ?->toArray(); return [ 'id' => $event['id'], 'kind' => $event['kind'], 'content' => $event['content'], 'pubkey' => $event['pubkey'], 'tags' => $event['tags'], 'created_at' => $event['created_at'], 'profile' => $profile, 'votedFor' => $votedFor, 'type' => str($event['content'])->after(',')->toString(), ]; }) ->sortByDesc('created_at') ->unique(fn ($event) => $event['pubkey'] . $event['type']) ->values(); $loadedBoardEvents = collect($boardEvents) ->map(function($event) { $profile = \App\Models\Profile::query() ->where('pubkey', $event['pubkey']) ->first() ?->toArray(); $votedFor = \App\Models\Profile::query() ->where('pubkey', str($event['content'])->before(',')->toString()) ->first() ?->toArray(); return [ 'id' => $event['id'], 'kind' => $event['kind'], 'content' => $event['content'], 'pubkey' => $event['pubkey'], 'tags' => $event['tags'], 'created_at' => $event['created_at'], 'profile' => $profile, 'votedFor' => $votedFor, 'type' => str($event['content'])->after(',')->toString(), ]; }) ->sortByDesc('created_at') ->values(); @endphp
Plebs
    @foreach($plebs as $pleb)
  • A
    {{ $pleb['profile']['name'] ?? $pleb['pubkey'] }}
    @foreach($positions as $name => $p) @php $votedResult = $loadedEvents->filter(fn ($e) => $e['pubkey'] === $pleb['pubkey'])->firstWhere('type', $name); @endphp
    @if($votedResult) @endif
    @endforeach
  • @endforeach
@if($currentPubkey) @php $electionConfig = collect(json_decode($election->candidates, true, 512, JSON_THROW_ON_ERROR)) ->map(function ($c) use ($loadedEvents, $currentPubkey) { $candidates = \App\Models\Profile::query() ->whereIn('pubkey', $c['c']) ->get() ->map(function ($p) use ($loadedEvents, $c, $currentPubkey) { $votedClass = ' bg-green-500/20 text-green-700'; $notVotedClass = ' bg-gray-500/20 text-gray-100'; $hasVoted = $loadedEvents ->filter(fn($e) => $e['type'] === $c['type'] && $e['pubkey'] === $currentPubkey) ->firstWhere('votedFor.pubkey', $p->pubkey); return [ 'pubkey' => $p->pubkey, 'name' => $p->name, 'picture' => $p->picture, 'votedClass' => $hasVoted ? $votedClass : $notVotedClass, ]; }); return [ 'type' => $c['type'], 'c' => $c['c'], 'candidates' => $candidates, ]; }); $electionConfigBoard = collect(json_decode($election->candidates, true, 512, JSON_THROW_ON_ERROR)) ->map(function ($c) use ($loadedBoardEvents, $currentPubkey) { $candidates = \App\Models\Profile::query() ->whereIn('pubkey', $c['c']) ->get() ->map(function ($p) use ($loadedBoardEvents, $c, $currentPubkey) { $votedClass = ' bg-green-500/20 text-green-700'; $notVotedClass = ' bg-gray-500/20 text-gray-100'; $hasVoted = $loadedBoardEvents ->filter(fn($e) => $e['type'] === $c['type'] && $e['pubkey'] === $currentPubkey) ->firstWhere('votedFor.pubkey', $p->pubkey); return [ 'pubkey' => $p->pubkey, 'name' => $p->name, 'picture' => $p->picture, 'votedClass' => $hasVoted ? $votedClass : $notVotedClass, 'hasVoted' => $hasVoted, ]; }); return [ 'type' => $c['type'], 'c' => $c['c'], 'candidates' => $candidates, ]; }); @endphp
@if($isNotClosed) @else @endif

Wahlen

Wahl des Präsidiums

@php $president = $positions['presidency']; $board = $positions['board']; @endphp

{{ $president['title'] }}

@php $votedResult = $loadedEvents->filter(fn ($event) => $event['pubkey'] === $currentPubkey)->firstWhere('type', 'presidency'); @endphp @if($votedResult) Du hast "{{ $votedResult['votedFor']['name'] ?? 'error' }}" gewählt @else Wähle deinen Kandidaten für das Präsidium. @endif
@foreach($electionConfig->firstWhere('type', 'presidency')['candidates'] ?? [] as $c)
{{ $c['name'] }} {{ $c['name'] }}
@endforeach

Wahl der übrigen Vorstandsmitglieder

Klicke auf den Kandidaten, um seine Position als Vorstandsmitglied zu bestätigen.
@foreach($electionConfigBoard->firstWhere('type', 'board')['candidates'] ?? [] as $c)
{{ $c['name'] }} {{ $c['name'] }}
@endforeach
@endif
@else

Wahlen

Du bist nicht berechtigt, die Wahlen einzusehen.

@endif
@endvolt