feat: add news and dashboard content routes with corresponding layouts

This commit is contained in:
Ardeman 2025-03-07 12:11:48 +08:00
parent afebd8b335
commit 18098d63ba
22 changed files with 38 additions and 59 deletions

View File

@ -12,7 +12,7 @@ import { LeftArrow } from '~/components/icons/left-arrow'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { APP } from '~/configs/meta' import { APP } from '~/configs/meta'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
export type ModalProperties = { export type ModalProperties = {
onClose: () => void onClose: () => void
@ -35,7 +35,7 @@ const DESCRIPTIONS: DescriptionMap = {
export const SuccessModal = ({ isOpen, onClose }: ModalProperties) => { export const SuccessModal = ({ isOpen, onClose }: ModalProperties) => {
const { setIsLoginOpen, setIsSubscribeOpen } = useNewsContext() const { setIsLoginOpen, setIsSubscribeOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const userData = loaderData?.userData const userData = loaderData?.userData
const message = isOpen const message = isOpen

View File

@ -5,13 +5,13 @@ import { useRouteLoaderData } from 'react-router'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { CarouselButton } from '~/components/ui/button-slide' import { CarouselButton } from '~/components/ui/button-slide'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
import type { TNews } from '~/types/news' import type { TNews } from '~/types/news'
import { getPremiumAttribute } from '~/utils/render' import { getPremiumAttribute } from '~/utils/render'
export const CarouselHero = (properties: TNews) => { export const CarouselHero = (properties: TNews) => {
const { setIsSuccessOpen } = useNewsContext() const { setIsSuccessOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const userData = loaderData?.userData const userData = loaderData?.userData
const { title, description, items } = properties const { title, description, items } = properties
const [emblaReference, emblaApi] = useEmblaCarousel({ loop: false }) const [emblaReference, emblaApi] = useEmblaCarousel({ loop: false })

View File

@ -5,13 +5,13 @@ import { useRouteLoaderData } from 'react-router'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { CarouselButton } from '~/components/ui/button-slide' import { CarouselButton } from '~/components/ui/button-slide'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
import type { TNews } from '~/types/news' import type { TNews } from '~/types/news'
import { getPremiumAttribute } from '~/utils/render' import { getPremiumAttribute } from '~/utils/render'
export const CarouselSection = (properties: TNews) => { export const CarouselSection = (properties: TNews) => {
const { setIsSuccessOpen } = useNewsContext() const { setIsSuccessOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const userData = loaderData?.userData const userData = loaderData?.userData
const { title, description, items } = properties const { title, description, items } = properties
const [emblaReference, emblaApi] = useEmblaCarousel({ const [emblaReference, emblaApi] = useEmblaCarousel({

View File

@ -5,13 +5,13 @@ import { CarouselNextIcon } from '~/components/icons/carousel-next'
import { CarouselPreviousIcon } from '~/components/icons/carousel-previous' import { CarouselPreviousIcon } from '~/components/icons/carousel-previous'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
import type { TNews } from '~/types/news' import type { TNews } from '~/types/news'
import { getPremiumAttribute } from '~/utils/render' import { getPremiumAttribute } from '~/utils/render'
export const CategorySection = (properties: TNews) => { export const CategorySection = (properties: TNews) => {
const { setIsSuccessOpen } = useNewsContext() const { setIsSuccessOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const userData = loaderData?.userData const userData = loaderData?.userData
const { title, description, items } = properties const { title, description, items } = properties

View File

@ -9,7 +9,7 @@ import { Button } from '~/components/ui/button'
import { Combobox } from '~/components/ui/combobox' import { Combobox } from '~/components/ui/combobox'
import { Input } from '~/components/ui/input' import { Input } from '~/components/ui/input'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
export const registerSchema = z export const registerSchema = z
.object({ .object({
@ -42,7 +42,7 @@ export const FormRegister = () => {
const [error, setError] = useState<string>() const [error, setError] = useState<string>()
const [disabled, setDisabled] = useState(false) const [disabled, setDisabled] = useState(false)
const fetcher = useFetcher() const fetcher = useFetcher()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const subscriptions = loaderData?.subscriptionsData const subscriptions = loaderData?.subscriptionsData
const formMethods = useRemixForm<TRegisterSchema>({ const formMethods = useRemixForm<TRegisterSchema>({

View File

@ -7,7 +7,7 @@ import { z } from 'zod'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { Combobox } from '~/components/ui/combobox' import { Combobox } from '~/components/ui/combobox'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
export const subscribeSchema = z.object({ export const subscribeSchema = z.object({
subscribe_plan: z subscribe_plan: z
@ -30,7 +30,7 @@ export default function FormSubscription() {
const fetcher = useFetcher() const fetcher = useFetcher()
const [error, setError] = useState<string>() const [error, setError] = useState<string>()
const [disabled, setDisabled] = useState(false) const [disabled, setDisabled] = useState(false)
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const subscriptions = loaderData?.subscriptionsData const subscriptions = loaderData?.subscriptionsData
const formMethods = useRemixForm<TSubscribeSchema>({ const formMethods = useRemixForm<TSubscribeSchema>({

View File

@ -7,7 +7,7 @@ import { MenuIcon } from '~/components/icons/menu'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import { HeaderSearch } from '~/layouts/news/header-search' import { HeaderSearch } from '~/layouts/news/header-search'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
type THeaderMenuMobile = { type THeaderMenuMobile = {
menu?: TCategoriesResponse['data'] menu?: TCategoriesResponse['data']
@ -17,7 +17,7 @@ export default function HeaderMenuMobile(properties: THeaderMenuMobile) {
const { menu } = properties const { menu } = properties
const [isMenuOpen, setIsMenuOpen] = useState(false) const [isMenuOpen, setIsMenuOpen] = useState(false)
const { setIsLoginOpen } = useNewsContext() const { setIsLoginOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const userData = loaderData?.userData const userData = loaderData?.userData
const fetcher = useFetcher() const fetcher = useFetcher()

View File

@ -1,12 +1,12 @@
import { Link, useRouteLoaderData } from 'react-router' import { Link, useRouteLoaderData } from 'react-router'
import HeaderMenuMobile from '~/layouts/news/header-menu-mobile' import HeaderMenuMobile from '~/layouts/news/header-menu-mobile'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
import { HeaderSearch } from './header-search' import { HeaderSearch } from './header-search'
export const HeaderMenu = () => { export const HeaderMenu = () => {
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const menu = loaderData?.categoriesData const menu = loaderData?.categoriesData
return ( return (

View File

@ -3,11 +3,11 @@ import { Link, useFetcher, useRouteLoaderData } from 'react-router'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { APP } from '~/configs/meta' import { APP } from '~/configs/meta'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
export const HeaderTop = () => { export const HeaderTop = () => {
const { setIsLoginOpen } = useNewsContext() const { setIsLoginOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const userData = loaderData?.userData const userData = loaderData?.userData
const fetcher = useFetcher() const fetcher = useFetcher()

View File

@ -8,12 +8,12 @@ import type { TTagResponse } from '~/apis/common/get-tags'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { UiTable } from '~/components/ui/table' import { UiTable } from '~/components/ui/table'
import { TitleDashboard } from '~/components/ui/title-dashboard' import { TitleDashboard } from '~/components/ui/title-dashboard'
import type { loader } from '~/routes/_admin.lg-admin._dashboard.contents' import type { loader } from '~/routes/_admin.lg-admin._dashboard.contents._index'
import { formatDate } from '~/utils/formatter' import { formatDate } from '~/utils/formatter'
export const ContentsPage = () => { export const ContentsPage = () => {
const loaderData = useRouteLoaderData<typeof loader>( const loaderData = useRouteLoaderData<typeof loader>(
'routes/_admin.lg-admin._dashboard.contents', 'routes/_admin.lg-admin._dashboard.contents._index',
) )
const newsData = loaderData?.newsData const newsData = loaderData?.newsData

View File

@ -3,14 +3,14 @@ import { useLocation, useRouteLoaderData } from 'react-router'
import { Card } from '~/components/ui/card' import { Card } from '~/components/ui/card'
import { CategorySection } from '~/components/ui/category-section' import { CategorySection } from '~/components/ui/category-section'
import { DUMMY_DESCRIPTION } from '~/data/contents' import { DUMMY_DESCRIPTION } from '~/data/contents'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_news'
import { BERITA } from './data' import { BERITA } from './data'
export const NewsCategoriesPage = () => { export const NewsCategoriesPage = () => {
const { pathname } = useLocation() const { pathname } = useLocation()
const code = pathname.split('/')[2] const code = pathname.split('/')[2]
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout') const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
const { name } = const { name } =
loaderData?.categoriesData.find((item) => item.code === code) || {} loaderData?.categoriesData.find((item) => item.code === code) || {}
const { items } = BERITA const { items } = BERITA

View File

@ -0,0 +1,4 @@
import { CreateCategoryPage } from '~/pages/category-create'
const DashboardCategoryLayout = () => <CreateCategoryPage />
export default DashboardCategoryLayout

View File

@ -2,7 +2,7 @@ import { getNews } from '~/apis/admin/get-news'
import { handleCookie } from '~/libs/cookies' import { handleCookie } from '~/libs/cookies'
import { ContentsPage } from '~/pages/dashboard-contents' import { ContentsPage } from '~/pages/dashboard-contents'
import type { Route } from './+types/_admin.lg-admin._dashboard.contents' import type { Route } from './+types/_admin.lg-admin._dashboard.contents._index'
export const loader = async ({ request }: Route.LoaderArgs) => { export const loader = async ({ request }: Route.LoaderArgs) => {
const { staffToken } = await handleCookie(request) const { staffToken } = await handleCookie(request)
@ -12,5 +12,5 @@ export const loader = async ({ request }: Route.LoaderArgs) => {
return { newsData } return { newsData }
} }
const DashboardContentsLayout = () => <ContentsPage /> const DashboardContentsIndexLayout = () => <ContentsPage />
export default DashboardContentsLayout export default DashboardContentsIndexLayout

View File

@ -0,0 +1,4 @@
import { ContentsFormPage } from '~/pages/contents-form'
const DashboardContentCreateLayout = () => <ContentsFormPage />
export default DashboardContentCreateLayout

View File

@ -0,0 +1,4 @@
import { UpdateContentsPage } from '~/pages/contents-update'
const DashboardContentUpdateLayout = () => <UpdateContentsPage />
export default DashboardContentUpdateLayout

View File

@ -1,11 +0,0 @@
import { AdminDashboardLayout } from '~/layouts/admin/dashboard'
import { CreateCategoryPage } from '~/pages/category-create'
const DashboardContentsLayout = () => {
return (
<AdminDashboardLayout>
<CreateCategoryPage />
</AdminDashboardLayout>
)
}
export default DashboardContentsLayout

View File

@ -1,11 +0,0 @@
import { AdminDashboardLayout } from '~/layouts/admin/dashboard'
import { ContentsFormPage } from '~/pages/contents-form'
const DashboardContentsLayout = () => {
return (
<AdminDashboardLayout>
<ContentsFormPage />
</AdminDashboardLayout>
)
}
export default DashboardContentsLayout

View File

@ -1,11 +0,0 @@
import { AdminDashboardLayout } from '~/layouts/admin/dashboard'
import { UpdateContentsPage } from '~/pages/contents-update'
const DashboardContentsLayout = () => {
return (
<AdminDashboardLayout>
<UpdateContentsPage />
</AdminDashboardLayout>
)
}
export default DashboardContentsLayout

View File

@ -7,7 +7,7 @@ import { NewsProvider } from '~/contexts/news'
import { NewsDefaultLayout } from '~/layouts/news/default' import { NewsDefaultLayout } from '~/layouts/news/default'
import { handleCookie } from '~/libs/cookies' import { handleCookie } from '~/libs/cookies'
import type { Route } from './+types/_layout' import type { Route } from './+types/_news'
export const loader = async ({ request }: Route.LoaderArgs) => { export const loader = async ({ request }: Route.LoaderArgs) => {
const { userToken } = await handleCookie(request) const { userToken } = await handleCookie(request)