This repository has no description
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}