Fixed several display and authentication issues
This commit is contained in:
150
index.php
150
index.php
@@ -489,15 +489,26 @@
|
|||||||
fetch('get_data.php')
|
fetch('get_data.php')
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
|
||||||
|
if (!Array.isArray(data)) {
|
||||||
|
if (data && data.error === 'Not authenticated') {
|
||||||
|
new bootstrap.Modal(document.getElementById('loginModal')).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error('get_data.php returned non-array:', data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const container = document.getElementById('projectGrid');
|
const container = document.getElementById('projectGrid');
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
|
|
||||||
data.forEach((project, idx) => {
|
data.forEach((project, idx) => {
|
||||||
|
|
||||||
const projectId = `project-${project.id}`;
|
const projectId = `project-${project.id}`;
|
||||||
const colorClass = `project-color-${idx % 10}`;
|
const colorClass = `project-color-${idx % 10}`;
|
||||||
|
|
||||||
const col = document.createElement('div');
|
const col = document.createElement('div');
|
||||||
|
|
||||||
col.className = `col-12 col-sm-6 col-md-4 col-lg-2 col-xl-2 col-xxl-1 g-2 m-0 project-column`;
|
col.className = `col-12 col-sm-6 col-md-4 col-lg-2 col-xl-2 col-xxl-1 g-2 m-0 project-column`;
|
||||||
col.dataset.projectId = project.id;
|
col.dataset.projectId = project.id;
|
||||||
col.classList.add("draggable-project");
|
col.classList.add("draggable-project");
|
||||||
@@ -714,22 +725,6 @@ document.querySelectorAll('.project-column').forEach(col => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let itemToDelete = null;
|
|
||||||
|
|
||||||
document.querySelectorAll('.delete-task-btn').forEach(btn => {
|
|
||||||
btn.addEventListener('click', () => {
|
|
||||||
itemToDelete = btn.dataset.taskId;
|
|
||||||
const modal = new bootstrap.Modal(document.getElementById('confirmDeleteModal'));
|
|
||||||
modal.show();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('confirmDeleteBtn').addEventListener('click', () => {
|
|
||||||
if (itemToDelete) {
|
|
||||||
fetch(`delete_task.php?id=${itemToDelete}`)
|
|
||||||
.then(() => location.reload()); // or re-fetch your UI
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,23 +793,6 @@ document.querySelectorAll('.project-column').forEach(col => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('settingsForm').addEventListener('submit', function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const newTitle = document.getElementById('titleText').value.trim();
|
|
||||||
const newIcon = document.getElementById('iconClass').value.trim();
|
|
||||||
|
|
||||||
if (newTitle) {
|
|
||||||
document.getElementById('appTitle').childNodes[1].textContent = newTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newIcon) {
|
|
||||||
const icon = document.getElementById('appIcon');
|
|
||||||
icon.className = `bi ${newIcon} me-2`;
|
|
||||||
}
|
|
||||||
|
|
||||||
bootstrap.Modal.getInstance(document.getElementById('settingsModal')).hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('settingsForm').addEventListener('submit', function (e) {
|
document.getElementById('settingsForm').addEventListener('submit', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -836,6 +814,7 @@ document.querySelectorAll('.project-column').forEach(col => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
document.getElementById('resetSettings').addEventListener('click', () => {
|
document.getElementById('resetSettings').addEventListener('click', () => {
|
||||||
fetch('reset_settings.php')
|
fetch('reset_settings.php')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -843,11 +822,102 @@ document.querySelectorAll('.project-column').forEach(col => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
|
||||||
loadSettings();
|
document.getElementById('showRegisterBtn').addEventListener('click', () => {
|
||||||
});
|
bootstrap.Modal.getInstance(document.getElementById('loginModal')).hide();
|
||||||
|
new bootstrap.Modal(document.getElementById('registerModal')).show();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('backToLoginBtn').addEventListener('click', () => {
|
||||||
|
bootstrap.Modal.getInstance(document.getElementById('registerModal')).hide();
|
||||||
|
new bootstrap.Modal(document.getElementById('loginModal')).show();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('loginForm').addEventListener('submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const email = document.getElementById('loginEmail').value.trim();
|
||||||
|
const password = document.getElementById('loginPassword').value;
|
||||||
|
|
||||||
|
const err = document.getElementById('loginError');
|
||||||
|
err.style.display = 'none';
|
||||||
|
err.textContent = '';
|
||||||
|
|
||||||
|
fetch('login.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ email, password })
|
||||||
|
})
|
||||||
|
.then(async r => {
|
||||||
|
const data = await r.json();
|
||||||
|
if (!r.ok) throw new Error(data.error || 'Login failed');
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
bootstrap.Modal.getInstance(document.getElementById('loginModal')).hide();
|
||||||
|
|
||||||
|
if (!data.user.can_manage_settings) {
|
||||||
|
document.querySelectorAll('.settings-btn').forEach(b => b.style.display = 'none');
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchProjects();
|
||||||
|
})
|
||||||
|
.catch(ex => {
|
||||||
|
err.textContent = ex.message;
|
||||||
|
err.style.display = 'block';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
document.getElementById('registerForm').addEventListener('submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const email = document.getElementById('registerEmail').value.trim();
|
||||||
|
const password = document.getElementById('registerPassword').value;
|
||||||
|
|
||||||
|
const err = document.getElementById('registerError');
|
||||||
|
const ok = document.getElementById('registerSuccess');
|
||||||
|
err.style.display = 'none'; err.textContent = '';
|
||||||
|
ok.style.display = 'none'; ok.textContent = '';
|
||||||
|
|
||||||
|
fetch('register.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ email, password })
|
||||||
|
})
|
||||||
|
.then(async r => {
|
||||||
|
const data = await r.json();
|
||||||
|
if (!r.ok) throw new Error(data.error || 'Registration failed');
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
ok.textContent = 'Account created. You can sign in now.';
|
||||||
|
ok.style.display = 'block';
|
||||||
|
})
|
||||||
|
.catch(ex => {
|
||||||
|
err.textContent = ex.message;
|
||||||
|
err.style.display = 'block';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', fetchProjects);
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
loadSettings();
|
||||||
|
|
||||||
|
fetch('me.php')
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(me => {
|
||||||
|
if (!me.logged_in) {
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById('loginModal'));
|
||||||
|
modal.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide settings button if user can't manage settings
|
||||||
|
if (!me.user.can_manage_settings) {
|
||||||
|
document.querySelectorAll('.settings-btn').forEach(b => b.style.display = 'none');
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchProjects();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user