@la-main-verte/shared-types 1.0.54 → 1.0.55

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@la-main-verte/shared-types",
3
- "version": "1.0.54",
3
+ "version": "1.0.55",
4
4
  "description": "Shared TypeScript interfaces for frontend of la-main-verte app",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
package/src/alert.d.ts CHANGED
@@ -1,7 +1,101 @@
1
+ export type IconNameI =
2
+ | 'arrow-down'
3
+ | 'arrow-down-a-z'
4
+ | 'arrow-up-a-z'
5
+ | 'arrow-left'
6
+ | 'arrow-up'
7
+ | 'arrow-up-short-wide'
8
+ | 'arrow-up-91'
9
+ | 'arrow-down-91'
10
+ | 'arrow-up-square-triangle'
11
+ | 'arrow-down-square-triangle'
12
+ | 'arrow-up-big-small'
13
+ | 'arrow-down-big-small'
14
+ | 'bag-seedling'
15
+ | 'bars'
16
+ | 'bell'
17
+ | 'broom-wide'
18
+ | 'bug'
19
+ | 'calendar-check'
20
+ | 'calendar-day'
21
+ | 'calendar-days'
22
+ | 'calendar-minus'
23
+ | 'calendar-pen'
24
+ | 'calendar-plus'
25
+ | 'camera'
26
+ | 'chart-pie'
27
+ | 'chart-tree-map'
28
+ | 'check'
29
+ | 'chevron-down'
30
+ | 'chevron-left'
31
+ | 'chevron-right'
32
+ | 'circle-question'
33
+ | 'city'
34
+ | 'cog'
35
+ | 'comment'
36
+ | 'comment-dots'
37
+ | 'comments-question-check'
38
+ | 'copy'
39
+ | 'columns-3'
40
+ | 'distribute-spacing-horizontal'
41
+ | 'distribute-spacing-vertical'
42
+ | 'envelope'
43
+ | 'eye'
44
+ | 'eye-slash'
45
+ | 'filter-circle-xmark'
46
+ | 'filter-list'
47
+ | 'flask'
48
+ | 'gear'
49
+ | 'heart'
50
+ | 'home'
51
+ | 'hand-back-point-up'
52
+ | 'house-chimney-heart'
53
+ | 'image'
54
+ | 'info'
55
+ | 'keyboard'
56
+ | 'lightbulb-on'
57
+ | 'lightbulb'
58
+ | 'lock'
59
+ | 'lock-open'
60
+ | 'messages-question'
61
+ | 'microphone'
62
+ | 'minus'
63
+ | 'note-medical'
64
+ | 'note-sticky'
65
+ | 'pencil'
66
+ | 'plus'
67
+ | 'pen-ruler'
68
+ | 'podcast'
69
+ | 'rotate'
70
+ | 'ruler'
71
+ | 'scissors'
72
+ | 'satellite-dish'
73
+ | 'search'
74
+ | 'seedling'
75
+ | 'sign-in-alt'
76
+ | 'sign-out-alt'
77
+ | 'share'
78
+ | 'shovel'
79
+ | 'snowflake'
80
+ | 'star'
81
+ | 'sun-bright'
82
+ | 'temperature-snow'
83
+ | 'thumbs-up'
84
+ | 'tomato'
85
+ | 'times'
86
+ | 'trash'
87
+ | 'trowel'
88
+ | 'user-plus'
89
+ | 'user-slash'
90
+ | 'wand-sparkles'
91
+ | 'wheat'
92
+ | 'x'
93
+ | string
94
+
1
95
  export interface AlertI {
2
96
  id: number
3
- tags: AlertTagI[]
4
- icon: IconName
97
+ tags?: AlertTagI[]
98
+ icon: IconNameI
5
99
  /**
6
100
  * ColourCode of the icon
7
101
  * Ex: #ffffff
@@ -9,6 +103,8 @@ export interface AlertI {
9
103
  iconColor: string
10
104
  message: string
11
105
  published_at?: Date
106
+ updated_at?: Date
107
+ status?: 'draft' | 'published'
12
108
  }
13
109
 
14
110
  export interface AlertTagI {
package/src/device.d.ts CHANGED
@@ -17,8 +17,8 @@ export interface DeviceDataI {
17
17
  uuid: string
18
18
  /** RAW User agent string from the device */
19
19
  userAgent?: string
20
- /** Optional platform (e.g., 'ios', 'android', 'windows') */
21
- platform?: 'ios' | 'android' | 'windows'
20
+ /** Optional platform (e.g., 'ios', 'android', 'web') */
21
+ platform?: 'ios' | 'android' | 'web'
22
22
  /** Optional version of the device */
23
23
  version?: string
24
24
  /**
@@ -35,6 +35,14 @@ export interface DeviceDataI {
35
35
  name?: string
36
36
  /** Optional app version of the device. Ex: 1.0.0 */
37
37
  appVersion?: string
38
+ /** Web Push endpoint associated with the device */
39
+ webPushEndpoint?: string
40
+ /** Web Push user public key */
41
+ webPushP256dh?: string
42
+ /** Web Push auth secret */
43
+ webPushAuth?: string
44
+ /** Web Push subscription payload */
45
+ webPushSubscription?: string
38
46
  /** Timestamp of when the device was created */
39
47
  createdAt: Date
40
48
  /** Timestamp of when the device was last updated */
@@ -2,12 +2,19 @@
2
2
  * A gardenMap is a collection of garden zones
3
3
  */
4
4
  export interface GardenMapI {
5
- id: number
6
- memberId: number
5
+ id: number;
6
+ name: string;
7
+ icon_name: string;
8
+ category?: string;
9
+ default: boolean;
10
+ width_in_units: number;
11
+ height_in_units: number;
12
+ createdAt: string;
13
+ Selections: SelectionI[];
7
14
  GardenZones: GardenZoneI[]
8
- createdAt: Date
9
- updatedAt: Date
15
+ imageUrl: string;
10
16
  }
17
+
11
18
  export interface GardenZoneI {
12
19
  id: number
13
20
  name: string | null
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Garden Overview Types
3
+ * Represents the detailed overview of a garden selection
4
+ */
5
+ import { PlantI } from './plant'
6
+
7
+ export interface GardenOverviewI {
8
+ id: number
9
+ title: string
10
+ iconName: string
11
+ yearOfCulture: number
12
+ statistics: GardenOverviewStatsI
13
+ }
14
+
15
+ export interface GardenOverviewStatsI {
16
+ totalSeeds: number
17
+ totalSurface: string
18
+ totalSurfaceWithoutCulture: string
19
+ surfaceComparisonMessage: string | null
20
+ familyDistribution: FamilyStatsI[]
21
+ fertilization: FertilizationStatsI
22
+ zones: GardenOverviewZoneStatsI[]
23
+ }
24
+
25
+ export interface FertilizationStatsI {
26
+ totalWeightInKg: number
27
+ weightComparisonMessage: string | null
28
+ fertilizerDetails: FertilizerStatsI[]
29
+ }
30
+
31
+ export interface FertilizerStatsI {
32
+ fertilizerName: string
33
+ fertilizerQuantity: string
34
+ imageURL: string
35
+ }
36
+
37
+ export interface FamilyStatsI {
38
+ family: string
39
+ hexColor: string
40
+ totalSeeds: number
41
+ totalSurface: string
42
+ percentage: number
43
+ plants: GardenOverviewPlantStatsI[]
44
+ }
45
+
46
+ /**
47
+ * Extended PlantI with overview-specific statistics
48
+ * Contains the full plant data plus surface, seedQuantity, and position
49
+ */
50
+ export interface GardenOverviewPlantStatsI extends PlantI {
51
+ seedQuantity: number
52
+ surface: string
53
+ position: number
54
+ densityMode: string
55
+ fertilizerName: string
56
+ fertilizerQuantity: string
57
+ }
58
+
59
+ export interface GardenOverviewZonePlantStatsI {
60
+ id: number
61
+ name: string
62
+ imageURL: string | null
63
+ }
64
+
65
+ export interface GardenOverviewZoneFertilizerStatsI {
66
+ name: string
67
+ quantity: string
68
+ }
69
+
70
+ export interface GardenOverviewZoneStatsI {
71
+ id: number
72
+ name: string
73
+ totalSeeds: number
74
+ surface: string
75
+ fertilizerQuantity: string
76
+ thumbnailURL: string
77
+ plants: GardenOverviewZonePlantStatsI[]
78
+ fertilizers: GardenOverviewZoneFertilizerStatsI[]
79
+ }
@@ -0,0 +1,159 @@
1
+ import type { PlantI } from './plant'
2
+ import type { SelectionI } from './selection'
3
+
4
+ export namespace HOME {
5
+ export type HeroCardMode = 'featuredSelection' | 'featuredPlant'
6
+
7
+ export type SectionComponentType =
8
+ | 'Header'
9
+ | 'HeroCards'
10
+ | 'PlantCarousel'
11
+ | 'HeroCardsCarousel'
12
+ | 'WideCardsCarousel'
13
+ | 'Weather'
14
+ | 'AdviceCarousel'
15
+ | 'OnboardingCard'
16
+
17
+ export type CarouselComponentType = Extract<
18
+ SectionComponentType,
19
+ 'PlantCarousel' | 'HeroCardsCarousel' | 'WideCardsCarousel'
20
+ >
21
+
22
+ export interface WeatherDayI {
23
+ date: string
24
+ minTempC: number
25
+ maxTempC: number
26
+ chanceOfRainPercentage: number | null
27
+ iconUrl: string | null
28
+ condition?: string | null
29
+ }
30
+
31
+ export interface WeatherSectionI {
32
+ componentType: 'Weather'
33
+ title: string
34
+ subtitle?: string
35
+ locationName: string
36
+ timezone: string
37
+ days: WeatherDayI[]
38
+ lastUpdatedAt: string
39
+ dataSource: 'weatherapi'
40
+ }
41
+
42
+ export interface HeaderSectionI {
43
+ componentType: 'Header'
44
+ title: string
45
+ subtitle: string
46
+ }
47
+
48
+ export interface AdviceI {
49
+ title: string
50
+ markdownContent: string
51
+ titleColor?: string
52
+ backgroundColor?: string
53
+ }
54
+
55
+ export interface AdviceSectionI {
56
+ componentType: 'AdviceCarousel'
57
+ title?: string
58
+ subtitle?: string
59
+ advices: AdviceI[]
60
+ }
61
+
62
+ export interface WideCardAuthorI {
63
+ name?: string | null
64
+ imageURL?: string | null
65
+ }
66
+
67
+ export interface WideCardItemI {
68
+ title?: string | null
69
+ text: string
70
+ badgeText?: string | null
71
+ thumbnailImageURL: string
72
+ author?: WideCardAuthorI | null
73
+ link?: string | null
74
+ metadata?: Record<string, unknown>
75
+ }
76
+
77
+ export interface WideCardsCarouselSectionI {
78
+ componentType: 'WideCardsCarousel'
79
+ title: string
80
+ subtitle?: string
81
+ cards: WideCardItemI[]
82
+ }
83
+
84
+ export interface HeroCardBlueprintI {
85
+ mode: HeroCardMode
86
+ title?: string | null
87
+ description?: string | null
88
+ backgroundColor?: string | null
89
+ backgroundImageUrl?: string | null
90
+ ctaLabel?: string | null
91
+ previewPlants?: PlantI[]
92
+ selection?: SelectionI | null
93
+ plant?: PlantI | null
94
+ }
95
+
96
+ export interface HeroCardsSectionI {
97
+ componentType: 'HeroCards'
98
+ title?: string | null
99
+ subtitle?: string | null
100
+ cards: HeroCardBlueprintI[]
101
+ }
102
+
103
+ export interface PlantCarouselSectionI {
104
+ componentType: 'PlantCarousel'
105
+ title: string
106
+ subtitle?: string
107
+ selection: SelectionI
108
+ displayRanking?: boolean
109
+ }
110
+
111
+ export interface HeroCardsCarouselSectionI {
112
+ componentType: 'HeroCardsCarousel'
113
+ selections: SelectionI[]
114
+ }
115
+
116
+ export interface FamilyRecommendationI {
117
+ family: string
118
+ headline: string
119
+ plants: PlantI[]
120
+ }
121
+
122
+ export interface FamilyExplorerSectionI {
123
+ componentType: 'FamilyExplorer'
124
+ title: string
125
+ subtitle?: string
126
+ families: FamilyRecommendationI[]
127
+ }
128
+
129
+ export interface OnboardingStepI {
130
+ id: string
131
+ title: string
132
+ description: string
133
+ isCompleted: boolean
134
+ ctaLink: string
135
+ }
136
+
137
+ export interface OnboardingCardSectionI {
138
+ componentType: 'OnboardingCard'
139
+ title: string
140
+ subtitle: string
141
+ steps: OnboardingStepI[]
142
+ completedStepsCount: number
143
+ totalStepsCount: number
144
+ }
145
+
146
+ export type SectionI =
147
+ | HeaderSectionI
148
+ | HeroCardsSectionI
149
+ | PlantCarouselSectionI
150
+ | HeroCardsCarouselSectionI
151
+ | WideCardsCarouselSectionI
152
+ | WeatherSectionI
153
+ | AdviceSectionI
154
+ | OnboardingCardSectionI
155
+
156
+ export interface Response {
157
+ sections: SectionI[]
158
+ }
159
+ }
package/src/index.ts CHANGED
@@ -6,16 +6,22 @@ export * from './task'
6
6
  export * from './calendarView'
7
7
  export * from './apiError'
8
8
  export * from './gardenMap'
9
+ export * from './gardenOverview'
9
10
  export * from './alert'
10
11
  export * from './image'
11
12
  export * from './note'
12
13
  export * from './taggedItem'
13
14
  export * from './fertilizer'
15
+ export * from './utmParams'
14
16
  import * as PlantsAPI from './plants.api'
15
17
  import * as UsersAPI from './users.api'
18
+ import * as SessionsAPI from './sessions.api'
19
+ import * as HomeAPI from './home.api'
16
20
 
17
21
  // Allow access to the API namespaces without conflicts
18
22
  export namespace API {
19
23
  export import PLANTS = PlantsAPI
20
24
  export import USERS = UsersAPI
25
+ export import SESSIONS = SessionsAPI
26
+ export import HOME = HomeAPI
21
27
  }
package/src/member.d.ts CHANGED
@@ -27,7 +27,7 @@ export interface MemberI {
27
27
  hasAnActiveSubscription?: boolean
28
28
  /**
29
29
  * Acts as a one-way not identifiable token.
30
- * Crisp and other services like Upvoty use this token to identify the user
30
+ * Crisp and other services may use this token to identify the user
31
31
  */
32
32
  userToken: string
33
33
  /**
@@ -1,4 +1,4 @@
1
- import { PlantI, PlantTagI } from './plant.d'
1
+ import { PlantI } from './plant.d'
2
2
  import { SelectionI } from './selection.d'
3
3
  import { ImageDataI } from './image.d'
4
4
 
@@ -59,4 +59,26 @@ export namespace PLANTS {
59
59
  */
60
60
  export type Response = PlantExtendedDataI[]
61
61
  }
62
+ export namespace UPDATE {
63
+ export interface Request {
64
+ params: {
65
+ slug: string
66
+ }
67
+ body: {
68
+ name?: string
69
+ description?: string
70
+ shared?: boolean
71
+ spaceBetweenSeedMin?: number | null
72
+ spaceBetweenSeedMax?: number | null
73
+ spaceBetweenAlleyMin?: number | null
74
+ spaceBetweenAlleyMax?: number | null
75
+ weeksToMaturity?: number | null
76
+ indoorSeeding?: boolean
77
+ outdoorSeeding?: boolean
78
+ sunRequirements?: 'partialShade' | 'fullSun' | 'fullShade' | null
79
+ isHardy?: boolean | null
80
+ }
81
+ }
82
+ export type Response = PlantI
83
+ }
62
84
  }
@@ -0,0 +1,134 @@
1
+ import type { UTMParams } from './utmParams'
2
+ import type { EventType, EventDetailsI } from '../../server/types/sessionEvent'
3
+ import type { PaymentProductTypeI } from '../../server/types/payment'
4
+
5
+ interface RequestHeaders {
6
+ 'x-session-token'?: string
7
+ 'x-native-app-version'?: string
8
+ 'x-application-type'?: 'react-native' | 'web'
9
+ 'user-agent'?: string
10
+ }
11
+
12
+ export namespace SESSIONS {
13
+ export namespace POST {
14
+ export interface Request {
15
+ headers: RequestHeaders
16
+ body: {
17
+ uuid?: string
18
+ platform?: 'web' | 'react-native' | 'unknown'
19
+ device_id?: number
20
+ app_version?: string
21
+ ip_address?: string
22
+ } & Partial<UTMParams>
23
+ }
24
+ export interface Response {
25
+ success: boolean
26
+ session: {
27
+ id: number
28
+ uuid: string
29
+ is_authenticated: boolean
30
+ expires_at: string
31
+ platform: string
32
+ first_seen_at: string
33
+ last_activity_at: string
34
+ }
35
+ message?: string
36
+ }
37
+ }
38
+
39
+ export namespace GET {
40
+ export interface Request {
41
+ headers: RequestHeaders
42
+ query: {
43
+ session_id: string
44
+ }
45
+ }
46
+ export interface Response {
47
+ success: boolean
48
+ session?: {
49
+ id: number
50
+ uuid: string
51
+ is_authenticated: boolean
52
+ expires_at: string
53
+ platform: string
54
+ first_seen_at: string
55
+ last_activity_at: string
56
+ memberId?: number
57
+ }
58
+ message?: string
59
+ }
60
+ }
61
+
62
+ export namespace EVENTS {
63
+ export namespace POST {
64
+ export interface Request {
65
+ headers: RequestHeaders
66
+ body: EventDetailsI & {
67
+ uuid: string
68
+ event_data?: any
69
+ // Feature usage specific
70
+ feature_name?: string
71
+ feature_action?: string
72
+ // Event metadata
73
+ platform?: 'web' | 'react-native' | 'unknown'
74
+ device_id?: number
75
+ app_version?: string
76
+ ip_address?: string
77
+ // Payment tracking
78
+ payment_customer_external_id?: string
79
+ payment_processor?: 'stripe' | 'apple' | 'google'
80
+ payment_middleware?: 'stripe' | 'revenuecat'
81
+ payment_product_type?: PaymentProductTypeI
82
+ payment_transaction_id?: string
83
+ // Revenue tracking
84
+ revenue_amount?: number
85
+ currency?: string
86
+ created_by?: 'server' | 'client' | 'unknown'
87
+ }
88
+ }
89
+ export interface Response {
90
+ success: boolean
91
+ event: {
92
+ id: number
93
+ sessionId: number
94
+ createdAt: string
95
+ } & EventDetailsI
96
+ message?: string
97
+ }
98
+ }
99
+
100
+ export namespace GET {
101
+ export interface Request {
102
+ headers: RequestHeaders
103
+ query: {
104
+ session_id?: string
105
+ event_type?: EventType
106
+ feature_name?: string
107
+ campaign_id?: string
108
+ start_date?: string
109
+ end_date?: string
110
+ limit?: number
111
+ offset?: number
112
+ }
113
+ }
114
+ export interface Response {
115
+ success: boolean
116
+ events: Array<
117
+ {
118
+ id: number
119
+ sessionId: number
120
+ event_data?: any
121
+ feature_name?: string
122
+ feature_action?: string
123
+ platform: string
124
+ revenue_amount?: number
125
+ currency?: string
126
+ createdAt: string
127
+ } & EventDetailsI
128
+ >
129
+ total_count: number
130
+ message?: string
131
+ }
132
+ }
133
+ }
134
+ }
@@ -1,5 +1,7 @@
1
1
  import type { DeviceDataI } from './device.d'
2
2
  import type { MemberI as MemberDataI } from './member.d'
3
+ import type { SelectionI } from './selection.d'
4
+ import type { PlantI } from './plant.d'
3
5
 
4
6
  interface RequestHeaders {
5
7
  'x-session-token': string
@@ -33,8 +35,56 @@ export namespace USERS {
33
35
  pushKey?: DeviceDataI['pushKey']
34
36
  apnsToken?: DeviceDataI['apnsToken']
35
37
  fcmToken?: DeviceDataI['fcmToken']
38
+ webPushEndpoint?: DeviceDataI['webPushEndpoint']
39
+ webPushP256dh?: DeviceDataI['webPushP256dh']
40
+ webPushAuth?: DeviceDataI['webPushAuth']
41
+ webPushSubscription?: DeviceDataI['webPushSubscription']
36
42
  }
37
43
  }
38
44
  export type Response = DeviceDataI
39
45
  }
