Files
waseel/components/oauth.tsx
T

108 lines
2.8 KiB
TypeScript

import * as Google from "expo-auth-session/providers/google";
import { router } from "expo-router";
import { useCallback, useEffect } from "react";
import { Image, Text, View, Alert } from "react-native";
import { icons } from "@/constants";
import { googleAuth } from "@/lib/auth";
import { useT } from "@/lib/i18n";
import { useSession } from "@/lib/session";
import { CustomButton } from "./custom-button";
type OAuthProps = {
title: string;
};
export const OAuth = ({ title }: OAuthProps) => {
const clientId = process.env.EXPO_PUBLIC_GOOGLE_AUTH_WEB_CLIENT_ID;
const iosClientId = process.env.EXPO_PUBLIC_GOOGLE_AUTH_IOS_CLIENT_ID;
const androidClientId =
process.env.EXPO_PUBLIC_GOOGLE_AUTH_ANDROID_CLIENT_ID;
const isConfigured = Boolean(
clientId && (androidClientId || iosClientId),
);
if (!isConfigured) return null;
return <GoogleOAuth title={title} clientId={clientId!} iosClientId={iosClientId} androidClientId={androidClientId} />;
};
function GoogleOAuth({
title,
clientId,
iosClientId,
androidClientId,
}: OAuthProps & {
clientId: string;
iosClientId?: string;
androidClientId?: string;
}) {
const { setSession } = useSession();
const t = useT();
const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
clientId,
iosClientId,
androidClientId,
});
useEffect(() => {
if (response?.type !== "success") return;
const idToken = response.params?.id_token;
if (!idToken) {
Alert.alert(t("components.oauth.alertFailTitle"), t("components.oauth.alertFailNoToken"));
return;
}
void (async () => {
try {
await setSession(await googleAuth(idToken));
router.replace("/");
} catch (err: any) {
console.error("OAuth error", err);
Alert.alert(
t("components.oauth.alertFailTitle"),
err?.message || t("components.oauth.alertFailFallback"),
);
}
})();
}, [response, setSession, t]);
const handleGoogleOAuth = useCallback(() => {
void promptAsync();
}, [promptAsync]);
return (
<View>
<View className="flex flex-row justify-center items-center mt-4 gap-x-3">
<View className="flex-1 h-px bg-general-100 dark:bg-neutral-700" />
<Text className="text-lg text-black dark:text-white">{t("components.oauth.or")}</Text>
<View className="flex-1 h-px bg-general-100 dark:bg-neutral-700" />
</View>
<CustomButton
title={title}
className="mt-5 w-full shadow-none"
iconLeft={() => (
<Image
source={icons.google}
alt={t("components.oauth.googleLogoAlt")}
resizeMode="contain"
className="h-5 w-5 mx-2"
/>
)}
bgVariant="outline"
textVariant="primary"
onPress={handleGoogleOAuth}
disabled={!request}
/>
</View>
);
}