114 lines
3.4 KiB
JavaScript
114 lines
3.4 KiB
JavaScript
import { useState, useEffect } from 'react'
|
||
import './App.css'
|
||
|
||
function App() {
|
||
const [userInfo, setUserInfo] = useState(null)
|
||
const [loading, setLoading] = useState(true)
|
||
const [error, setError] = useState(null)
|
||
|
||
useEffect(() => {
|
||
// Получаем информацию о пользователе от бэкенда
|
||
fetch('/api/user-info')
|
||
.then(response => {
|
||
if (!response.ok) {
|
||
throw new Error(`HTTP error! status: ${response.status}`)
|
||
}
|
||
return response.json()
|
||
})
|
||
.then(data => {
|
||
setUserInfo(data)
|
||
setLoading(false)
|
||
})
|
||
.catch(err => {
|
||
setError(err.message)
|
||
setLoading(false)
|
||
})
|
||
}, [])
|
||
|
||
if (loading) {
|
||
return (
|
||
<div className="container">
|
||
<div className="loading">Загрузка...</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
if (error) {
|
||
return (
|
||
<div className="container">
|
||
<div className="error">
|
||
<h2>Ошибка</h2>
|
||
<p>{error}</p>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="container">
|
||
<header className="header">
|
||
<h1>Dex Authentication Demo</h1>
|
||
<p className="subtitle">Демонстрация аутентификации через DexAuthenticator</p>
|
||
</header>
|
||
|
||
<div className="user-card">
|
||
<h2>Информация о пользователе</h2>
|
||
<div className="info-grid">
|
||
<div className="info-item">
|
||
<span className="label">Email:</span>
|
||
<span className="value">{userInfo.email || 'Не указан'}</span>
|
||
</div>
|
||
<div className="info-item">
|
||
<span className="label">Полное имя:</span>
|
||
<span className="value">{userInfo.full_name || 'Не указано'}</span>
|
||
</div>
|
||
{userInfo.organization && (
|
||
<div className="info-item">
|
||
<span className="label">Организация:</span>
|
||
<span className="value">{userInfo.organization.name}</span>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
<div className="roles-section">
|
||
<h3>Роли</h3>
|
||
<div className="roles-list">
|
||
{userInfo.roles && userInfo.roles.map(role => (
|
||
<div key={role.id} className="role-badge">
|
||
<span className="role-name">{role.name}</span>
|
||
{role.description && (
|
||
<span className="role-description">{role.description}</span>
|
||
)}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div className="links-section">
|
||
<h3>Доступные ресурсы</h3>
|
||
{userInfo.available_links && userInfo.available_links.length > 0 ? (
|
||
<div className="links-grid">
|
||
{userInfo.available_links.map(link => (
|
||
<a
|
||
key={link.id}
|
||
href={link.url}
|
||
className="link-card"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
>
|
||
<h4>{link.title}</h4>
|
||
{link.description && <p>{link.description}</p>}
|
||
</a>
|
||
))}
|
||
</div>
|
||
) : (
|
||
<p className="no-links">У вас нет доступных ресурсов</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default App
|