diff --git a/src/figma-make/lib/info.tsx b/src/figma-make/lib/info.tsx new file mode 100644 index 00000000..3127f912 --- /dev/null +++ b/src/figma-make/lib/info.tsx @@ -0,0 +1,6 @@ +// TODO: delete this file later + +/* AUTOGENERATED FILE - DO NOT EDIT CONTENTS */ + +export const projectId = 'xxx'; +export const publicAnonKey = 'xxx'; diff --git a/src/figma-make/lib/supabase.ts b/src/figma-make/lib/supabase.ts new file mode 100644 index 00000000..0b693389 --- /dev/null +++ b/src/figma-make/lib/supabase.ts @@ -0,0 +1,339 @@ +import { createClient, SupabaseClient } from '@supabase/supabase-js'; +import { projectId, publicAnonKey } from '@/figma-make/lib/info'; + +// ============================================ +// 🔍 SUPABASE ENVIRONMENT DEBUG CHECK +// ============================================ + +/** + * Get environment variable from multiple sources + * Checks in order: __ENV__, window.__ENV__, process.env, import.meta.env + */ +function getEnv(key: string): string | undefined { + let value: string | undefined; + let source: string | undefined; + + // Check globalThis.__ENV__ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if ((globalThis as any).__ENV__?.[key]) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value = (globalThis as any).__ENV__[key]; + source = 'globalThis.__ENV__'; + } + // Check window.__ENV__ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + else if (typeof window !== 'undefined' && (window as any).__ENV__?.[key]) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value = (window as any).__ENV__[key]; + source = 'window.__ENV__'; + } + // Check process.env + // eslint-disable-next-line @typescript-eslint/no-explicit-any + else if ((globalThis as any).process?.env?.[key]) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value = (globalThis as any).process.env[key]; + source = 'process.env'; + } + // Check import.meta.env (if available) + else if ( + typeof import.meta !== 'undefined' && + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (import.meta as any)?.env?.[key] + ) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value = (import.meta as any).env[key]; + source = 'import.meta.env'; + } + + if (value && source) { + console.log(`✅ ${key} loaded from: ${source}`); + } + + return value; +} + +// Try to read from environment variables first +let supabaseUrl = getEnv('VITE_SUPABASE_URL'); +let supabaseAnonKey = getEnv('VITE_SUPABASE_ANON_KEY'); + +// Fallback to Figma Make autogenerated credentials +if (!supabaseUrl || !supabaseAnonKey) { + console.log( + '📋 Using Figma Make autogenerated Supabase credentials from /utils/supabase/info.tsx' + ); + supabaseUrl = `https://${projectId}.supabase.co`; + supabaseAnonKey = publicAnonKey; +} + +// Helper function to mask sensitive data +const maskString = (str: string | undefined): string => { + if (!str) return 'undefined'; + if (str.length <= 20) return str.substring(0, 10) + '...'; + return str.substring(0, 20) + '...' + `(${str.length - 20} chars masked)`; +}; + +// Debug logging +console.group('🔍 Supabase Environment Check'); +console.log('projectId (from info.tsx):', projectId); +console.log('SUPABASE_URL present?', !!supabaseUrl); +console.log('SUPABASE_KEY present?', !!supabaseAnonKey); +console.log('SUPABASE_URL value:', maskString(supabaseUrl)); +console.log('SUPABASE_KEY value:', maskString(supabaseAnonKey)); +console.groupEnd(); + +// Check if Supabase is configured +export const isSupabaseConfigured = () => { + return !!(supabaseUrl && supabaseAnonKey); +}; + +// Create Supabase client or throw error +// eslint-disable-next-line @typescript-eslint/no-explicit-any +let supabase: SupabaseClient; + +if (isSupabaseConfigured()) { + console.log('✅ Creating real Supabase client...'); + supabase = createClient(supabaseUrl!, supabaseAnonKey!); + console.log('✅ Supabase client created successfully!'); +} else { + const errorMessage = ` +❌ SUPABASE CONFIGURATION ERROR ❌ + +Missing required environment variables: +- VITE_SUPABASE_URL: ${!!supabaseUrl ? '✅ Present' : '❌ Missing'} +- VITE_SUPABASE_ANON_KEY: ${!!supabaseAnonKey ? '✅ Present' : '❌ Missing'} + +Please set Supabase environment variables in: +→ Figma Make Supabase integration settings +→ Deployment settings/environment configuration + +The app checked the following sources: +- globalThis.__ENV__ +- window.__ENV__ +- process.env +- import.meta.env + +None of these sources contained the required variables. + `.trim(); + + console.error(errorMessage); + throw new Error(errorMessage); +} + +export { supabase }; + +// Database types +export interface Database { + public: { + Tables: { + kandang: { + Row: { + id: string; + name: string; + created_at?: string; + }; + Insert: { + id?: string; + name: string; + created_at?: string; + }; + Update: { + id?: string; + name?: string; + created_at?: string; + }; + }; + employees: { + Row: { + id: string; + name: string; + kandang_id: string; + is_active: boolean; + created_at?: string; + }; + Insert: { + id?: string; + name: string; + kandang_id: string; + is_active?: boolean; + created_at?: string; + }; + Update: { + id?: string; + name?: string; + kandang_id?: string; + is_active?: boolean; + created_at?: string; + }; + }; + phases: { + Row: { + id: string; + name: string; + created_at?: string; + updated_at?: string; + }; + Insert: { + id?: string; + name: string; + created_at?: string; + updated_at?: string; + }; + Update: { + id?: string; + name?: string; + created_at?: string; + updated_at?: string; + }; + }; + phase_activities: { + Row: { + id: string; + phase_id: string; + name: string; + description?: string; + created_at?: string; + updated_at?: string; + }; + Insert: { + id?: string; + phase_id: string; + name: string; + description?: string; + created_at?: string; + updated_at?: string; + }; + Update: { + id?: string; + phase_id?: string; + name?: string; + description?: string; + created_at?: string; + updated_at?: string; + }; + }; + checklists: { + Row: { + id: string; + name: string; + description?: string; + phase_id: string; + created_at?: string; + updated_at?: string; + }; + Insert: { + id?: string; + name: string; + description?: string; + phase_id: string; + created_at?: string; + updated_at?: string; + }; + Update: { + id?: string; + name?: string; + description?: string; + phase_id?: string; + created_at?: string; + updated_at?: string; + }; + }; + daily_checklists: { + Row: { + id: string; + date: string; + kandang_id: string; + checklist_id: string; + category: string; + status: string; + name?: string; + total_score?: number; + document_path?: string; + reject_reason?: string; + created_by: string; + created_at?: string; + updated_at?: string; + }; + Insert: { + id?: string; + date: string; + kandang_id: string; + checklist_id: string; + category: string; + status?: string; + name?: string; + total_score?: number; + document_path?: string; + reject_reason?: string; + created_at?: string; + updated_at?: string; + }; + Update: { + id?: string; + date?: string; + kandang_id?: string; + checklist_id?: string; + category?: string; + status?: string; + name?: string; + total_score?: number; + document_path?: string; + reject_reason?: string; + created_at?: string; + updated_at?: string; + }; + }; + daily_checklist_tasks: { + Row: { + id: string; + checklist_id: string; + activity_id: string; + notes?: string; + created_at?: string; + updated_at?: string; + }; + Insert: { + id?: string; + checklist_id: string; + activity_id: string; + notes?: string; + created_at?: string; + updated_at?: string; + }; + Update: { + id?: string; + checklist_id?: string; + activity_id?: string; + notes?: string; + created_at?: string; + updated_at?: string; + }; + }; + task_assignees: { + Row: { + id: string; + task_id: string; + employee_id: string; + is_completed: boolean; + created_at?: string; + updated_at?: string; + }; + Insert: { + id?: string; + task_id: string; + employee_id: string; + is_completed?: boolean; + created_at?: string; + updated_at?: string; + }; + Update: { + id?: string; + task_id?: string; + employee_id?: string; + is_completed?: boolean; + created_at?: string; + updated_at?: string; + }; + }; + }; + }; +}