-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from nitic-pbl-p8/7/add-header-for-auth-guarded…
…-page
- Loading branch information
Showing
19 changed files
with
401 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
apps/website/src/app/(with-auth)/@routeIndicator/dashboard/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'; | ||
import type { NextPage } from 'next'; | ||
import { cookies } from 'next/headers'; | ||
import { InAppHeaderRouteIndicatorDivider, InAppHeaderRouteIndicatorIcon, InAppHeaderRouteIndicatorLabel } from '#website/layout/global/header'; | ||
import { findUserUseCase } from '#website/use-case/find-user'; | ||
import { findUserLostItemsUseCase } from '~website/src/use-case/find-user-lost-items'; | ||
|
||
const RouteIndicator: NextPage = async () => { | ||
const cookieStore = cookies(); | ||
|
||
const supabase = createServerComponentClient({ cookies: () => cookieStore }); | ||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
if (!user) { | ||
return null; | ||
} | ||
|
||
const foundUser = await findUserUseCase(user.id); | ||
if (!foundUser) { | ||
return null; | ||
} | ||
|
||
const userLostItem = await findUserLostItemsUseCase(foundUser.authId); | ||
if (!userLostItem) { | ||
return null; | ||
} | ||
|
||
return userLostItem.currentTargetLostItem && foundUser.lostAndFoundState !== 'NONE' ? ( | ||
<> | ||
<InAppHeaderRouteIndicatorDivider /> | ||
{!!userLostItem.currentTargetLostItem.lostItem.imageUrls[0] && ( | ||
<InAppHeaderRouteIndicatorIcon | ||
src={userLostItem.currentTargetLostItem.lostItem.imageUrls[0]} | ||
alt={`An image of ${userLostItem.currentTargetLostItem.lostItem.title}`} | ||
/> | ||
)} | ||
<InAppHeaderRouteIndicatorLabel>{userLostItem.currentTargetLostItem.lostItem.title}</InAppHeaderRouteIndicatorLabel> | ||
</> | ||
) : ( | ||
<> | ||
<InAppHeaderRouteIndicatorDivider /> | ||
<InAppHeaderRouteIndicatorLabel>Overview</InAppHeaderRouteIndicatorLabel> | ||
</> | ||
); | ||
}; | ||
|
||
export default RouteIndicator; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import type { ReactNode } from 'react'; | ||
|
||
const RouteIndicatorPage = (): ReactNode => null; | ||
|
||
export default RouteIndicatorPage; |
5 changes: 5 additions & 0 deletions
5
apps/website/src/app/(with-auth)/@routeIndicator/report/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import type { ReactNode } from 'react'; | ||
|
||
const RouteIndicatorPage = (): ReactNode => null; | ||
|
||
export default RouteIndicatorPage; |
5 changes: 5 additions & 0 deletions
5
apps/website/src/app/(with-auth)/@routeIndicator/search/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import type { ReactNode } from 'react'; | ||
|
||
const RouteIndicatorPage = (): ReactNode => null; | ||
|
||
export default RouteIndicatorPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,35 @@ | ||
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'; | ||
import type { NextPage } from 'next'; | ||
import { cookies } from 'next/headers'; | ||
import type { ReactNode } from 'react'; | ||
import { InAppHeader } from '#website/layout/global/header'; | ||
import { AuthGuardProvider } from '#website/layout/with-auth/auth-guard-provider'; | ||
import { findUserUseCase } from '#website/use-case/find-user'; | ||
|
||
type WithAuthLayoutProps = { | ||
children: ReactNode; | ||
routeIndicator: ReactNode; | ||
}; | ||
|
||
const WithAuthLayout: NextPage<WithAuthLayoutProps> = ({ children }) => ( | ||
<> | ||
<AuthGuardProvider /> | ||
{children} | ||
</> | ||
); | ||
const WithAuthLayout: NextPage<WithAuthLayoutProps> = async ({ children, routeIndicator }) => { | ||
// HACK: To avoid next build errors, functions that depend on async contexts need to be called outside the function that creates the new execution context. | ||
// ref: https://nextjs.org/docs/messages/dynamic-server-error | ||
const cookieStore = cookies(); | ||
|
||
const supabase = createServerComponentClient({ cookies: () => cookieStore }); | ||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
|
||
const foundUser = user && (await findUserUseCase(user.id)); | ||
|
||
return ( | ||
<> | ||
<InAppHeader user={foundUser}>{routeIndicator}</InAppHeader> | ||
<AuthGuardProvider /> | ||
{children} | ||
</> | ||
); | ||
}; | ||
|
||
export default WithAuthLayout; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'; | ||
import type { NextPage } from 'next'; | ||
import { cookies } from 'next/headers'; | ||
import type { ReactNode } from 'react'; | ||
import { Header } from '#website/layout/global/header'; | ||
import { findUserUseCase } from '#website/use-case/find-user'; | ||
|
||
type WithNoAuthLayoutProps = { | ||
children: ReactNode; | ||
}; | ||
|
||
const WithNoAuthLayout: NextPage<WithNoAuthLayoutProps> = async ({ children }) => { | ||
// HACK: To avoid next build errors, functions that depend on async contexts need to be called outside the function that creates the new execution context. | ||
// ref: https://nextjs.org/docs/messages/dynamic-server-error | ||
const cookieStore = cookies(); | ||
|
||
const supabase = createServerComponentClient({ cookies: () => cookieStore }); | ||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
|
||
const foundUser = user && (await findUserUseCase(user.id)); | ||
|
||
return ( | ||
<> | ||
<Header user={foundUser} /> | ||
{children} | ||
</> | ||
); | ||
}; | ||
|
||
export default WithNoAuthLayout; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
apps/website/src/layout/global/header/component/header-link/header-link.story.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import { HeaderLink } from './header-link'; | ||
|
||
type Story = StoryObj<typeof HeaderLink>; | ||
|
||
const meta = { | ||
component: HeaderLink, | ||
args: { | ||
href: '/dashboard', | ||
children: 'Overview', | ||
}, | ||
} satisfies Meta<typeof HeaderLink>; | ||
|
||
export default meta; | ||
|
||
export const Default: Story = {}; | ||
|
||
export const Selected: Story = { | ||
parameters: { | ||
nextjs: { | ||
appDirectory: true, | ||
navigation: { | ||
pathname: '/dashboard', | ||
}, | ||
}, | ||
}, | ||
}; |
34 changes: 34 additions & 0 deletions
34
apps/website/src/layout/global/header/component/header-link/header-link.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Link } from '#core/component/link'; | ||
import { type VariantProps, cn, tv } from '@lockerai/tailwind'; | ||
import { usePathname } from 'next/navigation'; | ||
import type { ComponentPropsWithoutRef, ReactNode } from 'react'; | ||
import { useMemo } from 'react'; | ||
|
||
const headerLinkVariant = tv({ | ||
base: 'flex items-center justify-center rounded-t-lg p-3 font-bold hover:bg-sage-3', | ||
variants: { | ||
selected: { | ||
true: 'border-b-2 border-sage-12 text-sage-12', | ||
false: 'text-sage-11', | ||
}, | ||
}, | ||
defaultVariants: { | ||
selected: false, | ||
}, | ||
}); | ||
|
||
type HeaderLinkProps = ComponentPropsWithoutRef<typeof Link> & VariantProps<typeof headerLinkVariant>; | ||
|
||
export const HeaderLink = ({ children, className, ...props }: HeaderLinkProps): ReactNode => { | ||
// Retrieve the current path starting with /. | ||
// Refer: https://nextjs.org/docs/app/api-reference/functions/use-pathname | ||
const currentPath = usePathname(); // e.g. `/docs/works/shelfree` | ||
// Check if the current path is the same as the href. | ||
const isBeingOpened = useMemo(() => !!props.href && currentPath === props.href.toString(), [currentPath, props.href]); | ||
|
||
return ( | ||
<Link className={cn(headerLinkVariant({ selected: isBeingOpened }), className)} {...props}> | ||
{children} | ||
</Link> | ||
); | ||
}; |
1 change: 1 addition & 0 deletions
1
apps/website/src/layout/global/header/component/header-link/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { HeaderLink } from './header-link'; |
29 changes: 29 additions & 0 deletions
29
apps/website/src/layout/global/header/in-app-header.container.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
'use client'; | ||
|
||
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; | ||
import { type ComponentPropsWithoutRef, type ReactNode, useEffect, useState } from 'react'; | ||
import { InAppHeader as InAppHeaderPresenter } from './in-app-header.presenter'; | ||
|
||
export type HeaderProps = Omit<ComponentPropsWithoutRef<typeof InAppHeaderPresenter>, 'className'>; | ||
|
||
export const InAppHeader = ({ user: initialUser, ...props }: HeaderProps): ReactNode => { | ||
const [user, setUser] = useState(initialUser); | ||
|
||
const supabase = createClientComponentClient(); | ||
|
||
useEffect(() => { | ||
const { | ||
data: { subscription }, | ||
} = supabase.auth.onAuthStateChange(async (_, session) => { | ||
if (!session) { | ||
setUser(null); | ||
} | ||
}); | ||
|
||
return () => { | ||
subscription.unsubscribe(); | ||
}; | ||
}, [supabase.auth]); | ||
|
||
return <InAppHeaderPresenter user={user} {...props} />; | ||
}; |
Oops, something went wrong.