новый дизайн

This commit is contained in:
2026-07-25 18:36:45 +04:00
parent df7f98fe8b
commit c43a73e148
54 changed files with 4234 additions and 1110 deletions
+133
View File
@@ -0,0 +1,133 @@
<script setup>
import { Head, Link, router, useForm } from '@inertiajs/vue3';
import { ref } from 'vue';
import AdminLayout from '../../Layouts/AdminLayout.vue';
const props = defineProps({
site: { type: Object, required: true },
auth: { type: Object, required: true },
urls: { type: Object, required: true },
flash: { type: Object, default: () => ({}) },
transactions: { type: Array, default: () => [] },
search: { type: String, default: '' },
adjustUrl: { type: String, required: true },
old: { type: Object, default: () => ({}) },
});
const searchValue = ref(props.search);
const form = useForm({
account: props.old.account || '',
direction: props.old.direction || 'credit',
amount: props.old.amount || '',
reason: props.old.reason || '',
});
function submit() {
form.post(props.adjustUrl, {
preserveScroll: true,
onSuccess: () => form.reset(),
});
}
function searchTransactions() {
router.get(props.urls.admin_balances, {
search: searchValue.value || undefined,
}, { preserveState: true, replace: true });
}
</script>
<template>
<Head><title>Слёзы Элуны — {{ site.name }}</title></Head>
<AdminLayout :site="site" :auth="auth" :urls="urls" :flash="flash" current="balances">
<section class="admin-hero wrap">
<div>
<span class="eyebrow">Финансы</span>
<h1 class="h-display">Слёзы Элуны</h1>
<p class="lead">Ручные корректировки и полный журнал движения виртуальной валюты.</p>
</div>
<div class="admin-hero__badge"><small>Операций в выборке</small><strong>{{ transactions.length }}</strong></div>
</section>
<div class="admin-page wrap">
<section class="admin-section">
<div class="admin-split admin-split--form">
<article class="portal-card admin-panel corners">
<span class="admin-kicker">Новая операция</span>
<h2 class="h-serif">Изменить баланс</h2>
<form class="admin-form" @submit.prevent="submit">
<label class="admin-field">
<span>ID или логин аккаунта</span>
<input v-model="form.account" required />
<small v-if="form.errors.account">{{ form.errors.account }}</small>
</label>
<div class="admin-form-grid">
<label class="admin-field">
<span>Операция</span>
<select v-model="form.direction" required>
<option value="credit">Начислить</option>
<option value="debit">Снять</option>
</select>
<small v-if="form.errors.direction">{{ form.errors.direction }}</small>
</label>
<label class="admin-field">
<span>Количество</span>
<input v-model="form.amount" type="number" min="0.01" max="1000000" step="0.01" required />
<small v-if="form.errors.amount">{{ form.errors.amount }}</small>
</label>
</div>
<label class="admin-field">
<span>Причина</span>
<input v-model="form.reason" maxlength="255" placeholder="Компенсация, возврат, нарушение…" required />
<small v-if="form.errors.reason">{{ form.errors.reason }}</small>
</label>
<button class="btn btn-primary admin-submit" type="submit" :disabled="form.processing">
{{ form.processing ? 'Проводим…' : 'Провести операцию' }}
</button>
</form>
</article>
<article class="portal-card admin-panel admin-rules">
<span class="admin-kicker">Контроль</span>
<h2 class="h-serif">Правила операций</h2>
<div><span>01</span><p>Баланс аккаунта не может стать отрицательным.</p></div>
<div><span>02</span><p>В журнале сохраняются администратор, причина и итоговое значение.</p></div>
<div><span>03</span><p>Ошибочная операция исправляется отдельной обратной корректировкой.</p></div>
</article>
</div>
</section>
<section class="admin-section">
<div class="admin-section__head">
<div><span class="eyebrow">Аудит</span><h2 class="h-serif">Последние транзакции</h2></div>
<form class="admin-search" @submit.prevent="searchTransactions">
<input v-model="searchValue" type="search" placeholder="Логин или ID аккаунта" />
<button class="btn btn-primary" type="submit">Найти</button>
<Link v-if="search" class="btn btn-ghost" :href="urls.admin_balances">Сбросить</Link>
</form>
</div>
<div v-if="transactions.length" class="admin-ledger">
<article v-for="transaction in transactions" :key="transaction.id" class="portal-card admin-ledger__row">
<div>
<strong>{{ transaction.username }}</strong>
<small>ID #{{ transaction.account_id }} · {{ transaction.created_at }}</small>
</div>
<div>
<strong>{{ transaction.type_label }}</strong>
<small>{{ transaction.description }}</small>
<small v-if="transaction.admin">Администратор: {{ transaction.admin.username }} (#{{ transaction.admin.account_id }})</small>
</div>
<div class="admin-ledger__amount">
<strong :class="{ positive: transaction.is_positive }">
{{ transaction.is_positive ? '+' : '' }}{{ transaction.formatted_amount }}
</strong>
<small>Баланс: {{ transaction.formatted_balance_after }}</small>
</div>
</article>
</div>
<article v-else class="portal-card admin-empty"><p>Транзакции не найдены.</p></article>
</section>
</div>
</AdminLayout>
</template>