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 =
+ `
+
+
+
+
+
+

+
+
+
+
+
+
`
+ 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
+
+
+
+
+
+