From fbd67b01edc5290d27df41d941f2d5fa3497114a Mon Sep 17 00:00:00 2001 From: wyna Date: Fri, 11 Oct 2024 20:55:01 +0200 Subject: [PATCH 1/4] firebase delete list method --- src/api/firebase.js | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/api/firebase.js b/src/api/firebase.js index 4581091..bfc0ecc 100644 --- a/src/api/firebase.js +++ b/src/api/firebase.js @@ -8,6 +8,7 @@ import { updateDoc, addDoc, deleteDoc, + arrayRemove, } from 'firebase/firestore'; import { useEffect, useState } from 'react'; import { db } from './config'; @@ -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: [], From 57d60d0d35525f4d832edd452866e3c985be763a Mon Sep 17 00:00:00 2001 From: wyna Date: Fri, 11 Oct 2024 20:58:42 +0200 Subject: [PATCH 2/4] dfeat:delete list + remove from selected + disable delete for other user lists --- src/components/SingleList.jsx | 40 +++++++- src/views/Home.jsx | 2 + src/views/List.jsx | 173 +++++++++++++++++++--------------- 3 files changed, 134 insertions(+), 81 deletions(-) diff --git a/src/components/SingleList.jsx b/src/components/SingleList.jsx index 959ed85..4a3b111 100644 --- a/src/components/SingleList.jsx +++ b/src/components/SingleList.jsx @@ -1,13 +1,26 @@ +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'; export function SingleList({ name, path, + listPath, setListPath, handleShareModalClick, setSelectedItem, }) { + const [collectionId, setCollectionId] = useState(''); + const singleListPath = path.split('/')[0]; + const email = getAuth().currentUser.email; + + useEffect(() => { + setCollectionId(singleListPath); + }, []); + const navigate = useNavigate(); function handleClick() { @@ -20,6 +33,18 @@ 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`); + }; + return (
  • - + {getAuth().currentUser.uid === singleListPath ? ( + + ) : ( +
    + +
    + )}
  • ); diff --git a/src/views/Home.jsx b/src/views/Home.jsx index df527a5..cc4bd25 100644 --- a/src/views/Home.jsx +++ b/src/views/Home.jsx @@ -11,6 +11,7 @@ export function Home({ handleShareModalClick, }) { const [selectedItem, setSelectedItem] = useState(''); + return (
    @@ -40,6 +41,7 @@ export function Home({ key={index} name={item.name} path={item.path} + listPath={listPath} setListPath={setListPath} handleShareModalClick={handleShareModalClick} setSelectedItem={setSelectedItem} diff --git a/src/views/List.jsx b/src/views/List.jsx index 5096b01..6cc98d1 100644 --- a/src/views/List.jsx +++ b/src/views/List.jsx @@ -46,87 +46,104 @@ export function List({ data, listPath, listName }) { }; return ( -
    -
    -
    -

    - {listName} -

    - Description -
    -
    -
    - - - - - - - - Add New Item - - Fill in the details of the item you want to add. - - - + {listPath === '' ? ( +
    +
    +

    + No list selected +

    + Description - - -
    -
    -
      - {displayData.map((item) => ( - - ))} -
    - {displayData.length === 0 && search.length > 0 && ( -
    -

    No items found. Try searching for a different item!

    +
    - )} - {data.length === 0 && ( -
    -

    - Your list is empty. Start adding some items now! -

    - + ) : ( +
    +
    +
    +

    + {listName} +

    + Description +
    +
    +
    + + + + + + + + Add New Item + + Fill in the details of the item you want to add. + + + + + + +
    +
      + {displayData.map((item) => ( + + ))} +
    + {displayData.length === 0 && search.length > 0 && ( +
    +

    No items found. Try searching for a different item!

    +
    + )} + {data.length === 0 && ( +
    +

    + Your list is empty. Start adding some items now! +

    + +
    + )}
    )} -
    + ); } From 368aceaa51009c9162b393491960542e3e4772f7 Mon Sep 17 00:00:00 2001 From: wyna Date: Sat, 12 Oct 2024 19:20:24 +0200 Subject: [PATCH 3/4] delete confirmation + grey button tooltip --- src/components/SingleList.jsx | 84 ++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/src/components/SingleList.jsx b/src/components/SingleList.jsx index 4a3b111..e983d32 100644 --- a/src/components/SingleList.jsx +++ b/src/components/SingleList.jsx @@ -2,9 +2,28 @@ 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, @@ -13,6 +32,7 @@ export function SingleList({ handleShareModalClick, setSelectedItem, }) { + const [isAlertOpen, setIsAlertOpen] = useState(false); const [collectionId, setCollectionId] = useState(''); const singleListPath = path.split('/')[0]; const email = getAuth().currentUser.email; @@ -43,6 +63,7 @@ export function SingleList({ setListPath(''); } toast.success(`List ${name} was deleted`); + setIsAlertOpen(false); }; return ( @@ -61,16 +82,59 @@ export function SingleList({ {getAuth().currentUser.uid === singleListPath ? ( - + + + + + + + + Are you absolutely sure? + + + This will permanently delete your list. Do you really want to + delete {name}? + + + + setIsAlertOpen(false)} + > + Cancel + + handleDeleteClick(name)} + > + Continue + + + + ) : ( -
    - -
    + + + + + + +

    You cannot delete a list you don't own!

    +
    +
    +
    )}
    From 07e75a0e07c5536114023b2272461aec540874cd Mon Sep 17 00:00:00 2001 From: wyna Date: Sat, 12 Oct 2024 20:27:45 +0200 Subject: [PATCH 4/4] style: alert --- src/components/SingleList.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/SingleList.jsx b/src/components/SingleList.jsx index e983d32..10f9780 100644 --- a/src/components/SingleList.jsx +++ b/src/components/SingleList.jsx @@ -94,23 +94,23 @@ export function SingleList({ - + Are you absolutely sure? - + This will permanently delete your list. Do you really want to delete {name}? setIsAlertOpen(false)} > Cancel handleDeleteClick(name)} > Continue