Compare commits
2 Commits
cfc864cb43
...
4aa6c8d0d4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4aa6c8d0d4 | ||
|
|
25e136ba72 |
25
app/apis/common/get-categories.ts
Normal file
25
app/apis/common/get-categories.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
import { HttpServer, type THttpServer } from '~/libs/http-server'
|
||||
|
||||
const categorySchema = z.object({
|
||||
data: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
code: z.string(),
|
||||
name: z.string(),
|
||||
}),
|
||||
),
|
||||
})
|
||||
|
||||
export type TCategorySchema = z.infer<typeof categorySchema>
|
||||
|
||||
export const getCategories = async (parameters?: THttpServer) => {
|
||||
try {
|
||||
const { data } = await HttpServer(parameters).get(`/api/category`)
|
||||
return categorySchema.parse(data)
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line unicorn/no-useless-promise-resolve-reject
|
||||
return Promise.reject(error)
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,7 @@ import {
|
||||
|
||||
import type { ModalProperties } from '~/components/popup/success-modal'
|
||||
|
||||
export type NewsContextProperties = {
|
||||
type NewsContextProperties = {
|
||||
isLoginOpen: boolean
|
||||
setIsLoginOpen: Dispatch<SetStateAction<boolean>>
|
||||
isRegisterOpen: boolean
|
||||
|
||||
@ -1,14 +1,18 @@
|
||||
import { useState } from 'react'
|
||||
import { Link } from 'react-router'
|
||||
|
||||
import type { TCategorySchema } from '~/apis/common/get-categories'
|
||||
import { CloseIcon } from '~/components/icons/close'
|
||||
import { MenuIcon } from '~/components/icons/menu'
|
||||
import { useNewsContext } from '~/contexts/news'
|
||||
import { HeaderSearch } from '~/layouts/news/header-search'
|
||||
|
||||
import { MENU } from './menu'
|
||||
type THeaderMenuMobile = {
|
||||
menu?: TCategorySchema['data']
|
||||
}
|
||||
|
||||
export default function HeaderMenuMobile() {
|
||||
export default function HeaderMenuMobile(properties: THeaderMenuMobile) {
|
||||
const { menu } = properties
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false)
|
||||
const { setIsLoginOpen } = useNewsContext()
|
||||
|
||||
@ -38,19 +42,19 @@ export default function HeaderMenuMobile() {
|
||||
|
||||
{/* List Menu */}
|
||||
<ul className="mx-10 mt-10 max-lg:space-y-3 lg:ml-14 lg:flex lg:gap-x-5">
|
||||
{MENU.map((item, index) => (
|
||||
{menu?.map((item, index) => (
|
||||
<li
|
||||
key={index}
|
||||
className="px-3 max-lg:border-b max-lg:py-3"
|
||||
>
|
||||
<Link
|
||||
key={item.title}
|
||||
to={item.url}
|
||||
key={item.id}
|
||||
to={`/category/${item.code}`}
|
||||
className={
|
||||
'flex h-full items-center justify-center border-white px-[35px] sm:border-r'
|
||||
}
|
||||
>
|
||||
{item.title}
|
||||
{item.name}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@ -1,28 +1,31 @@
|
||||
import { Link } from 'react-router'
|
||||
import { Link, useRouteLoaderData } from 'react-router'
|
||||
|
||||
import HeaderMenuMobile from '~/layouts/news/header-menu-mobile'
|
||||
import type { loader } from '~/routes/_layout'
|
||||
|
||||
import { HeaderSearch } from './header-search'
|
||||
import { MENU } from './menu'
|
||||
|
||||
export const HeaderMenu = () => {
|
||||
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout')
|
||||
const menu = loaderData?.categoriesData
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="hidden h-[60px] items-center justify-between bg-[#2E2F7C] text-xl font-medium text-white sm:flex">
|
||||
{MENU.map((item) => (
|
||||
{menu?.map((item) => (
|
||||
<Link
|
||||
key={item.title}
|
||||
to={item.url}
|
||||
key={item.id}
|
||||
to={`/category/${item.code}`}
|
||||
className={
|
||||
'flex h-full items-center justify-center border-r border-white px-[35px]'
|
||||
}
|
||||
>
|
||||
{item.title}
|
||||
{item.name}
|
||||
</Link>
|
||||
))}
|
||||
<HeaderSearch />
|
||||
</div>
|
||||
<HeaderMenuMobile />
|
||||
<HeaderMenuMobile menu={menu} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -18,37 +18,6 @@ type TFooterMenu = {
|
||||
items: TMenu[]
|
||||
}
|
||||
|
||||
export const MENU: TMenu[] = [
|
||||
{
|
||||
title: 'Spotlight',
|
||||
url: '/category/spotlight',
|
||||
},
|
||||
{
|
||||
title: 'Berita',
|
||||
url: '/category/berita',
|
||||
},
|
||||
{
|
||||
title: 'Kasus',
|
||||
url: '/category/kasus',
|
||||
},
|
||||
{
|
||||
title: 'Kajian',
|
||||
url: '/category/kajian',
|
||||
},
|
||||
{
|
||||
title: 'Lifestyle',
|
||||
url: '/category/lifestyle',
|
||||
},
|
||||
{
|
||||
title: 'Event',
|
||||
url: '/category/event',
|
||||
},
|
||||
{
|
||||
title: 'Travel',
|
||||
url: '/category/travel',
|
||||
},
|
||||
]
|
||||
|
||||
export const FOOTER_MENU: TFooterMenu[] = [
|
||||
{
|
||||
group: 'About Us',
|
||||
|
||||
@ -1,132 +0,0 @@
|
||||
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/800x500.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/800x500.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',
|
||||
},
|
||||
],
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import { Outlet } from 'react-router'
|
||||
|
||||
import { getCategories } from '~/apis/common/get-categories'
|
||||
import { getSubscriptions } from '~/apis/common/get-subscriptions'
|
||||
import { NewsProvider } from '~/contexts/news'
|
||||
import { NewsDefaultLayout } from '~/layouts/news/default'
|
||||
@ -10,10 +11,12 @@ import type { Route } from './+types/_layout'
|
||||
export const loader = async ({ request }: Route.LoaderArgs) => {
|
||||
const { userToken } = await handleCookie(request)
|
||||
const { data: subscriptionsData } = await getSubscriptions()
|
||||
const { data: categoriesData } = await getCategories()
|
||||
|
||||
return {
|
||||
userToken,
|
||||
subscriptionsData,
|
||||
categoriesData,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user