@startsimpli/funnels 0.1.4 → 0.1.5

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 (151) hide show
  1. package/package.json +9 -31
  2. package/src/api/README.md +507 -0
  3. package/src/api/adapter.ts +106 -0
  4. package/src/api/client.test.ts +640 -0
  5. package/src/api/client.ts +385 -0
  6. package/src/api/default-adapter.ts +243 -0
  7. package/src/api/index.ts +24 -0
  8. package/src/components/FilterRuleEditor/ARCHITECTURE.md +354 -0
  9. package/src/components/FilterRuleEditor/FieldSelector.tsx +91 -0
  10. package/src/components/FilterRuleEditor/FilterRuleEditor.stories.tsx +462 -0
  11. package/src/components/FilterRuleEditor/FilterRuleEditor.test.tsx +520 -0
  12. package/src/components/FilterRuleEditor/FilterRuleEditor.tsx +225 -0
  13. package/src/components/FilterRuleEditor/LogicToggle.tsx +64 -0
  14. package/src/components/FilterRuleEditor/OperatorSelector.tsx +75 -0
  15. package/src/components/FilterRuleEditor/README.md +291 -0
  16. package/src/components/FilterRuleEditor/RuleRow.tsx +246 -0
  17. package/src/components/FilterRuleEditor/ValueInputs/BooleanValueInput.tsx +54 -0
  18. package/src/components/FilterRuleEditor/ValueInputs/ChoiceValueInput.tsx +83 -0
  19. package/src/components/FilterRuleEditor/ValueInputs/DateValueInput.tsx +70 -0
  20. package/src/components/FilterRuleEditor/ValueInputs/MultiChoiceValueInput.tsx +132 -0
  21. package/src/components/FilterRuleEditor/ValueInputs/NumberValueInput.tsx +73 -0
  22. package/src/components/FilterRuleEditor/ValueInputs/TextValueInput.tsx +50 -0
  23. package/src/components/FilterRuleEditor/ValueInputs/index.ts +12 -0
  24. package/src/components/FilterRuleEditor/constants.ts +64 -0
  25. package/src/components/FilterRuleEditor/index.ts +14 -0
  26. package/src/components/FunnelCard/DESIGN.md +447 -0
  27. package/src/components/FunnelCard/FunnelCard.stories.tsx +484 -0
  28. package/src/components/FunnelCard/FunnelCard.test.ts +257 -0
  29. package/src/components/FunnelCard/FunnelCard.test.tsx +336 -0
  30. package/src/components/FunnelCard/FunnelCard.tsx +204 -0
  31. package/src/components/FunnelCard/FunnelStats.tsx +68 -0
  32. package/src/components/FunnelCard/IMPLEMENTATION_SUMMARY.md +505 -0
  33. package/src/components/FunnelCard/INSTALLATION.md +304 -0
  34. package/src/components/FunnelCard/MatchBar.tsx +49 -0
  35. package/src/components/FunnelCard/README.md +294 -0
  36. package/src/components/FunnelCard/StageIndicator.tsx +62 -0
  37. package/src/components/FunnelCard/StatusBadge.tsx +52 -0
  38. package/src/components/FunnelCard/index.ts +14 -0
  39. package/src/components/FunnelPreview/EntityCard.tsx +72 -0
  40. package/src/components/FunnelPreview/FunnelPreview.stories.tsx +227 -0
  41. package/src/components/FunnelPreview/FunnelPreview.test.tsx +316 -0
  42. package/src/components/FunnelPreview/FunnelPreview.tsx +249 -0
  43. package/src/components/FunnelPreview/LoadingPreview.tsx +60 -0
  44. package/src/components/FunnelPreview/PreviewStats.tsx +78 -0
  45. package/src/components/FunnelPreview/README.md +337 -0
  46. package/src/components/FunnelPreview/StageBreakdown.tsx +94 -0
  47. package/src/components/FunnelPreview/example.tsx +286 -0
  48. package/src/components/FunnelPreview/index.ts +14 -0
  49. package/src/components/FunnelRunHistory/COMPONENT_SUMMARY.md +246 -0
  50. package/src/components/FunnelRunHistory/FunnelRunHistory.stories.tsx +272 -0
  51. package/src/components/FunnelRunHistory/FunnelRunHistory.test.tsx +323 -0
  52. package/src/components/FunnelRunHistory/FunnelRunHistory.tsx +329 -0
  53. package/src/components/FunnelRunHistory/README.md +325 -0
  54. package/src/components/FunnelRunHistory/RunActions.tsx +168 -0
  55. package/src/components/FunnelRunHistory/RunDetailsModal.tsx +221 -0
  56. package/src/components/FunnelRunHistory/RunFilters.tsx +128 -0
  57. package/src/components/FunnelRunHistory/RunRow.tsx +122 -0
  58. package/src/components/FunnelRunHistory/RunStatusBadge.tsx +75 -0
  59. package/src/components/FunnelRunHistory/StageBreakdownList.tsx +110 -0
  60. package/src/components/FunnelRunHistory/index.ts +51 -0
  61. package/src/components/FunnelRunHistory/types.ts +40 -0
  62. package/src/components/FunnelRunHistory/utils.test.ts +126 -0
  63. package/src/components/FunnelRunHistory/utils.ts +100 -0
  64. package/src/components/FunnelStageBuilder/AddStageButton.tsx +52 -0
  65. package/src/components/FunnelStageBuilder/FunnelStageBuilder.css +413 -0
  66. package/src/components/FunnelStageBuilder/FunnelStageBuilder.stories.tsx +312 -0
  67. package/src/components/FunnelStageBuilder/FunnelStageBuilder.test.tsx +304 -0
  68. package/src/components/FunnelStageBuilder/FunnelStageBuilder.tsx +321 -0
  69. package/src/components/FunnelStageBuilder/README.md +341 -0
  70. package/src/components/FunnelStageBuilder/StageActions.test.tsx +205 -0
  71. package/src/components/FunnelStageBuilder/StageActions.tsx +126 -0
  72. package/src/components/FunnelStageBuilder/StageCard.tsx +202 -0
  73. package/src/components/FunnelStageBuilder/StageForm.tsx +262 -0
  74. package/src/components/FunnelStageBuilder/TagInput.test.tsx +178 -0
  75. package/src/components/FunnelStageBuilder/TagInput.tsx +129 -0
  76. package/src/components/FunnelStageBuilder/index.ts +21 -0
  77. package/src/components/FunnelVisualFlow/FlowLegend.tsx +77 -0
  78. package/{dist/components/index.css → src/components/FunnelVisualFlow/FunnelVisualFlow.css} +89 -13
  79. package/src/components/FunnelVisualFlow/FunnelVisualFlow.stories.tsx +254 -0
  80. package/src/components/FunnelVisualFlow/FunnelVisualFlow.test.tsx +208 -0
  81. package/src/components/FunnelVisualFlow/FunnelVisualFlow.tsx +229 -0
  82. package/src/components/FunnelVisualFlow/README.md +323 -0
  83. package/src/components/FunnelVisualFlow/StageNode.tsx +188 -0
  84. package/src/components/FunnelVisualFlow/example.tsx +227 -0
  85. package/src/components/FunnelVisualFlow/index.ts +10 -0
  86. package/src/components/index.ts +102 -0
  87. package/src/core/README.md +307 -0
  88. package/src/core/engine.test.ts +1087 -0
  89. package/src/core/engine.ts +329 -0
  90. package/src/core/evaluator.example.ts +353 -0
  91. package/src/core/evaluator.test.ts +639 -0
  92. package/src/core/evaluator.ts +261 -0
  93. package/src/core/field-resolver.example.ts +175 -0
  94. package/src/core/field-resolver.test.ts +541 -0
  95. package/src/core/field-resolver.ts +247 -0
  96. package/src/core/index.ts +34 -0
  97. package/src/core/operators.test.ts +539 -0
  98. package/src/core/operators.ts +241 -0
  99. package/src/hooks/index.ts +5 -0
  100. package/src/hooks/useDebouncedValue.ts +28 -0
  101. package/src/index.ts +155 -0
  102. package/src/store/README.md +342 -0
  103. package/src/store/create-funnel-store.test.ts +686 -0
  104. package/src/store/create-funnel-store.ts +538 -0
  105. package/src/store/index.ts +9 -0
  106. package/src/store/types.ts +294 -0
  107. package/src/stories/CrossDomain.stories.tsx +149 -0
  108. package/src/stories/Welcome.stories.tsx +81 -0
  109. package/src/stories/demo-data/index.ts +3 -0
  110. package/src/stories/demo-data/investors.ts +216 -0
  111. package/src/stories/demo-data/leads.ts +223 -0
  112. package/src/stories/demo-data/recipes.ts +217 -0
  113. package/src/test/setup.ts +5 -0
  114. package/src/types/index.ts +843 -0
  115. package/dist/client-3ESO2NHy.d.ts +0 -310
  116. package/dist/client-CZu03ACp.d.cts +0 -310
  117. package/dist/components/index.cjs +0 -3241
  118. package/dist/components/index.cjs.map +0 -1
  119. package/dist/components/index.css.map +0 -1
  120. package/dist/components/index.d.cts +0 -726
  121. package/dist/components/index.d.ts +0 -726
  122. package/dist/components/index.js +0 -3194
  123. package/dist/components/index.js.map +0 -1
  124. package/dist/core/index.cjs +0 -500
  125. package/dist/core/index.cjs.map +0 -1
  126. package/dist/core/index.d.cts +0 -359
  127. package/dist/core/index.d.ts +0 -359
  128. package/dist/core/index.js +0 -486
  129. package/dist/core/index.js.map +0 -1
  130. package/dist/hooks/index.cjs +0 -20
  131. package/dist/hooks/index.cjs.map +0 -1
  132. package/dist/hooks/index.d.cts +0 -11
  133. package/dist/hooks/index.d.ts +0 -11
  134. package/dist/hooks/index.js +0 -18
  135. package/dist/hooks/index.js.map +0 -1
  136. package/dist/index-BGDEXbuz.d.cts +0 -434
  137. package/dist/index-BGDEXbuz.d.ts +0 -434
  138. package/dist/index.cjs +0 -4499
  139. package/dist/index.cjs.map +0 -1
  140. package/dist/index.css +0 -198
  141. package/dist/index.css.map +0 -1
  142. package/dist/index.d.cts +0 -99
  143. package/dist/index.d.ts +0 -99
  144. package/dist/index.js +0 -4421
  145. package/dist/index.js.map +0 -1
  146. package/dist/store/index.cjs +0 -389
  147. package/dist/store/index.cjs.map +0 -1
  148. package/dist/store/index.d.cts +0 -225
  149. package/dist/store/index.d.ts +0 -225
  150. package/dist/store/index.js +0 -386
  151. package/dist/store/index.js.map +0 -1
