Separate Client Portal & Dashboard

This commit is contained in:
2022-05-23 10:38:16 +07:00
parent f2e84e6244
commit 89bb57f357
569 changed files with 60252 additions and 280 deletions

View File

@@ -0,0 +1,18 @@
import { useContext } from 'react';
//
import { AuthContext } from '../contexts/LaravelAuthContext';
// import { AuthContext } from '../contexts/Auth0Context';
// import { AuthContext } from '../contexts/FirebaseContext';
// import { AuthContext } from '../contexts/AwsCognitoContext';
// ----------------------------------------------------------------------
const useAuth = () => {
const context = useContext(AuthContext);
if (!context) throw new Error('Auth context must be use inside AuthProvider');
return context;
};
export default useAuth;

View File

@@ -0,0 +1,8 @@
import { useContext } from 'react';
import { CollapseDrawerContext } from '../contexts/CollapseDrawerContext';
// ----------------------------------------------------------------------
const useCollapseDrawer = () => useContext(CollapseDrawerContext);
export default useCollapseDrawer;

View File

@@ -0,0 +1,16 @@
import { useRef, useEffect } from 'react';
// ----------------------------------------------------------------------
export default function useIsMountedRef() {
const isMounted = useRef(true);
useEffect(
() => () => {
isMounted.current = false;
},
[]
);
return isMounted;
}

View File

@@ -0,0 +1,33 @@
import { useState, useEffect } from 'react';
// ----------------------------------------------------------------------
export default function useLocalStorage<ValueType>(key: string, defaultValue: ValueType) {
const [value, setValue] = useState(() => {
const storedValue = localStorage.getItem(key);
return storedValue === null ? defaultValue : JSON.parse(storedValue);
});
useEffect(() => {
const listener = (e: StorageEvent) => {
if (e.storageArea === localStorage && e.key === key) {
setValue(e.newValue ? JSON.parse(e.newValue) : e.newValue);
}
};
window.addEventListener('storage', listener);
return () => {
window.removeEventListener('storage', listener);
};
}, [key, defaultValue]);
const setValueInLocalStorage = (newValue: ValueType) => {
setValue((currentValue: any) => {
const result = typeof newValue === 'function' ? newValue(currentValue) : newValue;
localStorage.setItem(key, JSON.stringify(result));
return result;
});
};
return [value, setValueInLocalStorage];
}

View File

@@ -0,0 +1,43 @@
import { useTranslation } from 'react-i18next';
// @mui
import { enUS, deDE, frFR } from '@mui/material/locale';
// ----------------------------------------------------------------------
const LANGS = [
{
label: 'English',
value: 'en',
systemValue: enUS,
icon: 'https://minimal-assets-api.vercel.app/assets/icons/ic_flag_en.svg',
},
{
label: 'German',
value: 'de',
systemValue: deDE,
icon: 'https://minimal-assets-api.vercel.app/assets/icons/ic_flag_de.svg',
},
{
label: 'French',
value: 'fr',
systemValue: frFR,
icon: 'https://minimal-assets-api.vercel.app/assets/icons/ic_flag_fr.svg',
},
];
export default function useLocales() {
const { i18n, t: translate } = useTranslation();
const langStorage = localStorage.getItem('i18nextLng');
const currentLang = LANGS.find((_lang) => _lang.value === langStorage) || LANGS[1];
const handleChangeLanguage = (newlang: string) => {
i18n.changeLanguage(newlang);
};
return {
onChangeLang: handleChangeLanguage,
translate,
currentLang,
allLang: LANGS,
};
}

View File

@@ -0,0 +1,26 @@
import { useState, useEffect } from 'react';
// ----------------------------------------------------------------------
export default function useOffSetTop(top: number) {
const [offsetTop, setOffSetTop] = useState(false);
const isTop = top || 100;
useEffect(() => {
window.onscroll = () => {
if (window.pageYOffset > isTop) {
setOffSetTop(true);
} else {
setOffSetTop(false);
}
};
return () => {
window.onscroll = null;
};
}, [isTop]);
return offsetTop;
}
// Usage
// const offset = useOffSetTop(100);

View File

@@ -0,0 +1,39 @@
// @mui
import { Breakpoint } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
// ----------------------------------------------------------------------
type Query = 'up' | 'down' | 'between' | 'only';
type Key = Breakpoint | number;
type Start = Breakpoint | number;
type End = Breakpoint | number;
export default function useResponsive(query: Query, key?: Key, start?: Start, end?: End) {
const theme = useTheme();
const mediaUp = useMediaQuery(theme.breakpoints.up(key as Key));
const mediaDown = useMediaQuery(theme.breakpoints.down(key as Key));
const mediaBetween = useMediaQuery(theme.breakpoints.between(start as Start, end as End));
const mediaOnly = useMediaQuery(theme.breakpoints.only(key as Breakpoint));
if (query === 'up') {
return mediaUp;
}
if (query === 'down') {
return mediaDown;
}
if (query === 'between') {
return mediaBetween;
}
if (query === 'only') {
return mediaOnly;
}
}

