updateweb
This commit is contained in:
213
website/admin/js/portfolio.js
Normal file
213
website/admin/js/portfolio.js
Normal file
@@ -0,0 +1,213 @@
|
||||
// Portfolio Management JavaScript
|
||||
|
||||
let projectsData = [];
|
||||
let projectModal;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
projectModal = new bootstrap.Modal(document.getElementById("projectModal"));
|
||||
checkAuth().then((authenticated) => {
|
||||
if (authenticated) {
|
||||
loadProjects();
|
||||
}
|
||||
});
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.get("action") === "create") {
|
||||
showCreateProject();
|
||||
}
|
||||
});
|
||||
|
||||
async function loadProjects() {
|
||||
try {
|
||||
const response = await fetch("/api/admin/portfolio/projects", {
|
||||
credentials: "include",
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
projectsData = data.projects;
|
||||
renderProjects(projectsData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load projects:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function renderProjects(projects) {
|
||||
const tbody = document.getElementById("projectsTableBody");
|
||||
if (projects.length === 0) {
|
||||
tbody.innerHTML = `
|
||||
<tr><td colspan="7" class="text-center p-4">
|
||||
<i class="bi bi-inbox" style="font-size: 3rem; color: #ccc;"></i>
|
||||
<p class="mt-3 text-muted">No projects found</p>
|
||||
<button class="btn btn-primary" onclick="showCreateProject()">
|
||||
<i class="bi bi-plus-circle"></i> Add Your First Project
|
||||
</button>
|
||||
</td></tr>`;
|
||||
return;
|
||||
}
|
||||
|
||||
tbody.innerHTML = projects
|
||||
.map(
|
||||
(p) => `
|
||||
<tr>
|
||||
<td>${p.id}</td>
|
||||
<td><strong>${escapeHtml(p.title)}</strong></td>
|
||||
<td>${escapeHtml((p.description || "").substring(0, 50))}...</td>
|
||||
<td>${p.category || "-"}</td>
|
||||
<td><span class="badge ${p.isactive ? "badge-success" : "badge-danger"}">
|
||||
${p.isactive ? "Active" : "Inactive"}</span></td>
|
||||
<td>${formatDate(p.createdat)}</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-info" onclick="editProject(${p.id})">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-danger" onclick="deleteProject(${
|
||||
p.id
|
||||
}, '${escapeHtml(p.title)}')">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>`
|
||||
)
|
||||
.join("");
|
||||
}
|
||||
|
||||
function filterProjects() {
|
||||
const searchTerm = document.getElementById("searchInput").value.toLowerCase();
|
||||
const filtered = projectsData.filter((p) =>
|
||||
p.title.toLowerCase().includes(searchTerm)
|
||||
);
|
||||
renderProjects(filtered);
|
||||
}
|
||||
|
||||
function showCreateProject() {
|
||||
document.getElementById("modalTitle").textContent = "Add Portfolio Project";
|
||||
document.getElementById("projectForm").reset();
|
||||
document.getElementById("projectId").value = "";
|
||||
document.getElementById("projectActive").checked = true;
|
||||
projectModal.show();
|
||||
}
|
||||
|
||||
async function editProject(id) {
|
||||
try {
|
||||
const response = await fetch(`/api/admin/portfolio/projects/${id}`, {
|
||||
credentials: "include",
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
const project = data.project;
|
||||
document.getElementById("modalTitle").textContent =
|
||||
"Edit Portfolio Project";
|
||||
document.getElementById("projectId").value = project.id;
|
||||
document.getElementById("projectTitle").value = project.title;
|
||||
document.getElementById("projectDescription").value =
|
||||
project.description || "";
|
||||
document.getElementById("projectCategory").value = project.category || "";
|
||||
document.getElementById("projectActive").checked = project.isactive;
|
||||
projectModal.show();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load project:", error);
|
||||
showError("Failed to load project details");
|
||||
}
|
||||
}
|
||||
|
||||
async function saveProject() {
|
||||
const id = document.getElementById("projectId").value;
|
||||
const formData = {
|
||||
title: document.getElementById("projectTitle").value,
|
||||
description: document.getElementById("projectDescription").value,
|
||||
category: document.getElementById("projectCategory").value,
|
||||
isactive: document.getElementById("projectActive").checked,
|
||||
};
|
||||
|
||||
if (!formData.title || !formData.description) {
|
||||
showError("Please fill in all required fields");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const url = id
|
||||
? `/api/admin/portfolio/projects/${id}`
|
||||
: "/api/admin/portfolio/projects";
|
||||
const method = id ? "PUT" : "POST";
|
||||
const response = await fetch(url, {
|
||||
method: method,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
credentials: "include",
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
showSuccess(
|
||||
id ? "Project updated successfully" : "Project created successfully"
|
||||
);
|
||||
projectModal.hide();
|
||||
loadProjects();
|
||||
} else {
|
||||
showError(data.message || "Failed to save project");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to save project:", error);
|
||||
showError("Failed to save project");
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteProject(id, name) {
|
||||
if (!confirm(`Are you sure you want to delete "${name}"?`)) return;
|
||||
try {
|
||||
const response = await fetch(`/api/admin/portfolio/projects/${id}`, {
|
||||
method: "DELETE",
|
||||
credentials: "include",
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
showSuccess("Project deleted successfully");
|
||||
loadProjects();
|
||||
} else {
|
||||
showError(data.message || "Failed to delete project");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to delete project:", error);
|
||||
showError("Failed to delete project");
|
||||
}
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
try {
|
||||
const response = await fetch("/api/admin/logout", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
});
|
||||
if (response.ok) window.location.href = "/admin/login.html";
|
||||
} catch (error) {
|
||||
console.error("Logout failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
const map = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
'"': """,
|
||||
"'": "'",
|
||||
};
|
||||
return text.replace(/[&<>"']/g, (m) => map[m]);
|
||||
}
|
||||
|
||||
function formatDate(dateString) {
|
||||
return new Date(dateString).toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
});
|
||||
}
|
||||
|
||||
function showSuccess(message) {
|
||||
alert(message);
|
||||
}
|
||||
function showError(message) {
|
||||
alert("Error: " + message);
|
||||
}
|
||||
Reference in New Issue
Block a user