Skip to content

Commit 4ae38e0

Browse files
authored
Merge pull request #70 from the-collab-lab/dialogs
Merge dialogs branch into main
2 parents 347b83a + c4d40b5 commit 4ae38e0

9 files changed

+173
-72
lines changed

src/components/Confirm.jsx

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { useEffect, useRef } from 'react';
2+
import Loading from './Loading';
3+
4+
const Confirm = ({ open, onClose, onConfirm, children, title, loading }) => {
5+
const confirmRef = useRef(null);
6+
const cancelRef = useRef(null);
7+
8+
// Opens/closes modal depending on open state
9+
useEffect(() => {
10+
const { current: el } = confirmRef;
11+
if (open) {
12+
el.showModal();
13+
cancelRef.current.focus();
14+
} else el.close();
15+
}, [open]);
16+
17+
return (
18+
<dialog
19+
className="rounded-md shadow-lg bg-puurWhite text-darkPurple"
20+
ref={confirmRef}
21+
onClose={onClose}
22+
>
23+
<div className="flex flex-col p-8 gap-8">
24+
<h1 className="text-2xl sm:text-3xl">{title}</h1>
25+
26+
{loading ? (
27+
<Loading />
28+
) : (
29+
<>
30+
{children}
31+
<div className="flex justify-center content-center flex-wrap gap-4 sm:gap8">
32+
<button
33+
onClick={onConfirm}
34+
aria-label="Confirm"
35+
className="flex items-center justify-center cursor-pointer bg-lightPurple hover:bg-hoverPurple transition ease-in-out rounded-md text-base sm:text-lg text-puurWhite px-4 py-2 gap-6 shadow-lg min-w-36 sm:min-w-40"
36+
>
37+
<i className="fa-solid fa-check"></i>
38+
Confirm
39+
</button>
40+
<button
41+
onClick={onClose}
42+
aria-label="Cancel"
43+
ref={cancelRef}
44+
className="flex items-center justify-center cursor-pointer border-2 border-darkPurple hover:border-hoverPurple hover:bg-hoverPurple transition ease-in-out rounded-md text-base sm:text-lg text-darkPurple hover:text-puurWhite px-4 py-2 gap-6 shadow-lg min-w-36 sm:min-w-40"
45+
>
46+
<i className="fa-solid fa-x"></i>
47+
Cancel
48+
</button>
49+
</div>
50+
</>
51+
)}
52+
</div>
53+
</dialog>
54+
);
55+
};
56+
57+
export default Confirm;

src/components/DeleteItem.jsx

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { useState } from 'react';
2+
import { deleteItem } from '../api/firebase';
3+
import Confirm from './Confirm';
4+
5+
const DeleteItem = ({ itemName, listPath, itemId }) => {
6+
const [open, setOpen] = useState(false);
7+
const [submitted, setSubmitted] = useState(false);
8+
9+
const handleDelete = (listPath, itemId) => {
10+
setSubmitted(true);
11+
deleteItem(listPath, itemId);
12+
return;
13+
};
14+
15+
const openConfirm = () => {
16+
setOpen(true);
17+
};
18+
const closeConfirm = () => {
19+
setOpen(false);
20+
};
21+
22+
return (
23+
<>
24+
<button
25+
onClick={openConfirm}
26+
aria-label={`Delete ${itemName}`}
27+
title={`Delete ${itemName}`}
28+
className="px-2 text-darkPurple rounded-md transition ease-in-out hover:text-alertRed focus:text-alertRed"
29+
>
30+
<i className="fa-solid fa-trash"></i>
31+
</button>
32+
<Confirm
33+
title={`Delete ${itemName.toUpperCase()}`}
34+
onClose={closeConfirm}
35+
onConfirm={() => handleDelete(listPath, itemId)}
36+
open={open}
37+
loading={submitted}
38+
>
39+
{`Do you really want to delete ${itemName.toUpperCase()} from this list?`}
40+
</Confirm>
41+
</>
42+
);
43+
};
44+
45+
export default DeleteItem;

