Improve Supabase connection testing
Enhance the Supabase connection test to provide more detailed error information and handle potential CORS issues.
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { RefreshCw, Info } from "lucide-react";
|
||||
import { RefreshCw, Info, HelpCircle, AlertCircle } from "lucide-react";
|
||||
import { toast } from "@/hooks/useToast.wrapper";
|
||||
import { testSupabaseConnection } from '@/lib/supabase';
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
||||
import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert";
|
||||
|
||||
interface TestResult {
|
||||
url: string;
|
||||
proxyUrl: string;
|
||||
usingProxy: boolean;
|
||||
proxyType?: string;
|
||||
client: boolean;
|
||||
restApi: boolean;
|
||||
auth: boolean;
|
||||
@@ -53,6 +55,13 @@ const SupabaseConnectionTest: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const hasProxyRecommendation = (errors: string[]) => {
|
||||
return errors.some(err =>
|
||||
err.includes('프록시 사용 시 정상 작동합니다') ||
|
||||
err.includes('프록시를 선택해보세요')
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold mb-4">연결 테스트</h2>
|
||||
@@ -99,18 +108,49 @@ const SupabaseConnectionTest: React.FC = () => {
|
||||
|
||||
{testResults.usingProxy && (
|
||||
<div className="bg-blue-50 border border-blue-200 rounded p-2 mt-2">
|
||||
<p className="text-xs">CORS 프록시 사용 중: {testResults.proxyUrl}</p>
|
||||
<p className="text-xs">CORS 프록시 사용 중: {testResults.proxyType || 'corsproxy.io'}</p>
|
||||
<p className="text-xs break-all mt-1">{testResults.proxyUrl}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{testResults.errors.length > 0 && hasProxyRecommendation(testResults.errors) && (
|
||||
<Alert className="bg-amber-50 border-amber-200 mt-3">
|
||||
<AlertCircle className="h-4 w-4 text-amber-600" />
|
||||
<AlertTitle className="text-amber-800 text-xs font-medium">프록시 변경 권장</AlertTitle>
|
||||
<AlertDescription className="text-amber-700 text-xs">
|
||||
{testResults.errors.find(err =>
|
||||
err.includes('프록시 사용 시 정상 작동합니다') ||
|
||||
err.includes('프록시를 선택해보세요')
|
||||
)}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{testResults.errors.length > 0 && (
|
||||
<div className="bg-red-50 border border-red-200 rounded p-2 mt-2">
|
||||
{testResults.errors.map((error: string, index: number) => (
|
||||
<p key={index} className="text-xs text-red-600">{error}</p>
|
||||
<p key={index} className="text-xs text-red-600 mb-1">{error}</p>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 오류 해결 팁 */}
|
||||
{!testResults.restApi && testResults.auth && (
|
||||
<div className="bg-yellow-50 border border-yellow-200 rounded p-2 mt-2">
|
||||
<div className="flex items-start gap-1">
|
||||
<HelpCircle className="h-4 w-4 text-yellow-600 mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-xs text-yellow-800 font-medium">인증은 성공했지만 API/DB 연결에 실패했습니다</p>
|
||||
<ul className="list-disc text-xs text-yellow-700 pl-4 mt-1">
|
||||
<li>다른 CORS 프록시 옵션을 시도해보세요</li>
|
||||
<li>Supabase 서버의 CORS 설정을 확인하세요</li>
|
||||
<li>브라우저 개발자 도구에서 네트워크 탭을 확인하세요</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 디버그 정보 섹션 추가 */}
|
||||
{testResults.debugInfo && (
|
||||
<Collapsible
|
||||
@@ -139,6 +179,18 @@ const SupabaseConnectionTest: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{testResults.usingProxy && (
|
||||
<div>
|
||||
<span className="font-medium">프록시 URL:</span>
|
||||
<div className="mt-1 bg-gray-100 p-1 rounded break-all">
|
||||
{testResults.proxyUrl}
|
||||
</div>
|
||||
<div className="mt-1">
|
||||
프록시 유형: {testResults.proxyType || 'corsproxy.io'}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<span className="font-medium">클라이언트 초기화:</span>
|
||||
<div className="mt-1 text-green-600">
|
||||
@@ -146,6 +198,15 @@ const SupabaseConnectionTest: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{testResults.debugInfo.lastErrorDetails && (
|
||||
<div>
|
||||
<span className="font-medium">마지막 오류 상세:</span>
|
||||
<div className="mt-1 bg-red-50 p-1 rounded break-all text-red-600">
|
||||
{testResults.debugInfo.lastErrorDetails}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<span className="font-medium">브라우저 정보:</span>
|
||||
<div className="mt-1 bg-gray-100 p-1 rounded break-all">
|
||||
|
||||
@@ -5,8 +5,13 @@ import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { DatabaseIcon, Save, RefreshCw, Shield, AlertTriangle, Check } from "lucide-react";
|
||||
import { toast } from "@/hooks/useToast.wrapper";
|
||||
import { configureSupabase, isCorsProxyEnabled } from "@/lib/supabase/config";
|
||||
import {
|
||||
configureSupabase,
|
||||
isCorsProxyEnabled,
|
||||
getProxyType
|
||||
} from "@/lib/supabase/config";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
|
||||
interface SupabaseSettingsFormProps {
|
||||
onSaved: () => void;
|
||||
@@ -16,6 +21,7 @@ const SupabaseSettingsForm: React.FC<SupabaseSettingsFormProps> = ({ onSaved })
|
||||
const [supabaseUrl, setSupabaseUrl] = useState('');
|
||||
const [supabaseKey, setSupabaseKey] = useState('');
|
||||
const [useProxy, setUseProxy] = useState(false);
|
||||
const [proxyType, setProxyType] = useState('corsproxy.io');
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
|
||||
// 저장된 설정 불러오기
|
||||
@@ -23,10 +29,12 @@ const SupabaseSettingsForm: React.FC<SupabaseSettingsFormProps> = ({ onSaved })
|
||||
const savedUrl = localStorage.getItem('supabase_url');
|
||||
const savedKey = localStorage.getItem('supabase_key');
|
||||
const proxyEnabled = isCorsProxyEnabled();
|
||||
const savedProxyType = getProxyType();
|
||||
|
||||
if (savedUrl) setSupabaseUrl(savedUrl);
|
||||
if (savedKey) setSupabaseKey(savedKey);
|
||||
setUseProxy(proxyEnabled);
|
||||
setProxyType(savedProxyType);
|
||||
}, []);
|
||||
|
||||
const validateUrl = (url: string): boolean => {
|
||||
@@ -57,7 +65,7 @@ const SupabaseSettingsForm: React.FC<SupabaseSettingsFormProps> = ({ onSaved })
|
||||
|
||||
try {
|
||||
// Supabase 설정 적용
|
||||
configureSupabase(supabaseUrl, supabaseKey, useProxy);
|
||||
configureSupabase(supabaseUrl, supabaseKey, useProxy, proxyType);
|
||||
|
||||
toast({
|
||||
title: "설정 저장 완료",
|
||||
@@ -153,6 +161,27 @@ const SupabaseSettingsForm: React.FC<SupabaseSettingsFormProps> = ({ onSaved })
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 프록시 서비스 선택 옵션 추가 */}
|
||||
{useProxy && (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="proxy-type" className="text-base">프록시 서비스 선택</Label>
|
||||
<Select value={proxyType} onValueChange={setProxyType}>
|
||||
<SelectTrigger id="proxy-type" className="w-full">
|
||||
<SelectValue placeholder="프록시 서비스 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="corsproxy.io">corsproxy.io (기본)</SelectItem>
|
||||
<SelectItem value="thingproxy">thingproxy.freeboard.io</SelectItem>
|
||||
<SelectItem value="allorigins">allorigins.win</SelectItem>
|
||||
<SelectItem value="cors-anywhere">cors-anywhere.herokuapp.com</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
특정 프록시 서비스가 작동하지 않으면 다른 서비스를 시도해보세요.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button
|
||||
onClick={handleSave}
|
||||
disabled={isSaving}
|
||||
|
||||
Reference in New Issue
Block a user