157 lines
6.0 KiB
HTML
157 lines
6.0 KiB
HTML
|
|
{% extends "base.html" %}
|
||
|
|
|
||
|
|
{% block content %}
|
||
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 40px;">
|
||
|
|
<div>
|
||
|
|
<h2 class="section-title">{{ artwork.title }}</h2>
|
||
|
|
|
||
|
|
<div class="card mb-3">
|
||
|
|
<div class="card-header">◆ Превью</div>
|
||
|
|
<div class="card-body">
|
||
|
|
<div class="art-preview" style="height: 350px;">
|
||
|
|
<canvas id="settings-art" width="500" height="350"></canvas>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<div class="card-header">◼ Информация</div>
|
||
|
|
<div class="card-body">
|
||
|
|
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; text-align: center;">
|
||
|
|
<div>
|
||
|
|
<p class="text-muted" style="margin-bottom: 5px;">ID</p>
|
||
|
|
<p style="font-size: 24px; font-weight: 700; color: var(--red);">#{{ artwork.id }}</p>
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<p class="text-muted" style="margin-bottom: 5px;">Цена</p>
|
||
|
|
<p style="font-size: 24px; font-weight: 700;">{{ artwork.price }} ₽</p>
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<p class="text-muted" style="margin-bottom: 5px;">Создано</p>
|
||
|
|
<p style="font-size: 14px; font-weight: 500;">{{ artwork.created_at[:10] if artwork.created_at else 'Недавно' }}</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div>
|
||
|
|
<h3 class="section-title">Настройки</h3>
|
||
|
|
|
||
|
|
{% if settings %}
|
||
|
|
<div class="card mb-3">
|
||
|
|
<div class="card-header">▲ Текущее описание</div>
|
||
|
|
<div class="card-body">
|
||
|
|
{% if settings.error %}
|
||
|
|
<div class="info-block" style="background: var(--red);">
|
||
|
|
Ошибка: {{ settings.error }}
|
||
|
|
</div>
|
||
|
|
{% elif settings.description %}
|
||
|
|
<p style="font-size: 16px; line-height: 1.6;">{{ settings.description }}</p>
|
||
|
|
{% else %}
|
||
|
|
<pre style="background: var(--black); color: var(--cream); padding: 15px; overflow-x: auto; font-family: monospace; font-size: 13px; white-space: pre-wrap; word-wrap: break-word;">{{ settings }}</pre>
|
||
|
|
{% endif %}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
{% endif %}
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<div class="card-header">◉ Изменить описание</div>
|
||
|
|
<div class="card-body">
|
||
|
|
<form method="POST" action="{{ url_for('update_settings') }}">
|
||
|
|
<input type="hidden" name="artwork_id" value="{{ artwork.id }}">
|
||
|
|
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="description" class="form-label">Описание работы</label>
|
||
|
|
<textarea class="form-control" id="description" name="description"
|
||
|
|
rows="6" placeholder="Опишите концепцию вашей работы...">{% if settings and settings.description %}{{ settings.description }}{% endif %}</textarea>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div style="display: flex; gap: 15px;">
|
||
|
|
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||
|
|
<a href="{{ url_for('index') }}" class="btn btn-secondary">Назад</a>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<style>
|
||
|
|
@media (max-width: 900px) {
|
||
|
|
div[style*="grid-template-columns: 1fr 1fr"] {
|
||
|
|
grid-template-columns: 1fr !important;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
const artworkData = {{ artwork.data|tojson }};
|
||
|
|
|
||
|
|
function drawArt(canvas, artData) {
|
||
|
|
try {
|
||
|
|
const ctx = canvas.getContext('2d');
|
||
|
|
const shapes = JSON.parse(artData);
|
||
|
|
|
||
|
|
ctx.fillStyle = '#F5F0E6';
|
||
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||
|
|
|
||
|
|
const scale = canvas.width / 100;
|
||
|
|
|
||
|
|
shapes.forEach(shape => {
|
||
|
|
ctx.save();
|
||
|
|
ctx.fillStyle = shape.color;
|
||
|
|
ctx.strokeStyle = shape.color;
|
||
|
|
ctx.lineWidth = 4;
|
||
|
|
|
||
|
|
const x = shape.x * scale;
|
||
|
|
const y = shape.y * scale;
|
||
|
|
const w = shape.width * scale;
|
||
|
|
const h = shape.height * scale;
|
||
|
|
const angle = (shape.angle || 0) * Math.PI / 180;
|
||
|
|
|
||
|
|
const cx = x + w / 2;
|
||
|
|
const cy = y + h / 2;
|
||
|
|
|
||
|
|
if (shape.type === 'rectangle' || shape.type === 'rotated_rect') {
|
||
|
|
ctx.translate(cx, cy);
|
||
|
|
ctx.rotate(angle);
|
||
|
|
ctx.fillRect(-w/2, -h/2, w, h);
|
||
|
|
} else if (shape.type === 'circle') {
|
||
|
|
ctx.beginPath();
|
||
|
|
ctx.arc(cx, cy, Math.min(w, h) / 2, 0, Math.PI * 2);
|
||
|
|
ctx.fill();
|
||
|
|
} else if (shape.type === 'triangle') {
|
||
|
|
ctx.translate(cx, cy);
|
||
|
|
ctx.rotate(angle);
|
||
|
|
ctx.beginPath();
|
||
|
|
ctx.moveTo(0, -h/2);
|
||
|
|
ctx.lineTo(w/2, h/2);
|
||
|
|
ctx.lineTo(-w/2, h/2);
|
||
|
|
ctx.closePath();
|
||
|
|
ctx.fill();
|
||
|
|
} else if (shape.type === 'line') {
|
||
|
|
ctx.translate(cx, cy);
|
||
|
|
ctx.rotate(angle);
|
||
|
|
ctx.beginPath();
|
||
|
|
ctx.moveTo(-w/2, 0);
|
||
|
|
ctx.lineTo(w/2, 0);
|
||
|
|
ctx.lineWidth = h || 4;
|
||
|
|
ctx.stroke();
|
||
|
|
}
|
||
|
|
ctx.restore();
|
||
|
|
});
|
||
|
|
} catch (e) {
|
||
|
|
console.error('Error:', e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
document.addEventListener('DOMContentLoaded', function() {
|
||
|
|
const canvas = document.getElementById('settings-art');
|
||
|
|
if (canvas && artworkData) {
|
||
|
|
drawArt(canvas, artworkData);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
{% endblock %}
|