src/components/DeleteList.jsx

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { useState } from 'react';
2+
import { deleteList } from '../api/firebase';
3+
import Confirm from './Confirm';
4+
5+
const DeleteList = ({ user, email, listPath, listName, setListPath }) => {
6+
const [open, setOpen] = useState(false);
7+
const [submitted, setSubmitted] = useState(false);
8+
9+
const handleDelete = (user, email, listPath, listName) => {
10+
setSubmitted(true);
11+
deleteList(user, email, listPath, listName);
12+
setListPath('');
13+
return;
14+
};
15+
16+
const openConfirm = () => {
17+
setOpen(true);
18+
};
19+
const closeConfirm = () => {
20+
setOpen(false);
21+
};
22+
23+
return (
24+
<>
25+
<button
26+
onClick={openConfirm}
27+
aria-label={`Delete ${listName.toUpperCase()}`}
28+
title={`Delete ${listName.toUpperCase()}`}
29+
className="rounded-md transition ease-in-out hover:text-alertRed focus:text-alertRed px-4 py-2"
30+
>
31+
<i className="fa-solid fa-trash"></i>
32+
</button>
33+
<Confirm
34+
title={`Delete ${listName.toUpperCase()} List`}
35+
onClose={closeConfirm}
36+
onConfirm={() => handleDelete(user, email, listPath, listName)}
37+
open={open}
38+
loading={submitted}
39+
>
40+
{listPath.includes(user)
41+
? `Do you really want to delete ${listName.toUpperCase()} list?`
42+
: `Do you really want to stop using ${listName.toUpperCase()} list?`}
43+
</Confirm>
44+
</>
45+
);
46+
};
47+
48+
export default DeleteList;

src/components/ListButtons.jsx

