From cab34317543088b763308308b396a33e6ac174f9 Mon Sep 17 00:00:00 2001 From: franco sanchez Date: Thu, 14 Nov 2024 12:58:33 -0300 Subject: [PATCH] feat: you can now edit the name of the collection and other enhancements --- src/components/modals/ModalCollection.tsx | 74 ++++++++++++++++--- .../profile/collections/MenuCollections.tsx | 57 ++++++++++++++ src/hooks/queries.ts | 12 +++ .../profile/collections/AllCollections.tsx | 24 ++++-- .../profile/collections/CollectionDetail.tsx | 47 ++++++++++-- src/routes.tsx | 2 +- src/services/api.ts | 13 ++++ src/utils/utils.ts | 1 + 8 files changed, 207 insertions(+), 23 deletions(-) create mode 100644 src/components/profile/collections/MenuCollections.tsx diff --git a/src/components/modals/ModalCollection.tsx b/src/components/modals/ModalCollection.tsx index 3617770..f287429 100644 --- a/src/components/modals/ModalCollection.tsx +++ b/src/components/modals/ModalCollection.tsx @@ -14,36 +14,86 @@ import { ModalOverlay, useColorModeValue, } from '@chakra-ui/react'; +import { FaCheckCircle } from 'react-icons/fa'; -import { useCreateCollections } from '@hooks/queries'; +import { useCreateCollections, useUpdateCollectionName } from '@hooks/queries'; import { useAuth } from '@contexts/AuthContext'; import { DisclosureType } from '@components/types'; +import { useMyToast } from '@hooks/useMyToast'; interface ModalCollectionType extends DisclosureType { + title: string; + textButton: string; + nameCollection?: string; + collectionId?: string; // Añade el ID de la colección + isEditing?: boolean; // Añade un flag para saber si estamos editando refetch: () => void; } -export function ModalCollection({ isOpen, onClose, refetch }: ModalCollectionType) { +export function ModalCollection({ + title, + textButton, + nameCollection, + collectionId, + isEditing = false, + isOpen, + onClose, + refetch, +}: ModalCollectionType) { const [name, setName] = useState(''); const bgColorBox = useColorModeValue('white', 'gray.900'); const bgColorInput = useColorModeValue('gray.100', 'gray.800'); const { currentUser } = useAuth(); const uid = currentUser?.uid; const navigate = useNavigate(); - const { mutate, isPending, isSuccess } = useCreateCollections(uid); + const myToast = useMyToast(); + + // Añade el mutation para actualizar + const updateMutation = useUpdateCollectionName(uid, collectionId); + const createMutation = useCreateCollections(uid); + + // Usa la mutation correspondiente según isEditing + const { mutate, isPending, isSuccess } = isEditing + ? updateMutation + : createMutation; + + // Carga el nombre inicial si estamos editando + useEffect(() => { + if (isEditing && nameCollection) { + setName(nameCollection); + } + }, [isEditing, nameCollection]); useEffect(() => { if (isSuccess) { onClose(); refetch(); setName(''); - navigate('/my-collections'); + + // Solo navega a /my-collections si estamos creando + if (!isEditing) { + navigate('/my-collections'); + } + + myToast({ + title: isEditing + ? 'Se actualizó la colección.' + : 'Se creó una nueva colección.', + icon: FaCheckCircle, + iconColor: 'green.700', + bgColor: 'black', + width: '200px', + color: 'whitesmoke', + align: 'center', + padding: '1', + fntSize: 'md', + bxSize: 5, + }); } - }, [isSuccess, navigate, onClose]); + }, [isSuccess, navigate, onClose, isEditing]); function handleNameCollection(e: React.ChangeEvent) { const { value } = e.target; - setName(value); } @@ -51,7 +101,11 @@ export function ModalCollection({ isOpen, onClose, refetch }: ModalCollectionTyp e.preventDefault(); if (!isPending) { - mutate(name); + if (isEditing && collectionId) { + mutate(name); + } else { + mutate(name); + } } } @@ -60,7 +114,7 @@ export function ModalCollection({ isOpen, onClose, refetch }: ModalCollectionTyp - Crear nueva colección + {title}
@@ -87,10 +141,10 @@ export function ModalCollection({ isOpen, onClose, refetch }: ModalCollectionTyp rounded='lg' isDisabled={!name || isPending} isLoading={isPending} - loadingText='Creando...' + loadingText={isEditing ? 'Actualizando...' : 'Creando...'} _hover={{ outline: 'none', bg: 'green.600' }} > - Crear + {textButton}
diff --git a/src/components/profile/collections/MenuCollections.tsx b/src/components/profile/collections/MenuCollections.tsx new file mode 100644 index 0000000..c346da3 --- /dev/null +++ b/src/components/profile/collections/MenuCollections.tsx @@ -0,0 +1,57 @@ +import React, { useEffect } from 'react'; +import { Menu, MenuButton, MenuList, MenuItem, IconButton } from '@chakra-ui/react'; +import { FiMoreVertical } from 'react-icons/fi'; +import { FaCheckCircle } from 'react-icons/fa'; + +import { useDeleteCollections } from '@hooks/queries'; +import { useAuth } from '@contexts/AuthContext'; +import { useMyToast } from '@hooks/useMyToast'; + +export function MenuCollections({ id, name, refetch }: any) { + const { currentUser } = useAuth(); + const uid = currentUser?.uid; + const myToast = useMyToast(); + const { mutate, isSuccess } = useDeleteCollections(); + + useEffect(() => { + if (isSuccess) { + refetch(); + myToast({ + title: `Se elimino la colección ${name}.`, + icon: FaCheckCircle, + iconColor: 'green.700', + bgColor: 'black', + width: '200px', + color: 'whitesmoke', + align: 'center', + padding: '1', + fntSize: 'md', + bxSize: 5, + }); + } + }, [isSuccess]); + + function deleteCollection(id: string) { + mutate([uid, id]); + } + + return ( + <> + + } + bg='transparent' + _hover={{ bg: 'transparent' }} + _active={{ bg: 'transparent' }} + /> + + deleteCollection(id)}> + Eliminar colección + + + + + ); +} diff --git a/src/hooks/queries.ts b/src/hooks/queries.ts index ebc40b1..015c6ea 100644 --- a/src/hooks/queries.ts +++ b/src/hooks/queries.ts @@ -31,6 +31,7 @@ import { getFindOneCollection, deleteCollections, postCollections, + patchCollectionsName, } from '@services/api'; import { useAccountActions } from '@hooks/useAccountActions'; import { keys } from '@utils/utils'; @@ -286,6 +287,16 @@ function useCreateCollections(userId: string | undefined) { }); } +function useUpdateCollectionName( + userId: string | undefined, + collectionId: string | undefined, +) { + return useMutation({ + mutationKey: [keys.updateCollectionsName], + mutationFn: (name: string) => patchCollectionsName(userId, collectionId, name), + }); +} + function useCollections(userId: string | undefined) { return useQuery({ queryKey: [keys.allCollections], @@ -368,6 +379,7 @@ export { useCollections, useCollectionDetail, useCreateCollections, + useUpdateCollectionName, useDeleteCollections, // Usuarios diff --git a/src/pages/profile/collections/AllCollections.tsx b/src/pages/profile/collections/AllCollections.tsx index bc8a02b..b845490 100644 --- a/src/pages/profile/collections/AllCollections.tsx +++ b/src/pages/profile/collections/AllCollections.tsx @@ -20,10 +20,11 @@ import { collections } from '@assets/assets'; import { MyContainer } from '@components/ui/MyContainer'; import { MySimpleGrid } from '@components/ui/MySimpleGrid'; import { ModalCollection } from '@components/modals/ModalCollection'; +import { SkeletonACollections } from '@components/skeletons/SkeletonACollections'; import { useCollections } from '@hooks/queries'; import { useAuth } from '@contexts/AuthContext'; import { parseDate } from '@utils/utils'; -import { SkeletonACollections } from '@components/skeletons/SkeletonACollections'; +import { MenuCollections } from '@components/profile/collections/MenuCollections'; export function AllCollections() { const bgColorButton = useColorModeValue('green.500', 'green.700'); @@ -31,10 +32,10 @@ export function AllCollections() { const { isOpen, onOpen, onClose } = useDisclosure(); const { currentUser } = useAuth(); const uid = currentUser?.uid; - const { data, refetch, isPending: isPendingData } = useCollections(uid); + const { data, refetch, isPending } = useCollections(uid); let collectionsUI; - if (isPendingData) { + if (isPending) { return ; } @@ -80,7 +81,7 @@ export function AllCollections() { to={`/my-collections/${id}`} tabIndex={-1} _hover={{ outline: 'none' }} - > */} + > */} + + + @@ -133,7 +137,13 @@ export function AllCollections() { - + { if (isSuccess) { navigate(`/my-collections`, { replace: true }); + myToast({ + title: `Se elimino la colección ${data?.name}.`, + icon: FaCheckCircle, + iconColor: 'green.700', + bgColor: 'black', + width: '200px', + color: 'whitesmoke', + align: 'center', + padding: '1', + fntSize: 'md', + bxSize: 5, + }); } }, [isSuccess, navigate]); @@ -115,6 +144,16 @@ export function CollectionDetail() { <> +