diff --git a/app.json b/app.json index 6eaee96..4a73aff 100644 --- a/app.json +++ b/app.json @@ -62,7 +62,8 @@ "color": "#ffffff", "defaultChannel": "default" } - ] + ], + "expo-font" ], "experiments": { "typedRoutes": true diff --git a/app/(auth)/_layout.tsx b/app/(auth)/_layout.tsx index 2edbd97..714d3b4 100644 --- a/app/(auth)/_layout.tsx +++ b/app/(auth)/_layout.tsx @@ -43,7 +43,7 @@ export default function TabLayout() { return ( - Welcome to Cally + Welcome to Cally props.navigation.navigate("settings")} label={"Manage Settings"} + labelStyle={{fontFamily: "Manrope_500Medium"}} iconSource={() => ( signOut()} /> diff --git a/app/_layout.tsx b/app/_layout.tsx index 1b0128e..b4e3938 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,44 +1,207 @@ -import {DefaultTheme, ThemeProvider} from '@react-navigation/native'; -import {useFonts} from 'expo-font'; -import {Stack} from 'expo-router'; -import * as SplashScreen from 'expo-splash-screen'; -import {useEffect} from 'react'; -import 'react-native-reanimated'; -import {AuthContextProvider} from "@/contexts/AuthContext"; -import {QueryClient, QueryClientProvider} from "react-query"; -import {Toast} from "react-native-ui-lib"; +import React, { useEffect } from "react"; +import { DefaultTheme, ThemeProvider } from "@react-navigation/native"; +import { + useFonts, + Manrope_200ExtraLight, + Manrope_300Light, + Manrope_400Regular, + Manrope_500Medium, + Manrope_600SemiBold, + Manrope_700Bold, + Manrope_800ExtraBold, +} from "@expo-google-fonts/manrope"; +import { Stack } from "expo-router"; +import * as SplashScreen from "expo-splash-screen"; +import "react-native-reanimated"; +import { AuthContextProvider } from "@/contexts/AuthContext"; +import { QueryClient, QueryClientProvider } from "react-query"; +import { + ThemeManager, + Typography, + Toast, + TextProps, +} from "react-native-ui-lib"; +import functions from "@react-native-firebase/functions"; +import auth from "@react-native-firebase/auth"; +import firestore from "@react-native-firebase/firestore"; SplashScreen.preventAutoHideAsync(); const queryClient = new QueryClient(); +if (__DEV__) { + functions().useEmulator('localhost', 5001); + firestore().useEmulator("localhost", 5471); + auth().useEmulator("http://localhost:9099"); +} + +type TextStyleBase = + | "text10" + | "text20" + | "text30" + | "text40" + | "text50" + | "text60" + | "text70" + | "text80" + | "text90" + | "text100"; +type TextStyleModifier = "R" | "M" | "BO" | "H" | "BL" | "L"; +type TextStyle = TextStyleBase | `${TextStyleBase}${TextStyleModifier}`; + +type TextStyleProps = { + [K in TextStyle]?: boolean; +}; + +type ExtendedTextProps = TextProps & TextStyleProps; + +interface FontStyle { + fontFamily: string; + fontSize: number; +} + +const getManropeFontStyle = (style: TextStyle): FontStyle => { + let fontFamily: string; + let fontSize: number; + + if (style.includes("L") || style.includes("BL")) + fontFamily = "Manrope_300Light"; + else if (style.includes("R")) fontFamily = "Manrope_400Regular"; + else if (style.includes("M")) fontFamily = "Manrope_500Medium"; + else if (style.includes("BO") || style.includes("H")) + fontFamily = "Manrope_700Bold"; + else { + const baseStyle = style.slice(0, 6) as TextStyleBase; + switch (baseStyle) { + case "text10": + case "text20": + fontFamily = "Manrope_700Bold"; + break; + case "text30": + case "text40": + fontFamily = "Manrope_600SemiBold"; + break; + case "text50": + fontFamily = "Manrope_400Regular"; + break; + default: + fontFamily = "Manrope_300Light"; + } + } + + switch (style.slice(0, 6) as TextStyleBase) { + case "text10": + fontSize = 64; + break; + case "text20": + fontSize = 50; + break; + case "text30": + fontSize = 36; + break; + case "text40": + fontSize = 28; + break; + case "text50": + fontSize = 24; + break; + case "text60": + fontSize = 20; + break; + case "text70": + fontSize = 16; + break; + case "text80": + fontSize = 14; + break; + case "text90": + fontSize = 12; + break; + case "text100": + fontSize = 10; + break; + default: + fontSize = 16; + } + + return { fontFamily, fontSize }; +}; + export default function RootLayout() { - const [loaded] = useFonts({ - SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'), - }); + const [loaded] = useFonts({ + Manrope_200ExtraLight, + Manrope_300Light, + Manrope_400Regular, + Manrope_500Medium, + Manrope_600SemiBold, + Manrope_700Bold, + Manrope_800ExtraBold, + }); + + useEffect(() => { + if (loaded) { + SplashScreen.hideAsync(); + + const typographies: Partial> = {}; + ( + [ + "text10", + "text20", + "text30", + "text40", + "text50", + "text60", + "text70", + "text80", + "text90", + "text100", + ] as const + ).forEach((baseStyle) => { + typographies[baseStyle] = getManropeFontStyle(baseStyle); + (["R", "M", "BO", "H", "BL", "L"] as const).forEach((modifier) => { + const style = `${baseStyle}${modifier}` as TextStyle; + typographies[style] = getManropeFontStyle(style); + }); + }); - useEffect(() => { - if (loaded) { - SplashScreen.hideAsync(); + Typography.loadTypographies(typographies); + + ThemeManager.setComponentTheme( + "Text", + (props: ExtendedTextProps, context: unknown) => { + const textStyle = ( + Object.keys(props) as Array + ).find((key) => typographies[key as TextStyle]) as + | TextStyle + | undefined; + + return { + style: [ + Typography.text50, + textStyle ? typographies[textStyle] : undefined, + ], + }; } - }, [loaded]); + ); + } + }, [loaded]); - if (!loaded) { - return null; - } + if (!loaded) { + return null; + } - return ( - - - - - - - - - - - - - ); + return ( + + + + + + + + + + + + + ); } diff --git a/assets/fonts/Manrope-VariableFont_wght.ttf b/assets/fonts/Manrope-VariableFont_wght.ttf new file mode 100644 index 0000000..f39ca39 Binary files /dev/null and b/assets/fonts/Manrope-VariableFont_wght.ttf differ diff --git a/assets/images/child-picture.png b/assets/images/child-picture.png new file mode 100644 index 0000000..5669ec4 Binary files /dev/null and b/assets/images/child-picture.png differ diff --git a/assets/images/child1-picture.png b/assets/images/child1-picture.png new file mode 100644 index 0000000..09a5ba1 Binary files /dev/null and b/assets/images/child1-picture.png differ diff --git a/assets/images/profile-picture.png b/assets/images/profile-picture.png new file mode 100644 index 0000000..f36ba43 Binary files /dev/null and b/assets/images/profile-picture.png differ diff --git a/assets/svgs/FireworksOrangeIcon.tsx b/assets/svgs/FireworksOrangeIcon.tsx new file mode 100644 index 0000000..6600231 --- /dev/null +++ b/assets/svgs/FireworksOrangeIcon.tsx @@ -0,0 +1,21 @@ +import * as React from "react" +import Svg, { G, Path, Defs, ClipPath, SvgProps } from "react-native-svg" + +const FireworksOrangeIcon: React.FC = (props) => ( + + + + + + + + + + +) +export default FireworksOrangeIcon diff --git a/assets/svgs/GiftIcon.tsx b/assets/svgs/GiftIcon.tsx new file mode 100644 index 0000000..ee4be5d --- /dev/null +++ b/assets/svgs/GiftIcon.tsx @@ -0,0 +1,23 @@ +import * as React from "react"; +import Svg, { Path, SvgProps } from "react-native-svg"; +const GiftIcon: React.FC = (props) => ( + + + + + + +); +export default GiftIcon; diff --git a/components/pages/brain_dump/BrainDumpPage.tsx b/components/pages/brain_dump/BrainDumpPage.tsx index 111ea6d..071854e 100644 --- a/components/pages/brain_dump/BrainDumpPage.tsx +++ b/components/pages/brain_dump/BrainDumpPage.tsx @@ -54,21 +54,20 @@ const BrainDumpPage = () => { height: 40, borderRadius: 30, backgroundColor: "#fd1775", - alignItems: "center", - justifyContent: "center", }} - centerV color="white" enableShadow - iconSource={() => ( - - )} onPress={() => { setIsAddVisible(true); }} - label="New" - text60R - /> + > + + + + New + + + { padding-15 style={{ borderRadius: 20, elevation: 2 }} > - + {props.item.title} - {props.item.description} + {props.item.description} diff --git a/components/pages/brain_dump/DumpList.tsx b/components/pages/brain_dump/DumpList.tsx index 86453ae..8cd8efb 100644 --- a/components/pages/brain_dump/DumpList.tsx +++ b/components/pages/brain_dump/DumpList.tsx @@ -19,7 +19,7 @@ const DumpList = (props: { searchText: string }) => { ); return ( - + item.title} diff --git a/components/pages/calendar/AddEventDialog.tsx b/components/pages/calendar/AddEventDialog.tsx index 2731d95..0ef37a6 100644 --- a/components/pages/calendar/AddEventDialog.tsx +++ b/components/pages/calendar/AddEventDialog.tsx @@ -20,7 +20,6 @@ import AddChoreDialog from "../todos/AddChoreDialog"; import { ToDosContextProvider } from "@/contexts/ToDosContext"; import UploadImageDialog from "./UploadImageDialog"; - export const AddEventDialog = () => { const [show, setShow] = useState(false); const [showManualInputModal, setShowManualInputModal] = useState(false); @@ -37,127 +36,137 @@ export const AddEventDialog = () => { const handleScanImageDialog = () => { setShow(false); setTimeout(() => { - setShowUploadDialog(true); + setShowUploadDialog(true); }, 100); - } + }; return ( - - <> - - setShow(false)}> - Go back to calendar - - - - - setShowManualInputModal(false)} - /> - - + setShow(false)} + panDirection={PanningProvider.Directions.DOWN} + center + > + + Create a new event + + + + + setShowManualInputModal(false)} + /> + + ); }; diff --git a/components/pages/calendar/CalendarPage.tsx b/components/pages/calendar/CalendarPage.tsx index 457c969..b928bfa 100644 --- a/components/pages/calendar/CalendarPage.tsx +++ b/components/pages/calendar/CalendarPage.tsx @@ -41,6 +41,8 @@ export default function CalendarPage() { const styles = StyleSheet.create({ segmentslblStyle: { fontSize: 14, + fontFamily: 'Manrope', + fontWeight: 'bold' }, calHeader: { borderWidth: 0, @@ -89,7 +91,7 @@ export default function CalendarPage() { }; return ( - + { text70L iconSource={() => } style={styles.finishShopBtn} + labelStyle={styles.addBtnLbl} enableShadow - onPress={() => {setIsAddingGrocery(true)}} + onPress={() => { + setIsAddingGrocery(true); + }} /> @@ -89,4 +92,5 @@ const styles = StyleSheet.create({ flex: 1, marginHorizontal: 3, }, + addBtnLbl: { fontFamily: "Manrope_500Medium", fontSize: 17, marginLeft: 5 }, }); diff --git a/components/pages/grocery/GroceryList.tsx b/components/pages/grocery/GroceryList.tsx index fe87ee9..1743c4d 100644 --- a/components/pages/grocery/GroceryList.tsx +++ b/components/pages/grocery/GroceryList.tsx @@ -1,13 +1,17 @@ -import {FlatList, StyleSheet} from "react-native"; -import React, {useEffect, useState} from "react"; -import {Button, Text, View} from "react-native-ui-lib"; +import { FlatList, StyleSheet } from "react-native"; +import React, { useEffect, useState } from "react"; +import { Button, Text, TouchableOpacity, View } from "react-native-ui-lib"; import GroceryItem from "./GroceryItem"; -import {GroceryCategory, GroceryFrequency, useGroceryContext,} from "@/contexts/GroceryContext"; +import { + GroceryCategory, + GroceryFrequency, + useGroceryContext, +} from "@/contexts/GroceryContext"; import HeaderTemplate from "@/components/shared/HeaderTemplate"; -import {AntDesign, MaterialIcons} from "@expo/vector-icons"; +import { AntDesign, MaterialIcons } from "@expo/vector-icons"; import EditGroceryItem from "./EditGroceryItem"; -import {ProfileType, useAuthContext} from "@/contexts/AuthContext"; -import {IGrocery} from "@/hooks/firebase/types/groceryData"; +import { ProfileType, useAuthContext } from "@/contexts/AuthContext"; +import { IGrocery } from "@/hooks/firebase/types/groceryData"; const GroceryList = () => { const { @@ -81,20 +85,35 @@ const GroceryList = () => { message={"Welcome to your grocery list"} isWelcome={false} > - + - + {approvedGroceries?.length} list{" "} {approvedGroceries?.length === 1 ? ( - + item ) : ( - + items )} @@ -103,19 +122,21 @@ const GroceryList = () => { - + {pendingGroceries?.length} pending -