'use client' import { useAuth } from '@thedaviddias/auth' import { Button } from '@thedaviddias/design-system/button' import { logger } from '@thedaviddias/logging' import { Download, Eye, Lock } from 'lucide-react' import { useRouter } from 'next/navigation' import { useEffect, useState } from 'react' import { toast } from 'sonner' import { Card } from '@/components/ui/card' import { analytics } from '@/lib/analytics' export default function PrivacySettingsPage() { const { user, isLoaded, reloadUser } = useAuth() const router = useRouter() const [settings, setSettings] = useState({ profilePublic: true, trackingOptOut: false, analyticsOptOut: false }) const [isLoading, setIsLoading] = useState(false) // Check if profile is incomplete (needs name or username to be visible) const isProfileIncomplete = Boolean( user && !user.user_metadata?.full_name && !user.user_metadata?.user_name && !user.publicMetadata?.github_username ) // Load and sync real user privacy settings useEffect(() => { if (user && isLoaded) { const isProfilePrivate = user.publicMetadata?.isProfilePrivate === true const currentProfilePublic = !isProfilePrivate // Only update if the value has actually changed to prevent unnecessary re-renders setSettings(prev => { if (prev.profilePublic !== currentProfilePublic) { return { ...prev, profilePublic: currentProfilePublic } } return prev }) } }, [user?.id, Boolean(user?.publicMetadata?.isProfilePrivate), isLoaded]) useEffect(() => { analytics.settingsPageView('privacy', 'settings') }, []) /** * Handle privacy setting change * @param key - Setting key to change * @param value - New value for the setting */ const handleSettingChange = async (key: string, value: boolean) => { if (key === 'profilePublic') { setIsLoading(true) // Update local state immediately for UI feedback setSettings(prev => ({ ...prev, [key]: value })) try { // Save to backend const response = await fetch('/api/user/update-metadata', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ isProfilePrivate: !value, // Invert since UI shows "Public" but metadata stores "Private" bio: user?.publicMetadata?.bio || null, work: user?.publicMetadata?.work || null, website: user?.publicMetadata?.website || null }) }) if (!response.ok) { // Revert on error setSettings(prev => ({ ...prev, [key]: !value })) const data = await response.json() toast.error(data.error || 'Failed to update privacy setting') return } // Track successful change analytics.settingsToggleChange(key, value, 'privacy') analytics.profileVisibilityToggle(value, 'settings-privacy') toast.success('Privacy setting updated') // Force reload user data to update all components await reloadUser() // Refresh to update all UI components router.refresh() } catch { // Revert on error setSettings(prev => ({ ...prev, [key]: !value })) toast.error('Failed to update privacy setting. Please try again.') } finally { setIsLoading(false) } } else { // For other settings, just update local state setSettings(prev => ({ ...prev, [key]: value })) analytics.settingsToggleChange(key, value, 'privacy') toast.success('Setting updated') } } /** * Handle data export request */ const handleExportData = async () => { try { analytics.exportData('settings-privacy') toast.info('Preparing your data export...') const response = await fetch('/api/user/export-data', { method: 'GET', headers: { 'Content-Type': 'application/json' } }) if (!response.ok) { throw new Error('Failed to export data') } const userData = await response.json() // Create downloadable JSON file const dataStr = JSON.stringify(userData, null, 2) const dataBlob = new Blob([dataStr], { type: 'application/json' }) // Create download link const url = URL.createObjectURL(dataBlob) const link = document.createElement('a') link.href = url link.download = `llms-txt-hub-data-export-${new Date().toISOString().split('T')[0]}.json` // Trigger download document.body.appendChild(link) link.click() document.body.removeChild(link) URL.revokeObjectURL(url) toast.success('Data export downloaded successfully') } catch (error) { logger.error(error instanceof Error ? error : new Error(String(error)), { data: error, tags: { type: 'page', page: 'privacy-settings' } }) toast.error('Failed to export data. Please try again.') } } return (
Control how your information is collected and displayed
Profile is hidden: Your profile won't appear in member listings because you haven't added a first name or username yet. Go to your profile and click "Edit Profile" to add this information.
We collect minimal data to provide our service. You have full control over your information and can request access or deletion at any time.
All data is encrypted in transit and at rest. We use industry-standard security measures and never share personal information with third parties without explicit consent.