fix: editor ui tweaks (resize textarea, gallery, filters)
This commit is contained in:
@@ -2,12 +2,7 @@
|
|||||||
<!-- Sidebar Filters -->
|
<!-- Sidebar Filters -->
|
||||||
<aside class="w-full xl:w-72 flex-shrink-0">
|
<aside class="w-full xl:w-72 flex-shrink-0">
|
||||||
<div class="card p-4 sticky top-6">
|
<div class="card p-4 sticky top-6">
|
||||||
<form id="filter-form" hx-get="/editor" hx-target="#content-area" hx-push-url="true" hx-trigger="submit, change delay:300ms">
|
<form id="filter-form" hx-get="/editor" hx-target="#content-area" hx-push-url="true" hx-trigger="submit">
|
||||||
{% for item in preserved_query %}
|
|
||||||
{% if item.key != "per_page" and item.key != "sort" and item.key != "editorial_status" %}
|
|
||||||
<input type="hidden" name="{{ item.key }}" value="{{ item.value }}">
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
<input type="hidden" name="editorial_status" value="{{ status_filter }}">
|
<input type="hidden" name="editorial_status" value="{{ status_filter }}">
|
||||||
|
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
@@ -53,7 +48,7 @@
|
|||||||
<div class="bg-app-bg border border-app-border rounded-lg p-2 max-h-48 overflow-y-auto space-y-1">
|
<div class="bg-app-bg border border-app-border rounded-lg p-2 max-h-48 overflow-y-auto space-y-1">
|
||||||
{% for item in facets.sources %}
|
{% for item in facets.sources %}
|
||||||
<label class="flex items-center gap-2 px-2 py-1 hover:bg-app-surfaceHover rounded cursor-pointer transition-colors group">
|
<label class="flex items-center gap-2 px-2 py-1 hover:bg-app-surfaceHover rounded cursor-pointer transition-colors group">
|
||||||
<input type="checkbox" name="source_id" value="{{ item.id }}" class="checkbox" {% if item.id|string in source_ids %}checked{% endif %} />
|
<input type="checkbox" name="source_id" value="{{ item.id }}" class="checkbox" {% if item.id in source_ids %}checked{% endif %} />
|
||||||
<span class="text-sm text-app-textMain flex-1 truncate group-hover:text-white" title="{{ item.name }}">{{ item.name }}</span>
|
<span class="text-sm text-app-textMain flex-1 truncate group-hover:text-white" title="{{ item.name }}">{{ item.name }}</span>
|
||||||
<span class="badge badge-neutral bg-transparent border-none">{{ item.count }}</span>
|
<span class="badge badge-neutral bg-transparent border-none">{{ item.count }}</span>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -65,9 +65,69 @@
|
|||||||
<!-- Right: Edit Area & Spoilers -->
|
<!-- Right: Edit Area & Spoilers -->
|
||||||
<div class="flex-1 flex flex-col min-w-0 p-5">
|
<div class="flex-1 flex flex-col min-w-0 p-5">
|
||||||
|
|
||||||
<!-- Edit Area -->
|
<!-- Photos (Moved above text, larger preview, alpine modal gallery) -->
|
||||||
|
{% if p.media_items %}
|
||||||
|
{% set photo_urls = [] %}
|
||||||
|
{% for m in p.media_items %}
|
||||||
|
{% if m.type == 'photo' and m.url %}
|
||||||
|
{% set _ = photo_urls.append(m.url) %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<div class="mb-4" x-data="{ galleryOpen: false, activeIdx: 0, images: {{ photo_urls | tojson | forceescape }} }" @keydown.escape.window="galleryOpen = false">
|
||||||
|
<div class="flex flex-wrap gap-2">
|
||||||
|
{% for m in p.media_items %}
|
||||||
|
{% if m.type == "photo" and m.url %}
|
||||||
|
{% set photo_idx = photo_urls.index(m.url) %}
|
||||||
|
<div @click="activeIdx = {{ photo_idx }}; galleryOpen = true" class="block w-32 h-32 rounded-lg overflow-hidden border border-app-border hover:border-app-primary transition-colors cursor-pointer">
|
||||||
|
<img src="{{ m.url }}" class="w-full h-full object-cover" loading="lazy">
|
||||||
|
</div>
|
||||||
|
{% elif m.url %}
|
||||||
|
<a href="{{ m.url }}" target="_blank" class="w-32 h-32 rounded-lg bg-app-bg border border-app-border flex items-center justify-center hover:text-app-primary transition-colors text-app-textMuted">
|
||||||
|
<i data-lucide="play-circle" class="w-10 h-10"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Alpine Modal Gallery -->
|
||||||
|
<template x-if="galleryOpen">
|
||||||
|
<div class="fixed inset-0 z-[100] flex items-center justify-center bg-black/90 backdrop-blur-sm p-4">
|
||||||
|
<!-- Close button -->
|
||||||
|
<button @click.prevent="galleryOpen = false" type="button" class="absolute top-4 right-4 text-white hover:text-app-primary transition-colors p-2">
|
||||||
|
<i data-lucide="x" class="w-8 h-8"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Previous -->
|
||||||
|
<button x-show="images.length > 1" @click.prevent="activeIdx = (activeIdx === 0) ? images.length - 1 : activeIdx - 1" type="button" class="absolute left-4 top-1/2 -translate-y-1/2 text-white hover:text-app-primary p-2">
|
||||||
|
<i data-lucide="chevron-left" class="w-10 h-10"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Image -->
|
||||||
|
<img :src="images[activeIdx]" class="max-w-full max-h-[90vh] object-contain rounded-lg shadow-2xl">
|
||||||
|
|
||||||
|
<!-- Next -->
|
||||||
|
<button x-show="images.length > 1" @click.prevent="activeIdx = (activeIdx === images.length - 1) ? 0 : activeIdx + 1" type="button" class="absolute right-4 top-1/2 -translate-y-1/2 text-white hover:text-app-primary p-2">
|
||||||
|
<i data-lucide="chevron-right" class="w-10 h-10"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Counter -->
|
||||||
|
<div x-show="images.length > 1" class="absolute bottom-4 left-1/2 -translate-x-1/2 text-white font-mono text-sm bg-black/50 px-3 py-1 rounded-full">
|
||||||
|
<span x-text="activeIdx + 1"></span> / <span x-text="images.length"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<!-- Edit Area (Auto resize textarea) -->
|
||||||
<label class="block text-xs font-bold text-app-textMuted mb-2 uppercase tracking-wider">Финальный текст</label>
|
<label class="block text-xs font-bold text-app-textMuted mb-2 uppercase tracking-wider">Финальный текст</label>
|
||||||
<textarea name="final_text" class="textarea w-full font-sans text-sm leading-relaxed resize-y p-3 bg-app-bg border border-app-border min-h-[150px]" placeholder="Напишите идеальный пост здесь...">{{ p.review_text }}</textarea>
|
<textarea name="final_text"
|
||||||
|
x-data="{ resize() { $el.style.height = 'auto'; $el.style.height = $el.scrollHeight + 'px' } }"
|
||||||
|
x-init="resize()"
|
||||||
|
@input="resize()"
|
||||||
|
class="textarea w-full font-sans text-sm leading-relaxed resize-none overflow-hidden p-3 bg-app-bg border border-app-border min-h-[150px]"
|
||||||
|
placeholder="Напишите идеальный пост здесь...">{{ p.review_text }}</textarea>
|
||||||
|
|
||||||
<!-- Meta Inputs row -->
|
<!-- Meta Inputs row -->
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
|
||||||
@@ -93,22 +153,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if p.media_items %}
|
|
||||||
<div class="mt-4 flex flex-wrap gap-2">
|
|
||||||
{% for m in p.media_items %}
|
|
||||||
{% if m.type == "photo" and m.url %}
|
|
||||||
<a href="{{ m.url }}" target="_blank" class="block w-16 h-16 rounded-lg overflow-hidden border border-app-border hover:border-app-primary transition-colors">
|
|
||||||
<img src="{{ m.url }}" class="w-full h-full object-cover" loading="lazy">
|
|
||||||
</a>
|
|
||||||
{% elif m.url %}
|
|
||||||
<a href="{{ m.url }}" target="_blank" class="w-16 h-16 rounded-lg bg-app-bg border border-app-border flex items-center justify-center hover:text-app-primary transition-colors text-app-textMuted">
|
|
||||||
<i data-lucide="play-circle" class="w-6 h-6"></i>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- Original / AI Spoiler -->
|
<!-- Original / AI Spoiler -->
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<details class="group/details">
|
<details class="group/details">
|
||||||
@@ -141,7 +185,7 @@
|
|||||||
<div class="mt-5 pt-4 border-t border-app-border flex flex-wrap items-center justify-between gap-3">
|
<div class="mt-5 pt-4 border-t border-app-border flex flex-wrap items-center justify-between gap-3">
|
||||||
<!-- Delete Button -->
|
<!-- Delete Button -->
|
||||||
<div>
|
<div>
|
||||||
{% if p.editorial_status in ['pending', 'ai_review', 'reviewing'] %}
|
{% if p.editorial_status != 'rejected' %}
|
||||||
<button class="btn btn-ghost btn-sm text-app-error hover:bg-app-errorBg hover:text-app-error" type="button"
|
<button class="btn btn-ghost btn-sm text-app-error hover:bg-app-errorBg hover:text-app-error" type="button"
|
||||||
hx-post="/editor/{{ p.id }}/reject" hx-target="#post-container-{{ p.id }}" hx-swap="outerHTML"
|
hx-post="/editor/{{ p.id }}/reject" hx-target="#post-container-{{ p.id }}" hx-swap="outerHTML"
|
||||||
hx-vals='{"csrf_token": "{{ user.csrf_token }}"}'
|
hx-vals='{"csrf_token": "{{ user.csrf_token }}"}'
|
||||||
|
|||||||
Reference in New Issue
Block a user