ekran autoryzacji przerobiony

This commit is contained in:
2025-06-10 21:39:52 +02:00
parent 56877548ed
commit 121d9d1e53
2 changed files with 164 additions and 86 deletions

View File

@@ -1,5 +1,5 @@
import React, {useEffect, useState} from 'react'; import React, {useEffect, useState} from 'react';
import {StyleSheet, ActivityIndicator, SafeAreaView, View, Platform} from 'react-native'; import {StyleSheet, ActivityIndicator, SafeAreaView, View, Platform, KeyboardAvoidingView} from 'react-native';
import {useAuthStore} from '@/store/authStore'; import {useAuthStore} from '@/store/authStore';
import {useRouter} from 'expo-router'; import {useRouter} from 'expo-router';
@@ -7,11 +7,11 @@ import {Box} from "@/components/ui/box"
import {Button, ButtonText, ButtonIcon} from "@/components/ui/button" import {Button, ButtonText, ButtonIcon} from "@/components/ui/button"
import {Center} from "@/components/ui/center" import {Center} from "@/components/ui/center"
import {Heading} from "@/components/ui/heading" import {Heading} from "@/components/ui/heading"
import {Input, InputField} from "@/components/ui/input" import {Input, InputField, InputIcon, InputSlot} from "@/components/ui/input"
import {Text} from "@/components/ui/text" import {Text} from "@/components/ui/text"
import {VStack} from "@/components/ui/vstack" import {VStack} from "@/components/ui/vstack"
import {HStack} from "@/components/ui/hstack" import {HStack} from "@/components/ui/hstack"
import {ArrowRightIcon} from "@/components/ui/icon" import {ArrowRightIcon, EyeIcon, EyeOffIcon} from "@/components/ui/icon"
import {Divider} from '@/components/ui/divider'; import {Divider} from '@/components/ui/divider';
import {Ionicons} from "@expo/vector-icons"; import {Ionicons} from "@expo/vector-icons";
@@ -30,6 +30,8 @@ WebBrowser.maybeCompleteAuthSession();
export default function Login() { export default function Login() {
const [email, setEmail] = useState(''); const [email, setEmail] = useState('');
const [password, setPassword] = useState(''); const [password, setPassword] = useState('');
const [emailError, setEmailError] = useState('');
const [showPassword, setShowPassword] = useState(false)
const {signIn, isLoading, signInWithGoogle} = useAuthStore(); const {signIn, isLoading, signInWithGoogle} = useAuthStore();
const router = useRouter(); const router = useRouter();
@@ -52,6 +54,11 @@ export default function Login() {
return; return;
} }
if (!validateEmail(email)) {
setEmailError('Nieprawidłowy format adresu email');
return;
}
try { try {
await signIn(email, password); await signIn(email, password);
alert(`Zalogowano jako ${email}`); alert(`Zalogowano jako ${email}`);
@@ -69,7 +76,7 @@ export default function Login() {
// const user = await AsyncStorage.getItem("@user"); // const user = await AsyncStorage.getItem("@user");
let user = null; let user = null;
if (!user) { if (!user) {
if(response.type === "success") { if (response.type === "success") {
user = await getUserInfo(response.authentication.accessToken) user = await getUserInfo(response.authentication.accessToken)
await signInWithGoogle(response.authentication.accessToken); await signInWithGoogle(response.authentication.accessToken);
alert(`Zalogowano jako ${user.email}`); alert(`Zalogowano jako ${user.email}`);
@@ -83,7 +90,7 @@ export default function Login() {
}; };
const getUserInfo = async (token) => { const getUserInfo = async (token) => {
if(!token) { if (!token) {
return return
} }
try { try {
@@ -103,6 +110,17 @@ export default function Login() {
} }
} }
const validateEmail = (email) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
const handleShowPassword = () => {
setShowPassword((showState) => {
return !showState
})
}
if (isLoading) { if (isLoading) {
return ( return (
<View style={styles.container}> <View style={styles.container}>
@@ -112,6 +130,11 @@ export default function Login() {
} }
return ( return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={{flex: 1}}
keyboardVerticalOffset={Platform.OS === "ios" ? 64 : 0}
>
<SafeAreaView style={styles.container}> <SafeAreaView style={styles.container}>
<Center> <Center>
<Box className="p-5 max-w-96 border border-background-300 rounded-lg"> <Box className="p-5 max-w-96 border border-background-300 rounded-lg">
@@ -119,7 +142,8 @@ export default function Login() {
<Heading className="leading-[30px]">Logowanie</Heading> <Heading className="leading-[30px]">Logowanie</Heading>
<Box className="flex flex-row"> <Box className="flex flex-row">
{/* <Link href="/registration" asChild> */} {/* <Link href="/registration" asChild> */}
<Button variant="link" size="sm" className="p-0" onPress={() => router.replace("/registration")}> <Button variant="link" size="sm" className="p-0"
onPress={() => router.replace("/registration")}>
<ButtonText style={styles.signupbutton}>Nie masz jeszcze konta? Załóz je <ButtonText style={styles.signupbutton}>Nie masz jeszcze konta? Załóz je
tutaj!</ButtonText> tutaj!</ButtonText>
<ButtonIcon className="mr-1" size="md" as={ArrowRightIcon}/> <ButtonIcon className="mr-1" size="md" as={ArrowRightIcon}/>
@@ -128,12 +152,26 @@ export default function Login() {
</Box> </Box>
</VStack> </VStack>
<VStack space="xl" className="py-2"> <VStack space="xl" className="py-2">
<Input> {emailError ? <Text style={styles.errorText}>{emailError}</Text> : null}
<InputField className="py-2" placeholder="Login" onChangeText={setEmail}/> <Input isRequired={true} isInvalid={!!emailError}>
<InputField className="py-2" inputMode="email" placeholder="Login"
onChangeText={(text) => {
setEmail(text);
if (text && !validateEmail(text)) {
setEmailError('Nieprawidłowy format adresu email');
} else {
setEmailError('');
}
}}
/>
</Input> </Input>
<Input> <Input isRequired={true}>
<InputField type="password" className="py-2" placeholder="Hasło" <InputField type={showPassword ? "text" : "password"} className="py-2"
placeholder="Hasło"
onChangeText={setPassword}/> onChangeText={setPassword}/>
<InputSlot className="pr-3" onPress={handleShowPassword}>
<InputIcon as={showPassword ? EyeIcon : EyeOffIcon}/>
</InputSlot>
</Input> </Input>
</VStack> </VStack>
<VStack space="lg" className="pt-4"> <VStack space="lg" className="pt-4">
@@ -155,6 +193,7 @@ export default function Login() {
</Box> </Box>
</Center> </Center>
</SafeAreaView> </SafeAreaView>
</KeyboardAvoidingView>
); );
} }
@@ -173,7 +212,7 @@ const styles = StyleSheet.create({
}, },
errorText: { errorText: {
color: 'red', color: 'red',
marginBottom: 10, fontSize: 12,
}, },
signupbutton: { signupbutton: {
fontWeight: '300', fontWeight: '300',

View File

@@ -1,22 +1,24 @@
import React, {useState} from 'react'; import React, {useState} from 'react';
import {StyleSheet, ActivityIndicator, SafeAreaView, View} from 'react-native'; import {StyleSheet, ActivityIndicator, SafeAreaView, View, Platform, KeyboardAvoidingView} from 'react-native';
import {useAuthStore} from '@/store/authStore'; import {useAuthStore} from '@/store/authStore';
import {useRouter} from 'expo-router'; import {useRouter} from 'expo-router';
import {Box} from "@/components/ui/box" import {Box} from "@/components/ui/box"
import {Button, ButtonText,ButtonIcon} from "@/components/ui/button" import {Button, ButtonText, ButtonIcon} from "@/components/ui/button"
import {ArrowRightIcon} from "@/components/ui/icon" import {ArrowRightIcon, EyeIcon, EyeOffIcon} from "@/components/ui/icon"
import {Center} from "@/components/ui/center" import {Center} from "@/components/ui/center"
import {Heading} from "@/components/ui/heading" import {Heading} from "@/components/ui/heading"
import {Input, InputField} from "@/components/ui/input" import {Input, InputField, InputIcon, InputSlot} from "@/components/ui/input"
import {VStack} from "@/components/ui/vstack" import {VStack} from "@/components/ui/vstack"
import {Link} from "expo-router" import {Text} from "@/components/ui/text";
export default function Registration() { export default function Registration() {
const [email, setEmail] = useState(''); const [email, setEmail] = useState('');
const [password, setPassword] = useState(''); const [password, setPassword] = useState('');
const [firstName, setFirstName] = useState(''); const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState(''); const [lastName, setLastName] = useState('');
const [emailError, setEmailError] = useState('');
const [showPassword, setShowPassword] = useState(false)
const {signUp, isLoading} = useAuthStore(); const {signUp, isLoading} = useAuthStore();
const router = useRouter(); const router = useRouter();
@@ -26,6 +28,11 @@ export default function Registration() {
return; return;
} }
if (!validateEmail(email)) {
setEmailError('Nieprawidłowy format adresu email');
return;
}
try { try {
await signUp({email, password, firstName, lastName}); await signUp({email, password, firstName, lastName});
alert(`Zalogowano jako ${email}`); alert(`Zalogowano jako ${email}`);
@@ -35,6 +42,17 @@ export default function Registration() {
} }
} }
const validateEmail = (email) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
const handleShowPassword = () => {
setShowPassword((showState) => {
return !showState
})
}
if (isLoading) { if (isLoading) {
return ( return (
<View style={styles.container}> <View style={styles.container}>
@@ -44,6 +62,11 @@ export default function Registration() {
} }
return ( return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={{flex: 1}}
keyboardVerticalOffset={Platform.OS === "ios" ? 64 : 0}
>
<SafeAreaView style={styles.container}> <SafeAreaView style={styles.container}>
<Center> <Center>
@@ -52,7 +75,8 @@ export default function Registration() {
<Heading className="leading-[30px]">Rejestracja</Heading> <Heading className="leading-[30px]">Rejestracja</Heading>
<Box className="flex flex-row"> <Box className="flex flex-row">
{/* <Link href="/login" asChild> */} {/* <Link href="/login" asChild> */}
<Button variant="link" size="sm" className="p-0" onPress={() => router.replace("/login")}> <Button variant="link" size="sm" className="p-0"
onPress={() => router.replace("/login")}>
<ButtonText style={styles.signupbutton}>Masz już konto? Zaloguj się!</ButtonText> <ButtonText style={styles.signupbutton}>Masz już konto? Zaloguj się!</ButtonText>
<ButtonIcon className="mr-1" size="md" as={ArrowRightIcon}/> <ButtonIcon className="mr-1" size="md" as={ArrowRightIcon}/>
</Button> </Button>
@@ -60,18 +84,32 @@ export default function Registration() {
</Box> </Box>
</VStack> </VStack>
<VStack space="xl" className="py-2"> <VStack space="xl" className="py-2">
<Input> {emailError ? <Text className="m-0 color-red-600">{emailError}</Text> : null}
<InputField type="email" className="py-2" placeholder="E-mail" onChangeText={setEmail}/> <Input isRequired={true}>
<InputField type="email" className="py-2" placeholder="E-mail"
onChangeText={(text) => {
setEmail(text);
if (text && !validateEmail(text)) {
setEmailError('Nieprawidłowy format adresu email');
} else {
setEmailError('');
}
}}
/>
</Input> </Input>
<Input> <Input isRequired={true}>
<InputField className="py-2" placeholder="Imię" onChangeText={setFirstName}/> <InputField className="py-2" placeholder="Imię" onChangeText={setFirstName}/>
</Input> </Input>
<Input> <Input isRequired={true}>
<InputField className="py-2" placeholder="Nazwisko" onChangeText={setLastName}/> <InputField className="py-2" placeholder="Nazwisko" onChangeText={setLastName}/>
</Input> </Input>
<Input> <Input isRequired={true}>
<InputField type="password" className="py-2" placeholder="Hasło" <InputField type={showPassword ? "text" : "password"} className="py-2"
placeholder="Hasło"
onChangeText={setPassword}/> onChangeText={setPassword}/>
<InputSlot className="pr-3" onPress={handleShowPassword}>
<InputIcon as={showPassword ? EyeIcon : EyeOffIcon}/>
</InputSlot>
</Input> </Input>
</VStack> </VStack>
<VStack space="lg" className="pt-4"> <VStack space="lg" className="pt-4">
@@ -83,6 +121,7 @@ export default function Registration() {
</Center> </Center>
</SafeAreaView> </SafeAreaView>
</KeyboardAvoidingView>
); );
} }