├── utils.js ├── auth.js ├── main.css ├── firestore.js ├── index.html └── app.js /utils.js: -------------------------------------------------------------------------------- 1 | // jshint esversion: 8 2 | export function getUUID() { 3 | var d = new Date().getTime(); 4 | var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace( 5 | /[xy]/g, 6 | function (c) { 7 | var r = (d + Math.random() * 16) % 16 | 0; 8 | d = Math.floor(d / 16); 9 | return (c == "x" ? r : (r & 0x3) | 0x8).toString(16); 10 | } 11 | ); 12 | return uuid; 13 | } 14 | -------------------------------------------------------------------------------- /auth.js: -------------------------------------------------------------------------------- 1 | // jshint esversion: 8 2 | const auth = firebase.auth(); 3 | const provider = new firebase.auth.GoogleAuthProvider(); 4 | 5 | auth.languageCode = "es"; 6 | 7 | export async function login() { 8 | try { 9 | const response = await auth.signInWithPopup(provider); 10 | return response.user; 11 | } catch (error) { 12 | throw new Error(error); 13 | } 14 | } 15 | 16 | export function logout() { 17 | auth.signOut(); 18 | } 19 | -------------------------------------------------------------------------------- /main.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | } 4 | 5 | #app { 6 | width: 700px; 7 | margin: 0 auto; 8 | } 9 | 10 | #user-info { 11 | text-align: center; 12 | } 13 | #user-info img { 14 | border-radius: 50%; 15 | display: block; 16 | width: 100px; 17 | margin: 0 auto; 18 | } 19 | #user-info span { 20 | display: block; 21 | padding: 10px 0; 22 | font-weight: bolder; 23 | font-size: 28px; 24 | } 25 | 26 | input[type="text"] { 27 | box-sizing: border-box; 28 | padding: 10px 5px; 29 | width: 100%; 30 | border-radius: 5px; 31 | } 32 | 33 | #todos-container li { 34 | list-style: none; 35 | padding: 15px 0; 36 | font-size: 20px; 37 | border-bottom: 1px solid #eee; 38 | } 39 | #todos-container li:hover { 40 | background-color: #eee; 41 | } 42 | 43 | .hidden { 44 | display: none; 45 | } 46 | -------------------------------------------------------------------------------- /firestore.js: -------------------------------------------------------------------------------- 1 | // jshint esversion: 8 2 | const db = firebase.firestore(); 3 | export async function insert(item) { 4 | try { 5 | const response = await db.collection("todos").add(todo); 6 | return response; 7 | } catch (error) { 8 | throw new Error(error); 9 | } 10 | } 11 | 12 | export async function getItems(uid) { 13 | try { 14 | let items = []; 15 | const response = await db 16 | .collection("todos") 17 | .where("userid", "==", uid) 18 | .get(); 19 | 20 | response.forEach(function (item) { 21 | items.push(item.data()); 22 | }); 23 | 24 | return items; 25 | } catch (error) { 26 | throw new Error(error); 27 | } 28 | } 29 | 30 | export async function update(id, completed) { 31 | try { 32 | let docId; 33 | const doc = await db.collection("todos").where("id", "==", id).get(); 34 | doc.forEach((i) => { 35 | docId = i.id; 36 | }); 37 | 38 | await db.collection("todos").doc(docId).update({ completed: completed }); 39 | } catch (error) { 40 | throw new Error(error); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 |
12 | 13 | 14 | 23 | 24 |
25 |
26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | // jshint esversion: 8 2 | import { login, logout } from "./auth.js"; 3 | import { insert, getItems, update } from "./firestore.js"; 4 | import { getUUID } from "./utils.js"; 5 | let currentUser; 6 | 7 | let todos = []; 8 | 9 | const buttonLogin = document.getElementById("button-login"); 10 | const buttonLogout = document.getElementById("button-logout"); 11 | const todoInput = document.getElementById("todo-input"); 12 | const todoForm = document.getElementById("todo-form"); 13 | const userInfo = document.getElementById("user-info"); 14 | const todosContainer = document.getElementById("todos-container"); 15 | 16 | firebase.auth().onAuthStateChanged((user) => { 17 | if (user) { 18 | // User is signed in, see docs for a list of available properties 19 | // https://firebase.google.com/docs/reference/js/firebase.User 20 | var uid = user.uid; 21 | currentUser = user; 22 | init(); 23 | } else { 24 | } 25 | }); 26 | 27 | todoForm.addEventListener("submit", (e) => { 28 | e.preventDefault(); 29 | const text = todoInput.value; 30 | if (text !== "") { 31 | addTodo(text); 32 | } 33 | }); 34 | 35 | buttonLogin.addEventListener("click", async (e) => { 36 | try { 37 | currentUser = await login(); 38 | init(); 39 | } catch (error) { 40 | console.error(error); 41 | } 42 | }); 43 | 44 | buttonLogout.addEventListener("click", (e) => { 45 | logout(); 46 | //localStorage.removeItem("user"); 47 | buttonLogin.classList.remove("hidden"); 48 | buttonLogout.classList.add("hidden"); 49 | todoForm.classList.add("hidden"); 50 | todosContainer.innerHTML = ""; 51 | }); 52 | 53 | async function init() { 54 | //localStorage.setItem("user", JSON.stringify(currentUser)); 55 | buttonLogin.classList.add("hidden"); 56 | buttonLogout.classList.remove("hidden"); 57 | todoForm.classList.remove("hidden"); 58 | userInfo.innerHTML = ` 59 | 60 | ${currentUser.displayName} 61 | `; 62 | 63 | loadTodos(); 64 | } 65 | 66 | async function addTodo(text) { 67 | try { 68 | const todo = { 69 | id: getUUID(), 70 | text: text, 71 | completed: false, 72 | userid: currentUser.uid, 73 | }; 74 | const response = await insert(todo); 75 | loadTodos(); 76 | } catch (error) { 77 | console.error(error); 78 | } 79 | } 80 | 81 | async function loadTodos() { 82 | todosContainer.innerHTML = ""; 83 | todos = []; 84 | 85 | try { 86 | const response = await getItems(currentUser.uid); 87 | 88 | todos = [...response]; 89 | renderTodos(); 90 | } catch (error) { 91 | console.error(error); 92 | } 93 | } 94 | 95 | function renderTodos() { 96 | let html = ""; 97 | todos.forEach((todo) => { 98 | html += ` 99 |
  • 100 | 103 | 104 |
  • 105 | `; 106 | }); 107 | 108 | todosContainer.innerHTML = html; 109 | 110 | document 111 | .querySelectorAll('#todos-container input[type="checkbox"]') 112 | .forEach((checkbox) => { 113 | checkbox.addEventListener("change", async (e) => { 114 | const id = e.target.id; 115 | try { 116 | await update(id, e.target.checked); 117 | } catch (error) { 118 | console.error(error); 119 | } 120 | }); 121 | }); 122 | } 123 | --------------------------------------------------------------------------------