Skip to content

Commit

Permalink
Merge pull request #52 from the-collab-lab/ja-style-manage-list
Browse files Browse the repository at this point in the history
Style Manage List Page and Add Toast Alerts
  • Loading branch information
sillytsundere authored Apr 5, 2024
2 parents 427e415 + a332ff9 commit 45f953a
Show file tree
Hide file tree
Showing 10 changed files with 226 additions and 170 deletions.
23 changes: 22 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"react": "^18.2.0",
"react-dark-mode-toggle-2": "^2.0.9",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.2"
"react-router-dom": "^6.14.2",
"react-toastify": "^10.0.5"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
Expand Down
88 changes: 35 additions & 53 deletions src/components/AddItem.jsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,45 @@
import { addItem } from '../api/firebase';
import { useRef } from 'react';
import { useRef, useState } from 'react';
import { isInputEmpty, isItemDuplicate } from '../utils/itemValidator.js';
import { SignInAlert } from './SignInAlert.jsx';
import { SignInAlert } from './ModalAlerts.jsx';
import { useAuth } from '../api/useAuth.jsx';
import '../custom-styles.css';
import { Button } from '@radix-ui/themes';
import { Box, TextField } from '@radix-ui/themes';
import { Box, Button, TextField, RadioGroup } from '@radix-ui/themes';
import { toast } from 'react-toastify';

