From 77c984326730d535a148d4081bd8079c46fe28d2 Mon Sep 17 00:00:00 2001 From: Ardeman Date: Sat, 22 Feb 2025 17:34:25 +0800 Subject: [PATCH] feat: implement news layout components and context for improved structure and functionality --- app/contexts/news.tsx | 36 +++++++++++++ app/layouts/news/default.tsx | 54 +++++++++++++++++++ app/layouts/{ => news}/footer-links.tsx | 0 app/layouts/{ => news}/footer-newsletter.tsx | 0 app/layouts/{ => news}/header-menu-mobile.tsx | 12 ++++- app/layouts/{ => news}/header-menu.tsx | 2 +- app/layouts/{ => news}/header-search.tsx | 0 app/layouts/{ => news}/header-top.tsx | 28 +--------- app/layouts/{ => news}/menu.ts | 0 app/routes/_layout.news.tsx | 25 +++------ eslint.config.mjs | 2 +- 11 files changed, 110 insertions(+), 49 deletions(-) create mode 100644 app/contexts/news.tsx create mode 100644 app/layouts/news/default.tsx rename app/layouts/{ => news}/footer-links.tsx (100%) rename app/layouts/{ => news}/footer-newsletter.tsx (100%) rename app/layouts/{ => news}/header-menu-mobile.tsx (85%) rename app/layouts/{ => news}/header-menu.tsx (91%) rename app/layouts/{ => news}/header-search.tsx (100%) rename app/layouts/{ => news}/header-top.tsx (59%) rename app/layouts/{ => news}/menu.ts (100%) diff --git a/app/contexts/news.tsx b/app/contexts/news.tsx new file mode 100644 index 0000000..d023b84 --- /dev/null +++ b/app/contexts/news.tsx @@ -0,0 +1,36 @@ +import React, { + createContext, + useState, + useContext, + type PropsWithChildren, +} from 'react' + +type NewsContextProperties = { + isLoginOpen: boolean + setIsLoginOpen: React.Dispatch> + isRegisterOpen: boolean + setIsRegisterOpen: React.Dispatch> +} + +const NewsContext = createContext(undefined) + +export const NewsProvider = ({ children }: PropsWithChildren) => { + const [isLoginOpen, setIsLoginOpen] = useState(false) + const [isRegisterOpen, setIsRegisterOpen] = useState(false) + + return ( + + {children} + + ) +} + +export const useNewsContext = (): NewsContextProperties => { + const context = useContext(NewsContext) + if (!context) { + throw new Error('useNewsContext must be used within a NewsProvider') + } + return context +} diff --git a/app/layouts/news/default.tsx b/app/layouts/news/default.tsx new file mode 100644 index 0000000..ad3c2ae --- /dev/null +++ b/app/layouts/news/default.tsx @@ -0,0 +1,54 @@ +import { type PropsWithChildren } from 'react' + +import { PopupModal } from '~/components/popup/modal' +import Banner from '~/components/ui/banner' +import { FormLogin } from '~/components/ui/form-login' +import { FormRegister } from '~/components/ui/form-register' +import { useNewsContext } from '~/contexts/news' + +import { FooterLinks } from './footer-links' +import { FooterNewsletter } from './footer-newsletter' +import { HeaderMenu } from './header-menu' +import { HeaderTop } from './header-top' + +export const NewsDefaultLayout = (properties: PropsWithChildren) => { + const { children } = properties + const { isLoginOpen, setIsLoginOpen, isRegisterOpen, setIsRegisterOpen } = + useNewsContext() + return ( +
+
+ + +
+
+ + {children} +
+ +
+ + +
+ + setIsLoginOpen(false)} + description="Selamat Datang, silakan daftarkan akun Anda untuk melanjutkan!" + > + + + + setIsRegisterOpen(false)} + description="Selamat Datang, silakan daftarkan akun Anda untuk melanjutkan!" + > + + +
+ ) +} diff --git a/app/layouts/footer-links.tsx b/app/layouts/news/footer-links.tsx similarity index 100% rename from app/layouts/footer-links.tsx rename to app/layouts/news/footer-links.tsx diff --git a/app/layouts/footer-newsletter.tsx b/app/layouts/news/footer-newsletter.tsx similarity index 100% rename from app/layouts/footer-newsletter.tsx rename to app/layouts/news/footer-newsletter.tsx diff --git a/app/layouts/header-menu-mobile.tsx b/app/layouts/news/header-menu-mobile.tsx similarity index 85% rename from app/layouts/header-menu-mobile.tsx rename to app/layouts/news/header-menu-mobile.tsx index def919b..1b9607e 100644 --- a/app/layouts/header-menu-mobile.tsx +++ b/app/layouts/news/header-menu-mobile.tsx @@ -3,12 +3,14 @@ import { Link } from 'react-router' import { CloseIcon } from '~/components/icons/close' import { MenuIcon } from '~/components/icons/menu' -import { HeaderSearch } from '~/layouts/header-search' +import { useNewsContext } from '~/contexts/news' +import { HeaderSearch } from '~/layouts/news/header-search' import { MENU } from './menu' export default function HeaderMenuMobile() { const [isMenuOpen, setIsMenuOpen] = useState(false) + const { setIsLoginOpen } = useNewsContext() const handleToggleMenu = (): void => { setIsMenuOpen(!isMenuOpen) @@ -53,7 +55,13 @@ export default function HeaderMenuMobile() { ))} - diff --git a/app/layouts/header-menu.tsx b/app/layouts/news/header-menu.tsx similarity index 91% rename from app/layouts/header-menu.tsx rename to app/layouts/news/header-menu.tsx index aca354e..6236017 100644 --- a/app/layouts/header-menu.tsx +++ b/app/layouts/news/header-menu.tsx @@ -1,6 +1,6 @@ import { Link } from 'react-router' -import HeaderMenuMobile from '~/layouts/header-menu-mobile' +import HeaderMenuMobile from '~/layouts/news/header-menu-mobile' import { HeaderSearch } from './header-search' import { MENU } from './menu' diff --git a/app/layouts/header-search.tsx b/app/layouts/news/header-search.tsx similarity index 100% rename from app/layouts/header-search.tsx rename to app/layouts/news/header-search.tsx diff --git a/app/layouts/header-top.tsx b/app/layouts/news/header-top.tsx similarity index 59% rename from app/layouts/header-top.tsx rename to app/layouts/news/header-top.tsx index 2a9c972..8b09855 100644 --- a/app/layouts/header-top.tsx +++ b/app/layouts/news/header-top.tsx @@ -1,16 +1,11 @@ -import { useState } from 'react' import { Link } from 'react-router' -import { PopupModal } from '~/components/popup/modal' import { Button } from '~/components/ui/button' -import { FormLogin } from '~/components/ui/form-login' -import { FormRegister } from '~/components/ui/form-register' +import { useNewsContext } from '~/contexts/news' import { APP } from '~/data/meta' export const HeaderTop = () => { - const [isLoginOpen, setIsLoginOpen] = useState(false) - const [isRegisterOpen, setIsRegisterOpen] = useState(false) - + const { setIsLoginOpen } = useNewsContext() return ( <>
@@ -47,25 +42,6 @@ export const HeaderTop = () => {
- - setIsLoginOpen(false)} - description="Selamat Datang, silakan daftarkan akun Anda untuk melanjutkan!" - > - - - - setIsRegisterOpen(false)} - description="Selamat Datang, silakan daftarkan akun Anda untuk melanjutkan!" - > - - ) } diff --git a/app/layouts/menu.ts b/app/layouts/news/menu.ts similarity index 100% rename from app/layouts/menu.ts rename to app/layouts/news/menu.ts diff --git a/app/routes/_layout.news.tsx b/app/routes/_layout.news.tsx index 097a02d..751a087 100644 --- a/app/routes/_layout.news.tsx +++ b/app/routes/_layout.news.tsx @@ -1,28 +1,15 @@ import { Outlet } from 'react-router' -import Banner from '~/components/ui/banner' -import { FooterLinks } from '~/layouts/footer-links' -import { FooterNewsletter } from '~/layouts/footer-newsletter' -import { HeaderMenu } from '~/layouts/header-menu' -import { HeaderTop } from '~/layouts/header-top' +import { NewsProvider } from '~/contexts/news' +import { NewsDefaultLayout } from '~/layouts/news/default' const NewsLayout = () => { return ( -
-
- - -
-
- + + -
- - -
+ + ) } diff --git a/eslint.config.mjs b/eslint.config.mjs index 517717c..8403701 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -82,7 +82,7 @@ export default tseslint.config( '~/factories/*/*', '~/pages/*/*', '~/hooks/*/*', - '~/layouts/*/*/*', + '~/layouts/*/*/*/*', '~/schemas/*/*/*', '~/types/*/*', '~/utils/*/**',