añadida funcionalidad de compartir y modificar las coords
This commit is contained in:
97
src/components/EditarModal.jsx
Normal file
97
src/components/EditarModal.jsx
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
export default function EditarModal({ tipo, coord, show, close, setCoords }) {
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const formData = new FormData(e.target);
|
||||||
|
const x = formData.get("x");
|
||||||
|
const y = formData.get("y");
|
||||||
|
const z = formData.get("z");
|
||||||
|
|
||||||
|
let storedTipo = localStorage.getItem(tipo);
|
||||||
|
if (storedTipo) {
|
||||||
|
let arr = JSON.parse(storedTipo);
|
||||||
|
const index = arr.findIndex((item) => item.num === coord.num);
|
||||||
|
if (index !== -1) {
|
||||||
|
arr[index] = {
|
||||||
|
...coord,
|
||||||
|
x: Number(x),
|
||||||
|
y: y ? Number(y) : null,
|
||||||
|
z: Number(z),
|
||||||
|
};
|
||||||
|
localStorage.setItem(tipo, JSON.stringify(arr));
|
||||||
|
setCoords(arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!show) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="modal"
|
||||||
|
id="formModal"
|
||||||
|
tabIndex="-1"
|
||||||
|
style={{ display: "block" }}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
<h5 className="modal-title">Update Coord</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
onClick={close}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Coordenada X</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
name="x"
|
||||||
|
className="form-control"
|
||||||
|
defaultValue={coord.x}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{coord.y != null && (
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Coordenada Y</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
name="y"
|
||||||
|
className="form-control"
|
||||||
|
defaultValue={coord.y}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Coordenada Z</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
name="z"
|
||||||
|
className="form-control"
|
||||||
|
defaultValue={coord.z}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<button type="submit" className="btn btn-primary m-2">
|
||||||
|
Actualizar
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-secondary"
|
||||||
|
onClick={close}
|
||||||
|
>
|
||||||
|
Cancelar
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
35
src/components/TimedToast.jsx
Normal file
35
src/components/TimedToast.jsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
export default function TimedToast({ message, durationMs, show, setShow }) {
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setShow(false);
|
||||||
|
}, durationMs);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [durationMs]);
|
||||||
|
|
||||||
|
if (!show) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="position-fixed bottom-0 end-0 p-3" style={{ zIndex: 11 }}>
|
||||||
|
<div
|
||||||
|
className="toast show"
|
||||||
|
role="alert"
|
||||||
|
aria-live="assertive"
|
||||||
|
aria-atomic="true"
|
||||||
|
>
|
||||||
|
<div className="toast-header">
|
||||||
|
<strong className="me-auto">Notification</strong>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
onClick={() => setShow(false)}
|
||||||
|
aria-label="Close"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="toast-body">{message}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ import EditarIcon from "./EditarIcon";
|
|||||||
import ShareIcon from "./ShareIcon";
|
import ShareIcon from "./ShareIcon";
|
||||||
import RemoveIcon from "./RemoveIcon";
|
import RemoveIcon from "./RemoveIcon";
|
||||||
import StaticModal from "./StaticModal";
|
import StaticModal from "./StaticModal";
|
||||||
|
import EditarModal from "./EditarModal";
|
||||||
|
import TimedToast from "./TimedToast";
|
||||||
|
|
||||||
function Modall({ show, CloseModal, Coord, Coords, EliminarCoord, tipo }) {
|
function Modall({ show, CloseModal, Coord, Coords, EliminarCoord, tipo }) {
|
||||||
if (show === true && Coord !== null) {
|
if (show === true && Coord !== null) {
|
||||||
@@ -26,10 +28,13 @@ export default function Keeper({ tipo }) {
|
|||||||
const [coords, setCoords] = useState(
|
const [coords, setCoords] = useState(
|
||||||
JSON.parse(localStorage.getItem(tipo) || "[]"),
|
JSON.parse(localStorage.getItem(tipo) || "[]"),
|
||||||
);
|
);
|
||||||
|
|
||||||
const collapseRef = useRef(null);
|
const collapseRef = useRef(null);
|
||||||
const [showModal, setModal] = useState(false);
|
const [showModal, setModal] = useState(false);
|
||||||
//const [showShareToast, setShowShareToast] = useState(false);
|
const [showEditar, setEditar] = useState(false);
|
||||||
|
const [showToast, setShowToast] = useState(false);
|
||||||
const [selCoord, setCoord] = useState(null);
|
const [selCoord, setCoord] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storedCoords = JSON.parse(localStorage.getItem(tipo) || "[]");
|
const storedCoords = JSON.parse(localStorage.getItem(tipo) || "[]");
|
||||||
|
|
||||||
@@ -39,12 +44,16 @@ export default function Keeper({ tipo }) {
|
|||||||
}
|
}
|
||||||
}, [tipo]);
|
}, [tipo]);
|
||||||
|
|
||||||
const Editar = () => {
|
const Editar = (coord) => {
|
||||||
//wip
|
setCoord(coord);
|
||||||
|
setEditar(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Compartir = () => {
|
const Compartir = (coord) => {
|
||||||
//wip
|
setCoord(coord);
|
||||||
|
const textToCopy = `X: ${coord.x}${coord.y ? ` Y: ${coord.y}` : ""} Z: ${coord.z}`;
|
||||||
|
navigator.clipboard.writeText(textToCopy);
|
||||||
|
setShowToast(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Remover = (coord) => {
|
const Remover = (coord) => {
|
||||||
@@ -69,6 +78,22 @@ export default function Keeper({ tipo }) {
|
|||||||
EliminarCoord={setCoords}
|
EliminarCoord={setCoords}
|
||||||
tipo={tipo}
|
tipo={tipo}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<EditarModal
|
||||||
|
show={showEditar}
|
||||||
|
close={() => setEditar(false)}
|
||||||
|
tipo={tipo}
|
||||||
|
coord={selCoord}
|
||||||
|
setCoords={setCoords}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TimedToast
|
||||||
|
durationMs={5000}
|
||||||
|
setShow={setShowToast}
|
||||||
|
show={showToast}
|
||||||
|
message={`Copiada Coordenada ${selCoord?.num}`}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="accordion" id="accordionNuevaCoord">
|
<div className="accordion" id="accordionNuevaCoord">
|
||||||
<div className="accordion-item">
|
<div className="accordion-item">
|
||||||
<h2 className="accordion-header" id="headingNuevaCoord">
|
<h2 className="accordion-header" id="headingNuevaCoord">
|
||||||
@@ -134,13 +159,13 @@ export default function Keeper({ tipo }) {
|
|||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
class="ms-2 btn btn-outline-warning btn-sm"
|
class="ms-2 btn btn-outline-warning btn-sm"
|
||||||
onClick={() => Editar()}
|
onClick={() => Editar(x)}
|
||||||
>
|
>
|
||||||
<EditarIcon />
|
<EditarIcon />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-outline-info ms-2"
|
className="btn btn-sm btn-outline-info ms-2"
|
||||||
onClick={() => Compartir()}
|
onClick={() => Compartir(x)}
|
||||||
>
|
>
|
||||||
<ShareIcon />
|
<ShareIcon />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user