/** * Custom Domains Settings Page * * Manage custom domains - BYOD and domain purchase. */ import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useOutletContext, Link } from 'react-router-dom'; import { Globe, Copy, Star, Trash2, RefreshCw, CheckCircle, AlertCircle, ShoppingCart, Lock, ArrowUpRight } from 'lucide-react'; import { Business, User, CustomDomain } from '../../types'; import { useCustomDomains, useAddCustomDomain, useDeleteCustomDomain, useVerifyCustomDomain, useSetPrimaryDomain } from '../../hooks/useCustomDomains'; import DomainPurchase from '../../components/DomainPurchase'; import { usePlanFeatures } from '../../hooks/usePlanFeatures'; const CustomDomainsSettings: React.FC = () => { const { t } = useTranslation(); const { business, user } = useOutletContext<{ business: Business; user: User; }>(); // Hooks const { data: customDomains = [], isLoading: domainsLoading } = useCustomDomains(); const addDomainMutation = useAddCustomDomain(); const deleteDomainMutation = useDeleteCustomDomain(); const verifyDomainMutation = useVerifyCustomDomain(); const setPrimaryMutation = useSetPrimaryDomain(); // Local state const [newDomain, setNewDomain] = useState(''); const [verifyingDomainId, setVerifyingDomainId] = useState(null); const [verifyError, setVerifyError] = useState(null); const [showToast, setShowToast] = useState(false); const isOwner = user.role === 'owner'; const { canUse } = usePlanFeatures(); const handleAddDomain = () => { if (!newDomain.trim()) return; addDomainMutation.mutate(newDomain, { onSuccess: () => { setNewDomain(''); setShowToast(true); setTimeout(() => setShowToast(false), 3000); }, onError: (error: any) => { alert(error.response?.data?.error || 'Failed to add domain'); }, }); }; const handleDeleteDomain = (domainId: number) => { if (!confirm('Are you sure you want to delete this custom domain?')) return; deleteDomainMutation.mutate(domainId, { onSuccess: () => { setShowToast(true); setTimeout(() => setShowToast(false), 3000); }, }); }; const handleVerifyDomain = (domainId: number) => { setVerifyingDomainId(domainId); setVerifyError(null); verifyDomainMutation.mutate(domainId, { onSuccess: (data: any) => { setVerifyingDomainId(null); if (data.verified) { setShowToast(true); setTimeout(() => setShowToast(false), 3000); } else { setVerifyError(data.message); } }, onError: (error: any) => { setVerifyingDomainId(null); setVerifyError(error.response?.data?.message || 'Verification failed'); }, }); }; const handleSetPrimary = (domainId: number) => { setPrimaryMutation.mutate(domainId, { onSuccess: () => { setShowToast(true); setTimeout(() => setShowToast(false), 3000); }, onError: (error: any) => { alert(error.response?.data?.error || 'Failed to set primary domain'); }, }); }; if (!isOwner) { return (

Only the business owner can access these settings.

); } const isCustomDomainLocked = !canUse('custom_domain'); return (
{/* Header */}

{t('settings.customDomains.title', 'Custom Domains')}

Use your own domains for your booking pages.

{/* Custom Domains Management - with overlay when locked */}
{isCustomDomainLocked && (
Upgrade to Enable Custom Domains
)}

Bring Your Own Domain

Connect a domain you already own

{/* Add New Domain Form */}
setNewDomain(e.target.value)} placeholder="booking.yourdomain.com" className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white rounded-lg focus:ring-2 focus:ring-brand-500 font-mono text-sm" onKeyPress={(e) => { if (e.key === 'Enter') { handleAddDomain(); } }} />
{/* Custom Domains List */} {domainsLoading ? (
Loading domains...
) : customDomains.length === 0 ? (

No custom domains yet. Add one above.

) : (
{customDomains.map((domain: CustomDomain) => (

{domain.domain}

{domain.is_primary && ( Primary )} {domain.is_verified ? ( Verified ) : ( Pending )}
{!domain.is_verified && (

Add DNS TXT record:

Name: {domain.dns_txt_record_name}
Value: {domain.dns_txt_record}
{verifyError && verifyingDomainId === domain.id && (

{verifyError}

)}
)}
{!domain.is_verified && ( )} {domain.is_verified && !domain.is_primary && ( )}
))}
)}
{/* Domain Purchase */}

Purchase a Domain

Search and register a new domain name

{/* Toast */} {showToast && (
Changes saved successfully
)}
); }; export default CustomDomainsSettings;