46
+ export namespace RECOMMENDATIONS {
47
+ export type ComponentType = 'PlantCarousel' | 'SelectionCarousel' | 'HeroCardsCarousel' | 'YourSelection'
48
+
49
+ interface BaseRecommendation {
50
+ id: string
51
+ componentType: ComponentType
52
+ title?: string
53
+ subtitle?: string
54
+ cardsVisible?: number
55
+ }
56
+
57
+ export interface PlantCarouselRecommendation extends BaseRecommendation {
58
+ componentType: 'PlantCarousel'
59
+ selection: SelectionI & { Plants?: PlantI[] }
60
+ displayRanking?: boolean
61
+ }
62
+
63
+ export interface SelectionCarouselRecommendation extends BaseRecommendation {
64
+ componentType: 'SelectionCarousel'
65
+ selections: SelectionI[]
66
+ displayRanking?: boolean
67
+ }
68
+
69
+ export interface HeroCardsCarouselRecommendation extends BaseRecommendation {
70
+ componentType: 'HeroCardsCarousel'
71
+ selections: SelectionI[]
72
+ }
73
+
74
+ export interface YourSelectionRecommendation extends BaseRecommendation {
75
+ componentType: 'YourSelection'
76
+ }
77
+
78
+ export type RecommendationI =
79
+ | PlantCarouselRecommendation
80
+ | SelectionCarouselRecommendation
81
+ | HeroCardsCarouselRecommendation
82
+ | YourSelectionRecommendation
83
+
84
+ export interface Request {
85
+ headers: RequestHeaders
86
+ }
87
+
88
+ export type Response = RecommendationI[]
89
+ }
40
90
  }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * UTMSource - Identifies the origin platform or website that sent the traffic
