EventosDetalle.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. import React, { useEffect, useState } from "react";
  2. import {
  3. Col,
  4. Row,
  5. Form,
  6. Input,
  7. Modal,
  8. Table,
  9. Select,
  10. Button,
  11. Upload,
  12. Divider,
  13. Checkbox,
  14. DatePicker,
  15. message,
  16. Tooltip,
  17. } from "antd";
  18. import {
  19. SaveOutlined,
  20. UploadOutlined,
  21. ArrowLeftOutlined,
  22. PlusCircleOutlined,
  23. MinusCircleOutlined,
  24. } from "@ant-design/icons";
  25. import "moment/locale/es-mx";
  26. import moment from "moment";
  27. import locale from "antd/es/date-picker/locale/es_ES";
  28. import { useHistory } from "react-router-dom";
  29. import { push, ref as refDatabase } from "firebase/database";
  30. import {
  31. addDoc,
  32. collection,
  33. doc,
  34. getDoc,
  35. updateDoc,
  36. onSnapshot,
  37. query as firebseQuery,
  38. getDocs,
  39. where,
  40. } from "firebase/firestore";
  41. import {
  42. ref as refStorage,
  43. uploadBytes,
  44. deleteObject,
  45. getStorage,
  46. getDownloadURL,
  47. } from "firebase/storage";
  48. import { useQuery } from "../../../hooks";
  49. import { ViewLoading } from "../../../components";
  50. import { DefaultLayout } from "../../../components/layouts";
  51. import { firestore, storage, database } from "../../../services/firebase";
  52. const EventosDetalle = () => {
  53. const urlweb = "/administracion/eventos";
  54. const query = useQuery();
  55. const history = useHistory();
  56. const { TextArea, Search } = Input;
  57. const { Option } = Select;
  58. const id = query.get("id");
  59. const editando = !!id;
  60. const [form] = Form.useForm();
  61. const [evento, setEvento] = useState([]);
  62. const [cargandoEvento, setCargandoEvento] = useState(true);
  63. const [guadandoCargando, setGuardandoCargando] = useState(false);
  64. const [sinFechaFin, setSinFechaFin] = useState(false);
  65. const [visible, setVisible] = useState(false);
  66. const [cargandoGrupos, setCargandoGrupos] = useState(true);
  67. const [grupos, setGrupos] = useState([]);
  68. const [filteredResults, setFilteredResults] = useState([]);
  69. const [searchInput, setSearchInput] = useState("");
  70. const [selectedGrupos, setSelectedGrupos] = useState([]);
  71. const [selectedFile, setSelectedFile] = useState(null);
  72. const [selectedFileList, setSelectedFileList] = useState([]);
  73. const [previaImg, setPreviaImg] = useState(null);
  74. const [redes, setRedes] = useState([]);
  75. const defaultText = (prop) =>
  76. prop || <span style={{ color: "#c7c3c3" }}>---</span>;
  77. const multipleButtonData = [
  78. {
  79. text: "Volver",
  80. to: () => history.goBack(),
  81. icon: <ArrowLeftOutlined />,
  82. props: { disabled: false, type: "primary" },
  83. },
  84. ];
  85. const columns = [
  86. {
  87. title: "Nombre",
  88. dataIndex: "nombre",
  89. key: "nombre",
  90. render: defaultText,
  91. },
  92. {
  93. title: "Ciudad",
  94. dataIndex: "ciudad",
  95. key: "ciudad",
  96. render: defaultText,
  97. },
  98. {
  99. title: "Creado",
  100. dataIndex: "timestamp",
  101. key: "timestamp",
  102. render: (_, item) =>
  103. moment(item?.timestamp?.toDate()).format("DD-MM-YYYY"),
  104. },
  105. ];
  106. const redesSociales = [
  107. "Facebook",
  108. "Twitter",
  109. "Instagram",
  110. "Whatsapp",
  111. "YouTube",
  112. "TikTok",
  113. "Otro",
  114. ];
  115. const acciones = [
  116. { id: 0, value: "Ver", label: "Ver", icon: "👁" },
  117. { id: 1, value: "Me gusta", label: "Me gusta", icon: "👍" },
  118. { id: 2, value: "Compartir", label: "Compartir", icon: "🔄" },
  119. ];
  120. const rowSelection = {
  121. onChange: (selectedRowKeys, _) => {
  122. setSelectedGrupos(selectedRowKeys);
  123. },
  124. };
  125. const obtenerUsuariosGrupo = async () => {
  126. try {
  127. const q = firebseQuery(
  128. collection(firestore, "usuarios"),
  129. where("grupos", "array-contains-any", selectedGrupos)
  130. );
  131. const querySnapshot = await getDocs(q);
  132. const docs = [];
  133. querySnapshot.forEach((doc) => {
  134. const data = doc.data();
  135. if (data?.estatus) {
  136. docs.push({
  137. grupos: data?.grupos,
  138. facebook: data?.facebook,
  139. twitter: data?.twitter,
  140. instagram: data?.instagram,
  141. telefono: data?.telefono,
  142. nombre: data?.nombre,
  143. uid: data?.uid,
  144. id: doc.id,
  145. facebookVerificado: data?.facebookVerificado,
  146. instagramVerificado: data?.instagramVerificado,
  147. twitterVerificado: data?.twitterVerificado,
  148. });
  149. }
  150. });
  151. return docs;
  152. } catch (error) {
  153. console.log("error al obtener grupos: ", error);
  154. }
  155. };
  156. const normFile = (e) => {
  157. if (Array.isArray(e)) {
  158. return e;
  159. }
  160. return e && e.fileList;
  161. };
  162. const dummyRequest = ({ onSuccess }) => {
  163. setTimeout(() => {
  164. onSuccess("ok");
  165. }, 0);
  166. };
  167. const onChangeFile = (info) => {
  168. let src = URL.createObjectURL(info.file.originFileObj);
  169. setPreviaImg(src);
  170. switch (info.file.status) {
  171. case "uploading":
  172. setSelectedFileList([info.file]);
  173. break;
  174. case "done":
  175. setSelectedFile(info.file);
  176. setSelectedFileList([info.file]);
  177. break;
  178. default:
  179. setSelectedFile(null);
  180. setSelectedFileList([]);
  181. }
  182. };
  183. const eliminarImagen = async (fileRoute) => {
  184. const storage = getStorage();
  185. const desertRef = refStorage(storage, fileRoute);
  186. deleteObject(desertRef)
  187. .then((e) => {})
  188. .catch((error) => {
  189. console.log(error);
  190. });
  191. };
  192. const onSearch = (searchValue) => {
  193. setSearchInput(searchValue);
  194. if (searchValue !== "") {
  195. const filteredData = grupos.filter((item) => {
  196. return Object.values(item)
  197. .join("")
  198. .toLowerCase()
  199. .includes(searchValue.toLowerCase());
  200. });
  201. setFilteredResults(filteredData);
  202. } else {
  203. setFilteredResults(grupos);
  204. }
  205. };
  206. const onFinish = async (values) => {
  207. try {
  208. const {
  209. accion,
  210. ciudad,
  211. descripcion,
  212. fechaFinal,
  213. fechaInicio,
  214. nombre,
  215. redSocial,
  216. url,
  217. } = values;
  218. setGuardandoCargando(true);
  219. let file = selectedFile ? selectedFile.originFileObj : null;
  220. if (!editando && !file) {
  221. Modal.warning({
  222. title: "Atención",
  223. content: "Debes subir una imagen del evento.",
  224. style: { marginTop: "20vh" },
  225. });
  226. }
  227. let rutaFoto = evento?.fotoEvento;
  228. let pathFirebase = evento?.pathFirebase;
  229. if (file) {
  230. if (editando) {
  231. await eliminarImagen(evento?.fotoEvento);
  232. }
  233. const postListRef = refDatabase(database, "fotosEventos");
  234. const newPostRef = push(postListRef);
  235. rutaFoto = `fotosEventos/${newPostRef?.key}`;
  236. const fotoRefStorage = refStorage(storage, rutaFoto);
  237. try {
  238. let res = await uploadBytes(fotoRefStorage, file);
  239. pathFirebase = await getDownloadURL(res?.ref);
  240. } catch (error) {
  241. console.log("Error en el uploadbytes: ", error);
  242. }
  243. }
  244. const docsUsuarios = await obtenerUsuariosGrupo();
  245. let resultado = { ...evento?.resultado };
  246. let usuarios = [];
  247. for (let u = 0; u < docsUsuarios?.length; u++) {
  248. if (resultado[docsUsuarios[u]?.uid] === undefined) {
  249. resultado[docsUsuarios[u]?.uid] = [];
  250. }
  251. if (resultado[docsUsuarios[u]?.uid]?.length < 1) {
  252. resultado = {
  253. ...resultado,
  254. [docsUsuarios[u].uid]: [],
  255. };
  256. }
  257. usuarios.push({
  258. id: docsUsuarios[u]?.id,
  259. uid: docsUsuarios[u]?.uid,
  260. grupos: docsUsuarios[u]?.grupos,
  261. nombre: docsUsuarios[u]?.nombre,
  262. twitter: docsUsuarios[u]?.twitter,
  263. telefono: docsUsuarios[u]?.telefono,
  264. facebook: docsUsuarios[u]?.facebook,
  265. instagram: docsUsuarios[u]?.instagram,
  266. facebookVerificado: Boolean(docsUsuarios[u]?.facebookVerificado),
  267. instagramVerificado: Boolean(docsUsuarios[u]?.instagramVerificado),
  268. twitterVerificado: Boolean(docsUsuarios[u]?.twitterVerificado),
  269. });
  270. }
  271. let body = {
  272. accion: accion || [],
  273. ciudad: ciudad || "",
  274. descripcion: descripcion || "",
  275. fechaFinal: fechaFinal?.toString() || "",
  276. fechaInicio: fechaInicio?.toString(),
  277. sinFechaFin: sinFechaFin,
  278. nombre: nombre || "",
  279. redSocial: redSocial || "",
  280. url: url || "",
  281. grupos: selectedGrupos,
  282. fotoEvento: rutaFoto,
  283. pathFirebase: pathFirebase,
  284. timestamp: editando ? evento?.timestamp : new Date(),
  285. estatus: editando ? evento?.estatus : true,
  286. usuarios: usuarios,
  287. redes: redes,
  288. resultado: resultado,
  289. sincronizado: null,
  290. };
  291. const tag = makeid(8);
  292. //Crear grupo de eventos
  293. if (redes.length > 0) {
  294. let grupoEvento = {
  295. accion: accion,
  296. ciudad: ciudad,
  297. descripcion: descripcion,
  298. fechaFinal: fechaFinal?.toString() || "",
  299. fechaInicio: fechaInicio?.toString(),
  300. sinFechaFin: sinFechaFin,
  301. nombre: nombre || "",
  302. grupos: selectedGrupos,
  303. fotoEvento: rutaFoto,
  304. pathFirebase: pathFirebase,
  305. timestamp: editando ? evento?.timestamp : new Date(),
  306. estatus: editando ? evento?.estatus : true,
  307. tag: tag,
  308. redes: redes,
  309. usuarios: usuarios,
  310. resultado: resultado,
  311. };
  312. await addDoc(collection(firestore, "gruposEvento"), grupoEvento);
  313. }
  314. if (editando) {
  315. await updateDoc(doc(firestore, "eventos", id), body);
  316. return;
  317. }
  318. for (let i = 0; i < redes?.length; i++) {
  319. body = {
  320. ...body,
  321. redSocial: redes[i]?.redSocial,
  322. url: redes[i]?.url,
  323. };
  324. if (!editando) {
  325. body["tag"] = tag;
  326. }
  327. await addDoc(collection(firestore, "eventos"), body);
  328. }
  329. Modal.success({
  330. title: "Éxito",
  331. content: "Evento guardado correctamente",
  332. });
  333. history.push(urlweb);
  334. } catch (error) {
  335. Modal.warning({
  336. title: "Atención",
  337. content: "Hubo un problema al guardar, intentalo de nuevo.",
  338. });
  339. console.log("Error al guardar evento: ", error);
  340. } finally {
  341. setGuardandoCargando(false);
  342. }
  343. };
  344. const onFinishFailed = () => {
  345. Modal.warning({
  346. title: "Atención",
  347. content: "Por favor revise los datos.",
  348. style: { marginTop: "20vh" },
  349. });
  350. };
  351. function makeid(length) {
  352. let result = "";
  353. const characters =
  354. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  355. const charactersLength = characters.length;
  356. for (var i = 0; i < length; i++) {
  357. result += characters.charAt(Math.floor(Math.random() * charactersLength));
  358. }
  359. return result;
  360. }
  361. const agregarRedSocial = () => {
  362. const key = makeid(6);
  363. const datos = [...redes];
  364. const url = form.getFieldValue("url");
  365. const red = form.getFieldValue("redSocial");
  366. if (!url) {
  367. message.warning({
  368. content: "Ingresa una URL",
  369. });
  370. return;
  371. }
  372. if (!red) {
  373. message.warning({
  374. content: "Selecciona una red social",
  375. });
  376. return;
  377. }
  378. let existe = false;
  379. for (let i = 0; i < redes.length; i++) {
  380. if (redes[i]?.redSocial === red) existe = true;
  381. break;
  382. }
  383. if (existe) {
  384. message.warning({
  385. content: "Esta red social ya existe, elige otra diferente.",
  386. });
  387. return;
  388. }
  389. datos.push({
  390. key: key,
  391. url: url,
  392. redSocial: red,
  393. });
  394. setRedes(datos);
  395. form.setFieldsValue({
  396. url: null,
  397. redSocial: null,
  398. });
  399. };
  400. const quitarRedSocial = (key) => {
  401. let data = [...redes];
  402. for (let i = 0; i < data?.length; i++) {
  403. if (redes[i].key === key) {
  404. data.splice(i, 1);
  405. break;
  406. }
  407. }
  408. setRedes(data);
  409. };
  410. const leerLink = (evento) => {
  411. let link = evento?.target?.value;
  412. const facebook =
  413. /https?:\/\/(www\.)?facebook\.com\/[a-zA-Z0-9.-]+\/?/ ||
  414. /https?:\/\/(www\.)?fb\.com\/[a-zA-Z0-9.-]+\/?/;
  415. const twitter = /https?:\/\/(www\.)?twitter\.com\/[a-zA-Z0-9.-]+\/?/;
  416. const instagram = /https?:\/\/(www\.)?instagram\.com\/[a-zA-Z0-9.-]+\/?/;
  417. const whatsapp = /https?:\/\/(www\.)?wa\.me\/[a-zA-Z0-9.-]+\/?/;
  418. const youtube = /https?:\/\/(www\.)?youtube\.com\/[a-zA-Z0-9.-]+\/?/g;
  419. const ytShort = /https?:\/\/(www\.)?youtu\.be\/[a-zA-Z0-9.-]+\/?/g;
  420. const tiktok = /https?:\/\/(?:www\.)?tiktok\.com\/.*?/g;
  421. if (facebook.test(link)) {
  422. form.setFieldsValue({ redSocial: "Facebook" });
  423. } else if (twitter.test(link)) {
  424. form.setFieldsValue({ redSocial: "Twitter" });
  425. } else if (instagram.test(link)) {
  426. form.setFieldsValue({ redSocial: "Instagram" });
  427. } else if (whatsapp.test(link)) {
  428. form.setFieldsValue({ redSocial: "Whatsapp" });
  429. } else if (youtube.test(link) || ytShort.test(link)) {
  430. form.setFieldsValue({ redSocial: "YouTube" });
  431. } else if (tiktok.test(link)) {
  432. form.setFieldsValue({ redSocial: "TikTok" });
  433. } else {
  434. form.setFieldsValue({ redSocial: "Otro" });
  435. }
  436. };
  437. // Grupos
  438. useEffect(() => {
  439. try {
  440. onSnapshot(collection(firestore, "grupos"), (querySnapshot) => {
  441. const docs = [];
  442. querySnapshot.forEach((doc) => {
  443. if (doc.data()?.estatus) {
  444. docs.push({ ...doc.data(), id: doc.id });
  445. }
  446. });
  447. setGrupos(docs);
  448. });
  449. } catch (error) {
  450. console.log("error al cargar grupos de firebase: ", error);
  451. } finally {
  452. setCargandoGrupos(false);
  453. }
  454. }, []);
  455. // Limpiar imagen
  456. useEffect(() => {
  457. if (!selectedFile) {
  458. setPreviaImg(null);
  459. }
  460. }, [selectedFile]);
  461. // Obtener detalles del evento.
  462. useEffect(() => {
  463. let mounted = true;
  464. if (mounted && editando) {
  465. try {
  466. setTimeout(async () => {
  467. const docRef = doc(firestore, "eventos", id);
  468. const docSnap = await getDoc(docRef);
  469. setEvento(docSnap.data());
  470. }, 0);
  471. } catch (error) {
  472. console.log("error al obtener evento: ", error);
  473. } finally {
  474. setCargandoEvento(false);
  475. }
  476. }
  477. return () => (mounted = false);
  478. }, [editando, id]);
  479. useEffect(() => {
  480. let mounted = true;
  481. if (mounted && evento && editando) {
  482. setPreviaImg(evento?.pathFirebase);
  483. setSinFechaFin(evento?.sinFechaFin);
  484. setSelectedGrupos(evento?.grupos);
  485. form.setFieldsValue({
  486. ...evento,
  487. fechaFinal: moment(evento?.fechaFinal),
  488. fechaInicio: moment(evento?.fechaInicio),
  489. });
  490. }
  491. return () => (mounted = false);
  492. }, [editando, evento, form]);
  493. if (cargandoEvento && editando) return <ViewLoading />;
  494. return (
  495. <DefaultLayout multipleButtonData={multipleButtonData}>
  496. <Modal
  497. title="Agregar grupos"
  498. centered
  499. open={visible}
  500. onOk={() => setVisible(false)}
  501. onCancel={() => setVisible(false)}
  502. okText="Guardar"
  503. width={800}
  504. >
  505. <Search
  506. placeholder="Buscar..."
  507. enterButton="Buscar"
  508. size="large"
  509. style={{ width: "100%" }}
  510. onSearch={onSearch}
  511. />
  512. <Divider />
  513. <Table
  514. dataSource={searchInput?.length > 1 ? filteredResults : grupos}
  515. rowKey="id"
  516. pagination={{
  517. pageSize: 5,
  518. }}
  519. rowSelection={{
  520. type: "checkbox",
  521. selectedRowKeys: selectedGrupos,
  522. ...rowSelection,
  523. }}
  524. loading={cargandoGrupos}
  525. columns={columns}
  526. size="small"
  527. scroll={{ x: 700 }}
  528. />
  529. </Modal>
  530. <Form
  531. name="form"
  532. form={form}
  533. autoComplete="off"
  534. layout="vertical"
  535. onFinish={onFinish}
  536. onFinishFailed={onFinishFailed}
  537. >
  538. {/* Imagen - Nombre - Ciudad - Descripción - Url - Red social */}
  539. <Row gutter={10}>
  540. {/* Columna 1 */}
  541. <Col
  542. className="gutter-row"
  543. xs={{ span: 24 }}
  544. sm={{ span: 24 }}
  545. md={{ span: 8 }}
  546. lg={{ span: 8 }}
  547. >
  548. <Row
  549. gutter={10}
  550. style={{
  551. display: "flex",
  552. flexDirection: "row",
  553. height: "100%",
  554. }}
  555. >
  556. <Col span={24}>
  557. <Form.Item
  558. name="upload"
  559. label="Imagen del evento"
  560. valuePropName="fileList"
  561. rules={[
  562. { required: editando ? false : true, message: "Requerido" },
  563. ]}
  564. getValueFromEvent={normFile}
  565. extra={editando && evento ? evento?.fotoEvento : null}
  566. >
  567. <Upload
  568. accept="image/gif, image/jpeg, image/png"
  569. fileList={selectedFileList}
  570. customRequest={dummyRequest}
  571. onChange={onChangeFile}
  572. name="fotoEvento"
  573. multiple={false}
  574. maxCount={1}
  575. >
  576. <Button icon={<UploadOutlined />}>Elegir imagen</Button>
  577. </Upload>
  578. </Form.Item>
  579. </Col>
  580. <Col span={24}>
  581. {previaImg ? <img src={previaImg} width="100%" alt="" /> : null}
  582. </Col>
  583. <Col span={24} style={{ marginTop: 133 }}>
  584. <Button
  585. block
  586. type="dashed"
  587. icon={<PlusCircleOutlined />}
  588. onClick={() => setVisible(true)}
  589. >
  590. Agregar grupos ({selectedGrupos?.length})
  591. </Button>
  592. </Col>
  593. </Row>
  594. </Col>
  595. {/* Columna 2 */}
  596. <Col
  597. className="gutter-row"
  598. xs={{ span: 24 }}
  599. sm={{ span: 24 }}
  600. md={{ span: 16 }}
  601. lg={{ span: 16 }}
  602. >
  603. {/* Nombre evento - Ciuad */}
  604. <Row gutter={10}>
  605. <Col
  606. className="gutter-row"
  607. xs={{ span: 24 }}
  608. sm={{ span: 24 }}
  609. md={{ span: 12 }}
  610. lg={{ span: 12 }}
  611. >
  612. <Form.Item
  613. label="Nombre del evento"
  614. name="nombre"
  615. rules={[{ required: true, message: "Requerido" }]}
  616. >
  617. <Input />
  618. </Form.Item>
  619. </Col>
  620. <Col
  621. className="gutter-row"
  622. xs={{ span: 24 }}
  623. sm={{ span: 24 }}
  624. md={{ span: 12 }}
  625. lg={{ span: 12 }}
  626. >
  627. <Form.Item
  628. label="Ciudad"
  629. name="ciudad"
  630. rules={[{ required: true, message: "Requerido" }]}
  631. >
  632. <Input />
  633. </Form.Item>
  634. </Col>
  635. </Row>
  636. {/* Descripción */}
  637. <Row gutter={10}>
  638. <Col className="gutter-row" span={24}>
  639. <Form.Item
  640. label="Descripción"
  641. name="descripcion"
  642. rules={[{ required: true, message: "Requerido" }]}
  643. >
  644. <TextArea placeholder="Ingrese una descripción..." rows={4} />
  645. </Form.Item>
  646. </Col>
  647. </Row>
  648. </Col>
  649. </Row>
  650. {/* Fecha de inicio - Fecha fin - sin fecha - Accion */}
  651. <Row gutter={10} style={{ marginTop: 30 }}>
  652. <Col
  653. className="gutter-row"
  654. xs={{ span: 24 }}
  655. sm={{ span: 24 }}
  656. md={{ span: 6 }}
  657. lg={{ span: 6 }}
  658. >
  659. <Form.Item
  660. rules={[{ required: true, message: "Requerido" }]}
  661. label="Fecha de inicio"
  662. name="fechaInicio"
  663. >
  664. <DatePicker
  665. format="YYYY-MM-DD HH:mm"
  666. style={{ width: "100%" }}
  667. locale={locale}
  668. showTime={{
  669. defaultValue: moment("00:00", "HH:mm"),
  670. }}
  671. />
  672. </Form.Item>
  673. </Col>
  674. <Col
  675. className="gutter-row"
  676. xs={{ span: 24 }}
  677. sm={{ span: 24 }}
  678. md={{ span: 6 }}
  679. lg={{ span: 6 }}
  680. >
  681. <Form.Item
  682. rules={[{ required: !sinFechaFin, message: "Requerido" }]}
  683. label="Fecha de finalización"
  684. name="fechaFinal"
  685. >
  686. <DatePicker
  687. disabled={sinFechaFin}
  688. format="YYYY-MM-DD HH:mm"
  689. style={{ width: "100%" }}
  690. locale={locale}
  691. showTime={{
  692. defaultValue: moment("00:00", "HH:mm"),
  693. }}
  694. />
  695. </Form.Item>
  696. </Col>
  697. <Col
  698. className="gutter-row"
  699. xs={{ span: 24 }}
  700. sm={{ span: 24 }}
  701. md={{ span: 6 }}
  702. lg={{ span: 6 }}
  703. >
  704. <Form.Item label="&nbsp;">
  705. <Checkbox
  706. checked={sinFechaFin}
  707. onChange={(e) => setSinFechaFin(e.target.checked)}
  708. >
  709. Sin fecha de finalización
  710. </Checkbox>
  711. </Form.Item>
  712. </Col>
  713. <Col
  714. className="gutter-row"
  715. xs={{ span: 24 }}
  716. sm={{ span: 24 }}
  717. md={{ span: 6 }}
  718. lg={{ span: 6 }}
  719. >
  720. <Form.Item label="Acción" name="accion">
  721. <Select
  722. mode="multiple"
  723. style={{ width: "100%" }}
  724. placeholder="Selecciona una o más opciones"
  725. optionLabelProp="label"
  726. >
  727. {acciones?.map((item) => (
  728. <Option
  729. value={item?.value}
  730. label={item?.label}
  731. key={item?.id}
  732. >
  733. <div className="demo-option-label-item">
  734. <span role="img" aria-label={item?.label}>
  735. {item?.icon}
  736. </span>
  737. {item?.label}
  738. </div>
  739. </Option>
  740. ))}
  741. </Select>
  742. </Form.Item>
  743. </Col>
  744. </Row>
  745. {/* URL - Red Social - Agregar [+] */}
  746. <Row gutter={10}>
  747. <Col
  748. className="gutter-row"
  749. xs={{ span: 24 }}
  750. sm={{ span: 24 }}
  751. md={{ span: 12 }}
  752. lg={{ span: 12 }}
  753. >
  754. <Form.Item label="URL" name="url">
  755. <Input onChange={(v) => leerLink(v)} />
  756. </Form.Item>
  757. </Col>
  758. <Col
  759. className="gutter-row"
  760. xs={{ span: 24 }}
  761. sm={{ span: 24 }}
  762. md={{ span: editando ? 12 : 9 }}
  763. lg={{ span: editando ? 12 : 9 }}
  764. >
  765. <Form.Item label="Red social" name="redSocial">
  766. <Select style={{ width: "100%" }} placeholder="Selecciona">
  767. {redesSociales?.map((item) => (
  768. <Option key={item} value={item}>
  769. {item}
  770. </Option>
  771. ))}
  772. </Select>
  773. </Form.Item>
  774. </Col>
  775. {!editando && (
  776. <Col
  777. className="gutter-row"
  778. xs={{ span: 24 }}
  779. sm={{ span: 24 }}
  780. md={{ span: 3 }}
  781. lg={{ span: 3 }}
  782. >
  783. <Form.Item label="&nbsp;">
  784. <Button
  785. type="primary"
  786. icon={<PlusCircleOutlined />}
  787. block
  788. onClick={agregarRedSocial}
  789. />
  790. </Form.Item>
  791. </Col>
  792. )}
  793. </Row>
  794. {redes.map((item) => (
  795. <Row key={item.key} gutter={10}>
  796. <Col
  797. className="gutter-row"
  798. xs={{ span: 24 }}
  799. sm={{ span: 24 }}
  800. md={{ span: 12 }}
  801. lg={{ span: 12 }}
  802. >
  803. <Form.Item label="&nbsp;">
  804. <Input readOnly value={item?.url} />
  805. </Form.Item>
  806. </Col>
  807. <Col
  808. className="gutter-row"
  809. xs={{ span: 24 }}
  810. sm={{ span: 24 }}
  811. md={{ span: 9 }}
  812. lg={{ span: 9 }}
  813. >
  814. <Form.Item label="&nbsp;">
  815. <Input readOnly value={item?.redSocial} />
  816. </Form.Item>
  817. </Col>
  818. <Col
  819. className="gutter-row"
  820. xs={{ span: 24 }}
  821. sm={{ span: 24 }}
  822. md={{ span: 3 }}
  823. lg={{ span: 3 }}
  824. >
  825. <Form.Item label="&nbsp;">
  826. <Tooltip title="Remover">
  827. <Button
  828. type="danger"
  829. icon={<MinusCircleOutlined />}
  830. block
  831. onClick={() => quitarRedSocial(item?.key)}
  832. />
  833. </Tooltip>
  834. </Form.Item>
  835. </Col>
  836. </Row>
  837. ))}
  838. <Row gutter={10}>
  839. <Col
  840. xs={{ span: 24 }}
  841. sm={{ span: 24 }}
  842. md={{ span: 12 }}
  843. lg={{ span: 8 }}
  844. >
  845. <Button
  846. type="primary"
  847. htmlType="submit"
  848. icon={<SaveOutlined />}
  849. block
  850. size="large"
  851. loading={guadandoCargando}
  852. >
  853. Guardar
  854. </Button>
  855. </Col>
  856. </Row>
  857. </Form>
  858. </DefaultLayout>
  859. );
  860. };
  861. export default EventosDetalle;