@burdenoff/microfe-kadaikodi 2026.723.1 → 2026.730.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/kadaikodi/KadaikodiRoutes.d.ts.map +1 -1
- package/dist/kadaikodi/KadaikodiRoutes.js +33 -29
- package/dist/kadaikodi/KadaikodiRoutes.js.map +1 -1
- package/dist/kadaikodi/hooks/useKadaikodiApi.d.ts +42 -0
- package/dist/kadaikodi/hooks/useKadaikodiApi.d.ts.map +1 -1
- package/dist/kadaikodi/hooks/useKadaikodiApi.js +133 -65
- package/dist/kadaikodi/hooks/useKadaikodiApi.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js +180 -162
- package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/LoyaltyManagementPage.d.ts +12 -0
- package/dist/kadaikodi/pages/cart-owner/LoyaltyManagementPage.d.ts.map +1 -0
- package/dist/kadaikodi/pages/cart-owner/LoyaltyManagementPage.js +198 -0
- package/dist/kadaikodi/pages/cart-owner/LoyaltyManagementPage.js.map +1 -0
- package/dist/kadaikodi/pages/customer/CustomerProfilePage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/customer/CustomerProfilePage.js +256 -97
- package/dist/kadaikodi/pages/customer/CustomerProfilePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomerProfilePage.js","names":[],"sources":["../../../../src/kadaikodi/pages/customer/CustomerProfilePage.tsx"],"sourcesContent":["/**\n * Customer Profile Page\n * @module kadaikodi/pages/customer\n *\n * Full profile management with 3-tab interface (Profile Info, Preferences, My Stats),\n * edit mode toggle, inline editable fields, emergency contact, dietary preferences,\n * food allergies, and stats/loyalty display.\n */\n\nimport { useState } from 'react';\nimport {\n User,\n MapPin,\n Bell,\n ChevronRight,\n Save,\n Heart,\n AlertTriangle,\n ShoppingBag,\n IndianRupee,\n BarChart3,\n Settings,\n UserCircle,\n Shield,\n CheckCircle2,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport { useOrders } from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\n\ntype ProfileTab = 'profile' | 'preferences' | 'stats';\n\ninterface EmergencyContact {\n name: string;\n phone: string;\n relationship: string;\n}\n\ninterface ProfileData {\n firstName: string;\n lastName: string;\n email: string;\n phone: string;\n emergencyContact: EmergencyContact;\n dietary: string[];\n allergies: string[];\n notifications: {\n orderUpdates: boolean;\n promotions: boolean;\n newsletter: boolean;\n sms: boolean;\n };\n}\n\nconst dietaryOptions = ['vegetarian', 'vegan', 'jain', 'keto', 'gluten-free', 'low-carb'];\nconst allergyOptions = ['nuts', 'dairy', 'eggs', 'soy', 'shellfish', 'gluten'];\n\nexport function CustomerProfilePage() {\n const { navigateTo, currentUser } = useKadaikodi();\n const { data: orders = [], isLoading: isLoadingOrders } = useOrders({\n customerId: currentUser?.id,\n });\n const [activeTab, setActiveTab] = useState<ProfileTab>('profile');\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n\n const showStatus = (msg: string) => {\n setStatusMessage(msg);\n setTimeout(() => setStatusMessage(null), 3000);\n };\n\n // Use currentUser from context — only real identity fields, no fabricated defaults\n const profile = {\n firstName: currentUser?.firstName || currentUser?.name?.split(' ')[0] || 'Customer',\n lastName: currentUser?.lastName || currentUser?.name?.split(' ').slice(1).join(' ') || '',\n email: currentUser?.email || '',\n phone: currentUser?.phone || '',\n profilePicture: currentUser?.avatar,\n };\n\n // Editable profile data — preferences/emergency contact start empty (no backend to load from)\n const [profileData, setProfileData] = useState<ProfileData>({\n firstName: profile.firstName,\n lastName: profile.lastName,\n email: profile.email,\n phone: profile.phone,\n emergencyContact: {\n name: '',\n phone: '',\n relationship: '',\n },\n dietary: [],\n allergies: [],\n notifications: {\n orderUpdates: true,\n promotions: true,\n newsletter: false,\n sms: true,\n },\n });\n\n const [editedData, setEditedData] = useState<ProfileData>({ ...profileData });\n\n // Calculate stats from real orders only\n const totalSpent = orders.reduce((acc, o) => acc + o.total, 0);\n const stats = {\n totalOrders: orders.length,\n totalSpent,\n avgOrderValue: orders.length > 0 ? Math.floor(totalSpent / orders.length) : 0,\n };\n\n const isLoading = isLoadingOrders;\n\n // Identity (name/email/phone/avatar) is owned by the platform account layer,\n // not by kadaikodi — there is no customer table here to persist to. So identity\n // is display-only and edits are routed to Account Security. Preferences and the\n // emergency contact have no kadaikodi persistence either, so they are applied\n // for the session only and labelled honestly (never a fake permanent save).\n const goToAccountSecurity = () => navigateTo('/auth/security');\n\n const handleSavePreferences = () => {\n setProfileData({ ...editedData });\n showStatus('Preferences applied for this session. Saved profiles are coming soon.');\n };\n\n const handleEmergencyContactChange = (field: keyof EmergencyContact, value: string) => {\n setEditedData((prev) => ({\n ...prev,\n emergencyContact: { ...prev.emergencyContact, [field]: value },\n }));\n };\n\n const handleNotificationChange = (field: string, value: boolean) => {\n setEditedData((prev) => ({\n ...prev,\n notifications: { ...prev.notifications, [field]: value },\n }));\n };\n\n const handleArrayToggle = (field: 'dietary' | 'allergies', value: string, checked: boolean) => {\n setEditedData((prev) => {\n const currentArray = prev[field];\n const newArray = checked\n ? [...currentArray, value]\n : currentArray.filter((item) => item !== value);\n return { ...prev, [field]: newArray };\n });\n };\n\n const tabs: Array<{ key: ProfileTab; label: string; icon: typeof UserCircle }> = [\n { key: 'profile', label: 'Profile Info', icon: UserCircle },\n { key: 'preferences', label: 'Preferences', icon: Settings },\n { key: 'stats', label: 'My Stats', icon: BarChart3 },\n ];\n\n if (isLoading) {\n return (\n <PageLayout title=\"My Profile\">\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-foreground mx-auto mb-4\" />\n <p className=\"text-sm text-text-secondary\">Loading profile...</p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout title=\"My Profile\" description=\"Manage your personal information and preferences\">\n <PagePurpose className=\"mb-6\">\n Your account, your way — keep your contact details, delivery address and preferences up to\n date, and manage how Kadaikodi reaches you. Accurate details mean smoother orders and\n deliveries.\n </PagePurpose>\n\n {/* Status message */}\n {statusMessage && (\n <div className=\"mb-4 rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-3 flex items-center gap-2\">\n <CheckCircle2 className=\"h-4 w-4 text-status-success-text shrink-0\" />\n <p className=\"text-sm text-status-success-text\">{statusMessage}</p>\n </div>\n )}\n\n {/* Profile Header — the one emphasis zone */}\n <GlassCard\n treatment=\"glass\"\n glow\n className=\"flex flex-col items-center sm:flex-row sm:items-start gap-6 p-6\"\n >\n <div className=\"relative\">\n <div className=\"h-24 w-24 rounded-full bg-bg-sunken overflow-hidden\">\n {profile.profilePicture ? (\n <img\n src={profile.profilePicture}\n alt={`${profile.firstName} ${profile.lastName}`}\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"flex h-full w-full items-center justify-center text-text-secondary\">\n <User className=\"h-10 w-10\" />\n </div>\n )}\n </div>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n title=\"Manage your photo in Account Security\"\n className=\"absolute bottom-0 right-0 flex h-8 w-8 items-center justify-center rounded-full bg-foreground text-background shadow-sm hover:opacity-90 transition-opacity\"\n >\n <Shield className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className=\"flex-1 text-center sm:text-left\">\n <h2 className=\"text-xl font-semibold text-text-primary\">\n {profileData.firstName} {profileData.lastName}\n </h2>\n {profileData.email && (\n <p className=\"mt-1 text-sm text-text-secondary\">{profileData.email}</p>\n )}\n {profileData.phone && (\n <p className=\"mt-0.5 text-sm text-text-secondary\">{profileData.phone}</p>\n )}\n </div>\n </GlassCard>\n\n {/* Tabs */}\n <div className=\"mt-6 rounded-lg border border-border-subtle bg-bg-surface\">\n <div className=\"border-b border-border-subtle\">\n <nav className=\"flex -mb-px overflow-x-auto\">\n {tabs.map((tab) => {\n const Icon = tab.icon;\n return (\n <button\n key={tab.key}\n type=\"button\"\n className={cn(\n 'flex items-center gap-2 py-3.5 px-5 text-sm font-medium whitespace-nowrap transition-colors',\n activeTab === tab.key\n ? 'border-b-2 border-foreground text-text-primary'\n : 'text-text-secondary hover:text-text-primary'\n )}\n onClick={() => setActiveTab(tab.key)}\n >\n <Icon className=\"h-4 w-4\" />\n {tab.label}\n </button>\n );\n })}\n </nav>\n </div>\n\n <div className=\"p-5 md:p-6\">\n {/* Profile Tab */}\n {activeTab === 'profile' && (\n <div className=\"space-y-6\">\n {/* Header — identity is managed in the platform account layer */}\n <div className=\"flex flex-wrap justify-between items-center gap-2\">\n <h3 className=\"text-lg font-semibold text-text-primary\">Personal Information</h3>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Shield className=\"h-3 w-3\" />\n Manage in Account Security\n </button>\n </div>\n <p className=\"-mt-3 text-xs text-text-secondary\">\n Your name, email and phone come from your Kadaikodi account. Update them in Account\n Security.\n </p>\n\n {/* Editable Fields */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-5\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n First Name\n </label>\n <input\n type=\"text\"\n value={profileData.firstName}\n disabled\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2.5 text-sm text-text-primary cursor-not-allowed\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Last Name\n </label>\n <input\n type=\"text\"\n value={profileData.lastName}\n disabled\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2.5 text-sm text-text-primary cursor-not-allowed\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Email\n </label>\n <input\n type=\"email\"\n value={profileData.email}\n disabled\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2.5 text-sm text-text-primary cursor-not-allowed\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Phone\n </label>\n <input\n type=\"tel\"\n value={profileData.phone}\n disabled\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2.5 text-sm text-text-primary cursor-not-allowed\"\n />\n </div>\n </div>\n\n {/* Primary Address */}\n <div>\n <h4 className=\"text-base font-semibold text-text-primary mb-3\">Primary Address</h4>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <p className=\"text-sm text-text-secondary\">\n You haven't saved a delivery address yet. Add one to speed up checkout.\n </p>\n <button\n type=\"button\"\n onClick={() => navigateTo('/customer/addresses')}\n className=\"mt-2 flex items-center gap-1 text-xs font-medium text-text-secondary hover:text-text-primary transition-colors\"\n >\n <MapPin className=\"h-3 w-3\" />\n Manage Addresses\n <ChevronRight className=\"h-3 w-3\" />\n </button>\n </div>\n </div>\n\n {/* Emergency Contact */}\n <div>\n <h4 className=\"text-base font-semibold text-text-primary mb-1 flex items-center gap-2\">\n <AlertTriangle className=\"h-4 w-4 text-text-secondary\" />\n Emergency Contact\n </h4>\n <p className=\"mb-3 text-xs text-text-secondary\">\n Applied for this session — persistent profile storage is coming soon.\n </p>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Name\n </label>\n <input\n type=\"text\"\n value={editedData.emergencyContact.name}\n onChange={(e) => handleEmergencyContactChange('name', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 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 Phone\n </label>\n <input\n type=\"tel\"\n value={editedData.emergencyContact.phone}\n onChange={(e) => handleEmergencyContactChange('phone', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 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 Relationship\n </label>\n <input\n type=\"text\"\n value={editedData.emergencyContact.relationship}\n onChange={(e) => handleEmergencyContactChange('relationship', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n </div>\n\n {/* Session-only save for the emergency contact */}\n <div className=\"flex gap-3 pt-4 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={handleSavePreferences}\n className=\"flex items-center gap-2 rounded-lg bg-foreground px-4 py-2.5 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n <Save className=\"h-4 w-4\" />\n Save for this session\n </button>\n </div>\n </div>\n )}\n\n {/* Preferences Tab */}\n {activeTab === 'preferences' && (\n <div className=\"space-y-8\">\n {/* Notification Preferences */}\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4 flex items-center gap-2\">\n <Bell className=\"h-4 w-4 text-text-secondary\" />\n Notification Preferences\n </h3>\n <div className=\"space-y-3\">\n {[\n { key: 'orderUpdates', label: 'Order status updates' },\n { key: 'promotions', label: 'Promotional offers and discounts' },\n { key: 'newsletter', label: 'Newsletter and food recommendations' },\n { key: 'sms', label: 'SMS notifications' },\n ].map((item) => (\n <label key={item.key} className=\"flex items-center gap-3 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={\n editedData.notifications[\n item.key as keyof typeof editedData.notifications\n ]\n }\n onChange={(e) => handleNotificationChange(item.key, e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle text-text-primary focus:ring-[var(--color-focus-ring)]\"\n />\n <span className=\"text-sm text-text-primary\">{item.label}</span>\n </label>\n ))}\n </div>\n </div>\n\n {/* Dietary Preferences */}\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4 flex items-center gap-2\">\n <Heart className=\"h-4 w-4 text-text-secondary\" />\n Dietary Preferences\n </h3>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3\">\n {dietaryOptions.map((diet) => (\n <label key={diet} className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={editedData.dietary.includes(diet)}\n onChange={(e) => handleArrayToggle('dietary', diet, e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle text-text-primary focus:ring-[var(--color-focus-ring)]\"\n />\n <span className=\"text-sm text-text-primary capitalize\">{diet}</span>\n </label>\n ))}\n </div>\n </div>\n\n {/* Food Allergies */}\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4 flex items-center gap-2\">\n <AlertTriangle className=\"h-4 w-4 text-status-error-text\" />\n Food Allergies\n </h3>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3\">\n {allergyOptions.map((allergy) => (\n <label key={allergy} className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={editedData.allergies.includes(allergy)}\n onChange={(e) => handleArrayToggle('allergies', allergy, e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle text-status-error-text focus:ring-destructive\"\n />\n <span className=\"text-sm text-text-primary capitalize\">{allergy}</span>\n </label>\n ))}\n </div>\n </div>\n\n {/* Save Preferences */}\n <div className=\"pt-4 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={handleSavePreferences}\n className=\"flex items-center gap-2 rounded-lg bg-foreground px-4 py-2.5 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n <Save className=\"h-4 w-4\" />\n Save Preferences\n </button>\n </div>\n </div>\n )}\n\n {/* Stats Tab */}\n {activeTab === 'stats' && (\n <div className=\"space-y-8\">\n {/* Top Stats Cards — derived from real orders only */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div className=\"rounded-lg bg-[var(--color-accent-soft)] p-5 border border-border-focus/20\">\n <div className=\"flex items-center gap-2 mb-2\">\n <ShoppingBag className=\"h-4 w-4 text-text-primary\" />\n <h4 className=\"text-sm font-medium text-text-primary\">Total Orders</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">{stats.totalOrders}</p>\n </div>\n <div className=\"rounded-lg bg-status-success-bg-subtle p-5 border border-status-success-text/20\">\n <div className=\"flex items-center gap-2 mb-2\">\n <IndianRupee className=\"h-4 w-4 text-status-success-text\" />\n <h4 className=\"text-sm font-medium text-status-success-text\">Total Spent</h4>\n </div>\n <p className=\"text-3xl font-bold text-status-success-text\">\n {formatCurrency(stats.totalSpent, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div className=\"rounded-lg bg-bg-surface p-5 border border-border-subtle\">\n <div className=\"flex items-center gap-2 mb-2\">\n <BarChart3 className=\"h-4 w-4 text-text-primary\" />\n <h4 className=\"text-sm font-medium text-text-primary\">Avg Order Value</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {formatCurrency(stats.avgOrderValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CustomerProfilePage.js","names":[],"sources":["../../../../src/kadaikodi/pages/customer/CustomerProfilePage.tsx"],"sourcesContent":["/**\n * Customer Profile Page\n * @module kadaikodi/pages/customer\n *\n * Full profile management with 3-tab interface (Profile Info, Preferences, My Stats),\n * edit mode toggle, inline editable fields, emergency contact, dietary preferences,\n * food allergies, and stats/loyalty display.\n */\n\nimport { useState } from 'react';\nimport {\n User,\n MapPin,\n Bell,\n ChevronRight,\n Save,\n Heart,\n AlertTriangle,\n ShoppingBag,\n IndianRupee,\n BarChart3,\n Settings,\n UserCircle,\n Shield,\n CheckCircle2,\n Gift,\n Sparkles,\n Loader2,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport {\n useOrders,\n useMyLoyaltyAccount,\n useMyLoyaltyTransactions,\n useRedeemLoyaltyPoints,\n} from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\n\nconst LOYALTY_MIN_REDEMPTION_POINTS = 100;\n\ntype ProfileTab = 'profile' | 'preferences' | 'stats' | 'rewards';\n\ninterface EmergencyContact {\n name: string;\n phone: string;\n relationship: string;\n}\n\ninterface ProfileData {\n firstName: string;\n lastName: string;\n email: string;\n phone: string;\n emergencyContact: EmergencyContact;\n dietary: string[];\n allergies: string[];\n notifications: {\n orderUpdates: boolean;\n promotions: boolean;\n newsletter: boolean;\n sms: boolean;\n };\n}\n\nconst dietaryOptions = ['vegetarian', 'vegan', 'jain', 'keto', 'gluten-free', 'low-carb'];\nconst allergyOptions = ['nuts', 'dairy', 'eggs', 'soy', 'shellfish', 'gluten'];\n\nexport function CustomerProfilePage() {\n const { navigateTo, currentUser } = useKadaikodi();\n const { data: orders = [], isLoading: isLoadingOrders } = useOrders({\n customerId: currentUser?.id,\n });\n const { data: loyaltyAccount, isLoading: isLoadingLoyaltyAccount } = useMyLoyaltyAccount();\n const { data: loyaltyTransactions = [], isLoading: isLoadingLoyaltyTransactions } =\n useMyLoyaltyTransactions();\n const redeemLoyaltyPoints = useRedeemLoyaltyPoints();\n const [redeemPoints, setRedeemPoints] = useState(String(LOYALTY_MIN_REDEMPTION_POINTS));\n const [redeemResult, setRedeemResult] = useState<{\n discountAmount: number;\n pointsRedeemed: number;\n } | null>(null);\n const [redeemError, setRedeemError] = useState<string | null>(null);\n const [activeTab, setActiveTab] = useState<ProfileTab>('profile');\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n\n const showStatus = (msg: string) => {\n setStatusMessage(msg);\n setTimeout(() => setStatusMessage(null), 3000);\n };\n\n // Use currentUser from context — only real identity fields, no fabricated defaults\n const profile = {\n firstName: currentUser?.firstName || currentUser?.name?.split(' ')[0] || 'Customer',\n lastName: currentUser?.lastName || currentUser?.name?.split(' ').slice(1).join(' ') || '',\n email: currentUser?.email || '',\n phone: currentUser?.phone || '',\n profilePicture: currentUser?.avatar,\n };\n\n // Editable profile data — preferences/emergency contact start empty (no backend to load from)\n const [profileData, setProfileData] = useState<ProfileData>({\n firstName: profile.firstName,\n lastName: profile.lastName,\n email: profile.email,\n phone: profile.phone,\n emergencyContact: {\n name: '',\n phone: '',\n relationship: '',\n },\n dietary: [],\n allergies: [],\n notifications: {\n orderUpdates: true,\n promotions: true,\n newsletter: false,\n sms: true,\n },\n });\n\n const [editedData, setEditedData] = useState<ProfileData>({ ...profileData });\n\n // Calculate stats from real orders only\n const totalSpent = orders.reduce((acc, o) => acc + o.total, 0);\n const stats = {\n totalOrders: orders.length,\n totalSpent,\n avgOrderValue: orders.length > 0 ? Math.floor(totalSpent / orders.length) : 0,\n };\n\n const isLoading = isLoadingOrders;\n\n // Identity (name/email/phone/avatar) is owned by the platform account layer,\n // not by kadaikodi — there is no customer table here to persist to. So identity\n // is display-only and edits are routed to Account Security. Preferences and the\n // emergency contact have no kadaikodi persistence either, so they are applied\n // for the session only and labelled honestly (never a fake permanent save).\n const goToAccountSecurity = () => navigateTo('/auth/security');\n\n const handleSavePreferences = () => {\n setProfileData({ ...editedData });\n showStatus('Preferences applied for this session. Saved profiles are coming soon.');\n };\n\n const handleEmergencyContactChange = (field: keyof EmergencyContact, value: string) => {\n setEditedData((prev) => ({\n ...prev,\n emergencyContact: { ...prev.emergencyContact, [field]: value },\n }));\n };\n\n const handleNotificationChange = (field: string, value: boolean) => {\n setEditedData((prev) => ({\n ...prev,\n notifications: { ...prev.notifications, [field]: value },\n }));\n };\n\n const handleArrayToggle = (field: 'dietary' | 'allergies', value: string, checked: boolean) => {\n setEditedData((prev) => {\n const currentArray = prev[field];\n const newArray = checked\n ? [...currentArray, value]\n : currentArray.filter((item) => item !== value);\n return { ...prev, [field]: newArray };\n });\n };\n\n const handleRedeemPoints = async () => {\n setRedeemError(null);\n setRedeemResult(null);\n const points = parseInt(redeemPoints, 10);\n if (!Number.isFinite(points) || points < LOYALTY_MIN_REDEMPTION_POINTS) {\n setRedeemError(`Enter at least ${LOYALTY_MIN_REDEMPTION_POINTS} points.`);\n return;\n }\n try {\n const result = await redeemLoyaltyPoints.mutateAsync(points);\n setRedeemResult({\n discountAmount: result.discountAmount,\n pointsRedeemed: result.pointsRedeemed,\n });\n setRedeemPoints(String(LOYALTY_MIN_REDEMPTION_POINTS));\n } catch (err) {\n setRedeemError(\n err instanceof Error ? err.message : 'Failed to redeem points. Please try again.'\n );\n }\n };\n\n const tabs: Array<{ key: ProfileTab; label: string; icon: typeof UserCircle }> = [\n { key: 'profile', label: 'Profile Info', icon: UserCircle },\n { key: 'preferences', label: 'Preferences', icon: Settings },\n { key: 'stats', label: 'My Stats', icon: BarChart3 },\n { key: 'rewards', label: 'Rewards', icon: Gift },\n ];\n\n if (isLoading) {\n return (\n <PageLayout title=\"My Profile\">\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-foreground mx-auto mb-4\" />\n <p className=\"text-sm text-text-secondary\">Loading profile...</p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout title=\"My Profile\" description=\"Manage your personal information and preferences\">\n <PagePurpose className=\"mb-6\">\n Your account, your way — keep your contact details, delivery address and preferences up to\n date, and manage how Kadaikodi reaches you. Accurate details mean smoother orders and\n deliveries.\n </PagePurpose>\n\n {/* Status message */}\n {statusMessage && (\n <div className=\"mb-4 rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-3 flex items-center gap-2\">\n <CheckCircle2 className=\"h-4 w-4 text-status-success-text shrink-0\" />\n <p className=\"text-sm text-status-success-text\">{statusMessage}</p>\n </div>\n )}\n\n {/* Profile Header — the one emphasis zone */}\n <GlassCard\n treatment=\"glass\"\n glow\n className=\"flex flex-col items-center sm:flex-row sm:items-start gap-6 p-6\"\n >\n <div className=\"relative\">\n <div className=\"h-24 w-24 rounded-full bg-bg-sunken overflow-hidden\">\n {profile.profilePicture ? (\n <img\n src={profile.profilePicture}\n alt={`${profile.firstName} ${profile.lastName}`}\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"flex h-full w-full items-center justify-center text-text-secondary\">\n <User className=\"h-10 w-10\" />\n </div>\n )}\n </div>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n title=\"Manage your photo in Account Security\"\n className=\"absolute bottom-0 right-0 flex h-8 w-8 items-center justify-center rounded-full bg-foreground text-background shadow-sm hover:opacity-90 transition-opacity\"\n >\n <Shield className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className=\"flex-1 text-center sm:text-left\">\n <h2 className=\"text-xl font-semibold text-text-primary\">\n {profileData.firstName} {profileData.lastName}\n </h2>\n {profileData.email && (\n <p className=\"mt-1 text-sm text-text-secondary\">{profileData.email}</p>\n )}\n {profileData.phone && (\n <p className=\"mt-0.5 text-sm text-text-secondary\">{profileData.phone}</p>\n )}\n </div>\n </GlassCard>\n\n {/* Tabs */}\n <div className=\"mt-6 rounded-lg border border-border-subtle bg-bg-surface\">\n <div className=\"border-b border-border-subtle\">\n <nav className=\"flex -mb-px overflow-x-auto\">\n {tabs.map((tab) => {\n const Icon = tab.icon;\n return (\n <button\n key={tab.key}\n type=\"button\"\n className={cn(\n 'flex items-center gap-2 py-3.5 px-5 text-sm font-medium whitespace-nowrap transition-colors',\n activeTab === tab.key\n ? 'border-b-2 border-foreground text-text-primary'\n : 'text-text-secondary hover:text-text-primary'\n )}\n onClick={() => setActiveTab(tab.key)}\n >\n <Icon className=\"h-4 w-4\" />\n {tab.label}\n </button>\n );\n })}\n </nav>\n </div>\n\n <div className=\"p-5 md:p-6\">\n {/* Profile Tab */}\n {activeTab === 'profile' && (\n <div className=\"space-y-6\">\n {/* Header — identity is managed in the platform account layer */}\n <div className=\"flex flex-wrap justify-between items-center gap-2\">\n <h3 className=\"text-lg font-semibold text-text-primary\">Personal Information</h3>\n <button\n type=\"button\"\n onClick={goToAccountSecurity}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n <Shield className=\"h-3 w-3\" />\n Manage in Account Security\n </button>\n </div>\n <p className=\"-mt-3 text-xs text-text-secondary\">\n Your name, email and phone come from your Kadaikodi account. Update them in Account\n Security.\n </p>\n\n {/* Editable Fields */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-5\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n First Name\n </label>\n <input\n type=\"text\"\n value={profileData.firstName}\n disabled\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2.5 text-sm text-text-primary cursor-not-allowed\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Last Name\n </label>\n <input\n type=\"text\"\n value={profileData.lastName}\n disabled\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2.5 text-sm text-text-primary cursor-not-allowed\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Email\n </label>\n <input\n type=\"email\"\n value={profileData.email}\n disabled\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2.5 text-sm text-text-primary cursor-not-allowed\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Phone\n </label>\n <input\n type=\"tel\"\n value={profileData.phone}\n disabled\n readOnly\n className=\"w-full rounded-lg border border-border-subtle bg-bg-sunken px-3 py-2.5 text-sm text-text-primary cursor-not-allowed\"\n />\n </div>\n </div>\n\n {/* Primary Address */}\n <div>\n <h4 className=\"text-base font-semibold text-text-primary mb-3\">Primary Address</h4>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <p className=\"text-sm text-text-secondary\">\n You haven't saved a delivery address yet. Add one to speed up checkout.\n </p>\n <button\n type=\"button\"\n onClick={() => navigateTo('/customer/addresses')}\n className=\"mt-2 flex items-center gap-1 text-xs font-medium text-text-secondary hover:text-text-primary transition-colors\"\n >\n <MapPin className=\"h-3 w-3\" />\n Manage Addresses\n <ChevronRight className=\"h-3 w-3\" />\n </button>\n </div>\n </div>\n\n {/* Emergency Contact */}\n <div>\n <h4 className=\"text-base font-semibold text-text-primary mb-1 flex items-center gap-2\">\n <AlertTriangle className=\"h-4 w-4 text-text-secondary\" />\n Emergency Contact\n </h4>\n <p className=\"mb-3 text-xs text-text-secondary\">\n Applied for this session — persistent profile storage is coming soon.\n </p>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1.5\">\n Name\n </label>\n <input\n type=\"text\"\n value={editedData.emergencyContact.name}\n onChange={(e) => handleEmergencyContactChange('name', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 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 Phone\n </label>\n <input\n type=\"tel\"\n value={editedData.emergencyContact.phone}\n onChange={(e) => handleEmergencyContactChange('phone', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 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 Relationship\n </label>\n <input\n type=\"text\"\n value={editedData.emergencyContact.relationship}\n onChange={(e) => handleEmergencyContactChange('relationship', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n </div>\n\n {/* Session-only save for the emergency contact */}\n <div className=\"flex gap-3 pt-4 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={handleSavePreferences}\n className=\"flex items-center gap-2 rounded-lg bg-foreground px-4 py-2.5 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n <Save className=\"h-4 w-4\" />\n Save for this session\n </button>\n </div>\n </div>\n )}\n\n {/* Preferences Tab */}\n {activeTab === 'preferences' && (\n <div className=\"space-y-8\">\n {/* Notification Preferences */}\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4 flex items-center gap-2\">\n <Bell className=\"h-4 w-4 text-text-secondary\" />\n Notification Preferences\n </h3>\n <div className=\"space-y-3\">\n {[\n { key: 'orderUpdates', label: 'Order status updates' },\n { key: 'promotions', label: 'Promotional offers and discounts' },\n { key: 'newsletter', label: 'Newsletter and food recommendations' },\n { key: 'sms', label: 'SMS notifications' },\n ].map((item) => (\n <label key={item.key} className=\"flex items-center gap-3 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={\n editedData.notifications[\n item.key as keyof typeof editedData.notifications\n ]\n }\n onChange={(e) => handleNotificationChange(item.key, e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle text-text-primary focus:ring-[var(--color-focus-ring)]\"\n />\n <span className=\"text-sm text-text-primary\">{item.label}</span>\n </label>\n ))}\n </div>\n </div>\n\n {/* Dietary Preferences */}\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4 flex items-center gap-2\">\n <Heart className=\"h-4 w-4 text-text-secondary\" />\n Dietary Preferences\n </h3>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3\">\n {dietaryOptions.map((diet) => (\n <label key={diet} className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={editedData.dietary.includes(diet)}\n onChange={(e) => handleArrayToggle('dietary', diet, e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle text-text-primary focus:ring-[var(--color-focus-ring)]\"\n />\n <span className=\"text-sm text-text-primary capitalize\">{diet}</span>\n </label>\n ))}\n </div>\n </div>\n\n {/* Food Allergies */}\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-4 flex items-center gap-2\">\n <AlertTriangle className=\"h-4 w-4 text-status-error-text\" />\n Food Allergies\n </h3>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3\">\n {allergyOptions.map((allergy) => (\n <label key={allergy} className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={editedData.allergies.includes(allergy)}\n onChange={(e) => handleArrayToggle('allergies', allergy, e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle text-status-error-text focus:ring-destructive\"\n />\n <span className=\"text-sm text-text-primary capitalize\">{allergy}</span>\n </label>\n ))}\n </div>\n </div>\n\n {/* Save Preferences */}\n <div className=\"pt-4 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={handleSavePreferences}\n className=\"flex items-center gap-2 rounded-lg bg-foreground px-4 py-2.5 text-sm font-medium text-background hover:opacity-90 transition-opacity\"\n >\n <Save className=\"h-4 w-4\" />\n Save Preferences\n </button>\n </div>\n </div>\n )}\n\n {/* Stats Tab */}\n {activeTab === 'stats' && (\n <div className=\"space-y-8\">\n {/* Top Stats Cards — derived from real orders only */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div className=\"rounded-lg bg-[var(--color-accent-soft)] p-5 border border-border-focus/20\">\n <div className=\"flex items-center gap-2 mb-2\">\n <ShoppingBag className=\"h-4 w-4 text-text-primary\" />\n <h4 className=\"text-sm font-medium text-text-primary\">Total Orders</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">{stats.totalOrders}</p>\n </div>\n <div className=\"rounded-lg bg-status-success-bg-subtle p-5 border border-status-success-text/20\">\n <div className=\"flex items-center gap-2 mb-2\">\n <IndianRupee className=\"h-4 w-4 text-status-success-text\" />\n <h4 className=\"text-sm font-medium text-status-success-text\">Total Spent</h4>\n </div>\n <p className=\"text-3xl font-bold text-status-success-text\">\n {formatCurrency(stats.totalSpent, { minimumFractionDigits: 0 })}\n </p>\n </div>\n <div className=\"rounded-lg bg-bg-surface p-5 border border-border-subtle\">\n <div className=\"flex items-center gap-2 mb-2\">\n <BarChart3 className=\"h-4 w-4 text-text-primary\" />\n <h4 className=\"text-sm font-medium text-text-primary\">Avg Order Value</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {formatCurrency(stats.avgOrderValue, { minimumFractionDigits: 0 })}\n </p>\n </div>\n </div>\n </div>\n )}\n\n {/* Rewards Tab — real loyalty account + redemption (BOFF-4290) */}\n {activeTab === 'rewards' && (\n <div className=\"space-y-8\">\n {isLoadingLoyaltyAccount ? (\n <div className=\"flex h-32 items-center justify-center\">\n <Loader2 className=\"h-6 w-6 animate-spin text-text-secondary\" />\n </div>\n ) : (\n <>\n {/* Balance Summary */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div className=\"rounded-lg bg-[var(--color-accent-soft)] p-5 border border-border-focus/20\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Gift className=\"h-4 w-4 text-text-primary\" />\n <h4 className=\"text-sm font-medium text-text-primary\">Points Balance</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {loyaltyAccount?.pointsBalance ?? 0}\n </p>\n </div>\n <div className=\"rounded-lg bg-status-success-bg-subtle p-5 border border-status-success-text/20\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Sparkles className=\"h-4 w-4 text-status-success-text\" />\n <h4 className=\"text-sm font-medium text-status-success-text\">\n Lifetime Earned\n </h4>\n </div>\n <p className=\"text-3xl font-bold text-status-success-text\">\n {loyaltyAccount?.lifetimePointsEarned ?? 0}\n </p>\n </div>\n <div className=\"rounded-lg bg-bg-surface p-5 border border-border-subtle\">\n <div className=\"flex items-center gap-2 mb-2\">\n <IndianRupee className=\"h-4 w-4 text-text-primary\" />\n <h4 className=\"text-sm font-medium text-text-primary\">Lifetime Redeemed</h4>\n </div>\n <p className=\"text-3xl font-bold text-text-primary\">\n {loyaltyAccount?.lifetimePointsRedeemed ?? 0}\n </p>\n </div>\n </div>\n\n {/* Redeem Points */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5\">\n <h3 className=\"text-base font-semibold text-text-primary mb-1\">\n Redeem Points for a Discount\n </h3>\n <p className=\"text-xs text-text-secondary mb-4\">\n 1 point = ₹0.50 discount. Minimum redemption is{' '}\n {LOYALTY_MIN_REDEMPTION_POINTS} points. Redeeming debits your balance\n immediately — apply the resulting discount amount at checkout on your next\n order.\n </p>\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <input\n type=\"number\"\n min={LOYALTY_MIN_REDEMPTION_POINTS}\n step={1}\n value={redeemPoints}\n onChange={(e) => setRedeemPoints(e.target.value)}\n className=\"w-full sm:w-40 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2.5 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n <button\n type=\"button\"\n onClick={handleRedeemPoints}\n disabled={\n redeemLoyaltyPoints.isPending ||\n (loyaltyAccount?.pointsBalance ?? 0) < LOYALTY_MIN_REDEMPTION_POINTS\n }\n className=\"flex items-center justify-center gap-2 rounded-lg bg-foreground px-4 py-2.5 text-sm font-medium text-background hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {redeemLoyaltyPoints.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Gift className=\"h-4 w-4\" />\n )}\n Redeem\n </button>\n </div>\n {redeemError && (\n <p className=\"mt-3 text-sm text-status-error-text\">{redeemError}</p>\n )}\n {redeemResult && (\n <div className=\"mt-3 rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-3 flex items-center gap-2\">\n <CheckCircle2 className=\"h-4 w-4 text-status-success-text shrink-0\" />\n <p className=\"text-sm text-status-success-text\">\n Redeemed {redeemResult.pointsRedeemed} points for a{' '}\n {formatCurrency(redeemResult.discountAmount, {\n minimumFractionDigits: 0,\n })}{' '}\n discount — enter this amount at checkout.\n </p>\n </div>\n )}\n </div>\n\n {/* Transaction History */}\n <div>\n <h3 className=\"text-base font-semibold text-text-primary mb-3\">\n Points History\n </h3>\n {isLoadingLoyaltyTransactions ? (\n <div className=\"flex h-24 items-center justify-center\">\n <Loader2 className=\"h-5 w-5 animate-spin text-text-secondary\" />\n </div>\n ) : loyaltyTransactions.length > 0 ? (\n <div className=\"space-y-2\">\n {loyaltyTransactions.map((txn) => (\n <div\n key={txn.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle bg-bg-surface p-3\"\n >\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {txn.description || txn.type}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {new Date(txn.createdAt).toLocaleDateString()}\n </p>\n </div>\n <p\n className={cn(\n 'text-sm font-semibold',\n txn.points >= 0\n ? 'text-status-success-text'\n : 'text-status-error-text'\n )}\n >\n {txn.points >= 0 ? '+' : ''}\n {txn.points} pts\n </p>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <p className=\"text-sm text-text-secondary\">\n No points activity yet — complete an order to start earning rewards.\n </p>\n </div>\n )}\n </div>\n </>\n )}\n </div>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;AAyCA,IAAM,IAAgC,KA0BhC,KAAiB;CAAC;CAAc;CAAS;CAAQ;CAAQ;CAAe;CAAW,EACnF,KAAiB;CAAC;CAAQ;CAAS;CAAQ;CAAO;CAAa;CAAS;AAE9E,SAAgB,IAAsB;CACpC,IAAM,EAAE,eAAY,mBAAgB,GAAc,EAC5C,EAAE,MAAM,IAAS,EAAE,EAAE,WAAW,MAAoB,EAAU,EAClE,YAAY,GAAa,IAC1B,CAAC,EACI,EAAE,MAAM,GAAgB,WAAW,MAA4B,GAAqB,EACpF,EAAE,MAAM,IAAsB,EAAE,EAAE,WAAW,OACjD,GAA0B,EACtB,IAAsB,GAAwB,EAC9C,CAAC,GAAc,KAAmB,EAAS,OAAO,EAA8B,CAAC,EACjF,CAAC,GAAc,KAAmB,EAG9B,KAAK,EACT,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAC7D,CAAC,GAAW,KAAgB,EAAqB,UAAU,EAC3D,CAAC,GAAe,KAAoB,EAAwB,KAAK,EAEjE,KAAc,MAAgB;AAElC,EADA,EAAiB,EAAI,EACrB,iBAAiB,EAAiB,KAAK,EAAE,IAAK;IAI1C,IAAU;EACd,WAAW,GAAa,aAAa,GAAa,MAAM,MAAM,IAAI,CAAC,MAAM;EACzE,UAAU,GAAa,YAAY,GAAa,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,IAAI;EACvF,OAAO,GAAa,SAAS;EAC7B,OAAO,GAAa,SAAS;EAC7B,gBAAgB,GAAa;EAC9B,EAGK,CAAC,GAAa,MAAkB,EAAsB;EAC1D,WAAW,EAAQ;EACnB,UAAU,EAAQ;EAClB,OAAO,EAAQ;EACf,OAAO,EAAQ;EACf,kBAAkB;GAChB,MAAM;GACN,OAAO;GACP,cAAc;GACf;EACD,SAAS,EAAE;EACX,WAAW,EAAE;EACb,eAAe;GACb,cAAc;GACd,YAAY;GACZ,YAAY;GACZ,KAAK;GACN;EACF,CAAC,EAEI,CAAC,GAAY,KAAiB,EAAsB,EAAE,GAAG,GAAa,CAAC,EAGvE,IAAa,EAAO,QAAQ,GAAK,MAAM,IAAM,EAAE,OAAO,EAAE,EACxD,IAAQ;EACZ,aAAa,EAAO;EACpB;EACA,eAAe,EAAO,SAAS,IAAI,KAAK,MAAM,IAAa,EAAO,OAAO,GAAG;EAC7E,EAEK,KAAY,GAOZ,UAA4B,EAAW,iBAAiB,EAExD,UAA8B;AAElC,EADA,GAAe,EAAE,GAAG,GAAY,CAAC,EACjC,EAAW,wEAAwE;IAG/E,KAAgC,GAA+B,MAAkB;AACrF,KAAe,OAAU;GACvB,GAAG;GACH,kBAAkB;IAAE,GAAG,EAAK;KAAmB,IAAQ;IAAO;GAC/D,EAAE;IAGC,MAA4B,GAAe,MAAmB;AAClE,KAAe,OAAU;GACvB,GAAG;GACH,eAAe;IAAE,GAAG,EAAK;KAAgB,IAAQ;IAAO;GACzD,EAAE;IAGC,KAAqB,GAAgC,GAAe,MAAqB;AAC7F,KAAe,MAAS;GACtB,IAAM,IAAe,EAAK,IACpB,IAAW,IACb,CAAC,GAAG,GAAc,EAAM,GACxB,EAAa,QAAQ,MAAS,MAAS,EAAM;AACjD,UAAO;IAAE,GAAG;KAAO,IAAQ;IAAU;IACrC;IAGE,KAAqB,YAAY;AAErC,EADA,EAAe,KAAK,EACpB,EAAgB,KAAK;EACrB,IAAM,IAAS,SAAS,GAAc,GAAG;AACzC,MAAI,CAAC,OAAO,SAAS,EAAO,IAAI,IAAS,GAA+B;AACtE,KAAe,kBAAkB,EAA8B,UAAU;AACzE;;AAEF,MAAI;GACF,IAAM,IAAS,MAAM,EAAoB,YAAY,EAAO;AAK5D,GAJA,EAAgB;IACd,gBAAgB,EAAO;IACvB,gBAAgB,EAAO;IACxB,CAAC,EACF,EAAgB,OAAO,EAA8B,CAAC;WAC/C,GAAK;AACZ,KACE,aAAe,QAAQ,EAAI,UAAU,6CACtC;;IAIC,KAA2E;EAC/E;GAAE,KAAK;GAAW,OAAO;GAAgB,MAAM;GAAY;EAC3D;GAAE,KAAK;GAAe,OAAO;GAAe,MAAM;GAAU;EAC5D;GAAE,KAAK;GAAS,OAAO;GAAY,MAAM;GAAW;EACpD;GAAE,KAAK;GAAW,OAAO;GAAW,MAAM;GAAM;EACjD;AAaD,QAXI,KAEA,kBAAC,GAAD;EAAY,OAAM;YAChB,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD,EAAK,WAAU,iFAAkF,CAAA,EACjG,kBAAC,KAAD;IAAG,WAAU;cAA8B;IAAsB,CAAA,CAC7D;;EACK,CAAA,GAKf,kBAAC,GAAD;EAAY,OAAM;EAAa,aAAY;YAA3C;GACE,kBAAC,GAAD;IAAa,WAAU;cAAO;IAIhB,CAAA;GAGb,KACC,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAc,WAAU,6CAA8C,CAAA,EACtE,kBAAC,KAAD;KAAG,WAAU;eAAoC;KAAkB,CAAA,CAC/D;;GAIR,kBAAC,GAAD;IACE,WAAU;IACV,MAAA;IACA,WAAU;cAHZ,CAKE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAQ,iBACP,kBAAC,OAAD;OACE,KAAK,EAAQ;OACb,KAAK,GAAG,EAAQ,UAAU,GAAG,EAAQ;OACrC,WAAU;OACV,CAAA,GAEF,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,IAAD,EAAM,WAAU,aAAc,CAAA;OAC1B,CAAA;MAEJ,CAAA,EACN,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,OAAM;MACN,WAAU;gBAEV,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;MACvB,CAAA,CACL;QAEN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACG,EAAY;QAAU;QAAE,EAAY;QAClC;;MACJ,EAAY,SACX,kBAAC,KAAD;OAAG,WAAU;iBAAoC,EAAY;OAAU,CAAA;MAExE,EAAY,SACX,kBAAC,KAAD;OAAG,WAAU;iBAAsC,EAAY;OAAU,CAAA;MAEvE;OACI;;GAGZ,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBACZ,GAAK,KAAK,MAAQ;OACjB,IAAM,IAAO,EAAI;AACjB,cACE,kBAAC,UAAD;QAEE,MAAK;QACL,WAAW,EACT,+FACA,MAAc,EAAI,MACd,mDACA,8CACL;QACD,eAAe,EAAa,EAAI,IAAI;kBATtC,CAWE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,EAAI,MACE;UAZF,EAAI,IAYF;QAEX;MACE,CAAA;KACF,CAAA,EAEN,kBAAC,OAAD;KAAK,WAAU;eAAf;MAEG,MAAc,aACb,kBAAC,OAAD;OAAK,WAAU;iBAAf;QAEE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,MAAD;UAAI,WAAU;oBAA0C;UAAyB,CAAA,EACjF,kBAAC,UAAD;UACE,MAAK;UACL,SAAS;UACT,WAAU;oBAHZ,CAKE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,6BAEvB;YACL;;QACN,kBAAC,KAAD;SAAG,WAAU;mBAAoC;SAG7C,CAAA;QAGJ,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAqD;WAE9D,CAAA,EACR,kBAAC,SAAD;WACE,MAAK;WACL,OAAO,EAAY;WACnB,UAAA;WACA,UAAA;WACA,WAAU;WACV,CAAA,CACE,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAqD;WAE9D,CAAA,EACR,kBAAC,SAAD;WACE,MAAK;WACL,OAAO,EAAY;WACnB,UAAA;WACA,UAAA;WACA,WAAU;WACV,CAAA,CACE,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAqD;WAE9D,CAAA,EACR,kBAAC,SAAD;WACE,MAAK;WACL,OAAO,EAAY;WACnB,UAAA;WACA,UAAA;WACA,WAAU;WACV,CAAA,CACE,EAAA,CAAA;UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAqD;WAE9D,CAAA,EACR,kBAAC,SAAD;WACE,MAAK;WACL,OAAO,EAAY;WACnB,UAAA;WACA,UAAA;WACA,WAAU;WACV,CAAA,CACE,EAAA,CAAA;UACF;;QAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAiD;SAAoB,CAAA,EACnF,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,KAAD;UAAG,WAAU;oBAA8B;UAEvC,CAAA,EACJ,kBAAC,UAAD;UACE,MAAK;UACL,eAAe,EAAW,sBAAsB;UAChD,WAAU;oBAHZ;WAKE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;;WAE9B,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA;WAC7B;YACL;WACF,EAAA,CAAA;QAGN,kBAAC,OAAD,EAAA,UAAA;SACE,kBAAC,MAAD;UAAI,WAAU;oBAAd,CACE,kBAAC,GAAD,EAAe,WAAU,+BAAgC,CAAA,EAAA,oBAEtD;;SACL,kBAAC,KAAD;UAAG,WAAU;oBAAmC;UAE5C,CAAA;SACJ,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;YAAO,WAAU;sBAAqD;YAE9D,CAAA,EACR,kBAAC,SAAD;YACE,MAAK;YACL,OAAO,EAAW,iBAAiB;YACnC,WAAW,MAAM,EAA6B,QAAQ,EAAE,OAAO,MAAM;YACrE,WAAU;YACV,CAAA,CACE,EAAA,CAAA;WACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;YAAO,WAAU;sBAAqD;YAE9D,CAAA,EACR,kBAAC,SAAD;YACE,MAAK;YACL,OAAO,EAAW,iBAAiB;YACnC,WAAW,MAAM,EAA6B,SAAS,EAAE,OAAO,MAAM;YACtE,WAAU;YACV,CAAA,CACE,EAAA,CAAA;WACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;YAAO,WAAU;sBAAqD;YAE9D,CAAA,EACR,kBAAC,SAAD;YACE,MAAK;YACL,OAAO,EAAW,iBAAiB;YACnC,WAAW,MAAM,EAA6B,gBAAgB,EAAE,OAAO,MAAM;YAC7E,WAAU;YACV,CAAA,CACE,EAAA,CAAA;WACF;;SACF,EAAA,CAAA;QAGN,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,UAAD;UACE,MAAK;UACL,SAAS;UACT,WAAU;oBAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,wBAErB;;SACL,CAAA;QACF;;MAIP,MAAc,iBACb,kBAAC,OAAD;OAAK,WAAU;iBAAf;QAEE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAd,CACE,kBAAC,IAAD,EAAM,WAAU,+BAAgC,CAAA,EAAA,2BAE7C;YACL,kBAAC,OAAD;SAAK,WAAU;mBACZ;UACC;WAAE,KAAK;WAAgB,OAAO;WAAwB;UACtD;WAAE,KAAK;WAAc,OAAO;WAAoC;UAChE;WAAE,KAAK;WAAc,OAAO;WAAuC;UACnE;WAAE,KAAK;WAAO,OAAO;WAAqB;UAC3C,CAAC,KAAK,MACL,kBAAC,SAAD;UAAsB,WAAU;oBAAhC,CACE,kBAAC,SAAD;WACE,MAAK;WACL,SACE,EAAW,cACT,EAAK;WAGT,WAAW,MAAM,GAAyB,EAAK,KAAK,EAAE,OAAO,QAAQ;WACrE,WAAU;WACV,CAAA,EACF,kBAAC,QAAD;WAAM,WAAU;qBAA6B,EAAK;WAAa,CAAA,CACzD;YAZI,EAAK,IAYT,CACR;SACE,CAAA,CACF,EAAA,CAAA;QAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAd,CACE,kBAAC,GAAD,EAAO,WAAU,+BAAgC,CAAA,EAAA,sBAE9C;YACL,kBAAC,OAAD;SAAK,WAAU;mBACZ,GAAe,KAAK,MACnB,kBAAC,SAAD;UAAkB,WAAU;oBAA5B,CACE,kBAAC,SAAD;WACE,MAAK;WACL,SAAS,EAAW,QAAQ,SAAS,EAAK;WAC1C,WAAW,MAAM,EAAkB,WAAW,GAAM,EAAE,OAAO,QAAQ;WACrE,WAAU;WACV,CAAA,EACF,kBAAC,QAAD;WAAM,WAAU;qBAAwC;WAAY,CAAA,CAC9D;YARI,EAQJ,CACR;SACE,CAAA,CACF,EAAA,CAAA;QAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAd,CACE,kBAAC,GAAD,EAAe,WAAU,kCAAmC,CAAA,EAAA,iBAEzD;YACL,kBAAC,OAAD;SAAK,WAAU;mBACZ,GAAe,KAAK,MACnB,kBAAC,SAAD;UAAqB,WAAU;oBAA/B,CACE,kBAAC,SAAD;WACE,MAAK;WACL,SAAS,EAAW,UAAU,SAAS,EAAQ;WAC/C,WAAW,MAAM,EAAkB,aAAa,GAAS,EAAE,OAAO,QAAQ;WAC1E,WAAU;WACV,CAAA,EACF,kBAAC,QAAD;WAAM,WAAU;qBAAwC;WAAe,CAAA,CACjE;YARI,EAQJ,CACR;SACE,CAAA,CACF,EAAA,CAAA;QAGN,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,UAAD;UACE,MAAK;UACL,SAAS;UACT,WAAU;oBAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,mBAErB;;SACL,CAAA;QACF;;MAIP,MAAc,WACb,kBAAC,OAAD;OAAK,WAAU;iBAEb,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,IAAD,EAAa,WAAU,6BAA8B,CAAA,EACrD,kBAAC,MAAD;YAAI,WAAU;sBAAwC;YAAiB,CAAA,CACnE;cACN,kBAAC,KAAD;WAAG,WAAU;qBAAwC,EAAM;WAAgB,CAAA,CACvE;;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAa,WAAU,oCAAqC,CAAA,EAC5D,kBAAC,MAAD;YAAI,WAAU;sBAA+C;YAAgB,CAAA,CACzE;cACN,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAe,EAAM,YAAY,EAAE,uBAAuB,GAAG,CAAC;WAC7D,CAAA,CACA;;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAW,WAAU,6BAA8B,CAAA,EACnD,kBAAC,MAAD;YAAI,WAAU;sBAAwC;YAAoB,CAAA,CACtE;cACN,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAe,EAAM,eAAe,EAAE,uBAAuB,GAAG,CAAC;WAChE,CAAA,CACA;;SACF;;OACF,CAAA;MAIP,MAAc,aACb,kBAAC,OAAD;OAAK,WAAU;iBACZ,IACC,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA;QAC5D,CAAA,GAEN,kBAAA,IAAA,EAAA,UAAA;QAEE,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,6BAA8B,CAAA,EAC9C,kBAAC,MAAD;aAAI,WAAU;uBAAwC;aAAmB,CAAA,CACrE;eACN,kBAAC,KAAD;YAAG,WAAU;sBACV,GAAgB,iBAAiB;YAChC,CAAA,CACA;;UACN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,IAAD,EAAU,WAAU,oCAAqC,CAAA,EACzD,kBAAC,MAAD;aAAI,WAAU;uBAA+C;aAExD,CAAA,CACD;eACN,kBAAC,KAAD;YAAG,WAAU;sBACV,GAAgB,wBAAwB;YACvC,CAAA,CACA;;UACN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,GAAD,EAAa,WAAU,6BAA8B,CAAA,EACrD,kBAAC,MAAD;aAAI,WAAU;uBAAwC;aAAsB,CAAA,CACxE;eACN,kBAAC,KAAD;YAAG,WAAU;sBACV,GAAgB,0BAA0B;YACzC,CAAA,CACA;;UACF;;QAGN,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,MAAD;WAAI,WAAU;qBAAiD;WAE1D,CAAA;UACL,kBAAC,KAAD;WAAG,WAAU;qBAAb;YAAgD;YACE;YAC/C;YAA8B;YAG7B;;UACJ,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,SAAD;YACE,MAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO;YACP,WAAW,MAAM,EAAgB,EAAE,OAAO,MAAM;YAChD,WAAU;YACV,CAAA,EACF,kBAAC,UAAD;YACE,MAAK;YACL,SAAS;YACT,UACE,EAAoB,cACnB,GAAgB,iBAAiB,KAAK;YAEzC,WAAU;sBAPZ,CASG,EAAoB,YACnB,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,GAE5C,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC5B,SAEK;cACL;;UACL,KACC,kBAAC,KAAD;WAAG,WAAU;qBAAuC;WAAgB,CAAA;UAErE,KACC,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAc,WAAU,6CAA8C,CAAA,EACtE,kBAAC,KAAD;YAAG,WAAU;sBAAb;aAAgD;aACpC,EAAa;aAAe;aAAc;aACnD,EAAe,EAAa,gBAAgB,EAC3C,uBAAuB,GACxB,CAAC;aAAE;aAAI;aAEN;cACA;;UAEJ;;QAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAiD;SAE1D,CAAA,EACJ,KACC,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA;SAC5D,CAAA,GACJ,EAAoB,SAAS,IAC/B,kBAAC,OAAD;SAAK,WAAU;mBACZ,EAAoB,KAAK,MACxB,kBAAC,OAAD;UAEE,WAAU;oBAFZ,CAIE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAI,eAAe,EAAI;WACtB,CAAA,EACJ,kBAAC,KAAD;WAAG,WAAU;qBACV,IAAI,KAAK,EAAI,UAAU,CAAC,oBAAoB;WAC3C,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,KAAD;WACE,WAAW,EACT,yBACA,EAAI,UAAU,IACV,6BACA,yBACL;qBANH;YAQG,EAAI,UAAU,IAAI,MAAM;YACxB,EAAI;YAAO;YACV;aACA;YAtBC,EAAI,GAsBL,CACN;SACE,CAAA,GAEN,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,KAAD;UAAG,WAAU;oBAA8B;UAEvC,CAAA;SACA,CAAA,CAEJ,EAAA,CAAA;QACL,EAAA,CAAA;OAED,CAAA;MAEJ;OACF;;GACK"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-kadaikodi",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.730.1",
|
|
4
4
|
"description": "Burdenoff Kadaikodi Microfrontend - Mobile services marketplace platform for connecting service providers with customers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|