mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-10 00:34:50 +00:00
Merge pull request #820 from pixelfed/frontend-ui-refactor
Frontend ui refactor
This commit is contained in:
commit
08631ada2b
12 changed files with 709 additions and 62 deletions
|
@ -15,4 +15,9 @@ class Avatar extends Model
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $dates = ['deleted_at'];
|
protected $dates = ['deleted_at'];
|
||||||
|
|
||||||
|
public function profile()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Profile::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
75
app/Console/Commands/FixDuplicateProfiles.php
Normal file
75
app/Console/Commands/FixDuplicateProfiles.php
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
use App\{
|
||||||
|
Like,
|
||||||
|
Media,
|
||||||
|
Profile,
|
||||||
|
Status,
|
||||||
|
User
|
||||||
|
};
|
||||||
|
|
||||||
|
class FixDuplicateProfiles extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'fix:profile:duplicates';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Fix duplicate profiles';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$profiles = Profile::selectRaw('count(user_id) as count,user_id,id')->whereNotNull('user_id')->groupBy('user_id')->orderBy('user_id', 'desc')->get()->where('count', '>', 1);
|
||||||
|
$count = $profiles->count();
|
||||||
|
if($count == 0) {
|
||||||
|
$this->info("No duplicate profiles found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->info("Found {$count} accounts with duplicate profiles...");
|
||||||
|
$bar = $this->output->createProgressBar($count);
|
||||||
|
$bar->start();
|
||||||
|
|
||||||
|
foreach ($profiles as $profile) {
|
||||||
|
$dup = Profile::whereUserId($profile->user_id)->get();
|
||||||
|
|
||||||
|
if(
|
||||||
|
$dup->first()->username === $dup->last()->username &&
|
||||||
|
$dup->last()->statuses()->count() == 0 &&
|
||||||
|
$dup->last()->followers()->count() == 0 &&
|
||||||
|
$dup->last()->likes()->count() == 0 &&
|
||||||
|
$dup->last()->media()->count() == 0
|
||||||
|
) {
|
||||||
|
$dup->last()->avatar->forceDelete();
|
||||||
|
$dup->last()->forceDelete();
|
||||||
|
}
|
||||||
|
$bar->advance();
|
||||||
|
}
|
||||||
|
$bar->finish();
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ use App\Http\Controllers\Admin\{
|
||||||
AdminSettingsController
|
AdminSettingsController
|
||||||
};
|
};
|
||||||
use App\Util\Lexer\PrettyNumber;
|
use App\Util\Lexer\PrettyNumber;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
class AdminController extends Controller
|
class AdminController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -181,10 +182,47 @@ class AdminController extends Controller
|
||||||
|
|
||||||
public function profiles(Request $request)
|
public function profiles(Request $request)
|
||||||
{
|
{
|
||||||
$profiles = Profile::orderBy('id','desc')->paginate(10);
|
$this->validate($request, [
|
||||||
|
'search' => 'nullable|string|max:250',
|
||||||
|
'filter' => [
|
||||||
|
'nullable',
|
||||||
|
'string',
|
||||||
|
Rule::in(['id','username','statuses_count','followers_count','likes_count'])
|
||||||
|
],
|
||||||
|
'order' => [
|
||||||
|
'nullable',
|
||||||
|
'string',
|
||||||
|
Rule::in(['asc','desc'])
|
||||||
|
],
|
||||||
|
'layout' => [
|
||||||
|
'nullable',
|
||||||
|
'string',
|
||||||
|
Rule::in(['card','list'])
|
||||||
|
],
|
||||||
|
'limit' => 'nullable|integer|min:1|max:50'
|
||||||
|
]);
|
||||||
|
$search = $request->input('search');
|
||||||
|
$filter = $request->input('filter');
|
||||||
|
$order = $request->input('order') ?? 'desc';
|
||||||
|
$limit = $request->input('limit') ?? 12;
|
||||||
|
if($search) {
|
||||||
|
$profiles = Profile::where('username','like', "%$search%")->orderBy('id','desc')->paginate($limit);
|
||||||
|
} else if($filter && $order) {
|
||||||
|
$profiles = Profile::withCount(['likes','statuses','followers'])->orderBy($filter, $order)->paginate($limit);
|
||||||
|
} else {
|
||||||
|
$profiles = Profile::orderBy('id','desc')->paginate($limit);
|
||||||
|
}
|
||||||
|
|
||||||
return view('admin.profiles.home', compact('profiles'));
|
return view('admin.profiles.home', compact('profiles'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function profileShow(Request $request, $id)
|
||||||
|
{
|
||||||
|
$profile = Profile::findOrFail($id);
|
||||||
|
$user = $profile->user;
|
||||||
|
return view('admin.profiles.edit', compact('profile', 'user'));
|
||||||
|
}
|
||||||
|
|
||||||
public function appsHome(Request $request)
|
public function appsHome(Request $request)
|
||||||
{
|
{
|
||||||
$filter = $request->input('filter');
|
$filter = $request->input('filter');
|
||||||
|
|
75
app/Observers/AvatarObserver.php
Normal file
75
app/Observers/AvatarObserver.php
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Observers;
|
||||||
|
|
||||||
|
use App\Avatar;
|
||||||
|
|
||||||
|
class AvatarObserver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle the avatar "created" event.
|
||||||
|
*
|
||||||
|
* @param \App\Avatar $avatar
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function created(Avatar $avatar)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the avatar "updated" event.
|
||||||
|
*
|
||||||
|
* @param \App\Avatar $avatar
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updated(Avatar $avatar)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the avatar "deleted" event.
|
||||||
|
*
|
||||||
|
* @param \App\Avatar $avatar
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleted(Avatar $avatar)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the avatar "deleting" event.
|
||||||
|
*
|
||||||
|
* @param \App\Avatar $avatar
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleting(Avatar $avatar)
|
||||||
|
{
|
||||||
|
$path = storage_path('app/'.$avatar->media_path);
|
||||||
|
@unlink($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the avatar "restored" event.
|
||||||
|
*
|
||||||
|
* @param \App\Avatar $avatar
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function restored(Avatar $avatar)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the avatar "force deleted" event.
|
||||||
|
*
|
||||||
|
* @param \App\Avatar $avatar
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function forceDeleted(Avatar $avatar)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Observers\UserObserver;
|
use App\Observers\{
|
||||||
use App\User;
|
AvatarObserver,
|
||||||
use Auth;
|
UserObserver
|
||||||
use Horizon;
|
};
|
||||||
|
use App\{Avatar,User};
|
||||||
|
use Auth, Horizon, URL;
|
||||||
use Illuminate\Support\Facades\Blade;
|
use Illuminate\Support\Facades\Blade;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
@ -21,6 +23,7 @@ class AppServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
Schema::defaultStringLength(191);
|
Schema::defaultStringLength(191);
|
||||||
|
|
||||||
|
Avatar::observe(AvatarObserver::class);
|
||||||
User::observe(UserObserver::class);
|
User::observe(UserObserver::class);
|
||||||
|
|
||||||
Horizon::auth(function ($request) {
|
Horizon::auth(function ($request) {
|
||||||
|
@ -43,17 +46,8 @@ class AppServiceProvider extends ServiceProvider
|
||||||
});
|
});
|
||||||
|
|
||||||
Blade::directive('prettySize', function ($expression) {
|
Blade::directive('prettySize', function ($expression) {
|
||||||
$size = intval($expression);
|
$size = \App\Util\Lexer\PrettyNumber::size($expression);
|
||||||
$precision = 0;
|
return "<?php echo '$size'; ?>";
|
||||||
$short = true;
|
|
||||||
$units = $short ?
|
|
||||||
['B', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] :
|
|
||||||
['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
||||||
for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {
|
|
||||||
}
|
|
||||||
$res = round($size, $precision).$units[$i];
|
|
||||||
|
|
||||||
return "<?php echo '$res'; ?>";
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Blade::directive('maxFileSize', function () {
|
Blade::directive('maxFileSize', function () {
|
||||||
|
|
|
@ -15,8 +15,8 @@ return [
|
||||||
|
|
||||||
'password' => 'Passwords must be at least six characters and match the confirmation.',
|
'password' => 'Passwords must be at least six characters and match the confirmation.',
|
||||||
'reset' => 'Your password has been reset!',
|
'reset' => 'Your password has been reset!',
|
||||||
'sent' => 'We have e-mailed your password reset link!',
|
'sent' => 'If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes. Please check your spam folder if you didn\'t receive this email.',
|
||||||
'token' => 'This password reset token is invalid.',
|
'token' => 'This password reset token is invalid.',
|
||||||
'user' => "We can't find a user with that e-mail address.",
|
'user' => 'If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes. Please check your spam folder if you didn\'t receive this email.',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
234
resources/views/admin/profiles/edit.blade.php
Normal file
234
resources/views/admin/profiles/edit.blade.php
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
@extends('admin.partial.template-full')
|
||||||
|
|
||||||
|
@section('section')
|
||||||
|
<div class="title d-flex justify-content-between align-items-center">
|
||||||
|
<span><a href="{{route('admin.profiles')}}" class="btn btn-outline-secondary btn-sm font-weight-bold">Back</a></span>
|
||||||
|
<h3 class="font-weight-bold">Edit Profile</h3>
|
||||||
|
<span><a href="#" class="btn btn-outline-primary btn-sm font-weight-bold disabled">Enable Editing</a></span>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-12 col-md-4">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<img src="{{$profile->avatarUrl()}}" class="box-shadow rounded-circle" width="128px" height="128px">
|
||||||
|
</div>
|
||||||
|
{{-- <div class="card-footer bg-white">
|
||||||
|
<p class="font-weight-bold mb-0 small">Last updated: {{$profile->avatar->updated_at->diffForHumans()}}</p>
|
||||||
|
</div> --}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-8">
|
||||||
|
<table class="table table-striped table-borderless table-sm">
|
||||||
|
<tbody>
|
||||||
|
@if($user)
|
||||||
|
<tr>
|
||||||
|
<th scope="row">user id</th>
|
||||||
|
<td>{{$user->id}}</td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
|
<tr>
|
||||||
|
<th scope="row">profile id</th>
|
||||||
|
<td>{{$profile->id}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">username</th>
|
||||||
|
<td>
|
||||||
|
{{$profile->username}}
|
||||||
|
@if($user && $user->is_admin == true)
|
||||||
|
<span class="badge badge-danger ml-3">Admin</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">display name</th>
|
||||||
|
<td>{{$profile->name}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">joined</th>
|
||||||
|
<td>{{$profile->created_at->format('M j Y')}}</td>
|
||||||
|
</tr>
|
||||||
|
@if($user)
|
||||||
|
<tr>
|
||||||
|
<th scope="row">email</th>
|
||||||
|
<td>
|
||||||
|
{{$user->email}}
|
||||||
|
@if($user->email_verified_at)
|
||||||
|
<span class="text-success font-weight-bold small pl-2">Verified</span>
|
||||||
|
@else
|
||||||
|
<span class="text-danger font-weight-bold small pl-2">Unverified</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{-- <div class="py-3">
|
||||||
|
<p class="font-weight-bold mb-0">
|
||||||
|
{{$profile->username}}
|
||||||
|
</p>
|
||||||
|
<p class="h3 font-weight-bold">
|
||||||
|
{{$profile->emailUrl()}}
|
||||||
|
</p>
|
||||||
|
<p class="font-weight-bold mb-0 text-muted">
|
||||||
|
Member Since: {{$profile->created_at->format('M Y')}}
|
||||||
|
</p>
|
||||||
|
</div> --}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-12 col-md-4 mb-3">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<p class="h4 mb-0 font-weight-bold">{{$profile->statusCount()}}</p>
|
||||||
|
<p class="text-muted font-weight-bold small mb-0">Posts</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-4 mb-3">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<p class="h4 mb-0 font-weight-bold">{{$profile->followingCount()}}</p>
|
||||||
|
<p class="text-muted font-weight-bold small mb-0">Following</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-4 mb-3">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<p class="h4 mb-0 font-weight-bold">{{$profile->followerCount()}}</p>
|
||||||
|
<p class="text-muted font-weight-bold small mb-0">Followers</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-3 mb-3">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<p class="h4 mb-0 font-weight-bold">{{$profile->bookmarks()->count()}}</p>
|
||||||
|
<p class="text-muted font-weight-bold small mb-0">Bookmarks</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-3 mb-3">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<p class="h4 mb-0 font-weight-bold">{{$profile->likes()->count()}}</p>
|
||||||
|
<p class="text-muted font-weight-bold small mb-0">Likes</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-3 mb-3">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<p class="h4 mb-0 font-weight-bold">{{$profile->reports()->count()}}</p>
|
||||||
|
<p class="text-muted font-weight-bold small mb-0">Reports Made</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-3 mb-3">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<p class="h4 mb-0 font-weight-bold">{{PrettyNumber::size($profile->media()->sum('size'))}}</p>
|
||||||
|
<p class="text-muted font-weight-bold small mb-0">Storage Used</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
{{-- <div class="mx-3">
|
||||||
|
<div class="sub-title h4 font-weight-bold mb-4">
|
||||||
|
Account Settings
|
||||||
|
</div>
|
||||||
|
<form>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="font-weight-bold text-muted">Display Name</label>
|
||||||
|
<input type="text" class="form-control" value="{{$user->name}}">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="font-weight-bold text-muted">Username</label>
|
||||||
|
<input type="text" class="form-control" value="{{$user->username}}">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="font-weight-bold text-muted">Email address</label>
|
||||||
|
<input type="email" class="form-control" value="{{$user->email}}" placeholder="Enter email">
|
||||||
|
<p class="help-text small text-muted font-weight-bold">
|
||||||
|
@if($user->email_verified_at)
|
||||||
|
<span class="text-success">Verified</span> for {{$user->email_verified_at->diffForHumans()}}
|
||||||
|
@else
|
||||||
|
<span class="text-danger">Unverified</span> email.
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<hr> --}}
|
||||||
|
<div class="mx-3">
|
||||||
|
<div class="sub-title h4 font-weight-bold mb-4">
|
||||||
|
Account Actions
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-12 col-md-4">
|
||||||
|
<form method="post" action="/i/admin/users/moderation/update" class="pb-3">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="profile_id" value="{{$profile->id}}">
|
||||||
|
<button class="btn btn-outline-primary py-0 font-weight-bold">Enforce CW</button>
|
||||||
|
<p class="help-text text-muted font-weight-bold small">Adds a CW to every post made by this account.</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-4">
|
||||||
|
<form method="post" action="/i/admin/users/moderation/update" class="pb-3">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="profile_id" value="{{$profile->id}}">
|
||||||
|
<button class="btn btn-outline-primary py-0 font-weight-bold">Unlisted Posts</button>
|
||||||
|
<p class="help-text text-muted font-weight-bold small">Removes account from public/network timelines.</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-4">
|
||||||
|
<form method="post" action="/i/admin/users/moderation/update" class="pb-3">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="profile_id" value="{{$profile->id}}">
|
||||||
|
<button class="btn btn-outline-primary py-0 font-weight-bold">No Autolinking</button>
|
||||||
|
<p class="help-text text-muted font-weight-bold small">Do not transform mentions, hashtags or urls into HTML.</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-4">
|
||||||
|
<form method="post" action="/i/admin/users/moderation/update" class="pb-3">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="profile_id" value="{{$profile->id}}">
|
||||||
|
<button class="btn btn-outline-primary py-0 font-weight-bold">Disable Account</button>
|
||||||
|
<p class="help-text text-muted font-weight-bold small">Temporarily disable account until next time user log in.</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 col-md-4">
|
||||||
|
<form method="post" action="/i/admin/users/moderation/update" class="pb-3">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="profile_id" value="{{$profile->id}}">
|
||||||
|
<button class="btn btn-outline-primary py-0 font-weight-bold">Suspend Account</button>
|
||||||
|
<p class="help-text text-muted font-weight-bold small">This prevents any new interactions, without deleting existing data.</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 col-md-4">
|
||||||
|
<form method="post" action="/i/admin/users/moderation/update" class="pb-3">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="profile_id" value="{{$profile->id}}">
|
||||||
|
<button class="btn btn-outline-danger py-0 font-weight-bold">Lock down Account</button>
|
||||||
|
<p class="help-text text-muted font-weight-bold small">This disables the account and changes the password, forcing account to reset password via verified email.</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<form method="post" action="/i/admin/users/moderation/update" class="pb-3">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="profile_id" value="{{$profile->id}}">
|
||||||
|
<button class="btn btn-outline-danger font-weight-bold btn-block">Delete Account</button>
|
||||||
|
<p class="help-text text-muted font-weight-bold small">Permanently delete this account.</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
|
@ -4,10 +4,22 @@
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h3 class="font-weight-bold d-inline-block">Profiles</h3>
|
<h3 class="font-weight-bold d-inline-block">Profiles</h3>
|
||||||
<span class="float-right">
|
<span class="float-right">
|
||||||
<a class="btn btn-{{request()->input('layout')!=='list'?'primary':'light'}} btn-sm" href="{{route('admin.profiles')}}">
|
<a class="btn btn-{{request()->input('layout')=='card'?'primary':'light'}} btn-sm" href="{{route('admin.profiles',[
|
||||||
|
'layout'=>'card',
|
||||||
|
'search' => request()->input('search'),
|
||||||
|
'page' => request()->input('page') ?? 1,
|
||||||
|
'filter' => request()->filter,
|
||||||
|
'order' => request()->order
|
||||||
|
])}}">
|
||||||
<i class="fas fa-th"></i>
|
<i class="fas fa-th"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-{{request()->input('layout')=='list'?'primary':'light'}} btn-sm mr-3" href="{{route('admin.profiles',['layout'=>'list', 'page' => request()->input('page') ?? 1])}}">
|
<a class="btn btn-{{request()->input('layout')!=='card'?'primary':'light'}} btn-sm mr-3" href="{{route('admin.profiles',[
|
||||||
|
'layout'=>'list',
|
||||||
|
'search' => request()->input('search'),
|
||||||
|
'page' => request()->input('page') ?? 1,
|
||||||
|
'filter' => request()->filter,
|
||||||
|
'order' => request()->order
|
||||||
|
])}}">
|
||||||
<i class="fas fa-list"></i>
|
<i class="fas fa-list"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown d-inline-block">
|
<div class="dropdown d-inline-block">
|
||||||
|
@ -20,63 +32,155 @@
|
||||||
<input type="hidden" name="layout" value="{{request()->input('layout')}}"></input>
|
<input type="hidden" name="layout" value="{{request()->input('layout')}}"></input>
|
||||||
<input type="hidden" name="page" value="{{request()->input('page')}}"></input>
|
<input type="hidden" name="page" value="{{request()->input('page')}}"></input>
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
<input class="form-control" name="search" placeholder="Filter by username, mime type" autocomplete="off"></input>
|
<input class="form-control" name="search" placeholder="Filter by username" autocomplete="off" value="{{request()->input('search')}}">
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
<button class="btn btn-outline-primary" type="submit">Filter</button>
|
<button class="btn btn-outline-primary" type="submit">Filter</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<p class="text-wrap p-1 p-md-3 text-center">
|
|
||||||
<a class="badge badge-primary p-1 btn-filter" href="#" data-filter="cw" data-filter-state="true" data-toggle="tooltip" title="Show Content Warning media">CW</a>
|
|
||||||
<a class="badge badge-primary p-1 btn-filter" href="#" data-filter="remote" data-filter-state="true" data-toggle="tooltip" title="Show remote media">Remote Media</a>
|
|
||||||
<a class="badge badge-primary p-1 btn-filter" href="#" data-filter="images" data-filter-state="true" data-toggle="tooltip" title="Show image media">Images</a>
|
|
||||||
<a class="badge badge-primary p-1 btn-filter" href="#" data-filter="videos" data-filter-state="true" data-toggle="tooltip" title="Show video media">Videos</a>
|
|
||||||
<a class="badge badge-light p-1 btn-filter" href="#" data-filter="stories" data-filter-state="false" data-toggle="tooltip" title="Show stories media">Stories</a>
|
|
||||||
<a class="badge badge-light p-1 btn-filter" href="#" data-filter="banned" data-filter-state="false" data-toggle="tooltip" title="Show banned media">Banned</a>
|
|
||||||
<a class="badge badge-light p-1 btn-filter" href="#" data-filter="reported" data-filter-state="false" data-toggle="tooltip" title="Show reported media">Reported</a>
|
|
||||||
<a class="badge badge-light p-1 btn-filter" href="#" data-filter="unlisted" data-filter-state="false" data-toggle="tooltip" title="Show unlisted media">Unlisted</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
@if(request()->input('layout') == 'list')
|
@if(request()->input('layout') !== 'card')
|
||||||
|
<div class="mb-3 bulk-actions d-none">
|
||||||
|
<div class="d-flex justify-content-between">
|
||||||
|
<span>
|
||||||
|
<span class="bulk-count font-weight-bold" data-count="0">
|
||||||
|
0
|
||||||
|
</span>
|
||||||
|
<span class="bulk-desc"> items selected</span>
|
||||||
|
</span>
|
||||||
|
<span class="d-inline-flex">
|
||||||
|
<select class="custom-select custom-select-sm font-weight-bold bulk-action">
|
||||||
|
<option selected disabled="">Select Bulk Action</option>
|
||||||
|
<option value="1" disabled="">Review (Coming in v0.9.0)</option>
|
||||||
|
<option value="2">Add C/W</option>
|
||||||
|
<option value="3">Unlist from timelines</option>
|
||||||
|
<option value="4">No Autolinking</option>
|
||||||
|
<option value="5">Suspend</option>
|
||||||
|
<option value="6">Delete</option>
|
||||||
|
</select>
|
||||||
|
<a class="btn btn-outline-primary btn-sm ml-3 font-weight-bold apply-bulk" href="#">
|
||||||
|
Apply
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead class="bg-light">
|
<thead class="bg-light">
|
||||||
<tr class="text-center">
|
<tr>
|
||||||
|
<th class="border-0" width="5%">
|
||||||
|
<div class="custom-control custom-checkbox table-check">
|
||||||
|
<input type="checkbox" class="custom-control-input row-check-item row-check-all" id="row-check-all">
|
||||||
|
<label class="custom-control-label" for="row-check-all"></label>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
<th scope="col" class="border-0" width="10%">
|
<th scope="col" class="border-0" width="10%">
|
||||||
<span>ID</span>
|
<span>
|
||||||
</th>
|
ID
|
||||||
<th scope="col" class="border-0" width="30%">
|
@if(request()->filter && request()->filter == 'id' && request()->order == 'asc')
|
||||||
<span>Username</span>
|
<a href="#" class="col-ord" data-col="id" data-dir="desc"><i class="fas fa-chevron-down"></i></a>
|
||||||
|
@else
|
||||||
|
<a href="#" class="col-ord" data-col="id" data-dir="asc"><i class="fas fa-chevron-up"></i></a>
|
||||||
|
@endif
|
||||||
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="border-0" width="15%">
|
<th scope="col" class="border-0" width="15%">
|
||||||
<span>Statuses</span>
|
<span>
|
||||||
|
Username
|
||||||
|
@if(request()->filter && request()->filter == 'username' && request()->order == 'asc')
|
||||||
|
<a href="#" class="col-ord" data-col="username" data-dir="desc"><i class="fas fa-chevron-down"></i></a>
|
||||||
|
@else
|
||||||
|
<a href="#" class="col-ord" data-col="username" data-dir="asc"><i class="fas fa-chevron-up"></i></a>
|
||||||
|
@endif
|
||||||
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="border-0" width="15%">
|
<th scope="col" class="border-0" width="20%">
|
||||||
<span>Storage</span>
|
<span>
|
||||||
|
Followers
|
||||||
|
@if(request()->filter && request()->filter == 'followers_count' && request()->order == 'asc')
|
||||||
|
<a href="#" class="col-ord" data-col="followers_count" data-dir="desc"><i class="fas fa-chevron-down"></i></a>
|
||||||
|
@else
|
||||||
|
<a href="#" class="col-ord" data-col="followers_count" data-dir="asc"><i class="fas fa-chevron-up"></i></a>
|
||||||
|
@endif
|
||||||
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="border-0" width="30%">
|
<th scope="col" class="border-0" width="20%">
|
||||||
|
<span>
|
||||||
|
Likes
|
||||||
|
@if(request()->filter && request()->filter == 'likes_count' && request()->order == 'asc')
|
||||||
|
<a href="#" class="col-ord" data-col="likes_count" data-dir="desc"><i class="fas fa-chevron-down"></i></a>
|
||||||
|
@else
|
||||||
|
<a href="#" class="col-ord" data-col="likes_count" data-dir="asc"><i class="fas fa-chevron-up"></i></a>
|
||||||
|
@endif
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="border-0" width="20%">
|
||||||
|
<span>
|
||||||
|
Statuses
|
||||||
|
@if(request()->filter && request()->filter == 'statuses_count' && request()->order == 'asc')
|
||||||
|
<a href="#" class="col-ord" data-col="statuses_count" data-dir="desc"><i class="fas fa-chevron-down"></i></a>
|
||||||
|
@else
|
||||||
|
<a href="#" class="col-ord" data-col="statuses_count" data-dir="asc"><i class="fas fa-chevron-up"></i></a>
|
||||||
|
@endif
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="border-0" width="10%">
|
||||||
|
<span>
|
||||||
|
Storage
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="border-0" width="10%">
|
||||||
<span>Actions</span>
|
<span>Actions</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@foreach($profiles as $profile)
|
@foreach($profiles as $profile)
|
||||||
<tr class="font-weight-bold text-center user-row">
|
<tr class="font-weight-bold text-center user-row">
|
||||||
<th scope="row">
|
<th scope="">
|
||||||
{{$profile->id}}
|
<div class="custom-control custom-checkbox">
|
||||||
|
<input type="checkbox" class="custom-control-input row-check-item" id="row-check-{{$profile->id}}" data-id="{{$profile->id}}">
|
||||||
|
<label class="custom-control-label" for="row-check-{{$profile->id}}"></label>
|
||||||
|
</div>
|
||||||
</th>
|
</th>
|
||||||
|
<td>
|
||||||
|
{{$profile->id}}
|
||||||
|
</td>
|
||||||
|
<td class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="{{$profile->username}}" style="max-width: 150px;">
|
||||||
|
{{$profile->username}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{$profile->followers()->count()}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{$profile->likes()->count()}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{$profile->statuses()->count()}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="filesize" data-size="{{$profile->media()->sum('size')}}">{{$profile->media()->sum('size')}} bytes</div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a class="btn btn-outline-secondary btn-sm py-0 mr-3" href="/i/admin/profiles/edit/{{$profile->id}}">Edit</a>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-center mt-5 small">
|
<div class="d-flex justify-content-center mt-5 small">
|
||||||
{{$profiles->links()}}
|
{{$profiles->appends([
|
||||||
|
'layout'=>request()->layout,
|
||||||
|
'search'=>request()->search,
|
||||||
|
'filter'=>request()->filter,
|
||||||
|
'order'=>request()->order
|
||||||
|
])->links()}}
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -84,7 +188,7 @@
|
||||||
<div class="col-12 col-md-4 mb-4">
|
<div class="col-12 col-md-4 mb-4">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header bg-white text-center" style="min-height: 80px">
|
<div class="card-header bg-white text-center" style="min-height: 80px">
|
||||||
<img class="box-shadow rounded-circle mb-3" src="{{$profile->avatarUrl()}}" width="64px">
|
<img class="box-shadow rounded-circle mb-3" src="{{$profile->avatarUrl()}}" width="64px" height="64px">
|
||||||
<p class="font-weight-bold mb-0 text-truncate">{{$profile->username}}</p>
|
<p class="font-weight-bold mb-0 text-truncate">{{$profile->username}}</p>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group list-group-flush small">
|
<ul class="list-group list-group-flush small">
|
||||||
|
@ -104,7 +208,7 @@
|
||||||
</li>
|
</li>
|
||||||
<li class="list-group-item text-center">
|
<li class="list-group-item text-center">
|
||||||
<a class="btn btn-outline-primary btn-sm py-0" href="{{$profile->url()}}">View</a>
|
<a class="btn btn-outline-primary btn-sm py-0" href="{{$profile->url()}}">View</a>
|
||||||
<a class="btn btn-outline-secondary btn-sm py-0" href="#">Actions</a>
|
<a class="btn btn-outline-secondary btn-sm py-0" href="/i/admin/profiles/edit/{{$profile->id}}">Edit</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -112,7 +216,12 @@
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-center mt-5 small">
|
<div class="d-flex justify-content-center mt-5 small">
|
||||||
{{$profiles->links()}}
|
{{$profiles->appends([
|
||||||
|
'layout'=>request()->layout,
|
||||||
|
'search'=>request()->search,
|
||||||
|
'filter'=>request()->filter,
|
||||||
|
'order'=>request()->order
|
||||||
|
])->links()}}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@endsection
|
@endsection
|
||||||
|
@ -124,7 +233,8 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-row:hover {
|
.user-row:hover,
|
||||||
|
.user-row-active {
|
||||||
background-color: #eff8ff;
|
background-color: #eff8ff;
|
||||||
}
|
}
|
||||||
.user-row:hover .action-row {
|
.user-row:hover .action-row {
|
||||||
|
@ -140,5 +250,128 @@
|
||||||
$('.filesize').each(function(k,v) {
|
$('.filesize').each(function(k,v) {
|
||||||
$(this).text(filesize(v.getAttribute('data-size'), {unix:true, round:0}))
|
$(this).text(filesize(v.getAttribute('data-size'), {unix:true, round:0}))
|
||||||
});
|
});
|
||||||
|
$('.col-ord').on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let el = $(this);
|
||||||
|
let ord = el.data('dir');
|
||||||
|
let col = el.data('col');
|
||||||
|
let wurl = new URL(window.location.href);
|
||||||
|
let query_string = wurl.search;
|
||||||
|
let search_params = new URLSearchParams(query_string);
|
||||||
|
|
||||||
|
if(ord == 'asc') {
|
||||||
|
search_params.set('filter', col);
|
||||||
|
search_params.set('order', ord);
|
||||||
|
wurl.search = search_params.toString();
|
||||||
|
el.find('i').removeClass('fa-chevron-up').addClass('fa-chevron-down');
|
||||||
|
el.data('dir', 'desc');
|
||||||
|
} else {
|
||||||
|
search_params.set('filter', col);
|
||||||
|
search_params.set('order', ord);
|
||||||
|
wurl.search = search_params.toString();
|
||||||
|
el.find('i').removeClass('fa-chevron-down').addClass('fa-chevron-up');
|
||||||
|
el.data('dir', 'asc');
|
||||||
|
}
|
||||||
|
window.location.href = wurl.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$(document).on('click', '#row-check-all', function(e) {
|
||||||
|
return;
|
||||||
|
let el = $(this);
|
||||||
|
let attr = el.attr('checked');
|
||||||
|
|
||||||
|
if (typeof attr !== typeof undefined && attr !== false) {
|
||||||
|
$('tbody .user-row').removeClass('user-row-active');
|
||||||
|
$('.bulk-actions').addClass('d-none');
|
||||||
|
$('.row-check-item').removeAttr('checked').prop('checked', false);
|
||||||
|
el.removeAttr('checked').prop('checked', false);
|
||||||
|
} else {
|
||||||
|
$('tbody .user-row').addClass('user-row-active');
|
||||||
|
$('.bulk-actions').removeClass('d-none');
|
||||||
|
el.attr('checked', '').prop('checked', true);
|
||||||
|
$('.row-check-item').attr('checked', '').prop('checked', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
let len = $('.row-check-item:checked').length;
|
||||||
|
if(attr == true) {
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
$('.bulk-count').text(len).attr('data-count', len);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$(document).on('click', '.row-check-item', function(e) {
|
||||||
|
return;
|
||||||
|
var el = $(this)[0];
|
||||||
|
let len = $('.row-check-item:checked').length;
|
||||||
|
if($('#row-check-all:checked').length > 0) {
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
if($(this).hasClass('row-check-all')) {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if(el.checked == true) {
|
||||||
|
$(this).parents().eq(2).addClass('user-row-active');
|
||||||
|
$('.bulk-actions').removeClass('d-none');
|
||||||
|
$('.bulk-count').text(len).attr('data-count', len);
|
||||||
|
} else {
|
||||||
|
$(this).parents().eq(2).removeClass('user-row-active');
|
||||||
|
if(len == 0) {
|
||||||
|
$('.bulk-actions').addClass('d-none');
|
||||||
|
} else {
|
||||||
|
$('.bulk-count').text(len).attr('data-count', len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(len == 0) {
|
||||||
|
$('.bulk-actions').addClass('d-none');
|
||||||
|
$('#row-check-all').prop('checked', false);
|
||||||
|
} else {
|
||||||
|
$('.bulk-actions').removeClass('d-none');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.apply-bulk', function(e) {
|
||||||
|
return;
|
||||||
|
e.preventDefault();
|
||||||
|
let len = $('.row-check-item:checked').length;
|
||||||
|
if($('#row-check-all:checked').length > 0) {
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
if(len == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let action = $('.bulk-action').val();
|
||||||
|
let ids = $('.row-check-item:checked').get().filter(i => {
|
||||||
|
let el = $(i);
|
||||||
|
if(el.hasClass('row-check-all')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}).map(i => {
|
||||||
|
return $(i).data('id');
|
||||||
|
});
|
||||||
|
let actions = [
|
||||||
|
'',
|
||||||
|
'review',
|
||||||
|
'cw',
|
||||||
|
'unlist',
|
||||||
|
'noautolink',
|
||||||
|
'suspend',
|
||||||
|
'delete'
|
||||||
|
];
|
||||||
|
action = actions[action];
|
||||||
|
if(!action) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
swal(
|
||||||
|
'Confirm',
|
||||||
|
'Are you sure you want to perform this action?',
|
||||||
|
'warning'
|
||||||
|
).then(res => {
|
||||||
|
console.log(action);
|
||||||
|
console.log(ids);
|
||||||
|
})
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
@endpush
|
@endpush
|
||||||
|
|
|
@ -66,12 +66,10 @@
|
||||||
<thead class="bg-light">
|
<thead class="bg-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
<div class="">
|
|
||||||
<div class="custom-control custom-checkbox table-check">
|
<div class="custom-control custom-checkbox table-check">
|
||||||
<input type="checkbox" class="custom-control-input row-check-item" id="row-check-all">
|
<input type="checkbox" class="custom-control-input row-check-item" id="row-check-all">
|
||||||
<label class="custom-control-label" for="row-check-all"></label>
|
<label class="custom-control-label" for="row-check-all"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">#</th>
|
<th scope="col">#</th>
|
||||||
<th scope="col">Reporter</th>
|
<th scope="col">Reporter</th>
|
||||||
|
@ -84,14 +82,14 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($reports as $report)
|
@foreach($reports as $report)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="">
|
<td scope="row">
|
||||||
<div class="custom-control custom-checkbox">
|
<div class="custom-control custom-checkbox">
|
||||||
<input type="checkbox" class="custom-control-input row-check-item" id="row-check-{{$report->id}}" data-resolved="{{$report->admin_seen?'true':'false'}}" data-id="{{$report->id}}">
|
<input type="checkbox" class="custom-control-input row-check-item" id="row-check-{{$report->id}}" data-resolved="{{$report->admin_seen?'true':'false'}}" data-id="{{$report->id}}">
|
||||||
<label class="custom-control-label" for="row-check-{{$report->id}}"></label>
|
<label class="custom-control-label" for="row-check-{{$report->id}}"></label>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{$report->url()}}" class="btn btn-sm btn-outline-primary">
|
<a href="{{$report->url()}}" class="btn btn-sm btn-outline-primary my-0 py-0">
|
||||||
{{$report->id}}
|
{{$report->id}}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
<div class="card-header bg-white p-3 text-center font-weight-bold">{{ __('Reset Password') }}</div>
|
<div class="card-header bg-white p-3 text-center font-weight-bold">{{ __('Reset Password') }}</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@if (session('status'))
|
@if (session('status') || $errors->has('email'))
|
||||||
<div class="alert alert-success">
|
<div class="alert alert-success">
|
||||||
{{ session('status') }}
|
{{ session('status') ?? $errors->first('email') }}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@ -19,13 +19,7 @@
|
||||||
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" placeholder="{{ __('E-Mail Address') }}" value="{{ old('email') }}" required>
|
<input id="email" type="email" class="form-control" name="email" placeholder="{{ __('E-Mail Address') }}" value="{{ old('email') }}" required>
|
||||||
|
|
||||||
@if ($errors->has('email'))
|
|
||||||
<span class="invalid-feedback">
|
|
||||||
<strong>{{ $errors->first('email') }}</strong>
|
|
||||||
</span>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ Route::domain(config('pixelfed.domain.admin'))->prefix('i/admin')->group(functio
|
||||||
Route::get('statuses/show/{id}', 'AdminController@showStatus');
|
Route::get('statuses/show/{id}', 'AdminController@showStatus');
|
||||||
Route::redirect('profiles', '/i/admin/profiles/list');
|
Route::redirect('profiles', '/i/admin/profiles/list');
|
||||||
Route::get('profiles/list', 'AdminController@profiles')->name('admin.profiles');
|
Route::get('profiles/list', 'AdminController@profiles')->name('admin.profiles');
|
||||||
|
Route::get('profiles/edit/{id}', 'AdminController@profileShow');
|
||||||
Route::redirect('users', '/users/list');
|
Route::redirect('users', '/users/list');
|
||||||
Route::get('users/list', 'AdminController@users')->name('admin.users');
|
Route::get('users/list', 'AdminController@users')->name('admin.users');
|
||||||
Route::get('users/edit/{id}', 'AdminController@editUser');
|
Route::get('users/edit/{id}', 'AdminController@editUser');
|
||||||
|
|
Loading…
Reference in a new issue