refactor: saasMode 분기 제거 — 항상 SaaS(OAuth only)로 동작
Mac/Windows 환경 불일치 해소. BUILD_TIME 상수, CONFIGURE 채널, 개발자 모드 UI 전부 제거. Supabase 설정은 supabase-config.ts SSOT.
This commit is contained in:
parent
feb82abbf7
commit
541f04d02b
12 changed files with 566 additions and 9587 deletions
|
|
@ -3,7 +3,7 @@
|
|||
// 로그인 상태 / Sync Now 버튼 / 마지막 동기화 / 환경변수 설정
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Box, Button, Stack, TextField, Alert, CircularProgress } from '@mui/material'
|
||||
import { Box, Button, Stack, Alert, CircularProgress } from '@mui/material'
|
||||
import CloudIcon from '@mui/icons-material/Cloud'
|
||||
import CloudDoneIcon from '@mui/icons-material/CloudDone'
|
||||
import GoogleIcon from '@mui/icons-material/Google'
|
||||
|
|
@ -16,7 +16,6 @@ interface CloudSyncState {
|
|||
userEmail: string | null
|
||||
lastSyncAt: number | null
|
||||
syncing: boolean
|
||||
saasMode: boolean
|
||||
}
|
||||
|
||||
interface SyncProgress {
|
||||
|
|
@ -31,11 +30,8 @@ export function CloudSyncSection(): React.ReactElement {
|
|||
authenticated: false,
|
||||
userEmail: null,
|
||||
lastSyncAt: null,
|
||||
syncing: false,
|
||||
saasMode: false
|
||||
syncing: false
|
||||
})
|
||||
const [supabaseUrl, setSupabaseUrl] = useState('')
|
||||
const [anonKey, setAnonKey] = useState('')
|
||||
const [progress, setProgress] = useState<SyncProgress | null>(null)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [info, setInfo] = useState<string | null>(null)
|
||||
|
|
@ -46,13 +42,6 @@ export function CloudSyncSection(): React.ReactElement {
|
|||
void window.electronAPI.cloudSync.getState().then((r) => {
|
||||
if (r.success) setState(r.data)
|
||||
})
|
||||
// 저장된 supabase 설정 로드
|
||||
void window.electronAPI.config.get({ key: 'supabaseUrl' as never }).then((r) => {
|
||||
if (r.success && typeof r.data === 'string') setSupabaseUrl(r.data)
|
||||
})
|
||||
void window.electronAPI.config.get({ key: 'supabaseAnonKey' as never }).then((r) => {
|
||||
if (r.success && typeof r.data === 'string') setAnonKey(r.data)
|
||||
})
|
||||
|
||||
const unsubAuth = window.electronAPI.cloudSync.onAuthChanged((payload) => {
|
||||
setState((prev) => ({
|
||||
|
|
@ -84,21 +73,6 @@ export function CloudSyncSection(): React.ReactElement {
|
|||
}
|
||||
}, [])
|
||||
|
||||
async function handleConfigure(): Promise<void> {
|
||||
setError(null)
|
||||
setBusy(true)
|
||||
try {
|
||||
const r = await window.electronAPI.cloudSync.configure({ url: supabaseUrl, anonKey })
|
||||
if (!r.success) {
|
||||
setError(r.error.message)
|
||||
} else {
|
||||
setInfo('Supabase 연결 설정 저장됨')
|
||||
}
|
||||
} finally {
|
||||
setBusy(false)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSignIn(provider: 'google' | 'github'): Promise<void> {
|
||||
setError(null)
|
||||
setBusy(true)
|
||||
|
|
@ -161,8 +135,7 @@ export function CloudSyncSection(): React.ReactElement {
|
|||
<Box sx={{ ...typoSx('heading'), color: d3roPalette.text.primary }}>Cloud Sync</Box>
|
||||
</Stack>
|
||||
|
||||
{!state.authenticated && state.saasMode && (
|
||||
// SaaS 빌드 타임 모드: URL/Key는 빌드에 박혀있으므로 OAuth 버튼만 노출.
|
||||
{!state.authenticated && (
|
||||
<Stack spacing={2}>
|
||||
<Box sx={{ ...typoSx('label'), color: d3roPalette.text.label, mb: 1 }}>OAuth 로그인</Box>
|
||||
<Stack direction="row" spacing={1}>
|
||||
|
|
@ -186,57 +159,6 @@ export function CloudSyncSection(): React.ReactElement {
|
|||
</Stack>
|
||||
)}
|
||||
|
||||
{!state.authenticated && !state.saasMode && (
|
||||
// Legacy 개발자 모드: 빌드 타임 env 미설정 → 사용자가 직접 입력 가능.
|
||||
<Stack spacing={2}>
|
||||
<Box sx={{ ...typoSx('label'), color: d3roPalette.text.label }}>
|
||||
SUPABASE 설정 (개발자 모드)
|
||||
</Box>
|
||||
<TextField
|
||||
label="Supabase URL"
|
||||
size="small"
|
||||
value={supabaseUrl}
|
||||
onChange={(e) => setSupabaseUrl(e.target.value)}
|
||||
placeholder="https://your-project.supabase.co"
|
||||
fullWidth
|
||||
/>
|
||||
<TextField
|
||||
label="Anon Key"
|
||||
size="small"
|
||||
value={anonKey}
|
||||
onChange={(e) => setAnonKey(e.target.value)}
|
||||
placeholder="eyJ..."
|
||||
type="password"
|
||||
fullWidth
|
||||
/>
|
||||
<Button variant="outlined" onClick={() => void handleConfigure()} disabled={busy}>
|
||||
저장
|
||||
</Button>
|
||||
|
||||
<Box sx={{ borderTop: `1px solid ${d3roPalette.border.subtle}`, pt: 2 }}>
|
||||
<Box sx={{ ...typoSx('label'), color: d3roPalette.text.label, mb: 1 }}>OAuth 로그인</Box>
|
||||
<Stack direction="row" spacing={1}>
|
||||
<Button
|
||||
variant="contained"
|
||||
startIcon={<GoogleIcon />}
|
||||
onClick={() => void handleSignIn('google')}
|
||||
disabled={busy || !supabaseUrl || !anonKey}
|
||||
>
|
||||
Google
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<GitHubIcon />}
|
||||
onClick={() => void handleSignIn('github')}
|
||||
disabled={busy || !supabaseUrl || !anonKey}
|
||||
>
|
||||
GitHub
|
||||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
{state.authenticated && (
|
||||
<Stack spacing={2}>
|
||||
<Box sx={{ color: d3roPalette.text.primary, fontSize: 13 }}>
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ export function OnboardingModal({ open, onClose }: OnboardingModalProps): React.
|
|||
const [selectedDevice, setSelectedDevice] = useState('default')
|
||||
const [hotkeyBinding, setHotkeyBinding] = useState<HotkeyBinding | null>(null)
|
||||
const [hotkeyModalOpen, setHotkeyModalOpen] = useState(false)
|
||||
const [saasMode, setSaasMode] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return
|
||||
setStep(0)
|
||||
|
|
@ -47,10 +45,6 @@ export function OnboardingModal({ open, onClose }: OnboardingModalProps): React.
|
|||
window.electronAPI.hotkey.getDictationShortcut().then((r) => {
|
||||
if (r.success && r.data) setHotkeyBinding(r.data)
|
||||
})
|
||||
// Cloud Sync step은 빌드 타임 Supabase env가 있을 때만 의미가 있음
|
||||
window.electronAPI.cloudSync.getState().then((r) => {
|
||||
if (r.success) setSaasMode(r.data.saasMode)
|
||||
})
|
||||
}, [open])
|
||||
|
||||
const handleFinish = (): void => {
|
||||
|
|
@ -59,9 +53,9 @@ export function OnboardingModal({ open, onClose }: OnboardingModalProps): React.
|
|||
onClose()
|
||||
}
|
||||
|
||||
// Ollama step(3) 다음 — saasMode면 Cloud Sync step(4), 아니면 바로 완료(5)로
|
||||
// Ollama step(3) 다음 → Cloud Sync step(4)로
|
||||
const nextAfterOllama = (): void => {
|
||||
setStep(saasMode ? 4 : 5)
|
||||
setStep(4)
|
||||
}
|
||||
|
||||
// Cloud Sync step에서 Back 누르면 Ollama(3)로 복귀
|
||||
|
|
@ -256,7 +250,7 @@ export function OnboardingModal({ open, onClose }: OnboardingModalProps): React.
|
|||
</Box>
|
||||
)}
|
||||
|
||||
{/* Step 4: Cloud Sync (선택, saasMode에서만 노출) */}
|
||||
{/* Step 4: Cloud Sync (선택) */}
|
||||
{step === 4 && (
|
||||
<Box>
|
||||
<Stack direction="row" alignItems="center" gap={1} mb={3}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue