fix conflict

This commit is contained in:
yaschalew
2026-05-28 08:44:26 +03:00
15 changed files with 4350 additions and 97 deletions

View File

@@ -1,13 +1,11 @@
import { Navigate, Outlet, Route, Routes, useLocation, useNavigate } from "react-router-dom";
import { DashboardLayout, type SidebarItem } from "@edr/ui-common";
import { LayoutDashboard, ShieldCheck, Users, Building2 } from "lucide-react";
import { LayoutDashboard, Network } from "lucide-react";
import { useAuth } from "./auth/useAuth";
import LoginPage from "./pages/auth/LoginPage";
import OverviewPage from "./pages/dashboard/OverviewPage";
import UsersPage from "./pages/dashboard/user-management/UsersPage";
import RolesPage from "./pages/dashboard/user-management/RolesPage";
import DepartmentsPage from "./pages/dashboard/user-management/DepartmentsPage";
import UserManagementPage from "./pages/dashboard/user-management/UserManagementPage";
import LoadingScreen from "./components/LoadingScreen";
const sidebarItems: SidebarItem[] = [
@@ -19,23 +17,7 @@ const sidebarItems: SidebarItem[] = [
{
label: "User management",
href: "/dashboard/user-management",
icon: <ShieldCheck />,
children: [
{
label: "Users",
href: "/dashboard/user-management/users",
icon: <Users />,
},
{
label: "Roles",
href: "/dashboard/user-management/roles",
},
{
label: "Departments",
href: "/dashboard/user-management/departments",
icon: <Building2 />,
},
],
icon: <Network />,
},
];
@@ -84,16 +66,9 @@ const App = () => {
<Route path="/dashboard" element={<Navigate to="/dashboard/overview" replace />} />
<Route path="/dashboard" element={<DashboardShell />}>
<Route path="overview" element={<OverviewPage />} />
<Route
path="user-management"
element={<Navigate to="/dashboard/user-management/users" replace />}
/>
<Route path="user-management/users" element={<UsersPage />} />
<Route path="user-management/roles" element={<RolesPage />} />
<Route
path="user-management/departments"
element={<DepartmentsPage />}
/>
<Route path="user-management" element={<UserManagementPage />} />
<Route path="org-structure" element={<Navigate to="/dashboard/user-management" replace />} />
<Route path="org-structure/*" element={<Navigate to="/dashboard/user-management" replace />} />
</Route>
<Route path="*" element={<Navigate to="/dashboard/overview" replace />} />
</Routes>

View File

@@ -125,8 +125,15 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
mfaEmailRef.current = null;
},
logout: () => {
const preservedTheme = window.localStorage.getItem("edr-theme");
clearSessionCookies();
localStorage.clear();
window.localStorage.clear();
if (preservedTheme === "dark" || preservedTheme === "light") {
window.localStorage.setItem("edr-theme", preservedTheme);
}
setUser(null);
window.location.replace("/auth");
},

View File

@@ -1,11 +1,47 @@
interface LocaleText {
en?: string;
am?: string;
}
interface AuthRole {
id?: string;
key?: string;
}
interface AuthPermission {
id?: string;
key?: string;
}
interface AuthEmployeePosition {
id?: string;
employeePositionId?: string;
name?: LocaleText;
key?: string;
isDelegate?: boolean;
parentPositionId?: string | null;
permissions?: AuthPermission[];
}
interface AuthEmployeeRecord {
id?: string;
organizationId?: string;
unitId?: string;
name?: LocaleText;
positions?: AuthEmployeePosition[];
}
export interface AuthUser {
id?: string;
email?: string;
username?: string;
name?: {
en?: string;
am?: string;
};
phoneNumber?: string;
name?: LocaleText;
roles?: AuthRole[];
permissions?: AuthPermission[];
employee?: AuthEmployeeRecord[];
hasSetPassword?: boolean;
status?: string;
}
export interface AuthTokens {

View File

@@ -104,40 +104,8 @@ const LoginPage = () => {
};
return (
<div className="min-h-screen bg-[radial-gradient(circle_at_top,_rgba(15,118,110,0.14),_transparent_44%),linear-gradient(180deg,_var(--background),_color-mix(in_oklab,_var(--background)_92%,_#0f766e_8%))] px-6 py-10">
<div className="min-h-screen px-6 py-10">
<div className="mx-auto grid min-h-[calc(100vh-5rem)] max-w-6xl gap-8 lg:grid-cols-[1.1fr_0.9fr]">
<section className="flex flex-col justify-between rounded-[2rem] border border-border/60 bg-card/85 p-8 shadow-[0_24px_80px_rgba(15,23,42,0.10)] backdrop-blur md:p-10">
<div>
<div className="inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-[#0f766e] text-lg font-semibold text-white shadow-lg shadow-[#0f766e]/20">
EDR
</div>
<p className="mt-6 text-sm font-medium uppercase tracking-[0.3em] text-[#0f766e]">
Freight operations
</p>
<h1 className="mt-4 max-w-xl text-4xl font-semibold tracking-tight text-foreground md:text-5xl">
Backoffice access for internal freight administration.
</h1>
<p className="mt-5 max-w-xl text-base leading-7 text-muted-foreground">
Review operational activity, manage access, and coordinate internal railway workflows from a single dashboard.
</p>
</div>
<div className="grid gap-4 rounded-3xl border border-border/60 bg-background/80 p-5 md:grid-cols-3">
<div>
<p className="text-xs uppercase tracking-[0.2em] text-muted-foreground">Region</p>
<p className="mt-2 text-sm font-medium text-foreground">Ethiopia default phone normalization</p>
</div>
<div>
<p className="text-xs uppercase tracking-[0.2em] text-muted-foreground">Session</p>
<p className="mt-2 text-sm font-medium text-foreground">7-day persistent token cookie</p>
</div>
<div>
<p className="text-xs uppercase tracking-[0.2em] text-muted-foreground">Access</p>
<p className="mt-2 text-sm font-medium text-foreground">Overview and user management</p>
</div>
</div>
</section>
<section className="flex items-center">
<div className="w-full rounded-[2rem] border border-border/60 bg-card p-8 shadow-[0_20px_60px_rgba(15,23,42,0.12)] md:p-10">
{!needsMfa ? (