- frontend/ 폴더로 프론트엔드 전체 이관 - signal-batch API 연동 (한국 선박 위치 데이터) - Tailwind CSS 4 + CSS 변수 테마 토큰 (dark/light) - i18next 다국어 (ko/en) 인프라 + 28개 컴포넌트 적용 - 레이어 패널 트리 구조 재설계 (카테고리별 온/오프, 범례) - Google OAuth 로그인 화면 + DEV LOGIN 우회 - 외부 API CORS 프록시 전환 (Airplanes.live, OpenSky, CelesTrak) - ShipLayer 이미지 탭 전환 (signal-batch / MarineTraffic) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
42 lines
884 B
TypeScript
42 lines
884 B
TypeScript
const AUTH_BASE = '/api/kcg/auth';
|
|
|
|
export interface AuthUser {
|
|
email: string;
|
|
name: string;
|
|
picture?: string;
|
|
}
|
|
|
|
export async function googleLogin(credential: string): Promise<AuthUser> {
|
|
const res = await fetch(`${AUTH_BASE}/google`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ credential }),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const body = await res.json().catch(() => ({}));
|
|
throw new Error(body.message ?? 'Login failed');
|
|
}
|
|
|
|
return res.json();
|
|
}
|
|
|
|
export async function getMe(): Promise<AuthUser> {
|
|
const res = await fetch(`${AUTH_BASE}/me`, {
|
|
credentials: 'include',
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error('Not authenticated');
|
|
}
|
|
|
|
return res.json();
|
|
}
|
|
|
|
export async function logout(): Promise<void> {
|
|
await fetch(`${AUTH_BASE}/logout`, {
|
|
method: 'POST',
|
|
credentials: 'include',
|
|
});
|
|
}
|