import { PureComponent } from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Paper from '@mui/material/Paper'; import Typography from '@mui/material/Typography'; import GoogleIcon from '@mui/icons-material/Google'; import { enqueueSnackbar } from 'notistack'; import { notifyErrorMessage } from '../utils/notify'; import authAutomat, { bootstrapAuthMe } from '../automats/authAutomat'; import { abortGoogleSignIn, FEDCM_BLOCKED_MESSAGE, GoogleSignInBlockedError, GoogleSignInCancelledError, logError, requestGoogleIdToken, } from '../auth/googleSignIn'; import quixposLogo from '../assets/quixpos-logo.png'; import { NAV_SURFACE, } from '../colors'; class LoginPage extends PureComponent { constructor(props) { super(props); this.state = { ...authAutomat.state, busy: false }; this.handleLogin = this.handleLogin.bind(this); } componentDidMount() { document.title = 'QuixPOS * Management Interface Login'; this.unsubscribe = authAutomat.subscribe(this, ['status', 'googleClientId']); } componentWillUnmount() { this.unsubscribe?.(); } async handleLogin() { const { googleClientId } = this.state; abortGoogleSignIn(); try { const idToken = await requestGoogleIdToken(googleClientId, { onFedcmBlocked: () => { enqueueSnackbar(FEDCM_BLOCKED_MESSAGE, { variant: 'warning', autoHideDuration: 12000, }); }, }); this.setState({ busy: true }); await authAutomat.actions.loginWithGoogle(idToken); await bootstrapAuthMe(); const params = new URLSearchParams(window.location.search); const returnTo = params.get('returnTo'); if (returnTo) { window.location.replace(returnTo); } } catch (err) { if (err instanceof GoogleSignInCancelledError) return; logError('[login] Google sign-in failed', { message: err?.message, name: err?.name, code: err?.code, status: err?.status, cause: err?.cause, stack: err?.stack, clientId: googleClientId, origin: window.location.origin, href: window.location.href, dashHost: window.__dashHost ? { isDashNative: window.__dashHost.isDashNative, googleSignIn: window.__dashHost.googleSignIn, } : null, error: err, }); if (err instanceof GoogleSignInBlockedError) { enqueueSnackbar(err.message, { variant: 'warning', autoHideDuration: 12000 }); return; } const detail = [err?.message || String(err), err?.code, err?.status] .filter(Boolean) .join(' · '); notifyErrorMessage(`Login failed: ${detail}`); } finally { this.setState({ busy: false }); } } render() { const { busy, status, googleClientId } = this.state; const loading = status === 'loading'; const ready = Boolean(googleClientId); return ( QuixPOS Management Interface Login ); } } export default LoginPage;