Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Delete lists #53

Merged
merged 5 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions src/api/firebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
updateDoc,
addDoc,
deleteDoc,
arrayRemove,
} from 'firebase/firestore';
import { useEffect, useState } from 'react';
import { db } from './config';
Expand Down Expand Up @@ -240,6 +241,91 @@ export async function deleteItem(listPath, id) {
}
}

export async function deleteList(collectionId, document, email) {
const listRef = doc(db, collectionId, document);
const userRef = doc(db, 'users', email);

try {
//check if list exists for debugging purposes
const docSnapshot = await getDoc(listRef);
if (!docSnapshot.exists()) {
console.log('Document does not exist:', listRef.path);
return;
} else {
console.log('Document exists:', listRef.path);
}
//actually delete the list
await deleteDoc(listRef);
console.log('Document deleted:', listRef.path);

//check if user list exists for debugging purposes
const docSnapshot2 = await getDoc(userRef);
if (!docSnapshot2.exists()) {
console.log('Document does not exist:', userRef.path);
return;
} else {
console.log('Document exists:', userRef.path);
}
//alert if user not found
const userDoc = await getDoc(userRef);
if (!userDoc.exists()) {
console.log('User document not found:', email);
return;
}
//show sharedLists contents before deleting ref
const sharedLists = userDoc.data().sharedLists;
console.log('Current sharedLists:', typeof sharedLists, sharedLists);
//actually delete ref from array
await updateDoc(userRef, {
sharedLists: arrayRemove(listRef),
});
console.log('User document updated');
} catch (error) {
console.error('Error deleting your list', error);
}
}

// export async function deleteCollection(listPath) {
// const collectionRef = collection(db, listPath);
// const query = collectionRef.orderBy('__name__').limit(500);
// console.log('delete collecton triggered');

// return new Promise((resolve, reject) => {
// console.log('inside promise');

// deleteQueryBatch(db, query, resolve).catch(reject);
// });
// }

// async function deleteQueryBatch(db, query, resolve) {
// const snapshot = await query.get();
// console.log('deletequery triggered');

// const batchSize = snapshot.size;
// if (batchSize === 0) {
// // When there are no documents left, we are done
// console.log('batch size 0');

// resolve();
// return;
// }

// // Delete documents in a batch
// const batch = db.batch();
// snapshot.docs.forEach((doc) => {
// console.log('deleted ', doc.ref);

// batch.delete(doc.ref);
// });
// await batch.commit();

// // Recurse on the next process tick, to avoid
// // exploding the stack.
// process.nextTick(() => {
// deleteQueryBatch(db, query, resolve);
// });
// }

export function comparePurchaseUrgency(arr) {
const groupedItems = {
Overdue: [],
Expand Down
106 changes: 102 additions & 4 deletions src/components/SingleList.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
import { deleteList } from '@/api';
import { getAuth } from 'firebase/auth';
import { useEffect, useState } from 'react';
import { FaShareNodes } from 'react-icons/fa6';
import { RiDeleteBin5Fill } from 'react-icons/ri';
import { useNavigate } from 'react-router-dom';
import toast from 'react-hot-toast';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from './ui/alert-dialog';
import { Button } from './ui/button';
import { Trash2 } from 'lucide-react';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';

export function SingleList({
name,
path,
listPath,
setListPath,
handleShareModalClick,
setSelectedItem,
}) {
const [isAlertOpen, setIsAlertOpen] = useState(false);
const [collectionId, setCollectionId] = useState('');
const singleListPath = path.split('/')[0];
const email = getAuth().currentUser.email;

useEffect(() => {
setCollectionId(singleListPath);
}, []);

const navigate = useNavigate();

function handleClick() {
Expand All @@ -20,6 +53,19 @@ export function SingleList({
handleShareModalClick();
};

const handleDeleteClick = async (name) => {
await deleteList(collectionId, name, email);
console.log(listPath, name);

if (listPath.includes(name)) {
console.log();

setListPath('');
}
toast.success(`List ${name} was deleted`);
setIsAlertOpen(false);
};

return (
<li className="flex flex-row align-middle justify-between px-2 py-3 rounded-[5px] text-[1.2em] space-x-5 w-full bg-white text-black">
<button
Expand All @@ -35,9 +81,61 @@ export function SingleList({
>
<FaShareNodes />
</button>
<button className="text-pink-500 hover:text-pink-600">
<RiDeleteBin5Fill />
</button>
{getAuth().currentUser.uid === singleListPath ? (
<AlertDialog open={isAlertOpen} onOpenChange={setIsAlertOpen}>
<AlertDialogTrigger asChild>
<Button
className="bg-transparent hover:bg-transparent"
type="button"
onClick={() => setIsAlertOpen(true)}
>
<Trash2 className="text-pink-500 hover:text-pink-600" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle className="text-pink-500">
Are you absolutely sure?
</AlertDialogTitle>
<AlertDialogDescription>
This will permanently delete your list. Do you really want to
delete {name}?
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel
className="p-5 bg-red-600 rounded text-white hover:bg-red-800"
onClick={() => setIsAlertOpen(false)}
>
Cancel
</AlertDialogCancel>
<AlertDialogAction
className="p-5 bg-green-600 rounded text-white hover:bg-green-800"
onClick={() => handleDeleteClick(name)}
>
Continue
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
) : (
<TooltipProvider>
<Tooltip delayDuration={100}>
<TooltipTrigger asChild>
<Button
className="bg-transparent hover:bg-transparent"
type="button"
onClick={() => setIsAlertOpen(true)}
>
<Trash2 className="text-gray-500" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>You cannot delete a list you don&#39;t own!</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
</div>
</li>
);
Expand Down
2 changes: 2 additions & 0 deletions src/views/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export function Home({
handleShareModalClick,
}) {
const [selectedItem, setSelectedItem] = useState('');

return (
<div className="flex flex-col space-y-10 justify-center ">
<div className="flex flex-row justify-center">
Expand Down Expand Up @@ -40,6 +41,7 @@ export function Home({
key={index}
name={item.name}
path={item.path}
listPath={listPath}
setListPath={setListPath}
handleShareModalClick={handleShareModalClick}
setSelectedItem={setSelectedItem}
Expand Down
Loading