Revert to version 15280ba
This commit is contained in:
parent
96847809f7
commit
935f41f960
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,3 @@
|
||||
node_modules/
|
||||
*/node_modules/
|
||||
*/build/
|
||||
.env
|
||||
|
||||
114
api.php
114
api.php
@ -1,114 +0,0 @@
|
||||
<?php
|
||||
// api.php
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// --- Helper function to get environment variables ---
|
||||
function get_env($key, $default = null) {
|
||||
$path = __DIR__ . '/.env';
|
||||
if (!file_exists($path)) {
|
||||
return $default;
|
||||
}
|
||||
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($lines as $line) {
|
||||
if (strpos(trim($line), '#') === 0) {
|
||||
continue;
|
||||
}
|
||||
list($name, $value) = explode('=', $line, 2);
|
||||
$name = trim($name);
|
||||
$value = trim($value);
|
||||
if ($name === $key) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
// --- Main Logic ---
|
||||
|
||||
// 1. Get API Key
|
||||
$apiKey = get_env('MISTRAL_API_KEY');
|
||||
if (!$apiKey) {
|
||||
echo json_encode(['reply' => 'Ошибка: API-ключ не найден. Пожалуйста, добавьте его в файл .env с именем MISTRAL_API_KEY.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 2. Get user message from POST request
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$userMessage = trim($input['message'] ?? '');
|
||||
|
||||
if (empty($userMessage)) {
|
||||
echo json_encode(['reply' => 'Пожалуйста, введите сообщение.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 3. Load the knowledge base
|
||||
$knowledgeBasePath = __DIR__ . '/db/knowledge_base.txt';
|
||||
if (!file_exists($knowledgeBasePath)) {
|
||||
echo json_encode(['reply' => 'Ошибка: База знаний не найдена.']);
|
||||
exit;
|
||||
}
|
||||
$knowledgeBase = file_get_contents($knowledgeBasePath);
|
||||
|
||||
// 4. Prepare the messages for the AI
|
||||
$systemPrompt = "Ты — ИИ-ассистент, специалист по внутренней системе управления складом под названием HUB. Твоя задача — отвечать на вопросы пользователя, основываясь ИСКЛЮЧИТЕЛЬНО на предоставленной базе знаний. Не придумывай ничего от себя. Если ответа в базе знаний нет, вежливо сообщи, что ты можешь отвечать только на вопросы, связанные с системой HUB.\n\nВот база знаний:\n---\n" . $knowledgeBase;
|
||||
|
||||
// 5. Call the Mistral API
|
||||
$url = 'https://api.mistral.ai/v1/chat/completions';
|
||||
|
||||
$data = [
|
||||
'model' => 'mistral-small-latest', // Or another suitable model
|
||||
'messages' => [
|
||||
[
|
||||
'role' => 'system',
|
||||
'content' => $systemPrompt
|
||||
],
|
||||
[
|
||||
'role' => 'user',
|
||||
'content' => $userMessage
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$options = [
|
||||
'http' => [
|
||||
'header' => "Content-Type: application/json\n" .
|
||||
"Authorization: Bearer " . $apiKey . "\n",
|
||||
'method' => 'POST',
|
||||
'content' => json_encode($data),
|
||||
'ignore_errors' => true
|
||||
]
|
||||
];
|
||||
|
||||
$context = stream_context_create($options);
|
||||
$response = file_get_contents($url, false, $context);
|
||||
$http_response_header = $http_response_header ?? [];
|
||||
|
||||
// 6. Process the response
|
||||
if ($response === FALSE) {
|
||||
$error = 'Не удалось связаться с API Mistral. ';
|
||||
$last_error = error_get_last();
|
||||
if ($last_error) {
|
||||
$error .= $last_error['message'];
|
||||
}
|
||||
$status_line = $http_response_header[0] ?? 'HTTP/1.1 500 Internal Server Error';
|
||||
preg_match('{HTTP/\S+\s(\d+)}', $status_line, $match);
|
||||
$status = $match[1] ?? 500;
|
||||
|
||||
error_log("Mistral API Error: Status $status, Response: $response");
|
||||
|
||||
echo json_encode(['reply' => "Ошибка при обращении к сервису ИИ (Mistral). Статус: $status. Пожалуйста, проверьте ключ API и настройки сервера."]);
|
||||
|
||||
} else {
|
||||
$result = json_decode($response, true);
|
||||
|
||||
if (isset($result['choices'][0]['message']['content'])) {
|
||||
$reply = $result['choices'][0]['message']['content'];
|
||||
echo json_encode(['reply' => $reply]);
|
||||
} else {
|
||||
// Log the actual error response from the API for debugging
|
||||
error_log("Mistral API - Unexpected response structure: " . $response);
|
||||
$errorMessage = $result['message'] ?? 'Неизвестная ошибка.';
|
||||
echo json_encode(['reply' => 'Получен неожиданный ответ от сервиса ИИ (Mistral). ' . $errorMessage]);
|
||||
}
|
||||
}
|
||||
@ -1,163 +0,0 @@
|
||||
|
||||
:root {
|
||||
--bg-color: #121212;
|
||||
--surface-color: #1E1E1E;
|
||||
--primary-color: #00FF9B;
|
||||
--secondary-color: #00C2FF;
|
||||
--text-color: #E0E0E0;
|
||||
--text-muted-color: #888;
|
||||
--border-radius-md: 12px;
|
||||
--border-radius-sm: 8px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
font-family: 'Roboto Mono', 'Consolas', 'Monaco', monospace;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
height: 100vh;
|
||||
max-height: 100vh; /* For mobile browsers */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 0;
|
||||
box-shadow: 0 0 40px rgba(0, 255, 155, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chat-header {
|
||||
padding: 16px 24px;
|
||||
background-color: var(--surface-color);
|
||||
border-bottom: 1px solid #333;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.chat-header h1 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
margin: 0;
|
||||
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.chat-header .text-muted {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted-color);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.chat-messages {
|
||||
flex-grow: 1;
|
||||
padding: 24px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
/* Custom scrollbar for webkit browsers */
|
||||
.chat-messages::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
.chat-messages::-webkit-scrollbar-track {
|
||||
background: var(--bg-color);
|
||||
}
|
||||
.chat-messages::-webkit-scrollbar-thumb {
|
||||
background-color: var(--surface-color);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.message {
|
||||
display: flex;
|
||||
max-width: 75%;
|
||||
}
|
||||
|
||||
.message-content {
|
||||
padding: 12px 16px;
|
||||
border-radius: var(--border-radius-md);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.message-content p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.bot-message {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.bot-message .message-content {
|
||||
background-color: var(--surface-color);
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
.user-message {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.user-message .message-content {
|
||||
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
||||
color: #000;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.chat-input-area {
|
||||
padding: 16px 24px;
|
||||
background-color: var(--surface-color);
|
||||
border-top: 1px solid #333;
|
||||
}
|
||||
|
||||
#chat-form .form-control {
|
||||
background-color: #333;
|
||||
border: 1px solid #444;
|
||||
color: var(--text-color);
|
||||
border-radius: var(--border-radius-sm);
|
||||
padding: 12px 16px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
#chat-form .form-control:focus {
|
||||
background-color: #333;
|
||||
color: var(--text-color);
|
||||
box-shadow: 0 0 0 2px var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
#chat-form .form-control::placeholder {
|
||||
color: var(--text-muted-color);
|
||||
}
|
||||
|
||||
#chat-form .btn {
|
||||
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
||||
border: none;
|
||||
border-radius: var(--border-radius-sm);
|
||||
margin-left: 12px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
#chat-form .btn:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
#chat-form .btn svg {
|
||||
color: #000;
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const chatForm = document.getElementById('chat-form');
|
||||
const messageInput = document.getElementById('message-input');
|
||||
const chatMessages = document.getElementById('chat-messages');
|
||||
|
||||
chatForm.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
const messageText = messageInput.value.trim();
|
||||
|
||||
if (messageText) {
|
||||
appendMessage(messageText, 'user');
|
||||
messageInput.value = '';
|
||||
|
||||
showBotTyping();
|
||||
|
||||
// Send message to backend
|
||||
fetch('api.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ message: messageText })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
removeBotTyping();
|
||||
appendMessage(data.reply, 'bot');
|
||||
})
|
||||
.catch(error => {
|
||||
removeBotTyping();
|
||||
console.error('Error:', error);
|
||||
appendMessage('Извините, произошла ошибка. Попробуйте еще раз.', 'bot');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function appendMessage(text, sender) {
|
||||
const messageWrapper = document.createElement('div');
|
||||
messageWrapper.classList.add('message', `${sender}-message`);
|
||||
|
||||
const messageContent = document.createElement('div');
|
||||
messageContent.classList.add('message-content');
|
||||
|
||||
const paragraph = document.createElement('p');
|
||||
paragraph.innerHTML = text; // Use innerHTML to render potential HTML tags from response
|
||||
|
||||
messageContent.appendChild(paragraph);
|
||||
messageWrapper.appendChild(messageContent);
|
||||
chatMessages.appendChild(messageWrapper);
|
||||
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
function showBotTyping() {
|
||||
const typingIndicator = document.createElement('div');
|
||||
typingIndicator.id = 'typing-indicator';
|
||||
typingIndicator.classList.add('message', 'bot-message');
|
||||
|
||||
const content = document.createElement('div');
|
||||
content.classList.add('message-content');
|
||||
|
||||
const p = document.createElement('p');
|
||||
p.textContent = '...';
|
||||
|
||||
content.appendChild(p);
|
||||
typingIndicator.appendChild(content);
|
||||
chatMessages.appendChild(typingIndicator);
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
function removeBotTyping() {
|
||||
const typingIndicator = document.getElementById('typing-indicator');
|
||||
if (typingIndicator) {
|
||||
typingIndicator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToBottom() {
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
}
|
||||
|
||||
// Initial scroll to bottom if content is already there
|
||||
scrollToBottom();
|
||||
});
|
||||
@ -1,2 +0,0 @@
|
||||
# База знаний: Система HUB ## 1. Введение в систему HUB **Цель:** Понять назначение HUB и его роль в управлении складскими данными. **HUB** — это система для управления складскими предметами (грузами, контейнерами, коробками и т.д.) и процессами их перемещения, хранения и инвентаризации. Она позволяет отслеживать состояние предметов, их историю, взаимодействие с контейнерами и логистическими точками, а также проводить пересчеты и настраивать складскую инфраструктуру. ### Ключевые понятия - **Предмет**: Объект хранения (например, ТЯ, коробка, отправление). - **Логистический контейнер (ЛК)**: Емкость для хранения/перемещения предметов (статусы: "Формируется", "Сформирован" и др.). - **Инвентаризация / пересчет**: Проверка фактического наличия предметов на складе против учетных данных. - **КМО**: Внутренний термин, предположительно связанный с документацией о материальных ошибках/недостачах (например, "Книга Материальных Остатков"). - **ЦМН**: Цель доставки (место назначения предмета). - **Тайм-слот**: Временной интервал для доставки. --- ## 2. Основы интерфейса HUB и карточка предмета **Цель:** Знакомство с интерфейсом HUB и структурой карточки предмета. HUB содержит главное меню, схему склада и таблицу со списком предметов. Основная работа ведется через **карточку предмета** — детализированное окно с информацией о конкретном объекте. ### 2.1 Структура карточки предмета Карточка доступна при клике на ID предмета в таблице **"Предметы"**. Она включает следующие вкладки: | Вкладка | Описание | Основные данные | |-------------------------|----------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| | **«О предмете»** | Основная информация о предмете. | Тип, статус, ID, номенклатура, принадлежность, стоимость, адрес хранения. | | **«Состав»** | Текущий и исторический состав контейнера (для предметов, являющихся контейнерами). | Список предметов внутри, даты
|
||||
1. навигация_по_карточке.pdf Навигация по карточке предмета В HUB можно просматривать информацию по всем типам предметов: ТЯ, КТЯ, тарная паллета, груз/транзитный груз, коробка/транзитная коробка, квант-коробка, отправление, экземпляр. Карточка предмета содержит: Вкладка «О предмете»: основная информация о предмете. Вкладка «Состав»: текущий и исторический состав контейнера. Вкладка «История (перемещения)» — перемещения между ячейками склада, контейнерами и логистическими точками. Вкладка «Отгрузки»: все выдачи предмета. Вкладка «Транспорт»: вхождения и выходы из транспортных сущностей. Вкладка «История свойств»: изменения свойств предмета (статус, ЦМН, слот доставки). 2. состав_лог_конт.pdf Просмотр состава логистического контейнера Открыть карточку контейнера, перейти на вкладку «Состав». По умолчанию отображается состав на текущий момент времени. Чтобы выгрузить состав в Excel, нажмите на значок «скачать» в правом верхнем углу. Важно: Для логистических контейнеров в статусе «Формируется» состав виден только в HUB. Для просмотра истории изменения состава логистического контейнера необходимо выключить тогл «Только с пустой датой извлечения». 3. пересчеты_hub.pdf Пересчеты и инвентаризации Вкладка «Пересчеты»: Запуск пересчетов: Выберите место или несколько мест на схеме склада. Нажмите на кнопку «Запустить пересчет». Подтвердите запуск в окне «Запустить пересчет?». Информация о ячейке: Нажмите на пиктограмму "i" справа от выбранной ячейки. Инфографика по пересчетам: Нажмите на кнопку в правой части экрана для просмотра инфографики. Просмотр детализированной информации: При нажатии на ID инвентаризации/пересчета откроется окно с детализированной информацией. В этом окне можно скачать фактический, балансовый списки и списки излишков и недостач. Вкладка «Задания»: Полная информация о заданиях на пересчет/инвентаризацию и их исполнителях. Утерянные предметы и акты на удержание КМО: На вкладках можно увидеть список утерянных предметов и акты на удержание КМО. 4. информа
|
||||
178
index.php
178
index.php
@ -1,59 +1,131 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
@ini_set('display_errors', '1');
|
||||
@error_reporting(E_ALL);
|
||||
@date_default_timezone_set('UTC');
|
||||
|
||||
$phpVersion = PHP_VERSION;
|
||||
$now = date('Y-m-d H:i:s');
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Your Logistic Koresh</title>
|
||||
<meta name="description" content="AI Assistant for HUB System">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:title" content="Your Logistic Koresh">
|
||||
<meta property="og:description" content="AI Assistant for HUB System">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content=""> <!-- Will be the current URL -->
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>New Style</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg-color-start: #6a11cb;
|
||||
--bg-color-end: #2575fc;
|
||||
--text-color: #ffffff;
|
||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
|
||||
animation: bg-pan 20s linear infinite;
|
||||
z-index: -1;
|
||||
}
|
||||
@keyframes bg-pan {
|
||||
0% { background-position: 0% 0%; }
|
||||
100% { background-position: 100% 100%; }
|
||||
}
|
||||
main {
|
||||
padding: 2rem;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-bg-color);
|
||||
border: 1px solid var(--card-border-color);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.loader {
|
||||
margin: 1.25rem auto 1.25rem;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 3px solid rgba(255, 255, 255, 0.25);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
.hint {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px; height: 1px;
|
||||
padding: 0; margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap; border: 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 1rem;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
p {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
code {
|
||||
background: rgba(0,0,0,0.2);
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
}
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="chat-container">
|
||||
<header class="chat-header">
|
||||
<h1>Your Logistic Koresh</h1>
|
||||
<p class="text-muted">AI Assistant for HUB System</p>
|
||||
</header>
|
||||
|
||||
<main class="chat-messages" id="chat-messages">
|
||||
<!-- Messages will be appended here by JS -->
|
||||
<div class="message bot-message">
|
||||
<div class="message-content">
|
||||
<p>Привет. Я — твой логистический кореш. Я здесь, чтобы помочь тебе с вопросами по системе HUB. Спрашивай, не стесняйся.</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="chat-input-area">
|
||||
<form id="chat-form" class="d-flex">
|
||||
<input type="text" id="message-input" class="form-control" placeholder="Введите ваш вопрос..." autocomplete="off" required>
|
||||
<button type="submit" class="btn btn-primary" id="send-button">
|
||||
<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="feather feather-send"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
|
||||
</button>
|
||||
</form>
|
||||
</footer>
|
||||
<main>
|
||||
<div class="card">
|
||||
<h1>Analyzing your requirements and generating your website…</h1>
|
||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
||||
<span class="sr-only">Loading…</span>
|
||||
</div>
|
||||
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWiZZy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
|
||||
<p class="hint">This page will update automatically as the plan is implemented.</p>
|
||||
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||
<!-- Custom JS -->
|
||||
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
||||
</main>
|
||||
<footer>
|
||||
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user