@@ -0,0 +1,216 @@
1
+ import type { FieldDefinition } from '../../types';
2
+
3
+ export const investorFields: FieldDefinition[] = [
4
+ {
5
+ name: 'firm.name',
6
+ type: 'text',
7
+ label: 'Firm Name',
8
+ category: 'firm',
9
+ description: 'Name of the investment firm',
10
+ },
11
+ {
12
+ name: 'firm.stage',
13
+ type: 'choice',
14
+ label: 'Investment Stage',
15
+ category: 'investment',
16
+ description: 'Preferred investment stage',
17
+ choices: ['Pre-Seed', 'Seed', 'Series A', 'Series B', 'Series C+', 'Growth'],
18
+ },
19
+ {
20
+ name: 'firm.checkSizeMin',
21
+ type: 'number',
22
+ label: 'Min Check Size',
23
+ category: 'investment',
24
+ description: 'Minimum investment amount (USD)',
25
+ unit: 'USD',
26
+ },
27
+ {
28
+ name: 'firm.checkSizeMax',
29
+ type: 'number',
30
+ label: 'Max Check Size',
31
+ category: 'investment',
32
+ description: 'Maximum investment amount (USD)',
33
+ unit: 'USD',
34
+ },
35
+ {
36
+ name: 'firm.sectors',
37
+ type: 'multi-choice',
38
+ label: 'Sectors',
39
+ category: 'investment',
40
+ description: 'Sectors of interest',
41
+ choices: ['SaaS', 'FinTech', 'HealthTech', 'AI/ML', 'Climate', 'Consumer', 'Enterprise'],
42
+ },
43
+ {
44
+ name: 'investor.name',
45
+ type: 'text',
46
+ label: 'Investor Name',
47
+ category: 'person',
48
+ description: 'Individual investor name',
49
+ },
50
+ {
51
+ name: 'investor.title',
52
+ type: 'text',
53
+ label: 'Title',
54
+ category: 'person',
55
+ description: 'Investor title/role',
56
+ },
57
+ {
58
+ name: 'investor.score',
59
+ type: 'number',
60
+ label: 'Fit Score',
61
+ category: 'metrics',
62
+ description: 'Internal fit score (0-100)',
63
+ unit: 'points',
64
+ },
65
+ {
66
+ name: 'firm.lastContactDays',
67
+ type: 'number',
68
+ label: 'Days Since Contact',
69
+ category: 'engagement',
70
+ description: 'Days since last contact',
71
+ unit: 'days',
72
+ },
73
+ {
74
+ name: 'firm.portfolioSize',
75
+ type: 'number',
76
+ label: 'Portfolio Size',
77
+ category: 'firm',
78
+ description: 'Number of portfolio companies',
79
+ unit: 'companies',
80
+ },
81
+ ];
82
+
83
+ export const sampleInvestors = [
84
+ {
85
+ id: 'inv-001',
86
+ 'firm.name': 'Acme Ventures',
87
+ 'firm.stage': 'Seed',
88
+ 'firm.checkSizeMin': 500000,
89
+ 'firm.checkSizeMax': 2000000,
90
+ 'firm.sectors': ['SaaS', 'AI/ML'],
91
+ 'investor.name': 'Sarah Chen',
92
+ 'investor.title': 'Partner',
93
+ 'investor.score': 92,
94
+ 'firm.lastContactDays': 7,
95
+ 'firm.portfolioSize': 45,
96
+ },
97
+ {
98
+ id: 'inv-002',
99
+ 'firm.name': 'TechStar Capital',
100
+ 'firm.stage': 'Series A',
101
+ 'firm.checkSizeMin': 3000000,
102
+ 'firm.checkSizeMax': 10000000,
103
+ 'firm.sectors': ['Enterprise', 'SaaS'],
104
+ 'investor.name': 'Michael Rodriguez',
105
+ 'investor.title': 'Managing Partner',
106
+ 'investor.score': 88,
107
+ 'firm.lastContactDays': 14,
108
+ 'firm.portfolioSize': 67,
109
+ },
110
+ {
111
+ id: 'inv-003',
112
+ 'firm.name': 'Climate Forward Fund',
113
+ 'firm.stage': 'Seed',
114
+ 'firm.checkSizeMin': 1000000,
115
+ 'firm.checkSizeMax': 5000000,
116
+ 'firm.sectors': ['Climate', 'AI/ML'],
117
+ 'investor.name': 'Jessica Park',
118
+ 'investor.title': 'Principal',
119
+ 'investor.score': 85,
120
+ 'firm.lastContactDays': 3,
121
+ 'firm.portfolioSize': 23,
122
+ },
123
+ {
124
+ id: 'inv-004',
125
+ 'firm.name': 'Early Stage Partners',
126
+ 'firm.stage': 'Pre-Seed',
127
+ 'firm.checkSizeMin': 100000,
128
+ 'firm.checkSizeMax': 500000,
129
+ 'firm.sectors': ['SaaS', 'Consumer', 'FinTech'],
130
+ 'investor.name': 'David Kim',
131
+ 'investor.title': 'General Partner',
132
+ 'investor.score': 78,
133
+ 'firm.lastContactDays': 21,
134
+ 'firm.portfolioSize': 89,
135
+ },
136
+ {
137
+ id: 'inv-005',
138
+ 'firm.name': 'HealthTech Innovations',
139
+ 'firm.stage': 'Series A',
140
+ 'firm.checkSizeMin': 5000000,
141
+ 'firm.checkSizeMax': 15000000,
142
+ 'firm.sectors': ['HealthTech', 'AI/ML'],
143
+ 'investor.name': 'Dr. Emily Watson',
144
+ 'investor.title': 'Senior Partner',
145
+ 'investor.score': 90,
146
+ 'firm.lastContactDays': 10,
147
+ 'firm.portfolioSize': 34,
148
+ },
149
+ ];
150
+
151
+ export const investorFunnelExample = {
152
+ id: 'funnel-001',
153
+ name: 'High-Priority Seed Investors',
154
+ description: 'Target seed-stage VCs with strong SaaS focus and recent engagement',
155
+ entityType: 'investor',
156
+ stages: [
157
+ {
158
+ id: 'stage-1',
159
+ name: 'Right Stage',
160
+ description: 'Seed or Pre-Seed investors',
161
+ order: 0,
162
+ rules: [
163
+ {
164
+ field: 'firm.stage',
165
+ operator: 'in',
166
+ value: ['Seed', 'Pre-Seed'],
167
+ logicalOperator: 'AND',
168
+ },
169
+ ],
170
+ },
171
+ {
172
+ id: 'stage-2',
173
+ name: 'Right Sectors',
174
+ description: 'Interested in SaaS or AI/ML',
175
+ order: 1,
176
+ rules: [
177
+ {
178
+ field: 'firm.sectors',
179
+ operator: 'contains_any',
180
+ value: ['SaaS', 'AI/ML'],
181
+ logicalOperator: 'AND',
182
+ },
183
+ ],
184
+ },
185
+ {
186
+ id: 'stage-3',
187
+ name: 'High Engagement',
188
+ description: 'Contacted within last 14 days',
189
+ order: 2,
190
+ rules: [
191
+ {
192
+ field: 'firm.lastContactDays',
193
+ operator: 'lte',
194
+ value: 14,
195
+ logicalOperator: 'AND',
196
+ },
197
+ ],
198
+ },
199
+ {
200
+ id: 'stage-4',
201
+ name: 'Strong Fit',
202
+ description: 'Fit score above 80',
203
+ order: 3,
204
+ rules: [
205
+ {
206
+ field: 'investor.score',
207
+ operator: 'gte',
208
+ value: 80,
209
+ logicalOperator: 'AND',
210
+ },
211
+ ],
212
+ },
213
+ ],
214
+ createdAt: new Date('2024-01-15'),
215
+ updatedAt: new Date('2024-02-01'),
216
+ };
@@ -0,0 +1,223 @@
1
+ import type { FieldDefinition } from '../../types';
2
+
3
+ export const leadFields: FieldDefinition[] = [
4
+ {
5
+ name: 'lead.name',
6
+ type: 'text',
7
+ label: 'Lead Name',
8
+ category: 'contact',
9
+ description: 'Contact name',
10
+ },
11
+ {
12
+ name: 'lead.company',
13
+ type: 'text',
14
+ label: 'Company',
15
+ category: 'contact',
16
+ description: 'Company name',
17
+ },
18
+ {
19
+ name: 'lead.industry',
20
+ type: 'choice',
21
+ label: 'Industry',
22
+ category: 'company',
23
+ description: 'Company industry',
24
+ choices: ['Technology', 'Healthcare', 'Finance', 'Retail', 'Manufacturing', 'Education', 'Real Estate'],
25
+ },
26
+ {
27
+ name: 'lead.companySize',
28
+ type: 'choice',
29
+ label: 'Company Size',
30
+ category: 'company',
31
+ description: 'Number of employees',
32
+ choices: ['1-10', '11-50', '51-200', '201-500', '501-1000', '1000+'],
33
+ },
34
+ {
35
+ name: 'lead.budget',
36
+ type: 'number',
37
+ label: 'Budget',
38
+ category: 'sales',
39
+ description: 'Estimated budget (USD)',
40
+ unit: 'USD',
41
+ },
42
+ {
43
+ name: 'lead.score',
44
+ type: 'number',
45
+ label: 'Lead Score',
46
+ category: 'metrics',
47
+ description: 'Lead qualification score (0-100)',
48
+ unit: 'points',
49
+ },
50
+ {
51
+ name: 'lead.source',
52
+ type: 'choice',
53
+ label: 'Source',
54
+ category: 'acquisition',
55
+ description: 'Lead source',
56
+ choices: ['Website', 'Referral', 'Social Media', 'Cold Outreach', 'Event', 'Partner'],
57
+ },
58
+ {
59
+ name: 'lead.status',
60
+ type: 'choice',
61
+ label: 'Status',
62
+ category: 'sales',
63
+ description: 'Current lead status',
64
+ choices: ['New', 'Contacted', 'Qualified', 'Proposal', 'Negotiation', 'Closed Won', 'Closed Lost'],
65
+ },
66
+ {
67
+ name: 'lead.emailOpens',
68
+ type: 'number',
69
+ label: 'Email Opens',
70
+ category: 'engagement',
71
+ description: 'Number of email opens',
72
+ unit: 'opens',
73
+ },
74
+ {
75
+ name: 'lead.websiteVisits',
76
+ type: 'number',
77
+ label: 'Website Visits',
78
+ category: 'engagement',
79
+ description: 'Number of website visits',
80
+ unit: 'visits',
81
+ },
82
+ ];
83
+
84
+ export const sampleLeads = [
85
+ {
86
+ id: 'lead-001',
87
+ 'lead.name': 'Alice Johnson',
88
+ 'lead.company': 'TechCorp Inc',
89
+ 'lead.industry': 'Technology',
90
+ 'lead.companySize': '51-200',
91
+ 'lead.budget': 50000,
92
+ 'lead.score': 85,
93
+ 'lead.source': 'Website',
94
+ 'lead.status': 'Qualified',
95
+ 'lead.emailOpens': 12,
96
+ 'lead.websiteVisits': 8,
97
+ },
98
+ {
99
+ id: 'lead-002',
100
+ 'lead.name': 'Bob Martinez',
101
+ 'lead.company': 'HealthPlus',
102
+ 'lead.industry': 'Healthcare',
103
+ 'lead.companySize': '201-500',
104
+ 'lead.budget': 120000,
105
+ 'lead.score': 92,
106
+ 'lead.source': 'Referral',
107
+ 'lead.status': 'Proposal',
108
+ 'lead.emailOpens': 18,
109
+ 'lead.websiteVisits': 15,
110
+ },
111
+ {
112
+ id: 'lead-003',
113
+ 'lead.name': 'Carol Davis',
114
+ 'lead.company': 'FinServe Group',
115
+ 'lead.industry': 'Finance',
116
+ 'lead.companySize': '501-1000',
117
+ 'lead.budget': 200000,
118
+ 'lead.score': 78,
119
+ 'lead.source': 'Event',
120
+ 'lead.status': 'Contacted',
121
+ 'lead.emailOpens': 5,
122
+ 'lead.websiteVisits': 3,
123
+ },
124
+ {
125
+ id: 'lead-004',
126
+ 'lead.name': 'David Wilson',
127
+ 'lead.company': 'Retail Solutions',
128
+ 'lead.industry': 'Retail',
129
+ 'lead.companySize': '11-50',
130
+ 'lead.budget': 25000,
131
+ 'lead.score': 65,
132
+ 'lead.source': 'Cold Outreach',
133
+ 'lead.status': 'New',
134
+ 'lead.emailOpens': 2,
135
+ 'lead.websiteVisits': 1,
136
+ },
137
+ {
138
+ id: 'lead-005',
139
+ 'lead.name': 'Emma Thompson',
140
+ 'lead.company': 'EduTech Academy',
141
+ 'lead.industry': 'Education',
142
+ 'lead.companySize': '51-200',
143
+ 'lead.budget': 75000,
144
+ 'lead.score': 88,
145
+ 'lead.source': 'Social Media',
146
+ 'lead.status': 'Qualified',
147
+ 'lead.emailOpens': 14,
148
+ 'lead.websiteVisits': 11,
149
+ },
150
+ ];
151
+
152
+ export const leadFunnelExample = {
153
+ id: 'funnel-003',
154
+ name: 'High-Value Enterprise Leads',
155
+ description: 'Target qualified enterprise leads with strong engagement',
156
+ entityType: 'lead',
157
+ stages: [
158
+ {
159
+ id: 'stage-1',
160
+ name: 'Enterprise Size',
161
+ description: 'Companies with 200+ employees',
162
+ order: 0,
163
+ rules: [
164
+ {
165
+ field: 'lead.companySize',
166
+ operator: 'in',
167
+ value: ['201-500', '501-1000', '1000+'],
168
+ logicalOperator: 'AND',
169
+ },
170
+ ],
171
+ },
172
+ {
173
+ id: 'stage-2',
174
+ name: 'Significant Budget',
175
+ description: 'Budget over $100k',
176
+ order: 1,
177
+ rules: [
178
+ {
179
+ field: 'lead.budget',
180
+ operator: 'gte',
181
+ value: 100000,
182
+ logicalOperator: 'AND',
183
+ },
184
+ ],
185
+ },
186
+ {
187
+ id: 'stage-3',
188
+ name: 'High Score',
189
+ description: 'Lead score above 75',
190
+ order: 2,
191
+ rules: [
192
+ {
193
+ field: 'lead.score',
194
+ operator: 'gte',
195
+ value: 75,
196
+ logicalOperator: 'AND',
197
+ },
198
+ ],
199
+ },
200
+ {
201
+ id: 'stage-4',
202
+ name: 'Active Engagement',
203
+ description: 'Multiple email opens and website visits',
204
+ order: 3,
205
+ rules: [
206
+ {
207
+ field: 'lead.emailOpens',
208
+ operator: 'gte',
209
+ value: 5,
210
+ logicalOperator: 'AND',
211
+ },
212
+ {
213
+ field: 'lead.websiteVisits',
214
+ operator: 'gte',
215
+ value: 3,
216
+ logicalOperator: 'AND',
217
+ },
218
+ ],
219
+ },
220
+ ],
221
+ createdAt: new Date('2024-01-10'),
222
+ updatedAt: new Date('2024-02-08'),
223
+ };
@@ -0,0 +1,217 @@
1
+ import type { FieldDefinition } from '../../types';
2
+
3
+ export const recipeFields: FieldDefinition[] = [
4
+ {
5
+ name: 'recipe.name',
6
+ type: 'text',
7
+ label: 'Recipe Name',
8
+ category: 'basic',
9
+ description: 'Name of the recipe',
10
+ },
11
+ {
12
+ name: 'recipe.cuisine',
13
+ type: 'choice',
14
+ label: 'Cuisine',
15
+ category: 'classification',
16
+ description: 'Type of cuisine',
17
+ choices: ['Italian', 'Mexican', 'Chinese', 'Indian', 'Japanese', 'Mediterranean', 'American', 'French'],
18
+ },
19
+ {
20
+ name: 'recipe.difficulty',
21
+ type: 'choice',
22
+ label: 'Difficulty',
23
+ category: 'classification',
24
+ description: 'Recipe difficulty level',
25
+ choices: ['Easy', 'Medium', 'Hard'],
26
+ },
27
+ {
28
+ name: 'recipe.cookTimeMinutes',
29
+ type: 'number',
30
+ label: 'Cook Time',
31
+ category: 'cooking',
32
+ description: 'Total cooking time in minutes',
33
+ unit: 'minutes',
34
+ },
35
+ {
36
+ name: 'recipe.servings',
37
+ type: 'number',
38
+ label: 'Servings',
39
+ category: 'cooking',
40
+ description: 'Number of servings',
41
+ unit: 'servings',
42
+ },
43
+ {
44
+ name: 'recipe.calories',
45
+ type: 'number',
46
+ label: 'Calories',
47
+ category: 'nutrition',
48
+ description: 'Calories per serving',
49
+ unit: 'kcal',
50
+ },
51
+ {
52
+ name: 'recipe.dietary',
53
+ type: 'multi-choice',
54
+ label: 'Dietary Tags',
55
+ category: 'classification',
56
+ description: 'Dietary restrictions/preferences',
57
+ choices: ['Vegetarian', 'Vegan', 'Gluten-Free', 'Dairy-Free', 'Keto', 'Paleo', 'Low-Carb'],
58
+ },
59
+ {
60
+ name: 'recipe.rating',
61
+ type: 'number',
62
+ label: 'Rating',
63
+ category: 'metrics',
64
+ description: 'Average user rating (0-5)',
65
+ unit: 'stars',
66
+ },
67
+ {
68
+ name: 'recipe.viewCount',
69
+ type: 'number',
70
+ label: 'View Count',
71
+ category: 'metrics',
72
+ description: 'Total number of views',
73
+ unit: 'views',
74
+ },
75
+ {
76
+ name: 'recipe.bookmarked',
77
+ type: 'boolean',
78
+ label: 'Bookmarked',
79
+ category: 'engagement',
80
+ description: 'User has bookmarked this recipe',
81
+ },
82
+ ];
83
+
84
+ export const sampleRecipes = [
85
+ {
86
+ id: 'recipe-001',
87
+ 'recipe.name': 'Classic Margherita Pizza',
88
+ 'recipe.cuisine': 'Italian',
89
+ 'recipe.difficulty': 'Medium',
90
+ 'recipe.cookTimeMinutes': 45,
91
+ 'recipe.servings': 4,
92
+ 'recipe.calories': 280,
93
+ 'recipe.dietary': ['Vegetarian'],
94
+ 'recipe.rating': 4.8,
95
+ 'recipe.viewCount': 12450,
96
+ 'recipe.bookmarked': true,
97
+ },
98
+ {
99
+ id: 'recipe-002',
100
+ 'recipe.name': 'Spicy Thai Basil Chicken',
101
+ 'recipe.cuisine': 'Chinese',
102
+ 'recipe.difficulty': 'Easy',
103
+ 'recipe.cookTimeMinutes': 25,
104
+ 'recipe.servings': 2,
105
+ 'recipe.calories': 320,
106
+ 'recipe.dietary': ['Gluten-Free', 'Dairy-Free'],
107
+ 'recipe.rating': 4.6,
108
+ 'recipe.viewCount': 8920,
109
+ 'recipe.bookmarked': false,
110
+ },
111
+ {
112
+ id: 'recipe-003',
113
+ 'recipe.name': 'Vegan Buddha Bowl',
114
+ 'recipe.cuisine': 'Mediterranean',
115
+ 'recipe.difficulty': 'Easy',
116
+ 'recipe.cookTimeMinutes': 30,
117
+ 'recipe.servings': 2,
118
+ 'recipe.calories': 350,
119
+ 'recipe.dietary': ['Vegan', 'Gluten-Free', 'Dairy-Free'],
120
+ 'recipe.rating': 4.9,
121
+ 'recipe.viewCount': 15600,
122
+ 'recipe.bookmarked': true,
123
+ },
124
+ {
125
+ id: 'recipe-004',
126
+ 'recipe.name': 'Chicken Tikka Masala',
127
+ 'recipe.cuisine': 'Indian',
128
+ 'recipe.difficulty': 'Hard',
129
+ 'recipe.cookTimeMinutes': 90,
130
+ 'recipe.servings': 6,
131
+ 'recipe.calories': 420,
132
+ 'recipe.dietary': ['Gluten-Free'],
133
+ 'recipe.rating': 4.7,
134
+ 'recipe.viewCount': 11200,
135
+ 'recipe.bookmarked': false,
136
+ },
137
+ {
138
+ id: 'recipe-005',
139
+ 'recipe.name': 'Keto Avocado Salad',
140
+ 'recipe.cuisine': 'American',
141
+ 'recipe.difficulty': 'Easy',
142
+ 'recipe.cookTimeMinutes': 15,
143
+ 'recipe.servings': 2,
144
+ 'recipe.calories': 240,
145
+ 'recipe.dietary': ['Keto', 'Vegetarian', 'Gluten-Free', 'Low-Carb'],
146
+ 'recipe.rating': 4.5,
147
+ 'recipe.viewCount': 9340,
148
+ 'recipe.bookmarked': true,
149
+ },
150
+ ];
151
+
152
+ export const recipeFunnelExample = {
153
+ id: 'funnel-002',
154
+ name: 'Quick Healthy Meals',
155
+ description: 'Easy recipes under 30 minutes with high ratings',
156
+ entityType: 'recipe',
157
+ stages: [
158
+ {
159
+ id: 'stage-1',
160
+ name: 'Quick Cook Time',
161
+ description: 'Recipes that take 30 minutes or less',
162
+ order: 0,
163
+ rules: [
164
+ {
165
+ field: 'recipe.cookTimeMinutes',
166
+ operator: 'lte',
167
+ value: 30,
168
+ logicalOperator: 'AND',
169
+ },
170
+ ],
171
+ },
172
+ {
173
+ id: 'stage-2',
174
+ name: 'Easy Difficulty',
175
+ description: 'Easy to make',
176
+ order: 1,
177
+ rules: [
178
+ {
179
+ field: 'recipe.difficulty',
180
+ operator: 'eq',
181
+ value: 'Easy',
182
+ logicalOperator: 'AND',
183
+ },
184
+ ],
185
+ },
186
+ {
187
+ id: 'stage-3',
188
+ name: 'Healthy',
189
+ description: 'Low calorie count',
190
+ order: 2,
191
+ rules: [
192
+ {
193
+ field: 'recipe.calories',
194
+ operator: 'lte',
195
+ value: 350,
196
+ logicalOperator: 'AND',
197
+ },
198
+ ],
199
+ },
200
+ {
201
+ id: 'stage-4',
202
+ name: 'Highly Rated',
203
+ description: 'Rating 4.5 or higher',
204
+ order: 3,
205
+ rules: [
206
+ {
207
+ field: 'recipe.rating',
208
+ operator: 'gte',
209
+ value: 4.5,
210
+ logicalOperator: 'AND',
211
+ },
212
+ ],
213
+ },
214
+ ],
215
+ createdAt: new Date('2024-01-20'),
216
+ updatedAt: new Date('2024-02-05'),
217
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Vitest test setup
3
+ */
4
+
5
+ import '@testing-library/jest-dom';