naim-firebase-auth-wrapper
Version:
React components and hooks for Firebase Authentication and Firestore with Mantine UI
87 lines • 5.85 kB
JavaScript
'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useState } from 'react';
import { useAuth } from '../hooks/useAuth';
import { TextInput, PasswordInput, Button, Stack, Paper, Title, Divider, Group, Text, Anchor, Modal, Center, Alert } from '@mantine/core';
import { IconBrandGoogle, IconAlertCircle } from '@tabler/icons-react';
import { validateEmail, validatePassword } from '../utils/validation';
import { handleServiceError } from '../utils/errorHandler';
export const Login = ({ onSuccess, onError, onRegisterClick, title = "Welcome Back", logo }) => {
const { signInWithGoogle, signInWithEmail, forgotPassword } = useAuth();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [resetModalOpen, setResetModalOpen] = useState(false);
const [resetEmail, setResetEmail] = useState('');
const [loading, setLoading] = useState(false);
const [resetLoading, setResetLoading] = useState(false);
const [emailError, setEmailError] = useState('');
const [passwordError, setPasswordError] = useState('');
const [formError, setFormError] = useState('');
const [resetSuccess, setResetSuccess] = useState(false);
const [resetError, setResetError] = useState('');
const handleGoogleLogin = async () => {
setLoading(true);
setFormError('');
try {
await signInWithGoogle();
onSuccess?.();
}
catch (error) {
const handledError = handleServiceError(error, 'Failed to sign in with Google');
setFormError(handledError.message);
onError?.(handledError);
}
finally {
setLoading(false);
}
};
const validateForm = () => {
const emailValidation = validateEmail(email);
const passwordValidation = validatePassword(password);
setEmailError(emailValidation.error);
setPasswordError(passwordValidation.error);
return emailValidation.isValid && passwordValidation.isValid;
};
const handleEmailLogin = async (e) => {
e.preventDefault();
if (!validateForm())
return;
setLoading(true);
setFormError('');
try {
await signInWithEmail(email, password);
onSuccess?.();
}
catch (error) {
const handledError = handleServiceError(error, 'Failed to sign in');
setFormError(handledError.message);
onError?.(handledError);
}
finally {
setLoading(false);
}
};
const handleForgotPassword = async () => {
const emailValidation = validateEmail(resetEmail);
if (!emailValidation.isValid) {
setResetError(emailValidation.error);
return;
}
setResetLoading(true);
setResetError('');
setResetSuccess(false);
try {
await forgotPassword(resetEmail);
setResetSuccess(true);
}
catch (error) {
const handledError = handleServiceError(error, 'Failed to send password reset email');
setResetError(handledError.message);
}
finally {
setResetLoading(false);
}
};
return (_jsxs(_Fragment, { children: [_jsxs(Paper, { radius: "md", p: "xl", withBorder: true, children: [logo && (_jsx(Center, { mb: "md", children: logo })), _jsx(Title, { order: 2, ta: "center", mt: "md", mb: 50, children: title }), formError && (_jsx(Alert, { icon: _jsx(IconAlertCircle, { size: 16 }), color: "red", mb: "md", withCloseButton: true, onClose: () => setFormError(''), children: formError })), _jsx("form", { onSubmit: handleEmailLogin, children: _jsxs(Stack, { children: [_jsx(TextInput, { required: true, label: "Email", placeholder: "hello@example.com", value: email, onChange: (e) => setEmail(e.target.value), error: emailError, radius: "md" }), _jsx(PasswordInput, { required: true, label: "Password", placeholder: "Your password", value: password, onChange: (e) => setPassword(e.target.value), error: passwordError, radius: "md" }), _jsx(Group, { justify: "space-between", children: _jsx(Anchor, { component: "button", type: "button", c: "dimmed", size: "sm", onClick: () => setResetModalOpen(true), children: "Forgot password?" }) }), _jsx(Button, { type: "submit", fullWidth: true, radius: "md", loading: loading, children: "Sign in" })] }) }), _jsx(Divider, { label: "Or continue with", labelPosition: "center", my: "lg" }), _jsx(Button, { leftSection: _jsx(IconBrandGoogle, { size: 16 }), variant: "outline", fullWidth: true, onClick: handleGoogleLogin, radius: "md", loading: loading, children: "Continue with Google" }), _jsxs(Text, { c: "dimmed", size: "sm", ta: "center", mt: "md", children: ["Don't have an account?", ' ', _jsx(Anchor, { component: "button", type: "button", onClick: onRegisterClick, children: "Create account" })] })] }), _jsx(Modal, { opened: resetModalOpen, onClose: () => setResetModalOpen(false), title: "Reset password", children: _jsx(Stack, { children: resetSuccess ? (_jsx(Alert, { color: "green", title: "Success", children: "Password reset instructions have been sent to your email." })) : (_jsxs(_Fragment, { children: [resetError && (_jsx(Alert, { icon: _jsx(IconAlertCircle, { size: 16 }), color: "red", withCloseButton: true, onClose: () => setResetError(''), children: resetError })), _jsx(TextInput, { required: true, label: "Email", placeholder: "Enter your email", value: resetEmail, onChange: (e) => setResetEmail(e.target.value), error: resetError && !resetEmail ? 'Email is required' : '' }), _jsx(Button, { onClick: handleForgotPassword, loading: resetLoading, fullWidth: true, children: "Send reset instructions" })] })) }) })] }));
};
//# sourceMappingURL=Login.js.map