diff --git a/docs/Views/createPost.js b/docs/Views/createPost.js new file mode 100644 index 00000000..991fd9d1 --- /dev/null +++ b/docs/Views/createPost.js @@ -0,0 +1,39 @@ +import loginFunctions from '../firebase/login.js'; +import { userAccess, createNewPost } from '../firebase/showData.js'; + +export default () => { + const createPostView = document.createElement('div'); + createPostView.setAttribute('class', 'Home'); + const header = document.querySelector('header'); + header.style.display = 'none'; + createPostView.innerHTML = ''; + createPostView.innerHTML = ` +
+
+ logo + Home + createPost + Profile + Cerrar Sesion +
+
+
+
+
Hola:

+ + +
+
`; + const logOutBtn = createPostView.querySelector('#logOutBtn'); + const newPostContent = createPostView.querySelector('#newTextPost'); + const userPhoto = createPostView.querySelector('#userPhoto'); + const userName = createPostView.querySelector('#username'); + userAccess(userName, userPhoto); + const submitNewPost = createPostView.querySelector('#submitNewPost'); + submitNewPost.addEventListener('click', (e) => { + e.preventDefault(); + createNewPost(newPostContent.value); + }); + logOutBtn.addEventListener('click', loginFunctions.sesionLogOut); + return createPostView; +}; diff --git a/docs/Views/home.js b/docs/Views/home.js new file mode 100644 index 00000000..6ff13b55 --- /dev/null +++ b/docs/Views/home.js @@ -0,0 +1,43 @@ +import loginFunctions from '../firebase/login.js'; +import { createNewPost, postTemplate } from '../firebase/showData.js'; + +export default () => { + const homeView = document.createElement('div'); + homeView.setAttribute('class', 'Home'); + const header = document.querySelector('header'); + header.style.display = 'none'; + homeView.innerHTML = ''; + homeView.innerHTML = ` +
+
+ logo + Home + Profile + Cerrar Sesion +
+
+
+
+
Bienvenida ${localStorage.getItem('displayName')}
+ + +
+
+
+
`; + const logOutBtn = homeView.querySelector('#logOutBtn'); + logOutBtn.addEventListener('click', loginFunctions.sesionLogOut); + const postContainer = homeView.querySelector('.sesionPrincipal1'); + + const newPostContent = homeView.querySelector('#newTextPost'); + const submitNewPost = homeView.querySelector('#submitNewPost'); + + submitNewPost.addEventListener('click', (e) => { + e.preventDefault(); + createNewPost(newPostContent.value); + newPostContent.value = ''; + }); + + postTemplate(postContainer); + return homeView; +}; diff --git a/docs/Views/index.js b/docs/Views/index.js new file mode 100644 index 00000000..085e3594 --- /dev/null +++ b/docs/Views/index.js @@ -0,0 +1,15 @@ +import Main from './main.js'; +import Register from './register.js'; +import Recovery from './passwordRecovery.js'; +import Home from './home.js'; +import Profile from './profile.js'; + +const components = { + principal: Main, + register: Register, + recoveryPass: Recovery, + home: Home, + profile: Profile, +}; + +export { components }; diff --git a/docs/Views/main.js b/docs/Views/main.js new file mode 100644 index 00000000..242de02e --- /dev/null +++ b/docs/Views/main.js @@ -0,0 +1,36 @@ +import loginFunctions from '../firebase/login.js'; + +export default () => { + const loginView = document.createElement('div'); + loginView.setAttribute('class', 'viewsStyle'); + loginView.innerHTML = ` +

Inicia Sesión con tu email

+
+ + + +
¿Has olvidado la contraseña?
+
+
+ +
+ +

¿No tienes cuenta? Registrate

+
`; + + // Nodos + const loginEmail = loginView.querySelector('#loginEmail'); + const loginPassword = loginView.querySelector('#loginPassword'); + const loginButton = loginView.querySelector('#loginButton'); + const facebookLogin = loginView.querySelector('#facebookLogin'); + const googleLogin = loginView.querySelector('#googleLogin'); + + // Listeners + googleLogin.addEventListener('click', loginFunctions.google); + facebookLogin.addEventListener('click', loginFunctions.facebook); + loginButton.addEventListener('click', (e) => { + e.preventDefault(); + loginFunctions.emailLogIn(loginEmail.value, loginPassword.value); + }); + return loginView; +}; diff --git a/docs/Views/passwordRecovery.js b/docs/Views/passwordRecovery.js new file mode 100644 index 00000000..a60314d7 --- /dev/null +++ b/docs/Views/passwordRecovery.js @@ -0,0 +1,30 @@ +import loginFunctions from '../firebase/login.js'; + +export default () => { + const recView = document.createElement('div'); + recView.setAttribute('class', 'viewsStyle'); + recView.innerHTML = ''; + recView.innerHTML = ` +

Recupera tu contraseña

+

Te enviaremos un correo electrónico para recuperar tu contraseña

+
+ + +
+
+

O

+ + +

¿No tienes cuenta? Registrate

+
`; + + // Nodos + const googleLogin = recView.querySelector('#googleLogin'); + const facebookLogin = recView.querySelector('#facebookLogin'); + + // Listeners + googleLogin.addEventListener('click', loginFunctions.google); + facebookLogin.addEventListener('click', loginFunctions.facebook); + + return recView; +}; diff --git a/docs/Views/profile.js b/docs/Views/profile.js new file mode 100644 index 00000000..b9bfc27a --- /dev/null +++ b/docs/Views/profile.js @@ -0,0 +1,53 @@ +import loginFunctions from '../firebase/login.js'; +import { currentUserPosts } from '../firebase/showData.js'; + +export default () => { + const profileView = document.createElement('div'); + profileView.setAttribute('class', 'Home'); + const header = document.querySelector('header'); + header.style.display = 'none'; + profileView.innerHTML = ''; + profileView.innerHTML = ` +
+
+ logo + Home + Profile + Cerrar Sesion +
+
+
+
+ photo +

${localStorage.getItem('displayName')}

+
+ +
+

Edita tus datos

+ + + + +
+
+
+
+
`; + const logOutBtn = profileView.querySelector('#logOutBtn'); + logOutBtn.addEventListener('click', loginFunctions.sesionLogOut); + const postContainer = profileView.querySelector('.sesionPrincipal1'); + + // funcion provisional + const editBtn = profileView.querySelector('#editProfile'); + editBtn.addEventListener('click', () => { + const editFields = profileView.querySelector('.updateInfo'); + editFields.style.display = 'flex'; + const updateInfo = profileView.querySelector('#sendUpdate'); + updateInfo.addEventListener('click', () => { + editFields.style.display = 'none'; + }); + }); + + currentUserPosts(postContainer); + return profileView; +}; diff --git a/docs/Views/register.js b/docs/Views/register.js new file mode 100644 index 00000000..4b2c2346 --- /dev/null +++ b/docs/Views/register.js @@ -0,0 +1,37 @@ +import loginFunctions from '../firebase/login.js'; + +export default () => { + const regView = document.createElement('div'); + regView.setAttribute('class', 'viewsStyle'); + regView.innerHTML = ''; + regView.innerHTML = ` +

Abre una cuenta:

+
+
+
+ +
¿Ya tienes una cuenta? Inicia Sesión
+
+
+

O

+ + +
`; + // Nodos + const registerEmail = regView.querySelector('#registerEmail'); + const registerPassword = regView.querySelector('#registerPassword'); + const registerButton1 = regView.querySelector('#registerButton1'); + const googleLogin = regView.querySelector('#googleLogin'); + const facebookLogin = regView.querySelector('#facebookLogin'); + + // Listeners + googleLogin.addEventListener('click', loginFunctions.google); + facebookLogin.addEventListener('click', loginFunctions.facebook); + + registerButton1.addEventListener('click', (e) => { + e.preventDefault(); + loginFunctions.emailRegister(registerEmail.value, registerPassword.value); + }); + + return regView; +}; diff --git a/docs/Views/router.js b/docs/Views/router.js new file mode 100644 index 00000000..d5159eda --- /dev/null +++ b/docs/Views/router.js @@ -0,0 +1,35 @@ +import { components } from './index.js'; + +const router = (route) => { + const container = document.querySelector('#root'); + container.innerHTML = ''; + switch (route) { + case '': + case '#/': + case '#/login': { + container.appendChild(components.principal()); + break; + } + case '#/register': { + container.appendChild(components.register()); + break; + } + case '#/passwordRecovery': { + container.appendChild(components.recoveryPass()); + break; + } + case '#/home': { + container.appendChild(components.home()); + break; + } + case '#/profile': { + container.appendChild(components.profile()); + break; + } + default: { + break; + } + } +}; + +export { router }; diff --git a/docs/example.js b/docs/example.js new file mode 100644 index 00000000..320e8301 --- /dev/null +++ b/docs/example.js @@ -0,0 +1,3 @@ +// export const example = () => { +// // aquí tu código +// } diff --git a/docs/firebase/login.js b/docs/firebase/login.js new file mode 100644 index 00000000..3c59bb96 --- /dev/null +++ b/docs/firebase/login.js @@ -0,0 +1,95 @@ +/* eslint-disable no-console */ +/* eslint-disable no-alert */ +export const database = firebase.firestore(); + +export default { + google: () => { + const provider = new firebase.auth.GoogleAuthProvider(); + firebase.auth().signInWithPopup(provider) + .then(() => { + // const user = result.user; + const currentUser = firebase.auth().currentUser; + database.collection('users').doc(currentUser.uid).set({ + id: currentUser.uid, + name: currentUser.displayName, + email: currentUser.email, + photo: currentUser.photoURL, + }); + window.location.hash = '#/home'; + }); + }, + facebook: () => { + const provider = new firebase.auth.FacebookAuthProvider(); + firebase.auth().signInWithPopup(provider) + .then(() => { + // const user = result.user; + const currentUser = firebase.auth().currentUser; + console.log(currentUser); + database.collection('users').doc(currentUser.uid).set({ + id: currentUser.uid, + name: currentUser.displayName, + email: currentUser.email, + photo: currentUser.photoURL, + }); + window.location.hash = '#/home'; + }); + }, + emailRegister: (mail, password) => { + firebase.auth().createUserWithEmailAndPassword(mail, password) + .then(() => { + // const user = result.user; + const currentUser = firebase.auth().currentUser; + console.log(currentUser); + database.collection('users').doc(currentUser.uid).set({ + id: currentUser.uid, + name: currentUser.displayName, + email: currentUser.email, + photo: currentUser.photoURL, + }); + window.location.hash = '#/home'; + }).catch((error) => { + const errorCode = error.code; + switch (errorCode) { + case 'auth/email-already-in-use': + alert('El email ingresado ya existe'); + break; + case 'auth/weak-password': + alert('La contraseña ingresada no es segura, intente de nuevo'); + break; + default: + alert(errorCode); + } + }); + }, + emailLogIn: (email, password) => { + firebase.auth().signInWithEmailAndPassword(email, password) + .then(() => { + window.location.hash = '#/home'; + }).catch((error) => { + const errorCode = error.code; + switch (errorCode) { + case 'auth/user-not-found': + alert('Usuario no encontrado, intenta de nuevo o registrate'); + break; + case 'auth/wrong-password': + alert('La contraseña es incorrecta, intenta de nuevo'); + break; + case 'auth/invalid-email': + alert('El correo ingresado no es válido'); + break; + default: + alert('Algo salió mal. Intente de nuevo'); + } + }); + }, + sesionLogOut: () => { + firebase.auth().signOut() + .then(() => { + alert('Sesión cerrada'); + document.querySelector('header').style.display = ''; + window.location.hash = '#/login'; + }).catch(() => { + alert('Algo salió mal. Intente de nuevo'); + }); + }, +}; diff --git a/docs/firebase/showData.js b/docs/firebase/showData.js new file mode 100644 index 00000000..81ac06bf --- /dev/null +++ b/docs/firebase/showData.js @@ -0,0 +1,151 @@ +/* eslint-disable no-alert */ +/* eslint-disable no-param-reassign */ +import { database } from './login.js'; + +// const storage = firebase.storage(); + +firebase.auth().onAuthStateChanged((user) => { + if (user) { + console.log(user); + localStorage.setItem('uid', user.uid); + localStorage.setItem('displayName', user.displayName); + localStorage.setItem('photoURL', user.photoURL); + } else { + console.log('No user is signed in'); + localStorage.removeItem('uid'); + localStorage.removeItem('displayName'); + localStorage.removeItem('photoURL'); + } +}); + +const dateConverter = (timeStampFormat) => { + const date = new Date(timeStampFormat * 1000); + const month = date.getMonth() + 1; + const day = date.getDate(); + const year = date.getFullYear(); + const hour = date.getHours(); + const minute = date.getMinutes(); + return (`${day}-${month}-${year} / ${hour}:${minute}`); +}; + +const deleteOption = (event) => { + database.collection('posts').doc(event.target.id).delete() + .then(() => { + alert('Document successfully deleted!'); + }) + .catch((error) => { + alert('Error removing document: ', error); + }); +}; + +const editPost = (event) => { + const modalEdit = document.querySelector('#modalEdit'); + document.querySelector('#modalEdit').style.display = 'block'; + const closeBtn = document.querySelector('#closeBtn'); + closeBtn.addEventListener('click', () => { + modalEdit.style.display = 'none'; + }); + document.querySelector('#editPostText').value = event.target.getAttribute('data-content'); + const btnEdit = document.querySelector('#submitEditPost'); + btnEdit.addEventListener('click', () => { + const postsRef = database.collection('posts').doc(event.target.id); + console.log(event.target.id); + const newContent = document.querySelector('#newTextPost').value; + console.log(newContent); + return postsRef.update({ + postContent: newContent, + }) + .then(() => { + alert('Document successfully updated!'); + document.querySelector('#modalEdit').style.display = 'none'; + }) + .catch((error) => { + // The document probably doesn't exist. + console.error('Error updating document: ', error); + }); + }); +}; + +export const createNewPost = (content) => { + const currentUserData = firebase.auth().currentUser; + database.collection('posts').add({ + postOwner: currentUserData.uid, + postNameOwner: currentUserData.displayName, + postPhotoOwner: currentUserData.photoURL, + postContent: content, + date: new Date(), + likes: {}, + }) + .then(() => { + alert('Tu post se ha guardado'); + }); +}; + +export const postTemplate = (templateContainer) => { + database.collection('posts').onSnapshot((querySnapshot) => { + templateContainer.innerHTML = ''; + querySnapshot.forEach((doc) => { + const timestampFormat = doc.data().date.seconds; + const newDateFormat = dateConverter(timestampFormat); + const userTemplate = ` +
+
+ +
+ ${doc.data().postNameOwner}
+ ${doc.data().postContent}
+ ${newDateFormat} +
+
+
+ + +
+
`; + templateContainer.innerHTML += userTemplate; + }); + }); +}; + +// obtener post propios +export const currentUserPosts = (postContainer) => { + postContainer.innerHTML = ''; + // const prueba = localStorage.getItem('uid'); + // console.log(prueba); + const currentUserRef = database.collection('posts'); + const query = currentUserRef.where('postOwner', '==', localStorage.getItem('uid')); + query.get() + .then((querySnapshot) => { + querySnapshot.forEach((doc) => { + // doc.data() is never undefined for query doc snapshots + const timestampFormat = doc.data().date.seconds; + const newDateFormat = dateConverter(timestampFormat); + const userTemplate = ` +
+
+ +
+ ${doc.data().postNameOwner}
+ ${doc.data().postContent}
+ ${newDateFormat} +
+
+
+ + + + +
+
`; + postContainer.innerHTML += userTemplate; + const DeleteBtns = postContainer.querySelectorAll('.delete'); + DeleteBtns.forEach(btn => btn.addEventListener('click', deleteOption)); + + const btn = postContainer.querySelectorAll('.edit'); + btn.forEach(bt => bt.addEventListener('click', editPost)); + }); + }) + .catch((error) => { + console.log('Error getting documents: ', error); + }); +}; diff --git a/docs/images/CodeMakers.png b/docs/images/CodeMakers.png new file mode 100644 index 00000000..cd3490fe Binary files /dev/null and b/docs/images/CodeMakers.png differ diff --git a/docs/images/Google.PNG b/docs/images/Google.PNG new file mode 100644 index 00000000..63478916 Binary files /dev/null and b/docs/images/Google.PNG differ diff --git a/docs/images/Google2.PNG b/docs/images/Google2.PNG new file mode 100644 index 00000000..63478916 Binary files /dev/null and b/docs/images/Google2.PNG differ diff --git a/docs/images/borrar.svg b/docs/images/borrar.svg new file mode 100644 index 00000000..62f5af1a --- /dev/null +++ b/docs/images/borrar.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/casa.svg b/docs/images/casa.svg new file mode 100644 index 00000000..b1c4a0d5 --- /dev/null +++ b/docs/images/casa.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/cerrar-sesion.svg b/docs/images/cerrar-sesion.svg new file mode 100644 index 00000000..1e35d224 --- /dev/null +++ b/docs/images/cerrar-sesion.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/corazon (1).svg b/docs/images/corazon (1).svg new file mode 100644 index 00000000..3daeba62 --- /dev/null +++ b/docs/images/corazon (1).svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/facebook.PNG b/docs/images/facebook.PNG new file mode 100644 index 00000000..84b0957d Binary files /dev/null and b/docs/images/facebook.PNG differ diff --git a/docs/images/facebook1.PNG b/docs/images/facebook1.PNG new file mode 100644 index 00000000..84b0957d Binary files /dev/null and b/docs/images/facebook1.PNG differ diff --git a/docs/images/facebook4.png b/docs/images/facebook4.png new file mode 100644 index 00000000..640ee7ac Binary files /dev/null and b/docs/images/facebook4.png differ diff --git a/docs/images/google4.png b/docs/images/google4.png new file mode 100644 index 00000000..f8fd170e Binary files /dev/null and b/docs/images/google4.png differ diff --git a/docs/images/profile.svg b/docs/images/profile.svg new file mode 100644 index 00000000..c700cfae --- /dev/null +++ b/docs/images/profile.svg @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/rectification.svg b/docs/images/rectification.svg new file mode 100644 index 00000000..0782e1a3 --- /dev/null +++ b/docs/images/rectification.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/writePost.svg b/docs/images/writePost.svg new file mode 100644 index 00000000..edfd0d5f --- /dev/null +++ b/docs/images/writePost.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..3da734fb --- /dev/null +++ b/docs/index.html @@ -0,0 +1,56 @@ + + + + + + + Code Makers + + + +
+
+ +

Unete a la Red Social de Programadoras

+
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/index.js b/docs/index.js new file mode 100644 index 00000000..5725fca1 --- /dev/null +++ b/docs/index.js @@ -0,0 +1,8 @@ +import { router } from './Views/router.js'; + +const init = () => { + router(window.location.hash); + window.addEventListener('hashchange', () => router(window.location.hash)); +}; + +window.addEventListener('load', init); diff --git a/docs/styles.css b/docs/styles.css new file mode 100644 index 00000000..7a50eba2 --- /dev/null +++ b/docs/styles.css @@ -0,0 +1,244 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto:500,700&display=swap'); + +html, body { + margin: 0; + padding: 0; + height: 100%; + font-family: 'Roboto', sans-serif; +} +/* contenedor principal */ +.container { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; +} + +/* header */ +header { + padding: 0.2rem; + background: rgb(47, 141, 218); + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} +.codeMakers {width: 12rem; height: 4rem;} +.viewsStyle { + width: 90%; +} +.views { + width: 90%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; +} +/* iniciar sesion con fb y google */ +.conectWithSocialMedia { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.buttons{ + border: 0; + height: 4rem; + margin: 0; + } +/* formulario */ +.registerForm { + width: 100%; + height: 50%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; +} +.recoveryForm { + width: 100%;; + height: 30%; + margin-bottom: 2rem; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; +} +input { + border: 0; + width: 100%; + height: 2rem; + background: linear-gradient(0deg, rgba(154,156,156,1) 0%, rgba(245,245,242,1) 100%); +} +button { + width: 100%; + height: 2.5rem; + border: 0; +} +.registerButton { + border: 0; + background: rgb(47, 141, 218); + border-radius: 18px 18px 18px 18px; + border: 6px outset rgb(47, 141, 218); + font-weight: bold; +} + + +/* vista de home */ +.Home { + width: 112%; + height: auto; +} +.homeOptions { + width: 100%; + display: flex; + justify-content: space-around; + align-items: center; +} + .btnHeader {width: 2rem; height: 2rem;} +.sesionPrincipal, .sesionPrincipal1 { + padding: 0; + margin: 1rem 0; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +} +.newPost { + width: 90%; + align-content: center; + display: flex; + flex-direction: column; +} +.welcome { + display: flex; + flex-direction: column; + align-items: center; + margin: 2rem 0; +} +.postForm { + width: 100%; + resize: none; +} + +hr {width: 90%; border-color: rgb(47, 141, 218);} +.postContainer { + margin: 0.5rem 0.3rem; + width: 90%; + padding: 0.5rem; + display: flex; + flex-direction: column; + justify-content: center; + border-radius: 26px 26px 26px 26px; + border: 0.25rem dashed #bdb5bd; + background: rgb(243, 243, 243); +} + .post { + display: flex; + width: 100%; + justify-content: space-around; + } + .postAuthor { + width: 4rem; + height: 4rem; + } + .postContent { + width: 85%; + height: auto; + padding: 0.3rem; + } + #date { + font-size: small; + color: #424040; + } + #ownerName {color: darkviolet;} + .postOptions { + width: 100%; + display: flex; + justify-content: flex-end; + } + .likes { + width: 1rem; + height: 1rem; + margin: 0.3rem 0.5rem; + } +textarea { + border-radius: 16px 16px 16px 16px; + border: 3px solid rgb(47, 141, 218); +} + +/* modal */ +.flex{ + width: 100%; + height:100%; + display: flex; + justify-content: space-between; + align-items: center; +} +.modal{ + display: none; + position: fixed; + overflow: auto; + width: 100%; + height:100%; + background: rgba(0, 0, 0, 0.452); +} +.contenido-modal{ + position: relative; + background-color: #ffffff; + margin: auto; + width: 90%; + box-shadow: 0 0 6px 0 rgba(0, 0, 0, .4); + animation-name: modal; + animation-duration: 1s; +} +@keyframes modal{ + from{top:-330px; opacity:0;} + to{top:0; opacity:1;} +} +.close{ + font-size: 1.5rem; + font-weight: bold; +} +.modal-header { + width: 95%; + height: 2rem; + padding: 0.5rem; + background: #EBE134; +} +.modal-body{ + padding: 20px 16px; +} +/* profile view */ +.nameandphoto { + margin: 5%; + display: flex; + width: 80%; + justify-content: space-around; +} +.userPhoto { + border-radius: 3.5rem; + width: 6rem; + height: 6rem; +} + +.updateInfo { + display: none; + flex-direction: column; + align-items: center; + width: 85%; + border-radius: 26px 26px 26px 26px; + border: 0.25rem dashed #bdb5bd; + background: rgb(243, 243, 243); + padding: 1rem; +} +.updateBtns { + width: 50%; + margin: 1rem; + background: rgb(47, 141, 218); + border-radius: 1rem; + border: 0.15rem solid rgb(0, 1, 41); + font-weight: bolder; +} diff --git a/package.json b/package.json index 9a365577..796f1d15 100644 --- a/package.json +++ b/package.json @@ -33,4 +33,4 @@ "stylelint": "^10.1.0", "stylelint-config-recommended": "^2.2.0" } -} \ No newline at end of file +} diff --git a/src/Views/home.js b/src/Views/home.js new file mode 100644 index 00000000..6ff13b55 --- /dev/null +++ b/src/Views/home.js @@ -0,0 +1,43 @@ +import loginFunctions from '../firebase/login.js'; +import { createNewPost, postTemplate } from '../firebase/showData.js'; + +export default () => { + const homeView = document.createElement('div'); + homeView.setAttribute('class', 'Home'); + const header = document.querySelector('header'); + header.style.display = 'none'; + homeView.innerHTML = ''; + homeView.innerHTML = ` +
+
+ logo + Home + Profile + Cerrar Sesion +
+
+
+
+
Bienvenida ${localStorage.getItem('displayName')}
+ + +
+
+
+
`; + const logOutBtn = homeView.querySelector('#logOutBtn'); + logOutBtn.addEventListener('click', loginFunctions.sesionLogOut); + const postContainer = homeView.querySelector('.sesionPrincipal1'); + + const newPostContent = homeView.querySelector('#newTextPost'); + const submitNewPost = homeView.querySelector('#submitNewPost'); + + submitNewPost.addEventListener('click', (e) => { + e.preventDefault(); + createNewPost(newPostContent.value); + newPostContent.value = ''; + }); + + postTemplate(postContainer); + return homeView; +}; diff --git a/src/Views/index.js b/src/Views/index.js new file mode 100644 index 00000000..085e3594 --- /dev/null +++ b/src/Views/index.js @@ -0,0 +1,15 @@ +import Main from './main.js'; +import Register from './register.js'; +import Recovery from './passwordRecovery.js'; +import Home from './home.js'; +import Profile from './profile.js'; + +const components = { + principal: Main, + register: Register, + recoveryPass: Recovery, + home: Home, + profile: Profile, +}; + +export { components }; diff --git a/src/Views/main.js b/src/Views/main.js new file mode 100644 index 00000000..242de02e --- /dev/null +++ b/src/Views/main.js @@ -0,0 +1,36 @@ +import loginFunctions from '../firebase/login.js'; + +export default () => { + const loginView = document.createElement('div'); + loginView.setAttribute('class', 'viewsStyle'); + loginView.innerHTML = ` +

Inicia Sesión con tu email

+
+ + + +
¿Has olvidado la contraseña?
+
+
+ +
+ +

¿No tienes cuenta? Registrate

+
`; + + // Nodos + const loginEmail = loginView.querySelector('#loginEmail'); + const loginPassword = loginView.querySelector('#loginPassword'); + const loginButton = loginView.querySelector('#loginButton'); + const facebookLogin = loginView.querySelector('#facebookLogin'); + const googleLogin = loginView.querySelector('#googleLogin'); + + // Listeners + googleLogin.addEventListener('click', loginFunctions.google); + facebookLogin.addEventListener('click', loginFunctions.facebook); + loginButton.addEventListener('click', (e) => { + e.preventDefault(); + loginFunctions.emailLogIn(loginEmail.value, loginPassword.value); + }); + return loginView; +}; diff --git a/src/Views/passwordRecovery.js b/src/Views/passwordRecovery.js new file mode 100644 index 00000000..a60314d7 --- /dev/null +++ b/src/Views/passwordRecovery.js @@ -0,0 +1,30 @@ +import loginFunctions from '../firebase/login.js'; + +export default () => { + const recView = document.createElement('div'); + recView.setAttribute('class', 'viewsStyle'); + recView.innerHTML = ''; + recView.innerHTML = ` +

Recupera tu contraseña

+

Te enviaremos un correo electrónico para recuperar tu contraseña

+
+ + +
+
+

O

+ + +

¿No tienes cuenta? Registrate

+
`; + + // Nodos + const googleLogin = recView.querySelector('#googleLogin'); + const facebookLogin = recView.querySelector('#facebookLogin'); + + // Listeners + googleLogin.addEventListener('click', loginFunctions.google); + facebookLogin.addEventListener('click', loginFunctions.facebook); + + return recView; +}; diff --git a/src/Views/profile.js b/src/Views/profile.js new file mode 100644 index 00000000..b9bfc27a --- /dev/null +++ b/src/Views/profile.js @@ -0,0 +1,53 @@ +import loginFunctions from '../firebase/login.js'; +import { currentUserPosts } from '../firebase/showData.js'; + +export default () => { + const profileView = document.createElement('div'); + profileView.setAttribute('class', 'Home'); + const header = document.querySelector('header'); + header.style.display = 'none'; + profileView.innerHTML = ''; + profileView.innerHTML = ` +
+
+ logo + Home + Profile + Cerrar Sesion +
+
+
+
+ photo +

${localStorage.getItem('displayName')}

+
+ +
+

Edita tus datos

+ + + + +
+
+
+
+
`; + const logOutBtn = profileView.querySelector('#logOutBtn'); + logOutBtn.addEventListener('click', loginFunctions.sesionLogOut); + const postContainer = profileView.querySelector('.sesionPrincipal1'); + + // funcion provisional + const editBtn = profileView.querySelector('#editProfile'); + editBtn.addEventListener('click', () => { + const editFields = profileView.querySelector('.updateInfo'); + editFields.style.display = 'flex'; + const updateInfo = profileView.querySelector('#sendUpdate'); + updateInfo.addEventListener('click', () => { + editFields.style.display = 'none'; + }); + }); + + currentUserPosts(postContainer); + return profileView; +}; diff --git a/src/Views/register.js b/src/Views/register.js new file mode 100644 index 00000000..4b2c2346 --- /dev/null +++ b/src/Views/register.js @@ -0,0 +1,37 @@ +import loginFunctions from '../firebase/login.js'; + +export default () => { + const regView = document.createElement('div'); + regView.setAttribute('class', 'viewsStyle'); + regView.innerHTML = ''; + regView.innerHTML = ` +

Abre una cuenta:

+
+
+
+ +
¿Ya tienes una cuenta? Inicia Sesión
+
+
+

O

+ + +
`; + // Nodos + const registerEmail = regView.querySelector('#registerEmail'); + const registerPassword = regView.querySelector('#registerPassword'); + const registerButton1 = regView.querySelector('#registerButton1'); + const googleLogin = regView.querySelector('#googleLogin'); + const facebookLogin = regView.querySelector('#facebookLogin'); + + // Listeners + googleLogin.addEventListener('click', loginFunctions.google); + facebookLogin.addEventListener('click', loginFunctions.facebook); + + registerButton1.addEventListener('click', (e) => { + e.preventDefault(); + loginFunctions.emailRegister(registerEmail.value, registerPassword.value); + }); + + return regView; +}; diff --git a/src/Views/router.js b/src/Views/router.js new file mode 100644 index 00000000..d5159eda --- /dev/null +++ b/src/Views/router.js @@ -0,0 +1,35 @@ +import { components } from './index.js'; + +const router = (route) => { + const container = document.querySelector('#root'); + container.innerHTML = ''; + switch (route) { + case '': + case '#/': + case '#/login': { + container.appendChild(components.principal()); + break; + } + case '#/register': { + container.appendChild(components.register()); + break; + } + case '#/passwordRecovery': { + container.appendChild(components.recoveryPass()); + break; + } + case '#/home': { + container.appendChild(components.home()); + break; + } + case '#/profile': { + container.appendChild(components.profile()); + break; + } + default: { + break; + } + } +}; + +export { router }; diff --git a/src/example.js b/src/example.js index 52d2c7ea..320e8301 100644 --- a/src/example.js +++ b/src/example.js @@ -1,3 +1,3 @@ -export const example = () => { - // aquí tu código -} \ No newline at end of file +// export const example = () => { +// // aquí tu código +// } diff --git a/src/firebase/login.js b/src/firebase/login.js new file mode 100644 index 00000000..3c59bb96 --- /dev/null +++ b/src/firebase/login.js @@ -0,0 +1,95 @@ +/* eslint-disable no-console */ +/* eslint-disable no-alert */ +export const database = firebase.firestore(); + +export default { + google: () => { + const provider = new firebase.auth.GoogleAuthProvider(); + firebase.auth().signInWithPopup(provider) + .then(() => { + // const user = result.user; + const currentUser = firebase.auth().currentUser; + database.collection('users').doc(currentUser.uid).set({ + id: currentUser.uid, + name: currentUser.displayName, + email: currentUser.email, + photo: currentUser.photoURL, + }); + window.location.hash = '#/home'; + }); + }, + facebook: () => { + const provider = new firebase.auth.FacebookAuthProvider(); + firebase.auth().signInWithPopup(provider) + .then(() => { + // const user = result.user; + const currentUser = firebase.auth().currentUser; + console.log(currentUser); + database.collection('users').doc(currentUser.uid).set({ + id: currentUser.uid, + name: currentUser.displayName, + email: currentUser.email, + photo: currentUser.photoURL, + }); + window.location.hash = '#/home'; + }); + }, + emailRegister: (mail, password) => { + firebase.auth().createUserWithEmailAndPassword(mail, password) + .then(() => { + // const user = result.user; + const currentUser = firebase.auth().currentUser; + console.log(currentUser); + database.collection('users').doc(currentUser.uid).set({ + id: currentUser.uid, + name: currentUser.displayName, + email: currentUser.email, + photo: currentUser.photoURL, + }); + window.location.hash = '#/home'; + }).catch((error) => { + const errorCode = error.code; + switch (errorCode) { + case 'auth/email-already-in-use': + alert('El email ingresado ya existe'); + break; + case 'auth/weak-password': + alert('La contraseña ingresada no es segura, intente de nuevo'); + break; + default: + alert(errorCode); + } + }); + }, + emailLogIn: (email, password) => { + firebase.auth().signInWithEmailAndPassword(email, password) + .then(() => { + window.location.hash = '#/home'; + }).catch((error) => { + const errorCode = error.code; + switch (errorCode) { + case 'auth/user-not-found': + alert('Usuario no encontrado, intenta de nuevo o registrate'); + break; + case 'auth/wrong-password': + alert('La contraseña es incorrecta, intenta de nuevo'); + break; + case 'auth/invalid-email': + alert('El correo ingresado no es válido'); + break; + default: + alert('Algo salió mal. Intente de nuevo'); + } + }); + }, + sesionLogOut: () => { + firebase.auth().signOut() + .then(() => { + alert('Sesión cerrada'); + document.querySelector('header').style.display = ''; + window.location.hash = '#/login'; + }).catch(() => { + alert('Algo salió mal. Intente de nuevo'); + }); + }, +}; diff --git a/src/firebase/showData.js b/src/firebase/showData.js new file mode 100644 index 00000000..81ac06bf --- /dev/null +++ b/src/firebase/showData.js @@ -0,0 +1,151 @@ +/* eslint-disable no-alert */ +/* eslint-disable no-param-reassign */ +import { database } from './login.js'; + +// const storage = firebase.storage(); + +firebase.auth().onAuthStateChanged((user) => { + if (user) { + console.log(user); + localStorage.setItem('uid', user.uid); + localStorage.setItem('displayName', user.displayName); + localStorage.setItem('photoURL', user.photoURL); + } else { + console.log('No user is signed in'); + localStorage.removeItem('uid'); + localStorage.removeItem('displayName'); + localStorage.removeItem('photoURL'); + } +}); + +const dateConverter = (timeStampFormat) => { + const date = new Date(timeStampFormat * 1000); + const month = date.getMonth() + 1; + const day = date.getDate(); + const year = date.getFullYear(); + const hour = date.getHours(); + const minute = date.getMinutes(); + return (`${day}-${month}-${year} / ${hour}:${minute}`); +}; + +const deleteOption = (event) => { + database.collection('posts').doc(event.target.id).delete() + .then(() => { + alert('Document successfully deleted!'); + }) + .catch((error) => { + alert('Error removing document: ', error); + }); +}; + +const editPost = (event) => { + const modalEdit = document.querySelector('#modalEdit'); + document.querySelector('#modalEdit').style.display = 'block'; + const closeBtn = document.querySelector('#closeBtn'); + closeBtn.addEventListener('click', () => { + modalEdit.style.display = 'none'; + }); + document.querySelector('#editPostText').value = event.target.getAttribute('data-content'); + const btnEdit = document.querySelector('#submitEditPost'); + btnEdit.addEventListener('click', () => { + const postsRef = database.collection('posts').doc(event.target.id); + console.log(event.target.id); + const newContent = document.querySelector('#newTextPost').value; + console.log(newContent); + return postsRef.update({ + postContent: newContent, + }) + .then(() => { + alert('Document successfully updated!'); + document.querySelector('#modalEdit').style.display = 'none'; + }) + .catch((error) => { + // The document probably doesn't exist. + console.error('Error updating document: ', error); + }); + }); +}; + +export const createNewPost = (content) => { + const currentUserData = firebase.auth().currentUser; + database.collection('posts').add({ + postOwner: currentUserData.uid, + postNameOwner: currentUserData.displayName, + postPhotoOwner: currentUserData.photoURL, + postContent: content, + date: new Date(), + likes: {}, + }) + .then(() => { + alert('Tu post se ha guardado'); + }); +}; + +export const postTemplate = (templateContainer) => { + database.collection('posts').onSnapshot((querySnapshot) => { + templateContainer.innerHTML = ''; + querySnapshot.forEach((doc) => { + const timestampFormat = doc.data().date.seconds; + const newDateFormat = dateConverter(timestampFormat); + const userTemplate = ` +
+
+ +
+ ${doc.data().postNameOwner}
+ ${doc.data().postContent}
+ ${newDateFormat} +
+
+
+ + +
+
`; + templateContainer.innerHTML += userTemplate; + }); + }); +}; + +// obtener post propios +export const currentUserPosts = (postContainer) => { + postContainer.innerHTML = ''; + // const prueba = localStorage.getItem('uid'); + // console.log(prueba); + const currentUserRef = database.collection('posts'); + const query = currentUserRef.where('postOwner', '==', localStorage.getItem('uid')); + query.get() + .then((querySnapshot) => { + querySnapshot.forEach((doc) => { + // doc.data() is never undefined for query doc snapshots + const timestampFormat = doc.data().date.seconds; + const newDateFormat = dateConverter(timestampFormat); + const userTemplate = ` +
+
+ +
+ ${doc.data().postNameOwner}
+ ${doc.data().postContent}
+ ${newDateFormat} +
+
+
+ + + + +
+
`; + postContainer.innerHTML += userTemplate; + const DeleteBtns = postContainer.querySelectorAll('.delete'); + DeleteBtns.forEach(btn => btn.addEventListener('click', deleteOption)); + + const btn = postContainer.querySelectorAll('.edit'); + btn.forEach(bt => bt.addEventListener('click', editPost)); + }); + }) + .catch((error) => { + console.log('Error getting documents: ', error); + }); +}; diff --git a/src/images/CodeMakers.png b/src/images/CodeMakers.png new file mode 100644 index 00000000..cd3490fe Binary files /dev/null and b/src/images/CodeMakers.png differ diff --git a/src/images/Google2.PNG b/src/images/Google2.PNG new file mode 100644 index 00000000..63478916 Binary files /dev/null and b/src/images/Google2.PNG differ diff --git a/src/images/borrar.svg b/src/images/borrar.svg new file mode 100644 index 00000000..62f5af1a --- /dev/null +++ b/src/images/borrar.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/casa.svg b/src/images/casa.svg new file mode 100644 index 00000000..b1c4a0d5 --- /dev/null +++ b/src/images/casa.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/cerrar-sesion.svg b/src/images/cerrar-sesion.svg new file mode 100644 index 00000000..1e35d224 --- /dev/null +++ b/src/images/cerrar-sesion.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/corazon (1).svg b/src/images/corazon (1).svg new file mode 100644 index 00000000..3daeba62 --- /dev/null +++ b/src/images/corazon (1).svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/facebook1.PNG b/src/images/facebook1.PNG new file mode 100644 index 00000000..84b0957d Binary files /dev/null and b/src/images/facebook1.PNG differ diff --git a/src/images/facebook4.png b/src/images/facebook4.png new file mode 100644 index 00000000..640ee7ac Binary files /dev/null and b/src/images/facebook4.png differ diff --git a/src/images/google4.png b/src/images/google4.png new file mode 100644 index 00000000..f8fd170e Binary files /dev/null and b/src/images/google4.png differ diff --git a/src/images/profile.svg b/src/images/profile.svg new file mode 100644 index 00000000..c700cfae --- /dev/null +++ b/src/images/profile.svg @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/rectification.svg b/src/images/rectification.svg new file mode 100644 index 00000000..0782e1a3 --- /dev/null +++ b/src/images/rectification.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/writePost.svg b/src/images/writePost.svg new file mode 100644 index 00000000..edfd0d5f --- /dev/null +++ b/src/images/writePost.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/index.html b/src/index.html index bb6937cc..3da734fb 100644 --- a/src/index.html +++ b/src/index.html @@ -4,9 +4,53 @@ - Document + Code Makers + +
+
+ +

Unete a la Red Social de Programadoras

+
+
+ + + + + + + + \ No newline at end of file diff --git a/src/index.js b/src/index.js index 35868bab..5725fca1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,8 @@ -import { example } from './example.js'; +import { router } from './Views/router.js'; -example(); +const init = () => { + router(window.location.hash); + window.addEventListener('hashchange', () => router(window.location.hash)); +}; + +window.addEventListener('load', init); diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 00000000..7a50eba2 --- /dev/null +++ b/src/styles.css @@ -0,0 +1,244 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto:500,700&display=swap'); + +html, body { + margin: 0; + padding: 0; + height: 100%; + font-family: 'Roboto', sans-serif; +} +/* contenedor principal */ +.container { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; +} + +/* header */ +header { + padding: 0.2rem; + background: rgb(47, 141, 218); + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} +.codeMakers {width: 12rem; height: 4rem;} +.viewsStyle { + width: 90%; +} +.views { + width: 90%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; +} +/* iniciar sesion con fb y google */ +.conectWithSocialMedia { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.buttons{ + border: 0; + height: 4rem; + margin: 0; + } +/* formulario */ +.registerForm { + width: 100%; + height: 50%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; +} +.recoveryForm { + width: 100%;; + height: 30%; + margin-bottom: 2rem; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; +} +input { + border: 0; + width: 100%; + height: 2rem; + background: linear-gradient(0deg, rgba(154,156,156,1) 0%, rgba(245,245,242,1) 100%); +} +button { + width: 100%; + height: 2.5rem; + border: 0; +} +.registerButton { + border: 0; + background: rgb(47, 141, 218); + border-radius: 18px 18px 18px 18px; + border: 6px outset rgb(47, 141, 218); + font-weight: bold; +} + + +/* vista de home */ +.Home { + width: 112%; + height: auto; +} +.homeOptions { + width: 100%; + display: flex; + justify-content: space-around; + align-items: center; +} + .btnHeader {width: 2rem; height: 2rem;} +.sesionPrincipal, .sesionPrincipal1 { + padding: 0; + margin: 1rem 0; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +} +.newPost { + width: 90%; + align-content: center; + display: flex; + flex-direction: column; +} +.welcome { + display: flex; + flex-direction: column; + align-items: center; + margin: 2rem 0; +} +.postForm { + width: 100%; + resize: none; +} + +hr {width: 90%; border-color: rgb(47, 141, 218);} +.postContainer { + margin: 0.5rem 0.3rem; + width: 90%; + padding: 0.5rem; + display: flex; + flex-direction: column; + justify-content: center; + border-radius: 26px 26px 26px 26px; + border: 0.25rem dashed #bdb5bd; + background: rgb(243, 243, 243); +} + .post { + display: flex; + width: 100%; + justify-content: space-around; + } + .postAuthor { + width: 4rem; + height: 4rem; + } + .postContent { + width: 85%; + height: auto; + padding: 0.3rem; + } + #date { + font-size: small; + color: #424040; + } + #ownerName {color: darkviolet;} + .postOptions { + width: 100%; + display: flex; + justify-content: flex-end; + } + .likes { + width: 1rem; + height: 1rem; + margin: 0.3rem 0.5rem; + } +textarea { + border-radius: 16px 16px 16px 16px; + border: 3px solid rgb(47, 141, 218); +} + +/* modal */ +.flex{ + width: 100%; + height:100%; + display: flex; + justify-content: space-between; + align-items: center; +} +.modal{ + display: none; + position: fixed; + overflow: auto; + width: 100%; + height:100%; + background: rgba(0, 0, 0, 0.452); +} +.contenido-modal{ + position: relative; + background-color: #ffffff; + margin: auto; + width: 90%; + box-shadow: 0 0 6px 0 rgba(0, 0, 0, .4); + animation-name: modal; + animation-duration: 1s; +} +@keyframes modal{ + from{top:-330px; opacity:0;} + to{top:0; opacity:1;} +} +.close{ + font-size: 1.5rem; + font-weight: bold; +} +.modal-header { + width: 95%; + height: 2rem; + padding: 0.5rem; + background: #EBE134; +} +.modal-body{ + padding: 20px 16px; +} +/* profile view */ +.nameandphoto { + margin: 5%; + display: flex; + width: 80%; + justify-content: space-around; +} +.userPhoto { + border-radius: 3.5rem; + width: 6rem; + height: 6rem; +} + +.updateInfo { + display: none; + flex-direction: column; + align-items: center; + width: 85%; + border-radius: 26px 26px 26px 26px; + border: 0.25rem dashed #bdb5bd; + background: rgb(243, 243, 243); + padding: 1rem; +} +.updateBtns { + width: 50%; + margin: 1rem; + background: rgb(47, 141, 218); + border-radius: 1rem; + border: 0.15rem solid rgb(0, 1, 41); + font-weight: bolder; +}