@la-main-verte/shared-types 1.0.72 → 1.0.74

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.72",
3
+ "version": "1.0.74",
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",
@@ -1,7 +1,7 @@
1
- import type { HOME } from './home.api'
2
-
3
- export namespace GARDEN_ZONE_BLUEPRINT {
4
- export interface Response {
5
- sections: HOME.SectionI[]
6
- }
7
- }
1
+ import type { HOME } from './home.api'
2
+
3
+ export namespace GARDEN_ZONE_BLUEPRINT {
4
+ export interface Response {
5
+ sections: HOME.SectionI[]
6
+ }
7
+ }
package/src/home.api.d.ts CHANGED
@@ -1,252 +1,257 @@
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 in grouped tasks */
152
- export interface TaskPlantPreviewI {
153
- name: string
154
- slug: string
155
- imageURL?: string | null
156
- }
157
-
158
- /** Family group info when multiple plants share the same task */
159
- export interface TaskFamilyGroupI {
160
- familyName: string
161
- plantsCount: number
162
- plants: TaskPlantPreviewI[]
163
- }
164
-
165
- export interface UpcomingTaskI {
166
- task: TaskI
167
- plantName: string
168
- plantSlug: string
169
- plantImageURL?: string | null
170
- gardenName: string
171
- gardenCategory: string
172
- selectionSlug: string
173
- /** If this task is grouped by family */
174
- familyGroup?: TaskFamilyGroupI
175
- }
176
-
177
- export interface UpcomingTaskAdviceI {
178
- content: string
179
- taskName: string
180
- plantName: string
181
- plantSlug: string
182
- plantImageURL?: string | null
183
- gardenName: string
184
- gardenCategory: string
185
- selectionSlug: string
186
- task: TaskI
187
- /** If this task is grouped by family */
188
- familyGroup?: TaskFamilyGroupI
189
- }
190
-
191
- export interface UpcomingTasksSectionI {
192
- componentType: 'UpcomingTasks'
193
- title: string
194
- subtitle?: string
195
- advices: UpcomingTaskAdviceI[]
196
- }
197
-
198
- /** Preview plant for WhenToSeedWhat section */
199
- export interface WhenToSeedWhatPlantPreviewI {
200
- id: number
201
- name: string
202
- family?: string | null
203
- slug: string
204
- imageURL?: string | null
205
- }
206
-
207
- /** A generic link card section with title, subtitle, URL, and optional preview images */
208
- export interface LinkCardSectionI {
209
- componentType: 'LinkCard'
210
- title: string
211
- subtitle?: string
212
- url: string
213
- previewPlants?: WhenToSeedWhatPlantPreviewI[]
214
- backgroundColor?: string
215
- /** Show a red badge indicator (replaces the plant preview stack when true) */
216
- showBadge?: boolean
217
- /** Optional badge count to display */
218
- badgeCount?: number
219
- }
220
-
221
- export type SectionI =
222
- | HeaderSectionI
223
- | HeroCardsSectionI
224
- | PlantCarouselSectionI
225
- | HeroCardsCarouselSectionI
226
- | WideCardsCarouselSectionI
227
- | WeatherSectionI
228
- | AdviceSectionI
229
- | OnboardingCardSectionI
230
- | UpcomingTasksSectionI
231
- | LinkCardSectionI
232
-
233
- export interface Response {
234
- sections: SectionI[]
235
- weather?: WeatherSectionI
236
- advice?: AdviceSectionI
237
- }
238
-
239
- export interface HeroCardItemI {
240
- id?: string | null
241
- mode: HeroCardMode
242
- title?: string | null
243
- description?: string | null
244
- backgroundColor?: string | null
245
- backgroundImageUrl?: string | null
246
- previewPlants?: PlantI[]
247
- ctaLabel?: string | null
248
- selection?: SelectionI | null
249
- plant?: PlantI | null
250
- ctaRoute?: string | null
251
- }
252
- }
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
+ plantName: string
173
+ plantSlug: string
174
+ plantImageURL?: string | null
175
+ gardenName: string
176
+ gardenCategory: string
177
+ selectionSlug: string
178
+ /** If this task is grouped by family */
179
+ familyGroup?: TaskFamilyGroupI
180
+ }
181
+
182
+ export interface UpcomingTaskAdviceI {
183
+ content: string
184
+ taskName: string
185
+ plantName: string
186
+ plantSlug: string
187
+ plantImageURL?: string | null
188
+ gardenName: string
189
+ gardenCategory: string
190
+ selectionSlug: string
191
+ task: TaskI
192
+ /** If this task is grouped by family */
193
+ familyGroup?: TaskFamilyGroupI
194
+ }
195
+
196
+ export interface UpcomingTasksSectionI {
197
+ componentType: 'UpcomingTasks'
198
+ title: string
199
+ subtitle?: string
200
+ advices: UpcomingTaskAdviceI[]
201
+ }
202
+
203
+ /** Preview plant for WhenToSeedWhat section */
204
+ export interface WhenToSeedWhatPlantPreviewI {
205
+ id: number
206
+ name: string
207
+ family?: string | null
208
+ slug: string
209
+ imageURL?: string | null
210
+ }
211
+
212
+ /** A generic link card section with title, subtitle, URL, and optional preview images */
213
+ export interface LinkCardSectionI {
214
+ componentType: 'LinkCard'
215
+ title: string
216
+ subtitle?: string
217
+ url: string
218
+ previewPlants?: WhenToSeedWhatPlantPreviewI[]
219
+ backgroundColor?: string
220
+ /** Show a red badge indicator (replaces the plant preview stack when true) */
221
+ showBadge?: boolean
222
+ /** Optional badge count to display */
223
+ badgeCount?: number
224
+ }
225
+
226
+ export type SectionI =
227
+ | HeaderSectionI
228
+ | HeroCardsSectionI
229
+ | PlantCarouselSectionI
230
+ | HeroCardsCarouselSectionI
231
+ | WideCardsCarouselSectionI
232
+ | WeatherSectionI
233
+ | AdviceSectionI
234
+ | OnboardingCardSectionI
235
+ | UpcomingTasksSectionI
236
+ | LinkCardSectionI
237
+
238
+ export interface Response {
239
+ sections: SectionI[]
240
+ weather?: WeatherSectionI
241
+ advice?: AdviceSectionI
242
+ }
243
+
244
+ export interface HeroCardItemI {
245
+ id?: string | null
246
+ mode: HeroCardMode
247
+ title?: string | null
248
+ description?: string | null
249
+ backgroundColor?: string | null
250
+ backgroundImageUrl?: string | null
251
+ previewPlants?: PlantI[]
252
+ ctaLabel?: string | null
253
+ selection?: SelectionI | null
254
+ plant?: PlantI | null
255
+ ctaRoute?: string | null
256
+ }
257
+ }
package/src/member.d.ts CHANGED
@@ -1,72 +1,72 @@
1
- import type { NoteI } from './note'
2
- import type { SelectionI } from './selection'
3
-
4
- export interface MemberI {
5
- id: number
6
- email: string
7
- firstName: string
8
- lastName: string
9
- /** Virtual field to get the user's full name */
10
- fullName?: string | null
11
- city?: string
12
- hardinessZoneName?: string
13
- createdAt: Date
14
- updatedAt: Date
15
- lastFreezingDate?: Date
16
- firstFreezingDate?: Date
17
- /**
18
- * Number of unread Crisp messages
19
- */
20
- unreadMessagesCount?: number
21
- notes?: NoteI[]
22
- selections?: SelectionI[]
23
- userActivities?: UserActivityI[]
24
- /**
25
- * hasAnActiveSubscription is a VIRTUAL FIELD used to check if the user has an active subscription
26
- */
27
- hasAnActiveSubscription?: boolean
28
- /**
29
- * Acts as a one-way not identifiable token.
30
- * Crisp uses this token to identify the user conversation
31
- */
32
- userToken: string
33
- /**
34
- * HMAC signature used by Crisp identity verification.
35
- * Signed on the backend from the user email.
36
- */
37
- crispUserEmailSignature?: string
38
- /**
39
- * neverAddedATask <=> Has the use ever open the task form?
40
- * Yes it is misleading, ticket is open to change it.
41
- * It was too intense to force the user to add a task.
42
- */
43
- neverAddedATask?: boolean
44
- neverAddedAPlant?: boolean
45
- neverAddedANote?: boolean
46
- neverTriedSpacingSection?: boolean
47
- neverTriedAiAgent?: boolean
48
- neverDeletedAPlant?: boolean
49
- neverDeletedATask?: boolean
50
- neverEditedATask?: boolean
51
- finishedOnboarding: boolean
52
- hasDownloadedNativeApp?: boolean
53
- unitSystem: 'imperial' | 'metric'
54
- gardenZoneTimelessPreference?: boolean
55
- subscriptionEndDate?: Date
56
- /**
57
- * Last fertilizer ID chosen by the user.
58
- * Used as the default fertilizer for new garden zones.
59
- */
60
- lastFertilizerIdChosen?: number
61
- /**
62
- * Virtual field to get the app badge count
63
- * ----------------------------------------
64
- * For now, it's just the number of unread messages.
65
- */
66
- badgeCount?: number
67
- /**
68
- * Number of unread alerts, cached version of unread alerts (the table) count
69
- */
70
- unreadAlertsCount?: number
71
- isAdmin: boolean
72
- }
1
+ import type { NoteI } from './note'
2
+ import type { SelectionI } from './selection'
3
+
4
+ export interface MemberI {
5
+ id: number
6
+ email: string
7
+ firstName: string
8
+ lastName: string
9
+ /** Virtual field to get the user's full name */
10
+ fullName?: string | null
11
+ city?: string
12
+ hardinessZoneName?: string
13
+ createdAt: Date
14
+ updatedAt: Date
15
+ lastFreezingDate?: Date
16
+ firstFreezingDate?: Date
17
+ /**
18
+ * Number of unread Crisp messages
19
+ */
20
+ unreadMessagesCount?: number
21
+ notes?: NoteI[]
22
+ selections?: SelectionI[]
23
+ userActivities?: UserActivityI[]
24
+ /**
25
+ * hasAnActiveSubscription is a VIRTUAL FIELD used to check if the user has an active subscription
26
+ */
27
+ hasAnActiveSubscription?: boolean
28
+ /**
29
+ * Acts as a one-way not identifiable token.
30
+ * Crisp uses this token to identify the user conversation
31
+ */
32
+ userToken: string
33
+ /**
34
+ * HMAC signature used by Crisp identity verification.
35
+ * Signed on the backend from the user email.
36
+ */
37
+ crispUserEmailSignature?: string
38
+ /**
39
+ * neverAddedATask <=> Has the use ever open the task form?
40
+ * Yes it is misleading, ticket is open to change it.
41
+ * It was too intense to force the user to add a task.
42
+ */
43
+ neverAddedATask?: boolean
44
+ neverAddedAPlant?: boolean
45
+ neverAddedANote?: boolean
46
+ neverTriedSpacingSection?: boolean
47
+ neverTriedAiAgent?: boolean
48
+ neverDeletedAPlant?: boolean
49
+ neverDeletedATask?: boolean
50
+ neverEditedATask?: boolean
51
+ finishedOnboarding: boolean
52
+ hasDownloadedNativeApp?: boolean
53
+ unitSystem: 'imperial' | 'metric'
54
+ gardenZoneTimelessPreference?: boolean
55
+ subscriptionEndDate?: Date
56
+ /**
57
+ * Last fertilizer ID chosen by the user.
58
+ * Used as the default fertilizer for new garden zones.
59
+ */
60
+ lastFertilizerIdChosen?: number
61
+ /**
62
+ * Virtual field to get the app badge count
63
+ * ----------------------------------------
64
+ * For now, it's just the number of unread messages.
65
+ */
66
+ badgeCount?: number
67
+ /**
68
+ * Number of unread alerts, cached version of unread alerts (the table) count
69
+ */
70
+ unreadAlertsCount?: number
71
+ isAdmin: boolean
72
+ }
@@ -33,4 +33,20 @@ export namespace PAGES {
33
33
  export interface MonthsPreviewResponse {
34
34
  months: MonthPreviewI[]
35
35
  }
36
+
37
+ export interface HelpVideoI {
38
+ id: string
39
+ youtubeVideoId: string
40
+ youtubeUrl: string
41
+ thumbnailUrl: string
42
+ title: string
43
+ subtitle: string
44
+ mp4Url: string | null
45
+ }
46
+
47
+ export interface HelpResponse {
48
+ title: string
49
+ subtitle?: string | null
50
+ videos: HelpVideoI[]
51
+ }
36
52
  }
