diff --git a/.gitignore b/.gitignore index f04936e..47a6633 100644 --- a/.gitignore +++ b/.gitignore @@ -88,7 +88,7 @@ dist # Gatsby files .cache/ -public + # Storybook build outputs .out diff --git a/public/images/1.png b/public/images/1.png new file mode 100644 index 0000000..74626ef Binary files /dev/null and b/public/images/1.png differ diff --git a/public/images/12.svg b/public/images/12.svg new file mode 100644 index 0000000..63c664f --- /dev/null +++ b/public/images/12.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/images/2.png b/public/images/2.png new file mode 100644 index 0000000..0f690c0 Binary files /dev/null and b/public/images/2.png differ diff --git a/public/images/avatars/avatar-1.png b/public/images/avatars/avatar-1.png new file mode 100644 index 0000000..1df25e6 Binary files /dev/null and b/public/images/avatars/avatar-1.png differ diff --git a/public/images/avatars/avatar-2.png b/public/images/avatars/avatar-2.png new file mode 100644 index 0000000..85456e7 Binary files /dev/null and b/public/images/avatars/avatar-2.png differ diff --git a/public/images/avatars/avatar-3.png b/public/images/avatars/avatar-3.png new file mode 100644 index 0000000..44aaa9f Binary files /dev/null and b/public/images/avatars/avatar-3.png differ diff --git a/public/images/avatars/avatar-4.png b/public/images/avatars/avatar-4.png new file mode 100644 index 0000000..dd9a5d2 Binary files /dev/null and b/public/images/avatars/avatar-4.png differ diff --git a/public/images/avatars/avatar-5.png b/public/images/avatars/avatar-5.png new file mode 100644 index 0000000..91cd8a3 Binary files /dev/null and b/public/images/avatars/avatar-5.png differ diff --git a/public/images/background-all.jpg b/public/images/background-all.jpg new file mode 100644 index 0000000..862f2d8 Binary files /dev/null and b/public/images/background-all.jpg differ diff --git a/public/images/background-auth.jpg b/public/images/background-auth.jpg new file mode 100644 index 0000000..ab481c3 Binary files /dev/null and b/public/images/background-auth.jpg differ diff --git a/public/images/background-call-to-action2.png b/public/images/background-call-to-action2.png new file mode 100644 index 0000000..a8974a7 Binary files /dev/null and b/public/images/background-call-to-action2.png differ diff --git a/public/images/background-call-to-action3.png b/public/images/background-call-to-action3.png new file mode 100644 index 0000000..4ae07e1 Binary files /dev/null and b/public/images/background-call-to-action3.png differ diff --git a/public/images/background-call-to-action4.png b/public/images/background-call-to-action4.png new file mode 100644 index 0000000..dfbed93 Binary files /dev/null and b/public/images/background-call-to-action4.png differ diff --git a/public/images/background-faqs.jpg b/public/images/background-faqs.jpg new file mode 100644 index 0000000..d9de04f Binary files /dev/null and b/public/images/background-faqs.jpg differ diff --git a/public/images/background-features.jpeg b/public/images/background-features.jpeg new file mode 100644 index 0000000..27ea775 Binary files /dev/null and b/public/images/background-features.jpeg differ diff --git a/public/images/background-features.jpg b/public/images/background-features.jpg new file mode 100644 index 0000000..6bea103 Binary files /dev/null and b/public/images/background-features.jpg differ diff --git a/public/images/background-features.png b/public/images/background-features.png new file mode 100644 index 0000000..c5b2945 Binary files /dev/null and b/public/images/background-features.png differ diff --git a/public/images/comments/favicon.svg b/public/images/comments/favicon.svg new file mode 100644 index 0000000..7c4770c --- /dev/null +++ b/public/images/comments/favicon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/public/images/comments/favicon.zip b/public/images/comments/favicon.zip new file mode 100644 index 0000000..c8a3391 Binary files /dev/null and b/public/images/comments/favicon.zip differ diff --git a/public/images/comments/favicon/apple-touch-icon.png b/public/images/comments/favicon/apple-touch-icon.png new file mode 100644 index 0000000..a909716 Binary files /dev/null and b/public/images/comments/favicon/apple-touch-icon.png differ diff --git a/public/images/comments/favicon/favicon-96x96.png b/public/images/comments/favicon/favicon-96x96.png new file mode 100644 index 0000000..ee7de77 Binary files /dev/null and b/public/images/comments/favicon/favicon-96x96.png differ diff --git a/public/images/comments/favicon/favicon.ico b/public/images/comments/favicon/favicon.ico new file mode 100644 index 0000000..bfb1865 Binary files /dev/null and b/public/images/comments/favicon/favicon.ico differ diff --git a/public/images/comments/favicon/favicon.svg b/public/images/comments/favicon/favicon.svg new file mode 100644 index 0000000..146e876 --- /dev/null +++ b/public/images/comments/favicon/favicon.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/images/comments/favicon/site.webmanifest b/public/images/comments/favicon/site.webmanifest new file mode 100644 index 0000000..ccf313a --- /dev/null +++ b/public/images/comments/favicon/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "MyWebSite", + "short_name": "MySite", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/public/images/comments/favicon/web-app-manifest-192x192.png b/public/images/comments/favicon/web-app-manifest-192x192.png new file mode 100644 index 0000000..217b96e Binary files /dev/null and b/public/images/comments/favicon/web-app-manifest-192x192.png differ diff --git a/public/images/comments/favicon/web-app-manifest-512x512.png b/public/images/comments/favicon/web-app-manifest-512x512.png new file mode 100644 index 0000000..987d984 Binary files /dev/null and b/public/images/comments/favicon/web-app-manifest-512x512.png differ diff --git a/public/images/community/community1.jpg b/public/images/community/community1.jpg new file mode 100644 index 0000000..37aaef8 Binary files /dev/null and b/public/images/community/community1.jpg differ diff --git a/public/images/community/community2.jpg b/public/images/community/community2.jpg new file mode 100644 index 0000000..7a1c036 Binary files /dev/null and b/public/images/community/community2.jpg differ diff --git a/public/images/community/community3.jpg b/public/images/community/community3.jpg new file mode 100644 index 0000000..0dfa6c8 Binary files /dev/null and b/public/images/community/community3.jpg differ diff --git a/public/images/community/community4.jpg b/public/images/community/community4.jpg new file mode 100644 index 0000000..7098d62 Binary files /dev/null and b/public/images/community/community4.jpg differ diff --git a/public/images/components/Activities.jsx b/public/images/components/Activities.jsx new file mode 100644 index 0000000..581b52b --- /dev/null +++ b/public/images/components/Activities.jsx @@ -0,0 +1,73 @@ +const posts = [ + { + id: 1, + title: 'Yoga', + href: '#', + description: + 'Step fully into your body. The perfect start to the morning.', + image: + '/images/act1.png', + }, + { + id: 2, + title: 'Meditation', + href: '#', + description: + 'Open your mind, enter a deeper state of awareness.', + image: + '/images/act3.png', + }, + { + id: 3, + title: 'Nutrition', + href: '#', + description: + 'Gluten-free, vegetarian, vegan, detox diets, & more.', + image: + '/images/act2.png', + }, + ] + + + export default function activities() { + return ( +
+
+
+

