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

feat: enhance login screen with social login options #373

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2bda6c0
feat: implement user information component
kshitij79 Jan 30, 2025
ebdc526
fix(css): fixed css properties
kshitij79 Feb 2, 2025
231799c
fix: refactor account component for better modularity & testability
kshitij79 Feb 9, 2025
bcf806c
Merge pull request #347 from gamesover/chore/340/bump-expo-to-52
pierrelstan Feb 16, 2025
f9ba193
fix: refactor account component and added test components
kshitij79 Feb 16, 2025
1d91eff
Merge pull request #329 from kshitij79/feature/user-info-component
pierrelstan Feb 16, 2025
112c816
chore: add missing workspace scripts in package.json
pierrelstan Feb 19, 2025
b7adea3
Merge pull request #349 from Greenstand/chore/add-missing-scripts
pierrelstan Feb 20, 2025
b10fb6d
feat: add custom button
pierrelstan Feb 20, 2025
687bdeb
refactor: rename function, add slot
pierrelstan Feb 20, 2025
3c63f8c
fix: add onboarding
pierrelstan Feb 20, 2025
e37268d
fix: rename function, add verifyAppLayoutStatus
pierrelstan Feb 20, 2025
df766df
Merge pull request #351 from Greenstand/fix/onboarding-screen
pierrelstan Feb 20, 2025
b402f81
feat: add login screen textinput button title (#354)
pierrelstan Feb 21, 2025
fa00544
feat: refactor code for reusability and remove third party package
Agastya18 Feb 23, 2025
8e376cb
feat: update login screen styles and improve accessibility of social …
Agastya18 Feb 26, 2025
7bb6659
fix: reset head pointer two steps back
Agastya18 Mar 1, 2025
f2b2ffe
feat: add social button component
Agastya18 Feb 23, 2025
9c91257
Merge branch 'main' into login-page
pierrelstan Mar 2, 2025
1eb01c6
Merge branch 'login-page' of https://github.com/Agastya18/treetracker…
Agastya18 Mar 3, 2025
4923a11
feat: implement login functionality and add password reset link
Agastya18 Mar 3, 2025
ff8e6d5
fix: enhance login screen with social login options and improve passw…
Agastya18 Mar 3, 2025
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
166 changes: 164 additions & 2 deletions apps/native/app/(auth)/login.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,165 @@
import LoginScreen from "@/screens/auth/Login.screen";
import React, { useState } from "react";
import {
View,
StyleSheet,
KeyboardAvoidingView,
Platform,
TouchableOpacity,
Text,
ScrollView,
} from "react-native";
import SocialButton from "@/components/SocialButton";
import CustomTextInput from "@/components/ui/common/CustomTextInput";
import CustomTitle from "@/components/ui/common/CustomTitle";
import CustomSubmitButton from "@/components/ui/common/CustomSubmitButton";
import { useRouter } from "expo-router";

export default () => <LoginScreen />;
const LoginScreen = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const isLoginEnabled = email.length > 0 && password.length > 0;
console.log(isLoginEnabled);
const router = useRouter();

const handleLogIn = () => {};

return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.keyboardContainer}>
<ScrollView contentContainerStyle={styles.scrollContainer}>
<CustomTitle title="Log In" />
<CustomTextInput
label="Email"
placeholder="Enter your email"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
error={false}
/>

<CustomTextInput
label="Password"
placeholder="Enter your password"
secureTextEntry
value={password}
onChangeText={setPassword}
error={false}
/>

<View style={styles.buttonContainer}>
<CustomSubmitButton
title="log in"
onPress={handleLogIn}
disabled={isLoginEnabled}
style={
(isLoginEnabled ? styles.buttonActive : styles.buttonDisabled,
[{ textTransform: "uppercase" }])
}
/>
</View>

<View style={styles.forgotPasswordContainer}>
<Text style={styles.forgotPasswordText}>Forgot password? </Text>
<TouchableOpacity onPress={() => router.navigate("/(auth)/login")}>
<Text style={styles.resetText}>Reset</Text>
</TouchableOpacity>
</View>

<Text style={styles.orText}>or</Text>

<SocialButton
iconName="google"
title="LOG IN WITH GMAIL"
onPress={() => console.log("Gmail Login")}
/>

<SocialButton
iconName="facebook-square"
title="LOG IN WITH FACEBOOK"
onPress={() => console.log("Facebook Login")}
/>

<SocialButton
iconName="github"
title="LOG IN WITH GITHUB"
onPress={() => console.log("GitHub Login")}
/>

