Merge branch 'fixesAfterMerge' of https://progit.zikor.pl/hamx/ArtisanConnectFrontend into fixesAfterMerge

This commit is contained in:
Patryk
2025-06-11 07:48:43 +02:00
4 changed files with 183 additions and 88 deletions

View File

@@ -1,5 +1,5 @@
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 {useRouter} from 'expo-router';
@@ -7,11 +7,11 @@ import {Box} from "@/components/ui/box"
import {Button, ButtonText, ButtonIcon} from "@/components/ui/button"
import {Center} from "@/components/ui/center"
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 {VStack} from "@/components/ui/vstack"
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 {Ionicons} from "@expo/vector-icons";
@@ -30,6 +30,8 @@ WebBrowser.maybeCompleteAuthSession();
export default function Login() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [emailError, setEmailError] = useState('');
const [showPassword, setShowPassword] = useState(false)
const {signIn, isLoading, signInWithGoogle} = useAuthStore();
const router = useRouter();
@@ -52,6 +54,11 @@ export default function Login() {
return;
}
if (!validateEmail(email)) {
setEmailError('Nieprawidłowy format adresu email');
return;
}
try {
await signIn(email, password);
alert(`Zalogowano jako ${email}`);
@@ -69,7 +76,7 @@ export default function Login() {
// const user = await AsyncStorage.getItem("@user");
let user = null;
if (!user) {
if(response.type === "success") {
if (response.type === "success") {
user = await getUserInfo(response.authentication.accessToken)
await signInWithGoogle(response.authentication.accessToken);
alert(`Zalogowano jako ${user.email}`);
@@ -83,7 +90,7 @@ export default function Login() {
};
const getUserInfo = async (token) => {
if(!token) {
if (!token) {
return
}
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) {
return (
<View style={styles.container}>
@@ -112,49 +130,70 @@ export default function Login() {
}
return (
<SafeAreaView style={styles.container}>
<Center>
<Box className="p-5 max-w-96 border border-background-300 rounded-lg">
<VStack className="pb-4" space="xs">
<Heading className="leading-[30px]">Logowanie</Heading>
<Box className="flex flex-row">
{/* <Link href="/registration" asChild> */}
<Button variant="link" size="sm" className="p-0" onPress={() => router.replace("/registration")}>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={{flex: 1}}
keyboardVerticalOffset={Platform.OS === "ios" ? 64 : 0}
>
<SafeAreaView style={styles.container}>
<Center>
<Box className="p-5 max-w-96 border border-background-300 rounded-lg">
<VStack className="pb-4" space="xs">
<Heading className="leading-[30px]">Logowanie</Heading>
<Box className="flex flex-row">
{/* <Link href="/registration" asChild> */}
<Button variant="link" size="sm" className="p-0"
onPress={() => router.replace("/registration")}>
<ButtonText style={styles.signupbutton}>Nie masz jeszcze konta? Załóz je
tutaj!</ButtonText>
<ButtonIcon className="mr-1" size="md" as={ArrowRightIcon}/>
</Button>
{/* </Link> */}
</Box>
</VStack>
<VStack space="xl" className="py-2">
<Input>
<InputField className="py-2" placeholder="Login" onChangeText={setEmail}/>
</Input>
<Input>
<InputField type="password" className="py-2" placeholder="Hasło"
onChangeText={setPassword}/>
</Input>
</VStack>
<VStack space="lg" className="pt-4">
<Button size="sm" onPress={handleInternalLogin}>
<ButtonText>Zaloguj się</ButtonText>
</Button>
</VStack>
{/* </Link> */}
</Box>
</VStack>
<VStack space="xl" className="py-2">
{emailError ? <Text style={styles.errorText}>{emailError}</Text> : null}
<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 isRequired={true}>
<InputField type={showPassword ? "text" : "password"} className="py-2"
placeholder="Hasło"
onChangeText={setPassword}/>
<InputSlot className="pr-3" onPress={handleShowPassword}>
<InputIcon as={showPassword ? EyeIcon : EyeOffIcon}/>
</InputSlot>
</Input>
</VStack>
<VStack space="lg" className="pt-4">
<Button size="sm" onPress={handleInternalLogin}>
<ButtonText>Zaloguj się</ButtonText>
</Button>
</VStack>
<HStack alignItems="center" space="sm" className="pt-6 pb-6">
<Divider flex={1}/>
<Text fontSize="$sm" className="text-gray-300">
lub
</Text>
<Divider flex={1}/>
</HStack>
<Button size="sm" onPress={() => promptAsync()}>
<Ionicons name="logo-google" color="#fff"/>
</Button>
</Box>
</Center>
</SafeAreaView>
<HStack alignItems="center" space="sm" className="pt-6 pb-6">
<Divider flex={1}/>
<Text fontSize="$sm" className="text-gray-300">
lub
</Text>
<Divider flex={1}/>
</HStack>
<Button size="sm" onPress={() => promptAsync()}>
<Ionicons name="logo-google" color="#fff"/>
</Button>
</Box>
</Center>
</SafeAreaView>
</KeyboardAvoidingView>
);
}
@@ -173,7 +212,7 @@ const styles = StyleSheet.create({
},
errorText: {
color: 'red',
marginBottom: 10,
fontSize: 12,
},
signupbutton: {
fontWeight: '300',

View File

@@ -391,6 +391,21 @@ export default function NoticeDetails() {
</Text>
</Text>
</Box>
{notice.attributes && notice.attributes.length > 0 && (
<Box className="mt-4 bg-gray-50 p-3 rounded-lg shadow-sm">
{notice.attributes.map((attribute, index) => (
<Text
key={index}
className="text-sm text-typography-500 mb-1"
>
{attribute.name}:{" "}
<Text className="font-bold text-gray-950">
{attribute.value}
</Text>
</Text>
))}
</Box>
)}
<Box className="mt-4 bg-gray-50 p-3 rounded-lg shadow-sm">
<Text className="text-2xl text-gray-950">Opis ogloszenia</Text>
<Text className="text-sm text-typography-700">

View File

@@ -1,22 +1,24 @@
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 {useRouter} from 'expo-router';
import {Box} from "@/components/ui/box"
import {Button, ButtonText,ButtonIcon} from "@/components/ui/button"
import {ArrowRightIcon} from "@/components/ui/icon"
import {Button, ButtonText, ButtonIcon} from "@/components/ui/button"
import {ArrowRightIcon, EyeIcon, EyeOffIcon} from "@/components/ui/icon"
import {Center} from "@/components/ui/center"
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 {Link} from "expo-router"
import {Text} from "@/components/ui/text";
export default function Registration() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [emailError, setEmailError] = useState('');
const [showPassword, setShowPassword] = useState(false)
const {signUp, isLoading} = useAuthStore();
const router = useRouter();
@@ -26,6 +28,11 @@ export default function Registration() {
return;
}
if (!validateEmail(email)) {
setEmailError('Nieprawidłowy format adresu email');
return;
}
try {
await signUp({email, password, firstName, lastName});
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) {
return (
<View style={styles.container}>
@@ -44,45 +62,66 @@ export default function Registration() {
}
return (
<SafeAreaView style={styles.container}>
<Center>
<Box className="p-5 w-[80%] border border-background-300 rounded-lg">
<VStack className="pb-4" space="xs">
<Heading className="leading-[30px]">Rejestracja</Heading>
<Box className="flex flex-row">
{/* <Link href="/login" asChild> */}
<Button variant="link" size="sm" className="p-0" onPress={() => router.replace("/login")}>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={{flex: 1}}
keyboardVerticalOffset={Platform.OS === "ios" ? 64 : 0}
>
<SafeAreaView style={styles.container}>
<Center>
<Box className="p-5 w-[80%] border border-background-300 rounded-lg">
<VStack className="pb-4" space="xs">
<Heading className="leading-[30px]">Rejestracja</Heading>
<Box className="flex flex-row">
{/* <Link href="/login" asChild> */}
<Button variant="link" size="sm" className="p-0"
onPress={() => router.replace("/login")}>
<ButtonText style={styles.signupbutton}>Masz już konto? Zaloguj się!</ButtonText>
<ButtonIcon className="mr-1" size="md" as={ArrowRightIcon}/>
</Button>
{/* </Link> */}
</Box>
</VStack>
<VStack space="xl" className="py-2">
<Input>
<InputField type="email" className="py-2" placeholder="E-mail" onChangeText={setEmail}/>
</Input>
<Input>
<InputField className="py-2" placeholder="Imię" onChangeText={setFirstName}/>
</Input>
<Input>
<InputField className="py-2" placeholder="Nazwisko" onChangeText={setLastName}/>
</Input>
<Input>
<InputField type="password" className="py-2" placeholder="Hasło"
onChangeText={setPassword}/>
</Input>
</VStack>
<VStack space="lg" className="pt-4">
<Button size="sm" onPress={handleInternalRegistration}>
<ButtonText>Zarejestruj się</ButtonText>
</Button>
</VStack>
</Box>
</Center>
</SafeAreaView>
{/* </Link> */}
</Box>
</VStack>
<VStack space="xl" className="py-2">
{emailError ? <Text className="m-0 color-red-600">{emailError}</Text> : null}
<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 isRequired={true}>
<InputField className="py-2" placeholder="Imię" onChangeText={setFirstName}/>
</Input>
<Input isRequired={true}>
<InputField className="py-2" placeholder="Nazwisko" onChangeText={setLastName}/>
</Input>
<Input isRequired={true}>
<InputField type={showPassword ? "text" : "password"} className="py-2"
placeholder="Hasło"
onChangeText={setPassword}/>
<InputSlot className="pr-3" onPress={handleShowPassword}>
<InputIcon as={showPassword ? EyeIcon : EyeOffIcon}/>
</InputSlot>
</Input>
</VStack>
<VStack space="lg" className="pt-4">
<Button size="sm" onPress={handleInternalRegistration}>
<ButtonText>Zarejestruj się</ButtonText>
</Button>
</VStack>
</Box>
</Center>
</SafeAreaView>
</KeyboardAvoidingView>
);
}
@@ -105,7 +144,7 @@ const styles = StyleSheet.create({
color: 'red',
marginBottom: 10,
},
signupbutton: {
signupbutton: {
fontWeight: '300',
textAlign: 'left',
},

View File

@@ -1,6 +1,6 @@
import { useLocalSearchParams, Stack } from "expo-router";
import { useState, useEffect } from "react";
import { FlatList, ActivityIndicator, Text } from "react-native";
import {FlatList, ActivityIndicator, Text, SafeAreaView} from "react-native";
import { Box } from "@/components/ui/box";
import { Image } from "@/components/ui/image";
import { VStack } from "@/components/ui/vstack";
@@ -44,6 +44,7 @@ export default function UserProfile() {
);
return (
<SafeAreaView className="flex-1" edges={['right', 'bottom', 'left']}>
<VStack className="p-4">
<Stack.Screen
options={{
@@ -54,7 +55,7 @@ export default function UserProfile() {
<Image
source={{
uri:
user.profileImage ||
user.image ||
"https://th.bing.com/th/id/OIP.3coo_N8sieled8QNroQmkgHaHa?rs=1&pid=ImgDetMain",
}}
className="h-16 w-16 rounded-full mr-4"
@@ -80,5 +81,6 @@ export default function UserProfile() {
<Text>Ten użytkownik nie ma żadnych ogłoszeń.</Text>
)}
</VStack>
</SafeAreaView>
);
}