@snapdragonsnursery/react-components 1.19.7 → 1.19.9
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
package/src/ChildSearchModal.jsx
CHANGED
|
@@ -57,6 +57,7 @@ const ChildSearchModal = ({
|
|
|
57
57
|
const [advancedFilters, setAdvancedFilters] = useState({
|
|
58
58
|
status: status || (activeOnly ? "active" : "all"),
|
|
59
59
|
selectedSiteId: siteId || "",
|
|
60
|
+
selectedRoomId: "",
|
|
60
61
|
dobFrom: dobFrom || "",
|
|
61
62
|
dobTo: dobTo || "",
|
|
62
63
|
ageFrom: ageFrom || "",
|
|
@@ -64,6 +65,7 @@ const ChildSearchModal = ({
|
|
|
64
65
|
sortBy: sortBy,
|
|
65
66
|
sortOrder: sortOrder,
|
|
66
67
|
});
|
|
68
|
+
const [rooms, setRooms] = useState([]);
|
|
67
69
|
|
|
68
70
|
// State for multi-select mode
|
|
69
71
|
const initialSelectedChildren = useMemo(
|
|
@@ -209,6 +211,11 @@ const ChildSearchModal = ({
|
|
|
209
211
|
params.append("active_only", "true");
|
|
210
212
|
}
|
|
211
213
|
|
|
214
|
+
// Add room filter
|
|
215
|
+
if (advancedFilters.selectedRoomId) {
|
|
216
|
+
params.append("room_id", advancedFilters.selectedRoomId.toString());
|
|
217
|
+
}
|
|
218
|
+
|
|
212
219
|
// Add date of birth filters
|
|
213
220
|
if (advancedFilters.dobFrom) {
|
|
214
221
|
params.append("dob_from", advancedFilters.dobFrom);
|
|
@@ -288,6 +295,31 @@ const ChildSearchModal = ({
|
|
|
288
295
|
}
|
|
289
296
|
}, [debouncedSearchTerm, pagination.page, isOpen, searchChildren]);
|
|
290
297
|
|
|
298
|
+
// Fetch rooms for selected site
|
|
299
|
+
useEffect(() => {
|
|
300
|
+
const fetchRooms = async () => {
|
|
301
|
+
if (!advancedFilters.selectedSiteId || !sites) return;
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
// Find the selected site and extract its rooms
|
|
305
|
+
const selectedSite = sites.find(
|
|
306
|
+
(site) => site.site_id === parseInt(advancedFilters.selectedSiteId, 10)
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
if (selectedSite && selectedSite.rooms) {
|
|
310
|
+
setRooms(selectedSite.rooms);
|
|
311
|
+
} else {
|
|
312
|
+
setRooms([]);
|
|
313
|
+
}
|
|
314
|
+
} catch (err) {
|
|
315
|
+
console.error("Error fetching rooms:", err);
|
|
316
|
+
setRooms([]);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
fetchRooms();
|
|
321
|
+
}, [advancedFilters.selectedSiteId, sites]);
|
|
322
|
+
|
|
291
323
|
// Reset selection when modal opens (for multi-select mode)
|
|
292
324
|
useEffect(() => {
|
|
293
325
|
if (isOpen && multiSelect) {
|
|
@@ -618,6 +650,7 @@ const ChildSearchModal = ({
|
|
|
618
650
|
setAdvancedFilters((prev) => ({
|
|
619
651
|
...prev,
|
|
620
652
|
selectedSiteId: e.target.value,
|
|
653
|
+
selectedRoomId: "", // Reset room when site changes
|
|
621
654
|
}))
|
|
622
655
|
}
|
|
623
656
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm dark:bg-gray-600 dark:text-white"
|
|
@@ -632,6 +665,32 @@ const ChildSearchModal = ({
|
|
|
632
665
|
</div>
|
|
633
666
|
)}
|
|
634
667
|
|
|
668
|
+
{/* Room Filter */}
|
|
669
|
+
{advancedFilters.selectedSiteId && rooms && rooms.length > 0 && (
|
|
670
|
+
<div>
|
|
671
|
+
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
672
|
+
Room
|
|
673
|
+
</label>
|
|
674
|
+
<select
|
|
675
|
+
value={advancedFilters.selectedRoomId}
|
|
676
|
+
onChange={(e) =>
|
|
677
|
+
setAdvancedFilters((prev) => ({
|
|
678
|
+
...prev,
|
|
679
|
+
selectedRoomId: e.target.value,
|
|
680
|
+
}))
|
|
681
|
+
}
|
|
682
|
+
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm dark:bg-gray-600 dark:text-white"
|
|
683
|
+
>
|
|
684
|
+
<option value="">All Rooms</option>
|
|
685
|
+
{rooms.map((room) => (
|
|
686
|
+
<option key={room.room_id} value={room.room_id}>
|
|
687
|
+
{room.room_name}
|
|
688
|
+
</option>
|
|
689
|
+
))}
|
|
690
|
+
</select>
|
|
691
|
+
</div>
|
|
692
|
+
)}
|
|
693
|
+
|
|
635
694
|
{/* Date of Birth Range */}
|
|
636
695
|
<div>
|
|
637
696
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
@@ -756,6 +815,7 @@ const ChildSearchModal = ({
|
|
|
756
815
|
setAdvancedFilters({
|
|
757
816
|
status: activeOnly ? "active" : "all",
|
|
758
817
|
selectedSiteId: "",
|
|
818
|
+
selectedRoomId: "",
|
|
759
819
|
dobFrom: "",
|
|
760
820
|
dobTo: "",
|
|
761
821
|
ageFrom: "",
|
|
@@ -908,6 +968,14 @@ const ChildSearchModal = ({
|
|
|
908
968
|
</div>
|
|
909
969
|
<div className="mt-1 text-sm text-gray-600 dark:text-gray-300">
|
|
910
970
|
<span>{child.site_name}</span>
|
|
971
|
+
{child.current_room_name && (
|
|
972
|
+
<>
|
|
973
|
+
<span className="mx-2">•</span>
|
|
974
|
+
<span className="font-medium">
|
|
975
|
+
{child.current_room_name}
|
|
976
|
+
</span>
|
|
977
|
+
</>
|
|
978
|
+
)}
|
|
911
979
|
{child.date_of_birth && (
|
|
912
980
|
<>
|
|
913
981
|
<span className="mx-2">•</span>
|
package/src/ChildSearchPage.jsx
CHANGED
|
@@ -82,6 +82,7 @@ const ChildSearchPage = ({
|
|
|
82
82
|
const [advancedFilters, setAdvancedFilters] = useState({
|
|
83
83
|
status: status || (activeOnly ? "active" : "all"),
|
|
84
84
|
selectedSiteId: siteId || "",
|
|
85
|
+
selectedRoomId: "",
|
|
85
86
|
dobFrom: dobFrom || "",
|
|
86
87
|
dobTo: dobTo || "",
|
|
87
88
|
ageFrom: ageFrom || "",
|
|
@@ -89,6 +90,7 @@ const ChildSearchPage = ({
|
|
|
89
90
|
sortBy: sortBy,
|
|
90
91
|
sortOrder: sortOrder,
|
|
91
92
|
});
|
|
93
|
+
const [rooms, setRooms] = useState([]);
|
|
92
94
|
|
|
93
95
|
// Table sorting state
|
|
94
96
|
const [sorting, setSorting] = useState([]);
|
|
@@ -179,6 +181,15 @@ const ChildSearchPage = ({
|
|
|
179
181
|
<span>{row.original.site_name}</span>
|
|
180
182
|
),
|
|
181
183
|
}),
|
|
184
|
+
// Room column
|
|
185
|
+
columnHelper.accessor("current_room_name", {
|
|
186
|
+
header: "Room",
|
|
187
|
+
cell: ({ row }) => (
|
|
188
|
+
<span>
|
|
189
|
+
{row.original.current_room_name || "N/A"}
|
|
190
|
+
</span>
|
|
191
|
+
),
|
|
192
|
+
}),
|
|
182
193
|
// Date of Birth column - sortable
|
|
183
194
|
columnHelper.accessor("date_of_birth", {
|
|
184
195
|
header: createSortableHeader("date_of_birth", "Date of Birth"),
|
|
@@ -343,6 +354,11 @@ const ChildSearchPage = ({
|
|
|
343
354
|
params.append("active_only", "true");
|
|
344
355
|
}
|
|
345
356
|
|
|
357
|
+
// Add room filter
|
|
358
|
+
if (debouncedAdvancedFilters.selectedRoomId) {
|
|
359
|
+
params.append("room_id", debouncedAdvancedFilters.selectedRoomId.toString());
|
|
360
|
+
}
|
|
361
|
+
|
|
346
362
|
// Add date of birth filters
|
|
347
363
|
if (debouncedAdvancedFilters.dobFrom) {
|
|
348
364
|
params.append("dob_from", debouncedAdvancedFilters.dobFrom);
|
|
@@ -468,6 +484,7 @@ const ChildSearchPage = ({
|
|
|
468
484
|
const clearedFilters = {
|
|
469
485
|
status: activeOnly ? "active" : "all",
|
|
470
486
|
selectedSiteId: "",
|
|
487
|
+
selectedRoomId: "",
|
|
471
488
|
dobFrom: "",
|
|
472
489
|
dobTo: "",
|
|
473
490
|
ageFrom: "",
|
|
@@ -26,12 +26,37 @@ const ChildSearchFilters = ({
|
|
|
26
26
|
// Local state for filters that haven't been applied yet
|
|
27
27
|
const [localFilters, setLocalFilters] = React.useState(filters);
|
|
28
28
|
const [hasUnsavedChanges, setHasUnsavedChanges] = React.useState(false);
|
|
29
|
+
const [rooms, setRooms] = React.useState([]);
|
|
29
30
|
|
|
30
31
|
// Update local filters when props change
|
|
31
32
|
React.useEffect(() => {
|
|
32
33
|
setLocalFilters(filters);
|
|
33
34
|
setHasUnsavedChanges(false);
|
|
34
35
|
}, [filters]);
|
|
36
|
+
|
|
37
|
+
// Fetch rooms for selected site
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
if (!localFilters.selectedSiteId || !sites) {
|
|
40
|
+
setRooms([]);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
// Find the selected site and extract its rooms
|
|
46
|
+
const selectedSite = sites.find(
|
|
47
|
+
(site) => site.site_id === parseInt(localFilters.selectedSiteId, 10)
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
if (selectedSite && selectedSite.rooms) {
|
|
51
|
+
setRooms(selectedSite.rooms);
|
|
52
|
+
} else {
|
|
53
|
+
setRooms([]);
|
|
54
|
+
}
|
|
55
|
+
} catch (err) {
|
|
56
|
+
console.error("Error fetching rooms:", err);
|
|
57
|
+
setRooms([]);
|
|
58
|
+
}
|
|
59
|
+
}, [localFilters.selectedSiteId, sites]);
|
|
35
60
|
// Convert existing date strings to DateRangePicker format
|
|
36
61
|
const getDateRange = () => {
|
|
37
62
|
if (localFilters.dobFrom || localFilters.dobTo) {
|
|
@@ -146,7 +171,10 @@ const ChildSearchFilters = ({
|
|
|
146
171
|
</label>
|
|
147
172
|
<Select
|
|
148
173
|
value={localFilters.selectedSiteId}
|
|
149
|
-
onChange={(e) =>
|
|
174
|
+
onChange={(e) => {
|
|
175
|
+
handleFilterChange("selectedSiteId", e.target.value);
|
|
176
|
+
handleFilterChange("selectedRoomId", ""); // Reset room when site changes
|
|
177
|
+
}}
|
|
150
178
|
className="bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-white"
|
|
151
179
|
>
|
|
152
180
|
<SelectOption value="">All Sites</SelectOption>
|
|
@@ -159,6 +187,27 @@ const ChildSearchFilters = ({
|
|
|
159
187
|
</div>
|
|
160
188
|
)}
|
|
161
189
|
|
|
190
|
+
{/* Room Filter */}
|
|
191
|
+
{localFilters.selectedSiteId && rooms && rooms.length > 0 && (
|
|
192
|
+
<div>
|
|
193
|
+
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
194
|
+
Room
|
|
195
|
+
</label>
|
|
196
|
+
<Select
|
|
197
|
+
value={localFilters.selectedRoomId}
|
|
198
|
+
onChange={(e) => handleFilterChange("selectedRoomId", e.target.value)}
|
|
199
|
+
className="bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-white"
|
|
200
|
+
>
|
|
201
|
+
<SelectOption value="">All Rooms</SelectOption>
|
|
202
|
+
{rooms.map((room) => (
|
|
203
|
+
<SelectOption key={room.room_id} value={room.room_id}>
|
|
204
|
+
{room.room_name}
|
|
205
|
+
</SelectOption>
|
|
206
|
+
))}
|
|
207
|
+
</Select>
|
|
208
|
+
</div>
|
|
209
|
+
)}
|
|
210
|
+
|
|
162
211
|
{/* Date of Birth Range */}
|
|
163
212
|
<div>
|
|
164
213
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
@@ -37,6 +37,8 @@ export function DateRangePicker({
|
|
|
37
37
|
// New: allow styling popover content and calendar for layout control
|
|
38
38
|
contentClassName,
|
|
39
39
|
calendarClassName,
|
|
40
|
+
// New: allow hiding the calendar icon
|
|
41
|
+
showIcon = true,
|
|
40
42
|
...props
|
|
41
43
|
}) {
|
|
42
44
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -180,7 +182,7 @@ export function DateRangePicker({
|
|
|
180
182
|
disabled={disabled}
|
|
181
183
|
{...props}
|
|
182
184
|
>
|
|
183
|
-
<CalendarIcon className="mr-2 h-4 w-4" />
|
|
185
|
+
{showIcon && <CalendarIcon className="mr-2 h-4 w-4 shrink-0" />}
|
|
184
186
|
{internalRange?.from ? (
|
|
185
187
|
internalRange.to ? (
|
|
186
188
|
<>
|
|
@@ -291,6 +293,8 @@ export function DatePicker({
|
|
|
291
293
|
disabled,
|
|
292
294
|
disableFuture = false,
|
|
293
295
|
displayFormat = "PPP",
|
|
296
|
+
// New: allow hiding the calendar icon
|
|
297
|
+
showIcon = true,
|
|
294
298
|
...props
|
|
295
299
|
}) {
|
|
296
300
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -313,7 +317,7 @@ export function DatePicker({
|
|
|
313
317
|
disabled={disabled}
|
|
314
318
|
{...props}
|
|
315
319
|
>
|
|
316
|
-
<CalendarIcon className="mr-2 h-4 w-4" />
|
|
320
|
+
{showIcon && <CalendarIcon className="mr-2 h-4 w-4 shrink-0" />}
|
|
317
321
|
{selectedDate ? (
|
|
318
322
|
format(selectedDate, displayFormat)
|
|
319
323
|
) : (
|