feat: implement logout action

This commit is contained in:
Ardeman 2025-02-27 23:50:46 +08:00
parent 5acf3970a3
commit 7db38d3b67
8 changed files with 70 additions and 19 deletions

View File

@ -42,7 +42,7 @@ export const PopupModal = ({
<DialogTitle className="relative flex justify-center">
<button
onClick={onClose}
className="absolute top-0 left-0 items-center lg:hidden"
className="absolute top-0 left-0 items-center sm:hidden"
>
<LeftArrow
width={50}

View File

@ -54,7 +54,7 @@ export const SuccessModal = ({ isOpen, onClose }: ModalProperties) => {
<DialogTitle className="relative flex justify-center">
<button
onClick={onClose}
className="absolute top-0 left-0 items-center lg:hidden"
className="absolute top-0 left-0 items-center sm:hidden"
>
<LeftArrow
width={50}

View File

@ -4,7 +4,7 @@ import { APP } from '~/configs/meta'
export const Banner = () => {
return (
<div className="min-h-[65px] lg:mx-10">
<div className="min-h-[65px] sm:mx-10">
<div className="relative">
<Link
to="/#"

View File

@ -115,7 +115,7 @@ export const Carousel = (properties: TNews) => {
<div>
<h3
className={twMerge(
'mt-2 w-full font-bold lg:mt-0',
'mt-2 w-full font-bold sm:mt-0',
type === 'hero'
? 'text-2xl sm:text-4xl'
: 'text-xl sm:text-2xl',

View File

@ -1,4 +1,4 @@
import { Link, useRouteLoaderData } from 'react-router'
import { Link, useFetcher, useRouteLoaderData } from 'react-router'
import { Button } from '~/components/ui/button'
import { APP } from '~/configs/meta'
@ -8,6 +8,7 @@ import type { loader } from '~/routes/_layout.news'
export const HeaderTop = () => {
const { setIsLoginOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout.news')
const fetcher = useFetcher()
return (
<>
@ -29,13 +30,28 @@ export const HeaderTop = () => {
<Button className="h-8 w-auto rounded-none px-3 text-xs sm:h-[50px] sm:w-[150px] sm:text-lg">
About Us
</Button>
<Button
variant="newsSecondary"
className="hidden sm:block"
onClick={() => setIsLoginOpen(true)}
>
{loaderData?.userToken ? 'Logout' : 'Masuk'}
</Button>
{loaderData?.userToken ? (
<fetcher.Form
method="POST"
action="/actions/news/logout"
>
<Button
variant="newsSecondary"
className="hidden sm:block"
type="submit"
>
Logout
</Button>
</fetcher.Form>
) : (
<Button
variant="newsSecondary"
className="hidden sm:block"
onClick={() => setIsLoginOpen(true)}
>
Masuk
</Button>
)}
</div>
</div>
</>

View File

@ -11,7 +11,7 @@ export const NewsPage = () => {
<Carousel {...SPOTLIGHT} />
</Card>
<div className="min-h-[400px] sm:min-h-[300px]">
<Newsletter className="mr-0 lg:-ml-14" />
<Newsletter className="mr-0 sm:-ml-14" />
</div>
<Card>
<Carousel {...BERITA} />

View File

@ -6,6 +6,7 @@ import {
Outlet,
Scripts,
ScrollRestoration,
type ShouldRevalidateFunctionArgs,
} from 'react-router'
import type { Route } from './+types/root'
@ -36,7 +37,17 @@ export const meta = ({ location }: Route.MetaArgs) => {
]
}
export function Layout({ children }: { children: ReactNode }) {
export const shouldRevalidate = ({
actionResult,
defaultShouldRevalidate,
}: ShouldRevalidateFunctionArgs) => {
if (actionResult?.success) {
return true
}
return defaultShouldRevalidate
}
export const Layout = ({ children }: { children: ReactNode }) => {
return (
<html lang="en">
<head>
@ -57,11 +68,7 @@ export function Layout({ children }: { children: ReactNode }) {
)
}
export default function App() {
return <Outlet />
}
export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
export const ErrorBoundary = ({ error }: Route.ErrorBoundaryProps) => {
let message = 'Oops!'
let details = 'An unexpected error occurred.'
let stack: string | undefined
@ -89,3 +96,9 @@ export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
</main>
)
}
const App = () => {
return <Outlet />
}
export default App

View File

@ -0,0 +1,22 @@
import { data } from 'react-router'
import { setUserLogoutHeaders } from '~/libs/logout-header.server'
export const action = async () => {
try {
const responseHeaders = setUserLogoutHeaders()
return data(
{ success: true },
{ headers: responseHeaders, status: 200, statusText: 'OK' },
)
} catch {
return data(
{
message: 'Something went wrong',
success: false,
},
{ status: 500 },
)
}
}