-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
167 lines (145 loc) · 6.7 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.5.2/firebase-app.js'
import { getDatabase,
ref,
push,
onValue,
remove,
update
} from 'https://www.gstatic.com/firebasejs/10.5.2/firebase-database.js'
import { v4 as uuidv4 } from 'https://jspm.dev/uuid'
// assign a new uuid to each user of the app
const thisUser = uuidv4()
const endorsementInputEl = document.getElementById('endorsement-input')
const endorsementsSection = document.getElementById('endorsements')
const form = document.getElementById('form')
const from = document.getElementById('from')
const to = document.getElementById('to')
const firebaseConfig = {
databaseURL: 'https://we-are-the-champions-d748d-default-rtdb.firebaseio.com/'
}
const app = initializeApp(firebaseConfig)
const database = getDatabase(app)
const endorsementsDB = ref(database, "endorsements")
// when all the required fields in the form have been populated
form.addEventListener('submit', function(e) {
e.preventDefault()
// extract the endorsement data from the DOM
const endorsementText = endorsementInputEl.value.replace(/</g, "<").replace(/>/g, ">")
const endorsementFrom = from.value.replace(/</g, "<").replace(/>/g, ">")
const endorsementTo = to.value.replace(/</g, "<").replace(/>/g, ">")
const likes = 0
const isLiked = false // used to signify if endorsement has at least 1 like
const endorsementWriter = thisUser
// push the endorsement to the database
push(endorsementsDB, {endorsementText, endorsementFrom, endorsementTo, likes, isLiked, endorsementWriter})
clearTextFields()
})
// when the database resets
onValue(endorsementsDB, function(snapshot) {
if (snapshot.exists()) {
// get the information stored in the database
const data = Object.entries(snapshot.val())
// clear the endorsements sections of the previous data (becauase now the snapshot looks different)
endorsementsSection.innerHTML = ''
// for each currently present endorsement
data.forEach(endorsementContent => {
// add it to the endorsements section
appendEndorsementToEndorsementsSection(endorsementContent)
})
} else {
endorsementsSection.textContent = "No endorsements written yet"
}
})
function appendEndorsementToEndorsementsSection(endorsement) {
const endorsementID = endorsement[0]
const { endorsementText, endorsementFrom, endorsementTo, endorsementWriter } = endorsement[1]
let { likes, isLiked, whoLiked } = endorsement[1]
let liked // used to signify if the endorsement has been liked in the DOM by THIS user
let hide // used to signify if this endorsement can be deleted by this user
// if this endorsement has been liked at least once AND by this user
if (isLiked && whoLiked.includes(thisUser)) {
liked = 'liked' // signify their like in the UI
}
// else if this endorsement is liked but not by this user
else if (whoLiked && !whoLiked.includes(thisUser)) {
liked = ''
}
// else, this endorsement hasn't been liked even once, represent this state
else {
liked = ''
whoLiked = []
}
// if thisUser wrote this endorsement
if (thisUser === endorsementWriter) {
// allow them to delete this endorsement
hide = ''
}
// else, if thisUser did not write this endorsement
else {
// don't allow them to delete this endorsement
hide = 'hidden'
}
let endorsementEl = `
<div class="endorsement-container" id="endorsement-container">
<i class="fa-solid fa-x delete-icon ${hide}" id="delete-icon"></i>
<p class="from">From ${endorsementFrom}</p>
<p class="endorsement">${endorsementText}</p>
<p class="to">To ${endorsementTo}</p>
<p class="${liked}"><i class="fa-solid fa-heart heart-icon"></i> <span>${likes}</span></p>
</div>
`
// write the endorsementEl to the top of endorsements section
// this way is better than using '.innerHTML' because the previous HTML data (and thus event listeners) don't get overwritten (or erased)
// on subsequent usages of .innerHTML
endorsementsSection.insertAdjacentHTML('afterbegin', endorsementEl)
// extract the endorsementEl from the DOM to be able to add a click event to the delete icon
endorsementEl = document.getElementById('endorsement-container')
const deleteIcon = endorsementEl.firstElementChild
const heartIcon = endorsementEl.lastElementChild
const locationOfEndorsementInDB = ref(database, `endorsements/${endorsementID}`)
// add a click event listener to the 'delete-icon' in the endorsement
deleteIcon.addEventListener('click', function() {
// remove this endorsement from the database and UI
remove(locationOfEndorsementInDB)
})
// add a click event to the the 'heart-icon' in the endorsement to be able to increment/decrement the endorsement's like count by 1
heartIcon.addEventListener('click', function() {
// if this is a unique instance of the app
if (thisUser) {
// set/unset liked class
if (!liked) { // if the endorsement is not liked, make it liked
likes++
isLiked = true // endorsement has at least 1 like
whoLiked.push(thisUser) // add this user to the whoLiked-this-endorsement collection
update(locationOfEndorsementInDB, {
likes: likes,
isLiked: isLiked,
whoLiked: whoLiked // update (or add) whoLiked array to database
})
} else { // if it is liked and the heart icon is clicked again, unlike this endorsement
likes--
whoLiked.splice(whoLiked.indexOf(thisUser), whoLiked.indexOf(thisUser)) // remove this user from the whoLiked-this-endorsement collection
if (likes === 0) {
isLiked = false // endorsement has no likes
update(locationOfEndorsementInDB, {
likes: likes,
isLiked: isLiked,
whoLiked: null // remove whoLiked array from database
})
} else { // endorsement has at least one like
update(locationOfEndorsementInDB, {
likes: likes,
whoLiked: whoLiked // update whoLiked array to database
})
}
}
}
})
}
function clearTextFields() {
// clear endorsement textarea
endorsementInputEl.value = ''
// clear "From" and "To" input fields
from.value = ''
to.value = ''
}