+8-19
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,29 @@ const ListButtons = (props) => {
33
const navigate = useNavigate();
44

55
const buttonVariants = {
6-
purple: 'flex items-center justify-center rounded-md bg-lightPurple',
6+
purple:
7+
'text-base sm:text-lg text-offWhite flex items-center justify-center rounded-md bg-lightPurple transition ease-in-out hover:bg-hoverPurple',
78
white:
8-
'flex items-center justify-center rounded-md bg-lightGrey border text-darkPurple',
9-
};
10-
11-
const iconVariants = {
12-
purple: 'fa-inverse',
13-
white: '',
14-
};
15-
16-
const textVariants = {
17-
purple: 'text-base sm:text-lg text-offWhite font-poppins',
18-
white: 'text-base sm:text-lg text-darkPurple font-poppins',
9+
'text-base sm:text-lg text-darkPurple flex items-center justify-center rounded-md bg-lightGrey border text-darkPurple transition ease-in-out hover:bg-hoverPurple hover:text-offWhite',
1910
};
2011

2112
return (
22-
<div className="grid sm:grid-cols-3 grid-cols-2 gap-x-2 py-6 text-base sm:text-lg">
13+
<div className="grid sm:grid-cols-3 grid-cols-2 gap-4 py-6 text-base sm:text-lg font-poppins">
2314
<button
2415
className={`sm:col-span-2 px-4 py-2 gap-6 shadow-lg ${buttonVariants[props.colorAdd]}`}
2516
onClick={() => navigate('/manage-list')}
2617
>
27-
<i className={`${iconVariants[props.colorAdd]} fa-solid fa-plus `}></i>
18+
<i className="fa-solid fa-plus"></i>
2819

29-
<span className={`${textVariants[props.colorAdd]}`}>Add item</span>
20+
<span>Add item</span>
3021
</button>
3122
<button
3223
className={`sm:col-span-1 gap-6 shadow-lg ${buttonVariants[props.colorShare]}`}
3324
onClick={() => navigate('/manage-list')}
3425
>
35-
<i
36-
className={`${iconVariants[props.colorShare]} fa-solid fa-share-nodes`}
37-
></i>
26+
<i className="fa-solid fa-share-nodes"></i>
3827

39-
<span className={`${textVariants[props.colorShare]}`}>Share list</span>
28+
<span>Share list</span>
4029
</button>
4130
</div>
4231
);

src/components/ListItem.jsx

+2-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { deleteItem } from '../api/firebase';
1+
import DeleteItem from './DeleteItem';
22

33
export function ListItem({
44
isRecentlyPurchased,
@@ -7,17 +7,6 @@ export function ListItem({
77
name,
88
updatePurchaseDate,
99
}) {
10-
const handleDelete = (listPath, itemId, itemName) => {
11-
if (
12-
window.confirm(
13-
`Do you really want to delete ${itemName.toUpperCase()} from this list?`,
14-
)
15-
) {
16-
deleteItem(listPath, itemId);
17-
}
18-
return;
19-
};
20-
2110
return (
2211
<div
2312
href="/"
@@ -58,13 +47,7 @@ export function ListItem({
5847
{name}
5948
</span>
6049
</div>
61-
<button
62-
className="px-2 text-darkPurple"
63-
onClick={() => handleDelete(listPath, itemId, name)}
64-
aria-label={`Delete ${name}`}
65-
>
66-
<i className="fa-solid fa-trash"></i>
67-
</button>
50+
<DeleteItem itemName={name} listPath={listPath} itemId={itemId} />
6851
</li>
6952
</div>
7053
);

src/components/SingleList.jsx

+8-32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useNavigate } from 'react-router-dom';
2-
import { deleteList } from '../api/firebase';
2+
import DeleteList from './DeleteList';
33

44
export function SingleList({ userEmail, name, path, setListPath, userId }) {
55
const navigate = useNavigate();
@@ -8,29 +8,6 @@ export function SingleList({ userEmail, name, path, setListPath, userId }) {
88
navigate(`/list/${path}`);
99
}
1010

11-
function handleDelete(user, email, listPath, listName) {
12-
if (listPath.includes(user)) {
13-
if (
14-
window.confirm(
15-
`Do you really want to delete ${listName.toUpperCase()} list?`,
16-
)
17-
) {
18-
deleteList(user, email, listPath, listName);
19-
setListPath('');
20-
}
21-
return;
22-
}
23-
if (
24-
window.confirm(
25-
`Do you really want to stop using ${listName.toUpperCase()} list?`,
26-
)
27-
) {
28-
deleteList(user, email, listPath, listName);
29-
setListPath('');
30-
}
31-
return;
32-
}
33-
3411
return (
3512
<li className="mb-8 bg-lightPurple w-full text-puurWhite flex justify-end shadow-lg rounded-md transition ease-in-out relative text-lg sm:text-xl hover:bg-hoverPurple">
3613
<button
@@ -39,14 +16,13 @@ export function SingleList({ userEmail, name, path, setListPath, userId }) {
3916
>
4017
{name}
4118
</button>
42-
<button
43-
className="rounded-md transition ease-in-out hover:text-alertRed focus:text-alertRed px-4 py-2"
44-
onClick={() => handleDelete(userId, userEmail, path, name)}
45-
aria-label={`Delete ${name} List`}
46-
title={`Delete ${name} List`}
47-
>
48-
<i className="fa-solid fa-trash"></i>
49-
</button>
19+
<DeleteList
20+
user={userId}
21+
email={userEmail}
22+
listPath={path}
23+
listName={name}
24+
setListPath={setListPath}
25+
/>
5026
</li>
5127
);
5228
}

src/components/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ export * from './SearchList';
55
export * from './Loading';
66
export * from './ButtonWithIcon';
77
export * from './ErrorMessage';
8+
export * from './DeleteList';
9+
export * from './Confirm';
10+
export * from './DeleteItem';

src/views/Layout.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export function Layout({ lists, listPath, user, isLoadingUser }) {
1212
return (
1313
<div className="w-screen flex flex-col text-poppins min-w-96 bg-puurWhite">
1414
<NavBar user={user} lists={lists} listPath={listPath} />
15-
<main className="h-screen w-full lg:pt-16 xl:w-9/12 xl:mx-auto">
15+
<main className="min-h-screen w-full lg:pt-16 xl:w-9/12 xl:mx-auto">
1616
{isLoadingUser ? (
1717
<Loading />
1818
) : !!user ? (

src/views/ManageList.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export function ManageList({ data, listPath, userId, userEmail }) {
179179
></input>
180180
<button
181181
type="submit"
182-
className=" col-span-3 sm:col-span-1 flex bg-lightGrey text-darkPurple border border-darkPurple justify-center items-center shadow-lg rounded-md transition ease-in-out hover:bg-darkPurple px-4 py-2 gap-6 shrink-0"
182+
className="col-span-3 sm:col-span-1 flex bg-lightGrey text-darkPurple border border-darkPurple justify-center items-center shadow-lg rounded-md transition ease-in-out hover:bg-hoverPurple hover:text-puurWhite px-4 py-2 gap-6 shrink-0"
183183
>
184184
<span>
185185
<i className="fa-solid fa-share-nodes"></i>

0 commit comments

Comments
 (0)