Initial commit
This commit is contained in:
+145
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @license
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import type { Session } from "@supabase/supabase-js";
|
||||
import { AnimatePresence, motion } from "motion/react";
|
||||
import { LoginScreen } from "./components/LoginScreen";
|
||||
import { PortalPrincipal } from "./components/PortalPrincipal";
|
||||
import { ALLOWED_EMAILS, isAllowedEmail } from "./lib/auth";
|
||||
import { isSupabaseConfigured, supabase } from "./lib/supabase";
|
||||
|
||||
export default function App() {
|
||||
const [session, setSession] = useState<Session | null>(null);
|
||||
const [isLoadingSession, setIsLoadingSession] = useState(true);
|
||||
const [authError, setAuthError] = useState("");
|
||||
|
||||
const validateAndSetSession = async (currentSession: Session | null) => {
|
||||
const email = currentSession?.user?.email;
|
||||
|
||||
if (!currentSession) {
|
||||
setSession(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAllowedEmail(email)) {
|
||||
setSession(null);
|
||||
setAuthError(
|
||||
"Este correo no tiene acceso al portal. Usa ymadera@gomezleemarketing.com o iaracena@gomezleemarketing.com."
|
||||
);
|
||||
await supabase?.auth.signOut();
|
||||
return;
|
||||
}
|
||||
|
||||
setAuthError("");
|
||||
setSession(currentSession);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!isSupabaseConfigured || !supabase) {
|
||||
setAuthError("Falta configurar Supabase en el archivo .env.local.");
|
||||
setIsLoadingSession(false);
|
||||
return;
|
||||
}
|
||||
|
||||
let isMounted = true;
|
||||
|
||||
supabase.auth.getSession().then(async ({ data, error }) => {
|
||||
if (!isMounted) return;
|
||||
|
||||
if (error) {
|
||||
setAuthError("No se pudo validar la sesión. Intenta iniciar sesión nuevamente.");
|
||||
setSession(null);
|
||||
} else {
|
||||
await validateAndSetSession(data.session);
|
||||
}
|
||||
|
||||
setIsLoadingSession(false);
|
||||
});
|
||||
|
||||
const { data: listener } = supabase.auth.onAuthStateChange(async (_event, currentSession) => {
|
||||
await validateAndSetSession(currentSession);
|
||||
setIsLoadingSession(false);
|
||||
});
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
listener.subscription.unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleLogin = async () => {
|
||||
setAuthError("");
|
||||
|
||||
if (!isSupabaseConfigured || !supabase) {
|
||||
setAuthError("Falta configurar VITE_SUPABASE_URL y VITE_SUPABASE_ANON_KEY en .env.local.");
|
||||
return;
|
||||
}
|
||||
|
||||
const redirectTo = `${window.location.origin}${import.meta.env.BASE_URL}`;
|
||||
|
||||
const { error } = await supabase.auth.signInWithOAuth({
|
||||
provider: "google",
|
||||
options: {
|
||||
redirectTo,
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
setAuthError("No se pudo iniciar sesión con Google. Revisa la configuración de Supabase Auth.");
|
||||
}
|
||||
};
|
||||
|
||||
const handleLogout = async () => {
|
||||
setAuthError("");
|
||||
await supabase?.auth.signOut();
|
||||
setSession(null);
|
||||
};
|
||||
|
||||
if (isLoadingSession) {
|
||||
return (
|
||||
<div className="min-h-screen bg-[#f5f3f3] flex items-center justify-center text-[#365c71] text-sm font-semibold">
|
||||
Validando sesión...
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const isLoggedIn = Boolean(session && isAllowedEmail(session.user.email));
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#fbf9f8]" id="app-container">
|
||||
<AnimatePresence mode="wait">
|
||||
{!isLoggedIn ? (
|
||||
<motion.div
|
||||
key="login"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="w-full h-full"
|
||||
>
|
||||
<LoginScreen
|
||||
onLogin={handleLogin}
|
||||
authError={authError}
|
||||
isSupabaseConfigured={isSupabaseConfigured}
|
||||
allowedEmails={ALLOWED_EMAILS}
|
||||
/>
|
||||
</motion.div>
|
||||
) : (
|
||||
<motion.div
|
||||
key="portal"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="w-full h-full"
|
||||
>
|
||||
<PortalPrincipal onLogout={handleLogout} userEmail={session?.user.email ?? ""} />
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user