mirror of
https://github.com/crivion/laranode.git
synced 2026-09-03 06:24:09 +08:00
regular user dashboard
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\SystemStatsService;
|
||||
use App\Models\Website;
|
||||
use App\Models\Database;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
@@ -41,6 +43,14 @@ class DashboardController extends Controller
|
||||
|
||||
public function user()
|
||||
{
|
||||
return Inertia::render('Dashboard/User/UserDashboard');
|
||||
$user = auth()->user();
|
||||
$websitesCount = Website::mine()->count();
|
||||
$databasesCount = Database::mine()->count();
|
||||
$websitesLimit = $user->domain_limit;
|
||||
$databasesLimit = $user->database_limit;
|
||||
|
||||
return Inertia::render('Dashboard/User/UserDashboard', compact(
|
||||
'websitesCount', 'websitesLimit', 'databasesCount', 'databasesLimit'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class Database extends Model
|
||||
{
|
||||
@@ -44,4 +45,10 @@ class Database extends Model
|
||||
{
|
||||
$this->attributes['db_password'] = encrypt($password);
|
||||
}
|
||||
|
||||
public function scopeMine(Builder $query): Builder
|
||||
{
|
||||
$user = auth()->user();
|
||||
return $query->when($user && !$user->isAdmin(), fn($query) => $query->where('user_id', $user->id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { FaUsers } from "react-icons/fa6";
|
||||
import { TbWorldWww } from 'react-icons/tb';
|
||||
import { FaDatabase } from 'react-icons/fa';
|
||||
import { VscFileSubmodule } from 'react-icons/vsc';
|
||||
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
|
||||
import { Head, Link } from '@inertiajs/react';
|
||||
import { usePage } from '@inertiajs/react';
|
||||
|
||||
export default function UserDashboard() {
|
||||
|
||||
const { auth } = usePage().props;
|
||||
const { auth, websitesCount, websitesLimit, databasesCount, databasesLimit } = usePage().props;
|
||||
|
||||
return (
|
||||
<AuthenticatedLayout
|
||||
@@ -18,14 +21,51 @@ export default function UserDashboard() {
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Head title="Accounts" />
|
||||
<Head title="Dashboard" />
|
||||
|
||||
<div className="max-w-7xl px-4 my-8">
|
||||
This is the user dashboard, {auth.user.username}
|
||||
<br />
|
||||
<Link href={route('accounts.leaveImpersonation')}>
|
||||
Leave Impersonation
|
||||
</Link>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="bg-white dark:bg-gray-850 rounded-lg p-5 border border-gray-200 dark:border-gray-800 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">Websites</div>
|
||||
<div className="text-2xl font-semibold text-gray-800 dark:text-gray-100 mt-1">
|
||||
{websitesCount}/{websitesLimit ?? '∞'}
|
||||
</div>
|
||||
<Link href={route('websites.index')} className="inline-block mt-3 text-sm text-blue-600 dark:text-blue-400 hover:underline">Manage Websites</Link>
|
||||
</div>
|
||||
<TbWorldWww className="w-12 h-12 text-indigo-500" />
|
||||
</div>
|
||||
|
||||
<div className="bg-white dark:bg-gray-850 rounded-lg p-5 border border-gray-200 dark:border-gray-800 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">Databases</div>
|
||||
<div className="text-2xl font-semibold text-gray-800 dark:text-gray-100 mt-1">
|
||||
{databasesCount}/{databasesLimit ?? '∞'}
|
||||
</div>
|
||||
<Link href={route('mysql.index')} className="inline-block mt-3 text-sm text-blue-600 dark:text-blue-400 hover:underline">Manage MySQL DBs</Link>
|
||||
</div>
|
||||
<FaDatabase className="w-12 h-12 text-emerald-500" />
|
||||
</div>
|
||||
|
||||
<div className="bg-white dark:bg-gray-850 rounded-lg p-5 border border-gray-200 dark:border-gray-800 flex items-center justify-between">
|
||||
<div>
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">File Manager</div>
|
||||
<div className="text-2xl font-semibold text-gray-800 dark:text-gray-100 mt-1"> </div>
|
||||
<Link href={route('filemanager')} className="inline-block mt-3 text-sm text-blue-600 dark:text-blue-400 hover:underline">Open File Manager</Link>
|
||||
</div>
|
||||
<VscFileSubmodule className="w-12 h-12 text-amber-500" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 text-sm text-gray-600 dark:text-gray-400">
|
||||
Logged in as <span className="font-medium">{auth.user.username}</span>
|
||||
{auth.user?.is_impersonating && (
|
||||
<>
|
||||
<span className="mx-2">•</span>
|
||||
<Link href={route('accounts.leaveImpersonation')} className="text-blue-600 dark:text-blue-400 hover:underline">Leave Impersonation</Link>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</AuthenticatedLayout>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user