diff --git a/.firebaserc b/.firebaserc new file mode 100644 index 00000000..d6a387ae --- /dev/null +++ b/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "socialnetwork-15a5f" + } +} diff --git a/_mocks_/firebase-mock.js b/_mocks_/firebase-mock.js new file mode 100644 index 00000000..0623878b --- /dev/null +++ b/_mocks_/firebase-mock.js @@ -0,0 +1,34 @@ + +/* const firestore = { + auth: () => { + return { + signInWithPopup: (provider) => { + return new Promise((resolve, reject) => { + resolve('datauser') + + + }) + } + } + } +} */ +//Creando un mock manual +/* const firebase = { + auth: () => { + return { + signInWithPopup: (provider) => { + return new Promise((resolve, reject) => { + resolve('datauser') + + + }) + } + } + }, + + +} + +export default jest.fn(() => { + return firebase +}) */ \ No newline at end of file diff --git a/database.rules.json b/database.rules.json new file mode 100644 index 00000000..c0aa595d --- /dev/null +++ b/database.rules.json @@ -0,0 +1,6 @@ +{ + "rules": { + ".read": "auth != null", + ".write": "auth != null" + } +} \ No newline at end of file diff --git a/firebase.json b/firebase.json new file mode 100644 index 00000000..2dbc6cb3 --- /dev/null +++ b/firebase.json @@ -0,0 +1,16 @@ +{ + "database": { + "rules": "database.rules.json" + }, + "hosting": { + "public": "src", + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**" + ] + }, + "storage": { + "rules": "storage.rules" + } +} diff --git a/package.json b/package.json index 9a365577..50d50137 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,6 @@ "scripts": { "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", "start": "serve src/" }, @@ -32,5 +30,8 @@ "serve": "^11.0.2", "stylelint": "^10.1.0", "stylelint-config-recommended": "^2.2.0" + }, + "dependencies": { + "bulma": "^0.8.2" } } \ No newline at end of file diff --git a/src/404.html b/src/404.html new file mode 100644 index 00000000..829eda8f --- /dev/null +++ b/src/404.html @@ -0,0 +1,33 @@ + + + + + + Page Not Found + + + + +
+

404

+

Page Not Found

+

The specified file was not found on this website. Please check the URL for mistakes and try again.

+

Why am I seeing this?

+

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

