@srimandir/kundli-generator 9.4.2 → 9.4.3

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.
Files changed (35) hide show
  1. package/dist/analytics-C7U4tH2y.js +3908 -0
  2. package/dist/analytics-C7U4tH2y.js.map +1 -0
  3. package/dist/analytics.d.ts +144 -0
  4. package/dist/components/KundliForm/KundliForm.d.ts +9 -1
  5. package/dist/components/KundliForm/sections/UserInfoFormSection/UserInfoFormSection.d.ts +5 -1
  6. package/dist/components/KundliForm/sections/UserInfoFormSection/useAtlasPlacesAutocomplete.d.ts +22 -0
  7. package/dist/components/KundliForm/sections/UserInfoFormSection/useGooglePlacesAutocomplete.d.ts +29 -8
  8. package/dist/components/KundliPage/KundliContext.d.ts +24 -1
  9. package/dist/components/KundliPage/KundliPage.d.ts +17 -1
  10. package/dist/components/KundliPage/KundliPageV1.d.ts +22 -1
  11. package/dist/components/KundliPage/KundliPageVariant.d.ts +5 -0
  12. package/dist/components/KundliPage/sections/UtmBannerSection/UtmBannerSection.d.ts +8 -0
  13. package/dist/components/KundliPage/sections/UtmBannerSection/index.d.ts +2 -0
  14. package/dist/components/KundliPage/sections/index.d.ts +1 -0
  15. package/dist/components/KundliPlanBottomSheet/ConsultationSlotModal.d.ts +28 -0
  16. package/dist/components/KundliPlanBottomSheet/KundliPlanBottomSheet.d.ts +14 -3
  17. package/dist/components/KundliPlanBottomSheet/PlanIcons.d.ts +10 -0
  18. package/dist/components/KundliPlanBottomSheet/consultationSlotDefaults.d.ts +44 -0
  19. package/dist/components/KundliPlanBottomSheet/index.d.ts +4 -1
  20. package/dist/components/KundliPlanBottomSheet/types.d.ts +46 -0
  21. package/dist/components/ThreeSkuPlanBottomSheet/ThreeSkuPlanBottomSheet.types.d.ts +11 -1
  22. package/dist/components/ThreeSkuPlanBottomSheet/constants.d.ts +26 -0
  23. package/dist/criticalCss-DTGMtg9k.js +2017 -0
  24. package/dist/criticalCss-DTGMtg9k.js.map +1 -0
  25. package/dist/form-entry.js +1 -1
  26. package/dist/i18n/I18nContext.d.ts +7 -1
  27. package/dist/index.d.ts +2 -0
  28. package/dist/kundli-generator.js +29 -27
  29. package/dist/page-entry.js +2 -2
  30. package/dist/style.css +1 -1
  31. package/package.json +2 -2
  32. package/dist/analytics-qrcpYMLy.js +0 -2994
  33. package/dist/analytics-qrcpYMLy.js.map +0 -1
  34. package/dist/criticalCss-Bj5LpOlA.js +0 -1914
  35. package/dist/criticalCss-Bj5LpOlA.js.map +0 -1
