211 lines
10 KiB
PHP
211 lines
10 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../../inc/auth.php';
|
|
require_once __DIR__ . '/../../inc/functions.php';
|
|
$session = auth_require('owner');
|
|
|
|
$pdo = getDB();
|
|
$message = '';
|
|
|
|
// Save item
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_item'])) {
|
|
$csrf = $_POST['csrf_token'] ?? '';
|
|
if (!auth_csrf_verify($csrf)) {
|
|
$message = 'Ошибка безопасности.';
|
|
} else {
|
|
$id = (int)($_POST['id'] ?? 0);
|
|
$step = (int)($_POST['step'] ?? 1);
|
|
$section = trim($_POST['section'] ?? '');
|
|
$key = trim($_POST['question_key'] ?? '');
|
|
$label = trim($_POST['label'] ?? '');
|
|
$type = $_POST['type'] ?? 'text';
|
|
$options = trim($_POST['options'] ?? '');
|
|
$required = isset($_POST['required']) ? 1 : 0;
|
|
$sortOrder = (int)($_POST['sort_order'] ?? 0);
|
|
$helpText = trim($_POST['help_text'] ?? '');
|
|
|
|
if ($key === '' || $label === '') {
|
|
$message = 'Ключ и название обязательны.';
|
|
} else {
|
|
try {
|
|
if ($id > 0) {
|
|
$stmt = $pdo->prepare("UPDATE questionnaire_items SET step=?, section=?, question_key=?, label=?, type=?, options=?, required=?, sort_order=?, help_text=? WHERE id=?");
|
|
$stmt->execute([$step, $section, $key, $label, $type, $options, $required, $sortOrder, $helpText, $id]);
|
|
} else {
|
|
$stmt = $pdo->prepare("INSERT INTO questionnaire_items (step, section, question_key, label, type, options, required, sort_order, help_text) VALUES (?,?,?,?,?,?,?,?,?)");
|
|
$stmt->execute([$step, $section, $key, $label, $type, $options, $required, $sortOrder, $helpText]);
|
|
}
|
|
$message = $id > 0 ? 'Вопрос обновлён.' : 'Вопрос создан.';
|
|
} catch (\PDOException $e) {
|
|
$message = 'Ошибка: ' . $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Delete item
|
|
if (isset($_GET['delete']) && auth_csrf_verify($_GET['csrf'] ?? '')) {
|
|
$pdo->prepare("DELETE FROM questionnaire_items WHERE id=?")->execute([(int)$_GET['delete']]);
|
|
$message = 'Вопрос удалён.';
|
|
}
|
|
|
|
// Toggle active
|
|
if (isset($_GET['toggle']) && auth_csrf_verify($_GET['csrf'] ?? '')) {
|
|
$pdo->prepare("UPDATE questionnaire_items SET is_active=NOT is_active WHERE id=?")->execute([(int)$_GET['toggle']]);
|
|
$message = 'Статус изменён.';
|
|
}
|
|
|
|
$editItem = null;
|
|
if (isset($_GET['edit'])) {
|
|
$stmt = $pdo->prepare("SELECT * FROM questionnaire_items WHERE id=?");
|
|
$stmt->execute([(int)$_GET['edit']]);
|
|
$editItem = $stmt->fetch();
|
|
}
|
|
|
|
$stepFilter = (int)($_GET['step'] ?? 0);
|
|
if ($stepFilter > 0) {
|
|
$stmt = $pdo->prepare("SELECT * FROM questionnaire_items WHERE step=? ORDER BY sort_order, id");
|
|
$stmt->execute([$stepFilter]);
|
|
} else {
|
|
$stmt = $pdo->query("SELECT * FROM questionnaire_items ORDER BY step, sort_order, id");
|
|
}
|
|
$items = $stmt->fetchAll();
|
|
|
|
$stepLabels = [1 => 'Коммерческий', 2 => 'Технический', 3 => 'Эксплуатация', 4 => 'Риски', 5 => 'Расчёт SLA'];
|
|
|
|
$csrf = auth_csrf_token();
|
|
require __DIR__ . '/../../inc/header.php';
|
|
?>
|
|
|
|
<div class="main-header">
|
|
<div>
|
|
<h1>Конфигурация опросника</h1>
|
|
<div class="breadcrumb"><a href="/service/dashboard.php">Главная</a> / <a href="questionnaire.php">Опросник</a> / Настройка</div>
|
|
</div>
|
|
<button class="btn btn-primary btn-sm" onclick="openModal()" data-tooltip="Добавить вопрос">+ Добавить вопрос</button>
|
|
</div>
|
|
|
|
<?php if ($message): ?>
|
|
<div class="alert alert-info"><?= htmlspecialchars($message) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="step-tabs" style="display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap;">
|
|
<a href="questionnaire_config.php" class="btn btn-secondary btn-sm <?= $stepFilter === 0 ? 'active' : '' ?>">Все шаги</a>
|
|
<?php foreach ($stepLabels as $num => $label): ?>
|
|
<a href="?step=<?= $num ?>" class="btn btn-secondary btn-sm <?= $stepFilter === $num ? 'active' : '' ?>"><?= $num ?>. <?= $label ?></a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Шаг</th>
|
|
<th>Секция</th>
|
|
<th>Ключ</th>
|
|
<th>Название</th>
|
|
<th>Тип</th>
|
|
<th>Обяз.</th>
|
|
<th>Порядок</th>
|
|
<th>Статус</th>
|
|
<th class="actions">Действия</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($items)): ?>
|
|
<tr><td colspan="9" style="text-align:center;color:var(--text-muted);">Нет вопросов</td></tr>
|
|
<?php endif; ?>
|
|
<?php foreach ($items as $item): ?>
|
|
<tr>
|
|
<td><?= $item['step'] ?></td>
|
|
<td><?= htmlspecialchars($item['section']) ?></td>
|
|
<td><code><?= htmlspecialchars($item['question_key']) ?></code></td>
|
|
<td><?= htmlspecialchars($item['label']) ?></td>
|
|
<td><?= $item['type'] ?></td>
|
|
<td><?= $item['required'] ? '✓' : '—' ?></td>
|
|
<td><?= $item['sort_order'] ?></td>
|
|
<td><span class="badge badge-<?= $item['is_active'] ? 'done' : 'cancelled' ?>"><?= $item['is_active'] ? 'Активен' : 'Отключён' ?></span></td>
|
|
<td class="actions">
|
|
<a href="?edit=<?= $item['id'] ?>" class="btn btn-secondary btn-sm" data-tooltip="Редактировать">✏️</a>
|
|
<a href="?toggle=<?= $item['id'] ?>&csrf=<?= $csrf ?>" class="btn btn-secondary btn-sm" data-tooltip="Переключить статус">🔄</a>
|
|
<a href="?delete=<?= $item['id'] ?>&csrf=<?= $csrf ?>" class="btn btn-danger btn-sm" onclick="return confirm('Удалить вопрос?')" data-tooltip="Удалить">🗑️</a>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-overlay <?= $editItem ? 'open' : '' ?>" id="itemModal">
|
|
<div class="modal">
|
|
<button class="modal-close" onclick="closeModal()">×</button>
|
|
<h2><?= $editItem ? 'Редактировать' : 'Добавить' ?> вопрос</h2>
|
|
<form method="post">
|
|
<input type="hidden" name="csrf_token" value="<?= $csrf ?>">
|
|
<input type="hidden" name="save_item" value="1">
|
|
<input type="hidden" name="id" value="<?= $editItem['id'] ?? 0 ?>">
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="step">Шаг *</label>
|
|
<select id="step" name="step" required>
|
|
<?php foreach ($stepLabels as $num => $label): ?>
|
|
<option value="<?= $num ?>" <?= ($editItem['step'] ?? 1) == $num ? 'selected' : '' ?>><?= $num ?>. <?= $label ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="type">Тип *</label>
|
|
<select id="type" name="type" required>
|
|
<?php foreach (['text','number','select','radio','checkbox','textarea'] as $t): ?>
|
|
<option value="<?= $t ?>" <?= ($editItem['type'] ?? 'text') === $t ? 'selected' : '' ?>><?= $t ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="section">Секция</label>
|
|
<input type="text" id="section" name="section" value="<?= htmlspecialchars($editItem['section'] ?? '') ?>">
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="question_key">Ключ *</label>
|
|
<input type="text" id="question_key" name="question_key" value="<?= htmlspecialchars($editItem['question_key'] ?? '') ?>" required>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sort_order">Порядок</label>
|
|
<input type="number" id="sort_order" name="sort_order" value="<?= $editItem['sort_order'] ?? 0 ?>">
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="label">Название *</label>
|
|
<input type="text" id="label" name="label" value="<?= htmlspecialchars($editItem['label'] ?? '') ?>" required>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="options">Опции (JSON)</label>
|
|
<textarea id="options" name="options" placeholder='{"key":"Label"} или ["opt1","opt2"]' rows="3"><?= htmlspecialchars($editItem['options'] ?? '') ?></textarea>
|
|
<small style="color:var(--text-muted);">Для select/radio: JSON объект или массив</small>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="help_text">Подсказка</label>
|
|
<input type="text" id="help_text" name="help_text" value="<?= htmlspecialchars($editItem['help_text'] ?? '') ?>">
|
|
</div>
|
|
<label class="form-check">
|
|
<input type="checkbox" name="required" <?= ($editItem['required'] ?? 0) ? 'checked' : '' ?>> Обязательное поле
|
|
</label>
|
|
<div style="margin-top:16px;">
|
|
<button type="submit" class="btn btn-primary">Сохранить</button>
|
|
<button type="button" class="btn btn-secondary" onclick="closeModal()">Отмена</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function openModal() { document.getElementById('itemModal').classList.add('open'); }
|
|
function closeModal() { document.getElementById('itemModal').classList.remove('open'); window.location.href = 'questionnaire_config.php'; }
|
|
</script>
|
|
|
|
<?php require __DIR__ . '/../../inc/footer.php'; ?>
|