diff --git a/apps/expo/app.config.ts b/apps/expo/app.config.ts index c732366..28972c6 100644 --- a/apps/expo/app.config.ts +++ b/apps/expo/app.config.ts @@ -2,8 +2,8 @@ import type { ConfigContext, ExpoConfig } from "@expo/config"; export default ({ config }: ConfigContext): ExpoConfig => ({ ...config, - name: "scribeHC", - slug: "scribehc", + name: "hyper", + slug: "hyper", scheme: "expo", version: "0.1.0", orientation: "portrait", @@ -19,7 +19,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ }, assetBundlePatterns: ["**/*"], ios: { - bundleIdentifier: "com.scribehc.app", + bundleIdentifier: "com.projecthyper.app", supportsTablet: true, usesAppleSignIn: true, config: { @@ -27,7 +27,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ }, }, android: { - package: "com.scribehc.app", + package: "com.projecthyper.app", adaptiveIcon: { foregroundImage: "./assets/icon.png", backgroundColor: "#18181A", @@ -47,10 +47,10 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ origin: false, }, eas: { - projectId: "bd3c6023-6da8-4e0d-8a0a-16c6eabd4cb7", + projectId: "914f340a-b357-48a8-8536-3c4b68dfcdad", }, }, - owner: "scribe-hc", + owner: "project-hyper", plugins: [ "expo-router", "expo-secure-store", @@ -78,5 +78,17 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ "Allow $(PRODUCT_NAME) to access your microphone.", }, ], + [ + "react-native-vision-camera", + { + cameraPermissionText: "$(PRODUCT_NAME) needs access to your Camera.", + + // optionally, if you want to record audio: + enableMicrophonePermission: true, + microphonePermissionText: + "$(PRODUCT_NAME) needs access to your Microphone.", + enableCodeScanner: true, + }, + ], ], }); diff --git a/apps/expo/package.json b/apps/expo/package.json index 19a8753..45a215c 100644 --- a/apps/expo/package.json +++ b/apps/expo/package.json @@ -33,6 +33,7 @@ "@react-navigation/drawer": "^6.7.2", "@react-navigation/native": "^6.1.18", "@shopify/flash-list": "1.7.0", + "@shopify/react-native-skia": "^1.3.9", "@supabase/auth-helpers-react": "catalog:supabase", "@supabase/supabase-js": "catalog:supabase", "@tanstack/react-query": "catalog:", @@ -75,6 +76,7 @@ "react-native": "~0.74.4", "react-native-avoid-softinput": "^5.0.0", "react-native-gesture-handler": "~2.18.0", + "react-native-graph": "^1.1.0", "react-native-ios-context-menu": "^2.5.1", "react-native-ios-utilities": "^4.4.5", "react-native-keyboard-controller": "^1.12.7", @@ -88,11 +90,13 @@ "react-native-screens": "~3.33.0", "react-native-svg": "15.4.0", "react-native-url-polyfill": "^2.0.0", + "react-native-vision-camera": "^4.5.1", "react-native-web": "~0.19.12", "superjson": "catalog:", "tailwind-merge": "^2.4.0", "tailwindcss": "catalog:tailwind", "tailwindcss-animate": "catalog:tailwind", + "victory-native": "^41.0.2", "zeego": "^1.10.0", "zustand": "^4.5.4" }, diff --git a/apps/expo/src/app/(auth)/reset-password.tsx b/apps/expo/src/app/(auth)/reset-password.tsx index 5cf42df..d3f6eec 100644 --- a/apps/expo/src/app/(auth)/reset-password.tsx +++ b/apps/expo/src/app/(auth)/reset-password.tsx @@ -1,11 +1,38 @@ -import React from "react"; +import { useState } from "react"; import { Keyboard, ScrollView, TouchableWithoutFeedback } from "react-native"; import { AvoidSoftInputView } from "react-native-avoid-softinput"; import { SafeAreaView } from "react-native-safe-area-context"; +import type { ResetPasswordFormProps } from "~/components/auth/reset-password-form"; import { ResetPasswordForm } from "~/components/auth/reset-password-form"; export default function ResetPasswordScreen() { + const { signIn } = useSignIn(); + const [successfulCreation, setSuccessfulCreation] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(""); + + const onSubmit: ResetPasswordFormProps["onSubmit"] = async (data) => { + setIsLoading(true); + try { + await signIn!.create({ + strategy: "reset_password_email_code", + identifier: data.email, + }); + setSuccessfulCreation(true); + setError(""); + } catch (err: unknown) { + setError(err.errors[0].message); + } finally { + setIsLoading(false); + } + }; + + const onVerificationSuccess = () => { + setSuccessfulCreation(false); + // Add any additional logic needed after successful verification + }; + return ( @@ -20,7 +47,13 @@ export default function ResetPasswordScreen() { showsVerticalScrollIndicator={true} className="flex-1 bg-secondary px-4 py-8" > - + diff --git a/apps/expo/src/app/(auth)/signup.tsx b/apps/expo/src/app/(auth)/signup.tsx index b2d23e0..f5ad917 100644 --- a/apps/expo/src/app/(auth)/signup.tsx +++ b/apps/expo/src/app/(auth)/signup.tsx @@ -19,22 +19,29 @@ export default function SignUpScreen() { const { isLoading: isLoadingSession } = useSessionContext(); const supabase = useSupabaseClient(); const [isLoading, setIsLoading] = useState(false); + const [pendingVerification, setPendingVerification] = useState(false); const onSubmit: SignUpFormProps["onSubmit"] = async (data) => { - if (isLoadingSession) { + if (!isLoaded) { return; } setIsLoading(true); try { - const { error } = await supabase.auth.signInWithPassword({ - email: data.email, + await signUp.create({ + emailAddress: data.email, password: data.password, }); - if (error) { - Alert.alert("Error", error.message); - } + console.log("signup create done"); + + // Send the email for verification + await signUp.prepareEmailAddressVerification({ strategy: "email_code" }); + + console.log("signup email sent"); + + // change the UI to our pending section + setPendingVerification(true); } catch (err: unknown) { console.error(JSON.stringify(err, null, 2)); } finally { diff --git a/apps/expo/src/components/auth/reset-password-form.tsx b/apps/expo/src/components/auth/reset-password-form.tsx index 9930608..ca7ede7 100644 --- a/apps/expo/src/components/auth/reset-password-form.tsx +++ b/apps/expo/src/components/auth/reset-password-form.tsx @@ -1,7 +1,6 @@ -import React, { useState } from "react"; +import type { SubmitHandler } from "react-hook-form"; import { View } from "react-native"; import Animated, { FadeInDown, FadeOutUp } from "react-native-reanimated"; -import { useSignIn } from "@clerk/clerk-expo"; import { zodResolver } from "@hookform/resolvers/zod"; import { Controller, FormProvider, useForm } from "react-hook-form"; @@ -16,11 +15,21 @@ import { Text } from "~/components/ui/text"; import { Loader2 } from "~/lib/icons/loader-2"; import { cn } from "~/lib/utils"; -const ResetPasswordForm = () => { - const { signIn } = useSignIn(); - const [successfulCreation, setSuccessfulCreation] = useState(false); - const [error, setError] = useState(""); +export interface ResetPasswordFormProps { + onSubmit: SubmitHandler; + isLoading: boolean; + error: string; + successfulCreation: boolean; + onVerificationSuccess: () => void; +} +const ResetPasswordForm: React.FC = ({ + onSubmit, + isLoading, + error, + successfulCreation, + onVerificationSuccess, +}) => { const form = useForm({ resolver: zodResolver(RequestPasswordResetSchema), defaultValues: { @@ -28,19 +37,6 @@ const ResetPasswordForm = () => { }, }); - const onSubmit = async (data: RequestPasswordReset) => { - try { - await signIn!.create({ - strategy: "reset_password_email_code", - identifier: data.email, - }); - setSuccessfulCreation(true); - setError(""); - } catch (err: unknown) { - setError(err.errors[0].message); - } - }; - return ( Reset Password @@ -88,9 +84,9 @@ const ResetPasswordForm = () => {