Improving user management and auto-refreshing user firms
This commit is contained in:
@@ -13,7 +13,7 @@ import routerBindings, {
|
||||
DocumentTitleHandler,
|
||||
UnsavedChangesNotifier,
|
||||
} from "@refinedev/react-router";
|
||||
import { BrowserRouter, Outlet, Route, Routes } from "react-router";
|
||||
import { BrowserRouter, Link, Outlet, Route, Routes } from "react-router";
|
||||
import { authProvider } from "./providers/auth-provider";
|
||||
import { dataProvider } from "./providers/data-provider";
|
||||
import { ColorModeContextProvider } from "./contexts/color-mode";
|
||||
@@ -58,7 +58,7 @@ function App() {
|
||||
<Route path="/hub" element={ <Hub /> } />
|
||||
<Route path="/hub/create-firm" element={ <CreateFirm /> } />
|
||||
</Route>
|
||||
<Route index element={<h1>HOME</h1>} />
|
||||
<Route index element={<h1>HOME <Link to={"/login"}>Login</Link></h1>} />
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route path="/register" element={<Register />} />
|
||||
<Route path="/forgot-password" element={<ForgotPassword />} />
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import {Navigate, useSearchParams} from "react-router";
|
||||
import {AuthPage} from "@refinedev/mui";
|
||||
import GoogleIcon from "@mui/icons-material/Google";
|
||||
import DiscordIcon from "../DiscordIcon";
|
||||
import { useLogout } from "@refinedev/core";
|
||||
|
||||
export const Logout = () => {
|
||||
const { mutate: logout } = useLogout();
|
||||
|
||||
return <button onClick={() => logout()}>Logout</button>;
|
||||
return <button onClick={() => logout()} >Logout</button>;
|
||||
};
|
||||
|
||||
@@ -10,13 +10,8 @@ import { useGetIdentity } from "@refinedev/core";
|
||||
import { HamburgerMenu, RefineThemedLayoutV2HeaderProps } from "@refinedev/mui";
|
||||
import React, { useContext } from "react";
|
||||
import { ColorModeContext } from "../../contexts/color-mode";
|
||||
import {Logout} from "../auth/Logout";
|
||||
|
||||
type IUser = {
|
||||
id: number;
|
||||
email: string;
|
||||
avatar: string;
|
||||
};
|
||||
import { Logout } from "../auth/Logout";
|
||||
import { IUser } from "../../interfaces";
|
||||
|
||||
export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
|
||||
sticky = true,
|
||||
@@ -50,7 +45,7 @@ export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
|
||||
{mode === "dark" ? <LightModeOutlined /> : <DarkModeOutlined />}
|
||||
</IconButton>
|
||||
|
||||
{(user?.avatar || user?.email) && (
|
||||
{(user?.email) && (
|
||||
<Stack
|
||||
direction="row"
|
||||
gap="16px"
|
||||
@@ -70,7 +65,7 @@ export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
|
||||
{user?.email}
|
||||
</Typography>
|
||||
)}
|
||||
<Avatar src={user?.avatar} alt={user?.email} />
|
||||
<Avatar src={"user?.avatar"} alt={user?.email} />
|
||||
<Logout />
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
13
gui/rpk-gui/src/interfaces/index.tsx
Normal file
13
gui/rpk-gui/src/interfaces/index.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
export type IFirm = {
|
||||
instance: string,
|
||||
name: string
|
||||
}
|
||||
|
||||
type User = {
|
||||
id: number,
|
||||
email: string,
|
||||
firms: [IFirm],
|
||||
};
|
||||
|
||||
export type IUser = User | null;
|
||||
@@ -8,10 +8,11 @@ import CrudTextWidget from "./widgets/crud-text-widget";
|
||||
import UnionEnumField from "./fields/union-enum";
|
||||
|
||||
type Props = {
|
||||
schemaName: string,
|
||||
resource: string,
|
||||
id?: string,
|
||||
//onSubmit: (data: IChangeEvent, event: FormEvent<any>) => void
|
||||
schemaName: string,
|
||||
resource: string,
|
||||
id?: string,
|
||||
//onSubmit: (data: IChangeEvent, event: FormEvent<any>) => void
|
||||
onSuccess?: (data: any) => void
|
||||
}
|
||||
|
||||
const customWidgets: RegistryWidgetsType = {
|
||||
@@ -22,12 +23,13 @@ const customFields: RegistryFieldsType = {
|
||||
AnyOfField: UnionEnumField
|
||||
}
|
||||
|
||||
export const CrudForm: React.FC<Props> = ({schemaName, resource, id}) => {
|
||||
export const CrudForm: React.FC<Props> = ({ schemaName, resource, id, onSuccess }) => {
|
||||
const { onFinish, query, formLoading } = useForm({
|
||||
resource: resource,
|
||||
action: id === undefined ? "create" : "edit",
|
||||
redirect: "show",
|
||||
id,
|
||||
onMutationSuccess: (data: any) => { if (onSuccess) { onSuccess(data) } },
|
||||
});
|
||||
|
||||
const record = query?.data?.data;
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
import { useInvalidateAuthStore } from "@refinedev/core";
|
||||
import { CrudForm } from "../../lib/crud/components/crud-form";
|
||||
import {empty_user} from "../../providers/auth-provider";
|
||||
|
||||
export const CreateFirm = () => {
|
||||
const invalidateAuthStore = useInvalidateAuthStore()
|
||||
const refreshUser = () => {
|
||||
empty_user();
|
||||
invalidateAuthStore().then();
|
||||
}
|
||||
|
||||
return (
|
||||
<CrudForm schemaName={"FirmCreate"} resource={"firms"} />
|
||||
<CrudForm
|
||||
schemaName={"FirmCreate"}
|
||||
resource={"firms"}
|
||||
onSuccess={() => { refreshUser() }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,38 @@
|
||||
import { Button } from "@mui/material";
|
||||
import { Link } from "react-router";
|
||||
import { useGetIdentity } from "@refinedev/core";
|
||||
|
||||
type Firm = {
|
||||
name: string,
|
||||
instance: string,
|
||||
}
|
||||
type User = {
|
||||
firms: [Firm],
|
||||
}
|
||||
|
||||
export const Hub = () => {
|
||||
const user = useGetIdentity<User>();
|
||||
|
||||
console.log(user);
|
||||
let ownFirms = [];
|
||||
let workFirms = [];
|
||||
//firms.forEach((f, index) => {
|
||||
// workFirms.push(<li>{f.instance}/{f.name}</li>)
|
||||
//})
|
||||
//{firms.map((f: Firm, index) => (
|
||||
// <li key={index}>{f.instance} / {f.name}</li>
|
||||
// ))}
|
||||
return (
|
||||
<div>
|
||||
<h1>HUB</h1>
|
||||
<p>List of managed firms</p>
|
||||
<p>List of firm you're working atx</p>
|
||||
<ul>
|
||||
<li></li>
|
||||
</ul>
|
||||
<p>List of firm you're working at</p>
|
||||
<ul>
|
||||
|
||||
</ul>
|
||||
<Link to="/hub/create-firm" ><Button >Create a new firm</Button></Link>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { AuthProvider } from "@refinedev/core";
|
||||
import {IUser} from "../interfaces";
|
||||
|
||||
const API_URL = "/api/v1";
|
||||
const LOCAL_STORAGE_USER_KEY = "rpk-gui-current-user";
|
||||
@@ -55,17 +57,24 @@ export const authProvider: AuthProvider = {
|
||||
return { success: false };
|
||||
},
|
||||
check: async () => {
|
||||
return { authenticated: Boolean(get_user()) };
|
||||
if (get_user() == null) {
|
||||
return {
|
||||
authenticated: false,
|
||||
redirectTo: "/login",
|
||||
logout: true
|
||||
}
|
||||
}
|
||||
return { authenticated: true };
|
||||
},
|
||||
getIdentity: async () => {
|
||||
getIdentity: async (): Promise<IUser> => {
|
||||
const user = get_user();
|
||||
if (user != null) {
|
||||
if (user !== null && !isEmpty(user)) {
|
||||
return user;
|
||||
}
|
||||
|
||||
const response = await fetch(`${API_URL}/users/me`);
|
||||
if (response.status < 200 || response.status > 299) {
|
||||
return
|
||||
return null;
|
||||
}
|
||||
const user_data = await response.json();
|
||||
store_user(user_data)
|
||||
@@ -163,6 +172,10 @@ function forget_user() {
|
||||
localStorage.removeItem(LOCAL_STORAGE_USER_KEY);
|
||||
}
|
||||
|
||||
export function empty_user() {
|
||||
store_user({})
|
||||
}
|
||||
|
||||
function findGetParameter(parameterName: string) {
|
||||
let result = null, tmp = [];
|
||||
location.search.substr(1).split("&")
|
||||
|
||||
Reference in New Issue
Block a user