From 69b9513a19e8d0aa280bae8ec7b91dd5e81de2fa Mon Sep 17 00:00:00 2001 From: "Alberto Duarte (PWC)" Date: Mon, 9 Oct 2023 17:31:33 +0100 Subject: Second commit --- .env | 4 +- .vscode/settings.json | 3 + android/gradlew.bat | 178 +++++++++--------- components/PreviewCard.tsx | 38 ++-- lib/requests.js | 20 +- screens/discover.js | 12 +- screens/home.js | 324 ++++++++++++++++----------------- screens/modal.js | 34 ++-- screens/passwordRecovery.js | 108 +++++------ screens/profile.js | 42 ++--- screens/signin.js | 356 ++++++++++++++++++------------------ screens/signup.js | 402 ++++++++++++++++++++--------------------- screens/topRated.js | 12 +- stacks/AuthNavigator.tsx | 72 ++++---- stacks/NavigatorHome.tsx | 152 ++++++++-------- static/images/netflix-logo.svg | 6 +- 16 files changed, 883 insertions(+), 880 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.env b/.env index f3a0248..ff3cfa7 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ -BASE_URL=https://api.themoviedb.org/3 -API_KEY=f247ff737ec8062f3b5e027789eab748 +BASE_URL=https://api.themoviedb.org/3 +API_KEY=f247ff737ec8062f3b5e027789eab748 IMG_ASSETS=https://image.tmdb.org/t/p/original \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8274afe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.compile.nullAnalysis.mode": "disabled" +} \ No newline at end of file diff --git a/android/gradlew.bat b/android/gradlew.bat index 107acd3..ac1b06f 100644 --- a/android/gradlew.bat +++ b/android/gradlew.bat @@ -1,89 +1,89 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/components/PreviewCard.tsx b/components/PreviewCard.tsx index 989ec34..5140fe2 100644 --- a/components/PreviewCard.tsx +++ b/components/PreviewCard.tsx @@ -1,20 +1,20 @@ -const imageURL = 'https://image.tmdb.org/t/p/original'; -import { ImageBackground, View } from "react-native"; -const baseURL ='https://api.themoviedb.org/3/' -import tw from 'twrnc'; - -const PreviewCard = ({ movie }) => { - return ( - - - - - - )} - - +const imageURL = 'https://image.tmdb.org/t/p/original'; +import { ImageBackground, View } from "react-native"; +const baseURL ='https://api.themoviedb.org/3/' +import tw from 'twrnc'; + +const PreviewCard = ({ movie }) => { + return ( + + + + + + )} + + export default PreviewCard \ No newline at end of file diff --git a/lib/requests.js b/lib/requests.js index 84c7664..965b2ee 100644 --- a/lib/requests.js +++ b/lib/requests.js @@ -1,10 +1,10 @@ -import {BASE_URL, API_KEY} from '@env'; -const apiKey = process.env.API_KEY; -const baseUrl = process.env.BASE_URL; -const requests = { - fetchTopRated: `${baseUrl}/movie/top_rated?api_key=${apiKey}&language=en`, - fetchTrendingMovies: `${baseUrl}/trending/movie/day?api_key=${apiKey}&language=en`, - fetchTrendingTv: `${baseUrl}/trending/tv/day?api_key=${apiKey}&language=en`, -}; - -export default requests; +import {BASE_URL, API_KEY} from '@env'; +const apiKey = process.env.API_KEY; +const baseUrl = process.env.BASE_URL; +const requests = { + fetchTopRated: `${baseUrl}/movie/top_rated?api_key=${apiKey}&language=en`, + fetchTrendingMovies: `${baseUrl}/trending/movie/day?api_key=${apiKey}&language=en`, + fetchTrendingTv: `${baseUrl}/trending/tv/day?api_key=${apiKey}&language=en`, +}; + +export default requests; diff --git a/screens/discover.js b/screens/discover.js index 0213eed..924308a 100644 --- a/screens/discover.js +++ b/screens/discover.js @@ -1,6 +1,6 @@ -import {Text} from 'react-native'; -const Discover = () => { - return Discover; -}; - -export default Discover; +import {Text} from 'react-native'; +const Discover = () => { + return Discover; +}; + +export default Discover; diff --git a/screens/home.js b/screens/home.js index 184bbf9..9d5addc 100644 --- a/screens/home.js +++ b/screens/home.js @@ -1,162 +1,162 @@ -import {useCallback, useEffect, useState} from 'react'; -import { - ImageBackground, - Platform, - Pressable, - SafeAreaView, - ScrollView, - Text, - TextInput, - View, -} from 'react-native'; -import tw from 'twrnc'; -import {useDeviceContext} from 'twrnc'; -import requests from '../lib/requests'; -import PreviewCard from '../components/PreviewCard'; -import Modal from './modal'; -//ICONS -import {TvIcon} from 'react-native-heroicons/outline'; -import {MagnifyingGlassIcon} from 'react-native-heroicons/outline'; -import {ChevronDownIcon} from 'react-native-heroicons/solid'; -import {UserIcon} from 'react-native-heroicons/outline'; -import ImageColors from 'react-native-image-colors'; -import LinearGradient from 'react-native-linear-gradient'; - -const Home = ({navigation}) => { - useDeviceContext(tw); - const imgAssets = process.env.IMG_ASSETS; - const [heroMovie, setHeroMovie] = useState(); - const [heroMovieColor, setHeroMovieColor] = useState(); - const [topRatedMovies, setTopRatedMovies] = useState(); - const [isModalVisible, setModalVisible] = useState(false); - const [modalContent, setModalContent] = useState(); - - const toggleModal = (movie) => { - setModalVisible(!isModalVisible); - setModalContent(movie); -}; - - useEffect(() => { - fetch(`https://api.themoviedb.org/3/movie/top_rated?api_key=f247ff737ec8062f3b5e027789eab748&language=en`) - .then(res => res.json()) - .then(data => { - setHeroMovie(data.results[1]); - setTopRatedMovies(data.results) - }); - }, []); - - useEffect(() => { - const fetchColor = async () => { - const data = await ImageColors.getColors( - `https://image.tmdb.org/t/p/original${heroMovie?.poster_path}`, - { - fallback: '#000000', - cache: true, - key: 'unique_key', - }, - ).then(data => { - if (Platform.OS === 'ios') { - setHeroMovieColor(data.primary); - } else { - setHeroMovieColor(data.average); - } - }); - } - if (heroMovie?.poster_path != undefined) { - fetchColor() - .catch(e => { - console.log(e) - return e - }); - } - }, [heroMovie]) - - return ( - - - - - For Matias - - - - - - - - - navigation.navigate('Profile')} - style={tw`rounded bg-white/20 w-6 h-6 flex items-center justify-center`} - > - - - - - - - TV Shows - - - Movies - - - Categories - - - - - - - {heroMovieColor !== undefined && ( - - )} - - Popular on Netflix - - { - topRatedMovies?.map((movie, index) => ( - toggleModal(movie)}> - - - ))} - - - {isModalVisible && ( - - )} - - - ); -}; - -export default Home; +import {useCallback, useEffect, useState} from 'react'; +import { + ImageBackground, + Platform, + Pressable, + SafeAreaView, + ScrollView, + Text, + TextInput, + View, +} from 'react-native'; +import tw from 'twrnc'; +import {useDeviceContext} from 'twrnc'; +import requests from '../lib/requests'; +import PreviewCard from '../components/PreviewCard'; +import Modal from './modal'; +//ICONS +import {TvIcon} from 'react-native-heroicons/outline'; +import {MagnifyingGlassIcon} from 'react-native-heroicons/outline'; +import {ChevronDownIcon} from 'react-native-heroicons/solid'; +import {UserIcon} from 'react-native-heroicons/outline'; +import ImageColors from 'react-native-image-colors'; +import LinearGradient from 'react-native-linear-gradient'; + +const Home = ({navigation}) => { + useDeviceContext(tw); + const imgAssets = process.env.IMG_ASSETS; + const [heroMovie, setHeroMovie] = useState(); + const [heroMovieColor, setHeroMovieColor] = useState(); + const [topRatedMovies, setTopRatedMovies] = useState(); + const [isModalVisible, setModalVisible] = useState(false); + const [modalContent, setModalContent] = useState(); + + const toggleModal = (movie) => { + setModalVisible(!isModalVisible); + setModalContent(movie); +}; + + useEffect(() => { + fetch(`https://api.themoviedb.org/3/movie/top_rated?api_key=f247ff737ec8062f3b5e027789eab748&language=en`) + .then(res => res.json()) + .then(data => { + setHeroMovie(data.results[1]); + setTopRatedMovies(data.results) + }); + }, []); + + useEffect(() => { + const fetchColor = async () => { + const data = await ImageColors.getColors( + `https://image.tmdb.org/t/p/original${heroMovie?.poster_path}`, + { + fallback: '#000000', + cache: true, + key: 'unique_key', + }, + ).then(data => { + if (Platform.OS === 'ios') { + setHeroMovieColor(data.primary); + } else { + setHeroMovieColor(data.average); + } + }); + } + if (heroMovie?.poster_path != undefined) { + fetchColor() + .catch(e => { + console.log(e) + return e + }); + } + }, [heroMovie]) + + return ( + + + + + For Matias + + + + + + + + + navigation.navigate('Profile')} + style={tw`rounded bg-white/20 w-6 h-6 flex items-center justify-center`} + > + + + + + + + TV Shows + + + Movies + + + Categories + + + + + + + {heroMovieColor !== undefined && ( + + )} + + Popular on Netflix + + { + topRatedMovies?.map((movie, index) => ( + toggleModal(movie)}> + + + ))} + + + {isModalVisible && ( + + )} + + + ); +}; + +export default Home; diff --git a/screens/modal.js b/screens/modal.js index 43181e4..1d51891 100644 --- a/screens/modal.js +++ b/screens/modal.js @@ -1,18 +1,18 @@ -import { Pressable, SafeAreaView, Text, View } from 'react-native'; -import tw from 'twrnc'; -import PreviewCard from '../components/PreviewCard'; - -const Modal = ({ closeModal, movie }) => { - return ( - - - {movie?.original_name || movie?.original_title} - - Dismiss - - - - ); -}; - +import { Pressable, SafeAreaView, Text, View } from 'react-native'; +import tw from 'twrnc'; +import PreviewCard from '../components/PreviewCard'; + +const Modal = ({ closeModal, movie }) => { + return ( + + + {movie?.original_name || movie?.original_title} + + Dismiss + + + + ); +}; + export default Modal; \ No newline at end of file diff --git a/screens/passwordRecovery.js b/screens/passwordRecovery.js index 61a5f10..94d00f2 100644 --- a/screens/passwordRecovery.js +++ b/screens/passwordRecovery.js @@ -1,54 +1,54 @@ -import { - Keyboard, - KeyboardAvoidingView, - Platform, - Pressable, - SafeAreaView, - Text, - TextInput, - TouchableWithoutFeedback, - View, -} from 'react-native'; - -import tw from 'twrnc'; - -import Logo from '../static/images/netflix-logo.svg'; - -const PasswordRecovery = ({navigation}) => { - return ( - - { - Keyboard.dismiss(); - }} - > - - - - - Recuperar contraseña - - - Recuperar contraseña - - navigation.goBack()} style={tw`mb-16`}> - Volver - - - - - - ); -}; - -export default PasswordRecovery; +import { + Keyboard, + KeyboardAvoidingView, + Platform, + Pressable, + SafeAreaView, + Text, + TextInput, + TouchableWithoutFeedback, + View, +} from 'react-native'; + +import tw from 'twrnc'; + +import Logo from '../static/images/netflix-logo.svg'; + +const PasswordRecovery = ({navigation}) => { + return ( + + { + Keyboard.dismiss(); + }} + > + + + + + Recuperar contraseña + + + Recuperar contraseña + + navigation.goBack()} style={tw`mb-16`}> + Volver + + + + + + ); +}; + +export default PasswordRecovery; diff --git a/screens/profile.js b/screens/profile.js index 0bd1cd9..53f71f0 100644 --- a/screens/profile.js +++ b/screens/profile.js @@ -1,21 +1,21 @@ -import React, { Component } from 'react'; -import { View, Text , Pressable} from 'react-native'; -import tw from 'twrnc' -import auth from '@react-native-firebase/auth'; - - -const Profile = () => { - return ( - - auth().signOut()} - > - Logout - - - ); -} - - -export default Profile; +import React, { Component } from 'react'; +import { View, Text , Pressable} from 'react-native'; +import tw from 'twrnc' +import auth from '@react-native-firebase/auth'; + + +const Profile = () => { + return ( + + auth().signOut()} + > + Logout + + + ); +} + + +export default Profile; diff --git a/screens/signin.js b/screens/signin.js index 49d328d..85a179e 100644 --- a/screens/signin.js +++ b/screens/signin.js @@ -1,178 +1,178 @@ -import {useEffect, useState} from 'react'; -import { - Image, - Keyboard, - KeyboardAvoidingView, - Platform, - Pressable, - SafeAreaView, - Text, - TextInput, - TouchableWithoutFeedback, - View, -} from 'react-native'; - -import tw from 'twrnc'; - -import {EyeIcon} from 'react-native-heroicons/outline'; -import {EyeSlashIcon} from 'react-native-heroicons/outline'; -import auth from '@react-native-firebase/auth'; - -const SignIn = ({navigation}) => { - - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); - const [isValidEmail, setIsValidEmail] = useState(false); - const [isValidPassword, setIsValidPassword] = useState(false); - const [isPasswordVisible, setIsPasswordVisible] = useState(true); - - useEffect(() => { - debounce(emailValidation()); - }, [email]); - - useEffect(() => { - debounce(passwordValidation()); - }, [password]); - - const emailValidation = () => { - const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; - if (!email || emailRegex.test(email) === false) { - setIsValidEmail(false); - return false; - } - setIsValidEmail(true); - return true; - }; - - const passwordValidation = () => { - const passwordRegex = /^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+])[A-Za-z\d!@#$%^&*()_+]{8,}$/i; - - - if (!password || passwordRegex.test(password) === false) { - setIsValidPassword(false) - return false - } - setIsValidPassword(true) - return true - } - - // Utility FN · Mover a carpeta utils/utils.js - const debounce = fn => { - let id = null; - - return (...args) => { - if (id) { - clearTimeout(id); - } - id = setTimeout(() => { - fn(...args); - id = null; - }, 300); - }; - }; - - const loginUser = () => { - if (isValidEmail && isValidPassword) { - auth() - .signInWithEmailAndPassword(email, password) - .then(() => { - console.log('User signed in successfully!'); - // Navigate to the home screen or other desired screen - }) - .catch(error => { - console.error(error); - // Display an error message to the user - }); - } -}; - - return ( - - { - Keyboard.dismiss(); - }} - > - - - - - - - ingresar - - { - setEmail(textInput); - }} - autoCapitalize={'none'} - keyboardType={'email-address'} - /> - - email incorrecto. - - - { - setIsPasswordVisible(!isPasswordVisible) - }} style={tw`absolute top-3 right-3 z-10`}> - {!isPasswordVisible? ( - - ) : ( - - )} - - { - setPassword(passwordInput) - }} - secureTextEntry={!isPasswordVisible} - /> - - - debe contener a-b-0-! - - - ingresar - - navigation.navigate('PasswordRecovery')} - style={tw`mb-16`} - > - ¿olvidaste tu contraseña? - - - ¿no tienes una cuenta? - navigation.navigate('SignUp')}> - registrate - - - - - - - ); -}; - -export default SignIn; +import {useEffect, useState} from 'react'; +import { + Image, + Keyboard, + KeyboardAvoidingView, + Platform, + Pressable, + SafeAreaView, + Text, + TextInput, + TouchableWithoutFeedback, + View, +} from 'react-native'; + +import tw from 'twrnc'; + +import {EyeIcon} from 'react-native-heroicons/outline'; +import {EyeSlashIcon} from 'react-native-heroicons/outline'; +import auth from '@react-native-firebase/auth'; + +const SignIn = ({navigation}) => { + + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [isValidEmail, setIsValidEmail] = useState(false); + const [isValidPassword, setIsValidPassword] = useState(false); + const [isPasswordVisible, setIsPasswordVisible] = useState(true); + + useEffect(() => { + debounce(emailValidation()); + }, [email]); + + useEffect(() => { + debounce(passwordValidation()); + }, [password]); + + const emailValidation = () => { + const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; + if (!email || emailRegex.test(email) === false) { + setIsValidEmail(false); + return false; + } + setIsValidEmail(true); + return true; + }; + + const passwordValidation = () => { + const passwordRegex = /^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+])[A-Za-z\d!@#$%^&*()_+]{8,}$/i; + + + if (!password || passwordRegex.test(password) === false) { + setIsValidPassword(false) + return false + } + setIsValidPassword(true) + return true + } + + // Utility FN · Mover a carpeta utils/utils.js + const debounce = fn => { + let id = null; + + return (...args) => { + if (id) { + clearTimeout(id); + } + id = setTimeout(() => { + fn(...args); + id = null; + }, 300); + }; + }; + + const loginUser = () => { + if (isValidEmail && isValidPassword) { + auth() + .signInWithEmailAndPassword(email, password) + .then(() => { + console.log('User signed in successfully!'); + // Navigate to the home screen or other desired screen + }) + .catch(error => { + console.error(error); + // Display an error message to the user + }); + } +}; + + return ( + + { + Keyboard.dismiss(); + }} + > + + + + + + + ingresar + + { + setEmail(textInput); + }} + autoCapitalize={'none'} + keyboardType={'email-address'} + /> + + email incorrecto. + + + { + setIsPasswordVisible(!isPasswordVisible) + }} style={tw`absolute top-3 right-3 z-10`}> + {!isPasswordVisible? ( + + ) : ( + + )} + + { + setPassword(passwordInput) + }} + secureTextEntry={!isPasswordVisible} + /> + + + debe contener a-b-0-! + + + ingresar + + navigation.navigate('PasswordRecovery')} + style={tw`mb-16`} + > + ¿olvidaste tu contraseña? + + + ¿no tienes una cuenta? + navigation.navigate('SignUp')}> + registrate + + + + + + + ); +}; + +export default SignIn; diff --git a/screens/signup.js b/screens/signup.js index 73edf4f..5f531d3 100644 --- a/screens/signup.js +++ b/screens/signup.js @@ -1,201 +1,201 @@ -import {useEffect, useState} from 'react'; -import { - Keyboard, - KeyboardAvoidingView, - Platform, - Pressable, - SafeAreaView, - Text, - TextInput, - TouchableWithoutFeedback, - View, -} from 'react-native'; - -import auth from '@react-native-firebase/auth'; -import tw from 'twrnc'; -import {useToast} from 'react-native-toast-notifications'; - -import Logo from '../static/images/netflix-logo.svg'; -import {EyeIcon} from 'react-native-heroicons/outline'; -import {EyeSlashIcon} from 'react-native-heroicons/outline'; - -const SignUp = ({navigation}) => { - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); - const [isValidEmail, setIsValidEmail] = useState(false); - const [isValidPassword, setIsValidPassword] = useState(false); - const [isPasswordVisible, setIsPasswordVisible] = useState(false); - - const toast = useToast(); - - useEffect(() => { - debounce(emailValidation()); - }, [email]); - - useEffect(() => { - debounce(passwordValidation()); - }, [password]); - - const emailValidation = () => { - const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; - if (!email || emailRegex.test(email) === false) { - setIsValidEmail(false); - return false; - } - setIsValidEmail(true); - return true; - }; - - const passwordValidation = () => { - const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/i; - if (!password || passwordRegex.test(password) === false) { - setIsValidPassword(false); - return false; - } - setIsValidPassword(true); - return true; - }; - - // Utility FN · Mover a carpeta utils/utils.js - const debounce = fn => { - let id = null; - - return (...args) => { - if (id) { - clearTimeout(id); - } - id = setTimeout(() => { - fn(...args); - id = null; - }, 300); - }; - }; - - const registerUser = () => { - if (isValidEmail && isValidPassword) { - auth() - .createUserWithEmailAndPassword(email, password) - .then(() => { - console.log('User account created & signed in!'); - }) - .catch(error => { - if (error.code === 'auth/email-already-in-use') { - console.log('That email address is already in use!'); - toast.show({ - type: 'info', - text1: 'Este email ya existe.', - text2: 'Por favor prueba un diferente.' - }); - toast.show('Este email ya existe', { - type: 'info', - data: { - subtitle: 'Por favor prueba uno diferente.', - }, - }); - console.log('hello') - return error - } - - if (error.code === 'auth/invalid-email') { - console.log('That email address is invalid!'); - return error - } - - console.error(error); - }); - } - }; - - return ( - - { - Keyboard.dismiss(); - }} - > - - - - - - Registrate - - { - setEmail(textInput); - }} - autoCorrect={false} - autoCapitalize={'none'} - keyboardType={'email-address'} - /> - - Email incorrecto. - - - { - setIsPasswordVisible(!isPasswordVisible); - }} - style={tw`absolute top-3 right-3 z-10`} - > - {!isPasswordVisible ? ( - - ) : ( - - )} - - { - setPassword(passwordInput); - }} - secureTextEntry={!isPasswordVisible} - /> - - - Debe contener A-b-0-! - - { - registerUser(); - }} - style={tw`mb-12`} - > - Registrate - - - ¿Ya tienes una cuenta? - navigation.navigate('SignIn')}> - Ingresa - - - - - - - ); -}; - -export default SignUp; +import {useEffect, useState} from 'react'; +import { + Keyboard, + KeyboardAvoidingView, + Platform, + Pressable, + SafeAreaView, + Text, + TextInput, + TouchableWithoutFeedback, + View, +} from 'react-native'; + +import auth from '@react-native-firebase/auth'; +import tw from 'twrnc'; +import {useToast} from 'react-native-toast-notifications'; + +import Logo from '../static/images/netflix-logo.svg'; +import {EyeIcon} from 'react-native-heroicons/outline'; +import {EyeSlashIcon} from 'react-native-heroicons/outline'; + +const SignUp = ({navigation}) => { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [isValidEmail, setIsValidEmail] = useState(false); + const [isValidPassword, setIsValidPassword] = useState(false); + const [isPasswordVisible, setIsPasswordVisible] = useState(false); + + const toast = useToast(); + + useEffect(() => { + debounce(emailValidation()); + }, [email]); + + useEffect(() => { + debounce(passwordValidation()); + }, [password]); + + const emailValidation = () => { + const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; + if (!email || emailRegex.test(email) === false) { + setIsValidEmail(false); + return false; + } + setIsValidEmail(true); + return true; + }; + + const passwordValidation = () => { + const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/i; + if (!password || passwordRegex.test(password) === false) { + setIsValidPassword(false); + return false; + } + setIsValidPassword(true); + return true; + }; + + // Utility FN · Mover a carpeta utils/utils.js + const debounce = fn => { + let id = null; + + return (...args) => { + if (id) { + clearTimeout(id); + } + id = setTimeout(() => { + fn(...args); + id = null; + }, 300); + }; + }; + + const registerUser = () => { + if (isValidEmail && isValidPassword) { + auth() + .createUserWithEmailAndPassword(email, password) + .then(() => { + console.log('User account created & signed in!'); + }) + .catch(error => { + if (error.code === 'auth/email-already-in-use') { + console.log('That email address is already in use!'); + toast.show({ + type: 'info', + text1: 'Este email ya existe.', + text2: 'Por favor prueba un diferente.' + }); + toast.show('Este email ya existe', { + type: 'info', + data: { + subtitle: 'Por favor prueba uno diferente.', + }, + }); + console.log('hello') + return error + } + + if (error.code === 'auth/invalid-email') { + console.log('That email address is invalid!'); + return error + } + + console.error(error); + }); + } + }; + + return ( + + { + Keyboard.dismiss(); + }} + > + + + + + + Registrate + + { + setEmail(textInput); + }} + autoCorrect={false} + autoCapitalize={'none'} + keyboardType={'email-address'} + /> + + Email incorrecto. + + + { + setIsPasswordVisible(!isPasswordVisible); + }} + style={tw`absolute top-3 right-3 z-10`} + > + {!isPasswordVisible ? ( + + ) : ( + + )} + + { + setPassword(passwordInput); + }} + secureTextEntry={!isPasswordVisible} + /> + + + Debe contener A-b-0-! + + { + registerUser(); + }} + style={tw`mb-12`} + > + Registrate + + + ¿Ya tienes una cuenta? + navigation.navigate('SignIn')}> + Ingresa + + + + + + + ); +}; + +export default SignUp; diff --git a/screens/topRated.js b/screens/topRated.js index e4685fe..9beae37 100644 --- a/screens/topRated.js +++ b/screens/topRated.js @@ -1,6 +1,6 @@ -import {Text} from 'react-native'; -const TopRated = () => { - return Top Rated; -}; - -export default TopRated; +import {Text} from 'react-native'; +const TopRated = () => { + return Top Rated; +}; + +export default TopRated; diff --git a/stacks/AuthNavigator.tsx b/stacks/AuthNavigator.tsx index b796bb7..90ec6a2 100644 --- a/stacks/AuthNavigator.tsx +++ b/stacks/AuthNavigator.tsx @@ -1,37 +1,37 @@ -import { createNativeStackNavigator } from "@react-navigation/native-stack"; -import SignIn from "../screens/signin"; -import SignUp from "../screens/signup"; -import PasswordRecovery from "../screens/passwordRecovery"; -import Modal from "../screens/modal"; - - const Stack = createNativeStackNavigator(); - -const AuthNavigator = () => { - return ( - - - - - - ); -}; - +import { createNativeStackNavigator } from "@react-navigation/native-stack"; +import SignIn from "../screens/signin"; +import SignUp from "../screens/signup"; +import PasswordRecovery from "../screens/passwordRecovery"; +import Modal from "../screens/modal"; + + const Stack = createNativeStackNavigator(); + +const AuthNavigator = () => { + return ( + + + + + + ); +}; + export default AuthNavigator; \ No newline at end of file diff --git a/stacks/NavigatorHome.tsx b/stacks/NavigatorHome.tsx index cb972ff..dda2b96 100644 --- a/stacks/NavigatorHome.tsx +++ b/stacks/NavigatorHome.tsx @@ -1,77 +1,77 @@ -import {HomeIcon} from 'react-native-heroicons/outline'; -import {StarIcon} from 'react-native-heroicons/outline'; -import {HomeIcon as HomeIconSolid} from 'react-native-heroicons/solid'; -import {StarIcon as StarIconSolid} from 'react-native-heroicons/solid'; -import {RocketLaunchIcon} from 'react-native-heroicons/outline'; -import {RocketLaunchIcon as RocketLaunchIconSolid} from 'react-native-heroicons/solid'; -import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; -import tw from 'twrnc'; -import Home from '../screens/home'; -import TopRated from '../screens/topRated'; -import Discover from '../screens/discover'; -import Modal from '../screens/modal'; - - const Tabs = createBottomTabNavigator(); - -const NavigatorHome = () => { - return ( - ({ - tabBarIcon: ({focused}) => { - if (route.name === 'Home') { - return focused ? ( - - ) : ( - - ); - } else if (route.name === 'TopRated') { - return focused ? ( - - ) : ( - - ); - } else if (route.name === 'Discover') { - return focused ? ( - - ) : ( - - ); - } - }, - tabBarStyle: { - backgroundColor: tw.color('gray-950'), - borderTopWidth: 0, - }, - tabBarLabelStyle: { - marginTop: -10, - marginBottom: 7, - }, - })} - > - - - - null }}/> - - ); -}; - +import {HomeIcon} from 'react-native-heroicons/outline'; +import {StarIcon} from 'react-native-heroicons/outline'; +import {HomeIcon as HomeIconSolid} from 'react-native-heroicons/solid'; +import {StarIcon as StarIconSolid} from 'react-native-heroicons/solid'; +import {RocketLaunchIcon} from 'react-native-heroicons/outline'; +import {RocketLaunchIcon as RocketLaunchIconSolid} from 'react-native-heroicons/solid'; +import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; +import tw from 'twrnc'; +import Home from '../screens/home'; +import TopRated from '../screens/topRated'; +import Discover from '../screens/discover'; +import Modal from '../screens/modal'; + + const Tabs = createBottomTabNavigator(); + +const NavigatorHome = () => { + return ( + ({ + tabBarIcon: ({focused}) => { + if (route.name === 'Home') { + return focused ? ( + + ) : ( + + ); + } else if (route.name === 'TopRated') { + return focused ? ( + + ) : ( + + ); + } else if (route.name === 'Discover') { + return focused ? ( + + ) : ( + + ); + } + }, + tabBarStyle: { + backgroundColor: tw.color('gray-950'), + borderTopWidth: 0, + }, + tabBarLabelStyle: { + marginTop: -10, + marginBottom: 7, + }, + })} + > + + + + null }}/> + + ); +}; + export default NavigatorHome; \ No newline at end of file diff --git a/static/images/netflix-logo.svg b/static/images/netflix-logo.svg index fa90ead..fa5c4c3 100644 --- a/static/images/netflix-logo.svg +++ b/static/images/netflix-logo.svg @@ -1,3 +1,3 @@ - - - + + + -- cgit v1.2.3-54-g00ecf