Introduce filament

This commit is contained in:
xiaomlove
2022-06-27 01:39:01 +08:00
parent aae45835ee
commit 1aca20070d
92 changed files with 3535 additions and 83 deletions

View File

@@ -0,0 +1,81 @@
<?php
namespace App\Auth;
use Illuminate\Auth\GuardHelpers;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Http\Request;
class NexusWebGuard implements Guard
{
use GuardHelpers;
/**
* The request instance.
*
* @var \Illuminate\Http\Request
*/
protected $request;
/**
* Create a new authentication guard.
*
* @param callable $callback
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Contracts\Auth\UserProvider|null $provider
* @return void
*/
public function __construct(Request $request, UserProvider $provider = null)
{
$this->request = $request;
$this->provider = $provider;
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if (! is_null($this->user)) {
return $this->user;
}
return $this->user = $this->provider->retrieveByCredentials($this->request->cookie());
}
/**
* Validate a user's credentials.
*
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = [])
{
$required = ['c_secure_pass', 'c_secure_uid', 'c_secure_login'];
foreach ($required as $value) {
if (empty($credentials[$value])) {
return false;
}
}
$b_id = base64($credentials["c_secure_uid"],false);
$id = intval($b_id ?? 0);
if (!$id || !is_valid_id($id) || strlen($credentials["c_secure_pass"]) != 32) {
return false;
}
if ($this->provider->retrieveById($id)) {
return true;
}
return false;
}
public function logout()
{
logoutcookie();
return nexus_redirect('login.php');
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace App\Auth;
use App\Models\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
class NexusWebUserProvider implements UserProvider
{
/**
* @var \Illuminate\Database\Eloquent\Builder
*/
protected $query;
public function __construct()
{
$this->query = User::query();
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
return $this->query->find($identifier);
}
/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
}
/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $token
* @return void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
if (!empty($credentials['c_secure_uid'])) {
$b_id = base64($credentials["c_secure_uid"],false);
return $this->query->find($b_id);
}
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
if ($credentials["c_secure_login"] == base64("yeah")) {
if ($credentials["c_secure_pass"] != md5($user->passhash . $_SERVER["REMOTE_ADDR"])) {
return false;
}
} else {
if ($credentials["c_secure_pass"] !== md5($user->passhash)) {
return false;
}
}
return true;
}
}

View File

@@ -78,13 +78,10 @@ class Test extends Command
*/
public function handle()
{
$a = 2;
$b = 2;
if ($a != 1 && $b == 2) {
echo "OK";
} else {
echo 'Bad';
}
$r = 'MTAwNDI%3D';
$r = 'MTAwNDI%3D';
$r = 'MTAwMDM%3D';
dd(base64_decode($r));
}

View File

@@ -0,0 +1,10 @@
<?php
namespace App\Filament;
trait NexusOptionsTrait
{
private static array $matchTypes = ['dec' => 'dec', 'hex' => 'hex'];
private static array $yesOrNo = ['yes' => 'yes', 'no' => 'no'];
}

18
app/Filament/PageList.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
namespace App\Filament;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Model;
class PageList extends ListRecords
{
protected ?string $maxContentWidth = 'full';
protected function getTableRecordUrlUsing(): ?\Closure
{
return function (Model $record): ?string {
return null;
};
}
}

View File

@@ -0,0 +1,7 @@
<?php
namespace App\Filament\Pages;
class Dashboard extends \Filament\Pages\Dashboard
{
protected ?string $maxContentWidth = 'full';
}

View File

