Skip to content

Commit

Permalink
chore: refactoring of form functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Franqsanz committed Mar 20, 2024
1 parent 38f865e commit b402ce7
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 151 deletions.
8 changes: 0 additions & 8 deletions netlify.toml

This file was deleted.

73 changes: 16 additions & 57 deletions src/components/forms/FormEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,19 @@ import { FaCheckCircle } from 'react-icons/fa';
import { IoWarningSharp } from 'react-icons/io5';

import { categories, formats, languages } from '../../data/links';
import { BookType } from '@components/types';
import { BookType, MyChangeEvent } from '@components/types';
import { useUpdateBook } from '@hooks/querys';
import { ModalCropper } from '@components/modals/ModalCropper';
import { generatePathUrl, sortArrayByLabel } from '@utils/utils';
import { sortArrayByLabel } from '@utils/utils';
import { MyPopover } from '@components/MyPopover';
import {
handleInputChange,
handleCategory,
handleField,
useFileInputRef,
} from '@components/forms/utils/utilsForm';
import { useMyToast } from '@hooks/useMyToast';
import { useGenerateSlug } from '@hooks/useGenerateSlug';
const Cropper = lazy(() => import('react-cropper'));

export function FormEdit({
Expand All @@ -52,12 +59,14 @@ export function FormEdit({
register,
formState: { errors },
} = useForm<BookType>();
let previewImgUI;
const { url, public_id } = image;
const navigate = useNavigate();
const { isOpen, onOpen, onClose } = useDisclosure();
const myToast = useMyToast();
const bgColorInput = useColorModeValue('gray.100', 'gray.800');
const bgColorButton = useColorModeValue('green.500', 'green.700');
const { fileInputRef, handleButtonClick } = useFileInputRef();
const [cropData, setCropData] = useState<string | null>(null);
const [previewImg, setPreviewImg] = useState<Blob | MediaSource | null>(null);
const [crop, setCrop] = useState<any>('');
Expand All @@ -78,9 +87,8 @@ export function FormEdit({
public_id,
},
});
let previewImgUI;
const fileInputRef = useRef<HTMLInputElement>(null);
const { mutate, isPending, isSuccess, error } = useUpdateBook(books);
useGenerateSlug(books.title, setBooks); // Genera el pathUrl (Slug)

function allFieldsBook(book: BookType): boolean {
return (
Expand All @@ -96,65 +104,16 @@ export function FormEdit({
const sortedLanguage = sortArrayByLabel(languages);
const sortedFormat = sortArrayByLabel(formats);

function handleChange(
e: React.ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>,
) {
const { name, value } = e.target;

// Si el campo es 'author', dividimos los nombres por comas en un array
if (name === 'authors') {
const authorNames = value.split(',');
setBooks({
...books,
[name]: authorNames, // Guardamos un array de nombres de autores
});
} else {
setBooks({
...books,
[name]: value,
});
}
function handleChange(e: MyChangeEvent) {
handleInputChange(e, books, setBooks);
}

function handleCategoryChange(selectedOptions) {
// Verificar si se seleccionaron opciones
if (selectedOptions && selectedOptions.length > 0) {
// Obtener los valores de las opciones seleccionadas
const selectedValues = selectedOptions.map((option) => option.value);

// Actualizar el estado de 'books' con los valores seleccionados
setBooks((prevBooks) => ({
...prevBooks,
category: selectedValues,
}));
} else {
// Si no se seleccionaron opciones, establecer el estado de 'category' como un array vacío
setBooks((prevBooks) => ({
...prevBooks,
category: [],
}));
}
handleCategory(selectedOptions, setBooks);
}

function handleFieldChange(fieldName, newValue) {
setBooks((books) => ({
...books,
[fieldName]: newValue,
}));
}

useEffect(() => {
// Genera el pathUrl basado en el título cada vez que se actualiza
const generatedPathUrl = generatePathUrl(books.title);
setBooks((books) => ({ ...books, pathUrl: generatedPathUrl }));
}, [books.title]);

function handleButtonClick() {
if (fileInputRef.current) {
fileInputRef.current.click();
}
handleField(fieldName, newValue, setBooks);
}

async function handleImageChange(e: React.ChangeEvent<HTMLInputElement>) {
Expand Down
121 changes: 39 additions & 82 deletions src/components/forms/NewBook.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Suspense, lazy, useState, useEffect, useRef } from 'react';
import React, { Suspense, lazy, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
FormControl,
Button,
Expand All @@ -8,9 +9,6 @@ import {
FormLabel,
Textarea,
Image,
Alert,
AlertIcon,
AlertTitle,
useColorModeValue,
useDisclosure,
Icon,
Expand All @@ -23,13 +21,23 @@ import { Select } from 'chakra-react-select';
import 'cropperjs/dist/cropper.css';
import { AiOutlineCloudUpload } from 'react-icons/ai';
import { BiImageAdd } from 'react-icons/bi';
import { FaCheckCircle } from 'react-icons/fa';
import { IoWarningSharp } from 'react-icons/io5';

import { categories, formats, languages } from '../../data/links';
import { BookType } from '@components/types';
import { BookType, MyChangeEvent } from '@components/types';
import { useMutatePost } from '@hooks/querys';
import { ModalCropper } from '@components/modals/ModalCropper';
import { generatePathUrl, sortArrayByLabel } from '@utils/utils';
import { sortArrayByLabel } from '@utils/utils';
import { useGenerateSlug } from '@hooks/useGenerateSlug';
import { MyPopover } from '@components/MyPopover';
import {
handleInputChange,
handleCategory,
handleField,
useFileInputRef,
} from '@components/forms/utils/utilsForm';
import { useMyToast } from '@hooks/useMyToast';
import { useAuth } from '@contexts/AuthContext';
const Cropper = lazy(() => import('react-cropper'));

Expand All @@ -39,12 +47,14 @@ export function FormNewBook() {
register,
formState: { errors },
} = useForm<BookType>();
let alertMessage;
let previewImgUI;
const navigate = useNavigate();
const { isOpen, onOpen, onClose } = useDisclosure();
const myToast = useMyToast();
const { currentUser } = useAuth();
const bgColorInput = useColorModeValue('gray.100', 'gray.800');
const bgColorButton = useColorModeValue('green.500', 'green.700');
const { fileInputRef, handleButtonClick } = useFileInputRef();
const { mutate, isPending, isSuccess, error } = useMutatePost();
const [cropData, setCropData] = useState<string | null>(null);
const [previewImg, setPreviewImg] = useState<Blob | MediaSource | null>(null);
Expand All @@ -66,6 +76,7 @@ export function FormNewBook() {
},
userId: currentUser?.uid,
});
useGenerateSlug(books.title, setBooks); // Genera el pathUrl (Slug)

function allFieldsBook(book: BookType): boolean {
return (
Expand All @@ -81,67 +92,16 @@ export function FormNewBook() {
const sortedLanguage = sortArrayByLabel(languages);
const sortedFormat = sortArrayByLabel(formats);

function handleChange(
e: React.ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>,
) {
const { name, value } = e.target;

// Si el campo es 'author', dividimos los nombres por comas en un array
if (name === 'authors') {
const authorNames = value.split(',');
setBooks({
...books,
[name]: authorNames, // Guardamos un array de nombres de autores
});
} else {
setBooks({
...books,
[name]: value,
});
}
function handleChange(e: MyChangeEvent) {
handleInputChange(e, books, setBooks);
}

function handleCategoryChange(selectedOptions) {
// Verificar si se seleccionaron opciones
if (selectedOptions && selectedOptions.length > 0) {
// Obtener los valores de las opciones seleccionadas
const selectedValues = selectedOptions.map((option) => option.value);

// Actualizar el estado de 'books' con los valores seleccionados
setBooks((prevBooks) => ({
...prevBooks,
category: selectedValues,
}));
} else {
// Si no se seleccionaron opciones, establecer el estado de 'category' como un array vacío
setBooks((prevBooks) => ({
...prevBooks,
category: [],
}));
}
handleCategory(selectedOptions, setBooks);
}

function handleFieldChange(fieldName, newValue) {
setBooks((books) => ({
...books,
[fieldName]: newValue,
}));
}

useEffect(() => {
// Genera el pathUrl basado en el título cada vez que se actualiza
const generatedPathUrl = generatePathUrl(books.title);
setBooks((books) => ({ ...books, pathUrl: generatedPathUrl }));
}, [books.title]);

const fileInputRef = useRef<HTMLInputElement>(null);

function handleButtonClick() {
if (fileInputRef.current) {
fileInputRef.current.click();
}
handleField(fieldName, newValue, setBooks);
}

async function handleImageChange(e: React.ChangeEvent<HTMLInputElement>) {
Expand Down Expand Up @@ -236,25 +196,23 @@ export function FormNewBook() {
}

if (isSuccess) {
alertMessage = (
<Alert status='success' variant='solid' rounded='xl'>
<AlertIcon color='black' />
<AlertTitle fontWeight='normal' color='black'>
¡Publicación exitosa!
</AlertTitle>
</Alert>
);
myToast({
title: 'Guardado',
description: '¡Publicación exitosa!',
icon: FaCheckCircle,
iconColor: 'green.700',
bgColor: 'black',
});

navigate('/explore', { replace: true });
} else if (error) {
alertMessage = (
<Alert status='error' variant='solid' rounded='xl'>
<AlertIcon />
<AlertTitle fontWeight='normal'>
Ha ocurrido un error al publicar.
</AlertTitle>
</Alert>
);
} else {
alertMessage = <Alert display='none' />;
myToast({
title: 'Ha ocurrido un error',
description: 'No se ha podido guardar las modificaciones.',
icon: IoWarningSharp,
iconColor: 'red.400',
bgColor: 'black',
});
}

return (
Expand All @@ -273,7 +231,7 @@ export function FormNewBook() {
p={{ base: 5, md: 10 }}
rounded='lg'
border='1px'
maxWidth='800px'
maxWidth='900px'
>
<Box mb='5' fontSize='md'>
Los campos con el{' '}
Expand Down Expand Up @@ -625,7 +583,6 @@ export function FormNewBook() {
</Box>
</Box>
</Flex>
<Box mt='10'>{alertMessage}</Box>
</Box>
</Flex>
</>
Expand Down
72 changes: 72 additions & 0 deletions src/components/forms/utils/utilsForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { useRef } from 'react';
// const fileInputRef = useRef<HTMLInputElement>(null);

function handleInputChange(
e,
books,
setBooks: React.Dispatch<React.SetStateAction<any>>,
) {
const { name, value } = e.target;

// Si el campo es 'author', dividimos los nombres por comas en un array
if (name === 'authors') {
const authorNames = value.split(',');
setBooks({
...books,
[name]: authorNames, // Guardamos un array de nombres de autores
});
} else {
setBooks({
...books,
[name]: value,
});
}
}

function handleCategory(
selectedOptions,
setBooks: React.Dispatch<React.SetStateAction<any>>,
) {
// Verificar si se seleccionaron opciones
if (selectedOptions && selectedOptions.length > 0) {
// Obtener los valores de las opciones seleccionadas
const selectedValues = selectedOptions.map((option) => option.value);

// Actualizar el estado de 'books' con los valores seleccionados
setBooks((prevBooks) => ({
...prevBooks,
category: selectedValues,
}));
} else {
// Si no se seleccionaron opciones, establecer el estado de 'category' como un array vacío
setBooks((prevBooks) => ({
...prevBooks,
category: [],
}));
}
}

function handleField(
fieldName,
newValue,
setBooks: React.Dispatch<React.SetStateAction<any>>,
) {
setBooks((books) => ({
...books,
[fieldName]: newValue,
}));
}

function useFileInputRef() {
const fileInputRef = useRef<HTMLInputElement>(null);

function handleButtonClick() {
if (fileInputRef.current) {
fileInputRef.current.click();
}
}

return { fileInputRef, handleButtonClick };
}

export { handleInputChange, handleCategory, handleField, useFileInputRef };
Loading

0 comments on commit b402ce7

Please sign in to comment.