main #7
@@ -26,11 +26,20 @@ export const cardsApi = createApi({
|
||||
getCardBookingDetails: builder.query({
|
||||
query: (bookingId) => `/website/passes/${bookingId}/details`,
|
||||
}),
|
||||
|
||||
storeRecipientDetails: builder.mutation({
|
||||
query: ({ recipientDetails, bookingId }) => ({ // keep the name of the variables being passed here same as when calling the mutation hook
|
||||
url: `/website/passes/${bookingId}/store-gift-details`,
|
||||
method: "PUT",
|
||||
body: recipientDetails
|
||||
}),
|
||||
}),
|
||||
})
|
||||
});
|
||||
|
||||
export const {
|
||||
useGetCardsinCartQuery,
|
||||
useGetCheckoutPageDataQuery,
|
||||
useGetCardBookingDetailsQuery
|
||||
useGetCardBookingDetailsQuery,
|
||||
useStoreRecipientDetailsMutation
|
||||
} = cardsApi;
|
||||
@@ -11,7 +11,8 @@ import { Separator } from '../components/ui/separator';
|
||||
import { useGetUserProfileDetailsQuery } from '../Redux/services/profile.service';
|
||||
import LoadingSpinner from '../components/LoadingSpinner';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useGetCardBookingDetailsQuery } from '../Redux/services/cards.service';
|
||||
import { useGetCardBookingDetailsQuery, useStoreRecepientDetailsMutation, useStoreRecipientDetailsMutation } from '../Redux/services/cards.service';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
export interface CheckoutOrderItem {
|
||||
city: string;
|
||||
@@ -174,6 +175,8 @@ export function PaymentDetailsPage({
|
||||
const [giftPhone, setGiftPhone] = useState('');
|
||||
const [giftCity, setGiftCity] = useState('');
|
||||
const [giftCountry, setGiftCountry] = useState('');
|
||||
const [giftIsd, setGiftIsd] = useState("")
|
||||
const [giftMessage, setGiftMessage] = useState("")
|
||||
|
||||
/* ── Profile Data (Same as ProfilePage) ── */
|
||||
const [formData, setFormData] = useState({
|
||||
@@ -191,8 +194,10 @@ export function PaymentDetailsPage({
|
||||
const userId = localStorage.getItem("userId");
|
||||
const { bookingId } = useParams()
|
||||
const { data: userDetails, isLoading } = useGetUserProfileDetailsQuery(userId);
|
||||
const { data: bookingDetails } = useGetCardBookingDetailsQuery(bookingId);
|
||||
console.log(bookingDetails)
|
||||
const { data } = useGetCardBookingDetailsQuery(bookingId);
|
||||
const [storeRecipientDetails, { isLoading: savingChanges }] = useStoreRecipientDetailsMutation();
|
||||
|
||||
const bookingDetails = data?.bookingDetails ?? null
|
||||
|
||||
// Populate formData from API (exactly like ProfilePage)
|
||||
useEffect(() => {
|
||||
@@ -230,6 +235,8 @@ export function PaymentDetailsPage({
|
||||
if (selectedTab === 'gift') {
|
||||
if (!giftFirstName.trim()) e.giftFirstName = 'Required';
|
||||
if (!giftLastName.trim()) e.giftLastName = 'Required';
|
||||
if (!giftIsd.trim()) e.giftIsd = 'Required';
|
||||
if (!giftMessage.trim()) e.giftMessage = 'Required';
|
||||
|
||||
if (!giftEmail.trim() || !/\S+@\S+\.\S+/.test(giftEmail)) {
|
||||
e.giftEmail = 'Valid email required';
|
||||
@@ -246,17 +253,44 @@ export function PaymentDetailsPage({
|
||||
return e;
|
||||
};
|
||||
|
||||
const recipientDetails = {
|
||||
isForSelf: true,
|
||||
recipientFirstName: giftFirstName,
|
||||
recipientLastName: giftLastName,
|
||||
recipientEmail: giftEmail,
|
||||
recipientIsdCode: `+${giftIsd}`,
|
||||
recipientPhone: giftPhone,
|
||||
recipientCity: giftCity,
|
||||
recipientCountry: giftCountry,
|
||||
giftMessage: giftMessage,
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
|
||||
const handleSaveProfile = async () => {
|
||||
try {
|
||||
console.log("Saving profile...", recipientDetails);
|
||||
const response = await storeRecipientDetails({ recipientDetails, bookingId });
|
||||
console.log(response)
|
||||
toast.success("gift details saved successfully!");
|
||||
} catch (error) {
|
||||
console.error("Error saving profile:", error);
|
||||
toast.error("Failed to update profile. Please try again.");
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const e = validate();
|
||||
setErrors(e);
|
||||
if (Object.keys(e).length > 0) return;
|
||||
|
||||
setSubmitting(true);
|
||||
setTimeout(() => {
|
||||
setSubmitting(false);
|
||||
onPaymentComplete();
|
||||
}, 1800);
|
||||
try {
|
||||
console.log("Saving profile...", recipientDetails);
|
||||
const response = await storeRecipientDetails({ recipientDetails, bookingId });
|
||||
console.log(response)
|
||||
toast.success("gift details saved successfully!");
|
||||
} catch (error) {
|
||||
console.error("Error saving profile:", error);
|
||||
toast.error("Failed to update profile. Please try again.");
|
||||
}
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
@@ -406,16 +440,15 @@ export function PaymentDetailsPage({
|
||||
placeholder="Enter recipient's last name"
|
||||
error={errors.giftLastName}
|
||||
/>
|
||||
|
||||
<Field
|
||||
label="Recipient Email"
|
||||
value={giftEmail}
|
||||
onChange={setGiftEmail}
|
||||
type="email"
|
||||
placeholder="Enter recipient's email"
|
||||
error={errors.giftEmail}
|
||||
label="Recipient ISD Code"
|
||||
value={giftIsd}
|
||||
onChange={setGiftIsd}
|
||||
placeholder="Enter recipient's ISD"
|
||||
error={errors.giftIsd}
|
||||
/>
|
||||
|
||||
|
||||
<Field
|
||||
label="Recipient Phone"
|
||||
value={giftPhone}
|
||||
@@ -425,6 +458,15 @@ export function PaymentDetailsPage({
|
||||
error={errors.giftPhone}
|
||||
/>
|
||||
|
||||
<Field
|
||||
label="Recipient Email"
|
||||
value={giftEmail}
|
||||
onChange={setGiftEmail}
|
||||
type="email"
|
||||
placeholder="Enter recipient's email"
|
||||
error={errors.giftEmail}
|
||||
/>
|
||||
|
||||
<Field
|
||||
label="Recipient City"
|
||||
value={giftCity}
|
||||
@@ -440,6 +482,13 @@ export function PaymentDetailsPage({
|
||||
placeholder="Enter recipient's country"
|
||||
error={errors.giftCountry}
|
||||
/>
|
||||
<Field
|
||||
label="Gift Message"
|
||||
value={giftMessage}
|
||||
onChange={setGiftMessage}
|
||||
placeholder="Enter gift message"
|
||||
error={errors.giftMessage}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
@@ -487,26 +536,26 @@ export function PaymentDetailsPage({
|
||||
|
||||
<div className="px-6 py-5 border-b border-gray-100">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className={`w-16 h-10 rounded-lg flex-shrink-0 flex items-center justify-center ${bookingDetails?.city?.cardMode.toLowerCase() === 'flexi'
|
||||
<div className={`w-16 h-10 rounded-lg flex-shrink-0 flex items-center justify-center ${bookingDetails?.cardMode.toLowerCase() === 'flexi'
|
||||
? 'bg-gradient-to-br from-[#f95faf] to-[#F95F62]'
|
||||
: 'bg-gradient-to-br from-[#F95F62] to-[#c94245]'
|
||||
}`}>
|
||||
<span className="font-poppins text-[10px] font-semibold text-white">{bookingDetails?.city?.cardMode}</span>
|
||||
<span className="font-poppins text-[10px] font-semibold text-white">{bookingDetails?.cardMode}</span>
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<h4 className="font-poppins text-base font-semibold text-[#2a2a2a]">{bookingDetails?.city?.name}</h4>
|
||||
<CardTypeBadge cardType={bookingDetails?.city?.cardMode} />
|
||||
<h4 className="font-poppins text-base font-semibold text-[#2a2a2a]">{bookingDetails?.name}</h4>
|
||||
<CardTypeBadge cardType={bookingDetails?.cardMode} />
|
||||
</div>
|
||||
<p className="font-poppins text-sm font-normal text-[#8e8e8e] mt-0.5">
|
||||
{bookingDetails?.city?.cardMode.toLowerCase() === 'flexi' ? `${bookingDetails?.city?.noOfAttractions} Attractions` : `${bookingDetails?.city?.noOfDays} Days`}
|
||||
{bookingDetails?.cardMode.toLowerCase() === 'flexi' ? `${bookingDetails?.noOfAttractions} Attractions` : `${bookingDetails?.noOfDays} Days`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 space-y-2">
|
||||
{[
|
||||
{ label: 'Adults', value: bookingDetails?.city?.totalAdult },
|
||||
{ label: 'Children', value: bookingDetails?.city?.totalChild },
|
||||
{ label: 'Adults', value: bookingDetails?.totalAdult },
|
||||
{ label: 'Children', value: bookingDetails?.totalChild },
|
||||
// { label: 'Qty', value: order.quantity },
|
||||
].map(({ label, value }) => (
|
||||
<div key={label} className="flex items-center justify-between">
|
||||
@@ -521,11 +570,11 @@ export function PaymentDetailsPage({
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-poppins text-sm font-normal text-[#555]">Subtotal</span>
|
||||
<span className="font-poppins text-sm font-normal text-[#2a2a2a]">${subtotal.toFixed(2)}</span>
|
||||
<span className="font-poppins text-sm font-normal text-[#2a2a2a]">${bookingDetails?.baseAmount}</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-poppins text-sm font-normal text-[#555]">GST (10%)</span>
|
||||
<span className="font-poppins text-sm font-normal text-[#2a2a2a]">${tax.toFixed(2)}</span>
|
||||
<span className="font-poppins text-sm font-normal text-[#2a2a2a]">${bookingDetails?.totalTaxAmount}</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-poppins text-sm font-normal text-[#555]">Booking fee</span>
|
||||
@@ -533,7 +582,7 @@ export function PaymentDetailsPage({
|
||||
</div>
|
||||
<div className="pt-3 border-t border-gray-100 flex items-center justify-between">
|
||||
<span className="font-poppins text-base font-semibold text-[#2a2a2a]">Total</span>
|
||||
<span className="font-poppins text-2xl font-semibold text-[#F95F62]">${total.toFixed(2)}</span>
|
||||
<span className="font-poppins text-2xl font-semibold text-[#F95F62]">${bookingDetails?.totalAmount}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -554,7 +603,7 @@ export function PaymentDetailsPage({
|
||||
) : (
|
||||
<>
|
||||
<Lock className="w-4 h-4" />
|
||||
Complete Payment · ${total.toFixed(2)}
|
||||
Complete Payment · ${bookingDetails.totalAmount}
|
||||
</>
|
||||
)}
|
||||
</motion.button>
|
||||
|
||||
Reference in New Issue
Block a user