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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -18,4 +18,3 @@ export const api = ky.create({
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -12,4 +12,3 @@ export const queryClient = new QueryClient({
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user