diff --git a/apps/expo/package.json b/apps/expo/package.json index 332cf55a..320b44ca 100644 --- a/apps/expo/package.json +++ b/apps/expo/package.json @@ -21,6 +21,7 @@ "@react-native-community/datetimepicker": "7.6.1", "@react-native-picker/picker": "2.6.1", "@react-navigation/drawer": "^6.6.11", + "@rehookify/datepicker": "^6.6.1", "@shopify/flash-list": "1.6.3", "@tamagui/babel-plugin": "^1.94.4", "@tamagui/config": "^1.94.4", @@ -40,6 +41,7 @@ "expo-linear-gradient": "~12.7.2", "expo-linking": "~6.2.2", "expo-router": "~3.4.8", + "expo-secure-store": "^13.0.1", "expo-splash-screen": "~0.26.4", "expo-status-bar": "~1.11.1", "react": "18.2.0", diff --git a/apps/expo/src/app/_layout.tsx b/apps/expo/src/app/_layout.tsx index e9ebb11a..902dc1d0 100644 --- a/apps/expo/src/app/_layout.tsx +++ b/apps/expo/src/app/_layout.tsx @@ -1,12 +1,15 @@ import { config } from "@tamagui/config/v3"; +import { z } from "zod"; import "@tamagui/core/reset.css"; +import type { TokenCache } from "@clerk/clerk-expo/dist/cache"; import type { FontSource } from "expo-font"; import { useColorScheme } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { useFonts } from "expo-font"; import { Stack } from "expo-router"; +import * as SecureStore from "expo-secure-store"; import { StatusBar } from "expo-status-bar"; import { ClerkProvider } from "@clerk/clerk-expo"; import InterBold from "@tamagui/font-inter/otf/Inter-Bold.otf"; @@ -14,7 +17,8 @@ import Inter from "@tamagui/font-inter/otf/Inter-Medium.otf"; import { ToastProvider, ToastViewport } from "@tamagui/toast"; import { createTamagui, TamaguiProvider, Theme } from "tamagui"; -import { HamburgerMenu, Logo } from "~/components"; +import Logo from "~/components/Logo"; +import HamburgerMenu from "~/components/navigation/HamburgerMenu"; import { TRPCProvider } from "~/utils"; import { env } from "../utils/env"; @@ -23,6 +27,23 @@ import { env } from "../utils/env"; const tamaguiConfig = createTamagui(config); +const tokenCache: TokenCache = { + async getToken(key: string) { + try { + return SecureStore.getItemAsync(key); + } catch (err) { + return null; + } + }, + async saveToken(key: string, value: string) { + try { + await SecureStore.setItemAsync(key, value); + } catch (err) { + console.error(err); + } + }, +}; + export default function RootLayout() { const [loaded] = useFonts({ Inter: Inter as FontSource, @@ -39,7 +60,10 @@ export default function RootLayout() { return ( - + Auth; +import SignInWithOAuth from "~/components/auth/SignInWithOAuth"; + +export default function AuthPage() { + const auth = useAuth(); + console.log("is signed in", auth.isSignedIn); + return ( + + + You are Signed in + + + + + + ); } diff --git a/apps/expo/src/app/home/_components/dish-card.tsx b/apps/expo/src/app/home/_components/dish-card.tsx index 89052ac5..5999ceac 100644 --- a/apps/expo/src/app/home/_components/dish-card.tsx +++ b/apps/expo/src/app/home/_components/dish-card.tsx @@ -2,9 +2,9 @@ import { Link } from "expo-router"; import { StarFull } from "@tamagui/lucide-icons"; import { Image, ListItem, Text, XStack, YGroup, YStack } from "tamagui"; -import type { MenuWithRelations } from "@zotmeal/db"; -import { PinButton } from "~/components"; +import type { MenuWithRelations } from "@zotmeal/db"; +import { PinButton } from '~/components'; type Station = MenuWithRelations["stations"][0]; type Dish = MenuWithRelations["stations"][0]["dishes"][0]; diff --git a/apps/expo/src/app/home/index.tsx b/apps/expo/src/app/home/index.tsx index b162f9cc..9f92732c 100644 --- a/apps/expo/src/app/home/index.tsx +++ b/apps/expo/src/app/home/index.tsx @@ -13,12 +13,12 @@ import { restaurantNames, } from "@zotmeal/utils"; -import { RestaurantTabs } from "~/components"; import { useMenuStore } from "~/utils"; import { api } from "~/utils/api"; +import { EventToast } from "./_components/event-toast"; import { PeriodPicker } from "./_components/period-picker"; import { StationTabs } from "./_components/station-tabs"; -import { EventToast } from './_components/event-toast'; +import RestaurantTabs from '~/components/navigation/RestaurantTabs'; export function Home() { const { anteateryMenu, brandywineMenu, setAnteateryMenu, setBrandywineMenu } = diff --git a/apps/expo/src/components/PinButton.tsx b/apps/expo/src/components/PinButton.tsx index 0cb06513..5470967b 100644 --- a/apps/expo/src/components/PinButton.tsx +++ b/apps/expo/src/components/PinButton.tsx @@ -8,7 +8,7 @@ interface PinButtonProps extends GetProps { dishName: string; } -export default function PinButton({ dishName, ...props }: PinButtonProps) { +export function PinButton({ dishName, ...props }: PinButtonProps) { const [pinnedItems, setPinnedItems] = useState>({}); const { getItem, setItem } = useAsyncStorage("pinnedItems"); diff --git a/apps/expo/src/components/auth/SignInWithOAuth.tsx b/apps/expo/src/components/auth/SignInWithOAuth.tsx new file mode 100644 index 00000000..38948ba1 --- /dev/null +++ b/apps/expo/src/components/auth/SignInWithOAuth.tsx @@ -0,0 +1,34 @@ +import React from "react"; +import { Button } from "react-native"; +import * as WebBrowser from "expo-web-browser"; +import { useOAuth } from "@clerk/clerk-expo"; + +import { useWarmUpBrowser } from "~/hooks/useWarmUpBrowser"; + +WebBrowser.maybeCompleteAuthSession(); + +const SignInWithOAuth = () => { + // Warm up the android browser to improve UX + // https://docs.expo.dev/guides/authentication/#improving-user-experience + useWarmUpBrowser(); + + const { startOAuthFlow } = useOAuth({ strategy: "oauth_google" }); + + const onPress = React.useCallback(async () => { + try { + const { createdSessionId, signIn, signUp, setActive } = + await startOAuthFlow(); + + if (createdSessionId && setActive) { + await setActive({ session: createdSessionId }); // Await the setActive function call + } else { + // Use signIn or signUp for next steps such as MFA + } + } catch (err) { + console.error("OAuth error", err); + } + }, []); + + return