This commit is contained in:
Lance Pioch 2024-04-21 01:00:48 -04:00
parent 204734914d
commit 3e239f9caa

View File

@ -37,95 +37,95 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->schema([ ->schema([
Tabs::make()->persistTabInQueryString() Tabs::make()->persistTabInQueryString()
->schema([ ->schema([
Tab::make('Account') Tab::make('Account')
->icon('tabler-user') ->icon('tabler-user')
->schema([ ->schema([
TextInput::make('username') TextInput::make('username')
->disabled() ->disabled()
->readOnly() ->readOnly()
->maxLength(191) ->maxLength(191)
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->autofocus(), ->autofocus(),
TextInput::make('email') TextInput::make('email')
->prefixIcon('tabler-mail') ->prefixIcon('tabler-mail')
->email() ->email()
->required() ->required()
->maxLength(191) ->maxLength(191)
->unique(ignoreRecord: true), ->unique(ignoreRecord: true),
TextInput::make('password') TextInput::make('password')
->password() ->password()
->prefixIcon('tabler-password') ->prefixIcon('tabler-password')
->revealable(filament()->arePasswordsRevealable()) ->revealable(filament()->arePasswordsRevealable())
->rule(Password::default()) ->rule(Password::default())
->autocomplete('new-password') ->autocomplete('new-password')
->dehydrated(fn ($state): bool => filled($state)) ->dehydrated(fn ($state): bool => filled($state))
->dehydrateStateUsing(fn ($state): string => Hash::make($state)) ->dehydrateStateUsing(fn ($state): string => Hash::make($state))
->live(debounce: 500) ->live(debounce: 500)
->same('passwordConfirmation'), ->same('passwordConfirmation'),
TextInput::make('passwordConfirmation') TextInput::make('passwordConfirmation')
->password() ->password()
->prefixIcon('tabler-password-fingerprint') ->prefixIcon('tabler-password-fingerprint')
->revealable(filament()->arePasswordsRevealable()) ->revealable(filament()->arePasswordsRevealable())
->required() ->required()
->visible(fn (Get $get): bool => filled($get('password'))) ->visible(fn (Get $get): bool => filled($get('password')))
->dehydrated(false), ->dehydrated(false),
Select::make('language') Select::make('language')
->required() ->required()
->prefixIcon('tabler-flag') ->prefixIcon('tabler-flag')
->live() ->live()
->default('en') ->default('en')
->helperText(fn (User $user, $state) => new HtmlString($user->isLanguageTranslated($state) ? '' : " ->helperText(fn (User $user, $state) => new HtmlString($user->isLanguageTranslated($state) ? '' : "
Your language ($state) has not been translated yet! Your language ($state) has not been translated yet!
But never fear, you can help fix that by But never fear, you can help fix that by
<a style='color: rgb(56, 189, 248)' href='https://crowdin.com/project/pelican-dev'>contributing directly here</a>. <a style='color: rgb(56, 189, 248)' href='https://crowdin.com/project/pelican-dev'>contributing directly here</a>.
") ")
) )
->options(fn (User $user) => $user->getAvailableLanguages()), ->options(fn (User $user) => $user->getAvailableLanguages()),
]), ]),
Tab::make('2FA') Tab::make('2FA')
->icon('tabler-shield-lock') ->icon('tabler-shield-lock')
->schema(function () { ->schema(function () {
if ($this->getUser()->use_totp) { if ($this->getUser()->use_totp) {
return [ return [
Placeholder::make('2FA already enabled!'), Placeholder::make('2FA already enabled!'),
]; ];
} }
$setupService = app(TwoFactorSetupService::class); $setupService = app(TwoFactorSetupService::class);
['image_url_data' => $url] = $setupService->handle($this->getUser()); ['image_url_data' => $url] = $setupService->handle($this->getUser());
$options = new QROptions([ $options = new QROptions([
'svgLogo' => public_path('pelican.svg'), 'svgLogo' => public_path('pelican.svg'),
'addLogoSpace' => true, 'addLogoSpace' => true,
'logoSpaceWidth' => 13, 'logoSpaceWidth' => 13,
'logoSpaceHeight' => 13, 'logoSpaceHeight' => 13,
]); ]);
// https://github.com/chillerlan/php-qrcode/blob/main/examples/svgWithLogo.php // https://github.com/chillerlan/php-qrcode/blob/main/examples/svgWithLogo.php
// SVG logo options (see extended class) // SVG logo options (see extended class)
$options->svgLogo = public_path('pelican.svg'); // logo from: https://github.com/simple-icons/simple-icons $options->svgLogo = public_path('pelican.svg'); // logo from: https://github.com/simple-icons/simple-icons
$options->svgLogoScale = 0.05; $options->svgLogoScale = 0.05;
// $options->svgLogoCssClass = 'dark'; // $options->svgLogoCssClass = 'dark';
// QROptions // QROptions
$options->version = Version::AUTO; $options->version = Version::AUTO;
// $options->outputInterface = QRSvgWithLogo::class; // $options->outputInterface = QRSvgWithLogo::class;
$options->outputBase64 = false; $options->outputBase64 = false;
$options->eccLevel = EccLevel::H; // ECC level H is necessary when using logos $options->eccLevel = EccLevel::H; // ECC level H is necessary when using logos
$options->addQuietzone = true; $options->addQuietzone = true;
// $options->drawLightModules = true; // $options->drawLightModules = true;
$options->connectPaths = true; $options->connectPaths = true;
$options->drawCircularModules = true; $options->drawCircularModules = true;
// $options->circleRadius = 0.45; // $options->circleRadius = 0.45;
$options->svgDefs = '<linearGradient id="gradient" x1="100%" y2="100%"> $options->svgDefs = '<linearGradient id="gradient" x1="100%" y2="100%">
<stop stop-color="#7dd4fc" offset="0"/> <stop stop-color="#7dd4fc" offset="0"/>
<stop stop-color="#38bdf8" offset="0.5"/> <stop stop-color="#38bdf8" offset="0.5"/>
<stop stop-color="#0369a1" offset="1"/> <stop stop-color="#0369a1" offset="1"/>
@ -135,92 +135,92 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
.light{fill: #000;} .light{fill: #000;}
]]></style>'; ]]></style>';
$image = (new QRCode($options))->render($url); $image = (new QRCode($options))->render($url);
return [ return [
Placeholder::make('qr') Placeholder::make('qr')
->label('Scan QR Code') ->label('Scan QR Code')
->content(fn () => new HtmlString(" ->content(fn () => new HtmlString("
<div style='width: 300px'>$image</div> <div style='width: 300px'>$image</div>
")) "))
->default('asdfasdf'), ->default('asdfasdf'),
]; ];
}), }),
Tab::make('API Keys') Tab::make('API Keys')
->icon('tabler-key') ->icon('tabler-key')
->schema([ ->schema([
Grid::make('asdf')->columns(5)->schema([ Grid::make('asdf')->columns(5)->schema([
Section::make('Create API Key')->columnSpan(3)->schema([ Section::make('Create API Key')->columnSpan(3)->schema([
TextInput::make('description'), TextInput::make('description'),
TagsInput::make('allowed_ips') TagsInput::make('allowed_ips')
->splitKeys([',', ' ', 'Tab']) ->splitKeys([',', ' ', 'Tab'])
->placeholder('Example: 127.0.0.1 or 192.168.1.1') ->placeholder('Example: 127.0.0.1 or 192.168.1.1')
->label('Whitelisted IP\'s') ->label('Whitelisted IP\'s')
->helperText('Press enter to add a new IP address or leave blank to allow any IP address') ->helperText('Press enter to add a new IP address or leave blank to allow any IP address')
->columnSpanFull(), ->columnSpanFull(),
])->headerActions([ ])->headerActions([
Action::make('Create') Action::make('Create')
->successRedirectUrl('/panel/profile?tab=-api-keys-tab') ->successRedirectUrl('/panel/profile?tab=-api-keys-tab')
->action(function (Get $get, Action $action) { ->action(function (Get $get, Action $action) {
$token = auth()->user()->createToken( $token = auth()->user()->createToken(
$get('description'), $get('description'),
$get('allowed_ips'), $get('allowed_ips'),
); );
Activity::event('user:api-key.create') Activity::event('user:api-key.create')
->subject($token->accessToken) ->subject($token->accessToken)
->property('identifier', $token->accessToken->identifier) ->property('identifier', $token->accessToken->identifier)
->log(); ->log();
$action->success(); $action->success();
}) }),
]), ]),
Section::make('API Keys')->columnSpan(2)->schema([ Section::make('API Keys')->columnSpan(2)->schema([
Repeater::make('keys') Repeater::make('keys')
->relationship('apiKeys') ->relationship('apiKeys')
->addable(false) ->addable(false)
->itemLabel(fn ($state) => $state['identifier']) ->itemLabel(fn ($state) => $state['identifier'])
->deleteAction(function (Action $action) { ->deleteAction(function (Action $action) {
$action->requiresConfirmation()->action(function (array $arguments, Repeater $component) { $action->requiresConfirmation()->action(function (array $arguments, Repeater $component) {
$items = $component->getState(); $items = $component->getState();
$key = $items[$arguments['item']]; $key = $items[$arguments['item']];
ApiKey::find($key['id'] ?? null)?->delete(); ApiKey::find($key['id'] ?? null)?->delete();
unset($items[$arguments['item']]); unset($items[$arguments['item']]);
$component->state($items); $component->state($items);
$component->callAfterStateUpdated(); $component->callAfterStateUpdated();
}); });
}) })
->schema(fn () => [ ->schema(fn () => [
Placeholder::make('adf')->label(fn (ApiKey $key) => $key->memo), Placeholder::make('adf')->label(fn (ApiKey $key) => $key->memo),
]), ]),
]),
]), ]),
]), ]),
]),
Tab::make('SSH Keys') Tab::make('SSH Keys')
->icon('tabler-lock-code') ->icon('tabler-lock-code')
->schema([ ->schema([
Placeholder::make('Coming soon!'), Placeholder::make('Coming soon!'),
]), ]),
Tab::make('Activity') Tab::make('Activity')
->icon('tabler-history') ->icon('tabler-history')
->schema([ ->schema([
Repeater::make('activity') Repeater::make('activity')
->deletable(false) ->deletable(false)
->addable(false) ->addable(false)
->relationship(null, function (Builder $query) { ->relationship(null, function (Builder $query) {
$query->orderBy('timestamp', 'desc'); $query->orderBy('timestamp', 'desc');
}) })
->schema([ ->schema([
Placeholder::make('activity!')->label('')->content(fn (ActivityLog $log) => new HtmlString($log->htmlable())), Placeholder::make('activity!')->label('')->content(fn (ActivityLog $log) => new HtmlString($log->htmlable())),
]), ]),
]), ]),
]), ]),
]) ])
->operation('edit') ->operation('edit')
->model($this->getUser()) ->model($this->getUser())