Итерация 1: каркас Slim 4 приложения
- Slim 4 + php-di контейнер с маршрутизацией - Docker Compose: app (PHP 8.3-FPM) + web (nginx) + db (MariaDB) - Phinx миграция: таблица users (uuid, username, password_hash) - Auth: login/logout с сессиями - Setup: создание первого пользователя - Dashboard с layout (Bootstrap 5.3) - CLI: bin/console, bin/run-scan-worker.php - Smoke test: scripts/check.sh - README.md, PLAN.md
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
<?php ob_start(); ?>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-4">
|
||||
<div class="card mt-5">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title text-center mb-4">Вход в Домовой</h4>
|
||||
<?php if (isset($error)): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<?php endif; ?>
|
||||
<form method="POST" action="/login">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Имя пользователя</label>
|
||||
<input type="text" class="form-control" id="username" name="username" required autofocus>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Пароль</label>
|
||||
<input type="password" class="form-control" id="password" name="password" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">Войти</button>
|
||||
</form>
|
||||
<div class="text-center mt-3">
|
||||
<small class="text-muted">
|
||||
Нет аккаунта? <a href="/setup">Создать первого пользователя</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php $content = ob_get_clean(); ?>
|
||||
<?php require dirname(__DIR__) . '/layout.php'; ?>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php ob_start(); ?>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-4">
|
||||
<div class="card mt-5">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title text-center mb-4">Создание первого пользователя</h4>
|
||||
<p class="text-muted text-center">Это будет администратор системы "Домовой"</p>
|
||||
<?php if (isset($error)): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<?php endif; ?>
|
||||
<form method="POST" action="/setup">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Имя пользователя</label>
|
||||
<input type="text" class="form-control" id="username" name="username" required autofocus
|
||||
minlength="2" maxlength="255">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Пароль</label>
|
||||
<input type="password" class="form-control" id="password" name="password" required
|
||||
minlength="8">
|
||||
<div class="form-text">Минимум 8 символов</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">Создать аккаунт</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php $content = ob_get_clean(); ?>
|
||||
<?php require dirname(__DIR__) . '/layout.php'; ?>
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php ob_start(); ?>
|
||||
<h2>Dashboard</h2>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-3">
|
||||
<div class="card text-white bg-primary">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Устройства</h5>
|
||||
<p class="card-text display-6">0</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card text-white bg-success">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Сервисы</h5>
|
||||
<p class="card-text display-6">0</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card text-white bg-info">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Новые находки</h5>
|
||||
<p class="card-text display-6">0</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card text-white bg-warning">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Требуют внимания</h5>
|
||||
<p class="card-text display-6">0</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
Последние найденные хосты
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">Нет данных. Запустите сканирование сети.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
Последние события
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">Нет событий.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Последний скан сети
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">Сканирование ещё не запускалось.</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php $content = ob_get_clean(); ?>
|
||||
<?php require dirname(__DIR__) . '/layout.php'; ?>
|
||||
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Домовой</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/assets/css/app.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="d-flex" id="wrapper">
|
||||
<!-- Sidebar -->
|
||||
<nav class="bg-dark text-white border-end" id="sidebar-wrapper" style="width: 250px; min-height: 100vh;">
|
||||
<div class="sidebar-heading p-3 border-bottom border-secondary">
|
||||
<a href="/dashboard" class="text-white text-decoration-none">
|
||||
<h4 class="mb-0">Домовой</h4>
|
||||
</a>
|
||||
</div>
|
||||
<div class="list-group list-group-flush">
|
||||
<a href="/dashboard" class="list-group-item list-group-item-action bg-dark text-white border-0">
|
||||
Dashboard
|
||||
</a>
|
||||
<a href="/discovery" class="list-group-item list-group-item-action bg-dark text-white border-0">
|
||||
Сканирование сети
|
||||
</a>
|
||||
<a href="/devices" class="list-group-item list-group-item-action bg-dark text-white border-0">
|
||||
Устройства
|
||||
</a>
|
||||
<a href="/services" class="list-group-item list-group-item-action bg-dark text-white border-0">
|
||||
Сервисы
|
||||
</a>
|
||||
<a href="/documents" class="list-group-item list-group-item-action bg-dark text-white border-0">
|
||||
Документы
|
||||
</a>
|
||||
<a href="/settings" class="list-group-item list-group-item-action bg-dark text-white border-0">
|
||||
Настройки
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Page Content -->
|
||||
<div id="page-content-wrapper" class="w-100">
|
||||
<!-- Top Navbar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark border-bottom border-secondary">
|
||||
<div class="container-fluid">
|
||||
<span class="navbar-brand text-light">Домовой</span>
|
||||
<div class="ms-auto d-flex align-items-center">
|
||||
<span class="text-light me-3"><?= htmlspecialchars($username ?? 'User') ?></span>
|
||||
<form method="POST" action="/logout" class="d-inline">
|
||||
<button type="submit" class="btn btn-outline-light btn-sm">Logout</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="container-fluid p-4">
|
||||
<?php if (isset($content)): ?>
|
||||
<?= $content ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user