@@ -0,0 +1,90 @@
<?php
namespace App\Filament\Resources\System;
use App\Filament\NexusOptionsTrait;
use App\Filament\Resources\System\AgentAllowResource\Pages;
use App\Filament\Resources\System\AgentAllowResource\RelationManagers;
use App\Models\AgentAllow;
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 AgentAllowResource extends Resource
{
use NexusOptionsTrait;
protected static ?string $model = AgentAllow::class;
protected static ?string $navigationIcon = 'heroicon-o-check';
protected static ?string $navigationGroup = 'System';
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.agent_allows');
}
public static function form(Form $form): Form
{
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\Textarea::make('comment'),
]);
}
public static function table(Table $table): Table
{
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'),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
RelationManagers\DeniesRelationManager::class,
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListAgentAllows::route('/'),
'create' => Pages\CreateAgentAllow::route('/create'),
'edit' => Pages\EditAgentAllow::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\System\AgentAllowResource\Pages;
use App\Filament\Resources\System\AgentAllowResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateAgentAllow extends CreateRecord
{
protected static string $resource = AgentAllowResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\System\AgentAllowResource\Pages;
use App\Filament\Resources\System\AgentAllowResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditAgentAllow extends EditRecord
{
protected static string $resource = AgentAllowResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\System\AgentAllowResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\System\AgentAllowResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
class ListAgentAllows extends PageList
{
protected static string $resource = AgentAllowResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Filament\Resources\System\AgentAllowResource\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 DeniesRelationManager extends RelationManager
{
protected static string $relationship = 'denies';
protected static ?string $recordTitleAttribute = 'name';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')->required()->maxLength(255),
Forms\Components\TextInput::make('peer_id')->required()->maxLength(255),
Forms\Components\TextInput::make('agent')->required()->maxLength(255),
Forms\Components\Textarea::make('comment'),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('peer_id'),
Tables\Columns\TextColumn::make('agent'),
])
->filters([
//
])
->headerActions([
Tables\Actions\CreateAction::make(),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace App\Filament\Resources\System;
use App\Filament\Resources\System\AgentDenyResource\Pages;
use App\Filament\Resources\System\AgentDenyResource\RelationManagers;
use App\Models\AgentDeny;
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 AgentDenyResource extends Resource
{
protected static ?string $model = AgentDeny::class;
protected static ?string $navigationIcon = 'heroicon-o-ban';
protected static ?string $navigationGroup = 'System';
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.agent_denies');
}
public static function form(Form $form): Form
{
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'),
]);
}
public static function table(Table $table): Table
{
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(),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListAgentDenies::route('/'),
'create' => Pages\CreateAgentDeny::route('/create'),
'edit' => Pages\EditAgentDeny::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\System\AgentDenyResource\Pages;
use App\Filament\Resources\System\AgentDenyResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateAgentDeny extends CreateRecord
{
protected static string $resource = AgentDenyResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\System\AgentDenyResource\Pages;
use App\Filament\Resources\System\AgentDenyResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditAgentDeny extends EditRecord
{
protected static string $resource = AgentDenyResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\System\AgentDenyResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\System\AgentDenyResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
class ListAgentDenies extends PageList
{
protected static string $resource = AgentDenyResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,102 @@
<?php
namespace App\Filament\Resources\System;
use App\Filament\Resources\System\ExamResource\Pages;
use App\Filament\Resources\System\ExamResource\RelationManagers;
use App\Models\Exam;
use App\Repositories\UserRepository;
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 ExamResource extends Resource
{
protected static ?string $model = Exam::class;
protected static ?string $navigationIcon = 'heroicon-o-exclamation';
protected static ?string $navigationGroup = 'System';
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.exams_list');
}
public static function form(Form $form): Form
{
$userRep = new UserRepository();
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]),
])->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])
->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'),
])->columns(2),
Forms\Components\Textarea::make('description')->columnSpan(['sm' => 2]),
]);
}
public static function table(Table $table): Table
{
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'),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListExams::route('/'),
'create' => Pages\CreateExam::route('/create'),
'edit' => Pages\EditExam::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\System\ExamResource\Pages;
use App\Filament\Resources\System\ExamResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateExam extends CreateRecord
{
protected static string $resource = ExamResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\System\ExamResource\Pages;
use App\Filament\Resources\System\ExamResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditExam extends EditRecord
{
protected static string $resource = ExamResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\System\ExamResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\System\ExamResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
class ListExams extends PageList
{
protected static string $resource = ExamResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,81 @@
<?php
namespace App\Filament\Resources\System;
use App\Filament\Resources\System\MedalResource\Pages;
use App\Filament\Resources\System\MedalResource\RelationManagers;
use App\Models\Medal;
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 MedalResource extends Resource
{
protected static ?string $model = Medal::class;
protected static ?string $navigationIcon = 'heroicon-o-badge-check';
protected static ?string $navigationGroup = 'System';
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.medals_list');
}
public static function form(Form $form): Form
{
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]),
]);
}
public static function table(Table $table): Table
{
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'),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListMedals::route('/'),
'create' => Pages\CreateMedal::route('/create'),
'edit' => Pages\EditMedal::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\System\MedalResource\Pages;
use App\Filament\Resources\System\MedalResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateMedal extends CreateRecord
{
protected static string $resource = MedalResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\System\MedalResource\Pages;
use App\Filament\Resources\System\MedalResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditMedal extends EditRecord
{
protected static string $resource = MedalResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\System\MedalResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\System\MedalResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
class ListMedals extends PageList
{
protected static string $resource = MedalResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace App\Filament\Resources\System;
use App\Filament\NexusOptionsTrait;
use App\Filament\Resources\System\SettingResource\Pages;
use App\Filament\Resources\System\SettingResource\RelationManagers;
use App\Models\Setting;
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 SettingResource extends Resource
{
use NexusOptionsTrait;
protected static ?string $model = Setting::class;
protected static ?string $navigationIcon = 'heroicon-o-cog';
protected static ?string $navigationGroup = 'System';
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.settings');
}
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')->required()->disabled()->columnSpan(['sm' => 2]),
Forms\Components\Textarea::make('value')->required()->columnSpan(['sm' => 2])
->afterStateHydrated(function (Forms\Components\Textarea $component, $state) {
$arr = json_decode($state, true);
if (is_array($arr)) {
$component->disabled();
}
})
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('name')->searchable(),
Tables\Columns\TextColumn::make('value')->limit(),
Tables\Columns\BadgeColumn::make('autoload')->colors(['success' => 'yes', 'warning' => 'no']),
Tables\Columns\TextColumn::make('updated_at'),
])
->filters([
Tables\Filters\SelectFilter::make('autoload')->options(self::$yesOrNo),
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
// Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListSettings::route('/'),
// 'create' => Pages\CreateSetting::route('/create'),
'edit' => Pages\EditSetting::route('/{record}/edit'),
'hit-and-run' => Pages\EditHitAndRun::route('/hit-and-run'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\System\SettingResource\Pages;
use App\Filament\Resources\System\SettingResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateSetting extends CreateRecord
{
protected static string $resource = SettingResource::class;
}

View File

@@ -0,0 +1,15 @@
<?php
namespace App\Filament\Resources\System\SettingResource\Pages;
use App\Filament\Resources\System\SettingResource;
use Filament\Resources\Pages\Page;
class EditHitAndRun extends Page
{
protected static string $resource = SettingResource::class;
protected static string $view = 'filament.resources.system.setting-resource.pages.edit-hit-and-run';
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Filament\Resources\System\SettingResource\Pages;
use App\Filament\Resources\System\SettingResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditSetting extends EditRecord
{
protected static string $resource = SettingResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
protected function getRedirectUrl(): ?string
{
return $this->getResource()::getUrl('index');
}
protected function mutateFormDataBeforeSave(array $data): array
{
$arr = json_decode($data['value'], true);
if (is_array($arr)) {
throw new \LogicException("Not support edit this !");
}
return $data;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\System\SettingResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\System\SettingResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
class ListSettings extends PageList
{
protected static string $resource = SettingResource::class;
protected function getActions(): array
{
return [
// Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace App\Filament\Resources\Torrent;
use App\Filament\Resources\Torrent\TagResource\Pages;
use App\Filament\Resources\Torrent\TagResource\RelationManagers;
use App\Models\Tag;
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 TagResource extends Resource
{
protected static ?string $model = Tag::class;
protected static ?string $navigationIcon = 'heroicon-o-tag';
protected static ?string $navigationGroup = 'Torrent';
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.tags_list');
}
public static function form(Form $form): Form
{
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(),
]);
}
public static function table(Table $table): Table
{
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'),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListTags::route('/'),
'create' => Pages\CreateTag::route('/create'),
'edit' => Pages\EditTag::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace App\Filament\Resources\Torrent\TagResource\Pages;
use App\Filament\Resources\Torrent\TagResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateTag extends CreateRecord
{
protected static string $resource = TagResource::class;
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Filament\Resources\Torrent\TagResource\Pages;
use App\Filament\Resources\Torrent\TagResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditTag extends EditRecord
{
protected static string $resource = TagResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
protected function getRedirectUrl(): ?string
{
return $this->getResource()::getUrl('index');
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\Torrent\TagResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\Torrent\TagResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
class ListTags extends PageList
{
protected static string $resource = TagResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace App\Filament\Resources\User;
use App\Filament\Resources\User\ExamUserResource\Pages;
use App\Filament\Resources\User\ExamUserResource\RelationManagers;
use App\Models\ExamUser;
use App\Repositories\ExamRepository;
use App\Repositories\HitAndRunRepository;
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;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
class ExamUserResource extends Resource
{
protected static ?string $model = ExamUser::class;
protected static ?string $navigationIcon = 'heroicon-o-user';
protected static ?string $navigationGroup = 'User';
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.exam_users');
}
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('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'),
])
->filters([
Tables\Filters\SelectFilter::make('status')->options(ExamUser::listStatus(true)),
Tables\Filters\SelectFilter::make('is_done')->options(['0' => 'No', '1' => 'yes']),
])
->actions([
// Tables\Actions\ViewAction::make(),
])
->prependBulkActions([
Tables\Actions\BulkAction::make('Avoid')->action(function (Collection $records) {
$idArr = $records->pluck('id')->toArray();
$rep = new ExamRepository();
$rep->avoidExamUserBulk(['id' => $idArr], Auth::user());
})
->deselectRecordsAfterCompletion()
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListExamUsers::route('/'),
'create' => Pages\CreateExamUser::route('/create'),
'edit' => Pages\EditExamUser::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\User\ExamUserResource\Pages;
use App\Filament\Resources\User\ExamUserResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateExamUser extends CreateRecord
{
protected static string $resource = ExamUserResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\User\ExamUserResource\Pages;
use App\Filament\Resources\User\ExamUserResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditExamUser extends EditRecord
{
protected static string $resource = ExamUserResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\User\ExamUserResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\User\ExamUserResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
class ListExamUsers extends PageList
{
protected static string $resource = ExamUserResource::class;
protected function getActions(): array
{
return [
// Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace App\Filament\Resources\User;
use App\Filament\Resources\User\HitAndRunResource\Pages;
use App\Filament\Resources\User\HitAndRunResource\RelationManagers;
use App\Models\HitAndRun;
use App\Repositories\HitAndRunRepository;
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;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
class HitAndRunResource extends Resource
{
protected static ?string $model = HitAndRun::class;
protected static ?string $navigationIcon = 'heroicon-o-beaker';
protected static ?string $navigationGroup = 'User';
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.hit_and_runs');
}
public static function form(Form $form): Form
{
return $form
->schema(Forms\Components\Card::make()->schema([
// Forms\Components\Select::make('user')->relationship('user', 'username')->required(),
// Forms\Components\Select::make('torrent_id')->relationship('torrent', 'name')->required(),
Forms\Components\Radio::make('status')->options(HitAndRun::listStatus(true))->inline()->required(),
// Forms\Components\Select::make('snatch_id')->relationship('snatch', 'uploaded'),
Forms\Components\Textarea::make('comment'),
Forms\Components\DateTimePicker::make('created_at')->displayFormat('Y-m-d H:i:s'),
]));
}
public static function table(Table $table): Table
{
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'),
])
->filters([
Tables\Filters\SelectFilter::make('status')->options(HitAndRun::listStatus(true)),
])
->actions([
Tables\Actions\ViewAction::make(),
])
->prependBulkActions([
Tables\Actions\BulkAction::make('Pardon')->action(function (Collection $records) {
$idArr = $records->pluck('id')->toArray();
$rep = new HitAndRunRepository();
$rep->bulkPardon(['id' => $idArr], Auth::user());
})
->deselectRecordsAfterCompletion()
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListHitAndRuns::route('/'),
// 'create' => Pages\CreateHitAndRun::route('/create'),
// 'edit' => Pages\EditHitAndRun::route('/{record}/edit'),
'view' => Pages\ViewHitAndRun::route('/{record}'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\User\HitAndRunResource\Pages;
use App\Filament\Resources\User\HitAndRunResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateHitAndRun extends CreateRecord
{
protected static string $resource = HitAndRunResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\User\HitAndRunResource\Pages;
use App\Filament\Resources\User\HitAndRunResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditHitAndRun extends EditRecord
{
protected static string $resource = HitAndRunResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\User\HitAndRunResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\User\HitAndRunResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
class ListHitAndRuns extends PageList
{
protected static string $resource = HitAndRunResource::class;
protected function getActions(): array
{
return [
// Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Filament\Resources\User\HitAndRunResource\Pages;
use App\Filament\Resources\User\HitAndRunResource;
use App\Models\HitAndRun;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ViewRecord;
use Filament\Forms;
class ViewHitAndRun extends ViewRecord
{
protected static string $resource = HitAndRunResource::class;
protected function getFormSchema(): array
{
return [
Forms\Components\TextInput::make('id'),
Forms\Components\TextInput::make('uid'),
Forms\Components\Radio::make('status')->options(HitAndRun::listStatus(true))->inline(),
Forms\Components\Textarea::make('comment'),
Forms\Components\DateTimePicker::make('created_at'),
];
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace App\Filament\Resources\User;
use App\Filament\Resources\User\UserResource\Pages;
use App\Filament\Resources\User\UserResource\RelationManagers;
use App\Models\User;
use Filament\Forms;
use Filament\Forms\Components\Grid;
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 UserResource extends Resource
{
protected static ?string $model = User::class;
protected static ?string $navigationIcon = 'heroicon-o-users';
protected static ?string $navigationGroup = 'User';
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.users_list');
}
public static function form(Form $form): Form
{
return $form
->schema(Forms\Components\Card::make()->schema([
Forms\Components\TextInput::make('username')->required(),
Forms\Components\TextInput::make('email')->required(),
Forms\Components\TextInput::make('password')->password()->required(),
Forms\Components\TextInput::make('password_confirmation')->password()->required()->same('password'),
Forms\Components\TextInput::make('id')->integer(),
Forms\Components\Select::make('class')->options(array_column(User::$classes, 'text')),
]));
}
public static function table(Table $table): Table
{
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('class')->label('Class')
->formatStateUsing(fn(Tables\Columns\Column $column) => $column->getRecord()->classText)
->sortable(),
Tables\Columns\TextColumn::make('uploaded')->label('Uploaded')
->formatStateUsing(fn(Tables\Columns\Column $column) => $column->getRecord()->uploadedText)
->sortable(),
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'),
])
->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']),
])
->actions([
Tables\Actions\ViewAction::make(),
])
->bulkActions([
// Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListUsers::route('/'),
'create' => Pages\CreateUser::route('/create'),
// 'edit' => Pages\EditUser::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Filament\Resources\User\UserResource\Pages;
use App\Filament\Resources\User\UserResource;
use App\Repositories\UserRepository;
use Filament\Pages\Actions;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Database\Eloquent\Model;
class CreateUser extends CreateRecord
{
protected static string $resource = UserResource::class;
public function create(bool $another = false): void
{
$userRep = new UserRepository();
$data = $this->form->getState();
try {
$this->record = $userRep->store($data);
$this->notify(
'success ',
$this->getCreatedNotificationMessage(),
);
$this->redirect($this->getRedirectUrl());
} catch (\Exception $exception) {
$this->notify(
'danger',
$exception->getMessage(),
);
}
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\User\UserResource\Pages;
use App\Filament\Resources\User\UserResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditUser extends EditRecord
{
protected static string $resource = UserResource::class;
protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Filament\Resources\User\UserResource\Pages;
use App\Filament\PageList;
use App\Filament\Resources\User\UserResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Model;
class ListUsers extends PageList
{
protected static string $resource = UserResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
// public function isTableSearchable(): bool
// {
// return true;
// }
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Widgets;
use Filament\Widgets\Widget;
class AccountInfo extends Widget
{
protected static string $view = 'filament.widgets.account-info';
protected int | string | array $columnSpan = 'full';
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Filament\Widgets;
use App\Models\Torrent;
use Closure;
use Filament\Tables;
use Filament\Widgets\TableWidget as BaseWidget;
use Illuminate\Database\Eloquent\Builder;
class LatestTorrents extends BaseWidget
{
protected static ?int $sort = 2;
protected function getTableHeading(): string | Closure | null
{
return __('dashboard.latest_torrent.page_title');
}
protected function isTablePaginationEnabled(): bool
{
return false;
}
protected function getTableQuery(): Builder
{
return Torrent::query()->orderBy('id', 'desc')->limit(5);
}
protected function getTableColumns(): array
{
return [
Tables\Columns\TextColumn::make('name')->limit(40),
Tables\Columns\TextColumn::make('user.username'),
Tables\Columns\TextColumn::make('size')->formatStateUsing(fn ($state) => mksize($state)),
Tables\Columns\TextColumn::make('added')->dateTime(),
];
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Filament\Widgets;
use App\Models\User;
use Closure;
use Filament\Tables;
use Filament\Widgets\TableWidget as BaseWidget;
use Illuminate\Database\Eloquent\Builder;
class LatestUsers extends BaseWidget
{
protected static ?int $sort = 1;
protected function getTableHeading(): string | Closure | null
{
return __('dashboard.latest_user.page_title');
}
protected function isTablePaginationEnabled(): bool
{
return false;
}
protected function getTableQuery(): Builder
{
return User::query()->orderBy('id', 'desc')->limit(5);
}
protected function getTableColumns(): array
{
return [
Tables\Columns\TextColumn::make('username'),
Tables\Columns\TextColumn::make('email'),
Tables\Columns\BadgeColumn::make('status')->colors(['success' => 'confirmed', 'danger' => 'pending']),
Tables\Columns\TextColumn::make('added')->dateTime(),
];
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace App\Filament\Widgets;
use App\Models\Torrent;
use Carbon\Carbon;
use Filament\Widgets\LineChartWidget;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;
class TorrentTrend extends LineChartWidget
{
protected static ?int $sort = 4;
protected function getHeading(): ?string
{
return __('dashboard.torrent_trend.page_title');
}
protected function getData(): array
{
$data = Trend::model(Torrent::class)
->dateColumn('added')
->between(
start: now()->subDays(30),
end: now(),
)
->perDay()
->count();
return [
'datasets' => [
[
'label' => 'Torrent',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => Carbon::parse($value->date)->format('m-d')),
];
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Filament\Widgets;
use App\Models\Torrent;
use App\Models\User;
use Carbon\Carbon;
use Filament\Widgets\LineChartWidget;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;
class UserTrend extends LineChartWidget
{
protected static ?int $sort = 3;
protected function getHeading(): ?string
{
return __('dashboard.user_trend.page_title');
}
protected function getData(): array
{
$data = Trend::model(User::class)
->dateColumn('added')
->between(
start: now()->subDays(30),
end: now(),
)
->perDay()
->count();
return [
'datasets' => [
[
'label' => 'User',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => Carbon::parse($value->date)->format('m-d')),
];
}
}

View File

@@ -58,6 +58,7 @@ class Kernel extends HttpKernel
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.nexus' => \App\Http\Middleware\NexusAuth::class,
'auth.filament' => \Filament\Http\Middleware\Authenticate::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,

View File

@@ -12,6 +12,11 @@ class EncryptCookies extends Middleware
* @var array
*/
protected $except = [
//
'c_secure_pass',
'c_secure_uid',
'c_secure_login',
'c_secure_ssl',
'c_secure_tracker_ssl',
];
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Middleware;
use Filament\Http\Middleware\Authenticate;
class Filament extends Authenticate
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string|null
*/
protected function redirectTo($request): string
{
return getSchemeAndHttpHost() . '/login.php';
}
}

View File

@@ -4,6 +4,7 @@ namespace App\Http\Middleware;
use Carbon\Carbon;
use Closure;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\App;
@@ -26,15 +27,18 @@ class Locale
public function handle(Request $request, Closure $next)
{
$user = $request->user();
$language = $user->language;
$locale = self::$languageMaps[$language->site_lang_folder] ?? 'en';
do_log("user: {$user->id}, language: {$language->id}, set locale: $locale");
App::setLocale($locale);
Carbon::setLocale($locale);
if ($user) {
$language = $user->language;
$locale = self::$languageMaps[$language->site_lang_folder] ?? 'en';
do_log("user: {$user->id}, language: {$language->id}, set locale: $locale");
App::setLocale($locale);
Carbon::setLocale($locale);
}
/** @var Response $response */
$response = $next($request);
$response->header('Request-Id', nexus()->getRequestId())->header('Running-In-Octane', RUNNING_IN_OCTANE ? 1 : 0);
if ($response instanceof Response || $response instanceof JsonResponse) {
$response->header('Request-Id', nexus()->getRequestId())->header('Running-In-Octane', RUNNING_IN_OCTANE ? 1 : 0);
}
return $response;
}

View File

@@ -26,9 +26,9 @@ class ExamResource extends JsonResource
'duration' => $this->duration ?: '',
'duration_text' => $this->duration_text,
'filters' => $this->normalizeFilters($this->resource),
'filters_formatted' => $this->formatFilters($this->resource),
'filters_formatted' => $this->filterFormatted,
'indexes' => $this->indexes,
'indexes_formatted' => $this->formatIndexes($this->resource),
'indexes_formatted' => $this->indexFormatted,
'status' => $this->status,
'status_text' => $this->statusText,
'is_discovered' => $this->is_discovered,
@@ -48,50 +48,4 @@ class ExamResource extends JsonResource
return $filters;
}
private function formatFilters(Exam $exam)
{
$currentFilters = $exam->filters;
$arr = [];
$filter = Exam::FILTER_USER_CLASS;
if (!empty($currentFilters->{$filter})) {
$classes = collect(User::$classes)->only($currentFilters->{$filter});
$arr[] = sprintf('%s: %s', Exam::$filters[$filter]['name'], $classes->pluck('text')->implode(', '));
}
$filter = Exam::FILTER_USER_REGISTER_TIME_RANGE;
if (!empty($currentFilters->{$filter})) {
$range = $currentFilters->{$filter};
$arr[] = sprintf(
"%s: \n%s ~ %s",
Exam::$filters[$filter]['name'],
$range[0] ? Carbon::parse($range[0])->toDateTimeString() : '-',
$range[1] ? Carbon::parse($range[1])->toDateTimeString() : '-'
);
}
$filter = Exam::FILTER_USER_DONATE;
if (!empty($currentFilters->{$filter})) {
$donateStatus = $classes = collect(User::$donateStatus)->only($currentFilters->{$filter});
$arr[] = sprintf('%s: %s', Exam::$filters[$filter]['name'], $donateStatus->pluck('text')->implode(', '));
}
return implode("\n", $arr);
}
private function formatIndexes(Exam $exam)
{
$indexes = $exam->indexes;
$arr = [];
foreach ($indexes as $index) {
if (isset($index['checked']) && $index['checked']) {
$arr[] = sprintf(
'%s: %s %s',
Exam::$indexes[$index['index']]['name'] ?? '',
$index['require_value'],
Exam::$indexes[$index['index']]['unit'] ?? ''
);
}
}
return implode("\n", $arr);
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
class Exam extends NexusModel
@@ -78,4 +79,51 @@ class Exam extends NexusModel
return '';
}
public function getIndexFormattedAttribute(): string
{
$indexes = $this->indexes;
$arr = [];
foreach ($indexes as $index) {
if (isset($index['checked']) && $index['checked']) {
$arr[] = sprintf(
'%s: %s %s',
self::$indexes[$index['index']]['name'] ?? '',
$index['require_value'],
self::$indexes[$index['index']]['unit'] ?? ''
);
}
}
return implode("<br/>", $arr);
}
public function getFilterFormattedAttribute(): string
{
$currentFilters = $this->filters;
$arr = [];
$filter = self::FILTER_USER_CLASS;
if (!empty($currentFilters->{$filter})) {
$classes = collect(User::$classes)->only($currentFilters->{$filter});
$arr[] = sprintf('%s: %s', self::$filters[$filter]['name'], $classes->pluck('text')->implode(', '));
}
$filter = self::FILTER_USER_REGISTER_TIME_RANGE;
if (!empty($currentFilters->{$filter})) {
$range = $currentFilters->{$filter};
$arr[] = sprintf(
"%s: \n%s ~ %s",
self::$filters[$filter]['name'],
$range[0] ? Carbon::parse($range[0])->toDateTimeString() : '-',
$range[1] ? Carbon::parse($range[1])->toDateTimeString() : '-'
);
}
$filter = self::FILTER_USER_DONATE;
if (!empty($currentFilters->{$filter})) {
$donateStatus = $classes = collect(User::$donateStatus)->only($currentFilters->{$filter});
$arr[] = sprintf('%s: %s', self::$filters[$filter]['name'], $donateStatus->pluck('text')->implode(', '));
}
return implode("<br/>", $arr);
}
}

View File

@@ -41,6 +41,21 @@ class ExamUser extends NexusModel
return self::$isDoneInfo[$this->is_done]['text'] ?? '';
}
public static function listStatus($onlyKeyValue = false): array
{
$result = self::$status;
$keyValues = [];
foreach ($result as $key => &$value) {
$text = nexus_trans('exam-user.status.' . $key);
$value['text'] = $text;
$keyValues[$key] = $text;
}
if ($onlyKeyValue) {
return $keyValues;
}
return $result;
}
public function getBeginAttribute()
{
$begin = $this->getRawOriginal('begin');

View File

@@ -55,11 +55,17 @@ class HitAndRun extends NexusModel
return nexus_trans('hr.status_' . $this->status);
}
public static function listStatus(): array
public static function listStatus($onlyKeyValue = false): array
{
$result = self::$status;
$keyValues = [];
foreach ($result as $key => &$value) {
$value['text'] = nexus_trans('hr.status_' . $key);
$text = nexus_trans('hr.status_' . $key);
$value['text'] = $text;
$keyValues[$key] = $text;
}
if ($onlyKeyValue) {
return $keyValues;
}
return $result;
}

View File

@@ -10,7 +10,7 @@ class Medal extends NexusModel
const GET_TYPE_GRANT = 2;
public static $getTypeText = [
public static array $getTypeText = [
self::GET_TYPE_EXCHANGE => ['text' => 'Exchange'],
self::GET_TYPE_GRANT => ['text' => 'Grant'],
];
@@ -19,6 +19,21 @@ class Medal extends NexusModel
public $timestamps = true;
public static function listGetTypes($onlyKeyValues = false): array
{
$results = self::$getTypeText;
$keyValues = [];
foreach ($results as $type => &$info) {
$text = nexus_trans("medal.get_types.$type");
$keyValues[$type] = $text;
$info['text'] = $text;
}
if ($onlyKeyValues) {
return $keyValues;
}
return $results;
}
public function getGetTypeTextAttribute($value): string
{
return self::$getTypeText[$this->get_type]['text'] ?? '';

View File

@@ -23,7 +23,7 @@ class NexusModel extends Model
*/
protected function serializeDate(\DateTimeInterface $date)
{
return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
return $date->format($this->dateFormat ?: 'Y-m-d H:i');
}
/**

View File

@@ -6,6 +6,7 @@ use App\Http\Middleware\Locale;
use App\Repositories\ExamRepository;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
@@ -13,8 +14,10 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Laravel\Sanctum\HasApiTokens;
use Nexus\Database\NexusDB;
use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasName;
class User extends Authenticatable
class User extends Authenticatable implements FilamentUser, HasName
{
use HasFactory, Notifiable, HasApiTokens;
@@ -99,6 +102,17 @@ class User extends Authenticatable
return $classText;
}
public function canAccessFilament(): bool
{
return true;
// return str_ends_with($this->email, '@yourdomain.com') && $this->hasVerifiedEmail();
}
public function getFilamentName(): string
{
return $this->username;
}
/**
* @see ExamRepository::isExamMatchUser()
*
@@ -120,7 +134,7 @@ class User extends Authenticatable
*/
protected function serializeDate(\DateTimeInterface $date): string
{
return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
return $date->format($this->dateFormat ?: 'Y-m-d H:i');
}
/**
@@ -244,6 +258,20 @@ class User extends Authenticatable
return 'en';
}
protected function uploadedText(): Attribute
{
return new Attribute(
get: fn($value, $attributes) => mksize($attributes['uploaded'])
);
}
protected function downloadedText(): Attribute
{
return new Attribute(
get: fn($value, $attributes) => mksize($attributes['downloaded'])
);
}
public static function getMinSeedPoints($class)
{
$setting = Setting::get("account.{$class}_min_seed_points");

View File

@@ -2,11 +2,13 @@
namespace App\Providers;
use Carbon\Carbon;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
use Illuminate\Http\Resources\Json\JsonResource;
use Nexus\Nexus;
use Filament\Facades\Filament;
class AppServiceProvider extends ServiceProvider
{
@@ -30,5 +32,13 @@ class AppServiceProvider extends ServiceProvider
// JsonResource::withoutWrapping();
DB::connection(config('database.default'))->enableQueryLog();
Filament::serving(function () {
Filament::registerNavigationGroups([
'User',
'Torrent',
'System',
]);
});
}
}

View File

@@ -2,6 +2,8 @@
namespace App\Providers;
use App\Auth\NexusWebGuard;
use App\Auth\NexusWebUserProvider;
use App\Models\User;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
@@ -31,6 +33,11 @@ class AuthServiceProvider extends ServiceProvider
Auth::viaRequest('nexus-cookie', function (Request $request) {
return $this->getUserByCookie($request->cookie());
});
Auth::extend('nexus-web', function ($app, $name, array $config) {
// 返回 Illuminate\Contracts\Auth\Guard 的实例 ...
return new NexusWebGuard($app->make('request'), new NexusWebUserProvider());
});
}
private function getUserByCookie($cookie)

View File

@@ -115,7 +115,7 @@ class UserRepository extends BaseRepository
'class' => $class
];
$user = new User($data);
if ($params['id']) {
if (!empty($params['id'])) {
if (User::query()->where('id', $params['id'])->exists()) {
throw new \InvalidArgumentException("uid: {$params['id']} already exists.");
}

View File

@@ -23,6 +23,7 @@
"require": {
"php": "^8.0",
"ext-bcmath": "*",
"ext-curl": "*",
"ext-gd": "*",
"ext-json": "*",
"ext-mbstring": "*",
@@ -32,6 +33,8 @@
"ext-xml": "*",
"doctrine/dbal": "^3.1",
"elasticsearch/elasticsearch": "^7.16",
"filament/filament": "^2.0",
"flowframe/laravel-trend": "^0.1.1",
"fruitcake/laravel-cors": "^2.0",
"geoip2/geoip2": "~2.0",
"hashids/hashids": "^4.1",

825
composer.lock generated
View File

@@ -4,8 +4,82 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "3387b3f52798b9a38c8eb3c895498916",
"content-hash": "3f8e2bfc2d866abff6ef37466f43be7c",
"packages": [
{
"name": "akaunting/laravel-money",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/akaunting/laravel-money.git",
"reference": "22336631239eb008e26d322faa208cbc50757a38"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/akaunting/laravel-money/zipball/22336631239eb008e26d322faa208cbc50757a38",
"reference": "22336631239eb008e26d322faa208cbc50757a38",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"illuminate/contracts": "^8.67|^9.0",
"illuminate/support": "^8.67|^9.0",
"illuminate/view": "^8.67|^9.0",
"php": "^8.0",
"vlucas/phpdotenv": "^5.4.1"
},
"require-dev": {
"orchestra/testbench": "^6.23|^7.4",
"phpunit/phpunit": "^9.5",
"vimeo/psalm": "^4.23"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Akaunting\\Money\\Provider"
]
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Akaunting\\Money\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Denis Duliçi",
"email": "info@akaunting.com",
"homepage": "https://akaunting.com",
"role": "Developer"
}
],
"description": "Currency formatting and conversion package for Laravel",
"keywords": [
"convert",
"currency",
"format",
"laravel",
"money"
],
"support": {
"issues": "https://github.com/akaunting/laravel-money/issues",
"source": "https://github.com/akaunting/laravel-money/tree/3.0.1"
},
"time": "2022-05-11T06:34:38+00:00"
},
{
"name": "asm89/stack-cors",
"version": "v2.1.1",
@@ -68,6 +142,168 @@
},
"time": "2022-01-18T09:12:03+00:00"
},
{
"name": "blade-ui-kit/blade-heroicons",
"version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/blade-ui-kit/blade-heroicons.git",
"reference": "a2749abc7b8eb6149ff643ffa99a3d33a2de7961"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/blade-ui-kit/blade-heroicons/zipball/a2749abc7b8eb6149ff643ffa99a3d33a2de7961",
"reference": "a2749abc7b8eb6149ff643ffa99a3d33a2de7961",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"blade-ui-kit/blade-icons": "^1.1",
"illuminate/support": "^8.0|^9.0",
"php": "^7.4|^8.0"
},
"require-dev": {
"orchestra/testbench": "^6.0|^7.0",
"phpunit/phpunit": "^9.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"BladeUI\\Heroicons\\BladeHeroiconsServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"BladeUI\\Heroicons\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dries Vints",
"homepage": "https://driesvints.com"
}
],
"description": "A package to easily make use of Heroicons in your Laravel Blade views.",
"homepage": "https://github.com/blade-ui-kit/blade-heroicons",
"keywords": [
"Heroicons",
"blade",
"laravel"
],
"support": {
"issues": "https://github.com/blade-ui-kit/blade-heroicons/issues",
"source": "https://github.com/blade-ui-kit/blade-heroicons/tree/1.3.1"
},
"funding": [
{
"url": "https://github.com/caneco",
"type": "github"
},
{
"url": "https://github.com/driesvints",
"type": "github"
}
],
"time": "2022-03-02T11:50:13+00:00"
},
{
"name": "blade-ui-kit/blade-icons",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/blade-ui-kit/blade-icons.git",
"reference": "012496d145bf4ea7fffd0beed9b9acbf434cc7c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/012496d145bf4ea7fffd0beed9b9acbf434cc7c8",
"reference": "012496d145bf4ea7fffd0beed9b9acbf434cc7c8",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"illuminate/contracts": "^8.0|^9.0",
"illuminate/filesystem": "^8.0|^9.0",
"illuminate/support": "^8.0|^9.0",
"illuminate/view": "^8.0|^9.0",
"php": "^7.4|^8.0",
"symfony/console": "^5.3|^6.0",
"symfony/finder": "^5.3|^6.0"
},
"require-dev": {
"mockery/mockery": "^1.3",
"orchestra/testbench": "^6.0|^7.0",
"phpunit/phpunit": "^9.0"
},
"bin": [
"bin/blade-icons-generate"
],
"type": "library",
"extra": {
"laravel": {
"providers": [
"BladeUI\\Icons\\BladeIconsServiceProvider"
]
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"BladeUI\\Icons\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dries Vints",
"homepage": "https://driesvints.com"
}
],
"description": "A package to easily make use of icons in your Laravel Blade views.",
"homepage": "https://github.com/blade-ui-kit/blade-icons",
"keywords": [
"blade",
"icons",
"laravel",
"svg"
],
"support": {
"issues": "https://github.com/blade-ui-kit/blade-icons/issues",
"source": "https://github.com/blade-ui-kit/blade-icons"
},
"funding": [
{
"url": "https://github.com/caneco",
"type": "github"
},
{
"url": "https://github.com/driesvints",
"type": "github"
}
],
"time": "2022-02-28T21:03:33+00:00"
},
{
"name": "brick/math",
"version": "0.9.3",
@@ -303,6 +539,123 @@
],
"time": "2022-03-16T11:22:07+00:00"
},
{
"name": "danharrin/date-format-converter",
"version": "v0.2.0",
"source": {
"type": "git",
"url": "https://github.com/danharrin/date-format-converter.git",
"reference": "ee448ab0cbe2ea36edb886a01670fc760e388f19"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/danharrin/date-format-converter/zipball/ee448ab0cbe2ea36edb886a01670fc760e388f19",
"reference": "ee448ab0cbe2ea36edb886a01670fc760e388f19",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": "^7.2|^8.0"
},
"type": "library",
"autoload": {
"files": [
"src/helpers.php",
"src/standards.php"
],
"psr-4": {
"DanHarrin\\DateFormatConverter\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dan Harrin",
"email": "dan@danharrin.com"
}
],
"description": "Convert token-based date formats between standards.",
"homepage": "https://github.com/danharrin/date-format-converter",
"support": {
"issues": "https://github.com/danharrin/date-format-converter/issues",
"source": "https://github.com/danharrin/date-format-converter"
},
"funding": [
{
"url": "https://github.com/danharrin",
"type": "github"
}
],
"time": "2021-02-10T23:58:47+00:00"
},
{
"name": "danharrin/livewire-rate-limiting",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/danharrin/livewire-rate-limiting.git",
"reference": "b99facf5b607fb0cde92a6f254f437295339f7de"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/danharrin/livewire-rate-limiting/zipball/b99facf5b607fb0cde92a6f254f437295339f7de",
"reference": "b99facf5b607fb0cde92a6f254f437295339f7de",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"illuminate/support": "^8.0|^9.0",
"php": "^8.0"
},
"require-dev": {
"livewire/livewire": "^2.3",
"orchestra/testbench": "^6.2|^7.0",
"phpunit/phpunit": "^9.4",
"symplify/monorepo-builder": "^9.0"
},
"type": "library",
"autoload": {
"psr-4": {
"DanHarrin\\LivewireRateLimiting\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dan Harrin",
"email": "dan@danharrin.com"
}
],
"description": "Apply rate limiters to Laravel Livewire actions.",
"homepage": "https://github.com/danharrin/livewire-rate-limiting",
"support": {
"issues": "https://github.com/danharrin/livewire-rate-limiting/issues",
"source": "https://github.com/danharrin/livewire-rate-limiting"
},
"funding": [
{
"url": "https://github.com/danharrin",
"type": "github"
}
],
"time": "2022-01-21T11:26:58+00:00"
},
{
"name": "dflydev/dot-access-data",
"version": "v3.0.1",
@@ -1270,6 +1623,251 @@
},
"time": "2021-11-16T11:51:30+00:00"
},
{
"name": "filament/filament",
"version": "v2.13.10",
"source": {
"type": "git",
"url": "https://github.com/filamentphp/admin.git",
"reference": "443de38677284820b1dc53f309495e75f22bdc01"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filamentphp/admin/zipball/443de38677284820b1dc53f309495e75f22bdc01",
"reference": "443de38677284820b1dc53f309495e75f22bdc01",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"danharrin/livewire-rate-limiting": "^0.3|^1.0",
"filament/forms": "self.version",
"filament/support": "self.version",
"filament/tables": "self.version",
"illuminate/auth": "^8.6|^9.0",
"illuminate/console": "^8.6|^9.0",
"illuminate/contracts": "^8.6|^9.0",
"illuminate/cookie": "^8.6|^9.0",
"illuminate/database": "^8.6|^9.0",
"illuminate/http": "^8.6|^9.0",
"illuminate/routing": "^8.6|^9.0",
"illuminate/session": "^8.6|^9.0",
"illuminate/support": "^8.6|^9.0",
"illuminate/view": "^8.6|^9.0",
"livewire/livewire": "^2.6",
"php": "^8.0",
"spatie/laravel-package-tools": "^1.9"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Filament\\FilamentServiceProvider"
]
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Filament\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Effortlessly build TALL-powered admin panels.",
"homepage": "https://github.com/filamentphp/filament",
"support": {
"issues": "https://github.com/filamentphp/filament/issues",
"source": "https://github.com/filamentphp/filament"
},
"time": "2022-06-24T10:38:51+00:00"
},
{
"name": "filament/forms",
"version": "v2.13.10",
"source": {
"type": "git",
"url": "https://github.com/filamentphp/forms.git",
"reference": "98ea2eb252dc4174fd8ecd438708ac05229eb2a8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filamentphp/forms/zipball/98ea2eb252dc4174fd8ecd438708ac05229eb2a8",
"reference": "98ea2eb252dc4174fd8ecd438708ac05229eb2a8",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"blade-ui-kit/blade-heroicons": "^1.2",
"danharrin/date-format-converter": "^0.2",
"filament/support": "self.version",
"illuminate/console": "^8.6|^9.0",
"illuminate/contracts": "^8.6|^9.0",
"illuminate/database": "^8.6|^9.0",
"illuminate/filesystem": "^8.6|^9.0",
"illuminate/support": "^8.6|^9.0",
"illuminate/validation": "^8.6|^9.0",
"illuminate/view": "^8.6|^9.0",
"livewire/livewire": "^2.6",
"php": "^8.0",
"spatie/laravel-package-tools": "^1.9"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Filament\\Forms\\FormsServiceProvider"
]
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Filament\\Forms\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Effortlessly build TALL-powered forms.",
"homepage": "https://github.com/filamentphp/filament",
"support": {
"issues": "https://github.com/filamentphp/filament/issues",
"source": "https://github.com/filamentphp/filament"
},
"time": "2022-06-24T10:38:46+00:00"
},
{
"name": "filament/support",
"version": "v2.13.10",
"source": {
"type": "git",
"url": "https://github.com/filamentphp/support.git",
"reference": "0ceb543182469cabae1796b3d680d2c3eb98a8cf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filamentphp/support/zipball/0ceb543182469cabae1796b3d680d2c3eb98a8cf",
"reference": "0ceb543182469cabae1796b3d680d2c3eb98a8cf",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"illuminate/contracts": "^8.6|^9.0",
"illuminate/support": "^8.6|^9.0",
"illuminate/view": "^8.6|^9.0",
"php": "^8.0",
"spatie/laravel-package-tools": "^1.9"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Filament\\Support\\SupportServiceProvider"
]
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Filament\\Support\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Associated helper methods and foundation code for Filament packages.",
"homepage": "https://github.com/filamentphp/filament",
"support": {
"issues": "https://github.com/filamentphp/filament/issues",
"source": "https://github.com/filamentphp/filament"
},
"time": "2022-06-24T10:38:48+00:00"
},
{
"name": "filament/tables",
"version": "v2.13.10",
"source": {
"type": "git",
"url": "https://github.com/filamentphp/tables.git",
"reference": "f6284bdaff160f577d081084675af62bc79cb348"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filamentphp/tables/zipball/f6284bdaff160f577d081084675af62bc79cb348",
"reference": "f6284bdaff160f577d081084675af62bc79cb348",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"akaunting/laravel-money": "^1.2|^2.0|^3.0",
"blade-ui-kit/blade-heroicons": "^1.2",
"filament/forms": "self.version",
"filament/support": "self.version",
"illuminate/console": "^8.6|^9.0",
"illuminate/contracts": "^8.6|^9.0",
"illuminate/database": "^8.6|^9.0",
"illuminate/filesystem": "^8.6|^9.0",
"illuminate/support": "^8.6|^9.0",
"illuminate/view": "^8.6|^9.0",
"livewire/livewire": "^2.6",
"php": "^8.0",
"spatie/laravel-package-tools": "^1.9"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Filament\\Tables\\TablesServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Filament\\Tables\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Effortlessly build TALL-powered tables.",
"homepage": "https://github.com/filamentphp/filament",
"support": {
"issues": "https://github.com/filamentphp/filament/issues",
"source": "https://github.com/filamentphp/filament"
},
"time": "2022-06-24T10:38:39+00:00"
},
{
"name": "firebase/php-jwt",
"version": "v5.5.1",
@@ -1333,6 +1931,86 @@
},
"time": "2021-11-08T20:18:51+00:00"
},
{
"name": "flowframe/laravel-trend",
"version": "v0.1.1",
"source": {
"type": "git",
"url": "https://github.com/Flowframe/laravel-trend.git",
"reference": "10f80dad8225caca58d286b580ebd27c2a0bf3fa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Flowframe/laravel-trend/zipball/10f80dad8225caca58d286b580ebd27c2a0bf3fa",
"reference": "10f80dad8225caca58d286b580ebd27c2a0bf3fa",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"illuminate/contracts": "^8.37|^9",
"php": "^8.0",
"spatie/laravel-package-tools": "^1.4.3"
},
"require-dev": {
"nunomaduro/collision": "^5.3|^6.1",
"orchestra/testbench": "^6.15|^7.0",
"pestphp/pest": "^1.18",
"pestphp/pest-plugin-laravel": "^1.1",
"spatie/laravel-ray": "^1.23",
"vimeo/psalm": "^4.8"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Flowframe\\Trend\\TrendServiceProvider"
],
"aliases": {
"Trend": "Flowframe\\Trend\\TrendFacade"
}
}
},
"autoload": {
"psr-4": {
"Flowframe\\Trend\\": "src",
"Flowframe\\Trend\\Database\\Factories\\": "database/factories"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Lars Klopstra",
"email": "lars@flowframe.nl",
"role": "Developer"
}
],
"description": "Easily generate model trends",
"homepage": "https://github.com/flowframe/laravel-trend",
"keywords": [
"Flowframe",
"laravel",
"laravel-trend"
],
"support": {
"issues": "https://github.com/Flowframe/laravel-trend/issues",
"source": "https://github.com/Flowframe/laravel-trend/tree/v0.1.1"
},
"funding": [
{
"url": "https://github.com/larsklopstra",
"type": "github"
}
],
"time": "2022-02-25T13:52:24+00:00"
},
{
"name": "fruitcake/laravel-cors",
"version": "v2.2.0",
@@ -3363,6 +4041,85 @@
],
"time": "2021-11-21T11:48:40+00:00"
},
{
"name": "livewire/livewire",
"version": "v2.10.5",
"source": {
"type": "git",
"url": "https://github.com/livewire/livewire.git",
"reference": "9ea6237760f627b3b6a05d15137880780ac843b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/livewire/livewire/zipball/9ea6237760f627b3b6a05d15137880780ac843b5",
"reference": "9ea6237760f627b3b6a05d15137880780ac843b5",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"illuminate/database": "^7.0|^8.0|^9.0",
"illuminate/support": "^7.0|^8.0|^9.0",
"illuminate/validation": "^7.0|^8.0|^9.0",
"league/mime-type-detection": "^1.9",
"php": "^7.2.5|^8.0",
"symfony/http-kernel": "^5.0|^6.0"
},
"require-dev": {
"calebporzio/sushi": "^2.1",
"laravel/framework": "^7.0|^8.0|^9.0",
"mockery/mockery": "^1.3.1",
"orchestra/testbench": "^5.0|^6.0|^7.0",
"orchestra/testbench-dusk": "^5.2|^6.0|^7.0",
"phpunit/phpunit": "^8.4|^9.0",
"psy/psysh": "@stable"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Livewire\\LivewireServiceProvider"
],
"aliases": {
"Livewire": "Livewire\\Livewire"
}
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Livewire\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Caleb Porzio",
"email": "calebporzio@gmail.com"
}
],
"description": "A front-end framework for Laravel.",
"support": {
"issues": "https://github.com/livewire/livewire/issues",
"source": "https://github.com/livewire/livewire/tree/v2.10.5"
},
"funding": [
{
"url": "https://github.com/livewire",
"type": "github"
}
],
"time": "2022-04-07T21:38:12+00:00"
},
{
"name": "masbug/flysystem-google-drive-ext",
"version": "v2.1.0",
@@ -5352,6 +6109,71 @@
},
"time": "2022-03-29T11:33:16+00:00"
},
{
"name": "spatie/laravel-package-tools",
"version": "1.12.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-package-tools.git",
"reference": "9e6c0382553f1317c02f1ae0ee71c64821eb5af0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/9e6c0382553f1317c02f1ae0ee71c64821eb5af0",
"reference": "9e6c0382553f1317c02f1ae0ee71c64821eb5af0",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"illuminate/contracts": "^7.0|^8.0|^9.0",
"php": "^7.4|^8.0"
},
"require-dev": {
"mockery/mockery": "^1.4",
"orchestra/testbench": "^5.0|^6.23|^7.0",
"phpunit/phpunit": "^9.4",
"spatie/test-time": "^1.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\LaravelPackageTools\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"role": "Developer"
}
],
"description": "Tools for creating Laravel packages",
"homepage": "https://github.com/spatie/laravel-package-tools",
"keywords": [
"laravel-package-tools",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/laravel-package-tools/issues",
"source": "https://github.com/spatie/laravel-package-tools/tree/1.12.0"
},
"funding": [
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2022-06-19T20:01:24+00:00"
},
{
"name": "spiral/goridge",
"version": "v3.1.2",
@@ -11918,6 +12740,7 @@
"platform": {
"php": "^8.0",
"ext-bcmath": "*",
"ext-curl": "*",
"ext-gd": "*",
"ext-json": "*",
"ext-mbstring": "*",

View File

@@ -49,6 +49,9 @@ return [
'nexus' => [
'driver' => 'nexus-cookie',
],
'nexus-web' => [
'driver' => 'nexus-web',
],
],
/*

View File

@@ -142,6 +142,14 @@ return [
'database' => (int)env('REDIS_CACHE_DB', '1'),
],
'session' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => (int)env('REDIS_PORT', '6379'),
'database' => 10,
],
],
];

293
config/filament.php Normal file
View File

@@ -0,0 +1,293 @@
<?php
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Http\Middleware\MirrorConfigToSubpackages;
use Filament\Pages;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
return [
/*
|--------------------------------------------------------------------------
| Filament Path
|--------------------------------------------------------------------------
|
| The default is `admin` but you can change it to whatever works best and
| doesn't conflict with the routing in your application.
|
*/
'path' => env('FILAMENT_PATH', 'filament'),
/*
|--------------------------------------------------------------------------
| Filament Core Path
|--------------------------------------------------------------------------
|
| This is the path which Filament will use to load it's core routes and assets.
| You may change it if it conflicts with your other routes.
|
*/
'core_path' => env('FILAMENT_CORE_PATH', 'filament'),
/*
|--------------------------------------------------------------------------
| Filament Domain
|--------------------------------------------------------------------------
|
| You may change the domain where Filament should be active. If the domain
| is empty, all domains will be valid.
|
*/
'domain' => env('FILAMENT_DOMAIN'),
/*
|--------------------------------------------------------------------------
| Homepage URL
|--------------------------------------------------------------------------
|
| This is the URL that Filament will redirect the user to when they click
| on the sidebar's header.
|
*/
'home_url' => '/',
/*
|--------------------------------------------------------------------------
| Brand Name
|--------------------------------------------------------------------------
|
| This will be displayed on the login page and in the sidebar's header.
|
*/
'brand' => 'NexusPHP',
/*
|--------------------------------------------------------------------------
| Auth
|--------------------------------------------------------------------------
|
| This is the configuration that Filament will use to handle authentication
| into the admin panel.
|
*/
'auth' => [
// 'guard' => env('FILAMENT_AUTH_GUARD', 'web'),
'guard' => env('FILAMENT_AUTH_GUARD', 'nexus-web'),
'pages' => [
'login' => \Filament\Http\Livewire\Auth\Login::class,
],
],
/*
|--------------------------------------------------------------------------
| Pages
|--------------------------------------------------------------------------
|
| This is the namespace and directory that Filament will automatically
| register pages from. You may also register pages here.
|
*/
'pages' => [
'namespace' => 'App\\Filament\\Pages',
'path' => app_path('Filament/Pages'),
'register' => [
// Pages\Dashboard::class,
\App\Filament\Pages\Dashboard::class,
],
],
/*
|--------------------------------------------------------------------------
| Resources
|--------------------------------------------------------------------------
|
| This is the namespace and directory that Filament will automatically
| register resources from. You may also register resources here.
|
*/
'resources' => [
'namespace' => 'App\\Filament\\Resources',
'path' => app_path('Filament/Resources'),
'register' => [],
],
/*
|--------------------------------------------------------------------------
| Widgets
|--------------------------------------------------------------------------
|
| This is the namespace and directory that Filament will automatically
| register dashboard widgets from. You may also register widgets here.
|
*/
'widgets' => [
'namespace' => 'App\\Filament\\Widgets',
'path' => app_path('Filament/Widgets'),
'register' => [
// Widgets\AccountWidget::class,
// Widgets\FilamentInfoWidget::class,
],
],
/*
|--------------------------------------------------------------------------
| Livewire
|--------------------------------------------------------------------------
|
| This is the namespace and directory that Filament will automatically
| register Livewire components inside.
|
*/
'livewire' => [
'namespace' => 'App\\Filament',
'path' => app_path('Filament'),
],
/*
|--------------------------------------------------------------------------
| Dark mode
|--------------------------------------------------------------------------
|
| By enabling this feature, your users are able to select between a light
| and dark appearance for the admin panel, or let their system decide.
|
*/
'dark_mode' => false,
/*
|--------------------------------------------------------------------------
| Layout
|--------------------------------------------------------------------------
|
| This is the configuration for the general layout of the admin panel.
|
| You may configure the max content width from `xl` to `7xl`, or `full`
| for no max width.
|
*/
'layout' => [
'forms' => [
'actions' => [
'alignment' => 'left',
],
'have_inline_labels' => false,
],
'footer' => [
'should_show_logo' => false,
],
'max_content_width' => null,
'notifications' => [
'vertical_alignment' => 'center',
'alignment' => 'center',
],
'sidebar' => [
'is_collapsible_on_desktop' => true,
'groups' => [
'are_collapsible' => true,
],
'width' => null,
],
],
/*
|--------------------------------------------------------------------------
| Favicon
|--------------------------------------------------------------------------
|
| This is the path to the favicon used for pages in the admin panel.
|
*/
'favicon' => null,
/*
|--------------------------------------------------------------------------
| Default Avatar Provider
|--------------------------------------------------------------------------
|
| This is the service that will be used to retrieve default avatars if one
| has not been uploaded.
|
*/
'default_avatar_provider' => \Filament\AvatarProviders\UiAvatarsProvider::class,
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| This is the storage disk Filament will use to put media. You may use any
| of the disks defined in the `config/filesystems.php`.
|
*/
'default_filesystem_disk' => env('FILAMENT_FILESYSTEM_DRIVER', 'public'),
/*
|--------------------------------------------------------------------------
| Google Fonts
|--------------------------------------------------------------------------
|
| This is the URL for Google Fonts that should be loaded. You may use any
| font, or set to `null` to prevent any Google Fonts from loading.
|
| When using a custom font, you should also set the font family in your
| custom theme's `tailwind.config.js` file.
|
*/
'google_fonts' => 'https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap',
/*
|--------------------------------------------------------------------------
| Middleware
|--------------------------------------------------------------------------
|
| You may customise the middleware stack that Filament uses to handle
| requests.
|
*/
'middleware' => [
'auth' => [
\App\Http\Middleware\Filament::class,
],
'base' => [
// EncryptCookies::class,
\App\Http\Middleware\EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
// AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DispatchServingFilamentEvent::class,
MirrorConfigToSubpackages::class,
\App\Http\Middleware\Locale::class,
],
],
];

68
config/forms.php Normal file
View File

@@ -0,0 +1,68 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Components
|--------------------------------------------------------------------------
|
| These are the settings that Filament will use to control the appearance
| and behaviour of form components.
|
*/
'components' => [
'actions' => [
'modal' => [
'actions' => [
'alignment' => 'left',
],
],
],
'date_time_picker' => [
'first_day_of_week' => 1, // 0 to 7 are accepted values, with Monday as 1 and Sunday as 7 or 0.
'display_formats' => [
'date' => 'Y-m-d',
'date_time' => 'Y-m-d H:i:s',
'date_time_with_seconds' => 'Y-m-d H:i:s',
'time' => 'H:i',
'time_with_seconds' => 'H:i:s',
],
],
],
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| This is the storage disk Filament will use to put media. You may use any
| of the disks defined in the `config/filesystems.php`.
|
*/
'default_filesystem_disk' => env('FORMS_FILESYSTEM_DRIVER', 'public'),
/*
|--------------------------------------------------------------------------
| Dark mode
|--------------------------------------------------------------------------
|
| By enabling this feature, your users are able to select between a light
| and dark appearance for forms, via Tailwind's Dark Mode feature.
|
| https://tailwindcss.com/docs/dark-mode
|
*/
'dark_mode' => false,
];

159
config/livewire.php Normal file
View File

@@ -0,0 +1,159 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Class Namespace
|--------------------------------------------------------------------------
|
| This value sets the root namespace for Livewire component classes in
| your application. This value affects component auto-discovery and
| any Livewire file helper commands, like `artisan make:livewire`.
|
| After changing this item, run: `php artisan livewire:discover`.
|
*/
'class_namespace' => 'App\\Http\\Livewire',
/*
|--------------------------------------------------------------------------
| View Path
|--------------------------------------------------------------------------
|
| This value sets the path for Livewire component views. This affects
| file manipulation helper commands like `artisan make:livewire`.
|
*/
'view_path' => resource_path('views/livewire'),
/*
|--------------------------------------------------------------------------
| Layout
|--------------------------------------------------------------------------
| The default layout view that will be used when rendering a component via
| Route::get('/some-endpoint', SomeComponent::class);. In this case the
| the view returned by SomeComponent will be wrapped in "layouts.app"
|
*/
'layout' => 'layouts.app',
/*
|--------------------------------------------------------------------------
| Livewire Assets URL
|--------------------------------------------------------------------------
|
| This value sets the path to Livewire JavaScript assets, for cases where
| your app's domain root is not the correct path. By default, Livewire
| will load its JavaScript assets from the app's "relative root".
|
| Examples: "/assets", "myurl.com/app".
|
*/
'asset_url' => null,
/*
|--------------------------------------------------------------------------
| Livewire App URL
|--------------------------------------------------------------------------
|
| This value should be used if livewire assets are served from CDN.
| Livewire will communicate with an app through this url.
|
| Examples: "https://my-app.com", "myurl.com/app".
|
*/
'app_url' => null,
/*
|--------------------------------------------------------------------------
| Livewire Endpoint Middleware Group
|--------------------------------------------------------------------------
|
| This value sets the middleware group that will be applied to the main
| Livewire "message" endpoint (the endpoint that gets hit everytime
| a Livewire component updates). It is set to "web" by default.
|
*/
'middleware_group' => 'auth.filament',
// 'middleware_group' => 'web',
/*
|--------------------------------------------------------------------------
| Livewire Temporary File Uploads Endpoint Configuration
|--------------------------------------------------------------------------
|
| Livewire handles file uploads by storing uploads in a temporary directory
| before the file is validated and stored permanently. All file uploads
| are directed to a global endpoint for temporary storage. The config
| items below are used for customizing the way the endpoint works.
|
*/
'temporary_file_upload' => [
'disk' => null, // Example: 'local', 's3' Default: 'default'
'rules' => null, // Example: ['file', 'mimes:png,jpg'] Default: ['required', 'file', 'max:12288'] (12MB)
'directory' => null, // Example: 'tmp' Default 'livewire-tmp'
'middleware' => null, // Example: 'throttle:5,1' Default: 'throttle:60,1'
'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs.
'png', 'gif', 'bmp', 'svg', 'wav', 'mp4',
'mov', 'avi', 'wmv', 'mp3', 'm4a',
'jpg', 'jpeg', 'mpga', 'webp', 'wma',
],
'max_upload_time' => 5, // Max duration (in minutes) before an upload gets invalidated.
],
/*
|--------------------------------------------------------------------------
| Manifest File Path
|--------------------------------------------------------------------------
|
| This value sets the path to the Livewire manifest file.
| The default should work for most cases (which is
| "<app_root>/bootstrap/cache/livewire-components.php"), but for specific
| cases like when hosting on Laravel Vapor, it could be set to a different value.
|
| Example: for Laravel Vapor, it would be "/tmp/storage/bootstrap/cache/livewire-components.php".
|
*/
'manifest_path' => null,
/*
|--------------------------------------------------------------------------
| Back Button Cache
|--------------------------------------------------------------------------
|
| This value determines whether the back button cache will be used on pages
| that contain Livewire. By disabling back button cache, it ensures that
| the back button shows the correct state of components, instead of
| potentially stale, cached data.
|
| Setting it to "false" (default) will disable back button cache.
|
*/
'back_button_cache' => false,
/*
|--------------------------------------------------------------------------
| Render On Redirect
|--------------------------------------------------------------------------
|
| This value determines whether Livewire will render before it's redirected
| or not. Setting it to "false" (default) will mean the render method is
| skipped when redirecting. And "true" will mean the render method is
| run before redirecting. Browsers bfcache can store a potentially
| stale view if render is skipped on redirect.
|
*/
'render_on_redirect' => false,
];

View File

@@ -18,7 +18,8 @@ return [
|
*/
'driver' => env('SESSION_DRIVER', 'file'),
// 'driver' => env('SESSION_DRIVER', 'file'),
'driver' => 'redis',
/*
|--------------------------------------------------------------------------
@@ -72,7 +73,8 @@ return [
|
*/
'connection' => env('SESSION_CONNECTION', null),
// 'connection' => env('SESSION_CONNECTION', null),
'connection' => 'session',
/*
|--------------------------------------------------------------------------

80
config/tables.php Normal file
View File

@@ -0,0 +1,80 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Date / Time Formatting
|--------------------------------------------------------------------------
|
| These are the formats that Filament will use to display dates and times
| by default.
|
*/
'date_format' => 'Y-m-d',
'date_time_format' => 'Y-m-d H:i',
'time_format' => 'H:i:s',
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| This is the storage disk Filament will use to find media. You may use any
| of the disks defined in the `config/filesystems.php`.
|
*/
'default_filesystem_disk' => env('TABLES_FILESYSTEM_DRIVER', 'public'),
/*
|--------------------------------------------------------------------------
| Dark mode
|--------------------------------------------------------------------------
|
| By enabling this feature, your users are able to select between a light
| and dark appearance for tables, via Tailwind's Dark Mode feature.
|
| https://tailwindcss.com/docs/dark-mode
|
*/
'dark_mode' => false,
/*
|--------------------------------------------------------------------------
| Pagination
|--------------------------------------------------------------------------
|
| This is the configuration for the pagination of tables.
|
*/
'pagination' => [
'default_records_per_page' => 10,
],
/*
|--------------------------------------------------------------------------
| Layout
|--------------------------------------------------------------------------
|
| This is the configuration for the general layout of tables.
|
*/
'layout' => [
'actions' => [
'cell' => [
'alignment' => 'right',
],
'modal' => [
'actions' => [
'alignment' => 'left',
],
],
],
],
];

View File

@@ -1,6 +1,6 @@
<?php
defined('VERSION_NUMBER') || define('VERSION_NUMBER', '1.7.17');
defined('RELEASE_DATE') || define('RELEASE_DATE', '2022-06-24');
defined('RELEASE_DATE') || define('RELEASE_DATE', '2022-06-27');
defined('IN_TRACKER') || define('IN_TRACKER', true);
defined('PROJECTNAME') || define("PROJECTNAME","NexusPHP");
defined('NEXUSPHPURL') || define("NEXUSPHPURL","https://nexusphp.org");

14
public/vendor/livewire/livewire.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
public/vendor/livewire/manifest.json vendored Normal file
View File

@@ -0,0 +1 @@
{"/livewire.js":"/livewire.js?id=c69d0f2801c01fcf8166"}

View File

@@ -0,0 +1,15 @@
<?php
return [
'sidebar' => [
'exam_users' => 'Exam Users',
'hit_and_runs' => 'Hit And Runs',
'users_list' => 'Users',
'tags_list' => 'Tags',
'agent_allows' => 'Agent Allows',
'agent_denies' => 'Agent Denies',
'exams_list' => 'Exams',
'medals_list' => 'Medals',
'settings' => 'Settings',
],
];

View File

@@ -52,6 +52,12 @@ return [
],
'latest_torrent' => [
'page_title' => 'Torrent latest',
]
],
'torrent_trend' => [
'page_title' => 'Torrent trend',
],
'user_trend' => [
'page_title' => 'User trend',
],
];

View File

@@ -5,5 +5,10 @@ return [
'list' => [
'page_title' => 'Exam users'
]
]
],
'status' => [
\App\Models\ExamUser::STATUS_FINISHED => 'Finished',
\App\Models\ExamUser::STATUS_AVOIDED => 'Avoided',
\App\Models\ExamUser::STATUS_NORMAL => 'Normal',
],
];

View File

@@ -6,5 +6,9 @@ return [
'list' => [
'page_title' => 'Medal list'
]
]
],
'get_types' => [
\App\Models\Medal::GET_TYPE_EXCHANGE => 'Exchange',
\App\Models\Medal::GET_TYPE_GRANT => 'Grant',
],
];

View File

@@ -0,0 +1,15 @@
<?php
return [
'sidebar' => [
'exam_users' => '用户考核',
'hit_and_runs' => '用户 H&R',
'users_list' => '用户列表',
'tags_list' => '标签',
'agent_allows' => '允许客户端',
'agent_denies' => '拒绝客户端',
'exams_list' => '考核',
'medals_list' => '勋章',
'settings' => '设置',
],
];

View File

@@ -52,6 +52,12 @@ return [
],
'latest_torrent' => [
'page_title' => '最新种子',
]
],
'torrent_trend' => [
'page_title' => '种子趋势',
],
'user_trend' => [
'page_title' => '用户趋势',
],
];

View File

@@ -5,5 +5,10 @@ return [
'list' => [
'page_title' => '考核用户列表'
]
]
],
'status' => [
\App\Models\ExamUser::STATUS_FINISHED => '已结束',
\App\Models\ExamUser::STATUS_AVOIDED => '已免除',
\App\Models\ExamUser::STATUS_NORMAL => '考核中',
],
];

View File

@@ -6,5 +6,9 @@ return [
'list' => [
'page_title' => '勋章列表'
]
]
],
'get_types' => [
\App\Models\Medal::GET_TYPE_EXCHANGE => '兑换',
\App\Models\Medal::GET_TYPE_GRANT => '授予',
],
];

View File

@@ -0,0 +1,15 @@
<?php
return [
'sidebar' => [
'exam_users' => '用戶考核',
'hit_and_runs' => '用戶 H&R',
'users_list' => '用戶列表',
'tags_list' => '標簽',
'agent_allows' => '允許客戶端',
'agent_denies' => '拒絕客戶端',
'exams_list' => '考核',
'medals_list' => '勛章',
'settings' => '設置',
],
];

View File

@@ -52,6 +52,12 @@ return [
],
'latest_torrent' => [
'page_title' => '最新種子',
]
],
'torrent_trend' => [
'page_title' => '種子趨勢',
],
'user_trend' => [
'page_title' => '用戶趨勢',
],
];

View File

@@ -5,5 +5,10 @@ return [
'list' => [
'page_title' => '考核用戶列表'
]
]
],
'status' => [
\App\Models\ExamUser::STATUS_FINISHED => '已結束',
\App\Models\ExamUser::STATUS_AVOIDED => '已免除',
\App\Models\ExamUser::STATUS_NORMAL => '考核中',
],
];

View File

@@ -6,5 +6,9 @@ return [
'list' => [
'page_title' => '勛章列表'
]
]
],
'get_types' => [
\App\Models\Medal::GET_TYPE_EXCHANGE => '兌換',
\App\Models\Medal::GET_TYPE_GRANT => '授予',
],
];

View File

@@ -0,0 +1,3 @@
<x-filament::page>
</x-filament::page>

View File

@@ -0,0 +1,16 @@
<x-filament::widget>
<x-filament::card>
@php
$user = \Filament\Facades\Filament::auth()->user();
@endphp
<div class="h-12 flex items-center space-x-4 rtl:space-x-reverse">
<div>
<h2 class="text-lg sm:text-xl font-bold tracking-tight">
{{ __('filament::widgets/account-widget.welcome', ['user' => \Filament\Facades\Filament::getUserName($user) . '(' . $user->classText . ')']) }}
</h2>
</div>
</div>
</x-filament::card>
</x-filament::widget>

View File

@@ -16,3 +16,7 @@ use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return redirect('https://nexusphp.org');
});
Route::get('test', function () {
dd(request()->cookie());
});