+ 구글 로그인을 불러오지 못했습니다. 아이디/비밀번호로 로그인해 주세요. +
+ ); + } + + // 높이를 미리 잡아 둔다 — 버튼이 뒤늦게 그려지면서 아래 내용이 밀리지 않게. + return ; +} diff --git a/solution/frontend/src/lib/autoSession.ts b/solution/frontend/src/lib/autoSession.ts index ca1e12d..93d8a27 100644 --- a/solution/frontend/src/lib/autoSession.ts +++ b/solution/frontend/src/lib/autoSession.ts @@ -1,6 +1,5 @@ -import {getAccessToken, login, me} from '@/api'; -import {UserRole} from '@/api'; -import {toAuthUser, useAuthStore} from '@/stores/auth'; +import {getAccessToken, login} from '@/api'; +import {establishSession} from '@/lib/session'; /** * 계정이 주입돼 있으면 화면을 열 때 조용히 세션을 확보한다. @@ -28,15 +27,7 @@ export function ensureAutoSession(): Promise- 사업장·정보 확인·발행을 관리합니다. + {selfServe + ? '내 가게 사이트를 만들고 발행합니다.' + : '사업장·정보 확인·발행을 관리합니다.'}
- 빌더는 로그인 없이도 사용할 수 있습니다.{' '} - - 빌더로 이동 - -
+ {selfServe && isGoogleLoginEnabled() && ( + <> ++ 아직 계정이 없으신가요?{' '} + + 회원가입 + +
+ )} ); diff --git a/solution/frontend/src/pages/SignupPage.tsx b/solution/frontend/src/pages/SignupPage.tsx new file mode 100644 index 0000000..4d2691b --- /dev/null +++ b/solution/frontend/src/pages/SignupPage.tsx @@ -0,0 +1,218 @@ +import {useState, type FormEvent} from 'react'; +import {Link, Navigate, useNavigate} from 'react-router'; +import {UserPlus} from 'lucide-react'; +import {googleLogin, signup} from '@/api'; +import {GoogleSignInButton} from '@/components/auth/GoogleSignInButton'; +import {Button} from '@/components/ui/button'; +import {Input} from '@/components/ui/input'; +import {isGoogleLoginEnabled} from '@/lib/googleIdentity'; +import {notify, notifyApiError} from '@/lib/notify'; +import {establishSession} from '@/lib/session'; +import {useAuthStore} from '@/stores/auth'; + +/** + * 회원가입. 가입 = **새 회사(테넌트) 1개 + 그 회사의 첫 계정 1개** 다(백엔드 auth_service.signup). + * + * ★ 여기 검사는 서버 규칙(services/auth_service.py 의 _LOGIN_ID_RE·_MIN_PASSWORD_LEN)의 사본이다. + * 두 벌이라 어긋날 수 있지만, 서버가 마지막 방어선이고 여기는 "제출 전에 알려주는" 역할이다. + * 규칙을 바꾸면 두 곳을 같이 고친다. + */ +const ID_RE = /^[a-zA-Z][a-zA-Z0-9._-]{3,19}$/; +const EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/; +const MIN_PASSWORD_LEN = 8; + +export function SignupPage() { + const navigate = useNavigate(); + const user = useAuthStore((s) => s.user); + + const [form, setForm] = useState({ + id: '', + password: '', + passwordConfirm: '', + name: '', + email: '', + companyName: '', + }); + const [isSubmitting, setIsSubmitting] = useState(false); + + if (user) return