@extends('layouts.app') @section('title', 'Журнал действий') {{-- Audit feed for /admin/activity_log.php. Rows come from two sources (activity_log + student_status_history) already normalised into one column shape by ActivityLogController, so this view only formats them. `changes` arrives as a JSON string in both cases — MySQL's JSON_OBJECT() on the status-history side, json_encode() on the activity_log side. --}} @php $actionLabels = [ 'payment.created' => 'Платёж добавлен', 'payment.deleted' => 'Платёж удалён', 'payment.status_changed' => 'Статус платежа изменён', 'charge.created' => 'Начисление добавлено', 'charge.deleted' => 'Начисление удалено', 'expense.created' => 'Расход добавлен', 'expense.updated' => 'Расход изменён', 'expense.deleted' => 'Расход удалён', 'teacher_bonus.created' => 'Бонус преподавателю начислен', 'tariff.created' => 'Тариф создан', 'tariff.updated' => 'Тариф изменён', 'tariff.deleted' => 'Тариф удалён', 'student_tariff.created' => 'Тариф назначен ученику', 'student_tariff.updated' => 'Тариф ученика изменён', 'student_general_tariff.updated' => 'Общий тариф ученика изменён', 'student_individual_tariff.updated' => 'Индивидуальный тариф ученика изменён', 'group_tariff.created' => 'Тариф назначен группе', 'group_tariff.updated' => 'Тариф группы изменён', 'group_tariff.deleted' => 'Тариф группы удалён', 'student_discount.updated' => 'Скидка изменена', 'student.status_changed' => 'Статус ученика изменён', ]; $fieldLabels = [ 'amount' => 'Сумма', 'payment_date' => 'Дата оплаты', 'charged_date' => 'Дата начисления', 'expense_date' => 'Дата расхода', 'bonus_date' => 'Дата бонуса', 'start_date' => 'Начало', 'end_date' => 'Окончание', 'description' => 'Описание', 'title' => 'Описание', 'note' => 'Примечание', 'category' => 'Категория', 'status_id' => 'Статус', 'status' => 'Статус', 'reason' => 'Причина', 'discount_percent' => 'Скидка, %', 'tariff_id' => 'Тариф (ID)', 'general_tariff_id' => 'Общий тариф (ID)', 'individual_tariff_id' => 'Индивидуальный тариф (ID)', 'lessons_remaining' => 'Осталось уроков', 'lessons_count' => 'Уроков в тарифе', 'duration_days' => 'Срок, дней', 'price' => 'Цена', 'name' => 'Название', 'group_id' => 'Группа (ID)', 'student_id' => 'Ученик (ID)', 'teacher_id' => 'Преподаватель (ID)', 'created_by' => 'Кем создано (ID)', 'id' => 'ID', ]; $actionBadge = function (string $action): string { return match (true) { str_ends_with($action, '.deleted') => 'danger', str_ends_with($action, '.created') => 'success', default => 'secondary', }; }; $formatValue = function ($value): string { if ($value === null || $value === '') { return '—'; } return is_scalar($value) ? (string) $value : json_encode($value, JSON_UNESCAPED_UNICODE); }; @endphp @section('content')

Журнал действий

Всего записей: {{ $entries->total() }}
@if ($dateFrom || $dateTo || $userId !== '' || $entityType !== '' || $search !== '') Сбросить @endif
@if ($entries->isNotEmpty())
@foreach ($entries as $entry) @php $changes = json_decode((string) $entry->changes, true) ?: []; $before = $changes['before'] ?? []; $after = $changes['after'] ?? []; $keys = array_keys($before + $after); @endphp @endforeach
Дата и время Кто Действие Ученик Изменения IP
{{ $entry->created_at }} {{ $entry->user_name ?? '—' }} @if ($entry->user_role)
{{ $entry->user_role }}
@endif
{{ $actionLabels[$entry->action] ?? $entry->action }} @if ($entry->entity_id)
#{{ $entry->entity_id }}
@endif
@if ($entry->student_id && trim((string) $entry->student_name) !== '') {{ $entry->student_name }} @else — @endif @if ($keys === []) @else @foreach ($keys as $key)
{{ $fieldLabels[$key] ?? $key }}: {{ $formatValue($before[$key] ?? null) }}{{ $formatValue($after[$key] ?? null) }}
@endforeach @endif
{{ $entry->ip ?? '—' }}
{{ $entries->withQueryString()->links('pagination::bootstrap-5') }} @else
Записей не найдено.
@endif
@endsection