@la-main-verte/shared-types 1.0.81 → 1.0.83
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 +1 -1
- package/src/home.api.d.ts +276 -258
- package/src/index.ts +2 -0
- package/src/plant.d.ts +189 -168
- package/src/plantSelection.d.ts +0 -1
- package/src/taxonFamily.d.ts +15 -0
package/package.json
CHANGED
package/src/home.api.d.ts
CHANGED
|
@@ -1,258 +1,276 @@
|
|
|
1
|
-
import type { PlantI } from './plant'
|
|
2
|
-
import type { SelectionI } from './selection'
|
|
3
|
-
import type { TaskI } from './task'
|
|
4
|
-
|
|
5
|
-
export namespace HOME {
|
|
6
|
-
export type HeroCardMode = 'featuredSelection' | 'featuredPlant'
|
|
7
|
-
|
|
8
|
-
export type SectionComponentType =
|
|
9
|
-
| 'Header'
|
|
10
|
-
| 'HeroCards'
|
|
11
|
-
| 'PlantCarousel'
|
|
12
|
-
| 'HeroCardsCarousel'
|
|
13
|
-
| 'WideCardsCarousel'
|
|
14
|
-
| 'Weather'
|
|
15
|
-
| 'AdviceCarousel'
|
|
16
|
-
| 'OnboardingCard'
|
|
17
|
-
| 'UpcomingTasks'
|
|
18
|
-
|
|
19
|
-
export type CarouselComponentType = Extract<
|
|
20
|
-
SectionComponentType,
|
|
21
|
-
'PlantCarousel' | 'HeroCardsCarousel' | 'WideCardsCarousel'
|
|
22
|
-
>
|
|
23
|
-
|
|
24
|
-
export interface WeatherDayI {
|
|
25
|
-
date: string
|
|
26
|
-
minTempC: number
|
|
27
|
-
maxTempC: number
|
|
28
|
-
iconUrl: string | null
|
|
29
|
-
condition?: string | null
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface WeatherSectionI {
|
|
33
|
-
componentType: 'Weather'
|
|
34
|
-
title: string
|
|
35
|
-
subtitle?: string
|
|
36
|
-
locationName: string
|
|
37
|
-
timezone: string
|
|
38
|
-
days: WeatherDayI[]
|
|
39
|
-
lastUpdatedAt: string
|
|
40
|
-
dataSource: 'weatherapi'
|
|
41
|
-
backgroundColor?: string
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface HeaderSectionI {
|
|
45
|
-
componentType: 'Header'
|
|
46
|
-
title: string
|
|
47
|
-
subtitle: string
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface AdviceI {
|
|
51
|
-
id?: string | number
|
|
52
|
-
title: string
|
|
53
|
-
markdownContent: string
|
|
54
|
-
titleColor?: string
|
|
55
|
-
backgroundColor?: string
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface AdviceSectionI {
|
|
59
|
-
componentType: 'AdviceCarousel'
|
|
60
|
-
title?: string
|
|
61
|
-
subtitle?: string
|
|
62
|
-
advices: AdviceI[]
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface WideCardAuthorI {
|
|
66
|
-
name?: string | null
|
|
67
|
-
imageURL?: string | null
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface WideCardItemI {
|
|
71
|
-
id?: string | number
|
|
72
|
-
title?: string | null
|
|
73
|
-
text: string
|
|
74
|
-
badgeText?: string | null
|
|
75
|
-
thumbnailImageURL: string
|
|
76
|
-
author?: WideCardAuthorI | null
|
|
77
|
-
link?: string | null
|
|
78
|
-
metadata?: Record<string, unknown>
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface WideCardsCarouselSectionI {
|
|
82
|
-
componentType: 'WideCardsCarousel'
|
|
83
|
-
title: string
|
|
84
|
-
subtitle?: string
|
|
85
|
-
cards: WideCardItemI[]
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export interface HeroCardBlueprintI {
|
|
89
|
-
mode: HeroCardMode
|
|
90
|
-
title?: string | null
|
|
91
|
-
description?: string | null
|
|
92
|
-
backgroundColor?: string | null
|
|
93
|
-
backgroundImageUrl?: string | null
|
|
94
|
-
ctaLabel?: string | null
|
|
95
|
-
ctaRoute?: string | null
|
|
96
|
-
previewPlants?: PlantI[]
|
|
97
|
-
selection?: SelectionI | null
|
|
98
|
-
plant?: PlantI | null
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export interface HeroCardsSectionI {
|
|
102
|
-
componentType: 'HeroCards'
|
|
103
|
-
title?: string | null
|
|
104
|
-
subtitle?: string | null
|
|
105
|
-
cards: HeroCardBlueprintI[]
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface PlantCarouselSectionI {
|
|
109
|
-
componentType: 'PlantCarousel'
|
|
110
|
-
title: string
|
|
111
|
-
subtitle?: string
|
|
112
|
-
selection: SelectionI
|
|
113
|
-
displayRanking?: boolean
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export interface HeroCardsCarouselSectionI {
|
|
117
|
-
componentType: 'HeroCardsCarousel'
|
|
118
|
-
selections: SelectionI[]
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export interface FamilyRecommendationI {
|
|
122
|
-
family: string
|
|
123
|
-
headline: string
|
|
124
|
-
plants: PlantI[]
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface FamilyExplorerSectionI {
|
|
128
|
-
componentType: 'FamilyExplorer'
|
|
129
|
-
title: string
|
|
130
|
-
subtitle?: string
|
|
131
|
-
families: FamilyRecommendationI[]
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export interface OnboardingStepI {
|
|
135
|
-
id: string
|
|
136
|
-
title: string
|
|
137
|
-
description: string
|
|
138
|
-
isCompleted: boolean
|
|
139
|
-
ctaLink: string
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export interface OnboardingCardSectionI {
|
|
143
|
-
componentType: 'OnboardingCard'
|
|
144
|
-
title: string
|
|
145
|
-
subtitle: string
|
|
146
|
-
steps: OnboardingStepI[]
|
|
147
|
-
completedStepsCount: number
|
|
148
|
-
totalStepsCount: number
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** Minimal plant info for preview display (e.g. parent plant in grouped tasks) */
|
|
152
|
-
export interface TaskPlantPreviewI {
|
|
153
|
-
name: string
|
|
154
|
-
slug: string
|
|
155
|
-
imageURL?: string | null
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/** Plant info within a family group — includes the task ID specific to this plant */
|
|
159
|
-
export interface TaskFamilyPlantPreviewI extends TaskPlantPreviewI {
|
|
160
|
-
taskId: number
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** Family group info when multiple plants share the same task */
|
|
164
|
-
export interface TaskFamilyGroupI {
|
|
165
|
-
familyName: string
|
|
166
|
-
plantsCount: number
|
|
167
|
-
plants: TaskFamilyPlantPreviewI[]
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export interface UpcomingTaskI {
|
|
171
|
-
task: TaskI
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
export
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
1
|
+
import type { PlantI } from './plant'
|
|
2
|
+
import type { SelectionI } from './selection'
|
|
3
|
+
import type { TaskI } from './task'
|
|
4
|
+
|
|
5
|
+
export namespace HOME {
|
|
6
|
+
export type HeroCardMode = 'featuredSelection' | 'featuredPlant'
|
|
7
|
+
|
|
8
|
+
export type SectionComponentType =
|
|
9
|
+
| 'Header'
|
|
10
|
+
| 'HeroCards'
|
|
11
|
+
| 'PlantCarousel'
|
|
12
|
+
| 'HeroCardsCarousel'
|
|
13
|
+
| 'WideCardsCarousel'
|
|
14
|
+
| 'Weather'
|
|
15
|
+
| 'AdviceCarousel'
|
|
16
|
+
| 'OnboardingCard'
|
|
17
|
+
| 'UpcomingTasks'
|
|
18
|
+
|
|
19
|
+
export type CarouselComponentType = Extract<
|
|
20
|
+
SectionComponentType,
|
|
21
|
+
'PlantCarousel' | 'HeroCardsCarousel' | 'WideCardsCarousel'
|
|
22
|
+
>
|
|
23
|
+
|
|
24
|
+
export interface WeatherDayI {
|
|
25
|
+
date: string
|
|
26
|
+
minTempC: number
|
|
27
|
+
maxTempC: number
|
|
28
|
+
iconUrl: string | null
|
|
29
|
+
condition?: string | null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface WeatherSectionI {
|
|
33
|
+
componentType: 'Weather'
|
|
34
|
+
title: string
|
|
35
|
+
subtitle?: string
|
|
36
|
+
locationName: string
|
|
37
|
+
timezone: string
|
|
38
|
+
days: WeatherDayI[]
|
|
39
|
+
lastUpdatedAt: string
|
|
40
|
+
dataSource: 'weatherapi'
|
|
41
|
+
backgroundColor?: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface HeaderSectionI {
|
|
45
|
+
componentType: 'Header'
|
|
46
|
+
title: string
|
|
47
|
+
subtitle: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface AdviceI {
|
|
51
|
+
id?: string | number
|
|
52
|
+
title: string
|
|
53
|
+
markdownContent: string
|
|
54
|
+
titleColor?: string
|
|
55
|
+
backgroundColor?: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface AdviceSectionI {
|
|
59
|
+
componentType: 'AdviceCarousel'
|
|
60
|
+
title?: string
|
|
61
|
+
subtitle?: string
|
|
62
|
+
advices: AdviceI[]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface WideCardAuthorI {
|
|
66
|
+
name?: string | null
|
|
67
|
+
imageURL?: string | null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface WideCardItemI {
|
|
71
|
+
id?: string | number
|
|
72
|
+
title?: string | null
|
|
73
|
+
text: string
|
|
74
|
+
badgeText?: string | null
|
|
75
|
+
thumbnailImageURL: string
|
|
76
|
+
author?: WideCardAuthorI | null
|
|
77
|
+
link?: string | null
|
|
78
|
+
metadata?: Record<string, unknown>
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface WideCardsCarouselSectionI {
|
|
82
|
+
componentType: 'WideCardsCarousel'
|
|
83
|
+
title: string
|
|
84
|
+
subtitle?: string
|
|
85
|
+
cards: WideCardItemI[]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface HeroCardBlueprintI {
|
|
89
|
+
mode: HeroCardMode
|
|
90
|
+
title?: string | null
|
|
91
|
+
description?: string | null
|
|
92
|
+
backgroundColor?: string | null
|
|
93
|
+
backgroundImageUrl?: string | null
|
|
94
|
+
ctaLabel?: string | null
|
|
95
|
+
ctaRoute?: string | null
|
|
96
|
+
previewPlants?: PlantI[]
|
|
97
|
+
selection?: SelectionI | null
|
|
98
|
+
plant?: PlantI | null
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface HeroCardsSectionI {
|
|
102
|
+
componentType: 'HeroCards'
|
|
103
|
+
title?: string | null
|
|
104
|
+
subtitle?: string | null
|
|
105
|
+
cards: HeroCardBlueprintI[]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface PlantCarouselSectionI {
|
|
109
|
+
componentType: 'PlantCarousel'
|
|
110
|
+
title: string
|
|
111
|
+
subtitle?: string
|
|
112
|
+
selection: SelectionI
|
|
113
|
+
displayRanking?: boolean
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface HeroCardsCarouselSectionI {
|
|
117
|
+
componentType: 'HeroCardsCarousel'
|
|
118
|
+
selections: SelectionI[]
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface FamilyRecommendationI {
|
|
122
|
+
family: string
|
|
123
|
+
headline: string
|
|
124
|
+
plants: PlantI[]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface FamilyExplorerSectionI {
|
|
128
|
+
componentType: 'FamilyExplorer'
|
|
129
|
+
title: string
|
|
130
|
+
subtitle?: string
|
|
131
|
+
families: FamilyRecommendationI[]
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface OnboardingStepI {
|
|
135
|
+
id: string
|
|
136
|
+
title: string
|
|
137
|
+
description: string
|
|
138
|
+
isCompleted: boolean
|
|
139
|
+
ctaLink: string
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface OnboardingCardSectionI {
|
|
143
|
+
componentType: 'OnboardingCard'
|
|
144
|
+
title: string
|
|
145
|
+
subtitle: string
|
|
146
|
+
steps: OnboardingStepI[]
|
|
147
|
+
completedStepsCount: number
|
|
148
|
+
totalStepsCount: number
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Minimal plant info for preview display (e.g. parent plant in grouped tasks) */
|
|
152
|
+
export interface TaskPlantPreviewI {
|
|
153
|
+
name: string
|
|
154
|
+
slug: string
|
|
155
|
+
imageURL?: string | null
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Plant info within a family group — includes the task ID specific to this plant */
|
|
159
|
+
export interface TaskFamilyPlantPreviewI extends TaskPlantPreviewI {
|
|
160
|
+
taskId: number
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Family group info when multiple plants share the same task */
|
|
164
|
+
export interface TaskFamilyGroupI {
|
|
165
|
+
familyName: string
|
|
166
|
+
plantsCount: number
|
|
167
|
+
plants: TaskFamilyPlantPreviewI[]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface UpcomingTaskI {
|
|
171
|
+
task: TaskI
|
|
172
|
+
/** PlantSelection id used by task list views to group tasks per planted item. */
|
|
173
|
+
plantSelectionId?: number
|
|
174
|
+
plantName: string
|
|
175
|
+
plantSlug: string
|
|
176
|
+
plantImageURL?: string | null
|
|
177
|
+
gardenName: string
|
|
178
|
+
gardenCategory: string
|
|
179
|
+
selectionSlug: string
|
|
180
|
+
/** If this task is grouped by family */
|
|
181
|
+
familyGroup?: TaskFamilyGroupI
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export type TaskListView = 'current' | 'completed' | 'earlier'
|
|
185
|
+
|
|
186
|
+
export interface TaskListTabI {
|
|
187
|
+
key: TaskListView
|
|
188
|
+
label: string
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export interface TaskListResponseI {
|
|
192
|
+
view: TaskListView
|
|
193
|
+
title: string
|
|
194
|
+
subtitle: string
|
|
195
|
+
emptyListMessage: string
|
|
196
|
+
tabs: TaskListTabI[]
|
|
197
|
+
tasks: UpcomingTaskI[]
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface UpcomingTaskAdviceI {
|
|
201
|
+
/** @deprecated Since 1.9.10, this field is always `''`. */
|
|
202
|
+
content: string
|
|
203
|
+
taskName: string
|
|
204
|
+
plantName: string
|
|
205
|
+
plantSlug: string
|
|
206
|
+
plantImageURL?: string | null
|
|
207
|
+
gardenName: string
|
|
208
|
+
gardenCategory: string
|
|
209
|
+
selectionSlug: string
|
|
210
|
+
task: TaskI
|
|
211
|
+
/** If this task is grouped by family */
|
|
212
|
+
familyGroup?: TaskFamilyGroupI
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export interface UpcomingTasksSectionI {
|
|
216
|
+
componentType: 'UpcomingTasks'
|
|
217
|
+
title: string
|
|
218
|
+
subtitle?: string
|
|
219
|
+
advices: UpcomingTaskAdviceI[]
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Preview plant for WhenToSeedWhat section */
|
|
223
|
+
export interface WhenToSeedWhatPlantPreviewI {
|
|
224
|
+
id: number
|
|
225
|
+
name: string
|
|
226
|
+
family?: string | null
|
|
227
|
+
slug: string
|
|
228
|
+
imageURL?: string | null
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** A generic link card section with title, subtitle, URL, and optional preview images */
|
|
232
|
+
export interface LinkCardSectionI {
|
|
233
|
+
componentType: 'LinkCard'
|
|
234
|
+
title: string
|
|
235
|
+
subtitle?: string
|
|
236
|
+
url: string
|
|
237
|
+
previewPlants?: WhenToSeedWhatPlantPreviewI[]
|
|
238
|
+
backgroundColor?: string
|
|
239
|
+
/** Show a red badge indicator (replaces the plant preview stack when true) */
|
|
240
|
+
showBadge?: boolean
|
|
241
|
+
/** Optional badge count to display */
|
|
242
|
+
badgeCount?: number
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export type SectionI =
|
|
246
|
+
| HeaderSectionI
|
|
247
|
+
| HeroCardsSectionI
|
|
248
|
+
| PlantCarouselSectionI
|
|
249
|
+
| HeroCardsCarouselSectionI
|
|
250
|
+
| WideCardsCarouselSectionI
|
|
251
|
+
| WeatherSectionI
|
|
252
|
+
| AdviceSectionI
|
|
253
|
+
| OnboardingCardSectionI
|
|
254
|
+
| UpcomingTasksSectionI
|
|
255
|
+
| LinkCardSectionI
|
|
256
|
+
|
|
257
|
+
export interface Response {
|
|
258
|
+
sections: SectionI[]
|
|
259
|
+
weather?: WeatherSectionI
|
|
260
|
+
advice?: AdviceSectionI
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export interface HeroCardItemI {
|
|
264
|
+
id?: string | null
|
|
265
|
+
mode: HeroCardMode
|
|
266
|
+
title?: string | null
|
|
267
|
+
description?: string | null
|
|
268
|
+
backgroundColor?: string | null
|
|
269
|
+
backgroundImageUrl?: string | null
|
|
270
|
+
previewPlants?: PlantI[]
|
|
271
|
+
ctaLabel?: string | null
|
|
272
|
+
selection?: SelectionI | null
|
|
273
|
+
plant?: PlantI | null
|
|
274
|
+
ctaRoute?: string | null
|
|
275
|
+
}
|
|
276
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,8 @@ export * from './taggedItem'
|
|
|
14
14
|
export * from './fertilizer'
|
|
15
15
|
export * from './utmParams'
|
|
16
16
|
export * from './plantFilters'
|
|
17
|
+
export * from './taxonFamily'
|
|
18
|
+
export * from './rotationGroup'
|
|
17
19
|
import * as PlantsAPI from './plants.api'
|
|
18
20
|
import * as UsersAPI from './users.api'
|
|
19
21
|
import * as SessionsAPI from './sessions.api'
|
package/src/plant.d.ts
CHANGED
|
@@ -1,168 +1,189 @@
|
|
|
1
|
-
import type { TaxonFamilyI } from './taxonFamily'
|
|
2
|
-
import type { SeedingInfoI } from './pages.api'
|
|
3
|
-
import type { PlantFilterI } from './plantFilters'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
*
|
|
65
|
-
* -
|
|
66
|
-
* -
|
|
67
|
-
* -
|
|
68
|
-
*
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
1
|
+
import type { TaxonFamilyI } from './taxonFamily'
|
|
2
|
+
import type { SeedingInfoI } from './pages.api'
|
|
3
|
+
import type { PlantFilterI } from './plantFilters'
|
|
4
|
+
import type { RotationGroup } from './rotationGroup'
|
|
5
|
+
/**
|
|
6
|
+
* Range filter value for min/max filters
|
|
7
|
+
*/
|
|
8
|
+
export interface RangeFilterValueI {
|
|
9
|
+
min: number
|
|
10
|
+
max: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Plant filter value types
|
|
15
|
+
* Represents the possible values for a single filter
|
|
16
|
+
*/
|
|
17
|
+
export type PlantFilterValueI = string | string[] | number | boolean | RangeFilterValueI
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Plant attributes for filtering
|
|
21
|
+
* Used in JSONB field and as query parameters
|
|
22
|
+
* Supports multiple value types for different filter types
|
|
23
|
+
*/
|
|
24
|
+
export type PlantAttributesI = Record<string, PlantFilterValueI>
|
|
25
|
+
|
|
26
|
+
export interface PlantI {
|
|
27
|
+
id: number
|
|
28
|
+
name: string
|
|
29
|
+
slug: string
|
|
30
|
+
description: string
|
|
31
|
+
descriptionSource?: string
|
|
32
|
+
female: boolean
|
|
33
|
+
family?: string | null
|
|
34
|
+
taxonFamilyId?: number | null
|
|
35
|
+
spaceBetweenSeedMin: number
|
|
36
|
+
spaceBetweenSeedMax: number
|
|
37
|
+
spaceBetweenAlleyMin: number
|
|
38
|
+
spaceBetweenAlleyMax: number
|
|
39
|
+
weeksInTransplant: number
|
|
40
|
+
weeksDuringWhichYouCanSeedOutdoor: number
|
|
41
|
+
weeksToMaturity: number
|
|
42
|
+
daysToMaturity: number | null
|
|
43
|
+
weeksToWaitAfterFreezingDate: number
|
|
44
|
+
weeksToHarvest: number
|
|
45
|
+
indoorSeeding: boolean
|
|
46
|
+
outdoorSeeding: boolean
|
|
47
|
+
azoteNeedsKgPerHa: number
|
|
48
|
+
hibernate: boolean
|
|
49
|
+
germinationTemperature: number | null
|
|
50
|
+
minGerminationTemperature: number | null
|
|
51
|
+
germinationNumberOfDays: string | null
|
|
52
|
+
germinationSeedDepth: string | null
|
|
53
|
+
cultivationInfo: string | null
|
|
54
|
+
parentId: number | null
|
|
55
|
+
memberId?: number
|
|
56
|
+
memberFirstName?: string | null
|
|
57
|
+
shared: boolean
|
|
58
|
+
hexColor: string | null
|
|
59
|
+
sunRequirements: 'partialShade' | 'fullSun' | 'fullShade' | null
|
|
60
|
+
isHardy: boolean | null
|
|
61
|
+
quantityForFiveInJardinVivrier?: number | null
|
|
62
|
+
imageURL: string
|
|
63
|
+
/**
|
|
64
|
+
* Filename of the plant's 3D mesh asset stored on S3.
|
|
65
|
+
* - Ideally a `.webp` file (e.g. `ail.webp`).
|
|
66
|
+
* - Stored in S3 under the `images/meshes/` folder.
|
|
67
|
+
* - By default named after the `Plant.slug` (e.g. `ail.webp` for the garlic plant).
|
|
68
|
+
* - Only the filename is persisted; the public URL is exposed through the
|
|
69
|
+
* virtual `meshURL` field.
|
|
70
|
+
*/
|
|
71
|
+
meshFilename: string | null
|
|
72
|
+
/**
|
|
73
|
+
* Public ImageKit URL to the plant's 3D mesh asset.
|
|
74
|
+
* Virtual field computed from `meshFilename`. The underlying file is
|
|
75
|
+
* stored on S3 at `images/meshes/{meshFilename}` and rewritten to
|
|
76
|
+
* ImageKit for CDN delivery and transformations.
|
|
77
|
+
*
|
|
78
|
+
* Falls back to `imageURL` when `meshFilename` is not set.
|
|
79
|
+
*
|
|
80
|
+
* Example: `https://ik.imagekit.io/lamainverte/meshes/ail.webp`
|
|
81
|
+
*/
|
|
82
|
+
meshURL: string
|
|
83
|
+
totalWeeksToMaturity: number
|
|
84
|
+
hasNoInformation: boolean
|
|
85
|
+
createdAt: Date
|
|
86
|
+
updatedAt: Date
|
|
87
|
+
translatedSunRequirements: 'Plein soleil' | 'Mi-ombre' | 'Ombre' | null
|
|
88
|
+
parent?: PlantI
|
|
89
|
+
children?: PlantI[]
|
|
90
|
+
PlantInventories?: PlantInventoryI[]
|
|
91
|
+
taggedItems?: TaggedItemI[]
|
|
92
|
+
/**
|
|
93
|
+
* List of selections that the plant is in.
|
|
94
|
+
* --------------------------------------
|
|
95
|
+
* Tends to be used for featured selections
|
|
96
|
+
*/
|
|
97
|
+
Selections?: SelectionI[]
|
|
98
|
+
tasks?: TaskI[]
|
|
99
|
+
Images?: ImageI[]
|
|
100
|
+
Member?: Partial<MemberI>
|
|
101
|
+
notes?: NoteI[]
|
|
102
|
+
/**
|
|
103
|
+
* Nitrogen-derived rotation group enum (virtual field on the Plant model).
|
|
104
|
+
* Source of truth for rotation classification — derived from
|
|
105
|
+
* `azoteNeedsKgPerHa` plus the regenerative override on `taxonFamily`.
|
|
106
|
+
*/
|
|
107
|
+
rotationGroup?: RotationGroup | null
|
|
108
|
+
/**
|
|
109
|
+
* French label of `rotationGroup`, ready for display.
|
|
110
|
+
*/
|
|
111
|
+
translatedRotationGroup?: string | null
|
|
112
|
+
taxonFamily?: TaxonFamilyI
|
|
113
|
+
seedingInfo: SeedingInfoI
|
|
114
|
+
/**
|
|
115
|
+
* Contextual search text for recommended plants
|
|
116
|
+
* Provides additional context when suggesting plants for specific garden zones
|
|
117
|
+
*/
|
|
118
|
+
contextualSearchText?: string
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
interface PlantInventoryI {
|
|
122
|
+
id: number
|
|
123
|
+
plantId: number
|
|
124
|
+
supplierName: string
|
|
125
|
+
plantName: string
|
|
126
|
+
supplierURL: string
|
|
127
|
+
imageLocation: string
|
|
128
|
+
description: string
|
|
129
|
+
inStock: boolean
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export type AvailableGrowingConditionsI = Record<string, string[]>
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* For each attribute filter key (e.g. "fruit.color"), the list of values that
|
|
136
|
+
* still yield at least one match under the current search + active filters.
|
|
137
|
+
* Consumed by the frontend to mark filter tags as "unavailable".
|
|
138
|
+
*/
|
|
139
|
+
export type AvailableAttributesI = Record<string, string[]>
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Which filter surface the frontend should render for the current search.
|
|
143
|
+
* - `specific`: family-specific filters (e.g. tomate attributes)
|
|
144
|
+
* - `general`: global growing-conditions filters
|
|
145
|
+
*
|
|
146
|
+
* Mutually exclusive by design — the two sets never appear together.
|
|
147
|
+
*/
|
|
148
|
+
export type PlantFiltersModeI = 'specific' | 'general'
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Backend-driven description of the filter UI for a given search response.
|
|
152
|
+
* The frontend is a dumb renderer: it shows the filters listed here with the
|
|
153
|
+
* given mode and marks tags whose value is not in `availability` as unavailable.
|
|
154
|
+
*/
|
|
155
|
+
export interface PlantFiltersUII {
|
|
156
|
+
mode: PlantFiltersModeI
|
|
157
|
+
filters: PlantFilterI[]
|
|
158
|
+
availability: Record<string, string[]>
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export interface GrowingConditionsConfigI {
|
|
162
|
+
filters: PlantFilterI[]
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface GrowingConditionsFiltersI {
|
|
166
|
+
sunRequirements?: 'partialShade' | 'fullShade'
|
|
167
|
+
rotationGroup?: 'regenerative' | 'demanding' | 'moderately_demanding' | 'less_demanding'
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface PlantSearchResultI {
|
|
171
|
+
plants: PlantModelI[]
|
|
172
|
+
selections: SelectionModelI[]
|
|
173
|
+
total?: number
|
|
174
|
+
familyName?: string
|
|
175
|
+
filtersUI?: PlantFiltersUII
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Response shape for `GET /selections/:slug/gardenZones/:id/rotation-suggestions`.
|
|
180
|
+
* - `advice`: short user-facing sentence explaining the recommendation
|
|
181
|
+
* - `Plants`: parent plants matching the recommended rotation group, with
|
|
182
|
+
* the avoided taxon families excluded. Empty when the zone has no usable
|
|
183
|
+
* history yet.
|
|
184
|
+
*/
|
|
185
|
+
export interface PlantRotationSuggestionsI {
|
|
186
|
+
targetYear: number
|
|
187
|
+
advice: string
|
|
188
|
+
Plants: PlantI[]
|
|
189
|
+
}
|
package/src/plantSelection.d.ts
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { RotationGroup } from './rotationGroup'
|
|
2
|
+
|
|
3
|
+
export interface TaxonFamilyI {
|
|
4
|
+
id: number
|
|
5
|
+
slug: string
|
|
6
|
+
translation_key: string
|
|
7
|
+
name: string
|
|
8
|
+
latin_name: string | null
|
|
9
|
+
kingdom: string
|
|
10
|
+
description: string | null
|
|
11
|
+
rotation_group: RotationGroup | null
|
|
12
|
+
translated_rotation_group: string | null
|
|
13
|
+
createdAt?: Date
|
|
14
|
+
updatedAt?: Date
|
|
15
|
+
}
|