121 lines
6.3 KiB
Vue
121 lines
6.3 KiB
Vue
<script setup>
|
||
import { Head } from '@inertiajs/vue3';
|
||
import AdminLayout from '../../Layouts/AdminLayout.vue';
|
||
import NewsForm from './Components/NewsForm.vue';
|
||
import StatCards from './Components/StatCards.vue';
|
||
|
||
const props = defineProps({
|
||
site: { type: Object, required: true },
|
||
auth: { type: Object, required: true },
|
||
urls: { type: Object, required: true },
|
||
flash: { type: Object, default: () => ({}) },
|
||
newsItems: { type: Array, default: () => [] },
|
||
newsStats: { type: Object, required: true },
|
||
feedPreview: { type: String, required: true },
|
||
feedUrl: { type: String, required: true },
|
||
storeUrl: { type: String, required: true },
|
||
old: { type: Object, default: () => ({}) },
|
||
});
|
||
|
||
const stats = [
|
||
{ label: 'Всего', value: props.newsStats.total },
|
||
{ label: 'Опубликовано', value: props.newsStats.published },
|
||
{ label: 'Черновики', value: props.newsStats.draft },
|
||
];
|
||
|
||
const bodyHint = 'Поддерживаются WoW-коды цветов |cFF...|r, иконки |T...|t, переносы строк и обычный текст.';
|
||
const createLabels = {
|
||
title: 'Название в админке',
|
||
published: 'Сразу публиковать эту запись',
|
||
body: 'Текст для клиента',
|
||
bodyHint,
|
||
submit: 'Добавить запись',
|
||
delete: 'Удалить запись',
|
||
deleteConfirm: 'Удалить эту запись из фида?',
|
||
};
|
||
const editLabels = {
|
||
...createLabels,
|
||
title: 'Название',
|
||
published: 'Показывать в публичном фиде',
|
||
body: 'Текст блока',
|
||
submit: 'Сохранить запись',
|
||
};
|
||
|
||
const example = `|TInterface\\ICONS\\INV_Misc_QuestionMark:25:25:0:-5|t |cFF00D1FFКлассический Азерот|r
|
||
|cFFA6D8FF- Клиент 1.12.1 (build 5875)|r
|
||
|cFFA6D8FF- Собери отряд и отправляйся в приключение|r`;
|
||
</script>
|
||
|
||
<template>
|
||
<Head><title>Новости WoW — {{ site.name }}</title></Head>
|
||
|
||
<AdminLayout :site="site" :auth="auth" :urls="urls" :flash="flash" current="login-news">
|
||
<section class="admin-hero wrap">
|
||
<div>
|
||
<span class="eyebrow">Клиент 1.12.1</span>
|
||
<h1 class="h-display">Новости логин-экрана WoW</h1>
|
||
<p class="lead">Raw-текст с игровой разметкой и готовый публичный SERVERALERT-фид.</p>
|
||
</div>
|
||
<div class="admin-hero__badge"><small>Опубликовано</small><strong>{{ newsStats.published }}</strong></div>
|
||
</section>
|
||
|
||
<div class="admin-page wrap">
|
||
<section class="admin-section">
|
||
<StatCards :items="stats" />
|
||
<div class="admin-split">
|
||
<article class="portal-card admin-panel corners">
|
||
<span class="admin-kicker">Публичная ссылка</span>
|
||
<h2 class="h-serif">Фид для клиента</h2>
|
||
<p>Ссылка доступна без авторизации и всегда возвращает plain text.</p>
|
||
<a class="btn btn-primary" :href="feedUrl" target="_blank" rel="noreferrer">Открыть фид</a>
|
||
<code class="admin-code-block">{{ feedUrl }}</code>
|
||
</article>
|
||
<article class="portal-card admin-panel">
|
||
<span class="admin-kicker">Итоговый ответ</span>
|
||
<h2 class="h-serif">Превью сервера</h2>
|
||
<pre class="admin-feed-preview">{{ feedPreview }}</pre>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="admin-section">
|
||
<div class="admin-split">
|
||
<article class="portal-card admin-panel corners">
|
||
<span class="admin-kicker">Новая запись</span>
|
||
<h2 class="h-serif">Добавить новость</h2>
|
||
<NewsForm :action="storeUrl" :labels="createLabels" :initial="old" />
|
||
</article>
|
||
<article class="portal-card admin-panel">
|
||
<span class="admin-kicker">Шаблон</span>
|
||
<h2 class="h-serif">Пример WoW-блока</h2>
|
||
<p>Префикс SERVERALERT добавляется автоматически.</p>
|
||
<pre class="admin-feed-preview">{{ example }}</pre>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="admin-section">
|
||
<div class="admin-section__head">
|
||
<div><span class="eyebrow">Текущие записи</span><h2 class="h-serif">Редактирование и публикация</h2></div>
|
||
<p>Опубликованные записи попадают в фид по порядку sort_order.</p>
|
||
</div>
|
||
<div v-if="newsItems.length" class="admin-editor-list">
|
||
<details v-for="item in newsItems" :key="item.id" class="portal-card admin-editor">
|
||
<summary>
|
||
<span>
|
||
<strong>{{ item.title }}</strong>
|
||
<small>Порядок: {{ item.sort_order }}<template v-if="item.updated_by"> · {{ item.updated_by }}</template><template v-if="item.updated_at"> · {{ item.updated_at }}</template></small>
|
||
</span>
|
||
<span :class="['admin-pill', { muted: !item.is_published }]">{{ item.is_published ? 'Опубликовано' : 'Черновик' }}</span>
|
||
</summary>
|
||
<div class="admin-editor__body">
|
||
<NewsForm :item="item" :action="item.update_url" :destroy-url="item.destroy_url" :labels="editLabels" />
|
||
</div>
|
||
</details>
|
||
</div>
|
||
<article v-else class="portal-card admin-empty"><p>Записей пока нет.</p></article>
|
||
</section>
|
||
</div>
|
||
</AdminLayout>
|
||
</template>
|