Auto commit: 2025-05-30T08:09:54.335Z
This commit is contained in:
parent
f5fa155b4a
commit
ce9d4737cc
File diff suppressed because one or more lines are too long
@ -30,26 +30,26 @@ const nextConfig = {
|
||||
source: '/home',
|
||||
destination: '/web_pages/home',
|
||||
},
|
||||
|
||||
{
|
||||
source: '/services',
|
||||
destination: '/web_pages/services',
|
||||
},
|
||||
|
||||
{
|
||||
source: '/contact',
|
||||
destination: '/web_pages/contact',
|
||||
},
|
||||
|
||||
{
|
||||
source: '/faq',
|
||||
destination: '/web_pages/faq',
|
||||
},
|
||||
|
||||
{
|
||||
source: '/blog',
|
||||
destination: '/web_pages/blog',
|
||||
},
|
||||
{
|
||||
source: '/exclusive-offers',
|
||||
destination: '/web_pages/exclusive-offers',
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
@ -67,6 +67,11 @@ export const webPagesNavBar = [
|
||||
href: '/blog',
|
||||
label: 'blog',
|
||||
},
|
||||
{
|
||||
href: '/exclusive-offers',
|
||||
label: 'عروض حصرية',
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
export default menuNavBar;
|
||||
|
||||
108
frontend/src/pages/web_pages/exclusive-offers.tsx
Normal file
108
frontend/src/pages/web_pages/exclusive-offers.tsx
Normal file
@ -0,0 +1,108 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import type { ReactElement } from 'react';
|
||||
import Head from 'next/head';
|
||||
import LayoutGuest from '../../../layouts/Guest';
|
||||
import WebSiteHeader from '../../../components/WebPageComponents/Header';
|
||||
import WebSiteFooter from '../../../components/WebPageComponents/Footer';
|
||||
|
||||
interface Flight {
|
||||
id: number;
|
||||
flight_number: string;
|
||||
price: number;
|
||||
partner: { id: number; name: string };
|
||||
}
|
||||
interface Hotel {
|
||||
id: number;
|
||||
name: string;
|
||||
price_per_night: number;
|
||||
partner: { id: number; name: string };
|
||||
}
|
||||
interface Review {
|
||||
id: number;
|
||||
partner: { id: number };
|
||||
rating: number;
|
||||
}
|
||||
|
||||
export default function ExclusiveOffers() {
|
||||
const [flights, setFlights] = useState<Flight[]>([]);
|
||||
const [hotels, setHotels] = useState<Hotel[]>([]);
|
||||
const [reviews, setReviews] = useState<Review[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
fetch('/api/flights')
|
||||
.then(res => res.json())
|
||||
.then(data => setFlights(data || []));
|
||||
fetch('/api/hotels')
|
||||
.then(res => res.json())
|
||||
.then(data => setHotels(data || []));
|
||||
fetch('/api/reviews')
|
||||
.then(res => res.json())
|
||||
.then(data => setReviews(data || []));
|
||||
}, []);
|
||||
|
||||
const getAvgRating = (partnerId: number) => {
|
||||
const list = reviews.filter(r => r.partner.id === partnerId);
|
||||
if (!list.length) return '-';
|
||||
const sum = list.reduce((acc, r) => acc + r.rating, 0);
|
||||
return (sum / list.length).toFixed(1);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>عروض حصرية | Royal Aurora</title>
|
||||
</Head>
|
||||
<WebSiteHeader projectName="Royal Aurora" />
|
||||
<main className="container mx-auto py-8 px-4">
|
||||
<section className="mb-12">
|
||||
<h2 className="text-2xl font-bold mb-4">عروض طيران حصرية</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{flights.map(f => (
|
||||
<div key={f.id} className="border rounded-lg shadow p-4 flex flex-col">
|
||||
<div className="h-40 bg-gray-200 mb-4 flex items-center justify-center text-gray-500">
|
||||
صورة طيران
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold">{f.flight_number}</h3>
|
||||
<p className="mt-2">السعر: ${f.price}</p>
|
||||
<p>تقييم: {getAvgRating(f.partner.id)}</p>
|
||||
<a
|
||||
href={`/bookings/new?flightId=${f.id}`}
|
||||
className="mt-auto bg-purple-600 text-white text-center py-2 rounded hover:bg-purple-700 transition"
|
||||
>
|
||||
احجز الآن
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-4">عروض فنادق حصرية</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{hotels.map(h => (
|
||||
<div key={h.id} className="border rounded-lg shadow p-4 flex flex-col">
|
||||
<div className="h-40 bg-gray-200 mb-4 flex items-center justify-center text-gray-500">
|
||||
صورة فندق
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold">{h.name}</h3>
|
||||
<p className="mt-2">السعر: ${h.price_per_night} / الليلة</p>
|
||||
<p>تقييم: {getAvgRating(h.partner.id)}</p>
|
||||
<a
|
||||
href={`/bookings/new?hotelId=${h.id}`}
|
||||
className="mt-auto bg-purple-600 text-white text-center py-2 rounded hover:bg-purple-700 transition"
|
||||
>
|
||||
احجز الآن
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<WebSiteFooter projectName="Royal Aurora" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// Assign guest layout for public access
|
||||
ExclusiveOffers.getLayout = function getLayout(page: ReactElement) {
|
||||
return <LayoutGuest>{page}</LayoutGuest>;
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user