Toast
1. Toast
src\components\ui\toast\index.ts
// class Toast {}
2. Op. Persist Toast
- Permite definir un toast antes de navegar a otra página
- Ej. Al agregar un producto, se actualiza correctamente, pero si redirige a otra página el toast normal no se muestra durante el tiempo definido, entonces con el persistente se muestra en la otra página, después de navegar
1. Wrapper
src\components\ui\toast\persist-toast.ts
import type { ToastOptions, ToastType } from "@/components/ui/toast";
import { toast } from "@/components/ui/toast";
const STORAGE_KEY = "persisted_toast";
interface PersistedToast {
message: string;
type: ToastType;
options: ToastOptions;
}
export const persistToast = {
show(
message: string,
type: ToastType = "default",
options: ToastOptions = {}
): void {
const data: PersistedToast = { message, type, options };
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(data));
},
checkAndShow(): void {
const persisted = sessionStorage.getItem(STORAGE_KEY);
if (persisted) {
const { message, type, options } = JSON.parse(
persisted
) as PersistedToast;
toast.show(message, type, options);
sessionStorage.removeItem(STORAGE_KEY);
}
},
};
2. Inicializar
- Inicializar en el archivo principal, como
MainLayout.astrooscripts.ts
src\layouts\Layout.astro
<html>
</html>
<script>
import { persistToast } from "@/components/ui/toast/persist-toast";
document.addEventListener("DOMContentLoaded", () => {
persistToast.checkAndShow();
});
</script>
3. Uso
src\pages\unit\edit[unitId].astro
<MainLayout title="Edit Unit">
</MainLayout>
<script>
import { toast } from "@/components/ui/toast";
import { persistToast } from "@/components/ui/toast/persist-toast";
import { ActionInputError, actions } from "astro:actions";
const form = document.querySelector("form") as HTMLFormElement;
const btnSubmit = document.getElementById("btn-submit") as HTMLButtonElement;
form.addEventListener("submit", async (e) => {
e.preventDefault();
btnSubmit.setAttribute("disabled", "disabled");
// Guardar referencia del Loading Toast
const loadingToast = toast.loading("Guardando...");
const formData = new FormData(form);
const { error } = await actions.updateUnit(formData);
// Cerrar Loading Toast
loadingToast.dismiss();
if (error) {
const errorMessage =
error instanceof ActionInputError
? Object.entries(error.fields)
.map(([field, messages]) => `${field}: ${messages?.join(", ")}`)
.join("\n")
: error.message;
// Toast
toast.error(errorMessage);
btnSubmit.removeAttribute("disabled");
return;
}
// Toast con persistencia entre páginas
persistToast.show("Unidad actualizada correctamente", "success");
const courseId = form.getAttribute("data-courseId");
window.location.replace(`/course/${courseId}`);
});
</script>
src\pages\lessons[unitId].astro
<MainLayout title="Lessons">
</MainLayout>
<script>
import { toast } from "@/components/ui/toast";
import { actions } from "astro:actions";
// Delete register and row
const btnDelete = document.querySelectorAll(".btn-delete");
btnDelete.forEach((btn) => {
btn.addEventListener("click", async (e) => {
const id = btn.getAttribute("data-id");
if (!id) return;
// Confirm Toast
const confirmDelete = await toast.confirm(
"¿Estás seguro de eliminar esta lección?"
);
if (!confirmDelete) return;
const { error } = await actions.deleteLesson(+id);
if (error) {
toast.error(error.message);
return;
}
document.getElementById(id.toString())?.remove();
toast.default("Lección eliminada correctamente");
});
});
</script>