gitea init

This commit is contained in:
skryper
2025-10-08 21:28:30 +04:00
commit d4651a423d
2518 changed files with 522832 additions and 0 deletions
@@ -0,0 +1,45 @@
<?php
require_once __DIR__ . '/includes/init.php';
?>
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use App\Config;
require_once Config::includePath('head.php');
require_once Config::includePath('navbar.php');
require_once Config::includePath('pageheader.php');
require_once Config::includePath('pagebodystart.php');
?>
<?php
require 'db.php';
$action = $_GET['action'] ?? 'list';
$id = $_GET['id'] ?? null;
switch ($action) {
case 'create':
include __DIR__ . '/product/create.php';
break;
case 'edit':
if ($id) {
include __DIR__ . '/product/edit.php';
} else {
echo "<div class='container-xl mt-4'><div class='alert alert-danger'>ID ვერ მოიძებნა.</div></div>";
}
break;
case 'list':
default:
include __DIR__ . '/product/list.php';
break;
}
?>
<?php require_once Config::includePath('footer.php'); ?>
+122
View File
@@ -0,0 +1,122 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/../../../includes/init.php';
require_once __DIR__ . '/../models/productmodels.php';
use App\Config;
// Product types-ების მიღება
ProductModel::setDb($pdo);
$productTypes = ProductModel::getProductTypes();
?>
<?php require_once Config::includePath('head.php'); ?>
<?php require_once Config::includePath('navbar.php'); ?>
<?php require_once Config::includePath('pageheader.php'); ?>
<?php require_once Config::includePath('pagebodystart.php'); ?>
<div class="container-xl mt-4">
<h2 class="mb-4">ახალი პროდუქტის დამატება</h2>
<form method="POST" action="dashboard.php?module=product&action=save">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Product Type</label>
<div class="row">
<div class="col">
<select name="type" class="form-select" id="product-type-select" required>
<option value="">აირჩიეთ ტიპი...</option>
<?php foreach ($productTypes as $type): ?>
<option value="<?= htmlspecialchars($type['name']) ?>" data-icon="<?= htmlspecialchars($type['icon']) ?>">
<?= htmlspecialchars($type['name']) ?>
<?php if ($type['description']): ?>
- <?= htmlspecialchars($type['description']) ?>
<?php endif; ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-auto">
<a href="dashboard.php?module=product&action=types" class="btn btn-outline-secondary" title="ტიპების მართვა">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 0 0-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 0 0-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 0 0-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 0 0-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 0 0 1.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"/>
</svg>
მართვა
</a>
</div>
</div>
<div class="mt-2" id="type-preview" style="display: none;">
<div class="d-flex align-items-center text-muted">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon me-2" id="type-icon">
</svg>
<span id="type-description"></span>
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Product Group</label>
<input type="text" name="group" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">დასახელება</label>
<input type="text" name="name" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">URL</label>
<input type="text" name="url" class="form-control">
</div>
<div class="mb-3">
<label class="form-label">მოდული</label>
<input type="text" name="module" class="form-control">
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" name="hidden" value="1" id="hiddenSwitch">
<label class="form-check-label" for="hiddenSwitch">შექმნა დამალულად</label>
</div>
</div>
</div>
<div class="form-footer mt-3">
<button type="submit" class="btn btn-primary">შენახვა</button>
<a href="dashboard.php?module=product&action=list" class="btn btn-secondary">გაუქმება</a>
</div>
</form>
</div>
<script>
// Product type selection preview
document.addEventListener('DOMContentLoaded', function() {
const typeSelect = document.getElementById('product-type-select');
const typePreview = document.getElementById('type-preview');
const typeIcon = document.getElementById('type-icon');
const typeDescription = document.getElementById('type-description');
typeSelect.addEventListener('change', function() {
const selectedOption = this.options[this.selectedIndex];
if (this.value) {
const iconName = selectedOption.getAttribute('data-icon') || 'box';
const description = selectedOption.text.split(' - ')[1] || '';
// Update icon
typeIcon.className = `icon me-2 icon-tabler icons-tabler-outline icon-tabler-${iconName}`;
// Update description
if (description) {
typeDescription.textContent = description;
typePreview.style.display = 'block';
} else {
typePreview.style.display = 'none';
}
} else {
typePreview.style.display = 'none';
}
});
});
</script>
<?php require_once Config::includePath('footer.php'); ?>
+33
View File
@@ -0,0 +1,33 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/../../../includes/init.php';
require_once __DIR__ . '/../models/productmodels.php';
use App\Config;
?>
<?php require_once Config::includePath('head.php'); ?>
<?php require_once Config::includePath('navbar.php'); ?>
<?php require_once Config::includePath('pageheader.php'); ?>
<?php require_once Config::includePath('pagebodystart.php'); ?>
<div class="tab-content mt-4">
<?php
$allowedTabs = ['details', 'pricing'];
if (!in_array($tab, $allowedTabs)) {
$tab = 'details';
}
$tabPath = __DIR__ . '/../tabs/' . $tab . '.php';
if (file_exists($tabPath)) {
include $tabPath;
} else {
echo "<div class='alert alert-danger'>ტაბის ფაილი ვერ მოიძებნა.</div>";
}
?>
</div>
+75
View File
@@ -0,0 +1,75 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/../../../includes/init.php';
require_once __DIR__ . '/../models/productmodels.php';
use App\Config;
?>
<?php require_once Config::includePath('head.php'); ?>
<?php require_once Config::includePath('navbar.php'); ?>
<?php require_once Config::includePath('pageheader.php'); ?>
<?php require_once Config::includePath('pagebodystart.php'); ?>
<?php if (isset($_GET['added']) && $_GET['added'] == 1): ?>
<div class="alert alert-success">პროდუქტი წარმატებით დაემატა.</div>
<?php endif; ?>
<div class="container-xl mt-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<h2>პროდუქტები და სერვისები</h2>
<div class="btn-list">
<a href="dashboard.php?module=product&action=types" class="btn btn-outline-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<rect x="3" y="3" width="7" height="7"/>
<rect x="14" y="3" width="7" height="7"/>
<rect x="14" y="14" width="7" height="7"/>
<rect x="3" y="14" width="7" height="7"/>
</svg>
ტიპების მართვა
</a>
<a href="dashboard.php?module=product&action=create" class="btn btn-primary">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path d="M12 5l0 14"/>
<path d="M5 12l14 0"/>
</svg>
ახალი პროდუქტი
</a>
</div>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Product Name</th>
<th>Group</th>
<th>Type</th>
<th>Pay Type</th>
<th>Auto Setup</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($products as $product): ?>
<tr>
<td><?= htmlspecialchars($product['id'] ?? '') ?></td>
<td><?= htmlspecialchars($product['name'] ?? '') ?></td>
<td><?= htmlspecialchars($product['group'] ?? '') ?></td>
<td><?= htmlspecialchars($product['type'] ?? '') ?></td>
<td><?= htmlspecialchars($product['pay_type'] ?? '') ?></td>
<td><?= htmlspecialchars($product['auto_setup'] ?? '') ?></td>
<td>
<a href="dashboard.php?module=product&action=edit&id=<?= $product['id'] ?>" class="btn btn-sm btn-warning">რედ.</a>
<a href="dashboard.php?module=product&action=delete&id=<?= $product['id'] ?>" class="btn btn-sm btn-danger" onclick="return confirm('წაშლა?');">წაშლა</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php require_once Config::includePath('footer.php'); ?>
@@ -0,0 +1,313 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/../../../includes/init.php';
require_once __DIR__ . '/../../../../vendor/autoload.php';
use App\Config;
?>
<?php require_once Config::includePath('head.php'); ?>
<?php require_once Config::includePath('navbar.php'); ?>
<?php require_once Config::includePath('pageheader.php'); ?>
<?php require_once Config::includePath('pagebodystart.php'); ?>
<div class="container-xl mt-4">
<!-- Page header -->
<div class="page-header d-print-none">
<div class="row align-items-center">
<div class="col">
<h2 class="page-title">პროდუქტის ტიპების მართვა</h2>
<div class="text-muted mt-1">პროდუქტების კატეგორიების კონფიგურაცია</div>
</div>
<div class="col-auto">
<div class="btn-list">
<?php if ($action === 'list'): ?>
<a href="dashboard.php?module=product&action=types&subaction=add" class="btn btn-primary">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path d="M12 5l0 14"/>
<path d="M5 12l14 0"/>
</svg>
ახალი ტიპი
</a>
<?php endif; ?>
<a href="dashboard.php?module=product&action=list" class="btn btn-outline-primary">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path d="M5 12l14 0"/>
<path d="M5 12l6 6"/>
<path d="M5 12l6 -6"/>
</svg>
უკან დაბრუნება
</a>
</div>
</div>
</div>
</div>
<!-- Messages -->
<?php if ($message): ?>
<div class="alert alert-<?= $messageType ?> alert-dismissible">
<div class="d-flex">
<div><?= htmlspecialchars($message) ?></div>
</div>
<a class="btn-close" data-bs-dismiss="alert" aria-label="close"></a>
</div>
<?php endif; ?>
<?php if ($action === 'list'): ?>
<!-- Product Types List -->
<div class="card">
<div class="card-header">
<h3 class="card-title">პროდუქტის ტიპები</h3>
<div class="card-actions">
<small class="text-muted">გადაათრიე რიგითობის ცვლილებისთვის</small>
</div>
</div>
<div class="card-body">
<?php if (empty($productTypes)): ?>
<div class="text-center text-muted py-4">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon mb-3">
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
<polyline points="3.27,6.96 12,12.01 20.73,6.96"/>
<line x1="12" y1="22.08" x2="12" y2="12"/>
</svg>
<h3>პროდუქტის ტიპები არ არის</h3>
<p class="text-muted">დაამატეთ ახალი პროდუქტის ტიპი</p>
</div>
<?php else: ?>
<div id="sortable-types" class="list-group list-group-flush">
<?php foreach ($productTypes as $type): ?>
<div class="list-group-item" data-id="<?= $type['id'] ?>">
<div class="row align-items-center">
<div class="col-auto">
<span class="handle cursor-move">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon text-muted">
<line x1="8" y1="6" x2="21" y2="6"/>
<line x1="8" y1="12" x2="21" y2="12"/>
<line x1="8" y1="18" x2="21" y2="18"/>
<line x1="3" y1="6" x2="3.01" y2="6"/>
<line x1="3" y1="12" x2="3.01" y2="12"/>
<line x1="3" y1="18" x2="3.01" y2="18"/>
</svg>
</span>
</div>
<div class="col-auto">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-<?= htmlspecialchars($type['icon']) ?>">
<!-- Icon will be rendered by Tabler -->
</svg>
</div>
<div class="col">
<div class="d-flex align-items-center">
<strong><?= htmlspecialchars($type['name']) ?></strong>
<?php if (!$type['is_active']): ?>
<span class="badge bg-secondary ms-2">უაქტივო</span>
<?php endif; ?>
</div>
<?php if ($type['description']): ?>
<div class="text-muted small"><?= htmlspecialchars($type['description']) ?></div>
<?php endif; ?>
<small class="text-muted">რიგითობა: <?= $type['sort_order'] ?></small>
</div>
<div class="col-auto">
<div class="btn-list">
<a href="dashboard.php?module=product&action=types&subaction=edit&id=<?= $type['id'] ?>" class="btn btn-sm btn-outline-primary">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"/>
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"/>
<path d="M16 5l3 3"/>
</svg>
რედაქტირება
</a>
<form method="post" style="display: inline;">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= $type['id'] ?>">
<button type="submit" class="btn btn-sm btn-outline-danger" onclick="return confirm('დარწმუნებული ხართ რომ გსურთ ამ ტიპის წაშლა?')">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path d="M4 7l16 0"/>
<path d="M10 11l0 6"/>
<path d="M14 11l0 6"/>
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"/>
<path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"/>
</svg>
წაშლა
</button>
</form>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<form id="sort-form" method="post" style="display: none;">
<input type="hidden" name="action" value="update_order">
<div id="sort-orders"></div>
</form>
<?php endif; ?>
</div>
</div>
<?php elseif ($action === 'add' || $action === 'edit'): ?>
<!-- Add/Edit Form -->
<div class="card">
<div class="card-header">
<h3 class="card-title">
<?= $action === 'add' ? 'ახალი პროდუქტის ტიპი' : 'პროდუქტის ტიპის რედაქტირება' ?>
</h3>
</div>
<div class="card-body">
<form method="post">
<input type="hidden" name="action" value="<?= $action ?>">
<?php if ($action === 'edit'): ?>
<input type="hidden" name="id" value="<?= $editType['id'] ?>">
<?php endif; ?>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">ტიპის სახელი</label>
<input type="text" name="name" class="form-control"
value="<?= htmlspecialchars($editType['name'] ?? '') ?>"
placeholder="მაგ: Shared Hosting" required>
</div>
<div class="mb-3">
<label class="form-label">აღწერა</label>
<textarea name="description" class="form-control" rows="3"
placeholder="ტიპის დეტალური აღწერა"><?= htmlspecialchars($editType['description'] ?? '') ?></textarea>
</div>
<div class="mb-3">
<label class="form-label">რიგითობა</label>
<input type="number" name="sort_order" class="form-control"
value="<?= $editType['sort_order'] ?? '0' ?>"
placeholder="0">
<small class="form-hint">უფრო პატარა რიცხვი = უფრო ზევით</small>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" name="is_active"
<?= ($editType['is_active'] ?? 1) ? 'checked' : '' ?>>
<label class="form-check-label">აქტიური</label>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">აიკონი</label>
<select name="icon" class="form-select" id="icon-select">
<?php foreach ($availableIcons as $iconName => $iconLabel): ?>
<option value="<?= $iconName ?>"
<?= ($editType['icon'] ?? 'box') === $iconName ? 'selected' : '' ?>>
<?= $iconLabel ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label">აიკონის გადახედვა</label>
<div class="icon-preview p-4 border rounded text-center">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline" id="preview-icon">
<!-- Icon preview -->
</svg>
<div class="mt-2 text-muted" id="preview-text">აიკონის გადახედვა</div>
</div>
</div>
</div>
</div>
<div class="card-actions">
<button type="submit" class="btn btn-primary">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
<polyline points="17,21 17,13 7,13 7,21"/>
<polyline points="7,3 7,8 15,8"/>
</svg>
შენახვა
</button>
<a href="dashboard.php?module=product&action=types" class="btn btn-secondary">გაუქმება</a>
</div>
</form>
</div>
</div>
<?php endif; ?>
</div>
<script src="../dist/js/tabler.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Sortable functionality
const sortableEl = document.getElementById('sortable-types');
if (sortableEl) {
const sortable = Sortable.create(sortableEl, {
handle: '.handle',
animation: 150,
onEnd: function() {
const items = sortableEl.querySelectorAll('.list-group-item');
const orders = {};
items.forEach((item, index) => {
const id = item.getAttribute('data-id');
orders[id] = index + 1;
});
// Update hidden form
const sortOrdersDiv = document.getElementById('sort-orders');
sortOrdersDiv.innerHTML = '';
Object.keys(orders).forEach(id => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = `orders[${id}]`;
input.value = orders[id];
sortOrdersDiv.appendChild(input);
});
// Submit form
document.getElementById('sort-form').submit();
}
});
}
// Icon preview
const iconSelect = document.getElementById('icon-select');
const previewIcon = document.getElementById('preview-icon');
const previewText = document.getElementById('preview-text');
if (iconSelect && previewIcon) {
function updateIconPreview() {
const selectedIcon = iconSelect.value;
const selectedText = iconSelect.options[iconSelect.selectedIndex].text;
// Update icon class
previewIcon.className = `icon icon-tabler icons-tabler-outline icon-tabler-${selectedIcon}`;
previewText.textContent = selectedText;
}
// Initialize preview
updateIconPreview();
// Update on change
iconSelect.addEventListener('change', updateIconPreview);
}
// Form validation
const form = document.querySelector('form[method="post"]');
if (form && form.querySelector('input[name="name"]')) {
form.addEventListener('submit', function(e) {
const nameInput = form.querySelector('input[name="name"]');
if (!nameInput.value.trim()) {
alert('ტიპის სახელი სავალდებულოა');
e.preventDefault();
nameInput.focus();
return false;
}
});
}
});
</script>
<?php require_once Config::includePath('footer.php'); ?>