37689-vm/index.php
2026-01-26 01:57:49 +00:00

461 lines
27 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
require_once 'db/config.php';
$project_name = $_SERVER['PROJECT_NAME'] ?? 'Nano Media AI';
$project_description = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Generate unique AI photos and high-quality stock videos.';
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($project_name); ?></title>
<meta name="description" content="<?php echo htmlspecialchars($project_description); ?>">
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Google Fonts: Inter & Montserrat -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Montserrat:wght@800&display=swap" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Editor Libraries -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
<!-- Custom CSS -->
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<style>
:root {
--nano-yellow: #FFDE59;
--nano-black: #1A1A1A;
--nano-white: #FFFFFF;
--nano-gray: #F5F5F5;
--nano-radius: 24px;
}
body {
background-color: var(--nano-gray);
font-family: 'Inter', sans-serif;
}
.navbar {
background-color: var(--nano-white) !important;
border-bottom: 2px solid var(--nano-black);
padding: 15px 0;
}
.navbar-brand {
font-family: 'Montserrat', sans-serif;
color: var(--nano-black) !important;
font-size: 1.5rem;
text-transform: uppercase;
}
.btn-nano {
background-color: var(--nano-yellow);
color: var(--nano-black);
border: 2px solid var(--nano-black);
border-radius: var(--nano-radius);
font-weight: 700;
padding: 10px 25px;
transition: all 0.2s ease;
}
.btn-nano:hover {
background-color: var(--nano-black);
color: var(--nano-yellow);
transform: translateY(-2px);
}
.card-nano {
background: var(--nano-white);
border: 2px solid var(--nano-black);
border-radius: var(--nano-radius);
box-shadow: 8px 8px 0px var(--nano-black);
overflow: hidden;
}
.form-control-nano {
border: 2px solid var(--nano-black);
border-radius: 15px;
padding: 12px;
font-weight: 500;
}
.form-control-nano:focus {
box-shadow: none;
border-color: var(--nano-yellow);
background-color: #fffde7;
}
.badge-nano {
background: var(--nano-yellow);
color: var(--nano-black);
border: 1px solid var(--nano-black);
border-radius: 10px;
padding: 5px 12px;
font-weight: 600;
}
.editor-preview-container {
background: #eee;
border: 2px solid var(--nano-black);
border-radius: var(--nano-radius);
overflow: hidden;
position: relative;
}
.canvas-container {
margin: 0 auto;
}
.sticker-item {
cursor: pointer;
transition: transform 0.2s;
border: 2px solid transparent;
border-radius: 10px;
padding: 5px;
font-size: 2rem;
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
}
.sticker-item:hover {
transform: scale(1.1);
border-color: var(--nano-yellow);
}
.tool-btn {
border: 2px solid var(--nano-black);
border-radius: 12px;
padding: 8px;
background: white;
transition: all 0.2s;
}
.tool-btn:hover, .tool-btn.active {
background: var(--nano-yellow);
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg sticky-top">
<div class="container">
<a class="navbar-brand fw-bold" href="/">
<i class="fas fa-banana text-warning me-2"></i><?php echo htmlspecialchars($project_name); ?>
</a>
<div class="ms-auto d-flex align-items-center">
<a href="#history" class="btn btn-nano btn-sm">История</a>
</div>
</div>
</nav>
<main class="container py-5">
<!-- Hero -->
<div class="text-center mb-5">
<h1 class="display-4 fw-black mb-3" style="font-family: 'Montserrat', sans-serif;">NANO GENERATOR 🍌</h1>
<p class="lead text-dark fw-medium">Создавай крутые ИИ фото и качественные сток-видео.</p>
</div>
<!-- Generator Section -->
<section class="row justify-content-center mb-5">
<div class="col-lg-12">
<div class="card-nano p-4">
<form id="generation-form">
<div class="row g-3">
<div class="col-md-2">
<label class="form-label small fw-bold">ТИП КОНТЕНТА</label>
<select class="form-select form-control-nano" id="media-type" name="type">
<option value="photo">ФОТО (ИИ)</option>
<option value="video">ВИДЕО (STOCK)</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label small fw-bold">СТИЛЬ</label>
<select class="form-select form-control-nano" id="style" name="style">
<option value="">ОРИГИНАЛ</option>
<option value="anime">АНИМЕ</option>
<option value="cyberpunk">КИБЕРПАНК</option>
<option value="3d-render">3D SOFT</option>
<option value="minimalism">МИНИМАЛИЗМ</option>
<option value="cinematic">КИНО</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">ТВОЙ ЗАПРОС</label>
<input type="text" class="form-control form-control-nano" id="prompt" name="prompt" placeholder="Что нарисуем или найдем?.." required>
</div>
<div class="col-md-2 d-flex align-items-end">
<button type="submit" class="btn btn-nano w-100" id="generate-btn">
СОЗДАТЬ
</button>
</div>
<div class="col-md-2 d-flex align-items-end">
<input type="file" id="upload-image" accept="image/*" class="d-none">
<button type="button" class="btn btn-outline-dark w-100 rounded-pill py-2" onclick="document.getElementById('upload-image').click()">
<i class="fas fa-upload me-1"></i> СВОЁ ФОТО
</button>
</div>
</div>
</form>
<div id="result-preview" class="mt-4 position-relative" style="min-height: 400px; background: #fafafa; border: 2px dashed #ccc; border-radius: 20px; display: flex; align-items: center; justify-content: center;">
<div class="text-center text-muted" id="placeholder-text">
<i class="fas fa-image fa-3x mb-3"></i>
<p class="fw-bold">ТУТ БУДЕТ МАГИЯ</p>
</div>
<div class="loading-spinner text-center d-none" id="loading-state">
<div class="spinner-border text-dark" role="status"></div>
<p class="mt-3 fw-bold">ГОТОВИМ БАНАНЫ...</p>
</div>
<div id="content-container" class="d-none w-100 h-100 p-2 text-center"></div>
<div id="info-overlay" class="position-absolute top-0 start-0 p-3 d-none">
<span class="badge-nano" id="provider-badge"></span>
</div>
<div id="action-buttons" class="position-absolute bottom-0 end-0 p-3 d-none d-flex gap-2">
<button class="btn btn-nano btn-sm" id="edit-btn">
<i class="fas fa-wand-magic-sparkles"></i> EDIT
</button>
<button class="btn btn-dark btn-sm rounded-pill" id="download-btn">
<i class="fas fa-download"></i>
</button>
</div>
</div>
</div>
<div id="status-message" class="mt-3 alert alert-warning border-2 border-dark d-none" role="alert"></div>
</div>
</section>
<!-- History -->
<section id="history" class="py-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="fw-black mb-0" style="font-family: 'Montserrat', sans-serif;">ГАЛЕРЕЯ 📂</h2>
<button class="btn btn-outline-dark btn-sm rounded-pill" onclick="location.reload()"><i class="fas fa-sync"></i> Обновить</button>
</div>
<div class="row g-4" id="history-grid">
<?php
try {
$stmt = db()->query("SELECT * FROM media_history ORDER BY created_at DESC LIMIT 12");
$history = $stmt->fetchAll();
foreach ($history as $item):
?>
<div class="col-md-4 col-sm-6">
<div class="card-nano h-100 history-card">
<?php if ($item['type'] === 'photo'): ?>
<img src="<?php echo htmlspecialchars($item['result_url']); ?>" class="w-100" style="height: 250px; object-fit: cover; border-bottom: 2px solid #000;">
<?php else: ?>
<div class="bg-dark" style="height: 250px; border-bottom: 2px solid #000; position: relative;">
<video class="w-100 h-100" style="object-fit: cover;" muted onmouseover="this.play()" onmouseout="this.pause()">
<source src="<?php echo htmlspecialchars($item['result_url']); ?>" type="video/mp4">
</video>
<div class="position-absolute top-50 start-50 translate-middle pointer-events-none">
<i class="fas fa-play text-white fa-2x opacity-50"></i>
</div>
</div>
<?php endif; ?>
<div class="p-3">
<p class="small fw-bold text-truncate mb-2 history-prompt"><?php echo htmlspecialchars($item['prompt']); ?></p>
<div class="d-flex justify-content-between align-items-center">
<span class="badge-nano py-1 px-2" style="font-size: 0.7rem;"><?php echo strtoupper($item['type']); ?></span>
<div class="d-flex gap-2">
<?php if ($item['type'] === 'photo'): ?>
<button class="btn btn-sm btn-outline-dark rounded-pill history-edit-btn" data-url="<?php echo htmlspecialchars($item['result_url']); ?>">
<i class="fas fa-magic"></i>
</button>
<?php endif; ?>
<a href="<?php echo htmlspecialchars($item['result_url']); ?>" download class="btn btn-sm btn-dark rounded-pill">
<i class="fas fa-download"></i>
</a>
</div>
</div>
</div>
</div>
</div>
<?php endforeach; } catch (Exception $e) {} ?>
</div>
</section>
</main>
<!-- Nano Editor Modal -->
<div class="modal fade" id="editorModal" data-bs-backdrop="static" tabindex="-1">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content card-nano border-0">
<div class="modal-header border-bottom border-2 border-dark bg-yellow-soft">
<h5 class="modal-title fw-black"><i class="fas fa-banana text-warning"></i> NANO EDITOR AI PRO</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body p-0">
<div class="row g-0">
<div class="col-lg-8 bg-light p-3 border-end border-2 border-dark d-flex flex-column">
<div class="editor-preview-container d-flex align-items-center justify-content-center flex-grow-1" style="min-height: 500px;">
<div id="fabric-wrapper">
<canvas id="editor-canvas"></canvas>
</div>
<img id="cropper-image" src="" style="display: none; max-width: 100%;">
<div id="editor-loading" class="position-absolute top-0 start-0 w-100 h-100 d-none flex-column align-items-center justify-content-center" style="background: rgba(255,255,255,0.8); z-index: 10;">
<div class="spinner-border text-dark"></div>
<span class="fw-bold mt-2">МАГИЯ В ПРОЦЕССЕ...</span>
</div>
</div>
<!-- Transform Controls (Quick Access) -->
<div id="transform-bar" class="mt-3 p-2 bg-white rounded-3 border border-2 border-dark d-flex justify-content-center gap-3 d-none">
<button class="btn btn-sm tool-btn" onclick="rotateLeft()"><i class="fas fa-undo"></i> -90°</button>
<button class="btn btn-sm tool-btn" onclick="rotateRight()"><i class="fas fa-redo"></i> +90°</button>
<button class="btn btn-sm tool-btn" onclick="flipH()"><i class="fas fa-arrows-alt-h"></i> Flip H</button>
<button class="btn btn-sm tool-btn" onclick="flipV()"><i class="fas fa-arrows-alt-v"></i> Flip V</button>
<button class="btn btn-sm btn-dark rounded-pill px-3" id="apply-crop-btn">APPLY CROP</button>
</div>
</div>
<div class="col-lg-4 p-4 overflow-auto" style="max-height: 80vh;">
<ul class="nav nav-tabs border-0 mb-3 flex-nowrap overflow-auto" id="editor-tabs">
<li class="nav-item"><button class="nav-link active fw-bold text-dark border-0 small" data-bs-toggle="tab" data-bs-target="#filters-panel">ФИЛЬТРЫ</button></li>
<li class="nav-item"><button class="nav-link fw-bold text-dark border-0 small" data-bs-toggle="tab" data-bs-target="#transform-panel">ТРАНСФОРМ</button></li>
<li class="nav-item"><button class="nav-link fw-bold text-dark border-0 small" data-bs-toggle="tab" data-bs-target="#decor-panel">ДЕКОР</button></li>
<li class="nav-item"><button class="nav-link fw-bold text-dark border-0 small" data-bs-toggle="tab" data-bs-target="#ai-magic-panel">AI MAGIC</button></li>
</ul>
<div class="tab-content pt-2">
<!-- Filters -->
<div class="tab-pane fade show active" id="filters-panel">
<?php
$filters = [
'brightness' => ['label' => 'Яркость', 'min' => 0, 'max' => 200, 'val' => 100],
'contrast' => ['label' => 'Контраст', 'min' => 0, 'max' => 200, 'val' => 100],
'saturate' => ['label' => 'Насыщенность', 'min' => 0, 'max' => 200, 'val' => 100],
'blur' => ['label' => 'Размытие', 'min' => 0, 'max' => 20, 'val' => 0],
'hue-rotate' => ['label' => 'Оттенок', 'min' => 0, 'max' => 360, 'val' => 0],
'sepia' => ['label' => 'Сепия', 'min' => 0, 'max' => 100, 'val' => 0],
'grayscale' => ['label' => 'Ч/Б', 'min' => 0, 'max' => 100, 'val' => 0],
'vignette' => ['label' => 'Виньетка', 'min' => 0, 'max' => 100, 'val' => 0],
'noise' => ['label' => 'Шум', 'min' => 0, 'max' => 100, 'val' => 0]
];
foreach ($filters as $id => $f): ?>
<div class="mb-3">
<div class="d-flex justify-content-between">
<label class="form-label small fw-bold"><?php echo $f['label']; ?></label>
<span class="small fw-bold text-muted" id="val-<?php echo $id; ?>"><?php echo $f['val']; ?></span>
</div>
<input type="range" class="form-range filter-range" data-filter="<?php echo $id; ?>" min="<?php echo $f['min']; ?>" max="<?php echo $f['max']; ?>" value="<?php echo $f['val']; ?>">
</div>
<?php endforeach; ?>
</div>
<!-- Transform -->
<div class="tab-pane fade" id="transform-panel">
<div class="d-grid gap-3">
<button class="btn btn-nano w-100" id="start-crop-btn">
<i class="fas fa-crop-alt"></i> ИНСТРУМЕНТ ОБРЕЗКИ
</button>
<div class="row g-2">
<div class="col-6">
<button class="btn btn-outline-dark w-100 py-3" onclick="rotateLeft()">
<i class="fas fa-undo d-block mb-1"></i> -90°
</button>
</div>
<div class="col-6">
<button class="btn btn-outline-dark w-100 py-3" onclick="rotateRight()">
<i class="fas fa-redo d-block mb-1"></i> +90°
</button>
</div>
<div class="col-6">
<button class="btn btn-outline-dark w-100 py-3" onclick="flipH()">
<i class="fas fa-arrows-alt-h d-block mb-1"></i> Flip H
</button>
</div>
<div class="col-6">
<button class="btn btn-outline-dark w-100 py-3" onclick="flipV()">
<i class="fas fa-arrows-alt-v d-block mb-1"></i> Flip V
</button>
</div>
</div>
</div>
</div>
<!-- Decor -->
<div class="tab-pane fade" id="decor-panel">
<div class="mb-4">
<label class="form-label small fw-bold">РИСОВАНИЕ КИСТЬЮ</label>
<div class="d-flex gap-2 mb-2">
<button class="btn tool-btn flex-grow-1" id="brush-toggle"><i class="fas fa-paint-brush"></i> Кисть</button>
<input type="color" class="form-control form-control-color border-2 border-dark" id="brush-color" value="#FFDE59" title="Цвет кисти">
</div>
<input type="range" class="form-range" id="brush-size" min="1" max="100" value="10">
</div>
<div class="mb-4">
<label class="form-label small fw-bold">ТЕКСТ</label>
<div class="input-group mb-2">
<input type="text" id="text-input" class="form-control form-control-nano" placeholder="Ваш текст...">
<button class="btn btn-dark" id="add-text-btn"><i class="fas fa-plus"></i></button>
</div>
<div class="d-flex gap-2">
<select id="font-family" class="form-select form-control-nano py-1">
<option value="Montserrat">Montserrat</option>
<option value="Inter">Inter</option>
<option value="Arial">Arial</option>
<option value="Courier New">Monospace</option>
</select>
<input type="color" class="form-control form-control-color border-2 border-dark" id="text-color" value="#000000">
</div>
</div>
<div class="mb-4">
<label class="form-label small fw-bold">СЛОИ (OBJECTS)</label>
<div class="d-flex gap-2">
<button class="btn btn-outline-dark btn-sm flex-grow-1" onclick="bringToFront()"><i class="fas fa-layer-group"></i> Вперёд</button>
<button class="btn btn-outline-dark btn-sm flex-grow-1" onclick="sendToBack()"><i class="fas fa-level-down-alt"></i> Назад</button>
<button class="btn btn-outline-danger btn-sm" onclick="deleteObject()"><i class="fas fa-trash"></i></button>
</div>
</div>
<div>
<label class="form-label small fw-bold">СТИКЕРЫ 🍌✨</label>
<div class="d-flex flex-wrap gap-2 p-2 bg-white rounded-3 border border-2 border-dark">
<div class="sticker-item" data-sticker="🍌">🍌</div>
<div class="sticker-item" data-sticker="🐒">🐒</div>
<div class="sticker-item" data-sticker="🌴">🌴</div>
<div class="sticker-item" data-sticker="🕶️">🕶️</div>
<div class="sticker-item" data-sticker="🔥">🔥</div>
<div class="sticker-item" data-sticker="❤️">❤️</div>
<div class="sticker-item" data-sticker="✨">✨</div>
<div class="sticker-item" data-sticker="🚀">🚀</div>
<div class="sticker-item" data-sticker="🎨">🎨</div>
<div class="sticker-item" data-sticker="⭐">⭐</div>
</div>
</div>
</div>
<!-- AI Magic -->
<div class="tab-pane fade" id="ai-magic-panel">
<div class="p-3 bg-yellow-soft rounded-4 border border-2 border-dark mb-3">
<label class="form-label small fw-bold">ЧТО ДОРИСОВАТЬ?</label>
<textarea class="form-control form-control-nano mb-2" id="ai-edit-prompt" rows="3" placeholder="Напр: Добавь солнечные очки..."></textarea>
<button class="btn btn-nano w-100" id="apply-ai-magic">ПРИМЕНИТЬ МАГИЮ</button>
</div>
<div class="d-grid gap-2">
<button class="btn btn-outline-dark btn-sm rounded-pill" id="remove-bg-btn"><i class="fas fa-user-slash me-1"></i> Удалить фон</button>
<button class="btn btn-outline-dark btn-sm rounded-pill" id="upscale-btn"><i class="fas fa-expand-arrows-alt me-1"></i> Улучшить (HD)</button>
</div>
</div>
</div>
<hr class="border-2 border-dark">
<div class="d-grid gap-2">
<button class="btn btn-outline-danger btn-sm rounded-pill" id="reset-editor"><i class="fas fa-undo"></i> СБРОСИТЬ ВСЁ</button>
<button class="btn btn-nano w-100 py-3 mt-2" id="save-edited-btn">
<i class="fas fa-download me-2"></i> СКАЧАТЬ PNG
</button>
<button class="btn btn-dark w-100 py-2 rounded-pill" id="save-to-gallery-btn">
<i class="fas fa-cloud-upload-alt me-2"></i> СОХРАНИТЬ В ГАЛЕРЕЮ
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer class="py-5 text-center">
<p class="small fw-bold">&copy; <?php echo date('Y'); ?> <?php echo htmlspecialchars($project_name); ?> 🍌</p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
</body>
</html>