Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Apple SignIn integration to Medica App #165

Merged
merged 2 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"infoPlist": {
"NSFaceIDUsageDescription": "This app uses Face ID and Touch ID for some features"
},
"bundleIdentifier": "com.supabase.medical"
"bundleIdentifier": "com.andela.matadors.medica"
},
"android": {
"jsEngine": "hermes",
Expand Down
7 changes: 2 additions & 5 deletions app/(app)/ActionMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,8 @@ export default function Index() {
<Image
style={{ width: "100%", height: "100%", borderRadius: 100 }}
source={{
uri:
authType !== "email"
? authType
? otherAuthImageUrl
: `${CDNURL + userData?.id + "/" + profilePhoto}`
uri:authType !== "email" && authType !== "apple"
? otherAuthImageUrl
: `${CDNURL + userData?.id + "/" + profilePhoto}`,
}}
/>
Expand Down
11 changes: 5 additions & 6 deletions app/(app)/Profile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,11 @@ const index = () => {
<Image
style={{ width: "100%", height: "100%", borderRadius: 100 }}
source={{
uri:
authType !== "email"
? authType
? otherAuthImageUrl
: `${CDNURL + userData?.id + "/" + profilePhoto}`
: `${CDNURL + userData?.id + "/" + profilePhoto}`,
uri:authType !== "email" && authType !== "apple"
? otherAuthImageUrl
: `${CDNURL + userData?.id + "/" + profilePhoto}`,


}}
/>
</View>
Expand Down
19 changes: 17 additions & 2 deletions app/(auth)/SignIn&SignOut/LetsYouIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
TouchableOpacity,
ScrollView,
ActivityIndicator,
Alert,
} from "react-native";
import { supabase } from "@/lib/supabase";
import { ThemeContext } from "@/ctx/ThemeContext";
Expand All @@ -27,6 +28,8 @@ import { makeRedirectUri } from "expo-auth-session";
import * as QueryParams from "expo-auth-session/build/QueryParams";
import React from "react";
import { useAuth } from "@/ctx/AuthContext";
import * as AppleAuthentication from 'expo-apple-authentication';


WebBrowser.maybeCompleteAuthSession();
const redirectTo = makeRedirectUri({
Expand All @@ -45,6 +48,7 @@ const LetsYouIn = () => {
setImageUrl,
setAuthType,
} = useAuth();
const { signInWithApple } = useAuth();
const [loading, setLoading] = useState(false);
const createSessionFromUrl = async (url: string) => {
const { params, errorCode } = QueryParams.getQueryParams(url);
Expand Down Expand Up @@ -126,7 +130,18 @@ const LetsYouIn = () => {
}
};
const { theme } = useContext(ThemeContext);

const handleSignInWithApple = async () => {
setLoading(true);
try {
await signInWithApple();
router.push("/(app)/ActionMenu");
} catch (error) {
console.error('Error signing in with Apple:', error);
// Handle error (show alert, reset loading state, etc.)
} finally {
setLoading(false);
}
};
const url = Linking.useURL();
if (url) createSessionFromUrl(url);

Expand Down Expand Up @@ -212,7 +227,7 @@ const LetsYouIn = () => {
</Text>
</TouchableOpacity>

<TouchableOpacity
<TouchableOpacity onPress={signInWithApple}
style={[
styles.middleButton,
{
Expand Down
22 changes: 20 additions & 2 deletions app/(auth)/SignIn&SignOut/SignInBlankForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import * as Linking from "expo-linking";
import { makeRedirectUri } from "expo-auth-session";
import * as QueryParams from "expo-auth-session/build/QueryParams";
import { useAuth } from "@/ctx/AuthContext";
import * as AppleAuthentication from 'expo-apple-authentication';

WebBrowser.maybeCompleteAuthSession();
const redirectTo = makeRedirectUri({
Expand Down Expand Up @@ -87,10 +88,11 @@ AppState.addEventListener("change", (state) => {
});

const Login = () => {
const { signInWithApple } = useAuth();
const { login } = useAuth();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
// const [loading, setLoading] = useState(false)
const [loading, setLoading] = useState(false)
const [secureTextEntry, setSecureTextEntry] = useState(true);
const [isChecked, setIsChecked] = useState(false);
const [emailFocused, setEmailFocused] = useState(false);
Expand Down Expand Up @@ -135,6 +137,22 @@ const Login = () => {
}
}

const supabaseAuth = supabase.schema('auth');

const handleSignInWithApple = async () => {
setLoading(true);
try {
await signInWithApple();
router.push("/(app)/ActionMenu");
} catch (error) {
console.error('Error signing in with Apple:', error);
// Handle error (show alert, reset loading state, etc.)
} finally {
setLoading(false);
}
};


return (
<ScrollView
style={{
Expand Down Expand Up @@ -343,7 +361,7 @@ const Login = () => {
</View>
</TouchableOpacity>

<TouchableOpacity>
<TouchableOpacity onPress={signInWithApple}>
<View
style={[
styles.smallCont,
Expand Down
22 changes: 4 additions & 18 deletions app/(auth)/SignIn&SignOut/SignUpBlankForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ import { appleBlackIcon, appleWhiteIcon } from "@/constants/icon";
import { supabase } from "@/lib/supabase";
import * as WebBrowser from "expo-web-browser";
import * as Linking from "expo-linking";
import { makeRedirectUri } from "expo-auth-session";
import { makeRedirectUri , useAuthRequest} from "expo-auth-session";
import * as QueryParams from "expo-auth-session/build/QueryParams";
import { useAuth } from "@/ctx/AuthContext";
import { ActivityIndicator } from "react-native";
import { Auth } from "@/components/AppleAuth";


WebBrowser.maybeCompleteAuthSession();
const redirectTo = makeRedirectUri({
Expand Down Expand Up @@ -331,23 +333,7 @@ export default function Signup() {
</View>
</TouchableOpacity>

<TouchableOpacity>
<View
style={[
styles.smallCont,
{
backgroundColor: theme === "dark" ? "#1F222A" : "#FFFFFF",
borderColor: theme === "dark" ? "#35383F" : "#EEEEEE",
},
{
backgroundColor: theme === "dark" ? "#1F222A" : "#FFFFFF",
borderColor: theme === "dark" ? "#35383F" : "#EEEEEE",
},
]}
>
<SvgXml xml={theme === "dark" ? appleWhiteIcon : appleBlackIcon} />
</View>
</TouchableOpacity>
<Auth />
</View>

<View style={{ gap: 3, flexDirection: "row" }}>
Expand Down
35 changes: 18 additions & 17 deletions app/(auth)/SignIn&SignOut/YourProfile/[email].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,24 @@ const YourProfile = () => {
});
}

console.log(formData.lastName);

async function handleSubmit() {
try {
setIsLoading(true);
await setUpUserInfo(
authType !== "email"
? authType

authType !== "email" && authType !== "apple"
? authType && authType !== "apple"
? {
...formData,
firstName: String(name).split(" ")[0],
lastName: String(name).split(" ")[1],
imageUrl: { uri: imageUrl, mimeType: "image/jpeg" },
}
...formData,
firstName: String(name).split(" ")[0],
lastName: String(name).split(" ")[1],
imageUrl: { uri: imageUrl, mimeType: "image/jpeg" },
}
: formData
: formData
);
)
} catch (err) {
setIsLoading(false);
const error: Error = err as Error;
Expand Down Expand Up @@ -95,10 +98,8 @@ const YourProfile = () => {
<View>
<SelectProfile
image={
authType
? authType
? { uri: imageUrl, mimeType: "image/jpeg" }
: formData
authType && authType !== "apple"
? { uri: imageUrl, mimeType: "image/jpeg" }
: formData.image
}
onChange={handleFormChange}
Expand All @@ -120,8 +121,8 @@ const YourProfile = () => {
placeholder="First Name"
name="firstName"
value={
authType !== "email"
? authType
authType !== "email" && authType !== "apple"
? authType || authType !== "apple"
? String(name).split(" ")[0]
: formData.firstName
: formData.firstName
Expand All @@ -132,8 +133,8 @@ const YourProfile = () => {
placeholder="Last Name"
name="lastName"
value={
authType !== "email"
? authType
authType !== "email" && authType !== "apple"
? authType || authType !== "apple"
? String(name).split(" ")[1]
: formData.lastName
: formData.lastName
Expand Down Expand Up @@ -227,7 +228,7 @@ const YourProfile = () => {
searchPlaceholder="Search..."
renderInputSearch={() => <></>}
value={formData.gender}
onChangeText={(e) => {}}
onChangeText={(e) => { }}
/>
</View>

Expand Down
85 changes: 85 additions & 0 deletions components/AppleAuth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Platform, Alert, View, TouchableOpacity, StyleSheet } from 'react-native';
import * as AppleAuthentication from 'expo-apple-authentication';
import { supabase } from '../lib/supabase';
import React, { useContext,useState } from 'react';
import { SvgXml } from 'react-native-svg';
import { router } from 'expo-router';
import { ThemeContext } from '@/ctx/ThemeContext';
import { BlackApple, WhiteApple } from '@/components/Icons/Icons';
import { makeRedirectUri, useAuthRequest } from 'expo-auth-session';
import * as WebBrowser from 'expo-web-browser';
import * as QueryParams from "expo-auth-session/build/QueryParams";
import { useAuth } from "@/ctx/AuthContext";

export function Auth() {
const { theme } = useContext(ThemeContext);

WebBrowser.maybeCompleteAuthSession();
const redirectTo = makeRedirectUri({
native: "com.medica://",
});
console.log({ redirectTo });

const createSessionFromUrl = async (url: string) => {
const { params, errorCode } = QueryParams.getQueryParams(url);

if (errorCode) throw new Error(errorCode);
const { access_token, refresh_token } = params;

if (!access_token) return;

const { data, error } = await supabase.auth.setSession({
access_token,
refresh_token,
});
if (error) throw error;
console.log("session", data.session);
return data.session;
};
const [loading, setLoading] = useState(false)
const { signInWithApple } = useAuth();

const handleSignInWithApple = async () => {
setLoading(true);
try {
await signInWithApple();
// Navigate to next screen upon successful sign-in if needed
router.push("/(app)/ActionMenu");
} catch (error) {
console.error('Error signing in with Apple:', error);
// Handle error (show alert, reset loading state, etc.)
} finally {
setLoading(false);
}
};

if (Platform.OS === 'ios') {
return (
<TouchableOpacity onPress={signInWithApple}>
<View
style={[
styles.smallCont,
{ backgroundColor: theme === 'dark' ? '#1F222A' : '#FFFFFF', borderColor: theme === 'dark' ? '#35383F' : '#EEEEEE' },
]}
>
<SvgXml xml={theme === 'dark' ? WhiteApple : BlackApple} />
</View>
</TouchableOpacity>
);
}

return null;
}

const styles = StyleSheet.create({
smallCont: {
width: 80,
height: 60,
backgroundColor: '#FFFFFF',
borderColor: '#eeeeee',
borderWidth: 1,
borderRadius: 16,
justifyContent: 'center',
alignItems: 'center',
},
});
6 changes: 6 additions & 0 deletions constants/Colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ export default {
tabIconDefault: "#ccc",
input : "#EEEEEE"
},
dark: {
text: '#FFFFFF',
background: '#000000',
tabIconDefault: '#555',
input: '#333333',
},
};

export const Colors = {
Expand Down
1 change: 1 addition & 0 deletions constants/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface AuthType {
refreshSession: () => void;
logout: () => void;
login: ( email: string, password: string) => Promise<void>;
signInWithApple: () => Promise<void>;
}

export interface Countries extends TCountries {
Expand Down
Loading
Loading