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 all 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
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
Loading