export function AddItem({ listPath, data }) {
const formRef = useRef(null);
const { user } = useAuth();
const [itemName, setItemName] = useState('');
const [daysUntilNextPurchase, setDaysUntilNextPurchase] = useState('');
const handleItemName = (e) => setItemName(e.currentTarget.value);
const handleDays = (e) => setDaysUntilNextPurchase(e.currentTarget.value);

const handleSubmit = async (e) => {
e.preventDefault();

const formData = new FormData(e.target);
const itemName = formData.get('itemName');
const daysUntilNextPurchase = parseInt(
formData.get('daysUntilNextPurchase'),
);

try {
if (isInputEmpty(itemName)) {
formRef.current.reset();
return alert('Cannot submit without an item name');
return toast.error('Cannot submit without an item name! 😬');
}

if (isItemDuplicate(itemName, data)) {
formRef.current.reset();
return alert(
'This item is already in the list, cannot submit a duplicate.',
return toast.error(
'This item is already in the list, cannot submit a duplicate 😬',
);
}

await addItem(listPath, {
itemName,
daysUntilNextPurchase,
});

alert('Item saved successfully');
toast.success(`${itemName} added to the list! 👍`);
formRef.current.reset();
setItemName('');
} catch (error) {
alert(`There was a problem: ${error.message}`);
toast.error(`There was a problem: ${error.message}`);
}
};

Expand All @@ -56,6 +54,7 @@ export function AddItem({ listPath, data }) {
name="itemName"
type="text"
id="item"
onChange={handleItemName}
></TextField.Root>
</Box>
</div>
Expand All @@ -67,44 +66,27 @@ export function AddItem({ listPath, data }) {

<p>Please select an option:</p>

<ul>
<li>
<label htmlFor="soon"> Soon (7 days)</label>
<input
value={7}
name="daysUntilNextPurchase"
type="radio"
id="soon"
defaultChecked
/>
</li>
<li>
<label htmlFor="kind-of-soon"> Kind of Soon (14 days)</label>
<input
value={14}
name="daysUntilNextPurchase"
type="radio"
id="kind-of-soon"
/>
</li>
<li>
<label htmlFor="not-soon"> Not Soon (30 days)</label>
<input
value={30}
name="daysUntilNextPurchase"
type="radio"
id="not-soon"
/>
</li>
</ul>
<RadioGroup.Root defaultValue={7}>
<RadioGroup.Item id="soon" onClick={handleDays} value={7}>
Soon (7 Days)
</RadioGroup.Item>
<RadioGroup.Item id="kind-of-soon" onClick={handleDays} value={14}>
Kind of Soon (14 Days)
</RadioGroup.Item>
<RadioGroup.Item id="not-soon" onClick={handleDays} value={30}>
Not Soon (30 Days)
</RadioGroup.Item>
</RadioGroup.Root>
</div>
{user ? (
<Button className="custom-button" type="submit" variant="solid">
Submit
</Button>
) : (
<SignInAlert action={'Submit'} />
)}
<Box as="div" py="5">
{user ? (
<Button className="custom-button" type="submit">
Submit
</Button>
) : (
<SignInAlert action={'Submit'} description={'add an item'} />
)}
</Box>
</form>
);
}
21 changes: 11 additions & 10 deletions src/components/ListItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import {
} from '../utils/dates';
import './ListItem.css';
import { Timestamp } from 'firebase/firestore';
import { Badge } from '@radix-ui/themes';
import { toast } from 'react-toastify';
import { DeleteItemConfirm } from './ModalAlerts';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTrashCan } from '@fortawesome/free-regular-svg-icons';
import { Badge } from '@radix-ui/themes';

export function ListItem({ listPath, item, name }) {
const [isChecked, setIsChecked] = useState(item.isChecked || false);
Expand All @@ -21,13 +23,11 @@ export function ListItem({ listPath, item, name }) {
}

async function handleDelete() {
if (window.confirm('Are you sure you want to delete this item?')) {
try {
const result = await deleteItem(listPath, item);
alert(result.message);
} catch (error) {
alert(`Failed to delete item: ${error.message}`);
}
try {
const result = await deleteItem(listPath, item);
toast.success(`${result.message} 👍`);
} catch (error) {
toast.error(`Failed to delete item: ${error.message}`);
}
}

Expand Down Expand Up @@ -97,13 +97,14 @@ export function ListItem({ listPath, item, name }) {
<label className="ListItem-label" htmlFor={item.id}>
<p>{name}</p>
</label>
<button
{/* <button
className="delete-btn"
aria-label={`Delete ${name}`}
onClick={handleDelete}
>
<FontAwesomeIcon className="delete-icon" icon={faTrashCan} />
</button>
</button> */}
<DeleteItemConfirm onDelete={handleDelete} name={name} />
</div>
<div className="ListItem-row">
{getUrgencyBadgeInfo && (
Expand Down
105 changes: 105 additions & 0 deletions src/components/ModalAlerts.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { AlertDialog, Button, Flex } from '@radix-ui/themes';
import { SignInButton } from '../api/useAuth';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTrashCan } from '@fortawesome/free-regular-svg-icons';
import '../custom-styles.css';

export function SignInAlert({ action, description }) {
return (
<AlertDialog.Root>
<AlertDialog.Trigger>
<Button className="custom-button">{action}</Button>
</AlertDialog.Trigger>
<AlertDialog.Content maxWidth="450px">
<AlertDialog.Title>Sign In</AlertDialog.Title>
<AlertDialog.Description size="2">
In order to {description}, you must sign in first.
</AlertDialog.Description>

<Flex gap="3" mt="4" justify="end">
<AlertDialog.Cancel>
<Button variant="soft" color="gray">
Cancel
</Button>
</AlertDialog.Cancel>
<AlertDialog.Action>
<SignInButton />
</AlertDialog.Action>
</Flex>
</AlertDialog.Content>
</AlertDialog.Root>
);
}

export function DeleteItemConfirm({ onDelete, name }) {
return (
<AlertDialog.Root>
<AlertDialog.Trigger>
<button className="delete-btn" aria-label={`Delete ${name}`}>
<FontAwesomeIcon className="delete-icon" icon={faTrashCan} />
</button>
</AlertDialog.Trigger>
<AlertDialog.Content maxWidth="450px">
<AlertDialog.Title>Confirm Delete</AlertDialog.Title>
<AlertDialog.Description size="2">
Are you sure you want to delete this item from the list?
</AlertDialog.Description>

<Flex gap="3" mt="4" justify="end">
<AlertDialog.Cancel>
<Button variant="soft" color="gray">
Cancel
</Button>
</AlertDialog.Cancel>
<AlertDialog.Action>
<Button
className="custom-delete-button"
variant="solid"
aria-label={`Delete ${name}`}
onClick={onDelete}
>
Delete
</Button>
</AlertDialog.Action>
</Flex>
</AlertDialog.Content>
</AlertDialog.Root>
);
}

export function DeleteListConfirm({ name, onDelete }) {
return (
<AlertDialog.Root>
<AlertDialog.Trigger>
<button aria-label={`Delete ${name}`}>
<FontAwesomeIcon icon={faTrashCan} />
</button>
</AlertDialog.Trigger>
<AlertDialog.Content maxWidth="450px">
<AlertDialog.Title>Confirm Delete</AlertDialog.Title>
<AlertDialog.Description size="2">
Are you sure you want to delete the {name} list? This action cannot be
undone and all items in this list will be deleted.
</AlertDialog.Description>

<Flex gap="3" mt="4" justify="end">
<AlertDialog.Cancel>
<Button variant="soft" color="gray">
Cancel
</Button>
</AlertDialog.Cancel>
<AlertDialog.Action>
<Button
className="custom-delete-button"
variant="solid"
aria-label={`Delete ${name}`}
onClick={onDelete}
>
Delete
</Button>
</AlertDialog.Action>
</Flex>
</AlertDialog.Content>
</AlertDialog.Root>
);
}
Loading

0 comments on commit 45f953a

Please sign in to comment.