Skip to content

Commit

Permalink
new layout of admin dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
amgno committed Sep 25, 2024
1 parent a64a45c commit 9197da8
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 90 deletions.
46 changes: 45 additions & 1 deletion admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,50 @@
#image-upload-area.highlight {
background-color: #f0f0f0;
}

.accordion {
width: 100%;
max-width: 800px;
margin: 0 auto;
}

.project-box {
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}

.project-header {
background-color: #f1f1f1;
padding: 10px 15px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
}

.project-header h3 {
margin: 0;
}

.project-content {
padding: 15px;
display: none;
}

.project-content.active {
display: block;
}

.project-actions {
margin-top: 15px;
display: flex;
justify-content: space-between;
}

.project-actions button {
padding: 5px 10px;
}
</style>
</head>

Expand Down Expand Up @@ -320,7 +364,7 @@ <h2>Admin Login</h2>

<div id="admin-panel" style="display: none;">
<h2>Projects Management</h2>
<div id="projects-list"></div>
<div id="projects-list" class="accordion"></div>
<div class="project-actions">
<button onclick="addProject()">Add New Project</button><br>
<button onclick="saveProjects()">Save Changes</button>
Expand Down
165 changes: 88 additions & 77 deletions admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function login() {
if (data.success) {
document.getElementById('login-form').style.display = 'none';
document.getElementById('admin-panel').style.display = 'block';
loadProjects();
displayProjects();
} else {
showNotification('Incorrect password', true);
}
Expand All @@ -39,66 +39,85 @@ function login() {
});
}