@@ -59,6 +59,32 @@ export declare const KUNDLI_ANALYTICS_EVENT_NAMES: {
59
59
  readonly kundli_plan_proceed_clicked: "kundli_plan_proceed_clicked";
60
60
  /** Plan sheet closed without proceeding */
61
61
  readonly kundli_plan_page_closed: "kundli_plan_page_closed";
62
+ /** "Select consultation slot" CTA clicked on the astrologer guidance plan card */
63
+ readonly kundli_plan_select_consultation_slot_clicked: "kundli_plan_select_consultation_slot_clicked";
64
+ /** Plan selection screen loads (full-screen consultation scheduling flow) */
65
+ readonly kundli_plan_screen_viewed: "kundli_plan_screen_viewed";
66
+ /** Slot selection screen loads */
67
+ readonly kundli_slot_screen_viewed: "kundli_slot_screen_viewed";
68
+ /** User picks a date */
69
+ readonly kundli_slot_date_selected: "kundli_slot_date_selected";
70
+ /** User switches Morning/Afternoon/Evening */
71
+ readonly kundli_day_part_selected: "kundli_day_part_selected";
72
+ /** User picks a guidance topic chip */
73
+ readonly kundli_guidance_topic_selected: "kundli_guidance_topic_selected";
74
+ /** User taps a time slot */
75
+ readonly kundli_slot_selected: "kundli_slot_selected";
76
+ /** User taps confirm slot / proceeds to reserve ("Proceed to payment" in the slot modal) */
77
+ readonly kundli_slot_reservation_requested: "kundli_slot_reservation_requested";
78
+ /** Payment screen loads with an active hold (tracked by host app's payment page) */
79
+ readonly kundli_payment_screen_viewed: "kundli_payment_screen_viewed";
80
+ /** User selects a payment method (tracked by host app's payment page) */
81
+ readonly kundli_payment_method_selected: "kundli_payment_method_selected";
82
+ /** User confirms payment / gateway opens (tracked by host app's payment page) */
83
+ readonly kundli_payment_initiated: "kundli_payment_initiated";
84
+ /** Success + confirmation screen shown (tracked by host app's confirmation page) */
85
+ readonly kundli_booking_confirmation_viewed: "kundli_booking_confirmation_viewed";
86
+ /** User routed back to re-select after losing their slot (expired/failed/taken) */
87
+ readonly kundli_slot_lost_fallback_shown: "kundli_slot_lost_fallback_shown";
62
88
  /** Legacy / alias: when landing page is viewed */
63
89
  readonly kundli_page_view: "kundli_page_view";
64
90
  /** Legacy / alias: when L1 form page is viewed (same as l1_page_opened) */
@@ -71,6 +97,12 @@ export declare const KUNDLI_ANALYTICS_EVENT_NAMES: {
71
97
  readonly kundli_view_sample_image_closed: "kundli_view_sample_image_closed";
72
98
  };
73
99
  export type KundliAnalyticsEventName = (typeof KUNDLI_ANALYTICS_EVENT_NAMES)[keyof typeof KUNDLI_ANALYTICS_EVENT_NAMES];
100
+ /**
101
+ * Whether a consultation-slot-modal event fired during the original,
102
+ * pre-payment booking flow, or during the "Book slot again" retry flow on
103
+ * /payment_success (payment already succeeded, slot booking failed).
104
+ */
105
+ export type ConsultationEventStatus = "pre_payment" | "post_payment";
74
106
  /** Optional analytics implementation. Pass from host to KundliPage/KundliForm to track events. */
75
107
  export interface KundliAnalytics {
76
108
  trackBannerClicked?(): void;
@@ -127,6 +159,9 @@ export interface KundliAnalytics {
127
159
  trackPlanSelected?(params: {
128
160
  planId: string;
129
161
  planName: string;
162
+ price?: string;
163
+ includes_consultation?: boolean;
164
+ cta_label?: string;
130
165
  }): void;
131
166
  /** Updated: includes question-related fields for the 3-SKU experiment. */
132
167
  trackPlanProceedClicked?(params: {
@@ -137,8 +172,117 @@ export interface KundliAnalytics {
137
172
  question_asked?: boolean;
138
173
  question_text?: string;
139
174
  question_source?: 'chip' | 'custom' | 'chip_edited';
175
+ cta_type?: 'proceed' | 'confirm_consultation_slot';
176
+ next_step?: 'payment' | 'slot_selection';
140
177
  }): void;
141
178
  trackPlanPageClosed?(): void;
179
+ /** Fires when the astrologer guidance plan's "Select consultation slot" CTA is clicked. */
180
+ trackSelectConsultationSlotClicked?(params: {
181
+ planId: string;
182
+ planName: string;
183
+ }): void;
184
+ /** Fires when the (full-screen) plan selection screen loads. */
185
+ trackPlanScreenViewed?(params: {
186
+ plans_shown: string[];
187
+ default_selected_plan: string;
188
+ }): void;
189
+ /** Fires as soon as the host app's availability response is received, regardless of whether the modal has rendered yet. */
190
+ trackAstrologerAvailabilityServed?(params: {
191
+ astrologers_shown: string[];
192
+ dates_available_count: number;
193
+ status: ConsultationEventStatus;
194
+ }): void;
195
+ /** Fires when the consultation slot selection screen (full-screen modal) loads. */
196
+ trackSlotScreenViewed?(params: {
197
+ astrologers_shown: string[];
198
+ dates_available_count: number;
199
+ status: ConsultationEventStatus;
200
+ }): void;
201
+ /** Fires when the modal auto-selects the default consultation language. */
202
+ trackConsultationLanguageDefaultSelected?(params: {
203
+ language: string;
204
+ status: ConsultationEventStatus;
205
+ }): void;
206
+ /** Fires when the user manually changes the consultation language via the dropdown. */
207
+ trackConsultationLanguageChanged?(params: {
208
+ previous_language: string;
209
+ new_language: string;
210
+ slots_available: "yes" | "no";
211
+ status: ConsultationEventStatus;
212
+ }): void;
213
+ /** Fires when the modal auto-selects the default consultation date. */
214
+ trackConsultationDateDefaultSelected?(params: {
215
+ date: string;
216
+ status: ConsultationEventStatus;
217
+ }): void;
218
+ /** Fires when the modal auto-selects the default consultation time. */
219
+ trackConsultationTimeDefaultSelected?(params: {
220
+ time: string;
221
+ gmt_offset: string;
222
+ status: ConsultationEventStatus;
223
+ }): void;
224
+ /** Fires when the user picks a date tab. */
225
+ trackSlotDateSelected?(params: {
226
+ date: string;
227
+ day_part_default: string;
228
+ status: ConsultationEventStatus;
229
+ }): void;
230
+ /** Fires when the user switches Morning/Afternoon/Evening. */
231
+ trackDayPartSelected?(params: {
232
+ day_part: string;
233
+ slots_available_count: number;
234
+ status: ConsultationEventStatus;
235
+ }): void;
236
+ /** Fires when the user picks a guidance topic chip. */
237
+ trackGuidanceTopicSelected?(params: {
238
+ topic: string;
239
+ status: ConsultationEventStatus;
240
+ }): void;
241
+ /** Fires when the user taps a time slot. */
242
+ trackSlotSelected?(params: {
243
+ astrologer_id?: string;
244
+ date: string;
245
+ time: string;
246
+ day_part: string;
247
+ topic: string | null;
248
+ status: ConsultationEventStatus;
249
+ }): void;
250
+ /** Fires when the user taps the slot modal's "Proceed to payment" (confirm slot) CTA. */
251
+ trackSlotReservationRequested?(params: {
252
+ astrologer_id?: string;
253
+ slot_datetime: string;
254
+ status: ConsultationEventStatus;
255
+ }): void;
256
+ /** Fires when the payment screen loads with an active hold. Tracked by the host app. */
257
+ trackPaymentScreenViewed?(params: {
258
+ reservation_id: string;
259
+ amount: number;
260
+ currency: string;
261
+ seconds_remaining: number;
262
+ }): void;
263
+ /** Fires when the user selects a payment method. Tracked by the host app. */
264
+ trackPaymentMethodSelected?(params: {
265
+ method: string;
266
+ provider?: string;
267
+ }): void;
268
+ /** Fires when the user confirms payment / gateway opens. Tracked by the host app. */
269
+ trackPaymentInitiated?(params: {
270
+ reservation_id: string;
271
+ amount: number;
272
+ currency: string;
273
+ method: string;
274
+ }): void;
275
+ /** Fires when the booking confirmation screen is shown. Tracked by the host app. */
276
+ trackBookingConfirmationViewed?(params: {
277
+ booking_id: string;
278
+ slot_datetime: string;
279
+ astrologer_id?: string;
280
+ topic: string;
281
+ }): void;
282
+ /** Fires when the user is routed back to re-select after losing their slot. Tracked by the host app. */
283
+ trackSlotLostFallbackShown?(params: {
284
+ reason: 'expired' | 'payment_failed' | 'slot_taken';
285
+ }): void;
142
286
  /** Fires once when the SKU comparison table enters the viewport (≥50% visible). */
143
287
  trackComparisonTableImpression?(): void;
144
288
  /** Fires the first time per card-expansion the user focuses the question textbox. */
@@ -4,6 +4,8 @@ import { AtlasSearchLocalities } from './sections/UserInfoFormSection/useGoogleP
4
4
  export interface KundliFormValues {
5
5
  fullName: string;
6
6
  phone?: string;
7
+ /** ISD/country code for `phone` (e.g. "+1", "+91"). Prefilled from a `country_code` query param for international users; defaults to "+91"/"+1" based on `isGlobal` when absent or invalid. */
8
+ phoneCountryCode?: string;
7
9
  gender?: "male" | "female" | "";
8
10
  email: string;
9
11
  language_code?: "hi" | "en" | "te" | "ta" | "kn" | "gu" | "mr" | "";
@@ -11,7 +13,9 @@ export interface KundliFormValues {
11
13
  birthTime: string;
12
14
  birthTimeUnknown: boolean;
13
15
  birthPlace: string;
16
+ /** Latitude of birth place, when known (e.g. from Atlas locality search). Optional; not set for Google Places selections. */
14
17
  birthPlaceLat?: number;
18
+ /** Longitude of birth place, when known (e.g. from Atlas locality search). Optional; not set for Google Places selections. */
15
19
  birthPlaceLng?: number;
16
20
  }
17
21
  export interface KundliFormProps {
@@ -34,8 +38,12 @@ export interface KundliFormProps {
34
38
  originalPriceLabel?: string;
35
39
  discountedPriceLabel?: string;
36
40
  discountPillLabel?: string;
37
- /** Atlas localities search callback used for Birth Place autocomplete */
41
+ /** Google Maps API key used for Birth Place autocomplete */
42
+ googleMapsApiKey?: string;
43
+ /** Atlas localities search callback, used for Birth Place autocomplete when `googleMapsAutocompleteEnabled` is false. */
38
44
  atlasSearchLocalities?: AtlasSearchLocalities;
45
+ /** When true (default), birth place autocomplete uses Google Places. When false, uses Atlas via `atlasSearchLocalities`. */
46
+ googleMapsAutocompleteEnabled?: boolean;
39
47
  /** Optional analytics (Mixpanel etc.). Also set on KundliProvider; passing here ensures events fire when form is used inside provider (e.g. avoids context loss from multiple React instances). */
40
48
  analytics?: KundliAnalytics;
41
49
  }
@@ -9,8 +9,12 @@ export interface UserInfoFormSectionProps {
9
9
  onPhoneIsdCodeChange: (code: string) => void;
10
10
  showV1ExtraFields?: boolean;
11
11
  analytics?: KundliAnalytics;
12
- /** Atlas localities search callback used for Birth Place autocomplete */
12
+ /** Google Maps API key used for Birth Place autocomplete */
13
+ googleMapsApiKey?: string;
14
+ /** Atlas localities search callback, used for Birth Place autocomplete when `googleMapsAutocompleteEnabled` is false. */
13
15
  atlasSearchLocalities?: AtlasSearchLocalities;
16
+ /** When true (default), birth place autocomplete uses Google Places. When false, uses Atlas via `atlasSearchLocalities`. */
17
+ googleMapsAutocompleteEnabled?: boolean;
14
18
  className?: string;
15
19
  }
16
20
  export declare const UserInfoFormSection: React.FC<UserInfoFormSectionProps>;
@@ -0,0 +1,22 @@
1
+ import { AtlasSearchLocalities } from './useGooglePlacesAutocomplete';
2
+ export interface AtlasPrediction {
3
+ id: string;
4
+ description: string;
5
+ secondary_text?: string;
6
+ lat: number;
7
+ lng: number;
8
+ }
9
+ /**
10
+ * Atlas-backed birth place autocomplete. Used when `googleMapsAutocompleteEnabled`
11
+ * is false, as an alternative to `useGooglePlacesAutocomplete`.
12
+ */
13
+ export declare const useAtlasPlacesAutocomplete: (params: {
14
+ searchLocalities?: AtlasSearchLocalities;
15
+ restrictCountry?: string;
16
+ }) => {
17
+ predictions: AtlasPrediction[];
18
+ isSearching: boolean;
19
+ loadError: string | null;
20
+ searchPlaces: (query: string) => Promise<void>;
21
+ clearPredictions: () => void;
22
+ };
@@ -1,9 +1,29 @@
1
1
  export interface PlacePrediction {
2
- id: string;
2
+ place_id: string;
3
3
  description: string;
4
- secondary_text?: string;
4
+ structured_formatting: {
5
+ main_text: string;
6
+ secondary_text: string;
7
+ };
8
+ }
9
+ export interface PlaceDetails {
10
+ display_name: string;
5
11
  lat: number;
6
12
  lng: number;
13
+ city?: string;
14
+ state?: string;
15
+ country?: string;
16
+ }
17
+ /**
18
+ * Atlas locality search types are kept for API compatibility with consumers
19
+ * that still pass an `atlasSearchLocalities` callback. Birth place
20
+ * autocomplete itself is powered by Google Places (see
21
+ * `useGooglePlacesAutocomplete` below); Atlas is accepted but not consumed.
22
+ */
23
+ export interface AtlasSearchOptions {
24
+ limit?: number;
25
+ offset?: number;
26
+ restrictCountry?: string;
7
27
  }
8
28
  export interface AtlasPlaceOption {
9
29
  id: string;
@@ -12,19 +32,20 @@ export interface AtlasPlaceOption {
12
32
  lat: number;
13
33
  lng: number;
14
34
  }
15
- export interface AtlasSearchOptions {
16
- limit?: number;
17
- offset?: number;
18
- restrictCountry?: string;
19
- }
20
35
  export type AtlasSearchLocalities = (query: string, options?: AtlasSearchOptions) => Promise<AtlasPlaceOption[]>;
21
36
  export declare const useGooglePlacesAutocomplete: (params: {
22
- searchLocalities?: AtlasSearchLocalities;
37
+ apiKey?: string;
38
+ language?: string;
23
39
  restrictCountry?: string;
40
+ /** If true, defer loading until explicitly triggered (default: false) */
41
+ deferLoad?: boolean;
24
42
  }) => {
43
+ isLoaded: boolean;
25
44
  predictions: PlacePrediction[];
26
45
  isSearching: boolean;
27
46
  loadError: string | null;
28
47
  searchPlaces: (query: string) => Promise<void>;
48
+ getPlaceDetails: (placeId: string) => Promise<PlaceDetails | null>;
29
49
  clearPredictions: () => void;
50
+ triggerLoad: () => void;
30
51
  };
@@ -2,6 +2,7 @@ import { SupportedLocale } from '../../i18n/translations';
2
2
  import { KundliFormValues } from '../KundliForm';
3
3
  import { KundliAnalytics } from '../../analytics';
4
4
  import { KundliImageComponent } from '../../types/image';
5
+ import { FetchConsultationSlots } from '../KundliPlanBottomSheet';
5
6
  import { AtlasSearchLocalities } from '../KundliForm/sections/UserInfoFormSection/useGooglePlacesAutocomplete';
6
7
  export type KundliView = "landing" | "form";
7
8
  export interface KundliContextConfig {
@@ -14,8 +15,30 @@ export interface KundliContextConfig {
14
15
  isGlobal?: boolean;
15
16
  /** Variant identifier for analytics tracking */
16
17
  variant?: string;
17
- /** Atlas localities search callback for birth place autocomplete */
18
+ /** Pre-fills form values on mount (e.g. from URL query params on a deep-linked SEO flow). */
19
+ initialFormValues?: Partial<KundliFormValues>;
20
+ /** When true, automatically opens the plan selection bottom sheet once (requires variant "v1"). Used for deep-linked flows where the form is already fully pre-filled. */
21
+ autoOpenPlanSheet?: boolean;
22
+ /** Google Maps API key for birth place autocomplete */
23
+ googleMapsApiKey?: string;
24
+ /** Atlas localities search callback, used for Birth Place autocomplete when `googleMapsAutocompleteEnabled` is false. */
18
25
  atlasSearchLocalities?: AtlasSearchLocalities;
26
+ /** When true (default), birth place autocomplete uses Google Places. When false, uses Atlas via `atlasSearchLocalities`. */
27
+ googleMapsAutocompleteEnabled?: boolean;
28
+ /**
29
+ * Feature flag (experiment-controlled). When true, the Kundli plan selection sheet
30
+ * (`KundliPlanBottomSheet`) renders full-screen with the left-aligned header style,
31
+ * and selecting the astrologer-consultation plan opens the full-screen
32
+ * `ConsultationSlotModal` (date/time/topic picker) before proceeding to payment.
33
+ * When false (default), behavior is unchanged: bottom sheet, centered header,
34
+ * astrologer-consultation plan proceeds straight to payment.
35
+ */
36
+ enableConsultationScheduling?: boolean;
37
+ /**
38
+ * Fetches real consultation slot availability from the host app (no API/endpoint
39
+ * knowledge lives in this package). Called by `ConsultationSlotModal` when it opens.
40
+ */
41
+ fetchConsultationSlots?: FetchConsultationSlots;
19
42
  logoUrl?: string;
20
43
  reportImageUrl?: string;
21
44
  /** When true, LCP report image can be loaded with priority (e.g. next/image priority). */
@@ -45,10 +45,26 @@ export interface KundliPageProps {
45
45
  analytics?: KundliAnalytics;
46
46
  /** Notify when user changes language (e.g. to keep form view in sync when switching from landing) */
47
47
  onLocaleChange?: (locale: SupportedLocale) => void;
48
- /** Atlas localities search callback for birth place autocomplete */
48
+ /** Google Maps API key for birth place autocomplete */
49
+ googleMapsApiKey?: string;
50
+ /** Atlas localities search callback, used for Birth Place autocomplete when `googleMapsAutocompleteEnabled` is false. */
49
51
  atlasSearchLocalities?: AtlasSearchLocalities;
52
+ /** When true (default), birth place autocomplete uses Google Places. When false, uses Atlas via `atlasSearchLocalities`. */
53
+ googleMapsAutocompleteEnabled?: boolean;
50
54
  /** Enables 3-SKU experiment flow when used with v1 variant. */
51
55
  enableThreeSkuFlow?: boolean;
56
+ /**
57
+ * Experiment-controlled feature flag (v1 variant only). When true, the Kundli plan
58
+ * sheet renders full-screen and the astrologer-consultation plan opens a full-screen
59
+ * scheduling modal before payment. When false (default), behavior is unchanged.
60
+ */
61
+ enableConsultationScheduling?: boolean;
62
+ /**
63
+ * Fetches real consultation slot availability from the host app (no API/endpoint
64
+ * knowledge lives in this package). Passed through to `KundliContext` and used by
65
+ * `ConsultationSlotModal` when it opens.
66
+ */
67
+ fetchConsultationSlots?: import('../KundliPlanBottomSheet').FetchConsultationSlots;
52
68
  /** URL for the "200+ page Kundli Report" sample link in 3-SKU table. */
53
69
  kundliReportSampleHref?: string;
54
70
  /** URL for the "1 Question" sample link in 3-SKU table. */
@@ -15,6 +15,10 @@ export interface KundliPageProps {
15
15
  userId?: number;
16
16
  /** Whether the user is global (international) or domestic */
17
17
  isGlobal?: boolean;
18
+ /** Pre-fills form values on mount (e.g. from URL query params on a deep-linked SEO flow). */
19
+ initialFormValues?: Partial<KundliFormValues>;
20
+ /** When true, automatically opens the plan selection bottom sheet once on mount. Used for deep-linked flows where the form is already fully pre-filled. */
21
+ autoOpenPlanSheet?: boolean;
18
22
  /** Header logo URL */
19
23
  logoUrl?: string;
20
24
  /** Premium report cover image URL */
@@ -45,10 +49,27 @@ export interface KundliPageProps {
45
49
  analytics?: KundliAnalytics;
46
50
  /** Notify when user changes language (e.g. to keep form view in sync when switching from landing) */
47
51
  onLocaleChange?: (locale: SupportedLocale) => void;
48
- /** Atlas localities search callback for birth place autocomplete */
52
+ /** Google Maps API key for birth place autocomplete */
53
+ googleMapsApiKey?: string;
54
+ /** Atlas localities search callback, used for Birth Place autocomplete when `googleMapsAutocompleteEnabled` is false. */
49
55
  atlasSearchLocalities?: AtlasSearchLocalities;
56
+ /** When true (default), birth place autocomplete uses Google Places. When false, uses Atlas via `atlasSearchLocalities`. */
57
+ googleMapsAutocompleteEnabled?: boolean;
50
58
  /** Enables 3-SKU experiment flow inside existing v1 page. */
51
59
  enableThreeSkuFlow?: boolean;
60
+ /**
61
+ * Experiment-controlled feature flag. When true, the Kundli plan sheet renders
62
+ * full-screen (matching header style) and the astrologer-consultation plan opens
63
+ * a full-screen date/time/topic scheduling modal before payment. When false
64
+ * (default), existing behavior is unchanged (bottom sheet, direct to payment).
65
+ */
66
+ enableConsultationScheduling?: boolean;
67
+ /**
68
+ * Fetches real consultation slot availability from the host app. Passed through
69
+ * to `KundliContext` and used by `ConsultationSlotModal` when it opens. No
70
+ * endpoint/URL knowledge lives in this package — the host app owns the API call.
71
+ */
72
+ fetchConsultationSlots?: import('../KundliPlanBottomSheet').FetchConsultationSlots;
52
73
  /** URL for the "200+ page Kundli Report" sample link in the 3-SKU table. */
53
74
  kundliReportSampleHref?: string;
54
75
  /** URL for the "1 Question" sample link in the 3-SKU table. */
@@ -1,5 +1,10 @@
1
1
  import { KundliPageProps as BaseKundliPageProps } from './KundliPage';
2
+ import { KundliFormValues } from '../KundliForm';
2
3
  export type KundliPageProps = BaseKundliPageProps & {
3
4
  variant?: "v1";
5
+ /** Pre-fills form values on mount (e.g. from URL query params on a deep-linked SEO flow). Only applies when `variant="v1"`. */
6
+ initialFormValues?: Partial<KundliFormValues>;
7
+ /** When true, automatically opens the plan selection bottom sheet once on mount. Only applies when `variant="v1"`. */
8
+ autoOpenPlanSheet?: boolean;
4
9
  };
5
10
  export declare const KundliPage: React.FC<KundliPageProps>;
@@ -0,0 +1,8 @@
1
+ import { KundliImageComponent } from '../../../../types/image';
2
+ export interface UtmBannerSectionProps {
3
+ imageUrl: string;
4
+ altText: string;
5
+ imageComponent?: KundliImageComponent;
6
+ className?: string;
7
+ }
8
+ export declare const UtmBannerSection: React.FC<UtmBannerSectionProps>;
@@ -0,0 +1,2 @@
1
+ export { UtmBannerSection } from './UtmBannerSection';
2
+ export type { UtmBannerSectionProps } from './UtmBannerSection';
@@ -1,5 +1,6 @@
1
1
  export { KundliHeader } from './KundliHeader';
2
2
  export { HeroSection } from './HeroSection';
3
+ export { UtmBannerSection } from './UtmBannerSection';
3
4
  export { PremiumReportOverview } from './PremiumReportOverview';
4
5
  export { UniversityCertification } from './UniversityCertification';
5
6
  export { ThreeStepsProcess } from './ThreeStepsProcess';
@@ -0,0 +1,28 @@
1
+ import { KundliPlanAstrologer, ConsultationSlotSelection } from './types';
2
+ import { KundliAnalytics } from '../../analytics';
3
+ export interface ConsultationSlotModalProps {
4
+ isOpen: boolean;
5
+ onClose: () => void;
6
+ onProceed: (selection: ConsultationSlotSelection) => void;
7
+ astrologers: KundliPlanAstrologer[];
8
+ t?: (key: string, options?: any) => string | undefined;
9
+ analytics?: KundliAnalytics;
10
+ /**
11
+ * Report language the user selected in the kundli form (e.g. "hi", "te").
12
+ * Drives which consultation language is preselected (see
13
+ * `getDefaultConsultationLanguage`). Defaults to `KundliContext`'s live
14
+ * `formValues.language_code` when not passed explicitly — callers not
15
+ * connected to that context (e.g. a standalone retry flow) must pass it.
16
+ */
17
+ reportLanguage?: string;
18
+ /**
19
+ * True for the "Book slot again" retry flow on /payment_success (payment
20
+ * already succeeded, original slot booking failed) — false/omitted for the
21
+ * original pre-payment booking flow. Tags every analytics event fired by
22
+ * this modal with `status: "pre_payment" | "post_payment"`, and hides the
23
+ * guidance-topic picker in the retry case (topic was already captured
24
+ * during the original pre-payment flow).
25
+ */
26
+ isPostPayment?: boolean;
27
+ }
28
+ export declare const ConsultationSlotModal: React.FC<ConsultationSlotModalProps>;
@@ -1,14 +1,24 @@
1
- import { KundliPlan } from './types';
1
+ import { KundliPlan, ConsultationSlotSelection } from './types';
2
2
  import { KundliAnalytics } from '../../analytics';
3
3
  export interface KundliPlanBottomSheetProps {
4
4
  isOpen: boolean;
5
5
  onClose: () => void;
6
6
  selectedPlan: KundliPlan | null;
7
7
  onSelectPlan: (plan: KundliPlan) => void;
8
- onProceed: (plan: KundliPlan) => void;
8
+ onProceed: (plan: KundliPlan, consultationSlot?: ConsultationSlotSelection) => void;
9
9
  plans?: KundliPlan[];
10
10
  t?: (key: string) => string;
11
11
  analytics?: KundliAnalytics;
12
+ /**
13
+ * Feature flag (experiment-controlled). When true, renders full-screen with the
14
+ * left-aligned header style, and the astrologer-consultation plan opens the
15
+ * full-screen `ConsultationSlotModal` before proceeding to payment.
16
+ * When false/undefined (default), falls back to `KundliContext`'s
17
+ * `enableConsultationScheduling` config, and finally to `false` — preserving the
18
+ * original bottom-sheet behavior (astrologer-consultation plan proceeds straight
19
+ * to payment, no scheduling modal).
20
+ */
21
+ enableConsultationScheduling?: boolean;
12
22
  }
13
23
  /**
14
24
  * Slide-up bottom sheet that lets the user choose a Kundli plan.
@@ -17,9 +27,10 @@ export interface KundliPlanBottomSheetProps {
17
27
  * Shown exclusively for the `v1` variant — the context gates this.
18
28
  */
19
29
  export declare const KundliPlanBottomSheet: React.FC<KundliPlanBottomSheetProps>;
20
- export type { KundliPlan } from './types';
30
+ export type { KundliPlan, ConsultationSlotSelection } from './types';
21
31
  export { getDefaultPlans } from './planDefaults';
22
32
  export { PlanCard } from './PlanCard';
23
33
  export { PlanSheetHeader } from './PlanSheetHeader';
24
34
  export { PlanFeatureList } from './PlanFeatureList';
25
35
  export { AstrologerCard } from './AstrologerCard';
36
+ export { ConsultationSlotModal } from './ConsultationSlotModal';
@@ -2,7 +2,17 @@ export declare const CheckIcon: React.FC;
2
2
  export declare const CrossIcon: React.FC;
3
3
  /** Back arrow chevron */
4
4
  export declare const ChevronLeftIcon: React.FC;
5
+ /** Down chevron, used by the consultation-language dropdown trigger */
6
+ export declare const ChevronDownIcon: React.FC;
5
7
  /** Lightning bolt icon for "Most popular" badge */
6
8
  export declare const BoltIcon: React.FC;
7
9
  /** Trend up icon for "Most popular" badge */
8
10
  export declare const TrendUpIcon: React.FC;
11
+ /** Sun icon for "Morning" period tab */
12
+ export declare const MorningIcon: React.FC;
13
+ /** Sun-cloud icon for "Afternoon" period tab */
14
+ export declare const AfternoonIcon: React.FC;
15
+ /** Moon icon for "Evening" period tab */
16
+ export declare const EveningIcon: React.FC;
17
+ /** Calendar-with-slash icon for the "No slots available" empty state */
18
+ export declare const CalendarOffIcon: React.FC;
@@ -0,0 +1,44 @@
1
+ import { ConsultationSlotDate, ConsultationSlotPeriod, ConsultationSlotsByLanguage } from './types';
2
+ /**
3
+ * Formats an ISO datetime (e.g. "2026-08-03T09:00:00+05:30") into a short
4
+ * label like "9:00 AM". Reads the hour/minute directly off the string
5
+ * instead of going through `Date`, so the slot shows the exact wall-clock
6
+ * time the backend sent rather than being reinterpreted in the browser's
7
+ * local timezone.
8
+ */
9
+ export declare const formatSlotTime: (isoDateTime: string) => string;
10
+ /** Builds a short day-tab label ("Today" / "Tomorrow" / weekday) + day number for a "yyyy-MM-dd" date string. */
11
+ export declare const formatSlotDayLabel: (isoDate: string, referenceDate?: Date) => ConsultationSlotDate;
12
+ export declare const CONSULTATION_PERIOD_ORDER: ConsultationSlotPeriod[];
13
+ /**
14
+ * Guidance topic chips shown before slot selection. Frontend-only, static
15
+ * list — never fetched from an API. `labelKey` resolves via the `t` prop
16
+ * (falls back to `label` when no translation is provided).
17
+ */
18
+ export declare const GUIDANCE_TOPICS: {
19
+ id: string;
20
+ labelKey: string;
21
+ label: string;
22
+ }[];
23
+ /**
24
+ * Consultation-language dropdown options shown on the slot selection screen.
25
+ * Matches the report-language codes the host app's preselect API returns
26
+ * availability for (`ConsultationSlotsByLanguage` keys). `labelKey` resolves
27
+ * via the `t` prop, reusing the same keys as the kundli form's report
28
+ * language chips (falls back to `label` when no translation is provided).
29
+ */
30
+ export declare const CONSULTATION_LANGUAGE_OPTIONS: {
31
+ code: string;
32
+ labelKey: string;
33
+ label: string;
34
+ }[];
35
+ export declare const languageHasAvailability: (language: ConsultationSlotsByLanguage[string] | undefined) => boolean;
36
+ /**
37
+ * Picks which consultation language should be preselected when the slot
38
+ * modal opens, based on the report language the user selected in the form:
39
+ * try that report language's default consultation language first, then its
40
+ * fallback, then — if neither has availability — whichever other language
41
+ * does, in `CONSULTATION_LANGUAGE_OPTIONS` order. Falls back to the default
42
+ * language itself if nothing has availability at all.
43
+ */
44
+ export declare const getDefaultConsultationLanguage: (slotsByLanguage: ConsultationSlotsByLanguage, reportLanguage: string | null | undefined, isGlobal: boolean) => string;
@@ -1,2 +1,5 @@
1
1
  export { KundliPlanBottomSheet, getDefaultPlans } from './KundliPlanBottomSheet';
2
- export type { KundliPlanBottomSheetProps, KundliPlan } from './KundliPlanBottomSheet';
2
+ export type { KundliPlanBottomSheetProps, KundliPlan, ConsultationSlotSelection } from './KundliPlanBottomSheet';
3
+ export { ConsultationSlotModal } from './ConsultationSlotModal';
4
+ export type { ConsultationSlotModalProps } from './ConsultationSlotModal';
5
+ export type { KundliPlanAstrologer, ConsultationSlot, ConsultationSlotDay, ConsultationSlotPeriod, ConsultationSlotsPreselectData, ConsultationSlotsByLanguage, FetchConsultationSlots, } from './types';
@@ -19,3 +19,49 @@ export interface KundliPlan {
19
19
  badge?: string;
20
20
  astrologers?: KundliPlanAstrologer[];
21
21
  }
22
+ /** A single selectable date tab, e.g. "Tomorrow", "21" */
23
+ export interface ConsultationSlotDate {
24
+ id: string;
25
+ dayLabel: string;
26
+ dayNum: string;
27
+ }
28
+ export type ConsultationSlotPeriod = "morning" | "afternoon" | "evening";
29
+ /** A single bookable time slot for a given day, as returned by the host app's slots API. */
30
+ export interface ConsultationSlot {
31
+ /** ISO datetime with offset, e.g. "2026-08-03T09:00:00+05:30" */
32
+ start: string;
33
+ /** ISO datetime with offset */
34
+ end: string;
35
+ period: ConsultationSlotPeriod;
36
+ }
37
+ /** A single day's availability, as returned by the host app's slots API. */
38
+ export interface ConsultationSlotDay {
39
+ /** ISO "yyyy-MM-dd" */
40
+ date: string;
41
+ has_availability: boolean;
42
+ slots: ConsultationSlot[];
43
+ }
44
+ /** Response shape for the host app's GET consultation slots (preselect) API. */
45
+ export interface ConsultationSlotsPreselectData {
46
+ start_date: string;
47
+ days: ConsultationSlotDay[];
48
+ }
49
+ /** Availability per report-language code (e.g. "en", "hi", "te", "ta", "kn", "gu", "mr"), as returned by the host app's slots API. */
50
+ export type ConsultationSlotsByLanguage = Record<string, ConsultationSlotsPreselectData>;
51
+ /** Callback provided by the host app to fetch real consultation slot availability for every report language at once. */
52
+ export type FetchConsultationSlots = () => Promise<ConsultationSlotsByLanguage>;
53
+ /** A guidance topic chip, e.g. "Career & work" */
54
+ export interface ConsultationTopic {
55
+ id: string;
56
+ label: string;
57
+ }
58
+ /** Details captured once the user completes the consultation slot selection flow. */
59
+ export interface ConsultationSlotSelection {
60
+ start: string;
61
+ end: string;
62
+ period: ConsultationSlotPeriod;
63
+ /** Guidance topic id the user picked (e.g. "career_work"). Frontend-only — never fetched from an API. */
64
+ topic?: string;
65
+ /** Report-language code the user picked in the slot modal's language dropdown (e.g. "en", "hi"). */
66
+ language?: string;
67
+ }