From 111710e217db4f299ef1494a68d76128d791759f Mon Sep 17 00:00:00 2001 From: Muhammad Hassan Date: Wed, 7 Aug 2024 02:58:23 -0700 Subject: [PATCH 001/121] Landing Page Layour Design Changed --- apps/vite/src/routeTree.gen.ts | 177 +----------------- .../app/components/landing_page/index.tsx | 148 ++++++++++----- .../landing_page/landingpage.style.tsx | 51 ++--- .../components/navigation/Navbar/Navbar.tsx | 18 +- 4 files changed, 143 insertions(+), 251 deletions(-) diff --git a/apps/vite/src/routeTree.gen.ts b/apps/vite/src/routeTree.gen.ts index 8e9dfcd1e..968fb50c5 100644 --- a/apps/vite/src/routeTree.gen.ts +++ b/apps/vite/src/routeTree.gen.ts @@ -174,163 +174,94 @@ const ProfileSettingsIndexLazyRoute = ProfileSettingsIndexLazyImport.update({ declare module '@tanstack/react-router' { interface FileRoutesByPath { '/': { - id: '/' - path: '/' - fullPath: '/' preLoaderRoute: typeof IndexImport parentRoute: typeof rootRoute } '/destination/query': { - id: '/destination/query' - path: '/destination/query' - fullPath: '/destination/query' preLoaderRoute: typeof DestinationQueryLazyImport parentRoute: typeof rootRoute } '/item/$itemId': { - id: '/item/$itemId' - path: '/item/$itemId' - fullPath: '/item/$itemId' preLoaderRoute: typeof ItemItemIdLazyImport parentRoute: typeof rootRoute } '/pack/$id': { - id: '/pack/$id' - path: '/pack/$id' - fullPath: '/pack/$id' preLoaderRoute: typeof PackIdLazyImport parentRoute: typeof rootRoute } '/pack/create': { - id: '/pack/create' - path: '/pack/create' - fullPath: '/pack/create' preLoaderRoute: typeof PackCreateLazyImport parentRoute: typeof rootRoute } '/profile/$id': { - id: '/profile/$id' - path: '/profile/$id' - fullPath: '/profile/$id' preLoaderRoute: typeof ProfileIdLazyImport parentRoute: typeof rootRoute } '/trip/$tripId': { - id: '/trip/$tripId' - path: '/trip/$tripId' - fullPath: '/trip/$tripId' preLoaderRoute: typeof TripTripIdLazyImport parentRoute: typeof rootRoute } '/trip/create': { - id: '/trip/create' - path: '/trip/create' - fullPath: '/trip/create' preLoaderRoute: typeof TripCreateLazyImport parentRoute: typeof rootRoute } '/about/': { - id: '/about/' - path: '/about' - fullPath: '/about' preLoaderRoute: typeof AboutIndexLazyImport parentRoute: typeof rootRoute } '/appearance/': { - id: '/appearance/' - path: '/appearance' - fullPath: '/appearance' preLoaderRoute: typeof AppearanceIndexLazyImport parentRoute: typeof rootRoute } '/dashboard/': { - id: '/dashboard/' - path: '/dashboard' - fullPath: '/dashboard' preLoaderRoute: typeof DashboardIndexLazyImport parentRoute: typeof rootRoute } '/feed/': { - id: '/feed/' - path: '/feed' - fullPath: '/feed' preLoaderRoute: typeof FeedIndexLazyImport parentRoute: typeof rootRoute } '/items/': { - id: '/items/' - path: '/items' - fullPath: '/items' preLoaderRoute: typeof ItemsIndexLazyImport parentRoute: typeof rootRoute } '/map/': { - id: '/map/' - path: '/map' - fullPath: '/map' preLoaderRoute: typeof MapIndexLazyImport parentRoute: typeof rootRoute } '/maps/': { - id: '/maps/' - path: '/maps' - fullPath: '/maps' preLoaderRoute: typeof MapsIndexLazyImport parentRoute: typeof rootRoute } '/packs/': { - id: '/packs/' - path: '/packs' - fullPath: '/packs' preLoaderRoute: typeof PacksIndexLazyImport parentRoute: typeof rootRoute } '/password-reset/': { - id: '/password-reset/' - path: '/password-reset' - fullPath: '/password-reset' preLoaderRoute: typeof PasswordResetIndexLazyImport parentRoute: typeof rootRoute } '/privacy/': { - id: '/privacy/' - path: '/privacy' - fullPath: '/privacy' preLoaderRoute: typeof PrivacyIndexLazyImport parentRoute: typeof rootRoute } '/profile/': { - id: '/profile/' - path: '/profile' - fullPath: '/profile' preLoaderRoute: typeof ProfileIndexLazyImport parentRoute: typeof rootRoute } '/register/': { - id: '/register/' - path: '/register' - fullPath: '/register' preLoaderRoute: typeof RegisterIndexLazyImport parentRoute: typeof rootRoute } '/sign-in/': { - id: '/sign-in/' - path: '/sign-in' - fullPath: '/sign-in' preLoaderRoute: typeof SignInIndexLazyImport parentRoute: typeof rootRoute } '/trips/': { - id: '/trips/' - path: '/trips' - fullPath: '/trips' preLoaderRoute: typeof TripsIndexLazyImport parentRoute: typeof rootRoute } '/profile/settings/': { - id: '/profile/settings/' - path: '/profile/settings' - fullPath: '/profile/settings' preLoaderRoute: typeof ProfileSettingsIndexLazyImport parentRoute: typeof rootRoute } @@ -339,7 +270,7 @@ declare module '@tanstack/react-router' { // Create and export the route tree -export const routeTree = rootRoute.addChildren({ +export const routeTree = rootRoute.addChildren([ IndexRoute, DestinationQueryLazyRoute, ItemItemIdLazyRoute, @@ -363,110 +294,6 @@ export const routeTree = rootRoute.addChildren({ SignInIndexLazyRoute, TripsIndexLazyRoute, ProfileSettingsIndexLazyRoute, -}) +]) /* prettier-ignore-end */ - -/* ROUTE_MANIFEST_START -{ - "routes": { - "__root__": { - "filePath": "__root.tsx", - "children": [ - "/", - "/destination/query", - "/item/$itemId", - "/pack/$id", - "/pack/create", - "/profile/$id", - "/trip/$tripId", - "/trip/create", - "/about/", - "/appearance/", - "/dashboard/", - "/feed/", - "/items/", - "/map/", - "/maps/", - "/packs/", - "/password-reset/", - "/privacy/", - "/profile/", - "/register/", - "/sign-in/", - "/trips/", - "/profile/settings/" - ] - }, - "/": { - "filePath": "index.tsx" - }, - "/destination/query": { - "filePath": "destination/query.lazy.tsx" - }, - "/item/$itemId": { - "filePath": "item/$itemId.lazy.tsx" - }, - "/pack/$id": { - "filePath": "pack/$id.lazy.tsx" - }, - "/pack/create": { - "filePath": "pack/create.lazy.tsx" - }, - "/profile/$id": { - "filePath": "profile/$id.lazy.tsx" - }, - "/trip/$tripId": { - "filePath": "trip/$tripId.lazy.tsx" - }, - "/trip/create": { - "filePath": "trip/create.lazy.tsx" - }, - "/about/": { - "filePath": "about/index.lazy.tsx" - }, - "/appearance/": { - "filePath": "appearance/index.lazy.tsx" - }, - "/dashboard/": { - "filePath": "dashboard/index.lazy.tsx" - }, - "/feed/": { - "filePath": "feed/index.lazy.tsx" - }, - "/items/": { - "filePath": "items/index.lazy.tsx" - }, - "/map/": { - "filePath": "map/index.lazy.tsx" - }, - "/maps/": { - "filePath": "maps/index.lazy.tsx" - }, - "/packs/": { - "filePath": "packs/index.lazy.tsx" - }, - "/password-reset/": { - "filePath": "password-reset/index.lazy.tsx" - }, - "/privacy/": { - "filePath": "privacy/index.lazy.tsx" - }, - "/profile/": { - "filePath": "profile/index.lazy.tsx" - }, - "/register/": { - "filePath": "register/index.lazy.tsx" - }, - "/sign-in/": { - "filePath": "sign-in/index.lazy.tsx" - }, - "/trips/": { - "filePath": "trips/index.lazy.tsx" - }, - "/profile/settings/": { - "filePath": "profile/settings/index.lazy.tsx" - } - } -} -ROUTE_MANIFEST_END */ diff --git a/packages/app/components/landing_page/index.tsx b/packages/app/components/landing_page/index.tsx index e99680042..6c97bc665 100644 --- a/packages/app/components/landing_page/index.tsx +++ b/packages/app/components/landing_page/index.tsx @@ -17,6 +17,7 @@ import { FAQ_ITEMS } from './constants'; import { LandingPageAccordion } from './LandingPageAccordion'; import loadStyles from './landingpage.style'; import { Redirect } from 'app/components/Redirect'; +import useResponsive from 'app/hooks/useResponsive'; const RButton: any = OriginalRButton; const RStack: any = OriginalRStack; @@ -24,6 +25,7 @@ const RStack: any = OriginalRStack; const LandingPage = () => { const { currentTheme } = useTheme(); const styles = useCustomStyles(loadStyles); + const { xxs, xs, xxl } = useResponsive(); const handleGetStarted = () => { return ; @@ -35,23 +37,37 @@ const LandingPage = () => { {Platform.OS === 'web' ? ( - - PackRat - + + PackRat + + ) : ( { PackRat )} - - The Ultimate Travel App + + + The Ultimate Travel App + + + + PackRat is the ultimate adventure planner designed for those who + love to explore the great outdoors. Plan and organize your trips + with ease, whether it's a weekend camping trip, a day hike, or a + cross-country road trip. + + + + Get Started + + + {/* { > */} {/* */} - - PackRat is the ultimate adventure planner designed for those who - love to explore the great outdoors. Plan and organize your trips - with ease, whether it's a weekend camping trip, a day hike, or a - cross-country road trip. - {Platform.OS === 'web' && ( { > - - Download on the App Store + + Download on App Store - + Download on Google Play - - - - - Use on Web - - + + + + Use as Web App + + + + )} { ))} - - - - Get Started - - - - + + {/* */} {/* */} diff --git a/packages/app/components/landing_page/landingpage.style.tsx b/packages/app/components/landing_page/landingpage.style.tsx index 7fbba8a1a..861e2fd45 100644 --- a/packages/app/components/landing_page/landingpage.style.tsx +++ b/packages/app/components/landing_page/landingpage.style.tsx @@ -1,7 +1,12 @@ +import useResponsive from 'app/hooks/useResponsive'; import { Platform } from 'react-native'; + + const loadStyles = (theme) => { const { currentTheme } = theme; + const { xxs, xs, xxl } = useResponsive(); + return { mutualStyles: { backgroundColor: currentTheme.colors.background, @@ -14,15 +19,15 @@ const loadStyles = (theme) => { justifyContent: 'center', alignItems: 'center', width: '100%', - backgroundColor: currentTheme.colors.background, + backgroundColor: 'rgb(248, 248, 248)', padding: 20, }, secondaryContentContainer: { - flex: 1, + // flex: 1, width: '100%', justifyContent: 'center', alignItems: 'center', - backgroundColor: currentTheme.colors.background, + backgroundColor: 'rgb(248, 248, 248)', }, appBadges: { flexDirection: 'column', @@ -37,44 +42,48 @@ const loadStyles = (theme) => { justifyContent: 'center', }, contentContainer: { - flex: 1, - justifyContent: 'center', + // flex: 1, + justifyContent: 'start', alignItems: 'center', - paddingHorizontal: 20, + // paddingHorizontal: 20, width: '100%', }, introText: { - fontSize: Platform.OS === 'web' ? 24 : 20, - fontWeight: Platform.OS === 'web' ? 'bold' : 'normal', - textAlign: 'center', - color: currentTheme.colors.text, + fontSize: Platform.OS === 'web' ? 20 : 20, + fontWeight: Platform.OS === 'web' ? 'normal' : 'normal', + textAlign: 'left', + marginTop : xs ? 0 : 30, + color: "#45607d", + width: '58vw', marginBottom: 20, // Ensure spacing between text and next elements paddingHorizontal: 10, // Adjust text alignment on smaller screens }, buttonContainer: { - paddingHorizontal: 20, - paddingBottom: 20, + // paddingHorizontal: 20, + // paddingBottom: 20, // width: '100%', // Ensure buttons are well-spaced and aligned + margin: 30, display: 'flex', + alignItems: 'center', justifyContent: 'center', // Center buttons horizontally }, getStartedButton: { - backgroundColor: currentTheme.colors.secondaryBlue, + backgroundColor: '#f3e7fc', height: 50, paddingVertical: 12, // Increase padding for better touch area paddingHorizontal: 30, - borderRadius: 8, // Rounded corners for modern look + borderRadius: 30, // Rounded corners for modern look alignItems: 'center', // Ensure text is centered within button }, footerText: { - color: currentTheme.colors.text, + color: '#315173', fontSize: 18, fontWeight: 'bold', }, card: { marginBottom: 10, - width: '100%', - backgroundColor: currentTheme.colors.secondaryBlue, + // width: '100%', + backgroundColor: "#fbfdff", }, cardHeader: { flexDirection: 'row', @@ -87,22 +96,22 @@ const loadStyles = (theme) => { }, transparentButton: { backgroundColor: 'transparent', - height: 80, + height: 'auto', }, icon: { fontSize: 40, - color: currentTheme.colors.text, + color: "#315173", marginRight: 10, }, featureText: { fontSize: 22, - color: currentTheme.colors.text, + color: "#315173", }, cardContent: { paddingHorizontal: 20, paddingVertical: 10, fontSize: 16, - color: currentTheme.colors.text, + color: "#315173", }, }; }; diff --git a/packages/app/components/navigation/Navbar/Navbar.tsx b/packages/app/components/navigation/Navbar/Navbar.tsx index 74f1812df..45c86e32d 100644 --- a/packages/app/components/navigation/Navbar/Navbar.tsx +++ b/packages/app/components/navigation/Navbar/Navbar.tsx @@ -22,7 +22,7 @@ export const Navbar = () => { return ( - + { }; const NavbarStyles = { - floatingBg: '#0284c7', + floatingBg: '#0c66a1', floatingRadius: 25, - floatingBlur: 'blur(2px)', - transition: 'all 0.2s ease-in-out', - floatingSpacing: 4, + floatingBlur: 'blur(4px)', + transition: 'all 0.3s ease-in', + floatingSpacing: 2, }; const loadStyles = (currentTheme, isScrolled, screenWidth) => { @@ -78,7 +78,9 @@ const loadStyles = (currentTheme, isScrolled, screenWidth) => { safeArea: { backgroundColor, width: '100%', - margin: 0, + margin: "0 auto", + justifyContent: 'center', + alignItems: 'center', transition: NavbarStyles.transition, ...Platform.select({ web: { @@ -93,12 +95,12 @@ 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%", }, }), }, container: { - width: '100vw', + width: '100&', maxWidth: '100%', // Ensure container does not exceed the viewport width flex: 1, // Ensure container can grow to fit content backgroundColor, From 2ffe2d7802be274f55cffcc1c8df1c47fa2e63f6 Mon Sep 17 00:00:00 2001 From: Muhammad Hassan Date: Fri, 9 Aug 2024 09:15:41 -0700 Subject: [PATCH 002/121] Landing Page Refactored --- apps/vite/src/styles/global.css | 2 +- .../app/components/landing_page/index.tsx | 105 ++++++----- .../landing_page/landingpage.style.tsx | 5 +- packages/app/components/navigation/Drawer.tsx | 2 +- .../components/navigation/Navbar/Navbar.tsx | 164 ++++++++++++------ 5 files changed, 186 insertions(+), 92 deletions(-) diff --git a/apps/vite/src/styles/global.css b/apps/vite/src/styles/global.css index 8c9f008ce..3e53435a2 100644 --- a/apps/vite/src/styles/global.css +++ b/apps/vite/src/styles/global.css @@ -1,5 +1,5 @@ body { - background-color: rgb(2, 132, 199) !important; + background-color: #f6f6f6 !important; } *:focus { diff --git a/packages/app/components/landing_page/index.tsx b/packages/app/components/landing_page/index.tsx index 6c97bc665..4f2f3d0a6 100644 --- a/packages/app/components/landing_page/index.tsx +++ b/packages/app/components/landing_page/index.tsx @@ -25,7 +25,7 @@ const RStack: any = OriginalRStack; const LandingPage = () => { const { currentTheme } = useTheme(); const styles = useCustomStyles(loadStyles); - const { xxs, xs, xxl } = useResponsive(); + const { xxs, xs, sm, xxl } = useResponsive(); const handleGetStarted = () => { return ; @@ -38,7 +38,7 @@ const LandingPage = () => { style={ { width: '100vw', - height: xs && xxs ? 'auto' : '70vh', + height: xs || sm || xxs ? 'auto' : '70vh', alignItems: 'center', textAlign: 'center', paddingVertical: 18, @@ -47,40 +47,42 @@ const LandingPage = () => { } as any } > - {Platform.OS === 'web' ? ( - + + {Platform.OS === 'web' ? ( PackRat - - ) : ( - - PackRat - - )} + ) : ( + + PackRat + + )} + { > The Ultimate Travel App @@ -134,8 +135,8 @@ const LandingPage = () => { margin: 10, padding: 32, backgroundColor: '#fbfdff', - width: xs ? '100%' : 'auto', - + width: xs || sm ? '100%' : 'auto', + boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.10)', }} > { alignItems: 'center', justifyContent: 'space-between', gap: 8, + width: '100%', }} > { size={44} color="#315173" /> - + Download on App Store @@ -163,7 +172,8 @@ const LandingPage = () => { margin: 10, padding: 32, backgroundColor: '#fbfdff', - width: xs ? '100%' : 'auto', + width: xs || sm ? '100%' : 'auto', + boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.10)', }} > { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', + width: '100%', gap: 8, }} > @@ -180,7 +191,14 @@ const LandingPage = () => { size={44} color="#315173" /> - + Download on Google Play @@ -191,8 +209,9 @@ const LandingPage = () => { margin: 10, padding: 32, backgroundColor: '#fbfdff', - width: xs ? '100%' : "auto", + width: xs || sm ? '100%' : 'auto', justifyContent: 'center', + boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.10)', }} > { flexDirection: 'row', alignItems: 'center', gap: 8, + width: '100%', }} > { size={44} color="#315173" /> - + Use as Web App diff --git a/packages/app/components/landing_page/landingpage.style.tsx b/packages/app/components/landing_page/landingpage.style.tsx index 861e2fd45..8397e0b63 100644 --- a/packages/app/components/landing_page/landingpage.style.tsx +++ b/packages/app/components/landing_page/landingpage.style.tsx @@ -5,7 +5,7 @@ import { Platform } from 'react-native'; const loadStyles = (theme) => { const { currentTheme } = theme; - const { xxs, xs, xxl } = useResponsive(); + const { xxs, xs, xxl, sm, lg } = useResponsive(); return { mutualStyles: { @@ -49,7 +49,7 @@ const loadStyles = (theme) => { width: '100%', }, introText: { - fontSize: Platform.OS === 'web' ? 20 : 20, + fontSize: Platform.OS === 'web' ? ((xs || sm) ? 16: 20) : 20, fontWeight: Platform.OS === 'web' ? 'normal' : 'normal', textAlign: 'left', marginTop : xs ? 0 : 30, @@ -84,6 +84,7 @@ const loadStyles = (theme) => { marginBottom: 10, // width: '100%', backgroundColor: "#fbfdff", + boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.10)' }, cardHeader: { flexDirection: 'row', diff --git a/packages/app/components/navigation/Drawer.tsx b/packages/app/components/navigation/Drawer.tsx index 6ba2ab388..59790f132 100644 --- a/packages/app/components/navigation/Drawer.tsx +++ b/packages/app/components/navigation/Drawer.tsx @@ -19,7 +19,7 @@ export function Drawer() { icon={} bg="transparent" outlineColor="transparent" - color="white" + color="#315173" fontWeight="bold" focusStyle={{ bg: 'transparent', diff --git a/packages/app/components/navigation/Navbar/Navbar.tsx b/packages/app/components/navigation/Navbar/Navbar.tsx index 45c86e32d..35280aa3e 100644 --- a/packages/app/components/navigation/Navbar/Navbar.tsx +++ b/packages/app/components/navigation/Navbar/Navbar.tsx @@ -9,78 +9,127 @@ 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 { MaterialCommunityIcons } from '@expo/vector-icons'; +import useResponsive from 'app/hooks/useResponsive'; export const Navbar = () => { - const { currentTheme } = useTheme(); + const { currentTheme, enableDarkMode, enableLightMode, isDark, isLight } = + useTheme(); + const toggleTheme = () => { + console.log(isLight); + if (isLight) { + return enableDarkMode(); + } + enableLightMode(); + }; const scrollTop = useScrollTop(); const { screenWidth } = useScreenWidth(); const isScrolled = !!scrollTop; + const { xxs, xs, sm, md, lg } = useResponsive(); const styles = useMemo(() => { - return StyleSheet.create(loadStyles(currentTheme, isScrolled, screenWidth)); + return StyleSheet.create( + loadStyles(currentTheme, isScrolled, screenWidth, xxs, xs, sm, md, lg), + ); }, [isScrolled, currentTheme, screenWidth]); const navigate = useNavigate(); return ( - - - - - { - navigate('/'); - }} - /> - { - navigate('/'); - }} - > - PackRat - + + + + + + + + + {/* { + navigate('/'); + }} + /> */} + { + navigate('/'); + }} + > + PackRat + + + - - - - + + + ); }; const NavbarStyles = { - floatingBg: '#0c66a1', - floatingRadius: 25, - floatingBlur: 'blur(4px)', - transition: 'all 0.3s ease-in', - floatingSpacing: 2, + floatingBg: '#f0f2f5', + floatingRadius: 30, + floatingBlur: 'blur(10px)', + transition: 'all 0.2s ease-in-out', + floatingSpacing: 1, }; -const loadStyles = (currentTheme, isScrolled, screenWidth) => { +const loadStyles = ( + currentTheme, + isScrolled, + screenWidth, + xxs, + xs, + sm, + md, + lg, +) => { const isWeb = Platform.OS === 'web'; const isFloating = isWeb && isScrolled; const backgroundColor = isFloating ? NavbarStyles.floatingBg - : currentTheme.colors.background; + : "#f6f6f6"; return StyleSheet.create({ + mainContainer: { + backgroundColor: '#f6f6f6', + display: 'flex', + alignContent: 'center', + alignItems: 'center', + justifyContent: 'center', + position: 'fixed', + top: 0, + left: 0, + right: 0, + zIndex: 100, + }, drawerStyles: { backgroundColor: currentTheme.colors.background, }, safeArea: { backgroundColor, width: '100%', - margin: "0 auto", - justifyContent: 'center', alignItems: 'center', + justifyContent: 'center', + margin: 'auto', + borderRadius: NavbarStyles.floatingRadius, transition: NavbarStyles.transition, ...Platform.select({ web: { @@ -89,28 +138,43 @@ const loadStyles = (currentTheme, isScrolled, screenWidth) => { backdropFilter: NavbarStyles.floatingBlur, marginTop: NavbarStyles.floatingSpacing, padding: NavbarStyles.floatingSpacing, - borderRadius: NavbarStyles.floatingRadius, + paddingTop: 6, + paddingBottom: 6, + boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.29)' } : {}), position: 'fixed' as 'fixed' | 'relative', top: 0, + // right: 0, + // left: 0, zIndex: 100, - // width: Platform.OS === 'web' ? '100vw' : "100%", + width: + Platform.OS === 'web' + ? xxs || xs || sm + ? '100vw' + : '90vw' + : xxs || xs || sm + ? '100%' + : '90%', + alignItems: 'center', + justifyContent: 'center', }, }), }, container: { - width: '100&', + width: '100%', maxWidth: '100%', // Ensure container does not exceed the viewport width flex: 1, // Ensure container can grow to fit content backgroundColor, borderRadius: NavbarStyles.floatingRadius, + paddingHorizontal: 16, + paddingVertical: 4, 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, + height: 'auto', // Ensure container takes full height of its container + // padding: 16, }, header: { flexDirection: 'row', // Keep flexDirection as row for initial alignment @@ -126,14 +190,16 @@ const loadStyles = (currentTheme, isScrolled, screenWidth) => { logo: { marginRight: 10, cursor: 'pointer', + color: "#315173", }, logoText: { - color: currentTheme.colors.text, - fontSize: 38, + color: "#315173", + fontSize: 24, fontWeight: '900', cursor: 'pointer', }, menuBar: { + color: "#315173", flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-end', From ad14f9328e3c5a22753b922b49ce8bb6692916ee Mon Sep 17 00:00:00 2001 From: Muhammad Hassan Date: Mon, 12 Aug 2024 02:01:30 -0700 Subject: [PATCH 003/121] Refactored Changes --- .../app/components/landing_page/index.tsx | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/packages/app/components/landing_page/index.tsx b/packages/app/components/landing_page/index.tsx index 4f2f3d0a6..22042bd55 100644 --- a/packages/app/components/landing_page/index.tsx +++ b/packages/app/components/landing_page/index.tsx @@ -38,12 +38,11 @@ const LandingPage = () => { style={ { width: '100vw', - height: xs || sm || xxs ? 'auto' : '70vh', alignItems: 'center', textAlign: 'center', paddingVertical: 18, marginTop: Platform.OS !== 'web' ? 25 : 65, - // flex: 1, + flex: 1, } as any } > @@ -133,7 +132,7 @@ const LandingPage = () => { title="App Store" style={{ margin: 10, - padding: 32, + padding: 40, backgroundColor: '#fbfdff', width: xs || sm ? '100%' : 'auto', boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.10)', @@ -142,7 +141,7 @@ const LandingPage = () => { { > { color: '#315173', fontStyle: 'normal', textAlign: 'left', + fontSize: 18 }} > Download on App Store @@ -170,7 +173,7 @@ const LandingPage = () => { title="Google Play" style={{ margin: 10, - padding: 32, + padding: 40, backgroundColor: '#fbfdff', width: xs || sm ? '100%' : 'auto', boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.10)', @@ -179,7 +182,7 @@ const LandingPage = () => { { > { fontStyle: 'normal', width: '100%', textAlign: 'left', + fontSize: 18 }} > Download on Google Play @@ -207,7 +214,7 @@ const LandingPage = () => { title="Web" style={{ margin: 10, - padding: 32, + padding: 40, backgroundColor: '#fbfdff', width: xs || sm ? '100%' : 'auto', justifyContent: 'center', @@ -216,7 +223,7 @@ const LandingPage = () => { > { > { fontStyle: 'normal', width: '100%', textAlign: 'left', + fontSize: 18 }} > Use as Web App From b0898306c4777559c8d887a2c27fa24699737bf2 Mon Sep 17 00:00:00 2001 From: Muhammad Hassan Date: Mon, 12 Aug 2024 07:58:04 -0700 Subject: [PATCH 004/121] Applied Requested Changes --- .../landing_page/LandingPageAccordion.tsx | 23 +- .../app/components/landing_page/index.tsx | 209 ++++++++++++------ .../landing_page/landingpage.style.tsx | 66 +++--- packages/app/components/navigation/Drawer.tsx | 8 +- .../components/navigation/Navbar/Navbar.tsx | 24 +- .../components/navigation/NavigationItem.tsx | 12 +- .../components/navigation/NavigationList.tsx | 8 +- 7 files changed, 201 insertions(+), 149 deletions(-) diff --git a/packages/app/components/landing_page/LandingPageAccordion.tsx b/packages/app/components/landing_page/LandingPageAccordion.tsx index 0102cdf3b..8c19805ae 100644 --- a/packages/app/components/landing_page/LandingPageAccordion.tsx +++ b/packages/app/components/landing_page/LandingPageAccordion.tsx @@ -9,31 +9,16 @@ const RButton: any = OriginalRButton; export const LandingPageAccordion = ({ title, content, iconName }) => { const styles = useCustomStyles(loadStyles); - const [expanded, toggleExpanded] = useAccordionState(); + // const [expanded, toggleExpanded] = useAccordionState(); return ( - - {title} - - - - + {title} + {content} - {expanded && ( - - {content} - - )} + ); }; diff --git a/packages/app/components/landing_page/index.tsx b/packages/app/components/landing_page/index.tsx index 22042bd55..e5b7223d5 100644 --- a/packages/app/components/landing_page/index.tsx +++ b/packages/app/components/landing_page/index.tsx @@ -62,7 +62,6 @@ const LandingPage = () => { margin: xs || sm ? 0 : 20, fontWeight: 'bolder', height: 'auto', - whiteSpace: 'pre-wrap', }} > @@ -91,7 +90,7 @@ const LandingPage = () => { style={{ color: '#ab766d', height: 'auto', - fontSize: xs || sm ? 28 : 40, + fontSize: xs || sm ? 34 : 44, fontWeight: xs || sm ? 'bold' : 'bolder', }} > @@ -108,6 +107,11 @@ const LandingPage = () => { Get Started + @@ -130,132 +134,205 @@ const LandingPage = () => { > - - + + + - Download on App Store - + + Get it on + + + App Store + + - + + + - - Download on Google Play - + + Get it on + + + Google Play + + - - + + + - Use as Web App - + + Use as + + + Web App + + )} {FAQ_ITEMS.map((item, index) => ( { const { currentTheme } = theme; - const { xxs, xs, xxl, sm, lg } = useResponsive(); + const { xxs, xs, xxl, sm, lg, md } = useResponsive(); return { mutualStyles: { @@ -49,30 +47,32 @@ const loadStyles = (theme) => { width: '100%', }, introText: { - fontSize: Platform.OS === 'web' ? ((xs || sm) ? 16: 20) : 20, + fontSize: (xs || sm ? 18 : 22), fontWeight: Platform.OS === 'web' ? 'normal' : 'normal', - textAlign: 'left', - marginTop : xs ? 0 : 30, - color: "#45607d", + textAlign: 'center', + marginTop: xs ? 0 : 30, + color: '#45607d', width: '58vw', marginBottom: 20, // Ensure spacing between text and next elements paddingHorizontal: 10, // Adjust text alignment on smaller screens }, buttonContainer: { - // paddingHorizontal: 20, - // paddingBottom: 20, - // width: '100%', // Ensure buttons are well-spaced and aligned margin: 30, display: 'flex', alignItems: 'center', + justifyContent: 'center', // Center buttons horizontally }, getStartedButton: { - backgroundColor: '#f3e7fc', + backgroundColor: 'transparent', height: 50, + borderWidth: 1, + borderColor: '#315173', + flexDirection: 'row', + justifyContent: 'center', paddingVertical: 12, // Increase padding for better touch area paddingHorizontal: 30, - borderRadius: 30, // Rounded corners for modern look + borderRadius: 8, // Rounded corners for modern look alignItems: 'center', // Ensure text is centered within button }, footerText: { @@ -80,39 +80,39 @@ const loadStyles = (theme) => { fontSize: 18, fontWeight: 'bold', }, + landingPageAccordion: { + flexDirection: 'row', + flexWrap: 'wrap', + // border: '10px solid black', + justifyContent: 'center', + }, card: { - marginBottom: 10, - // width: '100%', - backgroundColor: "#fbfdff", - boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.10)' + width: xs || sm || md ? '100%' : '30%', + margin: 8, + backgroundColor: 'transparent', + flexDirection: 'row', }, cardHeader: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', paddingHorizontal: 20, paddingVertical: 10, - textWrap: 'wrap', width: '100%', }, - transparentButton: { - backgroundColor: 'transparent', - height: 'auto', - }, icon: { - fontSize: 40, - color: "#315173", - marginRight: 10, + fontSize: 26, + width: '100%', + color: '#315173', }, featureText: { - fontSize: 22, - color: "#315173", + fontSize: 20, + color: '#315173', + marginTop: 10, + marginBottom: 10, + width: '100%', }, cardContent: { - paddingHorizontal: 20, - paddingVertical: 10, - fontSize: 16, - color: "#315173", + fontSize: 18, + color: '#315173', + width: '100%', }, }; }; diff --git a/packages/app/components/navigation/Drawer.tsx b/packages/app/components/navigation/Drawer.tsx index 59790f132..f962cd559 100644 --- a/packages/app/components/navigation/Drawer.tsx +++ b/packages/app/components/navigation/Drawer.tsx @@ -9,7 +9,7 @@ import { NavigationList } from './NavigationList'; const Popover: any = OriginalPopover; export function Drawer() { - const { currentTheme } = useTheme(); + const { currentTheme, isDark, isLight } = useTheme(); const styles = useCustomStyles(loadStyles); return ( @@ -30,7 +30,6 @@ export function Drawer() { bg: 'transparent', }} > - Menu @@ -50,7 +49,7 @@ export function Drawer() { borderWidth={1} borderColor="$borderColor" style={styles.popover} - bg={currentTheme.colors.background} + bg={isDark ? currentTheme.colors.background : '#f0f2f5'} enterStyle={{ opacity: 0 }} exitStyle={{ opacity: 0 }} elevate @@ -66,7 +65,7 @@ export function Drawer() { { }, popover: { alignItems: 'flex-start', + boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.29)' }, }; }; diff --git a/packages/app/components/navigation/Navbar/Navbar.tsx b/packages/app/components/navigation/Navbar/Navbar.tsx index 35280aa3e..287cf86c2 100644 --- a/packages/app/components/navigation/Navbar/Navbar.tsx +++ b/packages/app/components/navigation/Navbar/Navbar.tsx @@ -51,7 +51,7 @@ export const Navbar = () => { /> - {/* { onClick={() => { navigate('/'); }} - /> */} - + {/* { navigate('/'); }} > PackRat - + */} @@ -188,24 +188,18 @@ const loadStyles = ( alignItems: 'center', }, logo: { - marginRight: 10, - cursor: 'pointer', - color: "#315173", - }, - logoText: { - color: "#315173", - fontSize: 24, - fontWeight: '900', cursor: 'pointer', + backgroundColor: 'transparent', + filter: 'drop-shadow(0 0 1px blue)', }, menuBar: { color: "#315173", 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 + // paddingHorizontal: 16, + // flex: 1, // Keep flexible but consider its behavior with wrapping, + // flexWrap: 'wrap', // Allow items to wrap }, drawerTrigger: {}, menuBarItemActive: { diff --git a/packages/app/components/navigation/NavigationItem.tsx b/packages/app/components/navigation/NavigationItem.tsx index 7ea3c5dd8..04604e8be 100644 --- a/packages/app/components/navigation/NavigationItem.tsx +++ b/packages/app/components/navigation/NavigationItem.tsx @@ -29,7 +29,7 @@ export const NavigationItem = ({ onSelect, }: NavigationItemProps) => { const styles = useCustomStyles(loadStyles); - const { currentTheme } = useTheme(); + const { currentTheme, isDark, isLight } = useTheme(); const { IconComponent, isCurrentPage, handleItemPress } = useNavigationItem( item, onSelect, @@ -42,11 +42,7 @@ export const NavigationItem = ({ )} label={text} @@ -61,7 +57,7 @@ export const NavigationItem = ({ }; const loadStyles = (theme) => { - const { currentTheme } = theme; + const { currentTheme, isDark, isLight } = theme; return { menuBarItem: { @@ -71,7 +67,7 @@ const loadStyles = (theme) => { paddingHorizontal: 12, }, menuBarItemText: { - color: currentTheme.colors.text, + color: isDark ? currentTheme.colors.text : '#315173', fontSize: 15, }, menuBarItemActive: { diff --git a/packages/app/components/navigation/NavigationList.tsx b/packages/app/components/navigation/NavigationList.tsx index 6a31de984..c3d1d30bb 100644 --- a/packages/app/components/navigation/NavigationList.tsx +++ b/packages/app/components/navigation/NavigationList.tsx @@ -15,7 +15,7 @@ export const NavigationList: React.FC = ({ onItemSelect = () => {}, }) => { const isMobileView = useIsMobileView(); - const { currentTheme } = useTheme(); + const { currentTheme, isLight, isDark } = useTheme(); const { navigationItems } = useNavigationList(); return ( <> @@ -27,11 +27,11 @@ export const NavigationList: React.FC = ({ width: '100%', borderRadius: 8, marginBottom: isMobileView ? 6 : 0, - backgroundColor: currentTheme.colors.background, - color: currentTheme.colors.white, + backgroundColor: isDark ? currentTheme.colors.background : '#f0f2f5', + color: isDark ? currentTheme.colors.white : '#315173', }} hoverStyle={{ - bg: currentTheme.colors.secondaryBlue as any, + bg: isDark ? currentTheme.colors.secondaryBlue as any : 'rgb(249, 249, 249)', }} key={item.href + index} > From 32235e8df0da52df49c18494634554a3795f7f62 Mon Sep 17 00:00:00 2001 From: Muhammad Hassan Date: Wed, 14 Aug 2024 00:58:41 -0700 Subject: [PATCH 005/121] Minor Changes --- apps/vite/src/styles/global.css | 3 ++- packages/app/components/landing_page/index.tsx | 2 +- .../app/components/landing_page/landingpage.style.tsx | 11 ++++++++--- packages/app/components/navigation/Navbar/Navbar.tsx | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/apps/vite/src/styles/global.css b/apps/vite/src/styles/global.css index 3e53435a2..e535d8907 100644 --- a/apps/vite/src/styles/global.css +++ b/apps/vite/src/styles/global.css @@ -1,5 +1,6 @@ body { - background-color: #f6f6f6 !important; + background: hsla(0, 0%, 96%, 1) !important; + filter: progid: DXImageTransform.Microsoft.gradient( startColorstr="#F6F6F6", endColorstr="#E1DAE6", GradientType=1 ); } *:focus { diff --git a/packages/app/components/landing_page/index.tsx b/packages/app/components/landing_page/index.tsx index e5b7223d5..42e53c27d 100644 --- a/packages/app/components/landing_page/index.tsx +++ b/packages/app/components/landing_page/index.tsx @@ -180,7 +180,7 @@ const LandingPage = () => { fontWeight: 'bold', }} > - Get it on + Get it on the { justifyContent: 'center', alignItems: 'center', width: '100%', - backgroundColor: 'rgb(248, 248, 248)', + background: 'hsla(0, 0%, 96%, 1)', + filter: 'progid: DXImageTransform.Microsoft.gradient( startColorstr="#F6F6F6", endColorstr="#E1DAE6", GradientType=1 )', padding: 20, }, secondaryContentContainer: { @@ -25,14 +26,16 @@ const loadStyles = (theme) => { width: '100%', justifyContent: 'center', alignItems: 'center', - backgroundColor: 'rgb(248, 248, 248)', + // backgroundColor: 'rgb(248, 248, 248)', + background: 'hsla(0, 0%, 96%, 1)', + filter: 'progid: DXImageTransform.Microsoft.gradient( startColorstr="#F6F6F6", endColorstr="#E1DAE6", GradientType=1 )', }, appBadges: { flexDirection: 'column', justifyContent: 'center', alignItems: 'center', marginVertical: 20, - marginBottom: 20, + marginBottom: 40, }, backgroundImage: { flex: 1, @@ -83,6 +86,7 @@ const loadStyles = (theme) => { landingPageAccordion: { flexDirection: 'row', flexWrap: 'wrap', + width: xs || sm ? 'auto' : '80%' , // border: '10px solid black', justifyContent: 'center', }, @@ -106,6 +110,7 @@ const loadStyles = (theme) => { fontSize: 20, color: '#315173', marginTop: 10, + fontWeight: 'bold', marginBottom: 10, width: '100%', }, diff --git a/packages/app/components/navigation/Navbar/Navbar.tsx b/packages/app/components/navigation/Navbar/Navbar.tsx index 287cf86c2..5915086f6 100644 --- a/packages/app/components/navigation/Navbar/Navbar.tsx +++ b/packages/app/components/navigation/Navbar/Navbar.tsx @@ -190,7 +190,7 @@ const loadStyles = ( logo: { cursor: 'pointer', backgroundColor: 'transparent', - filter: 'drop-shadow(0 0 1px blue)', + filter: 'drop-shadow(0 0 1px #45607d)', }, menuBar: { color: "#315173", From 748f001ba84ab940202f8c481331e0cfb7d6718f Mon Sep 17 00:00:00 2001 From: Muhammad Hassan Date: Fri, 23 Aug 2024 20:32:31 +0500 Subject: [PATCH 006/121] Pocket Template Implementation First --- .../landing_page/LandingPageAccordion.tsx | 1 - .../app/components/landing_page/index.tsx | 51 +++++++++---------- .../landing_page/landingpage.style.tsx | 16 +++--- packages/app/theme/index.ts | 9 ++-- server/src/index.ts | 4 +- 5 files changed, 42 insertions(+), 39 deletions(-) diff --git a/packages/app/components/landing_page/LandingPageAccordion.tsx b/packages/app/components/landing_page/LandingPageAccordion.tsx index 8c19805ae..1c496af68 100644 --- a/packages/app/components/landing_page/LandingPageAccordion.tsx +++ b/packages/app/components/landing_page/LandingPageAccordion.tsx @@ -18,7 +18,6 @@ export const LandingPageAccordion = ({ title, content, iconName }) => { {title} {content} - ); }; diff --git a/packages/app/components/landing_page/index.tsx b/packages/app/components/landing_page/index.tsx index 42e53c27d..fc940b278 100644 --- a/packages/app/components/landing_page/index.tsx +++ b/packages/app/components/landing_page/index.tsx @@ -8,6 +8,7 @@ import { RH1, RCard, RH3, + YStack, } from '@packrat/ui'; import useTheme from '../../hooks/useTheme'; import { MaterialCommunityIcons } from '@expo/vector-icons'; @@ -25,15 +26,13 @@ const RStack: any = OriginalRStack; const LandingPage = () => { const { currentTheme } = useTheme(); const styles = useCustomStyles(loadStyles); - const { xxs, xs, sm, xxl } = useResponsive(); - - const handleGetStarted = () => { - return ; - }; + const { xs, sm, md, lg, xl, xxl } = useResponsive(); return ( + + { } as any } > - {Platform.OS === 'web' ? ( { > { Get Started @@ -140,7 +139,7 @@ const LandingPage = () => { margin: 10, backgroundColor: 'transparent', borderWidth: 1, - borderColor: '#315173', + borderColor: currentTheme.colors.textPrimary, width: xs || sm ? '100%' : 'auto', overflow: 'hidden', }} @@ -159,7 +158,7 @@ const LandingPage = () => { { { { margin: 10, backgroundColor: 'transparent', borderWidth: 1, - borderColor: '#315173', + borderColor: currentTheme.colors.textPrimary, width: xs || sm ? '100%' : 'auto', overflow: 'hidden', }} @@ -224,7 +223,7 @@ const LandingPage = () => { { { { margin: 10, backgroundColor: 'transparent', borderWidth: 1, - borderColor: '#315173', + borderColor: currentTheme.colors.textPrimary, width: xs || sm ? '100%' : 'auto', overflow: 'hidden', }} @@ -289,7 +288,7 @@ const LandingPage = () => { { { { fontWeight: Platform.OS === 'web' ? 'normal' : 'normal', textAlign: 'center', marginTop: xs ? 0 : 30, - color: '#45607d', + color: currentTheme.colors.textDarkGrey, width: '58vw', marginBottom: 20, // Ensure spacing between text and next elements paddingHorizontal: 10, // Adjust text alignment on smaller screens @@ -63,7 +63,6 @@ const loadStyles = (theme) => { margin: 30, display: 'flex', alignItems: 'center', - justifyContent: 'center', // Center buttons horizontally }, getStartedButton: { @@ -79,9 +78,9 @@ const loadStyles = (theme) => { alignItems: 'center', // Ensure text is centered within button }, footerText: { - color: '#315173', + color: currentTheme.colors.textDarkGrey, fontSize: 18, - fontWeight: 'bold', + // fontWeight: 'bold', }, landingPageAccordion: { flexDirection: 'row', @@ -95,6 +94,9 @@ const loadStyles = (theme) => { margin: 8, backgroundColor: 'transparent', flexDirection: 'row', + borderWidth: 1, + borderColor: 'rgba(0, 0, 0, 0.3)', + borderRadius: 16 }, cardHeader: { paddingHorizontal: 20, @@ -104,11 +106,11 @@ const loadStyles = (theme) => { icon: { fontSize: 26, width: '100%', - color: '#315173', + color: currentTheme.colors.icon, }, featureText: { fontSize: 20, - color: '#315173', + color: currentTheme.colors.textPrimary, marginTop: 10, fontWeight: 'bold', marginBottom: 10, @@ -116,7 +118,7 @@ const loadStyles = (theme) => { }, cardContent: { fontSize: 18, - color: '#315173', + color: currentTheme.colors.textPrimary, width: '100%', }, }; diff --git a/packages/app/theme/index.ts b/packages/app/theme/index.ts index 17305340c..08ebb364e 100644 --- a/packages/app/theme/index.ts +++ b/packages/app/theme/index.ts @@ -4,7 +4,7 @@ import { DefaultTheme } from 'react-native-paper'; export const theme = { colors: { primary: '#0A84FF', - background: '#0284c7', + background: 'black', secondaryBlue: '#0C66A1', accentPurple: '#6C63FF', card: '#fafafa', @@ -13,11 +13,12 @@ export const theme = { border: '#fafafa', notification: '#0A84FF', error: '#FF453A', - textPrimary: '#22c55e', + textPrimary: 'black', textSecondary: '#EBEBF599', textDarkGrey: '#3B3B3B', cardIconColor: '#22c55e', iconColor: '#FFFFFF', + icon: 'black', weatherIcon: '#0284c7', drawerIconColor: '#3B3B3B', white: '#FFFFFF', @@ -53,14 +54,16 @@ export const darkTheme = { border: '#4E4E50', notification: '#0A84FF', error: '#FF453A', - textPrimary: '#22c55e', + textPrimary: 'white', textSecondary: '#C5C6C799', textDarkGrey: '#3B3B3B', cardIconColor: '#22c55e', iconColor: '#C5C6C7', + icon: 'white', weatherIcon: '#0A84FF', drawerIconColor: '#3B3B3B', white: '#FFFFFF', + buttonBackgroundPrimary: '#404040' }, font: { headerFont: 56, diff --git a/server/src/index.ts b/server/src/index.ts index f7844c64b..50f6f040c 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -38,10 +38,10 @@ const app = new Hono<{ Bindings: Bindings }>(); // ref: https://hono.dev/middleware/builtin/compress // SETUP HTTPS Enforcement Middleware -app.use('*', enforceHttps()); // Apply to all routes +// app.use('*', enforceHttps()); // Apply to all routes // SETUP SECURITY HEADERS -app.use('*', securityHeaders()); // Apply to all routes +// app.use('*', securityHeaders()); // Apply to all routes // SETUP CORS app.use('*', async (c, next) => { From f3427b8d7c07fae707e553b4423bf72b2b80effd Mon Sep 17 00:00:00 2001 From: Muhammad Hassan Date: Sat, 24 Aug 2024 22:03:13 +0500 Subject: [PATCH 007/121] some changes --- packages/app/assets/PackRat Preview.jpg | Bin 0 -> 101994 bytes .../app/components/landing_page/index.tsx | 109 ++++++++---------- .../landing_page/landingpage.style.tsx | 14 +-- .../components/navigation/Navbar/Navbar.tsx | 44 ++++--- packages/app/theme/index.ts | 13 ++- 5 files changed, 95 insertions(+), 85 deletions(-) create mode 100644 packages/app/assets/PackRat Preview.jpg diff --git a/packages/app/assets/PackRat Preview.jpg b/packages/app/assets/PackRat Preview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b2ab4c2dd4a4209445331f19f8944f7f40e41d8f GIT binary patch literal 101994 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%0AdL zF|z-nl6_Il{*omp>|!gALlKI#0g$PS=&4VIQy57cM&!0QHfy!E@@tbF8Zz?F$>YioUzGN9 zTT_RWmwtkYNC5M0)FWiDn!bp4?Fs#dju;o%E?<_|g~ctcHpCsm9Yqhm9DQ+H0(vc& z%fpn#y5N|Tu_W?iX$IQqfra?l1lg3C#u&G@4^@+4+u1muT%n5C65f_HFuzF}-{JvWsP6H-rv7{yE++T{M; zg?<&qgPE%2=F{dKH1XyCBwfHxym&`)*u8xb$^l@fZlVv`v`tfP`laRM-+F^6hxl5* z>~jH#vKVLk;0lr4iz81Dj*01ssHLA>Wm+b4KRBvSI*X$#S{8UL!o;%k)R27-SbROa z2Z&a5ELg5-JNT%2ol`ksVX+5zT$s)fA&eOlZU(If)zeuU*U=>RwBDBDM$z#|9o6v}YfCB{?YfQA0R|ddq2&!CZ1kbpgD23**`shIo9tT` zHG1);bpHz}#=&Lu?5u1oq)kytequ0OE z)JS+T7ElYZeOrT^kDX{tCZygY2=&xQ%e{+mGfk21hKq3To zBUI(BVdvw-S;@z_u*uFfrF68|<$PmHA?1>{Z1JVNYVO3uYgw|Y*ppe(p((S+g|3Q8 zPDkKqnAboGOkrJ4(reDy?pkF=fleDiCsI$2H1*76noP~C2jc|v#+=Y8wSt>_z#~{x zX*TSnNA%mR8y2Mm7&XfWEdm6H-iLY1aTK7Q=Ih`B4myF%D@f2lrLqScnq9&9(8*3g zK{XAfw+GxmSp!`KI?B)tpu5L6JB0O!5nVk*i=o`k6lniaLsS-mS(M{yLpGa1lT>=2tlzu5+sAy^F!-2_nB z(#S$ol8qv_05g3oc?Y(baI`@CaNLj&u0sa#0&tNitE!i-naqjX>g$Un#!1#AuC~2H z-|!*c8cWs9pT3rUOsMl>=%#>cXG&!-&A_b}>=#pt^Nt3$J0h-5=QMjoedrMlN-;D` z$&pSnz`7-XQX_rN>vk@e*KHO|(7_8XO-SXo;~XCM)eEMgCaPduPfH2B=WmX+M{Pmm zv5=SAyzdg=aM!9=-ls2NNs(PeO_Y^U_P~5hNb(g245qhYq>=@R^ zu+OylKoO!5j{3wZam9ssn#^^>SMsnaovr*@@6h#p`prw@_aP}acFNaL8u6Z|bKZG> j{KUO*Dv0EW0dwHRSHZV9w0__8%fAx*|34k0*z5f-;gfN4 literal 0 HcmV?d00001 diff --git a/packages/app/components/landing_page/index.tsx b/packages/app/components/landing_page/index.tsx index fc940b278..7fd0a11d2 100644 --- a/packages/app/components/landing_page/index.tsx +++ b/packages/app/components/landing_page/index.tsx @@ -9,6 +9,7 @@ import { RCard, RH3, YStack, + RImage, } from '@packrat/ui'; import useTheme from '../../hooks/useTheme'; import { MaterialCommunityIcons } from '@expo/vector-icons'; @@ -30,89 +31,71 @@ const LandingPage = () => { return ( - - - - {Platform.OS === 'web' ? ( + + - PackRat + The Ultimate Travel App - ) : ( - - PackRat - - )} + + + PackRat is the ultimate adventure planner designed for those who + love to explore the great outdoors. Plan and organize your trips + with ease, whether it's a weekend camping trip, a day hike, or a + cross-country road trip. + + + + + Get Started + + + + - - + - The Ultimate Travel App - - - - PackRat is the ultimate adventure planner designed for those who - love to explore the great outdoors. Plan and organize your trips - with ease, whether it's a weekend camping trip, a day hike, or a - cross-country road trip. - - - - - Get Started - - - + width={40} + height={40} + // style={styles.logo} + alt="PackRat Logo" + /> @@ -146,7 +129,7 @@ const LandingPage = () => { > { width: '100%', }, introText: { - fontSize: (xs || sm ? 18 : 22), + fontSize: (xs || sm ? 18 : 20), fontWeight: Platform.OS === 'web' ? 'normal' : 'normal', textAlign: 'center', marginTop: xs ? 0 : 30, - color: currentTheme.colors.textDarkGrey, - width: '58vw', + color: currentTheme.colors.textPrimary, + textAlign: 'left', + width: '50vw', marginBottom: 20, // Ensure spacing between text and next elements paddingHorizontal: 10, // Adjust text alignment on smaller screens }, buttonContainer: { - margin: 30, display: 'flex', - alignItems: 'center', + alignItems: 'start', justifyContent: 'center', // Center buttons horizontally }, getStartedButton: { @@ -78,7 +78,7 @@ const loadStyles = (theme) => { alignItems: 'center', // Ensure text is centered within button }, footerText: { - color: currentTheme.colors.textDarkGrey, + color: currentTheme.colors.textPrimary, fontSize: 18, // fontWeight: 'bold', }, @@ -95,7 +95,7 @@ const loadStyles = (theme) => { backgroundColor: 'transparent', flexDirection: 'row', borderWidth: 1, - borderColor: 'rgba(0, 0, 0, 0.3)', + borderColor: currentTheme.colors.cardBorderPrimary, borderRadius: 16 }, cardHeader: { diff --git a/packages/app/components/navigation/Navbar/Navbar.tsx b/packages/app/components/navigation/Navbar/Navbar.tsx index 5915086f6..42736bc68 100644 --- a/packages/app/components/navigation/Navbar/Navbar.tsx +++ b/packages/app/components/navigation/Navbar/Navbar.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; import { View, Text, SafeAreaView, StyleSheet, Platform } from 'react-native'; -import { RButton, Container } from '@packrat/ui'; +import { RButton, Container, RLink } from '@packrat/ui'; import { useIsMobileView } from 'app/hooks/common'; import { useNavigate } from 'app/hooks/navigation'; import { NavigationList } from '../NavigationList'; @@ -75,7 +75,12 @@ export const Navbar = () => { PackRat */} - + + + Login + + + @@ -83,14 +88,6 @@ export const Navbar = () => { ); }; -const NavbarStyles = { - floatingBg: '#f0f2f5', - floatingRadius: 30, - floatingBlur: 'blur(10px)', - transition: 'all 0.2s ease-in-out', - floatingSpacing: 1, -}; - const loadStyles = ( currentTheme, isScrolled, @@ -101,13 +98,27 @@ const loadStyles = ( md, lg, ) => { + const NavbarStyles = { + floatingBg: currentTheme.colors.floatingBg, + floatingRadius: 30, + floatingBlur: 'blur(10px)', + transition: 'all 0.2s ease-in-out', + floatingSpacing: 1, + }; + const isWeb = Platform.OS === 'web'; const isFloating = isWeb && isScrolled; const backgroundColor = isFloating ? NavbarStyles.floatingBg - : "#f6f6f6"; + : currentTheme.colors.navbarPrimaryBackground; return StyleSheet.create({ + navbarThird: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + gap: 8, + }, mainContainer: { backgroundColor: '#f6f6f6', display: 'flex', @@ -140,7 +151,7 @@ const loadStyles = ( padding: NavbarStyles.floatingSpacing, paddingTop: 6, paddingBottom: 6, - boxShadow: '0px 0px 30px 0px rgba(0,0,0,0.29)' + boxShadow: currentTheme.colors.navbarBoxShadow, } : {}), position: 'fixed' as 'fixed' | 'relative', @@ -193,7 +204,7 @@ const loadStyles = ( filter: 'drop-shadow(0 0 1px #45607d)', }, menuBar: { - color: "#315173", + color: '#315173', flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-end', @@ -202,6 +213,13 @@ const loadStyles = ( // flexWrap: 'wrap', // Allow items to wrap }, drawerTrigger: {}, + loginButton: { + backgroundColor: 'transparent', + color: currentTheme.colors.textPrimary, + borderWidth: 1, + borderColor: currentTheme.colors.textPrimary, + overflow: 'hidden', + }, menuBarItemActive: { // Apply styles for the active item // ... diff --git a/packages/app/theme/index.ts b/packages/app/theme/index.ts index a62e3319e..b20466607 100644 --- a/packages/app/theme/index.ts +++ b/packages/app/theme/index.ts @@ -22,6 +22,11 @@ export const theme = { drawerIconColor: '#3B3B3B', white: '#FFFFFF', black: '#000000', + cardBorderPrimary: 'rgba(0, 0, 0, 0.3)', + buttonBackgroundPrimary: '#404040', + floatingBg: '#f0f2f5', + navbarBoxShadow: '0px 0px 30px 0px rgba(0, 0, 0, 0.29)', + navbarPrimaryBackground: '#f6f6f6', }, font: { headerFont: 56, @@ -56,14 +61,18 @@ export const darkTheme = { error: '#FF453A', textPrimary: 'white', textSecondary: '#C5C6C799', - textDarkGrey: '#3B3B3B', + textDarkGrey: '#B0B0B0', cardIconColor: '#22c55e', iconColor: '#C5C6C7', icon: 'white', weatherIcon: '#0A84FF', drawerIconColor: '#3B3B3B', white: '#FFFFFF', - buttonBackgroundPrimary: '#404040' + cardBorderPrimary: 'rgba(255, 255, 255, 0.3)', + buttonBackgroundPrimary: '#B0B0B0', + floatingBg: '#1C1C1E', + navbarBoxShadow: '0px 0px 30px 0px rgba(0, 0, 0, 0.29)', + navbarPrimaryBackground: 'black', }, font: { headerFont: 56, From 6165ab2d78df7566a7a68fa05b0a829eccac1b9c Mon Sep 17 00:00:00 2001 From: Muhammad Hassan Date: Mon, 26 Aug 2024 17:15:58 +0500 Subject: [PATCH 008/121] Landing Page UI Changed --- packages/app/components/footer/Footer.tsx | 127 +++++++++++++--- .../app/components/landing_page/index.tsx | 141 ++++++------------ .../landing_page/landingpage.style.tsx | 55 +++++-- .../components/navigation/Navbar/Navbar.tsx | 61 +++++--- packages/app/components/newsLetter/index.tsx | 30 ++++ packages/app/constants/footorLinks.ts | 22 +++ packages/app/theme/index.ts | 2 +- 7 files changed, 292 insertions(+), 146 deletions(-) create mode 100644 packages/app/components/newsLetter/index.tsx create mode 100644 packages/app/constants/footorLinks.ts diff --git a/packages/app/components/footer/Footer.tsx b/packages/app/components/footer/Footer.tsx index 80bdfe08b..52c71998f 100644 --- a/packages/app/components/footer/Footer.tsx +++ b/packages/app/components/footer/Footer.tsx @@ -1,32 +1,119 @@ -import { Text, View } from 'react-native'; +import { StyleSheet, Text, View } from 'react-native'; import { theme } from '../../theme'; import useTheme from '../../hooks/useTheme'; +import { RImage, RLink, RText } from '@packrat/ui'; +import { useNavigate } from 'app/hooks/navigation'; +import { useMemo } from 'react'; +import { footorLinks } from 'app/constants/footorLinks'; +import { NewsLetter } from 'app/components/newsLetter'; export default function Footer() { const { enableDarkMode, enableLightMode, isDark, isLight, currentTheme } = useTheme(); + const styles = useMemo(() => { + return StyleSheet.create(loadStyles(currentTheme)); + }, [currentTheme]); const year = new Date().getFullYear(); + const navigate = useNavigate(); return ( - + + + { + navigate('/'); + }} + /> + { + navigate('/'); + }} + > + The Ultimate Travel App + + + + {footorLinks.map((item) => { + return ( + + {item.label} + + ); + })} + + + + © 2024 Bierman Collective. All rights reserved. + + {/* */} + + + + ); +} + +const loadStyles = (currentTheme) => { + { + return StyleSheet.create({ + mainContainer: { + width: '100vw', + paddingTop: 80, + paddingBottom: 40, + backgroundColor: '#f6f6f6', + // border: '1px solid red', alignSelf: 'center', + alignItems: 'center', + justifyContent: 'center', position: 'relative', bottom: 0, - }} - > - - Copyright © {year} - - - ); -} + }, + firstMainContainer: { + width: '95%', + // border: '1px solid black', + }, + firstContainer: { + width: '100%', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-start', + gap: 4, + paddingVertical: 18, + }, + logo: { + backgroundColor: 'black', + borderRadius: 8, + }, + navLinks: { + flexDirection: 'row', + gap: 16, + fontSize: 14, + color: currentTheme.colors.textPrimary, + paddingBottom: 40, + }, + navItem: { color: currentTheme.colors.textPrimary }, + credit: { + color: currentTheme.colors.textPrimary, + fontSize: 13, + textAlign: 'left', + fontWeight: 'normal', + }, + lastContainer: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between' + } + }); + } +}; diff --git a/packages/app/components/landing_page/index.tsx b/packages/app/components/landing_page/index.tsx index 7fd0a11d2..46bd70896 100644 --- a/packages/app/components/landing_page/index.tsx +++ b/packages/app/components/landing_page/index.tsx @@ -11,6 +11,7 @@ import { YStack, RImage, } from '@packrat/ui'; + import useTheme from '../../hooks/useTheme'; import { MaterialCommunityIcons } from '@expo/vector-icons'; import { RLink } from '@packrat/ui'; @@ -20,6 +21,7 @@ import { LandingPageAccordion } from './LandingPageAccordion'; import loadStyles from './landingpage.style'; import { Redirect } from 'app/components/Redirect'; import useResponsive from 'app/hooks/useResponsive'; +import Footer from 'app/components/footer/Footer'; const RButton: any = OriginalRButton; const RStack: any = OriginalRStack; @@ -36,11 +38,11 @@ const LandingPage = () => { style={ { width: '100%', - alignItems: 'center', + // alignItems: 'center', textAlign: 'center', flexDirection: 'row', justifyContent: 'space-around', - paddingVertical: 18, + // paddingVertical: 18, marginTop: Platform.OS !== 'web' ? 25 : 65, flex: 1, } as any @@ -50,6 +52,7 @@ const LandingPage = () => { { cross-country road trip. - + {/* Get Started { color={currentTheme.colors.buttonBackgroundPrimary} /> - - - - - - - - - {/* */} - {/* */} - - {Platform.OS === 'web' && ( + */} { - - - - - - - - Use as - - - Web App - - - - - )} + + + + + + + + + {/* */} + {/* */} + + + Discover how the PackRat app is designed to make your adventures + easier and more enjoyable. + + + With a suite of powerful features tailored specifically for + backpackers, you'll have everything you need right at your + fingertips. From seamless route planning to real-time weather + updates, PackRat ensures you're prepared for every step of your + journey. Dive into the key features below to see how we can help + you elevate your backpacking experience: + + + { {/* */} {/* */} + +