228 lines
11 KiB
TypeScript
228 lines
11 KiB
TypeScript
"use client";
|
|
import AnimatedContainer from "@components/AnimatedConainer/AnimatedContainer";
|
|
import WhatsAppIcon from "@mui/icons-material/WhatsApp";
|
|
import LocationOnIcon from "@mui/icons-material/LocationOn";
|
|
import Button from "@core/app/components/Button/Button";
|
|
import LocationMap from "@core/app/components/LocationMap/LocationMap";
|
|
import EventIcon from "@mui/icons-material/Event";
|
|
import LocalOfferIcon from "@mui/icons-material/LocalOffer";
|
|
import PersonIcon from "@mui/icons-material/Person";
|
|
import AttachMoneyIcon from "@mui/icons-material/AttachMoney";
|
|
import { PublicOrganizationView } from "@core/Models/Company.model";
|
|
import OrganizationHeader from "@core/app/components/Home/OrganizationHeader/OrganizationHeader";
|
|
import { UserAppointmentView, UserAppointmentViewParams } from "@core/Models/Views.model";
|
|
import { useEffect, useState } from "react";
|
|
import { deleteAppointment, viewAppointment } from "../Appointments.Service";
|
|
import { useAlert } from "@core/Store/Alert.Store";
|
|
import { useParams } from "next/navigation";
|
|
import { EVENT_TYPES, useEventHandlerStore } from "@core/Store/EventHandler.Store";
|
|
import { useSessionStore } from "@core/Store/Sesion.Store";
|
|
import style from "./page.module.css";
|
|
import dayjs from "dayjs";
|
|
import "dayjs/locale/es";
|
|
import { formatPrice } from "@core/app/helpers/Numbers";
|
|
import { DeleteAppointmentParams } from "@core/Models/Appointments.model";
|
|
import { useConfirmStore } from "@core/Store/Confirm.Store";
|
|
import { useNavigation } from "@core/app/hooks/goto";
|
|
import { ScrollToTop } from "@core/app/components/ScrollTop";
|
|
|
|
dayjs.locale("es");
|
|
|
|
type UrlData = {
|
|
aid: string;
|
|
};
|
|
|
|
type PositionType = [number, number];
|
|
|
|
export default function OrganizationPublicProfile() {
|
|
const data = useParams<UrlData>();
|
|
const aid = data.aid;
|
|
const [appointmentInfo, setAppointmentInfo] = useState<UserAppointmentView | null>(null);
|
|
const [orgData, setOrgData] = useState<PublicOrganizationView | null>(null);
|
|
const [position, setPosition] = useState<PositionType>([0, 0]);
|
|
|
|
const alert = useAlert();
|
|
const confirm = useConfirmStore();
|
|
const eventHandler = useEventHandlerStore();
|
|
const SessionInfo = useSessionStore();
|
|
const { goTo } = useNavigation();
|
|
|
|
const loadAppointmentData = async () => {
|
|
const data: UserAppointmentViewParams = {
|
|
appointmentId: aid,
|
|
sessionUser: SessionInfo.userId,
|
|
};
|
|
|
|
eventHandler.setEventType(EVENT_TYPES.LOADING);
|
|
|
|
viewAppointment(data)
|
|
.then((response) => {
|
|
setAppointmentInfo(response);
|
|
setOrgData(response.organization);
|
|
setPosition([response.organization.latitude, response.organization.longitude]);
|
|
})
|
|
.catch((error) => {
|
|
console.error(error);
|
|
alert.showError(error.format());
|
|
})
|
|
.finally(() => {
|
|
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
|
});
|
|
};
|
|
|
|
const handleCancellAppointment = () => {
|
|
confirm.show(
|
|
"¿Está seguro que desea cancelar el turno?",
|
|
() => {
|
|
const data: DeleteAppointmentParams = {
|
|
id: aid,
|
|
validation: true,
|
|
sessionUser: SessionInfo.userId,
|
|
};
|
|
eventHandler.setEventType(EVENT_TYPES.LOADING);
|
|
deleteAppointment(data)
|
|
.then(() => {
|
|
alert.showSuccess("Turno cancelado correctamente.");
|
|
setTimeout(() => {
|
|
goTo("/landing/my-appointments");
|
|
}, 2000);
|
|
})
|
|
.catch((error) => {
|
|
alert.showError(error.format());
|
|
})
|
|
.finally(() => {
|
|
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
|
});
|
|
},
|
|
() => {}
|
|
);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!SessionInfo.userId) {
|
|
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
|
return;
|
|
}
|
|
loadAppointmentData();
|
|
}, [SessionInfo.userId]);
|
|
|
|
return (
|
|
<>
|
|
{appointmentInfo && orgData && (
|
|
<AnimatedContainer
|
|
color={orgData.headerColor}
|
|
minSize={150}
|
|
maxSize={500}
|
|
items={10}
|
|
style={{
|
|
background: `linear-gradient(180deg, ${orgData.headerColor} 0%, var(--white) 50%)`,
|
|
}}
|
|
>
|
|
<ScrollToTop />
|
|
<div className="homeCentered">
|
|
<OrganizationHeader organization={orgData} />
|
|
<div className={style.organizationContent}>
|
|
<div className={style.organizationServices}>
|
|
<h1>Detalles de tu Reserva</h1>
|
|
<p className={style.introText}>
|
|
Bienvenido a los detalles de tu turno. Aquí encontrarás toda la
|
|
información sobre tu reserva, así como opciones para cancelarla
|
|
o ponerte en contacto directo con nosotros.
|
|
</p>
|
|
|
|
<div className={style.infoGrid}>
|
|
<div className={style.infoCard}>
|
|
<div className={style.infoIconWrapper}>
|
|
<EventIcon />
|
|
</div>
|
|
<div className={style.infoContent}>
|
|
<span className={style.infoLabel}>Fecha y Hora</span>
|
|
<span className={style.infoValue}>
|
|
{dayjs(appointmentInfo.appointment.appointmentDate)
|
|
.format("D [de] MMMM [de] YYYY - HH:mm [hs]")}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={style.infoCard}>
|
|
<div className={style.infoIconWrapper}>
|
|
<LocalOfferIcon />
|
|
</div>
|
|
<div className={style.infoContent}>
|
|
<span className={style.infoLabel}>Servicio</span>
|
|
<span className={style.infoValue}>
|
|
{appointmentInfo.appointment.serviceName}
|
|
</span>
|
|
<span className={style.infoSubValue}>
|
|
{appointmentInfo.appointment.serviceDescription}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={style.infoCard}>
|
|
<div className={style.infoIconWrapper}>
|
|
<PersonIcon />
|
|
</div>
|
|
<div className={style.infoContent}>
|
|
<span className={style.infoLabel}>Profesional</span>
|
|
<span className={style.infoValue}>
|
|
{appointmentInfo.appointment.collaboratorName}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={style.infoCard}>
|
|
<div className={style.infoIconWrapper}>
|
|
<AttachMoneyIcon />
|
|
</div>
|
|
<div className={style.infoContent}>
|
|
<span className={style.infoLabel}>Precio</span>
|
|
<span className={style.infoValue}>
|
|
{formatPrice(appointmentInfo.appointment.price)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={style.organizationMap}>
|
|
<h2>Información Útil</h2>
|
|
<div className={style.mapWrapper}>
|
|
<LocationMap position={position} orgData={orgData} />
|
|
</div>
|
|
<div className={style.contactInfo}>
|
|
<div className={style.contactRow}>
|
|
<LocationOnIcon />
|
|
<span>{orgData.address}</span>
|
|
</div>
|
|
<div className={style.contactRow}>
|
|
<WhatsAppIcon />
|
|
<span>{orgData.phone}</span>
|
|
</div>
|
|
</div>
|
|
<div className={style.actionButtons}>
|
|
<Button
|
|
color="primary"
|
|
text="Cancelar turno"
|
|
width="100%"
|
|
onClick={handleCancellAppointment}
|
|
/>
|
|
<Button
|
|
color="secondary"
|
|
text="Enviar mensaje"
|
|
width="100%"
|
|
onClick={() => {
|
|
goTo(`/landing/org/${orgData.id}/send-message`);
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</AnimatedContainer>
|
|
)}
|
|
{appointmentInfo === null && <h1>Cargando...</h1>}
|
|
</>
|
|
);
|
|
}
|