3
+ *
4
+ * This type answers the question: "Where did this visitor come from?"
5
+ * It tracks the specific platform, website, or source that generated the traffic.
6
+ *
7
+ * Common values are included in the union type, but custom domains/values are also allowed.
8
+ */
9
+ export type UTMSource =
10
+ | 'google' // Google search results or Google Ads
11
+ | 'facebook' // Facebook posts, ads, or shared content
12
+ | 'instagram' // Instagram posts, stories, or ads
13
+ | 'youtube' // YouTube videos, ads, or descriptions
14
+ | 'email' // Email newsletter campaigns
15
+ | 'direct' // Direct visits to the website
16
+ | 'Brevo' // Our newsletter software
17
+ | (string & {}) // Custom domains like 'semencesduportage.com' or any other string
18
+
19
+ /**
20
+ * UTMMedium - Identifies the marketing channel or method used
21
+ *
22
+ * This type answers the question: "What type of marketing brought this visitor?"
23
+ * It categorizes the marketing method, whether paid, organic, or referral-based.
24
+ *
25
+ * Common values are included in the union type, but custom values are also allowed.
26
+ */
27
+ export type UTMMedium =
28
+ | 'cpc' // Cost-per-click advertising (Google Ads, Facebook Ads, etc.)
29
+ | 'paid' // Paid social media advertising campaigns
30
+ | 'organic' // Free/organic traffic (search engine results, social media posts)
31
+ | 'email' // Email marketing campaigns and newsletters
32
+ | 'push' // Push notification campaigns
33
+ | 'display' // Display/banner advertising
34
+ | 'referral' // Referral traffic from partnerships or other websites
35
+ | 'affiliate' // Affiliate marketing programs
36
+ | (string & {}) // Any other custom medium
37
+
38
+ /**
39
+ * UTMCampaign - Identifies the specific marketing campaign name
40
+ *
41
+ * This type answers the question: "Which specific campaign generated this traffic?"
42
+ * It allows you to track performance across different marketing initiatives.
43
+ *
44
+ * Examples:
45
+ * - 'alert_ID' - Alert based campaigns
46
+ * - 'summer_sale_2024' - Seasonal sales campaigns
47
+ * - 'new_user_discount' - User acquisition campaigns
48
+ * - 'retention_series' - Customer retention campaigns
49
+ */
50
+ export type UTMCampaign = 'reel' | 'alert' | string
51
+
52
+ /**
53
+ * UTMTerm - Identifies the specific keywords or search terms used
54
+ *
55
+ * This type answers the question: "What keywords or terms led to this visit?"
56
+ * It's particularly useful for paid search campaigns and organic search tracking.
57
+ *
58
+ * Examples:
59
+ * - 'tomato_seeds' - Specific keyword for tomato seed searches
60
+ * - 'planting_guide' - Specific keyword for planting guide searches
61
+ * - 'organic_fertilizer' - Product-specific keywords
62
+ * - 'garden_planning' - Service-related keywords
63
+ */
64
+ export type UTMTerm = string
65
+
66
+ /**
67
+ * UTMContent - Identifies the specific content variation or creative element
68
+ *
69
+ * This type answers the question: "Which specific content version was clicked?"
70
+ * It enables A/B testing and creative performance tracking.
71
+ *
72
+ * Examples:
73
+ * - 'headline_a' - Version A of a headline for A/B testing
74
+ * - 'image_garden_1' - Specific image used in the campaign
75
+ * - 'link_top_banner' - Specific link placement (top banner)
76
+ * - 'cta_button_blue' - Specific call-to-action button
77
+ */
78
+ export type UTMContent = string
79
+
80
+ /**
81
+ * UTMParams - Complete interface for all UTM tracking parameters
82
+ *
83
+ * This interface combines all UTM parameters into a single object for easy
84
+ * tracking and analytics. All parameters are optional to allow flexible usage.
85
+ *
86
+ * COOKIE STORAGE:
87
+ * Each parameter is stored as a separate cookie:
88
+ * - utm_source
89
+ * - utm_medium
90
+ * - utm_campaign
91
+ * - utm_term
92
+ * - utm_content
93
+ * - fbclid
94
+ * - fbp
95
+ * - gclid
96
+ *
97
+ * Usage example:
98
+ * const utmParams: UTMParams = {
99
+ * utm_source: 'facebook',
100
+ * utm_medium: 'paid',
101
+ * utm_campaign: 'hardiness_zone',
102
+ * utm_term: 'tomato_seeds',
103
+ * utm_content: 'headline_a',
104
+ * fbclid: 'IwAR123...',
105
+ * fbp: 'fb.1.1234567890.1234567890',
106
+ * gclid: 'EAIaIQobChMI...'
107
+ * };
108
+ */
109
+ export interface UTMParams {
110
+ /** Unique UUID session identifier from front-end tracking script */
111
+ uuid?: string
112
+ /** The source platform that generated the traffic */
113
+ utm_source?: UTMSource
114
+ /** The marketing channel or method used */
115
+ utm_medium?: UTMMedium
116
+ /** The specific campaign name */
117
+ utm_campaign?: UTMCampaign
118
+ /** The keywords or search terms used */
119
+ utm_term?: UTMTerm
120
+ /** The specific content variation or creative element */
121
+ utm_content?: UTMContent
122
+ /** Facebook click identifier for attribution (stored as fbclid in URL) */
123
+ fbclid?: string
124
+ /** Facebook browser ID for pixel tracking (stored as _fbp cookie) */
125
+ fbp?: string
126
+ /** Google Ads click identifier for attribution (stored as gclid in URL) */
127
+ gclid?: string
128
+ /** Google Ads click identifier for iOS/Android app to web (Google surfaces) */
129
+ gbraid?: string
130
+ /** Google Ads click identifier for iOS/Android app to web (non-Google surfaces) */
131
+ wbraid?: string
132
+ /** OLD Referral source from partners - now utm_source=jardinierparesseux */
133
+ referrer?: string
134
+ }