diff --git a/src/pages/SuperSavingsDetailsPage.tsx b/src/pages/SuperSavingsDetailsPage.tsx
new file mode 100644
index 0000000..b3b65fb
--- /dev/null
+++ b/src/pages/SuperSavingsDetailsPage.tsx
@@ -0,0 +1,387 @@
+import { ArrowLeft, Check, Clock, MapPin, Users, X } from 'lucide-react';
+import { motion } from 'motion/react';
+import { useParams } from 'react-router-dom';
+import { ImageWithFallback } from '../components/figma/ImageWithFallback';
+import LoadingSpinner from '../components/LoadingSpinner';
+import { Badge } from '../components/ui/badge';
+import { Button } from '../components/ui/button';
+import { Card } from '../components/ui/card';
+import { Layout } from '../Layout';
+import { useGetOfferDetailsByIdQuery } from '../Redux/services/cities.service';
+
+interface SuperSavingsDetailsPageProps {
+ onBackClick: () => void;
+ onCheckoutClick: () => void;
+ onSignInClick: () => void;
+ onSignOutClick?: () => void;
+ user?: { email: string; name: string } | null;
+}
+
+export function SuperSavingsDetailsPage({
+ onBackClick,
+ onCheckoutClick,
+ onSignInClick,
+ onSignOutClick,
+ user,
+}: SuperSavingsDetailsPageProps) {
+ const { id } = useParams();
+ const { data: offer, isLoading } = useGetOfferDetailsByIdQuery(Number(id));
+ const baseUrl = import.meta.env.VITE_BASE_URL;
+
+
+ if (isLoading) {
+ return
;
+ }
+
+ // Guard against missing data – but keep all UI elements
+ const safeOffer = offer || {
+ id: 0,
+ title: 'Offer Details',
+ description: 'No description available.',
+ cityXid: 0,
+ cardXid: 0,
+ cardTypeXid: 0,
+ categoryXid: 0,
+ partnerName: '',
+ offerCode: '',
+ websiteBannerImage: '',
+ mobileBannerImage: '',
+ redemptionLink: '',
+ passType: '',
+ startDateTime: null,
+ endDateTime: null,
+ applyToPasses: false,
+ stepsForBooking: null,
+ offerStatus: '',
+ isActive: true,
+ createdAt: '',
+ updatedAt: '',
+ city: { id: 0, cityName: 'Unknown City' },
+ card: { id: 0, title: 'Unknown Card' },
+ cardType: { id: 0, cardTypeDisplayName: 'Standard' },
+ category: { id: 0, categoryName: 'General' },
+ };
+
+ // Build badges from available API data (preserves the badge UI section)
+ const superSavingsBadges = [
+ safeOffer.category && { badgeXid: safeOffer.category.id, badge: { badgeName: safeOffer.category.categoryName } },
+ safeOffer.cardType && { badgeXid: safeOffer.cardType.id, badge: { badgeName: safeOffer.cardType.cardTypeDisplayName } },
+ safeOffer.offerCode && { badgeXid: -1, badge: { badgeName: `Code: ${safeOffer.offerCode}` } },
+ safeOffer.offerStatus && { badgeXid: -2, badge: { badgeName: safeOffer.offerStatus.toUpperCase() } },
+ ].filter(Boolean);
+
+ // Build gallery array from banner images (original expected superSavingsGalleries)
+ const superSavingsGalleries = [];
+ if (safeOffer.websiteBannerImage) {
+ superSavingsGalleries.push({ id: 1, filePathUrl: safeOffer.websiteBannerImage });
+ }
+ if (safeOffer.mobileBannerImage) {
+ superSavingsGalleries.push({ id: 2, filePathUrl: safeOffer.mobileBannerImage });
+ }
+ // If no images, add a placeholder
+ if (superSavingsGalleries.length === 0) {
+ superSavingsGalleries.push({ id: 0, filePathUrl: 'https://placehold.co/1200x800?text=No+Image' });
+ }
+
+ // Mock data for sections not present in API (preserve structure but show empty/fallback)
+ const durations = safeOffer.startDateTime && safeOffer.endDateTime
+ ? Math.round((new Date(safeOffer.endDateTime).getTime() - new Date(safeOffer.startDateTime).getTime()) / (1000 * 60))
+ : 'Not specified';
+ const groupSize = 'Not specified';
+ const ageRange = 'All ages';
+ const superSavingsLanguages: any[] = []; // API has no language data
+ const superSavingsHighlights: any[] = []; // API has no highlights
+ // Inclusions: API has none, so show empty state (or we could derive from redemptionLink etc.)
+ const superSavingsInclusions: any[] = [];
+ const address = safeOffer.city?.cityName || 'Location not specified';
+
+ return (
+
+
+ {/* Back Button */}
+
+
+
+
+ {/* Title and Badges Section */}
+
+
+ {superSavingsBadges.map((badge: any, index: number) => (
+
+ {badge.badge.badgeName}
+
+ ))}
+
+
+
+
+ {safeOffer.title}
+ {' '}
+
+ Day Trip by {safeOffer.partnerName || safeOffer.card?.title || 'Partner'}
+
+
+
+
+ {/* Image Gallery Section - preserved exactly as original */}
+
+ {/* Main large image */}
+
+
+
+
+ {/* Gallery images - use remaining images or repeat first if needed */}
+ {superSavingsGalleries.slice(1, 5).map((image: any) => (
+
+
+
+ ))}
+ {/* If less than 4 extra images, fill with placeholders to maintain grid */}
+ {superSavingsGalleries.slice(1, 5).length < 4 &&
+ Array(4 - superSavingsGalleries.slice(1, 5).length)
+ .fill(null)
+ .map((_, idx) => (
+
+ ))}
+
+
+ {/* Main Content Grid */}
+
+ {/* Left Content - Tour Details */}
+
+ {/* Overview Cards - preserved */}
+
+ {/* Duration */}
+
+
+
+
+ Duration
+
+ {typeof durations === 'number' ? `${durations} mins` : durations}
+
+
+
+ {/* Group Size */}
+
+
+
+
+ Group Size
+ {groupSize}
+
+
+ {/* Age Range */}
+
+
+
+
+ Age Range
+ {ageRange}
+
+
+ {/* Languages */}
+
+
+
+
+ Languages
+
+ {superSavingsLanguages?.length > 0
+ ? superSavingsLanguages?.map((lang: any) => lang.language.name).join(', ')
+ : 'English (default)'}
+
+
+
+
+ {/* Tour Overview */}
+
+
+
+ {safeOffer.description}
+
+
+
+ {/* Tour Highlights - preserved even if empty */}
+
+
+
+
+ Tour Highlights
+
+
+ {superSavingsHighlights.length > 0 ? (
+
+ {superSavingsHighlights.map((highlight: any) => (
+ -
+
+ {highlight.title}
+
+ ))}
+
+ ) : (
+
No highlights listed for this offer.
+ )}
+
+
+ {/* What's Included/Not Included - preserved */}
+
+
+
+
+ What's included
+
+
+
+ {/* Included */}
+
+
+
+ Included
+
+ {superSavingsInclusions.filter((inc: any) => inc.isInclusion === true).length > 0 ? (
+ superSavingsInclusions
+ .filter((inclusion: any) => inclusion.isInclusion === true)
+ .map((inclusion: any) => (
+
+
+
+
+
{inclusion.title}
+
+ ))
+ ) : (
+
No included items specified.
+ )}
+
+
+ {/* Not Included */}
+
+
+
+ Not Included
+
+ {superSavingsInclusions.filter((inc: any) => inc.isInclusion === false).length > 0 ? (
+ superSavingsInclusions
+ .filter((inclusion: any) => inclusion.isInclusion === false)
+ .map((inclusion: any) => (
+
+
+
+
+
{inclusion.title}
+
+ ))
+ ) : (
+
No excluded items specified.
+ )}
+
+
+
+
+ {/* Location on map - preserved */}
+
+
+
+
+ Location on map
+
+
+
+
+
+
+
+
Interactive Map
+
{safeOffer.title}
+
{address}
+
+
+
+
+
+ {/* Right Sidebar - Calendar and Booking (preserved, but you can add a real calendar if needed) */}
+
+
+ Book This Offer
+
+
+ Availability
+
+ {safeOffer.offerStatus === 'active' ? 'Available' : 'Unavailable'}
+
+
+ {safeOffer.startDateTime && (
+
+ Valid from
+
+ {new Date(safeOffer.startDateTime).toLocaleDateString()}
+
+
+ )}
+ {safeOffer.endDateTime && (
+
+ Valid until
+
+ {new Date(safeOffer.endDateTime).toLocaleDateString()}
+
+
+ )}
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/pages/SuperSavingsPage.tsx b/src/pages/SuperSavingsPage.tsx
index 8b9e680..40be9f3 100644
--- a/src/pages/SuperSavingsPage.tsx
+++ b/src/pages/SuperSavingsPage.tsx
@@ -17,6 +17,7 @@ import { TrustedCompanies } from '../components/TrustedCompanies';
import { Layout } from '../Layout';
import { useGetSelectedCityOffersQuery } from '../Redux/services/cities.service';
import LoadingSpinner from '../components/LoadingSpinner';
+import { useNavigate } from 'react-router-dom';
interface SuperSavingsPageProps {
onBackClick: () => void;
@@ -113,6 +114,7 @@ export function SuperSavingsPage({
user
}: SuperSavingsPageProps) {
+ const navigate = useNavigate();
const [categoryId, setCategoryId] = useState(null)
const [page, setPage] = useState(1)
const [limit, setLimit] = useState(4)
@@ -302,7 +304,8 @@ export function SuperSavingsPage({
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: index * 0.1 }}
>
-
+ navigate(`/super-savings/${offer.id}`)}>
{/* Image */}