Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: properly display header on landing page #44

Merged
merged 10 commits into from
Apr 8, 2024
114 changes: 81 additions & 33 deletions src/components/LandingHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { lightBinarLogo, darkBinarLogo } from '@baca/constants'
import { useColorScheme } from '@baca/contexts'
import { Box, Button, Icon, Pressable, Spacer } from '@baca/design-system'
import { useCallback, useTheme, useTranslation } from '@baca/hooks'
import { Box, Button, Icon, Pressable, Row, Spacer, Touchable } from '@baca/design-system'
import { useFullScreenModal } from '@baca/design-system/modals/useFullScreenModal'
import { useCallback, useMemo, useTheme, useTranslation } from '@baca/hooks'
import { useUniversalWidth } from '@baca/navigation/tabNavigator/hooks'
import { isSignedInAtom } from '@baca/store/auth'
import { useRouter } from 'expo-router'
import { useAtomValue } from 'jotai'
Expand All @@ -15,43 +17,92 @@ export function LandingHeader() {
const { t } = useTranslation()
const { push, canGoBack, back } = useRouter()

const height = 60 + top

const isDesktop = useUniversalWidth(768)

const isSignedIn = useAtomValue(isSignedInAtom)

const navigateToLogin = useCallback(() => push('/sign-in'), [push])
const navigateToSignUp = useCallback(() => push('/sign-up'), [push])

const height = 60 + top
const { closeFullScreenModal, modalComponentRenderFunction, presentFullScreenModal } =
useFullScreenModal()

return (
<View
style={[
{ borderBottomColor: colors.border.secondary, height, paddingTop: top },
jsStyles.appHeader,
Platform.select({ default: {}, web: { display: 'flex' } }),
]}
>
{canGoBack() ? (
<Pressable onPress={back}>
<Icon name="arrow-left-line" size={20} />
</Pressable>
) : (
<Image
resizeMethod="resize"
resizeMode="contain"
source={colorScheme === 'light' ? lightBinarLogo : darkBinarLogo}
style={jsStyles.logoWide}
/>
)}
{!isSignedIn ? (
<View style={jsStyles.rowContainer}>
const renderLeftMenu = useMemo(() => {
return canGoBack() ? (
<Pressable onPress={back}>
<Icon name="arrow-left-line" size={20} />
</Pressable>
) : (
<Image
resizeMethod="resize"
resizeMode="contain"
source={colorScheme === 'light' ? lightBinarLogo : darkBinarLogo}
style={jsStyles.logoWide}
/>
)
}, [back, canGoBack, colorScheme])

const fullScreenModal = modalComponentRenderFunction(
<Box flex={1}>
<View
style={[
{ borderBottomColor: colors.border.secondary, height, paddingTop: top },
jsStyles.appHeader,
Platform.select({ default: {}, web: { display: 'flex' } }),
]}
>
{renderLeftMenu}
<Touchable onPress={closeFullScreenModal}>
<Icon name="close-line" size={24} color="text.brand.primary" />
</Touchable>
</View>
<Box flex={1} />
<Box p={4} w="full">
<Button onPress={navigateToLogin}>{t('landing_screen.login_cta')}</Button>
<Spacer y="4" />
<Button onPress={navigateToSignUp}>{t('landing_screen.sign_up')}</Button>
</Box>
</Box>
)

const renderRightMenu = useMemo(() => {
if (isSignedIn) {
return <Box />
}

if (isDesktop) {
return (
<Row>
<Button onPress={navigateToLogin}>{t('landing_screen.login_cta')}</Button>
<Spacer x="4" />
<Button onPress={navigateToSignUp}>{t('landing_screen.sign_up')}</Button>
</View>
) : (
<Box />
)}
</View>
</Row>
)
}

return (
<Touchable onPress={presentFullScreenModal}>
<Icon name="menu-2-line" size={24} color="text.brand.primary" />
</Touchable>
)
}, [isDesktop, isSignedIn, navigateToLogin, navigateToSignUp, presentFullScreenModal, t])

return (
<>
<View
style={[
{ borderBottomColor: colors.border.secondary, height, paddingTop: top },
jsStyles.appHeader,
Platform.select({ default: {}, web: { display: 'flex' } }),
]}
>
{renderLeftMenu}
{renderRightMenu}
</View>
{fullScreenModal}
</>
)
}

Expand All @@ -66,7 +117,4 @@ const jsStyles = StyleSheet.create({
zIndex: 10,
},
logoWide: { height: 60, width: 150 },
rowContainer: {
flexDirection: 'row',
},
})
8 changes: 6 additions & 2 deletions src/components/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useTheme } from '@baca/hooks'
import { hex2rgba } from '@baca/utils'
import {
Modal as RNModal,
ModalProps,
Expand Down Expand Up @@ -48,7 +49,10 @@ export const Modal = ({
>
<ScrollableComponent
style={styles.scroll}
contentContainerStyle={[styles.scrollContent, { background: colors.bg.overlay }]}
contentContainerStyle={[
styles.scrollContent,
{ background: hex2rgba(colors.bg.overlay, 0.5) },
]}
showsVerticalScrollIndicator={false}
>
<TouchableWithoutFeedback>{children}</TouchableWithoutFeedback>
Expand All @@ -66,10 +70,10 @@ const styles = StyleSheet.create({
justifyContent: 'center',
},
scroll: {
paddingHorizontal: 32,
width: '100%',
},
scrollContent: {
justifyContent: 'center',
paddingHorizontal: 32,
},
})
1 change: 1 addition & 0 deletions src/design-system/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './bottomSheets'
export * from './components'
export * from './config'
export * from './modals'
export * from './utils'
37 changes: 37 additions & 0 deletions src/design-system/modals/FullScreenModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useBoolean, useImperativeHandle } from '@baca/hooks'
import { RefObject } from 'react'
import { Modal, ModalProps } from 'react-native'

import { Box } from '../components'

export type ModalMethods = {
present: () => void
close: () => void
}

type Props = {
modalRef: RefObject<ModalMethods>
} & ModalProps

export const FullScreenModal = ({ children, modalRef, ...rest }: Props) => {
const [isOpen, setIsOpen] = useBoolean(false)

useImperativeHandle(modalRef, () => ({
present: setIsOpen.on,
close: setIsOpen.off,
}))

return (
<Modal
{...rest}
animationType="fade"
transparent
visible={isOpen}
onRequestClose={setIsOpen.off}
>
<Box bg="bg.primary" w="100%" height="100%">
{children}
</Box>
</Modal>
)
}
2 changes: 2 additions & 0 deletions src/design-system/modals/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './FullScreenModal'
export * from './useFullScreenModal'
25 changes: 25 additions & 0 deletions src/design-system/modals/useFullScreenModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useCallback, useRef } from 'react'

