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,285 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { CardElement, useElements, useStripe } from "@stripe/react-stripe-js";
3
+ import { useDispatch } from "react-redux";
4
+ import { toast } from "react-toastify";
5
+ import { CreditCard, Plus, X, Trash2, Lock, Shield } from "lucide-react";
6
+ import "../../styles/CardManager.scss";
7
+ import {
8
+ deleteCard,
9
+ getCard,
10
+ saveCard,
11
+ } from "../../redux/slices/PropertySlice/PropertySlice";
12
+
13
+ const CardManager = () => {
14
+ const dispatch = useDispatch();
15
+ const stripe = useStripe();
16
+ const elements = useElements();
17
+
18
+ const [savedCards, setSavedCards] = useState([]);
19
+ const [loading, setLoading] = useState(false);
20
+ const [addingCards, setAddingCards] = useState([]);
21
+ const [deletingCard, setDeletingCard] = useState(null);
22
+
23
+ useEffect(() => {
24
+ dispatch(getCard())
25
+ .unwrap()
26
+ .then((data) => {
27
+ if (Array.isArray(data)) {
28
+ setSavedCards(data);
29
+ } else if (data?.payment_method_token) {
30
+ setSavedCards([data]);
31
+ } else {
32
+ setSavedCards([]);
33
+ }
34
+ })
35
+ .catch(() => {
36
+ toast.error("❌ Could not retrieve cards");
37
+ setSavedCards([]);
38
+ });
39
+ }, [dispatch]);
40
+
41
+ const handleDeleteCard = async (cardId) => {
42
+ setDeletingCard(cardId);
43
+ try {
44
+ await dispatch(deleteCard(cardId)).unwrap();
45
+ setSavedCards((prev) => prev.filter((card) => card.id !== cardId));
46
+ toast.success("Card deleted successfully");
47
+ } catch (error) {
48
+ toast.error(`❌ ${error.message}`);
49
+ } finally {
50
+ setDeletingCard(null);
51
+ }
52
+ };
53
+
54
+ const handleAddCard = () => {
55
+ const formId = Date.now();
56
+ setAddingCards((prev) => [...prev, formId]);
57
+ };
58
+
59
+ const handleSaveCard = async (formId) => {
60
+ if (!stripe || !elements) {
61
+ toast.error("❌ Stripe not ready");
62
+ return;
63
+ }
64
+
65
+ const cardElement = elements.getElement(CardElement);
66
+ if (!cardElement) {
67
+ toast.error("Card element not found");
68
+ return;
69
+ }
70
+
71
+ setLoading(true);
72
+ try {
73
+ const { token, error } = await stripe.createToken(cardElement);
74
+ if (error) throw new Error(error.message);
75
+
76
+ const cardData = {
77
+ cc_number: token?.card?.last4 || "****",
78
+ month: token?.card?.exp_month,
79
+ year: token?.card?.exp_year,
80
+ card_token: token?.id,
81
+ };
82
+
83
+ const saved = await dispatch(saveCard(cardData)).unwrap();
84
+
85
+ setSavedCards((prev) => [...prev, saved]);
86
+ setAddingCards((prev) => prev.filter((id) => id !== formId));
87
+ toast.success("Card added successfully");
88
+ } catch (error) {
89
+ toast.error(`❌ ${error.message}`);
90
+ } finally {
91
+ setLoading(false);
92
+ }
93
+ };
94
+
95
+ const handleCancelAdd = (formId) => {
96
+ setAddingCards((prev) => prev.filter((id) => id !== formId));
97
+ };
98
+
99
+ const getCardIcon = (brand) => {
100
+ switch (brand?.toLowerCase()) {
101
+ case "visa":
102
+ return "💳";
103
+ case "mastercard":
104
+ return "💳";
105
+ case "amex":
106
+ return "💳";
107
+ default:
108
+ return "💳";
109
+ }
110
+ };
111
+
112
+ return (
113
+ <div className="card-manager">
114
+ <div className="card-manager__container">
115
+ {/* Header */}
116
+ <div className="card-manager__header">
117
+ <div className="card-manager__header-icon">
118
+ <CreditCard className="icon" />
119
+ </div>
120
+ <h1 className="card-manager__title">Payment Cards</h1>
121
+ <p className="card-manager__subtitle">
122
+ Manage your saved payment methods securely
123
+ </p>
124
+ </div>
125
+ <div className="card-manager__content">
126
+ <div className="saved-cards">
127
+ <h2 className="saved-cards__title">
128
+ <Lock className="icon" />
129
+ Saved Cards ({savedCards?.length})
130
+ </h2>
131
+
132
+ {savedCards?.length > 0 ? (
133
+ <div
134
+ className={`saved-cards__grid ${
135
+ savedCards?.length === 1 ? "single-card" : ""
136
+ }`}
137
+ >
138
+ {savedCards?.map((card) => (
139
+ <div
140
+ key={card.id}
141
+ className={`credit-card credit-card--${
142
+ card.brand || "default"
143
+ }`}
144
+ >
145
+ <div className="credit-card__pattern"></div>
146
+ <div className="credit-card__content">
147
+ <div className="credit-card__header">
148
+ <div className="credit-card__icon">
149
+ {getCardIcon(card.brand)}
150
+ </div>
151
+ <button
152
+ onClick={() => handleDeleteCard(card.id)}
153
+ disabled={deletingCard === card.id}
154
+ className="credit-card__delete-btn"
155
+ >
156
+ {deletingCard === card.id ? (
157
+ <div className="Card_spinner"></div>
158
+ ) : (
159
+ <Trash2 className="icon" />
160
+ )}
161
+ </button>
162
+ </div>
163
+
164
+ <div className="credit-card__number">
165
+ <p>•••• •••• •••• {card.cc_number?.slice(-4)}</p>
166
+ </div>
167
+
168
+ <div className="credit-card__details">
169
+ <div className="credit-card__expiry">
170
+ <p className="label">EXPIRES</p>
171
+ <p className="value">
172
+ {String(card.exp_month || card.month).padStart(
173
+ 2,
174
+ "0"
175
+ )}
176
+ /{String(card.exp_year || card.year).slice(-2)}
177
+ </p>
178
+ </div>
179
+ <div className="credit-card__type">
180
+ <p className="label">TYPE</p>
181
+ <p className="value">{card.brand || "Card"}</p>
182
+ </div>
183
+ </div>
184
+ </div>
185
+ </div>
186
+ ))}
187
+ </div>
188
+ ) : (
189
+ <div className="empty-state">
190
+ <div className="empty-state__icon">
191
+ <CreditCard className="icon" />
192
+ </div>
193
+ <p className="empty-state__title">No cards saved yet</p>
194
+ <p className="empty-state__subtitle">
195
+ Add your first payment method to get started
196
+ </p>
197
+ </div>
198
+ )}
199
+ </div>
200
+ {addingCards.map((formId) => (
201
+ <div key={formId} className="card-form">
202
+ <div className="card-form__container">
203
+ <div className="card-form__header">
204
+ <h3 className="card-form__title">
205
+ <Plus className="icon" />
206
+ Add New Card
207
+ </h3>
208
+ <button
209
+ onClick={() => handleCancelAdd(formId)}
210
+ className="card-form__close-btn"
211
+ >
212
+ <X className="icon" />
213
+ </button>
214
+ </div>
215
+ <div className="card-form__input">
216
+ <CardElement
217
+ className="stripe-card-element"
218
+ options={{
219
+ hidePostalCode: true,
220
+ style: {
221
+ base: {
222
+ fontSize: "16px",
223
+ color: "#424770",
224
+ "::placeholder": {
225
+ color: "#aab7c4",
226
+ },
227
+ },
228
+ },
229
+ }}
230
+ />
231
+ </div>
232
+
233
+ <div className="card-form__actions">
234
+ <button
235
+ onClick={() => handleSaveCard(formId)}
236
+ disabled={loading || !stripe || !elements}
237
+ className="btn btn--primary"
238
+ >
239
+ {loading ? (
240
+ <>
241
+ <div className="Card_spinner"></div>
242
+ Saving...
243
+ </>
244
+ ) : (
245
+ <>
246
+ <Shield className="icon" />
247
+ Save Card Securely
248
+ </>
249
+ )}
250
+ </button>
251
+ <button
252
+ onClick={() => handleCancelAdd(formId)}
253
+ className="btn btn--secondary"
254
+ >
255
+ Cancel
256
+ </button>
257
+ </div>
258
+ </div>
259
+ </div>
260
+ ))}
261
+ <div className="add-card-section">
262
+ <button
263
+ onClick={handleAddCard}
264
+ disabled={addingCards.length > 0}
265
+ className="btn btn--add-card"
266
+ >
267
+ <Plus className="icon" />
268
+ Add New Payment Method
269
+ </button>
270
+ </div>
271
+ </div>
272
+
273
+ {/* Security Footer */}
274
+ <div className="card-manager__footer">
275
+ <p>
276
+ <Lock className="icon" />
277
+ Your payment information is encrypted and secure
278
+ </p>
279
+ </div>
280
+ </div>
281
+ </div>
282
+ );
283
+ };
284
+
285
+ export default CardManager;
@@ -30,33 +30,29 @@ const CheckoutForm = ({ bookingId, totalAmount }) => {
30
30
  const dispatch = useDispatch();
31
31
  const [message, setMessage] = useState("");
32
32
  const [loading, setLoading] = useState(false);
33
- const [cardExists, setCardExists] = useState(false);
34
- const [paymentMethod, setPaymentMethod] = useState(null);
35
- const [cardId, setCardId] = useState(null);
33
+ const [cards, setCards] = useState([]);
34
+ const [selectedCard, setSelectedCard] = useState(null);
35
+ const [showNewCardForm, setShowNewCardForm] = useState(true);
36
36
  const [paymentMethodIds, setPaymentMethodIds] = useState([]);
37
-
38
37
  useEffect(() => {
39
- dispatch(getCard())
40
- .unwrap()
41
- .then((data) => {
42
- if (data?.payment_method_token) {
43
- setCardExists(true);
44
- setCardId(data.id);
45
- setPaymentMethod({
46
- id: data.payment_method_token,
47
- last4: data.cc_number?.slice(-4) || "****",
48
- });
38
+ const fetchCards = async () => {
39
+ try {
40
+ const data = await dispatch(getCard()).unwrap();
41
+ setCards(data || []);
42
+ if (data && data.length > 0) {
43
+ setSelectedCard(data[0].payment_method_token);
44
+ setShowNewCardForm(false); // Hide new card form if cards exist
49
45
  } else {
50
- setCardExists(false);
51
- setPaymentMethod(null);
46
+ setShowNewCardForm(true); // Show new card form if no cards
52
47
  }
53
- })
54
- .catch((err) => {
55
- console.error("Failed to get card:", err);
56
- toast.error("❌ Could not retrieve card");
57
- setCardExists(false);
58
- setPaymentMethod(null);
59
- });
48
+ } catch (err) {
49
+ console.error("Failed to get cards:", err);
50
+ toast.error(" Could not retrieve cards");
51
+ setShowNewCardForm(true); // Show new card form on error
52
+ }
53
+ };
54
+
55
+ fetchCards();
60
56
  }, [dispatch]);
61
57
 
62
58
  useEffect(() => {
@@ -73,17 +69,38 @@ const CheckoutForm = ({ bookingId, totalAmount }) => {
73
69
  fetchPaymentMethods();
74
70
  }, [dispatch]);
75
71
 
76
- const handleDeleteCard = async () => {
72
+ const handleDeleteCard = async (cardId) => {
77
73
  try {
78
74
  await dispatch(deleteCardThunk(cardId)).unwrap();
79
- setCardExists(false);
80
- setPaymentMethod(null);
75
+ const updatedCards = cards.filter((card) => card.id !== cardId);
76
+ setCards(updatedCards);
77
+
78
+ if (selectedCard === cardId) {
79
+ setSelectedCard(
80
+ updatedCards.length > 0 ? updatedCards[0].payment_method_token : null
81
+ );
82
+ }
83
+
84
+ if (updatedCards.length === 0) {
85
+ setShowNewCardForm(true);
86
+ }
87
+
81
88
  successHandler("Card deleted successfully");
82
89
  } catch (error) {
83
90
  toast.error(`❌ ${error.message}`);
84
91
  }
85
92
  };
86
93
 
94
+ const handleCardSelection = (paymentMethodToken) => {
95
+ setSelectedCard(paymentMethodToken);
96
+ setShowNewCardForm(false);
97
+ };
98
+
99
+ const handleAddNewCard = () => {
100
+ setShowNewCardForm(true);
101
+ setSelectedCard(null);
102
+ };
103
+
87
104
  const handleSubmit = async (e) => {
88
105
  e.preventDefault();
89
106
 
@@ -91,14 +108,17 @@ const CheckoutForm = ({ bookingId, totalAmount }) => {
91
108
  toast.error("❌ Stripe not ready");
92
109
  return;
93
110
  }
111
+
94
112
  setLoading(true);
95
113
  try {
96
- if (!cardExists) {
114
+ // If adding a new card
115
+ if (showNewCardForm) {
97
116
  const cardElement = elements.getElement(CardElement);
98
117
  if (!cardElement) throw new Error("Card element not found");
99
118
 
100
119
  const { token, error } = await stripe.createToken(cardElement);
101
120
  if (error) throw new Error(error.message);
121
+
102
122
  const cardData = {
103
123
  cc_number: token?.card?.last4 || "****",
104
124
  month: token?.card?.exp_month,
@@ -107,28 +127,23 @@ const CheckoutForm = ({ bookingId, totalAmount }) => {
107
127
  };
108
128
 
109
129
  const saved = await dispatch(saveCard(cardData)).unwrap();
110
-
111
- setPaymentMethod({
112
- id: saved.payment_method_token,
113
- last4: saved.cc_number?.slice(-4) || "****",
114
- });
115
- setCardExists(true);
116
- setCardId(saved.id);
117
-
130
+ setCards([...cards, saved]);
131
+ setSelectedCard(saved.payment_method_token);
132
+ setShowNewCardForm(false);
118
133
  toast.success("Card added successfully");
119
134
  setLoading(false);
120
- return;
135
+ return; // Return after adding card, let user explicitly click pay
121
136
  }
122
- if (!paymentMethod?.id) {
123
- toast.error("Please add your card.");
124
- setLoading(false);
125
- return;
137
+
138
+ // Proceed with payment
139
+ if (!selectedCard) {
140
+ throw new Error("Please select or add a payment method");
126
141
  }
127
142
 
128
143
  await dispatch(
129
144
  createPayment({
130
145
  bookingId,
131
- paymentMethodId: paymentMethod?.id,
146
+ paymentMethodId: selectedCard,
132
147
  })
133
148
  ).unwrap();
134
149
 
@@ -152,7 +167,85 @@ const CheckoutForm = ({ bookingId, totalAmount }) => {
152
167
 
153
168
  return (
154
169
  <form onSubmit={handleSubmit} style={{ marginTop: 20 }}>
155
- {!cardExists && (
170
+ {cards.length > 0 && (
171
+ <div style={{ marginBottom: 20 }}>
172
+ <h3 style={{ marginBottom: 15 }}>Saved Payment Methods</h3>
173
+ {cards.map((card) => (
174
+ <div
175
+ key={card.id}
176
+ style={{
177
+ padding: 15,
178
+ border: `1px solid ${
179
+ selectedCard === card.payment_method_token
180
+ ? "rgb(212 235 255)"
181
+ : "#ccc"
182
+ }`,
183
+ borderRadius: 6,
184
+ backgroundColor:
185
+ selectedCard === card.payment_method_token
186
+ ? "rgb(212 235 255)"
187
+ : "#f8f9fa",
188
+ marginBottom: 10,
189
+ color: "#155724",
190
+ position: "relative",
191
+ display: "flex",
192
+ alignItems: "center",
193
+ }}
194
+ >
195
+ <input
196
+ type="radio"
197
+ id={`card-${card.id}`}
198
+ name="paymentMethod"
199
+ checked={
200
+ selectedCard === card.payment_method_token && !showNewCardForm
201
+ }
202
+ onChange={() => handleCardSelection(card.payment_method_token)}
203
+ style={{ marginRight: 10 }}
204
+ />
205
+ <label htmlFor={`card-${card.id}`} style={{ flex: 1 }}>
206
+ ****{card.cc_number} - Expires {card.month}/{card.year}
207
+ </label>
208
+ <button
209
+ type="button"
210
+ onClick={() => handleDeleteCard(card.id)}
211
+ style={{
212
+ background: "none",
213
+ border: "none",
214
+ color: "#c82333",
215
+ cursor: "pointer",
216
+ fontWeight: "bold",
217
+ fontSize: 18,
218
+ }}
219
+ >
220
+
221
+ </button>
222
+ </div>
223
+ ))}
224
+ </div>
225
+ )}
226
+
227
+ {!showNewCardForm && cards.length > 0 && (
228
+ <button
229
+ type="button"
230
+ onClick={handleAddNewCard}
231
+ style={{
232
+ width: "100%",
233
+ padding: "10px",
234
+ backgroundColor: "var(--primary-color)",
235
+ border: "1px dashed #ccc",
236
+ borderRadius: 5,
237
+ cursor: "pointer",
238
+ fontSize: 16,
239
+ marginBottom: 20,
240
+ color: "#fff",
241
+ fontWeight: 600,
242
+ }}
243
+ >
244
+ + Add New Card
245
+ </button>
246
+ )}
247
+
248
+ {showNewCardForm && (
156
249
  <div
157
250
  style={{
158
251
  padding: 10,
@@ -177,48 +270,17 @@ const CheckoutForm = ({ bookingId, totalAmount }) => {
177
270
  </div>
178
271
  )}
179
272
 
180
- {cardExists && paymentMethod && (
181
- <div
182
- style={{
183
- padding: 15,
184
- border: "1px solid #28a745",
185
- borderRadius: 6,
186
- backgroundColor: "#d4edda",
187
- marginBottom: 20,
188
- color: "#155724",
189
- position: "relative",
190
- }}
191
- >
192
- ✅ Card on file: ****{paymentMethod.last4}
193
- <button
194
- type="button"
195
- onClick={handleDeleteCard}
196
- style={{
197
- position: "absolute",
198
- right: 10,
199
- top: 10,
200
- background: "none",
201
- border: "none",
202
- color: "#c82333",
203
- cursor: "pointer",
204
- fontWeight: "bold",
205
- fontSize: 18,
206
- }}
207
- >
208
-
209
- </button>
210
- </div>
211
- )}
212
-
213
273
  <button
214
274
  type="submit"
215
- disabled={!stripe || loading}
275
+ disabled={!stripe || loading || (!selectedCard && !showNewCardForm)}
216
276
  style={{
217
277
  width: "100%",
218
278
  padding: "12px 20px",
219
279
  backgroundColor:
220
- !stripe || loading ? "#ccc" : cardExists ? "#28a745" : "#ffcc00",
221
- color: cardExists ? "#fff" : "#000",
280
+ !stripe || loading
281
+ ? "var(--primary-color)"
282
+ : "var(--primary-color)",
283
+ color: "#fff",
222
284
  border: "none",
223
285
  borderRadius: 5,
224
286
  cursor: loading ? "not-allowed" : "pointer",
@@ -227,12 +289,12 @@ const CheckoutForm = ({ bookingId, totalAmount }) => {
227
289
  }}
228
290
  >
229
291
  {loading
230
- ? cardExists
231
- ? "Processing Payment..."
232
- : "Saving Card..."
233
- : cardExists
234
- ? `Pay $${(totalAmount / 100).toFixed(2)}`
235
- : "Add Card"}
292
+ ? showNewCardForm
293
+ ? "Adding Card..."
294
+ : "Processing Payment..."
295
+ : showNewCardForm
296
+ ? "Add Card"
297
+ : `Pay $${(totalAmount / 100).toFixed(2)}`}
236
298
  </button>
237
299
 
238
300
  {message && (
@@ -286,6 +348,7 @@ const CheckOutPagePageMain = ({ bookingId, totalAmount }) => {
286
348
  >
287
349
  Booking ID: {bookingId}
288
350
  </p>
351
+
289
352
  <Elements stripe={stripePromise}>
290
353
  <CheckoutForm bookingId={bookingId} totalAmount={totalAmount} />
291
354
  </Elements>
@@ -105,7 +105,6 @@ const StayDetailPageContainer = () => {
105
105
  const start = moment(bookingStart, "YYYY-MM-DD");
106
106
  const end = moment(bookingEnd, "YYYY-MM-DD");
107
107
  const uniqueMonths = new Set();
108
- const MAX_CHAR_LIMIT = 250;
109
108
  let current = start.clone();
110
109
  while (current.isBefore(end, "day") || current.isSame(end, "day")) {
111
110
  uniqueMonths.add(`${current.year()}-${current.month() + 1}`);
@@ -141,9 +140,6 @@ const StayDetailPageContainer = () => {
141
140
  try {
142
141
  const action = await dispatch(reserveBooking(postData));
143
142
  if (action?.type === "payment/reserveBooking/fulfilled" && action) {
144
- successHandler(
145
- "Booking request sent. Please ! wait for owner's confirmation!!"
146
- );
147
143
  const bookingId = action?.payload?.id;
148
144
  if (bookingId) {
149
145
  setError("");
@@ -445,7 +441,6 @@ const StayDetailPageContainer = () => {
445
441
  </div>
446
442
  );
447
443
  })}
448
-
449
444
  <BookingModal
450
445
  isOpen={isBookingModalOpen}
451
446
  onClose={closeBookingModal}
@@ -457,7 +452,6 @@ const StayDetailPageContainer = () => {
457
452
  </>
458
453
  );
459
454
  };
460
-
461
455
  return (
462
456
  <div className="container listing-detail-page">
463
457
  <header className="listing-header" onClick={handleOpenModalImageGallery}>
@@ -497,7 +491,7 @@ const StayDetailPageContainer = () => {
497
491
  <section className="similar-properties-section">
498
492
  {/* <RoomSection propertyData={propertyData} /> */}
499
493
  <RenderSection />
500
- <PropertyDetailsCard propertyData={propertyData} />
494
+ {/* <PropertyDetailsCard propertyData={propertyData} /> */}
501
495
  </section>
502
496
 
503
497
  {imageModal && (