regular user dashboard

This commit is contained in:
Crivion
2025-10-23 09:53:16 +03:00
parent cc393d10dc
commit e046c77e05
3 changed files with 65 additions and 8 deletions

View File

@@ -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'
));
}
}

View File

@@ -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));
}
}

View File

@@ -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">&nbsp;</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>
);