@burdenoff/microfe-tours 2026.513.2 → 2026.516.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/generated/global-operations.d.ts +49 -0
- package/dist/generated/global-operations.d.ts.map +1 -1
- package/dist/generated/global-operations.js +84 -62
- package/dist/generated/global-operations.js.map +1 -1
- package/dist/tours/hooks/useTourBuilder.d.ts.map +1 -1
- package/dist/tours/hooks/useTourBuilder.js +22 -20
- package/dist/tours/hooks/useTourBuilder.js.map +1 -1
- package/dist/tours/hooks/useTourLifecycle.d.ts.map +1 -1
- package/dist/tours/hooks/useTourLifecycle.js +31 -18
- package/dist/tours/hooks/useTourLifecycle.js.map +1 -1
- package/dist/tours/pages/TourBuilderPage.d.ts.map +1 -1
- package/dist/tours/pages/TourBuilderPage.js +556 -182
- package/dist/tours/pages/TourBuilderPage.js.map +1 -1
- package/dist/tours/pages/TourPreviewPage.js +3 -3
- package/dist/tours/pages/ToursListPage.d.ts.map +1 -1
- package/dist/tours/pages/ToursListPage.js +156 -155
- package/dist/tours/pages/ToursListPage.js.map +1 -1
- package/dist/tours/store/toursStore.d.ts +2 -0
- package/dist/tours/store/toursStore.d.ts.map +1 -1
- package/dist/tours/store/toursStore.js +2 -0
- package/dist/tours/store/toursStore.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TourBuilderPage.js","names":[],"sources":["../../../src/tours/pages/TourBuilderPage.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport {\n Save,\n ArrowLeft,\n Eye,\n ListOrdered,\n BarChart3,\n Calendar,\n LayoutTemplate,\n} from 'lucide-react';\nimport { PermissionGate } from '@burdenoff/fe-libs/shared/components';\nimport { useTourBuilder } from '../hooks/useTourBuilder';\nimport { useTourLifecycle } from '../hooks/useTourLifecycle';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport type { Tour, TourTriggerType } from '../types';\nimport { useToursI18n } from '../i18n';\n\n/**\n * Tour builder page\n * Create or edit tour metadata\n */\nexport function TourBuilderPage() {\n const { tr } = useToursI18n();\n const { tourId } = useParams();\n const navigate = useNavigate();\n const { basePath = '/' } = useToursContext();\n const { hasPermission } = useToursPermissionAccess();\n const isNew = !tourId || tourId === 'new';\n const canCreate = hasPermission(TOUR_PERMISSIONS.TOUR_CREATE);\n const canUpdate = hasPermission(TOUR_PERMISSIONS.TOUR_UPDATE);\n const canCreateTemplate = hasPermission(TOUR_PERMISSIONS.TOUR_TEMPLATE_CREATE);\n const canSave = isNew ? canCreate : canUpdate;\n\n const { tour, loadTour, createTour, updateTour, saving, validationErrors, error } =\n useTourBuilder(tourId);\n const { saveAsTemplate } = useTourLifecycle();\n\n const defaultFormData = {\n name: '',\n description: '',\n productId: '',\n moduleId: '',\n pageId: '',\n isActive: true,\n status: 'DRAFT' as const,\n triggerType: 'MANUAL' as const,\n priority: 50,\n displayOrder: 1,\n startDate: '',\n endDate: '',\n };\n\n const [formData, setFormData] = useState<Partial<Tour>>(defaultFormData);\n\n const formInitializedRef = useRef(false);\n\n useEffect(() => {\n if (tourId && tourId !== 'new') {\n formInitializedRef.current = false;\n loadTour(tourId);\n }\n }, [tourId, loadTour]);\n\n useEffect(() => {\n if (tour && !formInitializedRef.current) {\n setFormData(tour);\n formInitializedRef.current = true;\n }\n }, [tour]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n try {\n if (tourId && tourId !== 'new') {\n await updateTour(tourId, formData);\n } else {\n await createTour(formData);\n }\n } catch (error) {\n console.error('Failed to save tour:', error);\n }\n };\n\n const handleBack = () => {\n navigate(`${basePath}/list`);\n };\n\n const formatDateTimeLocal = (value?: string) => {\n if (!value) return '';\n\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n\n return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, 16);\n };\n\n const handleSaveTemplate = async () => {\n if (!tourId || tourId === 'new') return;\n\n const defaultName = `${formData.name || tour?.name || 'Tour'} Template`;\n const name = window.prompt('Template name', defaultName);\n if (!name) return;\n\n const category =\n window.prompt(\n 'Template category (ONBOARDING, FEATURE_ANNOUNCEMENT, HELP, CUSTOM)',\n 'ONBOARDING'\n ) || 'ONBOARDING';\n\n try {\n await saveAsTemplate(tourId, {\n name,\n description: formData.description,\n category,\n isPublic: false,\n });\n navigate(`${basePath}/templates`);\n } catch (saveTemplateError) {\n console.error('Failed to save template:', saveTemplateError);\n }\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6 max-w-4xl mx-auto\">\n {/* Header */}\n <div className=\"flex items-center gap-4\">\n <button\n onClick={handleBack}\n className=\"p-2 hover:bg-accent rounded-md\"\n aria-label={tr('tourBuilder.goBack')}\n >\n <ArrowLeft size={20} />\n </button>\n <div className=\"flex-1\">\n <h1 className=\"text-xl sm:text-2xl font-bold text-foreground\">\n {tourId && tourId !== 'new'\n ? tr('tourBuilder.titleEdit')\n : tr('tourBuilder.titleCreate')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">{tr('tourBuilder.subtitle')}</p>\n </div>\n </div>\n\n {/* Form */}\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n {/* Basic Info */}\n <div className=\"border border-border rounded-md p-4 sm:p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4\">{tr('tourBuilder.sectionBasicInfo')}</h2>\n\n <div className=\"space-y-4\">\n {/* Name */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"tour-name\">\n {tr('tourBuilder.labelName')}\n </label>\n <input\n id=\"tour-name\"\n type=\"text\"\n value={formData.name || ''}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n required\n />\n </div>\n\n {/* Description */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"tour-description\">\n {tr('tourBuilder.labelDescription')}\n </label>\n <textarea\n id=\"tour-description\"\n value={formData.description || ''}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={3}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n />\n </div>\n\n {/* Product ID */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"product-id\">\n {tr('tourBuilder.labelProductId')}\n </label>\n <input\n id=\"product-id\"\n type=\"text\"\n value={formData.productId || ''}\n onChange={(e) => setFormData({ ...formData, productId: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n required\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"module-id\">\n Module ID\n </label>\n <input\n id=\"module-id\"\n type=\"text\"\n value={formData.moduleId || ''}\n onChange={(e) =>\n setFormData({ ...formData, moduleId: e.target.value || undefined })\n }\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n placeholder=\"vibecontrols\"\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"page-id\">\n Page ID\n </label>\n <input\n id=\"page-id\"\n type=\"text\"\n value={formData.pageId || ''}\n onChange={(e) =>\n setFormData({ ...formData, pageId: e.target.value || undefined })\n }\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n placeholder=\"agents\"\n />\n </div>\n </div>\n\n <label className=\"flex items-center gap-3 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={formData.isActive ?? true}\n onChange={(e) => setFormData({ ...formData, isActive: e.target.checked })}\n className=\"w-4 h-4 rounded\"\n />\n <span className=\"text-sm font-medium\">Active</span>\n </label>\n </div>\n </div>\n\n {/* Trigger Settings */}\n <div className=\"border border-border rounded-md p-4 sm:p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4\">{tr('tourBuilder.sectionTriggerSettings')}</h2>\n\n <div className=\"space-y-4\">\n {/* Trigger Type */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"trigger-type\">\n {tr('tourBuilder.labelTriggerType')}\n </label>\n <select\n id=\"trigger-type\"\n value={formData.triggerType || 'MANUAL'}\n onChange={(e) =>\n setFormData({ ...formData, triggerType: e.target.value as TourTriggerType })\n }\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n >\n <option value=\"MANUAL\">{tr('tourBuilder.triggerManual')}</option>\n <option value=\"AUTO_FIRST_VISIT\">{tr('tourBuilder.triggerAutoFirstVisit')}</option>\n <option value=\"AUTO_ALWAYS\">{tr('tourBuilder.triggerAutoAlways')}</option>\n <option value=\"ON_EVENT\">{tr('tourBuilder.triggerOnEvent')}</option>\n <option value=\"SCHEDULED\">{tr('tourBuilder.triggerScheduled')}</option>\n </select>\n </div>\n\n {/* Priority */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"priority\">\n {tr('tourBuilder.labelPriority')}\n </label>\n <input\n id=\"priority\"\n type=\"number\"\n min=\"1\"\n max=\"100\"\n value={formData.priority || 50}\n onChange={(e) => setFormData({ ...formData, priority: parseInt(e.target.value) })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"tour-start-date\">\n Start Date\n </label>\n <input\n id=\"tour-start-date\"\n type=\"datetime-local\"\n value={formatDateTimeLocal(formData.startDate)}\n onChange={(e) =>\n setFormData({\n ...formData,\n startDate: e.target.value\n ? new Date(e.target.value).toISOString()\n : undefined,\n })\n }\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"tour-end-date\">\n End Date\n </label>\n <input\n id=\"tour-end-date\"\n type=\"datetime-local\"\n value={formatDateTimeLocal(formData.endDate)}\n onChange={(e) =>\n setFormData({\n ...formData,\n endDate: e.target.value ? new Date(e.target.value).toISOString() : undefined,\n })\n }\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n />\n </div>\n </div>\n </div>\n </div>\n\n {/* API Error */}\n {error && (\n <div className=\"border border-destructive rounded-md p-4 bg-destructive/10\">\n <h3 className=\"font-semibold text-destructive mb-2\">{tr('tourBuilder.errorTitle')}</h3>\n <p className=\"text-sm text-destructive\">{error.message}</p>\n </div>\n )}\n\n {/* Validation Errors */}\n {validationErrors.length > 0 && (\n <div className=\"border border-destructive rounded-md p-4 bg-destructive/10\">\n <h3 className=\"font-semibold text-destructive mb-2\">\n {tr('tourBuilder.validationErrorsTitle')}\n </h3>\n <ul className=\"list-disc list-inside space-y-1\">\n {validationErrors.map((err, index) => (\n <li key={index} className=\"text-sm text-destructive\">\n {err.message}\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex flex-wrap gap-3\">\n <PermissionGate\n permission={isNew ? TOUR_PERMISSIONS.TOUR_CREATE : TOUR_PERMISSIONS.TOUR_UPDATE}\n >\n <button\n type=\"submit\"\n disabled={saving || !canSave}\n className=\"flex-1 min-w-[200px] px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 disabled:opacity-50 flex items-center justify-center gap-2\"\n >\n <Save size={20} />\n {saving\n ? tr('tourBuilder.saving')\n : tourId && tourId !== 'new'\n ? tr('tourBuilder.updateTour')\n : tr('tourBuilder.createAndAddSteps')}\n </button>\n </PermissionGate>\n {tourId && tourId !== 'new' && (\n <>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${tourId}/steps`)}\n className=\"px-4 py-2 bg-secondary text-secondary-foreground rounded-md hover:bg-secondary/80 flex items-center gap-2\"\n >\n <ListOrdered size={20} />\n {tr('tourBuilder.editSteps')}\n {tour?.steps && tour.steps.length > 0 && (\n <span className=\"ml-1 px-2 py-0.5 text-xs bg-primary/20 rounded-full\">\n {tour.steps.length}\n </span>\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${tourId}/preview`)}\n className=\"px-4 py-2 border border-border rounded-md hover:bg-accent flex items-center gap-2\"\n >\n <Eye size={20} />\n {tr('tourBuilder.preview')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${tourId}/analytics`)}\n className=\"px-4 py-2 border border-border rounded-md hover:bg-accent flex items-center gap-2\"\n >\n <BarChart3 size={20} />\n {tr('tourBuilder.analytics')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${tourId}/schedule`)}\n className=\"px-4 py-2 border border-border rounded-md hover:bg-accent flex items-center gap-2\"\n >\n <Calendar size={20} />\n Schedule\n </button>\n <PermissionGate permission={TOUR_PERMISSIONS.TOUR_TEMPLATE_CREATE}>\n <button\n type=\"button\"\n onClick={handleSaveTemplate}\n disabled={!canCreateTemplate}\n className=\"px-4 py-2 border border-border rounded-md hover:bg-accent flex items-center gap-2 disabled:opacity-50\"\n >\n <LayoutTemplate size={20} />\n Save as Template\n </button>\n </PermissionGate>\n </>\n )}\n </div>\n </form>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TourBuilderPage.js","names":[],"sources":["../../../src/tours/pages/TourBuilderPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport {\n Save,\n ArrowLeft,\n Eye,\n ListOrdered,\n BarChart3,\n Calendar,\n LayoutTemplate,\n} from 'lucide-react';\nimport { PermissionGate } from '@burdenoff/fe-libs/shared/components';\nimport { useTourBuilder } from '../hooks/useTourBuilder';\nimport { useTourLifecycle } from '../hooks/useTourLifecycle';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport type { Tour, TourTriggerType } from '../types';\nimport { useToursI18n } from '../i18n';\nimport { useGetPlatformProductsForToursQuery } from '../../generated/global-operations';\n\n// Covers the current platform catalog with room for planned products; custom slug entry remains the fallback.\nconst PLATFORM_PRODUCTS_QUERY_LIMIT = 250;\n\ninterface TourRouteModuleOption {\n moduleId: string;\n label: string;\n path: string;\n}\n\ninterface TourRoutePageOption {\n pageId: string;\n label: string;\n path: string;\n}\n\ninterface TourRouteCatalogEntry {\n productId: string;\n moduleId: string;\n moduleLabel: string;\n pageId: string;\n pageLabel: string;\n path: string;\n isModuleHome?: boolean;\n}\n\nconst TOUR_ROUTE_CATALOG: readonly TourRouteCatalogEntry[] = [\n {\n productId: 'vibecontrols',\n moduleId: 'dashboard',\n moduleLabel: 'Dashboard',\n pageId: 'dashboard',\n pageLabel: 'Dashboard',\n path: '/dashboard',\n isModuleHome: true,\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'home',\n pageLabel: 'Overview',\n path: '/vibecontrols',\n isModuleHome: true,\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'agents',\n pageLabel: 'Targets & Agents',\n path: '/vibecontrols/agents',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'vibes',\n pageLabel: 'Vibes',\n path: '/vibecontrols/vibes',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'sessions',\n pageLabel: 'Sessions',\n path: '/vibecontrols/sessions',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'ai',\n pageLabel: 'AI',\n path: '/vibecontrols/ai',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'catalogs',\n pageLabel: 'Catalogs',\n path: '/vibecontrols/catalogs',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'components',\n pageLabel: 'Components',\n path: '/vibecontrols/components',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'templates',\n pageLabel: 'Templates',\n path: '/vibecontrols/templates',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'actions',\n pageLabel: 'Actions',\n path: '/vibecontrols/actions',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'vibedeck',\n pageLabel: 'Decks',\n path: '/vibecontrols/vibedeck',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'calendar',\n pageLabel: 'Calendar',\n path: '/vibecontrols/calendar',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'tunnels',\n pageLabel: 'Tunnels',\n path: '/vibecontrols/tunnels',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'analytics',\n pageLabel: 'Analytics',\n path: '/vibecontrols/analytics',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'audit',\n pageLabel: 'Audit Log',\n path: '/vibecontrols/audit',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'health',\n pageLabel: 'Health',\n path: '/vibecontrols/health',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'vibecontrols',\n moduleLabel: 'VibeControls',\n pageId: 'settings',\n pageLabel: 'Settings',\n path: '/vibecontrols/settings',\n },\n {\n productId: 'vibecontrols',\n moduleId: 'scheduler',\n moduleLabel: 'Scheduler',\n pageId: 'scheduler',\n pageLabel: 'Scheduler',\n path: '/scheduler',\n isModuleHome: true,\n },\n {\n productId: 'vibecontrols',\n moduleId: 'sandbox',\n moduleLabel: 'Sandbox',\n pageId: 'sandbox',\n pageLabel: 'Sandbox',\n path: '/sandbox',\n isModuleHome: true,\n },\n] as const;\n\nfunction normalizeCatalogValue(value: string | null | undefined): string | undefined {\n const normalized = value?.trim();\n return normalized ? normalized : undefined;\n}\n\nfunction getRouteCatalog(productId: string | null | undefined): TourRouteCatalogEntry[] {\n const productKey = normalizeCatalogValue(productId);\n if (!productKey) return [];\n return TOUR_ROUTE_CATALOG.filter((entry) => entry.productId === productKey);\n}\n\nfunction getTourRouteModules(productId: string | null | undefined): TourRouteModuleOption[] {\n const modules = new Map<string, TourRouteModuleOption>();\n\n for (const entry of getRouteCatalog(productId)) {\n const existing = modules.get(entry.moduleId);\n if (!existing || entry.isModuleHome) {\n modules.set(entry.moduleId, {\n moduleId: entry.moduleId,\n label: entry.moduleLabel,\n path: entry.path,\n });\n }\n }\n\n return [...modules.values()];\n}\n\nfunction getTourRoutePages(\n productId: string | null | undefined,\n moduleId: string | null | undefined\n): TourRoutePageOption[] {\n const moduleKey = normalizeCatalogValue(moduleId);\n if (!moduleKey) return [];\n\n return getRouteCatalog(productId)\n .filter((entry) => entry.moduleId === moduleKey)\n .map((entry) => ({\n pageId: entry.pageId,\n label: entry.pageLabel,\n path: entry.path,\n }));\n}\n\n/**\n * Tour builder page\n * Create or edit tour metadata\n */\nexport function TourBuilderPage() {\n const { tr } = useToursI18n();\n const { tourId } = useParams();\n const navigate = useNavigate();\n const { basePath = '/' } = useToursContext();\n const { hasPermission } = useToursPermissionAccess();\n const isNew = !tourId || tourId === 'new';\n const canCreate = hasPermission(TOUR_PERMISSIONS.TOUR_CREATE);\n const canUpdate = hasPermission(TOUR_PERMISSIONS.TOUR_UPDATE);\n const canCreateTemplate = hasPermission(TOUR_PERMISSIONS.TOUR_TEMPLATE_CREATE);\n const canSave = isNew ? canCreate : canUpdate;\n\n const { tour, loadTour, createTour, updateTour, saving, validationErrors, error } =\n useTourBuilder(tourId);\n const { saveAsTemplate } = useTourLifecycle();\n const { data: productsData, loading: productsLoading } = useGetPlatformProductsForToursQuery({\n variables: { limit: PLATFORM_PRODUCTS_QUERY_LIMIT, offset: 0 },\n fetchPolicy: 'cache-and-network',\n });\n\n const defaultFormData = {\n name: '',\n description: '',\n productId: '',\n moduleId: '',\n pageId: '',\n isActive: true,\n status: 'DRAFT' as const,\n triggerType: 'MANUAL' as const,\n priority: 50,\n displayOrder: 1,\n startDate: '',\n endDate: '',\n };\n\n const [formData, setFormData] = useState<Partial<Tour>>(defaultFormData);\n const [customProductEntry, setCustomProductEntry] = useState(false);\n const [customModuleEntry, setCustomModuleEntry] = useState(false);\n const [customPageEntry, setCustomPageEntry] = useState(false);\n\n const formInitializedRef = useRef(false);\n\n const productOptions = useMemo(() => {\n return [...(productsData?.platformProducts.items ?? [])].sort((a, b) =>\n a.name.localeCompare(b.name)\n );\n }, [productsData]);\n\n const productOptionSlugs = useMemo(\n () => new Set(productOptions.map((product) => product.slug)),\n [productOptions]\n );\n\n const moduleOptions = useMemo(\n () => getTourRouteModules(formData.productId),\n [formData.productId]\n );\n\n const moduleOptionIds = useMemo(\n () => new Set(moduleOptions.map((moduleOption) => moduleOption.moduleId)),\n [moduleOptions]\n );\n\n const pageOptions = useMemo(\n () => getTourRoutePages(formData.productId, formData.moduleId),\n [formData.moduleId, formData.productId]\n );\n\n const pageOptionIds = useMemo(\n () => new Set(pageOptions.map((pageOption) => pageOption.pageId)),\n [pageOptions]\n );\n\n useEffect(() => {\n if (tourId && tourId !== 'new') {\n formInitializedRef.current = false;\n loadTour(tourId);\n }\n }, [tourId, loadTour]);\n\n useEffect(() => {\n if (tour && !formInitializedRef.current) {\n setFormData(tour);\n formInitializedRef.current = true;\n }\n }, [tour]);\n\n useEffect(() => {\n if (!formData.productId || productsLoading) {\n setCustomProductEntry(false);\n return;\n }\n setCustomProductEntry(productOptions.length > 0 && !productOptionSlugs.has(formData.productId));\n }, [formData.productId, productOptionSlugs, productOptions.length, productsLoading]);\n\n useEffect(() => {\n if (!formData.productId || !formData.moduleId) {\n setCustomModuleEntry(false);\n return;\n }\n setCustomModuleEntry(moduleOptions.length === 0 || !moduleOptionIds.has(formData.moduleId));\n }, [formData.moduleId, formData.productId, moduleOptionIds, moduleOptions.length]);\n\n useEffect(() => {\n if (!formData.productId || !formData.pageId) {\n setCustomPageEntry(false);\n return;\n }\n setCustomPageEntry(pageOptions.length === 0 || !pageOptionIds.has(formData.pageId));\n }, [formData.pageId, formData.productId, pageOptionIds, pageOptions.length]);\n\n const showCurrentProductOption = Boolean(\n formData.productId && !customProductEntry && !productOptionSlugs.has(formData.productId)\n );\n const showCurrentModuleOption = Boolean(\n formData.moduleId && !customModuleEntry && !moduleOptionIds.has(formData.moduleId)\n );\n const showCurrentPageOption = Boolean(\n formData.pageId && !customPageEntry && !pageOptionIds.has(formData.pageId)\n );\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n try {\n if (tourId && tourId !== 'new') {\n await updateTour(tourId, formData);\n } else {\n await createTour(formData);\n }\n } catch (error) {\n console.error('Failed to save tour:', error);\n }\n };\n\n const handleBack = () => {\n navigate(`${basePath}/list`);\n };\n\n const formatDateTimeLocal = (value?: string) => {\n if (!value) return '';\n\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n\n return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, 16);\n };\n\n const handleSaveTemplate = async () => {\n if (!tourId || tourId === 'new') return;\n\n const defaultName = `${formData.name || tour?.name || 'Tour'} Template`;\n const name = window.prompt('Template name', defaultName);\n if (!name) return;\n\n const category =\n window.prompt(\n 'Template category (ONBOARDING, FEATURE_ANNOUNCEMENT, HELP, CUSTOM)',\n 'ONBOARDING'\n ) || 'ONBOARDING';\n\n try {\n await saveAsTemplate(tourId, {\n name,\n description: formData.description,\n category,\n isPublic: false,\n });\n navigate(`${basePath}/templates`);\n } catch (saveTemplateError) {\n console.error('Failed to save template:', saveTemplateError);\n }\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6 max-w-4xl mx-auto\">\n {/* Header */}\n <div className=\"flex items-center gap-4\">\n <button\n onClick={handleBack}\n className=\"p-2 hover:bg-accent rounded-md\"\n aria-label={tr('tourBuilder.goBack')}\n >\n <ArrowLeft size={20} />\n </button>\n <div className=\"flex-1\">\n <h1 className=\"text-xl sm:text-2xl font-bold text-foreground\">\n {tourId && tourId !== 'new'\n ? tr('tourBuilder.titleEdit')\n : tr('tourBuilder.titleCreate')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">{tr('tourBuilder.subtitle')}</p>\n </div>\n </div>\n\n {/* Form */}\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n {/* Basic Info */}\n <div className=\"border border-border rounded-md p-4 sm:p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4\">{tr('tourBuilder.sectionBasicInfo')}</h2>\n\n <div className=\"space-y-4\">\n {/* Name */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"tour-name\">\n {tr('tourBuilder.labelName')}\n </label>\n <input\n id=\"tour-name\"\n type=\"text\"\n value={formData.name || ''}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n required\n />\n </div>\n\n {/* Description */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"tour-description\">\n {tr('tourBuilder.labelDescription')}\n </label>\n <textarea\n id=\"tour-description\"\n value={formData.description || ''}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={3}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n />\n </div>\n\n {/* Product ID */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"product-id\">\n {tr('tourBuilder.labelProductId')}\n </label>\n <select\n id=\"product-id\"\n value={customProductEntry ? '__custom__' : formData.productId || ''}\n onChange={(e) => {\n if (e.target.value === '__custom__') {\n setCustomProductEntry(true);\n setFormData({\n ...formData,\n productId: '',\n moduleId: undefined,\n pageId: undefined,\n });\n return;\n }\n\n setCustomProductEntry(false);\n setCustomModuleEntry(false);\n setCustomPageEntry(false);\n setFormData({\n ...formData,\n productId: e.target.value,\n moduleId: undefined,\n pageId: undefined,\n });\n }}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n required\n >\n <option value=\"\">Select product</option>\n {productsLoading ? <option disabled>Loading products...</option> : null}\n {productOptions.map((product) => (\n <option key={product.id} value={product.slug}>\n {product.name} ({product.slug})\n </option>\n ))}\n {showCurrentProductOption ? (\n <option value={formData.productId}>Current: {formData.productId}</option>\n ) : null}\n <option value=\"__custom__\">Custom product slug</option>\n </select>\n {customProductEntry ? (\n <input\n id=\"product-id-custom\"\n type=\"text\"\n value={formData.productId || ''}\n onChange={(e) =>\n setFormData({\n ...formData,\n productId: e.target.value,\n moduleId: undefined,\n pageId: undefined,\n })\n }\n className=\"mt-2 w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n placeholder=\"vibecontrols\"\n required\n />\n ) : null}\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"module-id\">\n Module ID\n </label>\n <select\n id=\"module-id\"\n value={customModuleEntry ? '__custom__' : formData.moduleId || ''}\n onChange={(e) => {\n if (e.target.value === '__custom__') {\n setCustomModuleEntry(true);\n setFormData({ ...formData, moduleId: '', pageId: undefined });\n return;\n }\n\n setCustomModuleEntry(false);\n setCustomPageEntry(false);\n setFormData({\n ...formData,\n moduleId: e.target.value || undefined,\n pageId: undefined,\n });\n }}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n disabled={!formData.productId}\n >\n <option value=\"\">All modules</option>\n {moduleOptions.map((moduleOption) => (\n <option key={moduleOption.moduleId} value={moduleOption.moduleId}>\n {moduleOption.label} ({moduleOption.moduleId})\n </option>\n ))}\n {showCurrentModuleOption ? (\n <option value={formData.moduleId}>Current: {formData.moduleId}</option>\n ) : null}\n <option value=\"__custom__\">Custom module ID</option>\n </select>\n {customModuleEntry ? (\n <input\n id=\"module-id-custom\"\n type=\"text\"\n value={formData.moduleId || ''}\n onChange={(e) =>\n setFormData({\n ...formData,\n moduleId: e.target.value || undefined,\n pageId: undefined,\n })\n }\n className=\"mt-2 w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n placeholder=\"vibecontrols\"\n />\n ) : null}\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"page-id\">\n Page ID\n </label>\n <select\n id=\"page-id\"\n value={customPageEntry ? '__custom__' : formData.pageId || ''}\n onChange={(e) => {\n if (e.target.value === '__custom__') {\n setCustomPageEntry(true);\n setFormData({ ...formData, pageId: '' });\n return;\n }\n\n setCustomPageEntry(false);\n setFormData({ ...formData, pageId: e.target.value || undefined });\n }}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n disabled={!formData.productId}\n >\n <option value=\"\">All pages</option>\n {pageOptions.map((pageOption) => (\n <option key={pageOption.pageId} value={pageOption.pageId}>\n {pageOption.label} ({pageOption.pageId})\n </option>\n ))}\n {showCurrentPageOption ? (\n <option value={formData.pageId}>Current: {formData.pageId}</option>\n ) : null}\n <option value=\"__custom__\">Custom page ID</option>\n </select>\n {customPageEntry ? (\n <input\n id=\"page-id-custom\"\n type=\"text\"\n value={formData.pageId || ''}\n onChange={(e) =>\n setFormData({ ...formData, pageId: e.target.value || undefined })\n }\n className=\"mt-2 w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n placeholder=\"agents\"\n />\n ) : null}\n </div>\n </div>\n\n <label className=\"flex items-center gap-3 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={formData.isActive ?? true}\n onChange={(e) => setFormData({ ...formData, isActive: e.target.checked })}\n className=\"w-4 h-4 rounded\"\n />\n <span className=\"text-sm font-medium\">Active</span>\n </label>\n </div>\n </div>\n\n {/* Trigger Settings */}\n <div className=\"border border-border rounded-md p-4 sm:p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4\">{tr('tourBuilder.sectionTriggerSettings')}</h2>\n\n <div className=\"space-y-4\">\n {/* Trigger Type */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"trigger-type\">\n {tr('tourBuilder.labelTriggerType')}\n </label>\n <select\n id=\"trigger-type\"\n value={formData.triggerType || 'MANUAL'}\n onChange={(e) =>\n setFormData({ ...formData, triggerType: e.target.value as TourTriggerType })\n }\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n >\n <option value=\"MANUAL\">{tr('tourBuilder.triggerManual')}</option>\n <option value=\"AUTO_FIRST_VISIT\">{tr('tourBuilder.triggerAutoFirstVisit')}</option>\n <option value=\"AUTO_ALWAYS\">{tr('tourBuilder.triggerAutoAlways')}</option>\n <option value=\"ON_EVENT\">{tr('tourBuilder.triggerOnEvent')}</option>\n <option value=\"SCHEDULED\">{tr('tourBuilder.triggerScheduled')}</option>\n </select>\n </div>\n\n {/* Priority */}\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"priority\">\n {tr('tourBuilder.labelPriority')}\n </label>\n <input\n id=\"priority\"\n type=\"number\"\n min=\"1\"\n max=\"100\"\n value={formData.priority || 50}\n onChange={(e) => {\n const priority = Number.parseInt(e.target.value, 10) || 50;\n setFormData({ ...formData, priority });\n }}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"tour-start-date\">\n Start Date\n </label>\n <input\n id=\"tour-start-date\"\n type=\"datetime-local\"\n value={formatDateTimeLocal(formData.startDate)}\n onChange={(e) =>\n setFormData({\n ...formData,\n startDate: e.target.value\n ? new Date(e.target.value).toISOString()\n : undefined,\n })\n }\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-2\" htmlFor=\"tour-end-date\">\n End Date\n </label>\n <input\n id=\"tour-end-date\"\n type=\"datetime-local\"\n value={formatDateTimeLocal(formData.endDate)}\n onChange={(e) =>\n setFormData({\n ...formData,\n endDate: e.target.value ? new Date(e.target.value).toISOString() : undefined,\n })\n }\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground\"\n />\n </div>\n </div>\n </div>\n </div>\n\n {/* API Error */}\n {error && (\n <div className=\"border border-destructive rounded-md p-4 bg-destructive/10\">\n <h3 className=\"font-semibold text-destructive mb-2\">{tr('tourBuilder.errorTitle')}</h3>\n <p className=\"text-sm text-destructive\">{error.message}</p>\n </div>\n )}\n\n {/* Validation Errors */}\n {validationErrors.length > 0 && (\n <div className=\"border border-destructive rounded-md p-4 bg-destructive/10\">\n <h3 className=\"font-semibold text-destructive mb-2\">\n {tr('tourBuilder.validationErrorsTitle')}\n </h3>\n <ul className=\"list-disc list-inside space-y-1\">\n {validationErrors.map((err, index) => (\n <li key={index} className=\"text-sm text-destructive\">\n {err.message}\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex flex-wrap gap-3\">\n <PermissionGate\n permission={isNew ? TOUR_PERMISSIONS.TOUR_CREATE : TOUR_PERMISSIONS.TOUR_UPDATE}\n >\n <button\n type=\"submit\"\n disabled={saving || !canSave}\n className=\"flex-1 min-w-[200px] px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 disabled:opacity-50 flex items-center justify-center gap-2\"\n >\n <Save size={20} />\n {saving\n ? tr('tourBuilder.saving')\n : tourId && tourId !== 'new'\n ? tr('tourBuilder.updateTour')\n : tr('tourBuilder.createAndAddSteps')}\n </button>\n </PermissionGate>\n {tourId && tourId !== 'new' && (\n <>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${tourId}/steps`)}\n className=\"px-4 py-2 bg-secondary text-secondary-foreground rounded-md hover:bg-secondary/80 flex items-center gap-2\"\n >\n <ListOrdered size={20} />\n {tr('tourBuilder.editSteps')}\n {tour?.steps && tour.steps.length > 0 && (\n <span className=\"ml-1 px-2 py-0.5 text-xs bg-primary/20 rounded-full\">\n {tour.steps.length}\n </span>\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${tourId}/preview`)}\n className=\"px-4 py-2 border border-border rounded-md hover:bg-accent flex items-center gap-2\"\n >\n <Eye size={20} />\n {tr('tourBuilder.preview')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${tourId}/analytics`)}\n className=\"px-4 py-2 border border-border rounded-md hover:bg-accent flex items-center gap-2\"\n >\n <BarChart3 size={20} />\n {tr('tourBuilder.analytics')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${tourId}/schedule`)}\n className=\"px-4 py-2 border border-border rounded-md hover:bg-accent flex items-center gap-2\"\n >\n <Calendar size={20} />\n Schedule\n </button>\n <PermissionGate permission={TOUR_PERMISSIONS.TOUR_TEMPLATE_CREATE}>\n <button\n type=\"button\"\n onClick={handleSaveTemplate}\n disabled={!canCreateTemplate}\n className=\"px-4 py-2 border border-border rounded-md hover:bg-accent flex items-center gap-2 disabled:opacity-50\"\n >\n <LayoutTemplate size={20} />\n Save as Template\n </button>\n </PermissionGate>\n </>\n )}\n </div>\n </form>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAsBA,IAAM,IAAgC,KAwBhC,IAAuD;CAC3D;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACN,cAAc;EACf;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACN,cAAc;EACf;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACP;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACN,cAAc;EACf;CACD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,QAAQ;EACR,WAAW;EACX,MAAM;EACN,cAAc;EACf;CACF;AAED,SAAS,EAAsB,GAAsD;AAEnF,QADmB,GAAO,MAAM,IACC,KAAA;;AAGnC,SAAS,EAAgB,GAA+D;CACtF,IAAM,IAAa,EAAsB,EAAU;AAEnD,QADK,IACE,EAAmB,QAAQ,MAAU,EAAM,cAAc,EAAW,GADnD,EAAE;;AAI5B,SAAS,EAAoB,GAA+D;CAC1F,IAAM,oBAAU,IAAI,KAAoC;AAExD,MAAK,IAAM,KAAS,EAAgB,EAAU,CAE5C,EAAI,CADa,EAAQ,IAAI,EAAM,SAAS,IAC3B,EAAM,iBACrB,EAAQ,IAAI,EAAM,UAAU;EAC1B,UAAU,EAAM;EAChB,OAAO,EAAM;EACb,MAAM,EAAM;EACb,CAAC;AAIN,QAAO,CAAC,GAAG,EAAQ,QAAQ,CAAC;;AAG9B,SAAS,EACP,GACA,GACuB;CACvB,IAAM,IAAY,EAAsB,EAAS;AAGjD,QAFK,IAEE,EAAgB,EAAU,CAC9B,QAAQ,MAAU,EAAM,aAAa,EAAU,CAC/C,KAAK,OAAW;EACf,QAAQ,EAAM;EACd,OAAO,EAAM;EACb,MAAM,EAAM;EACb,EAAE,GARkB,EAAE;;AAe3B,SAAgB,IAAkB;CAChC,IAAM,EAAE,UAAO,GAAc,EACvB,EAAE,cAAW,IAAW,EACxB,IAAW,IAAa,EACxB,EAAE,cAAW,QAAQ,GAAiB,EACtC,EAAE,qBAAkB,GAA0B,EAC9C,IAAQ,CAAC,KAAU,MAAW,OAC9B,IAAY,EAAc,EAAiB,YAAY,EACvD,KAAY,EAAc,EAAiB,YAAY,EACvD,KAAoB,EAAc,EAAiB,qBAAqB,EACxE,KAAU,IAAQ,IAAY,IAE9B,EAAE,SAAM,aAAU,gBAAY,eAAY,WAAQ,qBAAkB,aACxE,EAAe,EAAO,EAClB,EAAE,sBAAmB,GAAkB,EACvC,EAAE,MAAM,GAAc,SAAS,MAAoB,EAAoC;EAC3F,WAAW;GAAE,OAAO;GAA+B,QAAQ;GAAG;EAC9D,aAAa;EACd,CAAC,EAiBI,CAAC,GAAU,KAAe,EAfR;EACtB,MAAM;EACN,aAAa;EACb,WAAW;EACX,UAAU;EACV,QAAQ;EACR,UAAU;EACV,QAAQ;EACR,aAAa;EACb,UAAU;EACV,cAAc;EACd,WAAW;EACX,SAAS;EACV,CAEuE,EAClE,CAAC,GAAoB,KAAyB,EAAS,GAAM,EAC7D,CAAC,GAAmB,KAAwB,EAAS,GAAM,EAC3D,CAAC,GAAiB,KAAsB,EAAS,GAAM,EAEvD,IAAqB,EAAO,GAAM,EAElC,IAAiB,QACd,CAAC,GAAI,GAAc,iBAAiB,SAAS,EAAE,CAAE,CAAC,MAAM,GAAG,MAChE,EAAE,KAAK,cAAc,EAAE,KAAK,CAC7B,EACA,CAAC,EAAa,CAAC,EAEZ,IAAqB,QACnB,IAAI,IAAI,EAAe,KAAK,MAAY,EAAQ,KAAK,CAAC,EAC5D,CAAC,EAAe,CACjB,EAEK,IAAgB,QACd,EAAoB,EAAS,UAAU,EAC7C,CAAC,EAAS,UAAU,CACrB,EAEK,IAAkB,QAChB,IAAI,IAAI,EAAc,KAAK,MAAiB,EAAa,SAAS,CAAC,EACzE,CAAC,EAAc,CAChB,EAEK,IAAc,QACZ,EAAkB,EAAS,WAAW,EAAS,SAAS,EAC9D,CAAC,EAAS,UAAU,EAAS,UAAU,CACxC,EAEK,IAAgB,QACd,IAAI,IAAI,EAAY,KAAK,MAAe,EAAW,OAAO,CAAC,EACjE,CAAC,EAAY,CACd;AAgCD,CA9BA,QAAgB;AACd,EAAI,KAAU,MAAW,UACvB,EAAmB,UAAU,IAC7B,EAAS,EAAO;IAEjB,CAAC,GAAQ,EAAS,CAAC,EAEtB,QAAgB;AACd,EAAI,KAAQ,CAAC,EAAmB,YAC9B,EAAY,EAAK,EACjB,EAAmB,UAAU;IAE9B,CAAC,EAAK,CAAC,EAEV,QAAgB;AACd,MAAI,CAAC,EAAS,aAAa,GAAiB;AAC1C,KAAsB,GAAM;AAC5B;;AAEF,IAAsB,EAAe,SAAS,KAAK,CAAC,EAAmB,IAAI,EAAS,UAAU,CAAC;IAC9F;EAAC,EAAS;EAAW;EAAoB,EAAe;EAAQ;EAAgB,CAAC,EAEpF,QAAgB;AACd,MAAI,CAAC,EAAS,aAAa,CAAC,EAAS,UAAU;AAC7C,KAAqB,GAAM;AAC3B;;AAEF,IAAqB,EAAc,WAAW,KAAK,CAAC,EAAgB,IAAI,EAAS,SAAS,CAAC;IAC1F;EAAC,EAAS;EAAU,EAAS;EAAW;EAAiB,EAAc;EAAO,CAAC,EAElF,QAAgB;AACd,MAAI,CAAC,EAAS,aAAa,CAAC,EAAS,QAAQ;AAC3C,KAAmB,GAAM;AACzB;;AAEF,IAAmB,EAAY,WAAW,KAAK,CAAC,EAAc,IAAI,EAAS,OAAO,CAAC;IAClF;EAAC,EAAS;EAAQ,EAAS;EAAW;EAAe,EAAY;EAAO,CAAC;CAE5E,IAAM,KAA2B,GAC/B,EAAS,aAAa,CAAC,KAAsB,CAAC,EAAmB,IAAI,EAAS,UAAU,GAEpF,KAA0B,GAC9B,EAAS,YAAY,CAAC,KAAqB,CAAC,EAAgB,IAAI,EAAS,SAAS,GAE9E,KAAwB,GAC5B,EAAS,UAAU,CAAC,KAAmB,CAAC,EAAc,IAAI,EAAS,OAAO,GAGtE,KAAe,OAAO,MAAuB;AACjD,IAAE,gBAAgB;AAClB,MAAI;AACF,GAAI,KAAU,MAAW,QACvB,MAAM,EAAW,GAAQ,EAAS,GAElC,MAAM,GAAW,EAAS;WAErB,GAAO;AACd,WAAQ,MAAM,wBAAwB,EAAM;;IAI1C,WAAmB;AACvB,IAAS,GAAG,EAAS,OAAO;IAGxB,KAAuB,MAAmB;AAC9C,MAAI,CAAC,EAAO,QAAO;EAEnB,IAAM,IAAO,IAAI,KAAK,EAAM;AAK5B,SAJI,OAAO,MAAM,EAAK,SAAS,CAAC,GACvB,sBAGF,IAAI,KAAK,EAAK,SAAS,GAAG,EAAK,mBAAmB,GAAG,IAAM,EAAC,aAAa,CAAC,MAAM,GAAG,GAAG;;AA6B/F,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,UAAD;IACE,SAAS;IACT,WAAU;IACV,cAAY,EAAG,qBAAqB;cAEpC,kBAAC,GAAD,EAAW,MAAM,IAAM,CAAA;IAChB,CAAA,EACT,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAER,EADH,KAAU,MAAW,QACf,0BACA,0BAA0B;KAC9B,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eAAiC,EAAG,uBAAuB;KAAK,CAAA,CACzE;MACF;MAGN,kBAAC,QAAD;GAAM,UAAU;GAAc,WAAU;aAAxC;IAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAA8B,EAAG,+BAA+B;MAAM,CAAA,EAEpF,kBAAC,OAAD;MAAK,WAAU;gBAAf;OAEE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;QAAiC,SAAQ;kBACvD,EAAG,wBAAwB;QACtB,CAAA,EACR,kBAAC,SAAD;QACE,IAAG;QACH,MAAK;QACL,OAAO,EAAS,QAAQ;QACxB,WAAW,MAAM,EAAY;SAAE,GAAG;SAAU,MAAM,EAAE,OAAO;SAAO,CAAC;QACnE,WAAU;QACV,UAAA;QACA,CAAA,CACE,EAAA,CAAA;OAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;QAAiC,SAAQ;kBACvD,EAAG,+BAA+B;QAC7B,CAAA,EACR,kBAAC,YAAD;QACE,IAAG;QACH,OAAO,EAAS,eAAe;QAC/B,WAAW,MAAM,EAAY;SAAE,GAAG;SAAU,aAAa,EAAE,OAAO;SAAO,CAAC;QAC1E,MAAM;QACN,WAAU;QACV,CAAA,CACE,EAAA,CAAA;OAGN,kBAAC,OAAD,EAAA,UAAA;QACE,kBAAC,SAAD;SAAO,WAAU;SAAiC,SAAQ;mBACvD,EAAG,6BAA6B;SAC3B,CAAA;QACR,kBAAC,UAAD;SACE,IAAG;SACH,OAAO,IAAqB,eAAe,EAAS,aAAa;SACjE,WAAW,MAAM;AACf,cAAI,EAAE,OAAO,UAAU,cAAc;AAEnC,WADA,EAAsB,GAAK,EAC3B,EAAY;YACV,GAAG;YACH,WAAW;YACX,UAAU,KAAA;YACV,QAAQ,KAAA;YACT,CAAC;AACF;;AAMF,UAHA,EAAsB,GAAM,EAC5B,EAAqB,GAAM,EAC3B,EAAmB,GAAM,EACzB,EAAY;WACV,GAAG;WACH,WAAW,EAAE,OAAO;WACpB,UAAU,KAAA;WACV,QAAQ,KAAA;WACT,CAAC;;SAEJ,WAAU;SACV,UAAA;mBA1BF;UA4BE,kBAAC,UAAD;WAAQ,OAAM;qBAAG;WAAuB,CAAA;UACvC,IAAkB,kBAAC,UAAD;WAAQ,UAAA;qBAAS;WAA4B,CAAA,GAAG;UAClE,EAAe,KAAK,MACnB,kBAAC,UAAD;WAAyB,OAAO,EAAQ;qBAAxC;YACG,EAAQ;YAAK;YAAG,EAAQ;YAAK;YACvB;aAFI,EAAQ,GAEZ,CACT;UACD,KACC,kBAAC,UAAD;WAAQ,OAAO,EAAS;qBAAxB,CAAmC,aAAU,EAAS,UAAmB;eACvE;UACJ,kBAAC,UAAD;WAAQ,OAAM;qBAAa;WAA4B,CAAA;UAChD;;QACR,IACC,kBAAC,SAAD;SACE,IAAG;SACH,MAAK;SACL,OAAO,EAAS,aAAa;SAC7B,WAAW,MACT,EAAY;UACV,GAAG;UACH,WAAW,EAAE,OAAO;UACpB,UAAU,KAAA;UACV,QAAQ,KAAA;UACT,CAAC;SAEJ,WAAU;SACV,aAAY;SACZ,UAAA;SACA,CAAA,GACA;QACA,EAAA,CAAA;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAA,UAAA;SACE,kBAAC,SAAD;UAAO,WAAU;UAAiC,SAAQ;oBAAY;UAE9D,CAAA;SACR,kBAAC,UAAD;UACE,IAAG;UACH,OAAO,IAAoB,eAAe,EAAS,YAAY;UAC/D,WAAW,MAAM;AACf,eAAI,EAAE,OAAO,UAAU,cAAc;AAEnC,YADA,EAAqB,GAAK,EAC1B,EAAY;aAAE,GAAG;aAAU,UAAU;aAAI,QAAQ,KAAA;aAAW,CAAC;AAC7D;;AAKF,WAFA,EAAqB,GAAM,EAC3B,EAAmB,GAAM,EACzB,EAAY;YACV,GAAG;YACH,UAAU,EAAE,OAAO,SAAS,KAAA;YAC5B,QAAQ,KAAA;YACT,CAAC;;UAEJ,WAAU;UACV,UAAU,CAAC,EAAS;oBAnBtB;WAqBE,kBAAC,UAAD;YAAQ,OAAM;sBAAG;YAAoB,CAAA;WACpC,EAAc,KAAK,MAClB,kBAAC,UAAD;YAAoC,OAAO,EAAa;sBAAxD;aACG,EAAa;aAAM;aAAG,EAAa;aAAS;aACtC;cAFI,EAAa,SAEjB,CACT;WACD,KACC,kBAAC,UAAD;YAAQ,OAAO,EAAS;sBAAxB,CAAkC,aAAU,EAAS,SAAkB;gBACrE;WACJ,kBAAC,UAAD;YAAQ,OAAM;sBAAa;YAAyB,CAAA;WAC7C;;SACR,IACC,kBAAC,SAAD;UACE,IAAG;UACH,MAAK;UACL,OAAO,EAAS,YAAY;UAC5B,WAAW,MACT,EAAY;WACV,GAAG;WACH,UAAU,EAAE,OAAO,SAAS,KAAA;WAC5B,QAAQ,KAAA;WACT,CAAC;UAEJ,WAAU;UACV,aAAY;UACZ,CAAA,GACA;SACA,EAAA,CAAA,EAEN,kBAAC,OAAD,EAAA,UAAA;SACE,kBAAC,SAAD;UAAO,WAAU;UAAiC,SAAQ;oBAAU;UAE5D,CAAA;SACR,kBAAC,UAAD;UACE,IAAG;UACH,OAAO,IAAkB,eAAe,EAAS,UAAU;UAC3D,WAAW,MAAM;AACf,eAAI,EAAE,OAAO,UAAU,cAAc;AAEnC,YADA,EAAmB,GAAK,EACxB,EAAY;aAAE,GAAG;aAAU,QAAQ;aAAI,CAAC;AACxC;;AAIF,WADA,EAAmB,GAAM,EACzB,EAAY;YAAE,GAAG;YAAU,QAAQ,EAAE,OAAO,SAAS,KAAA;YAAW,CAAC;;UAEnE,WAAU;UACV,UAAU,CAAC,EAAS;oBAdtB;WAgBE,kBAAC,UAAD;YAAQ,OAAM;sBAAG;YAAkB,CAAA;WAClC,EAAY,KAAK,MAChB,kBAAC,UAAD;YAAgC,OAAO,EAAW;sBAAlD;aACG,EAAW;aAAM;aAAG,EAAW;aAAO;aAChC;cAFI,EAAW,OAEf,CACT;WACD,KACC,kBAAC,UAAD;YAAQ,OAAO,EAAS;sBAAxB,CAAgC,aAAU,EAAS,OAAgB;gBACjE;WACJ,kBAAC,UAAD;YAAQ,OAAM;sBAAa;YAAuB,CAAA;WAC3C;;SACR,IACC,kBAAC,SAAD;UACE,IAAG;UACH,MAAK;UACL,OAAO,EAAS,UAAU;UAC1B,WAAW,MACT,EAAY;WAAE,GAAG;WAAU,QAAQ,EAAE,OAAO,SAAS,KAAA;WAAW,CAAC;UAEnE,WAAU;UACV,aAAY;UACZ,CAAA,GACA;SACA,EAAA,CAAA,CACF;;OAEN,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACE,kBAAC,SAAD;SACE,MAAK;SACL,SAAS,EAAS,YAAY;SAC9B,WAAW,MAAM,EAAY;UAAE,GAAG;UAAU,UAAU,EAAE,OAAO;UAAS,CAAC;SACzE,WAAU;SACV,CAAA,EACF,kBAAC,QAAD;SAAM,WAAU;mBAAsB;SAAa,CAAA,CAC7C;;OACJ;QACF;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAA8B,EAAG,qCAAqC;MAAM,CAAA,EAE1F,kBAAC,OAAD;MAAK,WAAU;gBAAf;OAEE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;QAAiC,SAAQ;kBACvD,EAAG,+BAA+B;QAC7B,CAAA,EACR,kBAAC,UAAD;QACE,IAAG;QACH,OAAO,EAAS,eAAe;QAC/B,WAAW,MACT,EAAY;SAAE,GAAG;SAAU,aAAa,EAAE,OAAO;SAA0B,CAAC;QAE9E,WAAU;kBANZ;SAQE,kBAAC,UAAD;UAAQ,OAAM;oBAAU,EAAG,4BAA4B;UAAU,CAAA;SACjE,kBAAC,UAAD;UAAQ,OAAM;oBAAoB,EAAG,oCAAoC;UAAU,CAAA;SACnF,kBAAC,UAAD;UAAQ,OAAM;oBAAe,EAAG,gCAAgC;UAAU,CAAA;SAC1E,kBAAC,UAAD;UAAQ,OAAM;oBAAY,EAAG,6BAA6B;UAAU,CAAA;SACpE,kBAAC,UAAD;UAAQ,OAAM;oBAAa,EAAG,+BAA+B;UAAU,CAAA;SAChE;UACL,EAAA,CAAA;OAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;QAAiC,SAAQ;kBACvD,EAAG,4BAA4B;QAC1B,CAAA,EACR,kBAAC,SAAD;QACE,IAAG;QACH,MAAK;QACL,KAAI;QACJ,KAAI;QACJ,OAAO,EAAS,YAAY;QAC5B,WAAW,MAAM;SACf,IAAM,IAAW,OAAO,SAAS,EAAE,OAAO,OAAO,GAAG,IAAI;AACxD,WAAY;UAAE,GAAG;UAAU;UAAU,CAAC;;QAExC,WAAU;QACV,CAAA,CACE,EAAA,CAAA;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,WAAU;SAAiC,SAAQ;mBAAkB;SAEpE,CAAA,EACR,kBAAC,SAAD;SACE,IAAG;SACH,MAAK;SACL,OAAO,EAAoB,EAAS,UAAU;SAC9C,WAAW,MACT,EAAY;UACV,GAAG;UACH,WAAW,EAAE,OAAO,QAChB,IAAI,KAAK,EAAE,OAAO,MAAM,CAAC,aAAa,GACtC,KAAA;UACL,CAAC;SAEJ,WAAU;SACV,CAAA,CACE,EAAA,CAAA,EAEN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,WAAU;SAAiC,SAAQ;mBAAgB;SAElE,CAAA,EACR,kBAAC,SAAD;SACE,IAAG;SACH,MAAK;SACL,OAAO,EAAoB,EAAS,QAAQ;SAC5C,WAAW,MACT,EAAY;UACV,GAAG;UACH,SAAS,EAAE,OAAO,QAAQ,IAAI,KAAK,EAAE,OAAO,MAAM,CAAC,aAAa,GAAG,KAAA;UACpE,CAAC;SAEJ,WAAU;SACV,CAAA,CACE,EAAA,CAAA,CACF;;OACF;QACF;;IAGL,KACC,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAuC,EAAG,yBAAyB;MAAM,CAAA,EACvF,kBAAC,KAAD;MAAG,WAAU;gBAA4B,EAAM;MAAY,CAAA,CACvD;;IAIP,EAAiB,SAAS,KACzB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAG,oCAAoC;MACrC,CAAA,EACL,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAiB,KAAK,GAAK,MAC1B,kBAAC,MAAD;OAAgB,WAAU;iBACvB,EAAI;OACF,EAFI,EAEJ,CACL;MACC,CAAA,CACD;;IAIR,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,YAAY,IAAQ,EAAiB,cAAc,EAAiB;gBAEpE,kBAAC,UAAD;OACE,MAAK;OACL,UAAU,KAAU,CAAC;OACrB,WAAU;iBAHZ,CAKE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EAEd,EADH,IACM,uBACH,KAAU,MAAW,QAChB,2BACA,gCAAgC,CAClC;;MACM,CAAA,EAChB,KAAU,MAAW,SACpB,kBAAA,GAAA,EAAA,UAAA;MACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,GAAG,EAAS,GAAG,EAAO,QAAQ;OACtD,WAAU;iBAHZ;QAKE,kBAAC,GAAD,EAAa,MAAM,IAAM,CAAA;QACxB,EAAG,wBAAwB;QAC3B,GAAM,SAAS,EAAK,MAAM,SAAS,KAClC,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAK,MAAM;SACP,CAAA;QAEF;;MACT,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,GAAG,EAAS,GAAG,EAAO,UAAU;OACxD,WAAU;iBAHZ,CAKE,kBAAC,IAAD,EAAK,MAAM,IAAM,CAAA,EAChB,EAAG,sBAAsB,CACnB;;MACT,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,GAAG,EAAS,GAAG,EAAO,YAAY;OAC1D,WAAU;iBAHZ,CAKE,kBAAC,GAAD,EAAW,MAAM,IAAM,CAAA,EACtB,EAAG,wBAAwB,CACrB;;MACT,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,GAAG,EAAS,GAAG,EAAO,WAAW;OACzD,WAAU;iBAHZ,CAKE,kBAAC,IAAD,EAAU,MAAM,IAAM,CAAA,EAAA,WAEf;;MACT,kBAAC,GAAD;OAAgB,YAAY,EAAiB;iBAC3C,kBAAC,UAAD;QACE,MAAK;QACL,SAhbW,YAAY;AACrC,aAAI,CAAC,KAAU,MAAW,MAAO;SAEjC,IAAM,IAAc,GAAG,EAAS,QAAQ,GAAM,QAAQ,OAAO,YACvD,IAAO,OAAO,OAAO,iBAAiB,EAAY;AACxD,aAAI,CAAC,EAAM;SAEX,IAAM,IACJ,OAAO,OACL,sEACA,aACD,IAAI;AAEP,aAAI;AAOF,UANA,MAAM,EAAe,GAAQ;WAC3B;WACA,aAAa,EAAS;WACtB;WACA,UAAU;WACX,CAAC,EACF,EAAS,GAAG,EAAS,YAAY;kBAC1B,GAAmB;AAC1B,kBAAQ,MAAM,4BAA4B,EAAkB;;;QA2ZhD,UAAU,CAAC;QACX,WAAU;kBAJZ,CAME,kBAAC,IAAD,EAAgB,MAAM,IAAM,CAAA,EAAA,mBAErB;;OACM,CAAA;MAChB,EAAA,CAAA,CAED;;IACD;KACH"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useToursContext as e } from "../providers/ToursProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { useToursStore as t } from "../store/toursStore.js";
|
|
3
|
+
import { useToursPermissionAccess as n } from "../hooks/useToursPermissionAccess.js";
|
|
4
4
|
import { TOUR_PERMISSIONS as r } from "../../constants/permissions.js";
|
|
5
5
|
import { useToursI18n as i } from "../i18n.js";
|
|
6
6
|
import { useTourBuilder as a } from "../hooks/useTourBuilder.js";
|
|
@@ -11,7 +11,7 @@ import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
|
11
11
|
import { useNavigate as y, useParams as b } from "react-router-dom";
|
|
12
12
|
//#region src/tours/pages/TourPreviewPage.tsx
|
|
13
13
|
function x() {
|
|
14
|
-
let { tr: x } = i(), { tourId: S } = b(), C = y(), { basePath: w = "/" } = e(), { hasPermission: T } =
|
|
14
|
+
let { tr: x } = i(), { tourId: S } = b(), C = y(), { basePath: w = "/" } = e(), { hasPermission: T } = n(), E = T(r.TOUR_READ), { tour: D, loadTour: O } = a(S), { devicePreview: k } = t(), { isPreviewActive: A, currentStepIndex: j, currentStep: M, totalSteps: N, canGoNext: P, canGoPrevious: F, validationResults: I, startPreview: L, stopPreview: R, nextStep: z, previousStep: B, changeDevice: V, validateForPreview: H } = o(D || void 0);
|
|
15
15
|
if (s(() => {
|
|
16
16
|
S && O(S);
|
|
17
17
|
}, [S, O]), s(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToursListPage.d.ts","sourceRoot":"","sources":["../../../src/tours/pages/ToursListPage.tsx"],"names":[],"mappings":"AA+BA;;;GAGG;AACH,wBAAgB,aAAa,
|
|
1
|
+
{"version":3,"file":"ToursListPage.d.ts","sourceRoot":"","sources":["../../../src/tours/pages/ToursListPage.tsx"],"names":[],"mappings":"AA+BA;;;GAGG;AACH,wBAAgB,aAAa,4CA8a5B"}
|