Added user account overview for admins
This commit is contained in:
@@ -3,10 +3,11 @@ import { User, Lock, Server, MessageSquare, Shield, TrendingUp, Eye, EyeOff } fr
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '../config';
|
||||
|
||||
export default function Profile({ token, user, theme, onUsernameChange }) {
|
||||
export default function Profile({ token, user, theme, onUsernameChange, viewingUsername }) {
|
||||
const [stats, setStats] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [activeTab, setActiveTab] = useState('overview');
|
||||
const isViewingOther = viewingUsername && viewingUsername !== user?.username;
|
||||
|
||||
// Форма смены имени
|
||||
const [usernameForm, setUsernameForm] = useState({
|
||||
@@ -28,11 +29,15 @@ export default function Profile({ token, user, theme, onUsernameChange }) {
|
||||
|
||||
useEffect(() => {
|
||||
loadStats();
|
||||
}, []);
|
||||
}, [viewingUsername]);
|
||||
|
||||
const loadStats = async () => {
|
||||
try {
|
||||
const { data } = await axios.get(`${API_URL}/api/profile/stats`, {
|
||||
const endpoint = isViewingOther
|
||||
? `${API_URL}/api/profile/stats/${viewingUsername}`
|
||||
: `${API_URL}/api/profile/stats`;
|
||||
|
||||
const { data } = await axios.get(endpoint, {
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
setStats(data);
|
||||
@@ -157,49 +162,55 @@ export default function Profile({ token, user, theme, onUsernameChange }) {
|
||||
<div className="max-w-6xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="mb-6">
|
||||
<h1 className="text-2xl font-bold mb-2">Личный кабинет</h1>
|
||||
<p className={theme.textSecondary}>Управление профилем и настройками</p>
|
||||
<h1 className="text-2xl font-bold mb-2">
|
||||
{isViewingOther ? `Профиль пользователя: ${viewingUsername}` : 'Личный кабинет'}
|
||||
</h1>
|
||||
<p className={theme.textSecondary}>
|
||||
{isViewingOther ? 'Просмотр профиля другого пользователя' : 'Управление профилем и настройками'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Tabs */}
|
||||
<div className={`${theme.secondary} ${theme.border} border rounded-2xl mb-6 p-2 flex gap-2`}>
|
||||
<button
|
||||
onClick={() => setActiveTab('overview')}
|
||||
className={`flex-1 px-4 py-3 rounded-xl font-medium transition ${
|
||||
activeTab === 'overview'
|
||||
? `${theme.accent} text-white`
|
||||
: `${theme.hover}`
|
||||
}`}
|
||||
>
|
||||
<TrendingUp className="w-4 h-4 inline mr-2" />
|
||||
Обзор
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('username')}
|
||||
className={`flex-1 px-4 py-3 rounded-xl font-medium transition ${
|
||||
activeTab === 'username'
|
||||
? `${theme.accent} text-white`
|
||||
: `${theme.hover}`
|
||||
}`}
|
||||
>
|
||||
<User className="w-4 h-4 inline mr-2" />
|
||||
Имя пользователя
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('password')}
|
||||
className={`flex-1 px-4 py-3 rounded-xl font-medium transition ${
|
||||
activeTab === 'password'
|
||||
? `${theme.accent} text-white`
|
||||
: `${theme.hover}`
|
||||
}`}
|
||||
>
|
||||
<Lock className="w-4 h-4 inline mr-2" />
|
||||
Пароль
|
||||
</button>
|
||||
</div>
|
||||
{!isViewingOther && (
|
||||
<div className={`${theme.secondary} ${theme.border} border rounded-2xl mb-6 p-2 flex gap-2`}>
|
||||
<button
|
||||
onClick={() => setActiveTab('overview')}
|
||||
className={`flex-1 px-4 py-3 rounded-xl font-medium transition ${
|
||||
activeTab === 'overview'
|
||||
? `${theme.accent} text-white`
|
||||
: `${theme.hover}`
|
||||
}`}
|
||||
>
|
||||
<TrendingUp className="w-4 h-4 inline mr-2" />
|
||||
Обзор
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('username')}
|
||||
className={`flex-1 px-4 py-3 rounded-xl font-medium transition ${
|
||||
activeTab === 'username'
|
||||
? `${theme.accent} text-white`
|
||||
: `${theme.hover}`
|
||||
}`}
|
||||
>
|
||||
<User className="w-4 h-4 inline mr-2" />
|
||||
Имя пользователя
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('password')}
|
||||
className={`flex-1 px-4 py-3 rounded-xl font-medium transition ${
|
||||
activeTab === 'password'
|
||||
? `${theme.accent} text-white`
|
||||
: `${theme.hover}`
|
||||
}`}
|
||||
>
|
||||
<Lock className="w-4 h-4 inline mr-2" />
|
||||
Пароль
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Overview Tab */}
|
||||
{activeTab === 'overview' && (
|
||||
{(activeTab === 'overview' || isViewingOther) && (
|
||||
<div className="space-y-6">
|
||||
{/* User Info Card */}
|
||||
<div className={`${theme.card} ${theme.border} border rounded-2xl p-6`}>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Users as UsersIcon, Trash2, Shield, User } from 'lucide-react';
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '../config';
|
||||
|
||||
export default function Users({ token }) {
|
||||
export default function Users({ token, onViewProfile }) {
|
||||
const [users, setUsers] = useState([]);
|
||||
const [servers, setServers] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -111,7 +111,13 @@ export default function Users({ token }) {
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold">{user.username}</h3>
|
||||
<button
|
||||
onClick={() => onViewProfile && onViewProfile(user.username)}
|
||||
className="text-lg font-semibold hover:text-blue-400 transition cursor-pointer text-left"
|
||||
title="Просмотреть профиль"
|
||||
>
|
||||
{user.username}
|
||||
</button>
|
||||
<p className="text-sm text-gray-400">
|
||||
{user.role === 'admin' ? 'Администратор' : user.role === 'support' ? 'Тех. поддержка' : user.role === 'banned' ? 'Забанен' : 'Пользователь'}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user