This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / webapp / features / cards / components / addCardActions / AddCardActions.tsx
6.1 kB 231 lines
1'use client'; 2 3import { Dispatch, SetStateAction, useState } from 'react'; 4import useRemoveCardFromLibrary from '../../lib/mutations/useRemoveCardFromLibrary'; 5import { notifications } from '@mantine/notifications'; 6import { 7 Button, 8 Card, 9 Flex, 10 Group, 11 Input, 12 Stack, 13 Text, 14 Textarea, 15 VisuallyHidden, 16} from '@mantine/core'; 17import { BsExclamation, BsTrash2Fill } from 'react-icons/bs'; 18import { MdOutlineStickyNote2 } from 'react-icons/md'; 19 20interface Props { 21 cardId?: string; 22 note?: string; 23 noteId?: string; 24 onUpdateNote: Dispatch<SetStateAction<string | undefined>>; 25 onClose: () => void; 26} 27 28export default function AddCardActions(props: Props) { 29 const [showDeleteWarning, setShowDeleteWarning] = useState(false); 30 const [showDeleteCardWarning, setShowDeleteCardWarning] = useState(false); 31 const [noteMode, setNoteMode] = useState(false); 32 const [note, setNote] = useState(props.note); 33 const MAX_NOTE_LENGTH = 500; 34 35 const removeNote = useRemoveCardFromLibrary(); 36 const removeCard = useRemoveCardFromLibrary(); 37 38 const handleDeleteNote = () => { 39 if (!props.noteId) return; 40 41 removeNote.mutate(props.noteId, { 42 onError: () => { 43 notifications.show({ 44 message: 'Could not delete note', 45 color: 'red', 46 autoClose: 5000, 47 withCloseButton: true, 48 position: 'top-center', 49 icon: <BsExclamation />, 50 }); 51 }, 52 onSettled: () => { 53 props.onClose(); 54 }, 55 }); 56 }; 57 58 const handleDeleteCard = () => { 59 if (!props.cardId) return; 60 61 removeCard.mutate(props.cardId, { 62 onError: () => { 63 notifications.show({ 64 message: 'Could not delete card', 65 color: 'red', 66 autoClose: 5000, 67 withCloseButton: true, 68 position: 'top-center', 69 icon: <BsExclamation />, 70 }); 71 }, 72 onSettled: () => { 73 props.onClose(); 74 }, 75 }); 76 }; 77 78 if (noteMode) { 79 return ( 80 <Card 81 withBorder 82 component="article" 83 p={'xs'} 84 radius={'lg'} 85 style={{ cursor: 'pointer' }} 86 > 87 <Stack gap={'xs'}> 88 <Stack gap={0}> 89 <Flex justify="space-between"> 90 <Input.Label size="md" htmlFor="note"> 91 Your note 92 </Input.Label> 93 <Text c={'gray'} aria-hidden> 94 {note?.length ?? 0} / {MAX_NOTE_LENGTH} 95 </Text> 96 </Flex> 97 98 <Textarea 99 id="note" 100 placeholder="Add a note about this card" 101 variant="filled" 102 size="md" 103 rows={3} 104 maxLength={500} 105 value={note} 106 onChange={(e) => setNote(e.currentTarget.value)} 107 /> 108 <VisuallyHidden id="note-char-remaining" aria-live="polite"> 109 {`${MAX_NOTE_LENGTH - (note?.length ?? 0)} characters remaining`} 110 </VisuallyHidden> 111 </Stack> 112 <Group gap={'xs'} grow> 113 <Button 114 variant="light" 115 color="gray" 116 onClick={() => { 117 setNoteMode(false); 118 setNote(props.note); 119 }} 120 > 121 Cancel 122 </Button> 123 <Button 124 onClick={() => { 125 props.onUpdateNote(note); 126 setNoteMode(false); 127 }} 128 disabled={note?.trimEnd() === ''} 129 > 130 Ok 131 </Button> 132 </Group> 133 </Stack> 134 </Card> 135 ); 136 } 137 138 return ( 139 <Stack gap={'xs'}> 140 {showDeleteWarning ? ( 141 <Group justify="space-between" gap={'xs'}> 142 <Text>Delete note?</Text> 143 <Group gap={'xs'}> 144 <Button 145 size="xs" 146 color="red" 147 onClick={handleDeleteNote} 148 loading={removeNote.isPending} 149 > 150 Delete 151 </Button> 152 <Button 153 variant="light" 154 color="gray" 155 size="xs" 156 onClick={() => setShowDeleteWarning(false)} 157 > 158 Cancel 159 </Button> 160 </Group> 161 </Group> 162 ) : showDeleteCardWarning ? ( 163 <Group justify="space-between" gap={'xs'}> 164 <Text>Delete card?</Text> 165 <Group gap={'xs'}> 166 <Button 167 color="red" 168 size="xs" 169 onClick={handleDeleteCard} 170 loading={removeCard.isPending} 171 > 172 Delete 173 </Button> 174 <Button 175 variant="light" 176 color="gray" 177 size="xs" 178 onClick={() => setShowDeleteCardWarning(false)} 179 > 180 Cancel 181 </Button> 182 </Group> 183 </Group> 184 ) : ( 185 <Group gap={'xs'} justify="space-between"> 186 <Group gap={'xs'}> 187 <Button 188 variant="light" 189 size="xs" 190 color="gray" 191 leftSection={<MdOutlineStickyNote2 />} 192 onClick={(e) => { 193 e.stopPropagation(); 194 setNoteMode(true); 195 }} 196 > 197 {note ? 'Edit note' : 'Add note'} 198 </Button> 199 {props.noteId && ( 200 <Button 201 variant="light" 202 color="red" 203 size="xs" 204 onClick={(e) => { 205 e.stopPropagation(); 206 setShowDeleteWarning(true); 207 }} 208 > 209 Delete note 210 </Button> 211 )} 212 </Group> 213 {props.cardId && ( 214 <Button 215 variant="light" 216 color="red" 217 size="xs" 218 leftSection={<BsTrash2Fill />} 219 onClick={(e) => { 220 e.stopPropagation(); 221 setShowDeleteCardWarning(true); 222 }} 223 > 224 Delete card 225 </Button> 226 )} 227 </Group> 228 )} 229 </Stack> 230 ); 231}