Skip to content

Commit

Permalink
feat(mobile): create db user after sign up (#60)
Browse files Browse the repository at this point in the history
Resolves #5
  • Loading branch information
bkdev98 committed Jun 9, 2024
1 parent 8ce8536 commit 048c90d
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 46 deletions.
2 changes: 1 addition & 1 deletion apps/api/v1/validation/user.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { z } from 'zod'
export const zCreateUser = z.object({
id: z.string().optional(),
email: z.string().email(),
name: z.string().min(3),
name: z.string().optional(),
})

export type CreateUser = z.infer<typeof zCreateUser>
15 changes: 2 additions & 13 deletions apps/mobile/app/(app)/(tabs)/explore.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
import { Avatar, AvatarFallback, AvatarImage } from '@/components/Avatar'
import { Button } from '@/components/Button'
import { getHonoClient } from '@/lib/client'
import { useMeQuery } from '@/queries/auth'
import { useAuth } from '@clerk/clerk-expo'
import { useQuery } from '@tanstack/react-query'
import { ScrollView, Text, View } from 'react-native'

export default function TabTwoScreen() {
const { signOut } = useAuth()
const { data } = useQuery({
queryKey: ['me'],
queryFn: async () => {
const hc = await getHonoClient()
const res = await hc.v1.auth.me.$get()
if (!res.ok) {
throw new Error(await res.text())
}
return await res.json()
},
})
const { data } = useMeQuery()

return (
<ScrollView contentContainerClassName="flex-1 p-4">
Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/app/(app)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ export default function AuthenticatedLayout() {

useEffect(() => {
if (isLoaded) {
SplashScreen.hideAsync()
setTimeout(() => SplashScreen.hideAsync(), 1000)
}
}, [isLoaded])

if (!isSignedIn) {
if (!isSignedIn && isLoaded) {
return <Redirect href={'/login'} />
}

Expand Down
3 changes: 1 addition & 2 deletions apps/mobile/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import {
BeVietnamPro_700Bold,
useFonts,
} from '@expo-google-fonts/be-vietnam-pro'
import { Stack } from 'expo-router'
import * as SplashScreen from 'expo-splash-screen'
import { SplashScreen, Stack } from 'expo-router'
import * as WebBrowser from "expo-web-browser";

import 'react-native-reanimated'
Expand Down
7 changes: 7 additions & 0 deletions apps/mobile/components/auth/auth-email.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { zodResolver } from '@hookform/resolvers/zod'
import { useState } from 'react'
import { View } from 'react-native'

import { useCreateUserMutation } from '@/mutations/user'
import { XCircleIcon } from 'lucide-react-native'
import { FormProvider, useForm } from 'react-hook-form'
import { IconButton } from '../IconButton'
Expand All @@ -27,6 +28,8 @@ export function AuthEmail() {
const [verifying, setVerifying] = useState(false)
const [mode, setMode] = useState<'signUp' | 'signIn'>('signUp')

const { mutateAsync: createUser } = useCreateUserMutation()

const {
isLoaded: isSignUpLoaded,
signUp,
Expand Down Expand Up @@ -92,6 +95,10 @@ export function AuthEmail() {
if (signUpAttempt.status === 'complete') {
await setActiveSignUp({ session: signUpAttempt.createdSessionId })
// signed up
await createUser({
email: signUpAttempt.emailAddress!,
name: signUpAttempt.firstName ?? '',
})
} else {
console.error(signUpAttempt)
}
Expand Down
49 changes: 21 additions & 28 deletions apps/mobile/components/auth/auth-social.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useCreateUserMutation } from '@/mutations/user'
import { useOAuth } from '@clerk/clerk-expo'
import type { SvgProps } from 'react-native-svg'
import { Button } from '../Button'
Expand All @@ -7,24 +8,25 @@ import { GoogleLogo } from '../svg-assets/google-logo'
type AuthSocialProps = {
label: string
icon: React.ComponentType<SvgProps>
onPress?: () => void
strategy: 'oauth_google' | 'oauth_apple'
}

export function AuthSocial({ label, icon: Icon, onPress }: AuthSocialProps) {
return (
<Button label={label} leftIcon={Icon} variant="outline" onPress={onPress} />
)
}

export function GoogleAuthButton() {
const { startOAuthFlow } = useOAuth({ strategy: 'oauth_google' })
export function AuthSocial({ label, icon: Icon, strategy }: AuthSocialProps) {
const { startOAuthFlow } = useOAuth({ strategy })
const { mutateAsync: createUser } = useCreateUserMutation()

const onPress = async () => {
try {
const { createdSessionId, setActive } = await startOAuthFlow()
const { createdSessionId, setActive, signUp } = await startOAuthFlow()

if (createdSessionId) {
setActive?.({ session: createdSessionId })
if (signUp?.createdUserId) {
setTimeout(async () => await createUser({
email: signUp.emailAddress!,
name: signUp.firstName ?? '',
}), 1000)
}
} else {
// Use signIn or signUp for next steps such as MFA
}
Expand All @@ -33,37 +35,28 @@ export function GoogleAuthButton() {
}
}

return (
<Button label={label} leftIcon={Icon} variant="outline" onPress={onPress} />
)
}

export function GoogleAuthButton() {

return (
<AuthSocial
label="Sign in with Google"
icon={GoogleLogo}
onPress={onPress}
strategy="oauth_google"
/>
)
}

export function AppleAuthButton() {
const { startOAuthFlow } = useOAuth({ strategy: 'oauth_apple' })

const onPress = async () => {
try {
const { createdSessionId, setActive } = await startOAuthFlow()

if (createdSessionId) {
setActive?.({ session: createdSessionId })
} else {
// Use signIn or signUp for next steps such as MFA
}
} catch (err) {
console.error('OAuth error', err)
}
}

return (
<AuthSocial
label="Sign in with Apple"
icon={AppleLogo}
onPress={onPress}
strategy="oauth_apple"
/>
)
}
14 changes: 14 additions & 0 deletions apps/mobile/mutations/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { getHonoClient } from '@/lib/client'
import type { CreateUser } from '@6pm/api'
import { useMutation } from '@tanstack/react-query'

export function useCreateUserMutation() {
return useMutation({
mutationFn: async (data: CreateUser) => {
const hc = await getHonoClient()
await hc.v1.users.$post({
json: data,
})
},
})
}
16 changes: 16 additions & 0 deletions apps/mobile/queries/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { getHonoClient } from '@/lib/client'
import { useQuery } from '@tanstack/react-query'

export function useMeQuery() {
return useQuery({
queryKey: ['me'],
queryFn: async () => {
const hc = await getHonoClient()
const res = await hc.v1.auth.me.$get()
if (!res.ok) {
throw new Error(await res.text())
}
return await res.json()
},
})
}

0 comments on commit 048c90d

Please sign in to comment.