stay_commerce-frontend 0.1.0 → 0.1.1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/bundle.css +8665 -6069
  3. data/app/assets/builds/bundle.css.map +3 -3
  4. data/app/assets/builds/bundle.js +37877 -27557
  5. data/app/assets/builds/bundle.js.map +4 -4
  6. data/app/assets/builds/styles.css +6328 -5031
  7. data/app/assets/builds/styles.css.map +3 -3
  8. data/app/javascript/react/components/Accountpage/AccountInfo.jsx +2 -1
  9. data/app/javascript/react/components/AddNewProperty/CommonLayout.jsx +0 -2
  10. data/app/javascript/react/components/AddNewProperty/Description.jsx +51 -52
  11. data/app/javascript/react/components/AddNewProperty/Details.jsx +212 -129
  12. data/app/javascript/react/components/AddNewProperty/Images.jsx +122 -45
  13. data/app/javascript/react/components/AddNewProperty/Location.jsx +21 -14
  14. data/app/javascript/react/components/AddNewProperty/Room.jsx +639 -548
  15. data/app/javascript/react/components/AvatarDropdown/AvatarDropDown.jsx +9 -1
  16. data/app/javascript/react/components/FacilitiesSection/Facilities.jsx +18 -0
  17. data/app/javascript/react/components/FixedNavbar/FixedNav.jsx +20 -14
  18. data/app/javascript/react/components/HeroSectionDesign/BookingForm.jsx +136 -88
  19. data/app/javascript/react/components/HeroSectionDesign/MyPropertiesListing.jsx +79 -69
  20. data/app/javascript/react/components/Layout/Layout.js +8 -1
  21. data/app/javascript/react/components/Listing-stay-Detail/ApartmentCard.jsx +3 -3
  22. data/app/javascript/react/components/Listing-stay-Detail/BookingModal.jsx +167 -122
  23. data/app/javascript/react/components/Listing-stay-Detail/CardManager.jsx +285 -0
  24. data/app/javascript/react/components/Listing-stay-Detail/CheckoutForm.jsx +147 -84
  25. data/app/javascript/react/components/Listing-stay-Detail/ListingStayDetailPage.jsx +1 -7
  26. data/app/javascript/react/components/Listing-stay-Detail/PropertiesPage.jsx +464 -0
  27. data/app/javascript/react/components/MobileNav/MobileMenu.jsx +1 -4
  28. data/app/javascript/react/components/PropertyListing/MyProperties.jsx +45 -44
  29. data/app/javascript/react/components/PropertyListing/StayBooking/BookingDetails.jsx +4 -4
  30. data/app/javascript/react/components/PropertyListing/StayBooking/MyBooking.jsx +41 -29
  31. data/app/javascript/react/components/StayCard/StayCard.jsx +5 -3
  32. data/app/javascript/react/packs/index.jsx +1 -0
  33. data/app/javascript/react/packs/routes/Route.jsx +18 -1
  34. data/app/javascript/react/pages/Home.jsx +6 -4
  35. data/app/javascript/react/redux/slices/PropertySlice/PropertySlice.jsx +21 -21
  36. data/app/javascript/react/redux/slices/PropertySlice/Searchslice.jsx +53 -6
  37. data/app/javascript/react/redux/slices/UserSlice/UserSlice.jsx +1 -0
  38. data/app/javascript/react/shared/Avatar/Avatar.jsx +5 -8
  39. data/app/javascript/react/shared/Button/SecondryButton.jsx +9 -0
  40. data/app/javascript/react/shared/Loader.jsx +13 -0
  41. data/app/javascript/react/shared/Pagination.jsx +53 -0
  42. data/app/javascript/react/shared/Schema/FormSchema +143 -0
  43. data/app/javascript/react/styles/BookingDetails.scss +1 -0
  44. data/app/javascript/react/styles/CardManager.scss +608 -0
  45. data/app/javascript/react/styles/Loader.scss +30 -0
  46. data/app/javascript/react/styles/Pagination.scss +33 -0
  47. data/app/javascript/react/styles/PropertiesPage.scss +0 -4
  48. data/app/javascript/react/styles/RenderSection.scss +1 -0
  49. data/app/javascript/react/styles/accountpage.scss +3 -0
  50. data/app/javascript/react/styles/application.scss +13 -1
  51. data/app/javascript/react/styles/bookingform.scss +56 -28
  52. data/app/javascript/react/styles/buttonSecondry.scss +24 -0
  53. data/app/javascript/react/styles/checkbox.scss +34 -35
  54. data/app/javascript/react/styles/commonlayout.scss +7 -2
  55. data/app/javascript/react/styles/commonpage.scss +5 -1
  56. data/app/javascript/react/styles/description.scss +3 -0
  57. data/app/javascript/react/styles/facilities.scss +2 -1
  58. data/app/javascript/react/styles/fixednavbar.scss +8 -0
  59. data/app/javascript/react/styles/listingstaydetailpage.scss +5 -0
  60. data/app/javascript/react/styles/mobilemenu.scss +0 -1
  61. data/app/javascript/react/styles/mybooking.scss +20 -0
  62. data/app/javascript/react/styles/myproperty.scss +26 -0
  63. data/app/javascript/react/styles/propertydetailscard.scss +265 -267
  64. data/app/javascript/react/styles/react-datepicker/react-datepicker.css +869 -0
  65. data/app/javascript/react/styles/room.scss +13 -8
  66. data/app/javascript/react/utils/helpers/ToastErros.js +12 -0
  67. data/db/migrate/20250627101451_add_role_to_stay_users.rb +5 -0
  68. data/lib/stay_commerce/frontend/version.rb +1 -1
  69. metadata +15 -5
  70. data/app/javascript/react/components/HeroSectionDesign/PropertiesPage.jsx +0 -122
  71. data/app/javascript/react/shared/DateField/CustomDatePicker.jsx +0 -69
  72. data/app/javascript/react/styles/customdatepicker.scss +0 -120
