287 lines
13 KiB
TypeScript
287 lines
13 KiB
TypeScript
"use client";
|
|
import { useEffect, useState } from "react";
|
|
import API from "@services/Api.Service";
|
|
import { useSessionStore } from "@core/Store/Sesion.Store";
|
|
import { useAlert } from "@store/Alert.Store";
|
|
|
|
export default function CheckPendingInvitations() {
|
|
const SessionInfo = useSessionStore();
|
|
const alert = useAlert();
|
|
const [isChecking, setIsChecking] = useState(false);
|
|
const [pendingOrg, setPendingOrg] = useState<any>(null);
|
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
|
|
const checkInvitations = async () => {
|
|
if (!SessionInfo.userId || isChecking) return;
|
|
setIsChecking(true);
|
|
|
|
try {
|
|
const response = await API.post<any[]>("companies/get-by-user", { sessionUser: SessionInfo.userId });
|
|
const orgs = response || [];
|
|
|
|
// Buscar la primera organización donde la invitación esté pendiente de aceptación por parte del usuario
|
|
const foundOrg = orgs.find(org => org.guestOk === false);
|
|
if (foundOrg) {
|
|
setPendingOrg(foundOrg);
|
|
} else {
|
|
setPendingOrg(null);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error comprobando invitaciones:", error);
|
|
} finally {
|
|
setIsChecking(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (SessionInfo.userId) {
|
|
checkInvitations();
|
|
}
|
|
}, [SessionInfo.userId]);
|
|
|
|
const handleAccept = async () => {
|
|
if (!pendingOrg || isProcessing) return;
|
|
setIsProcessing(true);
|
|
try {
|
|
await API.post("employees/validate-guest", {
|
|
employeeId: pendingOrg.employeeId,
|
|
sessionUser: SessionInfo.userId
|
|
});
|
|
alert.showSuccess("¡Invitación aceptada exitosamente!");
|
|
setPendingOrg(null);
|
|
setTimeout(() => checkInvitations(), 1000);
|
|
} catch (e: any) {
|
|
alert.showError(e.message || "Ocurrió un error al aceptar");
|
|
} finally {
|
|
setIsProcessing(false);
|
|
}
|
|
};
|
|
|
|
const handleReject = async () => {
|
|
if (!pendingOrg || isProcessing) return;
|
|
setIsProcessing(true);
|
|
try {
|
|
await API.post("employees/reject-guest", {
|
|
employeeId: pendingOrg.employeeId,
|
|
sessionUser: SessionInfo.userId
|
|
});
|
|
alert.showInfo("Invitación rechazada.");
|
|
setPendingOrg(null);
|
|
setTimeout(() => checkInvitations(), 1000);
|
|
} catch (e: any) {
|
|
alert.showError(e.message || "Ocurrió un error al rechazar");
|
|
} finally {
|
|
setIsProcessing(false);
|
|
}
|
|
};
|
|
|
|
const handleLater = () => {
|
|
setPendingOrg(null);
|
|
};
|
|
|
|
if (!pendingOrg) return <></>;
|
|
|
|
return (
|
|
<>
|
|
<style>{`
|
|
@keyframes slideUpFade {
|
|
from { opacity: 0; transform: translate(-50%, 20px) scale(0.95); }
|
|
to { opacity: 1; transform: translate(-50%, 0) scale(1); }
|
|
}
|
|
@keyframes floatParticle {
|
|
0% { transform: translateY(0) scale(1); opacity: 0; }
|
|
50% { opacity: 0.8; transform: translateY(-20px) scale(1.2); }
|
|
100% { transform: translateY(-40px) scale(0.8); opacity: 0; }
|
|
}
|
|
`}</style>
|
|
|
|
{/* Overlay */}
|
|
<div style={{
|
|
position: 'fixed',
|
|
top: 0, left: 0, right: 0, bottom: 0,
|
|
backgroundColor: 'rgba(255, 255, 255, 0.4)',
|
|
backdropFilter: 'blur(8px)',
|
|
zIndex: 10000,
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center'
|
|
}}>
|
|
{/* Modal Container */}
|
|
<div style={{
|
|
position: 'absolute',
|
|
top: '30%',
|
|
left: '50%',
|
|
transform: 'translate(-50%, 0)',
|
|
width: '90%',
|
|
maxWidth: '420px',
|
|
backgroundColor: '#ffffff',
|
|
borderRadius: '24px',
|
|
boxShadow: '0 20px 40px rgba(0,0,0,0.1), 0 0 0 1px rgba(0,0,0,0.05), 0 0 40px rgba(255, 65, 108, 0.1)',
|
|
padding: '32px 24px',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center',
|
|
animation: 'slideUpFade 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards',
|
|
overflow: 'hidden'
|
|
}}>
|
|
|
|
{/* Decorative Background Elements */}
|
|
<div style={{ position: 'absolute', top: '-50px', right: '-50px', width: '150px', height: '150px', background: 'radial-gradient(circle, var(--wine-lighterX2) 0%, transparent 70%)', borderRadius: '50%' }} />
|
|
<div style={{ position: 'absolute', bottom: '-50px', left: '-50px', width: '150px', height: '150px', background: 'radial-gradient(circle, var(--wine-lighterX2) 0%, transparent 70%)', borderRadius: '50%' }} />
|
|
|
|
{/* Particles */}
|
|
<div style={{ position: 'absolute', top: '20px', left: '20%', width: '8px', height: '8px', borderRadius: '50%', background: 'var(--wine-light)', animation: 'floatParticle 3s infinite ease-in-out' }} />
|
|
<div style={{ position: 'absolute', top: '40px', right: '20%', width: '6px', height: '6px', borderRadius: '50%', background: 'var(--wine-dark)', animation: 'floatParticle 4s infinite ease-in-out 1s' }} />
|
|
<div style={{ position: 'absolute', top: '60px', left: '80%', width: '10px', height: '10px', borderRadius: '50%', background: 'var(--wine-lighter)', animation: 'floatParticle 3.5s infinite ease-in-out 0.5s' }} />
|
|
|
|
{/* Icon */}
|
|
<div style={{
|
|
width: '64px',
|
|
height: '64px',
|
|
borderRadius: '16px',
|
|
background: 'linear-gradient(135deg, var(--wine-dark) 0%, var(--wine-light) 100%)',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
marginBottom: '20px',
|
|
boxShadow: '0 8px 16px var(--wine-lighterX2)',
|
|
position: 'relative',
|
|
zIndex: 1
|
|
}}>
|
|
<span style={{ fontSize: '32px', color: '#fff' }}>✨</span>
|
|
</div>
|
|
|
|
<h2 style={{
|
|
fontSize: '24px',
|
|
fontWeight: '700',
|
|
color: '#1a1a1a',
|
|
textAlign: 'center',
|
|
marginBottom: '12px',
|
|
position: 'relative',
|
|
zIndex: 1
|
|
}}>
|
|
¡Tienes una nueva invitación!
|
|
</h2>
|
|
|
|
<p style={{
|
|
fontSize: '15px',
|
|
color: '#666',
|
|
textAlign: 'center',
|
|
marginBottom: '24px',
|
|
lineHeight: '1.5',
|
|
position: 'relative',
|
|
zIndex: 1
|
|
}}>
|
|
Has sido invitado a formar parte del equipo de colaboradores en:
|
|
</p>
|
|
|
|
{/* Company Card */}
|
|
<div style={{
|
|
width: '100%',
|
|
padding: '16px',
|
|
backgroundColor: '#f8f9fa',
|
|
borderRadius: '12px',
|
|
border: '1px solid #eaeaea',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
marginBottom: '32px',
|
|
position: 'relative',
|
|
zIndex: 1
|
|
}}>
|
|
<div style={{
|
|
width: '40px',
|
|
height: '40px',
|
|
borderRadius: '50%',
|
|
backgroundColor: '#e2e8f0',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
marginRight: '16px',
|
|
color: '#64748b',
|
|
fontWeight: 'bold',
|
|
fontSize: '16px'
|
|
}}>
|
|
{pendingOrg.name.charAt(0).toUpperCase()}
|
|
</div>
|
|
<div>
|
|
<div style={{ fontWeight: '600', color: '#1e293b', fontSize: '16px' }}>{pendingOrg.name}</div>
|
|
<div style={{ fontSize: '13px', color: '#64748b' }}>Nueva Oportunidad</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Buttons */}
|
|
<div style={{ display: 'flex', flexDirection: 'column', width: '100%', gap: '12px', position: 'relative', zIndex: 1 }}>
|
|
<button
|
|
onClick={handleAccept}
|
|
disabled={isProcessing}
|
|
style={{
|
|
width: '100%',
|
|
padding: '14px',
|
|
borderRadius: '12px',
|
|
background: 'linear-gradient(135deg, var(--wine-dark) 0%, var(--wine-light) 100%)',
|
|
color: '#fff',
|
|
border: 'none',
|
|
fontWeight: '600',
|
|
fontSize: '16px',
|
|
cursor: isProcessing ? 'not-allowed' : 'pointer',
|
|
boxShadow: '0 4px 12px var(--wine-lighterX2)',
|
|
transition: 'transform 0.2s, box-shadow 0.2s',
|
|
opacity: isProcessing ? 0.8 : 1
|
|
}}
|
|
onMouseOver={e => e.currentTarget.style.transform = 'translateY(-2px)'}
|
|
onMouseOut={e => e.currentTarget.style.transform = 'translateY(0)'}
|
|
>
|
|
{isProcessing ? 'Procesando...' : 'Aceptar Invitación'}
|
|
</button>
|
|
|
|
<div style={{ display: 'flex', gap: '12px' }}>
|
|
<button
|
|
onClick={handleReject}
|
|
disabled={isProcessing}
|
|
style={{
|
|
flex: 1,
|
|
padding: '12px',
|
|
borderRadius: '12px',
|
|
backgroundColor: 'transparent',
|
|
color: '#64748b',
|
|
border: '1px solid #cbd5e1',
|
|
fontWeight: '500',
|
|
fontSize: '14px',
|
|
cursor: isProcessing ? 'not-allowed' : 'pointer',
|
|
transition: 'all 0.2s'
|
|
}}
|
|
onMouseOver={e => { e.currentTarget.style.color = 'var(--wine-dark)'; e.currentTarget.style.borderColor = 'var(--wine-dark)'; }}
|
|
onMouseOut={e => { e.currentTarget.style.color = '#64748b'; e.currentTarget.style.borderColor = '#cbd5e1'; }}
|
|
>
|
|
Rechazar
|
|
</button>
|
|
|
|
<button
|
|
onClick={handleLater}
|
|
disabled={isProcessing}
|
|
style={{
|
|
flex: 1,
|
|
padding: '12px',
|
|
borderRadius: '12px',
|
|
backgroundColor: '#f1f5f9',
|
|
color: '#475569',
|
|
border: 'none',
|
|
fontWeight: '500',
|
|
fontSize: '14px',
|
|
cursor: isProcessing ? 'not-allowed' : 'pointer',
|
|
transition: 'background-color 0.2s'
|
|
}}
|
|
onMouseOver={e => e.currentTarget.style.backgroundColor = '#e2e8f0'}
|
|
onMouseOut={e => e.currentTarget.style.backgroundColor = '#f1f5f9'}
|
|
>
|
|
Más tarde
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|