d ZZT台 — 數位經濟、金融科技與飲食文化深度紀實
💻📱 最佳瀏覽提示:本站支援 Chrome、Safari、Edge、Firefox 主流瀏覽器,並自動適應手機、平板與桌機最佳排版顯示。
Z
ZZT台
金融科技 × 數位治理 × 飲食文化考察

以結構化視角,記錄科技演進與生活風味的深度軌跡

歡迎來到 ZZT台。這裡彙整了跨國金融科技觀察、AI 治理架構解析、以及橫跨台灣與日本的拉麵文化田野筆記。透過註冊會員或訂閱電子報,與我們一起探索表象背後的系統脈絡。

瀏覽最新文章

洞見與專欄文章

依分類探索公開觀點、會員專屬筆記與深度研究報告

加入 ZZT台 讀者社群

依照您的閱讀需求選擇適合的會員方案,隨時掌握最新深度分析

訂閱 ZZT台 電子報

每當新專欄發布時,直接由 newsletter@pttzzt.com 寄送精華觀點至您的信箱。

) const SUPABASE_URL = "https://pelmolegwzrpvtwhdiqf.supabase.co"; // 替換為你的 Supabase URL const SUPABASE_ANON_KEY = "sb_publishable_B69LUrfFNJgMNfqL13gXpA_9T72BloT"; // 替換為你的 Supabase Anon Key const supabaseClient = window.supabase ? window.supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY) : null; async function handleMemberRegister(e) { e.preventDefault(); const email = sanitizeInput(document.getElementById('reg-email').value); const pwd = document.getElementById('reg-pwd').value; const fb = document.getElementById('auth-feedback'); fb.classList.remove('hidden'); if (!checkPasswordStrength(pwd)) { fb.className = 'text-xs text-rose-400 text-center mt-4'; fb.textContent = '密碼須至少 12 碼,且同時包含英文字母、數字與特殊符號!'; return; } if (!supabaseClient) { fb.className = 'text-xs text-emerald-400 text-center mt-4'; fb.textContent = '✓ 模擬註冊成功(尚未連線 Supabase SDK)'; return; } // 呼叫 Supabase Auth 雲端註冊 API (會自動觸發 Resend 寄送驗證信) const { data, error } = await supabaseClient.auth.signUp({ email: email, password: pwd, options: { data: { role: 'member' } } }); if (error) { fb.className = 'text-xs text-rose-400 text-center mt-4'; fb.textContent = '註冊失敗:' + error.message; } else { fb.className = 'text-xs text-emerald-400 text-center mt-4'; fb.textContent = '✓ 註冊申請已送出!確認信已寄至您的信箱,請點擊信中連結完成驗證。'; } } async function handleMemberLogin(e) { e.preventDefault(); const email = sanitizeInput(document.getElementById('login-email').value); const pwd = document.getElementById('login-pwd').value; const fb = document.getElementById('auth-feedback'); fb.classList.remove('hidden'); if (!supabaseClient) { currentUser = { email, role: 'member' }; localStorage.setItem('pttzzt_current_user', JSON.stringify(currentUser)); updateUserHeader(); closeAuthModal(); return; } const { data, error } = await supabaseClient.auth.signInWithPassword({ email: email, password: pwd }); if (error) { fb.className = 'text-xs text-rose-400 text-center mt-4'; fb.textContent = '登入失敗:' + error.message; } else { currentUser = { email: data.user.email, role: data.user.user_metadata?.role || 'member' }; localStorage.setItem('pttzzt_current_user', JSON.stringify(currentUser)); updateUserHeader(); closeAuthModal(); } } async function handlePasswordReset(e) { e.preventDefault(); const email = sanitizeInput(document.getElementById('reset-email').value); const fb = document.getElementById('auth-feedback'); fb.classList.remove('hidden'); if (!supabaseClient) { fb.className = 'text-xs text-emerald-400 text-center mt-4'; fb.textContent = '若此信箱已註冊,系統已寄出密碼重置驗證碼。'; return; } // 呼叫 Supabase Auth 忘記密碼重置 API (透過 Resend 寄出重置信) const { error } = await supabaseClient.auth.resetPasswordForEmail(email, { redirectTo: 'https://pttzzt.com/index.html' }); fb.className = 'text-xs text-emerald-400 text-center mt-4'; fb.textContent = '若此信箱已註冊,重置密碼驗證信已由 newsletter@pttzzt.com 寄出。'; } function updateUserHeader() { const badge = document.getElementById('user-badge'); const btn = document.getElementById('btn-auth-main'); if (currentUser) { badge.textContent = `👤 會員:${currentUser.email}`; btn.textContent = '登出'; btn.onclick = () => { currentUser = null; localStorage.removeItem('pttzzt_current_user'); location.reload(); }; } } function handleNewsletterSubmit(e) { e.preventDefault(); const email = sanitizeInput(document.getElementById('nl-email').value); if (!email) return; const fb = document.getElementById('nl-feedback'); fb.classList.remove('hidden'); fb.textContent = `✓ 感謝訂閱!確認信已由 newsletter@pttzzt.com 寄送至 ${email}`; e.target.reset(); } function copyShortUrl() { navigator.clipboard?.writeText(activeShortUrl); const fb = document.getElementById('share-feedback'); fb.classList.remove('hidden'); fb.textContent = '✓ 已複製精簡短網址!未授權讀者點入仍受會員權限保護。'; } // 初始化 // 初始化:啟動時自動從雲端 API (/api/site-data) 載入 Notion 真實文章與站長後台最新設定 async function initLiveSite() { setLang('zh'); updateUserHeader(); try { const res = await fetch('/api/site-data'); if (res.ok) { const data = await res.json(); if (data.settings) siteSettings = data.settings; if (data.notionSynced && data.articles && data.articles.length > 0) { articles = data.articles; } setLang(currentLang); } } catch (e) { console.warn('使用預設快取內容顯示'); } } initLiveSite();