diff --git a/packages/app/README.md b/packages/app/README.md deleted file mode 100644 index 8d2b7dd2..00000000 --- a/packages/app/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# How to theme - -Current theme based on design system can be found here: GoodCollective/packages/app/src/theme -example of implementation can be found at: - -1. import components from 'native-base' instead of 'react-native' - 1a. they are mostly the same, but have extended styling options and are connected to the above mentioned theme -2. by using the withTheme hook you can apply styles similiar to how you would do with react-native's StyleSheet - ie. - -``` -import { withTheme } from '@gooddollar/good-design' -import { Text } from 'native-base' - -export const theme = { - baseStyle: { - fontStyles: { - title: { - fontWeight: 700, - color: 'black', - fontFamily: 'heading', - fontSize: 'md', - } - }, - ...// define additional styles - } -} - -const TestComponent = withTheme({ name: })(({ fontStyles }: any) => ( - TestText // add as props so that it can apply the definitions from theme -)) -``` - -3. todo: add example for breakpoint values -4. todo: add example for variants diff --git a/packages/app/src/components/AboutCard.tsx b/packages/app/src/components/AboutCard.tsx index 06a81376..ef83e269 100644 --- a/packages/app/src/components/AboutCard.tsx +++ b/packages/app/src/components/AboutCard.tsx @@ -1,63 +1,61 @@ import { Text, View } from 'native-base'; -import { withTheme } from '@gooddollar/good-design'; -export const theme = { - baseStyle: { - fontStyles: { - title: { - fontWeight: 700, - color: 'black', - fontFamily: 'heading', - fontSize: 'md', - }, - subTitle: { - color: 'goodGrey.500', - fontWeight: 700, - lineHeight: 24, - fontFamily: 'heading', - fontSize: 'sm', - }, - paragraph: { - color: 'goodGrey.500', - width: '100%', - lineHeight: 24, - fontWeight: 400, - fontSize: 'sm', - }, +export const aboutCardStyles = { + font: { + title: { + fontWeight: 700, + color: 'black', + fontFamily: 'heading', + fontSize: 'md', }, - styles: { - aboutContainer: { - padding: 15, - marginBottom: 10, - }, - mainContainer: { - width: '100%', - backgroundColor: 'white', - paddingVertical: 16, - paddingHorizontal: 12, - borderRadius: 20, - gap: 24, - }, - elevation: { - shadowColor: 'black', - shadowOffset: { - width: 0, - height: 12, - }, - shadowOpacity: 0.15, - shadowRadius: 15, - elevation: 24, + subTitle: { + color: 'goodGrey.500', + fontWeight: 700, + lineHeight: 24, + fontFamily: 'heading', + fontSize: 'sm', + }, + paragraph: { + color: 'goodGrey.500', + width: '100%', + lineHeight: 24, + fontWeight: 400, + fontSize: 'sm', + }, + }, + container: { + aboutContainer: { + padding: 15, + marginBottom: 10, + }, + mainContainer: { + width: '100%', + backgroundColor: 'white', + paddingVertical: 16, + paddingHorizontal: 12, + borderRadius: 20, + gap: 24, + }, + elevation: { + shadowColor: 'black', + shadowOffset: { + width: 0, + height: 12, }, + shadowOpacity: 0.15, + shadowRadius: 15, + elevation: 24, }, }, }; -const AboutCard = withTheme({ name: 'AboutCard' })(({ styles, fontStyles, ...props }: any) => { - const { title, subTitle, paragraph } = fontStyles; +const AboutCard = () => { + const { font, container } = aboutCardStyles; + const { title, subTitle, paragraph } = font; return ( - - + + About Collective GoodCollective makes visible the climate stewardship activities of individuals, and provides a direct channel @@ -103,6 +101,6 @@ const AboutCard = withTheme({ name: 'AboutCard' })(({ styles, fontStyles, ...pro ); -}); +}; export default AboutCard; diff --git a/packages/app/src/components/ActionButton.tsx b/packages/app/src/components/ActionButton.tsx index 62e40010..84ecd2fb 100644 --- a/packages/app/src/components/ActionButton.tsx +++ b/packages/app/src/components/ActionButton.tsx @@ -1,5 +1,4 @@ import { Box, Link, Pressable, Text, useBreakpointValue } from 'native-base'; -import { withTheme } from '@gooddollar/good-design'; import { InterSemiBold } from '../utils/webFonts'; @@ -9,81 +8,74 @@ type ActionButtonProps = { bg: string; textColor: string; onPress?: any; - buttonStyles?: any; }; -export const theme = { - baseStyle: { - buttonStyles: { - buttonContainer: { - justifyContent: 'space-evenly', - marginTop: 2, - }, +export const buttonStyles = { + buttonContainer: { + justifyContent: 'space-evenly', + marginTop: 2, + }, + button: { + width: '100%', + height: 47, + flex: 1, + justifyContent: 'space-between', + alignItems: 'center', + paddingRight: 10, + paddingLeft: 10, + paddingBottom: 1, + fontSize: 'md', + fontWeight: 700, + flexDirection: 'row', + flexWrap: 'wrap', + borderRadius: 50, + }, + buttonText: { + ...InterSemiBold, + fontSize: 'md', + }, +}; + +const ActionButton = ({ href, text, bg, textColor, onPress }: ActionButtonProps) => { + const responsiveStyles = useBreakpointValue({ + base: { button: { - width: '100%', + ...buttonStyles.button, + justifyContent: 'center', + }, + buttonText: { + ...buttonStyles.buttonText, height: 47, - flex: 1, - justifyContent: 'space-between', + display: 'flex', alignItems: 'center', - paddingRight: 10, - paddingLeft: 10, - paddingBottom: 1, - fontSize: 'md', - fontWeight: 700, - flexDirection: 'row', - flexWrap: 'wrap', - borderRadius: 50, }, - buttonText: { - ...InterSemiBold, - fontSize: 'md', + buttonContainer: { + ...buttonStyles.buttonContainer, + width: '100%', }, }, - }, -}; + lg: buttonStyles, + }); -const ActionButton = withTheme({ name: 'ActionButton' })( - ({ href, text, bg, textColor, onPress, buttonStyles }: ActionButtonProps) => { - const responsiveStyles = useBreakpointValue({ - base: { - button: { - ...buttonStyles.button, - justifyContent: 'center', - }, - buttonText: { - ...buttonStyles.buttonText, - height: 47, - display: 'flex', - alignItems: 'center', - }, - buttonContainer: { - ...buttonStyles.buttonContainer, - width: '100%', - }, - }, - md: buttonStyles, - }); + const { buttonContainer, button, buttonText } = responsiveStyles ?? {}; - const { buttonContainer, button, buttonText } = responsiveStyles ?? {}; + const content = ( + + + {text} + + + ); - const content = ( - - - {text} - - + if (href) { + return ( + + {content} + ); - - if (href) { - return ( - - {content} - - ); - } - - return {content}; } -); + + return {content}; +}; export default ActionButton; diff --git a/packages/app/src/components/CollectiveHomeCard.tsx b/packages/app/src/components/CollectiveHomeCard.tsx index 471a06b6..90ce7917 100644 --- a/packages/app/src/components/CollectiveHomeCard.tsx +++ b/packages/app/src/components/CollectiveHomeCard.tsx @@ -1,10 +1,11 @@ -import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { Image, StyleSheet, Text, TouchableOpacity, TouchableOpacityProps, View } from 'react-native'; + import { InterSemiBold, InterSmall } from '../utils/webFonts'; import useCrossNavigate from '../routes/useCrossNavigate'; import { Colors } from '../utils/colors'; -import { useMediaQuery } from 'native-base'; import { useState } from 'react'; import { Ocean } from '../assets'; +import { useScreenSize } from '../theme/hooks'; interface CollectiveHomeCardProps { name: string; @@ -15,11 +16,9 @@ interface CollectiveHomeCardProps { function CollectiveHomeCard({ name, description, headerImage, route }: CollectiveHomeCardProps) { const { navigate } = useCrossNavigate(); - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView, isTabletView } = useScreenSize(); - const headerImg = { uri: headerImage } ?? Ocean; + const headerImg = headerImage ? { uri: headerImage } : Ocean; const [isParagraphExpanded, setIsParagraphExpanded] = useState(false); @@ -28,8 +27,9 @@ function CollectiveHomeCard({ name, description, headerImage, route }: Collectiv style={[ styles.cardContainer, styles.elevation, - isDesktopResolution ? styles.cardContainerDesktop : {}, + isDesktopView ? styles.cardContainerDesktop : {}, isParagraphExpanded ? { height: 'auto' } : {}, + isTabletView ? { marginBottom: 20 } : {}, ]} onPress={() => navigate(`/collective/${route}`)}> diff --git a/packages/app/src/components/DonateComponent.tsx b/packages/app/src/components/DonateComponent.tsx index 6d17bd2e..6ee177fc 100644 --- a/packages/app/src/components/DonateComponent.tsx +++ b/packages/app/src/components/DonateComponent.tsx @@ -1,27 +1,30 @@ import { useCallback, useMemo, useState } from 'react'; import { Image, StyleSheet, Text, TextInput, View } from 'react-native'; +import { Link } from 'native-base'; +import { useAccount, useNetwork } from 'wagmi'; +import { useParams } from 'react-router-native'; +import Decimal from 'decimal.js'; +import { waitForTransaction } from '@wagmi/core'; +import { TransactionReceipt } from 'viem'; + import { InterRegular, InterSemiBold, InterSmall } from '../utils/webFonts'; import RoundedButton from './RoundedButton'; import CompleteDonationModal from './modals/CompleteDonationModal'; import { Colors } from '../utils/colors'; -import { Link, useMediaQuery } from 'native-base'; +import { useScreenSize } from '../theme/hooks'; + import Dropdown from './Dropdown'; import { getDonateStyles, getFrequencyPlural } from '../utils'; import { useContractCalls, useGetTokenPrice } from '../hooks'; -import { useAccount, useNetwork } from 'wagmi'; import { Collective } from '../models/models'; import { useGetTokenBalance } from '../hooks/useGetTokenBalance'; import { acceptablePriceImpact, Frequency, frequencyOptions, GDEnvTokens, SupportedNetwork } from '../models/constants'; import { InfoIconOrange } from '../assets'; -import { useParams } from 'react-router-native'; -import Decimal from 'decimal.js'; import { formatFiatCurrency } from '../lib/formatFiatCurrency'; import ErrorModal from './modals/ErrorModal'; import { SwapRouteState, useSwapRoute } from '../hooks/useSwapRoute'; import { useApproveSwapTokenCallback } from '../hooks/useApproveSwapTokenCallback'; import ApproveSwapModal from './modals/ApproveSwapModal'; -import { waitForTransaction } from '@wagmi/core'; -import { TransactionReceipt } from 'viem'; import { useToken, useTokenList } from '../hooks/useTokenList'; import { formatDecimalStringInput } from '../lib/formatDecimalStringInput'; import ThankYouModal from './modals/ThankYouModal'; @@ -32,9 +35,7 @@ interface DonateComponentProps { } function DonateComponent({ collective }: DonateComponentProps) { - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); const { id: collectiveId = '0x' } = useParams(); const { address, isConnected } = useAccount(); @@ -212,12 +213,12 @@ function DonateComponent({ collective }: DonateComponentProps) { const onCloseErrorModal = () => setErrorMessage(undefined); return ( - + Donate Support {collective.ipfs.name}{' '} - {isDesktopResolution && ( + {isDesktopView && ( <>
@@ -227,7 +228,7 @@ function DonateComponent({ collective }: DonateComponentProps) {
- {!isDesktopResolution && ( + {!isDesktopView && ( <> Donation Currency: @@ -256,7 +257,7 @@ function DonateComponent({ collective }: DonateComponentProps) { )} - {isDesktopResolution && ( + {isDesktopView && ( @@ -289,7 +290,7 @@ function DonateComponent({ collective }: DonateComponentProps) { Donation Frequency - How often do you want to donate this {!isDesktopResolution &&
} amount? + How often do you want to donate this {!isDesktopView &&
} amount?
@@ -319,7 +320,7 @@ function DonateComponent({ collective }: DonateComponentProps) { <> - {!isDesktopResolution && ( + {!isDesktopView && ( <> {frequency !== 'One-Time' && ( @@ -495,7 +496,7 @@ function DonateComponent({ collective }: DonateComponentProps) { )} - - - {rowInfo} - - - - - {currency} {formattedDonations} - {isDesktopResolution && currency && = {donationsUsdValue} USD} - - {!isDesktopResolution && currency && = {donationsUsdValue} USD} - - - - ); -} - -const styles = StyleSheet.create({ - row: { - width: '100%', - backgroundColor: Colors.white, - flex: 1, - flexDirection: 'row', - alignItems: 'center', - }, - imageTitleRow: { - width: '100%', - flex: 1, - flexDirection: 'row', - alignItems: 'center', - }, - rowIcon: { - height: 28, - width: 28, - }, - rowInfo: { - marginLeft: 8, - maxWidth: '60%', - fontWeight: '700', - fontSize: 16, - color: Colors.black, - ...InterSemiBold, - }, - rightItem: { - position: 'relative', - alignSelf: 'flex-end', - }, - rowData: { - color: Colors.gray[100], - textAlign: 'right', - fontSize: 16, - ...InterSemiBold, - gap: 2, - }, - rowBalance: { - fontSize: 12, - textAlign: 'right', - color: Colors.gray[200], - ...InterRegular, - }, -}); - -export default FlowingDonationsRowItem; diff --git a/packages/app/src/components/FlowingDonationsRowItem.tsx b/packages/app/src/components/FlowingDonationsRowItem.tsx index 6d39c5e1..5880985d 100644 --- a/packages/app/src/components/FlowingDonationsRowItem.tsx +++ b/packages/app/src/components/FlowingDonationsRowItem.tsx @@ -1,12 +1,14 @@ import { Image, Text, View, StyleSheet } from 'react-native'; +import Decimal from 'decimal.js'; + import { InterRegular, InterSemiBold } from '../utils/webFonts'; import { Colors } from '../utils/colors'; -import { useMediaQuery } from 'native-base'; +import { useScreenSize } from '../theme/hooks'; + import { useDonorCollectivesFlowingBalancesWithAltStaticBalance } from '../hooks/useFlowingBalance'; import { DonorCollective } from '../models/models'; import { useGetTokenBalance } from '../hooks/useGetTokenBalance'; import { SupportedNetwork } from '../models/constants'; -import Decimal from 'decimal.js'; import { useTokenByAddress } from '../hooks/useTokenList'; import { GoodDollarAmount } from './GoodDollarAmount'; @@ -30,9 +32,7 @@ function FlowingDonationsRowItem({ additionalBalance, }: FlowingDonationsRowItemProps) { const token = useTokenByAddress(currency); - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); const currentBalance = useGetTokenBalance(currency, collective, SupportedNetwork.CELO); const balanceUsed = additionalBalance @@ -59,9 +59,9 @@ function FlowingDonationsRowItem({ lastDigitsProps={{ style: { ...InterRegular, color: Colors.gray[200], fontWeight: 400 } }} amount={wei || '0'} /> - {isDesktopResolution && currency && = {usdValueCurrentPool} USD} + {isDesktopView && currency && = {usdValueCurrentPool} USD} - {!isDesktopResolution && currency && = {usdValueCurrentPool} USD} + {!isDesktopView && currency && = {usdValueCurrentPool} USD}
diff --git a/packages/app/src/components/Header/ConnectWalletMenu.tsx b/packages/app/src/components/Header/ConnectWalletMenu.tsx index b303c61e..28f37c45 100644 --- a/packages/app/src/components/Header/ConnectWalletMenu.tsx +++ b/packages/app/src/components/Header/ConnectWalletMenu.tsx @@ -1,10 +1,11 @@ +import { useState } from 'react'; import { Image, StyleSheet, Text, TextStyle, TouchableOpacity, View } from 'react-native'; import { useConnect } from 'wagmi'; + import { Colors } from '../../utils/colors'; -import { useState } from 'react'; import { RotatingArrowIcon } from './RotatingArrowIcon'; import { MetaMaskLogo, WalletConnectLogo, WalletConnectLogoWhite, WebIcon } from '../../assets'; -import { useMediaQuery } from 'native-base'; +import { useScreenSize } from '../../theme/hooks'; const supportedConnectors = { metaMask: 'MetaMask', @@ -16,7 +17,7 @@ interface ConnectWalletMenuProps { } export const ConnectWalletMenu = (props: ConnectWalletMenuProps) => { - const [isDesktopResolution] = useMediaQuery({ minWidth: 920 }); + const { isDesktopView } = useScreenSize(); const { dropdownOffset } = props; const { connect, connectors, isLoading, pendingConnector } = useConnect(); @@ -34,7 +35,7 @@ export const ConnectWalletMenu = (props: ConnectWalletMenuProps) => { } const onClickConnectWallet = () => { - if (isDesktopResolution) { + if (isDesktopView) { setOpenDropdown(!openDropdown); } else { const connector = connectors.find((conn) => conn.name === supportedConnectors.walletConnect); @@ -47,13 +48,13 @@ export const ConnectWalletMenu = (props: ConnectWalletMenuProps) => { return ( <> - - {!isDesktopResolution && ( + + {!isDesktopView && ( )} Connect Wallet - {isDesktopResolution && } + {isDesktopView && } {openDropdown && ( diff --git a/packages/app/src/components/Header/Header.tsx b/packages/app/src/components/Header/Header.tsx index 13cdf1fa..c5eb1bbb 100644 --- a/packages/app/src/components/Header/Header.tsx +++ b/packages/app/src/components/Header/Header.tsx @@ -1,23 +1,23 @@ import { Image, StyleSheet, TouchableOpacity, View } from 'react-native'; -import { useMediaQuery } from 'native-base'; import { useAccount } from 'wagmi'; + import { ConnectedAccountDisplay } from './ConnectedAccountDisplay'; import { ConnectWalletMenu } from './ConnectWalletMenu'; import { DropdownMenu } from './DropdownMenu'; + import useCrossNavigate from '../../routes/useCrossNavigate'; import { Colors } from '../../utils/colors'; import { BackIcon, HeaderLogo } from '../../assets'; +import { useScreenSize } from '../../theme/hooks'; function Header(): JSX.Element { const { address } = useAccount(); - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); const { navigate } = useCrossNavigate(); return ( - {isDesktopResolution && ( + {isDesktopView && ( navigate('/')}> @@ -25,23 +25,23 @@ function Header(): JSX.Element { - {address && } + {address && } {!address && } )} - {!isDesktopResolution && ( + {!isDesktopView && ( - {address && } + {address && } {!address && } diff --git a/packages/app/src/components/ImpactButton.tsx b/packages/app/src/components/ImpactButton.tsx index 9155edea..35bcb017 100644 --- a/packages/app/src/components/ImpactButton.tsx +++ b/packages/app/src/components/ImpactButton.tsx @@ -1,8 +1,9 @@ import { Image, Text, TouchableOpacity, View, StyleSheet } from 'react-native'; + import { InterSemiBold } from '../utils/webFonts'; import { Colors } from '../utils/colors'; -import { useMediaQuery } from 'native-base'; import { chevronRight } from '../assets'; +import { useScreenSize } from '../theme/hooks'; interface ImpactButtonProps { title: string; @@ -10,13 +11,11 @@ interface ImpactButtonProps { } function ImpactButton({ title, onClick }: ImpactButtonProps) { - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); return ( - - + + {title} diff --git a/packages/app/src/components/Layout/Layout.tsx b/packages/app/src/components/Layout/Layout.tsx index 77dbd5e3..ac9e4d0f 100644 --- a/packages/app/src/components/Layout/Layout.tsx +++ b/packages/app/src/components/Layout/Layout.tsx @@ -1,15 +1,17 @@ import { ReactNode } from 'react'; -import Header from '../Header/Header'; import { Platform, ScrollView, StyleSheet, View } from 'react-native'; -import ImpactButton from '../ImpactButton'; import { useLocation } from 'react-router-native'; -import { Colors } from '../../utils/colors'; +import { useSafeAreaFrame } from 'react-native-safe-area-context'; import { useAccount } from 'wagmi'; -import { useMediaQuery } from 'native-base'; + +import ImpactButton from '../ImpactButton'; +import { Colors } from '../../utils/colors'; +import Header from '../Header/Header'; + +import { useScreenSize } from '../../theme/hooks'; import useCrossNavigate from '../../routes/useCrossNavigate'; import Breadcrumb, { BreadcrumbPathEntry } from './Breadcrumb'; import { DesktopPageContentContainer } from './DesktopPageContentContainer'; -import { useSafeAreaFrame } from 'react-native-safe-area-context'; interface LayoutProps { children: ReactNode; @@ -21,9 +23,7 @@ function Layout({ children, breadcrumbPath }: LayoutProps) { const scrollViewHeight = safeAreaHeight - 105; const { address } = useAccount(); - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); const location = useLocation(); const { navigate } = useCrossNavigate(); @@ -33,7 +33,7 @@ function Layout({ children, breadcrumbPath }: LayoutProps) { const bodyStyles = { ...styles.body, - backgroundColor: isDesktopResolution ? Colors.brown[200] : Colors.gray[400], + backgroundColor: isDesktopView ? Colors.brown[200] : Colors.gray[400], }; const scrollViewStyles = [ @@ -45,7 +45,7 @@ function Layout({ children, breadcrumbPath }: LayoutProps) { return (
- {isDesktopResolution ? ( + {isDesktopView ? ( {breadcrumbPath && } @@ -58,9 +58,7 @@ function Layout({ children, breadcrumbPath }: LayoutProps) { ) : ( {children} )} - {isCollectivePage && !isDesktopResolution && ( - - )} + {isCollectivePage && !isDesktopView && } ); } @@ -82,7 +80,7 @@ const styles = StyleSheet.create({ native: 'scroll', default: 'auto', }), - backgroundColor: 'defaultGrey', + backgroundColor: 'goodGrey.50', }, }); diff --git a/packages/app/src/components/RowItem.tsx b/packages/app/src/components/RowItem.tsx index 798d3fd1..1ef4713a 100644 --- a/packages/app/src/components/RowItem.tsx +++ b/packages/app/src/components/RowItem.tsx @@ -1,8 +1,10 @@ import { Image, Text, View, StyleSheet } from 'react-native'; + import { InterRegular, InterSemiBold } from '../utils/webFonts'; import { Colors } from '../utils/colors'; +import { useScreenSize } from '../theme/hooks'; + import { formatFiatCurrency } from '../lib/formatFiatCurrency'; -import { useMediaQuery } from 'native-base'; import { GoodDollarAmount } from './GoodDollarAmount'; interface RowItemProps { @@ -14,9 +16,7 @@ interface RowItemProps { } function RowItem({ rowInfo, rowData, balance, currency, imageUrl }: RowItemProps) { - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); const usdBalance = balance ? formatFiatCurrency(balance) : '0.00'; @@ -38,10 +38,10 @@ function RowItem({ rowInfo, rowData, balance, currency, imageUrl }: RowItemProps }} amount={String(rowData)} /> - {isDesktopResolution ? = {usdBalance} USD : null} + {isDesktopView ? = {usdBalance} USD : null} ) : null} - {!isDesktopResolution && currency ? = {usdBalance} USD : null} + {!isDesktopView && currency ? = {usdBalance} USD : null} ); diff --git a/packages/app/src/components/TransactionList/TransactionList.tsx b/packages/app/src/components/TransactionList/TransactionList.tsx index 9b556501..dfe28513 100644 --- a/packages/app/src/components/TransactionList/TransactionList.tsx +++ b/packages/app/src/components/TransactionList/TransactionList.tsx @@ -1,8 +1,11 @@ import { Image, Text, View, Platform, StyleSheet } from 'react-native'; +import { Link } from 'native-base'; + import { InterRegular, InterSemiBold } from '../../utils/webFonts'; import { Colors } from '../../utils/colors'; -import { Link, useMediaQuery } from 'native-base'; import { chevronDown, TransactionIcon } from '../../assets'; +import { useScreenSize } from '../../theme/hooks'; + import { ClaimTx, Transaction } from '../../models/models'; import { useRecentTransactions } from '../../hooks/useRecentTransactions'; import { isSupportTx } from '../../models/typeUtil'; @@ -16,9 +19,7 @@ interface TransactionListProps { } function TransactionList({ collective }: TransactionListProps) { - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); const transactions: Transaction[] = useRecentTransactions(collective, 6, SUBGRAPH_POLL_INTERVAL); @@ -29,7 +30,7 @@ function TransactionList({ collective }: TransactionListProps) { Recent Transactions - {isDesktopResolution && } + {isDesktopView && } {transactions .slice(0, 5) @@ -41,7 +42,7 @@ function TransactionList({ collective }: TransactionListProps) { ) )} - {isDesktopResolution && transactions.length > 5 && ( + {isDesktopView && transactions.length > 5 && ( Show more diff --git a/packages/app/src/components/ViewCollective.tsx b/packages/app/src/components/ViewCollective.tsx index 6ed9580a..ab3af162 100644 --- a/packages/app/src/components/ViewCollective.tsx +++ b/packages/app/src/components/ViewCollective.tsx @@ -1,5 +1,8 @@ import { StyleSheet, Text, View, Image } from 'react-native'; import { useState } from 'react'; +import { Link } from 'native-base'; +import { useAccount } from 'wagmi'; + import RowItem from './RowItem'; import RoundedButton from './RoundedButton'; import StewardList from './StewardsList/StewardsList'; @@ -7,12 +10,13 @@ import TransactionList from './TransactionList/TransactionList'; import { InterSemiBold, InterSmall } from '../utils/webFonts'; import useCrossNavigate from '../routes/useCrossNavigate'; import StopDonationModal from './modals/StopDonationModal'; + import { Colors } from '../utils/colors'; -import { Link, useMediaQuery } from 'native-base'; +import { useScreenSize } from '../theme/hooks'; + import { formatTime } from '../lib/formatTime'; import { Collective } from '../models/models'; import { useDonorCollectiveByAddresses, useGetTokenPrice } from '../hooks'; -import { useAccount } from 'wagmi'; import { AtIcon, CalendarIcon, @@ -43,9 +47,7 @@ interface ViewCollectiveProps { function ViewCollective({ collective }: ViewCollectiveProps) { const { navigate } = useCrossNavigate(); - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); const { address: poolAddress, @@ -58,7 +60,7 @@ function ViewCollective({ collective }: ViewCollectiveProps) { } = collective; // default to oceanUri if headerImage is undefined - const headerImg = { uri: ipfs.headerImage } ?? Ocean; + const headerImg = ipfs?.headerImage ? { uri: ipfs.headerImage } : Ocean; const stewardsPaid = stewardCollectives.length; const infoLabel = collective.ipfs.infoLabel ?? defaultInfoLabel; @@ -87,7 +89,7 @@ function ViewCollective({ collective }: ViewCollectiveProps) { 2 ); - if (isDesktopResolution) { + if (isDesktopView) { return ( @@ -132,7 +134,7 @@ function ViewCollective({ collective }: ViewCollectiveProps) { {isDonating ? ( - {!isDesktopResolution && ( + {!isDesktopView && ( <> You Support this GoodCollective!! diff --git a/packages/app/src/components/WalletCards/WalletCards.tsx b/packages/app/src/components/WalletCards/WalletCards.tsx index faa0a262..6a91aeed 100644 --- a/packages/app/src/components/WalletCards/WalletCards.tsx +++ b/packages/app/src/components/WalletCards/WalletCards.tsx @@ -1,10 +1,11 @@ +import React from 'react'; import { Donor, IpfsCollective, Steward } from '../../models/models'; -import { useMediaQuery } from 'native-base'; import { View } from 'react-native'; + import StewardCollectiveCard from './StewardCollectiveCard'; import DonorCollectiveCard from './DonorCollectiveCard'; -import React from 'react'; import { styles } from './styles'; +import { useScreenSize } from '../../theme/hooks'; interface WalletCardsProps { donor?: Donor; @@ -23,11 +24,9 @@ function WalletCards({ ensName, tokenPrice, }: WalletCardsProps) { - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); - const dynamicContainerStyle: Record = isDesktopResolution + const dynamicContainerStyle: Record = isDesktopView ? { marginTop: 0, flexDirection: 'row', @@ -50,7 +49,7 @@ function WalletCards({ ipfsCollective={stewardIpfsCollectives[i]} ensName={ensName ?? undefined} tokenPrice={tokenPrice} - isDesktopResolution={isDesktopResolution} + isDesktopResolution={isDesktopView} /> ))} {donor && @@ -62,7 +61,7 @@ function WalletCards({ ipfsCollective={donorIpfsCollectives[i]} ensName={ensName ?? undefined} tokenPrice={tokenPrice} - isDesktopResolution={isDesktopResolution} + isDesktopResolution={isDesktopView} /> ))} diff --git a/packages/app/src/components/WalletProfile.tsx b/packages/app/src/components/WalletProfile.tsx index d44116ba..c4cc6fb9 100644 --- a/packages/app/src/components/WalletProfile.tsx +++ b/packages/app/src/components/WalletProfile.tsx @@ -1,10 +1,12 @@ import React from 'react'; import { Image, StyleSheet, Text, View } from 'react-native'; + import { Colors } from '../utils/colors'; import { InterSemiBold, InterSmall } from '../utils/webFonts'; +import { useScreenSize } from '../theme/hooks'; + import ProfileView from './ProfileView'; import WalletDetails from './WalletDetails/WalletDetails'; -import { useMediaQuery } from 'native-base'; import { Donor, Steward } from '../models/models'; import { useCollectivesMetadataById, useGetTokenPrice } from '../hooks'; import { LightningIcon } from '../assets'; @@ -22,9 +24,7 @@ interface WalletProfileProps { } function WalletProfile({ address, ensName, firstName, lastName, donor, steward, isWhitelisted }: WalletProfileProps) { - const [isDesktopResolution] = useMediaQuery({ - minWidth: 920, - }); + const { isDesktopView } = useScreenSize(); const userIdentifier = firstName ? `${firstName} ${lastName}` @@ -44,7 +44,7 @@ function WalletProfile({ address, ensName, firstName, lastName, donor, steward, donor?.collectives.map((collective) => collective.collective) ?? [] ); - if (isDesktopResolution) { + if (isDesktopView) { return ( diff --git a/packages/app/src/components/theme.ts b/packages/app/src/components/theme.ts deleted file mode 100644 index f7fd1b6b..00000000 --- a/packages/app/src/components/theme.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { theme as AboutCard } from './AboutCard'; -export { theme as ActionButton } from './ActionButton'; diff --git a/packages/app/src/hooks/useTotalStats.ts b/packages/app/src/hooks/useTotalStats.ts index 9527c06a..278098ba 100644 --- a/packages/app/src/hooks/useTotalStats.ts +++ b/packages/app/src/hooks/useTotalStats.ts @@ -5,9 +5,8 @@ import { formatGoodDollarAmount } from '../lib/calculateGoodDollarAmounts'; type StatsFormatted = { amount: string; - copy: string; }; -type TotalStats = { +export type TotalStats = { totalDonations: StatsFormatted; totalPools: StatsFormatted; totalMembers: StatsFormatted; diff --git a/packages/app/src/pages/HomePage.tsx b/packages/app/src/pages/HomePage.tsx index e561c2e5..3aaa167b 100644 --- a/packages/app/src/pages/HomePage.tsx +++ b/packages/app/src/pages/HomePage.tsx @@ -1,8 +1,10 @@ -import { useRef } from 'react'; -import { useScreenSize, withTheme } from '@gooddollar/good-design'; +import { FC, PropsWithChildren, useRef } from 'react'; import { Box, HStack, ScrollView, Spinner, Text, useBreakpointValue, VStack } from 'native-base'; +import { Platform } from 'react-native'; import { useTotalStats } from '../hooks'; +import type { TotalStats } from '../hooks'; +import { useScreenSize } from '../theme/hooks'; import ActionButton from '../components/ActionButton'; import CollectiveHomeCard from '../components/CollectiveHomeCard'; @@ -11,59 +13,65 @@ import Layout from '../components/Layout/Layout'; import { IpfsCollective } from '../models/models'; import { useCollectivesMetadata } from '../hooks'; -type HomePageProps = { - buttonStyles?: any; - containerStyles?: any; +const homeContainerStyles = { + flex: 1, + paddingY: 5, + minHeight: 'auto', + marginLeft: 'auto', + marginRight: 'auto', + shadow: 1, + padding: 4, + width: '100%', + backgroundColor: 'white', + borderRadius: 16, + maxWidth: 1312, }; -export const theme = { - baseStyle: { - containerStyles: { - body: { - flex: 1, - paddingTop: 5, - paddingBottom: 5, - minHeight: 'auto', - marginLeft: 'auto', - marginRight: 'auto', - shadow: 1, - padding: 4, - width: '100%', - backgroundColor: 'white', - borderRadius: 16, - maxWidth: 1312, - }, - sectionContainer: { - marginBottom: 20, - paddingTop: 0, - paddingLeft: 15, - paddingRight: 15, - }, - }, - }, -}; - -const HomePage = withTheme({ name: 'HomePage' })(({ containerStyles }: HomePageProps) => { - const collectives = useCollectivesMetadata(); - const totalStats = useTotalStats(); - - const { body, sectionContainer } = containerStyles ?? {}; - const { isTabletView } = useScreenSize(); +const CollectivesContainer: FC = ({ children }) => { + const { isDesktopView } = useScreenSize(); + const collectiveStyles = { + marginBottom: 20, + paddingTop: 0, + }; - const collectivesContainer = useBreakpointValue({ + const container = useBreakpointValue({ base: { - ...sectionContainer, + ...collectiveStyles, }, - md: { - ...sectionContainer, + lg: { + ...collectiveStyles, flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center', alignItems: 'flex-start', - gap: 24, }, }); + return ( + + {children} + + ); +}; + +const statsCopy: { [K in keyof TotalStats]: { copy: string } } = { + totalPools: { + copy: 'GoodCollective pools', + }, + totalDonations: { + copy: 'Total Donations', + }, + totalMembers: { + copy: 'GoodCollective Members Paid', + }, +}; + +const HomePage = () => { + const collectives = useCollectivesMetadata(); + const totalStats = useTotalStats(); + + const { isDesktopView } = useScreenSize(); + const collectivesSectionRef = useRef(null); const scrollToCollectives = () => { @@ -72,99 +80,111 @@ const HomePage = withTheme({ name: 'HomePage' })(({ containerStyles }: HomePageP } }; - if (!totalStats) return ; + const stats = totalStats + ? Object.keys(statsCopy).map((keys) => { + const key = keys as keyof typeof totalStats; + return { + amount: totalStats[key].amount, + copy: statsCopy[key].copy, + }; + }) + : []; return ( - - - - - - Empower Communities. Maximize Impact. - - {`GoodCollective is committed to empowering -individuals and communities by providing direct digital payments to those who need it most.`} - - - - - Impact to Date + {!totalStats ? ( + + ) : ( + + + + + + Empower Communities. Maximize Impact. - - {Object.values(totalStats).map(({ amount, copy }) => ( - - - {amount} - - {copy} - - ))} - + {`GoodCollective is committed to empowering +individuals and communities by providing direct digital payments to those who need it most.`} - - - - - - - - + + + + Impact to Date + + + {Object.values(stats).map(({ amount, copy }) => ( + + + {amount} + + {copy} + + ))} + + + + + + + + + + + - - - - - + + + + + + + + Explore GoodCollective Pools + + {`Check out existing GoodCollective pools and support existing members, or start your own!`} + - - - Explore GoodCollective Pools - - {`Check out existing GoodCollective pools and support existing members, or start your own!`} - - - - {!collectives ? ( - Loading... - ) : ( - collectives?.map((ipfsCollective: IpfsCollective) => ( - - )) - )} + + {!collectives ? ( + Loading... + ) : ( + collectives?.map((ipfsCollective: IpfsCollective) => ( + + )) + )} + - - + + )} ); -}); +}; export default HomePage; diff --git a/packages/app/src/pages/ViewDonorsPage.tsx b/packages/app/src/pages/ViewDonorsPage.tsx index 496924ed..e3298256 100644 --- a/packages/app/src/pages/ViewDonorsPage.tsx +++ b/packages/app/src/pages/ViewDonorsPage.tsx @@ -1,22 +1,24 @@ +import React from 'react'; import { StyleSheet, Text, View, Image } from 'react-native'; +import { useParams } from 'react-router-native'; + import Layout from '../components/Layout/Layout'; import { InterSemiBold } from '../utils/webFonts'; import { Colors } from '../utils/colors'; import { DonorBlue, Ocean } from '../assets'; -import { useParams } from 'react-router-native'; +import { useScreenSize } from '../theme/hooks'; + import { useCollectiveById } from '../hooks'; -import React from 'react'; -import { useMediaQuery } from 'native-base'; import DonorList from '../components/DonorsList/DonorsList'; function ViewDonorsPage() { - const [isDesktopResolution] = useMediaQuery({ minWidth: 612 }); + const { isTabletView } = useScreenSize(); const { id: collectiveId = '' } = useParams(); const collective = useCollectiveById(collectiveId); const headerImage = collective?.ipfs.headerImage ? { uri: collective.ipfs.headerImage } : Ocean; - if (isDesktopResolution) { + if (isTabletView) { return ( { + const isDesktopView = useBreakpointValue({ base: false, lg: true }); + const isTabletView = useBreakpointValue({ base: false, md: true }); + const isSmallTabletView = useBreakpointValue({ base: true, sm: true, md: false }); + const isMobileView = useBreakpointValue({ base: true, sm: false }); + + return { isMobileView, isSmallTabletView, isTabletView, isDesktopView }; +}; + +export default useScreenSize; diff --git a/packages/app/src/theme/theme.ts b/packages/app/src/theme/theme.ts index 3b5640d7..3395a8ad 100644 --- a/packages/app/src/theme/theme.ts +++ b/packages/app/src/theme/theme.ts @@ -1,27 +1,24 @@ import { extendTheme } from 'native-base'; import { fontConfig, getPlatformFamilies } from '@gooddollar/good-design'; -import * as components from '../components/theme'; -import * as pages from '../pages/theme'; - export const nbTheme = extendTheme({ fontConfig: getPlatformFamilies(fontConfig), colors: { /* g$ design system */ - gdPrimary: '#00AFFF', + primary: '#00AEFF', primaryHoverDark: '#0075AC', white: '#FFFFFF', black: '#000000', - defaultGrey: '#F3F3F3', + // text goodGrey: { - 50: '#F4F4F4', - 100: '#E6E6E6', - 200: '#CCCCCC', - 300: '#B0B0B0', - 400: '#1F2937', - 500: '#5A5A5A', - 600: '#000000', + 50: '#F3F3F3', + 100: '#F4F4F4', + 200: '#E6E6E6', + 300: '#CCCCCC', + 400: '#B0B0B0', + 500: '#1F2937', + 600: '#5A5A5A', }, goodPurple: { 100: '#E2EAFF', @@ -56,8 +53,8 @@ export const nbTheme = extendTheme({ // custom keys for breakpoints cannot be used in useBreakpoint hook so we override defaults base: 0, sm: 375, - md: 720, - lg: 976, + md: 580, + lg: 920, xl: 1280, '2xl': 1440, }, @@ -79,13 +76,11 @@ export const nbTheme = extendTheme({ '4xl': 60, }, components: { - ...components, - ...pages, Spinner: { variants: { 'page-loader': () => ({ borderWidth: '0', - color: 'gdPrimary', + color: 'goodPurple.400', paddingBottom: 4, }), },