From 3d65900fc4c046de4685b742a38055f5c28ef5f5 Mon Sep 17 00:00:00 2001 From: Jaanu423 Date: Thu, 9 Jul 2026 11:02:32 +0530 Subject: [PATCH] feat(election): Chairman/VC auto-resolution, member vote panel, read-only committee summary Co-Authored-By: Claude Sonnet 4.6 --- .../committee-board.component.html | 67 +++++-------- .../committee-board.component.scss | 32 ++++++- .../committee-board.component.ts | 52 ---------- .../meeting-vote/meeting-vote.component.html | 31 +++++- .../meeting-vote/meeting-vote.component.scss | 96 +++++++++++++++++++ .../meeting-vote/meeting-vote.component.ts | 11 +++ 6 files changed, 188 insertions(+), 101 deletions(-) diff --git a/src/app/election/components/committee-board/committee-board.component.html b/src/app/election/components/committee-board/committee-board.component.html index 01519c4fa..765028771 100644 --- a/src/app/election/components/committee-board/committee-board.component.html +++ b/src/app/election/components/committee-board/committee-board.component.html @@ -619,42 +619,29 @@
- -
- - - -
-
- -
- + {{ + item.resolution === 'APPROVED' + ? '✅ Approved' + : item.resolution === 'REJECTED' + ? '❌ Rejected' + : '⏸ Deferred' + }} + + } @else { + Awaiting Chairman / Vice Chairman vote + }
} @@ -663,15 +650,7 @@ } diff --git a/src/app/election/components/committee-board/committee-board.component.scss b/src/app/election/components/committee-board/committee-board.component.scss index c6bf996d3..6b0a6e31b 100644 --- a/src/app/election/components/committee-board/committee-board.component.scss +++ b/src/app/election/components/committee-board/committee-board.component.scss @@ -1829,10 +1829,34 @@ $font-family: margin-bottom: 8px; } - .res-buttons { - display: flex; - gap: 6px; - flex-wrap: wrap; + .res-badge { + display: inline-block; + padding: 4px 12px; + border-radius: 20px; + font-size: 11px; + font-weight: 700; + + &.res-badge-approved { + background: #dcfce7; + color: #15803d; + } + + &.res-badge-rejected { + background: #fee2e2; + color: #b91c1c; + } + + &.res-badge-deferred { + background: #fef3c7; + color: #b45309; + } + + &.res-badge-pending { + background: #f1f5f9; + color: #94a3b8; + font-style: italic; + font-weight: 400; + } } } diff --git a/src/app/election/components/committee-board/committee-board.component.ts b/src/app/election/components/committee-board/committee-board.component.ts index b001e022b..5102519d2 100644 --- a/src/app/election/components/committee-board/committee-board.component.ts +++ b/src/app/election/components/committee-board/committee-board.component.ts @@ -77,8 +77,6 @@ export class CommitteeBoardComponent implements OnInit { votePanelMeeting: any = null; voteSummary: any[] = []; voteSummaryLoading = false; - resolutionForm: Record = {}; - savingResolutions = false; ngOnInit(): void { this.load(); @@ -653,18 +651,10 @@ export class CommitteeBoardComponent implements OnInit { this.votePanelMeeting = meeting; this.showVotePanel = true; this.voteSummary = []; - this.resolutionForm = {}; this.voteSummaryLoading = true; this.service.getVoteSummary(meeting.id).subscribe({ next: (data) => { this.voteSummary = data ?? []; - this.resolutionForm = {}; - for (const item of this.voteSummary) { - this.resolutionForm[item.agendaId] = { - resolution: item.resolution ?? '', - discussionNotes: item.discussionNotes ?? '' - }; - } this.voteSummaryLoading = false; }, error: () => { @@ -680,48 +670,6 @@ export class CommitteeBoardComponent implements OnInit { this.voteSummary = []; } - saveResolutions(): void { - if (this.savingResolutions) return; - const meetingId = this.votePanelMeeting?.id; - if (!meetingId) return; - - const payload = Object.entries(this.resolutionForm) - .filter( - ([ - , - v - ]) => v.resolution - ) - .map( - ([ - agendaId, - v - ]) => ({ - agendaId: Number(agendaId), - resolution: v.resolution, - discussionNotes: v.discussionNotes - }) - ); - - if (!payload.length) { - this.snackBar.open('Please set at least one resolution.', 'Close', { duration: 3000 }); - return; - } - - this.savingResolutions = true; - this.service.saveResolutions(meetingId, payload).subscribe({ - next: () => { - this.savingResolutions = false; - this.snackBar.open('Resolutions saved and meeting minutes sent to all members.', 'Close', { duration: 4000 }); - this.closeVotePanel(); - }, - error: () => { - this.savingResolutions = false; - this.snackBar.open('Failed to save resolutions.', 'Close', { duration: 3000 }); - } - }); - } - resolutionIcon(r: string): string { return r === 'APPROVED' ? 'check_circle' : r === 'REJECTED' ? 'cancel' : 'pause_circle'; } diff --git a/src/app/election/components/meeting-vote/meeting-vote.component.html b/src/app/election/components/meeting-vote/meeting-vote.component.html index ecdcb659a..bd1a2f91d 100644 --- a/src/app/election/components/meeting-vote/meeting-vote.component.html +++ b/src/app/election/components/meeting-vote/meeting-vote.component.html @@ -126,7 +126,36 @@ - + + @if (item.memberVotes?.length) { +
+ + @if (showMemberVotes[item.agendaId]) { +
+ @for (mv of item.memberVotes; track mv.memberName) { +
+ {{ mv.memberName }} + @if (mv.designation) { + {{ mv.designation }} + } + @if (mv.vote) { + + {{ mv.vote === 'APPROVED' ? '✅' : mv.vote === 'REJECTED' ? '❌' : '—' }} + {{ mv.vote }} + + } @else { + Pending + } +
+ } +
+ } +
+ } + @if (selections[item.agendaId] === 'APPROVED' || selections[item.agendaId] === 'REJECTED') {