From 2b551aad28b13eb556383ad22b964f8b16237559 Mon Sep 17 00:00:00 2001 From: "fredy.siswanto" Date: Fri, 28 Feb 2025 16:50:44 +0700 Subject: [PATCH] feat: implement carousel components for news section and update layout styles --- app/app.css | 24 +++++ app/components/ui/carousel-hero.tsx | 99 +++++++++++++++++++ app/components/ui/carousel-section.tsx | 118 ++++++++++++++++++++++ app/data/contents.ts | 132 +++++++++++++++++++++++++ app/layouts/news/default.tsx | 2 +- app/pages/news/data.ts | 4 +- app/pages/news/index.tsx | 12 +-- 7 files changed, 381 insertions(+), 10 deletions(-) create mode 100644 app/components/ui/carousel-hero.tsx create mode 100644 app/components/ui/carousel-section.tsx create mode 100644 app/data/contents.ts diff --git a/app/app.css b/app/app.css index e743c14..4ef6f59 100644 --- a/app/app.css +++ b/app/app.css @@ -28,3 +28,27 @@ table.dataTable tbody > tr > td { border-right: none !important; border-bottom: 1px solid #ebebeb; } + +/* .embla.hero { + overflow: hidden; +} +.embla__container.hero { + display: flex; + background-color: yellow; +} +.embla__slide.hero { + flex: 0 0 100%; + min-width: 0; +} */ + +.embla__slide { + margin-right: 10px; + flex: 0 0 auto; + min-width: 0; + max-width: 100%; +} +@media (min-width: 768px) { + .embla__slide { + margin-right: 30px; + } +} diff --git a/app/components/ui/carousel-hero.tsx b/app/components/ui/carousel-hero.tsx new file mode 100644 index 0000000..54d4211 --- /dev/null +++ b/app/components/ui/carousel-hero.tsx @@ -0,0 +1,99 @@ +import useEmblaCarousel from 'embla-carousel-react' +import { useCallback } from 'react' +import { Link } from 'react-router' + +import { CarouselNextIcon } from '~/components/icons/carousel-next' +import { CarouselPreviousIcon } from '~/components/icons/carousel-previous' +import { Button } from '~/components/ui/button' +import { useNewsContext } from '~/contexts/news' +import type { TNews } from '~/types/news' + +export const CarouselHero = (properties: TNews) => { + const { setIsSuccessOpen } = useNewsContext() + const { title, description, items } = properties + const [emblaReference, emblaApi] = useEmblaCarousel({ loop: true }) + + const previousSlide = useCallback(() => { + if (emblaApi) emblaApi.scrollPrev() + }, [emblaApi]) + + const nextSlide = useCallback(() => { + if (emblaApi) emblaApi.scrollNext() + }, [emblaApi]) + + return ( +
+
+
+

+ {title} +

+

+ {description} +

+
+
+ + +
+
+ +
+
+ {items.map(({ featured, title, content, slug, isPremium }, index) => ( +
+
+ {title} +
+
+

+ {title} +

+

+ {content} +

+
+ +
+
+
+ ))} +
+
+
+ ) +} diff --git a/app/components/ui/carousel-section.tsx b/app/components/ui/carousel-section.tsx new file mode 100644 index 0000000..ebdda2c --- /dev/null +++ b/app/components/ui/carousel-section.tsx @@ -0,0 +1,118 @@ +import useEmblaCarousel from 'embla-carousel-react' +import { useCallback } from 'react' +import { Link } from 'react-router' + +import { CarouselNextIcon } from '~/components/icons/carousel-next' +import { CarouselPreviousIcon } from '~/components/icons/carousel-previous' +import { Button } from '~/components/ui/button' +import { useNewsContext } from '~/contexts/news' +import type { TNews } from '~/types/news' + +export const CarouselSection = (properties: TNews) => { + const { setIsSuccessOpen } = useNewsContext() + const { title, description, items } = properties + const [emblaReference, emblaApi] = useEmblaCarousel({ loop: false }) + + const previousSlide = useCallback(() => { + if (emblaApi) emblaApi.scrollPrev() + }, [emblaApi]) + + const nextSlide = useCallback(() => { + if (emblaApi) emblaApi.scrollNext() + }, [emblaApi]) + return ( +
+
+
+

+ {title} +

+

+ {description} +

+
+ +
+ + +
+
+ +
+
+ {items.map( + ({ featured, title, content, tags, slug, isPremium }, index) => ( +
+
+ {title} +
+
+ {tags?.map((item) => ( + + {item} + + ))} + {isPremium && ( + + Premium Content + + )} +
+ +
+

+ {title} +

+

+ {content} +

+
+ +
+
+
+ ), + )} +
+
+
+ ) +} diff --git a/app/data/contents.ts b/app/data/contents.ts new file mode 100644 index 0000000..2606211 --- /dev/null +++ b/app/data/contents.ts @@ -0,0 +1,132 @@ +import type { TNews } from '~/types/news' + +export const SPOTLIGHT: TNews = { + title: 'SPOTLIGHT', + description: 'Berita Terhangat hari ini', + type: 'hero', + items: [ + { + title: '01 Hotman Paris Membuka Perpustakaan di tengah Diskotik', + content: + 'Pengacara Kondang, Hotman Paris Hutapea, membuka sebuah perpustakaan baru di dalam diskotik nya yang berlokasi di daerah Jakarta Pusat, Hotman berkata Perpustakaan ini dibuka dengan harapan untuk meningkatkan gairah membaca masyarakat Indonesia, namun sayangnya..', + featured: '/images/news-1.jpg', + slug: 'hotman-paris-membuka-perpustakaan-di-tengah-diskotik', + }, + { + title: '02 Travelling as a way of self-discovery and progress', + content: + 'Pengacara Kondang, Hotman Paris Hutapea, membuka sebuah perpustakaan baru di dalam diskotik nya yang berlokasi di daerah Jakarta Pusat, Hotman berkata Perpustakaan ini dibuka dengan harapan untuk meningkatkan gairah membaca masyarakat Indonesia, namun sayangnya..', + featured: 'https://placehold.co/600x400.png', + slug: 'hotman-paris-membuka-perpustakaan-di-tengah-diskotik', + }, + { + title: '03 Travelling as a way of self-discovery and progress', + content: + 'Pengacara Kondang, Hotman Paris Hutapea, membuka sebuah perpustakaan baru di dalam diskotik nya yang berlokasi di daerah Jakarta Pusat, Hotman berkata Perpustakaan ini dibuka dengan harapan untuk meningkatkan gairah membaca masyarakat Indonesia, namun sayangnya..', + featured: '/images/news-1.jpg', + slug: 'hotman-paris-membuka-perpustakaan-di-tengah-diskotik', + }, + ], +} + +export const BERITA: TNews = { + title: 'BERITA', + description: 'Berita Terhangat hari ini', + type: 'grid', + items: [ + { + title: '01 Travelling as a way of self-discovery and progress ', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: '/images/news-2.jpg', + tags: ['Hukum Property'], + slug: 'travelling-as-a-way-of-self-discovery-and-progress', + }, + { + title: '02 How does writing influence your personal brand?', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: '/images/news-3.jpg', + tags: ['Hukum'], + slug: 'how-does-writing-influence-your-personal-brand', + }, + { + title: '03 Helping a local business reinvent itself', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: '/images/news-4.jpg', + tags: ['Hukum Property'], + isPremium: true, + slug: 'helping-a-local-business-reinvent-itself', + }, + { + title: 'Travelling as a way of self-discovery and progress', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: 'https://placehold.co/600x400.png', + tags: ['Hukum Property'], + slug: 'travelling-as-a-way-of-self-discovery-and-progress', + }, + { + title: 'How does writing influence your personal brand?', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: '/images/news-3.jpg', + tags: ['Hukum'], + slug: 'how-does-writing-influence-your-personal-brand', + }, + { + title: 'Helping a local business reinvent itself', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: '/images/news-4.jpg', + tags: ['Hukum Property'], + isPremium: true, + slug: 'helping-a-local-business-reinvent-itself', + }, + ], +} + +export const KAJIAN: TNews = { + title: 'KAJIAN', + description: 'Berita Terhangat hari ini', + type: 'grid', + items: [ + { + title: 'Travelling as a way of self-discovery and progress', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: '/images/news-2.jpg', + tags: ['Hukum Property'], + isPremium: true, + slug: 'travelling-as-a-way-of-self-discovery-and-progress', + }, + { + title: 'Travelling as a way of self-discovery and progress', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: 'https://placehold.co/600x400.png', + tags: ['Hukum Property'], + isPremium: true, + slug: 'travelling-as-a-way-of-self-discovery-and-progress', + }, + { + title: 'How does writing influence your personal brand?', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: '/images/news-3.jpg', + tags: ['Hukum Property'], + isPremium: true, + slug: 'how-does-writing-influence-your-personal-brand', + }, + { + title: 'Helping a local business reinvent itself', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', + featured: '/images/news-4.jpg', + tags: ['Hukum Property'], + isPremium: true, + slug: 'helping-a-local-business-reinvent-itself', + }, + ], +} diff --git a/app/layouts/news/default.tsx b/app/layouts/news/default.tsx index 5caf422..abdc8ca 100644 --- a/app/layouts/news/default.tsx +++ b/app/layouts/news/default.tsx @@ -34,7 +34,7 @@ export const NewsDefaultLayout = (properties: PropsWithChildren) => { -
+
{children}
diff --git a/app/pages/news/data.ts b/app/pages/news/data.ts index 2606211..e905e49 100644 --- a/app/pages/news/data.ts +++ b/app/pages/news/data.ts @@ -16,7 +16,7 @@ export const SPOTLIGHT: TNews = { title: '02 Travelling as a way of self-discovery and progress', content: 'Pengacara Kondang, Hotman Paris Hutapea, membuka sebuah perpustakaan baru di dalam diskotik nya yang berlokasi di daerah Jakarta Pusat, Hotman berkata Perpustakaan ini dibuka dengan harapan untuk meningkatkan gairah membaca masyarakat Indonesia, namun sayangnya..', - featured: 'https://placehold.co/600x400.png', + featured: 'https://placehold.co/800x500.png', slug: 'hotman-paris-membuka-perpustakaan-di-tengah-diskotik', }, { @@ -63,7 +63,7 @@ export const BERITA: TNews = { title: 'Travelling as a way of self-discovery and progress', content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: 'https://placehold.co/600x400.png', + featured: 'https://placehold.co/800x500.png', tags: ['Hukum Property'], slug: 'travelling-as-a-way-of-self-discovery-and-progress', }, diff --git a/app/pages/news/index.tsx b/app/pages/news/index.tsx index 730ddb0..f4b95d0 100644 --- a/app/pages/news/index.tsx +++ b/app/pages/news/index.tsx @@ -1,23 +1,21 @@ import { Card } from '~/components/ui/card' -import { Carousel } from '~/components/ui/carousel' +import { CarouselHero } from '~/components/ui/carousel-hero' +import { CarouselSection } from '~/components/ui/carousel-section' import { Newsletter } from '~/components/ui/newsletter' -import { BERITA, KAJIAN, SPOTLIGHT } from './data' +import { SPOTLIGHT, BERITA } from './data' export const NewsPage = () => { return (
- +
- - - - +
)