Files
SMT-Production-Management-F…/src/app.tsx
2026-05-05 22:55:31 +07:00

136 lines
3.2 KiB
TypeScript

import { history, RunTimeLayoutConfig, useIntl } from '@umijs/max';
import { Dropdown } from 'antd';
import { handleRequestConfig as devRequestConfig } from '../config/request_dev';
import { handleRequestConfig as prodRequestConfig } from '../config/request_prod';
import UnAccessPage from './components/403/403Page';
import { ROUTE_LOGIN } from './constants';
import { parseJwt } from './utils/jwtTokenUtils';
import { getToken, removeToken } from './utils/localStorageUtils';
// Avatar component with i18n support
const AvatarDropdown = () => {
const intl = useIntl();
return (
<Dropdown
menu={{
items: [
{
key: 'logout',
label: intl.formatMessage({ id: 'common.logout' }),
onClick: () => {
removeToken();
history.push(ROUTE_LOGIN);
},
},
],
}}
>
<div
style={{
width: 32,
height: 32,
borderRadius: '50%',
cursor: 'pointer',
backgroundColor: '#1890ff',
color: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontWeight: 'bold',
}}
>
{intl.formatMessage({ id: 'common.user' })}
</div>
</Dropdown>
);
};
export async function getInitialState() {
const token: string = getToken();
const { pathname } = history.location;
if (!token) {
if (pathname !== ROUTE_LOGIN) {
history.push(`${ROUTE_LOGIN}?redirect=${pathname}`);
} else {
history.push(ROUTE_LOGIN);
}
return {};
}
const parsed = parseJwt(token);
if (!parsed) {
removeToken();
if (pathname !== ROUTE_LOGIN) {
history.push(`${ROUTE_LOGIN}?redirect=${pathname}`);
} else {
history.push(ROUTE_LOGIN);
}
return {};
}
const { sub, exp } = parsed;
const now = Math.floor(Date.now() / 1000);
const oneHour = 60 * 60;
if (exp - now < oneHour) {
console.warn('Token expired or nearly expired, redirecting...');
removeToken();
if (pathname !== ROUTE_LOGIN) {
history.push(`${ROUTE_LOGIN}?redirect=${pathname}`);
} else {
history.push(ROUTE_LOGIN);
}
return {};
}
return {
currentUser: sub,
exp,
};
}
export const layout: RunTimeLayoutConfig = (initialState) => {
return {
title: 'SMT Production Management',
fixedHeader: true,
contentWidth: 'Fluid',
navTheme: 'light',
splitMenus: true,
menu: {
locale: true,
},
contentStyle: {
padding: 0,
margin: 0,
paddingInline: 0,
},
avatarProps: {
size: 'small',
render: () => <AvatarDropdown />,
},
layout: 'top',
logout: () => {
removeToken();
history.push(ROUTE_LOGIN);
},
onPageChange: () => {
if (!initialState.initialState) {
history.push(ROUTE_LOGIN);
}
},
menuHeaderRender: undefined,
unAccessible: <UnAccessPage />,
token: {
pageContainer: {
paddingInlinePageContainerContent: 0,
paddingBlockPageContainerContent: 0,
},
},
};
};
const isProdBuild = process.env.NODE_ENV === 'production';
export const request = isProdBuild ? prodRequestConfig : devRequestConfig;