// === Seven Yachts — shared components ===
const { useState, useEffect, useRef } = React;
// ---- Icons ----
function Icon({ name, size = 16 }) {
const s = { width: size, height: size, fill: 'none', stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round' };
switch (name) {
case 'heart':
return ;
case 'heart-fill':
return ;
case 'whatsapp':
return ;
case 'phone':
return ;
case 'arrow':
return ;
case 'arrow-up-right':
return ;
case 'menu':
return ;
case 'x':
return ;
case 'check':
return ;
case 'cal':
return ;
case 'users':
return ;
case 'compass':
return ;
case 'pin':
return ;
case 'sparkle':
return ;
case 'shield':
return ;
default: return null;
}
}
window.Icon = Icon;
// ---- Logo (pure wordmark, gold) ----
function Logo({ dark = false, height = 28, color }) {
// On dark backgrounds the wordmark sits in gold; on light, marine.
const c = color || (dark ? 'var(--marine)' : 'var(--gold)');
return (
Seven
Yachts
);
}
window.Logo = Logo;
// ---- Navbar ----
function Navbar({ route, setRoute, dark = true, lang, setLang, openFav, openBooking, favCount }) {
const [scrolled, setScrolled] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 40);
window.addEventListener('scroll', onScroll);
return () => window.removeEventListener('scroll', onScroll);
}, []);
const navItems = [
{ id: 'fleet', label: lang === 'ar' ? 'الأسطول' : 'Fleet' },
{ id: 'experiences', label: lang === 'ar' ? 'التجارب' : 'Experiences' },
{ id: 'destinations', label: lang === 'ar' ? 'الوجهات' : 'Destinations' },
{ id: 'sales', label: lang === 'ar' ? 'البيع' : 'Sales' },
{ id: 'about', label: lang === 'ar' ? 'عننا' : 'About' },
];
const cls = `navbar ${dark ? 'dark' : 'light'} ${scrolled ? 'scrolled' : ''}`;
return (
{navItems.map(i => (
))}
);
}
window.Navbar = Navbar;
// ---- Availability widget ----
function AvailabilityWidget({ compact, defaultYacht, onSubmit }) {
const today = new Date();
const tw = new Date(today.getTime() + 7 * 86400000);
const fmt = d => d.toISOString().slice(0, 10);
const [date, setDate] = useState(fmt(tw));
const [guests, setGuests] = useState(8);
const [yacht, setYacht] = useState(defaultYacht || 'any');
const [duration, setDuration] = useState('4hr');
const handle = (e) => {
e.preventDefault();
onSubmit && onSubmit({ date, guests, yacht, duration });
};
return (
);
}
window.AvailabilityWidget = AvailabilityWidget;
// ---- Yacht card (editorial) ----
function YachtCard({ yacht, layout = 'tall', dark = false, fav, toggleFav, onSelect, showRates, onEnquire }) {
const cls = `feature-card ${dark ? 'dark' : ''} ${layout === 'tall' ? 'fc-tall' : layout === 'wide' ? 'fc-wide' : ''}`;
return (
onSelect && onSelect(yacht.slug)}>
{yacht.builder}
{yacht.length} ft
{yacht.cruisingGuests && (<>up to {yacht.cruisingGuests}>)}
{yacht.confirmFleet && (<>confirm>)}
{yacht.name}
{showRates && yacht.fromHourly ? (
fromAED {fmtAED(yacht.fromHourly)} /hr · indicative
) : (
Rate on request
)}
);
}
window.YachtCard = YachtCard;
// ---- Footer ----
function Footer() {
return (
);
}
window.Footer = Footer;
// ---- Concept badge (small honest disclosure) ----
function ConceptBadge() {
const [hidden, setHidden] = useState(false);
if (hidden) return null;
return (
setHidden(true)} title="Hide">
Concept · Additive layer · Rates indicative
);
}
window.ConceptBadge = ConceptBadge;
// ---- Fleet marquee ----
function FleetMarquee() {
const items = FLEET.slice(0, 12);
const list = [...items, ...items];
return (
{list.map((y, i) => (
{y.name}
· {y.builder}
· {y.length} ft
◇
))}
);
}
window.FleetMarquee = FleetMarquee;