Initial commit: backend scaffold, auth, frontend login
- FastAPI + SQLAlchemy async + Alembic + Postgres backend - Auth: JWT access + rotating refresh tokens, argon2, roles, audit log - React 19 + Vite frontend: login page, protected route, auth context - Docker Compose: postgres, redis, migrate, api, worker (placeholder), frontend/nginx Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
.dashboard-shell {
|
||||
min-height: 100svh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dashboard-topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 24px;
|
||||
background: var(--color-surface);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.dashboard-brand {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.dashboard-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 14px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.dashboard-role {
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
background: var(--color-bg);
|
||||
border: 1px solid var(--color-border);
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.dashboard-logout {
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
border-radius: 8px;
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dashboard-logout:hover {
|
||||
border-color: var(--color-primary);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.dashboard-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.dashboard-placeholder {
|
||||
text-align: center;
|
||||
max-width: 420px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.dashboard-placeholder h2 {
|
||||
color: var(--color-text);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import '@/pages/DashboardPage.css'
|
||||
import { useAuth } from '@/features/auth/useAuth'
|
||||
|
||||
const ROLE_LABEL: Record<string, string> = {
|
||||
admin: 'Администратор',
|
||||
cashier: 'Кассир',
|
||||
viewer: 'Наблюдатель',
|
||||
}
|
||||
|
||||
/**
|
||||
* Временная заглушка. Очередь «получено, чек не пробит» — этап 6 плана,
|
||||
* пока здесь только подтверждение, что вход и защищённый роут работают.
|
||||
*/
|
||||
export function DashboardPage() {
|
||||
const { user, logout } = useAuth()
|
||||
|
||||
return (
|
||||
<div className="dashboard-shell">
|
||||
<header className="dashboard-topbar">
|
||||
<span className="dashboard-brand">lux_fiscal</span>
|
||||
<div className="dashboard-user">
|
||||
<span>{user?.full_name}</span>
|
||||
<span className="dashboard-role">{user ? (ROLE_LABEL[user.role] ?? user.role) : ''}</span>
|
||||
<button type="button" className="dashboard-logout" onClick={() => void logout()}>
|
||||
Выйти
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="dashboard-body">
|
||||
<div className="dashboard-placeholder">
|
||||
<h2>Очередь заказов появится здесь</h2>
|
||||
<p>
|
||||
Вход выполнен успешно. Экран «получено, чек не пробит» будет добавлен на следующих
|
||||
этапах — после интеграций с Новой Поштой и Checkbox.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user