function loadProjects() {
let currentOpenProject = null;

function displayProjects() {
const projectsList = document.getElementById('projects-list');
projectsList.innerHTML = '';

projects.forEach((project, index) => {
const projectDiv = document.createElement('div');
projectDiv.className = 'project-box';
projectDiv.innerHTML = `
<div class="project-header" onclick="toggleProject(${index})">
<h3>Project ${project.number}: ${project.name}</h3>
const projectBox = document.createElement('div');
projectBox.className = 'project-box';

const projectHeader = document.createElement('div');
projectHeader.className = 'project-header';
projectHeader.innerHTML = `<h3>${project.number} - ${project.name}</h3><span>▼</span>`;
projectHeader.addEventListener('click', () => toggleProject(index));

const projectContent = document.createElement('div');
projectContent.className = 'project-content';
projectContent.innerHTML = `
<div class="project-content-wrapper">
<label>
Number:
<input type="text" id="project-${index}-number" value="${project.number}">
</label>
<label>
Name:
<input type="text" id="project-${index}-name" value="${project.name}">
</label>
<label>
Type:
<input type="text" id="project-${index}-ptype" value="${project.ptype}">
</label>
<label>
Tools:
<input type="text" id="project-${index}-tools" value="${project.tools}">
</label>
<label>
Date:
<input type="text" id="project-${index}-date" value="${project.date}">
</label>
<label>
Background Color:
<input type="color" id="project-${index}-bgcolor" value="${project.bgcolor}">
</label>
<label>
Description:
<textarea id="project-${index}-description">${project.description}</textarea>
</label>
</div>
<div class="project-content" id="project-content-${index}">
<div class="project-content-wrapper">
${Object.entries(project).map(([key, value]) => {
if (key === 'description') {
return `
<label for="${index}-${key}">
${key}:
<textarea id="${index}-${key}">${value}</textarea>
</label>
`;
} else if (key === 'images') {
return `
<label>
${key}:
<input type="text" id="${index}-${key}" value="${value.join(', ')}">
<input type="file" id="${index}-${key}-upload" multiple accept="image/*">
<button onclick="uploadFiles(${index}, 'images')">Upload Images</button>
</label>
`;
} else if (key === 'pdf') {
return `
<label>
${key}:
<input type="text" id="${index}-${key}" value="${value}">
<input type="file" id="${index}-${key}-upload" accept="application/pdf">
<button onclick="uploadFiles(${index}, 'pdf')">Upload PDF</button>
</label>
`;
} else {
return `
<label for="${index}-${key}">
${key}:
<input type="text" id="${index}-${key}" value="${value}">
</label>
`;
}
}).join('')}
<div class="project-actions">
<button onclick="deleteProject(${index})">Delete Project</button>
<button onclick="showImageManagement(${index})">Manage Images</button>
</div>
</div>
<div class="project-actions">
<button onclick="showImageManagement(${index})">Manage Images</button>
<button onclick="deleteProject(${index})">Delete Project</button>
</div>
`;
projectsList.appendChild(projectDiv);

projectBox.appendChild(projectHeader);
projectBox.appendChild(projectContent);
projectsList.appendChild(projectBox);
});
}

function toggleProject(index) {
const projectContent = document.querySelectorAll('.project-content')[index];
const projectHeader = document.querySelectorAll('.project-header')[index];

if (currentOpenProject !== null && currentOpenProject !== index) {
const currentOpenContent = document.querySelectorAll('.project-content')[currentOpenProject];
const currentOpenHeader = document.querySelectorAll('.project-header')[currentOpenProject];
currentOpenContent.classList.remove('active');
currentOpenHeader.querySelector('span').textContent = '▼';
}

projectContent.classList.toggle('active');
projectHeader.querySelector('span').textContent = projectContent.classList.contains('active') ? '▲' : '▼';

currentOpenProject = projectContent.classList.contains('active') ? index : null;
}

function addProject() {
projects.push({
const newProject = {
number: String(projects.length + 1).padStart(2, '0'),
name: 'New Project',
description: '',
Expand All @@ -107,44 +126,39 @@ function addProject() {
date: '',
images: [],
pdf: '',
video: '',
bgcolor: ''
});
loadProjects();
saveProjects(); // Automatically save the new project
bgcolor: '#ffffff'
};

projects.push(newProject);
displayProjects();
toggleProject(projects.length - 1);
}

function deleteProject(index) {
if (confirm('Are you sure you want to delete this project?')) {
projects.splice(index, 1);
loadProjects();
displayProjects();
saveProjects();
}
}

function saveProjects() {
projects.forEach((project, index) => {
Object.keys(project).forEach(key => {
const input = document.getElementById(`${index}-${key}`);
if (input) {
if (key === 'images') {
const images = input.value.split(',').map(img => img.trim()).filter(img => img !== '');
project[key] = images.length > 0 ? images : [];
} else {
project[key] = input.value;
}
}
});
project.number = document.getElementById(`project-${index}-number`).value;
project.name = document.getElementById(`project-${index}-name`).value;
project.ptype = document.getElementById(`project-${index}-ptype`).value;
project.tools = document.getElementById(`project-${index}-tools`).value;
project.date = document.getElementById(`project-${index}-date`).value;
project.bgcolor = document.getElementById(`project-${index}-bgcolor`).value;
project.description = document.getElementById(`project-${index}-description`).value;
});

const projectsString = `const projects = ${JSON.stringify(projects, null, 2)};`;
const password = document.getElementById('password').value;

fetch('/save-projects', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ password, projects: projectsString }),
body: JSON.stringify(projects),
})
.then(response => response.json())
.then(data => {
Expand Down Expand Up @@ -211,11 +225,6 @@ function uploadFiles(files) {
xhr.send(formData);
}

function toggleProject(index) {
const content = document.getElementById(`project-content-${index}`);
content.classList.toggle('active');
}

let currentProjectIndex = -1;

function showImageManagement(index) {
Expand Down Expand Up @@ -320,4 +329,6 @@ document.addEventListener('DOMContentLoaded', function() {
const files = dt.files;
uploadFiles(files);
}

displayProjects();
});
12 changes: 12 additions & 0 deletions projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,17 @@ const projects = [
"/works/06 - Rolli di Genova/images/IMG_5269.png"
],
"bgcolor": "#590202"
},
{
"number": "07",
"name": "New Project",
"description": "",
"ptype": "",
"tools": "",
"date": "",
"images": [],
"pdf": "",
"video": "",
"bgcolor": "#000000"
}
];
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
• Add a progress bar for uploading images
• Fix the size of buttons on works for mobile view
• fix layout of the admin dashboard

• After deleting a project, and trying to open a existing one it gives an error



Expand Down
19 changes: 8 additions & 11 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,15 @@ app.post('/upload', upload.array('files'), (req, res) => {
});

app.post('/save-projects', (req, res) => {
const { password, projects } = req.body;
if (password !== ADMIN_PASSWORD) {
return res.status(401).json({ success: false, message: 'Unauthorized' });
}

fs.writeFile(path.join(__dirname, 'projects.js'), projects, (err) => {
if (err) {
console.error(err);
res.json({ success: false });
} else {
res.json({ success: true });
const updatedProjects = req.body;
const updatedData = `const projects = ${JSON.stringify(updatedProjects, null, 2)};`;

fs.writeFile(path.join(__dirname, 'projects.js'), updatedData, (writeErr) => {
if (writeErr) {
console.error(writeErr);
return res.status(500).json({ success: false, message: 'Error updating projects file' });
}
res.json({ success: true });
});
});

Expand Down

0 comments on commit 9197da8

Please sign in to comment.