<View style={styles.signupContainer}>
<Text style={styles.signupText}>Don't have an account? </Text>
<TouchableOpacity>
<Text style={styles.signupLink}>Sign up</Text>
</TouchableOpacity>
</View>
</ScrollView>
</KeyboardAvoidingView>
);
};

const styles = StyleSheet.create({
container: {
backgroundColor: "white",
},
keyboardContainer: {
flex: 1,
},
scrollContainer: {
flex: 1,
justifyContent: "center",
paddingHorizontal: 20,
},

buttonContainer: {
paddingVertical: 13,
alignItems: "center",
},
buttonActive: {
backgroundColor: "#61892F",
paddingVertical: 15,
width: "100%",
alignItems: "center",
},
buttonDisabled: {
backgroundColor: "gray",
opacity: 0.5,
paddingVertical: 15,
width: "100%",
alignItems: "center",
},
buttonText: {
fontSize: 18,
fontWeight: "bold",
color: "white",
},
orText: {
textAlign: "center",
color: "#666",
marginVertical: 20,
},

signupContainer: {
flexDirection: "row",
justifyContent: "center",
marginTop: 20,
},
signupText: {
color: "#333",
},
signupLink: {
color: "#6B8E23",
},
forgotPasswordContainer: {
flexDirection: "row",
justifyContent: "center",
marginBottom: 20,
},
forgotPasswordText: {
color: "#333",
},
resetText: {
color: "#6B8E23",
},
});

export default LoginScreen;
70 changes: 7 additions & 63 deletions apps/native/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,14 @@
import FontAwesome from "@expo/vector-icons/FontAwesome";
import { useFonts } from "expo-font";
import { Stack } from "expo-router";
import { Slot } from "expo-router";
import * as SplashScreen from "expo-splash-screen";
import { useEffect } from "react";
import React, { useEffect } from "react";
import "react-native-reanimated";
import {
MD3LightTheme as DefaultTheme,
PaperProvider,
} from "react-native-paper";

import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
import { StyleSheet } from "react-native";

export { ErrorBoundary } from "expo-router";

const theme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
primary: "tomato",
secondary: "yellow",
},
};

SplashScreen.preventAutoHideAsync();

export default function RootLayout() {
const [loaded, error] = useFonts({
export default function AppLayout() {
const [areFontsLoaded, fontLoadError] = useFonts({
SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
Roboto: require("../assets/fonts/Roboto-Regular.ttf"),
RobotoBold: require("../assets/fonts/Roboto-Bold.ttf"),
Expand All @@ -35,48 +17,10 @@ export default function RootLayout() {
});

useEffect(() => {
if (error) throw error;
}, [error]);

useEffect(() => {
if (loaded) {
if (areFontsLoaded || fontLoadError) {
SplashScreen.hideAsync();
}
}, [loaded]);
}, [areFontsLoaded, fontLoadError]);

if (!loaded) {
return null;
}

return (
<SafeAreaProvider>
<SafeAreaView style={styles.container}>
<RootLayoutNav />
</SafeAreaView>
</SafeAreaProvider>
);
return <Slot />;
}

export const options = {
headerShown: false,
};

function RootLayoutNav() {
return (
<PaperProvider theme={theme}>
<Stack>
<Stack.Screen name="index" options={{ headerShown: false }} />
<Stack.Screen name="(tabs)" options={options} />
<Stack.Screen name="(auth)/login" options={{ headerShown: false }} />
<Stack.Screen name="(auth)/register" options={{ headerShown: false }} />
<Stack.Screen name="accountConfirmation" options={options} />
</Stack>
</PaperProvider>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
});
26 changes: 24 additions & 2 deletions apps/native/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,24 @@
import OnboardingScreen from "@/screens/onboarding/Onboarding.screen";
export default () => <OnboardingScreen />;
import React, { useEffect, useState } from "react";
import { Redirect, useRouter } from "expo-router";
import AsyncStorage from "@react-native-async-storage/async-storage";

export default function InitialRoute() {
const [shouldShowOnboarding, setShouldShowOnboarding] = useState(false);
const router = useRouter();

useEffect(() => {
const verifyAppLaunchStatus = async () => {
const hasCompletedOnboarding = await AsyncStorage.getItem("hasLaunched");

if (hasCompletedOnboarding === null) {
setShouldShowOnboarding(true);
} else {
router.replace("/(auth)/login");
}
};

verifyAppLaunchStatus();
}, [router]);

return shouldShowOnboarding ? <Redirect href="/onboarding" /> : null;
}
Loading