feat: restructure routing and layouts for admin and news sections, update cookie paths

This commit is contained in:
Ardeman 2025-02-28 11:49:51 +08:00
parent 4b8fc0721e
commit 23e3493a3f
30 changed files with 55 additions and 64 deletions

View File

@ -136,7 +136,7 @@ export const Carousel = (properties: TNews) => {
},
to: '',
}
: { as: Link, to: `/news/detail/${slug}` })}
: { as: Link, to: `/detail/${slug}` })}
className={twMerge('', type === 'hero' ? '' : 'mb-5')}
>
View More

View File

@ -14,7 +14,7 @@ type TMetaTitleConfig = {
export const META_TITLE_CONFIG: TMetaTitleConfig = [
{
path: '/news',
path: '/',
title: 'Home',
},
{

View File

@ -11,7 +11,7 @@ export const Navbar = () => {
return (
<div className="flex h-20 items-center justify-between border-b border-[#ECECEC] bg-white px-10 py-5">
<Link
to="/news"
to="/"
className="h-full"
>
<img

View File

@ -9,7 +9,7 @@ export const FooterNewsletter = () => {
<div className="col-span-2 hidden gap-y-6 sm:grid">
<div className="h-[75px] bg-white p-3">
<Link
to="/news"
to="/"
className="h-full"
>
<img
@ -44,7 +44,7 @@ export const FooterNewsletter = () => {
<div className="block sm:hidden">
<div className="h-[60px] bg-white p-3">
<Link
to="/news"
to="/"
className="h-full"
>
<img

View File

@ -67,7 +67,7 @@ export const FormLogin = (properties: TProperties) => {
method="post"
onSubmit={handleSubmit}
className="space-y-4"
action="/actions/news/login"
action="/actions/login"
>
<Input
id="email"

View File

@ -3,17 +3,17 @@ import { Link, useFetcher, useRouteLoaderData } from 'react-router'
import { Button } from '~/components/ui/button'
import { APP } from '~/configs/meta'
import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout.news'
import type { loader } from '~/routes/_layout'
export const HeaderTop = () => {
const { setIsLoginOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout.news')
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout')
const fetcher = useFetcher()
return (
<div className="flex h-[60px] items-center justify-between bg-white px-5 align-middle sm:h-[100px] sm:gap-[15px] sm:px-[50px] sm:py-[20px]">
<Link
to="/news"
to="/"
className="mt-2 h-full py-2"
>
<img
@ -32,7 +32,7 @@ export const HeaderTop = () => {
{loaderData?.userToken ? (
<fetcher.Form
method="POST"
action="/actions/news/logout"
action="/actions/logout"
>
<Button
variant="newsSecondary"

View File

@ -21,31 +21,31 @@ type TFooterMenu = {
export const MENU: TMenu[] = [
{
title: 'Spotlight',
url: '/news/category/spotlight',
url: '/category/spotlight',
},
{
title: 'Berita',
url: '/news/category/berita',
url: '/category/berita',
},
{
title: 'Kasus',
url: '/news/category/kasus',
url: '/category/kasus',
},
{
title: 'Kajian',
url: '/news/category/kajian',
url: '/category/kajian',
},
{
title: 'Lifestyle',
url: '/news/category/lifestyle',
url: '/category/lifestyle',
},
{
title: 'Event',
url: '/news/category/event',
url: '/category/event',
},
{
title: 'Travel',
url: '/news/category/travel',
url: '/category/travel',
},
]
@ -55,23 +55,23 @@ export const FOOTER_MENU: TFooterMenu[] = [
items: [
{
title: 'Popular',
url: '/news/list?sort=popular',
url: '/list?sort=popular',
},
{
title: 'Trending',
url: '/news/list?sort=trending',
url: '/list?sort=trending',
},
{
title: 'Contact',
url: '/news/contact',
url: '/contact',
},
{
title: 'Support/Help',
url: '/news/support',
url: '/support',
},
{
title: 'Rquest Topic',
url: '/news/request-topic',
url: '/request-topic',
},
],
},
@ -80,23 +80,23 @@ export const FOOTER_MENU: TFooterMenu[] = [
items: [
{
title: 'FAQs',
url: '/news/faq',
url: '/faq',
},
{
title: 'Terms and Condition',
url: '/news/terms-condition',
url: '/terms-condition',
},
{
title: 'Support',
url: '/news/support',
url: '/support',
},
{
title: 'Link Nine',
url: '/news',
url: '/',
},
{
title: 'Link Ten',
url: '/news',
url: '/',
},
],
},
@ -130,14 +130,14 @@ export const FOOTER_MENU: TFooterMenu[] = [
export const COPYRIGHT_MENU: TMenu[] = [
{
title: 'Privacy Policy',
url: '/news/privacy-policy',
url: '/privacy-policy',
},
{
title: 'Terms of Service',
url: '/news/terms-of-service',
url: '/terms-of-service',
},
{
title: 'Cookies Settings',
url: '/news/cookies-settings',
url: '/cookies-settings',
},
]

View File

@ -7,7 +7,7 @@ export const userTokenCookieConfig = createCookie(USER_COOKIES.token, {
sameSite: 'lax',
secure: process.env.NODE_ENV === 'production',
secrets: [process.env.VITE_SALT_KEY || 'default-secret'],
path: '/news',
path: '/',
})
export const adminTokenCookieConfig = createCookie(ADMIN_COOKIES.token, {

View File

@ -4,7 +4,7 @@ export const setUserLogoutHeaders = () => {
const responseHeaders = new Headers()
responseHeaders.append(
'Set-Cookie',
`${USER_COOKIES.token}=; Path=/news; HttpOnly; SameSite=Strict; Max-Age=0`,
`${USER_COOKIES.token}=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0`,
)
return responseHeaders

View File

@ -6,7 +6,6 @@ import {
Outlet,
Scripts,
ScrollRestoration,
type ShouldRevalidateFunctionArgs,
} from 'react-router'
import type { Route } from './+types/root'
@ -37,16 +36,6 @@ export const meta = ({ location }: Route.MetaArgs) => {
]
}
export const shouldRevalidate = ({
actionResult,
defaultShouldRevalidate,
}: ShouldRevalidateFunctionArgs) => {
if (actionResult?.success) {
return true
}
return defaultShouldRevalidate
}
export const Layout = ({ children }: { children: ReactNode }) => {
return (
<html lang="en">

View File

@ -1,5 +1,7 @@
import { redirect } from 'react-router'
import { NewsPage } from '~/pages/news'
export async function loader() {
return redirect('/news')
const NewsIndexLayout = () => {
return <NewsPage />
}
export default NewsIndexLayout

View File

@ -1,7 +0,0 @@
import { NewsPage } from '~/pages/news'
const NewsIndexLayout = () => {
return <NewsPage />
}
export default NewsIndexLayout

View File

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

View File

@ -7,7 +7,7 @@ import { newsLoginRequest } from '~/apis/news/login'
import { loginSchema, type TLoginSchema } from '~/layouts/news/form-login'
import { generateTokenCookie } from '~/utils/token'
import type { Route } from './+types/actions.news.login'
import type { Route } from './+types/actions.login'
export const action = async ({ request }: Route.ActionArgs) => {
try {
@ -46,14 +46,22 @@ export const action = async ({ request }: Route.ActionArgs) => {
)
} catch (error) {
if (error instanceof XiorError) {
return data({
return data(
{
success: false,
message: error?.response?.data?.error?.message || error.message,
})
},
{
status: error?.response?.status || 500,
},
)
}
return data({
return data(
{
success: false,
message: 'Internal server error',
})
},
{ status: 500 },
)
}
}

View File

@ -7,6 +7,5 @@ export default defineConfig({
plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
build: {
cssMinify: true,
ssr: false,
},
})