Skip to content

Commit

Permalink
Merge pull request #57 from the-collab-lab/hm-loading-bug-fix
Browse files Browse the repository at this point in the history
Loading state bug fix and minor style adjustments
  • Loading branch information
Hudamabkhoot authored Oct 18, 2024
2 parents b80f2e4 + 32e36d7 commit fdbed55
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 47 deletions.
5 changes: 1 addition & 4 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import Login from './views/Login';

export function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);

/**
* This custom hook takes the path of a shopping list
Expand Down Expand Up @@ -43,7 +42,7 @@ export function App() {
* This custom hook takes our token and fetches the data for our list.
* Check ./api/firestore.js for its implementation.
*/
const data = useShoppingListData(listPath);
const { data, isLoading } = useShoppingListData(listPath);

const handleShareModalClick = () => {
console.log('isModalOpen', isModalOpen);
Expand All @@ -65,7 +64,6 @@ export function App() {
setListPath={setListPath}
isModalOpen={isModalOpen}
handleShareModalClick={handleShareModalClick}
setIsLoading={setIsLoading}
/>
}
/>
Expand All @@ -77,7 +75,6 @@ export function App() {
listPath={listPath}
listName={listName}
isLoading={isLoading}
setIsLoading={setIsLoading}
/>
}
/>
Expand Down
10 changes: 8 additions & 2 deletions src/api/firebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,15 @@ export function useShoppingListData(listPath) {
/** @type {import('firebase/firestore').DocumentData[]} */
const initialState = [];
const [data, setData] = useState(initialState);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
if (!listPath) return;
if (!listPath) {
setIsLoading(false);
return;
}

setIsLoading(true);
// When we get a listPath, we use it to subscribe to real-time updates
// from Firestore.
return onSnapshot(collection(db, listPath, 'items'), (snapshot) => {
Expand All @@ -84,11 +89,12 @@ export function useShoppingListData(listPath) {

// Update our React state with the new data.
setData(nextData);
setIsLoading(false);
});
}, [listPath]);

// Return the data so it can be used by our React components.
return data;
return { data, isLoading };
}

