Separate Client Portal & Dashboard
This commit is contained in:
27
frontend/dashboard/src/utils/axios.ts
Normal file
27
frontend/dashboard/src/utils/axios.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import axios from 'axios';
|
||||
// config
|
||||
import { HOST_API } from '../config';
|
||||
|
||||
import { getSession } from './token';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const token = getSession();
|
||||
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: HOST_API,
|
||||
// headers: {
|
||||
// 'X-Requested-With': 'XMLHttpRequest',
|
||||
// },
|
||||
// withCredentials: true,
|
||||
// headers: {
|
||||
// Authorization: `Bearer ${token}`
|
||||
// }
|
||||
});
|
||||
|
||||
axiosInstance.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => Promise.reject((error.response && error.response.data) || 'Something went wrong')
|
||||
);
|
||||
|
||||
export default axiosInstance;
|
||||
70
frontend/dashboard/src/utils/cssStyles.ts
Normal file
70
frontend/dashboard/src/utils/cssStyles.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { Theme, alpha } from '@mui/material/styles';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
type BackgroundBlurProps = {
|
||||
blur?: number;
|
||||
opacity?: number;
|
||||
color?: string;
|
||||
};
|
||||
|
||||
type BackgroundGradientProps = {
|
||||
direction?: string;
|
||||
startColor?: string;
|
||||
endColor?: string;
|
||||
};
|
||||
|
||||
interface BackgroundImageProps extends BackgroundGradientProps {
|
||||
url?: string;
|
||||
}
|
||||
|
||||
function getDirection(value = 'bottom') {
|
||||
return {
|
||||
top: 'to top',
|
||||
right: 'to right',
|
||||
bottom: 'to bottom',
|
||||
left: 'to left',
|
||||
}[value];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export default function cssStyles(theme?: Theme) {
|
||||
return {
|
||||
bgBlur: (props?: BackgroundBlurProps) => {
|
||||
const color = props?.color || theme?.palette.background.default || '#000000';
|
||||
|
||||
const blur = props?.blur || 6;
|
||||
const opacity = props?.opacity || 0.8;
|
||||
|
||||
return {
|
||||
backdropFilter: `blur(${blur}px)`,
|
||||
WebkitBackdropFilter: `blur(${blur}px)`, // Fix on Mobile
|
||||
backgroundColor: alpha(color, opacity),
|
||||
};
|
||||
},
|
||||
bgGradient: (props?: BackgroundGradientProps) => {
|
||||
const direction = getDirection(props?.direction);
|
||||
const startColor = props?.startColor || `${alpha('#000000', 0)} 0%`;
|
||||
const endColor = props?.endColor || '#000000 75%';
|
||||
|
||||
return {
|
||||
background: `linear-gradient(${direction}, ${startColor}, ${endColor});`,
|
||||
};
|
||||
},
|
||||
bgImage: (props?: BackgroundImageProps) => {
|
||||
const url =
|
||||
props?.url || 'https://minimal-assets-api.vercel.app/assets/images/bg_gradient.jpg';
|
||||
const direction = getDirection(props?.direction);
|
||||
const startColor = props?.startColor || alpha(theme?.palette.grey[900] || '#000000', 0.88);
|
||||
const endColor = props?.endColor || alpha(theme?.palette.grey[900] || '#000000', 0.88);
|
||||
|
||||
return {
|
||||
background: `linear-gradient(${direction}, ${startColor}, ${endColor}), url(${url})`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundPosition: 'center center',
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
23
frontend/dashboard/src/utils/formatNumber.ts
Normal file
23
frontend/dashboard/src/utils/formatNumber.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import numeral from 'numeral';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function fCurrency(number: string | number) {
|
||||
return numeral(number).format(Number.isInteger(number) ? '$0,0' : '$0,0.00');
|
||||
}
|
||||
|
||||
export function fPercent(number: number) {
|
||||
return numeral(number / 100).format('0.0%');
|
||||
}
|
||||
|
||||
export function fNumber(number: string | number) {
|
||||
return numeral(number).format();
|
||||
}
|
||||
|
||||
export function fShortenNumber(number: string | number) {
|
||||
return numeral(number).format('0.00a').replace('.00', '');
|
||||
}
|
||||
|
||||
export function fData(number: string | number) {
|
||||
return numeral(number).format('0.0 b');
|
||||
}
|
||||
25
frontend/dashboard/src/utils/formatTime.ts
Normal file
25
frontend/dashboard/src/utils/formatTime.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { format, getTime, formatDistanceToNow } from 'date-fns';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function fDate(date: Date | string | number) {
|
||||
return format(new Date(date), 'dd MMMM yyyy');
|
||||
}
|
||||
|
||||
export function fDateTime(date: Date | string | number) {
|
||||
return format(new Date(date), 'dd MMM yyyy p');
|
||||
}
|
||||
|
||||
export function fTimestamp(date: Date | string | number) {
|
||||
return getTime(new Date(date));
|
||||
}
|
||||
|
||||
export function fDateTimeSuffix(date: Date | string | number) {
|
||||
return format(new Date(date), 'dd/MM/yyyy hh:mm p');
|
||||
}
|
||||
|
||||
export function fToNow(date: Date | string | number) {
|
||||
return formatDistanceToNow(new Date(date), {
|
||||
addSuffix: true
|
||||
});
|
||||
}
|
||||
82
frontend/dashboard/src/utils/getColorPresets.ts
Normal file
82
frontend/dashboard/src/utils/getColorPresets.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
// theme
|
||||
import palette from '../theme/palette';
|
||||
// @type
|
||||
import { ThemeColorPresets } from '../components/settings/type';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export const colorPresets = [
|
||||
// DEFAULT
|
||||
{
|
||||
name: 'default',
|
||||
...palette.light.primary,
|
||||
},
|
||||
// PURPLE
|
||||
{
|
||||
name: 'purple',
|
||||
lighter: '#EBD6FD',
|
||||
light: '#B985F4',
|
||||
main: '#7635dc',
|
||||
dark: '#431A9E',
|
||||
darker: '#200A69',
|
||||
contrastText: '#fff',
|
||||
},
|
||||
// CYAN
|
||||
{
|
||||
name: 'cyan',
|
||||
lighter: '#D1FFFC',
|
||||
light: '#76F2FF',
|
||||
main: '#1CCAFF',
|
||||
dark: '#0E77B7',
|
||||
darker: '#053D7A',
|
||||
contrastText: palette.light.grey[800],
|
||||
},
|
||||
// BLUE
|
||||
{
|
||||
name: 'blue',
|
||||
lighter: '#D1E9FC',
|
||||
light: '#76B0F1',
|
||||
main: '#2065D1',
|
||||
dark: '#103996',
|
||||
darker: '#061B64',
|
||||
contrastText: '#fff',
|
||||
},
|
||||
// ORANGE
|
||||
{
|
||||
name: 'orange',
|
||||
lighter: '#FEF4D4',
|
||||
light: '#FED680',
|
||||
main: '#fda92d',
|
||||
dark: '#B66816',
|
||||
darker: '#793908',
|
||||
contrastText: palette.light.grey[800],
|
||||
},
|
||||
// RED
|
||||
{
|
||||
name: 'red',
|
||||
lighter: '#FFE3D5',
|
||||
light: '#FFC1AC',
|
||||
main: '#FF3030',
|
||||
dark: '#B71833',
|
||||
darker: '#7A0930',
|
||||
contrastText: '#fff',
|
||||
},
|
||||
];
|
||||
|
||||
export const defaultPreset = colorPresets[0];
|
||||
export const purplePreset = colorPresets[1];
|
||||
export const cyanPreset = colorPresets[2];
|
||||
export const bluePreset = colorPresets[3];
|
||||
export const orangePreset = colorPresets[4];
|
||||
export const redPreset = colorPresets[5];
|
||||
|
||||
export default function getColorPresets(presetsKey: ThemeColorPresets) {
|
||||
return {
|
||||
purple: purplePreset,
|
||||
cyan: cyanPreset,
|
||||
blue: bluePreset,
|
||||
orange: orangePreset,
|
||||
red: redPreset,
|
||||
default: defaultPreset,
|
||||
}[presetsKey];
|
||||
}
|
||||
72
frontend/dashboard/src/utils/getFontValue.ts
Normal file
72
frontend/dashboard/src/utils/getFontValue.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
// @mui
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { Variant } from '@mui/material/styles/createTypography';
|
||||
// hooks
|
||||
import useResponsive from '../hooks/useResponsive';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export default function GetFontValue(variant: Variant) {
|
||||
const theme = useTheme();
|
||||
const breakpoints = useWidth();
|
||||
|
||||
const key = theme.breakpoints.up(breakpoints === 'xl' ? 'lg' : breakpoints);
|
||||
|
||||
const hasResponsive =
|
||||
variant === 'h1' ||
|
||||
variant === 'h2' ||
|
||||
variant === 'h3' ||
|
||||
variant === 'h4' ||
|
||||
variant === 'h5' ||
|
||||
variant === 'h6';
|
||||
|
||||
const getFont: any =
|
||||
hasResponsive && theme.typography[variant][key]
|
||||
? theme.typography[variant][key]
|
||||
: theme.typography[variant];
|
||||
|
||||
const fontSize = remToPx(getFont.fontSize);
|
||||
const lineHeight = Number(theme.typography[variant].lineHeight) * fontSize;
|
||||
const { fontWeight, letterSpacing } = theme.typography[variant];
|
||||
|
||||
return { fontSize, lineHeight, fontWeight, letterSpacing };
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function remToPx(value: string) {
|
||||
return Math.round(parseFloat(value) * 16);
|
||||
}
|
||||
|
||||
export function pxToRem(value: number) {
|
||||
return `${value / 16}rem`;
|
||||
}
|
||||
|
||||
export function responsiveFontSizes({ sm, md, lg }: { sm: number; md: number; lg: number }) {
|
||||
return {
|
||||
'@media (min-width:600px)': {
|
||||
fontSize: pxToRem(sm),
|
||||
},
|
||||
'@media (min-width:900px)': {
|
||||
fontSize: pxToRem(md),
|
||||
},
|
||||
'@media (min-width:1200px)': {
|
||||
fontSize: pxToRem(lg),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function useWidth() {
|
||||
const theme = useTheme();
|
||||
const keys = [...theme.breakpoints.keys].reverse();
|
||||
return (
|
||||
// @ts-ignore not sure what is this
|
||||
keys.reduce((output, key) => {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const matches = useResponsive('up', key);
|
||||
return !output && matches ? key : output;
|
||||
}, null) || 'xs'
|
||||
);
|
||||
}
|
||||
43
frontend/dashboard/src/utils/token.ts
Normal file
43
frontend/dashboard/src/utils/token.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import axios from './axios';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// const isValidToken = (accessToken: string) => {
|
||||
// if (!accessToken) {
|
||||
// return false;
|
||||
// }
|
||||
// const decoded = jwtDecode<{ exp: number }>(accessToken);
|
||||
// const currentTime = Date.now() / 1000;
|
||||
|
||||
// return decoded.exp > currentTime;
|
||||
// };
|
||||
|
||||
// const handleTokenExpired = () => {
|
||||
// let expiredTimer;
|
||||
|
||||
// window.clearTimeout(expiredTimer);
|
||||
// const currentTime = Date.now();
|
||||
// const timeLeft = exp * 1000 - currentTime;
|
||||
// console.log(timeLeft);
|
||||
// expiredTimer = window.setTimeout(() => {
|
||||
// console.log('expired');
|
||||
// // You can do what ever you want here, like show a notification
|
||||
// }, timeLeft);
|
||||
// };
|
||||
|
||||
const setSession = (accessToken: string | null) => {
|
||||
if (accessToken) {
|
||||
localStorage.setItem('accessToken', accessToken);
|
||||
axios.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
|
||||
// This function below will handle when token is expired
|
||||
// const { exp } = jwtDecode(accessToken);
|
||||
// handleTokenExpired(exp);
|
||||
} else {
|
||||
localStorage.removeItem('accessToken');
|
||||
delete axios.defaults.headers.common.Authorization;
|
||||
}
|
||||
};
|
||||
|
||||
const getSession = () => window.localStorage.getItem('accessToken')
|
||||
|
||||
export { setSession, getSession };
|
||||
Reference in New Issue
Block a user