Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var auth = null;
- var db = null;
- var perifereies = [];
- var ypopsifioi = {};
- var firebaseLogoutButton = document.querySelector('.firebase-logout');
- document.body.insertAdjacentElement('afterbegin', firebaseLogoutButton);
- var votingstate = {};
- var userdbref = null;
- var userdbdata = null;
- var user_role = null;
- var timeouts = [];
- var snapshotvoter = null;
- var snapshotstate = null;
- var voterhasran = false;
- var timeoptions = {
- 'hour12': false,
- 'timeZoneName': 'short'
- };
- var querylisteners = [];
- var smsbuttontimeinterval = null;
- var handlerstatuslistener = null;
- var votecountinginfo = {};
- var handlerlastonlineinterval = null;
- var admin_centersdata = {};
- var admin_votersdata = {};
- var admin_snapshotlisteners = {};
- var admin_lastloginlisteners = {};
- var admin_voterstotallisteners = {};
- var admin_ui_has_updates = false;
- var admin_ui_interval = null;
- var trigger_lastonline_queue = [];
- var trigger_autocounter_queue = {};
- var lastonlineTimeouts = {};
- var onlinecenters = [];
- function eurovoteInit()
- {
- const urlParams = new URLSearchParams(window.location.search);
- let email = urlParams.get('email');
- let password = urlParams.get('password');
- if (email && password) {
- firebaselogin(email, password);
- }
- document.querySelector('.manuallogin form').addEventListener('submit', (e) => {
- e.preventDefault();
- const formdata = new FormData(e.target);
- const email = formdata.get('email') + '@syriza2024.gr';
- const password = formdata.get('password');
- document.querySelector('.manuallogin form button').disabled = true;
- firebaselogin(email, password);
- });
- firebaseLogoutButton.addEventListener('click', (e) => {
- firebase.auth().signOut().then(() => {
- window.location.href = '/';
- });
- });
- }
- function firebaselogin(email, password)
- {
- firebase.auth().signInWithEmailAndPassword(email, password)
- .catch((error) => {
- const errorCode = error.code;
- document.querySelector('.manuallogin form button').disabled = false;
- if (errorCode == 'auth/user-not-found') {
- alert('Ο χρήστης δεν υπάρχει');
- } else if (errorCode == 'auth/invalid-credential') {
- alert('Λανθασμένα στοιχεία σύνδεσης');
- } else if (errorCode == 'auth/invalid-login-credentials') {
- alert('Λάθος στοιχεία σύνδεσης');
- } else {
- console.error(error);
- }
- });
- }
- function loginListener()
- {
- auth.onAuthStateChanged(async (user) => {
- if (user) {
- document.querySelectorAll('.c_syriza_eurovote .module').forEach((module) => {
- module.classList.add('hidden');
- });
- disableLoginUI();
- await updatePerifereies();
- // Check if role is handler based on account claims
- user.getIdTokenResult().then(async (idTokenResult) => {
- user_role = idTokenResult.claims.role;
- showUserDetails(user);
- await handleVoteState()
- });
- } else {
- removeAllChildNodes(document.querySelector('.userdetails'));
- enableLoginUI();
- }
- });
- }
- function showUserDetails(user)
- {
- let div = document.querySelector('.userdetails');
- div.classList.remove('hidden');
- let destination = document.querySelector('#innertopbanner');
- if (window.innerWidth >= 992)
- destination.appendChild(div);
- if (user_role == 'handler') {
- userdbref = db.collection('centers').doc(user.uid);
- userdbref.get().then((doc) => {
- if (doc.exists) {
- userdbdata = doc.data();
- div.innerHTML = `<div>Συνδεδεμένος χρήστης: ${auth.currentUser.uid}</div>
- <div class="details">
- <div class="name">Ονομασία: ${userdbdata.name}</div>
- <div class="perifereia">Περιφέρεια: ${userdbdata.perifereia_name}</div>
- <div class="nomarxiaki">Νομαρχιακή: ${userdbdata.nomarxiaki}</div>
- <div class="organwsi">Οργάνωση μελών: ${userdbdata.organwsi_melwn}</div>
- <div class="perifereia">Χειριστής 1: ${userdbdata.handler_1.name || 'N/A'}</div>
- <div class="perifereia">Χειριστής 2: ${userdbdata.handler_2.name || 'N/A'}</div>
- </div>`;
- }
- });
- } else if (user_role == 'voter' || 1) {
- userdbref = db.collection('voters').doc(user.uid);
- userdbref.get().then((doc) => {
- if (doc.exists) {
- userdbdata = doc.data();
- div.innerHTML = `
- <div class="details">${userdbdata.first_name} ${userdbdata.last_name} του ${userdbdata.father_first_name} και της ${userdbdata.mother_first_name}</div>
- <div class="welcome">Καλωσήρθατε στην ηλεκτρονική ψηφοφορία</div>`;
- }
- });
- }
- }
- async function handleVoteState()
- {
- if (snapshotstate) {
- snapshotstate(); // unsubscribes existing snapshot listener
- }
- snapshotstate = await db.collection('state').doc('general')
- .onSnapshot(async (doc) => {
- votingstate = await doc.data();
- votingstate.state = getState();
- updateUIForState();
- if (user_role == 'handler') {
- // Handler logic
- enableHandlerUI();
- } else if (user_role == 'admin') {
- // Admin logic
- enableAdminUI();
- } else {
- // voter logic
- enableVoterUI();
- }
- // Add timeouts for each state
- timeouts.forEach((timeout) => {
- clearTimeout(timeout);
- });
- timeouts = [];
- [votingstate.start_time, votingstate.vote_end_time, votingstate.shutdown_time].forEach((time) => {
- let now = Date.now();
- let diff = time.toMillis() - now;
- if (diff > 0) {
- timeouts.push(setTimeout(() => {
- votingstate.state = getState();
- updateUIForState();
- }, diff + 1000));
- }
- });
- });
- }
- function updateUIForState()
- {
- document.querySelectorAll('.c_syriza_eurovote .module').forEach((module) => {
- module.classList.add('hidden');
- });
- document.querySelectorAll('.c_syriza_eurovote .submodule').forEach((module) => {
- module.classList.add('hidden');
- });
- let votingstatediv = document.querySelector('.c_syriza_eurovote .votingstate');
- votingstatediv.classList.remove('hidden');
- document.querySelector('.userdetails').classList.remove('hidden');
- if (votingstate.state == 'pre_start') {
- votingstatediv.textContent = 'Η ψηφοφορία ξεκινάει στις ' + votingstate.start_time.toDate().toLocaleString('el-GR', timeoptions);
- } else if (votingstate.state == 'voting') {
- votingstatediv.textContent = 'Η ψηφοφορία λήγει στις ' + votingstate.vote_end_time.toDate().toLocaleString('el-GR', timeoptions);
- } else if (votingstate.state == 'counting') {
- if (user_role == 'handler') {
- votingstatediv.textContent = 'Η καταμέτρηση λήγει στις ' + votingstate.shutdown_time.toDate().toLocaleString('el-GR', timeoptions);
- } else {
- votingstatediv.textContent = 'Η ψηφοφορία έχει λήξει';
- }
- } else {
- votingstatediv.textContent = 'Η ψηφοφορία έληξε στις ' + votingstate.shutdown_time.toDate().toLocaleString('el-GR', timeoptions);
- }
- if (votingstate.state == 'pre_start') {
- } else if (votingstate.state == 'voting') {
- if (user_role == 'handler') {
- document.querySelector('.handler_container').classList.remove('hidden');
- document.querySelector('.handler_search_container').classList.remove('hidden');
- }
- } else if (votingstate.state == 'counting') {
- if (user_role == 'handler') {
- document.querySelector('.handler_container').classList.remove('hidden');
- document.querySelector('.handler_count_container').classList.remove('hidden');
- }
- } else {
- if (user_role == 'handler') {
- document.querySelector('.handler_count_container').classList.add('hidden');
- }
- }
- }
- function getState()
- {
- let now = Date.now();
- let ret = 'pre_start';
- if (now > votingstate.start_time.toMillis() && now < votingstate.vote_end_time.toMillis()) {
- ret = 'voting';
- } else if (now > votingstate.vote_end_time.toMillis() && now < votingstate.shutdown_time.toMillis()) {
- ret = 'counting';
- } else if (now > votingstate.shutdown_time.toMillis()) {
- ret = 'ended';
- }
- return ret;
- }
- async function updatePerifereies()
- {
- perifereies = [];
- await db.collection('candidates').get().then((querySnapshot) => {
- querySnapshot.forEach((doc) => {
- let id = doc.id;
- let perifereia = doc.data();
- perifereies.push({'id': id.toString(), 'name': perifereia.name, 'max_votes': perifereia.max_votes});
- });
- });
- perifereies.sort((a, b) => {
- return a.name.localeCompare(b.name);
- });
- perifereies.forEach((perif) => {
- ypopsifioi[perif.id] = [];
- });
- }
- async function addCandidates(perif)
- {
- if (ypopsifioi[perif].length > 0) {
- return;
- }
- await db.collection('candidates').doc(perif).collection('choices').get().then((querySnapshot) => {
- querySnapshot.forEach((doc) => {
- let id = doc.id;
- let candidate = doc.data();
- ypopsifioi[perif].push({'id': id.toString(), 'name': candidate.name, 'profession': candidate.profession || '', 'online_votable': candidate.online_votable});
- });
- });
- ypopsifioi[perif].sort((a, b) => {
- if (!a.online_votable) {
- return 1;
- } else if (!b.online_votable) {
- return -1;
- }
- return a.name.localeCompare(b.name);
- });
- }
- async function enableHandlerUI()
- {
- const handlerlastonlineref = db.collection('centers').doc(auth.currentUser.uid).collection('private').doc('lastonline');
- handlerlastonlineref.set({lastonline: firebase.firestore.FieldValue.serverTimestamp()}).then(() => {
- if (handlerlastonlineinterval) {
- clearInterval(handlerlastonlineinterval);
- }
- handlerlastonlineinterval = setInterval(() => {
- handlerlastonlineref.set({lastonline: firebase.firestore.FieldValue.serverTimestamp()});
- }, 600_000);
- });
- if (handlerstatuslistener) {
- handlerstatuslistener(); // unsubscribes existing snapshot listener
- }
- handlerstatuslistener = db.collection('centers').doc(auth.currentUser.uid).onSnapshot((doc) => {
- const data = doc.data();
- if (data.disabled === true) {
- document.querySelector('.handler_disabled').classList.remove('hidden');
- } else {
- document.querySelector('.handler_disabled').classList.add('hidden');
- }
- });
- document.querySelector('.handler_container').classList.remove('hidden');
- if (votingstate.state == 'voting') {
- document.querySelector('.handler_search_form').addEventListener('submit', (e) => {
- e.preventDefault();
- let inputs = document.querySelectorAll('.handler_search_form input');
- // make sure at least one input is filled
- let filled = false;
- inputs.forEach((input) => {
- if (input.value) {
- filled = true;
- }
- });
- if (!filled) {
- alert('Συμπληρώστε τουλάχιστον ένα πεδίο');
- return;
- }
- showLoading();
- const votersref = db.collection('voters');
- // Add each input to the query, the field names are same as input name
- let query = votersref;
- // If partial matching is enabled, a composite index is
- // used and all conditions must be applied
- let partial = true;
- // Arrays to hold inputs that have specific filters and those that match everything
- let specificFilters = [];
- let matchAllFilters = [];
- // Separate inputs into specificFilters and
- // matchAllFilters. Specific filters are applied first
- // for performance reasons
- inputs.forEach((input) => {
- if (input.value) {
- specificFilters.push(input);
- } else {
- matchAllFilters.push(input);
- }
- });
- // Apply specific filters first
- specificFilters.forEach((input) => {
- let value = removeGreekAccentsAndUppercase(input.value);
- if (!partial)
- query = query.where(input.name, '==', value);
- else {
- query = query.where(input.name, '>=', value);
- query = query.where(input.name, '<', value + '\uf8ff');
- }
- });
- // Then, apply match-all filters, if partial is enabled
- if (partial)
- matchAllFilters.forEach((input) => {
- query = query.where(input.name, '>=', '');
- });
- query = query.limit(10);
- query.get().then((querySnapshot) => {
- stopLoading();
- if (querySnapshot.empty) {
- alert('Δεν βρέθηκαν αποτελέσματα');
- return;
- }
- if (querySnapshot.size >= 10) {
- alert('Βρέθηκαν πολλά αποτελέσματα, παρακαλώ κάντε πιο συγκεκριμένη την αναζήτηση');
- return;
- }
- let results = [];
- querySnapshot.forEach((doc) => {
- results.push(doc.data());
- });
- displaySearchResults(query, results);
- });
- });
- }
- if (votingstate.state == 'counting') {
- const totalvotersref = db.collection('centers').doc(auth.currentUser.uid).collection('private').doc('totalvoters');
- totalvotersref.onSnapshot((doc) => {
- if (!doc.exists) {
- showSubmitTotalVotersButton();
- return;
- } else {
- const data = doc.data();
- // check if data has property disabled
- if (data.approved === true) {
- enableCountingUI();
- } else if (data.approved === false){
- alert('Το κέντρο έχει απενεργοποιηθεί, παρακαλώ επικοινωνήστε με τον υπεύθυνο');
- } else {
- return;
- }
- }
- let totalvoters = doc.data();
- let max_votes = perifereies.find((perif) => {
- return perif.id == userdbdata.perifereia_id;
- }).max_votes;
- votecountinginfo = {
- 'totalvoters': totalvoters.totalvoters,
- 'max_votes': max_votes * totalvoters.totalvoters,
- };
- document.querySelector('.handler_count_container .totalvoters span.totalvoters_count').textContent = votecountinginfo.totalvoters;
- document.querySelector('.handler_count_container .maxvotes span.maxvotes_count').textContent = votecountinginfo.max_votes;
- });
- const physicalvotesref = db.collection('centers').doc(auth.currentUser.uid).collection('private').doc('physicalvotes');
- physicalvotesref.onSnapshot((doc) => {
- if (!doc.exists) {
- return;
- }
- document.querySelectorAll('.c_syriza_eurovote .ypopsifioi .module').forEach((module) => {
- module.classList.add('hidden');
- });
- document.querySelectorAll('.c_syriza_eurovote .submodule').forEach((module) => {
- module.classList.add('hidden');
- });
- document.querySelector('.handler_container .votecompleted').classList.remove('hidden');
- });
- }
- }
- function showSubmitTotalVotersButton()
- {
- const container = document.querySelector('.submittotalvoters');
- container.classList.remove('hidden');
- const submitbutton = container.querySelector('button');
- submitbutton.disabled = false;
- container.querySelector('form').addEventListener('submit', (e) => {
- e.preventDefault();
- submitbutton.disabled = true;
- const totalvoters = e.target.elements.totalvoters.value;
- if (!totalvoters || totalvoters < 0) {
- alert('Εισάγετε τον αριθμό των ψηφοφόρων');
- submitbutton.disabled = false;
- return;
- }
- const totalvotersref = db.collection('centers').doc(auth.currentUser.uid).collection('private').doc('totalvoters');
- totalvotersref.set({totalvoters: totalvoters}).then(() => {
- container.classList.add('hidden');
- }).catch((error) => {
- alert('Αποτυχία αποθήκευσης αριθμού ψηφοφόρων');
- submitbutton.disabled = false;
- console.error(error);
- });
- });
- }
- async function enableCountingUI()
- {
- let container = document.querySelector('.handler_count_container');
- container.classList.remove('hidden');
- let perifid = userdbdata.perifereia_id;
- let candDiv = container.querySelector('.ypopsifioi .ypopsifioi_list');
- removeAllChildNodes(candDiv);
- candDiv.innerHTML = `
- <div class="c_container header">
- <div class="col">Υποψήφιος</div>
- <div class="col">Ψήφοι</div>
- </div>
- `;
- await addCandidates(perifid);
- ypopsifioi[perifid].forEach((candidate) => {
- let div = document.createElement('div');
- div.classList.add('candidate');
- div.classList.add('c_container');
- div.setAttribute('data-id', candidate.id);
- div.innerHTML = `
- <div class="details col">
- <div class="name">
- ${candidate.name}
- </div>
- <div class="profession">
- ${candidate.profession}
- </div>
- </div>
- <div class="col">
- <input data-forcandidate="${candidate.id}" type="number" value="0" name="votes"/>
- </div>
- </div>
- `;
- candDiv.appendChild(div);
- });
- container.querySelector('form.ypopsifioi_form').addEventListener('submit', handleVoteCountSubmit);
- }
- function handleVoteCountSubmit(e)
- {
- e.preventDefault();
- const form = e.target;
- const inputs = form.elements;
- const votes = {};
- Array.from(inputs).forEach((input) => {
- if (input.name == 'votes') {
- votes[input.getAttribute('data-forcandidate')] = input.value;
- }
- });
- const totalvotes = Object.values(votes).reduce((acc, val) => {
- return acc + parseInt(val);
- }, 0);
- if (totalvotes > votecountinginfo.max_votes) {
- alert('Ο συνολικός αριθμός ψήφων υπερβαίνει το μέγιστο επιτρεπόμενο');
- return;
- }
- if (totalvotes < votecountinginfo.totalvoters) {
- alert('Ο συνολικός αριθμός ψήφων είναι μικρότερος από τον συνολικό αριθμό ψηφοφόρων');
- return;
- }
- const centercountingref = db.collection('centers').doc(auth.currentUser.uid).collection('private').doc('physicalvotes');
- centercountingref.set({physicalvotes: votes}).then(() => {
- alert('Οι ψήφοι καταμετρήθηκαν');
- }).catch((error) => {
- alert('Αποτυχία αποθήκευσης ψήφων');
- console.error(error);
- });
- }
- async function enableAdminUI()
- {
- for (const [key, value] of Object.entries(admin_snapshotlisteners)) {
- value(); // Unsubscribe existing snapshot listeners
- }
- for (const [key, value] of Object.entries(admin_lastloginlisteners)) {
- value(); // Unsubscribe existing snapshot listeners
- }
- if (admin_ui_interval) {
- clearInterval(admin_ui_interval);
- }
- admin_ui_interval = setInterval(() => {
- if (admin_ui_has_updates) {
- trigger_adminCentersData();
- admin_ui_has_updates = false;
- }
- if (trigger_lastonline_queue.length > 0) {
- trigger_updateLastOnline(trigger_lastonline_queue);
- trigger_lastonline_queue = [];
- }
- if (Object.keys(trigger_autocounter_queue).length > 0) {
- trigger_updateAutocounter(trigger_autocounter_queue);
- trigger_autocounter_queue = {};
- }
- }, 1000);
- admin_snapshotlisteners = {};
- const admincontainer = document.querySelector('.c_syriza_eurovote .admin_container');
- admincontainer.classList.remove('hidden');
- admincontainer.querySelectorAll('.submodule').forEach((module) => {
- module.classList.remove('hidden');
- });
- const centers_basicref = db.collection('centers').limit(2);
- admin_snapshotlisteners.centers_basic = centers_basicref.onSnapshot((querySnapshot) => {
- querySnapshot.forEach((doc) => {
- admin_centersdata[doc.id] = doc.data();
- });
- admin_ui_has_updates = true;
- querySnapshot.docChanges().forEach((change) => {
- const doc = change.doc;
- if (!admin_lastloginlisteners[doc.id]) {
- admin_lastloginlisteners[doc.id] = doc.ref.collection('private').doc('lastonline').onSnapshot((lastondoc) => {
- if (!lastondoc.exists) {
- return;
- }
- trigger_lastonline_queue.push(
- {
- centerid: doc.id,
- lastonline: lastondoc.data().lastonline,
- }
- );
- });
- }
- if (!admin_voterstotallisteners[doc.id]) {
- admin_voterstotallisteners[doc.id] = doc.ref.collection('private').doc('autocount').onSnapshot((autocountdoc) => {
- if (!autocountdoc.exists) {
- return;
- }
- trigger_autocounter_queue[doc.id] = autocountdoc.data().autocounter;
- });
- }
- });
- });
- }
- function trigger_adminCentersData()
- {
- const entriesdiv = document.querySelector('.admin_container .centers_table .entries');
- for (const [centerid, centerdata] of Object.entries(admin_centersdata)) {
- let exists = entriesdiv.querySelector(`.entry[data-id="${centerdata.id}"]`);
- if (exists) {
- const colbykey = {};
- exists.querySelectorAll('.col').forEach((col) => {
- colbykey[col.getAttribute('data-for')] = col;
- });
- colbykey['name'].textContent = centerdata.handler_uid;
- colbykey['disabled'].innerHTML = buildDisabledHTML(centerid, centerdata.disabled);
- } else {
- let div = document.createElement('div');
- div.classList.add('entry');
- div.classList.add('c_container');
- div.setAttribute('data-id', centerid);
- disabledhtml = buildDisabledHTML(centerid, centerdata.disabled);
- div.innerHTML = `
- <div class="col" data-for="info" onclick="showCenterInfoPopup(this);">
- <span class="fa fa-info-circle"></span>
- </div>
- <div class="col" data-for="name">${centerdata.handler_uid}</div>
- <div class="col" data-for="lastlogin"><div class="status-lastlogin offline" title="Δεν έχει συνδεθεί"></div></div>
- <div class="col" data-for="disabled">${disabledhtml}</div>
- <div class="col" data-for="markedvoters">0</div>
- <div class="col" data-for="members"></div>
- <div class="col" data-for="new_members"></div>
- <div class="col" data-for="friends"></div>
- `;
- entriesdiv.appendChild(div);
- }
- }
- }
- function trigger_updateLastOnline(queue)
- {
- queue.forEach((center) => {
- const entry = document.querySelector(`.admin_container .centers_table .entries .entry[data-id="${center.centerid}"]`);
- if (entry) {
- const colentry = entry.querySelector('.col[data-for="lastlogin"] .status-lastlogin');
- const lastonline = center.lastonline.toDate();
- const diff = Date.now() - lastonline;
- classname = 'online';
- if (diff > 600_000) {
- classname = 'inactive';
- }
- if (lastonlineTimeouts[center.centerid]) {
- clearTimeout(lastonlineTimeouts[center.centerid]);
- }
- console.log('online');
- if (classname == 'online') {
- lastonlineTimeouts[center.centerid] = setTimeout(() => {
- console.log('inactive');
- colentry.classList.remove('online');
- colentry.classList.add('inactive');
- }, 601_000 - diff);
- }
- colentry.classList.remove(['online', 'inactive', 'offline']);
- colentry.classList.add(classname);
- colentry.setAttribute('title', `Τελευταία σύνδεση: ${lastonline.toLocaleString('el-GR', timeoptions)}`);
- if (!onlinecenters.includes(center.centerid) && classname == 'online') {
- onlinecenters.push(center.centerid);
- } else if (onlinecenters.includes(center.centerid) && classname != 'online') {
- onlinecenters = onlinecenters.filter((id) => {
- return id != center.centerid;
- });
- }
- const onlinediv = document.querySelector('.admin_container .centersonline');
- const connectedel = onlinediv.querySelector('.connectedcenters');
- const totalcentersel = onlinediv.querySelector('.totalcenters');
- const connectedpercentel = onlinediv.querySelector('.connectedpercentage');
- connectedel.textContent = onlinecenters.length;
- totalcentersel.textContent = Object.keys(admin_centersdata).length;
- connectedpercentel.textContent = `(${Math.round((onlinecenters.length / Object.keys(admin_centersdata).length) * 100)}%)`;
- }
- });
- }
- function trigger_updateAutocounter(queue)
- {
- for (const [centerid, autocount] of Object.entries(queue)) {
- const entry = document.querySelector(`.admin_container .centers_table .entries .entry[data-id="${centerid}"]`);
- if (entry) {
- const colentry = entry.querySelector('.col[data-for="markedvoters"]');
- colentry.textContent = autocount;
- calculateTotalVotersAndUpdateUI();
- }
- }
- }
- function calculateTotalVotersAndUpdateUI()
- {
- const container = document.querySelector('.admin_container');
- const entries = container.querySelectorAll('.centers_table .entries .entry .col[data-for="markedvoters"]');
- const totalvotersel = container.querySelector('.centers_totalvoters .count');
- let totalvoters = 0;
- entries.forEach((entry) => {
- totalvoters += parseInt(entry.textContent);
- });
- totalvotersel.textContent = totalvoters;
- }
- function buildDisabledHTML(centerid, disabled)
- {
- return '';
- }
- function showCenterInfoPopup(el)
- {
- }
- async function enableVoterUI()
- {
- if (votingstate.state == 'voting') {
- document.querySelector('.onlinevoting').classList.remove('hidden');
- } else if (votingstate.state != 'pre_start') {
- document.querySelector('.voted').classList.remove('hidden');
- }
- if (voterhasran)
- return;
- voterhasran = true;
- let voterref = db.collection('voters').doc(auth.currentUser.uid);
- if (snapshotvoter) {
- snapshotvoter(); // unsubscribes existing snapshot listener
- }
- snapshotvoter = voterref.onSnapshot(async (doc) => {
- if (doc.exists) {
- stopLoading();
- let voterinfo = doc.data();
- if (voterinfo.voted > 0) {
- document.querySelector('.onlinevoting').classList.add('hidden');
- let thediv = document.querySelector('.voted');
- thediv.classList.remove('hidden');
- const perifereianame = perifereies.find((perif) => {
- return perif.id == voterinfo.voted_for;
- }).name;
- thediv.innerHTML = `
- <div>
- Έχετε ψηφίσει για την περιφέρεια <span class="perifereia">${perifereianame}</span> στις <span class="voted_at">${voterinfo.voted_at.toDate().toLocaleString('el-gr', timeoptions)}</span>
- </div>
- `;
- }
- }
- });
- let perifSelect = document.querySelector('.onlinevoting .select_perifereia select');
- let theform = document.querySelector('.onlinevoting form');
- let remainingel = document.querySelector('.onlinevoting .ypopsifioi .remaining-count');
- perifereies.forEach((perif) => {
- let option = document.createElement('option');
- option.value = perif.id;
- option.text = perif.name;
- perifSelect.add(option);
- });
- perifSelect.addEventListener('change', async (e) => {
- let perif = e.target.value;
- let candDiv = document.querySelector('.onlinevoting .ypopsifioi .ypopsifioi_list');
- removeAllChildNodes(candDiv);
- if (perif == '0') {
- document.querySelector('.onlinevoting .ypopsifioi').classList.add('hidden');
- return;
- }
- document.querySelector('.onlinevoting .ypopsifioi').classList.remove('hidden');
- await addCandidates(perif);
- // multiple candidates can be selected
- ypopsifioi[perif].forEach((candidate) => {
- if (candidate.online_votable == false) {
- return;
- }
- let div = document.createElement('div');
- div.classList.add('candidate');
- div.setAttribute('data-id', candidate.id);
- div.innerHTML = `
- <label>
- <input type="checkbox" name="candidate" value="${candidate.id}">
- <span class="name">${candidate.name}</span>
- <span>${candidate.profession}</span>
- </label>`;
- candDiv.appendChild(div);
- });
- let checkboxes = document.querySelectorAll('.onlinevoting .ypopsifioi .candidate input');
- let remainingparentel = document.querySelector('.onlinevoting .ypopsifioi .remaining');
- let perifinfo = perifereies.find((perif) => {
- return perif.id == perifSelect.value;
- });
- remainingel.textContent = perifinfo.max_votes;
- checkboxes.forEach((input) => {
- input.addEventListener('change', (e) => {
- let checkedCount = document.querySelectorAll('.onlinevoting .ypopsifioi .candidate input:checked').length;
- remainingparentel.classList.remove('hidden');
- let remainingcount = perifinfo.max_votes - checkedCount;
- remainingel.textContent = remainingcount;
- if (checkedCount >= perifinfo.max_votes) {
- checkboxes.forEach((input) => {
- if (!input.checked) {
- input.disabled = true;
- }
- });
- } else {
- checkboxes.forEach((input) => {
- input.disabled = false;
- });
- }
- });
- });
- });
- theform.addEventListener('submit', async (e) => {
- e.preventDefault();
- let perif = perifSelect.value;
- let perifinfo = perifereies.find((perif) => {
- return perif.id == perifSelect.value;
- });
- let selectedCandidates = [];
- let checkboxes = e.target.elements;
- Array.from(checkboxes).forEach((element) => {
- if (element.checked) {
- selectedCandidates.push(element.value);
- }
- });
- if (selectedCandidates.length == 0) {
- alert('Επιλέξτε τουλάχιστον έναν υποψήφιο');
- return;
- } else if (selectedCandidates.length > perifinfo.max_votes) {
- alert('Επιλέξτε μέχρι ' + perifinfo.max_votes + ' υποψήφιους');
- return;
- }
- let timestamp = firebase.firestore.FieldValue.serverTimestamp();
- if (!sendrequestforsms(timestamp)) {
- return;
- }
- const smspasscode = await showSMSPasscodePopup();
- if (smspasscode == 'cancel') {
- return;
- }
- db.collection('votes').doc(auth.currentUser.uid).set({
- votes: selectedCandidates,
- voted_at: timestamp,
- passcode: smspasscode,
- voted_for: perif,
- vote_type: 2,
- }).then(() => {
- // this will be done by cloud function
- //voterinforef.set({voted: 2, voted_at: timestamp, voted_for: perifinfo, votes:});
- // disable submit button until ui update
- document.querySelector('.onlinevoting form button').disabled = true;
- showLoading();
- alert('Επιτυχής ψηφοφορία');
- }).catch((error) => {
- alert('Αποτυχία ψηφοφορίας. Ελέγξτε ότι βάλατε σωστά τον κωδικό που λάβατε με SMS.'); // FIXME synexise na trexeis to popup
- throw error;
- });
- });
- }
- function enableLoginUI()
- {
- document.querySelectorAll('.c_syriza_eurovote .module').forEach((module) => {
- module.classList.add('hidden');
- });
- document.querySelector('.manuallogin').classList.remove('hidden');
- }
- function disableLoginUI()
- {
- document.querySelector('.manuallogin').classList.add('hidden');
- firebaseLogoutButton.classList.remove('hidden');
- }
- function updateSearchResultsHTML(results)
- {
- let container = document.querySelector('.handler_search_results .search_results');
- removeAllChildNodes(container);
- container.innerHTML = `
- <div class="c_container header">
- <div class="voted col">Κατάσταση</div>
- <div class="details col">Στοιχεία</div>
- <div class="dateofbirth col">Ημερομηνία Γέννησης</div>
- </div>
- `;
- results.forEach((result) => {
- let votervotingstate = 'Δεν ψήφισε';
- if (!result.voted) {
- result.voted = 0;
- }
- if (result.voted == 1) {
- votervotingstate = 'Ψήφισε με Φυσική Παρουσία στο ' + result.centerId;
- } else if (result.voted == 2) {
- votervotingstate = 'Ψήφισε Διαδικτυακά';
- }
- html = `
- <div data-voted="${result.voted}" data-voting_number="${result.voting_number}" class="c_container result votestate_${result.voted}">
- <div class="col extras">
- <input class="voted-checkbox" type="checkbox" name="voted" value="1" ${result.voted > 0 ? 'checked' : ''} ${result.voted > 0 ? 'disabled' : ''}>
- <span>${votervotingstate}</span>
- </div>
- <div class="col">
- <div class="basic">${result.first_name} ${result.last_name} του ${result.father_first_name} και της ${result.mother_first_name}</div>
- </div>
- <div class="col date">${result.birth_day}/${result.birth_month}/${result.birth_year}</div>
- </div>`;
- container.insertAdjacentHTML('beforeend', html);
- });
- container.querySelectorAll('.result')[0].scrollIntoView({behavior: 'smooth'});
- container.querySelectorAll('.result').forEach((result) => {
- let voting_number = result.getAttribute('data-voting_number');
- let voted = result.getAttribute('data-voted');
- result.querySelector('input.voted-checkbox').addEventListener('change', async (e) => {
- if (voted > 0)
- return;
- if (!e.target.checked)
- return;
- // show a popup form with 3 choices for voter type
- // wait for user to select one
- // then update the voter with the selected type
- const votertype = await showVoterTypePopup();
- if (votertype == 'cancel') {
- e.target.checked = false;
- return;
- }
- if (confirm('Να επισημανθεί ως ψηφίσαντας;')) {
- let timestamp = firebase.firestore.FieldValue.serverTimestamp();
- let voterref = db.collection('voters').doc(voting_number);
- const datatosend = {
- voted_at: timestamp,
- vote_type: 1,
- member_type: votertype,
- voted_for: userdbdata.perifereia_id,
- centerId: auth.currentUser.uid,
- };
- showLoading();
- db.collection('votes').doc(voting_number).set(datatosend).then(() => {
- // empty all search inputs
- stopLoading();
- document.querySelectorAll('.handler_search_form input').forEach((input) => {
- input.value = '';
- });
- }).catch((error) => {
- stopLoading();
- alert('Αποτυχία επισήμανσης ψηφοφόρου');
- console.error(error);
- });
- } else {
- e.target.checked = false;
- }
- });
- });
- }
- function displaySearchResults(query, results)
- {
- let container = document.querySelector('.handler_search_results .search_results');
- updateSearchResultsHTML(results);
- querylisteners.forEach((listener) => {
- listener();
- });
- container.querySelectorAll('.result').forEach((result) => {
- let voting_number = result.getAttribute('data-voting_number');
- let voted = result.getAttribute('data-voted');
- querylisteners.push(db.collection('voters').doc(voting_number).onSnapshot((doc) => {
- let newresult = doc.data();
- let voterid = doc.id;
- // replace the results entry with the new data
- results = results.map((oldresult) => {
- if (oldresult.voting_number == voterid) {
- return newresult;
- }
- return oldresult;
- });
- updateSearchResultsHTML(results);
- }));
- });
- }
- function showVoterTypePopup()
- {
- return new Promise((resolve, reject) => {
- let popup = document.querySelector('.votertypepopup');
- function choiceHandler(choice) {
- return () => {
- popup.classList.add('hidden');
- resolve(choice);
- };
- }
- document.querySelectorAll('.votertypepopup button').forEach((button) => {
- button.onclick = choiceHandler(button.dataset.choice);
- });
- popup.classList.remove('hidden');
- });
- }
- function showSMSPasscodePopup()
- {
- return new Promise((resolve, reject) => {
- let popup = document.querySelector('.modal.smspasscode');
- popup.querySelector('.mobileinfo').textContent = 'στον αριθμό '+userdbdata.mobile;
- if (smsbuttontimeinterval) {
- clearInterval(smsbuttontimeinterval);
- }
- addSMSButtonInterval();
- let inputs = popup.querySelectorAll('input');
- Array.from(inputs)[0].focus();
- let passcode = '';
- function inputHandler(e) {
- passcode = '';
- inputs.forEach((input) => {
- passcode += input.value;
- });
- if (passcode.length == inputs.length) {
- popup.classList.add('hidden');
- inputs.forEach((input) => {
- input.removeEventListener('input', inputHandler);
- });
- clearInterval(smsbuttontimeinterval);
- resolve(passcode);
- }
- if (e.target.nextElementSibling) {
- e.target.nextElementSibling.focus();
- }
- }
- inputs.forEach((input) => {
- input.value = '';
- input.addEventListener('input', inputHandler);
- });
- popup.querySelector('.close').addEventListener('click', () => {
- popup.classList.add('hidden');
- resolve('cancel');
- });
- popup.classList.remove('hidden');
- });
- }
- async function sendrequestforsms(timestamp) {
- addSMSButtonInterval();
- let smsauthrequestref = db.collection('sms-auth-requests').doc(auth.currentUser.uid);
- // generate a random id
- const id = Math.random().toString(36).substr(2, 9);
- const authreqdata = {
- 'timestamp': timestamp,
- 'id': id,
- 'mobile': userdbdata.mobile,
- };
- let success = true;
- await smsauthrequestref.set(authreqdata).then(() => {
- }).catch((error) => {
- success = false;
- alert('Αποτυχία ψηφοφορίας');
- });
- return success;
- }
- function addSMSButtonInterval() {
- const starttime = performance.now();
- const popup = document.querySelector('.modal.smspasscode');
- popup.querySelector('button.resend').disabled = true;
- smsbuttontimeinterval = setInterval(() => {
- const now = performance.now();
- const elapsed = now - starttime;
- const countdownel = popup.querySelector('.countdown')
- countdownel.textContent = '(' + Math.ceil((120000 - elapsed) / 1000) + ')';
- if (elapsed > 120000) {
- clearInterval(smsbuttontimeinterval);
- countdownel.textContent = '';
- popup.querySelector('button.resend').disabled = false;
- }
- }, 250);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement