@@ -4,21 +4,144 @@ import { Separator } from '@/components/ui/separator';
44import { ElectionRoundStatus } from '@/common/types' ;
55import { AuthContext } from '@/context/auth.context' ;
66import { useCurrentElectionRoundStore } from '@/context/election-round.store' ;
7+ import {
8+ useArchiveElectionRound ,
9+ useStartElectionRound ,
10+ useUnarchiveElectionRound ,
11+ useUnstartElectionRound ,
12+ } from '@/features/election-rounds/hooks' ;
713import { PencilIcon } from '@heroicons/react/24/outline' ;
8- import { Link } from '@tanstack/react-router' ;
9- import { useContext } from 'react' ;
14+ import { Link , useRouter } from '@tanstack/react-router' ;
15+ import { ArchiveIcon , FileEdit , PlayIcon } from 'lucide-react' ;
16+ import { useCallback , useContext } from 'react' ;
1017import { useTranslation } from 'react-i18next' ;
1118import { useElectionRoundDetails } from '../../features/election-event/hooks/election-event-hooks' ;
19+ import CoalitionDescription from '../CoalitionDescription/CoalitionDescription' ;
1220import ElectionRoundStatusBadge from '../ElectionRoundStatusBadge/ElectionRoundStatusBadge' ;
21+ import { useConfirm } from '../ui/alert-dialog-provider' ;
1322import { Button } from '../ui/button' ;
14- import CoalitionDescription from '../CoalitionDescription/CoalitionDescription ' ;
23+ import { useToast } from '../ui/use-toast ' ;
1524
1625export default function ElectionEventDescription ( ) {
1726 const { t } = useTranslation ( ) ;
1827 const currentElectionRoundId = useCurrentElectionRoundStore ( ( s ) => s . currentElectionRoundId ) ;
1928 const { data : electionEvent } = useElectionRoundDetails ( currentElectionRoundId ) ;
2029 const { userRole } = useContext ( AuthContext ) ;
2130
31+ const { toast } = useToast ( ) ;
32+ const confirm = useConfirm ( ) ;
33+
34+ const router = useRouter ( ) ;
35+
36+ const { mutate : unstartElectionRound } = useUnstartElectionRound ( ) ;
37+ const { mutate : startElectionRound } = useStartElectionRound ( ) ;
38+ const { mutate : archiveElectionRound } = useArchiveElectionRound ( ) ;
39+ const { mutate : unarchiveElectionRound } = useUnarchiveElectionRound ( ) ;
40+
41+ const handleArchiveElectionRound = useCallback ( async ( ) => {
42+ if (
43+ await confirm ( {
44+ title : `Archive election round: ${ electionEvent ! . englishTitle } ?` ,
45+ body : 'Are you sure you want to archive this election round?' ,
46+ } )
47+ ) {
48+ archiveElectionRound ( {
49+ electionRoundId : electionEvent ! . id ,
50+ onSuccess : ( ) => {
51+ router . invalidate ( ) ;
52+
53+ toast ( {
54+ title : 'Election round archived successfully' ,
55+ } ) ;
56+ } ,
57+ onError : ( ) =>
58+ toast ( {
59+ title : 'Error archiving election round' ,
60+ description : 'Please contact tech support' ,
61+ variant : 'destructive' ,
62+ } ) ,
63+ } ) ;
64+ }
65+ } , [ electionEvent , confirm ] ) ;
66+
67+ const handleUnstartElectionRound = useCallback ( async ( ) => {
68+ if (
69+ await confirm ( {
70+ title : `Draft election round: ${ electionEvent ! . englishTitle } ?` ,
71+ body : 'Are you sure you want to draft this election round?' ,
72+ } )
73+ ) {
74+ unstartElectionRound ( {
75+ electionRoundId : electionEvent ! . id ,
76+ onSuccess : ( ) => {
77+ router . invalidate ( ) ;
78+
79+ toast ( {
80+ title : 'Election round drafted successfully' ,
81+ } ) ;
82+ } ,
83+ onError : ( ) => {
84+ router . invalidate ( ) ;
85+ toast ( {
86+ title : 'Error drafting election round' ,
87+ description : 'Please contact tech support' ,
88+ variant : 'destructive' ,
89+ } ) ;
90+ } ,
91+ } ) ;
92+ }
93+ } , [ electionEvent , confirm ] ) ;
94+
95+ const handleUnarchiveElectionRound = useCallback ( async ( ) => {
96+ if (
97+ await confirm ( {
98+ title : `Unarchive election round: ${ electionEvent ! . englishTitle } ?` ,
99+ body : 'Are you sure you want to unarchive this election round?' ,
100+ } )
101+ ) {
102+ unarchiveElectionRound ( {
103+ electionRoundId : electionEvent ! . id ,
104+ onSuccess : ( ) => {
105+ router . invalidate ( ) ;
106+ toast ( {
107+ title : 'Election round unarchived successfully' ,
108+ } ) ;
109+ } ,
110+ onError : ( ) =>
111+ toast ( {
112+ title : 'Error unarchiving election round' ,
113+ description : 'Please contact tech support' ,
114+ variant : 'destructive' ,
115+ } ) ,
116+ } ) ;
117+ }
118+ } , [ electionEvent , confirm ] ) ;
119+
120+ const handleStartElectionRound = useCallback ( async ( ) => {
121+ if (
122+ await confirm ( {
123+ title : `Start election round: ${ electionEvent ! . englishTitle } ?` ,
124+ body : 'Are you sure you want to start this election round?' ,
125+ } )
126+ ) {
127+ startElectionRound ( {
128+ electionRoundId : electionEvent ! . id ,
129+ onSuccess : ( ) => {
130+ router . invalidate ( ) ;
131+ toast ( {
132+ title : 'Election round started successfully' ,
133+ } ) ;
134+ } ,
135+ onError : ( ) =>
136+ toast ( {
137+ title : 'Error starting election round' ,
138+ description : 'Please contact tech support' ,
139+ variant : 'destructive' ,
140+ } ) ,
141+ } ) ;
142+ }
143+ } , [ electionEvent , confirm ] ) ;
144+
22145 return (
23146 < div className = 'space-y-4' >
24147 < Card >
@@ -29,9 +152,32 @@ export default function ElectionEventDescription() {
29152 </ CardTitle >
30153 { userRole === 'PlatformAdmin' && (
31154 < div className = 'flex justify-end gap-4 px-6' >
155+ { ! ( electionEvent ! . status === ElectionRoundStatus . Archived ) ? (
156+ < Button onClick = { handleArchiveElectionRound } variant = 'ghost-primary' className = 'text-yellow-900' >
157+ < ArchiveIcon className = 'mr-2 h-4 w-4' />
158+ Archive
159+ </ Button >
160+ ) : (
161+ < Button onClick = { handleUnarchiveElectionRound } variant = 'ghost-primary' className = 'text-green-900' >
162+ < ArchiveIcon className = 'mr-2 h-4 w-4' />
163+ Unarchive
164+ </ Button >
165+ ) }
166+
167+ { ! ( electionEvent ! . status === ElectionRoundStatus . Started ) ? (
168+ < Button onClick = { handleStartElectionRound } variant = 'ghost-primary' className = 'text-green-900' >
169+ < PlayIcon className = 'mr-2 h-4 w-4' />
170+ Start
171+ </ Button >
172+ ) : (
173+ < Button onClick = { handleUnstartElectionRound } variant = 'ghost-primary' className = 'text-slate-700' >
174+ < FileEdit className = 'mr-2 h-4 w-4' />
175+ Draft
176+ </ Button >
177+ ) }
32178 < Link to = '/election-rounds/$electionRoundId/edit' params = { { electionRoundId : currentElectionRoundId } } >
33179 < Button variant = 'ghost-primary' >
34- < PencilIcon className = 'w-[18px] mr-2 text-purple-900' />
180+ < PencilIcon className = 'h-4 w-4 mr-2 text-purple-900' />
35181 < span className = 'text-base text-purple-900' > Edit</ span >
36182 </ Button >
37183 </ Link >
0 commit comments