Skip to content

Commit

Permalink
Merge pull request #59 from the-collab-lab/st-managelist
Browse files Browse the repository at this point in the history
Issue #21: Implement TailwindCSS for ManageList page, refactor naming to AddItem page and modal close for Create List.
  • Loading branch information
shuveksha-tuladhar authored Oct 10, 2024
2 parents dc23352 + 1bbe3db commit 4920011
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 126 deletions.
6 changes: 3 additions & 3 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { Suspense } from 'react';
import { Home, Layout, ManageList, Team } from './views';
import { Home, Layout, AddItem, Team } from './views';
import { Loading } from './components/Loading';
import { ProtectedRoute } from './components/ProtectedRoute';
import { useAuth, useShoppingListData, useShoppingLists } from './api';
Expand Down Expand Up @@ -59,10 +59,10 @@ export function App() {
}
/>
<Route
path="manage-list"
path="add-item"
element={
<ProtectedRoute>
<ManageList listPath={listPath} user={user} data={data} />
<AddItem listPath={listPath} user={user} data={data} />
</ProtectedRoute>
}
/>
Expand Down
148 changes: 148 additions & 0 deletions src/views/AddItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { ToastContainer } from 'react-toastify';
import { useState, useMemo } from 'react';
import { addItem } from '../api/firebase';
import { FaPlusSquare } from 'react-icons/fa';
import { IconButton } from '../components/IconButton';
import { notify } from '../utils/notifications';

