import {useEffect, useRef, useState} from 'react'; import {GOOGLE_CLIENT_ID, isGoogleLoginEnabled, loadGoogleIdentity} from '@/lib/googleIdentity'; /** * 구글이 그려 주는 버튼을 그대로 쓴다. * * ★ 우리가 직접 만든 버튼을 쓰지 않는 이유: 구글 브랜드 가이드가 로고·문구·비율을 정해 두고, * 그걸 어긋나게 그리면 심사에서 걸린다. renderButton 이 그 규격을 지켜 준다. * ★ 스크립트가 안 오면(광고 차단기·사내망) 빈 칸이 남는다 — 안내 문구로 바꿔 준다. * "눌러도 아무 일이 없는 자리"가 화면에 남는 게 제일 나쁘다. */ export function GoogleSignInButton({ onCredential, text = 'signin_with', }: { onCredential: (credential: string) => void; text?: 'continue_with' | 'signin_with' | 'signup_with'; }) { const holder = useRef(null); const [failed, setFailed] = useState(false); // 콜백은 ref 로 들고 간다 — GIS 는 initialize 시점의 함수를 붙잡고 있어서, // 의존성에 넣으면 렌더마다 버튼을 다시 그리게 된다. const handler = useRef(onCredential); handler.current = onCredential; useEffect(() => { if (!isGoogleLoginEnabled()) return; let alive = true; loadGoogleIdentity() .then((api) => { if (!alive || !holder.current) return; api.initialize({ client_id: GOOGLE_CLIENT_ID, callback: (res) => { if (res.credential) handler.current(res.credential); }, // 화면을 열자마자 마지막 계정으로 자동 로그인되는 동작은 끈다 — // 계정이 여러 개인 사람이 원하지 않은 계정으로 들어간다. auto_select: false, }); api.renderButton(holder.current, { type: 'standard', theme: 'outline', size: 'large', shape: 'rectangular', text, // ★ 'ko' 로는 영문('Continue with Google')이 그대로 나왔다. 지역까지 줘야 한국어다. // 문구는 우리가 못 정한다 — 구글 브랜드 가이드라 GIS 가 주는 번역을 그대로 쓴다. locale: 'ko_KR', logo_alignment: 'center', // GIS 는 숫자 px 만 받는다(최대 400). 컨테이너 폭이 잡히기 전이면 최소값으로 그린다. width: holder.current.offsetWidth || 320, }); }) .catch(() => { if (alive) setFailed(true); }); return () => { alive = false; }; }, [text]); if (!isGoogleLoginEnabled()) return null; if (failed) { return (

구글 로그인을 불러오지 못했습니다. 아이디/비밀번호로 로그인해 주세요.

); } // 높이를 미리 잡아 둔다 — 버튼이 뒤늦게 그려지면서 아래 내용이 밀리지 않게. return
; }