476 lines
11 KiB
PHP
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>
|