+ Mind, Body, and Soul: For a Deeper Connection. +

+
+
+ {posts.map((post) => ( + + ))} +
+
+
+ ) + } diff --git a/public/images/components/Boat.jsx b/public/images/components/Boat.jsx new file mode 100644 index 0000000..f06c497 --- /dev/null +++ b/public/images/components/Boat.jsx @@ -0,0 +1,196 @@ +'use client' + +import * as Headless from '@headlessui/react' +import { ArrowLongRightIcon } from '@heroicons/react/20/solid' +import { clsx } from 'clsx' +import { + motion, + useMotionValueEvent, + useScroll, + useSpring, +} from 'framer-motion' +import { useCallback, useLayoutEffect, useRef, useState } from 'react' +import useMeasure from 'react-use-measure' +import { Container } from './Container' +import { Link } from './link' +import { Heading, Subheading } from './text' + +const testimonials = [ + { + img: '/images/veda1.jpg', + name: '0 - 6 Years Old', + title: 'From birth to age 6, we offer ECD programs that change lives forever.', + subtitle: 'A beautiful 50-meter dahabiya offering a tranquil and organic platform for personalized cruises.', + quote: 'VEDA 1', + href: '/phases/phase1', + }, + { + img: '/images/veda2.jpg', + name: '6 - 15 Years Old', + title: 'Unlock the Potential of Youth with transformational learning experiences', + subtitle: 'An elegant 45-meter dahabiya, ideal for hosting larger groups, healing retreats, company getaways, and more.', + quote: 'VEDA 2', + href: '/phases/phase2', + }, + { + img: '/images/veda3.jpg', + name: '15 - 25 Years Old', + title: 'Skills that Earn & Regenerate Vocational paths that equip young people to live with purpose.', + subtitle: 'A cozy 18-meter dahabiya offering a serene floating home, perfect for private groups seeking tranquility and comfort on the Nile.', + quote: 'VEDA 3', + href: '/phases/phase3', + }, + { + img: '/images/veda4.jpg', + name: 'All Ages', + title: 'A unique portfolio of impact proven Community-led solutions worth implementing', + subtitle: 'A spaciou 55-meter dahabeya offering a serene retreat, perfect for bigger groups seeking tranquility and comfort on the Nile.', + quote: 'VEDA 4', + href: '/phases/phase4', + }, +] + +function TestimonialCard({ + subtitle, + name, + title, + img, + href, + children, + bounds, + scrollX, + ...props +}) { + let ref = useRef(null) + + let computeOpacity = useCallback(() => { + let element = ref.current + if (!element || bounds.width === 0) return 1 + + let rect = element.getBoundingClientRect() + + if (rect.left < bounds.left) { + let diff = bounds.left - rect.left + let percent = diff / rect.width + return Math.max(0.5, 1 - percent) + } else if (rect.right > bounds.right) { + let diff = rect.right - bounds.right + let percent = diff / rect.width + return Math.max(0.5, 1 - percent) + } else { + return 1 + } + }, [ref, bounds.width, bounds.left, bounds.right]) + + let opacity = useSpring(computeOpacity(), { + stiffness: 154, + damping: 23, + }) + + useLayoutEffect(() => { + opacity.set(computeOpacity()) + }, [computeOpacity, opacity]) + + useMotionValueEvent(scrollX, 'change', () => { + opacity.set(computeOpacity()) + }) + + return ( + + {/* Image Section */} +
+ +
+ + {/* Content Section Below Image */} +
+
+

+ {children} +

+
+ +

+ {subtitle} +

+ + + Learn More + + +
+
+ ) +} + +export function Boat() { + let scrollRef = useRef(null) + let { scrollX } = useScroll({ container: scrollRef }) + let [setReferenceWindowRef, bounds] = useMeasure() + let [activeIndex, setActiveIndex] = useState(0) + + useMotionValueEvent(scrollX, 'change', (x) => { + if (scrollRef.current && scrollRef.current.children[0]) { + setActiveIndex(Math.floor(x / scrollRef.current.children[0].clientWidth)) + } + }) + + function scrollTo(index) { + let gap = 32 + let width = scrollRef.current.children[0].offsetWidth + scrollRef.current.scrollTo({ left: (width + gap) * index }) + } + + return ( +
+ +
+

+ Dahabiyas +

+

+ Discover peaceful platforms where every detail ensures a truly memorable stay. Our fleet of traditional dahabiyas combines authentic Nile heritage with modern comfort, offering intimate sailing experiences that connect you with Egypt's timeless river culture. +

+
+
+
+ {testimonials.map(({ img, name, title, quote, href, subtitle }, testimonialIndex) => ( + scrollTo(testimonialIndex)} + > + {quote} + + ))} +
+
+
+ ) +} diff --git a/public/images/components/Boats.jsx b/public/images/components/Boats.jsx new file mode 100644 index 0000000..b4fea51 --- /dev/null +++ b/public/images/components/Boats.jsx @@ -0,0 +1,96 @@ +import { useId } from 'react'; +import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'; +import clsx from 'clsx'; + +import { Container } from '@/components/Container'; + +const people = [ + { + name: 'VEDA I', + role: 'The ideal retreat for luxury and privacy, perfect for intimate gatherings.', + image: '/images/dahabiyas/veda1.jpg', + bio: [ + '6 rooms & 4 suites with balconies.', + 'Hosts up to 20 people.', + 'Private bathroom ensuites.' + ], + xUrl: '#', + linkedinUrl: '#', + }, + { + name: 'VEDA II', + role: 'The perfect spacious space for larger groups seeking comfort', + image: '/images/dahabiyas/veda2.jpg', + bio: [ + '8 rooms & 2 suites with balconies.', + 'Hosts up to 20 people.', + 'Private bathroom ensuites.' + ], + xUrl: '#', + linkedinUrl: '#', + }, + { + name: 'VEDA III', + role: 'Senior Developer', + image: '/images/dahabiyas/veda3.jpg', + bio: [ + '5 rooms with balconies.', + 'Hosts up to 10 people.', + 'Private bathroom ensuites.' + ], + xUrl: '#', + linkedinUrl: '#', + }, + { + name: 'VEDA IV', + role: 'Senior Developer', + image: '/images/dahabiyas/veda4.jpg', + bio: [ + '10 rooms & 4 suites with balconies.', + 'Hosts up to 28 people.', + 'Private bathroom ensuites.' + ], + xUrl: '#', + linkedinUrl: '#', + }, + // More people... +]; + +export default function Boats() { + return ( +
+
+
+

