Refactor Protected and Public Routes for Consistent Loading UI; Enhance HomePage with User Company and Branch Details; Update LoginPage Layout; Introduce User Relations in Auth Services

This commit is contained in:
2025-10-03 17:52:56 +05:00
parent 531e2d2e7e
commit 0b024af454
31 changed files with 1770 additions and 115 deletions
+1 -2
View File
@@ -14,7 +14,7 @@ function ProtectedRoute({ children }: ProtectedRouteProps) {
// Показываем загрузку пока проверяем авторизацию
if (isLoading) {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="flex justify-center items-center min-h-screen">
<div className="text-xl">Проверка авторизации...</div>
</div>
);
@@ -30,4 +30,3 @@ function ProtectedRoute({ children }: ProtectedRouteProps) {
}
export default ProtectedRoute;
+1 -2
View File
@@ -15,7 +15,7 @@ function PublicRoute({ children }: PublicRouteProps) {
// Показываем загрузку пока проверяем авторизацию
if (isLoading) {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="flex justify-center items-center min-h-screen">
<div className="text-xl">Загрузка...</div>
</div>
);
@@ -31,4 +31,3 @@ function PublicRoute({ children }: PublicRouteProps) {
}
export default PublicRoute;
-1
View File
@@ -18,4 +18,3 @@ export const api = ky.create({
],
},
});
-1
View File
@@ -12,4 +12,3 @@ export const queryClient = new QueryClient({
},
},
});
+51 -7
View File
@@ -12,24 +12,68 @@ function HomePage() {
};
return (
<div className="min-h-screen bg-gray-50 py-8">
<div className="max-w-4xl mx-auto px-4">
<div className="bg-white rounded-lg shadow-md p-8">
<h1 className="text-3xl font-bold mb-6">Главная страница</h1>
<div className="py-8 min-h-screen bg-gray-50">
<div className="px-4 mx-auto max-w-4xl">
<div className="p-8 bg-white rounded-lg shadow-md">
<h1 className="mb-6 text-3xl font-bold">Главная страница</h1>
<div className="space-y-4">
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
<h2 className="text-xl font-semibold mb-2">
<div className="p-4 bg-blue-50 rounded-lg border border-blue-200">
<h2 className="mb-2 text-xl font-semibold">
Добро пожаловать, {user?.fullName}!
</h2>
<p className="text-gray-600">Email: {user?.email}</p>
<p className="text-gray-600">Роль: {user?.role}</p>
</div>
{user?.currentCompany && (
<div className="p-4 bg-green-50 rounded-lg border border-green-200">
<h3 className="mb-2 text-lg font-semibold">Компания</h3>
<p className="font-medium text-gray-700">
{user.currentCompany.name}
</p>
{user.currentCompany.description && (
<p className="mt-1 text-sm text-gray-600">
{user.currentCompany.description}
</p>
)}
</div>
)}
{user?.currentBranch && (
<div className="p-4 bg-purple-50 rounded-lg border border-purple-200">
<h3 className="mb-2 text-lg font-semibold">Филиал</h3>
<p className="font-medium text-gray-700">
{user.currentBranch.name}
</p>
{user.currentBranch.address && (
<p className="mt-1 text-sm text-gray-600">
Адрес: {user.currentBranch.address}
</p>
)}
{(user.currentBranch.city || user.currentBranch.country) && (
<p className="text-sm text-gray-600">
{[user.currentBranch.city, user.currentBranch.country]
.filter(Boolean)
.join(", ")}
</p>
)}
</div>
)}
{!user?.currentBranch && !user?.currentCompany && (
<div className="p-4 bg-yellow-50 rounded-lg border border-yellow-200">
<p className="text-yellow-800">
Вы не привязаны ни к одному филиалу. Обратитесь к
администратору.
</p>
</div>
)}
<button
onClick={handleLogout}
disabled={logoutMutation.isPending}
className="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 disabled:opacity-50"
className="px-4 py-2 text-white bg-red-600 rounded-md hover:bg-red-700 disabled:opacity-50"
>
{logoutMutation.isPending ? "Выход..." : "Выйти"}
</button>
+11 -8
View File
@@ -22,8 +22,8 @@ function LoginPage() {
};
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<div className="max-w-md w-full space-y-8 p-8 bg-white rounded-lg shadow-md">
<div className="flex justify-center items-center min-h-screen bg-gray-50">
<div className="p-8 space-y-8 w-full max-w-md bg-white rounded-lg shadow-md">
<div>
<h2 className="text-3xl font-bold text-center text-gray-900">
Вход в аккаунт
@@ -45,7 +45,7 @@ function LoginPage() {
required
value={email}
onChange={(e) => setEmail(e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
className="block px-3 py-2 mt-1 w-full rounded-md border border-gray-300 shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
placeholder="your@email.com"
/>
</div>
@@ -63,14 +63,14 @@ function LoginPage() {
required
value={password}
onChange={(e) => setPassword(e.target.value)}
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
className="block px-3 py-2 mt-1 w-full rounded-md border border-gray-300 shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
placeholder="••••••••"
/>
</div>
</div>
{loginMutation.isError && (
<div className="text-red-600 text-sm text-center">
<div className="text-sm text-center text-red-600">
Неверный email или пароль
</div>
)}
@@ -78,14 +78,17 @@ function LoginPage() {
<button
type="submit"
disabled={loginMutation.isPending}
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
className="flex justify-center px-4 py-2 w-full text-sm font-medium text-white bg-blue-600 rounded-md border border-transparent shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
>
{loginMutation.isPending ? "Вход..." : "Войти"}
</button>
<div className="text-center text-sm text-gray-600">
<div className="text-sm text-center text-gray-600">
Нет аккаунта?{" "}
<Link to="/register" className="text-blue-600 hover:text-blue-700 font-medium">
<Link
to="/register"
className="font-medium text-blue-600 hover:text-blue-700"
>
Зарегистрироваться
</Link>
</div>
+16 -1
View File
@@ -1,11 +1,27 @@
export type RoleName = "admin" | "director" | "manager";
export interface Branch {
id: string;
name: string;
address: string | null;
city: string | null;
country: string | null;
}
export interface Company {
id: string;
name: string;
description: string | null;
}
export interface User {
id: string;
email: string;
fullName: string;
role: RoleName;
createdAt: string;
currentBranch?: Branch;
currentCompany?: Company;
}
export interface LoginData {
@@ -35,4 +51,3 @@ export interface RegisterResponse {
export interface MeResponse {
user: User;
}