This commit is contained in:
2025-10-01 15:04:07 +05:00
commit b526a80e1f
33 changed files with 4581 additions and 0 deletions

113
frontend/src/App.jsx Normal file
View File

@@ -0,0 +1,113 @@
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.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.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