- V3 모바일 마스터 플랜 작성 (docs/v3/00-mobile-master-plan.md) 11개 Phase, 5주 로드맵, 전략 결정사항 확정 - 7개 디자인 HTML 레퍼런스 저장 (docs/v3/designs/) - app.json → app.config.ts 전환 + 환경변수 체계 - 5탭 네비게이션 (DASH/HIST/REC FAB/TALK/SET) - metro.config.js monorepo 격리 (root RN 0.84 충돌 해결) - ui-native 테마 디자인 목업 색상 동기화 - SafeArea 적용 (useSafeAreaInsets) - DEV 로그인 우회 (__DEV__ 전용) - Supabase .env 연동 - iOS 시뮬레이터 검증 완료
79 lines
2 KiB
TypeScript
79 lines
2 KiB
TypeScript
// apps/mobile/lib/auth-context.tsx
|
|
// Supabase 세션 Context + 로그인 시 Expo Push 토큰 자동 등록
|
|
|
|
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'
|
|
import type { Session, User } from '@supabase/supabase-js'
|
|
import { supabase } from './supabase'
|
|
import { registerPushToken } from './push'
|
|
|
|
interface AuthContextValue {
|
|
session: Session | null
|
|
user: User | null
|
|
loading: boolean
|
|
devBypass: () => void
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextValue>({
|
|
session: null,
|
|
user: null,
|
|
loading: true,
|
|
devBypass: () => {}
|
|
})
|
|
|
|
// DEV 전용 — 가짜 유저로 로그인 우회
|
|
const DEV_USER: User = {
|
|
id: 'dev-user-00000',
|
|
email: 'dev@d3ro.local',
|
|
app_metadata: {},
|
|
user_metadata: {},
|
|
aud: 'authenticated',
|
|
created_at: new Date().toISOString()
|
|
} as User
|
|
|
|
export function AuthProvider({ children }: { children: ReactNode }): React.ReactElement {
|
|
const [session, setSession] = useState<Session | null>(null)
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
supabase.auth
|
|
.getSession()
|
|
.then(({ data }) => {
|
|
setSession(data.session)
|
|
if (data.session?.user.id) {
|
|
void registerPushToken(data.session.user.id)
|
|
}
|
|
})
|
|
.finally(() => setLoading(false))
|
|
|
|
const {
|
|
data: { subscription }
|
|
} = supabase.auth.onAuthStateChange((_event, newSession) => {
|
|
setSession(newSession)
|
|
if (newSession?.user.id) {
|
|
void registerPushToken(newSession.user.id)
|
|
}
|
|
})
|
|
|
|
return () => {
|
|
subscription.unsubscribe()
|
|
}
|
|
}, [])
|
|
|
|
const [devMode, setDevMode] = useState(false)
|
|
|
|
function devBypass(): void {
|
|
setDevMode(true)
|
|
}
|
|
|
|
const effectiveUser = devMode ? DEV_USER : (session?.user ?? null)
|
|
|
|
return (
|
|
<AuthContext.Provider value={{ session, user: effectiveUser, loading, devBypass }}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function useAuth(): AuthContextValue {
|
|
return useContext(AuthContext)
|
|
}
|