Fix admin light theme media controls
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
APP_ENV=production
|
||||
APP_SECRET_KEY=change-me
|
||||
ADMIN_SITE_TITLE=Редакторская
|
||||
ADMIN_APP_TITLE=Редакторская
|
||||
ADMIN_BOOTSTRAP_LOGIN=admin
|
||||
ADMIN_BOOTSTRAP_PASSWORD=change-me-long-password
|
||||
|
||||
@@ -45,7 +45,7 @@ BASE_DIR = Path(__file__).resolve().parent
|
||||
PROJECT_ROOT = BASE_DIR.parents[1]
|
||||
FAVICON_PATH = PROJECT_ROOT / "favi.png"
|
||||
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
|
||||
app = FastAPI(title=settings.display_admin_title)
|
||||
app = FastAPI(title=settings.display_site_title)
|
||||
LOCAL_TZ = ZoneInfo("Asia/Yekaterinburg")
|
||||
MODEL_CACHE: dict[str, Any] = {"key": "", "at": 0.0, "models": []}
|
||||
UPLOAD_ROOT = Path("uploads").resolve()
|
||||
@@ -444,7 +444,13 @@ def require_csrf(user: dict, csrf_token: str) -> None:
|
||||
|
||||
|
||||
def base_context(request: Request, user: dict | None, **extra: Any) -> dict[str, Any]:
|
||||
ctx = {"request": request, "user": user, "app_env": settings.app_env, "app_title": settings.display_admin_title}
|
||||
ctx = {
|
||||
"request": request,
|
||||
"user": user,
|
||||
"app_env": settings.app_env,
|
||||
"app_title": settings.display_admin_title,
|
||||
"site_title": settings.display_site_title,
|
||||
}
|
||||
ctx.update(extra)
|
||||
return ctx
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
class Settings(BaseSettings):
|
||||
app_env: str = "production"
|
||||
app_secret_key: str = "change-me"
|
||||
admin_site_title: str = ""
|
||||
admin_app_title: str = "Редакторская"
|
||||
admin_bootstrap_login: str = "admin"
|
||||
admin_bootstrap_password: str = ""
|
||||
@@ -42,6 +43,10 @@ class Settings(BaseSettings):
|
||||
def display_admin_title(self) -> str:
|
||||
return self.admin_app_title.strip() or "Редакторская"
|
||||
|
||||
@property
|
||||
def display_site_title(self) -> str:
|
||||
return self.admin_site_title.strip() or "Редакторская"
|
||||
|
||||
@property
|
||||
def vk_storage_owner_id(self) -> int:
|
||||
return -abs(int(self.vk_storage_group_id))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/png" href="/favi.png">
|
||||
<title>{{ title or app_title or "Редакторская" }}</title>
|
||||
<title>{{ title or site_title or "Редакторская" }}</title>
|
||||
|
||||
<!-- Fonts: Fira Sans (UI) & Fira Code (Data) -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
@@ -106,6 +106,10 @@
|
||||
:root:not(.dark) .hover\:bg-app-error:hover.hover\:text-white {
|
||||
color: #fff !important;
|
||||
}
|
||||
:root:not(.dark) .media-gallery-layer .text-white,
|
||||
:root:not(.dark) .media-gallery-layer .hover\:text-app-primary:hover {
|
||||
color: #fff !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style type="text/tailwindcss">
|
||||
|
||||
@@ -71,31 +71,31 @@
|
||||
{% for m in p.media_items %}
|
||||
{% if m.type == "photo" and m.url %}
|
||||
{% set photo_idx = photo_urls.index(m.url) %}
|
||||
<label class="relative block w-32 h-32 rounded-lg overflow-hidden border border-app-border hover:border-app-primary transition-colors cursor-pointer group/media">
|
||||
<input type="checkbox" name="delete_media_ids" value="{{ m.id }}" class="peer sr-only">
|
||||
<div class="relative block w-32 h-32 rounded-lg overflow-hidden border border-app-border hover:border-app-primary transition-colors group/media">
|
||||
<input id="media-delete-{{ p.id }}-{{ m.id }}" type="checkbox" name="delete_media_ids" value="{{ m.id }}" class="peer sr-only">
|
||||
<img @click.prevent="activeIdx = {{ photo_idx }}; galleryOpen = true" src="{{ m.url }}" class="w-full h-full object-cover peer-checked:opacity-35" loading="lazy">
|
||||
<span class="absolute top-1.5 right-1.5 w-7 h-7 rounded-full bg-black/70 text-white border border-white/20 flex items-center justify-center opacity-80 group-hover/media:opacity-100 peer-checked:bg-app-error peer-checked:text-white transition-colors" title="Не публиковать это медиа">
|
||||
<label for="media-delete-{{ p.id }}-{{ m.id }}" class="absolute top-1.5 right-1.5 z-10 w-7 h-7 rounded-full bg-black/70 text-white border border-white/20 flex items-center justify-center opacity-80 group-hover/media:opacity-100 peer-checked:bg-app-error peer-checked:text-white transition-colors cursor-pointer" title="Не публиковать это медиа">
|
||||
<i data-lucide="x" class="w-4 h-4"></i>
|
||||
</span>
|
||||
<span class="absolute inset-x-0 bottom-0 hidden peer-checked:block bg-app-error text-white text-[10px] font-bold text-center py-1">Не публиковать</span>
|
||||
</label>
|
||||
<span class="absolute inset-x-0 bottom-0 hidden peer-checked:block pointer-events-none bg-app-error text-white text-[10px] font-bold text-center py-1">Не публиковать</span>
|
||||
</div>
|
||||
{% elif m.url %}
|
||||
<label class="relative 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 cursor-pointer group/media">
|
||||
<input type="checkbox" name="delete_media_ids" value="{{ m.id }}" class="peer sr-only">
|
||||
<a href="{{ m.url }}" target="_blank" class="peer-checked:opacity-35">
|
||||
<div class="relative 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 group/media">
|
||||
<input id="media-delete-{{ p.id }}-{{ m.id }}" type="checkbox" name="delete_media_ids" value="{{ m.id }}" class="peer sr-only">
|
||||
<a href="{{ m.url }}" target="_blank" class="absolute inset-0 flex items-center justify-center peer-checked:opacity-35">
|
||||
<i data-lucide="play-circle" class="w-10 h-10"></i>
|
||||
</a>
|
||||
<span class="absolute top-1.5 right-1.5 w-7 h-7 rounded-full bg-black/70 text-white border border-white/20 flex items-center justify-center opacity-80 group-hover/media:opacity-100 peer-checked:bg-app-error peer-checked:text-white transition-colors" title="Не публиковать это медиа">
|
||||
<label for="media-delete-{{ p.id }}-{{ m.id }}" class="absolute top-1.5 right-1.5 z-10 w-7 h-7 rounded-full bg-black/70 text-white border border-white/20 flex items-center justify-center opacity-80 group-hover/media:opacity-100 peer-checked:bg-app-error peer-checked:text-white transition-colors cursor-pointer" title="Не публиковать это медиа">
|
||||
<i data-lucide="x" class="w-4 h-4"></i>
|
||||
</span>
|
||||
<span class="absolute inset-x-0 bottom-0 hidden peer-checked:block bg-app-error text-white text-[10px] font-bold text-center py-1">Не публиковать</span>
|
||||
</label>
|
||||
<span class="absolute inset-x-0 bottom-0 hidden peer-checked:block pointer-events-none bg-app-error text-white text-[10px] font-bold text-center py-1">Не публиковать</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- Alpine Modal Gallery -->
|
||||
<div x-show="galleryOpen" style="display: none;" x-transition.opacity class="fixed inset-0 z-[100] flex items-center justify-center bg-black/90 backdrop-blur-sm p-4">
|
||||
<div x-show="galleryOpen" style="display: none;" x-transition.opacity class="media-gallery-layer 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">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-8 h-8" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
|
||||
|
||||
@@ -352,12 +352,12 @@
|
||||
{% elif s.value_type == "text" %}
|
||||
<div class="w-full flex flex-col gap-3">
|
||||
{% if prompt_hints and s.key in prompt_hints %}
|
||||
<div class="bg-blue-900/20 border border-blue-500/30 text-blue-200 text-xs p-4 rounded-lg flex flex-col gap-2">
|
||||
<strong class="text-blue-400 font-bold flex items-center gap-2"><i data-lucide="info" class="w-4 h-4"></i> {{ prompt_hints[s.key].title }}</strong>
|
||||
<div class="bg-app-primary/10 border border-app-primary/30 text-app-textMain text-xs p-4 rounded-lg flex flex-col gap-2">
|
||||
<strong class="text-app-primary font-bold flex items-center gap-2"><i data-lucide="info" class="w-4 h-4"></i> {{ prompt_hints[s.key].title }}</strong>
|
||||
<div class="leading-relaxed">{{ prompt_hints[s.key].body }}</div>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-2 pt-2 border-t border-blue-500/20">
|
||||
<div><span class="font-bold text-white uppercase tracking-wider text-[10px]">Как безопасно менять:</span><br>{{ prompt_hints[s.key].safe }}</div>
|
||||
<div><span class="font-bold text-white uppercase tracking-wider text-[10px]">На вход:</span><br>{{ prompt_hints[s.key].input }}</div>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-2 pt-2 border-t border-app-primary/20">
|
||||
<div><span class="font-bold text-app-textMain uppercase tracking-wider text-[10px]">Как безопасно менять:</span><br>{{ prompt_hints[s.key].safe }}</div>
|
||||
<div><span class="font-bold text-app-textMain uppercase tracking-wider text-[10px]">На вход:</span><br>{{ prompt_hints[s.key].input }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user