Files
cbsnexora/src/app/election/components/election-results/election-results.component.html
T
Jaanu423andClaude Sonnet 4.6 10b301c30c feat(election,family): family member KYC display, collapsible cards, linked/manual badges, create-as-client flow
- nomination-apply: show full KYC for linked family members via nested forkJoin, accordion expand/collapse cards, owner chips on KYC headers, 'Create as Client' button for manual entries
- family-members-tab: show Linked Client / Manual Entry badges, entry type in detail grid, 'Create as Client' button navigating with prefill state
- create-client + client-general-step: accept prefillData @Input from navigation state, patch form fields from family member data
- Add MPL-2.0 headers to all election module files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 17:30:29 +05:30

105 lines
3.6 KiB
HTML

<!--
Copyright since 2025 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<div class="election-results">
<div class="page-header">
<a routerLink="/election" class="back-link"><mat-icon>arrow_back</mat-icon></a>
<div>
<h2>Election Results</h2>
@if (election) {
<p class="sub-title">{{ election.title }}</p>
}
</div>
@if (canDeclare) {
<button class="btn-declare" (click)="declareResults()" [disabled]="declaring">
<mat-icon>gavel</mat-icon>
{{ declaring ? 'Declaring...' : 'Declare Results' }}
</button>
}
</div>
@if (loading) {
<div class="loading-state">
<div class="spinner"></div>
<p>Loading results...</p>
</div>
} @else if (results.length === 0) {
<div class="empty-state">
<mat-icon>bar_chart</mat-icon>
<h3>Results not yet declared</h3>
@if (canDeclare) {
<p>Voting is closed. Click "Declare Results" to compute and publish the results.</p>
} @else {
<p>Results will appear here once the election is complete and results are declared.</p>
}
</div>
} @else {
<div class="results-meta">
<div class="meta-chip">
<mat-icon>how_to_vote</mat-icon>
Election: {{ election?.electionDate | date: 'dd MMM yyyy' }}
</div>
@if (results[0]?.declaredDate) {
<div class="meta-chip">
<mat-icon>gavel</mat-icon>
Declared: {{ results[0].declaredDate | date: 'dd MMM yyyy HH:mm' }}
</div>
}
</div>
@for (group of groupByPost(); track group.postName) {
<div class="post-result">
<div class="post-result-header">
<h3>{{ group.postName }}</h3>
</div>
<!-- Winner Spotlight -->
@for (result of group.results; track result.id) {
@if (result.rankPosition === 1 && result.result === 'WON') {
<div class="winner-banner">
<div class="trophy-icon"><mat-icon>emoji_events</mat-icon></div>
<div class="winner-info">
<span class="winner-label">Winner</span>
<h4>{{ result.candidateName }}</h4>
<span class="winner-votes">{{ result.voteCount | number }} votes</span>
</div>
</div>
}
}
<!-- Results Table with Bar Chart -->
<div class="results-table">
@for (result of group.results; track result.id) {
<div class="result-row" [class.winner]="result.result === 'WON'">
<div class="rank">
@if (result.result === 'WON') {
<mat-icon class="won-icon">emoji_events</mat-icon>
} @else {
<span># {{ result.rankPosition }}</span>
}
</div>
<div class="candidate-name">{{ result.candidateName }}</div>
<div class="vote-bar">
<div
class="bar-fill"
[class.bar-won]="result.result === 'WON'"
[style.width.%]="barWidth(result.voteCount, maxVotes(group.results))"
></div>
<span class="vote-count">{{ result.voteCount | number }} votes</span>
</div>
<div class="result-badge" [class.won]="result.result === 'WON'" [class.lost]="result.result === 'LOST'">
{{ result.result }}
</div>
</div>
}
</div>
</div>
}
}
</div>