diff --git a/.eslintrc b/.eslintrc index a731d53c..4dab094c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -26,6 +26,7 @@ "jest/no-focused-tests": "error", "jest/no-identical-title": "error", "jest/prefer-to-have-length": "warn", - "jest/valid-expect": "error" + "jest/valid-expect": "error", + "import/no-unresolved": 0, } } \ No newline at end of file diff --git a/.gitignore b/.gitignore index 47735411..e0f3bf8e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ coverage/ node_modules/ .yarn.lock -package-lock.json \ No newline at end of file +package-lock.json +config.js + +Register.js \ No newline at end of file diff --git a/package.json b/package.json index 0c72f6c8..86165e50 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "stylelint": "stylelint --aei src/**/*.css", "pretest": "npm run htmlhint && npm run eslint && npm run stylelint", "test": "jest --coverage", - "start": "serve -s src/" + "start": "serve -s src/ -s" }, "devDependencies": { "@babel/core": "^7.11.4", @@ -28,7 +28,7 @@ "htmlhint": "^1.0.0", "jest": "^27.0.1", "regenerator-runtime": "^0.13.1", - "serve": "^13.0.2", + "serve": "^14.1.2", "stylelint": "^14.1.0", "stylelint-config-recommended": "^6.0.0" }, @@ -39,5 +39,8 @@ "createdAt": "2022-11-30T16:52:37.204Z", "version": "5.5.0", "commit": "51e941edf1cc991930aefd7dd9c406a7c43741c1" + }, + "dependencies": { + "firebase": "^9.15.0" } -} \ No newline at end of file +} diff --git a/src/comentarios.text b/src/comentarios.text new file mode 100644 index 00000000..e86b3d4d --- /dev/null +++ b/src/comentarios.text @@ -0,0 +1,273 @@ + +-------------------------------FEED--------------------------------------------- +const openModalAddPost = (feedSection) => { + //console.log('post'); + const containerAddPost = document.createElement('div'); + containerAddPost.className = 'container-add-post'; + feedSection.appendChild(containerAddPost); + const openModalAddPost = document.createElement('div'); + openModalAddPost.className = 'modal-add-post'; + containerAddPost.appendChild(openModalAddPost); +} + +------------------------------STYLE----------------------------------------- +.modal { + display: none; + background: url(img/fondo10.png); + background-size: cover; + background-position: center; + width: 100%; + height: 100%; + top: 0; + left: 0; + position: fixed; + padding: 15px; + justify-content: center; + align-items: center; +} + +.modal-container { + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(8px); + width: 320px; + height: 500px; + font-family: sans-serif; + padding: 25px; + border-radius: 15px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.close-modal { + margin-bottom: 30px; + margin-left: 320px; + width: 20px; + height: 25px; + border: transparent; + color: rgb(48, 46, 46); + background-color: transparent; + position: absolute; + top: 10px; + padding-left: 18px; + cursor: pointer; +} + +.container-add-post { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background: rgba(0, 0, 0, 0.4); +} + +.modal-add-post { + width: 80%; + height: 50vh; + background: #334E6F; + border-radius: 12px; +} + +------------------------------- estilos Vale------------ +.section-feed { + width: 360px; + height: 100vh; + overflow:scroll; + /*es el 100% para cualquier dispositivo*/ + /* display: grid; + grid-template-columns: 80px 200px 80px; + grid-template-rows: repeat(3, 200px); + gap: 5px; */ + position: relative; + /*para que el hijo posicionarse respecto al section-feed*/ + /* justify-content: center; */ + background: linear-gradient(180deg, #334E6F 0%, #8F9CA3 100%); + + +} + +/* .section-feed > * { + text-align: center; + justify-content: center; + align-items: center; + display: flex; +} */ +.tituloh2-feed { + font-family: 'Fredoka One'; + width: 300px; + height: 47px; + text-align: center; + font-style: normal; + font-weight: 400; + font-size: 35px; + line-height: 42px; + color: rgba(255, 242, 242, 0.25); + text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + margin: 0; + /* position: absolute; + top: 25px; + left: 19px */ +} + +.avatarImg { + width: 65px; + height: 65px; + + /* position: absolute; + right: 12px; + top:12px */ +} + + + .container-buttons { + position: absolute; + position: sticky; + bottom: 0; + left: 0; + top: 745px; + width: 360px; + height: 59px; + background-color: #F7DAE5; + display: grid; + grid-template-columns: repeat(3, 1fr); + /*las tres columnas tendrán la misma dimensión en cualquier dispositivo*/ +} + +.container-buttons button { + padding: 1rem; + border: none; + background: transparent; +} + +.feed-container-header { + display: flex; + align-items: center; + justify-content: space-between; + width: 100% !important; + padding: 1rem; +} + + +.contenedor-posts { + width: 100%; + height: 800px; + background-color: transparent; + border: none; + display: flex; + flex-direction: column; + margin : 0 0 0 20px; + gap:20px; + +} + +.post-div { + width: 90%; + height: 25vh; + border: 1px solid #52525C; + border-radius: 10px; + background-color: #ffffff; + font-family: 'Roboto', sans-serif; + font-size: 10px; + + + +} + +.parte-superior-post{ + background-color: #C3E2E6; + height: 6vh; + border-top-left-radius: 10px ; + border-top-right-radius: 10px ; + border-bottom: none; + display: flex; + align-items: center; +} + +.boton-editar{ + border: none; + background-color: transparent; + position: absolute; + right: 8vh; + color: #222222; + +} + +.boton-eliminar{ + border: none; + background-color: transparent; + position: absolute; + right: 4vh; + color:#222222 + + +} + +.boton-like{ + border: none; + color: #FA79AA; + background-color: transparent; + position: absolute; + + +} + +.titulo-post{ + font-family: 'Roboto', sans-serif; + font-size: 15px; + color:#52525C; +} + +.textoUser{ + border:none; + resize: none; + width: 90%; + height: 50px; + margin: 0 5px 0 20px; + border: 5px double #d6d6db; + border-radius: 3px; + text-indent: 5px; + margin-bottom: 10px; + margin-top: -40px; + +} +h2.titulo-post{ + position: relative; + top: -35px; + margin: 0 0 0 20px; +} +h3.descripcion-post{ + margin: 0 0 0 20px; + color:#222222; +} +h4.fecha-post { + position: relative; + top: 60px; + margin: 0 0 0 15px; + + color: #888686; + font-size: 10px; +} +.post-btn { + position: relative; + background :#3b5998; + border-radius: 2px; + width: 50px; + height: 20px; + color:#d6d6db; + text-shadow: 1px 0 1px #ffffff; + border: none; + left: 275px; + top: 5px; + +} + + +------BOTON EN EL FEEED DE VALE----------- +const logoutButton = document.createElement('button'); + logoutButton.id = 'idlogoutButton' + logoutButton.innerHTML = ''; \ No newline at end of file diff --git a/src/components/Home.js b/src/components/Home.js new file mode 100644 index 00000000..e89f0854 --- /dev/null +++ b/src/components/Home.js @@ -0,0 +1,54 @@ +import { onNavigate } from '../js/routes.js' + +export const home = () => { + const homeDiv = document.createElement('div'); + + const barraNavegacion = document.createElement('nav'); + barraNavegacion.className = 'navBarHome'; + homeDiv.appendChild(barraNavegacion); + + const listaBotones = document.createElement('ul'); + listaBotones.className = 'ul-home'; + barraNavegacion.appendChild(listaBotones); + + const buttonRegister = document.createElement('li'); + buttonRegister.className = 'navLink'; + buttonRegister.textContent = 'Sign up'; + buttonRegister.id = 'botonRegistrar'; + + buttonRegister.addEventListener('click', () => onNavigate('/registro')); + + const buttonLogin = document.createElement('li'); + buttonLogin.className = 'navLink'; + buttonLogin.textContent = 'Sign in / login'; + buttonLogin.id = 'botonLoguear'; + + buttonLogin.addEventListener('click', () => onNavigate('/login')); + + + listaBotones.appendChild(buttonRegister); + listaBotones.appendChild(buttonLogin); + + const sectionDiv = document.createElement('section'); + sectionDiv.className = 'bienvenida'; + const bienvenidaH5 = document.createElement('h5'); + bienvenidaH5.className = 'welcomeH5'; + const nameApp = document.createElement('h1'); + nameApp.className = 'nameAplication'; + + bienvenidaH5.textContent = 'Welcome t💗'; + nameApp.textContent = "Dad's Power"; + sectionDiv.appendChild(bienvenidaH5); + sectionDiv.appendChild(nameApp); + + homeDiv.appendChild(sectionDiv); + + const imagenInicio = document.createElement('img'); + imagenInicio.src = '/components/imagen/inicioApp.png'; + imagenInicio.className = 'imgInicio'; + + homeDiv.appendChild(imagenInicio); + + + return homeDiv; +} diff --git a/src/components/feed.js b/src/components/feed.js new file mode 100644 index 00000000..f4409772 --- /dev/null +++ b/src/components/feed.js @@ -0,0 +1,229 @@ +import { savePosts, getPost, deletePost } from "../lib/firebase/methodsFirestore.js"; +export const feed = () => { + + const feedSection = document.createElement('section'); + feedSection.className = 'section-feed'; + + const containerHeader = document.createElement('div'); + containerHeader.className = 'feed-container-header'; + + feedSection.appendChild(containerHeader); + + + const titulo = document.createElement('h2'); + titulo.textContent = "Dad's Power"; + titulo.className = 'tituloh2-feed'; + + containerHeader.appendChild(titulo); + + const perfil = document.createElement('div') + perfil.className = 'avatarUser'; + + + const avatarImg = document.createElement('img'); + avatarImg.className = 'avatarImg'; + avatarImg.src = '/components/imagen/avatar3.png'; + perfil.appendChild(avatarImg); + + containerHeader.appendChild(perfil); + + + const createContainerButtons = document.createElement('div'); + createContainerButtons.className = 'container-buttons'; + feedSection.appendChild(createContainerButtons); + + const perfilButton = document.createElement('button'); + perfilButton.type = 'button'; + perfilButton.id = 'idPerfilButton'; + perfilButton.className = 'perfil-button'; + perfilButton.innerHTML = ''; + + const comentarioButton = document.createElement('button'); + comentarioButton.type = 'button'; + comentarioButton.id = 'idcomentarioButton'; + comentarioButton.className = 'comentario-button'; + comentarioButton.innerHTML = ''; + + const logoutButton = document.createElement('button'); + logoutButton.type = 'button'; + logoutButton.id = 'idlogoutButton'; + logoutButton.className = 'logout-button'; + logoutButton.innerHTML = ''; + + createContainerButtons.appendChild(perfilButton); + createContainerButtons.appendChild(comentarioButton); + createContainerButtons.appendChild(logoutButton); + + + + + //----------------------------------FORMULARIO PARA POSTEAR-------------------------------------------------------------------------- + + const formulario = document.createElement('form'); + formulario.method = 'post'; + formulario.id = 'idForm'; + formulario.className = 'formulario-post'; + //console.log(formulario); + feedSection.appendChild(formulario); + + + const publicarPostButton = document.createElement('button'); + publicarPostButton.className = 'post-btn'; + publicarPostButton.type = 'submit'; + publicarPostButton.id = 'idPostButton'; + publicarPostButton.textContent = 'Post'; + formulario.appendChild(publicarPostButton); + + formulario.addEventListener('submit', (e) => { + e.preventDefault(); + + console.log('click'); + let textPost = document.getElementById('idUserPost').value; + if (textPost === null || textPost === '' || textPost.length == 0) { + alert('escriba un mensaje'); + } + else { + savePosts(textPost).then().catch(error => console.log("fallo la promesa para postear", error)); + alert('tu post ha sido publicado'); + // unsub(textPost).then(result => console.log(result)).catch(error => console.log("fallo la promesa mostrar en tiempo real los posts existentes", error)); + } + + formulario.reset(); + }); + + + const textoUser = document.createElement('textarea'); + + textoUser.className = 'textoUser'; + textoUser.name = 'addpost'; + textoUser.id = 'idUserPost'; + textoUser.placeholder = 'what do you need?'; + formulario.appendChild(textoUser); + + + + //----------------------MOSTRANDO POSTS EXISTENTES----------------------------- + + const contenedorPosts = document.createElement('div'); + contenedorPosts.className = 'contenedor-posts'; + feedSection.appendChild(contenedorPosts); + + + // savePosts(textoUser.value).then().catch(error => console.log("fallo la promesa para postear", error)); + + + // postsRef() + getPost(postsCollection => { + postsCollection.forEach((item) => { /*para traer los posts de mi colección */ + + const posts = item.data(); + //console.log(posts); + //console.log(posts["fecha"]); + const postCreado = document.createElement('div'); + postCreado.className = 'post-div'; + postCreado.innerHTML = ''; + postCreado.innerHTML = ` +
+
+ + +
+ +

${posts["autor"]}

+

${posts["descripcion"]}

+

${posts.date}

+
+ + `; + + contenedorPosts.append(postCreado); + + }); + }) + // .catch(error => console.log("fallo la promesa de firestore", error)) + + //MODAL LOG OUT + const modalLogOut = document.createElement('div'); + modalLogOut.className = 'modal'; + modalLogOut.id = 'idModalLogout'; + + modalLogOut.innerHTML = ` + + `; + feedSection.appendChild(modalLogOut); + + const closeModal = () => { + // console.log('cerrando'); + modalLogOut.style.display = 'none'; + } + + const openModal = () => { + // console.log('hello'); + modalLogOut.style.display = 'flex'; + } + + logoutButton.addEventListener('click', () => { + openModal(); + }); + + const closeModalLogout = modalLogOut.querySelector('#botonCancelar'); //no se puede usar getElementById porque aun no existe + if (closeModalLogout) { closeModalLogout.addEventListener('click', () => { closeModal() }); } + + // MODAL ELIMINAR + + const modalDelete = document.createElement('div'); + modalDelete.className = 'modal'; + modalDelete.id = 'idModalDelete'; + + modalDelete.innerHTML = ` + + `; + feedSection.appendChild(modalDelete); + + const closeModalDelete = () => { + console.log('cerrando'); + modalDelete.style.display = 'none'; + } + + const openModalDelete = () => { + console.log('hello'); + modalDelete.style.display = 'flex'; + } + contenedorPosts.addEventListener('click', () => { + console.log('click') + openModalDelete(); + }); + const openDelete = modalDelete.querySelector('#botonEliminar') + if(openDelete) { + openDelete.addEventListener('click', () => {openModalDelete()}); + + } + + + const aceptarEliminar = modalDelete.querySelector('#Eliminar'); + if (aceptarEliminar){ + aceptarEliminar.addEventListener('click', () => { deletePost(); + closeModalDelete()}); + } + const closeDelete = modalDelete.querySelector('#botonCancelarEliminar'); //no se puede usar getElementById porque aun no existe + if (closeDelete) + { closeDelete.addEventListener('click', () => { closeModalDelete() }); + } + + + + return feedSection; + +} + + diff --git a/src/components/imagen/avatar.png b/src/components/imagen/avatar.png new file mode 100644 index 00000000..17cc8be8 Binary files /dev/null and b/src/components/imagen/avatar.png differ diff --git a/src/components/imagen/avatar3.png b/src/components/imagen/avatar3.png new file mode 100644 index 00000000..52623337 Binary files /dev/null and b/src/components/imagen/avatar3.png differ diff --git a/src/components/imagen/google.png b/src/components/imagen/google.png new file mode 100644 index 00000000..ccbfe00d Binary files /dev/null and b/src/components/imagen/google.png differ diff --git a/src/components/imagen/inicioApp.png b/src/components/imagen/inicioApp.png new file mode 100644 index 00000000..400ff7da Binary files /dev/null and b/src/components/imagen/inicioApp.png differ diff --git a/src/components/login.js b/src/components/login.js new file mode 100644 index 00000000..a5587f1a --- /dev/null +++ b/src/components/login.js @@ -0,0 +1,78 @@ +export const login = () => { + + const signinSection = document.createElement('section'); + signinSection.className = 'sectionSignup-in' + const titulo = document.createElement('h2'); + titulo.textContent = "Dad's Power"; + titulo.className = 'tituloh2register-login'; + signinSection.appendChild(titulo); + + const formSI = document.createElement('form'); + formSI.className = 'form'; + formSI.method = 'post'; + formSI.id = 'formularioSI'; + + const divUser = document.createElement('div'); + divUser.className = 'contenedorForm' + signinSection.appendChild(divUser); + divUser.appendChild(formSI); + + + const inputEmail = document.createElement('input'); + const labelEmail = document.createElement('label'); + labelEmail.textContent = 'E-mail'; + labelEmail.className = 'labelEmailLogin'; + + formSI.appendChild(labelEmail); + inputEmail.type = 'e-mail'; + inputEmail.className = 'email'; + inputEmail.id = 'idCorreoSI'; + inputEmail.placeholder = 'example@gmail.com' + formSI.appendChild(inputEmail); + + //considerar agregar una diferencia en el parrafo que se imprima el mensaje de error segun sea para mail o pass + const errorSigninEmail = document.createElement('p'); + errorSigninEmail.className = 'message-error-email-login'; //aquí debe estar la diferencia en la className, distinto para email y pass + // errorSigninEmail.textContent = 'Aquí va error para email'; + formSI.appendChild(errorSigninEmail); + + const inputPasword = document.createElement('input'); + const labelPassword = document.createElement('label'); + labelPassword.textContent = 'Password'; + labelPassword.className = 'labelPasswordLogin'; + formSI.appendChild(labelPassword); + inputPasword.type = 'password'; + inputPasword.textContent = 'password'; + inputPasword.className = 'password'; + inputPasword.id = 'idContraseñaSI'; + inputPasword.placeholder = '******' + formSI.appendChild(inputPasword); + + //considerar agregar una diferencia en el parrafo que se imprima el mensaje de error segun sea para mail o pass + const errorSigninPassword = document.createElement('p'); + errorSigninPassword.className = 'message-error-password-login'; //aquí debe estar la diferencia en la className, distinto para email y pass + // errorSigninPassword.textContent = 'Aquí va error para password'; + formSI.appendChild(errorSigninPassword); + + const buttonSI = document.createElement('button'); + buttonSI.type = 'submit'; + buttonSI.textContent = 'submit' + buttonSI.className = 'btnSubmit'; + buttonSI.id = 'btnEnviarSI'; + formSI.appendChild(buttonSI); + + const buttonGoogle = document.createElement('button'); + buttonGoogle.textContent = 'Sign in with Google' + buttonGoogle.type = 'button'; + buttonGoogle.className = 'btnGoogle'; + buttonGoogle.id = 'entrarGoogle'; + + const imagenGoogle = document.createElement('img'); + imagenGoogle.src = '/components/imagen/google.png'; + imagenGoogle.className = 'imgGoogle'; + + buttonGoogle.appendChild(imagenGoogle); + formSI.appendChild(buttonGoogle); + + return signinSection; +} \ No newline at end of file diff --git a/src/components/registro.js b/src/components/registro.js new file mode 100644 index 00000000..defbba6e --- /dev/null +++ b/src/components/registro.js @@ -0,0 +1,94 @@ +import { onNavigate } from '../js/routes.js' + +export const register = () => { + + const signupSection = document.createElement('section'); + signupSection.className = 'sectionSignup-in' + const titulo = document.createElement('h2'); + titulo.textContent = "Dad's Power"; + titulo.className = 'tituloh2register-login'; + signupSection.appendChild(titulo); + + const formSU = document.createElement('form'); + formSU.className = 'form'; + formSU.method = 'post'; + formSU.id = 'formularioSU'; + + const divUser = document.createElement('div'); + divUser.className = 'contenedorForm' + signupSection.appendChild(divUser); + divUser.appendChild(formSU); + + const inputUser = document.createElement('input'); + const labelUser = document.createElement('label'); + labelUser.textContent = 'Username'; + labelUser.className ='usuario'; + formSU.appendChild(labelUser); + inputUser.type ='user'; + inputUser.className = 'username'; + inputUser.id = 'idUsername'; + inputUser.placeholder = 'Rob Scott'; + formSU.appendChild(inputUser); + + + const inputEmail = document.createElement('input'); + const labelEmail = document.createElement('label'); + labelEmail.textContent = 'E-mail'; + labelEmail.className = 'labelEmail'; + formSU.appendChild(labelEmail); + inputEmail.type = 'e-mail'; + inputEmail.className = 'email'; + inputEmail.id = 'idCorreoSU'; + inputEmail.placeholder = 'example@gmail.com' + formSU.appendChild(inputEmail); + + //considerar agregar una diferencia en el parrafo que se imprima el mensaje de error segun sea para mail o pass + const errorSignupEmail = document.createElement('p'); + errorSignupEmail.className ='message-error-email'; //aquí debe estar la diferencia en la className, distinto para email y pass + // errorSignupEmail.textContent = 'Aquí va error para email'; + formSU.appendChild(errorSignupEmail); + + + const inputPasword = document.createElement('input'); + const labelPassword = document.createElement('label'); + labelPassword.textContent = 'Password'; + labelPassword.className = 'labelPassword'; + formSU.appendChild(labelPassword); + inputPasword.type = 'password'; + inputPasword.textContent = 'password'; + inputPasword.className = 'password'; + inputPasword.id = 'idContraseñaSU'; + inputPasword.placeholder = '******' + formSU.appendChild(inputPasword); + + //considerar agregar una diferencia en el parrafo que se imprima el mensaje de error segun sea para mail o pass + const errorSignupPassword = document.createElement('p'); + errorSignupPassword.className ='message-error-password'; //aquí debe estar la diferencia en la className, distinto para email y pass + // errorSignupPassword.textContent = 'Aquí va error para password'; + formSU.appendChild(errorSignupPassword); + + + const buttonSU = document.createElement('button'); + buttonSU.type = 'submit'; + buttonSU.textContent = 'submit' + buttonSU.className = 'btnSubmit'; + buttonSU.id = 'btnEnviarSU'; + formSU.appendChild(buttonSU); + + const tienesCuenta = document.createElement('p'); + tienesCuenta.className = 'p-tienes-cuenta-register'; + tienesCuenta.textContent = 'Already have an account ?'; + formSU.appendChild(tienesCuenta); + + const buttonLogin = document.createElement('a'); + buttonLogin.className = 'signin-a'; + buttonLogin.textContent = 'Sign in'; + buttonLogin.id = 'botonLoguear'; + + + + tienesCuenta.appendChild(buttonLogin); + buttonLogin.addEventListener('click', () => onNavigate('/login')); + + return signupSection; +} diff --git a/src/index.html b/src/index.html index 788db3c9..158219ef 100644 --- a/src/index.html +++ b/src/index.html @@ -1,12 +1,112 @@ + + - Document + + Dad's Power + + + + + + + + + + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/js/routes.js b/src/js/routes.js new file mode 100644 index 00000000..2e415ee4 --- /dev/null +++ b/src/js/routes.js @@ -0,0 +1,36 @@ +import { home } from '../components/Home.js'; +import { register } from '../components/registro.js'; +import { login } from '../components/login.js'; +import { feed } from '../components/feed.js'; + + +const rootDiv = document.getElementById('root'); +const routes = { + '/': home, + '/registro': register, + '/login': login, + '/feed': feed, +}; + +export const onNavigate = (pathname) => { //se cambia la ruta + window.history.pushState( + {state:pathname}, + pathname, + window.location.origin + pathname, // requiere 3 parámetros - 1 estado vacio - asignar título - asignar la ruta// + ); + while (rootDiv.firstChild) { + rootDiv.removeChild(rootDiv.firstChild); + } + + rootDiv.appendChild(routes[pathname]()); +}; + + + const componentes = routes[window.location.pathname]; + + window.onpopstate = () => { + rootDiv.appendChild(componentes()); + }; + rootDiv.appendChild(componentes()); + + diff --git a/src/lib/firebase/config.js b/src/lib/firebase/config.js new file mode 100644 index 00000000..70246f07 --- /dev/null +++ b/src/lib/firebase/config.js @@ -0,0 +1,19 @@ +// // Import the functions you need from the SDKs you need +// import { initializeApp } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-app.js"; + + +// const firebaseConfig = { +// apiKey: 'AIzaSyAQKOcN9jLUCxn2zXz-mkJKV-BaeFjcKvo', +// authDomain: 'redsocialnvj-47db7.firebaseapp.com', +// projectId: 'redsocialnvj-47db7', +// storageBucket: 'redsocialnvj-47db7.appspot.com', +// messagingSenderId: '161909447570', +// appId: '1:161909447570:web:b126b68b577520ab947f4b', +// }; + +// // Initialize Firebase +// // console.log('app', app) +// // export const init = () =>{ +// // return app; +// // } +// export const app = initializeApp(firebaseConfig); diff --git a/src/lib/firebase/methodsAuth.js b/src/lib/firebase/methodsAuth.js new file mode 100644 index 00000000..742b6872 --- /dev/null +++ b/src/lib/firebase/methodsAuth.js @@ -0,0 +1,94 @@ +import { createUserWithEmailAndPassword, signInWithEmailAndPassword, signInWithPopup, GoogleAuthProvider, onAuthStateChanged, sendEmailVerification } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-auth.js"; + + +// construyendo un observador de Auth +export const verifiedWithEmail = (auth) => { + onAuthStateChanged(auth, (user) => { + + if (user) { + // User is signed in, see docs for a list of available properties + // https://firebase.google.com/docs/reference/js/firebase.User + var email = user.email; + const uid = user.uid; // código único del usuario asignado por Firebase + + // El usuario se encuentra logueado + console.log('auth:sign in'); + + var emailVerified = user.emailVerified; + if (emailVerified === false) { + console.log('Email no verificado'); + } else { + console.log('Email verificado'); + } + // ... + } else { + // el suusario no se encuentra logueado + console.log('auth: log out'); + } + }); +} + +export const verificarSendingMail = (auth) => { + sendEmailVerification(auth.currentUser) + .then(() => { + // Email verification sent! + alert('por favor verifique su correo'); + // ... + }); +} + +export const register = (auth, signupEmail, signupPassword) => { + return new Promise((resolve, reject) => { //resolve para retornar el valor deseado cuando una función se ejecute y reject para cuando una función retorna un valor no deseado./ + return createUserWithEmailAndPassword(auth, signupEmail, signupPassword) + .then((userCredential) => resolve(userCredential)) //está implícita una promesa/ + .catch(error => reject(error)) + + + }); + } + +export const login = (auth, email, password) => { + return new Promise((resolve, reject) => { //resolve para retornar el valor deseado cuando una función se ejecute y reject para cuando una función retorna un valor no deseado./ + return signInWithEmailAndPassword(auth, email, password) + .then(({ user }) => resolve(user)) //desestructuración del objeto user/ + .catch(error => reject(error)) + }) + } + + + + export const logOut = (auth) => { + auth.signOut().then(() => { + console.log('sign out'); + }); + } + + + export const loginWithGoogle = (auth) => { + return new Promise((resolve, reject) => { //resolve para retornar el valor deseado cuando una función se ejecute y reject para cuando una función retorna un valor no deseado./ + + const provider = new GoogleAuthProvider(); + + return signInWithPopup(auth, provider) + .then(({ user }) => resolve(user)) + .catch(error => reject(error)) + + }) + } + + + + // export const loginWithGoogle = (auth) => { + // const provider = new GoogleAuthProvider(); + + // signInWithPopup(auth, provider) + // .then(result => { + // const user = result.user; + // // closeModalSI(); + // console.log('sign in Google'); + // // signinForm.querySelector('.message-error').innerHTML = ''; + // }) + // .catch((error) => { + + // }); + // } \ No newline at end of file diff --git a/src/lib/firebase/methodsFirestore.js b/src/lib/firebase/methodsFirestore.js new file mode 100644 index 00000000..2353ce81 --- /dev/null +++ b/src/lib/firebase/methodsFirestore.js @@ -0,0 +1,61 @@ +// Import the functions you need from the SDKs you need +import { initializeApp } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-app.js"; + +const firebaseConfig = { + apiKey: 'AIzaSyAQKOcN9jLUCxn2zXz-mkJKV-BaeFjcKvo', + authDomain: 'redsocialnvj-47db7.firebaseapp.com', + projectId: 'redsocialnvj-47db7', + storageBucket: 'redsocialnvj-47db7.appspot.com', + messagingSenderId: '161909447570', + appId: '1:161909447570:web:b126b68b577520ab947f4b', + }; + +export const app = initializeApp(firebaseConfig); + + +import { getFirestore, collection, getDocs, addDoc , query ,orderBy, onSnapshot, deleteDoc ,doc} from "https://www.gstatic.com/firebasejs/9.15.0/firebase-firestore.js"; +// import { async } from "regenerator-runtime"; + +// Initialize Cloud Firestore and get a reference to the service +const db = getFirestore(app); + + +// Obtener la data desde el firestore +export const postsRef = async (id) => await getDocs(collection(db, 'posts', id)) + +//console.log('postsRef',postsRef()); + + +//---------------Generando nuevos post de forma dinámica---------------- + +//utilizando método addDoc de firestore con onSnapshot(actualización en tiempo real) + +export const savePosts = async (descripcion) => await addDoc(collection(db, 'posts'),{descripcion}) + + + export const getPost = (callback) => { + const qs = query(collection(db, 'posts'), orderBy( 'descripcion', 'asc')); + onSnapshot (qs,(callback)) +} + + // mostrar tiempo del post +// const date = new Date().toLocaleDateString('es-es', {month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric'}) + +//-----------------------------Eliminando post--------------------------- + export const deletePost = async (id) => await deleteDoc(doc (db , 'post', id)) + + + +//------------------------------Editando post----------------------------- +// export const udpDatePost = async (id) => await updateDoc(doc(db, 'post', id)) + + +//------------------Agregando interacciones, me gusta <3 -------------------- +// La idea es generar un array con los UserID para que sólo pueda haber uno por usuario +// (click en boton <3 sea un push con if(UserID no se encuentre en el array) else(si UserID está presente) se borre del array) + + + + + + diff --git a/src/lib/firebase/post.js b/src/lib/firebase/post.js new file mode 100644 index 00000000..1b93e0e9 --- /dev/null +++ b/src/lib/firebase/post.js @@ -0,0 +1,26 @@ +class Post { + constructor() { + this.fs = firebase.firestore(); + const settings = { timestampsInSnapshots: true } // fecha válida. timestampsInSnapshots(de firestore viene como timestamp y este métoso lo convierte a datetime que ocupa Js ) + this.fs.settings(settings); + } + crearPost(uid, emailUser, titulo, descripcion) { + return this.fs.collection('posts').add({ // adición de un post. También podemos utilizar nuestro propio Id usando: .doc("key").set({ + uid: uid, + autor: autor, + titulo: titulo, + descripcion: descripcion, + fecha: firebase.firestore.FieldValue.serverTimestamp() + }) + .then(refDoc => { // si la inserción(creación del post) fue exitosa debería dar en la consola el id del post que debería venir del firestore + console.log(`Id del post =>${refDoc.id}`) + }).catch(error => { + console.log(`Error de creación del post =>${error}`); + }) + } + consultarTodosPost() { + } + consultarPostxUsuario(emailUser) { + } +} + \ No newline at end of file diff --git a/src/lib/index.js b/src/lib/index.js deleted file mode 100644 index d1930899..00000000 --- a/src/lib/index.js +++ /dev/null @@ -1,6 +0,0 @@ -// aqui exportaras las funciones que necesites - -export const myFunction = () => { - // aqui tu codigo - console.log('Hola mundo!'); -}; diff --git a/src/main.js b/src/main.js index ac27e91a..4879d56f 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,148 @@ -// Este es el punto de entrada de tu aplicacion +// Import the functions of Firestore for posting +import { getAuth } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-auth.js"; +import { onNavigate } from "./js/routes.js"; +import { login, register, loginWithGoogle, verificarSendingMail, logOut } from "./lib/firebase/methodsAuth.js"; -import { myFunction } from './lib/index.js'; -myFunction(); +const auth = getAuth(); + +/*..................................AUTH CONTROLLER.................................*/ + + +function validarCorreo(correo) { + const expReg = /^[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 valido = expReg.test(correo); + console.log(valido); + if (valido === true) { + console.log('valido'); + return true; + } if (valido === false) { + console.log('invalido'); + return false; + } +} + +// SIGN UP +const signupForm = document.getElementById('formularioSU'); +if (signupForm) { + signupForm.addEventListener("submit", async (e) => { + e.preventDefault(); // para cancelar el evento de reinicio del formulario + console.log(signupForm.value); + let signupEmail = ''; + + const valorCorreo = document.getElementById('idCorreoSU').value; + const posibleCorreo = validarCorreo(valorCorreo); + if (posibleCorreo === true) { + signupEmail = valorCorreo; + } else { + signupEmail = ''; + } + const signupPassword = document.getElementById('idContraseñaSU').value; + + // función de Firebase para registrar un usuario + try { + const resultado = await register(auth, valorCorreo, signupPassword); + verificarSendingMail(auth) + console.log(resultado); + signupForm.reset(); + signupForm.querySelector('.message-error-email').innerHTML = ''; + signupForm.querySelector('.message-error-password').innerHTML = ''; + + } + catch ({ code, message }) { + console.log(message); + // personalizando los mensajes de los 2 errores mas comunes + if (code === 'auth/email-already-in-use') { + signupForm.querySelector('.message-error-email').innerHTML = 'El Email ya se encuentra registrado' + } else if (code === 'auth/weak-password') { + signupForm.querySelector('.message-error-password').innerHTML = 'La Contraseña debe tener al menos 6 carácteres' + } else { + signupForm.querySelector('.message-error').innerHTML = message; // mensajes por defecto de los otros posibles errores + } + } + console.log('signUp'); + + }); +}; + + +// SIGN IN + +const signinForm = document.getElementById('formularioSI'); +if (signinForm) { + signinForm.addEventListener('submit', async (e) => { + e.preventDefault(); + const emailInput = document.getElementById('idCorreoSI').value; + const passwordInput = document.getElementById('idContraseñaSI').value; + try { + const { emailVerified, email } = await login(auth, emailInput, passwordInput) + + //console.log(emailVerified,email); + /* permitir acceder a la página a solo los usuarios que hayan verificado su cuenta a través del correo electrónico enviado */ + if (emailVerified) { + onNavigate('/feed'); + console.log('Bienvenid@', email); + } else { + + /* auth.signOut();*/ + console.log('Por favor realiza la verificación de tu cuenta'); + } + // console.log(emailVerified) /* verificando el observador */ + + + signinForm.reset(); + signinForm.querySelector('.message-error-email-login').innerHTML = ''; + signinForm.querySelector('.message-error-password-login').innerHTML = ''; + + + } catch ({ code, message }) { + // console.log('error', error.message, error.code, error.response) + + if (code === 'auth/user-not-found') { + signinForm.querySelector('.message-error-email-login').innerHTML = 'El Usuario no se encuentra registrado'; + } else if (code === 'auth/wrong-password') { + signinForm.querySelector('.message-error-password-login').innerHTML = 'La Contraseña no corresponde al usuario'; + // } else { + // signinForm.querySelector('.message-error').innerHTML = message; //mensajes por defecto de los otros posibles errores + // } + } + + console.log('signIn'); + }; + }); +}; + +// LOGOUT +const logoutButton = document.getElementById('botonAceptar'); +if (logoutButton) { + logoutButton.addEventListener('click', () => { + logOut(auth); + onNavigate('/'); + + }); +} + +// GOOGLE LOGIN +const googleButton = document.getElementById('entrarGoogle') +if (googleButton) { + googleButton.addEventListener('click', async (e) => { + e.preventDefault(); + try { + const {emailVerified, email}= await loginWithGoogle(auth); + signinForm.reset(); + if (emailVerified) { + onNavigate('/feed'); + console.log('Bienvenid@', email); + } else { + + /* auth.signOut();*/ + console.log('Por favor realiza la verificación de tu cuenta'); + } + } + + catch (error) { + + }; + }); + + }; diff --git a/src/style.css b/src/style.css new file mode 100644 index 00000000..9aebb35d --- /dev/null +++ b/src/style.css @@ -0,0 +1,763 @@ +@import url('https://fonts.googleapis.com/css2?family=ABeeZee&display=swap'); + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +.btnSubmit:hover { + background: rgba(14, 13, 13, 0.5); +} + +input:hover { + background: rgba(245, 236, 236, 0.5); +} + +.btnGoogle:hover { + background: rgb(41, 41, 248); +} + +.message-error { + font-size: 12px; + font-family: sans-serif; + margin-top: 30px; + color: whitesmoke; + text-align: justify; + background-color: rgb(214, 42, 42); + border-radius: 5px; + width: 100%; + padding: 0px 5px; +} + +/* ESTILOS GENERALES */ + +input { + backdrop-filter: blur(15px); + width: 240px; + height: 45px; + border: transparent; + margin: 25px 30px 0px 30px; + cursor: pointer; + justify-content: center; + background: rgba(255, 255, 255, 0.32); + border-radius: 8px; + +} + +.btnSubmit { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + margin: 25px 30px 0 30px; + width: 240px; + height: 45px; + background: rgba(41, 41, 43, 0.8); + border-radius: 6px; + /* Inside auto layout */ + flex: none; + order: 0; + align-self: stretch; + flex-grow: 0; + color: rgba(255, 255, 255, 0.32); + font-size: 16px; + line-height: 25px; + letter-spacing: 2px; + border: none; + cursor: pointer; + +} + +/* Estilos para vista HOME*/ + +h1 { + font-family: 'Fredoka One'; + position: absolute; + width: 300px; + height: 47px; + left: 28px; + top: 115px; + font-style: normal; + font-weight: 400; + font-size: 35px; + line-height: 42px; + color: rgba(255, 242, 242, 0.25); + text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); +} + +h5 { + position: absolute; + width: 187px; + height: 18px; + left: 30px; + top: 75px; + font-family: 'ABeeZee'; + font-size: 18px; + line-height: 24px; + color: #f5efef; +} + +/* BARRA NAVEGACIÓN */ + +.navBarHome { + height: 40px; + width: 360px; + top: 5px; + left: 170px; + position: absolute; + z-index: 1; + +} + +.ul-home { + height: 40px; + width: 360px; + right: 0px; + justify-content: right; + +} + +.navLink { + display: inline-block; + font-family: century Gothic; + color: #575454; + margin: 5px; + text-align: right; + cursor: pointer; + color: #f5efef; + padding: 0 7px; + font-size: 14px; +} + +/* Estilos para Vista REGISTER */ +.sectionSignup-in { + width: 360px; + height: 800px; + justify-content: center; + background: linear-gradient(180deg, #334E6F 0%, #8F9CA3 100%); +} + +.tituloh2register-login { + font-family: 'Fredoka One'; + width: 300px; + height: 47px; + text-align: center; + font-style: normal; + font-weight: 400; + font-size: 35px; + line-height: 42px; + color: rgba(255, 242, 242, 0.25); + text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + margin: 0; + position: absolute; + top: 100px; + left: 35px; +} + +.contenedorForm { + background: rgba(255, 255, 255, 0.32); + box-shadow: 0px 3px 10px rgba(46, 46, 66, 0.1); + display: flex; + flex-direction: column; + align-items: flex-start; + padding: 24px; + gap: 24px; + position: absolute; + width: 340px; + height: 460px; + left: 10px; + top: 190px; + border-radius: 30px; +} + +.form { + display: contents; + justify-content: center; + align-items: center; +} + +.password, +.email, +.username { + line-height: 24px; + color: #000000; + align-items: center; + text-align: center; + +} + +/* Dar color más tenue al placeholder de los input */ +input::placeholder { + color: #8F9CA3; +} + +/* Estilos para los títulos de los labels de cada input */ +.usuario { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 15px; + line-height: 150%; + color: #52525C; + position: absolute; + left: 55px; + /* left: 140px; */ +} + +.labelEmailLogin { + top: 25px; + left: 55px; + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 15px; + line-height: 150%; + color: #52525C; + position: absolute; +} + +.labelPasswordLogin { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 15px; + line-height: 150%; + color: #52525C; + position: absolute; + left: 55px; + /* left: 141px; */ + top: 120px; +} + +/* Estilos para mensaje de error */ + +.message-error-email-login { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 150%; + color: #d16b49; + position: absolute; + left: 55px; + top: 97px; +} + +.message-error-password-login { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 150%; + color: #d16b49; + position: absolute; + left: 55px; + top: 190px; +} + +.p-tienes-cuenta-register { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 150%; + color: #52525C; + position: absolute; + left: 72px; + bottom: 60px; +} + +/* Parrafo con enlace a sigin */ + +.p-tienes-cuenta { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 150%; + color: #52525C; + position: absolute; + left: 75px; + bottom: 60px; +} + +.enlace-signin { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 150%; + color: #52525C; + position: absolute; + left: 60px; + bottom: 60px; +} + +.imgInicio { + width: 360px; + height: 800px; + z-index: 0; +} + +.signin-a { + text-decoration: underline; + color: #294074; + text-align: center; + cursor: pointer; + +} + +.imgGoogle { + width: 34px; + height: 33.4px; + /*padding: 1%;*/ + margin: -1.775rem .17rem 0rem 0rem; + padding: 0px; + display: flex; + align-items: baseline; + /* position: absolute; */ + left: 55px; + background-color: #f5efef; + border: 6px solid #f5efef; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} + +.btnGoogle { + /* background: transparent;*/ + /*background: linear-gradient(294deg, rgba(238, 174, 202, 1) 0%, rgba(148, 187, 233, 1) 100%); */ + width: 219px; + height: 35px; + border-radius: 3px; + border: none; + color: rgb(225, 220, 245); + text-align: center; + border: 1px solid rgb(0, 81, 255); + background-color: rgb(0, 81, 255); + cursor: pointer; + justify-content: center; + margin: 25px 30px 0px 38px; + /* padding-left: 30px; */ + font-size: 16px; + text-align: right; + padding-right: 28px; + padding-top: 10px; + text-shadow: 1px 0 1px #ffffff; + +} + +/*estilos del SignUp*/ +.contenedorForm { + background: rgba(255, 255, 255, 0.32); + box-shadow: 0px 3px 10px rgba(46, 46, 66, 0.1); + display: flex; + flex-direction: column; + align-items: flex-start; + padding: 24px; + gap: 24px; + position: absolute; + width: 340px; + height: 460px; + left: 10px; + top: 190px; + border-radius: 30px; +} + +.form { + display: contents; + justify-content: center; + align-items: center; +} + +.password, +.email, +.username { + line-height: 24px; + color: #000000; + align-items: center; + text-align: center; + +} + +/* Dar color más tenue al placeholder de los input */ +input::placeholder { + color: #8F9CA3; +} + +/* Estilos para los títulos de los labels de cada input */ +.usuario { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 15px; + line-height: 150%; + color: #52525C; + position: absolute; + left: 55px; + /* left: 140px; */ +} + +.labelEmail { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 15px; + line-height: 150%; + color: #52525C; + position: absolute; + /* left: 152px; */ + left: 55px; + top: 120px; +} + +.labelPassword { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 15px; + line-height: 150%; + color: #52525C; + position: absolute; + left: 55px; + /* left: 141px; */ + top: 215px; + +} + +/* Estilos para mensaje de error */ + +.message-error-email { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 150%; + color: #d16b49; + position: absolute; + left: 55px; + top: 190px; +} + +.message-error-password { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 150%; + color: #d16b49; + position: absolute; + left: 55px; + top: 285px; +} + +/* Parrafo con enlace a sigin */ + +.p-tienes-cuenta { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 150%; + color: #52525C; + position: absolute; + left: 100px; + bottom: 60px; +} + +.enlace-signin { + font-family: 'Century Gothic'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 150%; + color: #52525C; + position: absolute; + left: 60px; + bottom: 60px; +} + +.imgInicio { + width: 360px; + height: 800px; +} + +/* .....................estilos SECTION FEED............... */ + +.section-feed { + width: 360px; + height: 100vh; + overflow: scroll; + /*es el 100% para cualquier dispositivo*/ + overflow: scroll; + position: relative; + /*para que el hijo posicionarse respecto al section-feed*/ + /* justify-content: center; */ + background: linear-gradient(180deg, #334E6F 0%, #8F9CA3 100%); + + +} + + +.tituloh2-feed { + font-family: 'Fredoka One'; + width: 300px; + height: 47px; + text-align: center; + font-style: normal; + font-weight: 400; + font-size: 35px; + line-height: 42px; + color: rgba(255, 242, 242, 0.25); + text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + margin: 0; + /* position: absolute; + top: 25px; + left: 19px */ +} + +.avatarImg { + width: 65px; + height: 65px; + + /* position: absolute; + right: 12px; + top:12px */ +} + + +.container-buttons { + position: absolute; + position: sticky; + z-index: 1; + bottom: 0; + left: 0; + top: 745px; + width: 360px; + height: 59px; + background-color: #F7DAE5; + display: grid; + grid-template-columns: repeat(3, 1fr); + /*las tres columnas tendrán la misma dimensión en cualquier dispositivo*/ +} + +.container-buttons button { + padding: 1rem; + border: none; + background: transparent; +} + +.perfil-button { + cursor: pointer !important; +} + +.comentario-button { + cursor: pointer; +} + +.logout-button { + cursor: pointer; +} + +.feed-container-header { + display: flex; + align-items: center; + justify-content: space-between; + width: 100% !important; + padding: 1rem; +} + + +.contenedor-posts { + width: 100%; + height: 800px; + background-color: transparent; + border: none; + display: flex; + flex-direction: column; + margin: 0 0 0 20px; + gap: 20px; + +} + +.post-div { + width: 90%; + height: 25vh; + border: 1px solid #52525C; + border-radius: 10px; + background-color: #ffffff; + font-family: 'Roboto', sans-serif; + font-size: 10px; + +} + +.parte-superior-post { + background-color: #C3E2E6; + height: 6vh; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + border-bottom: none; + display: flex; + align-items: center; +} + +.boton-editar { + border: none; + background-color: transparent; + position: absolute; + right: 8vh; + color: #222222; + cursor: pointer; +} + +.boton-eliminar { + border: none; + background-color: transparent; + position: absolute; + right: 4vh; + color: #222222; + cursor: pointer; + +} + +.boton-like { + border: none; + color: #FA79AA; + background-color: transparent; + position: absolute; + margin-top: 110px; + right: 4vh; + font-size: 10px; + font-family: 'roboto, sans-serif'; + cursor: pointer; + +} + +.titulo-post { + font-family: 'Roboto', sans-serif; + font-size: 15px; + color: #52525C; +} + +.textoUser { + border: none; + resize: none; + width: 90%; + height: 50px; + margin: 0 5px 0 20px; + border: 5px double #d6d6db; + border-radius: 3px; + text-indent: 5px; + margin-bottom: 10px; + margin-top: -40px; + +} + +h2.titulo-post { + position: relative; + top: -35px; + margin: 0 0 0 20px; +} + +h3.descripcion-post { + margin: 0 0 0 20px; + color: #222222; +} + +h4.fecha-post { + position: relative; + top: 60px; + margin: 0 0 0 15px; + + color: #888686; + font-size: 10px; +} + +.post-btn { + position: relative; + background: #3b5998; + border-radius: 2px; + width: 50px; + height: 20px; + color: #d6d6db; + text-shadow: 1px 0 1px #ffffff; + border: none; + left: 275px; + top: 5px; + cursor: pointer; + +} + +/*modal logout*/ + +.modal { + display: none; + background: rgba(0, 0, 0, 0.4); + width: 100%; + height: 100%; + top: 0; + left: 0; + position: fixed; + padding: 15px; + justify-content: center; + align-items: center; +} + +.modal-container { + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(8px); + width: 261.13px; + height: 136px; + left: 49px; + top: 306px; + font-family: sans-serif; + + color: rgb(65, 65, 68); + padding: 25px; + border-radius: 15px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + border: 2px solid rgba(82, 82, 92, 0.5); + + +} +.boton-aceptar{ + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(8px); + border-bottom-left-radius: 15px; + width: 130px; + height: 30px; + border:transparent; + position: relative; + top: 40px; + left:-65px; + color:rgba(201, 23, 23, 1); + border: solid 1px rgba(82, 82, 92, 0.5); + cursor: pointer; +} +.boton-cancelar{ + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(8px); + border-bottom-right-radius: 15px; + width: 130px; + height: 30px; + border: solid 1px rgba(82, 82, 92, 0.5); + position: relative; + top: 23px; + left: 65px; + color:rgba(82, 82, 92, 1); + cursor: pointer; + +} +.texto-delete{ + font-style: normal; + font-weight: 400; + font-size: 18px; + line-height: 21px; + text-align: center; + margin-top: 35px; + + +}