import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useOutletContext } from 'react-router-dom'; import { Business, User, CustomDomain } from '../types'; import { Save, Globe, Palette, BookKey, Check, Sparkles, CheckCircle, Link2, AlertCircle, ExternalLink, Copy, Crown, ShieldCheck, Trash2, RefreshCw, Star, Eye, EyeOff, Key, ShoppingCart, Building2, Users, Lock, Wallet, X, Plus, Layers, Pencil } from 'lucide-react'; import DomainPurchase from '../components/DomainPurchase'; import { useBusinessOAuthSettings, useUpdateBusinessOAuthSettings } from '../hooks/useBusinessOAuth'; import { useCustomDomains, useAddCustomDomain, useDeleteCustomDomain, useVerifyCustomDomain, useSetPrimaryDomain } from '../hooks/useCustomDomains'; import { useBusinessOAuthCredentials, useUpdateBusinessOAuthCredentials } from '../hooks/useBusinessOAuthCredentials'; import { useResourceTypes, useCreateResourceType, useUpdateResourceType, useDeleteResourceType } from '../hooks/useResourceTypes'; import OnboardingWizard from '../components/OnboardingWizard'; // Curated color palettes with complementary primary and secondary colors const colorPalettes = [ { name: 'Ocean Blue', description: 'Professional & trustworthy', primary: '#2563eb', secondary: '#0ea5e9', preview: 'bg-gradient-to-br from-blue-600 to-sky-500', }, { name: 'Sky Blue', description: 'Light & airy', primary: '#0ea5e9', secondary: '#38bdf8', preview: 'bg-gradient-to-br from-sky-500 to-sky-400', }, { name: 'Cyan Splash', description: 'Modern & vibrant', primary: '#06b6d4', secondary: '#22d3ee', preview: 'bg-gradient-to-br from-cyan-500 to-cyan-400', }, { name: 'Aqua Fresh', description: 'Clean & refreshing', primary: '#14b8a6', secondary: '#2dd4bf', preview: 'bg-gradient-to-br from-teal-500 to-teal-400', }, { name: 'Mint Green', description: 'Soft & welcoming', primary: '#10b981', secondary: '#34d399', preview: 'bg-gradient-to-br from-emerald-500 to-emerald-400', }, { name: 'Coral Reef', description: 'Warm & inviting', primary: '#f97316', secondary: '#fb923c', preview: 'bg-gradient-to-br from-orange-500 to-orange-400', }, { name: 'Lavender Dream', description: 'Gentle & elegant', primary: '#a78bfa', secondary: '#c4b5fd', preview: 'bg-gradient-to-br from-violet-400 to-violet-300', }, { name: 'Rose Pink', description: 'Friendly & modern', primary: '#ec4899', secondary: '#f472b6', preview: 'bg-gradient-to-br from-pink-500 to-pink-400', }, { name: 'Forest Green', description: 'Natural & calming', primary: '#059669', secondary: '#10b981', preview: 'bg-gradient-to-br from-emerald-600 to-emerald-400', }, { name: 'Royal Purple', description: 'Creative & luxurious', primary: '#7c3aed', secondary: '#a78bfa', preview: 'bg-gradient-to-br from-violet-600 to-purple-400', }, { name: 'Slate Gray', description: 'Minimal & sophisticated', primary: '#475569', secondary: '#64748b', preview: 'bg-gradient-to-br from-slate-600 to-slate-400', }, { name: 'Crimson Red', description: 'Bold & dynamic', primary: '#dc2626', secondary: '#ef4444', preview: 'bg-gradient-to-br from-red-600 to-red-400', }, ]; type SettingsTab = 'general' | 'domains' | 'authentication' | 'resources'; // Resource Types Management Section Component const ResourceTypesSection: React.FC = () => { const { t } = useTranslation(); const { data: resourceTypes = [], isLoading } = useResourceTypes(); const createResourceType = useCreateResourceType(); const updateResourceType = useUpdateResourceType(); const deleteResourceType = useDeleteResourceType(); const [isModalOpen, setIsModalOpen] = useState(false); const [editingType, setEditingType] = useState(null); const [formData, setFormData] = useState({ name: '', description: '', category: 'OTHER' as 'STAFF' | 'OTHER', iconName: '', }); const openCreateModal = () => { setEditingType(null); setFormData({ name: '', description: '', category: 'OTHER', iconName: '' }); setIsModalOpen(true); }; const openEditModal = (type: any) => { setEditingType(type); setFormData({ name: type.name, description: type.description || '', category: type.category, iconName: type.icon_name || type.iconName || '', }); setIsModalOpen(true); }; const closeModal = () => { setIsModalOpen(false); setEditingType(null); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { if (editingType) { await updateResourceType.mutateAsync({ id: editingType.id, updates: formData, }); } else { await createResourceType.mutateAsync(formData); } closeModal(); } catch (error) { console.error('Failed to save resource type:', error); } }; const handleDelete = async (id: string, name: string) => { if (window.confirm(`Are you sure you want to delete the "${name}" resource type?`)) { try { await deleteResourceType.mutateAsync(id); } catch (error: any) { alert(error.response?.data?.error || 'Failed to delete resource type'); } } }; return (

{t('settings.resourceTypes', 'Resource Types')}

{t('settings.resourceTypesDescription', 'Define custom types for your resources (e.g., Stylist, Treatment Room, Equipment)')}

{isLoading ? (
) : resourceTypes.length === 0 ? (

{t('settings.noResourceTypes', 'No custom resource types yet.')}

{t('settings.addFirstResourceType', 'Add your first resource type to categorize your resources.')}

) : (
{resourceTypes.map((type: any) => { const isDefault = type.is_default || type.isDefault; return (
{type.category === 'STAFF' ? : }

{type.name} {isDefault && ( Default )}

{type.category === 'STAFF' ? 'Requires staff assignment' : 'General resource'}

{type.description && (

{type.description}

)}
{!isDefault && ( )}
); })}
)} {/* Modal for Create/Edit */} {isModalOpen && (

{editingType ? t('settings.editResourceType', 'Edit Resource Type') : t('settings.addResourceType', 'Add Resource Type')}

setFormData({ ...formData, name: e.target.value })} required className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-brand-500" placeholder={t('settings.resourceTypeNamePlaceholder', 'e.g., Stylist, Treatment Room, Camera')} />