Reformating route and renaming firm and correcting login redirections

This commit is contained in:
2025-04-11 22:00:57 +02:00
parent d1718becde
commit 4e613554e6
7 changed files with 132 additions and 34 deletions

View File

@@ -23,8 +23,8 @@ import { ForgotPassword } from "./components/auth/ForgotPassword";
import { UpdatePassword } from "./components/auth/UpdatePassword"; import { UpdatePassword } from "./components/auth/UpdatePassword";
import { Header } from "./components"; import { Header } from "./components";
import { Hub } from "./pages/hub"; import { HubRoutes } from "./pages/hub";
import { CreateFirm } from "./pages/hub/CreateFirm"; import { FirmRoutes } from "./pages/firm";
function App() { function App() {
return ( return (
@@ -43,26 +43,42 @@ function App() {
syncWithLocation: true, syncWithLocation: true,
warnWhenUnsavedChanges: true, warnWhenUnsavedChanges: true,
useNewQueryKeys: true, useNewQueryKeys: true,
disableTelemetry: true disableTelemetry: true,
reactQuery: {
clientConfig: {
defaultOptions: {
queries: {
retry: (failureCount, error) => {
// @ts-ignore
if (error.status >= 400 && error.status <= 499) {
return false
}
return failureCount < 4
},
}
}
}
}
}} }}
> >
<Header />
<Routes> <Routes>
<Route <Route
element={( element={(
<Authenticated key="authenticated-routes" redirectOnFail="/login" fallback={<CatchAllNavigate to="/login"/>}> <Authenticated key="authenticated-routes" redirectOnFail="/auth/login" fallback={<CatchAllNavigate to="/auth/login"/>}>
<Outlet /> <Outlet />
</Authenticated> </Authenticated>
)} )}
> >
<Route path="/hub" element={ <Hub /> } /> <Route path="hub/*" element={<HubRoutes />} />
<Route path="/hub/create-firm" element={ <CreateFirm /> } /> <Route path="firm/*" element={<FirmRoutes />} />
</Route> </Route>
<Route index element={<h1>HOME&nbsp;<Link to={"/login"}>Login</Link></h1>} /> <Route path="auth/*" element={<><Header /><Outlet /></>}>
<Route path="/login" element={<Login />} /> <Route path="login" element={<Login />} />
<Route path="/register" element={<Register />} /> <Route path="register" element={<Register />} />
<Route path="/forgot-password" element={<ForgotPassword />} /> <Route path="forgot-password" element={<ForgotPassword />} />
<Route path="/update-password" element={<UpdatePassword />} /> <Route path="update-password" element={<UpdatePassword />} />
</Route>
<Route index element={<><Header /><h1>HOME&nbsp;<Link to={"/auth/login"}>Login</Link></h1></>} />
</Routes> </Routes>
<UnsavedChangesNotifier /> <UnsavedChangesNotifier />
<DocumentTitleHandler /> <DocumentTitleHandler />

View File

@@ -12,11 +12,13 @@ import React, { useContext } from "react";
import { ColorModeContext } from "../../contexts/color-mode"; import { ColorModeContext } from "../../contexts/color-mode";
import { Logout } from "../auth/Logout"; import { Logout } from "../auth/Logout";
import { IUser } from "../../interfaces"; import { IUser } from "../../interfaces";
import { FirmContext } from "../../contexts/FirmContext";
export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({ export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
sticky = true, sticky = true,
}) => { }) => {
const { mode, setMode } = useContext(ColorModeContext); const { mode, setMode } = useContext(ColorModeContext);
const { currentFirm } = useContext(FirmContext);
const { data: user } = useGetIdentity<IUser>(); const { data: user } = useGetIdentity<IUser>();

View File

@@ -0,0 +1,25 @@
import React, { createContext, PropsWithChildren } from 'react';
import { IFirm } from "../interfaces";
import { useParams } from "react-router";
type FirmContextType = {
currentFirm: IFirm,
}
export const FirmContext = createContext<FirmContextType>(
{} as FirmContextType
);
export const FirmContextProvider: React.FC<PropsWithChildren> = ({ children }: PropsWithChildren) => {
const { instance, firm } = useParams<IFirm>()
if (instance === undefined || firm === undefined) {
return "Error"
}
return (
<FirmContext.Provider value={{currentFirm: {instance, firm}}} >
{ children }
</FirmContext.Provider>
);
}

View File

@@ -1,7 +1,7 @@
export type IFirm = { export type IFirm = {
instance: string, instance: string,
name: string firm: string
} }
type User = { type User = {

View File

@@ -0,0 +1,28 @@
import {Route, Routes} from "react-router";
import React, { useContext } from "react";
import { FirmContext, FirmContextProvider } from "../../contexts/FirmContext";
import { Header } from "../../components";
export const FirmRoutes = () => {
return (
<>
<Header />
<Routes>
<Route path="/:instance/:firm/*" element={
<FirmContextProvider>
<Routes>
<Route index element={ <FirmHome /> } />
</Routes>
</FirmContextProvider>
} />
</Routes>
</>
);
}
const FirmHome = () => {
const { currentFirm } = useContext(FirmContext);
return (
<h1>This is la firme {currentFirm.instance} / {currentFirm.firm}</h1>
);
}

View File

@@ -1,14 +1,30 @@
import { Button } from "@mui/material"; import { Button } from "@mui/material";
import { Link } from "react-router"; import ExitToAppIcon from '@mui/icons-material/ExitToApp';
import React from 'react';
import {Link, Route, Routes} from "react-router";
import { useGetIdentity, useList } from "@refinedev/core"; import { useGetIdentity, useList } from "@refinedev/core";
import { IAuthUser, IFirm } from "../../interfaces"; import { IAuthUser, IFirm } from "../../interfaces";
import {CreateFirm} from "./CreateFirm";
import {Header} from "../../components";
export const Hub = () => { export const HubRoutes = () => {
const { data: user } = useGetIdentity<IAuthUser>(); return (
<>
<Header />
<Routes>
<Route index element={ <HubHome /> } />
<Route path="create-firm" element={ <CreateFirm /> } />
</Routes>
</>
);
};
const HubHome = () => {
const { data: user, refetch } = useGetIdentity<IAuthUser>();
const { data: list } = useList<IFirm>({resource: "hub/users/firms/", pagination: { mode: "off" }}, ) const { data: list } = useList<IFirm>({resource: "hub/users/firms/", pagination: { mode: "off" }}, )
if (user === undefined || list === undefined) { if (user === undefined || list === undefined) {
return <p>Loading</p> return <p>Loading</p>;
} }
console.log("list data: ", list); console.log("list data: ", list);
const ownedFirms = list.data; const ownedFirms = list.data;
@@ -16,23 +32,25 @@ export const Hub = () => {
return <p>Loading</p> return <p>Loading</p>
} }
console.log("owned firms: ", ownedFirms); console.log("owned firms: ", ownedFirms);
return ( return (
<div> <div>
<h1>HUB</h1> <h1>HUB</h1>
<p>List of managed firms</p> <p>List of managed firms</p>
<ul> <ul>
{ownedFirms.map((f: IFirm, index) => ( {ownedFirms.map((f: IFirm, index) => (
<li key={index}>{f.instance} / {f.name}</li> <li key={index}>{f.instance} / {f.firm}</li>
))} ))}
</ul> </ul>
<p>List of firm you're working at</p> <p>List of firm you're working at</p>
<ul> <ul>
{user.firms.map((f: IFirm, index) => ( {user.firms.map((f: IFirm, index) => (
<li key={index}>{f.instance} / {f.name}</li> <li key={index}>
{f.instance} / {f.firm}&nbsp;<Link to={`/firm/${f.instance}/${f.firm}`}><ExitToAppIcon /></Link>
</li>
))} ))}
</ul> </ul>
<Link to="/hub/create-firm" ><Button>Create a new firm</Button></Link> <Link to="/hub/create-firm" ><Button>Create a new firm</Button></Link>
<Button onClick={() => refetch()}>Refresh</Button>
</div> </div>
); )
}; }

View File

@@ -7,9 +7,12 @@ const LOCAL_STORAGE_USER_KEY = "rpk-gui-current-user";
const GOOGLE_SCOPES = { "scopes": "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email" }; const GOOGLE_SCOPES = { "scopes": "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email" };
const DISCORD_SCOPES = { "scopes": "identify email" } const DISCORD_SCOPES = { "scopes": "identify email" }
const DEFAULT_LOGIN_REDIRECT = "/hub"
export const authProvider: AuthProvider = { export const authProvider: AuthProvider = {
login: async ({ providerName, email, password }) => { login: async ({ providerName, email, password }) => {
const to_param = findGetParameter("to"); const to_param = findGetParameter("to");
const redirect = to_param === null ? DEFAULT_LOGIN_REDIRECT : to_param
if (providerName) { if (providerName) {
let scope = {}; let scope = {};
if (providerName === "google") { if (providerName === "google") {
@@ -22,11 +25,14 @@ export const authProvider: AuthProvider = {
const response = await fetch(url, { method: "GET", },); const response = await fetch(url, { method: "GET", },);
const body = await response.json(); const body = await response.json();
if (to_param) {
localStorage.setItem("redirect_after_login", to_param); localStorage.setItem("redirect_after_login", redirect);
}
window.location.href = body.authorization_url; window.location.href = body.authorization_url;
return { success: true }; return {
success: true,
redirectTo: ""
};
} else if (email !== undefined && password !== undefined) { } else if (email !== undefined && password !== undefined) {
const params = new URLSearchParams({"grant_type": "password", "username": email, "password": password}); const params = new URLSearchParams({"grant_type": "password", "username": email, "password": password});
const response = await fetch( const response = await fetch(
@@ -42,7 +48,10 @@ export const authProvider: AuthProvider = {
const user = await response.json(); const user = await response.json();
store_user(user); store_user(user);
return { success: true }; return {
success: true,
redirectTo: redirect,
};
} }
} }
@@ -60,7 +69,7 @@ export const authProvider: AuthProvider = {
if (get_user() == null) { if (get_user() == null) {
return { return {
authenticated: false, authenticated: false,
redirectTo: "/login", redirectTo: "/auth/login",
logout: true logout: true
} }
} }
@@ -142,7 +151,7 @@ export const authProvider: AuthProvider = {
if (error?.status === 401) { if (error?.status === 401) {
forget_user(); forget_user();
return { return {
redirectTo: "/login", redirectTo: "/auth/login",
logout: true, logout: true,
error: { message: "Authentication required" }, error: { message: "Authentication required" },
} as OnErrorResponse; } as OnErrorResponse;