@@ -10,6 +10,8 @@ import {
1010import { cn } from 'utils/class-names' ;
1111import Button from 'components/input/button' ;
1212import { useState } from 'react' ;
13+ import ReminderToken from './reminder-token' ;
14+ import Switch from 'components/input/switch' ;
1315
1416interface CharacterTokenProps {
1517 playerName ?: string ;
@@ -18,10 +20,13 @@ interface CharacterTokenProps {
1820 players : BOTCPlayer [ ] ;
1921 playerIndex : number ;
2022 setPlayers : ( newPlayers : BOTCPlayer [ ] ) => void ;
23+ allCharacters ?: CharacterId [ ] ;
2124}
2225
23- const FIRST_NIGHT_CHARACTERS = new Set ( FIRST_NIGHT_TEXT . map ( ( [ id , _ ] ) => id ) ) ;
24- const OTHER_NIGHT_CHARACTERS = new Set ( OTHER_NIGHTS_TEXT . map ( ( [ id , _ ] ) => id ) ) ;
26+ const FIRST_NIGHT_CHARACTERS = new Set ( FIRST_NIGHT_TEXT . map ( ( { id } ) => id ) ) ;
27+ const OTHER_NIGHT_CHARACTERS = new Set ( OTHER_NIGHTS_TEXT . map ( ( { id } ) => id ) ) ;
28+
29+ type SelectMode = 'none' | 'reminder' ;
2530
2631const CharacterToken = ( {
2732 playerName,
@@ -30,11 +35,14 @@ const CharacterToken = ({
3035 players,
3136 playerIndex,
3237 setPlayers,
38+ allCharacters = [ ] ,
3339} : CharacterTokenProps ) => {
3440 const character = characterId ? CHARACTERS [ characterId ] : undefined ;
3541 const hasLeftLeaf = characterId && FIRST_NIGHT_CHARACTERS . has ( characterId ) ;
3642 const hasRightLeaf = characterId && OTHER_NIGHT_CHARACTERS . has ( characterId ) ;
3743 const [ modalOpen , setModalOpen ] = useState ( false ) ;
44+ const [ selectMode , setSelectMode ] = useState < SelectMode > ( 'none' ) ;
45+ const [ showAllReminders , setShowAllReminders ] = useState ( false ) ;
3846
3947 const killOrRevivePlayer = ( ) => {
4048 const newPlayers = players . slice ( ) ;
@@ -45,15 +53,18 @@ const CharacterToken = ({
4553 setPlayers ( newPlayers ) ;
4654 } ;
4755
56+ const canKill = character ?. reminderTokens ?. includes ( 'Killed by' ) ?? false ;
57+
4858 return (
4959 < Modal
5060 title = {
51- playerName
52- ? playerName + ( character ? `, the ${ character . name } ` : '' )
53- : character
54- ? character . name
55- : 'Token '
61+ selectMode === 'none'
62+ ? character
63+ ? character . name + ( playerName ? ` ( ${ playerName } )` : '' )
64+ : 'Empty Token'
65+ : 'Add reminder token '
5666 }
67+ withCloseButton
5768 open = { modalOpen }
5869 onFocus = { ( ) => {
5970 setModalOpen ( true ) ;
@@ -88,7 +99,6 @@ const CharacterToken = ({
8899 src = '/botc/leaf-right.webp'
89100 />
90101 ) }
91-
92102 { character && (
93103 < >
94104 < img
@@ -101,7 +111,7 @@ const CharacterToken = ({
101111 d = 'M 13 75 C 13 160, 138 160, 138 75'
102112 id = 'curve'
103113 fill = 'transparent'
104- > </ path >
114+ / >
105115 < text textAnchor = 'middle' >
106116 < textPath startOffset = '50%' href = '#curve' >
107117 { character . name }
@@ -113,9 +123,58 @@ const CharacterToken = ({
113123 </ div >
114124 }
115125 >
116- < Button onClick = { killOrRevivePlayer } >
117- { dead ? 'Revive' : 'Kill' } player
118- </ Button >
126+ { character ?. description }
127+ { selectMode === 'none' && (
128+ < div className = 'grid grid-cols-2 gap-x-4 gap-y-2' >
129+ < Button fullWidth onClick = { killOrRevivePlayer } >
130+ { dead ? 'Revive' : 'Kill' } this player
131+ </ Button >
132+ < Button fullWidth disabled = { ! canKill } onClick = { killOrRevivePlayer } >
133+ Kill another player
134+ </ Button >
135+ < Button
136+ fullWidth
137+ onClick = { ( ) => {
138+ setSelectMode ( 'reminder' ) ;
139+ } }
140+ >
141+ Add reminder
142+ </ Button >
143+ </ div >
144+ ) }
145+ { selectMode === 'reminder' && (
146+ < div className = 'flex flex-col gap-4' >
147+ < div className = 'grid grid-cols-4 gap-y-2 md:grid-cols-5 lg:grid-cols-7' >
148+ { ( showAllReminders
149+ ? allCharacters
150+ : players . flatMap ( ( p ) => p . characterId )
151+ ) . flatMap (
152+ ( id ) =>
153+ CHARACTERS [ id ] . reminderTokens ?. map ( ( reminderText ) => (
154+ < ReminderToken
155+ key = { id + reminderText }
156+ onClick = { ( ) => {
157+ const newPlayers = players . slice ( ) ;
158+ newPlayers [ playerIndex ] ?. reminders . push ( {
159+ characterId : id ,
160+ message : reminderText ,
161+ } ) ;
162+ setPlayers ( newPlayers ) ;
163+ setModalOpen ( false ) ;
164+ } }
165+ characterId = { id }
166+ text = { reminderText }
167+ />
168+ ) ) ?? [ ] ,
169+ ) }
170+ </ div >
171+ < Switch
172+ label = 'Show all reminders'
173+ value = { showAllReminders }
174+ onChange = { setShowAllReminders }
175+ />
176+ </ div >
177+ ) }
119178 </ Modal >
120179 ) ;
121180} ;
0 commit comments