mirror of
https://github.com/HDInnovations/UNIT3D-Community-Edition.git
synced 2026-02-06 03:28:58 -06:00
add: staff history search
This commit is contained in:
27
app/Http/Controllers/Staff/HistoryController.php
Normal file
27
app/Http/Controllers/Staff/HistoryController.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* NOTICE OF LICENSE.
|
||||
*
|
||||
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
|
||||
* The details is bundled with this project in the file LICENSE.txt.
|
||||
*
|
||||
* @project UNIT3D Community Edition
|
||||
*
|
||||
* @author Roardom <roardom@protonmail.com>
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Staff;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class HistoryController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display All Pages.
|
||||
*/
|
||||
public function index(): \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
{
|
||||
return view('Staff.history.index');
|
||||
}
|
||||
}
|
||||
174
app/Http/Livewire/HistorySearch.php
Normal file
174
app/Http/Livewire/HistorySearch.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* NOTICE OF LICENSE.
|
||||
*
|
||||
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
|
||||
* The details is bundled with this project in the file LICENSE.txt.
|
||||
*
|
||||
* @project UNIT3D Community Edition
|
||||
*
|
||||
* @author Roardom <roardom@protonmail.com>
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
|
||||
*/
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Models\History;
|
||||
use App\Models\Torrent;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
/**
|
||||
* @property \Illuminate\Contracts\Pagination\LengthAwarePaginator $histories
|
||||
*/
|
||||
class HistorySearch extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
public int $perPage = 25;
|
||||
public string $agent = '';
|
||||
public string $torrent = '';
|
||||
public string $user = '';
|
||||
public string $seeder = 'any';
|
||||
public string $active = 'any';
|
||||
public string $groupBy = 'none';
|
||||
public string $sortField = '';
|
||||
public string $sortDirection = 'desc';
|
||||
|
||||
protected $queryString = [
|
||||
'page' => ['except' => 1],
|
||||
'perPage' => ['except' => 25],
|
||||
'agent' => ['except' => ''],
|
||||
'torrent' => ['except' => ''],
|
||||
'user' => ['except' => ''],
|
||||
'seeder' => ['except' => 'any'],
|
||||
'active' => ['except' => 'any'],
|
||||
'groupBy' => ['except' => 'none'],
|
||||
'sortField' => ['except' => ''],
|
||||
'sortDirection' => ['except' => 'desc'],
|
||||
];
|
||||
|
||||
final public function updatedPage(): void
|
||||
{
|
||||
$this->emit('paginationChanged');
|
||||
}
|
||||
|
||||
final public function updatingUser(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
final public function updatingAgent(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
final public function updatingTorrent(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
final public function updatingSeeder(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
final public function updatingActive(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
final public function updatingGroupBy(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
final public function getHistoriesProperty(): \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
{
|
||||
return History::query()
|
||||
->with('user', 'torrent:id,name')
|
||||
->when(
|
||||
$this->groupBy === 'user_id',
|
||||
fn ($query) => $query->groupBy('user_id')
|
||||
->select([
|
||||
'user_id',
|
||||
DB::raw('COUNT(*) AS torrent_count'),
|
||||
DB::raw('SUM(uploaded) AS uploaded_sum'),
|
||||
DB::raw('SUM(actual_uploaded) AS actual_uploaded_sum'),
|
||||
DB::raw('SUM(client_uploaded) AS client_uploaded_sum'),
|
||||
DB::raw('SUM(downloaded) AS downloaded_sum'),
|
||||
DB::raw('SUM(actual_downloaded) AS actual_downloaded_sum'),
|
||||
DB::raw('SUM(client_downloaded) AS client_downloaded_sum'),
|
||||
DB::raw('SUM(refunded_download) AS refunded_download_sum'),
|
||||
DB::raw('AVG(seedtime) AS seedtime_avg'),
|
||||
DB::raw('MIN(created_at) AS created_at_min'),
|
||||
DB::raw('MAX(updated_at) AS updated_at_max'),
|
||||
DB::raw('SUM(active AND seeder) AS seeding_count'),
|
||||
DB::raw('SUM(active AND NOT seeder) AS leeching_count'),
|
||||
DB::raw('SUM(prewarn = 1) AS prewarn_count'),
|
||||
DB::raw('SUM(hitrun = 1) AS hitrun_count'),
|
||||
DB::raw('SUM(immune = 1) AS immune_count'),
|
||||
])
|
||||
->withCasts([
|
||||
'created_at_min' => 'datetime',
|
||||
'updated_at_max' => 'datetime',
|
||||
]),
|
||||
fn ($query) => $query
|
||||
->select([
|
||||
'user_id',
|
||||
'torrent_id',
|
||||
'uploaded',
|
||||
'actual_uploaded',
|
||||
'client_uploaded',
|
||||
'downloaded',
|
||||
'actual_downloaded',
|
||||
'client_downloaded',
|
||||
'refunded_download',
|
||||
'seedtime',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'completed_at',
|
||||
DB::raw('active AND seeder AS seeding'),
|
||||
DB::raw('active AND NOT seeder AS leeching '),
|
||||
'prewarn',
|
||||
'hitrun',
|
||||
'immune',
|
||||
])
|
||||
)
|
||||
->when($this->torrent !== '', fn ($query) => $query->whereIn(
|
||||
'history.torrent_id',
|
||||
Torrent::select('id')->where('name', 'LIKE', '%'.str_replace(' ', '%', $this->torrent).'%')
|
||||
))
|
||||
->when($this->user !== '', fn ($query) => $query->whereIn(
|
||||
'history.user_id',
|
||||
User::select('id')->where('username', 'LIKE', $this->user)
|
||||
))
|
||||
->when($this->agent !== '', fn ($query) => $query->where('history.agent', 'LIKE', $this->agent.'%'))
|
||||
->when($this->active === 'include', fn ($query) => $query->where('active', '=', true))
|
||||
->when($this->active === 'exclude', fn ($query) => $query->where('active', '=', false))
|
||||
->when($this->seeder === 'include', fn ($query) => $query->where('seeder', '=', true))
|
||||
->when($this->seeder === 'exclude', fn ($query) => $query->where('seeder', '=', false))
|
||||
->when($this->sortField !== '', fn ($query) => $query->orderBy($this->sortField, $this->sortDirection))
|
||||
->paginate($this->perPage);
|
||||
}
|
||||
|
||||
final public function sortBy($field): void
|
||||
{
|
||||
if ($this->sortField === $field) {
|
||||
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
$this->sortDirection = 'asc';
|
||||
}
|
||||
|
||||
$this->sortField = $field;
|
||||
}
|
||||
|
||||
final public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Contracts\Foundation\Application
|
||||
{
|
||||
return view('livewire.history-search', [
|
||||
'histories' => $this->histories,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -194,6 +194,12 @@
|
||||
Peers
|
||||
</a>
|
||||
</p>
|
||||
<p class="form__group form__group--horizontal">
|
||||
<a class="form__button form__button--text" href="{{ route('staff.histories.index') }}">
|
||||
<i class="{{ config('other.font-awesome') }} fa-columns"></i>
|
||||
Histories
|
||||
</a>
|
||||
</p>
|
||||
<p class="form__group form__group--horizontal">
|
||||
<a class="form__button form__button--text" href="{{ route('staff.rss.index') }}">
|
||||
<i class="{{ config('other.font-awesome') }} fa-rss"></i>
|
||||
|
||||
22
resources/views/Staff/history/index.blade.php
Normal file
22
resources/views/Staff/history/index.blade.php
Normal file
@@ -0,0 +1,22 @@
|
||||
@extends('layout.default')
|
||||
|
||||
@section('title')
|
||||
<title>History - {{ config('other.title') }}</title>
|
||||
@endsection
|
||||
|
||||
@section('breadcrumbs')
|
||||
<li class="breadcrumbV2">
|
||||
<a href="{{ route('staff.dashboard.index') }}" class="breadcrumb__link">
|
||||
{{ __('staff.staff-dashboard') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="breadcrumb--active">
|
||||
History
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
@section('page', 'page__history--index')
|
||||
|
||||
@section('content')
|
||||
@livewire('history-search')
|
||||
@endsection
|
||||
364
resources/views/livewire/history-search.blade.php
Normal file
364
resources/views/livewire/history-search.blade.php
Normal file
@@ -0,0 +1,364 @@
|
||||
<div style="display: flex; flex-direction: column; row-gap: 1rem;">
|
||||
<section class="panelV2">
|
||||
<header class="panel__header">
|
||||
<h2 class="panel__heading">{{ __('common.search') }}</h2>
|
||||
</header>
|
||||
<div class="panel__body" style="padding: 5px;">
|
||||
<form class="form">
|
||||
<div class="form__group--short-horizontal">
|
||||
<p class="form__group">
|
||||
<input wire:model="torrent" class="form__text" placeholder=" ">
|
||||
<label class="form__label form__label--floating">Torrent Name</label>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<input wire:model="user" class="form__text" placeholder=" ">
|
||||
<label class="form__label form__label--floating">Username</label>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<input wire:model="agent" class="form__text" placeholder=" ">
|
||||
<label class="form__label form__label--floating">Agent</label>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<select wire:model="seeder" class="form__select" placeholder=" ">
|
||||
<option value="any">Any</option>
|
||||
<option value="include">Completed</option>
|
||||
<option value="exclude">Incomplete</option>
|
||||
</select>
|
||||
<label class="form__label form__label--floating">Completed</label>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<select wire:model="active" class="form__select" placeholder=" ">
|
||||
<option value="any">Any</option>
|
||||
<option value="exclude">Inactive</option>
|
||||
<option value="include">Active</option>
|
||||
</select>
|
||||
<label class="form__label form__label--floating">Active</label>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<select wire:model="groupBy" class="form__select" placeholder=" ">
|
||||
<option value="none">None</option>
|
||||
<option value="user_id">User</option>
|
||||
</select>
|
||||
<label class="form__label form__label--floating">Group By</label>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
<section class="panelV2">
|
||||
<h2 class="panel__heading">Histories</h2>
|
||||
<div class="panel__body" wire:loading.block>
|
||||
Loading...
|
||||
</div>
|
||||
<div class="data-table-wrapper">
|
||||
@switch ($groupBy)
|
||||
@case('user_id')
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th wire:click="sortBy('histories.user_id')" role="columnheader button">
|
||||
{{ __('user.user') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.user_id'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.torrent_count')" role="columnheader button">
|
||||
{{ __('torrent.torrents') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'torrent_count'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.uploaded_sum')" role="columnheader button">
|
||||
{{ __('user.credited-upload') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.uploaded_sum'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.actual_uploaded_sum')" role="columnheader button">
|
||||
{{ __('user.upload-true') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.actual_uploaded_sum'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.client_uploaded_sum')" role="columnheader button">
|
||||
Client Upload
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.client_uploaded_sum'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.downloaded_sum')" role="columnheader button">
|
||||
{{ __('user.credited-download') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.downloaded_sum'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.actual_downloaded_sum')" role="columnheader button">
|
||||
{{ __('user.download-true') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.actual_downloaded_sum'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.client_downloaded_sum')" role="columnheader button">
|
||||
Client Download
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.client_downloaded_sum'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.refunded_downloaded_sum')" role="columnheader button">
|
||||
{{ __('torrent.refunded') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.refunded_downloaded_sum'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.created_at_min')" role="columnheader button">
|
||||
{{ __('torrent.started') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.created_at_min'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.updated_at_max')" role="columnheader button">
|
||||
Announced
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.updated_at_max'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.seedtime_avg')" role="columnheader button">
|
||||
{{ __('user.avg-seedtime') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.seedtime_avg'])
|
||||
</th>
|
||||
<th wire:click="sortBy('seeding_count')" role="columnheader button">
|
||||
{{ __('torrent.seeding') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'seeding_count'])
|
||||
</th>
|
||||
<th wire:click="sortBy('leeching_count')" role="columnheader button">
|
||||
{{ __('torrent.leeching') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'leeching_count'])
|
||||
</th>
|
||||
<th wire:click="sortBy('prewarn_count')" role="columnheader button" title="{{ __('torrent.prewarn') }}">
|
||||
<i class="fas fa-exclamation"></i>
|
||||
</th>
|
||||
<th wire:click="sortBy('hitrun_count')" role="columnheader button" title="{{ __('torrent.hitrun') }}">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
</th>
|
||||
<th wire:click="sortBy('immune_count')" role="columnheader button" title="{{ __('torrent.immune') }}">
|
||||
<i class="fas fa-syringe"></i>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($histories as $history)
|
||||
<tr>
|
||||
<td>
|
||||
<x-user_tag :user="$history->user" :anon="false" />
|
||||
</td>
|
||||
<td>
|
||||
{{ $history->torrent_count }}
|
||||
</td>
|
||||
<td title="{{ $history->uploaded_sum }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->uploaded_sum, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->actual_uploaded_sum }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->actual_uploaded_sum, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->client_uploaded_sum }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->client_uploaded_sum, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->downloaded_sum }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->downloaded_sum, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->actual_downloaded_sum }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->actual_downloaded_sum, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->client_downloaded_sum }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->client_downloaded_sum, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->refunded_downloaded_sum }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->refunded_downloaded_sum, 2) }}
|
||||
</td>
|
||||
<td>
|
||||
<time datetime="{{ $history->created_at_min }}" title="{{ $history->created_at_min }}">
|
||||
{{ $history->created_at_min ? $history->created_at_min->diffForHumans() : 'N/A' }}
|
||||
</time>
|
||||
</td>
|
||||
<td>
|
||||
<time datetime="{{ $history->updated_at_max }}" title="{{ $history->updated_at_max }}">
|
||||
{{ $history->updated_at_max ? $history->updated_at_max->diffForHumans() : 'N/A' }}
|
||||
</time>
|
||||
</td>
|
||||
@if ($history->seedtime < config('hitrun.seedtime'))
|
||||
<td class="text-red" title="{{ App\Helpers\StringHelper::timeElapsed($history->seedtime_avg) }}">
|
||||
{{ $weeks = intdiv($history->seedtime_avg ?? 0, 3600 * 24 * 7) }}w {{ intdiv(($history->seedtime_avg ?? 0) - $weeks * 3600 * 24 * 7, 3600) }}h
|
||||
</td>
|
||||
@else
|
||||
<td class="text-green" title="{{ App\Helpers\StringHelper::timeElapsed($history->seedtime_avg) }}">
|
||||
{{ $weeks = intdiv($history->seedtime_avg ?? 0, 3600 * 24 * 7) }}w {{ intdiv(($history->seedtime_avg ?? 0) - $weeks * 3600 * 24 * 7, 3600) }}h
|
||||
</td>
|
||||
@endif
|
||||
<td>{{ $history->seeding_count }}</td>
|
||||
<td>{{ $history->leeching_count }}</td>
|
||||
<td>{{ $history->immune_count }}</td>
|
||||
<td>{{ $history->hitrun_count }}</td>
|
||||
<td>{{ $history->prewarn_count }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@break
|
||||
@default
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th wire:click="sortBy('histories.user_id')" role="columnheader button">
|
||||
{{ __('user.user') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.user_id'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.torrent_id')" role="columnheader button">
|
||||
{{ __('torrent.torrent') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.torrent_id'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.agent')" role="columnheader button">
|
||||
{{ __('torrent.agent') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.agent'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.uploaded')" role="columnheader button">
|
||||
{{ __('user.credited-upload') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.uploaded'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.actual_uploaded')" role="columnheader button">
|
||||
{{ __('user.upload-true') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.actual_uploaded'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.client_uploaded')" role="columnheader button">
|
||||
Client Upload
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.client_uploaded'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.downloaded')" role="columnheader button">
|
||||
{{ __('user.credited-download') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.downloaded'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.actual_downloaded')" role="columnheader button">
|
||||
{{ __('user.download-true') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.actual_downloaded'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.client_downloaded')" role="columnheader button">
|
||||
Client Download
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.client_downloaded'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.refunded_downloaded')" role="columnheader button">
|
||||
{{ __('torrent.refunded') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.refunded_downloaded'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.created_at')" role="columnheader button">
|
||||
{{ __('torrent.started') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.created_at'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.updated_at')" role="columnheader button">
|
||||
Announced
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.updated_at'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.completed_at')" role="columnheader button">
|
||||
{{ __('torrent.completed_at') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.completed_at'])
|
||||
</th>
|
||||
<th wire:click="sortBy('histories.seedtime')" role="columnheader button">
|
||||
{{ __('torrent.seedtime') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'histories.seedtime'])
|
||||
</th>
|
||||
<th wire:click="sortBy('seeding')" role="columnheader button">
|
||||
{{ __('torrent.seeding') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'seeding'])
|
||||
</th>
|
||||
<th wire:click="sortBy('leeching')" role="columnheader button">
|
||||
{{ __('torrent.leeching') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'leeching'])
|
||||
</th>
|
||||
<th wire:click="sortBy('prewarn')" role="columnheader button" title="{{ __('torrent.prewarn') }}">
|
||||
<i class="fas fa-exclamation"></i>
|
||||
</th>
|
||||
<th wire:click="sortBy('hitrun')" role="columnheader button" title="{{ __('torrent.hitrun') }}">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
</th>
|
||||
<th wire:click="sortBy('immune')" role="columnheader button" title="{{ __('torrent.immune') }}">
|
||||
<i class="fas fa-syringe"></i>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($histories as $history)
|
||||
<tr>
|
||||
<td>
|
||||
<x-user_tag :user="$history->user" :anon="false" />
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ route('torrents.show', ['id' => $history->torrent_id]) }}">
|
||||
{{ $history->torrent->name ?? '' }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ $history->agent }}</td>
|
||||
<td title="{{ $history->uploaded }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->uploaded, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->actual_uploaded }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->actual_uploaded, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->client_uploaded }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->client_uploaded, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->downloaded }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->downloaded, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->actual_downloaded }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->actual_downloaded, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->client_downloaded }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->client_downloaded, 2) }}
|
||||
</td>
|
||||
<td title="{{ $history->refunded_downloaded }}">
|
||||
{{ App\Helpers\StringHelper::formatBytes($history->refunded_downloaded, 2) }}
|
||||
</td>
|
||||
<td>
|
||||
<time datetime="{{ $history->created_at }}" title="{{ $history->created_at }}">
|
||||
{{ $history->created_at ? $history->created_at->diffForHumans() : 'N/A' }}
|
||||
</time>
|
||||
</td>
|
||||
<td>
|
||||
<time datetime="{{ $history->updated_at }}" title="{{ $history->updated_at }}">
|
||||
{{ $history->updated_at ? $history->updated_at->diffForHumans() : 'N/A' }}
|
||||
</time>
|
||||
</td>
|
||||
<td>
|
||||
<time datetime="{{ $history->completed_at }}" title="{{ $history->completed_at }}">
|
||||
{{ $history->completed_at ? $history->completed_at->diffForHumans() : 'N/A' }}
|
||||
</time>
|
||||
</td>
|
||||
@if ($history->seedtime < config('hitrun.seedtime'))
|
||||
<td class="text-red" title="{{ App\Helpers\StringHelper::timeElapsed($history->seedtime) }}">
|
||||
{{ $weeks = intdiv($history->seedtime ?? 0, 3600 * 24 * 7) }}w {{ intdiv(($history->seedtime ?? 0) - $weeks * 3600 * 24 * 7, 3600) }}h
|
||||
</td>
|
||||
@else
|
||||
<td class="text-green" title="{{ App\Helpers\StringHelper::timeElapsed($history->seedtime) }}">
|
||||
{{ $weeks = intdiv($history->seedtime ?? 0, 3600 * 24 * 7) }}w {{ intdiv(($history->seedtime ?? 0) - $weeks * 3600 * 24 * 7, 3600) }}h
|
||||
</td>
|
||||
@endif
|
||||
<td>
|
||||
@if ($history->active)
|
||||
<i class="{{ config('other.font-awesome') }} text-green fa-check" title="Active"></i>
|
||||
@else
|
||||
<i class="{{ config('other.font-awesome') }} text-red fa-times" title="Inactive"></i>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($history->seeder)
|
||||
<i class="{{ config('other.font-awesome') }} text-green fa-check" title="Seeder"></i>
|
||||
@else
|
||||
<i class="{{ config('other.font-awesome') }} text-red fa-times" title="Leecher"></i>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($history->immune)
|
||||
<i class="{{ config('other.font-awesome') }} text-green fa-check" title="Immune"></i>
|
||||
@else
|
||||
<i class="{{ config('other.font-awesome') }} text-red fa-times" title="Not immune"></i>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($history->hitrun)
|
||||
<i class="{{ config('other.font-awesome') }} text-green fa-check" title="Warned"></i>
|
||||
@else
|
||||
<i class="{{ config('other.font-awesome') }} text-red fa-times" title="Not warned"></i>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($history->prewarn)
|
||||
<i class="{{ config('other.font-awesome') }} text-green fa-check" title="Prewarned"></i>
|
||||
@else
|
||||
<i class="{{ config('other.font-awesome') }} text-red fa-times" title="Not Prewarned"></i>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endswitch
|
||||
{{ $histories->links('partials.pagination') }}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
@@ -831,6 +831,13 @@ Route::middleware('language')->group(function (): void {
|
||||
});
|
||||
});
|
||||
|
||||
// History
|
||||
Route::prefix('histories')->group(function (): void {
|
||||
Route::name('histories.')->group(function (): void {
|
||||
Route::get('/', [App\Http\Controllers\Staff\HistoryController::class, 'index'])->name('index');
|
||||
});
|
||||
});
|
||||
|
||||
// Invites Log
|
||||
Route::prefix('invites')->group(function (): void {
|
||||
Route::name('invites.')->group(function (): void {
|
||||
|
||||
Reference in New Issue
Block a user