gitea init
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
// Users index controller - redirects to management
|
||||
header("Location: dashboard.php?module=users&action=management");
|
||||
exit;
|
||||
?>
|
||||
@@ -0,0 +1,200 @@
|
||||
<?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/usermodel.php';
|
||||
|
||||
UserModel::setDb($pdo);
|
||||
|
||||
$message = '';
|
||||
$messageType = '';
|
||||
$action = $_GET['subaction'] ?? 'list';
|
||||
|
||||
// POST მოთხოვნების მართვა
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$postAction = $_POST['action'] ?? '';
|
||||
|
||||
switch ($postAction) {
|
||||
case 'add':
|
||||
$data = [
|
||||
'first_name' => trim($_POST['first_name'] ?? ''),
|
||||
'last_name' => trim($_POST['last_name'] ?? ''),
|
||||
'email' => trim($_POST['email'] ?? ''),
|
||||
'password' => $_POST['password'] ?? '',
|
||||
'role' => $_POST['role'] ?? 'user',
|
||||
'is_active' => isset($_POST['is_active']) ? 1 : 0
|
||||
];
|
||||
|
||||
// ვალიდაცია
|
||||
$errors = [];
|
||||
if (empty($data['first_name'])) $errors[] = 'სახელი სავალდებულოა';
|
||||
if (empty($data['last_name'])) $errors[] = 'გვარი სავალდებულოა';
|
||||
if (empty($data['email']) || !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
|
||||
$errors[] = 'ვალიდური ელ.ფოსტა სავალდებულოა';
|
||||
}
|
||||
if (empty($data['password']) || strlen($data['password']) < 6) {
|
||||
$errors[] = 'პაროლი უნდა იყოს მინიმუმ 6 სიმბოლო';
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
$message = implode('<br>', $errors);
|
||||
$messageType = 'danger';
|
||||
} else {
|
||||
try {
|
||||
UserModel::createUser($data);
|
||||
$message = 'მომხმარებელი წარმატებით დაემატა';
|
||||
$messageType = 'success';
|
||||
$action = 'list';
|
||||
} catch (Exception $e) {
|
||||
$message = 'შეცდომა: ' . $e->getMessage();
|
||||
$messageType = 'danger';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'edit':
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
$data = [
|
||||
'first_name' => trim($_POST['first_name'] ?? ''),
|
||||
'last_name' => trim($_POST['last_name'] ?? ''),
|
||||
'email' => trim($_POST['email'] ?? ''),
|
||||
'password' => $_POST['password'] ?? '',
|
||||
'role' => $_POST['role'] ?? 'user',
|
||||
'is_active' => isset($_POST['is_active']) ? 1 : 0
|
||||
];
|
||||
|
||||
// ვალიდაცია
|
||||
$errors = [];
|
||||
if (empty($data['first_name'])) $errors[] = 'სახელი სავალდებულოა';
|
||||
if (empty($data['last_name'])) $errors[] = 'გვარი სავალდებულოა';
|
||||
if (empty($data['email']) || !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
|
||||
$errors[] = 'ვალიდური ელ.ფოსტა სავალდებულოა';
|
||||
}
|
||||
if (!empty($data['password']) && strlen($data['password']) < 6) {
|
||||
$errors[] = 'პაროლი უნდა იყოს მინიმუმ 6 სიმბოლო';
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
$message = implode('<br>', $errors);
|
||||
$messageType = 'danger';
|
||||
} else {
|
||||
try {
|
||||
UserModel::updateUser($id, $data);
|
||||
$message = 'მომხმარებელი წარმატებით განახლდა';
|
||||
$messageType = 'success';
|
||||
$action = 'list';
|
||||
} catch (Exception $e) {
|
||||
$message = 'შეცდომა: ' . $e->getMessage();
|
||||
$messageType = 'danger';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
if ($id > 0) {
|
||||
try {
|
||||
UserModel::deleteUser($id);
|
||||
$message = 'მომხმარებელი წარმატებით წაიშალა';
|
||||
$messageType = 'success';
|
||||
} catch (Exception $e) {
|
||||
$message = 'შეცდომა: ' . $e->getMessage();
|
||||
$messageType = 'danger';
|
||||
}
|
||||
}
|
||||
$action = 'list';
|
||||
break;
|
||||
|
||||
case 'toggle_status':
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
if ($id > 0) {
|
||||
try {
|
||||
UserModel::toggleUserStatus($id);
|
||||
$message = 'მომხმარებლის სტატუსი შეიცვალა';
|
||||
$messageType = 'success';
|
||||
} catch (Exception $e) {
|
||||
$message = 'შეცდომა: ' . $e->getMessage();
|
||||
$messageType = 'danger';
|
||||
}
|
||||
}
|
||||
$action = 'list';
|
||||
break;
|
||||
|
||||
case 'change_password':
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
$currentPassword = $_POST['current_password'] ?? '';
|
||||
$newPassword = $_POST['new_password'] ?? '';
|
||||
$confirmPassword = $_POST['confirm_password'] ?? '';
|
||||
|
||||
$errors = [];
|
||||
if (empty($currentPassword)) $errors[] = 'მიმდინარე პაროლი სავალდებულოა';
|
||||
if (empty($newPassword) || strlen($newPassword) < 6) {
|
||||
$errors[] = 'ახალი პაროლი უნდა იყოს მინიმუმ 6 სიმბოლო';
|
||||
}
|
||||
if ($newPassword !== $confirmPassword) $errors[] = 'პაროლები არ ემთხვევა';
|
||||
|
||||
if (!empty($errors)) {
|
||||
$message = implode('<br>', $errors);
|
||||
$messageType = 'danger';
|
||||
} else {
|
||||
try {
|
||||
UserModel::changePassword($id, $currentPassword, $newPassword);
|
||||
$message = 'პაროლი წარმატებით შეიცვალა';
|
||||
$messageType = 'success';
|
||||
} catch (Exception $e) {
|
||||
$message = 'შეცდომა: ' . $e->getMessage();
|
||||
$messageType = 'danger';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// მონაცემების მომზადება view-სთვის
|
||||
switch ($action) {
|
||||
case 'add':
|
||||
case 'edit':
|
||||
$availableRoles = UserModel::getAvailableRoles();
|
||||
if ($action === 'edit') {
|
||||
$editId = (int)($_GET['id'] ?? 0);
|
||||
$editUser = UserModel::getUserById($editId);
|
||||
if (!$editUser) {
|
||||
$message = 'მომხმარებელი ვერ მოიძებნა';
|
||||
$messageType = 'danger';
|
||||
$action = 'list';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'profile':
|
||||
$profileId = (int)($_GET['id'] ?? $_SESSION['user_id'] ?? 0);
|
||||
$profileUser = UserModel::getUserById($profileId);
|
||||
if (!$profileUser) {
|
||||
$message = 'მომხმარებელი ვერ მოიძებნა';
|
||||
$messageType = 'danger';
|
||||
$action = 'list';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'list':
|
||||
default:
|
||||
// Search და Filter პარამეტრები
|
||||
$search = $_GET['search'] ?? '';
|
||||
$role = $_GET['role'] ?? '';
|
||||
$status = $_GET['status'] ?? '';
|
||||
|
||||
if ($search || $role || $status !== '') {
|
||||
$users = UserModel::searchUsers($search, $role, $status);
|
||||
} else {
|
||||
$users = UserModel::getAllUsers();
|
||||
}
|
||||
|
||||
$userStats = UserModel::getUserStats();
|
||||
$availableRoles = UserModel::getAvailableRoles();
|
||||
break;
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../views/users_management.php';
|
||||
?>
|
||||
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
class UserModel
|
||||
{
|
||||
protected static $db;
|
||||
|
||||
public static function setDb($pdo)
|
||||
{
|
||||
self::$db = $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* ყველა მომხმარებლის მიღება
|
||||
*/
|
||||
public static function getAllUsers()
|
||||
{
|
||||
$stmt = self::$db->query("SELECT * FROM users ORDER BY created_at DESC");
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* კონკრეტული მომხმარებლის მიღება ID-ით
|
||||
*/
|
||||
public static function getUserById($id)
|
||||
{
|
||||
$stmt = self::$db->prepare("SELECT * FROM users WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* მომხმარებლის მიღება ელ.ფოსტით
|
||||
*/
|
||||
public static function getUserByEmail($email)
|
||||
{
|
||||
$stmt = self::$db->prepare("SELECT * FROM users WHERE email = ?");
|
||||
$stmt->execute([$email]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* ახალი მომხმარებლის დამატება
|
||||
*/
|
||||
public static function createUser($data)
|
||||
{
|
||||
// ვამოწმებთ არსებობს თუ არა ასეთი ელ.ფოსტა
|
||||
if (self::getUserByEmail($data['email'])) {
|
||||
throw new Exception("მომხმარებელი ამ ელ.ფოსტით უკვე არსებობს");
|
||||
}
|
||||
|
||||
$hashedPassword = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
|
||||
$stmt = self::$db->prepare("
|
||||
INSERT INTO users (first_name, last_name, email, password, role, is_active)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
|
||||
return $stmt->execute([
|
||||
$data['first_name'],
|
||||
$data['last_name'],
|
||||
$data['email'],
|
||||
$hashedPassword,
|
||||
$data['role'] ?? 'user',
|
||||
$data['is_active'] ?? 1
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* მომხმარებლის განახლება
|
||||
*/
|
||||
public static function updateUser($id, $data)
|
||||
{
|
||||
// ვამოწმებთ ელ.ფოსტის უნიკალურობას (თუ შეიცვალა)
|
||||
$currentUser = self::getUserById($id);
|
||||
if (!$currentUser) {
|
||||
throw new Exception("მომხმარებელი ვერ მოიძებნა");
|
||||
}
|
||||
|
||||
if ($currentUser['email'] !== $data['email']) {
|
||||
$existingUser = self::getUserByEmail($data['email']);
|
||||
if ($existingUser && $existingUser['id'] != $id) {
|
||||
throw new Exception("მომხმარებელი ამ ელ.ფოსტით უკვე არსებობს");
|
||||
}
|
||||
}
|
||||
|
||||
$updateFields = [
|
||||
'first_name' => $data['first_name'],
|
||||
'last_name' => $data['last_name'],
|
||||
'email' => $data['email'],
|
||||
'role' => $data['role'] ?? 'user',
|
||||
'is_active' => $data['is_active'] ?? 1
|
||||
];
|
||||
|
||||
// თუ ახალი პაროლი არის მითითებული
|
||||
if (!empty($data['password'])) {
|
||||
$updateFields['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
$sql = "UPDATE users SET first_name = ?, last_name = ?, email = ?, password = ?, role = ?, is_active = ?, updated_at = NOW() WHERE id = ?";
|
||||
$params = array_values($updateFields);
|
||||
$params[] = $id;
|
||||
} else {
|
||||
unset($updateFields['password']);
|
||||
$sql = "UPDATE users SET first_name = ?, last_name = ?, email = ?, role = ?, is_active = ?, updated_at = NOW() WHERE id = ?";
|
||||
$params = array_values($updateFields);
|
||||
$params[] = $id;
|
||||
}
|
||||
|
||||
$stmt = self::$db->prepare($sql);
|
||||
return $stmt->execute($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* მომხმარებლის წაშლა
|
||||
*/
|
||||
public static function deleteUser($id)
|
||||
{
|
||||
// ვამოწმებთ არ არის თუ არა ეს უკანასკნელი ადმინი
|
||||
$admins = self::getAdminUsers();
|
||||
$userToDelete = self::getUserById($id);
|
||||
|
||||
if ($userToDelete['role'] === 'admin' && count($admins) <= 1) {
|
||||
throw new Exception("ვერ შეიძლება უკანასკნელი ადმინისტრატორის წაშლა");
|
||||
}
|
||||
|
||||
$stmt = self::$db->prepare("DELETE FROM users WHERE id = ?");
|
||||
return $stmt->execute([$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* მომხმარებლის სტატუსის ცვლილება
|
||||
*/
|
||||
public static function toggleUserStatus($id)
|
||||
{
|
||||
$user = self::getUserById($id);
|
||||
if (!$user) {
|
||||
throw new Exception("მომხმარებელი ვერ მოიძებნა");
|
||||
}
|
||||
|
||||
$newStatus = $user['is_active'] ? 0 : 1;
|
||||
|
||||
// ვამოწმებთ ადმინების რაოდენობას
|
||||
if ($user['role'] === 'admin' && $user['is_active'] && $newStatus === 0) {
|
||||
$activeAdmins = self::getActiveAdminUsers();
|
||||
if (count($activeAdmins) <= 1) {
|
||||
throw new Exception("ვერ შეიძლება უკანასკნელი აქტიური ადმინისტრატორის გამორთვა");
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = self::$db->prepare("UPDATE users SET is_active = ? WHERE id = ?");
|
||||
return $stmt->execute([$newStatus, $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* პაროლის შეცვლა
|
||||
*/
|
||||
public static function changePassword($id, $currentPassword, $newPassword)
|
||||
{
|
||||
$user = self::getUserById($id);
|
||||
if (!$user) {
|
||||
throw new Exception("მომხმარებელი ვერ მოიძებნა");
|
||||
}
|
||||
|
||||
if (!password_verify($currentPassword, $user['password'])) {
|
||||
throw new Exception("მიმდინარე პაროლი არასწორია");
|
||||
}
|
||||
|
||||
$hashedPassword = password_hash($newPassword, PASSWORD_DEFAULT);
|
||||
$stmt = self::$db->prepare("UPDATE users SET password = ?, updated_at = NOW() WHERE id = ?");
|
||||
return $stmt->execute([$hashedPassword, $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* ადმინისტრატორების მიღება
|
||||
*/
|
||||
public static function getAdminUsers()
|
||||
{
|
||||
$stmt = self::$db->prepare("SELECT * FROM users WHERE role = 'admin'");
|
||||
$stmt->execute();
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* აქტიური ადმინისტრატორების მიღება
|
||||
*/
|
||||
public static function getActiveAdminUsers()
|
||||
{
|
||||
$stmt = self::$db->prepare("SELECT * FROM users WHERE role = 'admin' AND is_active = 1");
|
||||
$stmt->execute();
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* მომხმარებლების სტატისტიკა
|
||||
*/
|
||||
public static function getUserStats()
|
||||
{
|
||||
$stats = [];
|
||||
|
||||
// სულ მომხმარებლები
|
||||
$stmt = self::$db->query("SELECT COUNT(*) FROM users");
|
||||
$stats['total'] = $stmt->fetchColumn();
|
||||
|
||||
// აქტიური მომხმარებლები
|
||||
$stmt = self::$db->query("SELECT COUNT(*) FROM users WHERE is_active = 1");
|
||||
$stats['active'] = $stmt->fetchColumn();
|
||||
|
||||
// ადმინისტრატორები
|
||||
$stmt = self::$db->query("SELECT COUNT(*) FROM users WHERE role = 'admin'");
|
||||
$stats['admins'] = $stmt->fetchColumn();
|
||||
|
||||
// ამ თვის ახალი მომხმარებლები
|
||||
$stmt = self::$db->query("SELECT COUNT(*) FROM users WHERE created_at >= DATE_FORMAT(NOW(), '%Y-%m-01')");
|
||||
$stats['this_month'] = $stmt->fetchColumn();
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* ხელმისაწვდომი როლები
|
||||
*/
|
||||
public static function getAvailableRoles()
|
||||
{
|
||||
return [
|
||||
'admin' => 'ადმინისტრატორი',
|
||||
'manager' => 'მენეჯერი',
|
||||
'user' => 'მომხმარებელი',
|
||||
'guest' => 'სტუმარი'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* მომხმარებლის search და filter
|
||||
*/
|
||||
public static function searchUsers($search = '', $role = '', $status = '')
|
||||
{
|
||||
$sql = "SELECT * FROM users WHERE 1=1";
|
||||
$params = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$sql .= " AND (first_name LIKE ? OR last_name LIKE ? OR email LIKE ?)";
|
||||
$searchTerm = "%$search%";
|
||||
$params[] = $searchTerm;
|
||||
$params[] = $searchTerm;
|
||||
$params[] = $searchTerm;
|
||||
}
|
||||
|
||||
if (!empty($role)) {
|
||||
$sql .= " AND role = ?";
|
||||
$params[] = $role;
|
||||
}
|
||||
|
||||
if ($status !== '') {
|
||||
$sql .= " AND is_active = ?";
|
||||
$params[] = (int)$status;
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY created_at DESC";
|
||||
|
||||
$stmt = self::$db->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,584 @@
|
||||
<?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">
|
||||
<?php
|
||||
switch ($action) {
|
||||
case 'add': echo 'ახალი მომხმარებლის დამატება'; break;
|
||||
case 'edit': echo 'მომხმარებლის რედაქტირება'; break;
|
||||
case 'profile': echo 'მომხმარებლის პროფილი'; break;
|
||||
default: echo 'მომხმარებლების მართვა'; break;
|
||||
}
|
||||
?>
|
||||
</h2>
|
||||
<?php if ($action === 'list'): ?>
|
||||
<div class="text-muted mt-1">სისტემის მომხმარებლების კონფიგურაცია და მართვა</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="btn-list">
|
||||
<?php if ($action === 'list'): ?>
|
||||
<a href="dashboard.php?module=users&action=management&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 else: ?>
|
||||
<a href="dashboard.php?module=users&action=management" 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>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Messages -->
|
||||
<?php if ($message): ?>
|
||||
<div class="alert alert-<?= $messageType ?> alert-dismissible">
|
||||
<div class="d-flex">
|
||||
<div><?= $message ?></div>
|
||||
</div>
|
||||
<a class="btn-close" data-bs-dismiss="alert" aria-label="close"></a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($action === 'list'): ?>
|
||||
<!-- Statistics Cards -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="subheader">სულ მომხმარებლები</div>
|
||||
<div class="ms-auto lh-1">
|
||||
<div class="dropdown">
|
||||
<a class="dropdown-toggle text-muted" href="#" data-bs-toggle="dropdown">
|
||||
<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">
|
||||
<circle cx="12" cy="12" r="1"/>
|
||||
<circle cx="12" cy="5" r="1"/>
|
||||
<circle cx="12" cy="19" r="1"/>
|
||||
</svg>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-end">
|
||||
<a class="dropdown-item" href="dashboard.php?module=users&action=management">ყველას ნახვა</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h1 mb-3"><?= $userStats['total'] ?></div>
|
||||
<div class="d-flex mb-2">
|
||||
<div>რეგისტრაცია</div>
|
||||
<div class="ms-auto">
|
||||
<span class="text-green d-inline-flex align-items-center lh-1">
|
||||
<?= $userStats['this_month'] ?> <small class="text-muted ms-1">ამ თვეში</small>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="subheader">აქტიური</div>
|
||||
<div class="h1 mb-3 text-green"><?= $userStats['active'] ?></div>
|
||||
<div class="d-flex mb-2">
|
||||
<div>უაქტივო</div>
|
||||
<div class="ms-auto">
|
||||
<span class="text-red"><?= $userStats['total'] - $userStats['active'] ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="subheader">ადმინისტრატორები</div>
|
||||
<div class="h1 mb-3 text-blue"><?= $userStats['admins'] ?></div>
|
||||
<div class="d-flex mb-2">
|
||||
<div>სხვა როლები</div>
|
||||
<div class="ms-auto">
|
||||
<span class="text-muted"><?= $userStats['total'] - $userStats['admins'] ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="subheader">ონლაინ</div>
|
||||
<div class="h1 mb-3 text-yellow">0</div>
|
||||
<div class="d-flex mb-2">
|
||||
<div>უკანასკნელი აქტივობა</div>
|
||||
<div class="ms-auto">
|
||||
<span class="text-muted">დღეს</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search and Filter -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<form method="get" class="row">
|
||||
<input type="hidden" name="module" value="users">
|
||||
<input type="hidden" name="action" value="management">
|
||||
|
||||
<div class="col-md-3">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ძიება</label>
|
||||
<input type="text" name="search" class="form-control"
|
||||
value="<?= htmlspecialchars($_GET['search'] ?? '') ?>"
|
||||
placeholder="სახელი, გვარი, ელ.ფოსტა...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">როლი</label>
|
||||
<select name="role" class="form-select">
|
||||
<option value="">ყველა როლი</option>
|
||||
<?php foreach ($availableRoles as $roleKey => $roleLabel): ?>
|
||||
<option value="<?= $roleKey ?>" <?= ($_GET['role'] ?? '') === $roleKey ? 'selected' : '' ?>>
|
||||
<?= $roleLabel ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">სტატუსი</label>
|
||||
<select name="status" class="form-select">
|
||||
<option value="">ყველა სტატუსი</option>
|
||||
<option value="1" <?= ($_GET['status'] ?? '') === '1' ? 'selected' : '' ?>>აქტიური</option>
|
||||
<option value="0" <?= ($_GET['status'] ?? '') === '0' ? 'selected' : '' ?>>უაქტივო</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="mb-3">
|
||||
<label class="form-label"> </label>
|
||||
<div class="btn-list">
|
||||
<button type="submit" class="btn btn-primary w-100">ძიება</button>
|
||||
<a href="dashboard.php?module=users&action=management" class="btn btn-outline-secondary">გასუფთავება</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Users List -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">მომხმარებლების სია</h3>
|
||||
<div class="card-actions">
|
||||
<span class="text-muted">სულ: <?= count($users) ?> მომხმარებელი</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if (empty($users)): ?>
|
||||
<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="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="12" cy="7" r="4"/>
|
||||
</svg>
|
||||
<h3>მომხმარებლები ვერ მოიძებნა</h3>
|
||||
<p class="text-muted">შეცვალეთ ფილტრები ან დაამატეთ ახალი მომხმარებელი</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-vcenter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>მომხმარებელი</th>
|
||||
<th>ელ.ფოსტა</th>
|
||||
<th>როლი</th>
|
||||
<th>სტატუსი</th>
|
||||
<th>რეგისტრაცია</th>
|
||||
<th>მოქმედებები</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($users as $user): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="avatar bg-<?= $user['role'] === 'admin' ? 'red' : ($user['is_active'] ? 'green' : 'secondary') ?>-lt">
|
||||
<?= strtoupper(substr($user['first_name'], 0, 1) . substr($user['last_name'], 0, 1)) ?>
|
||||
</span>
|
||||
<div class="ms-2">
|
||||
<div class="fw-bold"><?= htmlspecialchars($user['first_name'] . ' ' . $user['last_name']) ?></div>
|
||||
<div class="text-muted small">ID: <?= $user['id'] ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div><?= htmlspecialchars($user['email']) ?></div>
|
||||
<?php if ($user['id'] == $_SESSION['user_id']): ?>
|
||||
<small class="text-blue">ეს ხარ თუ</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-<?= $user['role'] === 'admin' ? 'red' : ($user['role'] === 'manager' ? 'blue' : 'secondary') ?>">
|
||||
<?= $availableRoles[$user['role']] ?? $user['role'] ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-<?= $user['is_active'] ? 'success' : 'danger' ?>">
|
||||
<?= $user['is_active'] ? 'აქტიური' : 'უაქტივო' ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div><?= date('Y-m-d', strtotime($user['created_at'])) ?></div>
|
||||
<small class="text-muted"><?= date('H:i', strtotime($user['created_at'])) ?></small>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-list">
|
||||
<a href="dashboard.php?module=users&action=management&subaction=profile&id=<?= $user['id'] ?>"
|
||||
class="btn btn-sm btn-outline-info" 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="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="12" cy="7" r="4"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="dashboard.php?module=users&action=management&subaction=edit&id=<?= $user['id'] ?>"
|
||||
class="btn btn-sm btn-outline-primary" 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="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="toggle_status">
|
||||
<input type="hidden" name="id" value="<?= $user['id'] ?>">
|
||||
<button type="submit" class="btn btn-sm btn-outline-<?= $user['is_active'] ? 'warning' : 'success' ?>"
|
||||
title="<?= $user['is_active'] ? 'გამორთვა' : 'ჩართვა' ?>"
|
||||
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">
|
||||
<?php if ($user['is_active']): ?>
|
||||
<path d="M10 3H6a2 2 0 0 0-2 2v14c0 5.5 7.5 3 7.5 3s7.5 2.5 7.5-3V5a2 2 0 0 0-2-2h-4"/>
|
||||
<path d="M8 5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2"/>
|
||||
<?php else: ?>
|
||||
<path d="M9 11l3 3l8 -8"/>
|
||||
<?php endif; ?>
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
<?php if ($user['id'] != $_SESSION['user_id']): ?>
|
||||
<form method="post" style="display: inline;">
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<input type="hidden" name="id" value="<?= $user['id'] ?>">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="წაშლა"
|
||||
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>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?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="<?= $editUser['id'] ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">სახელი</label>
|
||||
<input type="text" name="first_name" class="form-control"
|
||||
value="<?= htmlspecialchars($editUser['first_name'] ?? '') ?>"
|
||||
placeholder="სახელი" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">გვარი</label>
|
||||
<input type="text" name="last_name" class="form-control"
|
||||
value="<?= htmlspecialchars($editUser['last_name'] ?? '') ?>"
|
||||
placeholder="გვარი" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ელ.ფოსტა</label>
|
||||
<input type="email" name="email" class="form-control"
|
||||
value="<?= htmlspecialchars($editUser['email'] ?? '') ?>"
|
||||
placeholder="user@example.com" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">პაროლი <?= $action === 'edit' ? '(დატოვეთ ცარიელი თუ არ გსურთ ცვლილება)' : '' ?></label>
|
||||
<input type="password" name="password" class="form-control"
|
||||
placeholder="••••••••" <?= $action === 'add' ? 'required' : '' ?>>
|
||||
<?php if ($action === 'add'): ?>
|
||||
<small class="form-hint">მინიმუმ 6 სიმბოლო</small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">როლი</label>
|
||||
<select name="role" class="form-select" required>
|
||||
<?php foreach ($availableRoles as $roleKey => $roleLabel): ?>
|
||||
<option value="<?= $roleKey ?>"
|
||||
<?= ($editUser['role'] ?? 'user') === $roleKey ? 'selected' : '' ?>>
|
||||
<?= $roleLabel ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-check form-switch mb-3">
|
||||
<input class="form-check-input" type="checkbox" name="is_active"
|
||||
<?= ($editUser['is_active'] ?? 1) ? 'checked' : '' ?>>
|
||||
<label class="form-check-label">აქტიური მომხმარებელი</label>
|
||||
</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=users&action=management" class="btn btn-secondary">გაუქმება</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php elseif ($action === 'profile'): ?>
|
||||
<!-- User Profile -->
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<!-- Profile Info -->
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<span class="avatar avatar-xl bg-<?= $profileUser['role'] === 'admin' ? 'red' : ($profileUser['is_active'] ? 'green' : 'secondary') ?>-lt mb-3">
|
||||
<?= strtoupper(substr($profileUser['first_name'], 0, 1) . substr($profileUser['last_name'], 0, 1)) ?>
|
||||
</span>
|
||||
<h3 class="m-0 mb-1"><?= htmlspecialchars($profileUser['first_name'] . ' ' . $profileUser['last_name']) ?></h3>
|
||||
<div class="text-muted"><?= htmlspecialchars($profileUser['email']) ?></div>
|
||||
<div class="mt-3">
|
||||
<span class="badge bg-<?= $profileUser['role'] === 'admin' ? 'red' : ($profileUser['role'] === 'manager' ? 'blue' : 'secondary') ?> me-1">
|
||||
<?= $availableRoles[$profileUser['role']] ?? $profileUser['role'] ?>
|
||||
</span>
|
||||
<span class="badge bg-<?= $profileUser['is_active'] ? 'success' : 'danger' ?>">
|
||||
<?= $profileUser['is_active'] ? 'აქტიური' : 'უაქტივო' ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="row text-center">
|
||||
<div class="col">
|
||||
<div class="h4 m-0">ID</div>
|
||||
<div class="text-muted"><?= $profileUser['id'] ?></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="h4 m-0">რეგისტრაცია</div>
|
||||
<div class="text-muted"><?= date('Y-m-d', strtotime($profileUser['created_at'])) ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<!-- Profile Details -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">პროფილის დეტალები</h3>
|
||||
<div class="card-actions">
|
||||
<a href="dashboard.php?module=users&action=management&subaction=edit&id=<?= $profileUser['id'] ?>" class="btn btn-primary btn-sm">
|
||||
რედაქტირება
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">სახელი</label>
|
||||
<div class="form-control-plaintext"><?= htmlspecialchars($profileUser['first_name']) ?></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ელ.ფოსტა</label>
|
||||
<div class="form-control-plaintext"><?= htmlspecialchars($profileUser['email']) ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">გვარი</label>
|
||||
<div class="form-control-plaintext"><?= htmlspecialchars($profileUser['last_name']) ?></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ბოლო განახლება</label>
|
||||
<div class="form-control-plaintext">
|
||||
<?= $profileUser['updated_at'] ? date('Y-m-d H:i', strtotime($profileUser['updated_at'])) : 'არასდროს' ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Password Change -->
|
||||
<?php if ($profileUser['id'] == $_SESSION['user_id']): ?>
|
||||
<div class="card mt-4">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">პაროლის შეცვლა</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="change_password">
|
||||
<input type="hidden" name="id" value="<?= $profileUser['id'] ?>">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">მიმდინარე პაროლი</label>
|
||||
<input type="password" name="current_password" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ახალი პაროლი</label>
|
||||
<input type="password" name="new_password" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">პაროლის დადასტურება</label>
|
||||
<input type="password" name="confirm_password" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-warning">პაროლის შეცვლა</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script src="../dist/js/tabler.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Form validation
|
||||
const forms = document.querySelectorAll('form[method="post"]');
|
||||
forms.forEach(form => {
|
||||
form.addEventListener('submit', function(e) {
|
||||
const action = form.querySelector('input[name="action"]')?.value;
|
||||
|
||||
if (action === 'add' || action === 'edit') {
|
||||
const firstName = form.querySelector('input[name="first_name"]')?.value.trim();
|
||||
const lastName = form.querySelector('input[name="last_name"]')?.value.trim();
|
||||
const email = form.querySelector('input[name="email"]')?.value.trim();
|
||||
const password = form.querySelector('input[name="password"]')?.value;
|
||||
|
||||
let errors = [];
|
||||
|
||||
if (!firstName) errors.push('სახელი სავალდებულოა');
|
||||
if (!lastName) errors.push('გვარი სავალდებულოა');
|
||||
if (!email || !email.includes('@')) errors.push('ვალიდური ელ.ფოსტა სავალდებულოა');
|
||||
|
||||
if (action === 'add' && (!password || password.length < 6)) {
|
||||
errors.push('პაროლი უნდა იყოს მინიმუმ 6 სიმბოლო');
|
||||
}
|
||||
|
||||
if (action === 'edit' && password && password.length < 6) {
|
||||
errors.push('პაროლი უნდა იყოს მინიმუმ 6 სიმბოლო');
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
alert('შეცდომები:\n' + errors.join('\n'));
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (action === 'change_password') {
|
||||
const currentPassword = form.querySelector('input[name="current_password"]')?.value;
|
||||
const newPassword = form.querySelector('input[name="new_password"]')?.value;
|
||||
const confirmPassword = form.querySelector('input[name="confirm_password"]')?.value;
|
||||
|
||||
let errors = [];
|
||||
|
||||
if (!currentPassword) errors.push('მიმდინარე პაროლი სავალდებულოა');
|
||||
if (!newPassword || newPassword.length < 6) errors.push('ახალი პაროლი უნდა იყოს მინიმუმ 6 სიმბოლო');
|
||||
if (newPassword !== confirmPassword) errors.push('პაროლები არ ემთხვევა');
|
||||
|
||||
if (errors.length > 0) {
|
||||
alert('შეცდომები:\n' + errors.join('\n'));
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once Config::includePath('footer.php'); ?>
|
||||
Reference in New Issue
Block a user