Our team

+

+ We’re a dynamic group of individuals who are passionate about what we do and dedicated to delivering the + best results for our clients. +

+
+
    + {people.map((person) => ( +
  • +
    + {person.name} +
    +

    {person.name}

    +
      + {person.bio.map((item, index) => ( +
    • {item}
    • + ))} +
    +
  • + ))} +
+
+
+ ) +} diff --git a/public/images/components/Button.jsx b/public/images/components/Button.jsx new file mode 100644 index 0000000..4a56105 --- /dev/null +++ b/public/images/components/Button.jsx @@ -0,0 +1,55 @@ +import Link from 'next/link' +import clsx from 'clsx' + +const baseStyles = { + solid: + 'group inline-flex items-center justify-center rounded-xl py-1.5 px-3.5 lg:py-2 lg:px-4 text-xs lg:text-sm font-light focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2', + solidNoRounded: + 'group inline-flex items-center justify-center py-1.5 px-3.5 lg:py-2 lg:px-4 text-xs lg:text-sm font-light focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2', + outline: + 'group inline-flex ring-1 items-center justify-center rounded-xl py-1.5 px-3.5 lg:py-2 lg:px-4 text-xs lg:text-sm font-light focus:outline-none', +} + +const variantStyles = { + solid: { + slate: + 'bg-gold-900 text-white hover:bg-gold-800 hover:text-slate-100 active:bg-gold-800 active:text-gold-300 focus-visible:outline-gold-900', + blue: 'bg-[#28602C] text-white hover:text-slate-100 hover:bg-[#245527] active:bg-[#1e4a21] active:text-slate-100 focus-visible:outline-[#28602C]', + olive: 'bg-primary-olive text-white hover:bg-secondary-gold hover:text-text-dark active:bg-secondary-gold active:text-text-dark focus-visible:outline-primary-olive', + terracotta: 'bg-primary-terracotta text-white hover:bg-primary-olive hover:text-white active:bg-primary-olive active:text-white focus-visible:outline-primary-terracotta', + white: + 'bg-white text-slate-100 hover:bg-gold-50 active:bg-gold-200 active:text-slate-100 focus-visible:outline-white', + }, + solidNoRounded: { + bookNow: 'bg-darkgr-900 text-white hover:bg-darkgr-800 active:bg-darkgr-700 focus-visible:outline-darkgr-900', + }, + outline: { + slate: + 'ring-slate-200 text-slate-200 hover:text-slate-300 hover:ring-slate-300 active:bg-slate-100 active:text-slate-200 focus-visible:outline-gold-600 focus-visible:ring-slate-300', + white: + 'ring-slate-700 text-white hover:ring-slate-300 active:ring-slate-200 active:text-slate-100 focus-visible:outline-white', + }, +} + +export function Button({ className, ...props }) { + props.variant ??= 'solid' + props.color ??= 'slate' + + className = clsx( + baseStyles[props.variant], + props.variant === 'outline' + ? variantStyles.outline[props.color] + : props.variant === 'solid' + ? variantStyles.solid[props.color] + : props.variant === 'solidNoRounded' + ? variantStyles.solidNoRounded[props.color] + : undefined, + className, + ) + + return typeof props.href === 'undefined' ? ( +