@licklist/design 0.78.5-dev.107 → 0.78.5-dev.109
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/bitbucket-pipelines.yml +4 -13
- package/dist/Maintenance/Maintenance.scss.js +1 -1
- package/dist/index.js +2 -0
- package/dist/product-set/form/ProductsControl.d.ts +1 -2
- package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
- package/dist/product-set/form/ProductsControl.js +24 -0
- package/dist/v2/components/ActionMenu/ActionMenu.scss.js +1 -1
- package/dist/v2/components/Badge/Badge.scss.js +1 -1
- package/dist/v2/components/Button/Button.scss.js +1 -1
- package/dist/v2/components/Button/GhostButton.scss.js +1 -1
- package/dist/v2/components/Checkbox/Checkbox.scss.js +1 -1
- package/dist/v2/components/DataTable/DataTable.d.ts.map +1 -1
- package/dist/v2/components/DataTable/DataTable.js +2 -86
- package/dist/v2/components/IconButton/IconButton.scss.js +1 -1
- package/dist/v2/components/Modal/DeleteModal.d.ts.map +1 -1
- package/dist/v2/components/Modal/DeleteModal.js +11 -13
- package/dist/v2/components/Modal/DeleteModal.scss.js +1 -1
- package/dist/v2/components/NPSScore/NPSScore.scss.js +1 -1
- package/dist/v2/components/NewTabs/NewTabs.scss.js +1 -1
- package/dist/v2/components/PeriodCard/PeriodCard.d.ts +66 -0
- package/dist/v2/components/PeriodCard/PeriodCard.d.ts.map +1 -0
- package/dist/v2/components/PeriodCard/PeriodCard.js +351 -0
- package/dist/v2/components/PeriodCard/PeriodCard.scss.js +6 -0
- package/dist/v2/components/PeriodCard/index.d.ts +3 -0
- package/dist/v2/components/PeriodCard/index.d.ts.map +1 -0
- package/dist/v2/components/ReorderRow/ReorderRow.d.ts +24 -0
- package/dist/v2/components/ReorderRow/ReorderRow.d.ts.map +1 -0
- package/dist/v2/components/ReorderRow/ReorderRow.js +109 -0
- package/dist/v2/components/ReorderRow/ReorderRow.scss.js +6 -0
- package/dist/v2/components/ReorderRow/index.d.ts +3 -0
- package/dist/v2/components/ReorderRow/index.d.ts.map +1 -0
- package/dist/v2/components/Select/Select.scss.js +1 -1
- package/dist/v2/components/StatusBadge/StatusBadge.scss.js +1 -1
- package/dist/v2/components/StepIndicator/StepIndicator.scss.js +1 -1
- package/dist/v2/components/Tabs/Tabs.scss.js +1 -1
- package/dist/v2/components/Toggle/Toggle.d.ts.map +1 -1
- package/dist/v2/components/Toggle/Toggle.js +5 -8
- package/dist/v2/components/Tooltip/Tooltip.scss.js +1 -1
- package/dist/v2/components/UserAvatar/UserAvatar.scss.js +1 -1
- package/dist/v2/components/UserPanel/UserPanel.scss.js +1 -1
- package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.scss.js +1 -1
- package/dist/v2/components/ZoneCard/ZoneCard.scss.js +1 -1
- package/dist/v2/components/index.d.ts +4 -0
- package/dist/v2/components/index.d.ts.map +1 -1
- package/dist/v2/dashboard-analytics/chart/Chart.scss.js +1 -1
- package/dist/v2/dashboard-analytics/metric-card/MetricCard.scss.js +1 -1
- package/dist/v2/dashboard-analytics/venue-card/VenueCard.scss.js +1 -1
- package/dist/v2/dashboard-analytics/venue-closed-card/VenueClosedCard.scss.js +1 -1
- package/dist/v2/icons/index.js +16 -1
- package/dist/v2/index.d.ts +8 -0
- package/dist/v2/index.d.ts.map +1 -1
- package/dist/v2/navigation/DashboardLayout/AdminSidebar.scss.js +1 -1
- package/dist/v2/navigation/DashboardLayout/DashboardLayout.scss.js +1 -1
- package/dist/v2/navigation/DashboardLayout/ProviderSidebar.scss.js +1 -1
- package/dist/v2/navigation/DashboardLayout/TopNavigation.scss.js +1 -1
- package/dist/v2/pages/Settings/SettingsTabs.scss.js +1 -1
- package/dist/v2/pages/Settings/components/SidebarCustomisation.js +5 -0
- package/dist/v2/pages/Settings/components/SidebarCustomisation.scss.js +1 -1
- package/dist/v2/pages/Settings/components/SidebarNavItem.js +5 -0
- package/dist/v2/pages/auth/AuthLayout/AuthLayout.scss.js +1 -1
- package/dist/v2/shadcn/components/ui/accordion.d.ts +8 -0
- package/dist/v2/shadcn/components/ui/accordion.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/alert-dialog.d.ts +21 -0
- package/dist/v2/shadcn/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/alert.d.ts +9 -0
- package/dist/v2/shadcn/components/ui/alert.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/aspect-ratio.d.ts +4 -0
- package/dist/v2/shadcn/components/ui/aspect-ratio.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/avatar.d.ts +7 -0
- package/dist/v2/shadcn/components/ui/avatar.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/badge.d.ts +10 -0
- package/dist/v2/shadcn/components/ui/badge.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/breadcrumb.d.ts +20 -0
- package/dist/v2/shadcn/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/button.d.ts +14 -0
- package/dist/v2/shadcn/components/ui/button.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/calendar.d.ts +9 -0
- package/dist/v2/shadcn/components/ui/calendar.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/card.d.ts +9 -0
- package/dist/v2/shadcn/components/ui/card.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/carousel.d.ts +19 -0
- package/dist/v2/shadcn/components/ui/carousel.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/checkbox.d.ts +6 -0
- package/dist/v2/shadcn/components/ui/checkbox.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/checkbox.js +115 -0
- package/dist/v2/shadcn/components/ui/checkbox.scss.js +6 -0
- package/dist/v2/shadcn/components/ui/collapsible.d.ts +6 -0
- package/dist/v2/shadcn/components/ui/collapsible.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/command.d.ts +83 -0
- package/dist/v2/shadcn/components/ui/command.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/context-menu.d.ts +28 -0
- package/dist/v2/shadcn/components/ui/context-menu.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/dialog.d.ts +20 -0
- package/dist/v2/shadcn/components/ui/dialog.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/dialog.js +169 -0
- package/dist/v2/shadcn/components/ui/drawer.d.ts +23 -0
- package/dist/v2/shadcn/components/ui/drawer.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/v2/shadcn/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/form.d.ts +24 -0
- package/dist/v2/shadcn/components/ui/form.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/hover-card.d.ts +7 -0
- package/dist/v2/shadcn/components/ui/hover-card.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/input-otp.d.ts +35 -0
- package/dist/v2/shadcn/components/ui/input-otp.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/input.d.ts +6 -0
- package/dist/v2/shadcn/components/ui/input.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/label.d.ts +6 -0
- package/dist/v2/shadcn/components/ui/label.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/menubar.d.ts +34 -0
- package/dist/v2/shadcn/components/ui/menubar.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/navigation-menu.d.ts +13 -0
- package/dist/v2/shadcn/components/ui/navigation-menu.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/pagination.d.ts +29 -0
- package/dist/v2/shadcn/components/ui/pagination.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/popover.d.ts +7 -0
- package/dist/v2/shadcn/components/ui/popover.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/progress.d.ts +5 -0
- package/dist/v2/shadcn/components/ui/progress.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/radio-card.d.ts +12 -0
- package/dist/v2/shadcn/components/ui/radio-card.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/radio-group.d.ts +6 -0
- package/dist/v2/shadcn/components/ui/radio-group.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/scroll-area.d.ts +6 -0
- package/dist/v2/shadcn/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/select.d.ts +14 -0
- package/dist/v2/shadcn/components/ui/select.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/separator.d.ts +5 -0
- package/dist/v2/shadcn/components/ui/separator.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/sheet.d.ts +26 -0
- package/dist/v2/shadcn/components/ui/sheet.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/sidebar.d.ts +67 -0
- package/dist/v2/shadcn/components/ui/sidebar.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/skeleton.d.ts +3 -0
- package/dist/v2/shadcn/components/ui/skeleton.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/slider.d.ts +5 -0
- package/dist/v2/shadcn/components/ui/slider.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/switch.d.ts +6 -0
- package/dist/v2/shadcn/components/ui/switch.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/switch.js +115 -0
- package/dist/v2/shadcn/components/ui/switch.scss.js +6 -0
- package/dist/v2/shadcn/components/ui/table-pagination.d.ts +11 -0
- package/dist/v2/shadcn/components/ui/table-pagination.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/table.d.ts +11 -0
- package/dist/v2/shadcn/components/ui/table.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/tabs.d.ts +8 -0
- package/dist/v2/shadcn/components/ui/tabs.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/textarea.d.ts +6 -0
- package/dist/v2/shadcn/components/ui/textarea.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/toast.d.ts +16 -0
- package/dist/v2/shadcn/components/ui/toast.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/toaster.d.ts +2 -0
- package/dist/v2/shadcn/components/ui/toaster.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/toggle-group.d.ts +13 -0
- package/dist/v2/shadcn/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/toggle.d.ts +13 -0
- package/dist/v2/shadcn/components/ui/toggle.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/tooltip.d.ts +8 -0
- package/dist/v2/shadcn/components/ui/tooltip.d.ts.map +1 -0
- package/dist/v2/shadcn/components/ui/use-toast.d.ts +3 -0
- package/dist/v2/shadcn/components/ui/use-toast.d.ts.map +1 -0
- package/dist/v2/shadcn/hooks/use-mobile.d.ts +2 -0
- package/dist/v2/shadcn/hooks/use-mobile.d.ts.map +1 -0
- package/dist/v2/shadcn/hooks/use-toast.d.ts +45 -0
- package/dist/v2/shadcn/hooks/use-toast.d.ts.map +1 -0
- package/dist/v2/shadcn/index.d.ts +20 -0
- package/dist/v2/shadcn/index.d.ts.map +1 -0
- package/dist/v2/shadcn/lib/utils.d.ts +3 -0
- package/dist/v2/shadcn/lib/utils.d.ts.map +1 -0
- package/dist/v2/shadcn/lib/utils.js +11 -0
- package/dist/v2/shadcn/styles/globals.css +112 -0
- package/dist/v2/styles/form/NewInput.scss.js +1 -1
- package/package.json +6 -6
- package/rollup.config.js +2 -16
- package/src/iframe/payment/payment-status-page/PaymentStatusPage.tsx +1 -1
- package/src/product-set/form/ProductsControl.tsx +1 -2
- package/src/v2/components/DataTable/DataTable.tsx +1 -23
- package/src/v2/components/Modal/DeleteModal.tsx +20 -12
- package/src/v2/components/PeriodCard/PeriodCard.scss +157 -0
- package/src/v2/components/PeriodCard/PeriodCard.stories.tsx +245 -0
- package/src/v2/components/PeriodCard/PeriodCard.tsx +350 -0
- package/src/v2/components/PeriodCard/index.ts +8 -0
- package/src/v2/components/ReorderRow/ReorderRow.scss +68 -0
- package/src/v2/components/ReorderRow/ReorderRow.stories.tsx +124 -0
- package/src/v2/components/ReorderRow/ReorderRow.tsx +88 -0
- package/src/v2/components/ReorderRow/index.ts +2 -0
- package/src/v2/components/Toggle/Toggle.tsx +5 -6
- package/src/v2/components/index.ts +6 -0
- package/src/v2/index.ts +82 -0
- package/src/v2/shadcn/_reference/AccountManagerCard.tsx +45 -0
- package/src/v2/shadcn/_reference/AffiliatesTable.tsx +178 -0
- package/src/v2/shadcn/_reference/AuditArchive.tsx +165 -0
- package/src/v2/shadcn/_reference/AuditContent.tsx +270 -0
- package/src/v2/shadcn/_reference/AutomationsGeneralSettings.tsx +251 -0
- package/src/v2/shadcn/_reference/AvatarUpload.tsx +150 -0
- package/src/v2/shadcn/_reference/BookingsSummaryCard.tsx +268 -0
- package/src/v2/shadcn/_reference/CodeCleanUpAudit.tsx +274 -0
- package/src/v2/shadcn/_reference/CompaniesTable.tsx +387 -0
- package/src/v2/shadcn/_reference/ComponentAudit.tsx +239 -0
- package/src/v2/shadcn/_reference/ConfigureSettingsCard.tsx +95 -0
- package/src/v2/shadcn/_reference/CustomerCard.tsx +155 -0
- package/src/v2/shadcn/_reference/DashboardCards.tsx +50 -0
- package/src/v2/shadcn/_reference/DashboardFooter.tsx +18 -0
- package/src/v2/shadcn/_reference/DiarySettings.tsx +187 -0
- package/src/v2/shadcn/_reference/DiaryView.tsx +998 -0
- package/src/v2/shadcn/_reference/EmptyState.tsx +76 -0
- package/src/v2/shadcn/_reference/EntityInfoCard.tsx +48 -0
- package/src/v2/shadcn/_reference/ExistingUserAssignments.tsx +131 -0
- package/src/v2/shadcn/_reference/FeatureToggle.tsx +72 -0
- package/src/v2/shadcn/_reference/FlowCard.tsx +170 -0
- package/src/v2/shadcn/_reference/FlowsContent.tsx +688 -0
- package/src/v2/shadcn/_reference/FlowsGeneralSettings.tsx +27 -0
- package/src/v2/shadcn/_reference/GeneralSettings.tsx +33 -0
- package/src/v2/shadcn/_reference/InventoryGeneralSettings.tsx +82 -0
- package/src/v2/shadcn/_reference/LanguageSelector.tsx +97 -0
- package/src/v2/shadcn/_reference/LoadingScreen.tsx +25 -0
- package/src/v2/shadcn/_reference/LoadingSpinner.tsx +41 -0
- package/src/v2/shadcn/_reference/ManagedClientsList.tsx +121 -0
- package/src/v2/shadcn/_reference/NPSScore.tsx +379 -0
- package/src/v2/shadcn/_reference/NPSSummaryCard.tsx +181 -0
- package/src/v2/shadcn/_reference/NotificationBanner.tsx +129 -0
- package/src/v2/shadcn/_reference/NotificationPanel.tsx +208 -0
- package/src/v2/shadcn/_reference/OnlineUsersCard.tsx +73 -0
- package/src/v2/shadcn/_reference/ProtectedRoute.tsx +39 -0
- package/src/v2/shadcn/_reference/ProvidersTable.tsx +353 -0
- package/src/v2/shadcn/_reference/QuickAddPanel.tsx +1057 -0
- package/src/v2/shadcn/_reference/QuickFilters.tsx +112 -0
- package/src/v2/shadcn/_reference/ScheduleView.tsx +410 -0
- package/src/v2/shadcn/_reference/ScrollToTop.tsx +14 -0
- package/src/v2/shadcn/_reference/SecondaryNav.tsx +50 -0
- package/src/v2/shadcn/_reference/SecuritySettings.tsx +258 -0
- package/src/v2/shadcn/_reference/SessionDetailView.tsx +294 -0
- package/src/v2/shadcn/_reference/Sidebar.tsx +14 -0
- package/src/v2/shadcn/_reference/SidebarAwareLayout.tsx +30 -0
- package/src/v2/shadcn/_reference/SidebarLabelCustomization.tsx +285 -0
- package/src/v2/shadcn/_reference/SimulationBanner.tsx +57 -0
- package/src/v2/shadcn/_reference/SortControls.tsx +65 -0
- package/src/v2/shadcn/_reference/StatusBadge.tsx +49 -0
- package/src/v2/shadcn/_reference/StyleGuideContent.tsx +331 -0
- package/src/v2/shadcn/_reference/TableActionMenu.tsx +126 -0
- package/src/v2/shadcn/_reference/ThemeProvider.tsx +119 -0
- package/src/v2/shadcn/_reference/ThemeSettings.tsx +73 -0
- package/src/v2/shadcn/_reference/TopNavigation.tsx +332 -0
- package/src/v2/shadcn/_reference/UserActivityHistory.tsx +209 -0
- package/src/v2/shadcn/_reference/UserLanguageSettings.tsx +94 -0
- package/src/v2/shadcn/_reference/UserPanel.tsx +472 -0
- package/src/v2/shadcn/_reference/UsersTable.tsx +1023 -0
- package/src/v2/shadcn/_reference/WaiverForm.tsx +301 -0
- package/src/v2/shadcn/_reference/WaiversGeneralSettings.tsx +46 -0
- package/src/v2/shadcn/_reference/WaiversTable.tsx +290 -0
- package/src/v2/shadcn/_reference/WaiversTemplatesSettings.tsx +416 -0
- package/src/v2/shadcn/_reference/ai/AIChatPanel.tsx +313 -0
- package/src/v2/shadcn/_reference/ai/AIChatSearchBar.tsx +36 -0
- package/src/v2/shadcn/_reference/ai/ChatInteractiveBlock.tsx +298 -0
- package/src/v2/shadcn/_reference/ai/ChatMessageContent.tsx +40 -0
- package/src/v2/shadcn/_reference/ai/parseInteractiveBlocks.ts +142 -0
- package/src/v2/shadcn/_reference/auth/AuthLayout.tsx +55 -0
- package/src/v2/shadcn/_reference/auth/CreatePasswordForm.tsx +285 -0
- package/src/v2/shadcn/_reference/auth/CreatePasswordPanel.tsx +20 -0
- package/src/v2/shadcn/_reference/auth/LoginFooter.tsx +14 -0
- package/src/v2/shadcn/_reference/auth/LoginForm.tsx +205 -0
- package/src/v2/shadcn/_reference/auth/LoginPanel.tsx +41 -0
- package/src/v2/shadcn/_reference/auth/ResetPasswordForm.tsx +102 -0
- package/src/v2/shadcn/_reference/auth/ResetPasswordPanel.tsx +20 -0
- package/src/v2/shadcn/_reference/auth/VerifyEmailForm.tsx +95 -0
- package/src/v2/shadcn/_reference/auth/VerifyEmailPanel.tsx +20 -0
- package/src/v2/shadcn/_reference/email/EmailAttachment.tsx +119 -0
- package/src/v2/shadcn/_reference/email/EmailAutomation.tsx +92 -0
- package/src/v2/shadcn/_reference/email/EmailPlaceholders.tsx +64 -0
- package/src/v2/shadcn/_reference/email/UnlayerEmailEditor.tsx +41 -0
- package/src/v2/shadcn/_reference/email/emailTemplateData.ts +53 -0
- package/src/v2/shadcn/_reference/emptyStateIcons.tsx +103 -0
- package/src/v2/shadcn/_reference/games/MazeGame.tsx +394 -0
- package/src/v2/shadcn/_reference/games/RunnerGame.tsx +497 -0
- package/src/v2/shadcn/_reference/logos/BookedLogoFull.tsx +36 -0
- package/src/v2/shadcn/_reference/logos/BookedLogoMark.tsx +31 -0
- package/src/v2/shadcn/_reference/logos/BookedLogoNew.tsx +36 -0
- package/src/v2/shadcn/_reference/pricing/DynamicPricingRulesEditor.tsx +401 -0
- package/src/v2/shadcn/_reference/pricing/DynamicPricingTierCard.tsx +77 -0
- package/src/v2/shadcn/_reference/pricing/DynamicPricingTiersList.tsx +218 -0
- package/src/v2/shadcn/_reference/pricing/PricingCalendar.tsx +810 -0
- package/src/v2/shadcn/_reference/pricing/PricingPeriodCard.tsx +152 -0
- package/src/v2/shadcn/_reference/pricing/PricingPeriodForm.tsx +377 -0
- package/src/v2/shadcn/_reference/pricing/PricingPeriodsList.tsx +213 -0
- package/src/v2/shadcn/_reference/pricing/getRuleSummary.ts +39 -0
- package/src/v2/shadcn/_reference/products/AvailabilityRulesSection.tsx +184 -0
- package/src/v2/shadcn/_reference/products/AvailabilitySection.tsx +677 -0
- package/src/v2/shadcn/_reference/products/BookingTypeConfigOptions.tsx +40 -0
- package/src/v2/shadcn/_reference/products/CapacityPeriodsSection.tsx +238 -0
- package/src/v2/shadcn/_reference/products/DynamicPricingTiersSection.tsx +131 -0
- package/src/v2/shadcn/_reference/products/GiftCardOrdersTab.tsx +192 -0
- package/src/v2/shadcn/_reference/products/GiftCardSettings.tsx +342 -0
- package/src/v2/shadcn/_reference/products/PackageProductsSection.tsx +322 -0
- package/src/v2/shadcn/_reference/products/PricingSection.tsx +173 -0
- package/src/v2/shadcn/_reference/products/ProductTypeFields.tsx +353 -0
- package/src/v2/shadcn/_reference/products/ProductTypeIcon.tsx +95 -0
- package/src/v2/shadcn/_reference/products/VariablePricingSection.tsx +140 -0
- package/src/v2/shadcn/_reference/products/productTypeConfig.ts +182 -0
- package/src/v2/shadcn/_reference/shared/BackButton.tsx +50 -0
- package/src/v2/shadcn/_reference/shared/CancelConfirmationDialog.tsx +18 -0
- package/src/v2/shadcn/_reference/shared/ConfirmationDialog.tsx +136 -0
- package/src/v2/shadcn/_reference/shared/DeleteConfirmationDialog.tsx +18 -0
- package/src/v2/shadcn/_reference/shared/DeleteEntityPage.tsx +221 -0
- package/src/v2/shadcn/_reference/shared/SidebarIcons.tsx +108 -0
- package/src/v2/shadcn/_reference/shared/UnifiedSidebar.tsx +722 -0
- package/src/v2/shadcn/_reference/tables/BulkActionsBar.tsx +68 -0
- package/src/v2/shadcn/_reference/tables/DataTable.tsx +221 -0
- package/src/v2/shadcn/_reference/tables/TableControls.tsx +94 -0
- package/src/v2/shadcn/_reference/tables/index.ts +3 -0
- package/src/v2/shadcn/_reference/tables/types.ts +79 -0
- package/src/v2/shadcn/_reference/zones/LegacyZoneSettings.tsx +299 -0
- package/src/v2/shadcn/components/ui/accordion.stories.tsx +63 -0
- package/src/v2/shadcn/components/ui/accordion.tsx +52 -0
- package/src/v2/shadcn/components/ui/alert-dialog.stories.tsx +44 -0
- package/src/v2/shadcn/components/ui/alert-dialog.tsx +104 -0
- package/src/v2/shadcn/components/ui/alert.stories.tsx +44 -0
- package/src/v2/shadcn/components/ui/alert.tsx +43 -0
- package/src/v2/shadcn/components/ui/aspect-ratio.stories.tsx +46 -0
- package/src/v2/shadcn/components/ui/aspect-ratio.tsx +5 -0
- package/src/v2/shadcn/components/ui/avatar.stories.tsx +39 -0
- package/src/v2/shadcn/components/ui/avatar.tsx +38 -0
- package/src/v2/shadcn/components/ui/badge.stories.tsx +17 -0
- package/src/v2/shadcn/components/ui/badge.tsx +30 -0
- package/src/v2/shadcn/components/ui/breadcrumb.stories.tsx +91 -0
- package/src/v2/shadcn/components/ui/breadcrumb.tsx +90 -0
- package/src/v2/shadcn/components/ui/button.stories.tsx +20 -0
- package/src/v2/shadcn/components/ui/button.tsx +60 -0
- package/src/v2/shadcn/components/ui/calendar.stories.tsx +61 -0
- package/src/v2/shadcn/components/ui/calendar.tsx +54 -0
- package/src/v2/shadcn/components/ui/card.stories.tsx +37 -0
- package/src/v2/shadcn/components/ui/card.tsx +43 -0
- package/src/v2/shadcn/components/ui/carousel.stories.tsx +92 -0
- package/src/v2/shadcn/components/ui/carousel.tsx +224 -0
- package/src/v2/shadcn/components/ui/checkbox.scss +38 -0
- package/src/v2/shadcn/components/ui/checkbox.stories.tsx +23 -0
- package/src/v2/shadcn/components/ui/checkbox.tsx +24 -0
- package/src/v2/shadcn/components/ui/collapsible.stories.tsx +59 -0
- package/src/v2/shadcn/components/ui/collapsible.tsx +9 -0
- package/src/v2/shadcn/components/ui/command.stories.tsx +70 -0
- package/src/v2/shadcn/components/ui/command.tsx +132 -0
- package/src/v2/shadcn/components/ui/context-menu.stories.tsx +72 -0
- package/src/v2/shadcn/components/ui/context-menu.tsx +178 -0
- package/src/v2/shadcn/components/ui/dialog.stories.tsx +67 -0
- package/src/v2/shadcn/components/ui/dialog.tsx +95 -0
- package/src/v2/shadcn/components/ui/drawer.stories.tsx +50 -0
- package/src/v2/shadcn/components/ui/drawer.tsx +87 -0
- package/src/v2/shadcn/components/ui/dropdown-menu.stories.tsx +73 -0
- package/src/v2/shadcn/components/ui/dropdown-menu.tsx +179 -0
- package/src/v2/shadcn/components/ui/form.stories.tsx +105 -0
- package/src/v2/shadcn/components/ui/form.tsx +129 -0
- package/src/v2/shadcn/components/ui/hover-card.stories.tsx +35 -0
- package/src/v2/shadcn/components/ui/hover-card.tsx +27 -0
- package/src/v2/shadcn/components/ui/input-otp.stories.tsx +72 -0
- package/src/v2/shadcn/components/ui/input-otp.tsx +61 -0
- package/src/v2/shadcn/components/ui/input.stories.tsx +16 -0
- package/src/v2/shadcn/components/ui/input.tsx +25 -0
- package/src/v2/shadcn/components/ui/label.stories.tsx +13 -0
- package/src/v2/shadcn/components/ui/label.tsx +17 -0
- package/src/v2/shadcn/components/ui/menubar.stories.tsx +86 -0
- package/src/v2/shadcn/components/ui/menubar.tsx +207 -0
- package/src/v2/shadcn/components/ui/navigation-menu.stories.tsx +68 -0
- package/src/v2/shadcn/components/ui/navigation-menu.tsx +120 -0
- package/src/v2/shadcn/components/ui/pagination.stories.tsx +78 -0
- package/src/v2/shadcn/components/ui/pagination.tsx +81 -0
- package/src/v2/shadcn/components/ui/popover.stories.tsx +44 -0
- package/src/v2/shadcn/components/ui/popover.tsx +29 -0
- package/src/v2/shadcn/components/ui/progress.stories.tsx +17 -0
- package/src/v2/shadcn/components/ui/progress.tsx +23 -0
- package/src/v2/shadcn/components/ui/radio-card.stories.tsx +68 -0
- package/src/v2/shadcn/components/ui/radio-card.tsx +52 -0
- package/src/v2/shadcn/components/ui/radio-group.stories.tsx +77 -0
- package/src/v2/shadcn/components/ui/radio-group.tsx +35 -0
- package/src/v2/shadcn/components/ui/scroll-area.stories.tsx +56 -0
- package/src/v2/shadcn/components/ui/scroll-area.tsx +38 -0
- package/src/v2/shadcn/components/ui/select.stories.tsx +60 -0
- package/src/v2/shadcn/components/ui/select.tsx +148 -0
- package/src/v2/shadcn/components/ui/separator.stories.tsx +30 -0
- package/src/v2/shadcn/components/ui/separator.tsx +20 -0
- package/src/v2/shadcn/components/ui/sheet.stories.tsx +115 -0
- package/src/v2/shadcn/components/ui/sheet.tsx +107 -0
- package/src/v2/shadcn/components/ui/sidebar.stories.tsx +167 -0
- package/src/v2/shadcn/components/ui/sidebar.tsx +637 -0
- package/src/v2/shadcn/components/ui/skeleton.stories.tsx +36 -0
- package/src/v2/shadcn/components/ui/skeleton.tsx +7 -0
- package/src/v2/shadcn/components/ui/slider.stories.tsx +16 -0
- package/src/v2/shadcn/components/ui/slider.tsx +23 -0
- package/src/v2/shadcn/components/ui/switch.scss +63 -0
- package/src/v2/shadcn/components/ui/switch.stories.tsx +23 -0
- package/src/v2/shadcn/components/ui/switch.tsx +24 -0
- package/src/v2/shadcn/components/ui/table-pagination.stories.tsx +81 -0
- package/src/v2/shadcn/components/ui/table-pagination.tsx +61 -0
- package/src/v2/shadcn/components/ui/table.stories.tsx +40 -0
- package/src/v2/shadcn/components/ui/table.tsx +72 -0
- package/src/v2/shadcn/components/ui/tabs.stories.tsx +85 -0
- package/src/v2/shadcn/components/ui/tabs.tsx +53 -0
- package/src/v2/shadcn/components/ui/textarea.stories.tsx +15 -0
- package/src/v2/shadcn/components/ui/textarea.tsx +21 -0
- package/src/v2/shadcn/components/ui/toast.stories.tsx +77 -0
- package/src/v2/shadcn/components/ui/toast.tsx +111 -0
- package/src/v2/shadcn/components/ui/toaster.stories.tsx +46 -0
- package/src/v2/shadcn/components/ui/toaster.tsx +24 -0
- package/src/v2/shadcn/components/ui/toggle-group.stories.tsx +95 -0
- package/src/v2/shadcn/components/ui/toggle-group.tsx +49 -0
- package/src/v2/shadcn/components/ui/toggle.stories.tsx +18 -0
- package/src/v2/shadcn/components/ui/toggle.tsx +37 -0
- package/src/v2/shadcn/components/ui/tooltip.stories.tsx +57 -0
- package/src/v2/shadcn/components/ui/tooltip.tsx +28 -0
- package/src/v2/shadcn/components/ui/use-toast.ts +3 -0
- package/src/v2/shadcn/hooks/use-mobile.tsx +19 -0
- package/src/v2/shadcn/hooks/use-toast.ts +184 -0
- package/src/v2/shadcn/index.ts +76 -0
- package/src/v2/shadcn/lib/utils.ts +6 -0
- package/src/v2/shadcn/styles/globals.css +112 -0
- package/.vscode/settings.json +0 -3
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button } from '../ui/button';
|
|
3
|
+
import { Input } from '../ui/input';
|
|
4
|
+
import { Label } from '../ui/label';
|
|
5
|
+
import { RadioGroup, RadioGroupItem } from '../ui/radio-group';
|
|
6
|
+
import { IconPlus, IconCross } from '../../../icons';
|
|
7
|
+
|
|
8
|
+
export interface PriceTier {
|
|
9
|
+
name: string;
|
|
10
|
+
price: number | '';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface PricingSectionProps {
|
|
14
|
+
values: Record<string, any>;
|
|
15
|
+
onChange: (field: string, value: any) => void;
|
|
16
|
+
hideTypeSelector?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const PricingSection: React.FC<PricingSectionProps> = ({
|
|
20
|
+
values,
|
|
21
|
+
onChange,
|
|
22
|
+
hideTypeSelector = false,
|
|
23
|
+
}) => {
|
|
24
|
+
const pricingType = values.pricing_type || 'fixed';
|
|
25
|
+
const priceTiers: PriceTier[] = values.price_tiers || [{ name: '', price: '' }];
|
|
26
|
+
|
|
27
|
+
const handlePricingTypeChange = (type: string) => {
|
|
28
|
+
onChange('pricing_type', type);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const addPriceTier = () => {
|
|
32
|
+
const newTiers = [...priceTiers, { name: '', price: '' }];
|
|
33
|
+
onChange('price_tiers', newTiers);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const updatePriceTier = (index: number, field: 'name' | 'price', value: string | number) => {
|
|
37
|
+
const newTiers = [...priceTiers];
|
|
38
|
+
if (field === 'price') {
|
|
39
|
+
newTiers[index] = { ...newTiers[index], price: value === '' ? '' : Number(value) };
|
|
40
|
+
} else {
|
|
41
|
+
newTiers[index] = { ...newTiers[index], name: value as string };
|
|
42
|
+
}
|
|
43
|
+
onChange('price_tiers', newTiers);
|
|
44
|
+
|
|
45
|
+
// Also update the main price field with the first tier's price for backwards compatibility
|
|
46
|
+
if (index === 0 && field === 'price') {
|
|
47
|
+
onChange('price', value === '' ? null : Number(value));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const removePriceTier = (index: number) => {
|
|
52
|
+
if (priceTiers.length <= 1) return; // Keep at least one tier
|
|
53
|
+
const newTiers = priceTiers.filter((_, i) => i !== index);
|
|
54
|
+
onChange('price_tiers', newTiers);
|
|
55
|
+
|
|
56
|
+
// Update main price field with first tier's price
|
|
57
|
+
if (newTiers.length > 0) {
|
|
58
|
+
onChange('price', newTiers[0].price === '' ? null : newTiers[0].price);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const showTierNames = priceTiers.length > 1;
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<div className="flex flex-col gap-4 pt-4 border-t border-border-primary">
|
|
66
|
+
<h2 className="text-label-primary text-xl font-semibold">Pricing</h2>
|
|
67
|
+
|
|
68
|
+
{/* Pricing Type Selection */}
|
|
69
|
+
{!hideTypeSelector && (
|
|
70
|
+
<RadioGroup
|
|
71
|
+
value={pricingType}
|
|
72
|
+
onValueChange={handlePricingTypeChange}
|
|
73
|
+
className="flex gap-4"
|
|
74
|
+
>
|
|
75
|
+
<label className={`flex items-center gap-2 px-4 py-2 rounded-lg border cursor-pointer transition-colors ${
|
|
76
|
+
pricingType === 'fixed'
|
|
77
|
+
? 'border-border-selected bg-surface-action-soft'
|
|
78
|
+
: 'border-border-primary hover:border-border-hover'
|
|
79
|
+
}`}>
|
|
80
|
+
<RadioGroupItem value="fixed" id="pricing-fixed" />
|
|
81
|
+
<span className="text-label-primary">Fixed</span>
|
|
82
|
+
</label>
|
|
83
|
+
<label className={`flex items-center gap-2 px-4 py-2 rounded-lg border opacity-50 cursor-not-allowed ${
|
|
84
|
+
pricingType === 'variable'
|
|
85
|
+
? 'border-border-selected bg-surface-action-soft'
|
|
86
|
+
: 'border-border-primary'
|
|
87
|
+
}`}>
|
|
88
|
+
<RadioGroupItem value="variable" id="pricing-variable" disabled />
|
|
89
|
+
<span className="text-label-tertiary">Variable</span>
|
|
90
|
+
<span className="text-xs text-label-tertiary">(Coming soon)</span>
|
|
91
|
+
</label>
|
|
92
|
+
<label className={`flex items-center gap-2 px-4 py-2 rounded-lg border opacity-50 cursor-not-allowed ${
|
|
93
|
+
pricingType === 'dynamic'
|
|
94
|
+
? 'border-border-selected bg-surface-action-soft'
|
|
95
|
+
: 'border-border-primary'
|
|
96
|
+
}`}>
|
|
97
|
+
<RadioGroupItem value="dynamic" id="pricing-dynamic" disabled />
|
|
98
|
+
<span className="text-label-tertiary">Dynamic</span>
|
|
99
|
+
<span className="text-xs text-label-tertiary">(Coming soon)</span>
|
|
100
|
+
</label>
|
|
101
|
+
</RadioGroup>
|
|
102
|
+
)}
|
|
103
|
+
|
|
104
|
+
{/* Fixed Pricing Tiers */}
|
|
105
|
+
{pricingType === 'fixed' && (
|
|
106
|
+
<div className="flex flex-col gap-3">
|
|
107
|
+
<div className="flex flex-col gap-2">
|
|
108
|
+
{priceTiers.map((tier, index) => (
|
|
109
|
+
<div key={index} className="flex items-center gap-3">
|
|
110
|
+
{showTierNames && (
|
|
111
|
+
<div className="flex-1">
|
|
112
|
+
{index === 0 && <Label className="text-xs text-label-tertiary mb-1 block">Tier Name</Label>}
|
|
113
|
+
<Input
|
|
114
|
+
type="text"
|
|
115
|
+
value={tier.name}
|
|
116
|
+
onChange={(e) => updatePriceTier(index, 'name', e.target.value)}
|
|
117
|
+
|
|
118
|
+
className="w-full"
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
)}
|
|
122
|
+
<div className={showTierNames ? 'w-32' : 'w-40'}>
|
|
123
|
+
{index === 0 && <Label className="text-xs text-label-tertiary mb-1 block">Price</Label>}
|
|
124
|
+
<div className="relative">
|
|
125
|
+
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-label-secondary">£</span>
|
|
126
|
+
<Input
|
|
127
|
+
type="text"
|
|
128
|
+
inputMode="decimal"
|
|
129
|
+
defaultValue={tier.price === '' ? '' : typeof tier.price === 'number' ? tier.price.toFixed(2) : tier.price}
|
|
130
|
+
key={`tier-${index}-${tier.price}`}
|
|
131
|
+
onBlur={(e) => {
|
|
132
|
+
const raw = e.target.value.trim();
|
|
133
|
+
if (raw === '') return;
|
|
134
|
+
const v = parseFloat(parseFloat(raw).toFixed(2));
|
|
135
|
+
if (!isNaN(v)) {
|
|
136
|
+
updatePriceTier(index, 'price', v);
|
|
137
|
+
e.target.value = v.toFixed(2);
|
|
138
|
+
}
|
|
139
|
+
}}
|
|
140
|
+
className="pl-7"
|
|
141
|
+
/>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
{priceTiers.length > 1 && (
|
|
145
|
+
<button
|
|
146
|
+
type="button"
|
|
147
|
+
onClick={() => removePriceTier(index)}
|
|
148
|
+
className={`p-1.5 text-label-tertiary hover:text-label-danger transition-colors ${index === 0 ? 'mt-5' : ''}`}
|
|
149
|
+
>
|
|
150
|
+
<IconCross className="w-4 h-4 fill-current" />
|
|
151
|
+
</button>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
))}
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<Button
|
|
158
|
+
type="button"
|
|
159
|
+
variant="outline"
|
|
160
|
+
onClick={addPriceTier}
|
|
161
|
+
className="w-fit"
|
|
162
|
+
withIcon
|
|
163
|
+
>
|
|
164
|
+
<IconPlus className="w-4 h-4 fill-fill-secondary" />
|
|
165
|
+
Add Price
|
|
166
|
+
</Button>
|
|
167
|
+
</div>
|
|
168
|
+
)}
|
|
169
|
+
</div>
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export default PricingSection;
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { Input } from '../ui/input';
|
|
3
|
+
import { Label } from '../ui/label';
|
|
4
|
+
import { Textarea } from '../ui/textarea';
|
|
5
|
+
import { Checkbox } from '../ui/checkbox';
|
|
6
|
+
import {
|
|
7
|
+
Select,
|
|
8
|
+
SelectContent,
|
|
9
|
+
SelectItem,
|
|
10
|
+
SelectTrigger,
|
|
11
|
+
SelectValue,
|
|
12
|
+
} from '../ui/select';
|
|
13
|
+
import { getFieldsForType, ProductFieldConfig } from './productTypeConfig';
|
|
14
|
+
import { supabase } from '@/integrations/supabase/client';
|
|
15
|
+
|
|
16
|
+
interface Zone {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface Resource {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
instances: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface ProductTypeFieldsProps {
|
|
28
|
+
productType: string;
|
|
29
|
+
values: Record<string, any>;
|
|
30
|
+
onChange: (field: string, value: any) => void;
|
|
31
|
+
showErrors?: boolean;
|
|
32
|
+
providerId?: string;
|
|
33
|
+
filterFields?: string[];
|
|
34
|
+
selectedZoneId?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const ProductTypeFields: React.FC<ProductTypeFieldsProps> = ({
|
|
38
|
+
productType,
|
|
39
|
+
values,
|
|
40
|
+
onChange,
|
|
41
|
+
showErrors = false,
|
|
42
|
+
providerId,
|
|
43
|
+
filterFields,
|
|
44
|
+
selectedZoneId,
|
|
45
|
+
}) => {
|
|
46
|
+
const allFields = getFieldsForType(productType);
|
|
47
|
+
const fields = filterFields
|
|
48
|
+
? allFields.filter(f => filterFields.includes(f.name))
|
|
49
|
+
: allFields;
|
|
50
|
+
const [zones, setZones] = useState<Zone[]>([]);
|
|
51
|
+
const [loadingZones, setLoadingZones] = useState(false);
|
|
52
|
+
const [resources, setResources] = useState<Resource[]>([]);
|
|
53
|
+
const [loadingResources, setLoadingResources] = useState(false);
|
|
54
|
+
|
|
55
|
+
// Fetch zones when provider context is available
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const fetchZones = async () => {
|
|
58
|
+
if (!providerId) return;
|
|
59
|
+
|
|
60
|
+
setLoadingZones(true);
|
|
61
|
+
try {
|
|
62
|
+
const { data, error } = await supabase
|
|
63
|
+
.from('zones')
|
|
64
|
+
.select('id, name')
|
|
65
|
+
.eq('provider_id', providerId)
|
|
66
|
+
.eq('status', 'active')
|
|
67
|
+
.order('display_order');
|
|
68
|
+
|
|
69
|
+
if (error) throw error;
|
|
70
|
+
setZones(data || []);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error('Error fetching zones:', error);
|
|
73
|
+
} finally {
|
|
74
|
+
setLoadingZones(false);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
fetchZones();
|
|
79
|
+
}, [providerId]);
|
|
80
|
+
|
|
81
|
+
// Fetch resources when zone is selected
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
const fetchResources = async () => {
|
|
84
|
+
const zoneId = selectedZoneId || values.zone_id;
|
|
85
|
+
if (!zoneId) {
|
|
86
|
+
setResources([]);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
setLoadingResources(true);
|
|
91
|
+
try {
|
|
92
|
+
const { data, error } = await supabase
|
|
93
|
+
.from('resources')
|
|
94
|
+
.select('id, name, instances')
|
|
95
|
+
.eq('zone_id', zoneId)
|
|
96
|
+
.order('name');
|
|
97
|
+
|
|
98
|
+
if (error) throw error;
|
|
99
|
+
setResources(data || []);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error('Error fetching resources:', error);
|
|
102
|
+
} finally {
|
|
103
|
+
setLoadingResources(false);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
fetchResources();
|
|
108
|
+
}, [selectedZoneId, values.zone_id]);
|
|
109
|
+
|
|
110
|
+
const renderField = (field: ProductFieldConfig) => {
|
|
111
|
+
// Check conditional visibility
|
|
112
|
+
if (field.conditionalOn) {
|
|
113
|
+
const conditionMet = values[field.conditionalOn.field] === field.conditionalOn.value;
|
|
114
|
+
if (!conditionMet) return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const value = values[field.name] ?? '';
|
|
118
|
+
|
|
119
|
+
switch (field.type) {
|
|
120
|
+
case 'text':
|
|
121
|
+
return (
|
|
122
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
123
|
+
<Label htmlFor={field.name}>{field.label}</Label>
|
|
124
|
+
<div className="flex items-center gap-2">
|
|
125
|
+
<Input
|
|
126
|
+
id={field.name}
|
|
127
|
+
type="text"
|
|
128
|
+
value={value}
|
|
129
|
+
onChange={(e) => onChange(field.name, e.target.value)}
|
|
130
|
+
placeholder={field.placeholder}
|
|
131
|
+
className="flex-1"
|
|
132
|
+
/>
|
|
133
|
+
{field.unit && (
|
|
134
|
+
<span className="text-label-secondary text-sm">{field.unit}</span>
|
|
135
|
+
)}
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
case 'number':
|
|
141
|
+
return (
|
|
142
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
143
|
+
<Label htmlFor={field.name}>{field.label}</Label>
|
|
144
|
+
<div className="flex items-center gap-2">
|
|
145
|
+
{field.unit === '£' && (
|
|
146
|
+
<span className="text-label-secondary text-sm">{field.unit}</span>
|
|
147
|
+
)}
|
|
148
|
+
<Input
|
|
149
|
+
id={field.name}
|
|
150
|
+
type="number"
|
|
151
|
+
value={value}
|
|
152
|
+
onChange={(e) => onChange(field.name, e.target.value ? parseFloat(e.target.value) : '')}
|
|
153
|
+
placeholder={field.placeholder}
|
|
154
|
+
className="flex-1"
|
|
155
|
+
min={0}
|
|
156
|
+
step={field.unit === '£' ? '0.01' : '1'}
|
|
157
|
+
/>
|
|
158
|
+
{field.unit && field.unit !== '£' && (
|
|
159
|
+
<span className="text-label-secondary text-sm">{field.unit}</span>
|
|
160
|
+
)}
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
case 'textarea':
|
|
166
|
+
return (
|
|
167
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
168
|
+
<Label htmlFor={field.name}>{field.label}</Label>
|
|
169
|
+
<Textarea
|
|
170
|
+
id={field.name}
|
|
171
|
+
value={value}
|
|
172
|
+
onChange={(e) => onChange(field.name, e.target.value)}
|
|
173
|
+
placeholder={field.placeholder}
|
|
174
|
+
rows={3}
|
|
175
|
+
/>
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
case 'resource-select':
|
|
180
|
+
// Only render resource select if we have a zone selected
|
|
181
|
+
const zoneId = selectedZoneId || values.zone_id;
|
|
182
|
+
if (!zoneId) {
|
|
183
|
+
return (
|
|
184
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
185
|
+
<Label htmlFor={field.name}>{field.label}</Label>
|
|
186
|
+
<p className="text-label-tertiary text-sm">Select a zone first</p>
|
|
187
|
+
</div>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return (
|
|
192
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
193
|
+
<Label htmlFor={field.name}>{field.label}</Label>
|
|
194
|
+
<Select value={value} onValueChange={(val) => onChange(field.name, val)}>
|
|
195
|
+
<SelectTrigger className="bg-surface-primary">
|
|
196
|
+
<SelectValue placeholder={loadingResources ? "Loading resources..." : "Select resource"} />
|
|
197
|
+
</SelectTrigger>
|
|
198
|
+
<SelectContent className="bg-surface-primary border border-border-primary z-50">
|
|
199
|
+
{resources.map((resource) => (
|
|
200
|
+
<SelectItem key={resource.id} value={resource.id}>
|
|
201
|
+
{resource.name} {resource.instances > 1 ? `(${resource.instances} available)` : ''}
|
|
202
|
+
</SelectItem>
|
|
203
|
+
))}
|
|
204
|
+
{resources.length === 0 && !loadingResources && (
|
|
205
|
+
<div className="px-2 py-1.5 text-label-secondary text-sm">
|
|
206
|
+
No resources in this zone
|
|
207
|
+
</div>
|
|
208
|
+
)}
|
|
209
|
+
</SelectContent>
|
|
210
|
+
</Select>
|
|
211
|
+
</div>
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
case 'select':
|
|
215
|
+
return (
|
|
216
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
217
|
+
<Label htmlFor={field.name}>{field.label}</Label>
|
|
218
|
+
<Select value={value} onValueChange={(val) => onChange(field.name, val)}>
|
|
219
|
+
<SelectTrigger className="bg-surface-primary">
|
|
220
|
+
<SelectValue placeholder={`Select ${field.label.toLowerCase()}`} />
|
|
221
|
+
</SelectTrigger>
|
|
222
|
+
<SelectContent className="bg-surface-primary border border-border-primary z-50">
|
|
223
|
+
{field.options?.map((option) => (
|
|
224
|
+
<SelectItem key={option.value} value={option.value}>
|
|
225
|
+
{option.label}
|
|
226
|
+
</SelectItem>
|
|
227
|
+
))}
|
|
228
|
+
</SelectContent>
|
|
229
|
+
</Select>
|
|
230
|
+
</div>
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
case 'zone-select':
|
|
234
|
+
// Only render zone select if we have a provider context
|
|
235
|
+
if (!providerId) return null;
|
|
236
|
+
|
|
237
|
+
return (
|
|
238
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
239
|
+
<Label htmlFor={field.name}>{field.label}</Label>
|
|
240
|
+
<Select value={value} onValueChange={(val) => onChange(field.name, val)}>
|
|
241
|
+
<SelectTrigger className="bg-surface-primary">
|
|
242
|
+
<SelectValue placeholder={loadingZones ? "Loading zones..." : "Select zone"} />
|
|
243
|
+
</SelectTrigger>
|
|
244
|
+
<SelectContent className="bg-surface-primary border border-border-primary z-50">
|
|
245
|
+
{zones.map((zone) => (
|
|
246
|
+
<SelectItem key={zone.id} value={zone.id}>
|
|
247
|
+
{zone.name}
|
|
248
|
+
</SelectItem>
|
|
249
|
+
))}
|
|
250
|
+
{zones.length === 0 && !loadingZones && (
|
|
251
|
+
<div className="px-2 py-1.5 text-label-secondary text-sm">
|
|
252
|
+
No zones available
|
|
253
|
+
</div>
|
|
254
|
+
)}
|
|
255
|
+
</SelectContent>
|
|
256
|
+
</Select>
|
|
257
|
+
</div>
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
case 'checkbox':
|
|
261
|
+
return (
|
|
262
|
+
<div key={field.name} className="flex items-center gap-3">
|
|
263
|
+
<Checkbox
|
|
264
|
+
id={field.name}
|
|
265
|
+
checked={value === true}
|
|
266
|
+
onCheckedChange={(checked) => onChange(field.name, checked)}
|
|
267
|
+
/>
|
|
268
|
+
<Label htmlFor={field.name} className="cursor-pointer">
|
|
269
|
+
{field.label}
|
|
270
|
+
</Label>
|
|
271
|
+
</div>
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
case 'date':
|
|
275
|
+
return (
|
|
276
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
277
|
+
<Label htmlFor={field.name}>{field.label}</Label>
|
|
278
|
+
<Input
|
|
279
|
+
id={field.name}
|
|
280
|
+
type="date"
|
|
281
|
+
value={value}
|
|
282
|
+
onChange={(e) => onChange(field.name, e.target.value)}
|
|
283
|
+
/>
|
|
284
|
+
</div>
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
case 'time':
|
|
288
|
+
return (
|
|
289
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
290
|
+
<Label htmlFor={field.name}>{field.label}</Label>
|
|
291
|
+
<Input
|
|
292
|
+
id={field.name}
|
|
293
|
+
type="time"
|
|
294
|
+
value={value}
|
|
295
|
+
onChange={(e) => onChange(field.name, e.target.value)}
|
|
296
|
+
/>
|
|
297
|
+
</div>
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
case 'duration-hours-minutes':
|
|
301
|
+
// Get hours and minutes values for this duration field
|
|
302
|
+
const hoursValue = values[`${field.name}_hours`] ?? '';
|
|
303
|
+
const minutesValue = values[`${field.name}_minutes`] ?? '';
|
|
304
|
+
|
|
305
|
+
return (
|
|
306
|
+
<div key={field.name} className="flex flex-col gap-2">
|
|
307
|
+
<Label>{field.label}</Label>
|
|
308
|
+
<div className="flex items-center gap-3">
|
|
309
|
+
<div className="flex items-center gap-2">
|
|
310
|
+
<Input
|
|
311
|
+
id={`${field.name}_hours`}
|
|
312
|
+
type="number"
|
|
313
|
+
value={hoursValue}
|
|
314
|
+
onChange={(e) => onChange(`${field.name}_hours`, e.target.value ? parseInt(e.target.value) : '')}
|
|
315
|
+
|
|
316
|
+
className="w-20"
|
|
317
|
+
min={0}
|
|
318
|
+
max={23}
|
|
319
|
+
/>
|
|
320
|
+
<span className="text-label-secondary text-sm">hours</span>
|
|
321
|
+
</div>
|
|
322
|
+
<div className="flex items-center gap-2">
|
|
323
|
+
<Input
|
|
324
|
+
id={`${field.name}_minutes`}
|
|
325
|
+
type="number"
|
|
326
|
+
value={minutesValue}
|
|
327
|
+
onChange={(e) => onChange(`${field.name}_minutes`, e.target.value ? parseInt(e.target.value) : '')}
|
|
328
|
+
|
|
329
|
+
className="w-20"
|
|
330
|
+
min={0}
|
|
331
|
+
max={59}
|
|
332
|
+
/>
|
|
333
|
+
<span className="text-label-secondary text-sm">minutes</span>
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
</div>
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
default:
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
if (!productType) return null;
|
|
345
|
+
|
|
346
|
+
return (
|
|
347
|
+
<div className="flex flex-col gap-4">
|
|
348
|
+
{fields.map(renderField)}
|
|
349
|
+
</div>
|
|
350
|
+
);
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
export default ProductTypeFields;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface ProductTypeIconProps {
|
|
4
|
+
type: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
size?: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Inline SVG components using the project's icon set for instant rendering
|
|
10
|
+
const ActivityIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
11
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
12
|
+
<path d="M13.8299 12.7899L12 13.4559V17H9.99997V12.05H10.015L15.2834 10.1325C15.5274 10.0386 15.7922 9.99162 16.0648 10.0008C17.1762 10.0281 18.1522 10.7567 18.4917 11.8204C18.678 12.4043 18.848 12.7984 19.0015 13.0025C19.9138 14.2155 21.3653 15 23 15V17C20.8253 17 18.8823 16.0083 17.5984 14.4526L16.9008 18.4085L19 20.17V27H17V21.1025L14.7307 19.1984L14.003 23.3253L7.10938 22.1098L7.45667 20.1401L12.3807 21.0084L13.8299 12.7899ZM17.5 9.5C16.3954 9.5 15.5 8.60457 15.5 7.5C15.5 6.39543 16.3954 5.5 17.5 5.5C18.6046 5.5 19.5 6.39543 19.5 7.5C19.5 8.60457 18.6046 9.5 17.5 9.5Z" fill="currentColor"/>
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const PackageIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
17
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
18
|
+
<path d="M16 3L27 9V23L16 29L5 23V9L16 3ZM16 5.311L7 10.1564V21.8436L16 26.689L25 21.8436V10.1564L16 5.311ZM16 19C13.2386 19 11 16.7614 11 14C11 11.2386 13.2386 9 16 9C18.7614 9 21 11.2386 21 14C21 16.7614 18.7614 19 16 19ZM16 17C17.6569 17 19 15.6569 19 14C19 12.3431 17.6569 11 16 11C14.3431 11 13 12.3431 13 14C13 15.6569 14.3431 17 16 17Z" fill="currentColor"/>
|
|
19
|
+
</svg>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const TimeIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
23
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
24
|
+
<path d="M16 26C10.4771 26 6 21.5228 6 16C6 10.4771 10.4771 6 16 6C21.5228 6 26 10.4771 26 16C26 21.5228 21.5228 26 16 26ZM16 24C20.4183 24 24 20.4183 24 16C24 11.5817 20.4183 8 16 8C11.5817 8 8 11.5817 8 16C8 20.4183 11.5817 24 16 24ZM17 16H21V18H15V11H17V16Z" fill="currentColor"/>
|
|
25
|
+
</svg>
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const TicketIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
29
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
30
|
+
<path d="M25.0049 6.99976C25.5572 6.99976 26.0049 7.44747 26.0049 7.99976V13.4998C24.6242 13.4998 23.5049 14.6191 23.5049 15.9998C23.5049 17.3805 24.6242 18.4998 26.0049 18.4998V23.9998C26.0049 24.5521 25.5572 24.9998 25.0049 24.9998H7.00488C6.4526 24.9998 6.00488 24.5521 6.00488 23.9998V18.4998C7.38559 18.4998 8.50488 17.3805 8.50488 15.9998C8.50488 14.6191 7.38559 13.4998 6.00488 13.4998V7.99976C6.00488 7.44747 6.4526 6.99976 7.00488 6.99976H25.0049ZM24.0049 8.99976H8.00488V11.9678L8.16077 12.0488C9.49935 12.7808 10.4252 14.1733 10.5 15.788L10.5049 15.9998C10.5049 17.704 9.55755 19.1869 8.16077 19.9507L8.00488 20.0308V22.9998H24.0049V20.0308L23.849 19.9507C22.5104 19.2187 21.5846 17.8263 21.5098 16.2116L21.5049 15.9998C21.5049 14.2956 22.4522 12.8126 23.849 12.0488L24.0049 11.9678V8.99976Z" fill="currentColor"/>
|
|
31
|
+
</svg>
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const FoodIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
35
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
36
|
+
<path d="M8.22235 7.80753L14.9399 14.525L12.1114 17.3535L8.22235 13.4644C6.66026 11.9023 6.66026 9.36963 8.22235 7.80753ZM18.2683 16.1464L17.4147 16.9999L24.4858 24.071L23.0716 25.4852L16.0005 18.4141L8.92946 25.4852L7.51525 24.071L16.854 14.7322C16.2664 13.2752 16.8738 11.1769 18.4754 9.5753C20.428 7.62268 23.119 7.1478 24.4858 8.51464C25.8526 9.88147 25.3778 12.5724 23.4251 14.525C21.8235 16.1267 19.7252 16.7341 18.2683 16.1464Z" fill="currentColor"/>
|
|
37
|
+
</svg>
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const ClothingIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
41
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
42
|
+
<path d="M12.998 7C12.998 8.65685 14.3412 10 15.998 10C17.6549 10 18.998 8.65685 18.998 7H24.998C25.5503 7 25.998 7.44772 25.998 8V15C25.998 15.5523 25.5503 16 24.998 16H22.997L22.998 24C22.998 24.5523 22.5503 25 21.998 25H9.99805C9.44576 25 8.99805 24.5523 8.99805 24L8.99705 15.999L6.99805 16C6.44576 16 5.99805 15.5523 5.99805 15V8C5.99805 7.44772 6.44576 7 6.99805 7H12.998ZM23.998 8.999H20.581L20.5642 9.04018C19.8115 10.7223 18.1566 11.9125 16.2149 11.9954L15.998 12C13.9633 12 12.2124 10.7846 11.4319 9.04018L11.414 8.999H7.99805V13.999L10.9968 13.998L10.997 23H20.998L20.9968 14L23.998 13.999V8.999Z" fill="currentColor"/>
|
|
43
|
+
</svg>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const UserIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
47
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
48
|
+
<path d="M8 26C8 21.5817 11.5817 18 16 18C20.4183 18 24 21.5817 24 26H22C22 22.6863 19.3137 20 16 20C12.6863 20 10 22.6863 10 26H8ZM16 17C12.685 17 10 14.315 10 11C10 7.685 12.685 5 16 5C19.315 5 22 7.685 22 11C22 14.315 19.315 17 16 17ZM16 15C18.21 15 20 13.21 20 11C20 8.79 18.21 7 16 7C13.79 7 12 8.79 12 11C12 13.21 13.79 15 16 15Z" fill="currentColor"/>
|
|
49
|
+
</svg>
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const GiftCardIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
53
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
54
|
+
<path d="M5 6C4.44772 6 4 6.44772 4 7V12H8C9.10457 12 10 12.8954 10 14C10 15.1046 9.10457 16 8 16H4V26C4 26.5523 4.44772 27 5 27H27C27.5523 27 28 26.5523 28 26V16H24C22.8954 16 22 15.1046 22 14C22 12.8954 22.8954 12 24 12H28V7C28 6.44772 27.5523 6 27 6H5ZM6 8H26V10H24C22.3431 10 21 11.3431 21 13C21 14.6569 22.3431 16 24 16H26V17H6V16H8C9.65685 16 11 14.6569 11 13C11 11.3431 9.65685 10 8 10H6V8ZM6 19H26V25H6V19Z" fill="currentColor" />
|
|
55
|
+
</svg>
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const InfoCardIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
59
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
60
|
+
<path d="M7 10H25V22H7V10ZM6 8C5.44772 8 5 8.44772 5 9V23C5 23.5523 5.44772 24 6 24H26C26.5523 24 27 23.5523 27 23V9C27 8.44772 26.5523 8 26 8H6ZM17 13H23V15H17V13ZM22 17H17V19H22V17ZM10 17H11V20H13V15H10V17ZM13 12H11V14H13V12Z" fill="currentColor"/>
|
|
61
|
+
</svg>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const TelephoneIcon = ({ size = 20, className = '' }: { size?: number; className?: string }) => (
|
|
65
|
+
<svg width={size} height={size} viewBox="0 0 32 32" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
|
|
66
|
+
<path d="M25 20.42V23.9561C25 24.4811 24.5941 24.9167 24.0705 24.9537C23.6331 24.9846 23.2763 25 23 25C14.1634 25 7 17.8366 7 9C7 8.72371 7.01545 8.36687 7.04635 7.9295C7.08337 7.40588 7.51894 7 8.04386 7H11.5801C11.8368 7 12.0518 7.19442 12.0775 7.4498C12.1007 7.67907 12.1222 7.86314 12.1421 8.00202C12.3443 9.41472 12.7575 10.7594 13.3487 12.003C13.4436 12.2026 13.3817 12.4416 13.2018 12.5701L11.0436 14.1118C12.3575 17.1811 14.8189 19.6425 17.8882 20.9565L19.4271 18.8019C19.5572 18.6199 19.799 18.5573 20.001 18.6532C21.2446 19.2439 22.5891 19.6566 24.0016 19.8584C24.1396 19.8782 24.3225 19.8995 24.5502 19.9225C24.8056 19.9483 25 20.1633 25 20.42Z" fill="currentColor"/>
|
|
67
|
+
</svg>
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const iconComponents: Record<string, React.FC<{ size?: number; className?: string }>> = {
|
|
71
|
+
activity: ActivityIcon,
|
|
72
|
+
sessions: TimeIcon,
|
|
73
|
+
tickets: TicketIcon,
|
|
74
|
+
offers: TicketIcon,
|
|
75
|
+
memberships: UserIcon,
|
|
76
|
+
gift_cards: GiftCardIcon,
|
|
77
|
+
food_beverage: FoodIcon,
|
|
78
|
+
clothing: ClothingIcon,
|
|
79
|
+
item: TelephoneIcon,
|
|
80
|
+
packages: PackageIcon,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const ProductTypeIcon: React.FC<ProductTypeIconProps> = ({
|
|
84
|
+
type,
|
|
85
|
+
className = '',
|
|
86
|
+
size = 20,
|
|
87
|
+
}) => {
|
|
88
|
+
const IconComponent = iconComponents[type];
|
|
89
|
+
|
|
90
|
+
if (!IconComponent) return null;
|
|
91
|
+
|
|
92
|
+
return <IconComponent size={size} className={`text-label-primary ${className}`} />;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export default ProductTypeIcon;
|