package/src/plant.d.ts CHANGED
@@ -1,115 +1,107 @@
1
- import type { TaxonFamilyI } from './taxonFamily'
2
- import type { SeedingInfoI } from './pages.api'
3
- /**
4
- * Range filter value for min/max filters
5
- */
6
- export interface RangeFilterValueI {
7
- min: number
8
- max: number
9
- }
10
-
11
- /**
12
- * Plant filter value types
13
- * Represents the possible values for a single filter
14
- */
15
- export type PlantFilterValueI = string | string[] | number | boolean | RangeFilterValueI
16
-
17
- /**
18
- * Plant attributes for filtering
19
- * Used in JSONB field and as query parameters
20
- * Supports multiple value types for different filter types
21
- */
22
- export type PlantAttributesI = Record<string, PlantFilterValueI>
23
-
24
- export interface PlantI {
25
- id: number
26
- name: string
27
- slug: string
28
- description: string
29
- descriptionSource?: string
30
- female: boolean
31
- family?: string | null
32
- taxonFamilyId?: number | null
33
- spaceBetweenSeedMin: number
34
- spaceBetweenSeedMax: number
35
- spaceBetweenAlleyMin: number
36
- spaceBetweenAlleyMax: number
37
- weeksInTransplant: number
38
- weeksDuringWhichYouCanSeedOutdoor: number
39
- weeksToMaturity: number
40
- weeksToWaitAfterFreezingDate: number
41
- weeksToHarvest: number
42
- indoorSeeding: boolean
43
- outdoorSeeding: boolean
44
- azoteNeedsKgPerHa: number
45
- hibernate: boolean
46
- germinationTemperature: number | null
47
- minGerminationTemperature: number | null
48
- germinationNumberOfDays: string | null
49
- germinationSeedDepth: string | null
50
- cultivationInfo: string | null
51
- parentId: number | null
52
- memberId?: number
53
- memberFirstName?: string | null
54
- shared: boolean
55
- hexColor: string | null
56
- sunRequirements: 'partialShade' | 'fullSun' | 'fullShade' | null
57
- isHardy: boolean | null
58
- imageURL: string
59
- totalWeeksToMaturity: number
60
- hasNoInformation: boolean
61
- createdAt: Date
62
- updatedAt: Date
63
- translatedSunRequirements: 'Plein soleil' | 'Mi-ombre' | 'Ombre' | null
64
- parent?: PlantI
65
- children?: PlantI[]
66
- PlantInventories?: PlantInventoryI[]
67
- taggedItems?: TaggedItemI[]
68
- /**
69
- * List of selections that the plant is in.
70
- * --------------------------------------
71
- * Tends to be used for featured selections
72
- */
73
- Selections?: SelectionI[]
74
- tasks?: TaskI[]
75
- Images?: ImageI[]
76
- Member?: Partial<MemberI>
77
- notes?: NoteI[]
78
- rotationGroup?: string
79
- // @deprecate once v1.8.1 is fully adopted
80
- rotationFamily?: string
81
- taxonFamily?: TaxonFamilyI
82
- seedingInfo: SeedingInfoI
83
- /**
84
- * Contextual search text for recommended plants
85
- * Provides additional context when suggesting plants for specific garden zones
86
- */
87
- contextualSearchText?: string
88
- }
89
-
90
- interface PlantTagI {
91
- name: string
92
- /**
93
- * JSONB field containing plant-specific attributes for filtering
94
- * Ex: { growth: { type: 'déterminée' }, fruit: { color: 'rouge' } }
95
- */
96
- attributes?: PlantAttributesI
97
- }
98
-
99
- interface PlantInventoryI {
100
- id: number
101
- plantId: number
102
- supplierName: string
103
- plantName: string
104
- supplierURL: string
105
- imageLocation: string
106
- description: string
107
- inStock: boolean
108
- }
109
-
110
- export interface PlantSearchResultI {
111
- plants: PlantModelI[]
112
- selections: SelectionModelI[]
113
- total?: number
114
- familyName?: string
115
- }
1
+ import type { TaxonFamilyI } from './taxonFamily'
2
+ import type { SeedingInfoI } from './pages.api'
3
+ /**
4
+ * Range filter value for min/max filters
5
+ */
6
+ export interface RangeFilterValueI {
7
+ min: number
8
+ max: number
9
+ }
10
+
11
+ /**
12
+ * Plant filter value types
13
+ * Represents the possible values for a single filter
14
+ */
15
+ export type PlantFilterValueI = string | string[] | number | boolean | RangeFilterValueI
16
+
17
+ /**
18
+ * Plant attributes for filtering
19
+ * Used in JSONB field and as query parameters
20
+ * Supports multiple value types for different filter types
21
+ */
22
+ export type PlantAttributesI = Record<string, PlantFilterValueI>
23
+
24
+ export interface PlantI {
25
+ id: number
26
+ name: string
27
+ slug: string
28
+ description: string
29
+ descriptionSource?: string
30
+ female: boolean
31
+ family?: string | null
32
+ taxonFamilyId?: number | null
33
+ spaceBetweenSeedMin: number
34
+ spaceBetweenSeedMax: number
35
+ spaceBetweenAlleyMin: number
36
+ spaceBetweenAlleyMax: number
37
+ weeksInTransplant: number
38
+ weeksDuringWhichYouCanSeedOutdoor: number
39
+ weeksToMaturity: number
40
+ daysToMaturity: number | null
41
+ weeksToWaitAfterFreezingDate: number
42
+ weeksToHarvest: number
43
+ indoorSeeding: boolean
44
+ outdoorSeeding: boolean
45
+ azoteNeedsKgPerHa: number
46
+ hibernate: boolean
47
+ germinationTemperature: number | null
48
+ minGerminationTemperature: number | null
49
+ germinationNumberOfDays: string | null
50
+ germinationSeedDepth: string | null
51
+ cultivationInfo: string | null
52
+ parentId: number | null
53
+ memberId?: number
54
+ memberFirstName?: string | null
55
+ shared: boolean
56
+ hexColor: string | null
57
+ sunRequirements: 'partialShade' | 'fullSun' | 'fullShade' | null
58
+ isHardy: boolean | null
59
+ imageURL: string
60
+ totalWeeksToMaturity: number
61
+ hasNoInformation: boolean
62
+ createdAt: Date
63
+ updatedAt: Date
64
+ translatedSunRequirements: 'Plein soleil' | 'Mi-ombre' | 'Ombre' | null
65
+ parent?: PlantI
66
+ children?: PlantI[]
67
+ PlantInventories?: PlantInventoryI[]
68
+ taggedItems?: TaggedItemI[]
69
+ /**
70
+ * List of selections that the plant is in.
71
+ * --------------------------------------
72
+ * Tends to be used for featured selections
73
+ */
74
+ Selections?: SelectionI[]
75
+ tasks?: TaskI[]
76
+ Images?: ImageI[]
77
+ Member?: Partial<MemberI>
78
+ notes?: NoteI[]
79
+ rotationGroup?: string
80
+ // @deprecate once v1.8.1 is fully adopted
81
+ rotationFamily?: string
82
+ taxonFamily?: TaxonFamilyI
83
+ seedingInfo: SeedingInfoI
84
+ /**
85
+ * Contextual search text for recommended plants
86
+ * Provides additional context when suggesting plants for specific garden zones
87
+ */
88
+ contextualSearchText?: string
89
+ }
90
+
91
+ interface PlantInventoryI {
92
+ id: number
93
+ plantId: number
94
+ supplierName: string
95
+ plantName: string
96
+ supplierURL: string
97
+ imageLocation: string
98
+ description: string
99
+ inStock: boolean
100
+ }
101
+
102
+ export interface PlantSearchResultI {
103
+ plants: PlantModelI[]
104
+ selections: SelectionModelI[]
105
+ total?: number
106
+ familyName?: string
107
+ }
@@ -80,7 +80,7 @@ export namespace PLANTS {
80
80
  spaceBetweenSeedMax?: number | null
81
81
  spaceBetweenAlleyMin?: number | null
82
82
  spaceBetweenAlleyMax?: number | null
83
- weeksToMaturity?: number | null
83
+ daysToMaturity?: number | null
84
84
  indoorSeeding?: boolean
85
85
  outdoorSeeding?: boolean
86
86
  sunRequirements?: 'partialShade' | 'fullSun' | 'fullShade' | null
package/src/task.d.ts CHANGED
@@ -10,6 +10,8 @@ export interface TaskI {
10
10
  colourCode: string
11
11
  iconName?: string
12
12
  private: boolean
13
+ isDone: boolean
14
+ doneAt?: Date
13
15
  }
14
16
 
15
17
  /**
@@ -27,6 +29,25 @@ export interface TaskTagI {
27
29
  iconName?: string
28
30
  }
29
31
 
32
+ /** Optional toast notification payload returned after task completion. All fields are optional — the frontend applies its own defaults for any missing field. */
33
+ export interface CompleteTaskToastI {
34
+ title?: string
35
+ subtitle?: string
36
+ iconName?: string
37
+ }
38
+
39
+ /**
40
+ * Response returned when one or more tasks are marked as done.
41
+ * Keys are plant slugs, values are the full updated task list for that plant selection.
42
+ * Single completion returns a record with one entry; bulk returns one entry per plant.
43
+ */
44
+ export interface CompleteTaskResponseI {
45
+ success: boolean
46
+ updatedTasksByPlant: Record<string, TaskI[]>
47
+ /** Optional toast to display after completion. Missing fields fall back to frontend defaults. */
48
+ toast?: CompleteTaskToastI
49
+ }
50
+
30
51
  /**
31
52
  * Data used to create or edit a task
32
53
  */