Skip to content

Commit

Permalink
Merge pull request #53 from the-collab-lab/qg-feat-delete-list
Browse files Browse the repository at this point in the history
Feat: Delete lists
  • Loading branch information
Wyna-7 authored Oct 12, 2024
2 parents 7eba74b + ed975e4 commit 83c0428
Show file tree
Hide file tree
Showing 4 changed files with 284 additions and 96 deletions.
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
109 changes: 102 additions & 7 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 { Trash2 } from 'lucide-react';
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 pl-4 pr-4 py-[10px] rounded-[3px] text-[1em] space-x-3 w-full bg-white dark:bg-[#2f3031] text-black dark:text-gray-200 shadow-md shadow-slate-400 dark:shadow-gray-600 border border-gray-300 dark:border-gray-500 mt-2 sm:pl-6 sm:pr-6 sm:py-[14px] sm:rounded-[5px] sm:text-[1.2em] sm:space-x-5">
<button
Expand All @@ -36,12 +82,61 @@ export function SingleList({
>
<FaShareNodes className="w-5 h-5 sm:w-6 sm:h-6" />
</button>
<button
aria-label="Delete list"
className="text-ruby-pink hover:text-ruby-pink hover:text-opacity-80 dark:text-emerald-500 dark:hover:text-emerald-300 dark:hover:text-opacity-80 transform hover:scale-110 transition-transform duration-150 sm:hover:scale-125"
>
<Trash2 className="w-5 h-5 sm:w-6 sm:h-6 md:w-7 md:h-7" />
</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-sm text-slate-800 dark:text-slate-400 sm:text-lg">
Are you absolutely sure?
</AlertDialogTitle>
<AlertDialogDescription className="text-slate-700">
This will permanently delete your list. Do you really want to
delete {name}?
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel
className="bg-white text-slate-700 hover:bg-slate-100 px-6 border rounded-lg sm:px-8 sm:rounded-xl"
onClick={() => setIsAlertOpen(false)}
>
Cancel
</AlertDialogCancel>
<AlertDialogAction
className="bg-primary-pink text-white hover:bg-opacity-90 px-6 border rounded-lg sm:px-8 sm:rounded-xl"
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 @@ -49,6 +50,7 @@ export function Home({
key={index}
name={item.name}
path={item.path}
listPath={listPath}
setListPath={setListPath}
handleShareModalClick={handleShareModalClick}
setSelectedItem={setSelectedItem}
Expand Down
Loading

0 comments on commit 83c0428

Please sign in to comment.