'use client'; import { useState, useEffect } from "react"; import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { SendIcon, Loader2, GlobeIcon, ChevronDownIcon, Ship, InfoIcon } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem } from "@/components/ui/dropdown-menu" import { useTranslation } from '@/i18n/client' import { useRouter, useParams, usePathname, useSearchParams } from 'next/navigation'; import { InputOTP, InputOTPGroup, InputOTPSlot, } from "@/components/ui/input-otp" import { signIn } from 'next-auth/react'; import { sendOtpAction } from "@/lib/users/send-otp"; import { verifyTokenAction } from "@/lib/users/verifyToken"; import { buttonVariants } from "@/components/ui/button" import Link from "next/link" import Image from 'next/image'; // 추가: Image 컴포넌트 import export function LoginForm({ className, ...props }: React.ComponentProps<"div">) { const params = useParams() || {}; const pathname = usePathname() || ''; const router = useRouter(); const searchParams = useSearchParams(); const token = searchParams?.get('token') || null; const [showCredentialsForm, setShowCredentialsForm] = useState(false); const lng = params.lng as string; const { t, i18n } = useTranslation(lng, 'login'); const { toast } = useToast(); const handleChangeLanguage = (lang: string) => { const segments = pathname.split('/'); segments[1] = lang; router.push(segments.join('/')); }; const currentLanguageText = i18n.language === 'ko' ? t('languages.korean') : t('languages.english'); const [email, setEmail] = useState(''); const [otpSent, setOtpSent] = useState(false); const [isLoading, setIsLoading] = useState(false); const [otp, setOtp] = useState(''); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const goToVendorRegistration = () => { router.push(`/${lng}/partners/repository`); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setIsLoading(true); try { const result = await sendOtpAction(email, lng); if (result.success) { setOtpSent(true); toast({ title: t('otpSentTitle'), description: t('otpSentMessage'), }); } else { // Handle specific error types let errorMessage = t('defaultErrorMessage'); // You can handle different error types differently if (result.error === 'userNotFound') { errorMessage = t('userNotFoundMessage'); } toast({ title: t('errorTitle'), description: result.message || errorMessage, variant: 'destructive', }); } } catch (error) { // This will catch network errors or other unexpected issues console.error(error); toast({ title: t('errorTitle'), description: t('networkErrorMessage'), variant: 'destructive', }); } finally { setIsLoading(false); } }; async function handleOtpSubmit(e: React.FormEvent) { e.preventDefault(); setIsLoading(true); try { // next-auth의 Credentials Provider로 로그인 시도 const result = await signIn('credentials', { email, code: otp, redirect: false, // 커스텀 처리 위해 redirect: false }); if (result?.ok) { // 토스트 메시지 표시 toast({ title: t('loginSuccess'), description: t('youAreLoggedIn'), }); router.push(`/${lng}/partners/dashboard`); } else { toast({ title: t('errorTitle'), description: t('defaultErrorMessage'), variant: 'destructive', }); } } catch (error) { console.error('Login error:', error); toast({ title: t('errorTitle'), description: t('defaultErrorMessage'), variant: 'destructive', }); } finally { setIsLoading(false); } } // 새로운 로그인 처리 함수 추가 const handleCredentialsLogin = async () => { if (!username || !password) { toast({ title: t('errorTitle'), description: t('credentialsRequired'), variant: 'destructive', }); return; } setIsLoading(true); try { // next-auth의 다른 credentials provider로 로그인 시도 const result = await signIn('credentials-password', { username, password, redirect: false, }); if (result?.ok) { toast({ title: t('loginSuccess'), description: t('youAreLoggedIn'), }); router.push(`/${lng}/partners/dashboard`); } else { toast({ title: t('errorTitle'), description: t('invalidCredentials'), variant: 'destructive', }); } } catch (error) { console.error('Login error:', error); toast({ title: t('errorTitle'), description: t('defaultErrorMessage'), variant: 'destructive', }); } finally { setIsLoading(false); } }; useEffect(() => { const verifyToken = async () => { if (!token) return; setIsLoading(true); try { const data = await verifyTokenAction(token); if (data.valid) { setOtpSent(true); setEmail(data.email ?? ''); } else { toast({ title: t('errorTitle'), description: t('invalidToken'), variant: 'destructive', }); } } catch (error) { toast({ title: t('errorTitle'), description: t('defaultErrorMessage'), variant: 'destructive', }); } finally { setIsLoading(false); } }; verifyToken(); }, [token, toast, t]); return (
{/* Left Content */}
{/* Top bar with Logo + eVCP (left) and "Request Vendor Repository" (right) */}
{/* logo */} eVCP
{'업체 등록 신청'}
{/* Content section that occupies remaining space, centered vertically */}
{/* Your form container */}
{/* Here's your existing login/OTP forms: */} {/* {!otpSent ? ( */} {/*
*/}

{t('loginMessage')}

{/* 설명 텍스트 추가 - 업체 등록 관련 안내 */}

{'등록된 업체만 로그인하실 수 있습니다. 아직 등록되지 않은 업체라면 상단의 업체 등록 신청 버튼을 이용해주세요.'}

{/* S-Gips 로그인 폼이 표시되지 않을 때만 이메일 입력 필드 표시 */} {!showCredentialsForm && ( <>
setEmail(e.target.value)} />
{/* 구분선과 "Or continue with" 섹션 추가 */}
{t('orContinueWith')}
{/* S-Gips 로그인 버튼 */} {/* 업체 등록 안내 링크 추가 */} )} {/* ID/비밀번호 로그인 폼 - 버튼 클릭 시에만 표시 */} {showCredentialsForm && ( <>
setUsername(e.target.value)} /> setPassword(e.target.value)} /> {/* 뒤로 가기 버튼 */}
)}
handleChangeLanguage(value)} > {t('languages.english')} {t('languages.korean')}
{/* ) : (

{t('loginMessage')}

setOtp(value)} >
handleChangeLanguage(value)} > {t('languages.english')} {t('languages.korean')}
)} */}
{t('termsMessage')} {t('termsOfService')} {t('and')} {t('privacyPolicy')}.
{/* Right BG 이미지 영역 - Image 컴포넌트로 수정 */}
{/* Image 컴포넌트로 대체 */}
Background image

“{t("blockquote")}”

{/* */}
) }