export function AddItem({ listPath, data }) {
const [itemName, setItemName] = useState('');
const [daysUntilNextPurchase, setDaysUntilNextPurchase] = useState(7);

const messages = {
added: 'Your item was successfully added!',
failed:
"Your item wasn't added! There was an error saving the item. Please try again.",
empty: 'Please enter an item to add to your list.',
duplicate: 'Item already exists!',
};

const extractedListName = listPath.match(/(?<=\/).*$/)[0];

const normalizeString = (str) =>
str.toLowerCase().replace(/[^a-z0-9-]+/g, '');

const normalizedData = useMemo(
() => data.map((item) => normalizeString(item.name)),
[data],
);
const handleSubmit = async (event) => {
event.preventDefault();

const normalizedItemName = normalizeString(itemName.trim());

if (!normalizedItemName) {
notify(messages['empty'], 'warning');
return;
}

const itemMatch = normalizedData.includes(normalizedItemName);

if (itemMatch) {
notify(messages['duplicate'], 'warning');
return;
}

try {
await addItem(listPath, {
itemName: normalizedItemName,
daysUntilNextPurchase,
});
setItemName('');
setDaysUntilNextPurchase(7);
notify(messages['added'], 'success');
} catch (error) {
console.error('Error adding item:', error);
notify(messages['failed'], 'error');
}
};

return (
<div className="container p-6 rounded-lg shadow-md">
<ToastContainer />
<h1 className="text-4xl text-txtPrimary font-semibold my-6 text-center">
Manage Your Shopping List for{' '}
<span className="text-txtSecondary font-bold">{extractedListName}</span>
</h1>
<form onSubmit={handleSubmit} className="space-y-6">
<div className="flex flex-col mb-4 items-center">
<label
htmlFor="itemName"
className="text-3xl text-txtPrimary font-semibold"
>
Please enter an item name
</label>
<input
type="text"
id="itemName"
value={itemName}
onChange={(e) => setItemName(e.target.value)}
placeholder="Add an item name"
className="border border-gray-300 rounded-lg p-2 w-full focus:ring focus:ring-blue-300 focus:outline-none transition duration-150 ease-in-out hover:shadow-md"
/>
</div>
<fieldset className="border border-gray-200 p-8 m-6 rounded-lg shadow-md">
<legend className="text-3xl text-txtPrimary mb-4 font-semibold">
How soon will you need to buy this item again?
</legend>
<div className="grid grid-cols-1 md:grid-cols-3 gap-10 justify-items-center items-center">
<div className="border border-gray-300 p-2 bg-radio-gradient w-[20rem] rounded-lg transition-transform duration-300 hover:scale-105 hover:shadow-lg">
<label className="flex items-center justify-center cursor-pointer w-full mb-4 mt-4">
<input
type="radio"
value={7}
checked={daysUntilNextPurchase === 7}
onChange={() => setDaysUntilNextPurchase(7)}
className="mr-4 text-txtPrimary"
/>
<span className="text-2xl font-medium text-white ">
Soon (7 days)
</span>
</label>
</div>

<div className="border border-gray-300 p-2 bg-radio-gradient w-[20rem] rounded-lg transition-transform duration-300 hover:scale-105 hover:shadow-lg">
<label className="flex items-center justify-center cursor-pointer max-w-sm mb-4 mt-4">
<input
type="radio"
value={14}
checked={daysUntilNextPurchase === 14}
onChange={() => setDaysUntilNextPurchase(14)}
className="mr-6"
/>
<span className="text-2xl font-medium text-white ">
Kind of soon (14 days)
</span>
</label>
</div>

<div className="border border-gray-300 p-2 bg-radio-gradient w-[20rem] rounded-lg transition-transform duration-300 hover:scale-105 hover:shadow-lg">
<label className="flex items-center justify-center cursor-pointer max-w-md mb-4 mt-4">
<input
type="radio"
value={30}
checked={daysUntilNextPurchase === 30}
onChange={() => setDaysUntilNextPurchase(30)}
className="mr-3"
/>
<span className="text-2xl font-medium text-white ">
Not soon (30 days)
</span>
</label>
</div>
</div>
</fieldset>
<div className="flex justify-center">
<IconButton
aria-label="Add item to your list"
as="button"
label="Add an item"
IconComponent={FaPlusSquare}
className="mt-1 block w-1/8 rounded-md border border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-lg py-3 px-4"
/>
</div>
</form>
<br></br>
</div>
);
}
9 changes: 5 additions & 4 deletions src/views/CreateList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ export function CreateList({
isCreateListModalOpen,
setIsCreateListModalOpen,
user,
setListPath,
}) {
const userId = user?.uid;
const userEmail = user?.email;

const [listPath, setListPath] = useState('');
const [listName, setListName] = useState('');

const handleChange = (event) => {
Expand All @@ -25,8 +25,9 @@ export function CreateList({
if (listName) {
try {
const newListPath = await createList(userId, userEmail, listName);
notify('List is sucessfully created', 'success');
setListPath(newListPath);
setIsCreateListModalOpen(false);
notify(`${listName} is sucessfully created`, 'success');
} catch {
notify('There was an error adding your list', 'error');
}
Expand Down Expand Up @@ -58,7 +59,7 @@ export function CreateList({
<IconButton
aria-label="Add a list"
as="button"
className="inline-flex justify-center rounded-md bg-[#184E77] px-4 py-[.75rem] text-lg font-medium text-white shadow-sm hover:bg-[#1E6091] transition duration-200 ease-in-out mr-10"
className="inline-flex justify-center rounded-md bg-btnPrimary px-4 py-[.75rem] text-lg font-medium text-white shadow-sm hover:bg-btnPrimary transition duration-200 ease-in-out mr-10"
label="Add"
IconComponent={FaPlusSquare}
type="submit"
Expand All @@ -67,7 +68,7 @@ export function CreateList({
aria-label="Cancel adding"
as="button"
onClick={() => setIsCreateListModalOpen(false)}
className="inline-flex justify-center rounded-md bg-[#184E77] px-4 py-[.75rem] text-lg font-medium text-white shadow-sm ring-1 ring-gray-300 hover:bg-[#1E6091] transition duration-200 ease-in-out" // Increased button padding and font size
className="inline-flex justify-center rounded-md bg-btnPrimary px-4 py-[.75rem] text-lg font-medium text-white shadow-sm ring-1 ring-gray-300 hover:bg-btnPrimary transition duration-200 ease-in-out" // Increased button padding and font size
label="Cancel"
IconComponent={FaTimes}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/views/Disclosure.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function Disclosure({
listpath,
setListPath,
}) {
const [isOpen, setIsOpen] = useState(false);
const [isOpen, setIsOpen] = useState(listpath === currentListPath);

useEffect(() => {
if (currentListPath !== listpath) {
Expand Down
1 change: 1 addition & 0 deletions src/views/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export function Home({ data, lists, listPath, setListPath, user }) {
isCreateListModalOpen={isCreateListModalOpen}
setIsCreateListModalOpen={setIsCreateListModalOpen}
user={user}
setListPath={setListPath}
/>
)}
<div className="flex justify-center items-center">
Expand Down
2 changes: 1 addition & 1 deletion src/views/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function Layout() {
IconComponent={FaCartPlus}
//className
label="Add Item"
to="/manage-list"
to="/add-item"
/>
<IconButton
aria-label="Sign Out"
Expand Down
116 changes: 0 additions & 116 deletions src/views/ManageList.jsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/views/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './ManageList';
export * from './AddItem';
export * from './Home';
export * from './Layout';
export * from './LandingPage';
Expand Down
4 changes: 4 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export default {
txtPrimary: '#184E77', // Primary color Text
txtSecondary: '#34A0A4', // Secondary color Text
},
backgroundImage: {
'radio-gradient':
'linear-gradient(to top, #34A0A4, #168AAD, #1A759F, #1E6091, #184E77)',
},
},
},
plugins: [],
Expand Down

0 comments on commit 4920011

Please sign in to comment.