Production Implementation Guide
Code patterns for replacing mock hooks with real Supabase logic.
PRID: 1902
VERIFIED
2 min read
🛠️ Production Implementation Guide: Swapping Mocks for Reality
Context: You have the UI shell. Now you need to inject the logic.
Prerequisite: A Supabase project created and keys added to .env.
1. Replacing Authentication
File: src/hooks/useAuth.ts
The Mock Pattern (Current)
typescriptconst login = async () => { localStorage.setItem('auth_token', 'mock'); setState({ user: mockUser }); }
The Production Pattern (Target)
typescriptimport { supabase } from '../lib/supabase'; export const useAuth = () => { const [user, setUser] = useState(null); // 1. Listen to Auth State useEffect(() => { supabase.auth.getSession().then(({ data: { session } }) => { setUser(session?.user ?? null); }); const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => { setUser(session?.user ?? null); }); return () => subscription.unsubscribe(); }, []); // 2. Real Login Action const login = async (email) => { const { error } = await supabase.auth.signInWithOtp({ email }); if (error) throw error; }; return { user, login }; }
2. Connecting the Database
Scenario: Fetching a list of "Projects" for the dashboard.
The Mock Pattern
typescript// src/hooks/useProjects.ts import { mockProjects } from '../mocks/projects'; // ... return mockProjects after timeout
The Production Pattern
typescript// src/hooks/useProjects.ts import { useQuery } from '@tanstack/react-query'; import { supabase } from '../lib/supabase'; export const useProjects = () => { return useQuery({ queryKey: ['projects'], queryFn: async () => { const { data, error } = await supabase .from('projects') .select('*') .order('created_at', { ascending: false }); if (error) throw error; return data; } }); };
3. Handling Form Submissions (Contact/Newsletter)
File: src/hooks/useContact.ts
The Production Pattern
Instead of mocking a success message, insert directly into a table.
typescriptconst submit = async (formData) => { setStatus('loading'); const { error } = await supabase .from('inbox_messages') .insert([ { name: formData.name, email: formData.email, message: formData.message, type: 'contact' } ]); if (error) { setStatus('error'); // Log error to Sentry here } else { setStatus('success'); } };
4. The "Lovable" Shortcut (Recommended)
Instead of writing the above manually, you can use Lovable to write it for you.
- Copy your current hook (e.g.,
useAuth.ts). - Paste into Lovable.
- Prompt: "Refactor this hook to use the
@supabase/supabase-jsclient. Assumesrc/lib/supabase.tsexports the client. Handle loading and error states." - Copy Back the result.
This is the GLC Protocol in action: Visuals (G) -> Structure (Mouth Ship) -> Logic (L).