'use client';
import { ExtensionService } from '@/services/extensionService';
import {
Stack,
Text,
Button,
UnstyledButton,
TextInput,
PasswordInput,
Alert,
} from '@mantine/core';
import { BiRightArrowAlt } from 'react-icons/bi';
import { MdOutlineAlternateEmail, MdLock } from 'react-icons/md';
import { useAuth } from '@/hooks/useAuth';
import { useForm } from '@mantine/form';
import { useRouter, useSearchParams } from 'next/navigation';
import { useEffect, useState } from 'react';
import { createSembleClient } from '@/services/apiClient';
export default function LoginForm() {
const router = useRouter();
const searchParams = useSearchParams();
const { isAuthenticated, refreshAuth } = useAuth();
const [isCheckingAuth, setIsCheckingAuth] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState('');
const isExtensionLogin = searchParams.get('extension-login') === 'true';
const client = createSembleClient();
const handleExtensionTokenGeneration = async () => {
try {
setIsLoading(true);
const tokens = await client.generateExtensionTokens();
await ExtensionService.sendTokensToExtension(tokens);
setError('');
// Clear the extension tokens requested flag
ExtensionService.clearExtensionTokensRequested();
// Redirect to extension success page after successful extension token generation
router.push('/extension/auth/complete');
} catch (err: any) {
// Clear the flag even on failure
ExtensionService.clearExtensionTokensRequested();
// Redirect to extension error page
router.push('/extension/auth/error');
} finally {
setIsLoading(false);
}
};
useEffect(() => {
if (isAuthenticated) {
isExtensionLogin
? handleExtensionTokenGeneration()
: router.push('/home');
} else {
setIsCheckingAuth(false);
}
}, [isAuthenticated, isExtensionLogin]);
const handleOAuthSubmit = async (e: React.FormEvent) => {
e.preventDefault();
// validate form
const isValid = form.validateField('handle');
if (!isValid) return;
try {
setIsLoading(true);
setError('');
if (isExtensionLogin) {
ExtensionService.setExtensionTokensRequested();
}
console.log('HANDLE', form.values.handle.trimEnd());
const { authUrl } = await client.initiateOAuthSignIn({
handle: form.values.handle.trimEnd(),
});
window.location.href = authUrl;
} catch (err: any) {
setError(err.message || 'An error occurred during login');
} finally {
setIsLoading(false);
}
};
const handleAppPasswordSubmit = async (e: React.FormEvent) => {
e.preventDefault();
// validate
const validation = form.validate();
if (validation.hasErrors) return;
try {
setIsLoading(true);
setError('');
await client.loginWithAppPassword({
identifier: form.values.handle.trimEnd(),
appPassword: form.values.appPassword,
});
// Refresh auth state to fetch user profile with new tokens (cookies are set automatically)
await refreshAuth();
if (isExtensionLogin) {
await handleExtensionTokenGeneration();
} else {
router.push('/home');
}
} catch (err: any) {
setError(err.message || 'Invalid credentials');
} finally {
setIsLoading(false);
}
};
const form = useForm({
initialValues: {
handle: '',
appPassword: '',
useAppPassword: false,
},
validate: {
handle: (value) => (value.trim() ? null : 'Handle is required'),
appPassword: (value, values) =>
values.useAppPassword && value.trim() === ''
? 'App password is required'
: null,
},
});
if (form.values.useAppPassword) {
return (
{
form.setFieldValue('useAppPassword', false);
setError('');
}}
>
Use OAuth login
);
}
return (
);
}