import React, { useEffect, useState } from "react"; import { Col, Row, Form, Input, Modal, Table, Select, Button, Upload, Divider, Checkbox, DatePicker, message, Tooltip, } from "antd"; import { SaveOutlined, UploadOutlined, ArrowLeftOutlined, PlusCircleOutlined, MinusCircleOutlined, } from "@ant-design/icons"; import "moment/locale/es-mx"; import moment from "moment"; import locale from "antd/es/date-picker/locale/es_ES"; import { useHistory } from "react-router-dom"; import { push, ref as refDatabase } from "firebase/database"; import { addDoc, collection, doc, getDoc, updateDoc, onSnapshot, query as firebseQuery, getDocs, where, } from "firebase/firestore"; import { ref as refStorage, uploadBytes, deleteObject, getStorage, getDownloadURL, } from "firebase/storage"; import { useQuery } from "../../../hooks"; import { ViewLoading } from "../../../components"; import { DefaultLayout } from "../../../components/layouts"; import { firestore, storage, database } from "../../../services/firebase"; const EventosDetalle = () => { const urlweb = "/administracion/eventos"; const query = useQuery(); const history = useHistory(); const { TextArea, Search } = Input; const { Option } = Select; const id = query.get("id"); const editando = !!id; const [form] = Form.useForm(); const [evento, setEvento] = useState([]); const [cargandoEvento, setCargandoEvento] = useState(true); const [guadandoCargando, setGuardandoCargando] = useState(false); const [sinFechaFin, setSinFechaFin] = useState(false); const [visible, setVisible] = useState(false); const [cargandoGrupos, setCargandoGrupos] = useState(true); const [grupos, setGrupos] = useState([]); const [filteredResults, setFilteredResults] = useState([]); const [searchInput, setSearchInput] = useState(""); const [selectedGrupos, setSelectedGrupos] = useState([]); const [selectedFile, setSelectedFile] = useState(null); const [selectedFileList, setSelectedFileList] = useState([]); const [previaImg, setPreviaImg] = useState(null); const [redes, setRedes] = useState([]); const defaultText = (prop) => prop || ---; const multipleButtonData = [ { text: "Volver", to: () => history.goBack(), icon: , props: { disabled: false, type: "primary" }, }, ]; const columns = [ { title: "Nombre", dataIndex: "nombre", key: "nombre", render: defaultText, }, { title: "Ciudad", dataIndex: "ciudad", key: "ciudad", render: defaultText, }, { title: "Creado", dataIndex: "timestamp", key: "timestamp", render: (_, item) => moment(item?.timestamp?.toDate()).format("DD-MM-YYYY"), }, ]; const redesSociales = [ "Facebook", "Twitter", "Instagram", "Whatsapp", "YouTube", "TikTok", "Otro", ]; const acciones = [ { id: 0, value: "Ver", label: "Ver", icon: "馃憗" }, { id: 1, value: "Me gusta", label: "Me gusta", icon: "馃憤" }, { id: 2, value: "Compartir", label: "Compartir", icon: "馃攧" }, ]; const rowSelection = { onChange: (selectedRowKeys, _) => { setSelectedGrupos(selectedRowKeys); }, }; const obtenerUsuariosGrupo = async () => { try { const q = firebseQuery( collection(firestore, "usuarios"), where("grupos", "array-contains-any", selectedGrupos), ); const querySnapshot = await getDocs(q); const docs = []; querySnapshot.forEach((doc) => { const data = doc.data(); if (data?.estatus) { docs.push({ grupos: data?.grupos, facebook: data?.facebook, twitter: data?.twitter, instagram: data?.instagram, telefono: data?.telefono, nombre: data?.nombre, uid: data?.uid, id: doc.id, facebookVerificado: data?.facebookVerificado, instagramVerificado: data?.instagramVerificado, twitterVerificado: data?.twitterVerificado, }); } }); return docs; } catch (error) { console.log("error al obtener grupos: ", error); } }; const normFile = (e) => { if (Array.isArray(e)) { return e; } return e && e.fileList; }; const dummyRequest = ({ onSuccess }) => { setTimeout(() => { onSuccess("ok"); }, 0); }; const onChangeFile = (info) => { let src = URL.createObjectURL(info.file.originFileObj); setPreviaImg(src); switch (info.file.status) { case "uploading": setSelectedFileList([info.file]); break; case "done": setSelectedFile(info.file); setSelectedFileList([info.file]); break; default: setSelectedFile(null); setSelectedFileList([]); } }; const eliminarImagen = async (fileRoute) => { const storage = getStorage(); const desertRef = refStorage(storage, fileRoute); deleteObject(desertRef) .then((e) => {}) .catch((error) => { console.log(error); }); }; const onSearch = (searchValue) => { setSearchInput(searchValue); if (searchValue !== "") { const filteredData = grupos.filter((item) => { return Object.values(item) .join("") .toLowerCase() .includes(searchValue.toLowerCase()); }); setFilteredResults(filteredData); } else { setFilteredResults(grupos); } }; const onFinish = async (values) => { try { const { accion, ciudad, descripcion, fechaFinal, fechaInicio, nombre, redSocial, url, } = values; setGuardandoCargando(true); let file = selectedFile ? selectedFile.originFileObj : null; if (!editando && !file) { Modal.warning({ title: "Atenci贸n", content: "Debes subir una imagen del evento.", style: { marginTop: "20vh" }, }); } let rutaFoto = evento?.fotoEvento; let pathFirebase = evento?.pathFirebase; if (file) { if (editando) { await eliminarImagen(evento?.fotoEvento); } const postListRef = refDatabase(database, "fotosEventos"); const newPostRef = push(postListRef); rutaFoto = `fotosEventos/${newPostRef?.key}`; const fotoRefStorage = refStorage(storage, rutaFoto); try { let res = await uploadBytes(fotoRefStorage, file); pathFirebase = await getDownloadURL(res?.ref); } catch (error) { console.log("Error en el uploadbytes: ", error); } } const docsUsuarios = await obtenerUsuariosGrupo(); let resultado = { ...evento?.resultado }; let usuarios = []; for (let u = 0; u < docsUsuarios?.length; u++) { if (resultado[docsUsuarios[u]?.uid] === undefined) { resultado[docsUsuarios[u]?.uid] = []; } if (resultado[docsUsuarios[u]?.uid]?.length < 1) { resultado = { ...resultado, [docsUsuarios[u].uid]: [], }; } usuarios.push({ id: docsUsuarios[u]?.id, uid: docsUsuarios[u]?.uid, grupos: docsUsuarios[u]?.grupos, nombre: docsUsuarios[u]?.nombre, twitter: docsUsuarios[u]?.twitter, telefono: docsUsuarios[u]?.telefono, facebook: docsUsuarios[u]?.facebook, instagram: docsUsuarios[u]?.instagram, facebookVerificado: Boolean(docsUsuarios[u]?.facebookVerificado), instagramVerificado: Boolean(docsUsuarios[u]?.instagramVerificado), twitterVerificado: Boolean(docsUsuarios[u]?.twitterVerificado), }); } let body = { accion: accion || [], ciudad: ciudad || "", descripcion: descripcion || "", fechaFinal: fechaFinal?.toString() || "", fechaInicio: fechaInicio?.toString(), sinFechaFin: sinFechaFin, nombre: nombre || "", redSocial: redSocial || "", url: url || "", grupos: selectedGrupos, fotoEvento: rutaFoto, pathFirebase: pathFirebase, timestamp: editando ? evento?.timestamp : new Date(), estatus: editando ? evento?.estatus : true, usuarios: usuarios, redes: redes, resultado: resultado, sincronizado: null, }; const tag = makeid(8); let grupoEventoRef = null; //Crear grupo de eventos if (redes.length > 0) { let grupoEvento = { accion: accion, ciudad: ciudad, descripcion: descripcion, fechaFinal: fechaFinal?.toString() || "", fechaInicio: fechaInicio?.toString(), sinFechaFin: sinFechaFin, nombre: nombre || "", grupos: selectedGrupos, fotoEvento: rutaFoto, pathFirebase: pathFirebase, timestamp: editando ? evento?.timestamp : new Date(), estatus: editando ? evento?.estatus : true, tag: tag, redes: redes, usuarios: usuarios, resultado: resultado, }; grupoEventoRef = await addDoc( collection(firestore, "gruposEvento"), grupoEvento, ); } if (editando) { await updateDoc(doc(firestore, "eventos", id), body); return; } for (let i = 0; i < redes?.length; i++) { body = { ...body, redSocial: redes[i]?.redSocial, url: redes[i]?.url, }; if (!editando) { body["tag"] = tag; } await addDoc(collection(firestore, "eventos"), body); } Modal.success({ title: "脡xito", content: "Evento guardado correctamente", }); history.push(`${urlweb}/detalleGrupo?id=${grupoEventoRef.id}&tag=${tag}`); } catch (error) { Modal.warning({ title: "Atenci贸n", content: "Hubo un problema al guardar, intentalo de nuevo.", }); console.log("Error al guardar evento: ", error); } finally { setGuardandoCargando(false); } }; const onFinishFailed = () => { Modal.warning({ title: "Atenci贸n", content: "Por favor revise los datos.", style: { marginTop: "20vh" }, }); }; function makeid(length) { let result = ""; const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; const charactersLength = characters.length; for (var i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } const agregarRedSocial = () => { const key = makeid(6); const datos = [...redes]; const url = form.getFieldValue("url"); const red = form.getFieldValue("redSocial"); if (!url) { message.warning({ content: "Ingresa una URL", }); return; } if (!red) { message.warning({ content: "Selecciona una red social", }); return; } let existe = false; for (let i = 0; i < redes.length; i++) { if (redes[i]?.redSocial === red) existe = true; break; } if (existe) { message.warning({ content: "Esta red social ya existe, elige otra diferente.", }); return; } datos.push({ key: key, url: url, redSocial: red, }); setRedes(datos); form.setFieldsValue({ url: null, redSocial: null, }); }; const quitarRedSocial = (key) => { let data = [...redes]; for (let i = 0; i < data?.length; i++) { if (redes[i].key === key) { data.splice(i, 1); break; } } setRedes(data); }; const leerLink = (evento) => { let link = evento?.target?.value; const facebook = /https?:\/\/(www\.)?facebook\.com\/[a-zA-Z0-9.-]+\/?/ || /https?:\/\/(www\.)?fb\.com\/[a-zA-Z0-9.-]+\/?/; const x = /https?:\/\/(www\.)?x\.com\/[a-zA-Z0-9.-]+\/?/; const instagram = /https?:\/\/(www\.)?instagram\.com\/[a-zA-Z0-9.-]+\/?/; const whatsapp = /https?:\/\/(www\.)?wa\.me\/[a-zA-Z0-9.-]+\/?/; const youtube = /https?:\/\/(www\.)?youtube\.com\/[a-zA-Z0-9.-]+\/?/g; const ytShort = /https?:\/\/(www\.)?youtu\.be\/[a-zA-Z0-9.-]+\/?/g; const tiktok = /https?:\/\/(?:www\.)?tiktok\.com\/.*?/g; if (facebook.test(link)) { form.setFieldsValue({ redSocial: "Facebook" }); } else if (x.test(link)) { form.setFieldsValue({ redSocial: "Twitter" }); } else if (instagram.test(link)) { form.setFieldsValue({ redSocial: "Instagram" }); } else if (whatsapp.test(link)) { form.setFieldsValue({ redSocial: "Whatsapp" }); } else if (youtube.test(link) || ytShort.test(link)) { form.setFieldsValue({ redSocial: "YouTube" }); } else if (tiktok.test(link)) { form.setFieldsValue({ redSocial: "TikTok" }); } else { form.setFieldsValue({ redSocial: "Otro" }); } }; // Grupos useEffect(() => { try { onSnapshot(collection(firestore, "grupos"), (querySnapshot) => { const docs = []; querySnapshot.forEach((doc) => { if (doc.data()?.estatus) { docs.push({ ...doc.data(), id: doc.id }); } }); setGrupos(docs); }); } catch (error) { console.log("error al cargar grupos de firebase: ", error); } finally { setCargandoGrupos(false); } }, []); // Limpiar imagen useEffect(() => { if (!selectedFile) { setPreviaImg(null); } }, [selectedFile]); // Obtener detalles del evento. useEffect(() => { let mounted = true; if (mounted && editando) { try { setTimeout(async () => { const docRef = doc(firestore, "eventos", id); const docSnap = await getDoc(docRef); setEvento(docSnap.data()); }, 0); } catch (error) { console.log("error al obtener evento: ", error); } finally { setCargandoEvento(false); } } return () => (mounted = false); }, [editando, id]); useEffect(() => { let mounted = true; if (mounted && evento && editando) { setPreviaImg(evento?.pathFirebase); setSinFechaFin(evento?.sinFechaFin); setSelectedGrupos(evento?.grupos); form.setFieldsValue({ ...evento, fechaFinal: moment(evento?.fechaFinal), fechaInicio: moment(evento?.fechaInicio), }); } return () => (mounted = false); }, [editando, evento, form]); if (cargandoEvento && editando) return ; return ( setVisible(false)} onCancel={() => setVisible(false)} okText="Guardar" width={800} > 1 ? filteredResults : grupos} rowKey="id" pagination={{ pageSize: 5, }} rowSelection={{ type: "checkbox", selectedRowKeys: selectedGrupos, ...rowSelection, }} loading={cargandoGrupos} columns={columns} size="small" scroll={{ x: 700 }} /> {/* Imagen - Nombre - Ciudad - Descripci贸n - Url - Red social */} {/* Columna 1 */} }>Elegir imagen {previaImg ? : null} } onClick={() => setVisible(true)} > Agregar grupos ({selectedGrupos?.length}) {/* Columna 2 */} {/* Nombre evento - Ciuad */} {/* Descripci贸n */} {/* Fecha de inicio - Fecha fin - sin fecha - Accion */} setSinFechaFin(e.target.checked)} > Sin fecha de finalizaci贸n {acciones?.map((item) => ( {item?.icon} {item?.label} ))} {/* URL - Red Social - Agregar [+] */} leerLink(v)} /> {redesSociales?.map((item) => ( {item === "Twitter" ? "X" : item} ))} {!editando && ( } block onClick={agregarRedSocial} /> )} {redes.map((item) => ( } block onClick={() => quitarRedSocial(item?.key)} /> ))} } block size="large" loading={guadandoCargando} > Guardar ); }; export default EventosDetalle;