mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-03 14:10:57 +08:00
improve filament trans + user profile actions
This commit is contained in:
@@ -11,7 +11,7 @@ class StatTable extends Widget
|
||||
|
||||
protected function getHeader(): string
|
||||
{
|
||||
return nulll;
|
||||
|
||||
}
|
||||
|
||||
protected function getTableRows(): array
|
||||
|
||||
@@ -44,20 +44,20 @@ class AgentAllowResource extends Resource
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('family')->required(),
|
||||
Forms\Components\TextInput::make('start_name')->required(),
|
||||
Forms\Components\TextInput::make('peer_id_start')->required(),
|
||||
Forms\Components\TextInput::make('peer_id_pattern')->required(),
|
||||
Forms\Components\Radio::make('peer_id_matchtype')->options(self::$matchTypes)->required(),
|
||||
Forms\Components\TextInput::make('peer_id_match_num')->integer()->required(),
|
||||
Forms\Components\TextInput::make('agent_start')->required(),
|
||||
Forms\Components\TextInput::make('agent_pattern')->required(),
|
||||
Forms\Components\Radio::make('agent_matchtype')->options(self::$matchTypes)->required(),
|
||||
Forms\Components\TextInput::make('agent_match_num')->required(),
|
||||
Forms\Components\Radio::make('exception')->options(self::$yesOrNo)->required(),
|
||||
Forms\Components\Radio::make('allowhttps')->options(self::$yesOrNo)->required(),
|
||||
Forms\Components\TextInput::make('family')->required()->label(__('label.agent_allow.family')),
|
||||
Forms\Components\TextInput::make('start_name')->required()->label(__('label.agent_allow.start_name')),
|
||||
Forms\Components\TextInput::make('peer_id_start')->required()->label(__('label.agent_allow.peer_id_start')),
|
||||
Forms\Components\TextInput::make('peer_id_pattern')->required()->label(__('label.agent_allow.peer_id_pattern')),
|
||||
Forms\Components\Radio::make('peer_id_matchtype')->options(self::$matchTypes)->required()->label(__('label.agent_allow.peer_id_matchtype')),
|
||||
Forms\Components\TextInput::make('peer_id_match_num')->integer()->required()->label(__('label.agent_allow.peer_id_match_num')),
|
||||
Forms\Components\TextInput::make('agent_start')->required()->label(__('label.agent_allow.agent_start')),
|
||||
Forms\Components\TextInput::make('agent_pattern')->required()->label(__('label.agent_allow.agent_pattern')),
|
||||
Forms\Components\Radio::make('agent_matchtype')->options(self::$matchTypes)->required()->label(__('label.agent_allow.agent_matchtype')),
|
||||
Forms\Components\TextInput::make('agent_match_num')->required()->label(__('label.agent_allow.agent_match_num')),
|
||||
Forms\Components\Radio::make('exception')->options(self::$yesOrNo)->required()->label(__('label.agent_allow.exception')),
|
||||
Forms\Components\Radio::make('allowhttps')->options(self::$yesOrNo)->required()->label(__('label.agent_allow.allowhttps')),
|
||||
|
||||
Forms\Components\Textarea::make('comment'),
|
||||
Forms\Components\Textarea::make('comment')->label(__('label.comment')),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -66,10 +66,10 @@ class AgentAllowResource extends Resource
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('family')->searchable(),
|
||||
Tables\Columns\TextColumn::make('start_name')->searchable(),
|
||||
Tables\Columns\TextColumn::make('peer_id_start'),
|
||||
Tables\Columns\TextColumn::make('agent_start'),
|
||||
Tables\Columns\TextColumn::make('family')->searchable()->label(__('label.agent_allow.family')),
|
||||
Tables\Columns\TextColumn::make('start_name')->searchable()->label(__('label.agent_allow.start_name')),
|
||||
Tables\Columns\TextColumn::make('peer_id_start')->label(__('label.agent_allow.peer_id_start')),
|
||||
Tables\Columns\TextColumn::make('agent_start')->label(__('label.agent_allow.agent_start')),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
|
||||
@@ -4,8 +4,10 @@ namespace App\Filament\Resources\System\AgentAllowResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\System\AgentAllowResource;
|
||||
use App\Repositories\AgentAllowRepository;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Forms;
|
||||
|
||||
class ListAgentAllows extends PageList
|
||||
{
|
||||
@@ -15,6 +17,23 @@ class ListAgentAllows extends PageList
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
Actions\Action::make('check')
|
||||
->label(__('admin.resources.agent_allow.check_modal_btn'))
|
||||
->form([
|
||||
Forms\Components\TextInput::make('peer_id')->required(),
|
||||
Forms\Components\TextInput::make('agent')->required(),
|
||||
])
|
||||
->modalHeading(__('admin.resources.agent_allow.check_modal_header'))
|
||||
->action(function ($data) {
|
||||
$agentAllowRep = new AgentAllowRepository();
|
||||
try {
|
||||
$result = $agentAllowRep->checkClient($data['peer_id'], $data['agent']);
|
||||
$this->notify('success', __('admin.resources.agent_allow.check_pass_msg', ['id' => $result->id]));
|
||||
} catch (\Exception $exception) {
|
||||
$this->notify('danger', $exception->getMessage());
|
||||
}
|
||||
})
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,11 +36,11 @@ class AgentDenyResource extends Resource
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Select::make('family_id')->label('Allow family')
|
||||
->relationship('family', 'family')->required(),
|
||||
Forms\Components\TextInput::make('name')->required(),
|
||||
Forms\Components\TextInput::make('peer_id')->required(),
|
||||
Forms\Components\TextInput::make('agent')->required(),
|
||||
Forms\Components\Textarea::make('comment'),
|
||||
->relationship('family', 'family')->required()->label(__('label.agent_allow.family')),
|
||||
Forms\Components\TextInput::make('name')->required()->label(__('label.name')),
|
||||
Forms\Components\TextInput::make('peer_id')->required()->label(__('label.agent_deny.peer_id')),
|
||||
Forms\Components\TextInput::make('agent')->required()->label(__('label.agent_deny.agent')),
|
||||
Forms\Components\Textarea::make('comment')->label(__('label.comment')),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -49,10 +49,10 @@ class AgentDenyResource extends Resource
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('family.family')->label('Family'),
|
||||
Tables\Columns\TextColumn::make('name')->searchable(),
|
||||
Tables\Columns\TextColumn::make('peer_id')->searchable(),
|
||||
Tables\Columns\TextColumn::make('agent')->searchable(),
|
||||
Tables\Columns\TextColumn::make('family.family')->label(__('label.agent_allow.family')),
|
||||
Tables\Columns\TextColumn::make('name')->searchable()->label(__('label.name')),
|
||||
Tables\Columns\TextColumn::make('peer_id')->searchable()->label(__('label.agent_deny.peer_id')),
|
||||
Tables\Columns\TextColumn::make('agent')->searchable()->label(__('label.agent_deny.agent')),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Filament\Resources\System;
|
||||
|
||||
use App\Filament\OptionsTrait;
|
||||
use App\Filament\Resources\System\ExamResource\Pages;
|
||||
use App\Filament\Resources\System\ExamResource\RelationManagers;
|
||||
use App\Models\Exam;
|
||||
@@ -16,12 +17,18 @@ use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class ExamResource extends Resource
|
||||
{
|
||||
use OptionsTrait;
|
||||
|
||||
protected static ?string $model = Exam::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-exclamation';
|
||||
|
||||
protected static ?string $navigationGroup = 'System';
|
||||
|
||||
const IS_DISCOVERED_OPTIONS = ['0' => 'No', '1' => 'Yes'];
|
||||
|
||||
const STATUS_OPTIONS = ['0' => 'Enabled', '1' => 'Disabled'];
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.exams_list');
|
||||
@@ -38,24 +45,41 @@ class ExamResource extends Resource
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Section::make('Base info')->schema([
|
||||
Forms\Components\TextInput::make('name')->required()->columnSpan(['sm' => 2]),
|
||||
Forms\Components\TextInput::make('priority')->columnSpan(['sm' => 2])->helperText('The higher the value, the higher the priority, and when multiple exam match the same user, the one with the highest priority is assigned.'),
|
||||
Forms\Components\Radio::make('status')->options(['0' => 'Enabled', '1' => 'Disabled'])->inline()->columnSpan(['sm' => 2]),
|
||||
Forms\Components\Radio::make('is_discovered')->options(['0' => 'No', '1' => 'Yes'])->label('Discovered')->inline()->columnSpan(['sm' => 2]),
|
||||
Forms\Components\TextInput::make('name')->required()->columnSpan(['sm' => 2])->label(__('label.name')),
|
||||
Forms\Components\TextInput::make('priority')
|
||||
->columnSpan(['sm' => 2])
|
||||
->label(__("label.priority"))
|
||||
->helperText('The higher the value, the higher the priority, and when multiple exam match the same user, the one with the highest priority is assigned.'),
|
||||
Forms\Components\Radio::make('status')
|
||||
->options(self::STATUS_OPTIONS)
|
||||
->inline()
|
||||
->label(__('label.status'))
|
||||
->columnSpan(['sm' => 2]),
|
||||
Forms\Components\Radio::make('is_discovered')
|
||||
->options(self::IS_DISCOVERED_OPTIONS)
|
||||
->label(__('label.exam.is_discovered'))
|
||||
->inline()
|
||||
->columnSpan(['sm' => 2]),
|
||||
])->columns(2),
|
||||
|
||||
Forms\Components\Section::make('Time')->schema([
|
||||
Forms\Components\DateTimePicker::make('begin'),
|
||||
Forms\Components\DateTimePicker::make('end'),
|
||||
Forms\Components\TextInput::make('duration')->integer()->columnSpan(['sm' => 2])
|
||||
Forms\Components\DateTimePicker::make('begin')->label(__('label.begin')),
|
||||
Forms\Components\DateTimePicker::make('end')->label(__('label.begin')),
|
||||
Forms\Components\TextInput::make('duration')
|
||||
->integer()
|
||||
->columnSpan(['sm' => 2])
|
||||
->label(__('label.duration'))
|
||||
->helperText('Unit: days. When assign to user, begin and end are used if they are specified. Otherwise begin time is the time at assignment, and the end time is the time at assignment plus the duration.'),
|
||||
])->columns(2),
|
||||
|
||||
Forms\Components\Section::make('Select user')->schema([
|
||||
Forms\Components\CheckboxList::make('filters.classes')->options($userRep->listClass())->columnSpan(['sm' => 2])->columns(4)->label('Classes'),
|
||||
Forms\Components\DateTimePicker::make('filters.register_time_range.0')->label('Register time begin'),
|
||||
Forms\Components\DateTimePicker::make('filters.register_time_range.1')->label('Register time end'),
|
||||
Forms\Components\Toggle::make('filters.donate_status')->label('Donated'),
|
||||
Forms\Components\CheckboxList::make('filters.classes')
|
||||
->options($userRep->listClass())->columnSpan(['sm' => 2])
|
||||
->columns(4)
|
||||
->label(__('label.user.class')),
|
||||
Forms\Components\DateTimePicker::make('filters.register_time_range.0')->label(__("label.exam.register_time_range.begin")),
|
||||
Forms\Components\DateTimePicker::make('filters.register_time_range.1')->label(__("label.exam.register_time_range.end")),
|
||||
Forms\Components\Toggle::make('filters.donate_status')->label(__('label.exam.donated')),
|
||||
])->columns(2),
|
||||
|
||||
|
||||
@@ -68,18 +92,19 @@ class ExamResource extends Resource
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('name'),
|
||||
Tables\Columns\TextColumn::make('indexFormatted')->label('Indexes')->html(),
|
||||
Tables\Columns\TextColumn::make('begin'),
|
||||
Tables\Columns\TextColumn::make('end'),
|
||||
Tables\Columns\TextColumn::make('durationText')->label('Duration'),
|
||||
Tables\Columns\TextColumn::make('filterFormatted')->label('Target users')->html(),
|
||||
Tables\Columns\BooleanColumn::make('is_discovered')->label('Discovered'),
|
||||
Tables\Columns\TextColumn::make('priority')->label('Priority'),
|
||||
Tables\Columns\TextColumn::make('statusText')->label('Status'),
|
||||
Tables\Columns\TextColumn::make('name')->searchable()->label(__('label.name')),
|
||||
Tables\Columns\TextColumn::make('indexFormatted')->label(__('label.exam.index_formatted'))->html(),
|
||||
Tables\Columns\TextColumn::make('begin')->label(__('label.begin')),
|
||||
Tables\Columns\TextColumn::make('end')->label(__('label.begin')),
|
||||
Tables\Columns\TextColumn::make('durationText')->label(__('label.duration')),
|
||||
Tables\Columns\TextColumn::make('filterFormatted')->label(__('label.exam.filter_formatted'))->html(),
|
||||
Tables\Columns\BooleanColumn::make('is_discovered')->label(__('label.exam.is_discovered')),
|
||||
Tables\Columns\TextColumn::make('priority')->label(__('label.priority')),
|
||||
Tables\Columns\TextColumn::make('statusText')->label(__('label.status')),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
Tables\Filters\SelectFilter::make('is_discovered')->options(self::IS_DISCOVERED_OPTIONS)->label(__("label.exam.is_discovered")),
|
||||
Tables\Filters\SelectFilter::make('status')->options(self::STATUS_OPTIONS)->label(__("label.status")),
|
||||
])
|
||||
->actions([
|
||||
// Tables\Actions\EditAction::make(),
|
||||
|
||||
@@ -35,13 +35,22 @@ class MedalResource extends Resource
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')->required(),
|
||||
Forms\Components\TextInput::make('price')->required()->integer(),
|
||||
Forms\Components\TextInput::make('image_large')->required(),
|
||||
Forms\Components\TextInput::make('image_small')->required(),
|
||||
Forms\Components\Radio::make('get_type')->options(Medal::listGetTypes(true))->inline()->columnSpan(['sm' => 2])->required(),
|
||||
Forms\Components\TextInput::make('duration')->integer()->columnSpan(['sm' => 2])->helperText('Unit: day, if empty, belongs to user forever.'),
|
||||
Forms\Components\Textarea::make('description')->columnSpan(['sm' => 2]),
|
||||
Forms\Components\TextInput::make('name')->required()->label(__('label.name')),
|
||||
Forms\Components\TextInput::make('price')->required()->integer()->label(__('label.price')),
|
||||
Forms\Components\TextInput::make('image_large')->required()->label(__('label.medal.image_large')),
|
||||
Forms\Components\TextInput::make('image_small')->required()->label(__('label.medal.image_small')),
|
||||
Forms\Components\Radio::make('get_type')
|
||||
->options(Medal::listGetTypes(true))
|
||||
->inline()
|
||||
->columnSpan(['sm' => 2])
|
||||
->label(__('label.medal.get_type'))
|
||||
->required(),
|
||||
Forms\Components\TextInput::make('duration')
|
||||
->integer()
|
||||
->columnSpan(['sm' => 2])
|
||||
->label(__('label.medal.duration'))
|
||||
->helperText(__('label.medal.duration_help')),
|
||||
Forms\Components\Textarea::make('description')->columnSpan(['sm' => 2])->label(__('label.description')),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -50,12 +59,12 @@ class MedalResource extends Resource
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('name'),
|
||||
Tables\Columns\ImageColumn::make('image_large')->height(120),
|
||||
Tables\Columns\ImageColumn::make('image_small')->height(120),
|
||||
Tables\Columns\TextColumn::make('getTypeText')->label('Get type'),
|
||||
Tables\Columns\TextColumn::make('price'),
|
||||
Tables\Columns\TextColumn::make('duration'),
|
||||
Tables\Columns\TextColumn::make('name')->label(__('label.name')),
|
||||
Tables\Columns\ImageColumn::make('image_large')->height(120)->label(__('label.medal.image_large')),
|
||||
Tables\Columns\ImageColumn::make('image_small')->height(120)->label(__('label.medal.image_small')),
|
||||
Tables\Columns\TextColumn::make('getTypeText')->label('Get type')->label(__('label.medal.get_type')),
|
||||
Tables\Columns\TextColumn::make('price')->label(__('label.price')),
|
||||
Tables\Columns\TextColumn::make('duration')->label(__('label.medal.duration')),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
|
||||
@@ -35,14 +35,14 @@ class TagResource extends Resource
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')->required(),
|
||||
Forms\Components\TextInput::make('color')->required()->label('Background color'),
|
||||
Forms\Components\TextInput::make('font_color')->required(),
|
||||
Forms\Components\TextInput::make('font_size')->required(),
|
||||
Forms\Components\TextInput::make('margin')->required(),
|
||||
Forms\Components\TextInput::make('padding')->required(),
|
||||
Forms\Components\TextInput::make('border_radius')->required(),
|
||||
Forms\Components\TextInput::make('priority')->integer(),
|
||||
Forms\Components\TextInput::make('name')->required()->label(__('label.name')),
|
||||
Forms\Components\TextInput::make('color')->required()->label(__('label.tag.color')),
|
||||
Forms\Components\TextInput::make('font_color')->required()->label(__('label.tag.font_color')),
|
||||
Forms\Components\TextInput::make('font_size')->required()->label(__('label.tag.font_size')),
|
||||
Forms\Components\TextInput::make('margin')->required()->label(__('label.tag.margin')),
|
||||
Forms\Components\TextInput::make('padding')->required()->label(__('label.tag.padding')),
|
||||
Forms\Components\TextInput::make('border_radius')->required()->label(__('label.tag.border_radius')),
|
||||
Forms\Components\TextInput::make('priority')->integer()->label(__('label.priority')),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -51,15 +51,15 @@ class TagResource extends Resource
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('name'),
|
||||
Tables\Columns\TextColumn::make('color')->label('Background color'),
|
||||
Tables\Columns\TextColumn::make('font_color'),
|
||||
Tables\Columns\TextColumn::make('font_size'),
|
||||
Tables\Columns\TextColumn::make('margin'),
|
||||
Tables\Columns\TextColumn::make('padding'),
|
||||
Tables\Columns\TextColumn::make('border_radius'),
|
||||
Tables\Columns\TextColumn::make('priority'),
|
||||
Tables\Columns\TextColumn::make('updated_at')->dateTime('Y-m-d H:i'),
|
||||
Tables\Columns\TextColumn::make('name')->label(__('label.name')),
|
||||
Tables\Columns\TextColumn::make('color')->label(__('label.tag.color')),
|
||||
Tables\Columns\TextColumn::make('font_color')->label(__('label.tag.font_color')),
|
||||
Tables\Columns\TextColumn::make('font_size')->label(__('label.tag.font_size')),
|
||||
Tables\Columns\TextColumn::make('margin')->label(__('label.tag.margin')),
|
||||
Tables\Columns\TextColumn::make('padding')->label(__('label.tag.padding')),
|
||||
Tables\Columns\TextColumn::make('border_radius')->label(__('label.tag.border_radius')),
|
||||
Tables\Columns\TextColumn::make('priority')->label(__('label.priority')),
|
||||
Tables\Columns\TextColumn::make('updated_at')->dateTime()->label(__('label.updated_at')),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
|
||||
@@ -48,15 +48,17 @@ class ExamUserResource extends Resource
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('user.username')->label('User')->searchable(),
|
||||
Tables\Columns\TextColumn::make('exam.name')->label('Exam'),
|
||||
Tables\Columns\BooleanColumn::make('is_done')->label('Is done'),
|
||||
Tables\Columns\TextColumn::make('statusText')->label('Status'),
|
||||
Tables\Columns\TextColumn::make('created_at')->dateTime('Y-m-d H:i'),
|
||||
Tables\Columns\TextColumn::make('user.username')->label(__('label.username'))->searchable(),
|
||||
Tables\Columns\TextColumn::make('exam.name')->label(__('label.exam.label')),
|
||||
Tables\Columns\TextColumn::make('begin')->label(__('label.begin'))->dateTime(),
|
||||
Tables\Columns\TextColumn::make('end')->label(__('label.end'))->dateTime(),
|
||||
Tables\Columns\BooleanColumn::make('is_done')->label(__('label.exam.is_done')),
|
||||
Tables\Columns\TextColumn::make('statusText')->label(__('label.status')),
|
||||
Tables\Columns\TextColumn::make('created_at')->dateTime()->label(__('label.created_at')),
|
||||
])
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('status')->options(ExamUser::listStatus(true)),
|
||||
Tables\Filters\SelectFilter::make('is_done')->options(['0' => 'No', '1' => 'yes']),
|
||||
Tables\Filters\SelectFilter::make('status')->options(ExamUser::listStatus(true))->label(__("label.status")),
|
||||
Tables\Filters\SelectFilter::make('is_done')->options(['0' => 'No', '1' => 'yes'])->label(__('label.exam.is_done')),
|
||||
])
|
||||
->actions([
|
||||
// Tables\Actions\ViewAction::make(),
|
||||
@@ -68,6 +70,8 @@ class ExamUserResource extends Resource
|
||||
$rep->avoidExamUserBulk(['id' => $idArr], Auth::user());
|
||||
})
|
||||
->deselectRecordsAfterCompletion()
|
||||
->label(__('admin.resources.exam_user.bulk_action_avoid_label'))
|
||||
->icon('heroicon-o-x')
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,17 +52,17 @@ class HitAndRunResource extends Resource
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('user.username')->searchable(),
|
||||
Tables\Columns\TextColumn::make('torrent.name')->limit(50),
|
||||
Tables\Columns\TextColumn::make('snatch.uploadText')->label('Uploaded'),
|
||||
Tables\Columns\TextColumn::make('snatch.downloadText')->label('Downloaded'),
|
||||
Tables\Columns\TextColumn::make('snatch.shareRatio')->label('Ratio'),
|
||||
Tables\Columns\TextColumn::make('seedTimeRequired'),
|
||||
Tables\Columns\TextColumn::make('inspectTimeLeft'),
|
||||
Tables\Columns\TextColumn::make('statusText')->label('Status'),
|
||||
Tables\Columns\TextColumn::make('user.username')->searchable()->label(__('label.username')),
|
||||
Tables\Columns\TextColumn::make('torrent.name')->limit(50)->label(__('label.torrent.label')),
|
||||
Tables\Columns\TextColumn::make('snatch.uploadText')->label(__('label.uploaded')),
|
||||
Tables\Columns\TextColumn::make('snatch.downloadText')->label(__('label.downloaded')),
|
||||
Tables\Columns\TextColumn::make('snatch.shareRatio')->label(__('label.ratio')),
|
||||
Tables\Columns\TextColumn::make('seedTimeRequired')->label(__('label.seed_time_required')),
|
||||
Tables\Columns\TextColumn::make('inspectTimeLeft')->label(__('label.inspect_time_left')),
|
||||
Tables\Columns\TextColumn::make('statusText')->label(__('label.status')),
|
||||
])
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('status')->options(HitAndRun::listStatus(true)),
|
||||
Tables\Filters\SelectFilter::make('status')->options(HitAndRun::listStatus(true))->label(__('label.status')),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\ViewAction::make(),
|
||||
|
||||
78
app/Filament/Resources/User/UserMedalResource.php
Normal file
78
app/Filament/Resources/User/UserMedalResource.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User;
|
||||
|
||||
use App\Filament\Resources\User\UserMedalResource\Pages;
|
||||
use App\Filament\Resources\User\UserMedalResource\RelationManagers;
|
||||
use App\Models\UserMedal;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class UserMedalResource extends Resource
|
||||
{
|
||||
protected static ?string $model = UserMedal::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-flag';
|
||||
|
||||
protected static ?string $navigationGroup = 'User';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.users_medal');
|
||||
}
|
||||
|
||||
public static function getBreadcrumb(): string
|
||||
{
|
||||
return self::getNavigationLabel();
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
//
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('user.username')->label(__('label.username'))->searchable(),
|
||||
Tables\Columns\TextColumn::make('medal.name')->label(__('label.medal.label'))->searchable(),
|
||||
Tables\Columns\ImageColumn::make('medal.image_large')->label(__('label.image')),
|
||||
Tables\Columns\TextColumn::make('expire_at')->label(__('label.expire_at'))->dateTime(),
|
||||
])
|
||||
->filters([
|
||||
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListUserMedals::route('/'),
|
||||
'create' => Pages\CreateUserMedal::route('/create'),
|
||||
'edit' => Pages\EditUserMedal::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\UserMedalResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\UserMedalResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateUserMedal extends CreateRecord
|
||||
{
|
||||
protected static string $resource = UserMedalResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\UserMedalResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\UserMedalResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditUserMedal extends EditRecord
|
||||
{
|
||||
protected static string $resource = UserMedalResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\UserMedalResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\User\UserMedalResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListUserMedals extends PageList
|
||||
{
|
||||
protected static string $resource = UserMedalResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
// Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Filament\Resources\User;
|
||||
|
||||
use App\Filament\OptionsTrait;
|
||||
use App\Filament\Resources\User\UserResource\Pages;
|
||||
use App\Filament\Resources\User\UserResource\RelationManagers;
|
||||
use App\Models\User;
|
||||
@@ -17,6 +18,8 @@ use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class UserResource extends Resource
|
||||
{
|
||||
use OptionsTrait;
|
||||
|
||||
protected static ?string $model = User::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-users';
|
||||
@@ -51,27 +54,27 @@ class UserResource extends Resource
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')->sortable(),
|
||||
Tables\Columns\TextColumn::make('username')->searchable(),
|
||||
Tables\Columns\TextColumn::make('email')->searchable(),
|
||||
Tables\Columns\TextColumn::make('username')->searchable()->label(__("label.user.username")),
|
||||
Tables\Columns\TextColumn::make('email')->searchable()->label(__("label.email")),
|
||||
Tables\Columns\TextColumn::make('class')->label('Class')
|
||||
->formatStateUsing(fn(Tables\Columns\Column $column) => $column->getRecord()->classText)
|
||||
->sortable(),
|
||||
->sortable()->label(__("label.user.class")),
|
||||
Tables\Columns\TextColumn::make('uploaded')->label('Uploaded')
|
||||
->formatStateUsing(fn(Tables\Columns\Column $column) => $column->getRecord()->uploadedText)
|
||||
->sortable(),
|
||||
->sortable()->label(__("label.uploaded")),
|
||||
Tables\Columns\TextColumn::make('downloaded')->label('Downloaded')
|
||||
->formatStateUsing(fn(Tables\Columns\Column $column) => $column->getRecord()->downloadedText)
|
||||
->sortable(),
|
||||
Tables\Columns\BadgeColumn::make('status')->colors(['success' => 'confirmed', 'warning' => 'pending']),
|
||||
Tables\Columns\BadgeColumn::make('enabled')->colors(['success' => 'yes', 'danger' => 'no']),
|
||||
Tables\Columns\TextColumn::make('added')->sortable()->dateTime('Y-m-d H:i'),
|
||||
Tables\Columns\TextColumn::make('last_access')->dateTime('Y-m-d H:i'),
|
||||
->sortable()->label(__("label.downloaded")),
|
||||
Tables\Columns\BadgeColumn::make('status')->colors(['success' => 'confirmed', 'warning' => 'pending'])->label(__("label.user.status")),
|
||||
Tables\Columns\BadgeColumn::make('enabled')->colors(['success' => 'yes', 'danger' => 'no'])->label(__("label.user.enabled")),
|
||||
Tables\Columns\TextColumn::make('added')->sortable()->dateTime('Y-m-d H:i')->label(__("label.added")),
|
||||
Tables\Columns\TextColumn::make('last_access')->dateTime('Y-m-d H:i')->label(__("label.last_access")),
|
||||
])
|
||||
->defaultSort('added', 'desc')
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('class')->options(array_column(User::$classes, 'text')),
|
||||
Tables\Filters\SelectFilter::make('status')->options(['confirmed' => 'confirmed', 'pending' => 'pending']),
|
||||
Tables\Filters\SelectFilter::make('enabled')->options(['enabled' => 'enabled', 'disabled' => 'disabled']),
|
||||
Tables\Filters\SelectFilter::make('class')->options(array_column(User::$classes, 'text'))->label(__('label.user.class')),
|
||||
Tables\Filters\SelectFilter::make('status')->options(['confirmed' => 'confirmed', 'pending' => 'pending'])->label(__('label.user.status')),
|
||||
Tables\Filters\SelectFilter::make('enabled')->options(self::$yesOrNo)->label(__('label.user.enabled')),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\ViewAction::make(),
|
||||
@@ -84,7 +87,7 @@ class UserResource extends Resource
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
// RelationManagers\MedalsRelationManager::class,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -3,27 +3,215 @@
|
||||
namespace App\Filament\Resources\User\UserResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\UserResource;
|
||||
use App\Models\Medal;
|
||||
use App\Models\User;
|
||||
use App\Repositories\ExamRepository;
|
||||
use App\Repositories\UserRepository;
|
||||
use Filament\Resources\Pages\Concerns\HasRelationManagers;
|
||||
use Filament\Resources\Pages\Concerns\InteractsWithRecord;
|
||||
use Filament\Resources\Pages\Page;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Forms;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UserProfile extends Page
|
||||
{
|
||||
use InteractsWithRecord;
|
||||
use HasRelationManagers;
|
||||
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
protected static string $view = 'filament.resources.user.user-resource.pages.user-profile';
|
||||
|
||||
protected ?User $user;
|
||||
const EVENT_RECORD_UPDATED = 'recordUpdated';
|
||||
|
||||
protected $listeners = [
|
||||
self::EVENT_RECORD_UPDATED => 'updateRecord'
|
||||
];
|
||||
|
||||
public function updateRecord($id)
|
||||
{
|
||||
$this->record = $this->resolveRecord($id);
|
||||
}
|
||||
|
||||
public function mount($record)
|
||||
{
|
||||
$this->user = User::query()->with(['inviter'])->findOrFail($record);
|
||||
$this->updateRecord($record);
|
||||
}
|
||||
|
||||
protected function getViewData(): array
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
'user' => $this->user,
|
||||
];
|
||||
$actions = [];
|
||||
if ($this->record->two_step_secret) {
|
||||
$actions[] = $this->buildDisableTwoStepAuthenticationAction();
|
||||
}
|
||||
$actions[] = $this->buildResetPasswordAction();
|
||||
$actions[] = $this->buildAssignExamAction();
|
||||
$actions[] = $this->buildGrantMedalAction();
|
||||
$actions[] = $this->buildChangeBonusEtcAction();
|
||||
$actions[] = $this->buildEnableDisableAction();
|
||||
return $actions;
|
||||
}
|
||||
|
||||
private function buildEnableDisableAction(): Actions\Action
|
||||
{
|
||||
return Actions\Action::make($this->record->enabled == 'yes' ? __('admin.resources.user.actions.disable_modal_btn') : __('admin.resources.user.actions.enable_modal_btn'))
|
||||
->modalHeading($this->record->enabled == 'yes' ? __('admin.resources.user.actions.disable_modal_title') : __('admin.resources.user.actions.enable_modal_title'))
|
||||
->form([
|
||||
Forms\Components\TextInput::make('reason')->label(__('admin.resources.user.actions.enable_disable_reason'))->placeholder(__('admin.resources.user.actions.enable_disable_reason_placeholder')),
|
||||
Forms\Components\Hidden::make('action')->default($this->record->enabled == 'yes' ? 'disable' : 'enable'),
|
||||
Forms\Components\Hidden::make('uid')->default($this->record->id),
|
||||
])
|
||||
->action(function ($data) {
|
||||
$userRep = new UserRepository();
|
||||
try {
|
||||
if ($data['action'] == 'enable') {
|
||||
$userRep->enableUser(Auth::user(), $data['uid'], $data['reason']);
|
||||
} elseif ($data['action'] == 'disable') {
|
||||
$userRep->disableUser(Auth::user(), $data['uid'], $data['reason']);
|
||||
}
|
||||
$this->notify('success', 'Success!');
|
||||
$this->emitSelf(self::EVENT_RECORD_UPDATED, $data['uid']);
|
||||
} catch (\Exception $exception) {
|
||||
$this->notify('danger', $exception->getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function buildDisableTwoStepAuthenticationAction(): Actions\Action
|
||||
{
|
||||
return Actions\Action::make(__('admin.resources.user.actions.disable_two_step_authentication'))
|
||||
->modalHeading(__('admin.resources.user.actions.disable_two_step_authentication'))
|
||||
->requiresConfirmation()
|
||||
->action(function ($data) {
|
||||
$userRep = new UserRepository();
|
||||
try {
|
||||
$userRep->removeTwoStepAuthentication(Auth::user(), $this->record->id);
|
||||
$this->notify('success', 'Success!');
|
||||
$this->emitSelf(self::EVENT_RECORD_UPDATED, $this->record->id);
|
||||
} catch (\Exception $exception) {
|
||||
$this->notify('danger', $exception->getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function buildChangeBonusEtcAction(): Actions\Action
|
||||
{
|
||||
return Actions\Action::make(__('admin.resources.user.actions.change_bonus_etc_btn'))
|
||||
->modalHeading(__('admin.resources.user.actions.change_bonus_etc_btn'))
|
||||
->form([
|
||||
Forms\Components\Radio::make('field')->options([
|
||||
'uploaded' => __('label.user.uploaded'),
|
||||
'downloaded' => __('label.user.downloaded'),
|
||||
'invites' => __('label.user.invites'),
|
||||
'seedbonus' => __('label.user.seedbonus'),
|
||||
'attendance_card' => __('label.user.attendance_card'),
|
||||
])->label(__('admin.resources.user.actions.change_bonus_etc_field_label'))->inline()->required(),
|
||||
Forms\Components\Radio::make('action')->options([
|
||||
'Increment' => __("admin.resources.user.actions.change_bonus_etc_action_increment"),
|
||||
'Decrement' => __("admin.resources.user.actions.change_bonus_etc_action_decrement"),
|
||||
])->label(__('admin.resources.user.actions.change_bonus_etc_action_label'))->inline()->required(),
|
||||
Forms\Components\TextInput::make('value')->integer()->required()
|
||||
->label(__('admin.resources.user.actions.change_bonus_etc_value_label'))
|
||||
->helperText(__('admin.resources.user.actions.change_bonus_etc_value_help')),
|
||||
Forms\Components\Textarea::make('reason')->label(__('admin.resources.user.actions.change_bonus_etc_reason_label')),
|
||||
])
|
||||
->action(function ($data) {
|
||||
$userRep = new UserRepository();
|
||||
try {
|
||||
$userRep->incrementDecrement(Auth::user(), $this->record->id, $data['action'], $data['field'], $data['value'], $data['reason']);
|
||||
$this->notify('success', 'Success!');
|
||||
$this->emitSelf(self::EVENT_RECORD_UPDATED, $this->record->id);
|
||||
} catch (\Exception $exception) {
|
||||
$this->notify('danger', $exception->getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function buildResetPasswordAction()
|
||||
{
|
||||
return Actions\Action::make(__('admin.resources.user.actions.reset_password_btn'))
|
||||
->modalHeading(__('admin.resources.user.actions.reset_password_btn'))
|
||||
->form([
|
||||
Forms\Components\TextInput::make('password')->label(__('admin.resources.user.actions.reset_password_label'))->required(),
|
||||
Forms\Components\TextInput::make('password_confirmation')
|
||||
->label(__('admin.resources.user.actions.reset_password_confirmation_label'))
|
||||
->same('password')
|
||||
->required(),
|
||||
])
|
||||
->action(function ($data) {
|
||||
$userRep = new UserRepository();
|
||||
try {
|
||||
$userRep->resetPassword($this->record->id, $data['password'], $data['password_confirmation']);
|
||||
$this->notify('success', 'Success!');
|
||||
$this->emitSelf(self::EVENT_RECORD_UPDATED, $this->record->id);
|
||||
} catch (\Exception $exception) {
|
||||
$this->notify('danger', $exception->getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function buildAssignExamAction()
|
||||
{
|
||||
return Actions\Action::make(__('admin.resources.user.actions.assign_exam_btn'))
|
||||
->modalHeading(__('admin.resources.user.actions.assign_exam_btn'))
|
||||
->form([
|
||||
Forms\Components\Select::make('exam_id')
|
||||
->options((new ExamRepository())->listMatchExam($this->record->id)->pluck('name', 'id'))
|
||||
->label(__('admin.resources.user.actions.assign_exam_exam_label'))->required(),
|
||||
Forms\Components\DateTimePicker::make('begin')->label(__('admin.resources.user.actions.assign_exam_begin_label')),
|
||||
Forms\Components\DateTimePicker::make('end')->label(__('admin.resources.user.actions.assign_exam_end_label'))
|
||||
->helperText(__('admin.resources.user.actions.assign_exam_end_help')),
|
||||
|
||||
])
|
||||
->action(function ($data) {
|
||||
$examRep = new ExamRepository();
|
||||
try {
|
||||
$examRep->assignToUser($this->record->id, $data['exam_id'], $data['begin'], $data['end']);
|
||||
$this->notify('success', 'Success!');
|
||||
$this->emitSelf(self::EVENT_RECORD_UPDATED, $this->record->id);
|
||||
} catch (\Exception $exception) {
|
||||
$this->notify('danger', $exception->getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function buildGrantMedalAction()
|
||||
{
|
||||
return Actions\Action::make(__('admin.resources.user.actions.grant_medal_btn'))
|
||||
->modalHeading(__('admin.resources.user.actions.grant_medal_btn'))
|
||||
->form([
|
||||
Forms\Components\Select::make('medal_id')
|
||||
->options(Medal::query()->pluck('name', 'id'))
|
||||
->label(__('admin.resources.user.actions.grant_medal_medal_label'))
|
||||
->required(),
|
||||
|
||||
Forms\Components\TextInput::make('duration')
|
||||
->label(__('admin.resources.user.actions.grant_medal_duration_label'))
|
||||
->helperText(__('admin.resources.user.actions.grant_medal_duration_help'))
|
||||
->integer(),
|
||||
|
||||
])
|
||||
->action(function ($data) {
|
||||
$examRep = new ExamRepository();
|
||||
try {
|
||||
$examRep->assignToUser($this->record->id, $data['exam_id'], $data['begin'], $data['end']);
|
||||
$this->notify('success', 'Success!');
|
||||
$this->emitSelf(self::EVENT_RECORD_UPDATED, $this->record->id);
|
||||
} catch (\Exception $exception) {
|
||||
$this->notify('danger', $exception->getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// protected function getViewData(): array
|
||||
// {
|
||||
// return [
|
||||
// 'enableDisableAction' => $this->buildEnableDisableAction(),
|
||||
// ];
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\UserResource\RelationManagers;
|
||||
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class MedalsRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'medals';
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'name';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('name')->label(__('label.name')),
|
||||
Tables\Columns\ImageColumn::make('image_large')->label(__('label.image')),
|
||||
Tables\Columns\ImageColumn::make('expire_at')->label(__('label.expire_at')),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
// Tables\Actions\CreateAction::make(),
|
||||
])
|
||||
->actions([
|
||||
// Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ class ExamUser extends NexusModel
|
||||
|
||||
public function getStatusTextAttribute(): string
|
||||
{
|
||||
return self::$status[$this->status]['text'] ?? '';
|
||||
return nexus_trans('exam-user.status.' . $this->status);
|
||||
}
|
||||
|
||||
public function getIsDoneTextAttribute(): string
|
||||
|
||||
@@ -9,5 +9,14 @@ class UserMedal extends NexusModel
|
||||
const STATUS_NOT_WEARING = 0;
|
||||
const STATUS_WEARING = 1;
|
||||
|
||||
public function medal()
|
||||
{
|
||||
return $this->belongsTo(Medal::class, 'medal_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'uid');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ class UserRepository extends BaseRepository
|
||||
return true;
|
||||
}
|
||||
|
||||
public function enableUser(User $operator, $uid)
|
||||
public function enableUser(User $operator, $uid, $reason = '')
|
||||
{
|
||||
$targetUser = User::query()->findOrFail($uid, ['id', 'enabled', 'username', 'class']);
|
||||
if ($targetUser->enabled == User::ENABLED_YES) {
|
||||
@@ -194,7 +194,7 @@ class UserRepository extends BaseRepository
|
||||
$update['leechwarn'] = 'no';
|
||||
$update['leechwarnuntil'] = null;
|
||||
}
|
||||
$modCommentText = sprintf("%s - Enable by %s.", now()->format('Y-m-d'), $operator->username);
|
||||
$modCommentText = sprintf("%s - Enable by %s, reason: %s", now()->format('Y-m-d'), $operator->username, $reason);
|
||||
$targetUser->updateWithModComment($update, $modCommentText);
|
||||
do_log("user: $uid, $modCommentText, update: " . nexus_json_encode($update));
|
||||
return true;
|
||||
@@ -217,7 +217,7 @@ class UserRepository extends BaseRepository
|
||||
$fieldMap = [
|
||||
'uploaded' => 'uploaded',
|
||||
'downloaded' => 'downloaded',
|
||||
'bonus' => 'seedbonus',
|
||||
'seedbonus' => 'seedbonus',
|
||||
'invites' => 'invites',
|
||||
'attendance_card' => 'attendance_card',
|
||||
];
|
||||
|
||||
@@ -12,4 +12,45 @@ return [
|
||||
'medals_list' => 'Medals',
|
||||
'settings' => 'Settings',
|
||||
],
|
||||
'resources' => [
|
||||
'agent_allow' => [
|
||||
'check_modal_btn' => 'Check',
|
||||
'check_modal_header' => 'Detect if the client is allowed',
|
||||
'check_pass_msg' => 'Congratulations, this client was passed by rule :id!',
|
||||
],
|
||||
'user' => [
|
||||
'actions' => [
|
||||
'enable_modal_btn' => 'Enable',
|
||||
'enable_modal_title' => 'Enable user',
|
||||
'enable_disable_reason' => 'Reason',
|
||||
'enable_disable_reason_placeholder' => 'Optional',
|
||||
'disable_modal_btn' => 'Disable',
|
||||
'disable_modal_title' => 'Disable user',
|
||||
'disable_two_step_authentication' => 'Cancel two-step authentication',
|
||||
'change_bonus_etc_btn' => 'Change Uploaded etc.',
|
||||
'change_bonus_etc_action_increment' => 'Increment',
|
||||
'change_bonus_etc_action_decrement' => 'Decrement',
|
||||
'change_bonus_etc_field_label' => 'Field',
|
||||
'change_bonus_etc_action_label' => 'Action',
|
||||
'change_bonus_etc_value_label' => 'Value',
|
||||
'change_bonus_etc_value_help' => 'If the type is Uploaded/Download, the unit is: GB',
|
||||
'change_bonus_etc_reason_label' => 'Reason',
|
||||
'reset_password_btn' => 'Reset password',
|
||||
'reset_password_label' => 'New password',
|
||||
'reset_password_confirmation_label' => 'Confirm new password',
|
||||
'assign_exam_btn' => 'Assign exam',
|
||||
'assign_exam_exam_label' => 'Select exam',
|
||||
'assign_exam_begin_label' => 'Begin time',
|
||||
'assign_exam_end_label' => 'End time',
|
||||
'assign_exam_end_help' => 'If you do not specify a begin/end time, the time range set by the exam itself will be used',
|
||||
'grant_medal_btn' => 'Grant medal',
|
||||
'grant_medal_medal_label' => 'Select medal',
|
||||
'grant_medal_duration_label' => 'Duration',
|
||||
'grant_medal_duration_help' => 'Unit: days. If left blank, the user has permanent possession',
|
||||
]
|
||||
],
|
||||
'exam_user' => [
|
||||
'bulk_action_avoid_label' => 'Bulk avoid',
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
@@ -36,6 +36,66 @@ return [
|
||||
]
|
||||
],
|
||||
'user' => [
|
||||
'uploaded' => 'Uploaded',
|
||||
'downloaded' => 'Downloaded',
|
||||
'invites' => 'Invites',
|
||||
'seedbonus' => 'Bonus',
|
||||
'attendance_card' => 'Attendance ard',
|
||||
'class' => 'Class',
|
||||
'status' => 'Status',
|
||||
'enabled' => 'Enabled',
|
||||
'username' => 'Username',
|
||||
],
|
||||
'medal' => [
|
||||
'label' => 'Medal',
|
||||
'image_large' => 'Image large',
|
||||
'image_small' => 'Image small',
|
||||
'get_type' => 'Get type',
|
||||
'duration' => 'Duration',
|
||||
'duration_help' => 'Unit: days. If left blank, the user has permanent possession',
|
||||
],
|
||||
'exam' => [
|
||||
'label' => 'Exam',
|
||||
'is_done' => 'Is done',
|
||||
'is_discovered' => 'Discovered',
|
||||
'register_time_range' => [
|
||||
'begin' => 'Register time begin',
|
||||
'end' => 'Register time end',
|
||||
],
|
||||
'donated' => 'Donated',
|
||||
'index_formatted' => 'Exam indexes',
|
||||
'filter_formatted' => 'Target users',
|
||||
],
|
||||
'torrent' => [
|
||||
'label' => 'Torrent',
|
||||
],
|
||||
'hit_and_run' => [
|
||||
|
||||
]
|
||||
],
|
||||
'tag' => [
|
||||
'color' => 'Background color',
|
||||
'font_color' => 'Font color',
|
||||
'font_size' => 'Font size',
|
||||
'margin' => 'Margin',
|
||||
'padding' => 'Padding',
|
||||
'border_radius' => 'Border radius',
|
||||
],
|
||||
'agent_allow' => [
|
||||
'family' => 'Family',
|
||||
'start_name' => 'Start name',
|
||||
'peer_id_start' => 'Peer ID start',
|
||||
'peer_id_pattern' => 'Peer ID pattern',
|
||||
'peer_id_matchtype' => 'Peer ID match type',
|
||||
'peer_id_match_num' => 'Peer ID match num',
|
||||
'agent_start' => 'Agent start',
|
||||
'agent_pattern' => 'Agent pattern',
|
||||
'agent_matchtype' => 'Agent match type',
|
||||
'agent_match_num' => 'Agent match num',
|
||||
'exception' => 'Exception',
|
||||
'allowhttps' => 'Allow https',
|
||||
],
|
||||
'agent_deny' => [
|
||||
'peer_id' => 'Peer ID',
|
||||
'agent' => 'Agent',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -11,5 +11,47 @@ return [
|
||||
'exams_list' => '考核',
|
||||
'medals_list' => '勋章',
|
||||
'settings' => '设置',
|
||||
'users_medal' => '用户勋章',
|
||||
],
|
||||
'resources' => [
|
||||
'agent_allow' => [
|
||||
'check_modal_btn' => '检测',
|
||||
'check_modal_header' => '检测客户端是否被允许',
|
||||
'check_pass_msg' => '恭喜,此客户端被规则 :id 通过!',
|
||||
],
|
||||
'user' => [
|
||||
'actions' => [
|
||||
'enable_modal_btn' => '启用',
|
||||
'enable_modal_title' => '启用用户',
|
||||
'enable_disable_reason' => '原因',
|
||||
'enable_disable_reason_placeholder' => '可选',
|
||||
'disable_modal_btn' => '禁用',
|
||||
'disable_modal_title' => '禁用用户',
|
||||
'disable_two_step_authentication' => '取消两步登录验证',
|
||||
'change_bonus_etc_btn' => '修改上传量等',
|
||||
'change_bonus_etc_action_increment' => '增加',
|
||||
'change_bonus_etc_action_decrement' => '减少',
|
||||
'change_bonus_etc_field_label' => '类别',
|
||||
'change_bonus_etc_action_label' => '动作',
|
||||
'change_bonus_etc_value_label' => '数量',
|
||||
'change_bonus_etc_value_help' => '如果类别是上传量/下载量,单位为:GB',
|
||||
'change_bonus_etc_reason_label' => '原因',
|
||||
'reset_password_btn' => '重置密码',
|
||||
'reset_password_label' => '新密码',
|
||||
'reset_password_confirmation_label' => '确认新密码',
|
||||
'assign_exam_btn' => '分配考核',
|
||||
'assign_exam_exam_label' => '选择考核',
|
||||
'assign_exam_begin_label' => '开始时间',
|
||||
'assign_exam_end_label' => '结束时间',
|
||||
'assign_exam_end_help' => '如果不指定开始/结束时间,将使用考核本身设定的时间范围',
|
||||
'grant_medal_btn' => '授予勋章',
|
||||
'grant_medal_medal_label' => '选择勋章',
|
||||
'grant_medal_duration_label' => '有效时长',
|
||||
'grant_medal_duration_help' => '单位:天。如果留空,用户永久拥有',
|
||||
]
|
||||
],
|
||||
'exam_user' => [
|
||||
'bulk_action_avoid_label' => '批量免除',
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
@@ -1,6 +1,28 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'name' => '名称',
|
||||
'email' => '邮箱',
|
||||
'image' => '图片',
|
||||
'expire_at' => '过期时间',
|
||||
'username' => '用户',
|
||||
'status' => '状态',
|
||||
'created_at' => '创建时间',
|
||||
'updated_at' => '更新时间',
|
||||
'begin' => '开始时间',
|
||||
'end' => '结束时间',
|
||||
'uploaded' => '上传量',
|
||||
'downloaded' => '下载量',
|
||||
'ratio' => '分享率',
|
||||
'seed_time_required' => '还需做种时间',
|
||||
'inspect_time_left' => '考察剩余时间',
|
||||
'added' => '添加时间',
|
||||
'last_access' => '最后访问时间',
|
||||
'priority' => '优先级',
|
||||
'comment' => '备注',
|
||||
'duration' => '时长',
|
||||
'description' => '描述',
|
||||
'price' => '价格',
|
||||
'setting' => [
|
||||
'nav_text' => '设置',
|
||||
'backup' => [
|
||||
@@ -36,6 +58,66 @@ return [
|
||||
]
|
||||
],
|
||||
'user' => [
|
||||
'uploaded' => '上传量',
|
||||
'downloaded' => '下载量',
|
||||
'invites' => '邀请',
|
||||
'seedbonus' => '魔力',
|
||||
'attendance_card' => '补签卡',
|
||||
'class' => '等级',
|
||||
'status' => '状态',
|
||||
'enabled' => '启用',
|
||||
'username' => '用户名',
|
||||
],
|
||||
'medal' => [
|
||||
'label' => '勋章',
|
||||
'image_large' => '大图',
|
||||
'image_small' => '小图',
|
||||
'get_type' => '获取方式',
|
||||
'duration' => '有效时长',
|
||||
'duration_help' => '单位:天。如果留空,用户永久拥有',
|
||||
],
|
||||
'exam' => [
|
||||
'label' => '考核',
|
||||
'is_done' => '是否完成',
|
||||
'is_discovered' => '自动发现',
|
||||
'register_time_range' => [
|
||||
'begin' => '注册时间开始',
|
||||
'end' => '注册时间结束',
|
||||
],
|
||||
'donated' => '是否捐赠',
|
||||
'index_formatted' => '考核指标',
|
||||
'filter_formatted' => '目标用户',
|
||||
],
|
||||
'torrent' => [
|
||||
'label' => '种子',
|
||||
],
|
||||
'hit_and_run' => [
|
||||
|
||||
]
|
||||
],
|
||||
'tag' => [
|
||||
'color' => '背景颜色',
|
||||
'font_color' => '字体颜色',
|
||||
'font_size' => '字体大小',
|
||||
'margin' => '外边距',
|
||||
'padding' => '内边距',
|
||||
'border_radius' => '边框圆角',
|
||||
],
|
||||
'agent_allow' => [
|
||||
'family' => '系列',
|
||||
'start_name' => '起始名称',
|
||||
'peer_id_start' => 'Peer ID 超始',
|
||||
'peer_id_pattern' => 'Peer ID 正则',
|
||||
'peer_id_matchtype' => 'Peer ID 匹配类型',
|
||||
'peer_id_match_num' => 'Peer ID 匹配次数',
|
||||
'agent_start' => 'Agent 起始',
|
||||
'agent_pattern' => 'Agent 正则',
|
||||
'agent_matchtype' => 'Agent 匹配类型',
|
||||
'agent_match_num' => 'Agent 匹配次数',
|
||||
'exception' => '排除',
|
||||
'allowhttps' => '允许 https',
|
||||
],
|
||||
'agent_deny' => [
|
||||
'peer_id' => 'Peer ID',
|
||||
'agent' => 'Agent',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -11,5 +11,47 @@ return [
|
||||
'exams_list' => '考核',
|
||||
'medals_list' => '勛章',
|
||||
'settings' => '設置',
|
||||
'users_medal' => '用戶勛章',
|
||||
],
|
||||
'resources' => [
|
||||
'agent_allow' => [
|
||||
'check_modal_btn' => '檢測',
|
||||
'check_modal_header' => '檢測客戶端是否被允許',
|
||||
'check_pass_msg' => '恭喜,此客戶端被規則 :id 通過!',
|
||||
],
|
||||
'user' => [
|
||||
'actions' => [
|
||||
'enable_modal_btn' => '啟用',
|
||||
'enable_modal_title' => '啟用用戶',
|
||||
'enable_disable_reason' => '原因',
|
||||
'enable_disable_reason_placeholder' => '可選',
|
||||
'disable_modal_btn' => '禁用',
|
||||
'disable_modal_title' => '禁用用戶',
|
||||
'disable_two_step_authentication' => '取消兩步登錄驗證',
|
||||
'change_bonus_etc_btn' => '修改上傳量等',
|
||||
'change_bonus_etc_action_increment' => '增加',
|
||||
'change_bonus_etc_action_decrement' => '減少',
|
||||
'change_bonus_etc_field_label' => '類別',
|
||||
'change_bonus_etc_action_label' => '動作',
|
||||
'change_bonus_etc_value_label' => '數量',
|
||||
'change_bonus_etc_value_help' => '如果類別是上傳量/下載量,單位為:GB',
|
||||
'change_bonus_etc_reason_label' => '原因',
|
||||
'reset_password_btn' => '重置密碼',
|
||||
'reset_password_label' => '新密碼',
|
||||
'reset_password_confirmation_label' => '確認新密碼',
|
||||
'assign_exam_btn' => '分配考核',
|
||||
'assign_exam_exam_label' => '選擇考核',
|
||||
'assign_exam_begin_label' => '開始時間',
|
||||
'assign_exam_end_label' => '結束時間',
|
||||
'assign_exam_end_help' => '如果不指定開始/結束時間,將使用考核本身設定的時間範圍',
|
||||
'grant_medal_btn' => '授予勛章',
|
||||
'grant_medal_medal_label' => '選擇勛章',
|
||||
'grant_medal_duration_label' => '有效時長',
|
||||
'grant_medal_duration_help' => '單位:天。如果留空,用戶永久擁有',
|
||||
]
|
||||
],
|
||||
'exam_user' => [
|
||||
'bulk_action_avoid_label' => '批量免除',
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
@@ -1,6 +1,28 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'name' => '名稱',
|
||||
'email' => '郵箱',
|
||||
'image' => '圖片',
|
||||
'expire_at' => '過期時間',
|
||||
'username' => '用戶',
|
||||
'status' => '狀態',
|
||||
'created_at' => '創建時間',
|
||||
'updated_at' => '更新時間',
|
||||
'begin' => '開始時間',
|
||||
'end' => '結束時間',
|
||||
'uploaded' => '上傳量',
|
||||
'downloaded' => '下載量',
|
||||
'ratio' => '分享率',
|
||||
'seed_time_required' => '還需做種時間',
|
||||
'inspect_time_left' => '考察剩余時間',
|
||||
'added' => '添加時間',
|
||||
'last_access' => '最後訪問時間',
|
||||
'priority' => '優先級',
|
||||
'comment' => '備註',
|
||||
'duration' => '時長',
|
||||
'description' => '描述',
|
||||
'price' => '價格',
|
||||
'setting' => [
|
||||
'nav_text' => '設置',
|
||||
'backup' => [
|
||||
@@ -36,6 +58,66 @@ return [
|
||||
]
|
||||
],
|
||||
'user' => [
|
||||
'uploaded' => '上傳量',
|
||||
'downloaded' => '下載量',
|
||||
'invites' => '邀請',
|
||||
'seedbonus' => '魔力',
|
||||
'attendance_card' => '補簽卡',
|
||||
'class' => '等級',
|
||||
'status' => '狀態',
|
||||
'enabled' => '啟用',
|
||||
'username' => '用戶名',
|
||||
],
|
||||
'medal' => [
|
||||
'label' => '勛章',
|
||||
'image_large' => '大圖',
|
||||
'image_small' => '小圖',
|
||||
'get_type' => '獲取方式',
|
||||
'duration' => '有效時長',
|
||||
'duration_help' => '單位:天。如果留空,用戶永久擁有',
|
||||
],
|
||||
'exam' => [
|
||||
'label' => '考核',
|
||||
'is_done' => '是否完成',
|
||||
'is_discovered' => '自動發現',
|
||||
'register_time_range' => [
|
||||
'begin' => '註冊時間開始',
|
||||
'end' => '註冊時間結束',
|
||||
],
|
||||
'donated' => '是否捐贈',
|
||||
'index_formatted' => '考核指標',
|
||||
'filter_formatted' => '目標用戶',
|
||||
],
|
||||
'torrent' => [
|
||||
'label' => '種子',
|
||||
],
|
||||
'hit_and_run' => [
|
||||
|
||||
]
|
||||
],
|
||||
'tag' => [
|
||||
'color' => '背景顏色',
|
||||
'font_color' => '字體顏色',
|
||||
'font_size' => '字體大小',
|
||||
'margin' => '外邊距',
|
||||
'padding' => '內邊距',
|
||||
'border_radius' => '邊框圓角',
|
||||
],
|
||||
'agent_allow' => [
|
||||
'family' => '系列',
|
||||
'start_name' => '起始名稱',
|
||||
'peer_id_start' => 'Peer ID 超始',
|
||||
'peer_id_pattern' => 'Peer ID 正則',
|
||||
'peer_id_matchtype' => 'Peer ID 匹配類型',
|
||||
'peer_id_match_num' => 'Peer ID 匹配次數',
|
||||
'agent_start' => 'Agent 起始',
|
||||
'agent_pattern' => 'Agent 正則',
|
||||
'agent_matchtype' => 'Agent 匹配類型',
|
||||
'agent_match_num' => 'Agent 匹配次數',
|
||||
'exception' => '排除',
|
||||
'allowhttps' => '允許 https',
|
||||
],
|
||||
'agent_deny' => [
|
||||
'peer_id' => 'Peer ID',
|
||||
'agent' => 'Agent',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -5,83 +5,83 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>UID</th>
|
||||
<td>{{$user->id}}</td>
|
||||
<td>{{$record->id}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<td>{{$user->username}}</td>
|
||||
<td>{{$record->username}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<td>{{$user->email}}</td>
|
||||
<td>{{$record->email}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<td>{{$user->status}}</td>
|
||||
<td>{{$record->status}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Enabled</th>
|
||||
<td>{{$user->enabled}}</td>
|
||||
<td><button class="border px-1 rounded">Disable</button></td>
|
||||
<td>{{$record->enabled}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Added</th>
|
||||
<td>{{$user->added}}</td>
|
||||
<td>{{$record->added}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Last access</th>
|
||||
<td>{{$user->last_access}}</td>
|
||||
<td>{{$record->last_access}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<td>{{$user->classText}}</td>
|
||||
<td>{{$record->classText}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Invite by</th>
|
||||
<td>{{$user->inviter->username ?? ''}}</td>
|
||||
<td><button class="border px-1 rounded">View</button></td>
|
||||
<td>{{$record->inviter->username ?? ''}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Tow-step authentication</th>
|
||||
<td>{{$user->two_step_secret ? 'Enabled' : 'Disabled'}}</td>
|
||||
<td><button class="border px-1 rounded">Disable</button></td>
|
||||
<td>{{$record->two_step_secret ? 'Enabled' : 'Disabled'}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Seed points</th>
|
||||
<td>{{$user->seed_points}}</td>
|
||||
<td><button class="border px-1 rounded">Change</button></td>
|
||||
<td>{{$record->seed_points}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Attendance card</th>
|
||||
<td>{{$user->attendance_card}}</td>
|
||||
<td><button class="border px-1 rounded">Change</button></td>
|
||||
<td>{{$record->attendance_card}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Invites</th>
|
||||
<td>{{$user->invites}}</td>
|
||||
<td><button class="border px-1 rounded">Change</button></td>
|
||||
<td>{{$record->invites}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Uploaded</th>
|
||||
<td>{{$user->uploadedText}}</td>
|
||||
<td><button class="border px-1 rounded">Change</button></td>
|
||||
<td>{{$record->uploadedText}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Downloaded</th>
|
||||
<td>{{$user->downloadedText}}</td>
|
||||
<td><button class="border px-1 rounded">Change</button></td>
|
||||
<td>{{$record->downloadedText}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Bonus</th>
|
||||
<td>{{$user->seedbonus}}</td>
|
||||
<td><button class="border px-1 rounded">Change</button></td>
|
||||
<td>{{$record->seedbonus}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -91,4 +91,10 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@if (count($relationManagers = $this->getRelationManagers()))
|
||||
<x-filament::hr />
|
||||
|
||||
<x-filament::resources.relation-managers :active-manager="$activeRelationManager" :managers="$relationManagers" :owner-record="$record" />
|
||||
@endif
|
||||
</x-filament::page>
|
||||
|
||||
@@ -1,40 +1,36 @@
|
||||
<x-filament::widget>
|
||||
<x-filament::card>
|
||||
<div class="p-2 space-y-2 bg-white rounded-xl shadow">
|
||||
<div class="space-y-2">
|
||||
<div class="px-4 py-2 space-y-4">
|
||||
<div class="flex items-center justify-between gap-8">
|
||||
<h2 class="text-xl font-semibold tracking-tight filament-card-heading">
|
||||
{{$header}}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div aria-hidden="true" class="border-t filament-hr"></div>
|
||||
|
||||
<div>
|
||||
<table class="w-full text-left rtl:text-right divide-y table-auto filament-tables-table">
|
||||
<tbody class="divide-y whitespace-nowrap">
|
||||
@foreach(array_chunk($data, 2) as $chunk)
|
||||
<tr class="filament-tables-row">
|
||||
@foreach($chunk as $item)
|
||||
<th class="filament-tables-cell"><div class="px-4 py-3 filament-tables-text-column">{{$item['text']}}</div></th>
|
||||
<td class="filament-tables-cell"
|
||||
@if($loop->count == 1)
|
||||
colspan="3"
|
||||
@endif
|
||||
>
|
||||
<div class="px-4 py-3 filament-tables-text-column">{{$item['value']}}</div>
|
||||
</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
<x-filament::widget class="filament-widgets-table-widget">
|
||||
<div class="p-2 space-y-2 bg-white rounded-xl shadow">
|
||||
<div class="space-y-2">
|
||||
<div class="px-4 py-2 space-y-4">
|
||||
<div class="flex items-center justify-between gap-8">
|
||||
<h2 class="text-xl font-semibold tracking-tight filament-card-heading">
|
||||
{{$header}}
|
||||
</h2>
|
||||
</div>
|
||||
<div aria-hidden="true" class="border-t filament-hr"></div>
|
||||
<div class="overflow-y-auto relative">
|
||||
<table class="w-full text-left rtl:text-right divide-y table-auto filament-tables-table">
|
||||
<tbody class="divide-y whitespace-nowrap">
|
||||
@foreach(array_chunk($data, 2) as $chunk)
|
||||
<tr class="filament-tables-row">
|
||||
@foreach($chunk as $item)
|
||||
<th class="filament-tables-cell"><div class="px-4 py-3 filament-tables-text-column">{{$item['text']}}</div></th>
|
||||
<td class="filament-tables-cell"
|
||||
@if($loop->count == 1)
|
||||
colspan="3"
|
||||
@endif
|
||||
>
|
||||
<div class="px-4 py-3 filament-tables-text-column">{{$item['value']}}</div>
|
||||
</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-filament::card>
|
||||
</div>
|
||||
</x-filament::widget>
|
||||
|
||||
Reference in New Issue
Block a user