import React, { useEffect, useState } from "react"; import { BrightnessMediumIcon, Checkbox, DarkModeIcon, IconButton, Label, LightModeIcon, MailIcon, Menu, MenuItem, Typography } from "@firecms/ui"; import { ErrorView, FireCMSLogo, LanguageToggle, useModeController, useTranslation } from "@firecms/core"; import { GoogleLoginButton } from "./GoogleLoginButton"; import { FireCMSBackend } from "../../types"; import { LoginButton } from "@firecms/firebase"; import { CloudUserPasswordForm } from "./CloudUserPasswordForm"; export interface FireCMSCloudLoginViewProps { fireCMSBackend: FireCMSBackend; includeGoogleAdminScopes: boolean; includeLogo: boolean; includeGoogleDisclosure: boolean; includeTermsAndNewsLetter: boolean; disableMarketing?: boolean; onAnalyticsEvent?: (event: string, params?: object) => void; title?: React.ReactNode; subtitle?: React.ReactNode; } /** * Use this component to render a login view, that updates * the state of the {@link AuthController} based on the result * @group Firebase */ export function FireCMSCloudLoginView({ fireCMSBackend, includeGoogleAdminScopes, includeLogo, includeGoogleDisclosure, includeTermsAndNewsLetter, disableMarketing, onAnalyticsEvent, title, subtitle }: FireCMSCloudLoginViewProps) { const { t } = useTranslation(); const { mode, setMode } = useModeController(); const [termsAccepted, setTermsAccepted] = useState(false); const [subscribeToNewsletter, setSubscribeToNewsletter] = useState(false); const [fadeIn, setFadeIn] = useState(false); const [passwordLoginSelected, setPasswordLoginSelected] = useState(false); useEffect(() => { const timer = setTimeout(() => { setFadeIn(true); }, 10); onAnalyticsEvent?.("view_displayed"); return () => clearTimeout(timer); }, [onAnalyticsEvent]); function buildErrorView() { let errorView: any; const ignoredCodes = ["auth/popup-closed-by-user", "auth/cancelled-popup-request"]; if (fireCMSBackend.authProviderError && !ignoredCodes.includes(fireCMSBackend.authProviderError.code)) { if (fireCMSBackend.authProviderError.code === "auth/user-not-found") errorView = ; else if (fireCMSBackend.authProviderError.code === "auth/wrong-password") errorView = ; else if (fireCMSBackend.authProviderError.code === "auth/user-disabled") errorView = ; else if (fireCMSBackend.authProviderError.code === "auth/account-exists-with-different-credential") errorView = ; else if (fireCMSBackend.authProviderError.code === "auth/email-already-in-use") errorView = ; else errorView = ; } return errorView; } const fadeStyle = { opacity: fadeIn ? 1 : 0, transition: "opacity 0.6s ease-in-out" }; // Permissions required mode - simple centered dialog if (includeGoogleAdminScopes) { return (
{includeLogo && (
)} {includeLogo && ( {title || ( <> FireCMS CLOUD )} )} {subtitle && ( {subtitle} )}
{ onAnalyticsEvent?.("google_attempt"); fireCMSBackend.googleLogin(includeGoogleAdminScopes).then((user) => { onAnalyticsEvent?.("google_success"); }).catch((error) => { onAnalyticsEvent?.("google_error", { error: error?.code }); }); }}/> {fireCMSBackend.permissionsNotGrantedError && } {buildErrorView()}
); } // Normal login mode - full view with marketing section return (
{/* Split background for desktop */} {!disableMarketing && (
)}
{mode === "dark" ? : } }> setMode("dark")}> {t("dark_mode")} setMode("light")}> {t("light_mode")} setMode("system")}> {t("system_mode")}
{/* Marketing Section - Left Side (Desktop only) */} {!disableMarketing &&
{t("build_admin_panel_in_minutes")}
  • {t("go_live_instantly")} {t("create_production_ready_back_offices")} {t("without_the_frontend_hassle")}
  • {t("automatic_setup")} {t("from_your_existing_firestore_data")}
  • {t("seamless_real_time_firebase_integration")}
  • {t("intuitive_spreadsheet_like_ui")} {t("your_whole_team_can_use")}
  • {t("focus_on_your_app")} {t("not_the_admin_panel")}
} {/* Login Content - Right Side */}
{includeLogo && (
)} {includeLogo && ( {title || ( <> FireCMS CLOUD )} )} {subtitle && ( {subtitle} )}
{includeTermsAndNewsLetter &&
{!passwordLoginSelected &&
}
} {!passwordLoginSelected && { onAnalyticsEvent?.("google_attempt"); fireCMSBackend.googleLogin(includeGoogleAdminScopes).then((user) => { onAnalyticsEvent?.("google_success"); if (subscribeToNewsletter && user?.email) { subscribeNewsletter(user.email); } }).catch((error) => { onAnalyticsEvent?.("google_error", { error: error?.code }); }); }}/>} {!passwordLoginSelected && } onClick={() => { onAnalyticsEvent?.("password_method_selected"); setPasswordLoginSelected(true); }}/>} {passwordLoginSelected && setPasswordLoginSelected(false)} onAnalyticsEvent={onAnalyticsEvent} />} {buildErrorView()} {includeGoogleDisclosure && {t("firecms_cloud_google_disclosure")} {t("google_api_services_user_data_policy")}, {t("including_the_limited_use_requirements")} }
); } const subscribeNewsletter = (email: string) => { const url = "https://api.firecms.co/notifications/newsletter"; fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email_address: email, source: "saas" }) }).then((res) => { }); }