stay_commerce-frontend 0.1.0
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/builds/404error-RVKQJ4S4.digested.jpg +0 -0
- data/app/assets/builds/Facebook-5HJUILVR.digested.svg +3 -0
- data/app/assets/builds/Google-CZ3UPVSC.digested.svg +6 -0
- data/app/assets/builds/application.js +95 -0
- data/app/assets/builds/application.js.map +7 -0
- data/app/assets/builds/beach-KAZW5GM3.digested.jpg +0 -0
- data/app/assets/builds/beach2-3ARC34NS.digested.jpg +0 -0
- data/app/assets/builds/beach3-PSTOH5FV.digested.jpg +0 -0
- data/app/assets/builds/beach4-PWNRPD3S.digested.jpg +0 -0
- data/app/assets/builds/beach5-SBOKKRHF.digested.jpg +0 -0
- data/app/assets/builds/beach6-SXZ5Y5AI.digested.jpg +0 -0
- data/app/assets/builds/beach7-FNBMFVKK.digested.jpg +0 -0
- data/app/assets/builds/beach8-TD7LTRQM.digested.jpg +0 -0
- data/app/assets/builds/bg-image-H7UGUMV2.digested.jpg +0 -0
- data/app/assets/builds/bgimage-DU3PCXKN.digested.jpg +0 -0
- data/app/assets/builds/bundle.css +30914 -0
- data/app/assets/builds/bundle.css.map +7 -0
- data/app/assets/builds/bundle.js +74569 -0
- data/app/assets/builds/bundle.js.map +7 -0
- data/app/assets/builds/hotel1-HGBXPKJK.digested.jpg +0 -0
- data/app/assets/builds/logo_updated-KQWAXLYL.digested.png +0 -0
- data/app/assets/builds/styles.css +6422 -0
- data/app/assets/builds/styles.css.map +7 -0
- data/app/assets/config/manifest.js +2 -0
- data/app/assets/images/favicon.ico +0 -0
- data/app/assets/images/stay_commerce/frontend/beach-666122_1280 (1).jpg +0 -0
- data/app/assets/images/stay_commerce/frontend/beach-666122_1280.jpg +0 -0
- data/app/assets/stylesheets/stay_commerce/frontend/application.css +15 -0
- data/app/controllers/stay_commerce/frontend/application_controller.rb +8 -0
- data/app/controllers/stay_commerce/frontend/welcome_controller.rb +6 -0
- data/app/helpers/stay_commerce/frontend/application_helper.rb +6 -0
- data/app/javascript/Images/404error.jpg +0 -0
- data/app/javascript/Images/Facebook.svg +3 -0
- data/app/javascript/Images/Google.svg +6 -0
- data/app/javascript/Images/beach-2245867_1280.jpg +0 -0
- data/app/javascript/Images/beach.jpg +0 -0
- data/app/javascript/Images/beach2.jpg +0 -0
- data/app/javascript/Images/beach3.jpg +0 -0
- data/app/javascript/Images/beach4.jpg +0 -0
- data/app/javascript/Images/beach5.jpg +0 -0
- data/app/javascript/Images/beach6.jpg +0 -0
- data/app/javascript/Images/beach7.jpg +0 -0
- data/app/javascript/Images/beach8.jpg +0 -0
- data/app/javascript/Images/bg-image.jpg +0 -0
- data/app/javascript/Images/bgimage.jpg +0 -0
- data/app/javascript/Images/blog-1.jpg +0 -0
- data/app/javascript/Images/gallery.png +0 -0
- data/app/javascript/Images/home 5.jpg +0 -0
- data/app/javascript/Images/home1.jpg +0 -0
- data/app/javascript/Images/home2.jpg +0 -0
- data/app/javascript/Images/home3.jpg +0 -0
- data/app/javascript/Images/home6.jpg +0 -0
- data/app/javascript/Images/hotel1.jpg +0 -0
- data/app/javascript/Images/room1.jpg +0 -0
- data/app/javascript/Images/room2.jpg +0 -0
- data/app/javascript/Images/room3.jpg +0 -0
- data/app/javascript/Images/room4.jpg +0 -0
- data/app/javascript/Images/wine-4520213_1280.jpg +0 -0
- data/app/javascript/application.js +1 -0
- data/app/javascript/react/Api/apiConstants.js +47 -0
- data/app/javascript/react/assets/beach-2245867_1280.jpg +0 -0
- data/app/javascript/react/assets/logo.png +0 -0
- data/app/javascript/react/assets/logo_updated.png +0 -0
- data/app/javascript/react/components/AboutUsPage/AboutPage.jsx +41 -0
- data/app/javascript/react/components/AboutusFront/About.jsx +37 -0
- data/app/javascript/react/components/Accommodation/Accommodation.jsx +32 -0
- data/app/javascript/react/components/Accommodation/NormalListing.jsx +50 -0
- data/app/javascript/react/components/Accommodation/SpecialListing.jsx +51 -0
- data/app/javascript/react/components/Accountpage/AccountInfo.jsx +217 -0
- data/app/javascript/react/components/Accountpage/AccountPage.jsx +27 -0
- data/app/javascript/react/components/Accountpage/CommonPage.jsx +24 -0
- data/app/javascript/react/components/AddNewProperty/CommonLayout.jsx +68 -0
- data/app/javascript/react/components/AddNewProperty/Description.jsx +229 -0
- data/app/javascript/react/components/AddNewProperty/Details.jsx +234 -0
- data/app/javascript/react/components/AddNewProperty/Images.jsx +196 -0
- data/app/javascript/react/components/AddNewProperty/Location.jsx +239 -0
- data/app/javascript/react/components/AddNewProperty/Room.jsx +1132 -0
- data/app/javascript/react/components/AvatarDropdown/AvatarDropDown.jsx +142 -0
- data/app/javascript/react/components/BlogDesign/BlogsLatest.jsx +67 -0
- data/app/javascript/react/components/ContactUs/Contact.jsx +89 -0
- data/app/javascript/react/components/FacilitiesSection/Facilities.jsx +66 -0
- data/app/javascript/react/components/FixedNavbar/FixedNav.jsx +88 -0
- data/app/javascript/react/components/ForgetPassword/ForgetPassword.jsx +103 -0
- data/app/javascript/react/components/Gallery/Gallery.jsx +164 -0
- data/app/javascript/react/components/GalleryModalLight/GalleryModalLight.jsx +35 -0
- data/app/javascript/react/components/GallerySlider/GallerySlider.jsx +58 -0
- data/app/javascript/react/components/Headers/PropertyCard.jsx +46 -0
- data/app/javascript/react/components/HeroSectionDesign/BookingForm.jsx +178 -0
- data/app/javascript/react/components/HeroSectionDesign/HeroSection.jsx +29 -0
- data/app/javascript/react/components/HeroSectionDesign/MyPropertiesListing.jsx +104 -0
- data/app/javascript/react/components/HeroSectionDesign/PropertiesPage.jsx +122 -0
- data/app/javascript/react/components/HotelListing/Listing.jsx +48 -0
- data/app/javascript/react/components/Layout/Layout.js +18 -0
- data/app/javascript/react/components/Listing-stay-Detail/AmenitiesFeatures.jsx +58 -0
- data/app/javascript/react/components/Listing-stay-Detail/AmenitiesModal.jsx +250 -0
- data/app/javascript/react/components/Listing-stay-Detail/ApartmentCard.jsx +120 -0
- data/app/javascript/react/components/Listing-stay-Detail/BookingModal.jsx +398 -0
- data/app/javascript/react/components/Listing-stay-Detail/CheckoutForm.jsx +296 -0
- data/app/javascript/react/components/Listing-stay-Detail/ListingStayDetailPage.jsx +512 -0
- data/app/javascript/react/components/Listing-stay-Detail/PropertyDescription.jsx +76 -0
- data/app/javascript/react/components/Listing-stay-Detail/PropertyDetailsCard.jsx +62 -0
- data/app/javascript/react/components/Listing-stay-Detail/Reviews.jsx +132 -0
- data/app/javascript/react/components/Listing-stay-Detail/RoomDescriptionModal.jsx +105 -0
- data/app/javascript/react/components/Listing-stay-Detail/Rules.jsx +23 -0
- data/app/javascript/react/components/ListingImageGallery/ListingImageGallery.jsx +30 -0
- data/app/javascript/react/components/LoginPage/LoginPage.jsx +115 -0
- data/app/javascript/react/components/MobileNav/MobileMenu.jsx +47 -0
- data/app/javascript/react/components/Navbar/Navbar.jsx +25 -0
- data/app/javascript/react/components/Page404/Page404.jsx +30 -0
- data/app/javascript/react/components/PropertyListing/MyProperties.jsx +146 -0
- data/app/javascript/react/components/PropertyListing/StayBooking/BookingDetails.jsx +178 -0
- data/app/javascript/react/components/PropertyListing/StayBooking/MyBooking.jsx +83 -0
- data/app/javascript/react/components/ResetPassword/ResetPassword.jsx +117 -0
- data/app/javascript/react/components/SignupPage/SignupPage.jsx +185 -0
- data/app/javascript/react/components/SmallNavbar/SmallNav.jsx +51 -0
- data/app/javascript/react/components/SocialAuth/SocialAuth.jsx +21 -0
- data/app/javascript/react/components/StayCard/StayCard.jsx +69 -0
- data/app/javascript/react/components/StayCard/StayCard2.jsx +45 -0
- data/app/javascript/react/components/StayCard/StayCard3.jsx +45 -0
- data/app/javascript/react/components/TestimonialSection/Testimonial.jsx +113 -0
- data/app/javascript/react/components/Unauthorized/Unauthorized.jsx +12 -0
- data/app/javascript/react/data/jsons/__countryListing.json +201 -0
- data/app/javascript/react/packs/App.js +26 -0
- data/app/javascript/react/packs/index.jsx +38 -0
- data/app/javascript/react/packs/routes/ParentRoute.jsx +14 -0
- data/app/javascript/react/packs/routes/Route.jsx +163 -0
- data/app/javascript/react/pages/AccommodationList.jsx +21 -0
- data/app/javascript/react/pages/Home.jsx +32 -0
- data/app/javascript/react/redux/slices/AuthSlice/AuthSlice.jsx +100 -0
- data/app/javascript/react/redux/slices/PropertySlice/PropertySlice.jsx +722 -0
- data/app/javascript/react/redux/slices/PropertySlice/Searchslice.jsx +36 -0
- data/app/javascript/react/redux/slices/UserSlice/UserSlice.jsx +215 -0
- data/app/javascript/react/redux/store.js +35 -0
- data/app/javascript/react/shared/Avatar/Avatar.jsx +32 -0
- data/app/javascript/react/shared/Badge/Badge.jsx +33 -0
- data/app/javascript/react/shared/Button/Button.jsx +67 -0
- data/app/javascript/react/shared/Button/ButtonPrimary.jsx +11 -0
- data/app/javascript/react/shared/Button/ButtonSelect.jsx +9 -0
- data/app/javascript/react/shared/Checkbox/Checkbox.jsx +38 -0
- data/app/javascript/react/shared/CurrencySymbol.jsx +6 -0
- data/app/javascript/react/shared/DateField/CustomDatePicker.jsx +69 -0
- data/app/javascript/react/shared/FooterSection/Footer.jsx +75 -0
- data/app/javascript/react/shared/FormField/FormField.jsx +75 -0
- data/app/javascript/react/shared/FormItem/FormItem.jsx +20 -0
- data/app/javascript/react/shared/Input/Input.jsx +27 -0
- data/app/javascript/react/shared/Label/Label.jsx +12 -0
- data/app/javascript/react/shared/Modal.jsx +20 -0
- data/app/javascript/react/shared/NcImage/NcImage.jsx +101 -0
- data/app/javascript/react/shared/NcImage/PlaceIcon.jsx +31 -0
- data/app/javascript/react/shared/NcImage/placecImageIcon.svg +6 -0
- data/app/javascript/react/shared/Select/Select.jsx +20 -0
- data/app/javascript/react/styles/404error.scss +58 -0
- data/app/javascript/react/styles/ApartmentCard.scss +126 -0
- data/app/javascript/react/styles/BookingDetails.scss +457 -0
- data/app/javascript/react/styles/Modal.scss +36 -0
- data/app/javascript/react/styles/PropertiesPage.scss +219 -0
- data/app/javascript/react/styles/RenderSection.scss +480 -0
- data/app/javascript/react/styles/about.scss +97 -0
- data/app/javascript/react/styles/accountinfo.scss +67 -0
- data/app/javascript/react/styles/accountpage.scss +36 -0
- data/app/javascript/react/styles/amenitiesfeatures.scss +223 -0
- data/app/javascript/react/styles/application.scss +87 -0
- data/app/javascript/react/styles/avatar.scss +39 -0
- data/app/javascript/react/styles/avatardropdown.scss +57 -0
- data/app/javascript/react/styles/badge.scss +90 -0
- data/app/javascript/react/styles/blog.scss +100 -0
- data/app/javascript/react/styles/bookingform.scss +124 -0
- data/app/javascript/react/styles/button.scss +44 -0
- data/app/javascript/react/styles/buttonprimary.scss +32 -0
- data/app/javascript/react/styles/checkbox.scss +37 -0
- data/app/javascript/react/styles/commonlayout.scss +83 -0
- data/app/javascript/react/styles/commonpage.scss +51 -0
- data/app/javascript/react/styles/contact.scss +173 -0
- data/app/javascript/react/styles/customdatepicker.scss +120 -0
- data/app/javascript/react/styles/description.scss +21 -0
- data/app/javascript/react/styles/details.scss +88 -0
- data/app/javascript/react/styles/facilities.scss +131 -0
- data/app/javascript/react/styles/fixednavbar.scss +137 -0
- data/app/javascript/react/styles/fonts.scss +22 -0
- data/app/javascript/react/styles/footer.scss +300 -0
- data/app/javascript/react/styles/forgetpassword.scss +68 -0
- data/app/javascript/react/styles/formfield.scss +39 -0
- data/app/javascript/react/styles/formitem.scss +20 -0
- data/app/javascript/react/styles/gallery.scss +142 -0
- data/app/javascript/react/styles/gallerymodallight.scss +137 -0
- data/app/javascript/react/styles/galleryslider.scss +114 -0
- data/app/javascript/react/styles/header.scss +49 -0
- data/app/javascript/react/styles/herosection.scss +61 -0
- data/app/javascript/react/styles/images.scss +112 -0
- data/app/javascript/react/styles/input.scss +58 -0
- data/app/javascript/react/styles/label.scss +11 -0
- data/app/javascript/react/styles/listing.scss +94 -0
- data/app/javascript/react/styles/listingimagegallery.scss +57 -0
- data/app/javascript/react/styles/listingstaydetailpage.scss +887 -0
- data/app/javascript/react/styles/location.scss +66 -0
- data/app/javascript/react/styles/loginpage.scss +150 -0
- data/app/javascript/react/styles/mobilemenu.scss +53 -0
- data/app/javascript/react/styles/mybooking.scss +104 -0
- data/app/javascript/react/styles/myproperty.scss +51 -0
- data/app/javascript/react/styles/ncimage.scss +24 -0
- data/app/javascript/react/styles/normallisting.scss +95 -0
- data/app/javascript/react/styles/property-description.scss +75 -0
- data/app/javascript/react/styles/propertycard.scss +48 -0
- data/app/javascript/react/styles/propertydetailscard.scss +302 -0
- data/app/javascript/react/styles/resetpassword.scss +79 -0
- data/app/javascript/react/styles/reviews.scss +185 -0
- data/app/javascript/react/styles/room.scss +275 -0
- data/app/javascript/react/styles/rooms.scss +0 -0
- data/app/javascript/react/styles/select.scss +44 -0
- data/app/javascript/react/styles/signuppage.scss +132 -0
- data/app/javascript/react/styles/smallnav.scss +94 -0
- data/app/javascript/react/styles/socialauth.scss +62 -0
- data/app/javascript/react/styles/speciallisting.scss +94 -0
- data/app/javascript/react/styles/staycard.scss +77 -0
- data/app/javascript/react/styles/staycard2.scss +115 -0
- data/app/javascript/react/styles/testimonial.scss +216 -0
- data/app/javascript/react/styles/unauthorized.scss +22 -0
- data/app/javascript/react/styles/variables.scss +3 -0
- data/app/javascript/react/styles/wrapper.scss +4 -0
- data/app/javascript/react/utils/formSchema.js +120 -0
- data/app/javascript/react/utils/helpers/APIHelper.jsx +55 -0
- data/app/javascript/react/utils/helpers/ErrorHandler.js +21 -0
- data/app/javascript/react/utils/helpers/InfoHandler.js +15 -0
- data/app/javascript/react/utils/helpers/SuccessHandler.js +12 -0
- data/app/javascript/react/utils/helpers/isInViewPortIntersectionObserver.jsx +39 -0
- data/app/jobs/stay_commerce/frontend/application_job.rb +6 -0
- data/app/mailers/stay_commerce/frontend/application_mailer.rb +8 -0
- data/app/models/stay_commerce/frontend/application_record.rb +7 -0
- data/app/views/layouts/stay_commerce/frontend/application.html.erb +61 -0
- data/app/views/stay_commerce/frontend/welcome/index.html.erb +2 -0
- data/config/initializers/cors.rb +6 -0
- data/config/initializers/devise.rb +359 -0
- data/config/routes.rb +11 -0
- data/lib/stay_commerce/frontend/engine.rb +14 -0
- data/lib/stay_commerce/frontend/version.rb +5 -0
- data/lib/stay_commerce/frontend.rb +8 -0
- data/lib/tasks/stay_commerce/frontend_tasks.rake +4 -0
- metadata +370 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
2
|
+
import { Calendar, Users, MapPin, Ship, Phone } from "lucide-react";
|
3
|
+
import GallerySlider from "../../GallerySlider/GallerySlider";
|
4
|
+
import { getBookingDetails } from "../../../redux/slices/PropertySlice/PropertySlice";
|
5
|
+
import { useParams } from "react-router-dom";
|
6
|
+
import { useDispatch } from "react-redux";
|
7
|
+
import { useSelector } from "react-redux";
|
8
|
+
import "../../../styles/BookingDetails.scss";
|
9
|
+
|
10
|
+
const BookingInterface = () => {
|
11
|
+
const dispatch = useDispatch();
|
12
|
+
const [bookingRequestDetails, setBookingRequestDetails] = useState(null);
|
13
|
+
const { id } = useParams();
|
14
|
+
const { data: currentUser } = useSelector((state) => state.user);
|
15
|
+
const displayUser = currentUser?.is_host
|
16
|
+
? bookingRequestDetails?.user
|
17
|
+
: bookingRequestDetails?.property_user;
|
18
|
+
const location = `${bookingRequestDetails?.property?.city}, ${bookingRequestDetails?.property?.state}, ${bookingRequestDetails?.property?.country}`;
|
19
|
+
|
20
|
+
const fetchAllManageBooking = async () => {
|
21
|
+
const action = await dispatch(getBookingDetails(id));
|
22
|
+
if (action?.payload?.success) {
|
23
|
+
const data = action.payload.booking;
|
24
|
+
setBookingRequestDetails(data);
|
25
|
+
}
|
26
|
+
};
|
27
|
+
|
28
|
+
useEffect(() => {
|
29
|
+
fetchAllManageBooking();
|
30
|
+
}, [dispatch]);
|
31
|
+
|
32
|
+
return (
|
33
|
+
<div className="container">
|
34
|
+
<div className="booking-container">
|
35
|
+
<div className="sidebar">
|
36
|
+
{/* Contact Info */}
|
37
|
+
<div className="contact-card">
|
38
|
+
<div className="profile-header">
|
39
|
+
<div className="profile-avatar">
|
40
|
+
{displayUser?.image ? (
|
41
|
+
<img
|
42
|
+
src={displayUser.image}
|
43
|
+
alt={displayUser.full_name}
|
44
|
+
className="avatar-image-deatils"
|
45
|
+
/>
|
46
|
+
) : (
|
47
|
+
<span className="avatar-initial">
|
48
|
+
{displayUser?.full_name?.charAt(0) || "U"}
|
49
|
+
</span>
|
50
|
+
)}
|
51
|
+
</div>
|
52
|
+
|
53
|
+
<div className="profile-info">
|
54
|
+
<h3 className="profile-name">{displayUser?.full_name}</h3>
|
55
|
+
<p className="profile-nationality">Nationality: Peru</p>
|
56
|
+
</div>
|
57
|
+
</div>
|
58
|
+
|
59
|
+
<div className="contact-details">
|
60
|
+
<div className="contact-field">
|
61
|
+
<span className="field-label">Language:</span>
|
62
|
+
<span className="field-value">Italian, Peruvian, English</span>
|
63
|
+
</div>
|
64
|
+
|
65
|
+
<div className="contact-field">
|
66
|
+
<span className="field-label">Email:</span>
|
67
|
+
<div className="email-container">
|
68
|
+
<span className="field-value">{displayUser?.email}</span>
|
69
|
+
<span className="verified-badge">Verified</span>
|
70
|
+
</div>
|
71
|
+
</div>
|
72
|
+
|
73
|
+
<div className="contact-field">
|
74
|
+
<span className="field-label">Phone:</span>
|
75
|
+
<div className="phone-container">
|
76
|
+
<Phone className="contact-icon" />
|
77
|
+
<span className="field-value">{displayUser?.phone}</span>
|
78
|
+
</div>
|
79
|
+
</div>
|
80
|
+
|
81
|
+
<div className="contact-field">
|
82
|
+
<span className="field-label">About:</span>
|
83
|
+
<p className="about-text">
|
84
|
+
{displayUser?.about_me || "No bio available."}
|
85
|
+
</p>
|
86
|
+
</div>
|
87
|
+
</div>
|
88
|
+
</div>
|
89
|
+
|
90
|
+
<div className="property-card">
|
91
|
+
<GallerySlider
|
92
|
+
images={bookingRequestDetails?.line_items[0]?.rooms?.room_images}
|
93
|
+
alt="Luxury Penthouse"
|
94
|
+
style={{ height: "300px" }}
|
95
|
+
/>
|
96
|
+
<div className="property-content">
|
97
|
+
<h3 className="property-title">
|
98
|
+
{bookingRequestDetails?.line_items[0]?.rooms?.name}
|
99
|
+
</h3>
|
100
|
+
<div className="property-features">
|
101
|
+
<div className="guest-badge">
|
102
|
+
<span className="guest-label">
|
103
|
+
{" "}
|
104
|
+
<Users className="feature-icon" />
|
105
|
+
Guests:
|
106
|
+
</span>
|
107
|
+
<span className="value">
|
108
|
+
{bookingRequestDetails?.number_of_guests}
|
109
|
+
</span>
|
110
|
+
</div>
|
111
|
+
<div className="feature">
|
112
|
+
<MapPin className="feature-icon" />
|
113
|
+
<span>{location}</span>
|
114
|
+
</div>
|
115
|
+
</div>
|
116
|
+
<div className="price-section-details">
|
117
|
+
<div className="period">Total</div>
|
118
|
+
<div className="amount">
|
119
|
+
$ {bookingRequestDetails?.item_total}
|
120
|
+
</div>
|
121
|
+
</div>
|
122
|
+
</div>
|
123
|
+
</div>
|
124
|
+
</div>
|
125
|
+
<div className="booking-grid">
|
126
|
+
{/* Main Booking Form */}
|
127
|
+
<div className="booking-form-section">
|
128
|
+
<div className="booking-form">
|
129
|
+
<h2 className="booking-title">
|
130
|
+
Booking {bookingRequestDetails?.number} for{" "}
|
131
|
+
{bookingRequestDetails?.property?.title}
|
132
|
+
</h2>
|
133
|
+
|
134
|
+
<div className="booking-details">
|
135
|
+
<div className="detail-row">
|
136
|
+
<span className="label">Date of Visit:</span>
|
137
|
+
<span className="value">
|
138
|
+
{bookingRequestDetails?.check_in_date} -{" "}
|
139
|
+
{bookingRequestDetails?.check_out_date}
|
140
|
+
</span>
|
141
|
+
</div>
|
142
|
+
<div className="detail-row">
|
143
|
+
<span className="label">Pay Amount:</span>
|
144
|
+
<span className="value">
|
145
|
+
$ {bookingRequestDetails?.item_total}
|
146
|
+
</span>
|
147
|
+
</div>
|
148
|
+
<div className="detail-row">
|
149
|
+
<span className="label">Guests:</span>
|
150
|
+
<span className="value">
|
151
|
+
{bookingRequestDetails?.number_of_guests}
|
152
|
+
</span>
|
153
|
+
</div>
|
154
|
+
</div>
|
155
|
+
|
156
|
+
<div className="action-buttons">
|
157
|
+
<button
|
158
|
+
className="btn btn-primary "
|
159
|
+
style={{
|
160
|
+
cursor: "not-allowed",
|
161
|
+
backgroundColor: "#495387",
|
162
|
+
}}
|
163
|
+
>
|
164
|
+
<Calendar className="icon" />
|
165
|
+
Booking Confirmed
|
166
|
+
</button>
|
167
|
+
</div>
|
168
|
+
</div>
|
169
|
+
</div>
|
170
|
+
|
171
|
+
{/* Sidebar */}
|
172
|
+
</div>
|
173
|
+
</div>{" "}
|
174
|
+
</div>
|
175
|
+
);
|
176
|
+
};
|
177
|
+
|
178
|
+
export default BookingInterface;
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import React, { useCallback, useEffect, useState } from "react";
|
2
|
+
import "../../../styles/mybooking.scss";
|
3
|
+
import StayCard from "../../StayCard/StayCard";
|
4
|
+
import {
|
5
|
+
getHostBookingsDetails,
|
6
|
+
getUserBookingsDetails,
|
7
|
+
} from "../../../redux/slices/PropertySlice/PropertySlice";
|
8
|
+
import { useDispatch, useSelector } from "react-redux";
|
9
|
+
import { useNavigate } from "react-router-dom";
|
10
|
+
|
11
|
+
const MyBooking = () => {
|
12
|
+
const dispatch = useDispatch();
|
13
|
+
const navigate = useNavigate();
|
14
|
+
const [bookingData, setBookingData] = useState(null);
|
15
|
+
const [query, setQuery] = useState("");
|
16
|
+
const [isLoading, setIsLoading] = useState(false);
|
17
|
+
const { data: currentUser } = useSelector((state) => state.user);
|
18
|
+
|
19
|
+
const fetchBookings = useCallback(
|
20
|
+
async (page) => {
|
21
|
+
setIsLoading(true);
|
22
|
+
try {
|
23
|
+
if (currentUser?.is_host) {
|
24
|
+
const response = await dispatch(
|
25
|
+
getHostBookingsDetails({ page })
|
26
|
+
).unwrap();
|
27
|
+
setBookingData(response);
|
28
|
+
} else {
|
29
|
+
const response = await dispatch(
|
30
|
+
getUserBookingsDetails({ page })
|
31
|
+
).unwrap();
|
32
|
+
setBookingData(response);
|
33
|
+
}
|
34
|
+
} catch (error) {
|
35
|
+
console.error("Error fetching bookings:", error);
|
36
|
+
} finally {
|
37
|
+
setIsLoading(false);
|
38
|
+
}
|
39
|
+
},
|
40
|
+
[dispatch, currentUser]
|
41
|
+
);
|
42
|
+
|
43
|
+
useEffect(() => {
|
44
|
+
fetchBookings(1);
|
45
|
+
}, [fetchBookings]);
|
46
|
+
|
47
|
+
return (
|
48
|
+
<div className="my-booking-container">
|
49
|
+
<div className="my-booking-content">
|
50
|
+
<h1 className="heading">My Bookings</h1>
|
51
|
+
<p className="subheading">
|
52
|
+
View the complete list of all your booking requests.
|
53
|
+
</p>
|
54
|
+
|
55
|
+
{/* <div className="search-bar">
|
56
|
+
<FormField
|
57
|
+
type="text"
|
58
|
+
value={query}
|
59
|
+
onChange={(e) => setQuery(e.target.value)}
|
60
|
+
placeholder="Search By Property Name..."
|
61
|
+
className="search-input"
|
62
|
+
/>
|
63
|
+
<ButtonPrimary className="search-button">Search</ButtonPrimary>
|
64
|
+
</div> */}
|
65
|
+
|
66
|
+
{/* Stay Cards Grid */}
|
67
|
+
<div className="stay-cards">
|
68
|
+
{isLoading ? (
|
69
|
+
<div className="loader">Loading bookings...</div>
|
70
|
+
) : bookingData?.bookings?.length > 0 ? (
|
71
|
+
bookingData.bookings.map((booking) => (
|
72
|
+
<StayCard key={booking.id} booking={booking} />
|
73
|
+
))
|
74
|
+
) : (
|
75
|
+
<p className="no-results">No bookings found.</p>
|
76
|
+
)}
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
</div>
|
80
|
+
);
|
81
|
+
};
|
82
|
+
|
83
|
+
export default MyBooking;
|
@@ -0,0 +1,117 @@
|
|
1
|
+
import React, { useEffect } from "react";
|
2
|
+
import { Formik, Form, Field, ErrorMessage } from "formik";
|
3
|
+
import { useDispatch } from "react-redux";
|
4
|
+
import { useNavigate, useLocation } from "react-router-dom";
|
5
|
+
import { toast } from "react-toastify";
|
6
|
+
import ButtonPrimary from "../../shared/Button/ButtonPrimary";
|
7
|
+
import "../../styles/resetpassword.scss";
|
8
|
+
import { createNewPassword } from "../../redux/slices/UserSlice/UserSlice";
|
9
|
+
import {editValidationSchema} from "../../utils/formSchema";
|
10
|
+
|
11
|
+
const ResetPassword = () => {
|
12
|
+
const dispatch = useDispatch();
|
13
|
+
const navigate = useNavigate();
|
14
|
+
const location = useLocation();
|
15
|
+
const searchParams = new URLSearchParams(location.search);
|
16
|
+
const resetTokenFromURL = searchParams.get("reset_password_token");
|
17
|
+
const [manualToken, setManualToken] = React.useState("");
|
18
|
+
const finalToken = resetTokenFromURL || manualToken;
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
return (
|
23
|
+
<div className="reset-password">
|
24
|
+
<div className="reset-password__container">
|
25
|
+
<h2 className="reset-password__title">Reset Password</h2>
|
26
|
+
<Formik
|
27
|
+
initialValues={{ password: "", confirmPassword: "" }}
|
28
|
+
validationSchema={editValidationSchema}
|
29
|
+
onSubmit={async (values, { setSubmitting }) => {
|
30
|
+
try {
|
31
|
+
dispatch(
|
32
|
+
createNewPassword({
|
33
|
+
token: finalToken,
|
34
|
+
payload: {
|
35
|
+
password: values.password,
|
36
|
+
confirm_password: values.confirmPassword,
|
37
|
+
message: "",
|
38
|
+
},
|
39
|
+
})
|
40
|
+
)
|
41
|
+
.unwrap()
|
42
|
+
.then((res) => {
|
43
|
+
if (res?.success) {
|
44
|
+
toast.success(res?.message || "Password reset successful!");
|
45
|
+
navigate("/login");
|
46
|
+
} else {
|
47
|
+
toast.error(res?.message || "Password reset failed.");
|
48
|
+
}
|
49
|
+
});
|
50
|
+
} catch (error) {
|
51
|
+
console.error("Failed to reset password:", error);
|
52
|
+
const errorMessage =
|
53
|
+
error?.response?.data?.message ||
|
54
|
+
"Failed to reset password. Please try again.";
|
55
|
+
toast.error(errorMessage);
|
56
|
+
} finally {
|
57
|
+
setSubmitting(false);
|
58
|
+
}
|
59
|
+
}}
|
60
|
+
>
|
61
|
+
{({ isSubmitting }) => (
|
62
|
+
<Form>
|
63
|
+
<div className="reset-password__field">
|
64
|
+
<label htmlFor="password" className="reset-password__label">
|
65
|
+
New Password
|
66
|
+
</label>
|
67
|
+
<Field
|
68
|
+
type="password"
|
69
|
+
name="password"
|
70
|
+
id="password"
|
71
|
+
placeholder="Enter your new password"
|
72
|
+
className="reset-password__input"
|
73
|
+
/>
|
74
|
+
<ErrorMessage
|
75
|
+
name="password"
|
76
|
+
component="div"
|
77
|
+
className="reset-password__error"
|
78
|
+
/>
|
79
|
+
</div>
|
80
|
+
|
81
|
+
<div className="reset-password__field">
|
82
|
+
<label
|
83
|
+
htmlFor="confirmPassword"
|
84
|
+
className="reset-password__label"
|
85
|
+
>
|
86
|
+
Confirm Password
|
87
|
+
</label>
|
88
|
+
<Field
|
89
|
+
type="password"
|
90
|
+
name="confirmPassword"
|
91
|
+
id="confirmPassword"
|
92
|
+
placeholder="Confirm your new password"
|
93
|
+
className="reset-password__input"
|
94
|
+
/>
|
95
|
+
<ErrorMessage
|
96
|
+
name="confirmPassword"
|
97
|
+
component="div"
|
98
|
+
className="reset-password__error"
|
99
|
+
/>
|
100
|
+
</div>
|
101
|
+
|
102
|
+
<ButtonPrimary
|
103
|
+
type="submit"
|
104
|
+
className="request-password-reset__button"
|
105
|
+
disabled={isSubmitting}
|
106
|
+
>
|
107
|
+
{isSubmitting ? "Updating..." : "Reset Password"}
|
108
|
+
</ButtonPrimary>
|
109
|
+
</Form>
|
110
|
+
)}
|
111
|
+
</Formik>
|
112
|
+
</div>
|
113
|
+
</div>
|
114
|
+
);
|
115
|
+
};
|
116
|
+
|
117
|
+
export default ResetPassword;
|
@@ -0,0 +1,185 @@
|
|
1
|
+
import React, { useState } from "react";
|
2
|
+
import { useFormik } from "formik";
|
3
|
+
import { useDispatch, useSelector } from "react-redux";
|
4
|
+
import { signupUser } from "../../redux/slices/AuthSlice/AuthSlice";
|
5
|
+
import { Link, useNavigate } from "react-router-dom";
|
6
|
+
import { signupSchema } from "../../utils/formSchema";
|
7
|
+
import successHandler from "../../utils/helpers/SuccessHandler";
|
8
|
+
import "../../styles/signuppage.scss";
|
9
|
+
import FormField from "../../shared/FormField/FormField";
|
10
|
+
import { getCurrentUser } from "../../redux/slices/UserSlice/UserSlice";
|
11
|
+
import "../../styles/formfield.scss";
|
12
|
+
import SocialAuth from "../SocialAuth/SocialAuth";
|
13
|
+
import ButtonSelect from "../../shared/Button/ButtonSelect";
|
14
|
+
|
15
|
+
const SignupPage = () => {
|
16
|
+
const dispatch = useDispatch();
|
17
|
+
const navigate = useNavigate();
|
18
|
+
const { loading } = useSelector((state) => state.auth);
|
19
|
+
const [activeTab, setActiveTab] = useState("user");
|
20
|
+
|
21
|
+
const formik = useFormik({
|
22
|
+
initialValues: {
|
23
|
+
first_name: "",
|
24
|
+
last_name: "",
|
25
|
+
email: "",
|
26
|
+
// phone: "",
|
27
|
+
password: "",
|
28
|
+
confirm_password: "",
|
29
|
+
// date_of_birth: "",
|
30
|
+
is_host: activeTab,
|
31
|
+
},
|
32
|
+
validationSchema: signupSchema,
|
33
|
+
onSubmit: (values, { setSubmitting, resetForm }) => {
|
34
|
+
setSubmitting(true);
|
35
|
+
const userData = {
|
36
|
+
// ...values,
|
37
|
+
first_name: values.first_name,
|
38
|
+
last_name: values.last_name,
|
39
|
+
email: values.email,
|
40
|
+
password: values.password,
|
41
|
+
comfirm_password: values.confirm_password,
|
42
|
+
// date_of_birth: values.date_of_birth,
|
43
|
+
// phone: values.phone,
|
44
|
+
type: activeTab,
|
45
|
+
};
|
46
|
+
dispatch(signupUser(userData))
|
47
|
+
.unwrap()
|
48
|
+
.then((response) => {
|
49
|
+
if (response?.access_token) {
|
50
|
+
localStorage.setItem("authToken", response.access_token);
|
51
|
+
successHandler("Signup successful! Welcome aboard!");
|
52
|
+
dispatch(getCurrentUser());
|
53
|
+
navigate("/");
|
54
|
+
resetForm();
|
55
|
+
}
|
56
|
+
})
|
57
|
+
.catch((error) => {
|
58
|
+
formik.setErrors({
|
59
|
+
apiError: error?.error_description || "Signup failed",
|
60
|
+
});
|
61
|
+
})
|
62
|
+
.finally(() => setSubmitting(false));
|
63
|
+
},
|
64
|
+
});
|
65
|
+
|
66
|
+
return (
|
67
|
+
<div className="signup-container">
|
68
|
+
<span className="logos">👑 STAY COMMERCE</span>
|
69
|
+
<div className="signup-card">
|
70
|
+
<div className="sign-title">
|
71
|
+
<h2>Signup</h2>
|
72
|
+
</div>
|
73
|
+
|
74
|
+
{/* Student & Host Selection */}
|
75
|
+
<div className="role-selection">
|
76
|
+
<ButtonSelect
|
77
|
+
className={`role-button ${activeTab === "user" ? "active" : ""}`}
|
78
|
+
onClick={() => setActiveTab("user")}
|
79
|
+
>
|
80
|
+
User
|
81
|
+
</ButtonSelect>
|
82
|
+
<ButtonSelect
|
83
|
+
className={`role-button ${activeTab === "host" ? "active" : ""}`}
|
84
|
+
onClick={() => setActiveTab("host")}
|
85
|
+
>
|
86
|
+
Host
|
87
|
+
</ButtonSelect>
|
88
|
+
</div>
|
89
|
+
|
90
|
+
{activeTab === "user" && (
|
91
|
+
<div className="social-login">
|
92
|
+
<SocialAuth />
|
93
|
+
<h4>OR</h4>
|
94
|
+
</div>
|
95
|
+
)}
|
96
|
+
|
97
|
+
<form className="signup-form" onSubmit={formik.handleSubmit}>
|
98
|
+
<FormField
|
99
|
+
label="First Name"
|
100
|
+
name="first_name"
|
101
|
+
type="text"
|
102
|
+
placeholder="First Name"
|
103
|
+
{...formik.getFieldProps("first_name")}
|
104
|
+
error={formik.touched.first_name && formik.errors.first_name}
|
105
|
+
/>
|
106
|
+
|
107
|
+
<FormField
|
108
|
+
label="Last Name"
|
109
|
+
name="last_name"
|
110
|
+
type="text"
|
111
|
+
placeholder="Last Name"
|
112
|
+
{...formik.getFieldProps("last_name")}
|
113
|
+
error={formik.touched.last_name && formik.errors.last_name}
|
114
|
+
/>
|
115
|
+
|
116
|
+
<FormField
|
117
|
+
label="Email"
|
118
|
+
name="email"
|
119
|
+
type="email"
|
120
|
+
placeholder="Email"
|
121
|
+
{...formik.getFieldProps("email")}
|
122
|
+
error={formik.touched.email && formik.errors.email}
|
123
|
+
/>
|
124
|
+
{/* {activeTab === "host" && (
|
125
|
+
<FormField
|
126
|
+
label="Phone Number"
|
127
|
+
name="phone"
|
128
|
+
type="text"
|
129
|
+
placeholder="Phone Number"
|
130
|
+
{...formik.getFieldProps("phone")}
|
131
|
+
error={formik.touched.phone && formik.errors.phone}
|
132
|
+
/>
|
133
|
+
)} */}
|
134
|
+
{/*
|
135
|
+
<FormField
|
136
|
+
label="Date of Birth"
|
137
|
+
name="date_of_birth"
|
138
|
+
type="date"
|
139
|
+
placeholder="Date of Birth"
|
140
|
+
{...formik.getFieldProps("date_of_birth")}
|
141
|
+
error={formik.touched.date_of_birth && formik.errors.date_of_birth}
|
142
|
+
/> */}
|
143
|
+
|
144
|
+
<FormField
|
145
|
+
label="Password"
|
146
|
+
name="password"
|
147
|
+
type="password"
|
148
|
+
placeholder="Password"
|
149
|
+
{...formik.getFieldProps("password")}
|
150
|
+
error={formik.touched.password && formik.errors.password}
|
151
|
+
/>
|
152
|
+
|
153
|
+
<FormField
|
154
|
+
label="Confirm Password"
|
155
|
+
name="confirm_password"
|
156
|
+
type="password"
|
157
|
+
placeholder="Confirm Password"
|
158
|
+
{...formik.getFieldProps("confirm_password")}
|
159
|
+
error={
|
160
|
+
formik.touched.confirm_password && formik.errors.confirm_password
|
161
|
+
}
|
162
|
+
/>
|
163
|
+
|
164
|
+
<button
|
165
|
+
type="submit"
|
166
|
+
className="signup-button"
|
167
|
+
disabled={formik.isSubmitting || loading}
|
168
|
+
>
|
169
|
+
{formik.isSubmitting || loading ? "Signing up..." : "Submit"}
|
170
|
+
</button>
|
171
|
+
|
172
|
+
{formik.errors.apiError && (
|
173
|
+
<p className="error-text">{formik.errors.apiError}</p>
|
174
|
+
)}
|
175
|
+
</form>
|
176
|
+
|
177
|
+
<p className="login-text">
|
178
|
+
Already have an account? <Link to="/login">Login</Link>
|
179
|
+
</p>
|
180
|
+
</div>
|
181
|
+
</div>
|
182
|
+
);
|
183
|
+
};
|
184
|
+
|
185
|
+
export default SignupPage;
|
@@ -0,0 +1,51 @@
|
|
1
|
+
// import React from "react";
|
2
|
+
// import { Link, useLocation } from "react-router-dom";
|
3
|
+
// import "../../styles/fixednavbar.scss";
|
4
|
+
// import MobileMenu from "../MobileNav/MobileMenu";
|
5
|
+
// import "../../styles/smallnav.scss";
|
6
|
+
|
7
|
+
|
8
|
+
// function SmallNavbar() {
|
9
|
+
// const location = useLocation();
|
10
|
+
// return (
|
11
|
+
// <nav className="navbar small">
|
12
|
+
// <div className="wrap">
|
13
|
+
// <div className="small">
|
14
|
+
// <div className="navContentSmall">
|
15
|
+
// {/* Logo */}
|
16
|
+
// <div className="logo">
|
17
|
+
// <span className="logospan">👑 STAY COMMERCE</span>
|
18
|
+
// </div>
|
19
|
+
|
20
|
+
|
21
|
+
// <div className="navMenu smallMenu">
|
22
|
+
// {[
|
23
|
+
// { name: "HOME", path: "/" },
|
24
|
+
// { name: "ABOUT US", path: "/about-us" },
|
25
|
+
// { name: "ACCOMMODATION", path: "/accommodation" },
|
26
|
+
// { name: "GALLERY", path: "/gallery" },
|
27
|
+
// { name: "BLOG", path: "/blog" },
|
28
|
+
// { name: "ELEMENT", path: "/element" },
|
29
|
+
// { name: "CONTACT", path: "/contact" },
|
30
|
+
// ].map((item) => (
|
31
|
+
// <Link
|
32
|
+
// key={item.name}
|
33
|
+
// to={item.path}
|
34
|
+
// className={`navLink ${
|
35
|
+
// location.pathname === item.path ? "active" : ""
|
36
|
+
// }`}
|
37
|
+
// >
|
38
|
+
// {item.name}
|
39
|
+
// </Link>
|
40
|
+
// ))}
|
41
|
+
// </div>
|
42
|
+
// < MobileMenu />
|
43
|
+
// </div>
|
44
|
+
// </div>
|
45
|
+
// </div>
|
46
|
+
// </nav>
|
47
|
+
|
48
|
+
// );
|
49
|
+
// }
|
50
|
+
|
51
|
+
// export default SmallNavbar;
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import facebookSvg from "../../../Images/Facebook.svg";
|
3
|
+
import googleSvg from "../../../Images/Google.svg";
|
4
|
+
import "../../styles/socialauth.scss";
|
5
|
+
|
6
|
+
const SocialAuth = () => {
|
7
|
+
return (
|
8
|
+
<div className="social-auth">
|
9
|
+
<button className="social-button google">
|
10
|
+
<img src={googleSvg} alt="Google" />
|
11
|
+
Google
|
12
|
+
</button>
|
13
|
+
<button className="social-button facebook">
|
14
|
+
<img src={facebookSvg} alt="Facebook" />
|
15
|
+
Facebook
|
16
|
+
</button>
|
17
|
+
</div>
|
18
|
+
);
|
19
|
+
};
|
20
|
+
|
21
|
+
export default SocialAuth;
|