diff --git a/package.json b/package.json index 1d89e14..93e4f4c 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,8 @@ "htmlhint": "htmlhint dist/*.html ", "eslint": "eslint --ext .js src/ test/", "stylelint": "stylelint --aei src/**/*.css", - "pretest": "npm run htmlhint && npm run eslint && npm run stylelint", - "test": "jest --coverage", + "pretest": "npm run htmlhint && npm run stylelint", + "test": "jest --env=jsdom --coverage", "dev": "vite dev src", "start": "npm run dev", "build": "vite build", @@ -41,5 +41,8 @@ "createdAt": "2023-06-06T21:37:46.504Z", "version": "6.3.0", "commit": "a942adeb868f1fe54b86e34cc4fc4ddb0601700d" + }, + "dependencies": { + "firebase": "^10.0.0" } -} \ No newline at end of file +} diff --git a/src/Images/background.png b/src/Images/background.png new file mode 100644 index 0000000..623f209 Binary files /dev/null and b/src/Images/background.png differ diff --git a/src/Images/background_phone.png b/src/Images/background_phone.png new file mode 100644 index 0000000..2c33212 Binary files /dev/null and b/src/Images/background_phone.png differ diff --git a/src/Images/google.svg b/src/Images/google.svg new file mode 100644 index 0000000..2071a63 --- /dev/null +++ b/src/Images/google.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Images/icon.png b/src/Images/icon.png new file mode 100644 index 0000000..b2b297b Binary files /dev/null and b/src/Images/icon.png differ diff --git a/src/Images/planet.png b/src/Images/planet.png new file mode 100644 index 0000000..cca6746 Binary files /dev/null and b/src/Images/planet.png differ diff --git a/src/Images/space-purple.png b/src/Images/space-purple.png new file mode 100644 index 0000000..3dbc155 Binary files /dev/null and b/src/Images/space-purple.png differ diff --git a/src/Images/space-white.png b/src/Images/space-white.png new file mode 100644 index 0000000..95f78b9 Binary files /dev/null and b/src/Images/space-white.png differ diff --git a/src/components/feed.js b/src/components/feed.js new file mode 100644 index 0000000..3678101 --- /dev/null +++ b/src/components/feed.js @@ -0,0 +1,57 @@ +import { collection, doc, setDoc, addDoc, getDocs, onSnapshot, updateDoc, deleteDoc, Timestamp } from "firebase/firestore"; +import { db } from '../lib/firebase.js'; + +//let showFeed = getElementById('root') +export const feed = (onNavigate) => { + const homeDiv = document.createElement('div'); + homeDiv.className = 'container'; + const showFeed = + `
+ + +
+
+
+ icon planet +
+
+ + +
+
+
+
+
` + homeDiv.innerHTML = showFeed; + return homeDiv +} diff --git a/src/components/home.js b/src/components/home.js new file mode 100644 index 0000000..9241d9d --- /dev/null +++ b/src/components/home.js @@ -0,0 +1,21 @@ +export const home = (onNavigate) => { + const homeDiv = document.createElement('div'); + homeDiv.className = 'container'; + + const buttonDiv = document.createElement('div'); + buttonDiv.className = 'div-button'; + homeDiv.appendChild(buttonDiv); + + const buttonRegister = document.createElement('button'); + buttonRegister.textContent = 'Register'; + buttonRegister.className = 'button button-register'; + + const buttonLogin = document.createElement('button'); + buttonLogin.textContent = 'Login'; + buttonLogin.className = 'button button-login'; + buttonRegister.addEventListener('click', () => onNavigate('/register')); + buttonLogin.addEventListener('click', () => onNavigate('/login')); + buttonDiv.appendChild(buttonRegister); + buttonDiv.appendChild(buttonLogin); + return homeDiv; +}; diff --git a/src/components/login.js b/src/components/login.js new file mode 100644 index 0000000..9a825c9 --- /dev/null +++ b/src/components/login.js @@ -0,0 +1,244 @@ +import { signInUser, signInGoogle } from '../lib/auth.js'; + +export const login = (onNavigate) => { + const homeDiv = document.createElement('div'); + homeDiv.className = 'container'; + + // Splash screen + const splashScreenDiv = document.createElement('div'); + splashScreenDiv.className = 'container__splash'; + homeDiv.append(splashScreenDiv); + + const planetDiv = document.createElement('div'); + planetDiv.setAttribute('className', 'container__splash-img'); + splashScreenDiv.append(planetDiv); + + const planetImg = document.createElement('img'); + planetImg.className = 'planet-img'; + planetImg.src = '../Images/planet.png'; + planetDiv.append(planetImg); + + const brandDiv = document.createElement('div'); + brandDiv.className = 'container__brand'; + splashScreenDiv.append(brandDiv); + + const brand = document.createElement('img'); + brand.className = 'brand'; + brand.src = '../Images/space-white.png'; + brandDiv.append(brand); + + const sloganDiv = document.createElement('div'); + sloganDiv.className = 'container__slogan'; + splashScreenDiv.append(sloganDiv); + + const slogan = document.createElement('p'); + slogan.className = 'slogan'; + slogan.textContent = 'Connecting the Universe,\n One Explorer at a Time' + sloganDiv.append(slogan); + + const btnStartDiv = document.createElement('div'); + btnStartDiv.className = 'container__btn-start'; + splashScreenDiv.append(btnStartDiv); + + const btnStart = document.createElement('p'); + btnStart.className = 'btn-start'; + btnStart.textContent = 'Start your adventure'; + btnStartDiv.append(btnStart); + + // Form + + const formDiv = document.createElement('div'); + formDiv.className = 'container__form'; + homeDiv.append(formDiv); + + const headerDiv = document.createElement('div'); + headerDiv.className = 'container__header'; + formDiv.appendChild(headerDiv); + + const iconDiv = document.createElement('div'); + iconDiv.className = 'container__icon'; + headerDiv.appendChild(iconDiv); + + const icon = document.createElement('img'); + icon.className = 'icon'; + icon.src = '../Images/icon.png'; + iconDiv.appendChild(icon); + + const titleDiv = document.createElement('div'); + titleDiv.textContent = 'Welcome back to the orbit!'; + titleDiv.className = 'container__title'; + headerDiv.appendChild(titleDiv); + + const signInDiv = document.createElement('div'); + signInDiv.textContent = 'Sign In'; + signInDiv.className = 'container__singin'; + headerDiv.appendChild(signInDiv); + + const buttonHome = document.createElement('button'); + buttonHome.className = 'button button-home'; + buttonHome.textContent = 'Home'; + + // Create form to login + const form = document.createElement('form'); + form.className = 'form-login'; + + // Email Input + const inputEmail = document.createElement('input'); + inputEmail.id = 'email'; + inputEmail.className = 'input input-email'; + inputEmail.placeholder = 'Email'; + form.appendChild(inputEmail); + + // Password Input + const inputPassword = document.createElement('input'); + inputPassword.id = 'password'; + inputPassword.className = 'input input-password'; + inputPassword.type = 'password'; + inputPassword.placeholder = 'Password'; + form.appendChild(inputPassword); + + //Sign In button + const buttonDataLogin = document.createElement('input'); + buttonDataLogin.className = 'button button-login'; + buttonDataLogin.type = 'submit'; + buttonDataLogin.value = 'Login'; + form.appendChild(buttonDataLogin); + formDiv.appendChild(form); + + const optionalDiv = document.createElement('div'); + optionalDiv.className = 'container__optional'; + form.appendChild(optionalDiv); + + const lineOne = document.createElement('div'); + lineOne.className = 'line line-one'; + optionalDiv.appendChild(lineOne); + + const textOptional = document.createElement('div'); + textOptional.className = 'or'; + textOptional.textContent = 'or'; + optionalDiv.appendChild(textOptional); + + const lineTwo = document.createElement('div'); + lineTwo.className = 'line line-two'; + optionalDiv.appendChild(lineTwo); + + //sign in google + const buttonGoogle = document.createElement('button'); + buttonGoogle.className = 'button button-google'; + form.appendChild(buttonGoogle); + + const textButtonGoogleDiv = document.createElement('div'); + textButtonGoogleDiv.className = 'container__text-google'; + buttonGoogle.append(textButtonGoogleDiv); + + const textButtonGoogle = document.createElement('p'); + textButtonGoogle.className = 'text-google'; + textButtonGoogle.textContent = 'Login with google'; + textButtonGoogleDiv.appendChild(textButtonGoogle); + + const iconGoogleDiv = document.createElement('div'); + iconGoogleDiv.className = 'container__icon-google'; + buttonGoogle.append(iconGoogleDiv); + + const iconGoogle = document.createElement('img'); + iconGoogle.className = 'icon-google'; + iconGoogle.src = '../Images/google.svg'; + iconGoogleDiv.appendChild(iconGoogle); + + // Redirect to Register + const redirectSignUpDiv = document.createElement('div'); + redirectSignUpDiv.className = 'container__redirect container__redirect-register'; + form.appendChild(redirectSignUpDiv); + + const descriptionTextRegisterDiv = document.createElement('div'); + descriptionTextRegisterDiv.className = 'container__description container__description-register--inside'; + redirectSignUpDiv.appendChild(descriptionTextRegisterDiv); + + const descriptionTextRegister = document.createElement('p'); + descriptionTextRegister.className = 'text-description text-description-register'; + descriptionTextRegister.textContent = 'Don\'t have an account?'; + descriptionTextRegisterDiv.append(descriptionTextRegister); + + const redirectTextSignUp = document.createElement('span'); + redirectTextSignUp.className = 'text-redirect text-redirect-register'; + redirectTextSignUp.textContent = ' Create one here.'; + redirectSignUpDiv.append(redirectTextSignUp); + + // Code to see failure text + const failureText = document.createElement('p'); + failureText.className = 'failure-text failure-text-hidden'; + form.appendChild(failureText); + + buttonDataLogin.addEventListener('click', (e) => { + e.preventDefault(); + const email = inputEmail.value; + const password = inputPassword.value; + failureText.textContent = ''; + + console.log(email, password); + const errorMessages = { + passwordEmpty: 'Enter a cosmic password!', + emailEmpty: 'Enter your email', + invalidEmail: 'Wait! Invalid email!', + }; + + const validationErrors = []; + + if (password === '') { + validationErrors.push('passwordEmpty'); + } else if (email === '') { + validationErrors.push('emailEmpty'); + } else if (!email.includes('@') || !email.includes('.')) { + validationErrors.push('invalidEmail'); + } + + if (validationErrors.length > 0) { + failureText.textContent = errorMessages[validationErrors[0]]; + failureText.classList.remove('failure-text-hidden'); + } else { + signInUser(email, password) + .then((response) => { + const user = response.user; + console.log(response); + // buttonDataLogin.addEventListener('click', () => onNavigate('/feed')); + onNavigate('/feed'); + // IdP data available using getAdditionalUserInfo(response) + // ... + }) + .catch((error) => { + console.log(error); + // Handle Errors here. + if (error.code === 'auth/invalid-email') { + failureText.textContent = 'Invalid email'; + } else if (error.code === 'auth/wrong-password') { + failureText.textContent = 'Incorrect password'; + } else if (error.code === 'auth/user-not-found') { + failureText.textContent = 'This user does not exist'; + } + failureText.classList.remove('failure-text-hidden'); + }); + } + }); + + buttonGoogle.addEventListener('click', (e) => { + e.preventDefault(); + + signInGoogle() + .then((response) => { + // This gives you a Google Access Token. You can use it to access the Google API. + + // The signed-in user info. + const user = response.user; + console.log(response); + // IdP data available using getAdditionalUserInfo(response) + // ... + }) + .catch((error) => { + console.log(error); + // Handle Errors here. + }); + }); + redirectTextSignUp.addEventListener('click', () => onNavigate('/register')); + + return homeDiv; +}; diff --git a/src/components/register.js b/src/components/register.js new file mode 100644 index 0000000..a8b6272 --- /dev/null +++ b/src/components/register.js @@ -0,0 +1,199 @@ +import { createUser } from '../lib/auth.js'; + +export const register = (onNavigate) => { + const homeDiv = document.createElement('div'); + homeDiv.className = 'container'; + + // Splash screen + const splashScreenDiv = document.createElement('div'); + splashScreenDiv.className = 'container__splash'; + homeDiv.append(splashScreenDiv); + + const planetDiv = document.createElement('div'); + planetDiv.setAttribute('className', 'container__splash-img'); + splashScreenDiv.append(planetDiv); + + const planetImg = document.createElement('img'); + planetImg.className = 'planet-img'; + planetImg.src = '../Images/planet.png'; + planetDiv.append(planetImg); + + const brandDiv = document.createElement('div'); + brandDiv.className = 'container__brand'; + splashScreenDiv.append(brandDiv); + + const brand = document.createElement('img'); + brand.className = 'brand'; + brand.src = '../Images/space-white.png'; + brandDiv.append(brand); + + const sloganDiv = document.createElement('div'); + sloganDiv.className = 'container__slogan'; + splashScreenDiv.append(sloganDiv); + + const slogan = document.createElement('p'); + slogan.className = 'slogan'; + slogan.textContent = 'Connecting the Universe,\n One Explorer at a Time' + sloganDiv.append(slogan); + + const btnStartDiv = document.createElement('div'); + btnStartDiv.className = 'container__btn-start'; + splashScreenDiv.append(btnStartDiv); + + const btnStart = document.createElement('p'); + btnStart.className = 'btn-start'; + btnStart.textContent = 'Start your adventure' + btnStartDiv.append(btnStart); + + // Form + + const formDiv = document.createElement('div'); + formDiv.className = 'container__form'; + homeDiv.append(formDiv) + + const headerDiv = document.createElement('div'); + headerDiv.className = 'container__header'; + formDiv.appendChild(headerDiv); + + const iconDiv = document.createElement('div'); + iconDiv.className = 'container__icon'; + headerDiv.appendChild(iconDiv); + + const icon = document.createElement('img'); + icon.className = 'icon'; + icon.src = '../Images/icon.png'; + iconDiv.appendChild(icon); + + const titleDiv = document.createElement('div'); + titleDiv.textContent = 'Start your adventure here'; + titleDiv.className = 'container__title'; + headerDiv.appendChild(titleDiv); + + + // Create form to register + const form = document.createElement('form'); + form.className = 'form-register'; + formDiv.appendChild(form); + + // Username Input + const inputUser = document.createElement('input'); + inputUser.className = 'input input-user'; + inputUser.type = 'text'; + inputUser.placeholder = 'Username'; + form.appendChild(inputUser); + + // Email Input + const inputEmail = document.createElement('input'); + inputEmail.id = 'email'; + inputEmail.className = 'input input-email'; + inputEmail.placeholder = 'Email'; + form.appendChild(inputEmail); + + // Password Input + const inputPassword = document.createElement('input'); + inputPassword.id = 'password'; + inputPassword.className = 'input input-password'; + inputPassword.type = 'password'; + inputPassword.placeholder = 'Password'; + form.appendChild(inputPassword); + + //Register button + const buttonDataRegister = document.createElement('input'); + buttonDataRegister.className = 'button button-register'; + buttonDataRegister.type = 'submit'; + buttonDataRegister.value = 'Register'; + form.appendChild(buttonDataRegister); + + + // Redirect to Log In + const redirectSignInDiv = document.createElement('div'); + redirectSignInDiv.className = 'container__redirect container__redirect-login'; + form.appendChild(redirectSignInDiv); + + const descriptionTextLoginDiv = document.createElement('div'); + descriptionTextLoginDiv.className = 'container__description container__description-login--inside'; + redirectSignInDiv.appendChild(descriptionTextLoginDiv); + + const descriptionTextLogin = document.createElement('p'); + descriptionTextLogin.className = 'text-description text-description-login'; + descriptionTextLogin.textContent = 'Already have a Space account?'; + descriptionTextLoginDiv.append(descriptionTextLogin); + + const redirectTextSignIn = document.createElement('span'); + redirectTextSignIn.className = 'text-redirect text-redirect-login'; + redirectTextSignIn.textContent = 'Sign In'; + redirectSignInDiv.append(redirectTextSignIn); + + // Code to see failure text + const failureText = document.createElement('p'); + failureText.className = 'failure-text failure-text-hidden'; + form.appendChild(failureText); + + + // Action of button + buttonDataRegister.addEventListener('click', (e) => { + e.preventDefault(); + const registerEmail = inputEmail.value; + const registerPassword = inputPassword.value; + + const email = inputEmail.value; + const password = inputPassword.value; + + failureText.textContent = ''; + failureText.classList.add('failure-text-hidden'); + + const errorMessages = { + emailAndPasswordEmpty: + 'Spaceship Error, we need your email and password!', + passwordEmpty: 'Enter a cosmic password!', + emailEmpty: 'Enter your email', + invalidEmail: 'Wait! Invalid email!', + shortPassword: 'Spaceship Error! Your password needs 6 characters!', + }; + + const validationErrors = []; + + if (email === '' && password === '') { + validationErrors.push('emailAndPasswordEmpty'); + } else if (password === '') { + validationErrors.push('passwordEmpty'); + } else if (email === '') { + validationErrors.push('emailEmpty'); + } else if (!email.includes('@') || !email.includes('.')) { + validationErrors.push('invalidEmail'); + } else if (password.length < 6) { + validationErrors.push('shortPassword'); + } + + if (validationErrors.length > 0) { + failureText.textContent = errorMessages[validationErrors[0]]; + failureText.classList.remove('failure-text-hidden'); + } else { + // If no errors proceed with register + // {OH} Example of promises Firebase below: + // createUser(registerEmail, registerPassword) + // .then((response) => {console.log(response)}).catch((error) => {console.error(error)}); + createUser(registerEmail, registerPassword) + .then((response) => { + console.log(response); + onNavigate('/feed'); + }) + .catch((error) => { + console.error(error); + if (error.code === 'auth/email-already-in-use') { + failureText.textContent = 'Email already in use'; + } else if (error.code === 'auth/invalid-email') { + failureText.textContent = 'Invalid email'; + } + failureText.classList.remove('failure-text-hidden'); + }); + buttonDataRegister.disabled = true; + } + }); + + // End errors validation + + redirectTextSignIn.addEventListener('click', () => onNavigate('/login')); + + return homeDiv; +}; diff --git a/src/fonts/Poppins-family/DREAMS.ttf b/src/fonts/Poppins-family/DREAMS.ttf new file mode 100644 index 0000000..91e70b7 Binary files /dev/null and b/src/fonts/Poppins-family/DREAMS.ttf differ diff --git a/src/fonts/Poppins-family/Poppins-Bold.ttf b/src/fonts/Poppins-family/Poppins-Bold.ttf new file mode 100644 index 0000000..00559ee Binary files /dev/null and b/src/fonts/Poppins-family/Poppins-Bold.ttf differ diff --git a/src/fonts/Poppins-family/Poppins-Light.ttf b/src/fonts/Poppins-family/Poppins-Light.ttf new file mode 100644 index 0000000..bc36bcc Binary files /dev/null and b/src/fonts/Poppins-family/Poppins-Light.ttf differ diff --git a/src/fonts/Poppins-family/Poppins-Regular.ttf b/src/fonts/Poppins-family/Poppins-Regular.ttf new file mode 100644 index 0000000..9f0c71b Binary files /dev/null and b/src/fonts/Poppins-family/Poppins-Regular.ttf differ diff --git a/src/index.html b/src/index.html index 788db3c..58fdf3f 100644 --- a/src/index.html +++ b/src/index.html @@ -1,12 +1,15 @@ - - - - - Document - - - - - \ No newline at end of file + + + + + + Space + + +
+ + + + diff --git a/src/lib/auth.js b/src/lib/auth.js new file mode 100644 index 0000000..01285b8 --- /dev/null +++ b/src/lib/auth.js @@ -0,0 +1,31 @@ +import { + createUserWithEmailAndPassword, + signInWithEmailAndPassword, + signInWithRedirect, + onAuthStateChanged +} from 'firebase/auth'; +import { auth, provider } from './firebase'; + + + +export const createUser = (email, password) => + createUserWithEmailAndPassword(auth, email, password); + +export const signInUser = (email, password) => + signInWithEmailAndPassword(auth, email, password); + +export const signInGoogle = () => + signInWithRedirect(auth, provider); // Return the result of the function execution + +export const stateChanged = () => + onAuthStateChanged(auth, (user) => { + if (user) { + // User is signed in, see docs for a list of available properties + // https://firebase.google.com/docs/reference/js/auth.user + const uid = user.uid; + // ... + } else { + // User is signed out + // ... + } + }); diff --git a/src/lib/database.js b/src/lib/database.js new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/firebase.js b/src/lib/firebase.js new file mode 100644 index 0000000..d0c1d26 --- /dev/null +++ b/src/lib/firebase.js @@ -0,0 +1,28 @@ +// Import the functions you need from the SDKs you need +import { initializeApp } from 'firebase/app'; +import { getFirestore } from 'firebase/firestore'; +import { getAuth, GoogleAuthProvider } from 'firebase/auth'; +// TODO: Add SDKs for Firebase products that you want to use +// https://firebase.google.com/docs/web/setup#available-libraries +// Your web app's Firebase configuration +// For Firebase JS SDK v7.20.0 and later, measurementId is optional +const firebaseConfig = { + apiKey: 'AIzaSyDUCgNWPRcNJN-VT3np_vAdZd7VEaNMwcc', + authDomain: 'social-borrador-5d39c.firebaseapp.com', + projectId: 'social-borrador-5d39c', + storageBucket: 'social-borrador-5d39c.appspot.com', + messagingSenderId: '630047055563', + appId: '1:630047055563:web:5fc61c529fd7533cea054e', + measurementId: 'G-K8PCLTY7B2', +}; + +// Initialize Firebase +export const provider = new GoogleAuthProvider(); +const app = initializeApp(firebaseConfig); +export const auth = getAuth(app); +// Initialize Cloud Firestore and get a reference to the service +export const db = getFirestore(app); + +export const savePost = (description) => { + console.log(description); +}; diff --git a/src/lib/index.js b/src/lib/index.js deleted file mode 100644 index d193089..0000000 --- a/src/lib/index.js +++ /dev/null @@ -1,6 +0,0 @@ -// aqui exportaras las funciones que necesites - -export const myFunction = () => { - // aqui tu codigo - console.log('Hola mundo!'); -}; diff --git a/src/main.js b/src/main.js index ac27e91..9c90ae5 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,27 @@ -// Este es el punto de entrada de tu aplicacion +import { home } from './components/home.js'; +import { register } from './components/register.js'; +import { login } from './components/login.js'; +import { feed } from './components/feed.js'; -import { myFunction } from './lib/index.js'; -myFunction(); +const rootDiv = document.getElementById('root'); +const routes = { + '/': home, + '/register': register, + '/login': login, + '/feed': feed, +}; +const onNavigate = (pathname) => { + window.history.pushState({}, pathname, window.location.origin + pathname); + while (rootDiv.firstChild) { + rootDiv.removeChild(rootDiv.firstChild); + } + rootDiv.appendChild(routes[pathname](onNavigate)); +}; + +const component = routes[window.location.pathname]; /*const component = feed */ +window.onpopstate = () => { + rootDiv.appendChild(component(onNavigate)); +}; + +rootDiv.appendChild(component(onNavigate)); diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 0000000..748bac6 --- /dev/null +++ b/src/styles.css @@ -0,0 +1,345 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;700&display=swap'); + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + height: 100vh; + font-family: 'Poppins', sans-serif; +} + +/*Estilos de la pantalla Register*/ +.container { + height: 100vh; +} + +.container__splash { + display: none; +} + +.container__singin { + font-family: 'Poppins', sans-serif; + font-weight: normal; + font-size: 26px; + color: #c9c9c9; + margin-bottom: 45px; +} + +.container__form { + height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + background-image: url(/Images/background.png); + background-size: cover; + padding: 20px; + box-sizing: border-box; +} + +.container__header { + display: flex; + flex-direction: column; + /* align-items: center; */ + width: 261px; +} + +.container__title { + width: 100%; + padding-bottom: 15px; + text-align: left; + color: #ffff; + font-weight: bold; + font-size: 44px; + line-height: 3rem; +} + +.container__icon { + display: flex; + flex-direction: column; + width: 56px; + height: 49.22px; + align-self: self-start; +} + +.form-register { + display: flex; + flex-direction: column; + gap: 0.8rem; +} + +.form-login { + display: flex; + flex-direction: column; + gap: 0.8rem; +} + +.container-input p { + color: #757575; + font-size: 14px; +} + +.input { + font-family: 'Poppins', sans-serif; + font-weight: normal; + font-size: 16px; + width: 261px; + height: 54px; + border-radius: 7px; + border-color: #ffffff; + background-color: transparent; + color: #c9c9c9; + display: flex; + margin: auto; + padding: 10px 18px; +} + +.input::placeholder { + color:#848484 +} + +.button { + font-family: 'Poppins', sans-serif; + font-weight: normal; + font-size: 16px; + width: 261px; + color: #ffff; + border-radius: 20px; + border: none; + background-color: #513ba1; + gap: 2rem; + display: flex; + justify-content: center; + margin: auto; + padding: 7px 15px; + cursor: pointer; +} + +.button:hover { + opacity: 0.8; + background-color: #7B23FE; +} + +.container__optional { + display: flex; + justify-content: space-around; + align-items: center; +} + +.line { + height: 0px; + width: 112px; + border: 1.5px solid #ffff; +} + +.or { + font-family: 'Poppins', sans-serif; + font-weight: normal; + font-size: 19px; + color: #ffff; +} + +.button-google { + display: flex; + flex-direction: row-reverse; + width: 261px; + max-height: 37.33px; + color: #000000; + border-radius: 20px; + border: none; + background-color: #b8ace3; + gap: 2rem; + align-items: center; + margin: auto; + padding: 7px 15px; +} + +.button-google:hover { + color: aliceblue +} + +.container__text-google { + font-size: 16px; + font-family: 'Poppins', sans-serif; + font-weight: normal; + text-align: left; + color: #020202; + position: relative; + right: 33px; +} + +.container__icon-google { + float: left; + margin-right: 12px; + margin: 5px 12px 0px 0px; +} + +.container__icon-google img { + filter: brightness(0) saturate(100%) invert(17%) sepia(0%) saturate(0%) + hue-rotate(26deg) brightness(97%) contrast(83%); + width: 34px; +} + +.container__redirect { + display: flex; + align-items: center; + margin-top: 10px; +} + +.container__description { + font-size: 14px; + margin-right: 7px; + color: #ffffff; +} + +.text-redirect { + font-size: 14px; + font-weight: bold; + /* color: #513ba1; #472ea2 #4f33b2 */ + color: #f8f0ff; + cursor: pointer; +} + +.text-redirect:hover { + text-decoration: underline; +} + +/*Estilos de la pantalla Home*/ +.div-button { + display: grid; + place-items: center; + position: absolute; + gap: 2rem; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); +} + +/*Styles for failure text*/ +.input-container p { + margin: 5px 0 0 5px; + color: #757575; + font-size: 14px; +} + +/*Responsive*/ + +/* @media (min-width: 481px) and (max-width: 768px) { +} */ + +@media (min-width: 769px) and (max-width: 1920px) { + .container { + display: flex; + flex-direction: row; + } + + .container__splash { + width: 55%; + background-image: url(./Images/background.png); + background-size: cover; + display: flex; + flex-direction: column; + align-items: center; + } + + .container__splash-img { + width: 100%; + } + + .planet-img { + width: 100%; + } + + .container__brand { + display: flex; + justify-content: center; + } + + .brand { + width: 40%; + } + + .slogan { + font-size: 17px; + color: #ffff; + padding: 30px 10px; + font-size: 1rem; + white-space: pre-wrap; + } + + .btn-start { + color: #ffff; + display: none; + } + + .container__singin { + font-family: 'Poppins', sans-serif; + font-weight: normal; + font-size: 26px; + color: #757575; + margin-bottom: 45px; + } + + .container__form { + width: 45%; + background-image: none; + } + + .container__title { + width: 100%; + padding-bottom: 15px; + text-align: left; + color: #513ba1; + font-size: 44px; + line-height: 3rem; + } + + .container__icon img { + filter: brightness(0) saturate(100%) invert(28%) sepia(21%) saturate(2877%) + hue-rotate(221deg) brightness(93%) contrast(101%); + } + + .input { + border: 1px solid #757575; + color: #19002A; + background-color: transparent; + } + + .input::placeholder { + color:#919191 + } + + .line { + height: 0px; + width: 112px; + border: 0.5px solid #757575; + } + + .or { + font-family: 'Poppins', sans-serif; + font-weight: normal; + font-size: 19px; + color: #757575; + } + + .container__description { + font-size: 14px; + margin-right: 7px; + color: #757575; + } + + .text-redirect { + font-size: 14px; + font-weight: bold; + /* color: #513ba1; #472ea2 #4f33b2 */ + color: #513ba1; + cursor: pointer; + } + + .text-redirect:hover { + text-decoration: underline; + } +} diff --git a/test/index.spec.js b/test/index.spec.js deleted file mode 100644 index 91f11a3..0000000 --- a/test/index.spec.js +++ /dev/null @@ -1,8 +0,0 @@ -// importamos la funcion que vamos a testear -import { myFunction } from '../src/lib/index'; - -describe('myFunction', () => { - it('debería ser una función', () => { - expect(typeof myFunction).toBe('function'); - }); -}); diff --git a/test/register.spec.js b/test/register.spec.js new file mode 100644 index 0000000..c97b471 --- /dev/null +++ b/test/register.spec.js @@ -0,0 +1,90 @@ +// import register from '../src/components/register'; +import { createUser } from '../src/lib/auth.js'; +import { register } from '../src/components/register'; + + +jest.mock('../src/lib/auth.js'); + +function tick() { + return new Promise((resolve) => { + setTimeout(resolve, 0); + }); +} + +describe('Unit tests for register', () => { + let inputEmail; + let inputPassword; + let buttonDataRegister; + let failureText; + + beforeEach(() => { + const onNavigateMock = () => {}; + while (document.body.firstChild) { + document.body.removeChild(document.body.firstChild); + } + document.body.appendChild(register(onNavigateMock)); + inputEmail = document.getElementById('email'); + inputPassword = document.getElementById('password'); + buttonDataRegister = document.querySelector('.button-register'); + failureText = document.querySelector('.failure-text'); + }); + + it('should display an error message if the email is invalid', async () => { + createUser.mockRejectedValueOnce(new Error('auth/invalid-email')); + + inputEmail.value = 'invalid-email'; + inputPassword.value = 'password'; + + buttonDataRegister.click(); + await tick(); + + expect(failureText.textContent).toBe('Wait! Invalid email!'); + expect(failureText.classList.contains('failure-text-hidden')).toBe(false); + }); + + it('should display an error message if the password is too short', async () => { + createUser.mockRejectedValueOnce(new Error('auth/weak-password')); + + inputEmail.value = 'valid-email@example.com'; + inputPassword.value = 'short'; + + buttonDataRegister.click(); + await tick(); + + expect(failureText.textContent).toBe( + 'Spaceship Error! Your password needs 6 characters!' + ); + expect(failureText.classList.contains('failure-text-hidden')).toBe(false); + }); + + it('should display an error message if the email is already in use', async () => { + const errorMessage = 'Email already in use'; + createUser.mockRejectedValueOnce(new Error('auth/email-already-in-use')); + + inputEmail.value = 'existing-email@example.com'; + inputPassword.value = 'password'; + + buttonDataRegister.click(); + await tick(); + + expect(failureText.textContent).toBe(errorMessage); + expect(failureText.classList.contains('failure-text-hidden')).toBe(false); + }); + +/* it('should not display an error message when succesful register', async () => { + createUser.mockResolvedValueOnce({ + user: { userCredential: 12345, email: 'validemail@mail.com' }, + }); + + inputEmail.value = 'validemail@mail.com'; + inputPassword.value = 'validpassword'; + + buttonDataRegister.click(); + await tick(); + + expect(failureText.textContent).toBe(''); + + //expect(failureText.classList.contains('failure-text-hidden')).not.toBe(false); + }); */ + +}); diff --git a/vite.config.js b/vite.config.js index e284e5d..eac2b85 100644 --- a/vite.config.js +++ b/vite.config.js @@ -26,4 +26,4 @@ export default defineConfig(({ command }) => { }; } return {}; -}); +}); \ No newline at end of file