mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-26 14:26:06 +00:00
feat: add Space integration for user authentication and model management with OAuth support
This commit is contained in:
@@ -20,10 +20,10 @@ import {
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { httpClient } from '@/app/infra/http/HttpClient';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Mail, Lock } from 'lucide-react';
|
||||
import { Mail, Lock, Loader2 } from 'lucide-react';
|
||||
import langbotIcon from '@/app/assets/langbot-logo.webp';
|
||||
import { toast } from 'sonner';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -38,6 +38,7 @@ const formSchema = (t: (key: string) => string) =>
|
||||
export default function Register() {
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const [spaceLoading, setSpaceLoading] = useState(false);
|
||||
|
||||
const form = useForm<z.infer<ReturnType<typeof formSchema>>>({
|
||||
resolver: zodResolver(formSchema(t)),
|
||||
@@ -78,6 +79,26 @@ export default function Register() {
|
||||
});
|
||||
}
|
||||
|
||||
// Space OAuth redirect handler
|
||||
const handleSpaceLoginClick = async () => {
|
||||
setSpaceLoading(true);
|
||||
|
||||
try {
|
||||
// Build the redirect URI to the OAuth callback page
|
||||
const currentOrigin = window.location.origin;
|
||||
const redirectUri = `${currentOrigin}/auth/space/callback`;
|
||||
|
||||
// Get the authorization URL from backend
|
||||
const response = await httpClient.getSpaceAuthorizeUrl(redirectUri);
|
||||
|
||||
// Redirect to Space authorization page
|
||||
window.location.href = response.authorize_url;
|
||||
} catch {
|
||||
toast.error(t('common.spaceLoginFailed'));
|
||||
setSpaceLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-neutral-900">
|
||||
<Card className="w-[375px] shadow-lg dark:shadow-white/10">
|
||||
@@ -100,7 +121,66 @@ export default function Register() {
|
||||
{t('register.adminAccountNote')}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<CardContent className="space-y-6">
|
||||
{/* Space Login - Recommended */}
|
||||
<div className="space-y-3">
|
||||
<Button
|
||||
type="button"
|
||||
className="w-full cursor-pointer"
|
||||
onClick={handleSpaceLoginClick}
|
||||
disabled={spaceLoading}
|
||||
>
|
||||
{spaceLoading ? (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<svg
|
||||
className="mr-2 h-4 w-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 2L2 7L12 12L22 7L12 2Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M2 17L12 22L22 17"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M2 12L12 17L22 12"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
{t('register.initWithSpace')}
|
||||
</Button>
|
||||
<p className="text-xs text-center text-muted-foreground">
|
||||
{t('register.spaceRecommended')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 flex items-center">
|
||||
<span className="w-full border-t" />
|
||||
</div>
|
||||
<div className="relative flex justify-center text-xs uppercase">
|
||||
<span className="bg-white dark:bg-card px-2 text-muted-foreground">
|
||||
{t('common.or')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Local Account Registration */}
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
||||
<FormField
|
||||
@@ -146,8 +226,12 @@ export default function Register() {
|
||||
)}
|
||||
/>
|
||||
|
||||
<Button type="submit" className="w-full mt-4 cursor-pointer">
|
||||
{t('register.register')}
|
||||
<Button
|
||||
type="submit"
|
||||
variant="outline"
|
||||
className="w-full cursor-pointer"
|
||||
>
|
||||
{t('register.registerLocal')}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
Reference in New Issue
Block a user