Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions libs/ui/src/presentation/components/base/ContentContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { YStack } from 'tamagui';
import { ReactNode } from 'react';

type ContentContainerProps = {
children: ReactNode;
};

export const ContentContainer = ({ children }: ContentContainerProps) => (
<YStack flex={1} width="100%" maxWidth={1440} alignSelf="center">
{children}
</YStack>
);
47 changes: 42 additions & 5 deletions libs/ui/src/presentation/components/base/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { PortalProvider, XStack, YStack } from 'tamagui';
import { Menu } from '@tamagui/lucide-icons';
import { Button, PortalProvider, XStack, YStack, useMedia } from 'tamagui';
import { Sidebar } from './Sidebar';
import { Navbar } from './Navbar/Navbar';
import { ReactNode } from 'react';
import { ContentContainer } from './ContentContainer';
import { ReactNode, useEffect, useState } from 'react';

export type LayoutProps = {
children: React.ReactNode;
Expand All @@ -18,18 +20,53 @@ export const Layout = ({
rightActionItem,
onLogoutPress,
}: LayoutProps) => {
const media = useMedia();
const [isSidebarShown, setIsSidebarShown] = useState(false);

// Default: open on desktop, closed on mobile/tablet
useEffect(() => {
setIsSidebarShown(!!media.gtMd);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); // Intentionally runs once on mount with initial media value

const onToggleSidebar = () => setIsSidebarShown((prev) => !prev);

const hamburgerButton = (
<Button
icon={Menu}
size="$3"
variant="outlined"
circular
onPress={onToggleSidebar}
aria-label="Toggle navigation menu"
data-testid="sidebar-toggle"
/>
);

return (
<PortalProvider shouldAddRootHost>
<XStack flex={1}>
<Sidebar onLogoutPress={onLogoutPress} />
<Sidebar
onLogoutPress={onLogoutPress}
isShown={isSidebarShown}
onToggle={onToggleSidebar}
onOpenChange={setIsSidebarShown}
/>
<YStack flex={1}>
<Navbar
title={title}
showBackButton={showBackButton}
rightActionItem={rightActionItem}
leftActionItem={!media.gtMd ? hamburgerButton : undefined}
/>
<YStack padding="$5" gap="$3" flex={1}>
{children}
<YStack
flex={1}
padding="$5"
$xs={{ padding: '$3' }}
$sm={{ padding: '$4' }}
gap="$3"
>
<ContentContainer>{children}</ContentContainer>
</YStack>
</YStack>
</XStack>
Expand Down
11 changes: 9 additions & 2 deletions libs/ui/src/presentation/components/base/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@ export type NavbarProps = {
title: string;
showBackButton?: boolean;
rightActionItem?: ReactNode;
leftActionItem?: ReactNode;
};

export const Navbar = ({
title,
showBackButton,
rightActionItem,
leftActionItem,
}: NavbarProps) => {
const { onBackButtonPress } = useNavbarState();
return (
<XStack
padding="$3"
justifyContent="space-between"
alignItems="center"
backgroundColor="$gray1"
$xs={{ flexDirection: 'column', alignItems: 'flex-start', gap: '$2' }}
>
<XStack alignItems="center" gap="$3">
<XStack alignItems="center" gap="$3" flex={1}>
{leftActionItem}
{showBackButton && (
<Button
icon={ArrowLeft}
Expand All @@ -31,7 +36,9 @@ export const Navbar = ({
size="$3"
/>
)}
<H4>{title}</H4>
<H4 numberOfLines={1} ellipsizeMode="tail" flex={1}>
{title}
</H4>
</XStack>
{rightActionItem}
</XStack>
Expand Down
8 changes: 8 additions & 0 deletions libs/ui/src/presentation/components/base/ResponsiveStack.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { XStack } from 'tamagui';
import type { XStackProps } from 'tamagui';

export type ResponsiveStackProps = XStackProps;

export const ResponsiveStack = (props: ResponsiveStackProps) => (
<XStack flexDirection="row" $md={{ flexDirection: 'column' }} {...props} />
);
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
} from '@tamagui/lucide-icons';
import { NamedExoticComponent, useEffect, useState } from 'react';
import { useRouter } from 'solito/router';
import {} from 'solito';

type MenuItem = {
title: string;
Expand Down Expand Up @@ -61,17 +60,14 @@ const items: MenuItem[] = [
];

export const useSidebarState = () => {
const [isShown, setIsShown] = useState(true);

const onToggleButtonPress = () => setIsShown((prev) => !prev);

const router = useRouter();

const [accordionValue, setAccordionValue] = useState<string>();
const [currentPath, setCurrentPath] = useState<string>();

useEffect(() => {
setCurrentPath(window.location.pathname);
if (typeof window !== 'undefined') {
setCurrentPath(window.location.pathname);
}
}, []);

useEffect(() => {
Expand All @@ -89,8 +85,6 @@ export const useSidebarState = () => {
}, [currentPath]);

return {
isShown,
onToggleButtonPress,
router,
items,
accordionValue,
Expand Down
Loading