Skip to content

Commit

Permalink
Merge pull request #59 from the-collab-lab/sc-issue-22
Browse files Browse the repository at this point in the history
Sc issue 22
  • Loading branch information
eonflower authored Apr 5, 2024
2 parents 8078eb5 + 9ca831f commit 855ca48
Show file tree
Hide file tree
Showing 15 changed files with 527 additions and 193 deletions.
13 changes: 13 additions & 0 deletions public/sprite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export function App() {
data={lists}
setListPath={setListPath}
setLoading={setLoading}
loading={loading}
/>
</Suspense>
}
Expand Down
3 changes: 0 additions & 3 deletions src/api/useAuth.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,9 @@ export const SignInButton = () => {
await getRedirectResult(auth);
} catch (redirectError) {
console.error('Error during redirect sign-in:', redirectError);
// TODO ADD TOAST ONCE COMPONENT COMMITTED
}
} else {
console.error('Error during popup sign-in:', error);
// TODO ADD TOAST ONCE COMPONENT COMMITTED
}
} finally {
setLoading(false);
Expand Down Expand Up @@ -70,7 +68,6 @@ export const SignOutButton = () => {
} catch (error) {
console.error('Error signing out:', error);
window.alert('Error signing out. Please try again.');
// TODO ADD TOAST ONCE COMPONENT IS COMPLETE
} finally {
setLoading(false);
}
Expand Down
100 changes: 69 additions & 31 deletions src/components/AddItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import TextInput from '../components/TextInput';
import Button from './Button';
import SelectInput from './SelectInput';
import { GoPlus } from 'react-icons/go';
import { useToast } from '../utils/hooks';
import Toast from './Toast';

export default function AddItem({ listPath, data }) {
const { toasts, addToast } = useToast();

const initialState = {
itemName: '',
daysUntilNextPurchase: '',
Expand All @@ -28,29 +32,58 @@ export default function AddItem({ listPath, data }) {
e.preventDefault();

const newItemName = itemValue.itemName.trim();

// Check that the user added the timeframe
if (itemValue.daysUntilNextPurchase === '') {
alert('Please select a timeframe to add item to list!');
addToast({
id: 'toastTimeframe',
message: 'Eeep, select a time frame to add an item to your list!',
iconName: 'warning',
color: 'orange',
});
return;
}
// Check if the itemName is empty
if (newItemName === '') {
alert(`Please name your item. Empty spaces don't count!`);
addToast({
id: 'toastEmptyName',
message: "Please name your item. Heh, empty spaces don't count!",
iconName: 'warning',
color: 'orange',
});
return;
}

// Check if the itemName already exists in the list
if (existingItem(newItemName)) {
alert('Uh oh, this item is already in your list!');
addToast({
id: 'toastExistingItem',
message: `All good, ${newItemName} is already in your list!`,
iconName: 'error',
color: 'red',
});
return;
}

try {
// adds item after checks pass
await addItem(listPath, itemValue);
alert(`${newItemName} added to list!`);
addToast({
id: 'toastItemAdded',
message: `Done! ${newItemName} added to list!`,
iconName: 'check',
color: 'blue',
});
setItemValue(initialState);
// alert(`Done! ${newItemName} added to list!`);
} catch (err) {
alert('Error adding item to database');
// alerts user something else went wrong
addToast({
id: 'toastItemAddErr',
message: `There was an error adding ${newItemName} to your list, please try again`,
iconName: 'error',
color: 'red',
});
console.error(err);
}
};

Expand All @@ -63,30 +96,35 @@ export default function AddItem({ listPath, data }) {
};

return (
<form onSubmit={handleSubmit}>
<div className="flex items-end flex-wrap xsm:justify-center sm:justify-normal xsm:gap-2 sm:gap-4 w-full xsm:mb-4">
<TextInput
label="Add item"
name="itemName"
placeholder="Add item to list"
onChange={handleInputChange}
value={itemValue.itemName}
/>
<SelectInput
label="Timeframe"
id="timeframe"
name="daysUntilNextPurchase"
value={itemValue.daysUntilNextPurchase}
onChange={handleInputChange}
/>
<Button
type="submit"
text="Add item"
bgColor="bg-tcl-blue"
textColor="text-white"
icon={<GoPlus size={19} />}
/>
</div>
</form>
<>
{toasts.map((toast) => (
<Toast key={toast.id} {...toast} />
))}
<form onSubmit={handleSubmit}>
<div className="flex items-end flex-wrap xsm:justify-center sm:justify-normal xsm:gap-2 sm:gap-4 w-full xsm:mb-4">
<TextInput
label="Add item"
name="itemName"
placeholder="Add item to list"
onChange={handleInputChange}
value={itemValue.itemName}
/>
<SelectInput
label="Timeframe"
id="timeframe"
name="daysUntilNextPurchase"
value={itemValue.daysUntilNextPurchase}
onChange={handleInputChange}
/>
<Button
type="submit"
text="Add item"
bgColor="bg-tcl-blue"
textColor="text-white"
icon={<GoPlus size={19} />}
/>
</div>
</form>
</>
);
}
47 changes: 33 additions & 14 deletions src/components/AddList.jsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,70 @@
import { useNavigate } from 'react-router-dom';
import { useState } from 'react';
import { GoPlus } from 'react-icons/go';
import { createList } from '../api';
import { useAuth } from '../api/useAuth.jsx';
import { useToast } from '../utils/hooks.js';
import Button from './Button.jsx';
import TextInput from './TextInput.jsx';
import { GoPlus } from 'react-icons/go';
import Toast from './Toast';
import capitalizeFirstLetterOfEachWord from '../utils/capitalize.js';

export default function AddList({ setListPath }) {
const [listName, setListName] = useState('');
const [message, setMessage] = useState('');
const navigate = useNavigate();
const { user } = useAuth();
const { toasts, addToast } = useToast();

const handleSubmit = async (e) => {
e.preventDefault();
try {
if (!listName) {
window.alert('Please enter a list name');
addToast({
id: 'noListName',
message: 'Please name your list',
iconName: 'warning',
color: 'orange',
});
return;
}
const newList = await createList(user.uid, user.email, listName);
const listPath = user.uid + '/' + listName;
// if list is created newList will be true else newList will be false
if (newList) {
setListName('');
setMessage(
`${capitalizeFirstLetterOfEachWord(listName)} was successfully created.`,
);
addToast({
id: 'newListCreated',
message: `Your list, ${capitalizeFirstLetterOfEachWord(listName)}, was successfully created.`,
iconName: 'check',
color: 'blue',
});
setListPath(listPath);
setTimeout(() => {
navigate('/list');
}, 2000);
}, 3000);
} else {
setMessage(
`${capitalizeFirstLetterOfEachWord(listName)} was not created. Please try again.`,
);
addToast({
id: 'problemCreatingList',
message: `Eeep, ${capitalizeFirstLetterOfEachWord(listName)} list was not created. Please try again.`,
iconName: 'error',
color: 'red',
});
}
} catch (err) {
console.error(err);
setMessage(
`An error occurred while creating your list, ${listName}: ${err.message}.`,
);
addToast({
id: 'errorCreatingList',
message: `An error occurred while creating your list, ${listName}: ${err.message}.`,
iconName: 'error',
color: 'red',
});
}
};
return (
<>
{toasts.map((toast) => (
<Toast key={toast.id} {...toast} />
))}
<form
onSubmit={handleSubmit}
className="flex justify-center items-end flex-wrap space-x-2 gap-2"
Expand All @@ -63,7 +83,6 @@ export default function AddList({ setListPath }) {
icon={<GoPlus size={19} />}
/>
</form>
{message ? <p>{message}</p> : null}
</>
);
}
58 changes: 58 additions & 0 deletions src/components/ConfirmToast.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Svg from './Svg';

const ConfirmToast = ({
id,
message,
iconName,
color,
onConfirm,
onCancel,
}) => {
// Render the toast only if the message is not empty
if (!message) {
return null;
}
return (
<div className="fixed inset-0 flex items-center justify-center z-50 backdrop-brightness-50">
<div
id={id}
className={`w-full max-w-md my-2 py-8 px-4 mb-3 text-gray-500 bg-white rounded-lg shadow-xl border border-gray-100`}
role="alert"
>
<div className="flex items-center">
<div
className={`inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-${color}-500 bg-${color}-100 rounded-lg`}
>
<Svg className="w-4 h-4" aria-hidden="true" symbolId={iconName} />
<span className="sr-only">{iconName} icon</span>
</div>
<div className="ms-3 text-sm font-normal">
<span className="text-sm font-semibold text-gray-900">
{message}
</span>
<div className="my-2 text-sm font-normal">
This action is forever-eva-eva.
</div>
<div className="mt-[20px] flex w-full">
<button
type="button"
onClick={onCancel}
className="mr-[10px] w-full border-1 border-gray-200 rounded-md px-4 py-[12px]"
>
Cancel
</button>
<button
onClick={onConfirm}
className="rounded-md w-full px-4 py-[12px] text-white bg-red-700"
>
Delete
</button>
</div>
</div>
</div>
</div>
</div>
);
};

export default ConfirmToast;
Loading

0 comments on commit 855ca48

Please sign in to comment.