/**
Expand Down
11 changes: 8 additions & 3 deletions src/components/CreateShoppingList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createList } from '../api/firebase';
import { useNavigate } from 'react-router-dom';
import toast from 'react-hot-toast';
import { Input } from './ui/input';
import { ListPlus } from 'lucide-react';

export default function CreateShoppingList({ user, setListPath }) {
const [listName, setListName] = useState('');
Expand All @@ -28,20 +29,24 @@ export default function CreateShoppingList({ user, setListPath }) {
onSubmit={handleSubmit}
className="relative w-full flex items-center justify-center gap-4 max-w-lg mx-auto "
>
<div className="flex flex-col w-full max-w-xs ">
<label htmlFor="shoppingList" className="text-sm font-light ">
<div className="flex flex-col w-full max-w-xs relative">
<label htmlFor="shoppingList" className="text-sm font-light pb-2">
Create a new list
</label>
<Input
className="border-[1px] rounded-[5px] text-[1em] h-[3rem] pl-10 focus-visible:outline-none focus:ring-1 focus:ring-primary-green text-black dark:text-white bg-white dark:bg-bg-black"
id="shoppingList"
type="text"
value={listName}
placeholder="Enter your list name..."
onChange={(e) => setListName(e.target.value)}
required
/>
<span className="absolute inset-y-0 left-0 top-7 flex items-center pl-3 pointer-events-none">
<ListPlus className="h-5 w-5 text-grey" />
</span>
</div>
<div className="flex pt-5">
<div className="flex pt-5 mt-2">
<button
type="submit"
className="bg-light-green hover:bg-light-green dark:bg-primary-green dark:hover:bg-primary-green hover:bg-opacity-75 dark:hover:bg-opacity-75 text-black font-bold h-[3rem] px-5 rounded-[5px] flex items-center space-x-2"
Expand Down
4 changes: 2 additions & 2 deletions src/components/ListItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export function ListItem({
<Dialog open={isOpen} onOpenChange={() => handleOpenModal(id)}>
<DialogTrigger asChild>
<Button className="bg-transparent hover:bg-transparent p-0">
<Pencil className="w-5 h-5 md:w-6 md:h-6 text-light-grey hover:text-opacity-75 dark:text-emerald-500 dark:hover:text-opacity-80 transform hover:scale-110 transition-transform duration-150 sm:hover:scale-125" />
<Pencil className="w-5 h-5 text-light-grey hover:text-opacity-75 dark:text-emerald-500 dark:hover:text-opacity-80 transform hover:scale-110 transition-transform duration-150 sm:hover:scale-125" />
</Button>
</DialogTrigger>
<DialogContent>
Expand Down Expand Up @@ -146,7 +146,7 @@ export function ListItem({
id={id}
onClick={() => setIsAlertOpen(true)}
>
<Trash2 className="w-5 h-5 md:w-6 md:h-6 text-gray-600 hover:text-opacity-75 dark:text-emerald-500 dark:hover:text-opacity-80 transform hover:scale-110 transition-transform duration-150 sm:hover:scale-125" />
<Trash2 className="w-5 h-5 text-gray-600 hover:text-opacity-75 dark:text-emerald-500 dark:hover:text-opacity-80 transform hover:scale-110 transition-transform duration-150 sm:hover:scale-125" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent className="p-6 sm:p-10">
Expand Down
8 changes: 4 additions & 4 deletions src/components/SearchBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export function SearchBar({ allData, setDisplayData, setSearch, search }) {
};

return (
<form className="relative w-full -top-[3px]">
<label htmlFor="shoppingList" className="text-sm font-light">
<form className="relative w-full">
<label htmlFor="shoppingList" className="text-sm font-light pb-2">
Filter lists
</label>
<Input
Expand All @@ -24,9 +24,9 @@ export function SearchBar({ allData, setDisplayData, setSearch, search }) {
value={search}
placeholder="Search..."
onChange={handleInputChange}
className="border-[1px] rounded-[5px] text-[1em] h-[3rem] pl-10 focus-visible:outline-none focus:ring-1 focus:ring-primary-green text-black dark:text-white bg-white dark:bg-bg-black"
className="border-[1px] rounded-[5px] mt-2 text-[1em] h-[3rem] pl-10 focus-visible:outline-none focus:ring-1 focus:ring-primary-green text-black dark:text-white bg-white dark:bg-bg-black"
/>
<span className="absolute inset-y-0 left-0 top-6 flex items-center pl-3 pointer-events-none">
<span className="absolute inset-y-0 left-0 top-8 flex items-center pl-3 pointer-events-none">
<ListFilter className="h-5 w-5 text-grey" />
</span>
</form>
Expand Down
20 changes: 13 additions & 7 deletions src/components/SingleList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ export function SingleList({
setListPath,
handleShareModalClick,
setSelectedItem,
setIsLoading,
}) {
const [isAlertOpen, setIsAlertOpen] = useState(false);
const [collectionId, setCollectionId] = useState('');
const [shouldNavigate, setShouldNavigate] = useState(false);
const singleListPath = path.split('/')[0];
const email = getAuth().currentUser.email;

Expand All @@ -44,10 +44,16 @@ export function SingleList({

const navigate = useNavigate();

useEffect(() => {
if (shouldNavigate) {
navigate('/list');
setShouldNavigate(false);
}
}, [shouldNavigate]);

function handleClick() {
setIsLoading(true);
setListPath(path);
navigate(`/list`);
setShouldNavigate(true);
}

const handleShareClick = () => {
Expand Down Expand Up @@ -83,7 +89,7 @@ export function SingleList({
aria-label="Share list"
className="text-green-500 hover:text-green-500 dark:text-ruby-pink dark:hover:text-primary-pink hover:text-opacity-80 dark:hover:text-opacity-80 transform hover:scale-110 transition-transform duration-150 sm:hover:scale-125"
>
<FaShareNodes className="w-5 h-5 md:w-6 md:h-6" />
<FaShareNodes className="w-5 h-5" />
</button>
) : (
<TooltipProvider>
Expand All @@ -94,7 +100,7 @@ export function SingleList({
type="button"
onClick={() => setIsAlertOpen(true)}
>
<FaShareNodes className="w-5 h-5 md:w-6 md:h-6 text-gray-500" />
<FaShareNodes className="w-5 h-5 text-gray-500" />
</Button>
</TooltipTrigger>
<TooltipContent>
Expand All @@ -111,7 +117,7 @@ export function SingleList({
type="button"
onClick={() => setIsAlertOpen(true)}
>
<Trash2 className="w-5 h-5 md:w-6 md:h-6 text-primary-pink hover:text-opacity-75 dark:text-emerald-500 dark:hover:text-opacity-80 transform hover:scale-110 transition-transform duration-150 sm:hover:scale-125" />
<Trash2 className="w-5 h-5 text-primary-pink hover:text-opacity-75 dark:text-emerald-500 dark:hover:text-opacity-80 transform hover:scale-110 transition-transform duration-150 sm:hover:scale-125" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
Expand Down Expand Up @@ -149,7 +155,7 @@ export function SingleList({
type="button"
onClick={() => setIsAlertOpen(true)}
>
<Trash2 className="text-gray-500" />
<Trash2 className="w-5 h-5 text-gray-500" />
</Button>
</TooltipTrigger>
<TooltipContent>
Expand Down
2 changes: 0 additions & 2 deletions src/views/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export function Home({
setListPath,
isModalOpen,
handleShareModalClick,
setIsLoading,
}) {
const [selectedItem, setSelectedItem] = useState('');

Expand Down Expand Up @@ -55,7 +54,6 @@ export function Home({
setListPath={setListPath}
handleShareModalClick={handleShareModalClick}
setSelectedItem={setSelectedItem}
setIsLoading={setIsLoading}
/>
))}
</ul>
Expand Down
50 changes: 27 additions & 23 deletions src/views/List.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@ import {
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { SquarePlus } from 'lucide-react';
import { useNavigate } from 'react-router-dom';

export function List({ data, listPath, listName, isLoading, setIsLoading }) {
export function List({ data, listPath, listName, isLoading }) {
const [search, setSearch] = useState('');
const [allData, setAllData] = useState([]);
const [displayData, setDisplayData] = useState([]);
const [isOpen, setIsOpen] = useState(false);
const [openItemId, setOpenItemId] = useState(null);
const [noData, setNoData] = useState(false);

useEffect(() => {
setIsLoading(true);
const arrayWithIndicator = data.map((item) => ({
...item,
indicator: getIndicator(item),
Expand All @@ -34,19 +33,6 @@ export function List({ data, listPath, listName, isLoading, setIsLoading }) {
setDisplayData(urgencyData);
}, [data]);

useEffect(() => {
if (displayData.length > 1) {
setIsLoading(false);
}
}, [displayData]);

setTimeout(() => {
if (data.length === 0) {
setIsLoading(false);
setNoData(true);
}
}, 2000);

const handleAddModal = () => {
if (search.length > 0) {
setDisplayData(allData);
Expand All @@ -60,20 +46,38 @@ export function List({ data, listPath, listName, isLoading, setIsLoading }) {
setOpenItemId((prevId) => (prevId === id ? null : id));
};

const navigate = useNavigate();

function handleClick() {
navigate('/');
}

return (
<>
{listPath === '' ? (
<div className="flex flex-col space-y-10 justify-center items-center">
{listPath === '' || !listPath ? (
<div className="flex flex-col space-y-10 justify-center items-center gap-3">
<div className="relative inline-block">
<h1 className="font-[montserrat] text-3xl font-bold text-gray">
<span className="relative inline-block">No list selected</span>
</h1>
<img
src="/img/underline.png"
src="/img/ruby-underline.png"
alt="Description"
className="absolute bottom-[-12px] -right-3 w-14 h-3 dark:hidden"
/>
<img
src="/img/light-pink-underline.png"
alt="Description"
className="absolute bottom-[-12px] -right-3 w-14 h-3"
className="absolute bottom-[-12px] -right-3 w-14 h-3 hidden dark:block"
/>
</div>
<Button
onClick={handleClick}
className="bg-ruby-pink text-white rounded-xl dark:bg-primary-green dark:text-black w-full hover:bg-ruby-pink dark:hover:bg-primary-green hover:bg-opacity-75 dark:hover:bg-opacity-75 text-sm md:text-base font-semibold max-w-[250px]"
>
<SquarePlus className="h-5 w-5 md:w-6 md:h-6 mr-2" />
Let&#39;s get you started!
</Button>
</div>
) : (
<div className="flex flex-col space-y-10 justify-center items-center">
Expand Down Expand Up @@ -104,7 +108,7 @@ export function List({ data, listPath, listName, isLoading, setIsLoading }) {
<Dialog open={isOpen} onOpenChange={handleAddModal}>
<DialogTrigger asChild className="items-start mt-[19px]">
<Button className="bg-transparen hover:bg-transparen p-0">
<SquarePlus className="h-10 w-10 text-primary-green dark:text-primary-pink transition-opacity hover:opacity-75" />
<SquarePlus className="h-10 w-10 mt-2 text-primary-green dark:text-primary-pink transition-opacity hover:opacity-75" />
</Button>
</DialogTrigger>
<DialogContent>
Expand Down Expand Up @@ -165,13 +169,13 @@ export function List({ data, listPath, listName, isLoading, setIsLoading }) {
))}
</ul>
)}
{!isLoading && noData && displayData.length === 0 && (
{!isLoading && data.length === 0 && (
<div className="flex flex-col justify-center items-center gap-4 w-full mx-auto">
<p className="text-grey text-center">
Your list is empty. Start adding some items now!
</p>
<Button
className="bg-primary-pink text-white rounded-xl dark:bg-primary-green dark:text-black w-full hover:bg-primary-pink hover:bg-opacity-75 text-sm font-semibold max-w-[150px]"
className="bg-primary-pink text-white rounded-xl dark:bg-primary-green dark:text-black w-full hover:bg-primary-pink dark:hover:bg-primary-green hover:bg-opacity-75 dark:hover:bg-opacity-75 text-sm font-semibold max-w-[150px]"
id="addFirstItem"
onClick={() => setIsOpen((prev) => !prev)}
>
Expand Down

0 comments on commit fdbed55

Please sign in to comment.