import { FullScreenModal, ModalMethods } from './FullScreenModal'

export const useFullScreenModal = () => {
const modalRef = useRef<ModalMethods>(null)

const modalComponentRenderFunction = (children: JSX.Element | JSX.Element[]) => {
return <FullScreenModal modalRef={modalRef}>{children}</FullScreenModal>
}

const presentFullScreenModal = useCallback(() => {
modalRef.current?.present?.()
}, [])

const closeFullScreenModal = useCallback(() => {
modalRef.current?.close?.()
}, [])

return {
modalComponentRenderFunction,
presentFullScreenModal,
closeFullScreenModal,
}
}
31 changes: 16 additions & 15 deletions src/navigation/tabNavigator/components/BottomBar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Icon } from '@baca/design-system'
import { Column, Icon, Text } from '@baca/design-system'
import { useTheme } from '@baca/hooks'
import cssStyles from '@baca/styles'
import { Platform, StyleSheet, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'

import { TabBarItemWrapper } from './TabBarItemWrapper'
import { bottomTabs } from '../navigation-config'
import { bottomTabs, getTabColor } from '../navigation-config'
import { cns } from '../utils'

export function BottomBar({ visible }: { visible: boolean }) {
Expand All @@ -28,21 +28,27 @@ export function BottomBar({ visible }: { visible: boolean }) {
{bottomTabs.map((tab, i) => (
<TabBarItemWrapper key={i} name={tab.name} id={tab.id} params={tab.params}>
{({ focused, pressed, hovered }) => (
<Icon
name={focused ? tab.iconFocused : tab.icon}
size={40}
color="nav.item.button.icon.fg"
<Column
px={2}
alignItems="center"
style={[
jsStyles.tabIcon,
pressed && jsStyles.tabIconPressed,
Platform.select({
web: {
transitionDuration: '200ms',
transform: hovered ? [{ scale: 1.2 }] : [{ scale: 1 }],
transform: [{ scale: hovered ? 1.1 : pressed ? 0.9 : 1 }],
},
}),
]}
/>
gap={2}
>
<Icon
name={focused ? tab.iconFocused : tab.icon}
size={24}
color={getTabColor(focused)}
/>
<Text.XsMedium color={getTabColor(focused)}>{tab.displayedName}</Text.XsMedium>
</Column>
)}
</TabBarItemWrapper>
))}
Expand All @@ -56,16 +62,11 @@ const jsStyles = StyleSheet.create({
alignItems: 'center',
borderTopWidth: 1,
flexDirection: 'row',
height: 49,
height: 56,
justifyContent: 'space-around',
paddingHorizontal: 16,
},

tabIcon: {
paddingHorizontal: 8,
},
tabIconPressed: {
opacity: 0.8,
transform: [{ scale: 0.9 }],
},
})
14 changes: 4 additions & 10 deletions src/navigation/tabNavigator/components/HeaderLogo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { Pressable } from '@bacons/react-views'
import { Link } from 'expo-router'
import { Platform, StyleSheet, View } from 'react-native'

import { useWidth } from '../hooks'
import { useUniversalWidth } from '../hooks'
import { cns } from '../utils'

export function HeaderLogo() {
const { colors } = useTheme()
const isLargeHorizontal = useWidth(1264)
const isLargeHorizontal = useUniversalWidth(1264)

return (
<View
Expand All @@ -19,14 +19,7 @@ export function HeaderLogo() {
web: cns(cssStyles.headerContainer),
})}
>
<Link
style={Platform.select({
default: jsStyles.headerLink,
web: cns(cssStyles.headerLink),
})}
href="/"
asChild
>
<Link style={jsStyles.headerLink} href="/" asChild>
<Pressable>
{({ hovered }) => (
<View
Expand Down Expand Up @@ -69,6 +62,7 @@ const jsStyles = StyleSheet.create({
},
headerLink: {
alignItems: 'center',
paddingBottom: 24,
},
headerLogo: {
alignItems: 'center',
Expand Down
9 changes: 5 additions & 4 deletions src/navigation/tabNavigator/components/SideBar.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { useTheme } from '@baca/hooks'
import { useSafeAreaInsets, useTheme } from '@baca/hooks'
import { signOut } from '@baca/store/auth'
import cssStyles from '@baca/styles'
import { Platform, StyleSheet, View } from 'react-native'

import { HeaderLogo } from './HeaderLogo'
import { SideBarTabItem } from './SideBarTabItem'
import { useWidth } from '../hooks'
import { useUniversalWidth } from '../hooks'
import { upperSideTabs } from '../navigation-config'
import { cns } from '../utils'

const NAV_MEDIUM_WIDTH = 244

export function SideBar({ visible }: { visible: boolean }) {
const { colors } = useTheme()
const isLarge = useWidth(1264)
const { top } = useSafeAreaInsets()
const isLarge = useUniversalWidth(1264)

return (
<View
Expand All @@ -38,6 +39,7 @@ export function SideBar({ visible }: { visible: boolean }) {
<View
style={[
jsStyles.sidebarInner,
{ paddingTop: top + 8 },
{ borderRightColor: colors.border.secondary },
...Platform.select({
default: [
Expand Down Expand Up @@ -106,7 +108,6 @@ const jsStyles = StyleSheet.create({
minWidth: 72,
paddingBottom: 20,
paddingHorizontal: 12,
paddingTop: 8,
position: 'absolute',
width: 72,
},
Expand Down
Loading
Loading