+
+ + diff --git a/src/example.js b/src/example.js deleted file mode 100644 index 52d2c7ea..00000000 --- a/src/example.js +++ /dev/null @@ -1,3 +0,0 @@ -export const example = () => { - // aquí tu código -} \ No newline at end of file diff --git a/src/img/Thumbs.db b/src/img/Thumbs.db new file mode 100644 index 00000000..0d009261 Binary files /dev/null and b/src/img/Thumbs.db differ diff --git a/src/img/ojo.png b/src/img/ojo.png new file mode 100644 index 00000000..80ff1eeb Binary files /dev/null and b/src/img/ojo.png differ diff --git a/src/img/slider1.png b/src/img/slider1.png new file mode 100644 index 00000000..43d4e886 Binary files /dev/null and b/src/img/slider1.png differ diff --git a/src/img/slider2.png b/src/img/slider2.png new file mode 100644 index 00000000..98d32eff Binary files /dev/null and b/src/img/slider2.png differ diff --git a/src/img/slider3.png b/src/img/slider3.png new file mode 100644 index 00000000..fab737a8 Binary files /dev/null and b/src/img/slider3.png differ diff --git a/src/index.html b/src/index.html index bb6937cc..17589d3a 100644 --- a/src/index.html +++ b/src/index.html @@ -1,12 +1,71 @@ + Document + + + + + - + +
+
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/index.js b/src/index.js index 35868bab..61241052 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,254 @@ -import { example } from './example.js'; +/* import { root } from "/main.js"; +import { viewLogin } from '/main.js' +import { viewSign } from '/main.js' +import { renderHomeView } from "./views/home.js" */ +import { renderPostView } from "./views/post.js" +//import { renderProfileView } from "./views/profile.js" +//import { renderLoginView } from "./views/login.js" +/* import { renderExitView } from "./views/exit.js" +import { userObserverProfile } from "./views/profile.js" */ +import { principalView } from "../main.js"; + +/* export const components = { + home: renderHomeView, + post: renderPostView, + profile: renderProfileView, + exit: renderExitView +}; */ + + +//Instanciar Firestore +const db = firebase.firestore(); + +//login, instancia del provedor del servicio +const provider = new firebase.auth.GoogleAuthProvider(); +const providerf = new firebase.auth.FacebookAuthProvider(); + +//Autenticar con Google +export function loginGoogle(errorGooFbkModal) { + //console.log(viewLogin); + let btngoGoogle = document.querySelector('#goGoogle') + btngoGoogle.addEventListener('click', (e) => { + e.preventDefault() + firebase.auth()//Se llama a la func autenticar + .signInWithPopup(provider)//Se va a usar una popUp y se va a loguear con la var provider que es google + .then(function (result) {//lo que se hace cuando el usuario ya inicio sension y ya dio permisos, nos dio su info + console.log(result.user);//trae info de usuario(correo, nombre, foto, etc) + saveDataG(result.user)//Se le manda a la func guardDatos para hacer uns BD + renderPostView(); + //userObserverProfile() + + + }) + .catch(function (error) { + errorGooFbkModal.classList.add('is-active'); + console.log('error:', error); + }) + }); +} + +//Guardar datos gmail en BD +function saveDataG(user) { + //console.log(user); + const docRef = db.collection('datausers/').doc(user.uid) + docRef.get().then(userBD => { + if (userBD.exists === true) { + console.log(userBD); + console.log('ya existe'); + + } else { + console.log('no existe'); + console.log(userBD); + docRef.set({ + uid: user.uid,//Servirá para eliminar + name: user.displayName,//Se obtiene el nom + email: user.email, + photo: user.photoURL, + //interests: 'uhuggy' + }) + .then(function () { + console.log('Los datos se guardaron'); + }) + .catch(function (error) { + console.log('Hubo en error:', error); + }) + + } + }) + /* const docRef = db.collection('datausers/').doc(user.uid);//la / y el + user.uid hace que no se duplique el usuario */ + + updateData(docRef) +} + +//Leer los datos de la BD +function updateData(docRef) { + docRef.get().then(function (snapshot) { + let myData = snapshot.data(); + console.log(myData); + /* div.innerHTML = `Hola ${myData.nombre}` */ + }) +} + + +//Autenticar con facebook +export function loginFacebook(errorGooFbkModal) { + let btngoFacebook = document.querySelector('#goFacebook'); + btngoFacebook.addEventListener('click', function (e) { + e.preventDefault() + firebase.auth()//Se llama a la func autenticar + .signInWithPopup(providerf)//Se va a usar una popUp y se va a loguear con la var provider que es google + .then(function (result) {//lo que se hace cuando el usuario ya inicio sension y ya dio permisos, nos dio su info + console.log(result.user);//trae info de usuario(correo, nombre, foto, etc) + console.log(result.credential); + saveDataF(result.user)//Se le manda a la func guardDatos para hacer una BD + //userObserverProfile() + renderPostView(); + + //div.innerHTML = `` + + }) + .catch(function (error) { + errorGooFbkModal.classList.add('is-active'); + console.log('Hubo en error:', error); + }) + }); +} + +//Guardar datos Fb en BD +function saveDataF(user) { + //console.log(user); + const docRef = db.collection('datausers/').doc(user.uid) + docRef.get().then(userBD => { + if (userBD.exists === true) { + console.log(userBD); + console.log('ya existe'); + + } else { + console.log('no existe'); + console.log(userBD); + docRef.set({ + uid: user.uid,//Servirá para eliminar + name: user.displayName,//Se obtiene el nom + email: user.email, + photo: user.photoURL, + interests: 'Interes' + }) + .then(function () { + console.log('Los datos se guardaron'); + }) + .catch(function (error) { + console.log('Hubo en error:', error); + }) + + } + }) + updateDataFb(docRef) +} + +//Leer los datos de la BD +function updateDataFb(docRef) { + docRef.get().then(function (snapshot) { + let myData = snapshot.data(); + console.log(myData); + /* div.innerHTML = `Hola ${myData.nombre} ` */ + }) +} + + +//Crear cuenta con email +//Registrarse: +export function createUser(newName, newEmail, newPassword, registryModal, alreadyExistModal) { + //console.log(user); + console.log(newName + newEmail + newPassword); + //const expRegName = /^[a-z0-9_-]{3,16}$/ + const expRegEmail = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/ + const expRegPass = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$/ + if (expRegPass.test(newPassword) === true && expRegEmail.test(newEmail) === true) { + firebase.auth().createUserWithEmailAndPassword(newEmail, newPassword) + + .then(function (user) { + console.log('Se ha creado la cuenta!'); + console.log(user.user); + saveEmailBD(newName, newEmail, newPassword, user) + renderPostView(); + }) + .catch(function (error) {//Si la cuenta se ha creado se muestra el error + alreadyExistModal.classList.add('is-active'); + console.log(error.message); + }) + } else { + registryModal.classList.add('is-active'); + //alert('Comprueba tu correo o contraseña (debe contener al menos 6 caracteres,un número, una minúscula y al menos una mayúscula).') + } +} + +//:Guardar los datos en BD +function saveEmailBD(newName, newEmail, newPassword, user) { + const docRef = db.collection('datausers/').doc(user.user.uid);//la / y el + user.uid hace que no se duplique el usuario + docRef.set({ + name: newName, + email: newEmail, + password: newPassword, + interests: 'Interés', + photo: 'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcS_nu03Fphc39lFDYvqsGjluX8keorjzG79akJclhK2fS2SwLKo&usqp=CAU', + uid: user.user.uid + + }) + .then(function () { + console.log('Los datos se guardaron'); + }) + .catch(function (error) { + console.log('Hubo en error:', error); + }) +} + + +//Inicio de Sesión: +//:Comparar los datos del usuario con los datos que usó para crear cuenta +export function loginUser(email, password, errorModal) { + //console.log(email + password + errorModal); + firebase.auth().signInWithEmailAndPassword(email, password) + .then(function (user) { + console.log('Datos correctos, bienvenido!') + //console.log(user); + renderPostView() + }) + .catch(function (error) { + errorModal.classList.add('is-active'); + //alert('Upsi, datos incorrectos'); + }) + +} + + +//Salir de la sesión: +export function signoutUser() { + //e.preventDefault() + firebase.auth().signOut(); + console.log('Adiós Bye'); + /* const divRoot = document.querySelector('#root') + divRoot.innerHTML = principal() */ + principalView() + +} + +//Nos dice que usuario tiene sesión abierta y nos trae sus datos de la BD +function userObserver() { + firebase.auth().onAuthStateChanged(function (user) { + //console.log(user); + if (user) { + const docRef = db.collection('datausers/').doc(user.uid); + docRef.get().then(function (snapshot) { + let myData = snapshot.data(); + console.log(myData) + }) + } else { + // No user is signed in. + console.log('No user'); + } + }); +} + + +userObserver() -example(); diff --git a/src/main.js b/src/main.js new file mode 100644 index 00000000..1e97ee5a --- /dev/null +++ b/src/main.js @@ -0,0 +1,146 @@ +// import { changeView } from './views/viewcontroler.js' +import { renderPostView } from "./views/post.js" +// import { showPosts } from "./views/home.js" +import { userObserverProfile } from "./views/profile.js" +// import { renderExitView } from "./views/exit.js" +import login from "./views/login.js" +import signIn from "./views/signIn.js" +import principal from "./views/principal.js" +import { loginGoogle } from '/index.js'// Se importa para usar addEventListener +import { loginFacebook } from '/index.js' +import { createUser } from '/index.js' +import { loginUser } from '/index.js' +import { signoutUser } from '/index.js' + + +// Nodos +export const root = document.querySelector('#root'); +export const showP = document.querySelector('#showP') +export const navBar = document.querySelector('#navBar'); +const homeButton = document.querySelector('#home'); +const postButton = document.querySelector('#post'); +const profileButton = document.querySelector('#profile'); +const exitButton = document.querySelector('#exit'); + +homeButton.addEventListener('click', renderPostView); +//homeButton.addEventListener('click', showPosts); +postButton.addEventListener('click', renderPostView); +profileButton.addEventListener('click', userObserverProfile); +exitButton.addEventListener('click', signoutUser); + + +// Función de inicio que cambia la URL +/* const init = () => { + window.addEventListener('hashchange', () => changeView(window.location.hash)) +} +window.addEventListener('load', init); + */ +// Boton para cerrar sesión +/* const btnExit = document.querySelector('#goOut') +btnExit.addEventListener('click', signoutUser) + */ +// Al cargar la pag mostrar vista (una antes de iniciar sesión) +window.onload = principalView(); + +export function principalView() { + root.innerHTML = principal(); + let goLogin = document.querySelector('#goLogin') + goLogin.addEventListener('click', viewLogin) +} + +// Mostrar vista iniciar sesión +export function viewLogin() { + root.innerHTML = login() + let goSignIn = document.querySelector('#goSignIn'); + + // Listeners modales + const btnCloseError = document.querySelector('#btnCloseError'); + btnCloseError.addEventListener('click', closeError); + const errorGooFbkModal = document.querySelector('#noAccountGooFbk'); + const btnCloseGoogleError = document.querySelector('#btnCloseNoGooFbk'); + btnCloseGoogleError.addEventListener('click', closeGooFbkError) + + // Ingresar + let btnEnter = document.querySelector('#enter'); + btnEnter.addEventListener('click', function (e) { + e.preventDefault(); + let email = document.querySelector('#email').value; + let password = document.querySelector('#password').value; + const errorModal = document.querySelector('#errorModal'); + /* console.log(email); + console.log(password); */ + loginUser(email, password, errorModal); + }) + // Ocultar Modaless + function closeError() { + errorModal.classList.remove('is-active'); + } + function closeGooFbkError() { + errorGooFbkModal.classList.remove('is-active'); + } + viewSign(goSignIn) + loginGoogle(errorGooFbkModal) + loginFacebook(errorGooFbkModal) +} + +//Mostrar vista Resgistro +export function viewSign(goSignIn) { + goSignIn.addEventListener('click', (e) => { + e.preventDefault() + root.innerHTML = signIn() + + //Listeners Modales + const btnCloseError = document.querySelector('#btnCloseError'); + btnCloseError.addEventListener('click', closeError); + const btnCloseExist = document.querySelector('#btnCloseExistAccount'); + btnCloseExist.addEventListener('click', closeErrorExist); + let btnBack = document.querySelector('#backOne') + const errorGooFbkModal = document.querySelector('#noAccountGooFbk'); + const btnCloseGoogleError = document.querySelector('#btnCloseNoGooFbk'); + btnCloseGoogleError.addEventListener('click', closeGooFbkError) + + //Crear cuenta + let btnRegister = document.querySelector('#signIn') + btnRegister.addEventListener('click', function (e) { + e.preventDefault() + + //Leer variables del form + const newName = document.querySelector('#newName').value + const newEmail = document.querySelector('#newEmail').value + const newPassword = document.querySelector('#newPassword').value + const registryModal = document.querySelector('#registryModal');// el id lo tiene el overlay + const alreadyExistModal = document.querySelector('#alreadyExistModal'); + /* console.log(newName); + console.log(newEmail); + console.log(newPassword); */ + createUser(newName, newEmail, newPassword, registryModal, alreadyExistModal) + + + }) + //Ocultar Modales + function closeError() { + registryModal.classList.remove('is-active'); + } + function closeErrorExist() { + alreadyExistModal.classList.remove('is-active'); + } + function closeGooFbkError() { + errorGooFbkModal.classList.remove('is-active'); + } + arrowBack(btnBack) + loginGoogle(errorGooFbkModal) + loginFacebook(errorGooFbkModal) + }) + +} + +//Regresar a inicio de sesión +function arrowBack(btnBack) { + btnBack.addEventListener('click', (e) => { + e.preventDefault() + root.innerHTML = login() + viewLogin() + }) +} + + diff --git a/src/pops.js b/src/pops.js new file mode 100644 index 00000000..8ae79bd8 --- /dev/null +++ b/src/pops.js @@ -0,0 +1,175 @@ +const areYouSure = ` + + + +` + + +const saveChange = ` + + +` +const divRoot = document.querySelector('#root') +divRoot.innerHTML = saveChange + +// Are you sure that you want to delete the element? +/* const overDelete = document.createElement('div'); +overDelete.className = 'overSmall'; +overDelete.id = 'overDelete'; +overDelete.innerHTML = ` +
+
+
+ +
+
+ +

Estás seguro que quieres eliminar el elemento?

+ + + +
+ +
+
+` +document.body.appendChild(overDelete); + +// Open PopUpDelete +const btnPop = document.querySelector('#pop') +const overlayDelete = document.querySelector('#overDelete');// el id lo tiene el overlay +const popup = document.querySelector('.popSmall'); +const btnClosePopup = document.querySelector('#btn-cerrar-delete'); +btnPop.addEventListener('click', abrirPopup); +btnClosePopup.addEventListener('click', cerrarPopup); + +function abrirPopup() { + overlayDelete.classList.add('active'); + popup.classList.add('active'); +} +function cerrarPopup() { + overlayDelete.classList.remove('active'); + popup.classList.remove('active'); +} + +//Task Completed + +const overComplete = document.createElement('div'); +overComplete.className = 'overSmall'; +overComplete.id = 'overComplete'; +overComplete.innerHTML = ` +
+
+
+ +
+
+ +

Se han guardado tus cambios

+
+ +
+
+` +document.body.appendChild(overComplete); + +// Open PopUp Task Complete +const btnComplete = document.querySelector('#taskCompleted') +const overComp = document.querySelector('#overComplete');// el id lo tiene el overlay +const popuptask = document.querySelector('.popSmall'); +const btnCloseTask = document.querySelector('#btn-cerrar-complete'); +btnComplete.addEventListener('click', openComplete); +btnCloseTask.addEventListener('click', closeComplete); + +function openComplete() { + overComp.classList.add('active'); + popuptask.classList.add('active'); +} +function closeComplete() { + overComp.classList.remove('active'); + popuptask.classList.remove('active'); +} + +//Show Error + +const overError = document.createElement('div'); +overError.className = 'overSmall'; +overError.id = 'overError'; +overError.innerHTML = ` +
+
+
+

ERROR

+ +

Intenta de nuevo, alguno de tus datos no coincide

+
+
+ +
+ +
+
+` +document.body.appendChild(overError); + +// Open PopUp error +const btnError = document.querySelector('#showError') +const overErr = document.querySelector('#overError');// el id lo tiene el overlay +const popupError = document.querySelector('.popSmall'); +const btnCloseError = document.querySelector('#btn-cerrar-error'); +btnError.addEventListener('click', openError); +btnCloseError.addEventListener('click', closeError); + +function openError() { + overErr.classList.add('active'); + popupError.classList.add('active'); +} +function closeError() { + overErr.classList.remove('active'); + popupError.classList.remove('active'); +} + */ + +/* const profileCard = document.createElement('div'); +profileCard.className = 'profileCard'; +profileCard.innerHTML = ` +
+
+
+

Estás seguro que quieres eliminar el elemento?

+ +
+ + +` +profileContainer.appendChild(profileCard); */ + +/* const closeButton = document.createElement('div'); +closeButton.className = 'closeButton'; +profileCard.appendChild(closeButton); */ + +/* const close = document.createElement('a'); +close.className = 'btn-cerrar-popup'; +closeButton.appendChild(close); +const icon = document.createElement('i'); +icon.className = 'far fa-times-circle'; +close.appendChild(icon); */ \ No newline at end of file diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 00000000..af6fa559 --- /dev/null +++ b/src/styles.css @@ -0,0 +1,328 @@ + + +#root{ + height: 100vh; +} + +/* *{ + margin:0; + padding:0; + box-sizing: border-box; + font-family: 'Poppins', sans-serif; + font-size: medium; +} */ + + + + +body{ + /*background-color:#131515;*/ + background-size: cover; + background-color:#232323; + /* height: 600px; */ + color: rgb(212, 144, 41); + height: 100vh; + +} +.form-container{ + background-color:#232323; + margin-top: 0px; + padding-top: 80px; + padding-left: 50px; + padding-right: 50px; + padding-bottom: 50px; + justify-content: center; + color:#FAFAFA; +} +.titles{ + font-size: large; +} + +.centerItem{ + margin: 10px, 50px,10px,50px; + display: flex; + justify-content: center; + text-align: center; +} +.centerIndepent{ + margin: 10px, 50px,10px,50px; + justify-content: center; + text-align: center; +} +.container-separate{ + margin-top: 20px; + +} +a{ + text-decoration-color: #A5DED3; + text-decoration:none; + color: #A5DED3; +} + +.btnIcon{ + margin-top: 50px; + margin: 16px; +} + +.registryLink{ + margin-top: 80px; +} +.back{ + padding: 20px; + justify-content:left; + margin-left: 30px; + margin-top: 30px; +} +.rudyIcon{ + justify-content: center; + color: #A5DED3; +} + +.modal-content{ + width: 80px; + display: flex; + justify-content: center; +} +.containerPop{ + background-color: #E5E5E5; + color:#232323; + text-align: center; + margin: 15px; + padding: 15px; + } + +.imagePop{ + font-size: 100px; + color: #000000; + } +.acceptDelete{ + font-size: 25px; + background-color: #47C674; + margin-right: 20px; + border-radius: 10px; + color:#2E2F32; + + } +.cancelDelete{ + font-size: 25px; + background-color: #FF385F; + margin-left: 20px; + border-radius: 12px; + padding-right: 10px; + padding-left: 10px; + color:#2E2F32; + +} +.ocultEditProfile{ + visibility: hidden; +} +.active{ + visibility: visible; +} + +.fileInput{ + border-radius: 20px; + background-color:#FAFAFA; + margin-top: 10px; + margin-left: 25px; + +} +#interest{ +margin: 20px; + color: #FAFAFA; +} +.textareaInterest{ + border-style: solid; + border-color: aqua; + width: 200px; + height: 50px; + border-radius: 20px; + text-align: center; + +} + .counter{ + margin: 5px; + /* background-color: cadetblue; */ + color:#232323; +} +.contentLikes{ + display: flex; + align-items: center; +} +.likes{ + margin: 5px; + font-size: 18px; + color:#232323; +} + +.colorLike{ + color:yellow; + +} +.sectionPosts{ + height: 100%; + background-color:#232323; +} +.postContent{ + background-color: #FAFAFA; + border-radius: 20px; + color: #232323; + margin: 15px; +} +.imgUserPost{ + width:50px; + height:50px; + border-radius:25px; + margin: 10px 5px 10px 10px; +} + @media (min-width:700px) and (max-width:1024px){ + .form-container{ + background-color:#232323; + margin-top: 0px; + padding-top: 320px; + padding-left: 150px; + padding-right: 150px; + padding-bottom: 100px; + justify-content: center; + color:#FAFAFA; + } + .back{ + padding: 20px; + margin-left: 150px; + margin-top: 0px; + } + + + #welcome-title{ + margin-bottom: 0px; + margin-top: 0px; + color: darkviolet; +} + + #instructions{ + padding: 10px; + margin-bottom: 10px; + } + + /* #editProfile{ + position: absolute; + } */ + .info-profile{ + padding-bottom: 0px; + margin-bottom: -60px; + } + + .slider{ + width: 100%; + overflow: hidden; + position: relative; + + } + + .welcome-info{ + width: 80%; + } + + .icons{ + cursor: pointer; +} + +.photo-profile{ + margin-bottom: 5px; +} + + + #nameProfile{ + margin-bottom: 0px; + } + + #welcome-title{ + margin-bottom: 0px; + margin-top: 10px; + color: darkviolet; + } + + #welcome-title{ + margin-bottom: 0px; + margin-top: 0px; + color: darkviolet; +} + + #instructions{ + padding: 10px; + margin-bottom: 10px; + } + + /* #editProfile{ + position: absolute; + } */ + .info-profile{ + padding-bottom: 0px; + margin-bottom: -60px; + } + + .slider{ + width: 100%; + overflow: hidden; + position: relative; + + } + + .welcome-info{ + width: 80%; + background-color: rgba(255, 255, 255, 0.24); + position: absolute; + bottom: 45px; + right: 75px; + } + + + #thisPhoto{ + border-radius: 50%; + } + + + /* Para el slide */ + .slider{ + width: 100%; + height: 100% ; + + margin: 0; + overflow: hidden; + background-size: cover; + } + + .slider ul{ + display: flex; + padding: 0; + + width: 300%; + animation: cambio 20s infinite; + animation-timing-function: ease-in; + } + + .slider li{ + width: 100%; + list-style: none; + } + + .slider img{ + width: 100%; + height: 100%; + } + + @keyframes cambio { + 0% { margin-left: 0; } + 20% { margin-left: 0; } + + 25% { margin-left: -100%; } + 45% { margin-left: -100%; } + + 50% { margin-left: -200%; } + 70% { margin-left: -200%; } + } + + + #goLogin{ + margin-bottom: 20px; + } diff --git a/src/views/exit.js b/src/views/exit.js new file mode 100644 index 00000000..a0d65e73 --- /dev/null +++ b/src/views/exit.js @@ -0,0 +1,9 @@ +import { root } from '../main.js'; + +export const renderExitView = () => { + + + `

Exit

+ ` + root.innerHTML = renderExitView; +}; \ No newline at end of file diff --git a/src/views/home.js b/src/views/home.js new file mode 100644 index 00000000..e69de29b diff --git a/src/views/login.js b/src/views/login.js new file mode 100644 index 00000000..159d898d --- /dev/null +++ b/src/views/login.js @@ -0,0 +1,71 @@ +import { navBar } from "../main.js"; +export default () => { + const viewLogin = ` +
+
+
+

Iniciar Sesión

+
+ +
+ + + + +
+
+ + + + +
+ + +

O accede con:

+ +
+ +
+ +
+ + +
+ + + +
+
+ + + + + `; + navBar.style.display = 'none' + return viewLogin + +} + + diff --git a/src/views/post.js b/src/views/post.js new file mode 100644 index 00000000..bba780d2 --- /dev/null +++ b/src/views/post.js @@ -0,0 +1,312 @@ +import { root } from "../main.js"; +import { navBar } from "../main.js"; +//Esto dibuja la vista donde se puede agregar un post + +let db = firebase.firestore() + +export function renderPostView() { + const posts = + `
+
+

Escribe tu microcuento:

+

Titulo:

+ + +
+ +
+ +
+ +
+ +
+ +
+
+ + ` + navBar.style.display = 'block' + root.innerHTML = posts + + + //Nodos Imagen + const fileInput = document.querySelector("#file") + const sectionPosts = document.querySelector("#putPosts") + //Nodos publicación + + const newPost = document.querySelector("#newPost") + newPost.addEventListener('click', readText) + + readFile(fileInput, sectionPosts) + + showPosts(sectionPosts) + +} + +function readFile(fileInput, sectionPosts) { + let url + + //const fileInput = document.querySelector("#file") + fileInput.onchange = (e) => { + console.log(e); + let file = e.target.files[0] + console.log(file); + firebase.storage().ref("postsList").child(file.name).put(file) + .then(snap => { + console.log(snap); + return snap.ref.getDownloadURL() + }) + .then(link => { + url = link + console.log(url); + const img = document.createElement('img') + img.src = url + sectionPosts.appendChild(img) + textImage() + }) + .catch(err => { + alert("Error:", err); + }) + } + function textImage() { + const text = document.querySelector('#body').value + const title = document.querySelector("#title").value + + firebase.auth().onAuthStateChanged(function (user) { + //console.log(user); + const docRef = db.collection('datausers/').doc(user.uid); + docRef.get().then(function (snapshot) { + let userData = snapshot.data(); + console.log(userData); + let post = { + title: title, + text: text, + user: userData.name, + photo: userData.photo,//photoURL + date: new Date(), + img: url, + uid: userData.uid + } + addNewPost(post) + .then(res => { + console.log(res) + }) + .catch(err => { + console.log("No hay nuevo post", err) + }) + addPostBD(post) + + }) + + }); + + } + +} + +function readText() { + const text = document.querySelector('#body').value + const title = document.querySelector("#title").value + /* let user = firebase.auth().currentUser; + console.log(user); + */ + firebase.auth().onAuthStateChanged(function (user) { + //console.log(user); + const docRef = db.collection('datausers/').doc(user.uid); + docRef.get().then(function (snapshot) { + let userData = snapshot.data(); + console.log(userData); + let post = { + title: title, + text: text, + user: userData.name, + photo: userData.photo,//photoURL + date: new Date(), + uid: userData.uid + } + addNewPost(post) + .then(res => { + console.log(res) + }) + .catch(err => { + console.log("No hay nuevo post", err) + }) + addPostBD(post) + + }) + + }); + +} + + +//Se agrega el post a la collección postsList en la BD +function addNewPost(post) { + return firebase.firestore().collection("postsList").add(post) +} + + +/* function dataBD() { + firebase.firestore().collection("postsList").get().then(function (docs) { + docs.forEach(function (doc) { + console.log(doc.id); + }); + }); +} +dataBD() + */ + +//Se agregan los post al perfil del usuario +function addPostBD(post) { + let user = firebase.auth().currentUser; + console.log(user); + const docRef = db.collection('datausers/').doc(user.uid); + docRef.update({ + post: firebase.firestore.FieldValue.arrayUnion(post) + }) +} + +//Muestra los posts en tiempo real +function showPosts(sectionPosts) { + + firebase.firestore().collection("postsList").onSnapshot(snap => { + clean(sectionPosts) + snap.forEach(doc => { + console.log(doc.data()); + + if (doc.data().img === undefined && doc.data().photo != undefined) { + let renderPosts = `
+ +

${doc.data().user}

+

${doc.data().title}

+

${doc.data().text}

+
+ +
${doc.data().likes}
+ +
+
` + const newNode = document.createElement("div") + newNode.innerHTML = renderPosts + sectionPosts.appendChild(newNode) + + } if (doc.data().img != undefined && doc.data().photo != undefined) { + let renderPosts = `
+ +

${doc.data().user}

+

Titulo:${doc.data().title}

+

${doc.data().text}

+ +
+ +
${doc.data().likes}
+ + +
+
` + const newNode = document.createElement("div") + newNode.innerHTML = renderPosts + sectionPosts.appendChild(newNode) + + } /* else { + let renderPosts = `
+

Autor: ${doc.data().user}

+

Titulo:${doc.data().title}

+

${doc.data().text}

+ +
+ +
${doc.data().likes}
+ +
+ +
` + const newNode = document.createElement("div") + newNode.innerHTML = renderPosts + sectionPosts.appendChild(newNode) + } */ + + //LIKES + let btnLike = document.querySelectorAll('.btnLike') + //console.log(btnLike); + let btnClick = btnLike[btnLike.length - 1] + console.log(btnClick); + + btnClick.addEventListener('click', counter) + //let resultLikes = document.querySelectorAll('.resultCounter') + //let listResultLikes = resultLikes[resultLikes.length - 1] + let countLikes = 0 + function counter() { + let user = firebase.auth().currentUser; + + console.log(user.displayName); + let whoLike = user.displayName + + let idPost = btnClick.getAttribute('dataid') + console.log(idPost); + countLikes = countLikes + 1 + console.log(countLikes); + + const docPost = firebase.firestore().collection("postsList").doc(idPost) + docPost.get().then(docPost => { + let whosLikePost = docPost.data().whoLike + console.log(whosLikePost); + /* console.log(whosLikePost.includes(whoLike)); + let checkUser = whosLikePost.includes(whoLike) */ + if (whosLikePost === undefined) { + saveLikes(countLikes, idPost, whoLike) + btnClick.classList.add('colorLike') + + } if (whosLikePost != undefined) { + console.log(whosLikePost.includes(whoLike)); + let checkUser = whosLikePost.includes(whoLike) + if (checkUser === false) { + saveLikes(countLikes, idPost, whoLike) + btnClick.classList.add('colorLike') + } + + } + }); + } + + //COMENTS + /* let btnComentPost = document.querySelectorAll('.comentPost') + let btnComent = btnComentPost[btnComentPost.length - 1] + console.log(btnComent); */ + //EDITAR + /* let btnComentPost = document.querySelectorAll('.comentPost') + let btnComent = btnComentPost[btnComentPost.length - 1] + console.log(btnComent); + */ + }) + }) + + +} + +function saveLikes(countLikes, idPost, whoLike) { + const docPost = firebase.firestore().collection("postsList").doc(idPost) + docPost.update({ + likes: firebase.firestore.FieldValue.increment(countLikes), + whoLike: [whoLike] + }) +} + + +//Antes de poner el nuevo post limpia la sectionPost para evitar se dupliquen +function clean(sectionPosts) { + sectionPosts.innerHTML = ''; +} + + diff --git a/src/views/principal.js b/src/views/principal.js new file mode 100644 index 00000000..b4111eab --- /dev/null +++ b/src/views/principal.js @@ -0,0 +1,33 @@ +import { navBar } from "../main.js"; + +export default () => { + + const principal = ` + +
+ + +
+
+
+

Microcuentos

+

ilustrados

+

*Escribe un microcuento*
*Ilustra un microcuento*
++Escribe e ilustra++

+
+
+ +
+
+
+
+ ` + + + navBar.style.display = 'none' + + return principal +} \ No newline at end of file diff --git a/src/views/profile.js b/src/views/profile.js new file mode 100644 index 00000000..a09c539a --- /dev/null +++ b/src/views/profile.js @@ -0,0 +1,320 @@ +import { root } from "../main.js"; +import { navBar } from "../main.js"; +//import { userObserver } from '/index.js' + +const db = firebase.firestore(); + +export function userObserverProfile() { + firebase.auth().onAuthStateChanged(function (user) { + // if (user) { + const docRef = db.collection('datausers/').doc(user.uid); + docRef.get().then(function (snapshot) { + let myData = snapshot.data(); + console.log(myData); + root.innerHTML = renderProfileView(myData) + edit() + + }) + /* } else { + // No user is signed in. + console.log('No user'); + } */ + + }); + +} + +/* export function renderProfileView(myData) { + //console.log(myData); + if (myData) { + const profile = + ` + +

Mi perfil

+
+
+
+
+ +

+ ${myData.name} +

+

+ ${myData.email} +

+
${myData.interests}
+ + + + + + + + + +` + navBar.style.display = 'block' + return profile + } + +} + */ +export function renderProfileView(myData) { + //console.log(myData); + if (myData) { + const profile = + ` + +

Mi perfil

+
+
+
+
+ + +

${myData.name}

+

${myData.email}

+
+
${myData.interests}
+
+ +
+ + +
+ + + +` + navBar.style.display = 'block' + return profile + } + +} + +/* export function renderProfileView(myData) { + //console.log(myData); + if (myData) { + const profile = + ` + +

Mi perfil

+
+
+
+
+ +

+ ${myData.name} +

+

+ ${myData.email} +

+
${myData.interests}
+ + + + + + + + +` + navBar.style.display = 'block' + return profile + } + +} */ + + +function edit() { + //Listeners modal + const btnCloseChange = document.querySelector('#btnCloseChange'); + btnCloseChange.addEventListener('click', closeChange); + const saveChange = document.querySelector('#saveChange'); + function closeChange() { + saveChange.classList.remove('is-active'); + } + + //Listeners Editar Perfil + let btnEditProfile = document.querySelector('#editProfile') + let btnSaveProfile = document.querySelector('#saveProfile') + btnEditProfile.addEventListener('click', editProfile) + btnSaveProfile.addEventListener('click', saveProfile) + let textareaInterest = document.querySelector('#interestsProfile') + //console.log(userObserver) + + + function editProfile() { + let file = document.querySelector('#file') + let nameProfile = document.querySelector('#nameProfile').contentEditable = 'true' + let emailProfile = document.querySelector('#emailProfile').contentEditable = 'true' + let prevImage = document.querySelector('#changeImage') + let photoProfile = document.querySelector('#photoProfile') + readFile(file, photoProfile, prevImage) + + + //console.log(text.innerHTML) + btnSaveProfile.classList.add('active'); + textareaInterest.classList.add('active'); + file.classList.add('active') + } + + function readFile(file, photoProfile, prevImage) { + + + //const fileInput = document.querySelector("#file") + file.onchange = (e) => { + console.log(e); + let file = e.target.files[0] + console.log(file); + firebase.storage().ref("photoUsers").child(file.name).put(file) + .then(snap => { + console.log(snap); + return snap.ref.getDownloadURL() + + }) + .then(link => { + prevImage.remove() + let url = link + console.log(url); + const img = document.createElement('img') + img.id = 'newImage' + img.src = url + photoProfile.appendChild(img) + }) + + + .catch(err => { + alert("Error:", err); + }) + + } + } + + + function saveProfile() { + + let divInterest = document.querySelector('#interest') + let nameProfile = document.querySelector('#nameProfile') + let emailProfile = document.querySelector('#emailProfile') + + //let textareaInterest = document.querySelector('#interestsProfile') + let interestsProfile = textareaInterest.value + divInterest.innerHTML = interestsProfile + + //console.log(nameProfile.innerHTML) + //console.log(emailProfile.innerHTML) + let newNameProfile = nameProfile.innerHTML + let newEmailProfile = emailProfile.innerHTML + + btnSaveProfile.classList.remove('active'); + textareaInterest.classList.remove('active'); + file.classList.remove('active'); + if (btnSaveProfile.classList != 'active') { + nameProfile.contentEditable = 'false' + emailProfile.contentEditable = 'false' + } + + //profileUpdate(newNameProfile, newEmailProfile) + saveProfileBD(newNameProfile, newEmailProfile, interestsProfile) + + } + + function saveProfileBD(newNameProfile, newEmailProfile, interestsProfile) { + let user = firebase.auth().currentUser; + let imagProfile = document.querySelector('#newImage') + let urlImage + if (imagProfile) { + urlImage = imagProfile.getAttribute('src') + console.log(urlImage); + const docRef = db.collection('datausers/').doc(user.uid);//la / y el + user.uid hace que no se duplique el usuario + docRef.update({ + name: newNameProfile, + email: newEmailProfile, + interests: interestsProfile, + photo: urlImage, + //password: newPassword, + uid: user.uid + }) + .then(function () { + saveChange.classList.add('is-active'); + console.log(saveChange); + }) + .catch(function (error) { + console.log('Hubo en error:', error); + }) + } else { + let thisPhoto = document.querySelector('#thisPhoto') + urlImage = thisPhoto.getAttribute('src') + console.log(urlImage); + const docRef = db.collection('datausers/').doc(user.uid);//la / y el + user.uid hace que no se duplique el usuario + docRef.update({ + name: newNameProfile, + email: newEmailProfile, + interests: interestsProfile, + photo: urlImage, + //password: newPassword, + uid: user.uid + }) + .then(function () { + saveChange.classList.add('is-active'); + console.log('Se actualizaron datos de perfil'); + }) + .catch(function (error) { + console.log('Hubo en error:', error); + }) + + } + + /* const docRef = db.collection('datausers/').doc(user.uid);//la / y el + user.uid hace que no se duplique el usuario + docRef.update({ + name: newNameProfile, + email: newEmailProfile, + interests: interestsProfile, + photo: urlImage, + //password: newPassword, + uid: user.uid + }) + .then(function () { + saveChange.classList.add('is-active'); + console.log(saveChange); + }) + .catch(function (error) { + console.log('Hubo en error:', error); + }) */ + } + + +} + + + + diff --git a/src/views/signIn.js b/src/views/signIn.js new file mode 100644 index 00000000..2c1848b8 --- /dev/null +++ b/src/views/signIn.js @@ -0,0 +1,82 @@ +import { navBar } from "../main.js"; +export default () => { + const viewSignIn = ` +
+
+
+

Crea una cuenta

+
+
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +

O accede con:

+
+ + +
+ +
+
+ + + + + + + + ` + navBar.style.display = 'none' + return viewSignIn +} \ No newline at end of file diff --git a/src/views/viewcontroler.js b/src/views/viewcontroler.js new file mode 100644 index 00000000..a4497bea --- /dev/null +++ b/src/views/viewcontroler.js @@ -0,0 +1,15 @@ +/* import { components } from '../index.js' +import { root } from "../main.js"; +// Funcion que cambia la vista +export const changeView = (route) => { + root.innerHTML = ''; + switch (route) { + case '#/Home': { return root.appendChild(components.home); } + case '#/Post': { return root.appendChild(components.post); } + case '#/My_profile': { return root.appendChild(components.profile); } + case '#/Exit': { return root.appendChild(components.exit); } + default: + break; + } + console.log(route); +}; */ \ No newline at end of file diff --git a/storage.rules b/storage.rules new file mode 100644 index 00000000..d494542e --- /dev/null +++ b/storage.rules @@ -0,0 +1,7 @@ +service firebase.storage { + match /b/{bucket}/o { + match /{allPaths=**} { + allow read, write: if request.auth!=null; + } + } +} diff --git a/test/example.spec.js b/test/example.spec.js index 1aca05e9..f5775824 100644 --- a/test/example.spec.js +++ b/test/example.spec.js @@ -1,7 +1,32 @@ -import { example } from '../src/example.js'; +import mockFirebase from '../_mocks_/firebase-mock.js' +//import { loginGoogle } from '../src/index.js'; +//import * as login from '../src/index.js' -describe('example', () => { +/* global.firebase = { + auth: jest.fn(() => ({ + signInWithPopup: jest.fn(() => new Promise((resolve, reject) => { + resolve(true) + })) + })) +} + +test('Login email', () => { + let email = 'ejemplo@hotmail.com' + let password = 'ejem' + + expect(auth.loginUser(email, password)).toBe('No cumple con 6 caracteres') + +}) */ + + + + +global.firebase = mockFirebase(); + + +describe('loginGoogle', () => { it('debería ser una función', () => { - expect(typeof example).toBe('function'); + expect(typeof loginGoogle).toBe('function'); }); -}); \ No newline at end of file +}); +