@@ -0,0 +1,464 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { useFormik } from "formik";
3
+ import "../../styles/listingstaydetailpage.scss";
4
+ import moment from "moment";
5
+ import { reserveBooking } from "../../redux/slices/PropertySlice/PropertySlice";
6
+ import { useDispatch, useSelector } from "react-redux";
7
+ import GallerySlider from "../GallerySlider/GallerySlider";
8
+ import Badge from "../../shared/Badge/Badge";
9
+ import { currencySymbol } from "../../shared/CurrencySymbol";
10
+ import "../../styles/RenderSection.scss";
11
+ import { useNavigate } from "react-router-dom";
12
+ import { User, DoorOpen, Bed, Expand } from "lucide-react";
13
+ import BookingModal from "./BookingModal";
14
+ import AmenitiesModal from "./AmenitiesModal";
15
+ import RoomDescriptionModal from "./RoomDescriptionModal";
16
+ import { searchProperties } from "../../redux/slices/PropertySlice/Searchslice";
17
+ import Pagination from "../../shared/Pagination";
18
+ import Loader from "../../shared/Loader";
19
+
20
+ const PropertiesPage = () => {
21
+ const dispatch = useDispatch();
22
+ const {
23
+ searchResults,
24
+ startDate,
25
+ endDate,
26
+ totalGuests,
27
+ latitude,
28
+ longitude,
29
+ data,
30
+ loading,
31
+ } = useSelector((state) => state.search);
32
+ const roomsData = searchResults || [];
33
+ const [isBookingModalOpen, setIsBookingModalOpen] = useState(false);
34
+ const [selectedRoomForBooking, setSelectedRoomForBooking] = useState(null);
35
+ const [isAmenitiesModalOpen, setIsAmenitiesModalOpen] = useState(false);
36
+ const [selectedRoomForAmenities, setSelectedRoomForAmenities] =
37
+ useState(null);
38
+ const [currentPage, setCurrentPage] = useState(1);
39
+
40
+ useEffect(() => {
41
+ const start = startDate
42
+ ? moment(startDate).format("YYYY-MM-DD")
43
+ : moment().format("YYYY-MM-DD");
44
+ const end = endDate
45
+ ? moment(endDate).format("YYYY-MM-DD")
46
+ : moment().add(2, "days").format("YYYY-MM-DD");
47
+ const guests = totalGuests || 1;
48
+ const lat = latitude || "28.6139";
49
+ const lng = longitude || "77.2090";
50
+ const searchQuery = `q[availability_start_lteq]=${start}&q[availability_end_gteq]=${end}&q[guest_number_gteq]=${guests}&q[latitude]=${lat}&q[longitude]=${lng}&page=${currentPage}`;
51
+ dispatch(searchProperties(searchQuery));
52
+ }, [
53
+ dispatch,
54
+ startDate,
55
+ endDate,
56
+ totalGuests,
57
+ latitude,
58
+ longitude,
59
+ currentPage,
60
+ ]);
61
+
62
+ const RenderSection = () => {
63
+ const navigate = useNavigate();
64
+ const [error, setError] = useState("");
65
+ const [isButtonDisabled, setIsButtonDisabled] = useState(true);
66
+ const [isLoading, setIsLoading] = useState(false);
67
+ const dispatch = useDispatch();
68
+ const [selectedRoomForDesc, setSelectedRoomForDesc] = useState(null);
69
+
70
+ const formik = useFormik({
71
+ initialValues: {
72
+ number_of_guests: null,
73
+ booking_start: null,
74
+ booking_end: null,
75
+ room_id: null,
76
+ line_items_attributes: [],
77
+ price_per_month: null,
78
+ },
79
+ enableReinitialize: true,
80
+ onSubmit: (values) => {
81
+ handleSubmit(values);
82
+ },
83
+ });
84
+
85
+ const calculateMonthsDifference = (bookingStart, bookingEnd) => {
86
+ const start = moment(bookingStart, "YYYY-MM-DD");
87
+ const end = moment(bookingEnd, "YYYY-MM-DD");
88
+ const uniqueMonths = new Set();
89
+ let current = start.clone();
90
+ while (current.isBefore(end, "day") || current.isSame(end, "day")) {
91
+ uniqueMonths.add(`${current.year()}-${current.month() + 1}`);
92
+ current.add(1, "day");
93
+ }
94
+ return uniqueMonths.size;
95
+ };
96
+
97
+ const handleSubmit = async (values) => {
98
+ const propertyId = selectedRoomForBooking?.property?.slug;
99
+ if (!propertyId) {
100
+ setError("Property ID not found. Please try again.");
101
+ return;
102
+ }
103
+
104
+ const postData = {
105
+ booking: {
106
+ number_of_guests: Number(values.number_of_guests),
107
+ property_id: propertyId,
108
+ check_in_date: moment(values.booking_start).format("YYYY-MM-DD"),
109
+ check_out_date: moment(values.booking_end).format("YYYY-MM-DD"),
110
+ no_of_months: calculateMonthsDifference(
111
+ moment(values.booking_start).format("YYYY-MM-DD"),
112
+ moment(values.booking_end).format("YYYY-MM-DD")
113
+ ),
114
+ line_items_attributes: [
115
+ {
116
+ room_id: values.room_id,
117
+ price: values.price_per_month,
118
+ quantity: 1,
119
+ property_id: propertyId,
120
+ },
121
+ ],
122
+ },
123
+ };
124
+ setIsLoading(true);
125
+ try {
126
+ const action = await dispatch(reserveBooking(postData));
127
+
128
+ if (action?.type === "payment/reserveBooking/fulfilled" && action) {
129
+ const bookingId = action?.payload?.id;
130
+ if (bookingId) {
131
+ setError("");
132
+ setIsBookingModalOpen(false);
133
+ navigate(`/myreservations/${bookingId}`);
134
+ } else {
135
+ setError("Failed to reserve booking. Please try again.");
136
+ }
137
+ } else {
138
+ setError(
139
+ action?.payload?.message ||
140
+ "Failed to reserve booking. Please try again."
141
+ );
142
+ }
143
+ } catch (error) {
144
+ console.error("Booking Error:", error);
145
+ setError("Failed to reserve booking. Please try again.");
146
+ } finally {
147
+ setIsLoading(false);
148
+ }
149
+ };
150
+
151
+ const openBookingModal = (room) => {
152
+ setSelectedRoomForBooking(room);
153
+ setIsBookingModalOpen(true);
154
+ };
155
+
156
+ const closeBookingModal = () => {
157
+ setIsBookingModalOpen(false);
158
+ setSelectedRoomForBooking(null);
159
+ setError("");
160
+ };
161
+
162
+ const openAmenitiesModal = (room) => {
163
+ setSelectedRoomForAmenities(room);
164
+ setIsAmenitiesModalOpen(true);
165
+ };
166
+
167
+ const closeAmenitiesModal = () => {
168
+ setIsAmenitiesModalOpen(false);
169
+ setSelectedRoomForAmenities(null);
170
+ };
171
+
172
+ const modifiedStatus = (status) => {
173
+ switch (status) {
174
+ case "active":
175
+ return "Active";
176
+ case "inactive":
177
+ return "Inactive";
178
+ default:
179
+ return "";
180
+ }
181
+ };
182
+
183
+ useEffect(() => {
184
+ const { booking_start, booking_end, number_of_guests } = formik.values;
185
+ if (booking_start && booking_end && number_of_guests) {
186
+ setIsButtonDisabled(false);
187
+ } else {
188
+ setIsButtonDisabled(true);
189
+ }
190
+ }, [formik.values]);
191
+
192
+ const selectedRoom = formik?.values?.room_id;
193
+ if (!roomsData || roomsData.length === 0) {
194
+ return (
195
+ <div className="no-results">
196
+ <p>No rooms available.</p>
197
+ </div>
198
+ );
199
+ }
200
+
201
+ return (
202
+ <>
203
+ <h2 className="section-title">Rooms</h2>
204
+ {roomsData.map((room, index) => {
205
+ const features = room?.features || [];
206
+ const amenities = room?.amenities || [];
207
+ const totalItems = features.length + amenities.length;
208
+ const showViewAllButton = totalItems > 4;
209
+ const displayFeatures = showViewAllButton
210
+ ? features.slice(0, 2)
211
+ : features;
212
+ const displayAmenities = showViewAllButton
213
+ ? amenities.slice(0, 2)
214
+ : amenities;
215
+
216
+ return (
217
+ <div key={room?.id} className="section-container">
218
+ <div className="room-container">
219
+ <header>
220
+ <div className="room-item-wrapper">
221
+ <div
222
+ className="room-image"
223
+ style={{ position: "relative" }}
224
+ >
225
+ <GallerySlider
226
+ ratioClass="gallery-aspect"
227
+ images={room?.room_images || []}
228
+ style={{
229
+ height: "370px",
230
+ borderTopLeftRadius: "20px",
231
+ borderBottomLeftRadius: "20px",
232
+ }}
233
+ />
234
+ <div
235
+ style={{
236
+ position: "absolute",
237
+ top: "12px",
238
+ left: "12px",
239
+ zIndex: 10,
240
+ }}
241
+ >
242
+ <Badge
243
+ name={modifiedStatus(room?.status) || "Property"}
244
+ />
245
+ </div>
246
+ </div>
247
+
248
+ <div style={{ width: "100%", padding: "20px 20px 0 0" }}>
249
+ <div className="room-content">
250
+ <div className="rooms-parents">
251
+ <div
252
+ style={{ display: "flex", alignItems: "center" }}
253
+ >
254
+ <h2 className="room-title">{room?.name}</h2>
255
+ </div>
256
+ </div>
257
+ <hr style={{ marginTop: 0 }} />
258
+
259
+ <div className="room-features">
260
+ <div className="feature-item">
261
+ <User className="icon" size={18} />
262
+ <span>{room?.max_guests || "N/A"}</span>
263
+ </div>
264
+ <div className="feature-item">
265
+ <DoorOpen className="icon" size={18} />
266
+ <span>{room?.room_type?.name || "Room Type"}</span>
267
+ </div>
268
+ <div className="feature-item">
269
+ <Bed className="icon" size={18} />
270
+ <span>{room?.bed_type?.name || "Bed Type"}</span>
271
+ </div>
272
+ <div className="feature-item">
273
+ <Expand className="icon" size={18} />
274
+ <span>
275
+ {room?.size ? `${room.size} sq ft` : "Size N/A"}
276
+ </span>
277
+ </div>
278
+ </div>
279
+ </div>
280
+
281
+ <div className="rooms-design">
282
+ <div className="section-header">
283
+ <div className="sub-heading">
284
+ Features & Amenities
285
+ </div>
286
+ {showViewAllButton && (
287
+ <div className="view-all-item">
288
+ <button
289
+ onClick={() => openAmenitiesModal(room)}
290
+ className="btn-view-more"
291
+ >
292
+ <span>View All ({totalItems})</span>
293
+ </button>
294
+ </div>
295
+ )}
296
+ </div>
297
+ {displayFeatures.length > 0 ||
298
+ displayAmenities.length > 0 ? (
299
+ <div className="amenities-style">
300
+ {displayFeatures.map((feature) => {
301
+ const IconComponent = feature?.icon_name || null;
302
+ return (
303
+ <div
304
+ key={feature?.id}
305
+ className="amenity-item-style"
306
+ >
307
+ {IconComponent && <IconComponent />}
308
+ <span>{feature?.name}</span>
309
+ </div>
310
+ );
311
+ })}
312
+ {displayAmenities.map((amenity) => {
313
+ const IconComponent = amenity?.icon_name || null;
314
+ return (
315
+ <div
316
+ key={amenity?.id}
317
+ className="amenity-item-style"
318
+ >
319
+ {amenity?.image ? (
320
+ <NcImage
321
+ src={amenity?.image}
322
+ alt={amenity?.name}
323
+ className="w-8 h-8 object-cover rounded-md"
324
+ />
325
+ ) : (
326
+ IconComponent && <IconComponent />
327
+ )}
328
+ <span>{amenity?.name}</span>
329
+ </div>
330
+ );
331
+ })}
332
+ </div>
333
+ ) : (
334
+ <p
335
+ style={{
336
+ fontSize: "14px",
337
+ color: "#6b7280",
338
+ textAlign: "center",
339
+ }}
340
+ >
341
+ Features & Amenities not available.
342
+ </p>
343
+ )}
344
+ </div>
345
+
346
+ <AmenitiesModal
347
+ isOpen={isAmenitiesModalOpen}
348
+ onClose={closeAmenitiesModal}
349
+ room={selectedRoomForAmenities}
350
+ />
351
+
352
+ <div className="rooms-design">
353
+ <div className="section-header">
354
+ <div className="sub-heading">Room Description</div>
355
+ </div>
356
+
357
+ {room?.description?.length > 180 ? (
358
+ <div className="description-container-listing">
359
+ <span className="description">
360
+ {room?.description?.substring(0, 180)}...
361
+ </span>
362
+ <button
363
+ onClick={() => setSelectedRoomForDesc(room)}
364
+ className="btn-view-more-listing"
365
+ >
366
+ View Full Description
367
+ </button>
368
+ </div>
369
+ ) : (
370
+ <span className="description">
371
+ {room?.description || "No description available."}
372
+ </span>
373
+ )}
374
+ </div>
375
+
376
+ <div
377
+ style={{
378
+ width: "100%",
379
+ display: "flex",
380
+ justifyContent: "end",
381
+ alignItems: "center",
382
+ }}
383
+ >
384
+ <div
385
+ className="button-group"
386
+ style={{
387
+ width: "130px",
388
+ }}
389
+ >
390
+ <button
391
+ className={`btn-booking ${
392
+ room?.status === "inactive" ? "disabled" : ""
393
+ }`}
394
+ onClick={() => openBookingModal(room)}
395
+ disabled={room?.status === "inactive"}
396
+ >
397
+ <span className="price-text">
398
+ {`${currencySymbol()}${
399
+ room?.price_per_month || 0
400
+ }`}
401
+ <span className="per-month">/mo</span>
402
+ </span>
403
+ <span className="cta-text">Book Now</span>
404
+ </button>
405
+ </div>
406
+ </div>
407
+
408
+ <RoomDescriptionModal
409
+ isOpen={!!selectedRoomForDesc}
410
+ onClose={() => setSelectedRoomForDesc(null)}
411
+ room={selectedRoomForDesc}
412
+ />
413
+ </div>
414
+ </div>
415
+ </header>
416
+ </div>
417
+
418
+ <div className="sidebar-container">
419
+ <div>
420
+ {room?.status === "inactive" && (
421
+ <Badge name="Room is Inactive" />
422
+ )}
423
+ </div>
424
+ </div>
425
+ </div>
426
+ );
427
+ })}
428
+
429
+ <BookingModal
430
+ isOpen={isBookingModalOpen}
431
+ onClose={closeBookingModal}
432
+ room={selectedRoomForBooking}
433
+ propertyData={selectedRoomForBooking?.property}
434
+ onSubmit={handleSubmit}
435
+ isLoading={isLoading}
436
+ />
437
+ </>
438
+ );
439
+ };
440
+ return (
441
+ <div className="container listing-detail-page">
442
+ <section className="similar-properties-section">
443
+ {loading || !data?.success ? (
444
+ <Loader text="Searching Properties..." />
445
+ ) : (
446
+ <>
447
+ <RenderSection />
448
+ {data?.meta?.total_pages > 1 && (
449
+ <Pagination
450
+ currentPage={data.meta.current_page}
451
+ totalPages={data.meta.total_pages}
452
+ onPageChange={setCurrentPage}
453
+ />
454
+ )}
455
+ </>
456
+ )}
457
+ </section>
458
+ </div>
459
+ );
460
+ };
461
+
462
+ export default function ListingStayDetailPage() {
463
+ return <PropertiesPage />;
464
+ }
@@ -12,11 +12,8 @@ function MobileMenu() {
12
12
  const navItems = [
13
13
  { name: "HOME", path: "/" },
14
14
  { name: "ABOUT US", path: "/about-us" },
15
- { name: "ACCOMMODATION", path: "/accommodation" },
15
+ // { name: "ACCOMMODATION", path: "/accommodation" },
16
16
  { name: "GALLERY", path: "/gallery" },
17
- { name: "BLOG", path: "/blog" },
18
- { name: "ELEMENT", path: "/element" },
19
- { name: "CONTACT", path: "/contact" },
20
17
  ];
21
18
 
22
19
  return (
@@ -5,8 +5,8 @@ import PropertyCard from "../Headers/PropertyCard";
5
5
  import ButtonPrimary from "../../shared/Button/ButtonPrimary";
6
6
  import "../../styles/myproperty.scss";
7
7
  import { getallPropertieslisting } from "../../redux/slices/PropertySlice/PropertySlice";
8
- import PropertiesPage from "../HeroSectionDesign/PropertiesPage";
9
8
  import MyPropertiesListing from "../HeroSectionDesign/MyPropertiesListing";
9
+ import Pagination from "../../shared/Pagination";
10
10
 
11
11
  const MyProperties = () => {
12
12
  const dispatch = useDispatch();
@@ -23,7 +23,7 @@ const MyProperties = () => {
23
23
  id: apiItem?.id,
24
24
  title: apiItem?.title,
25
25
  place_images: apiItem?.place_images,
26
- address: `${apiItem?.city}, ${apiItem?.state}`,
26
+ address: `${apiItem?.address}, ${apiItem?.country}`,
27
27
  availability_start: apiItem?.availability_start,
28
28
  availability_end: apiItem?.availability_end,
29
29
  price: apiItem?.price_per_month,
@@ -52,38 +52,23 @@ const MyProperties = () => {
52
52
  setTotalPages(res?.meta?.total_pages || 1);
53
53
  } else {
54
54
  setAllData([]);
55
- setTotalPages(1); // Or 0, depending on your UI handling
55
+ setTotalPages(1);
56
56
  }
57
57
  } catch (error) {
58
58
  console.error("Error fetching properties:", error);
59
59
  setAllData([]);
60
- setTotalPages(1); // Optional fallback
60
+ setTotalPages(1);
61
61
  } finally {
62
62
  setIsLoading(false);
63
63
  }
64
64
  };
65
65
 
66
- // // 🔍 Search handler
67
- // const handleSearch = async () => {
68
- // if (!query.trim()) return;
69
- // setIsSearchLoading(true);
70
- // try {
71
- // await fetchData(1);
72
- // setPage(1);
73
- // } catch (error) {
74
- // console.error("Search error:", error);
75
- // } finally {
76
- // setIsSearchLoading(false);
77
- // }
78
- // };
79
66
  const handleSearch = async () => {
80
67
  if (!query.trim()) return;
81
68
  setIsSearchLoading(true);
82
69
  try {
83
- const success = await fetchData(1);
84
- if (success) {
85
- setPage(1); // ✅ Set page only when fetch is successful
86
- }
70
+ await fetchData(1);
71
+ setPage(1);
87
72
  } catch (error) {
88
73
  console.error("Search error:", error);
89
74
  } finally {
@@ -91,15 +76,18 @@ const MyProperties = () => {
91
76
  }
92
77
  };
93
78
 
94
- // ⌨️ Handle query input
95
79
  const handleSearchChange = (event) => {
96
80
  setQuery(event.target.value);
97
81
  };
98
82
 
99
- // 📦 Auto-fetch on mount or when query is cleared
83
+ useEffect(() => {
84
+ fetchData(page);
85
+ }, [page]);
86
+
100
87
  useEffect(() => {
101
88
  if (query.length === 0) {
102
89
  fetchData(1);
90
+ setPage(1);
103
91
  }
104
92
  }, [query]);
105
93
 
@@ -109,34 +97,47 @@ const MyProperties = () => {
109
97
  <div className="myListing-header">
110
98
  {/* 🔍 Search Input */}
111
99
  {/* <div className="myListing-search">
112
- <div className="search-bar">
113
- <input
114
- type="text"
115
- value={query}
116
- onChange={handleSearchChange}
117
- placeholder="Search By Property Name..."
118
- className="search-input"
119
- />
120
- <ButtonPrimary
121
- onClick={handleSearch}
122
- className={`search-button ${
123
- isSearchLoading || query.trim() === ""
124
- ? "search-button-disabled"
125
- : "search-button-active"
126
- }`}
127
- disabled={isSearchLoading || query.trim() === ""}
128
- >
129
- {isSearchLoading ? "Searching..." : "Search"}
130
- </ButtonPrimary>
131
- </div>
132
- </div> */}
100
+ <div className="search-bar">
101
+ <input
102
+ type="text"
103
+ value={query}
104
+ onChange={handleSearchChange}
105
+ placeholder="Search By Property Name..."
106
+ className="search-input"
107
+ />
108
+ <ButtonPrimary
109
+ onClick={handleSearch}
110
+ className={`search-button ${
111
+ isSearchLoading || query.trim() === ""
112
+ ? "search-button-disabled"
113
+ : "search-button-active"
114
+ }`}
115
+ disabled={isSearchLoading || query.trim() === ""}
116
+ >
117
+ {isSearchLoading ? "Searching..." : "Search"}
118
+ </ButtonPrimary>
119
+ </div>
120
+ </div> */}
133
121
  <div className="myListing-property-cards">
134
122
  <MyPropertiesListing
135
123
  heading="My Properties"
136
124
  stayListings={allData}
137
125
  setAllData={setAllData}
126
+ isLoading={isLoading}
138
127
  />
139
128
  </div>
129
+ {totalPages > 1 && (
130
+ <div className="myListing-pagination">
131
+ <Pagination
132
+ currentPage={page}
133
+ totalPages={totalPages}
134
+ onPageChange={(newPage) => {
135
+ if (newPage !== page) setPage(newPage);
136
+ }}
137
+ isLoading={isLoading}
138
+ />
139
+ </div>
140
+ )}
140
141
  </div>
141
142
  </div>
142
143
  </div>
@@ -89,13 +89,13 @@ const BookingInterface = () => {
89
89
 
90
90
  <div className="property-card">
91
91
  <GallerySlider
92
- images={bookingRequestDetails?.line_items[0]?.rooms?.room_images}
92
+ images={bookingRequestDetails?.rooms[0]?.room_images}
93
93
  alt="Luxury Penthouse"
94
94
  style={{ height: "300px" }}
95
95
  />
96
96
  <div className="property-content">
97
97
  <h3 className="property-title">
98
- {bookingRequestDetails?.line_items[0]?.rooms?.name}
98
+ {bookingRequestDetails?.rooms?.[0].name}
99
99
  </h3>
100
100
  <div className="property-features">
101
101
  <div className="guest-badge">
@@ -116,7 +116,7 @@ const BookingInterface = () => {
116
116
  <div className="price-section-details">
117
117
  <div className="period">Total</div>
118
118
  <div className="amount">
119
- $ {bookingRequestDetails?.item_total}
119
+ ${bookingRequestDetails?.item_total}
120
120
  </div>
121
121
  </div>
122
122
  </div>
@@ -142,7 +142,7 @@ const BookingInterface = () => {
142
142
  <div className="detail-row">
143
143
  <span className="label">Pay Amount:</span>
144
144
  <span className="value">
145
- $ {bookingRequestDetails?.item_total}
145
+ ${bookingRequestDetails?.item_total}
146
146
  </span>
147
147
  </div>
148
148
  <div className="detail-row">