@burdenoff/microfe-adaptercloud 2026.624.1 → 2026.625.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adaptercloud/components/EmptyState.js +17 -21
- package/dist/adaptercloud/components/EmptyState.js.map +1 -1
- package/dist/adaptercloud/components/InvestmentCard.js +25 -23
- package/dist/adaptercloud/components/InvestmentCard.js.map +1 -1
- package/dist/adaptercloud/components/MetricsCard.js +18 -12
- package/dist/adaptercloud/components/MetricsCard.js.map +1 -1
- package/dist/adaptercloud/components/PageLayout.js +38 -19
- package/dist/adaptercloud/components/PageLayout.js.map +1 -1
- package/dist/adaptercloud/components/RatingDisplay.js +3 -3
- package/dist/adaptercloud/components/RatingDisplay.js.map +1 -1
- package/dist/adaptercloud/components/StatusBadge.js +36 -16
- package/dist/adaptercloud/components/StatusBadge.js.map +1 -1
- package/dist/adaptercloud/pages/HomePage.js +242 -231
- package/dist/adaptercloud/pages/HomePage.js.map +1 -1
- package/dist/adaptercloud/pages/admin/AdminAnalyticsPage.js +33 -33
- package/dist/adaptercloud/pages/admin/AdminAnalyticsPage.js.map +1 -1
- package/dist/adaptercloud/pages/admin/AdminDashboard.js +32 -32
- package/dist/adaptercloud/pages/admin/AdminDashboard.js.map +1 -1
- package/dist/adaptercloud/pages/admin/AdminFinancialPage.js +11 -11
- package/dist/adaptercloud/pages/admin/AdminFinancialPage.js.map +1 -1
- package/dist/adaptercloud/pages/admin/AdminOrdersPage.js +11 -11
- package/dist/adaptercloud/pages/admin/AdminOrdersPage.js.map +1 -1
- package/dist/adaptercloud/pages/admin/AdminProfilePage.js +3 -3
- package/dist/adaptercloud/pages/admin/AdminProfilePage.js.map +1 -1
- package/dist/adaptercloud/pages/admin/AdminSettingsPage.js +1 -1
- package/dist/adaptercloud/pages/admin/AdminSettingsPage.js.map +1 -1
- package/dist/adaptercloud/pages/admin/CartManagementPage.js +28 -28
- package/dist/adaptercloud/pages/admin/CartManagementPage.js.map +1 -1
- package/dist/adaptercloud/pages/admin/UserManagementPage.js +25 -25
- package/dist/adaptercloud/pages/admin/UserManagementPage.js.map +1 -1
- package/dist/adaptercloud/pages/cart-owner/AnalyticsDashboard.js +19 -19
- package/dist/adaptercloud/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
- package/dist/adaptercloud/pages/cart-owner/BusinessSettingsPage.js +7 -7
- package/dist/adaptercloud/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
- package/dist/adaptercloud/pages/cart-owner/CartOwnerDashboard.js +40 -37
- package/dist/adaptercloud/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
- package/dist/adaptercloud/pages/cart-owner/CartOwnerProfilePage.js +21 -21
- package/dist/adaptercloud/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
- package/dist/adaptercloud/pages/cart-owner/CartServiceConfigPage.js +24 -24
- package/dist/adaptercloud/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
- package/dist/adaptercloud/pages/cart-owner/InventoryManagementPage.js +20 -20
- package/dist/adaptercloud/pages/cart-owner/InventoryManagementPage.js.map +1 -1
- package/dist/adaptercloud/pages/cart-owner/OrderManagementPage.js +36 -36
- package/dist/adaptercloud/pages/cart-owner/OrderManagementPage.js.map +1 -1
- package/dist/adaptercloud/pages/cart-owner/StaffManagementPage.js +25 -25
- package/dist/adaptercloud/pages/cart-owner/StaffManagementPage.js.map +1 -1
- package/dist/adaptercloud/pages/common/HelpSupportPage.js +43 -43
- package/dist/adaptercloud/pages/common/HelpSupportPage.js.map +1 -1
- package/dist/adaptercloud/pages/common/NotificationCenterPage.js +32 -31
- package/dist/adaptercloud/pages/common/NotificationCenterPage.js.map +1 -1
- package/dist/adaptercloud/pages/common/SettingsPage.js +8 -8
- package/dist/adaptercloud/pages/common/SettingsPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/BookingDetailsPage.js +22 -21
- package/dist/adaptercloud/pages/customer/BookingDetailsPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/CartDetailPage.js +18 -17
- package/dist/adaptercloud/pages/customer/CartDetailPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/CartDiscoveryPage.js +12 -11
- package/dist/adaptercloud/pages/customer/CartDiscoveryPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/CheckoutPage.js +9 -9
- package/dist/adaptercloud/pages/customer/CheckoutPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/CustomerDashboard.js +30 -30
- package/dist/adaptercloud/pages/customer/CustomerDashboard.js.map +1 -1
- package/dist/adaptercloud/pages/customer/CustomerProfilePage.js +19 -19
- package/dist/adaptercloud/pages/customer/CustomerProfilePage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/DirectServiceBookingPage.js +24 -23
- package/dist/adaptercloud/pages/customer/DirectServiceBookingPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/FavoritesPage.js +9 -8
- package/dist/adaptercloud/pages/customer/FavoritesPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/OrderHistoryPage.js +4 -3
- package/dist/adaptercloud/pages/customer/OrderHistoryPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/OrderTrackingPage.js +15 -14
- package/dist/adaptercloud/pages/customer/OrderTrackingPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/PaymentMethodsPage.js +10 -9
- package/dist/adaptercloud/pages/customer/PaymentMethodsPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/ReviewsPage.js +18 -17
- package/dist/adaptercloud/pages/customer/ReviewsPage.js.map +1 -1
- package/dist/adaptercloud/pages/customer/SavedAddressesPage.js +14 -13
- package/dist/adaptercloud/pages/customer/SavedAddressesPage.js.map +1 -1
- package/dist/adaptercloud/pages/investor/InvestmentDetailsPage.js +32 -32
- package/dist/adaptercloud/pages/investor/InvestmentDetailsPage.js.map +1 -1
- package/dist/adaptercloud/pages/investor/InvestmentOpportunitiesPage.js +14 -13
- package/dist/adaptercloud/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
- package/dist/adaptercloud/pages/investor/InvestorAnalyticsPage.js +27 -27
- package/dist/adaptercloud/pages/investor/InvestorAnalyticsPage.js.map +1 -1
- package/dist/adaptercloud/pages/investor/InvestorDashboard.js +16 -16
- package/dist/adaptercloud/pages/investor/InvestorDashboard.js.map +1 -1
- package/dist/adaptercloud/pages/investor/InvestorInvestmentsPage.js +9 -8
- package/dist/adaptercloud/pages/investor/InvestorInvestmentsPage.js.map +1 -1
- package/dist/adaptercloud/pages/investor/InvestorPortfolioPage.js +12 -12
- package/dist/adaptercloud/pages/investor/InvestorPortfolioPage.js.map +1 -1
- package/dist/adaptercloud/pages/investor/InvestorProfilePage.js +19 -19
- package/dist/adaptercloud/pages/investor/InvestorProfilePage.js.map +1 -1
- package/dist/adaptercloud/pages/worker/TaskDetailsPage.js +26 -25
- package/dist/adaptercloud/pages/worker/TaskDetailsPage.js.map +1 -1
- package/dist/adaptercloud/pages/worker/WorkerDashboard.js +43 -43
- package/dist/adaptercloud/pages/worker/WorkerDashboard.js.map +1 -1
- package/dist/adaptercloud/pages/worker/WorkerOrdersPage.js +37 -36
- package/dist/adaptercloud/pages/worker/WorkerOrdersPage.js.map +1 -1
- package/dist/adaptercloud/pages/worker/WorkerProfilePage.js +34 -34
- package/dist/adaptercloud/pages/worker/WorkerProfilePage.js.map +1 -1
- package/dist/adaptercloud/pages/worker/WorkerSchedulePage.js +27 -25
- package/dist/adaptercloud/pages/worker/WorkerSchedulePage.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsPage.js","names":[],"sources":["../../../../src/adaptercloud/pages/common/SettingsPage.tsx"],"sourcesContent":["/**\n * Settings Page\n * @module adaptercloud/pages/common\n *\n * Full-featured settings with 5 tabs: Profile, Preferences, Security,\n * Privacy, and Billing. Form validation, save state, sidebar navigation.\n */\n\nimport { useState, useCallback, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n User,\n Settings,\n Sun,\n Moon,\n Monitor,\n Globe,\n Bell,\n Shield,\n Eye,\n EyeOff,\n Save,\n RotateCcw,\n Lock,\n Smartphone,\n Laptop,\n LogOut,\n Trash2,\n CreditCard,\n Receipt,\n Building2,\n MapPin,\n Camera,\n AlertTriangle,\n CheckCircle2,\n Loader2,\n} from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { useAdapterCloud } from '../../context/AdapterCloudContext';\nimport { cn } from '../../utils/cn';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype ThemeOption = 'light' | 'dark' | 'system';\ntype LanguageOption = 'en' | 'ta' | 'hi' | 'kn' | 'te' | 'ml';\ntype TabId = 'profile' | 'preferences' | 'security' | 'privacy' | 'billing';\n\ninterface TrustedDevice {\n id: string;\n name: string;\n browser: string;\n os: string;\n lastActive: string;\n isCurrent: boolean;\n}\n\ninterface UserSettings {\n profile: {\n firstName: string;\n lastName: string;\n email: string;\n phone: string;\n bio: string;\n dateOfBirth: string;\n gender: string;\n profilePicture: string;\n };\n preferences: {\n theme: ThemeOption;\n language: LanguageOption;\n timezone: string;\n currency: string;\n notifications: {\n email: boolean;\n sms: boolean;\n push: boolean;\n orderUpdates: boolean;\n promotions: boolean;\n newsletters: boolean;\n security: boolean;\n };\n };\n security: {\n twoFactorEnabled: boolean;\n loginAlerts: boolean;\n sessionTimeout: string;\n trustedDevices: TrustedDevice[];\n };\n privacy: {\n profileVisibility: 'public' | 'private' | 'friends';\n dataSharing: {\n analytics: boolean;\n marketing: boolean;\n thirdParty: boolean;\n };\n locationTracking: boolean;\n activityHistory: boolean;\n };\n billing: {\n paymentMethod: { type: string; last4: string; provider: string } | null;\n autoRecharge: boolean;\n autoRechargeAmount: string;\n invoiceEmail: string;\n gstNumber: string;\n companyName: string;\n billingAddress: string;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst defaultSettings: UserSettings = {\n profile: {\n firstName: 'Priya',\n lastName: 'Customer',\n email: 'customer@burdenoff.com',\n phone: '+91 98765 43220',\n bio: 'Food enthusiast and tech lover. Always exploring new services and experiences in Bangalore.',\n dateOfBirth: '1992-08-15',\n gender: 'female',\n profilePicture: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=200',\n },\n preferences: {\n theme: 'system',\n language: 'en',\n timezone: 'Asia/Kolkata',\n currency: 'INR',\n notifications: {\n email: true,\n sms: true,\n push: true,\n orderUpdates: true,\n promotions: false,\n newsletters: false,\n security: true,\n },\n },\n security: {\n twoFactorEnabled: false,\n loginAlerts: true,\n sessionTimeout: '30',\n trustedDevices: [\n {\n id: 'dev-1',\n name: 'MacBook Pro',\n browser: 'Chrome 126.0',\n os: 'macOS Sonoma',\n lastActive: '2024-06-24T09:30:00Z',\n isCurrent: true,\n },\n {\n id: 'dev-2',\n name: 'iPhone 15',\n browser: 'Safari Mobile',\n os: 'iOS 17.5',\n lastActive: '2024-06-23T18:45:00Z',\n isCurrent: false,\n },\n {\n id: 'dev-3',\n name: 'Samsung Galaxy S24',\n browser: 'Chrome Mobile',\n os: 'Android 14',\n lastActive: '2024-06-20T12:00:00Z',\n isCurrent: false,\n },\n ],\n },\n privacy: {\n profileVisibility: 'private',\n dataSharing: {\n analytics: true,\n marketing: false,\n thirdParty: false,\n },\n locationTracking: true,\n activityHistory: true,\n },\n billing: {\n paymentMethod: { type: 'card', last4: '4532', provider: 'Visa' },\n autoRecharge: false,\n autoRechargeAmount: '1000',\n invoiceEmail: 'customer@burdenoff.com',\n gstNumber: '29ABCDE1234F1Z5',\n companyName: '',\n billingAddress: '123 Tech Park, Koramangala, Bangalore 560034',\n },\n};\n\n// ---------------------------------------------------------------------------\n// Tab config\n// ---------------------------------------------------------------------------\n\nconst tabConfig: { id: TabId; label: string; icon: typeof User }[] = [\n { id: 'profile', label: 'Profile', icon: User },\n { id: 'preferences', label: 'Preferences', icon: Settings },\n { id: 'security', label: 'Security', icon: Shield },\n { id: 'privacy', label: 'Privacy', icon: Eye },\n { id: 'billing', label: 'Billing', icon: CreditCard },\n];\n\n// ---------------------------------------------------------------------------\n// Toggle Switch component (inline)\n// ---------------------------------------------------------------------------\n\nfunction ToggleSwitch({\n checked,\n onChange,\n label,\n}: {\n checked: boolean;\n onChange: (val: boolean) => void;\n label?: string;\n}) {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n aria-label={label}\n onClick={() => onChange(!checked)}\n className={cn(\n 'relative inline-flex h-6 w-11 items-center rounded-full transition-colors shrink-0',\n checked ? 'bg-action-primary-bg' : 'bg-bg-sunken'\n )}\n >\n <span\n className={cn(\n 'inline-block h-4 w-4 transform rounded-full bg-white transition-transform',\n checked ? 'translate-x-6' : 'translate-x-1'\n )}\n />\n </button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function SettingsPage() {\n const { currentUser } = useAdapterCloud();\n const { t: translate } = useI18n();\n const [activeTab, setActiveTab] = useState<TabId>('profile');\n const [settings, setSettings] = useState<UserSettings>(() => {\n const s = { ...defaultSettings };\n if (currentUser?.firstName) s.profile.firstName = currentUser.firstName;\n if (currentUser?.lastName) s.profile.lastName = currentUser.lastName;\n if (currentUser?.email) s.profile.email = currentUser.email;\n return s;\n });\n const [hasChanges, setHasChanges] = useState(false);\n const [saving, setSaving] = useState(false);\n const [saveMessage, setSaveMessage] = useState('');\n const t = useCallback(\n (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n const localizedTabConfig = useMemo(\n () =>\n tabConfig.map((tab) => ({\n ...tab,\n label:\n tab.id === 'profile'\n ? t('adaptercloud.settings.tabs.profile', 'Profile')\n : tab.id === 'preferences'\n ? t('adaptercloud.settings.tabs.preferences', 'Preferences')\n : tab.id === 'security'\n ? t('adaptercloud.settings.tabs.security', 'Security')\n : tab.id === 'privacy'\n ? t('adaptercloud.settings.tabs.privacy', 'Privacy')\n : t('adaptercloud.settings.tabs.billing', 'Billing'),\n })),\n [t]\n );\n\n // Deep update helper\n const update = useCallback(\n <S extends keyof UserSettings, F extends keyof UserSettings[S]>(\n section: S,\n field: F,\n value: UserSettings[S][F]\n ) => {\n setSettings((prev) => ({\n ...prev,\n [section]: { ...prev[section], [field]: value },\n }));\n setHasChanges(true);\n setSaveMessage('');\n },\n []\n );\n\n const updateNested = useCallback(\n (section: keyof UserSettings, sub: string, field: string, value: boolean | string) => {\n setSettings((prev) => ({\n ...prev,\n [section]: {\n ...prev[section],\n [sub]: {\n ...((prev[section] as Record<string, unknown>)[sub] as Record<string, unknown>),\n [field]: value,\n },\n },\n }));\n setHasChanges(true);\n setSaveMessage('');\n },\n []\n );\n\n const resetSettings = useCallback(() => {\n setSettings(defaultSettings);\n setHasChanges(false);\n setSaveMessage('');\n }, []);\n\n const saveSettings = useCallback(async () => {\n // Basic validation\n if (!settings.profile.firstName.trim() || !settings.profile.lastName.trim()) {\n setSaveMessage(\n t('adaptercloud.settings.validation.nameRequired', 'First name and last name are required.')\n );\n setActiveTab('profile');\n return;\n }\n if (!settings.profile.email.trim() || !settings.profile.email.includes('@')) {\n setSaveMessage(\n t('adaptercloud.settings.validation.emailRequired', 'A valid email address is required.')\n );\n setActiveTab('profile');\n return;\n }\n\n setSaving(true);\n setSaveMessage('');\n // Simulate API\n await new Promise((r) => setTimeout(r, 1200));\n setSaving(false);\n setHasChanges(false);\n setSaveMessage(t('adaptercloud.settings.saveSuccess', 'Settings saved successfully!'));\n setTimeout(() => setSaveMessage(''), 3000);\n }, [settings, t]);\n\n const removeDevice = useCallback((id: string) => {\n setSettings((prev) => ({\n ...prev,\n security: {\n ...prev.security,\n trustedDevices: prev.security.trustedDevices.filter((d) => d.id !== id),\n },\n }));\n setHasChanges(true);\n }, []);\n\n const logoutAllDevices = useCallback(() => {\n setSettings((prev) => ({\n ...prev,\n security: {\n ...prev.security,\n trustedDevices: prev.security.trustedDevices.filter((d) => d.isCurrent),\n },\n }));\n setHasChanges(true);\n }, []);\n\n const handleDeleteAccount = useCallback(() => {\n if (\n window.confirm(\n t(\n 'adaptercloud.settings.deleteConfirm',\n 'Are you sure you want to delete your account? This action cannot be undone.'\n )\n )\n ) {\n alert(\n t(\n 'adaptercloud.settings.deleteSubmitted',\n 'Account deletion request submitted. You will receive a confirmation email.'\n )\n );\n }\n }, [t]);\n\n // ---- Profile Tab ----\n const renderProfile = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">Personal Information</h3>\n\n {/* Profile Picture */}\n <div className=\"flex items-center gap-4\">\n <div className=\"relative\">\n <img\n src={settings.profile.profilePicture}\n alt=\"Profile\"\n className=\"h-20 w-20 rounded-full object-cover border border-border-subtle\"\n />\n <button\n type=\"button\"\n onClick={() => alert('Photo upload coming soon')}\n className=\"absolute -bottom-1 -right-1 flex h-7 w-7 items-center justify-center rounded-full bg-action-primary-bg text-action-primary-text shadow-sm hover:bg-action-primary-bg/90\"\n >\n <Camera className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Profile Picture</p>\n <p className=\"text-xs text-text-secondary\">Upload a new photo (JPG, PNG, max 2MB)</p>\n </div>\n </div>\n\n {/* Name */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">First Name *</label>\n <input\n type=\"text\"\n value={settings.profile.firstName}\n onChange={(e) => update('profile', 'firstName', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Last Name *</label>\n <input\n type=\"text\"\n value={settings.profile.lastName}\n onChange={(e) => update('profile', 'lastName', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n\n {/* Email & Phone */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Email Address *\n </label>\n <input\n type=\"email\"\n value={settings.profile.email}\n onChange={(e) => update('profile', 'email', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Phone Number</label>\n <input\n type=\"tel\"\n value={settings.profile.phone}\n onChange={(e) => update('profile', 'phone', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n\n {/* Bio */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Bio</label>\n <textarea\n rows={3}\n value={settings.profile.bio}\n onChange={(e) => update('profile', 'bio', e.target.value)}\n placeholder=\"Tell us about yourself...\"\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n\n {/* DOB & Gender */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Date of Birth</label>\n <input\n type=\"date\"\n value={settings.profile.dateOfBirth}\n onChange={(e) => update('profile', 'dateOfBirth', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Gender</label>\n <select\n value={settings.profile.gender}\n onChange={(e) => update('profile', 'gender', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select gender</option>\n <option value=\"male\">Male</option>\n <option value=\"female\">Female</option>\n <option value=\"other\">Other</option>\n <option value=\"prefer-not-to-say\">Prefer not to say</option>\n </select>\n </div>\n </div>\n </div>\n );\n\n // ---- Preferences Tab ----\n const renderPreferences = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">App Preferences</h3>\n\n {/* Language, Timezone, Currency */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n <span className=\"flex items-center gap-1.5\">\n <Globe className=\"h-4 w-4 text-text-secondary\" /> Language\n </span>\n </label>\n <select\n value={settings.preferences.language}\n onChange={(e) => update('preferences', 'language', e.target.value as LanguageOption)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"en\">English</option>\n <option value=\"hi\">Hindi</option>\n <option value=\"ta\">Tamil</option>\n <option value=\"kn\">Kannada</option>\n <option value=\"te\">Telugu</option>\n <option value=\"ml\">Malayalam</option>\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Timezone</label>\n <select\n value={settings.preferences.timezone}\n onChange={(e) => update('preferences', 'timezone', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"Asia/Kolkata\">India (IST)</option>\n <option value=\"Asia/Dubai\">Dubai (GST)</option>\n <option value=\"Europe/London\">London (GMT)</option>\n <option value=\"America/New_York\">New York (EST)</option>\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Currency</label>\n <select\n value={settings.preferences.currency}\n onChange={(e) => update('preferences', 'currency', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"INR\">Indian Rupee (₹)</option>\n <option value=\"USD\">US Dollar ($)</option>\n <option value=\"EUR\">Euro (€)</option>\n <option value=\"GBP\">British Pound (£)</option>\n </select>\n </div>\n </div>\n\n {/* Theme */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-3\">Theme</label>\n <div className=\"flex gap-3 flex-wrap\">\n {(\n [\n { value: 'light', label: 'Light', Icon: Sun },\n { value: 'dark', label: 'Dark', Icon: Moon },\n { value: 'system', label: 'System', Icon: Monitor },\n ] as const\n ).map(({ value, label, Icon }) => (\n <label\n key={value}\n className={cn(\n 'flex items-center gap-2 rounded-lg border px-4 py-2.5 text-sm font-medium cursor-pointer transition-colors',\n settings.preferences.theme === value\n ? 'border-primary bg-action-primary-bg/10 text-text-primary'\n : 'border-border-subtle text-text-secondary hover:border-accent-foreground/20 hover:text-text-primary'\n )}\n >\n <input\n type=\"radio\"\n name=\"theme\"\n value={value}\n checked={settings.preferences.theme === value}\n onChange={(e) => update('preferences', 'theme', e.target.value as ThemeOption)}\n className=\"sr-only\"\n />\n <Icon className=\"h-4 w-4\" />\n {label}\n </label>\n ))}\n </div>\n </div>\n\n {/* Notification Toggles */}\n <div>\n <div className=\"flex items-center gap-2 mb-4\">\n <Bell className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-semibold text-text-primary\">Notification Preferences</h4>\n </div>\n <div className=\"space-y-3\">\n {(\n [\n { key: 'email', label: 'Email notifications' },\n { key: 'sms', label: 'SMS notifications' },\n { key: 'push', label: 'Push notifications' },\n { key: 'orderUpdates', label: 'Order status updates' },\n { key: 'promotions', label: 'Promotional offers' },\n { key: 'newsletters', label: 'Newsletters and updates' },\n { key: 'security', label: 'Security alerts' },\n ] as const\n ).map((item) => (\n <div\n key={item.key}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle p-3\"\n >\n <span className=\"text-sm text-text-primary\">{item.label}</span>\n <ToggleSwitch\n checked={settings.preferences.notifications[item.key]}\n onChange={(val) => updateNested('preferences', 'notifications', item.key, val)}\n label={item.label}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n\n // ---- Security Tab ----\n const renderSecurity = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">Security Settings</h3>\n\n {/* Warning banner */}\n <div className=\"flex items-start gap-3 rounded-lg border border-yellow-500/30 bg-yellow-500/5 p-4\">\n <AlertTriangle className=\"h-5 w-5 text-yellow-600 dark:text-yellow-400 shrink-0 mt-0.5\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Account Security</p>\n <p className=\"text-xs text-text-secondary\">\n Keep your account secure by enabling two-factor authentication and monitoring login\n activity.\n </p>\n </div>\n </div>\n\n {/* 2FA */}\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <Lock className=\"h-4 w-4 text-text-secondary\" />\n <p className=\"text-sm font-medium text-text-primary\">Two-Factor Authentication</p>\n </div>\n <p className=\"text-xs text-text-secondary mt-0.5 ml-6\">\n Add an extra layer of security to your account\n </p>\n </div>\n <ToggleSwitch\n checked={settings.security.twoFactorEnabled}\n onChange={(val) => update('security', 'twoFactorEnabled', val)}\n label=\"Two-factor authentication\"\n />\n </div>\n\n {/* Login Alerts */}\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">Login Alerts</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n Get notified when someone logs into your account\n </p>\n </div>\n <ToggleSwitch\n checked={settings.security.loginAlerts}\n onChange={(val) => update('security', 'loginAlerts', val)}\n label=\"Login alerts\"\n />\n </div>\n\n {/* Session Timeout */}\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">Session Timeout</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">Auto-logout after inactivity</p>\n </div>\n <select\n value={settings.security.sessionTimeout}\n onChange={(e) => update('security', 'sessionTimeout', e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] w-36\"\n >\n <option value=\"15\">15 minutes</option>\n <option value=\"30\">30 minutes</option>\n <option value=\"60\">1 hour</option>\n <option value=\"120\">2 hours</option>\n <option value=\"0\">Never</option>\n </select>\n </div>\n\n {/* Trusted Devices */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">Trusted Devices</h4>\n <div className=\"space-y-3\">\n {settings.security.trustedDevices.map((device) => (\n <div\n key={device.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\"\n >\n <div className=\"flex items-center gap-3\">\n {device.os.toLowerCase().includes('mac') ||\n device.os.toLowerCase().includes('windows') ? (\n <Laptop className=\"h-5 w-5 text-text-secondary shrink-0\" />\n ) : (\n <Smartphone className=\"h-5 w-5 text-text-secondary shrink-0\" />\n )}\n <div>\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm font-medium text-text-primary\">{device.name}</p>\n {device.isCurrent && (\n <span className=\"inline-flex items-center rounded-full bg-green-500/20 px-2 py-0.5 text-xs font-medium text-green-600 dark:text-green-400\">\n Current\n </span>\n )}\n </div>\n <p className=\"text-xs text-text-secondary\">\n {device.browser} · {device.os}\n </p>\n </div>\n </div>\n {!device.isCurrent && (\n <button\n type=\"button\"\n onClick={() => removeDevice(device.id)}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text hover:bg-status-error-bg/10 transition-colors\"\n >\n Remove\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-wrap gap-3\">\n <button\n type=\"button\"\n onClick={() => alert('Password change functionality coming soon')}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Lock className=\"h-4 w-4\" />\n Change Password\n </button>\n <button\n type=\"button\"\n onClick={logoutAllDevices}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <LogOut className=\"h-4 w-4\" />\n Logout All Devices\n </button>\n </div>\n </div>\n );\n\n // ---- Privacy Tab ----\n const renderPrivacy = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">Privacy Controls</h3>\n\n {/* Profile Visibility */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n <span className=\"flex items-center gap-1.5\">\n <Eye className=\"h-4 w-4 text-text-secondary\" /> Profile Visibility\n </span>\n </label>\n <select\n value={settings.privacy.profileVisibility}\n onChange={(e) =>\n update(\n 'privacy',\n 'profileVisibility',\n e.target.value as 'public' | 'private' | 'friends'\n )\n }\n className=\"w-full max-w-sm rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"public\">Public - Anyone can see your profile</option>\n <option value=\"private\">Private - Only you can see your profile</option>\n <option value=\"friends\">Friends - Only friends can see your profile</option>\n </select>\n </div>\n\n {/* Data Sharing */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">Data Sharing</h4>\n <div className=\"space-y-3\">\n {(\n [\n { key: 'analytics', label: 'Share usage analytics to improve the app' },\n { key: 'marketing', label: 'Share data for personalized marketing' },\n { key: 'thirdParty', label: 'Share data with third-party partners' },\n ] as const\n ).map((item) => (\n <div\n key={item.key}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle p-3\"\n >\n <span className=\"text-sm text-text-primary\">{item.label}</span>\n <ToggleSwitch\n checked={settings.privacy.dataSharing[item.key]}\n onChange={(val) => updateNested('privacy', 'dataSharing', item.key, val)}\n label={item.label}\n />\n </div>\n ))}\n </div>\n </div>\n\n {/* Location & Activity */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Location Tracking</p>\n <p className=\"text-xs text-text-secondary\">\n Allow app to track your location for better service\n </p>\n </div>\n <ToggleSwitch\n checked={settings.privacy.locationTracking}\n onChange={(val) => update('privacy', 'locationTracking', val)}\n label=\"Location tracking\"\n />\n </div>\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Activity History</p>\n <p className=\"text-xs text-text-secondary\">\n Keep track of your orders and activities\n </p>\n </div>\n <ToggleSwitch\n checked={settings.privacy.activityHistory}\n onChange={(val) => update('privacy', 'activityHistory', val)}\n label=\"Activity history\"\n />\n </div>\n </div>\n\n {/* Delete Account */}\n <div className=\"rounded-lg border border-red-500/30 bg-red-500/5 p-4\">\n <div className=\"flex items-start gap-3\">\n <Trash2 className=\"h-5 w-5 text-red-600 dark:text-red-400 shrink-0 mt-0.5\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Delete Account</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n Permanently delete your account and all associated data. This action cannot be undone.\n </p>\n <button\n type=\"button\"\n onClick={handleDeleteAccount}\n className=\"mt-3 rounded-lg border border-red-500/30 px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/10 transition-colors\"\n >\n Delete Account\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n\n // ---- Billing Tab ----\n const renderBilling = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">Billing & Payments</h3>\n\n {/* Default Payment Method */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">\n <span className=\"flex items-center gap-1.5\">\n <CreditCard className=\"h-4 w-4 text-text-secondary\" /> Default Payment Method\n </span>\n </h4>\n {settings.billing.paymentMethod ? (\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div className=\"flex items-center gap-3\">\n <CreditCard className=\"h-6 w-6 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {settings.billing.paymentMethod.provider} ending in{' '}\n {settings.billing.paymentMethod.last4}\n </p>\n <p className=\"text-xs text-text-secondary capitalize\">\n {settings.billing.paymentMethod.type}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => alert('Change payment method coming soon')}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Change\n </button>\n </div>\n ) : (\n <div className=\"rounded-lg border border-border-subtle p-4 text-center\">\n <p className=\"text-sm text-text-secondary\">No default payment method set</p>\n <button\n type=\"button\"\n onClick={() => alert('Add payment method coming soon')}\n className=\"mt-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n Add Payment Method\n </button>\n </div>\n )}\n </div>\n\n {/* Auto Recharge */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">Auto Recharge</h4>\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4 mb-3\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Enable Auto Recharge</p>\n <p className=\"text-xs text-text-secondary\">\n Automatically add money when wallet balance is low\n </p>\n </div>\n <ToggleSwitch\n checked={settings.billing.autoRecharge}\n onChange={(val) => update('billing', 'autoRecharge', val)}\n label=\"Auto recharge\"\n />\n </div>\n {settings.billing.autoRecharge && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Auto Recharge Amount (₹)\n </label>\n <input\n type=\"number\"\n value={settings.billing.autoRechargeAmount}\n onChange={(e) => update('billing', 'autoRechargeAmount', e.target.value)}\n placeholder=\"1000\"\n className=\"w-full max-w-xs rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n )}\n </div>\n\n {/* Invoice Email */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n <span className=\"flex items-center gap-1.5\">\n <Receipt className=\"h-4 w-4 text-text-secondary\" /> Invoice Email\n </span>\n </label>\n <input\n type=\"email\"\n value={settings.billing.invoiceEmail}\n onChange={(e) => update('billing', 'invoiceEmail', e.target.value)}\n placeholder=\"billing@example.com\"\n className=\"w-full max-w-sm rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n {/* Tax Info */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">\n <span className=\"flex items-center gap-1.5\">\n <Building2 className=\"h-4 w-4 text-text-secondary\" /> Tax Information\n </span>\n </h4>\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">GST Number</label>\n <input\n type=\"text\"\n value={settings.billing.gstNumber}\n onChange={(e) => update('billing', 'gstNumber', e.target.value)}\n placeholder=\"29ABCDE1234F1Z5\"\n className=\"w-full max-w-sm rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Company Name</label>\n <input\n type=\"text\"\n value={settings.billing.companyName}\n onChange={(e) => update('billing', 'companyName', e.target.value)}\n placeholder=\"Your Company Name\"\n className=\"w-full max-w-sm rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n <span className=\"flex items-center gap-1.5\">\n <MapPin className=\"h-4 w-4 text-text-secondary\" /> Billing Address\n </span>\n </label>\n <textarea\n rows={3}\n value={settings.billing.billingAddress}\n onChange={(e) => update('billing', 'billingAddress', e.target.value)}\n placeholder=\"Enter your complete billing address\"\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n </div>\n </div>\n </div>\n );\n\n // ---- Render function map ----\n const renderTab: Record<TabId, () => React.ReactNode> = {\n profile: renderProfile,\n preferences: renderPreferences,\n security: renderSecurity,\n privacy: renderPrivacy,\n billing: renderBilling,\n };\n\n return (\n <PageLayout\n title={t('adaptercloud.settings.title', 'Settings')}\n description={t(\n 'adaptercloud.settings.description',\n 'Manage your preferences and account settings'\n )}\n actions={\n <div className=\"flex items-center gap-2\">\n {hasChanges && (\n <button\n type=\"button\"\n onClick={resetSettings}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n {t('adaptercloud.settings.reset', 'Reset')}\n </button>\n )}\n <button\n type=\"button\"\n disabled={!hasChanges || saving}\n onClick={saveSettings}\n className={cn(\n 'flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium transition-colors',\n hasChanges && !saving\n ? 'bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90'\n : 'bg-bg-sunken text-text-secondary cursor-not-allowed'\n )}\n >\n {saving ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n {t('adaptercloud.settings.saving', 'Saving...')}\n </>\n ) : (\n <>\n <Save className=\"h-4 w-4\" />\n {t('adaptercloud.settings.save', 'Save Settings')}\n </>\n )}\n </button>\n </div>\n }\n >\n {/* Save message */}\n {saveMessage && (\n <div\n className={cn(\n 'mb-6 flex items-center gap-2 rounded-lg border p-3 text-sm',\n saveMessage.includes('successfully')\n ? 'border-green-500/30 bg-green-500/5 text-green-600 dark:text-green-400'\n : 'border-red-500/30 bg-red-500/5 text-red-600 dark:text-red-400'\n )}\n >\n {saveMessage.includes('successfully') ? (\n <CheckCircle2 className=\"h-4 w-4 shrink-0\" />\n ) : (\n <AlertTriangle className=\"h-4 w-4 shrink-0\" />\n )}\n {saveMessage}\n </div>\n )}\n\n <div className=\"flex flex-col gap-6 lg:flex-row\">\n {/* Sidebar (Desktop) / Tab Row (Mobile) */}\n <div className=\"shrink-0 lg:w-56\">\n {/* Mobile grid */}\n <div className=\"grid grid-cols-5 gap-1 lg:hidden\">\n {localizedTabConfig.map((tab) => {\n const TabIcon = tab.icon;\n return (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex flex-col items-center gap-1 rounded-lg py-2.5 text-center transition-colors',\n activeTab === tab.id\n ? 'bg-action-primary-bg/10 text-text-primary'\n : 'text-text-secondary hover:text-text-primary hover:bg-accent'\n )}\n >\n <TabIcon className=\"h-4 w-4\" />\n <span className=\"text-xs font-medium\">{tab.label}</span>\n </button>\n );\n })}\n </div>\n {/* Desktop sidebar */}\n <div className=\"hidden lg:block rounded-lg border border-border-subtle bg-bg-surface\">\n <div className=\"p-3 border-b border-border-subtle\">\n <p className=\"text-sm font-semibold text-text-primary\">\n {t('adaptercloud.settings.title', 'Settings')}\n </p>\n </div>\n <nav className=\"p-2\">\n {localizedTabConfig.map((tab) => {\n const TabIcon = tab.icon;\n return (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-sm font-medium transition-colors mb-0.5',\n activeTab === tab.id\n ? 'bg-action-primary-bg/10 text-text-primary'\n : 'text-text-secondary hover:text-text-primary hover:bg-accent'\n )}\n >\n <TabIcon className=\"h-4 w-4\" />\n {tab.label}\n </button>\n );\n })}\n </nav>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 rounded-lg border border-border-subtle bg-bg-surface p-6\">\n {renderTab[activeTab]()}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SettingsPage.js","names":[],"sources":["../../../../src/adaptercloud/pages/common/SettingsPage.tsx"],"sourcesContent":["/**\n * Settings Page\n * @module adaptercloud/pages/common\n *\n * Full-featured settings with 5 tabs: Profile, Preferences, Security,\n * Privacy, and Billing. Form validation, save state, sidebar navigation.\n */\n\nimport { useState, useCallback, useMemo } from'react';\nimport { useI18n } from'@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n User,\n Settings,\n Sun,\n Moon,\n Monitor,\n Globe,\n Bell,\n Shield,\n Eye,\n EyeOff,\n Save,\n RotateCcw,\n Lock,\n Smartphone,\n Laptop,\n LogOut,\n Trash2,\n CreditCard,\n Receipt,\n Building2,\n MapPin,\n Camera,\n AlertTriangle,\n CheckCircle2,\n Loader2,\n} from'lucide-react';\nimport { PageLayout } from'../../components/PageLayout';\nimport { useAdapterCloud } from'../../context/AdapterCloudContext';\nimport { cn } from'../../utils/cn';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype ThemeOption = 'light' | 'dark' | 'system';\ntype LanguageOption = 'en' | 'ta' | 'hi' | 'kn' | 'te' | 'ml';\ntype TabId = 'profile' | 'preferences' | 'security' | 'privacy' | 'billing';\n\ninterface TrustedDevice {\n id: string;\n name: string;\n browser: string;\n os: string;\n lastActive: string;\n isCurrent: boolean;\n}\n\ninterface UserSettings {\n profile: {\n firstName: string;\n lastName: string;\n email: string;\n phone: string;\n bio: string;\n dateOfBirth: string;\n gender: string;\n profilePicture: string;\n };\n preferences: {\n theme: ThemeOption;\n language: LanguageOption;\n timezone: string;\n currency: string;\n notifications: {\n email: boolean;\n sms: boolean;\n push: boolean;\n orderUpdates: boolean;\n promotions: boolean;\n newsletters: boolean;\n security: boolean;\n };\n };\n security: {\n twoFactorEnabled: boolean;\n loginAlerts: boolean;\n sessionTimeout: string;\n trustedDevices: TrustedDevice[];\n };\n privacy: {\n profileVisibility: 'public' | 'private' | 'friends';\n dataSharing: {\n analytics: boolean;\n marketing: boolean;\n thirdParty: boolean;\n };\n locationTracking: boolean;\n activityHistory: boolean;\n };\n billing: {\n paymentMethod: { type: string; last4: string; provider: string } | null;\n autoRecharge: boolean;\n autoRechargeAmount: string;\n invoiceEmail: string;\n gstNumber: string;\n companyName: string;\n billingAddress: string;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst defaultSettings: UserSettings = {\n profile: {\n firstName: 'Priya',\n lastName: 'Customer',\n email: 'customer@burdenoff.com',\n phone: '+91 98765 43220',\n bio: 'Food enthusiast and tech lover. Always exploring new services and experiences in Bangalore.',\n dateOfBirth: '1992-08-15',\n gender: 'female',\n profilePicture: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=200',\n },\n preferences: {\n theme: 'system',\n language: 'en',\n timezone: 'Asia/Kolkata',\n currency: 'INR',\n notifications: {\n email: true,\n sms: true,\n push: true,\n orderUpdates: true,\n promotions: false,\n newsletters: false,\n security: true,\n },\n },\n security: {\n twoFactorEnabled: false,\n loginAlerts: true,\n sessionTimeout: '30',\n trustedDevices: [\n {\n id: 'dev-1',\n name: 'MacBook Pro',\n browser: 'Chrome 126.0',\n os: 'macOS Sonoma',\n lastActive: '2024-06-24T09:30:00Z',\n isCurrent: true,\n },\n {\n id: 'dev-2',\n name: 'iPhone 15',\n browser: 'Safari Mobile',\n os: 'iOS 17.5',\n lastActive: '2024-06-23T18:45:00Z',\n isCurrent: false,\n },\n {\n id: 'dev-3',\n name: 'Samsung Galaxy S24',\n browser: 'Chrome Mobile',\n os: 'Android 14',\n lastActive: '2024-06-20T12:00:00Z',\n isCurrent: false,\n },\n ],\n },\n privacy: {\n profileVisibility: 'private',\n dataSharing: {\n analytics: true,\n marketing: false,\n thirdParty: false,\n },\n locationTracking: true,\n activityHistory: true,\n },\n billing: {\n paymentMethod: { type: 'card', last4: '4532', provider: 'Visa' },\n autoRecharge: false,\n autoRechargeAmount: '1000',\n invoiceEmail: 'customer@burdenoff.com',\n gstNumber: '29ABCDE1234F1Z5',\n companyName: '',\n billingAddress: '123 Tech Park, Koramangala, Bangalore 560034',\n },\n};\n\n// ---------------------------------------------------------------------------\n// Tab config\n// ---------------------------------------------------------------------------\n\nconst tabConfig: { id: TabId; label: string; icon: typeof User }[] = [\n { id: 'profile', label: 'Profile', icon: User },\n { id: 'preferences', label: 'Preferences', icon: Settings },\n { id: 'security', label: 'Security', icon: Shield },\n { id: 'privacy', label: 'Privacy', icon: Eye },\n { id: 'billing', label: 'Billing', icon: CreditCard },\n];\n\n// ---------------------------------------------------------------------------\n// Toggle Switch component (inline)\n// ---------------------------------------------------------------------------\n\nfunction ToggleSwitch({\n checked,\n onChange,\n label,\n}: {\n checked: boolean;\n onChange: (val: boolean) => void;\n label?: string;\n}) {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n aria-label={label}\n onClick={() => onChange(!checked)}\n className={cn(\n 'relative inline-flex h-6 w-11 items-center rounded-full transition-colors shrink-0',\n checked ? 'bg-action-primary-bg' : 'bg-bg-sunken'\n )}\n >\n <span\n className={cn(\n 'inline-block h-4 w-4 transform rounded-full bg-white transition-transform',\n checked ? 'translate-x-6' : 'translate-x-1'\n )}\n />\n </button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function SettingsPage() {\n const { currentUser } = useAdapterCloud();\n const { t: translate } = useI18n();\n const [activeTab, setActiveTab] = useState<TabId>('profile');\n const [settings, setSettings] = useState<UserSettings>(() => {\n const s = { ...defaultSettings };\n if (currentUser?.firstName) s.profile.firstName = currentUser.firstName;\n if (currentUser?.lastName) s.profile.lastName = currentUser.lastName;\n if (currentUser?.email) s.profile.email = currentUser.email;\n return s;\n });\n const [hasChanges, setHasChanges] = useState(false);\n const [saving, setSaving] = useState(false);\n const [saveMessage, setSaveMessage] = useState('');\n const t = useCallback(\n (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n const localizedTabConfig = useMemo(\n () =>\n tabConfig.map((tab) => ({\n ...tab,\n label:\n tab.id === 'profile'\n ? t('adaptercloud.settings.tabs.profile', 'Profile')\n : tab.id === 'preferences'\n ? t('adaptercloud.settings.tabs.preferences', 'Preferences')\n : tab.id === 'security'\n ? t('adaptercloud.settings.tabs.security', 'Security')\n : tab.id === 'privacy'\n ? t('adaptercloud.settings.tabs.privacy', 'Privacy')\n : t('adaptercloud.settings.tabs.billing', 'Billing'),\n })),\n [t]\n );\n\n // Deep update helper\n const update = useCallback(\n <S extends keyof UserSettings, F extends keyof UserSettings[S]>(\n section: S,\n field: F,\n value: UserSettings[S][F]\n ) => {\n setSettings((prev) => ({\n ...prev,\n [section]: { ...prev[section], [field]: value },\n }));\n setHasChanges(true);\n setSaveMessage('');\n },\n []\n );\n\n const updateNested = useCallback(\n (section: keyof UserSettings, sub: string, field: string, value: boolean | string) => {\n setSettings((prev) => ({\n ...prev,\n [section]: {\n ...prev[section],\n [sub]: {\n ...((prev[section] as Record<string, unknown>)[sub] as Record<string, unknown>),\n [field]: value,\n },\n },\n }));\n setHasChanges(true);\n setSaveMessage('');\n },\n []\n );\n\n const resetSettings = useCallback(() => {\n setSettings(defaultSettings);\n setHasChanges(false);\n setSaveMessage('');\n }, []);\n\n const saveSettings = useCallback(async () => {\n // Basic validation\n if (!settings.profile.firstName.trim() || !settings.profile.lastName.trim()) {\n setSaveMessage(\n t('adaptercloud.settings.validation.nameRequired', 'First name and last name are required.')\n );\n setActiveTab('profile');\n return;\n }\n if (!settings.profile.email.trim() || !settings.profile.email.includes('@')) {\n setSaveMessage(\n t('adaptercloud.settings.validation.emailRequired', 'A valid email address is required.')\n );\n setActiveTab('profile');\n return;\n }\n\n setSaving(true);\n setSaveMessage('');\n // Simulate API\n await new Promise((r) => setTimeout(r, 1200));\n setSaving(false);\n setHasChanges(false);\n setSaveMessage(t('adaptercloud.settings.saveSuccess', 'Settings saved successfully!'));\n setTimeout(() => setSaveMessage(''), 3000);\n }, [settings, t]);\n\n const removeDevice = useCallback((id: string) => {\n setSettings((prev) => ({\n ...prev,\n security: {\n ...prev.security,\n trustedDevices: prev.security.trustedDevices.filter((d) => d.id !== id),\n },\n }));\n setHasChanges(true);\n }, []);\n\n const logoutAllDevices = useCallback(() => {\n setSettings((prev) => ({\n ...prev,\n security: {\n ...prev.security,\n trustedDevices: prev.security.trustedDevices.filter((d) => d.isCurrent),\n },\n }));\n setHasChanges(true);\n }, []);\n\n const handleDeleteAccount = useCallback(() => {\n if (\n window.confirm(\n t(\n 'adaptercloud.settings.deleteConfirm',\n 'Are you sure you want to delete your account? This action cannot be undone.'\n )\n )\n ) {\n alert(\n t(\n 'adaptercloud.settings.deleteSubmitted',\n 'Account deletion request submitted. You will receive a confirmation email.'\n )\n );\n }\n }, [t]);\n\n // ---- Profile Tab ----\n const renderProfile = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">Personal Information</h3>\n\n {/* Profile Picture */}\n <div className=\"flex items-center gap-4\">\n <div className=\"relative\">\n <img\n src={settings.profile.profilePicture}\n alt=\"Profile\"\n className=\"h-20 w-20 rounded-full object-cover border border-border-subtle\"\n />\n <button\n type=\"button\"\n onClick={() => alert('Photo upload coming soon')}\n className=\"absolute -bottom-1 -right-1 flex h-7 w-7 items-center justify-center rounded-full bg-action-primary-bg text-action-primary-text shadow-sm hover:bg-action-primary-bg/90\"\n >\n <Camera className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Profile Picture</p>\n <p className=\"text-xs text-text-secondary\">Upload a new photo (JPG, PNG, max 2MB)</p>\n </div>\n </div>\n\n {/* Name */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">First Name *</label>\n <input\n type=\"text\"\n value={settings.profile.firstName}\n onChange={(e) => update('profile', 'firstName', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Last Name *</label>\n <input\n type=\"text\"\n value={settings.profile.lastName}\n onChange={(e) => update('profile', 'lastName', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n\n {/* Email & Phone */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Email Address *\n </label>\n <input\n type=\"email\"\n value={settings.profile.email}\n onChange={(e) => update('profile', 'email', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Phone Number</label>\n <input\n type=\"tel\"\n value={settings.profile.phone}\n onChange={(e) => update('profile', 'phone', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n\n {/* Bio */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Bio</label>\n <textarea\n rows={3}\n value={settings.profile.bio}\n onChange={(e) => update('profile', 'bio', e.target.value)}\n placeholder=\"Tell us about yourself...\"\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n\n {/* DOB & Gender */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Date of Birth</label>\n <input\n type=\"date\"\n value={settings.profile.dateOfBirth}\n onChange={(e) => update('profile', 'dateOfBirth', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Gender</label>\n <select\n value={settings.profile.gender}\n onChange={(e) => update('profile', 'gender', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Select gender</option>\n <option value=\"male\">Male</option>\n <option value=\"female\">Female</option>\n <option value=\"other\">Other</option>\n <option value=\"prefer-not-to-say\">Prefer not to say</option>\n </select>\n </div>\n </div>\n </div>\n );\n\n // ---- Preferences Tab ----\n const renderPreferences = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">App Preferences</h3>\n\n {/* Language, Timezone, Currency */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n <span className=\"flex items-center gap-1.5\">\n <Globe className=\"h-4 w-4 text-text-secondary\" /> Language\n </span>\n </label>\n <select\n value={settings.preferences.language}\n onChange={(e) => update('preferences', 'language', e.target.value as LanguageOption)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"en\">English</option>\n <option value=\"hi\">Hindi</option>\n <option value=\"ta\">Tamil</option>\n <option value=\"kn\">Kannada</option>\n <option value=\"te\">Telugu</option>\n <option value=\"ml\">Malayalam</option>\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Timezone</label>\n <select\n value={settings.preferences.timezone}\n onChange={(e) => update('preferences', 'timezone', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"Asia/Kolkata\">India (IST)</option>\n <option value=\"Asia/Dubai\">Dubai (GST)</option>\n <option value=\"Europe/London\">London (GMT)</option>\n <option value=\"America/New_York\">New York (EST)</option>\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Currency</label>\n <select\n value={settings.preferences.currency}\n onChange={(e) => update('preferences', 'currency', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"INR\">Indian Rupee (₹)</option>\n <option value=\"USD\">US Dollar ($)</option>\n <option value=\"EUR\">Euro (€)</option>\n <option value=\"GBP\">British Pound (£)</option>\n </select>\n </div>\n </div>\n\n {/* Theme */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-3\">Theme</label>\n <div className=\"flex gap-3 flex-wrap\">\n {(\n [\n { value: 'light', label: 'Light', Icon: Sun },\n { value: 'dark', label: 'Dark', Icon: Moon },\n { value: 'system', label: 'System', Icon: Monitor },\n ] as const\n ).map(({ value, label, Icon }) => (\n <label\n key={value}\n className={cn(\n 'flex items-center gap-2 rounded-lg border px-4 py-2.5 text-sm font-medium cursor-pointer transition-colors',\n settings.preferences.theme === value\n ? 'border-primary bg-action-primary-bg/10 text-text-primary'\n : 'border-border-subtle text-text-secondary hover:border-accent-foreground/20 hover:text-text-primary'\n )}\n >\n <input\n type=\"radio\"\n name=\"theme\"\n value={value}\n checked={settings.preferences.theme === value}\n onChange={(e) => update('preferences', 'theme', e.target.value as ThemeOption)}\n className=\"sr-only\"\n />\n <Icon className=\"h-4 w-4\" />\n {label}\n </label>\n ))}\n </div>\n </div>\n\n {/* Notification Toggles */}\n <div>\n <div className=\"flex items-center gap-2 mb-4\">\n <Bell className=\"h-4 w-4 text-text-secondary\" />\n <h4 className=\"text-sm font-semibold text-text-primary\">Notification Preferences</h4>\n </div>\n <div className=\"space-y-3\">\n {(\n [\n { key: 'email', label: 'Email notifications' },\n { key: 'sms', label: 'SMS notifications' },\n { key: 'push', label: 'Push notifications' },\n { key: 'orderUpdates', label: 'Order status updates' },\n { key: 'promotions', label: 'Promotional offers' },\n { key: 'newsletters', label: 'Newsletters and updates' },\n { key: 'security', label: 'Security alerts' },\n ] as const\n ).map((item) => (\n <div\n key={item.key}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle p-3\"\n >\n <span className=\"text-sm text-text-primary\">{item.label}</span>\n <ToggleSwitch\n checked={settings.preferences.notifications[item.key]}\n onChange={(val) => updateNested('preferences', 'notifications', item.key, val)}\n label={item.label}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n\n // ---- Security Tab ----\n const renderSecurity = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">Security Settings</h3>\n\n {/* Warning banner */}\n <div className=\"flex items-start gap-3 rounded-lg border border-status-warning-border/30 bg-status-warning-bg-subtle/5 p-4\">\n <AlertTriangle className=\"h-5 w-5 text-status-warning-text shrink-0 mt-0.5\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Account Security</p>\n <p className=\"text-xs text-text-secondary\">\n Keep your account secure by enabling two-factor authentication and monitoring login\n activity.\n </p>\n </div>\n </div>\n\n {/* 2FA */}\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <Lock className=\"h-4 w-4 text-text-secondary\" />\n <p className=\"text-sm font-medium text-text-primary\">Two-Factor Authentication</p>\n </div>\n <p className=\"text-xs text-text-secondary mt-0.5 ml-6\">\n Add an extra layer of security to your account\n </p>\n </div>\n <ToggleSwitch\n checked={settings.security.twoFactorEnabled}\n onChange={(val) => update('security', 'twoFactorEnabled', val)}\n label=\"Two-factor authentication\"\n />\n </div>\n\n {/* Login Alerts */}\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">Login Alerts</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n Get notified when someone logs into your account\n </p>\n </div>\n <ToggleSwitch\n checked={settings.security.loginAlerts}\n onChange={(val) => update('security', 'loginAlerts', val)}\n label=\"Login alerts\"\n />\n </div>\n\n {/* Session Timeout */}\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">Session Timeout</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">Auto-logout after inactivity</p>\n </div>\n <select\n value={settings.security.sessionTimeout}\n onChange={(e) => update('security', 'sessionTimeout', e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] w-36\"\n >\n <option value=\"15\">15 minutes</option>\n <option value=\"30\">30 minutes</option>\n <option value=\"60\">1 hour</option>\n <option value=\"120\">2 hours</option>\n <option value=\"0\">Never</option>\n </select>\n </div>\n\n {/* Trusted Devices */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">Trusted Devices</h4>\n <div className=\"space-y-3\">\n {settings.security.trustedDevices.map((device) => (\n <div\n key={device.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\"\n >\n <div className=\"flex items-center gap-3\">\n {device.os.toLowerCase().includes('mac') ||\n device.os.toLowerCase().includes('windows') ? (\n <Laptop className=\"h-5 w-5 text-text-secondary shrink-0\" />\n ) : (\n <Smartphone className=\"h-5 w-5 text-text-secondary shrink-0\" />\n )}\n <div>\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm font-medium text-text-primary\">{device.name}</p>\n {device.isCurrent && (\n <span className=\"inline-flex items-center rounded-full bg-status-success-bg-subtle/20 px-2 py-0.5 text-xs font-medium text-status-success-text\">\n Current\n </span>\n )}\n </div>\n <p className=\"text-xs text-text-secondary\">\n {device.browser} · {device.os}\n </p>\n </div>\n </div>\n {!device.isCurrent && (\n <button\n type=\"button\"\n onClick={() => removeDevice(device.id)}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text hover:bg-status-error-bg/10 transition-colors\"\n >\n Remove\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-wrap gap-3\">\n <button\n type=\"button\"\n onClick={() => alert('Password change functionality coming soon')}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Lock className=\"h-4 w-4\" />\n Change Password\n </button>\n <button\n type=\"button\"\n onClick={logoutAllDevices}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <LogOut className=\"h-4 w-4\" />\n Logout All Devices\n </button>\n </div>\n </div>\n );\n\n // ---- Privacy Tab ----\n const renderPrivacy = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">Privacy Controls</h3>\n\n {/* Profile Visibility */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n <span className=\"flex items-center gap-1.5\">\n <Eye className=\"h-4 w-4 text-text-secondary\" /> Profile Visibility\n </span>\n </label>\n <select\n value={settings.privacy.profileVisibility}\n onChange={(e) =>\n update(\n 'privacy',\n 'profileVisibility',\n e.target.value as'public' | 'private' | 'friends'\n )\n }\n className=\"w-full max-w-sm rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"public\">Public - Anyone can see your profile</option>\n <option value=\"private\">Private - Only you can see your profile</option>\n <option value=\"friends\">Friends - Only friends can see your profile</option>\n </select>\n </div>\n\n {/* Data Sharing */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">Data Sharing</h4>\n <div className=\"space-y-3\">\n {(\n [\n { key: 'analytics', label: 'Share usage analytics to improve the app' },\n { key: 'marketing', label: 'Share data for personalized marketing' },\n { key: 'thirdParty', label: 'Share data with third-party partners' },\n ] as const\n ).map((item) => (\n <div\n key={item.key}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle p-3\"\n >\n <span className=\"text-sm text-text-primary\">{item.label}</span>\n <ToggleSwitch\n checked={settings.privacy.dataSharing[item.key]}\n onChange={(val) => updateNested('privacy', 'dataSharing', item.key, val)}\n label={item.label}\n />\n </div>\n ))}\n </div>\n </div>\n\n {/* Location & Activity */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Location Tracking</p>\n <p className=\"text-xs text-text-secondary\">\n Allow app to track your location for better service\n </p>\n </div>\n <ToggleSwitch\n checked={settings.privacy.locationTracking}\n onChange={(val) => update('privacy', 'locationTracking', val)}\n label=\"Location tracking\"\n />\n </div>\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Activity History</p>\n <p className=\"text-xs text-text-secondary\">\n Keep track of your orders and activities\n </p>\n </div>\n <ToggleSwitch\n checked={settings.privacy.activityHistory}\n onChange={(val) => update('privacy', 'activityHistory', val)}\n label=\"Activity history\"\n />\n </div>\n </div>\n\n {/* Delete Account */}\n <div className=\"rounded-lg border border-status-error-border/30 bg-status-error-bg-subtle/5 p-4\">\n <div className=\"flex items-start gap-3\">\n <Trash2 className=\"h-5 w-5 text-status-error-text shrink-0 mt-0.5\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Delete Account</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n Permanently delete your account and all associated data. This action cannot be undone.\n </p>\n <button\n type=\"button\"\n onClick={handleDeleteAccount}\n className=\"mt-3 rounded-lg border border-status-error-border/30 px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/10 transition-colors\"\n >\n Delete Account\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n\n // ---- Billing Tab ----\n const renderBilling = () => (\n <div className=\"space-y-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">Billing & Payments</h3>\n\n {/* Default Payment Method */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">\n <span className=\"flex items-center gap-1.5\">\n <CreditCard className=\"h-4 w-4 text-text-secondary\" /> Default Payment Method\n </span>\n </h4>\n {settings.billing.paymentMethod ? (\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4\">\n <div className=\"flex items-center gap-3\">\n <CreditCard className=\"h-6 w-6 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {settings.billing.paymentMethod.provider} ending in{' '}\n {settings.billing.paymentMethod.last4}\n </p>\n <p className=\"text-xs text-text-secondary capitalize\">\n {settings.billing.paymentMethod.type}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => alert('Change payment method coming soon')}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Change\n </button>\n </div>\n ) : (\n <div className=\"rounded-lg border border-border-subtle p-4 text-center\">\n <p className=\"text-sm text-text-secondary\">No default payment method set</p>\n <button\n type=\"button\"\n onClick={() => alert('Add payment method coming soon')}\n className=\"mt-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n Add Payment Method\n </button>\n </div>\n )}\n </div>\n\n {/* Auto Recharge */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">Auto Recharge</h4>\n <div className=\"flex items-center justify-between rounded-lg border border-border-subtle p-4 mb-3\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Enable Auto Recharge</p>\n <p className=\"text-xs text-text-secondary\">\n Automatically add money when wallet balance is low\n </p>\n </div>\n <ToggleSwitch\n checked={settings.billing.autoRecharge}\n onChange={(val) => update('billing', 'autoRecharge', val)}\n label=\"Auto recharge\"\n />\n </div>\n {settings.billing.autoRecharge && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Auto Recharge Amount (₹)\n </label>\n <input\n type=\"number\"\n value={settings.billing.autoRechargeAmount}\n onChange={(e) => update('billing', 'autoRechargeAmount', e.target.value)}\n placeholder=\"1000\"\n className=\"w-full max-w-xs rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n )}\n </div>\n\n {/* Invoice Email */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n <span className=\"flex items-center gap-1.5\">\n <Receipt className=\"h-4 w-4 text-text-secondary\" /> Invoice Email\n </span>\n </label>\n <input\n type=\"email\"\n value={settings.billing.invoiceEmail}\n onChange={(e) => update('billing', 'invoiceEmail', e.target.value)}\n placeholder=\"billing@example.com\"\n className=\"w-full max-w-sm rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n {/* Tax Info */}\n <div>\n <h4 className=\"text-sm font-semibold text-text-primary mb-3\">\n <span className=\"flex items-center gap-1.5\">\n <Building2 className=\"h-4 w-4 text-text-secondary\" /> Tax Information\n </span>\n </h4>\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">GST Number</label>\n <input\n type=\"text\"\n value={settings.billing.gstNumber}\n onChange={(e) => update('billing', 'gstNumber', e.target.value)}\n placeholder=\"29ABCDE1234F1Z5\"\n className=\"w-full max-w-sm rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">Company Name</label>\n <input\n type=\"text\"\n value={settings.billing.companyName}\n onChange={(e) => update('billing', 'companyName', e.target.value)}\n placeholder=\"Your Company Name\"\n className=\"w-full max-w-sm rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n <span className=\"flex items-center gap-1.5\">\n <MapPin className=\"h-4 w-4 text-text-secondary\" /> Billing Address\n </span>\n </label>\n <textarea\n rows={3}\n value={settings.billing.billingAddress}\n onChange={(e) => update('billing', 'billingAddress', e.target.value)}\n placeholder=\"Enter your complete billing address\"\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n </div>\n </div>\n </div>\n );\n\n // ---- Render function map ----\n const renderTab: Record<TabId, () => React.ReactNode> = {\n profile: renderProfile,\n preferences: renderPreferences,\n security: renderSecurity,\n privacy: renderPrivacy,\n billing: renderBilling,\n };\n\n return (\n <PageLayout\n title={t('adaptercloud.settings.title', 'Settings')}\n description={t(\n 'adaptercloud.settings.description',\n 'Manage your preferences and account settings'\n )}\n actions={\n <div className=\"flex items-center gap-2\">\n {hasChanges && (\n <button\n type=\"button\"\n onClick={resetSettings}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n {t('adaptercloud.settings.reset', 'Reset')}\n </button>\n )}\n <button\n type=\"button\"\n disabled={!hasChanges || saving}\n onClick={saveSettings}\n className={cn(\n 'flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium transition-colors',\n hasChanges && !saving\n ? 'bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90'\n : 'bg-bg-sunken text-text-secondary cursor-not-allowed'\n )}\n >\n {saving ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n {t('adaptercloud.settings.saving', 'Saving...')}\n </>\n ) : (\n <>\n <Save className=\"h-4 w-4\" />\n {t('adaptercloud.settings.save', 'Save Settings')}\n </>\n )}\n </button>\n </div>\n }\n >\n {/* Save message */}\n {saveMessage && (\n <div\n className={cn(\n 'mb-6 flex items-center gap-2 rounded-lg border p-3 text-sm',\n saveMessage.includes('successfully')\n ? 'border-status-success-border/30 bg-status-success-bg-subtle/5 text-status-success-text'\n : 'border-status-error-border/30 bg-status-error-bg-subtle/5 text-status-error-text'\n )}\n >\n {saveMessage.includes('successfully') ? (\n <CheckCircle2 className=\"h-4 w-4 shrink-0\" />\n ) : (\n <AlertTriangle className=\"h-4 w-4 shrink-0\" />\n )}\n {saveMessage}\n </div>\n )}\n\n <div className=\"flex flex-col gap-6 lg:flex-row\">\n {/* Sidebar (Desktop) / Tab Row (Mobile) */}\n <div className=\"shrink-0 lg:w-56\">\n {/* Mobile grid */}\n <div className=\"grid grid-cols-5 gap-1 lg:hidden\">\n {localizedTabConfig.map((tab) => {\n const TabIcon = tab.icon;\n return (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex flex-col items-center gap-1 rounded-lg py-2.5 text-center transition-colors',\n activeTab === tab.id\n ? 'bg-action-primary-bg/10 text-text-primary'\n : 'text-text-secondary hover:text-text-primary hover:bg-accent'\n )}\n >\n <TabIcon className=\"h-4 w-4\" />\n <span className=\"text-xs font-medium\">{tab.label}</span>\n </button>\n );\n })}\n </div>\n {/* Desktop sidebar */}\n <div className=\"hidden lg:block rounded-lg border border-border-subtle bg-bg-surface\">\n <div className=\"p-3 border-b border-border-subtle\">\n <p className=\"text-sm font-semibold text-text-primary\">\n {t('adaptercloud.settings.title', 'Settings')}\n </p>\n </div>\n <nav className=\"p-2\">\n {localizedTabConfig.map((tab) => {\n const TabIcon = tab.icon;\n return (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-sm font-medium transition-colors mb-0.5',\n activeTab === tab.id\n ? 'bg-action-primary-bg/10 text-text-primary'\n : 'text-text-secondary hover:text-text-primary hover:bg-accent'\n )}\n >\n <TabIcon className=\"h-4 w-4\" />\n {tab.label}\n </button>\n );\n })}\n </nav>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 rounded-lg border border-border-seam bg-bg-surface p-6 bg-gloss-card shadow-pop\">\n {renderTab[activeTab]()}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -192,9 +192,10 @@ function D() {
|
|
|
192
192
|
if (!A) return /* @__PURE__ */ C(n, {
|
|
193
193
|
title: "Booking Not Found",
|
|
194
194
|
children: /* @__PURE__ */ C(i, {
|
|
195
|
+
illustration: "empty-generic",
|
|
195
196
|
icon: /* @__PURE__ */ C(f, { className: "h-12 w-12" }),
|
|
196
197
|
title: "Booking not found",
|
|
197
|
-
description: `No booking found with ID
|
|
198
|
+
description: `No booking found with ID"${T}".`,
|
|
198
199
|
action: /* @__PURE__ */ C("button", {
|
|
199
200
|
type: "button",
|
|
200
201
|
onClick: () => D("/customer/dashboard"),
|
|
@@ -216,9 +217,9 @@ function D() {
|
|
|
216
217
|
}),
|
|
217
218
|
actions: /* @__PURE__ */ C(r, { status: A.status }),
|
|
218
219
|
children: [O && /* @__PURE__ */ w("div", {
|
|
219
|
-
className: "mb-4 rounded-lg border border-
|
|
220
|
-
children: [/* @__PURE__ */ C(p, { className: "h-4 w-4 text-
|
|
221
|
-
className: "text-sm text-
|
|
220
|
+
className: "mb-4 rounded-lg border border-status-success-border/30 bg-status-success-bg-subtle/10 p-3 flex items-center gap-2",
|
|
221
|
+
children: [/* @__PURE__ */ C(p, { className: "h-4 w-4 text-status-success-text shrink-0" }), /* @__PURE__ */ C("p", {
|
|
222
|
+
className: "text-sm text-status-success-text",
|
|
222
223
|
children: O
|
|
223
224
|
})]
|
|
224
225
|
}), /* @__PURE__ */ w("div", {
|
|
@@ -227,7 +228,7 @@ function D() {
|
|
|
227
228
|
className: "lg:col-span-2 space-y-6",
|
|
228
229
|
children: [
|
|
229
230
|
/* @__PURE__ */ w("div", {
|
|
230
|
-
className: "rounded-lg border border-border-
|
|
231
|
+
className: "rounded-lg border border-border-seam bg-bg-surface p-6 bg-gloss-card shadow-pop",
|
|
231
232
|
children: [
|
|
232
233
|
/* @__PURE__ */ C("h2", {
|
|
233
234
|
className: "text-lg font-semibold text-text-primary",
|
|
@@ -265,11 +266,11 @@ function D() {
|
|
|
265
266
|
})]
|
|
266
267
|
}),
|
|
267
268
|
A.cancellationReason && /* @__PURE__ */ w("div", {
|
|
268
|
-
className: "mt-4 rounded-md bg-
|
|
269
|
+
className: "mt-4 rounded-md bg-status-error-bg-subtle/5 border border-status-error-border/20 p-3",
|
|
269
270
|
children: [/* @__PURE__ */ w("div", {
|
|
270
271
|
className: "flex items-center gap-2 mb-1",
|
|
271
|
-
children: [/* @__PURE__ */ C(l, { className: "h-3.5 w-3.5 text-
|
|
272
|
-
className: "text-xs font-medium text-
|
|
272
|
+
children: [/* @__PURE__ */ C(l, { className: "h-3.5 w-3.5 text-status-error-text" }), /* @__PURE__ */ C("p", {
|
|
273
|
+
className: "text-xs font-medium text-status-error-text",
|
|
273
274
|
children: "Cancellation Reason"
|
|
274
275
|
})]
|
|
275
276
|
}), /* @__PURE__ */ C("p", {
|
|
@@ -280,7 +281,7 @@ function D() {
|
|
|
280
281
|
]
|
|
281
282
|
}),
|
|
282
283
|
/* @__PURE__ */ w("div", {
|
|
283
|
-
className: "rounded-lg border border-border-
|
|
284
|
+
className: "rounded-lg border border-border-seam bg-bg-surface p-6 bg-gloss-card shadow-pop",
|
|
284
285
|
children: [
|
|
285
286
|
/* @__PURE__ */ C("h2", {
|
|
286
287
|
className: "text-base font-semibold text-text-primary mb-4",
|
|
@@ -306,7 +307,7 @@ function D() {
|
|
|
306
307
|
}),
|
|
307
308
|
/* @__PURE__ */ w("div", {
|
|
308
309
|
className: "flex items-center gap-1 mt-1",
|
|
309
|
-
children: [/* @__PURE__ */ C(b, { className: "h-3 w-3 fill-
|
|
310
|
+
children: [/* @__PURE__ */ C(b, { className: "h-3 w-3 fill-status-warning-text text-status-warning-text" }), /* @__PURE__ */ C("span", {
|
|
310
311
|
className: "text-xs font-medium text-text-primary",
|
|
311
312
|
children: A.provider.rating
|
|
312
313
|
})]
|
|
@@ -327,7 +328,7 @@ function D() {
|
|
|
327
328
|
]
|
|
328
329
|
}),
|
|
329
330
|
/* @__PURE__ */ w("div", {
|
|
330
|
-
className: "rounded-lg border border-border-
|
|
331
|
+
className: "rounded-lg border border-border-seam bg-bg-surface p-6 bg-gloss-card shadow-pop",
|
|
331
332
|
children: [/* @__PURE__ */ C("h2", {
|
|
332
333
|
className: "text-base font-semibold text-text-primary mb-5",
|
|
333
334
|
children: "Booking Timeline"
|
|
@@ -340,9 +341,9 @@ function D() {
|
|
|
340
341
|
children: [/* @__PURE__ */ w("div", {
|
|
341
342
|
className: "flex flex-col items-center",
|
|
342
343
|
children: [/* @__PURE__ */ C("div", {
|
|
343
|
-
className: t("flex h-8 w-8 shrink-0 items-center justify-center rounded-full", i ? "bg-
|
|
344
|
+
className: t("flex h-8 w-8 shrink-0 items-center justify-center rounded-full", i ? "bg-status-error-bg-subtle/10 text-status-error-text" : e.completed ? "bg-status-success-bg-subtle/10 text-status-success-text" : "bg-bg-sunken text-text-secondary"),
|
|
344
345
|
children: /* @__PURE__ */ C(a, { className: "h-4 w-4" })
|
|
345
|
-
}), !r && /* @__PURE__ */ C("div", { className: t("w-0.5 flex-1 my-1", e.completed ? "bg-
|
|
346
|
+
}), !r && /* @__PURE__ */ C("div", { className: t("w-0.5 flex-1 my-1", e.completed ? "bg-status-success-bg-subtle/30" : "bg-border") })]
|
|
346
347
|
}), /* @__PURE__ */ w("div", {
|
|
347
348
|
className: t("pb-6", r && "pb-0"),
|
|
348
349
|
children: [/* @__PURE__ */ C("p", {
|
|
@@ -380,7 +381,7 @@ function D() {
|
|
|
380
381
|
className: "space-y-6",
|
|
381
382
|
children: [
|
|
382
383
|
/* @__PURE__ */ w("div", {
|
|
383
|
-
className: "rounded-lg border border-border-
|
|
384
|
+
className: "rounded-lg border border-border-seam bg-bg-surface p-5 bg-gloss-card shadow-pop",
|
|
384
385
|
children: [
|
|
385
386
|
/* @__PURE__ */ C("h3", {
|
|
386
387
|
className: "text-base font-semibold text-text-primary mb-3",
|
|
@@ -406,7 +407,7 @@ function D() {
|
|
|
406
407
|
/* @__PURE__ */ w("div", {
|
|
407
408
|
className: "flex items-center gap-1 mt-0.5",
|
|
408
409
|
children: [
|
|
409
|
-
/* @__PURE__ */ C(b, { className: "h-3 w-3 fill-
|
|
410
|
+
/* @__PURE__ */ C(b, { className: "h-3 w-3 fill-status-warning-text text-status-warning-text" }),
|
|
410
411
|
/* @__PURE__ */ C("span", {
|
|
411
412
|
className: "text-xs font-medium text-text-primary",
|
|
412
413
|
children: A.provider.rating
|
|
@@ -443,7 +444,7 @@ function D() {
|
|
|
443
444
|
]
|
|
444
445
|
}),
|
|
445
446
|
/* @__PURE__ */ w("div", {
|
|
446
|
-
className: "rounded-lg border border-border-
|
|
447
|
+
className: "rounded-lg border border-border-seam bg-bg-surface p-5 bg-gloss-card shadow-pop",
|
|
447
448
|
children: [/* @__PURE__ */ C("h3", {
|
|
448
449
|
className: "text-base font-semibold text-text-primary mb-3",
|
|
449
450
|
children: "Service Location"
|
|
@@ -472,7 +473,7 @@ function D() {
|
|
|
472
473
|
})]
|
|
473
474
|
}),
|
|
474
475
|
/* @__PURE__ */ w("div", {
|
|
475
|
-
className: "rounded-lg border border-border-
|
|
476
|
+
className: "rounded-lg border border-border-seam bg-bg-surface p-5 bg-gloss-card shadow-pop",
|
|
476
477
|
children: [/* @__PURE__ */ C("h3", {
|
|
477
478
|
className: "text-base font-semibold text-text-primary mb-3",
|
|
478
479
|
children: "Price Breakdown"
|
|
@@ -512,10 +513,10 @@ function D() {
|
|
|
512
513
|
A.pricing.discount > 0 && /* @__PURE__ */ w("div", {
|
|
513
514
|
className: "flex justify-between",
|
|
514
515
|
children: [/* @__PURE__ */ C("span", {
|
|
515
|
-
className: "text-
|
|
516
|
+
className: "text-status-success-text",
|
|
516
517
|
children: "Discount"
|
|
517
518
|
}), /* @__PURE__ */ w("span", {
|
|
518
|
-
className: "text-
|
|
519
|
+
className: "text-status-success-text",
|
|
519
520
|
children: ["-", a(A.pricing.discount, { minimumFractionDigits: 0 })]
|
|
520
521
|
})]
|
|
521
522
|
}),
|
|
@@ -533,7 +534,7 @@ function D() {
|
|
|
533
534
|
})]
|
|
534
535
|
}),
|
|
535
536
|
/* @__PURE__ */ w("div", {
|
|
536
|
-
className: "rounded-lg border border-border-
|
|
537
|
+
className: "rounded-lg border border-border-seam bg-bg-surface p-5 bg-gloss-card shadow-pop",
|
|
537
538
|
children: [/* @__PURE__ */ C("h3", {
|
|
538
539
|
className: "text-base font-semibold text-text-primary mb-3",
|
|
539
540
|
children: "Booking Info"
|
|
@@ -579,7 +580,7 @@ function D() {
|
|
|
579
580
|
}),
|
|
580
581
|
P && /* @__PURE__ */ w("button", {
|
|
581
582
|
type: "button",
|
|
582
|
-
className: "w-full inline-flex items-center justify-center gap-2 rounded-lg border border-
|
|
583
|
+
className: "w-full inline-flex items-center justify-center gap-2 rounded-lg border border-status-error-border/30 bg-status-error-bg-subtle/5 px-4 py-3 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle/10 transition-colors",
|
|
583
584
|
children: [/* @__PURE__ */ C(x, { className: "h-4 w-4" }), "Cancel Booking"]
|
|
584
585
|
})
|
|
585
586
|
]
|