CoolFace
Apppublic

s6663296/pet-lost-found

sourceHugging Facemitupdated 9mo agoView on Hugging Face
0likes
test-connection.html339 linesDownload Raw Back to root
1<!DOCTYPE html>
2<html lang="zh-TW">
3
4<head>
5    <meta charset="UTF-8">
6    <meta name="viewport" content="width=device-width, initial-scale=1.0">
7    <title>Supabase 連接測試</title>
8    <style>
9        body {
10            font-family: Arial, sans-serif;
11            max-width: 800px;
12            margin: 50px auto;
13            padding: 20px;
14            background-color: #f5f5f5;
15        }
16
17        .card {
18            background: white;
19            border-radius: 10px;
20            padding: 30px;
21            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
22            margin-bottom: 20px;
23        }
24
25        h1 {
26            color: #2d756f;
27            text-align: center;
28        }
29
30        .status {
31            padding: 15px;
32            border-radius: 8px;
33            margin: 10px 0;
34            font-weight: bold;
35        }
36
37        .success {
38            background-color: #d4edda;
39            color: #155724;
40            border: 1px solid #c3e6cb;
41        }
42
43        .error {
44            background-color: #f8d7da;
45            color: #721c24;
46            border: 1px solid #f5c6cb;
47        }
48
49        .warning {
50            background-color: #fff3cd;
51            color: #856404;
52            border: 1px solid #ffeeba;
53        }
54
55        .info {
56            background-color: #d1ecf1;
57            color: #0c5460;
58            border: 1px solid #bee5eb;
59        }
60
61        button {
62            background-color: #2d756f;
63            color: white;
64            border: none;
65            padding: 12px 24px;
66            border-radius: 5px;
67            cursor: pointer;
68            font-size: 16px;
69            margin: 5px;
70        }
71
72        button:hover {
73            background-color: #25655c;
74        }
75
76        button:disabled {
77            background-color: #ccc;
78            cursor: not-allowed;
79        }
80
81        pre {
82            background: #f8f9fa;
83            padding: 15px;
84            border-radius: 5px;
85            overflow-x: auto;
86            font-size: 14px;
87        }
88
89        .test-item {
90            display: flex;
91            align-items: center;
92            padding: 10px 0;
93            border-bottom: 1px solid #eee;
94        }
95
96        .test-item:last-child {
97            border-bottom: none;
98        }
99
100        .test-name {
101            flex: 1;
102        }
103
104        .test-result {
105            padding: 5px 15px;
106            border-radius: 20px;
107            font-size: 14px;
108        }
109
110        .spinner {
111            display: inline-block;
112            width: 20px;
113            height: 20px;
114            border: 3px solid #f3f3f3;
115            border-top: 3px solid #2d756f;
116            border-radius: 50%;
117            animation: spin 1s linear infinite;
118        }
119
120        @keyframes spin {
121            0% {
122                transform: rotate(0deg);
123            }
124
125            100% {
126                transform: rotate(360deg);
127            }
128        }
129    </style>
130</head>
131
132<body>
133    <h1>🔌 Supabase 連接測試</h1>
134
135    <div class="card">
136        <h2>Step 1: 檢查配置</h2>
137        <div id="config-check">
138            <div class="status info">點擊下方按鈕開始測試</div>
139        </div>
140        <button onclick="runAllTests()">🚀 開始測試連接</button>
141    </div>
142
143    <div class="card">
144        <h2>Step 2: 測試結果</h2>
145        <div id="test-results">
146            <div class="test-item">
147                <span class="test-name">1. Supabase SDK 載入</span>
148                <span id="test-sdk" class="test-result">待測試</span>
149            </div>
150            <div class="test-item">
151                <span class="test-name">2. 配置檔案載入</span>
152                <span id="test-config" class="test-result">待測試</span>
153            </div>
154            <div class="test-item">
155                <span class="test-name">3. 資料庫連接</span>
156                <span id="test-connection" class="test-result">待測試</span>
157            </div>
158            <div class="test-item">
159                <span class="test-name">4. 資料表存在</span>
160                <span id="test-tables" class="test-result">待測試</span>
161            </div>
162            <div class="test-item">
163                <span class="test-name">5. Storage 連接</span>
164                <span id="test-storage" class="test-result">待測試</span>
165            </div>
166        </div>
167    </div>
168
169    <div class="card">
170        <h2>Step 3: 詳細資訊</h2>
171        <pre id="details">測試後將顯示詳細資訊...</pre>
172    </div>
173
174    <div class="card">
175        <h2>快速修復</h2>
176        <p>如果連接失敗,請檢查:</p>
177        <ol>
178            <li>打開 <code>supabase-config.js</code></li>
179            <li>確認 <code>SUPABASE_URL</code> 是否正確(格式:https://xxxxx.supabase.co)</li>
180            <li>確認 <code>SUPABASE_ANON_KEY</code> 是否正確</li>
181            <li>確認已在 Supabase Dashboard 執行了 SQL 建表</li>
182        </ol>
183    </div>
184
185    <!-- Supabase SDK -->
186    <script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
187    <script src="supabase-config.js"></script>
188
189    <script>
190        const details = [];
191
192        function setTestResult(elementId, success, message) {
193            const el = document.getElementById(elementId);
194            if (success === 'loading') {
195                el.innerHTML = '<span class="spinner"></span>';
196                el.style.background = '#f8f9fa';
197            } else if (success) {
198                el.textContent = '✅ 通過';
199                el.style.background = '#d4edda';
200                el.style.color = '#155724';
201            } else {
202                el.textContent = '❌ 失敗';
203                el.style.background = '#f8d7da';
204                el.style.color = '#721c24';
205            }
206            if (message) {
207                details.push(message);
208                document.getElementById('details').textContent = details.join('\n\n');
209            }
210        }
211
212        async function runAllTests() {
213            details.length = 0;
214            document.getElementById('config-check').innerHTML = '<div class="status info">測試中...</div>';
215
216            // Test 1: SDK 載入
217            setTestResult('test-sdk', 'loading');
218            setTestResult('test-config', 'loading');
219            setTestResult('test-connection', 'loading');
220            setTestResult('test-tables', 'loading');
221            setTestResult('test-storage', 'loading');
222
223            await new Promise(r => setTimeout(r, 500));
224
225            // Test 1: Check SDK
226            if (typeof window.supabase !== 'undefined') {
227                setTestResult('test-sdk', true, '✅ Test 1: Supabase SDK 已成功載入');
228            } else {
229                setTestResult('test-sdk', false, '❌ Test 1: Supabase SDK 未載入\n   → 檢查網路連接');
230                document.getElementById('config-check').innerHTML = '<div class="status error">SDK 載入失敗</div>';
231                return;
232            }
233
234            // Test 2: Check Config
235            await new Promise(r => setTimeout(r, 300));
236            try {
237                // 直接檢查 supabase 客戶端是否已初始化
238                if (typeof supabase !== 'undefined' && supabase.auth) {
239                    setTestResult('test-config', true,
240                        '✅ Test 2: 配置檔案已載入\n' +
241                        '   Supabase 客戶端已初始化');
242                } else {
243                    setTestResult('test-config', false,
244                        '❌ Test 2: Supabase 客戶端未初始化\n' +
245                        '   → 請檢查 supabase-config.js 是否正確');
246                    return;
247                }
248            } catch (e) {
249                setTestResult('test-config', false, '❌ Test 2: supabase-config.js 載入錯誤: ' + e.message);
250                return;
251            }
252
253            // Test 3: Database Connection
254            await new Promise(r => setTimeout(r, 300));
255            try {
256                const { data, error } = await supabase.from('users').select('count', { count: 'exact', head: true });
257                if (error) throw error;
258                setTestResult('test-connection', true, '✅ Test 3: 資料庫連接成功');
259            } catch (err) {
260                if (err.message.includes('relation') || err.message.includes('does not exist')) {
261                    setTestResult('test-connection', true, '✅ Test 3: 資料庫連接成功(但資料表未建立)');
262                    setTestResult('test-tables', false,
263                        '❌ Test 4: 資料表不存在\n' +
264                        '   → 請到 Supabase Dashboard → SQL Editor\n' +
265                        '   → 執行 supabase-setup.sql 的內容');
266                    setTestResult('test-storage', 'loading');
267                } else {
268                    setTestResult('test-connection', false,
269                        '❌ Test 3: 資料庫連接失敗\n' +
270                        '   錯誤: ' + err.message);
271                    setTestResult('test-tables', false);
272                    setTestResult('test-storage', false);
273                    document.getElementById('config-check').innerHTML = '<div class="status error">連接失敗</div>';
274                    return;
275                }
276            }
277
278            // Test 4: Tables Exist
279            await new Promise(r => setTimeout(r, 300));
280            try {
281                const tables = ['users', 'cases', 'case_photos', 'reports', 'admins'];
282                let allExist = true;
283                let existingTables = [];
284                let missingTables = [];
285
286                for (const table of tables) {
287                    const { error } = await supabase.from(table).select('count', { count: 'exact', head: true });
288                    if (error && (error.message.includes('relation') || error.message.includes('does not exist'))) {
289                        allExist = false;
290                        missingTables.push(table);
291                    } else {
292                        existingTables.push(table);
293                    }
294                }
295
296                if (allExist) {
297                    setTestResult('test-tables', true, '✅ Test 4: 所有資料表已存在\n   Tables: ' + tables.join(', '));
298                } else {
299                    setTestResult('test-tables', false,
300                        '⚠️ Test 4: 部分資料表缺失\n' +
301                        '   已存在: ' + (existingTables.length ? existingTables.join(', ') : '無') + '\n' +
302                        '   缺少: ' + missingTables.join(', ') + '\n' +
303                        '   → 請執行 supabase-setup.sql');
304                }
305            } catch (err) {
306                setTestResult('test-tables', false, '❌ Test 4: 無法檢查資料表');
307            }
308
309            // Test 5: Storage
310            await new Promise(r => setTimeout(r, 300));
311            try {
312                const { data, error } = await supabase.storage.listBuckets();
313                if (error) throw error;
314
315                const petPhotosBucket = data.find(b => b.name === 'pet-photos');
316                if (petPhotosBucket) {
317                    setTestResult('test-storage', true, '✅ Test 5: Storage bucket "pet-photos" 已存在');
318                } else {
319                    setTestResult('test-storage', false,
320                        '⚠️ Test 5: Storage bucket "pet-photos" 不存在\n' +
321                        '   → 現有 buckets: ' + (data.map(b => b.name).join(', ') || '無') + '\n' +
322                        '   → 請到 Storage 建立名為 pet-photos 的 bucket');
323                }
324            } catch (err) {
325                setTestResult('test-storage', false, '❌ Test 5: Storage 連接失敗\n   ' + err.message);
326            }
327
328            // Final Status
329            const allPassed = !document.getElementById('details').textContent.includes('❌');
330            if (allPassed) {
331                document.getElementById('config-check').innerHTML = '<div class="status success">🎉 所有測試通過!Supabase 已成功連接!</div>';
332            } else {
333                document.getElementById('config-check').innerHTML = '<div class="status warning">⚠️ 部分測試未通過,請查看詳細資訊</div>';
334            }
335        }
336    </script>
337</body>
338
339</html>