View File

@@ -0,0 +1,8 @@
import { useContext } from 'react';
import { SettingsContext } from '../contexts/SettingsContext';
// ----------------------------------------------------------------------
const useSettings = () => useContext(SettingsContext);
export default useSettings;

View File

@@ -0,0 +1,138 @@
import { useState } from 'react';
// ----------------------------------------------------------------------
export type UseTableProps = {
dense: boolean;
page: number;
setPage: React.Dispatch<React.SetStateAction<number>>;
rowsPerPage: number;
order: 'asc' | 'desc';
orderBy: string;
//
selected: string[];
setSelected: React.Dispatch<React.SetStateAction<string[]>>;
onSelectRow: (id: string) => void;
onSelectAllRows: (checked: boolean, newSelecteds: string[]) => void;
//
onSort: (id: string) => void;
onChangePage: (event: unknown, newPage: number) => void;
onChangeRowsPerPage: (event: React.ChangeEvent<HTMLInputElement>) => void;
onChangeDense: (event: React.ChangeEvent<HTMLInputElement>) => void;
};
export type Props = {
defaultDense?: boolean;
defaultOrder?: 'asc' | 'desc';
defaultOrderBy?: string;
defaultSelected?: string[];
defaultRowsPerPage?: number;
defaultCurrentPage?: number;
};
export default function useTable(props?: Props) {
const [dense, setDense] = useState(props?.defaultDense || false);
const [orderBy, setOrderBy] = useState(props?.defaultOrderBy || 'name');
const [order, setOrder] = useState<'asc' | 'desc'>(props?.defaultOrder || 'asc');
const [page, setPage] = useState(props?.defaultCurrentPage || 0);
const [rowsPerPage, setRowsPerPage] = useState(props?.defaultRowsPerPage || 5);
const [selected, setSelected] = useState<string[]>(props?.defaultSelected || []);
const onSort = (id: string) => {
const isAsc = orderBy === id && order === 'asc';
if (id !== '') {
setOrder(isAsc ? 'desc' : 'asc');
setOrderBy(id);
}
};
const onSelectRow = (id: string) => {
const selectedIndex = selected.indexOf(id);
let newSelected: string[] = [];
if (selectedIndex === -1) {
newSelected = newSelected.concat(selected, id);
} else if (selectedIndex === 0) {
newSelected = newSelected.concat(selected.slice(1));
} else if (selectedIndex === selected.length - 1) {
newSelected = newSelected.concat(selected.slice(0, -1));
} else if (selectedIndex > 0) {
newSelected = newSelected.concat(
selected.slice(0, selectedIndex),
selected.slice(selectedIndex + 1)
);
}
setSelected(newSelected);
};
const onSelectAllRows = (checked: boolean, newSelecteds: string[]) => {
if (checked) {
setSelected(newSelecteds);
return;
}
setSelected([]);
};
const onChangePage = (event: unknown, newPage: number) => {
setPage(newPage);
};
const onChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
const onChangeDense = (event: React.ChangeEvent<HTMLInputElement>) => {
setDense(event.target.checked);
};
return {
dense,
order,
page,
setPage,
orderBy,
rowsPerPage,
//
selected,
setSelected,
onSelectRow,
onSelectAllRows,
//
onSort,
onChangePage,
onChangeDense,
onChangeRowsPerPage,
};
}
// ----------------------------------------------------------------------
export function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
if (b[orderBy] < a[orderBy]) {
return -1;
}
if (b[orderBy] > a[orderBy]) {
return 1;
}
return 0;
}
export function getComparator<Key extends keyof any>(
order: 'asc' | 'desc',
orderBy: Key
): (a: { [key in Key]: number | string }, b: { [key in Key]: number | string }) => number {
return order === 'desc'
? (a, b) => descendingComparator(a, b, orderBy)
: (a, b) => -descendingComparator(a, b, orderBy);
}
export function emptyRows(page: number, rowsPerPage: number, arrayLength: number) {
return page > 0 ? Math.max(0, (1 + page) * rowsPerPage - arrayLength) : 0;
}

View File

@@ -0,0 +1,15 @@
import { useState } from 'react';
// ----------------------------------------------------------------------
export default function useTabs(defaultValues?: string) {
const [currentTab, setCurrentTab] = useState(defaultValues || '');
return {
currentTab,
onChangeTab: (event: React.SyntheticEvent<Element, Event>, newValue: any) => {
setCurrentTab(newValue);
},
setCurrentTab,
};
}

View File

@@ -0,0 +1,15 @@
import { useState } from 'react';
// ----------------------------------------------------------------------
export default function useToggle(defaultChecked?: boolean) {
const [toggle, setToggle] = useState(defaultChecked || false);
return {
toggle,
onToggle: () => setToggle(!toggle),
onOpen: () => setToggle(true),
onClose: () => setToggle(false),
setToggle,
};
}