Skip to content

Commit

Permalink
Merge pull request #1162 from andrew-bierman/Introduce-sidebar-Tauri
Browse files Browse the repository at this point in the history
  • Loading branch information
andrew-bierman authored Aug 13, 2024
2 parents b3c9ed9 + 69ce323 commit 9904d50
Show file tree
Hide file tree
Showing 9 changed files with 396 additions and 8 deletions.
1 change: 0 additions & 1 deletion apps/tauri/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import React, { StrictMode } from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider, createRouter } from '@tanstack/react-router';
Expand Down
14 changes: 9 additions & 5 deletions apps/tauri/src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ import React from 'react';
import { MainContentWeb } from '@packrat/ui';
import { createRootRoute, Link, Outlet } from '@tanstack/react-router';
import { TanStackRouterDevtools } from '@tanstack/router-devtools';
import { Navbar } from 'app/components/navigation';
import { NavbarTauri } from 'app/components/navigation';
import { Provider } from 'app/provider';
import { View } from 'react-native';
import { FullSideBar } from 'app/components/navigation/SideBar';

export const Route = createRootRoute({
component: () => (
<Provider>
<Navbar />
<MainContentWeb>
<Outlet />
</MainContentWeb>
<NavbarTauri />
<View style={{ paddingLeft: 300, paddingRight: 10 }}>
<MainContentWeb>
<Outlet />
</MainContentWeb>
</View>
<TanStackRouterDevtools />
</Provider>
),
Expand Down
13 changes: 12 additions & 1 deletion apps/tauri/src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Dashboard from 'app/screens/dashboard';
import LandingPage from 'app/components/landing_page';
import { useAuthUser } from 'app/auth/hooks';
import { createFileRoute } from '@tanstack/react-router';
import { ScrollView } from 'react-native';

export const Route = createFileRoute('/')({
component: Home,
Expand All @@ -11,5 +12,15 @@ export const Route = createFileRoute('/')({
export default function Home() {
const user = useAuthUser();

return <>{!user ? <LandingPage /> : <Dashboard />}</>;
return (
<>
{!user ? (
<LandingPage />
) : (
<ScrollView horizontal={false}>
<Dashboard />
</ScrollView>
)}
</>
);
}
2 changes: 1 addition & 1 deletion packages/app/components/navigation/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const loadStyles = (currentTheme, isScrolled, screenWidth) => {
position: 'fixed' as 'fixed' | 'relative',
top: 0,
zIndex: 100,
width: Platform.OS === 'web' ? '100vw' : "100%",
width: Platform.OS === 'web' ? '100vw' : '100%',
},
}),
},
Expand Down
161 changes: 161 additions & 0 deletions packages/app/components/navigation/Navbar/NavbarTauri.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import React, { useMemo } from 'react';
import { View, Text, SafeAreaView, StyleSheet, Platform } from 'react-native';
import { RButton, Container } from '@packrat/ui';
import { useIsMobileView } from 'app/hooks/common';
import { useNavigate } from 'app/hooks/navigation';
import { NavigationList } from '../NavigationList';
import { Drawer } from '../Drawer';
import { useScrollTop } from 'app/hooks/common/useScrollTop';
import { useScreenWidth } from 'app/hooks/common';
import useTheme from 'app/hooks/useTheme';
import { RImage } from '@packrat/ui';
import FullSideBar from '../Sidebar/SideBar';

export const NavbarTauri = () => {
const { currentTheme } = useTheme();
const scrollTop = useScrollTop();
const { screenWidth } = useScreenWidth();
const isScrolled = !!scrollTop;
const styles = useMemo(() => {
return StyleSheet.create(loadStyles(currentTheme, isScrolled, screenWidth));
}, [isScrolled, currentTheme, screenWidth]);
const navigate = useNavigate();

return (
<SafeAreaView style={styles.safeArea}>
<Container>
<View style={styles.container}>
<View style={styles.logoContainer}>
<RImage
source={{
// TODO: Update this to use the PackRat logo from the assets folder
uri: 'https://github.com/andrew-bierman/PackRat/blob/main/packages/app/assets/packrat_icon.png?raw=true',
width: 40,
height: 40,
}}
width={40}
height={40}
style={styles.logo}
alt="PackRat Logo"
onClick={() => {
navigate('/');
}}
/>
<Text
style={styles.logoText}
onPress={() => {
navigate('/');
}}
>
PackRat
</Text>
</View>
<FullSideBar />
</View>
</Container>
</SafeAreaView>
);
};

const NavbarStyles = {
floatingBg: '#0284c7',
floatingRadius: 25,
floatingBlur: 'blur(2px)',
transition: 'all 0.2s ease-in-out',
floatingSpacing: 4,
};

const loadStyles = (currentTheme, isScrolled, screenWidth) => {
const isWeb = Platform.OS === 'web';
const isFloating = isWeb && isScrolled;
const backgroundColor = isFloating
? NavbarStyles.floatingBg
: currentTheme.colors.background;

return StyleSheet.create({
drawerStyles: {
backgroundColor: currentTheme.colors.background,
},
safeArea: {
backgroundColor,
width: '100%',
margin: 0,
transition: NavbarStyles.transition,
...Platform.select({
web: {
...(isFloating
? {
backdropFilter: NavbarStyles.floatingBlur,
marginTop: NavbarStyles.floatingSpacing,
padding: NavbarStyles.floatingSpacing,
borderRadius: NavbarStyles.floatingRadius,
}
: {}),
position: 'fixed' as 'fixed' | 'relative',
top: 0,
zIndex: 100,
width: Platform.OS === 'web' ? '100vw' : '100%',
},
}),
},
container: {
width: '100vw',
maxWidth: '100%', // Ensure container does not exceed the viewport width
flex: 1, // Ensure container can grow to fit content
backgroundColor,
borderRadius: NavbarStyles.floatingRadius,
flexDirection: 'row', // Keep flexDirection as row for alignment
justifyContent: 'space-between',
alignItems: 'center',
flexWrap: 'wrap', // Allow items to wrap
height: 60, // Ensure container takes full height of its container
padding: 16,
},
header: {
flexDirection: 'row', // Keep flexDirection as row for initial alignment
alignItems: 'center',
justifyContent: 'space-between',
width: '100%', // Ensure header takes full width of its container
flexWrap: 'wrap', // Allow header items to wrap
},
logoContainer: {
flexDirection: 'row',
alignItems: 'center',
},
logo: {
marginRight: 10,
cursor: 'pointer',
},
logoText: {
color: currentTheme.colors.text,
fontSize: 38,
fontWeight: '900',
cursor: 'pointer',
},
menuBar: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-end',
paddingHorizontal: 16,
flex: 1, // Keep flexible but consider its behavior with wrapping,
flexWrap: 'wrap', // Allow items to wrap
},
drawerTrigger: {},
menuBarItemActive: {
// Apply styles for the active item
// ...
},
menuBarItemTextActive: {
// Apply styles for the active item's text
// ...
},
menuBarItemSelected: {
// Apply styles for the selected item
// ...
},
menuBarItemTextSelected: {
// Apply styles for the selected item's text
// ...
},
});
};
1 change: 1 addition & 0 deletions packages/app/components/navigation/Navbar/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { Navbar } from './Navbar';
export { NavbarTauri } from './NavbarTauri';
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { useNavigationList } from 'app/hooks/navigation';
import { NavigationItem } from '../NavigationItem';
import { useIsMobileView } from 'app/hooks/common';
import { View } from 'tamagui';
import useTheme from '../../../hooks/useTheme';

interface ProfileNavigationList {
itemStyle?: any;
onItemSelect?: (item: any) => void;
}

export const ProfileNavigationList = ({ itemStyle, onItemSelect }) => {
const isMobileView = useIsMobileView();
const { currentTheme } = useTheme();
const { navigationItems } = useNavigationList();

return (
<>
{navigationItems
?.filter(({ href }) => href === '/profile' || href === '/logout')
.map(({ type, ...Item }, index) => {
const item = Item as any;
console.log(item);

return (
<View
style={{
width: '100%',
borderRadius: 8,
marginBottom: isMobileView ? 6 : 0,
backgroundColor: currentTheme.colors.background,
color: currentTheme.colors.white,
}}
hoverStyle={{
bg: currentTheme.colors.secondaryBlue as any,
}}
key={item.href + index}
>
{type === 'link' ? (
<NavigationItem
item={item}
itemStyle={itemStyle}
key={item.href + index}
onSelect={onItemSelect}
isMobileView={isMobileView}
/>
) : (
item.Component && <item.Component />
)}
</View>
);
})}
</>
);
};
99 changes: 99 additions & 0 deletions packages/app/components/navigation/Sidebar/SideBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { useState } from 'react';
import { View, useMedia, styled } from 'tamagui';
import { RIconButton } from '@packrat/ui';
import useTheme from 'app/hooks/useTheme';
import Ionicons from '@expo/vector-icons/Ionicons';
import { SidebarNavigationList } from './SidebarNavigationList';
import { ProfileNavigationList } from './ProfileNavigationList';

export function FullSideBar() {
const [openDrawer, setOpenDrawer] = useState(false);
const { sm } = useMedia();

return (
<View flexDirection="row" height="100%" width="100%">
{!sm && <Sidebar />}
{sm && <FloatingSideBar open={openDrawer} setOpen={setOpenDrawer} />}
<ProfileDrawer open={openDrawer} setOpen={setOpenDrawer} />
</View>
);
}

FullSideBar.fileName = 'FullSideBar';

function Sidebar() {
const { currentTheme } = useTheme();

return (
<View
flexDirection="column"
height="300vh"
width={300}
backgroundColor={currentTheme.colors.background}
position="fixed"
left={0}
top={75}
>
<SidebarNavigationList
itemStyle={{
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 8,
}}
onItemSelect={() => {}}
/>
</View>
);
}

function ProfileDrawer({
open,
setOpen,
onItemSelect,
}: {
open: boolean;
setOpen: (open: boolean) => void;
onItemSelect: (item: any) => void;
}) {
const { currentTheme } = useTheme();

return (
<View position="absolute" top={0} right={0}>
<RIconButton
backgroundColor="transparent"
icon={<Ionicons name="person-circle" size={30} color="white" />}
onPress={() => setOpen(!open)}
/>
{open && (
<View
style={{
position: 'absolute',
top: 50,
right: 0,
width: 180,
padding: 10,
backgroundColor: currentTheme.colors.background,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.2,
shadowRadius: 8,
elevation: 10,
zIndex: 1000,
}}
>
<ProfileNavigationList
itemStyle={{
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 8,
}}
onItemSelect={onItemSelect}
/>
</View>
)}
</View>
);
}

export default FullSideBar;
Loading

0 comments on commit 9904d50

Please sign in to comment.