Szatuna/dashboard/devplan.php
2026-02-26 14:35:27 +01:00

476 lines
11 KiB
PHP

<?php
include '../managers/cookie.php';
if (isset($_GET['api']) && $_GET['api'] === '1') {
header('Content-Type: application/json');
$jsonFile = __DIR__ . '/../managers/devplan.json';
function ensureDirectory($file) {
$dir = dirname($file);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
}
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['action'] === 'load') {
ensureDirectory($jsonFile);
if (file_exists($jsonFile)) {
$content = file_get_contents($jsonFile);
echo $content;
} else {
echo json_encode(['plans' => []]);
}
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'save') {
ensureDirectory($jsonFile);
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (json_last_error() === JSON_ERROR_NONE) {
file_put_contents($jsonFile, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
echo json_encode(['success' => true]);
} else {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Hibás JSON formátum']);
}
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'complete') {
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE || !isset($data['index'])) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Hibás JSON formátum']);
exit;
}
$index = (int)$data['index'];
// Devplan betöltése
ensureDirectory($jsonFile);
$devplanData = ['plans' => []];
if (file_exists($jsonFile)) {
$content = file_get_contents($jsonFile);
$devplanData = json_decode($content, true);
if (!is_array($devplanData) || !isset($devplanData['plans'])) {
$devplanData = ['plans' => []];
}
}
if (!isset($devplanData['plans'][$index])) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Érvénytelen index']);
exit;
}
$planName = $devplanData['plans'][$index];
// Version.json betöltése
$versionFile = __DIR__ . '/../managers/version.json';
$versionData = ['updates' => []];
if (file_exists($versionFile)) {
$versionContent = file_get_contents($versionFile);
$versionData = json_decode($versionContent, true);
if (!is_array($versionData) || !isset($versionData['updates'])) {
$versionData = ['updates' => []];
}
}
// Legutóbbi build szám használata
if (empty($versionData['updates'])) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Nincs meglévő build szám']);
exit;
}
$build = $versionData['updates'][0]['build'];
// Changelog bejegyzés hozzáadása a legutóbbi buildhez
if (!in_array($planName, $versionData['updates'][0]['changes'], true)) {
array_unshift($versionData['updates'][0]['changes'], $planName);
}
// Version.json mentése
file_put_contents($versionFile, json_encode($versionData, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
// Terv törlése a devplan.json-ból
array_splice($devplanData['plans'], $index, 1);
file_put_contents($jsonFile, json_encode($devplanData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
echo json_encode(['success' => true, 'build' => $build]);
exit;
}
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Hibás kérés']);
exit;
} else {
$CanEdit = false;
$localIP = trim(shell_exec('hostname -I | cut -d" " -f1'));
if (UserHasPerm("god_profile") && $userID == 1 && $localIP == '192.168.15.10') {
$CanEdit = true;
}
}
?>
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../css/login.css">
<title>Fejlesztési Tervek</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: linear-gradient(135deg, var(--bgcolorlight) 0%, var(--bgcolordark) 100%);
padding: 20px;
}
.Background {
z-index: 0;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: linear-gradient(135deg, var(--bgcolorlight) 0%, var(--bgcolordark) 100%);
}
.devplanContainer {
z-index: 1;
position: relative;
max-width: 700px;
margin: 0 auto;
background: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
padding: 30px;
}
h1 {
color: #2980b9;
margin-bottom: 30px;
text-align: center;
}
.plan-list {
list-style: none;
margin-bottom: 30px;
}
.plan-item {
background: #f8f9fa;
border-left: 4px solid #2980b9;
padding: 15px;
margin-bottom: 10px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
transition: all 0.2s;
}
.plan-item:hover {
box-shadow: 0 2px 8px rgba(41, 128, 185, 0.2);
}
.plan-item.dragging {
opacity: 0.5;
}
.plan-content {
flex: 1;
color: #333;
}
.plan-controls {
display: flex;
gap: 8px;
}
.devplanBtn {
background: #2980b9;
color: white;
border: none;
padding: 8px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background 0.2s;
}
.devplanBtn:hover {
background: #1f6391;
}
.devplanBtn-complete {
background: #27ae60;
}
.devplanBtn-complete:hover {
background: #1e8449;
}
.devplanBtn-delete {
background: #e74c3c;
}
.devplanBtn-delete:hover {
background: #c0392b;
}
.devplanBtn:disabled {
background: #95a5a6;
cursor: not-allowed;
}
.add-section {
border-top: 2px solid #ecf0f1;
padding-top: 20px;
}
.input-group {
display: flex;
gap: 10px;
}
.input-group input {
flex: 1;
padding: 12px;
border: 2px solid #2980b9;
border-radius: 4px;
font-size: 14px;
margin: unset;
background: unset;
color: #333;
}
.input-group input:focus {
outline: none;
border-color: #1f6391;
}
.empty-state {
text-align: center;
color: #95a5a6;
padding: 40px;
font-style: italic;
}
.drag-handle {
cursor: grab;
color: #2980b9;
margin-right: 10px;
font-size: 18px;
}
.drag-handle:active {
cursor: grabbing;
}
</style>
</head>
<body>
<div class="Background"></div>
<div class="devplanContainer">
<h1>Fejlesztési Tervek</h1>
<ul class="plan-list" id="planList"></ul>
<div class="add-section" id="addSection">
<div class="input-group">
<input type="text" id="newPlanInput" placeholder="Új fejlesztési terv hozzáadása...">
<button class="devplanBtn" onclick="addPlan()">Hozzáadás</button>
</div>
</div>
</div>
<script>
const canEdit = <?= $CanEdit ? 'true' : 'false' ?>;
let plans = [];
let draggedElement = null;
async function loadPlans() {
try {
const response = await fetch('devplan.php?action=load&api=1');
const data = await response.json();
plans = data.plans || [];
renderPlans();
} catch (error) {
console.error('Hiba a tervek betöltésekor:', error);
}
}
async function savePlans() {
try {
await fetch('devplan.php?action=save&api=1', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ plans: plans })
});
} catch (error) {
console.error('Hiba a mentés során:', error);
}
}
function renderPlans() {
const listElement = document.getElementById('planList');
listElement.innerHTML = '';
if (!canEdit) {
document.getElementById("addSection").style.display = 'none';
}
if (plans.length === 0) {
listElement.innerHTML = '<div class="empty-state">Még nincsenek fejlesztési tervek</div>';
return;
}
plans.forEach((plan, index) => {
const li = document.createElement('li');
li.className = 'plan-item';
li.draggable = canEdit;
li.dataset.index = index;
li.innerHTML = `
${canEdit ? '<span class="drag-handle">☰</span>' : ''}
<div class="plan-content">${escapeHtml(plan)}</div>
<div class="plan-controls">
${canEdit ? `<button class="devplanBtn devplanBtn-complete" onclick="completePlan(${index})" title="Kész, áthelyezés a changelogba">✓</button>` : ''}
${canEdit ? `<button class="devplanBtn devplanBtn-delete" onclick="deletePlan(${index})">Törlés</button>` : ''}
</div>
`;
if (canEdit) {
li.addEventListener('dragstart', handleDragStart);
li.addEventListener('dragend', handleDragEnd);
li.addEventListener('dragover', handleDragOver);
li.addEventListener('drop', handleDrop);
}
listElement.appendChild(li);
});
}
function handleDragStart(e) {
draggedElement = this;
this.classList.add('dragging');
e.dataTransfer.effectAllowed = 'move';
}
function handleDragEnd(e) {
this.classList.remove('dragging');
draggedElement = null;
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
e.dataTransfer.dropEffect = 'move';
return false;
}
function handleDrop(e) {
if (e.stopPropagation) {
e.stopPropagation();
}
if (draggedElement !== this) {
const draggedIndex = parseInt(draggedElement.dataset.index);
const targetIndex = parseInt(this.dataset.index);
const draggedPlan = plans[draggedIndex];
plans.splice(draggedIndex, 1);
plans.splice(targetIndex, 0, draggedPlan);
savePlans();
renderPlans();
}
return false;
}
async function addPlan() {
if (!canEdit) return;
const input = document.getElementById('newPlanInput');
const value = input.value.trim();
if (value === '') {
alert('Kérlek, adj meg egy fejlesztési tervet!');
return;
}
plans.push(value);
input.value = '';
await savePlans();
renderPlans();
}
async function deletePlan(index) {
if (!canEdit) return;
if (confirm('Biztosan törölni szeretnéd ezt a tervet?')) {
plans.splice(index, 1);
await savePlans();
renderPlans();
}
}
async function completePlan(index) {
if (!canEdit) return;
if (confirm('A terv kész? Áthelyezed a changelogba?')) {
try {
const response = await fetch('devplan.php?action=complete&api=1', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ index: index })
});
const result = await response.json();
if (result.success) {
await loadPlans();
alert('A terv sikeresen áthelyezve a changelogba!\nBuild szám: ' + result.build);
} else {
alert('Hiba történt: ' + (result.error || 'Ismeretlen hiba'));
}
} catch (error) {
console.error('Hiba a terv befejezésekor:', error);
alert('Hiba történt a művelet során.');
}
}
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
document.getElementById('newPlanInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
addPlan();
}
});
loadPlans();
</script>
</body>
</html>