add front-urban
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
'use client'
|
||||
|
||||
// React Imports
|
||||
import { forwardRef } from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import MuiAvatar from '@mui/material/Avatar'
|
||||
import { lighten, styled } from '@mui/material/styles'
|
||||
import type { AvatarProps } from '@mui/material/Avatar'
|
||||
|
||||
// Type Imports
|
||||
import type { ThemeColor } from '@core/types'
|
||||
|
||||
export type CustomAvatarProps = AvatarProps & {
|
||||
color?: ThemeColor
|
||||
skin?: 'filled' | 'light' | 'light-static'
|
||||
size?: number
|
||||
}
|
||||
|
||||
const Avatar = styled(MuiAvatar)<CustomAvatarProps>(({ skin, color, size, theme }) => {
|
||||
return {
|
||||
...(color &&
|
||||
skin === 'light' && {
|
||||
backgroundColor: `var(--mui-palette-${color}-lightOpacity)`,
|
||||
color: `var(--mui-palette-${color}-main)`
|
||||
}),
|
||||
...(color &&
|
||||
skin === 'light-static' && {
|
||||
backgroundColor: lighten(theme.palette[color as ThemeColor].main, 0.84),
|
||||
color: `var(--mui-palette-${color}-main)`
|
||||
}),
|
||||
...(color &&
|
||||
skin === 'filled' && {
|
||||
backgroundColor: `var(--mui-palette-${color}-main)`,
|
||||
color: `var(--mui-palette-${color}-contrastText)`
|
||||
}),
|
||||
...(size && {
|
||||
height: size,
|
||||
width: size
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const CustomAvatar = forwardRef<HTMLDivElement, CustomAvatarProps>((props: CustomAvatarProps, ref) => {
|
||||
// Props
|
||||
const { color, skin = 'filled', ...rest } = props
|
||||
|
||||
return <Avatar color={color} skin={skin} ref={ref} {...rest} />
|
||||
})
|
||||
|
||||
export default CustomAvatar
|
||||
@@ -0,0 +1,75 @@
|
||||
'use client'
|
||||
|
||||
import MuiButton from '@mui/material/Button'
|
||||
import { styled } from '@mui/material/styles'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
const CustomIconButton = styled(MuiButton)(({ color, size, theme, variant }) => {
|
||||
return {
|
||||
minInlineSize: 0,
|
||||
...(size === 'small'
|
||||
? {
|
||||
fontSize: '20px',
|
||||
padding: theme.spacing(variant === 'outlined' ? 1 : 1.25),
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}
|
||||
: {
|
||||
...(size === 'large'
|
||||
? {
|
||||
fontSize: '24px',
|
||||
padding: theme.spacing(variant === 'outlined' ? 2 : 2.25),
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}
|
||||
: {
|
||||
fontSize: '22px',
|
||||
padding: theme.spacing(variant === 'outlined' ? 1.5 : 1.75),
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
})
|
||||
}),
|
||||
...(!color && {
|
||||
color: 'var(--mui-palette-action-active)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': {
|
||||
backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)'
|
||||
}
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-action-active)'
|
||||
},
|
||||
...(variant === 'outlined' && {
|
||||
border: 'none !important',
|
||||
...(size === 'small'
|
||||
? {
|
||||
padding: theme.spacing(1.5)
|
||||
}
|
||||
: {
|
||||
...(size === 'large'
|
||||
? {
|
||||
padding: theme.spacing(2.25)
|
||||
}
|
||||
: {
|
||||
padding: theme.spacing(1.75)
|
||||
})
|
||||
})
|
||||
}),
|
||||
...(variant === 'contained' && {
|
||||
boxShadow: 'none !important',
|
||||
backgroundColor: 'transparent'
|
||||
})
|
||||
})
|
||||
}
|
||||
}) as typeof MuiButton
|
||||
|
||||
export default CustomIconButton
|
||||
@@ -0,0 +1,135 @@
|
||||
'use client'
|
||||
|
||||
// React Imports
|
||||
import { useRef, useState } from 'react'
|
||||
import type { ReactElement, ReactNode, SyntheticEvent } from 'react'
|
||||
|
||||
// Next Imports
|
||||
import Link from 'next/link'
|
||||
|
||||
// MUI Imports
|
||||
import Tooltip from '@mui/material/Tooltip'
|
||||
import Box from '@mui/material/Box'
|
||||
import Popper from '@mui/material/Popper'
|
||||
import MenuItem from '@mui/material/MenuItem'
|
||||
import MenuList from '@mui/material/MenuList'
|
||||
import ClickAwayListener from '@mui/material/ClickAwayListener'
|
||||
import Fade from '@mui/material/Fade'
|
||||
import Paper from '@mui/material/Paper'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import Divider from '@mui/material/Divider'
|
||||
|
||||
// Third-party Imports
|
||||
import classnames from 'classnames'
|
||||
|
||||
// Type Imports
|
||||
import type { OptionsMenuType, OptionType, OptionMenuItemType } from './types'
|
||||
|
||||
const IconButtonWrapper = (props: Pick<OptionsMenuType, 'tooltipProps'> & { children: ReactElement }) => {
|
||||
// Props
|
||||
const { tooltipProps, children } = props
|
||||
|
||||
return tooltipProps?.title ? <Tooltip {...tooltipProps}>{children}</Tooltip> : children
|
||||
}
|
||||
|
||||
const MenuItemWrapper = ({ children, option }: { children: ReactNode; option: OptionMenuItemType }) => {
|
||||
if (option.href) {
|
||||
return (
|
||||
<Box component={Link} href={option.href} {...option.linkProps}>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
} else {
|
||||
return <>{children}</>
|
||||
}
|
||||
}
|
||||
|
||||
const OptionMenu = (props: OptionsMenuType) => {
|
||||
// Props
|
||||
const { tooltipProps, icon, iconClassName, options, leftAlignMenu, iconButtonProps } = props
|
||||
|
||||
// States
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
// Refs
|
||||
const anchorRef = useRef<HTMLButtonElement>(null)
|
||||
|
||||
const handleToggle = () => {
|
||||
setOpen(prevOpen => !prevOpen)
|
||||
}
|
||||
|
||||
const handleClose = (event: Event | SyntheticEvent) => {
|
||||
if (anchorRef.current && anchorRef.current.contains(event.target as HTMLElement)) {
|
||||
return
|
||||
}
|
||||
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconButtonWrapper tooltipProps={tooltipProps}>
|
||||
<IconButton ref={anchorRef} size='small' onClick={handleToggle} {...iconButtonProps}>
|
||||
{typeof icon === 'string' ? (
|
||||
<i className={classnames(icon, iconClassName)} />
|
||||
) : (icon as ReactNode) ? (
|
||||
icon
|
||||
) : (
|
||||
<i className={classnames('ri-more-2-line', iconClassName)} />
|
||||
)}
|
||||
</IconButton>
|
||||
</IconButtonWrapper>
|
||||
<Popper
|
||||
open={open}
|
||||
anchorEl={anchorRef.current}
|
||||
placement={leftAlignMenu ? 'bottom-start' : 'bottom-end'}
|
||||
transition
|
||||
disablePortal
|
||||
sx={{ zIndex: 1 }}
|
||||
>
|
||||
{({ TransitionProps }) => (
|
||||
<Fade {...TransitionProps}>
|
||||
<Paper className='shadow-lg'>
|
||||
<ClickAwayListener onClickAway={handleClose}>
|
||||
<MenuList autoFocusItem={open}>
|
||||
{options.map((option: OptionType, index: number) => {
|
||||
if (typeof option === 'string') {
|
||||
return (
|
||||
<MenuItem key={index} onClick={handleClose}>
|
||||
{option}
|
||||
</MenuItem>
|
||||
)
|
||||
} else if ('divider' in option) {
|
||||
return option.divider && <Divider key={index} {...option.dividerProps} />
|
||||
} else {
|
||||
return (
|
||||
<MenuItem
|
||||
key={index}
|
||||
{...option.menuItemProps}
|
||||
{...(option.href && { className: 'p-0' })}
|
||||
onClick={e => {
|
||||
handleClose(e)
|
||||
option.menuItemProps && option.menuItemProps.onClick
|
||||
? option.menuItemProps.onClick(e)
|
||||
: null
|
||||
}}
|
||||
>
|
||||
<MenuItemWrapper option={option}>
|
||||
{(typeof option.icon === 'string' ? <i className={option.icon} /> : option.icon) || null}
|
||||
{option.text}
|
||||
</MenuItemWrapper>
|
||||
</MenuItem>
|
||||
)
|
||||
}
|
||||
})}
|
||||
</MenuList>
|
||||
</ClickAwayListener>
|
||||
</Paper>
|
||||
</Fade>
|
||||
)}
|
||||
</Popper>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default OptionMenu
|
||||
@@ -0,0 +1,42 @@
|
||||
// React Imports
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
// Next Imports
|
||||
import type { LinkProps } from 'next/link'
|
||||
|
||||
// MUI Imports
|
||||
import type { IconButtonProps } from '@mui/material/IconButton'
|
||||
import type { MenuItemProps } from '@mui/material/MenuItem'
|
||||
import type { DividerProps } from '@mui/material/Divider'
|
||||
import type { BoxProps } from '@mui/material/Box'
|
||||
import type { TooltipProps } from '@mui/material/Tooltip'
|
||||
|
||||
export type OptionDividerType = {
|
||||
divider: boolean
|
||||
dividerProps?: DividerProps
|
||||
href?: never
|
||||
icon?: never
|
||||
text?: never
|
||||
linkProps?: never
|
||||
menuItemProps?: never
|
||||
}
|
||||
export type OptionMenuItemType = {
|
||||
text: ReactNode
|
||||
icon?: ReactNode
|
||||
linkProps?: BoxProps
|
||||
href?: LinkProps['href']
|
||||
menuItemProps?: MenuItemProps
|
||||
divider?: never
|
||||
dividerProps?: never
|
||||
}
|
||||
|
||||
export type OptionType = string | OptionDividerType | OptionMenuItemType
|
||||
|
||||
export type OptionsMenuType = {
|
||||
tooltipProps?: Omit<TooltipProps, 'children'>
|
||||
icon?: ReactNode
|
||||
iconClassName?: string
|
||||
options: OptionType[]
|
||||
leftAlignMenu?: boolean
|
||||
iconButtonProps?: IconButtonProps
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
'use client'
|
||||
|
||||
// React Imports
|
||||
import type { ReactNode } from 'react'
|
||||
import { createContext, useMemo, useState } from 'react'
|
||||
|
||||
// Type Imports
|
||||
import type { Mode } from '@core/types'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
// Hook Imports
|
||||
import { useObjectCookie } from '@core/hooks/useObjectCookie'
|
||||
|
||||
// Settings type
|
||||
export type Settings = {
|
||||
mode?: Mode
|
||||
}
|
||||
|
||||
// UpdateSettingsOptions type
|
||||
type UpdateSettingsOptions = {
|
||||
updateCookie?: boolean
|
||||
}
|
||||
|
||||
// SettingsContextProps type
|
||||
type SettingsContextProps = {
|
||||
settings: Settings
|
||||
updateSettings: (settings: Partial<Settings>, options?: UpdateSettingsOptions) => void
|
||||
isSettingsChanged: boolean
|
||||
resetSettings: () => void
|
||||
updatePageSettings: (settings: Partial<Settings>) => () => void
|
||||
}
|
||||
|
||||
type Props = {
|
||||
children: ReactNode
|
||||
settingsCookie: Settings | null
|
||||
mode?: Mode
|
||||
}
|
||||
|
||||
// Initial Settings Context
|
||||
export const SettingsContext = createContext<SettingsContextProps | null>(null)
|
||||
|
||||
// Settings Provider
|
||||
export const SettingsProvider = (props: Props) => {
|
||||
// Initial Settings
|
||||
const initialSettings: Settings = {
|
||||
mode: themeConfig.mode
|
||||
}
|
||||
|
||||
const updatedInitialSettings = {
|
||||
...initialSettings,
|
||||
mode: props.mode || themeConfig.mode
|
||||
}
|
||||
|
||||
// Cookies
|
||||
const [settingsCookie, updateSettingsCookie] = useObjectCookie<Settings>(
|
||||
themeConfig.settingsCookieName,
|
||||
JSON.stringify(props.settingsCookie) !== '{}' ? props.settingsCookie : updatedInitialSettings
|
||||
)
|
||||
|
||||
// State
|
||||
const [_settingsState, _updateSettingsState] = useState<Settings>(
|
||||
JSON.stringify(settingsCookie) !== '{}' ? settingsCookie : updatedInitialSettings
|
||||
)
|
||||
|
||||
const updateSettings = (settings: Partial<Settings>, options?: UpdateSettingsOptions) => {
|
||||
const { updateCookie = true } = options || {}
|
||||
|
||||
_updateSettingsState(prev => {
|
||||
const newSettings = { ...prev, ...settings }
|
||||
|
||||
// Update cookie if needed
|
||||
if (updateCookie) updateSettingsCookie(newSettings)
|
||||
|
||||
return newSettings
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the settings for page with the provided settings object.
|
||||
* Updated settings won't be saved to cookie hence will be reverted once navigating away from the page.
|
||||
*
|
||||
* @param settings - The partial settings object containing the properties to update.
|
||||
* @returns A function to reset the page settings.
|
||||
*
|
||||
* @example
|
||||
* useEffect(() => {
|
||||
* return updatePageSettings({ theme: 'dark' });
|
||||
* }, []);
|
||||
*/
|
||||
const updatePageSettings = (settings: Partial<Settings>): (() => void) => {
|
||||
updateSettings(settings, { updateCookie: false })
|
||||
|
||||
// Returns a function to reset the page settings
|
||||
return () => updateSettings(settingsCookie, { updateCookie: false })
|
||||
}
|
||||
|
||||
const resetSettings = () => {
|
||||
updateSettings(initialSettings)
|
||||
}
|
||||
|
||||
const isSettingsChanged = useMemo(
|
||||
() => JSON.stringify(initialSettings) !== JSON.stringify(_settingsState),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[_settingsState]
|
||||
)
|
||||
|
||||
return (
|
||||
<SettingsContext.Provider
|
||||
value={{
|
||||
settings: _settingsState,
|
||||
updateSettings,
|
||||
isSettingsChanged,
|
||||
resetSettings,
|
||||
updatePageSettings
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</SettingsContext.Provider>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
export const downloadInvoicePdf = async (invoiceId: string) => {
|
||||
const response = await apiClient.get(
|
||||
`/invoices/download/${invoiceId}`,
|
||||
{ responseType: 'blob' }
|
||||
);
|
||||
|
||||
const blob = new Blob([response.data], { type: 'application/pdf' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `factura-${invoiceId}.pdf`;
|
||||
a.click();
|
||||
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
// src/@core/hooks/useAccessLogs.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useUserAuth } from '@/app/context/UserAuth';
|
||||
|
||||
export type AccessLog = {
|
||||
id: string;
|
||||
userId: string;
|
||||
direction: 'INGRESS' | 'EGRESS';
|
||||
timestamp: string;
|
||||
};
|
||||
|
||||
export type ResponseAccessLogs = {
|
||||
userId: string;
|
||||
name: string;
|
||||
accessLogs: AccessLog[];
|
||||
};
|
||||
|
||||
export function useAccessLogs(userId?: string, date?: string, enabled: boolean = true) {
|
||||
const { token } = useUserAuth();
|
||||
const [data, setData] = useState<ResponseAccessLogs | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fetchData = useCallback(
|
||||
async (signal?: AbortSignal) => {
|
||||
if (!enabled || !userId || !date) return;
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const res = await apiClient.get<ResponseAccessLogs>('/attendance', {
|
||||
params: { userId, date },
|
||||
signal,
|
||||
});
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError') return;
|
||||
setError(e?.response?.data?.message ?? 'No se pudieron cargar los registros de acceso.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[enabled, userId, date, token]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const ctrl = new AbortController();
|
||||
fetchData(ctrl.signal);
|
||||
return () => ctrl.abort();
|
||||
}, [fetchData]);
|
||||
|
||||
return { data, loading, error, refresh: fetchData };
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// src/@core/hooks/useAttendeesSnapshot.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useUserAuth } from '@/app/context/UserAuth';
|
||||
|
||||
export type ResponseAttendeesSnapshot = {
|
||||
dateRange: { start: string; end: string };
|
||||
instructors: { id: string; name: string }[];
|
||||
assistants: { id: string; name: string }[];
|
||||
attendance: { id: string; name: string }[];
|
||||
};
|
||||
|
||||
export function useAttendeesSnapshot(snapshotId?: string, enabled: boolean = true) {
|
||||
const { token } = useUserAuth();
|
||||
const [data, setData] = useState<ResponseAttendeesSnapshot | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fetchData = useCallback(
|
||||
async (signal?: AbortSignal) => {
|
||||
if (!enabled || !snapshotId) return;
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const res = await apiClient.get<ResponseAttendeesSnapshot>(
|
||||
`/sessions/${snapshotId}/attendees`,
|
||||
{ signal }
|
||||
);
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError') return;
|
||||
setError(e?.response?.data?.message ?? 'No se pudieron cargar los asistentes.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[enabled, snapshotId, token]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const ctrl = new AbortController();
|
||||
fetchData(ctrl.signal);
|
||||
return () => ctrl.abort();
|
||||
}, [fetchData]);
|
||||
|
||||
return { data, loading, error, refresh: fetchData };
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// useClases.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { Clase } from '@/views/clases/DetailClaseDialog';
|
||||
|
||||
type Options = {
|
||||
/** Lanza el fetch al montar el hook (default: true) */
|
||||
auto?: boolean;
|
||||
/** Filtro de estado: 'all', 'active', 'inactive' */
|
||||
status?: 'all' | 'active' | 'inactive';
|
||||
};
|
||||
|
||||
type UseClasesResult = {
|
||||
data: Clase[];
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
/** Vuelve a pedir la lista */
|
||||
refresh: () => Promise<void>;
|
||||
/** Setea manualmente el array (útil para optimist updates) */
|
||||
setData: React.Dispatch<React.SetStateAction<Clase[]>>;
|
||||
};
|
||||
|
||||
export function useClases(opts: Options = {}): UseClasesResult {
|
||||
const { auto = true, status = 'all' } = opts;
|
||||
|
||||
const [data, setData] = useState<Clase[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
// guardamos una referencia al abortController para cancelar en unmount
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
// cancelar request previa si hubiera
|
||||
if (abortRef.current) abortRef.current.abort();
|
||||
const ac = new AbortController();
|
||||
abortRef.current = ac;
|
||||
|
||||
try {
|
||||
const params = status && status !== 'all' ? { status } : undefined;
|
||||
const res = await apiClient.get<Clase[]>('/sessions', { params, signal: ac.signal });
|
||||
setData(res.data ?? []);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return;
|
||||
setError(e);
|
||||
console.error('Error al obtener clases:', e);
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false);
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto) refresh();
|
||||
return () => {
|
||||
// cancelar si el componente se desmonta
|
||||
abortRef.current?.abort();
|
||||
};
|
||||
}, [auto, refresh]);
|
||||
|
||||
return { data, loading, error, refresh, setData };
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// useDashboard.ts
|
||||
'use client'
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import apiClient from '@/lib/apiClient'
|
||||
import { useUserAuth } from '@/app/context/UserAuth'
|
||||
|
||||
export type DashboardUser = {
|
||||
message: string
|
||||
accessLog: { currentAccess: string; lastAccess: string }
|
||||
cardDetails: { sessions: number; users: number; assistants: number; revenue: number }
|
||||
sessions: { id: string; description: string; instructors: string; startDate: string }[]
|
||||
}
|
||||
|
||||
type Options = {
|
||||
auto?: boolean
|
||||
}
|
||||
|
||||
type UseDashboardResult = {
|
||||
data: DashboardUser | null
|
||||
loading: boolean
|
||||
error: unknown
|
||||
refresh: () => Promise<void>
|
||||
}
|
||||
|
||||
export function useDashboard(opts: Options = {}): UseDashboardResult {
|
||||
const { token } = useUserAuth()
|
||||
const { auto = true } = opts
|
||||
|
||||
const [data, setData] = useState<DashboardUser | null>(null)
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [error, setError] = useState<unknown>(null)
|
||||
|
||||
const abortRef = useRef<AbortController | null>(null)
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
// si no hay token aún, no pidas nada ni cambies loading
|
||||
if (!token) return
|
||||
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
abortRef.current?.abort()
|
||||
const ac = new AbortController()
|
||||
abortRef.current = ac
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<DashboardUser>('/dashboard', { signal: ac.signal })
|
||||
setData(res.data ?? null)
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return
|
||||
setError(e)
|
||||
console.error('Error al obtener dashboard:', e)
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false)
|
||||
}
|
||||
}, [token]) // ← incluye token!
|
||||
|
||||
useEffect(() => {
|
||||
if (auto && token) refresh() // ← solo cuando haya token
|
||||
return () => abortRef.current?.abort()
|
||||
}, [auto, token, refresh]) // ← depende de token también
|
||||
|
||||
return { data, loading, error, refresh }
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// React Imports
|
||||
import { useMemo } from 'react'
|
||||
|
||||
// Third-party imports
|
||||
import { useColorScheme } from '@mui/material'
|
||||
|
||||
// Type imports
|
||||
import type { Mode } from '@core/types'
|
||||
|
||||
export const useImageVariant = (mode: Mode, imgLight: string, imgDark: string): string => {
|
||||
// Hooks
|
||||
const { mode: muiMode } = useColorScheme()
|
||||
|
||||
return useMemo(() => {
|
||||
const isServer = typeof window === 'undefined'
|
||||
|
||||
const currentMode = (() => {
|
||||
if (isServer) return mode
|
||||
|
||||
return muiMode
|
||||
})()
|
||||
|
||||
const isDarkMode = currentMode === 'dark'
|
||||
|
||||
return isDarkMode ? imgDark : imgLight
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [mode, muiMode])
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// src/@core/hooks/useInstructors.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useUserAuth } from '@/app/context/UserAuth';
|
||||
import type { Instructor } from '@/app/modules/users/dto/instructor.dto';
|
||||
|
||||
type UseInstructorsResult = {
|
||||
data: Instructor[];
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
refresh: () => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook para obtener la lista de instructores.
|
||||
* - Lee el token del contexto.
|
||||
* - Maneja estados data/loading/error.
|
||||
* - Cancela la request al desmontar.
|
||||
*/
|
||||
export function useInstructors(enabled: boolean = true): UseInstructorsResult {
|
||||
const { token } = useUserAuth();
|
||||
|
||||
const [data, setData] = useState<Instructor[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fetchData = useCallback(
|
||||
async (signal?: AbortSignal) => {
|
||||
if (!token) {
|
||||
setData([]);
|
||||
setLoading(false);
|
||||
setError(null);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const res = await apiClient.get<Instructor[]>('/users/instructor', { signal });
|
||||
|
||||
setData(res.data ?? []);
|
||||
} catch (err: any) {
|
||||
if (err?.name !== 'CanceledError') {
|
||||
const msg =
|
||||
err?.response?.data?.message ||
|
||||
err?.message ||
|
||||
'Error al obtener instructores.';
|
||||
setError(msg);
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[token]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
const ctrl = new AbortController();
|
||||
fetchData(ctrl.signal);
|
||||
return () => ctrl.abort();
|
||||
}, [enabled, fetchData]);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
await fetchData();
|
||||
}, [fetchData]);
|
||||
|
||||
return { data, loading, error, refresh };
|
||||
}
|
||||
|
||||
export default useInstructors;
|
||||
@@ -0,0 +1,68 @@
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
export type InvoiceStatus = 'PENDING' | 'PAID' | 'FAILED' | 'CANCELED';
|
||||
|
||||
export type InvoiceWithDescription = {
|
||||
id: string;
|
||||
subscriptionId: string;
|
||||
base64Invoice: string | null;
|
||||
linkPayment: string | null;
|
||||
status: InvoiceStatus | string;
|
||||
amount: number;
|
||||
createdAt: string | Date;
|
||||
updatedAt: string | Date;
|
||||
description: string;
|
||||
};
|
||||
|
||||
export type UseInvoicesOptions = {
|
||||
auto?: boolean;
|
||||
};
|
||||
|
||||
export type UseInvoicesResult = {
|
||||
data: InvoiceWithDescription[];
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
refresh: () => Promise<void>;
|
||||
setData: React.Dispatch<React.SetStateAction<InvoiceWithDescription[]>>;
|
||||
};
|
||||
|
||||
export function useInvoices(
|
||||
userId: string,
|
||||
opts: UseInvoicesOptions = {}
|
||||
): UseInvoicesResult {
|
||||
const { auto = true } = opts;
|
||||
|
||||
const [data, setData] = useState<InvoiceWithDescription[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!userId) return;
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
if (abortRef.current) abortRef.current.abort();
|
||||
const ac = new AbortController();
|
||||
abortRef.current = ac;
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<InvoiceWithDescription[] | null>(`/invoices/${encodeURIComponent(userId)}`, { signal: ac.signal });
|
||||
setData((res.data ?? []) as InvoiceWithDescription[]);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return;
|
||||
setError(e);
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false);
|
||||
}
|
||||
}, [userId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto) refresh();
|
||||
return () => abortRef.current?.abort();
|
||||
}, [auto, refresh, userId]);
|
||||
|
||||
return { data, loading, error, refresh, setData };
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// React Imports
|
||||
import { useMemo } from 'react'
|
||||
|
||||
// Third-party Imports
|
||||
import { useCookie } from 'react-use'
|
||||
|
||||
export const useObjectCookie = <T>(key: string, fallback?: T | null): [T, (newVal: T) => void] => {
|
||||
// Hooks
|
||||
const [valStr, updateCookie] = useCookie(key)
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const value = useMemo<T>(() => (valStr ? JSON.parse(valStr) : fallback), [valStr])
|
||||
|
||||
const updateValue = (newVal: T) => {
|
||||
updateCookie(JSON.stringify(newVal))
|
||||
}
|
||||
|
||||
return [value, updateValue]
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
export type ProfilePictureResponse = {
|
||||
profilePicture: string | null;
|
||||
updatedAt: string | null;
|
||||
};
|
||||
|
||||
export type UseProfilePictureOptions = {
|
||||
auto?: boolean;
|
||||
};
|
||||
|
||||
export type UseProfilePictureResult = {
|
||||
profilePicture: string | null;
|
||||
updatedAt: string | null;
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
refresh: () => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook para obtener la foto de perfil de un usuario
|
||||
*
|
||||
* @param userId - ID del usuario
|
||||
* @param options - Opciones de configuración
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const { profilePicture, loading, error, refresh } = useProfilePicture('user-123', { auto: true });
|
||||
*
|
||||
* return (
|
||||
* <img src={profilePicture || '/default-avatar.png'} alt="Profile" />
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
export function useProfilePicture(
|
||||
userId: string,
|
||||
options: UseProfilePictureOptions = {}
|
||||
): UseProfilePictureResult {
|
||||
const { auto = true } = options;
|
||||
|
||||
const [profilePicture, setProfilePicture] = useState<string | null>(null);
|
||||
const [updatedAt, setUpdatedAt] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!userId) return;
|
||||
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<ProfilePictureResponse>(`/users/${encodeURIComponent(userId)}/profile-picture`);
|
||||
|
||||
setProfilePicture(res.data.profilePicture);
|
||||
setUpdatedAt(res.data.updatedAt);
|
||||
} catch (e: any) {
|
||||
setError(e);
|
||||
setProfilePicture(null);
|
||||
setUpdatedAt(null);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [userId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto && userId) {
|
||||
refresh();
|
||||
}
|
||||
}, [auto, userId, refresh]);
|
||||
|
||||
return {
|
||||
profilePicture,
|
||||
updatedAt,
|
||||
loading,
|
||||
error,
|
||||
refresh,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// useSessionInvoicesByMonth.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
export type InvoiceStatus = 'PENDING' | 'PAID' | 'CANCELED';
|
||||
|
||||
export type AssistantInvoice = {
|
||||
id: string;
|
||||
name: string;
|
||||
hasInvoice: boolean;
|
||||
invoiceStatus: InvoiceStatus | null;
|
||||
invoiceId: string | null;
|
||||
amount: number | null;
|
||||
};
|
||||
|
||||
export type SessionInvoicesByMonth = {
|
||||
sessionId: string;
|
||||
sessionCustomId: string;
|
||||
sessionDescription: string;
|
||||
sessionType: string;
|
||||
month: string;
|
||||
year: string;
|
||||
assistants: AssistantInvoice[];
|
||||
};
|
||||
|
||||
type Options = {
|
||||
sessionId: string;
|
||||
month: string; // "01" a "12"
|
||||
year: string; // "YYYY"
|
||||
auto?: boolean;
|
||||
};
|
||||
|
||||
type UseSessionInvoicesByMonthResult = {
|
||||
data: SessionInvoicesByMonth | null;
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
refresh: () => Promise<void>;
|
||||
};
|
||||
|
||||
export function useSessionInvoicesByMonth(
|
||||
opts: Options
|
||||
): UseSessionInvoicesByMonthResult {
|
||||
const { sessionId, month, year, auto = true } = opts;
|
||||
|
||||
const [data, setData] = useState<SessionInvoicesByMonth | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!sessionId || !month || !year) {
|
||||
setData(null);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
// Cancelar request previa si hubiera
|
||||
if (abortRef.current) abortRef.current.abort();
|
||||
const ac = new AbortController();
|
||||
abortRef.current = ac;
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<SessionInvoicesByMonth>(
|
||||
`/sessions/${sessionId}/invoices-by-month`,
|
||||
{ params: { month, year }, signal: ac.signal }
|
||||
);
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return;
|
||||
setError(e);
|
||||
console.error('Error al obtener facturas por mes:', e);
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false);
|
||||
}
|
||||
}, [sessionId, month, year]);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto) refresh();
|
||||
return () => {
|
||||
abortRef.current?.abort();
|
||||
};
|
||||
}, [auto, refresh]);
|
||||
|
||||
return { data, loading, error, refresh };
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// useSessionParticipants.ts
|
||||
'use client';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
export type Participant = { id: string; name: string; customId?: string };
|
||||
|
||||
export function useSessionParticipants(token: string, sessionId: string, auto = true) {
|
||||
const [selected, setSelected] = useState<Participant[]>([]);
|
||||
const [available, setAvailable] = useState<Participant[]>([]);
|
||||
const [loading, setLoading] = useState(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true); setError(null);
|
||||
try {
|
||||
const { data } = await apiClient.get(`/sessions/${sessionId}/participants`);
|
||||
setSelected(data.selected);
|
||||
setAvailable(data.available);
|
||||
} catch (e) { setError(e); } finally { setLoading(false); }
|
||||
}, [sessionId]);
|
||||
|
||||
const save = useCallback(async () => {
|
||||
await apiClient.put(`/sessions/${sessionId}/participants`, {
|
||||
userIds: selected.map(s => s.id),
|
||||
});
|
||||
}, [sessionId, selected]);
|
||||
|
||||
useEffect(() => { if (auto) refresh(); }, [auto, refresh]);
|
||||
|
||||
// helpers UI
|
||||
const add = (p: Participant) => {
|
||||
setAvailable(prev => prev.filter(x => x.id !== p.id));
|
||||
setSelected(prev => [...prev, p]);
|
||||
};
|
||||
const remove = (p: Participant) => {
|
||||
setSelected(prev => prev.filter(x => x.id !== p.id));
|
||||
setAvailable(prev => [...prev, p]);
|
||||
};
|
||||
|
||||
return { selected, available, setSelected, setAvailable, loading, error, refresh, save, add, remove };
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// React Imports
|
||||
import { useContext } from 'react'
|
||||
|
||||
// Context Imports
|
||||
import { SettingsContext } from '@core/contexts/settingsContext'
|
||||
|
||||
export const useSettings = () => {
|
||||
// Hooks
|
||||
const context = useContext(SettingsContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error('useSettingsContext must be used within a SettingsProvider')
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
'use client';
|
||||
import type { SystemConfig, UpdateSystemConfigDto } from '@/@core/types/system-config';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
export type UseSystemConfigOptions = {};
|
||||
|
||||
export type UseSystemConfigResult = {
|
||||
data: SystemConfig | null;
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
fetchConfig: () => Promise<void>;
|
||||
updateConfig: (dto: UpdateSystemConfigDto) => Promise<void>;
|
||||
reloadConfig: () => Promise<void>;
|
||||
updating: boolean;
|
||||
reloading: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook para gestionar la configuración del sistema
|
||||
*/
|
||||
export function useSystemConfig(
|
||||
options: UseSystemConfigOptions = {}
|
||||
): UseSystemConfigResult {
|
||||
|
||||
const [data, setData] = useState<SystemConfig | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [updating, setUpdating] = useState<boolean>(false);
|
||||
const [reloading, setReloading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
// Obtener configuración actual
|
||||
const fetchConfig = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<SystemConfig>('/system-config');
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
console.log('Error fetching system config:', e);
|
||||
setError(e);
|
||||
throw e;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Actualizar configuración
|
||||
const updateConfig = useCallback(
|
||||
async (dto: UpdateSystemConfigDto) => {
|
||||
setUpdating(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const res = await apiClient.patch<SystemConfig>('/system-config', dto);
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
setError(e);
|
||||
throw e;
|
||||
} finally {
|
||||
setUpdating(false);
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
// Recargar configuración desde BD
|
||||
const reloadConfig = useCallback(async () => {
|
||||
setReloading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<SystemConfig>('/system-config/reload');
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
setError(e);
|
||||
throw e;
|
||||
} finally {
|
||||
setReloading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return {
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
fetchConfig,
|
||||
updateConfig,
|
||||
reloadConfig,
|
||||
updating,
|
||||
reloading,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { useUserAuth } from '@/app/context/UserAuth';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useState } from 'react';
|
||||
|
||||
export const useToggleUserActive = () => {
|
||||
const { token } = useUserAuth();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const toggleActive = async (userId: string, isActive: boolean) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
<<<<<<< Updated upstream
|
||||
const deleted = isActive ? null : new Date().toISOString();
|
||||
const response = await apiClient.put(`/users/${userId}/active`, { deleted });
|
||||
console.log('✅ User active status updated successfully:', response.data);
|
||||
=======
|
||||
const url = `${process.env.NEXT_PUBLIC_BACKEND_URL ?? ''}/users/${userId}/active`;
|
||||
const deleted = isActive ? null : new Date().toISOString();
|
||||
const response = await axios.put(
|
||||
url,
|
||||
{ deleted },
|
||||
{ headers: { Authorization: `Bearer ${token}` } }
|
||||
);
|
||||
>>>>>>> Stashed changes
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error('❌ Error al cambiar estado del usuario', err);
|
||||
setError('No se pudo cambiar el estado del usuario');
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return { toggleActive, loading, error };
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useCallback } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import type { InvoiceStatus } from './useInvoices';
|
||||
|
||||
export type UpdateInvoiceStatusParams = {
|
||||
userId: string;
|
||||
invoiceId: string;
|
||||
status: InvoiceStatus;
|
||||
};
|
||||
|
||||
export type UpdateInvoiceStatusOptions = {
|
||||
onSuccess?: () => void | Promise<void>;
|
||||
onError?: (error: any) => void;
|
||||
};
|
||||
|
||||
export type UpdateInvoiceStatusResult = {
|
||||
mutate: (params: UpdateInvoiceStatusParams) => Promise<void>;
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
isSuccess: boolean;
|
||||
reset: () => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook para actualizar el estado de una factura
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const { mutate, loading, error, isSuccess } = useUpdateInvoiceStatus({
|
||||
* onSuccess: () => {
|
||||
* toast.success('Factura actualizada');
|
||||
* refetchInvoices();
|
||||
* },
|
||||
* onError: (error) => {
|
||||
* toast.error('Error al actualizar factura');
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* // Usar la mutación
|
||||
* await mutate({
|
||||
* userId: 'user-123',
|
||||
* invoiceId: 'invoice-456',
|
||||
* status: 'PAID'
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function useUpdateInvoiceStatus(
|
||||
options: UpdateInvoiceStatusOptions = {}
|
||||
): UpdateInvoiceStatusResult {
|
||||
const { onSuccess, onError } = options;
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
const [isSuccess, setIsSuccess] = useState<boolean>(false);
|
||||
|
||||
const mutate = useCallback(
|
||||
async ({ userId, invoiceId, status }: UpdateInvoiceStatusParams) => {
|
||||
if (!userId || !invoiceId || !status) {
|
||||
const validationError = new Error('userId, invoiceId y status son requeridos');
|
||||
setError(validationError);
|
||||
onError?.(validationError);
|
||||
throw validationError;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
setIsSuccess(false);
|
||||
|
||||
try {
|
||||
await apiClient.put(
|
||||
`/invoices/${encodeURIComponent(userId)}/${encodeURIComponent(invoiceId)}`,
|
||||
{ status }
|
||||
);
|
||||
|
||||
setIsSuccess(true);
|
||||
|
||||
// Ejecutar callback de éxito
|
||||
await onSuccess?.();
|
||||
} catch (e: any) {
|
||||
setError(e);
|
||||
setIsSuccess(false);
|
||||
onError?.(e);
|
||||
throw e;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[onSuccess, onError]
|
||||
);
|
||||
|
||||
const reset = useCallback(() => {
|
||||
setLoading(false);
|
||||
setError(null);
|
||||
setIsSuccess(false);
|
||||
}, []);
|
||||
|
||||
return { mutate, loading, error, isSuccess, reset };
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// useUsuarios.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { Usuario } from '@/views/usuarios/usuarios.dto';
|
||||
|
||||
type Options = {
|
||||
/** Lanza el fetch al montar el hook (default: true) */
|
||||
auto?: boolean;
|
||||
};
|
||||
|
||||
type UseUsuariosResult = {
|
||||
data: Usuario[];
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
/** Vuelve a pedir la lista */
|
||||
refresh: () => Promise<void>;
|
||||
/** Setea manualmente el array (útil para optimist updates) */
|
||||
setData: React.Dispatch<React.SetStateAction<Usuario[]>>;
|
||||
};
|
||||
|
||||
export function useUsuarios(opts: Options = {}): UseUsuariosResult {
|
||||
const { auto = true } = opts;
|
||||
|
||||
const [data, setData] = useState<Usuario[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
// guardamos una referencia al abortController para cancelar en unmount
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
// cancelar request previa si hubiera
|
||||
if (abortRef.current) abortRef.current.abort();
|
||||
const ac = new AbortController();
|
||||
abortRef.current = ac;
|
||||
|
||||
try {
|
||||
<<<<<<< Updated upstream
|
||||
const res = await apiClient.get<Usuario[]>('/users', { signal: ac.signal });
|
||||
=======
|
||||
if (!token) throw new Error('Token no encontrado');
|
||||
|
||||
// Asegurar que baseUrl no esté vacío
|
||||
const backendUrl = baseUrl
|
||||
const url = `${backendUrl}/users`;
|
||||
|
||||
|
||||
const res = await axios.get<Usuario[]>(url, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
signal: ac.signal, // axios v1 soporta AbortController
|
||||
});
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
setData(res.data ?? []);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return;
|
||||
setError(e);
|
||||
console.error('Error al obtener usuarios:', e);
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto) refresh();
|
||||
return () => {
|
||||
// cancelar si el componente se desmonta
|
||||
abortRef.current?.abort();
|
||||
};
|
||||
}, [auto, refresh]);
|
||||
|
||||
return { data, loading, error, refresh, setData };
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// hooks/useWhatsappStatus.ts
|
||||
'use client';
|
||||
import useSWR from 'swr';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
const WHATSAPP_STATUS_PATH = '/whatsapp/status';
|
||||
|
||||
const fetcher = async (path: string) => {
|
||||
const res = await apiClient.get(path);
|
||||
return res.data; // { status, phone, qr }
|
||||
};
|
||||
|
||||
export type UseWhatsappStatusOptions = {};
|
||||
|
||||
export function useWhatsappStatus(_options: UseWhatsappStatusOptions = {}) {
|
||||
const { data, error, isLoading, mutate } = useSWR(
|
||||
WHATSAPP_STATUS_PATH,
|
||||
fetcher,
|
||||
{
|
||||
// más frecuencia si NO hay sesión; más relajado si ya está conectada
|
||||
refreshInterval: (data) =>
|
||||
data?.status === 'Correcto' ? 30_000 : 3_000,
|
||||
revalidateOnFocus: false,
|
||||
shouldRetryOnError: true,
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
status: data?.status ?? 'Sin session',
|
||||
phone: data?.phone ?? 'No disponible',
|
||||
qr: data?.qr ?? null,
|
||||
loading: isLoading,
|
||||
error,
|
||||
refresh: () => mutate(), // botón "Actualizar"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// MUI imports
|
||||
import Box from '@mui/material/Box'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import type { BoxProps } from '@mui/material/Box'
|
||||
|
||||
const StepperWrapper = styled(Box)<BoxProps>(({ theme }) => {
|
||||
return {
|
||||
[theme.breakpoints.down('md')]: {
|
||||
'& .MuiStepper-horizontal:not(.MuiStepper-alternativeLabel)': {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-start'
|
||||
}
|
||||
},
|
||||
'& .MuiStep-root': {
|
||||
'& .MuiStepLabel-iconContainer:empty': {
|
||||
display: 'none'
|
||||
},
|
||||
'& .step-label': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
'& .step-number': {
|
||||
...theme.typography.h4,
|
||||
marginRight: theme.spacing(2)
|
||||
},
|
||||
'&:not(:has(.step-subtitle)) .step-number': {
|
||||
...theme.typography.h6
|
||||
},
|
||||
'& .step-title': {
|
||||
...theme.typography.body1,
|
||||
letterSpacing: 0.15,
|
||||
fontWeight: 500
|
||||
},
|
||||
'& .step-subtitle': {
|
||||
...theme.typography.body2,
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
},
|
||||
'& .MuiStepLabel-root.Mui-disabled': {
|
||||
'& .step-number': {
|
||||
color: 'var(--mui-palette-text-disabled)'
|
||||
}
|
||||
},
|
||||
'& .Mui-error': {
|
||||
'& .MuiStepLabel-labelContainer, & .step-number, & .step-title, & .step-subtitle': {
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .MuiStepConnector-root': {
|
||||
'& .MuiStepConnector-line': {
|
||||
borderBlockStartWidth: 3,
|
||||
borderRadius: 3
|
||||
},
|
||||
'&.Mui-active, &.Mui-completed': {
|
||||
'& .MuiStepConnector-line': {
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
},
|
||||
'&.Mui-disabled .MuiStepConnector-line': {
|
||||
borderColor: 'var(--mui-palette-primary-lightOpacity)'
|
||||
}
|
||||
},
|
||||
'& .MuiStepper-alternativeLabel': {
|
||||
'& .MuiStepConnector-root': {
|
||||
top: 9
|
||||
},
|
||||
'& .MuiStepLabel-labelContainer': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column'
|
||||
}
|
||||
},
|
||||
'& .MuiStepper-vertical': {
|
||||
'& .MuiStep-root': {
|
||||
'& .step-label': {
|
||||
justifyContent: 'flex-start'
|
||||
},
|
||||
'& .MuiStepContent-root': {
|
||||
borderInlineStartWidth: 3,
|
||||
marginLeft: theme.spacing(2.25),
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'& .button-wrapper': {
|
||||
marginTop: theme.spacing(4)
|
||||
},
|
||||
'&.active + .MuiStepConnector-root .MuiStepConnector-line': {
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
},
|
||||
'& .MuiStepConnector-root': {
|
||||
marginLeft: theme.spacing(2.25),
|
||||
'& .MuiStepConnector-line': {
|
||||
borderBlockStartWidth: 0,
|
||||
borderInlineStartWidth: 3,
|
||||
borderRadius: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default StepperWrapper
|
||||
@@ -0,0 +1,92 @@
|
||||
.table {
|
||||
inline-size: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.875rem;
|
||||
white-space: nowrap;
|
||||
|
||||
[align='right'] > * {
|
||||
text-align: end;
|
||||
}
|
||||
[align='center'] > * {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
thead {
|
||||
text-transform: uppercase;
|
||||
color: var(--mui-palette-text-primary);
|
||||
|
||||
th {
|
||||
font-weight: 500;
|
||||
font-size: 0.8125rem;
|
||||
letter-spacing: 0.2px;
|
||||
line-height: 1.8462;
|
||||
text-align: start;
|
||||
block-size: 56px;
|
||||
background-color: var(--mui-palette-customColors-tableHeaderBg);
|
||||
&:not(:first-of-type):not(:last-of-type) {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
&:first-of-type {
|
||||
&:not(:has(input[type='checkbox'])) {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1.25rem 1rem;
|
||||
}
|
||||
&:has(input[type='checkbox']) {
|
||||
padding-inline-start: 0.6875rem;
|
||||
}
|
||||
}
|
||||
&:last-of-type {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1rem 1.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
color: var(--mui-palette-text-secondary);
|
||||
|
||||
th,
|
||||
td {
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.4667;
|
||||
block-size: 50px;
|
||||
&:not(:first-of-type):not(:last-of-type) {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
&:first-of-type {
|
||||
&:not(:has(input[type='checkbox'])) {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1.25rem 1rem;
|
||||
}
|
||||
&:has(input[type='checkbox']) {
|
||||
padding-inline-start: 0.6875rem;
|
||||
}
|
||||
}
|
||||
&:last-of-type {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1rem 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
tr:not(:last-child) {
|
||||
border-block-end: 1px solid var(--border-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cellWithInput input {
|
||||
inline-size: 100%;
|
||||
background-color: transparent;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
border-radius: var(--mui-shape-customBorderRadius-sm);
|
||||
padding-block: 6px;
|
||||
padding-inline: 10px;
|
||||
margin-inline: -10px;
|
||||
|
||||
&:focus-visible {
|
||||
outline: 1px solid var(--mui-palette-primary-main);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// MUI Imports
|
||||
import { lighten } from '@mui/material/styles'
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { MenuItemStyles } from '@menu/types'
|
||||
|
||||
// Util Imports
|
||||
import { menuClasses } from '@menu/utils/menuClasses'
|
||||
|
||||
const menuItemStyles = (theme: Theme): MenuItemStyles => {
|
||||
return {
|
||||
root: {
|
||||
marginBlockStart: theme.spacing(1.5),
|
||||
[`&.${menuClasses.subMenuRoot}.${menuClasses.open} > .${menuClasses.button}, &.${menuClasses.subMenuRoot} > .${menuClasses.button}.${menuClasses.active}`]:
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-action-selected) !important'
|
||||
},
|
||||
[`&.${menuClasses.disabled} > .${menuClasses.button}`]: {
|
||||
color: 'var(--mui-palette-text-disabled)',
|
||||
[`& .${menuClasses.icon}`]: {
|
||||
color: 'inherit'
|
||||
}
|
||||
},
|
||||
[`&:not(.${menuClasses.subMenuRoot}) > .${menuClasses.button}.${menuClasses.active}`]: {
|
||||
color: 'var(--mui-palette-primary-contrastText)',
|
||||
background:
|
||||
theme.direction === 'ltr'
|
||||
? `linear-gradient(270deg, var(--mui-palette-primary-main), ${lighten(
|
||||
theme.palette.primary.main,
|
||||
0.5
|
||||
)} 100%)`
|
||||
: `linear-gradient(270deg, ${lighten(
|
||||
theme.palette.primary.main,
|
||||
0.5
|
||||
)}, var(--mui-palette-primary-main) 100%)`,
|
||||
[`& .${menuClasses.icon}`]: {
|
||||
color: 'inherit'
|
||||
}
|
||||
}
|
||||
},
|
||||
button: ({ active }) => ({
|
||||
paddingBlock: theme.spacing(2),
|
||||
'&:has(.MuiChip-root)': {
|
||||
paddingBlock: theme.spacing(1.75)
|
||||
},
|
||||
paddingInlineStart: theme.spacing(5.5),
|
||||
paddingInlineEnd: theme.spacing(3.5),
|
||||
borderStartEndRadius: 50,
|
||||
borderEndEndRadius: 50,
|
||||
...(!active && {
|
||||
'&:hover, &:focus-visible': {
|
||||
backgroundColor: 'var(--mui-palette-action-hover)'
|
||||
},
|
||||
'&[aria-expanded="true"]': {
|
||||
backgroundColor: 'var(--mui-palette-action-selected)'
|
||||
}
|
||||
})
|
||||
}),
|
||||
icon: ({ level }) => ({
|
||||
...(level === 0 && {
|
||||
fontSize: '1.375rem',
|
||||
marginInlineEnd: theme.spacing(2)
|
||||
}),
|
||||
...(level > 0 && {
|
||||
fontSize: '0.75rem',
|
||||
color: 'var(--mui-palette-text-secondary)',
|
||||
marginInlineEnd: theme.spacing(3.5)
|
||||
}),
|
||||
...(level === 1 && {
|
||||
marginInlineStart: theme.spacing(1.5)
|
||||
}),
|
||||
...(level > 1 && {
|
||||
marginInlineStart: theme.spacing(1.5 + 2.5 * (level - 1))
|
||||
}),
|
||||
'& > i, & > svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}),
|
||||
prefix: {
|
||||
marginInlineEnd: theme.spacing(2)
|
||||
},
|
||||
suffix: {
|
||||
marginInlineStart: theme.spacing(2)
|
||||
},
|
||||
subMenuExpandIcon: {
|
||||
fontSize: '1.375rem',
|
||||
marginInlineStart: theme.spacing(2),
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
},
|
||||
subMenuContent: {
|
||||
backgroundColor: 'transparent'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default menuItemStyles
|
||||
@@ -0,0 +1,42 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { MenuProps } from '@menu/vertical-menu'
|
||||
|
||||
// Util Imports
|
||||
import { menuClasses } from '@menu/utils/menuClasses'
|
||||
|
||||
const menuSectionStyles = (theme: Theme): MenuProps['menuSectionStyles'] => {
|
||||
return {
|
||||
root: {
|
||||
marginBlockStart: theme.spacing(7),
|
||||
[`& .${menuClasses.menuSectionContent}`]: {
|
||||
color: 'var(--mui-palette-text-disabled)',
|
||||
paddingInline: '0 !important',
|
||||
paddingBlock: `${theme.spacing(1.75)} !important`,
|
||||
gap: theme.spacing(2.5),
|
||||
|
||||
'&:before': {
|
||||
content: '""',
|
||||
blockSize: 1,
|
||||
inlineSize: '0.875rem',
|
||||
backgroundColor: 'var(--mui-palette-divider)'
|
||||
},
|
||||
'&:after': {
|
||||
content: '""',
|
||||
blockSize: 1,
|
||||
flexGrow: 1,
|
||||
backgroundColor: 'var(--mui-palette-divider)'
|
||||
}
|
||||
},
|
||||
[`& .${menuClasses.menuSectionLabel}`]: {
|
||||
flexGrow: 0,
|
||||
fontSize: '13px',
|
||||
lineHeight: 1.38462
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default menuSectionStyles
|
||||
@@ -0,0 +1,35 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Util Imports
|
||||
import { menuClasses, verticalNavClasses } from '@menu/utils/menuClasses'
|
||||
|
||||
const navigationCustomStyles = (theme: Theme) => {
|
||||
return {
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
zIndex: 'var(--drawer-z-index) !important',
|
||||
[`& .${verticalNavClasses.bgColorContainer}`]: {
|
||||
backgroundColor: 'var(--mui-palette-background-default)'
|
||||
},
|
||||
[`& .${verticalNavClasses.header}`]: {
|
||||
paddingBlock: theme.spacing(5),
|
||||
paddingInline: theme.spacing(5.5, 4)
|
||||
},
|
||||
[`& .${verticalNavClasses.container}`]: {
|
||||
transition: 'none',
|
||||
borderColor: 'transparent',
|
||||
[`& .${verticalNavClasses.toggled}`]: {
|
||||
boxShadow: 'var(--mui-customShadows-lg)'
|
||||
}
|
||||
},
|
||||
[`& .${menuClasses.root}`]: {
|
||||
paddingBlockEnd: theme.spacing(2),
|
||||
paddingInlineEnd: theme.spacing(4)
|
||||
},
|
||||
[`& .${verticalNavClasses.backdrop}`]: {
|
||||
backgroundColor: 'var(--backdrop-color)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default navigationCustomStyles
|
||||
@@ -0,0 +1,77 @@
|
||||
// React Imports
|
||||
import type { SVGAttributes } from 'react'
|
||||
|
||||
const Logo = (props: SVGAttributes<SVGElement>) => {
|
||||
return (
|
||||
<svg width='1.2658em' height='1em' viewBox='0 0 100 79' fill='none' xmlns='http://www.w3.org/2000/svg' {...props}>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M4.92008 0.501904L22.662 11.4573C23.614 12.0451 24.1936 13.0844 24.1936 14.2036V64.2521C24.1936 65.3871 23.5976 66.4387 22.6241 67.0214L4.8822 77.6429C3.35344 78.5581 1.37254 78.0602 0.457741 76.5307C0.158194 76.0299 0 75.4572 0 74.8736V3.24818C0 1.46582 1.44424 0.0209274 3.22581 0.0209274C3.82422 0.0209274 4.41085 0.18746 4.92008 0.501904Z'
|
||||
fill='currentColor'
|
||||
/>
|
||||
<path
|
||||
opacity='0.077704'
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M0 26.1063L24.1936 39.9852V53.5915L0 26.1063Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
opacity='0.077704'
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M0 26.1063L24.1936 39.6319V47.9438L0 26.1063Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M95.084 0.489601L77.3421 11.4083C76.3878 11.9956 75.8064 13.0362 75.8064 14.1571V64.2526C75.8064 65.3875 76.4024 66.4391 77.3759 67.0219L95.1178 77.6433C96.6466 78.5585 98.6275 78.0606 99.5423 76.5312C99.8418 76.0303 100 75.4576 100 74.874V3.23842C100 1.45605 98.5558 0.0111618 96.7742 0.0111618C96.1774 0.0111618 95.5923 0.176782 95.084 0.489601Z'
|
||||
fill='currentColor'
|
||||
/>
|
||||
<path
|
||||
opacity='0.077704'
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M100 26.1063L75.8064 39.956V54.0023L100 26.1063Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
opacity='0.077704'
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M100 26.1063L75.8064 39.6199V48.3546L100 26.1063Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M4.91149 0.475694L50 28.123V54.7479L0 26.0986V3.22726C0 1.44489 1.44424 0 3.22581 0C3.8208 0 4.4042 0.164633 4.91149 0.475694Z'
|
||||
fill='currentColor'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M4.91149 0.475694L50 28.123V54.7479L0 26.0986V3.22726C0 1.44489 1.44424 0 3.22581 0C3.8208 0 4.4042 0.164633 4.91149 0.475694Z'
|
||||
fill='white'
|
||||
fillOpacity='0.15'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M95.0885 0.475694L50 28.123V54.7479L100 26.0986V3.22726C100 1.44489 98.5558 0 96.7742 0C96.1792 0 95.5958 0.164633 95.0885 0.475694Z'
|
||||
fill='currentColor'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M95.0885 0.475694L50 28.123V54.7479L100 26.0986V3.22726C100 1.44489 98.5558 0 96.7742 0C96.1792 0 95.5958 0.164633 95.0885 0.475694Z'
|
||||
fill='white'
|
||||
fillOpacity='0.3'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default Logo
|
||||
@@ -0,0 +1,74 @@
|
||||
import plugin from 'tailwindcss/plugin'
|
||||
|
||||
module.exports = plugin(function () {}, {
|
||||
theme: {
|
||||
borderColor: ({ theme }) => ({
|
||||
...theme('colors'),
|
||||
DEFAULT: 'var(--border-color, currentColor)'
|
||||
}),
|
||||
borderRadius: {
|
||||
none: '0px',
|
||||
xs: 'var(--mui-shape-customBorderRadius-xs)',
|
||||
sm: 'var(--mui-shape-customBorderRadius-sm)',
|
||||
DEFAULT: '0.375rem',
|
||||
md: 'var(--mui-shape-customBorderRadius-md)',
|
||||
lg: 'var(--mui-shape-customBorderRadius-lg)',
|
||||
xl: 'var(--mui-shape-customBorderRadius-xl)',
|
||||
'2xl': '0.75rem',
|
||||
'3xl': '1rem',
|
||||
'4xl': '1.5rem',
|
||||
full: '9999px'
|
||||
},
|
||||
screens: {
|
||||
sm: '600px',
|
||||
md: '900px',
|
||||
lg: '1200px',
|
||||
xl: '1536px',
|
||||
'2xl': '1920px'
|
||||
},
|
||||
extend: {
|
||||
boxShadow: {
|
||||
xs: 'var(--mui-customShadows-xs)',
|
||||
sm: 'var(--mui-customShadows-sm)',
|
||||
DEFAULT: 'var(--mui-customShadows-md)',
|
||||
md: 'var(--mui-customShadows-md)',
|
||||
lg: 'var(--mui-customShadows-lg)',
|
||||
xl: 'var(--mui-customShadows-xl)'
|
||||
},
|
||||
colors: {
|
||||
primary: 'var(--primary-color)',
|
||||
primaryLight: 'var(--mui-palette-primary-lightOpacity)',
|
||||
primaryLighter: 'var(--mui-palette-primary-lighterOpacity)',
|
||||
secondary: 'var(--mui-palette-secondary-main)',
|
||||
error: 'var(--mui-palette-error-main)',
|
||||
errorLight: 'var(--mui-palette-error-lightOpacity)',
|
||||
errorLighter: 'var(--mui-palette-error-lighterOpacity)',
|
||||
warning: 'var(--mui-palette-warning-main)',
|
||||
info: 'var(--mui-palette-info-main)',
|
||||
success: 'var(--mui-palette-success-main)',
|
||||
textPrimary: 'var(--mui-palette-text-primary)',
|
||||
textSecondary: 'var(--mui-palette-text-secondary)',
|
||||
textDisabled: 'var(--mui-palette-text-disabled)',
|
||||
actionActive: 'var(--mui-palette-action-active)',
|
||||
actionHover: 'var(--mui-palette-action-hover)',
|
||||
actionSelected: 'var(--mui-palette-action-selected)',
|
||||
actionFocus: 'var(--mui-palette-action-focus)',
|
||||
backgroundPaper: 'var(--mui-palette-background-paper)',
|
||||
backgroundDefault: 'var(--mui-palette-background-default)',
|
||||
track: 'var(--mui-palette-customColors-trackBg)',
|
||||
backdrop: 'var(--backdrop-color)',
|
||||
facebook: '#497ce2',
|
||||
twitter: '#1da1f2',
|
||||
github: '#272727',
|
||||
googlePlus: '#db4437'
|
||||
},
|
||||
zIndex: {
|
||||
header: 'var(--header-z-index)',
|
||||
footer: 'var(--footer-z-index)',
|
||||
customizer: 'var(--customizer-z-index)',
|
||||
search: 'var(--search-z-index)',
|
||||
drawer: 'var(--drawer-z-index)'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,329 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const colorSchemes = (): Theme['colorSchemes'] => {
|
||||
const skin = 'default' as string
|
||||
|
||||
return {
|
||||
light: {
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#8C57FF',
|
||||
light: '#A379FF',
|
||||
dark: '#7E4EE6',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.38)'
|
||||
},
|
||||
secondary: {
|
||||
main: '#8A8D93',
|
||||
light: '#A1A4A9',
|
||||
dark: '#7C7F84',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.38)'
|
||||
},
|
||||
error: {
|
||||
main: '#FF4C51',
|
||||
light: '#FF7074',
|
||||
dark: '#E64449',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.38)'
|
||||
},
|
||||
warning: {
|
||||
main: '#FFB400',
|
||||
light: '#FFC333',
|
||||
dark: '#E6A200',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.38)'
|
||||
},
|
||||
info: {
|
||||
main: '#16B1FF',
|
||||
light: '#45C1FF',
|
||||
dark: '#149FE6',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.38)'
|
||||
},
|
||||
success: {
|
||||
main: '#56CA00',
|
||||
light: '#78D533',
|
||||
dark: '#4DB600',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.38)'
|
||||
},
|
||||
text: {
|
||||
primary: `rgb(var(--mui-mainColorChannels-light) / 0.9)`,
|
||||
secondary: `rgb(var(--mui-mainColorChannels-light) / 0.7)`,
|
||||
disabled: `rgb(var(--mui-mainColorChannels-light) / 0.4)`,
|
||||
primaryChannel: 'var(--mui-mainColorChannels-light)',
|
||||
secondaryChannel: 'var(--mui-mainColorChannels-light)'
|
||||
},
|
||||
divider: `rgb(var(--mui-mainColorChannels-light) / 0.12)`,
|
||||
dividerChannel: 'var(--mui-mainColorChannels-light)',
|
||||
background: {
|
||||
default: skin === 'bordered' ? '#FFFFFF' : '#F4F5FA',
|
||||
paper: '#FFFFFF'
|
||||
},
|
||||
action: {
|
||||
active: `rgb(var(--mui-mainColorChannels-light) / 0.6)`,
|
||||
hover: `rgb(var(--mui-mainColorChannels-light) / 0.04)`,
|
||||
selected: `rgb(var(--mui-mainColorChannels-light) / 0.08)`,
|
||||
disabled: `rgb(var(--mui-mainColorChannels-light) / 0.3)`,
|
||||
disabledBackground: `rgb(var(--mui-mainColorChannels-light) / 0.12)`,
|
||||
focus: `rgb(var(--mui-mainColorChannels-light) / 0.1)`,
|
||||
focusOpacity: 0.1,
|
||||
activeChannel: 'var(--mui-mainColorChannels-light)',
|
||||
selectedChannel: 'var(--mui-mainColorChannels-light)'
|
||||
},
|
||||
Alert: {
|
||||
errorColor: 'var(--mui-palette-error-main)',
|
||||
warningColor: 'var(--mui-palette-warning-main)',
|
||||
infoColor: 'var(--mui-palette-info-main)',
|
||||
successColor: 'var(--mui-palette-success-main)',
|
||||
errorStandardBg: 'var(--mui-palette-error-lightOpacity)',
|
||||
warningStandardBg: 'var(--mui-palette-warning-lightOpacity)',
|
||||
infoStandardBg: 'var(--mui-palette-info-lightOpacity)',
|
||||
successStandardBg: 'var(--mui-palette-success-lightOpacity)',
|
||||
errorFilledColor: 'var(--mui-palette-error-contrastText)',
|
||||
warningFilledColor: 'var(--mui-palette-warning-contrastText)',
|
||||
infoFilledColor: 'var(--mui-palette-info-contrastText)',
|
||||
successFilledColor: 'var(--mui-palette-success-contrastText)',
|
||||
errorFilledBg: 'var(--mui-palette-error-main)',
|
||||
warningFilledBg: 'var(--mui-palette-warning-main)',
|
||||
infoFilledBg: 'var(--mui-palette-info-main)',
|
||||
successFilledBg: 'var(--mui-palette-success-main)'
|
||||
},
|
||||
Avatar: {
|
||||
defaultBg: '#F0EFF0'
|
||||
},
|
||||
Chip: {
|
||||
defaultBorder: 'var(--mui-palette-divider)'
|
||||
},
|
||||
FilledInput: {
|
||||
bg: `rgb(var(--mui-mainColorChannels-light) / 0.06)`,
|
||||
hoverBg: `rgb(var(--mui-mainColorChannels-light) / 0.08)`,
|
||||
disabledBg: `rgb(var(--mui-mainColorChannels-light) / 0.06)`
|
||||
},
|
||||
LinearProgress: {
|
||||
primaryBg: 'var(--mui-palette-primary-mainOpacity)',
|
||||
secondaryBg: 'var(--mui-palette-secondary-mainOpacity)',
|
||||
errorBg: 'var(--mui-palette-error-mainOpacity)',
|
||||
warningBg: 'var(--mui-palette-warning-mainOpacity)',
|
||||
infoBg: 'var(--mui-palette-info-mainOpacity)',
|
||||
successBg: 'var(--mui-palette-success-mainOpacity)'
|
||||
},
|
||||
SnackbarContent: {
|
||||
bg: '#1A0E33',
|
||||
color: 'var(--mui-palette-background-paper)'
|
||||
},
|
||||
Switch: {
|
||||
defaultColor: 'var(--mui-palette-common-white)',
|
||||
defaultDisabledColor: 'var(--mui-palette-common-white)',
|
||||
primaryDisabledColor: 'var(--mui-palette-common-white)',
|
||||
secondaryDisabledColor: 'var(--mui-palette-common-white)',
|
||||
errorDisabledColor: 'var(--mui-palette-common-white)',
|
||||
warningDisabledColor: 'var(--mui-palette-common-white)',
|
||||
infoDisabledColor: 'var(--mui-palette-common-white)',
|
||||
successDisabledColor: 'var(--mui-palette-common-white)'
|
||||
},
|
||||
Tooltip: {
|
||||
bg: '#1A0E33'
|
||||
},
|
||||
TableCell: {
|
||||
border: 'var(--mui-palette-divider)'
|
||||
},
|
||||
customColors: {
|
||||
bodyBg: '#F4F5FA',
|
||||
chatBg: '#F7F6FA',
|
||||
greyLightBg: '#FAFAFA',
|
||||
inputBorder: `rgb(var(--mui-mainColorChannels-light) / 0.22)`,
|
||||
tableHeaderBg: '#F6F7FB',
|
||||
tooltipText: '#FFFFFF',
|
||||
trackBg: '#F0F2F8'
|
||||
}
|
||||
}
|
||||
},
|
||||
dark: {
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#8C57FF',
|
||||
light: '#A379FF',
|
||||
dark: '#7E4EE6',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.38)'
|
||||
},
|
||||
secondary: {
|
||||
main: '#8A8D93',
|
||||
light: '#A1A4A9',
|
||||
dark: '#7C7F84',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.38)'
|
||||
},
|
||||
error: {
|
||||
main: '#FF4C51',
|
||||
light: '#FF7074',
|
||||
dark: '#E64449',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.38)'
|
||||
},
|
||||
warning: {
|
||||
main: '#FFB400',
|
||||
light: '#FFC333',
|
||||
dark: '#E6A200',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.38)'
|
||||
},
|
||||
info: {
|
||||
main: '#16B1FF',
|
||||
light: '#45C1FF',
|
||||
dark: '#149FE6',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.38)'
|
||||
},
|
||||
success: {
|
||||
main: '#56CA00',
|
||||
light: '#78D533',
|
||||
dark: '#4DB600',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.38)'
|
||||
},
|
||||
text: {
|
||||
primary: `rgb(var(--mui-mainColorChannels-dark) / 0.9)`,
|
||||
secondary: `rgb(var(--mui-mainColorChannels-dark) / 0.7)`,
|
||||
disabled: `rgb(var(--mui-mainColorChannels-dark) / 0.4)`,
|
||||
primaryChannel: 'var(--mui-mainColorChannels-dark)',
|
||||
secondaryChannel: 'var(--mui-mainColorChannels-dark)'
|
||||
},
|
||||
divider: `rgb(var(--mui-mainColorChannels-dark) / 0.12)`,
|
||||
dividerChannel: 'var(--mui-mainColorChannels-dark)',
|
||||
background: {
|
||||
default: skin === 'bordered' ? '#312D4B' : '#28243D',
|
||||
paper: '#312D4B'
|
||||
},
|
||||
action: {
|
||||
active: `rgb(var(--mui-mainColorChannels-dark) / 0.6)`,
|
||||
hover: `rgb(var(--mui-mainColorChannels-dark) / 0.04)`,
|
||||
selected: `rgb(var(--mui-mainColorChannels-dark) / 0.08)`,
|
||||
disabled: `rgb(var(--mui-mainColorChannels-dark) / 0.3)`,
|
||||
disabledBackground: `rgb(var(--mui-mainColorChannels-dark) / 0.12)`,
|
||||
focus: `rgb(var(--mui-mainColorChannels-dark) / 0.1)`,
|
||||
focusOpacity: 0.1,
|
||||
activeChannel: 'var(--mui-mainColorChannels-dark)',
|
||||
selectedChannel: 'var(--mui-mainColorChannels-dark)'
|
||||
},
|
||||
Alert: {
|
||||
errorColor: 'var(--mui-palette-error-main)',
|
||||
warningColor: 'var(--mui-palette-warning-main)',
|
||||
infoColor: 'var(--mui-palette-info-main)',
|
||||
successColor: 'var(--mui-palette-success-main)',
|
||||
errorStandardBg: 'var(--mui-palette-error-lightOpacity)',
|
||||
warningStandardBg: 'var(--mui-palette-warning-lightOpacity)',
|
||||
infoStandardBg: 'var(--mui-palette-info-lightOpacity)',
|
||||
successStandardBg: 'var(--mui-palette-success-lightOpacity)',
|
||||
errorFilledColor: 'var(--mui-palette-error-contrastText)',
|
||||
warningFilledColor: 'var(--mui-palette-warning-contrastText)',
|
||||
infoFilledColor: 'var(--mui-palette-info-contrastText)',
|
||||
successFilledColor: 'var(--mui-palette-success-contrastText)',
|
||||
errorFilledBg: 'var(--mui-palette-error-main)',
|
||||
warningFilledBg: 'var(--mui-palette-warning-main)',
|
||||
infoFilledBg: 'var(--mui-palette-info-main)',
|
||||
successFilledBg: 'var(--mui-palette-success-main)'
|
||||
},
|
||||
Avatar: {
|
||||
defaultBg: '#3F3B59'
|
||||
},
|
||||
Chip: {
|
||||
defaultBorder: 'var(--mui-palette-divider)'
|
||||
},
|
||||
FilledInput: {
|
||||
bg: `rgb(var(--mui-mainColorChannels-dark) / 0.06)`,
|
||||
hoverBg: `rgb(var(--mui-mainColorChannels-dark) / 0.08)`,
|
||||
disabledBg: `rgb(var(--mui-mainColorChannels-dark) / 0.06)`
|
||||
},
|
||||
LinearProgress: {
|
||||
primaryBg: 'var(--mui-palette-primary-mainOpacity)',
|
||||
secondaryBg: 'var(--mui-palette-secondary-mainOpacity)',
|
||||
errorBg: 'var(--mui-palette-error-mainOpacity)',
|
||||
warningBg: 'var(--mui-palette-warning-mainOpacity)',
|
||||
infoBg: 'var(--mui-palette-info-mainOpacity)',
|
||||
successBg: 'var(--mui-palette-success-mainOpacity)'
|
||||
},
|
||||
SnackbarContent: {
|
||||
bg: '#F7F4FF',
|
||||
color: 'var(--mui-palette-background-paper)'
|
||||
},
|
||||
Switch: {
|
||||
defaultColor: 'var(--mui-palette-common-white)',
|
||||
defaultDisabledColor: 'var(--mui-palette-common-white)',
|
||||
primaryDisabledColor: 'var(--mui-palette-common-white)',
|
||||
secondaryDisabledColor: 'var(--mui-palette-common-white)',
|
||||
errorDisabledColor: 'var(--mui-palette-common-white)',
|
||||
warningDisabledColor: 'var(--mui-palette-common-white)',
|
||||
infoDisabledColor: 'var(--mui-palette-common-white)',
|
||||
successDisabledColor: 'var(--mui-palette-common-white)'
|
||||
},
|
||||
Tooltip: {
|
||||
bg: '#F7F4FF'
|
||||
},
|
||||
TableCell: {
|
||||
border: 'var(--mui-palette-divider)'
|
||||
},
|
||||
customColors: {
|
||||
bodyBg: '#28243D',
|
||||
chatBg: '#373452',
|
||||
greyLightBg: '#373350',
|
||||
inputBorder: `rgb(var(--mui-mainColorChannels-dark) / 0.22)`,
|
||||
tableHeaderBg: '#3D3759',
|
||||
tooltipText: '#312D4B',
|
||||
trackBg: '#474360'
|
||||
}
|
||||
}
|
||||
}
|
||||
} as Theme['colorSchemes']
|
||||
}
|
||||
|
||||
export default colorSchemes
|
||||
@@ -0,0 +1,17 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { SystemMode } from '@core/types'
|
||||
|
||||
const customShadows = (mode: SystemMode): Theme['customShadows'] => {
|
||||
return {
|
||||
xs: `0px 2px 4px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.16 : 0.2})`,
|
||||
sm: `0px 3px 6px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.18 : 0.22})`,
|
||||
md: `0px 4px 10px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.2 : 0.24})`,
|
||||
lg: `0px 6px 16px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.22 : 0.26})`,
|
||||
xl: `0px 8px 28px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.24 : 0.28})`
|
||||
}
|
||||
}
|
||||
|
||||
export default customShadows
|
||||
@@ -0,0 +1,48 @@
|
||||
// Next Imports
|
||||
import { Inter } from 'next/font/google'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { SystemMode } from '@core/types'
|
||||
|
||||
// Theme Options Imports
|
||||
import overrides from './overrides'
|
||||
import colorSchemes from './colorSchemes'
|
||||
import spacing from './spacing'
|
||||
import shadows from './shadows'
|
||||
import customShadows from './customShadows'
|
||||
import typography from './typography'
|
||||
|
||||
const inter = Inter({ subsets: ['latin'], weight: ['300', '400', '500', '600', '700', '800', '900'] })
|
||||
|
||||
const theme = (mode: SystemMode, direction: Theme['direction']): Theme => {
|
||||
return {
|
||||
direction,
|
||||
components: overrides(),
|
||||
colorSchemes: colorSchemes(),
|
||||
...spacing,
|
||||
shape: {
|
||||
borderRadius: 6,
|
||||
customBorderRadius: {
|
||||
xs: 2,
|
||||
sm: 4,
|
||||
md: 6,
|
||||
lg: 8,
|
||||
xl: 10
|
||||
}
|
||||
},
|
||||
shadows: shadows(mode),
|
||||
typography: typography(inter.style.fontFamily),
|
||||
customShadows: customShadows(mode),
|
||||
mainColorChannels: {
|
||||
light: '46 38 61',
|
||||
dark: '231 227 252',
|
||||
lightShadow: '46 38 61',
|
||||
darkShadow: '19 17 32'
|
||||
}
|
||||
} as Theme
|
||||
}
|
||||
|
||||
export default theme
|
||||
@@ -0,0 +1,90 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const accordion = (skin: Skin): Theme['components'] => ({
|
||||
MuiAccordion: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
variant: 'outlined'
|
||||
})
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
transition: theme.transitions.create(['margin', 'border-radius', 'box-shadow']),
|
||||
...(skin !== 'bordered'
|
||||
? {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
: {
|
||||
'&:not(.Mui-expanded) + &:not(.Mui-expanded)': {
|
||||
borderBlockStart: 0
|
||||
},
|
||||
'&:not(.Mui-expanded):has(+ &:not(.Mui-expanded))': {
|
||||
borderBlockEnd: 0
|
||||
}
|
||||
}),
|
||||
'&:not(.Mui-expanded):has(+ .Mui-expanded)': {
|
||||
borderBottomLeftRadius: 'var(--mui-shape-borderRadius)',
|
||||
borderBottomRightRadius: 'var(--mui-shape-borderRadius)'
|
||||
},
|
||||
'&.Mui-expanded': {
|
||||
borderRadius: 'var(--mui-shape-borderRadius)',
|
||||
...(skin !== 'bordered' && {
|
||||
boxShadow: 'var(--mui-customShadows-md)'
|
||||
}),
|
||||
margin: theme.spacing(2, 0),
|
||||
'& + .MuiAccordion-root': {
|
||||
borderTopLeftRadius: 'var(--mui-shape-borderRadius)',
|
||||
borderTopRightRadius: 'var(--mui-shape-borderRadius)',
|
||||
'&:before': {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiAccordionSummary: {
|
||||
defaultProps: {
|
||||
expandIcon: <i className='ri-arrow-down-s-line' />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(3, 5),
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
'&.Mui-expanded': {
|
||||
minHeight: 48
|
||||
},
|
||||
'& .MuiTypography-root': {
|
||||
color: 'inherit',
|
||||
fontWeight: theme.typography.fontWeightMedium
|
||||
}
|
||||
}),
|
||||
content: {
|
||||
margin: '0 !important'
|
||||
},
|
||||
expandIconWrapper: {
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
fontSize: '1.25rem',
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiAccordionDetails: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(0, 5, 5),
|
||||
'& .MuiTypography-root': {
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default accordion
|
||||
@@ -0,0 +1,179 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const alerts: Theme['components'] = {
|
||||
MuiAlert: {
|
||||
defaultProps: {
|
||||
iconMapping: {
|
||||
error: <i className='ri-error-warning-line' />,
|
||||
warning: <i className='ri-alert-line' />,
|
||||
info: <i className='ri-information-line' />,
|
||||
success: <i className='ri-checkbox-circle-line' />
|
||||
}
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(4),
|
||||
gap: theme.spacing(4),
|
||||
...theme.typography.body1,
|
||||
'&:not(:has(.MuiAlertTitle-root))': {
|
||||
'& .MuiAlert-icon + .MuiAlert-message': {
|
||||
alignSelf: 'center'
|
||||
}
|
||||
}
|
||||
}),
|
||||
icon: {
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
minWidth: 30,
|
||||
height: 30,
|
||||
borderRadius: 'var(--mui-shape-borderRadius)',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
},
|
||||
message: {
|
||||
padding: 0
|
||||
},
|
||||
action: {
|
||||
padding: 0,
|
||||
marginRight: 0
|
||||
}
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'standard', severity: 'error' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-error-main)',
|
||||
color: 'var(--mui-palette-error-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'standard', severity: 'warning' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-warning-main)',
|
||||
color: 'var(--mui-palette-warning-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'standard', severity: 'info' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-info-main)',
|
||||
color: 'var(--mui-palette-info-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'standard', severity: 'success' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-success-main)',
|
||||
color: 'var(--mui-palette-success-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', severity: 'error' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-error-main)',
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-error-mainOpacity)',
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', severity: 'warning' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-warning-main)',
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-warning-mainOpacity)',
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', severity: 'info' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-info-main)',
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-info-mainOpacity)',
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', severity: 'success' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-success-main)',
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-success-mainOpacity)',
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', severity: 'error' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
color: 'var(--mui-palette-error-main)',
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', severity: 'warning' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
color: 'var(--mui-palette-warning-main)',
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', severity: 'info' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
color: 'var(--mui-palette-info-main)',
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', severity: 'success' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
color: 'var(--mui-palette-success-main)',
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
MuiAlertTitle: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
...theme.typography.h5,
|
||||
marginTop: 0,
|
||||
marginBottom: theme.spacing(1),
|
||||
color: 'inherit'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default alerts
|
||||
@@ -0,0 +1,76 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const autocomplete = (skin: Skin): Theme['components'] => ({
|
||||
MuiAutocomplete: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
slotProps: {
|
||||
paper: {
|
||||
variant: 'outlined'
|
||||
}
|
||||
}
|
||||
}),
|
||||
ChipProps: {
|
||||
size: 'small'
|
||||
},
|
||||
popupIcon: <i className='ri-arrow-down-s-line' />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiButtonBase-root.Mui-disabled i, & .MuiButtonBase-root.Mui-disabled svg': {
|
||||
color: 'var(--mui-palette-action-disabled)'
|
||||
},
|
||||
'& .MuiOutlinedInput-input': {
|
||||
height: '1.4375em'
|
||||
}
|
||||
},
|
||||
input: {
|
||||
'& + .MuiAutocomplete-endAdornment': {
|
||||
right: '1rem',
|
||||
'& i, & svg': {
|
||||
fontSize: '1.5rem',
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
},
|
||||
'& .MuiAutocomplete-clearIndicator': {
|
||||
padding: 2
|
||||
}
|
||||
},
|
||||
'&.MuiInputBase-inputSizeSmall + .MuiAutocomplete-endAdornment': {
|
||||
'& i, & svg': {
|
||||
fontSize: '1.375rem'
|
||||
}
|
||||
}
|
||||
},
|
||||
paper: {
|
||||
...(skin !== 'bordered' && {
|
||||
boxShadow: 'var(--mui-customShadows-lg)',
|
||||
marginBlockStart: '0.125rem'
|
||||
})
|
||||
},
|
||||
listbox: ({ theme }) => ({
|
||||
'& .MuiAutocomplete-option': {
|
||||
padding: theme.spacing(2, 5),
|
||||
'&[aria-selected="true"]': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
'&.Mui-focused, &.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .MuiAutocomplete-option.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-action-hover)'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default autocomplete
|
||||
@@ -0,0 +1,38 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const avatar: Theme['components'] = {
|
||||
MuiAvatarGroup: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
justifyContent: 'flex-end',
|
||||
'& .MuiAvatar-root': {
|
||||
borderColor: 'var(--mui-palette-background-paper)'
|
||||
},
|
||||
'&.pull-up .MuiAvatar-root': {
|
||||
cursor: 'pointer',
|
||||
transition: theme.transitions.create(['box-shadow', 'transform'], {
|
||||
easing: 'ease',
|
||||
duration: theme.transitions.duration.shorter
|
||||
}),
|
||||
'&:hover': {
|
||||
zIndex: 2,
|
||||
boxShadow: 'var(--mui-customShadows-md)',
|
||||
transform: 'translateY(-5px)'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiAvatar: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
fontSize: theme.typography.body1.fontSize,
|
||||
lineHeight: 1.2
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default avatar
|
||||
@@ -0,0 +1,16 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const backdrop: Theme['components'] = {
|
||||
MuiBackdrop: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:not(.MuiBackdrop-invisible)': {
|
||||
backgroundColor: 'var(--backdrop-color)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default backdrop
|
||||
@@ -0,0 +1,19 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const badges: Theme['components'] = {
|
||||
MuiBadge: {
|
||||
styleOverrides: {
|
||||
standard: ({ theme }) => ({
|
||||
height: 22,
|
||||
minWidth: 22,
|
||||
borderRadius: 20,
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
lineHeight: 1.07,
|
||||
padding: theme.spacing(1, 2)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default badges
|
||||
@@ -0,0 +1,29 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const breadcrumbs: Theme['components'] = {
|
||||
MuiBreadcrumbs: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& svg, & i': {
|
||||
fontSize: '1.25rem'
|
||||
},
|
||||
'& a': {
|
||||
textDecoration: 'none',
|
||||
color: 'var(--mui-palette-text-secondary)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
}
|
||||
}
|
||||
},
|
||||
li: ({ theme }) => ({
|
||||
lineHeight: theme.typography.body1.lineHeight,
|
||||
'& > *:not(a)': {
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default breadcrumbs
|
||||
@@ -0,0 +1,73 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
const buttonGroup: Theme['components'] = {
|
||||
MuiButtonGroup: {
|
||||
defaultProps: {
|
||||
disableRipple: themeConfig.disableRipple
|
||||
},
|
||||
styleOverrides: {
|
||||
contained: ({ ownerState }) => ({
|
||||
boxShadow: 'var(--mui-customShadows-xs)',
|
||||
...(ownerState.disabled && {
|
||||
boxShadow: 'none'
|
||||
})
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'text', color: 'primary' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'secondary' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'error' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'warning' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'info' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'success' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default buttonGroup
|
||||
@@ -0,0 +1,377 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
const iconStyles = (size?: string) => ({
|
||||
'& > *:nth-of-type(1)': {
|
||||
...(size === 'small'
|
||||
? {
|
||||
fontSize: '14px'
|
||||
}
|
||||
: {
|
||||
...(size === 'medium'
|
||||
? {
|
||||
fontSize: '16px'
|
||||
}
|
||||
: {
|
||||
fontSize: '20px'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const button: Theme['components'] = {
|
||||
MuiButtonBase: {
|
||||
defaultProps: {
|
||||
disableRipple: themeConfig.disableRipple
|
||||
}
|
||||
},
|
||||
MuiButton: {
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
...(ownerState.variant === 'text'
|
||||
? {
|
||||
...(ownerState.size === 'small' && {
|
||||
padding: theme.spacing(2, 2.5)
|
||||
}),
|
||||
...(ownerState.size === 'medium' && {
|
||||
padding: theme.spacing(2, 3.5)
|
||||
}),
|
||||
...(ownerState.size === 'large' && {
|
||||
padding: theme.spacing(2, 4.5)
|
||||
})
|
||||
}
|
||||
: {
|
||||
...(ownerState.variant === 'outlined'
|
||||
? {
|
||||
...(ownerState.size === 'small' && {
|
||||
padding: theme.spacing(1.75, 3.25)
|
||||
}),
|
||||
...(ownerState.size === 'medium' && {
|
||||
padding: theme.spacing(1.75, 4.25)
|
||||
}),
|
||||
...(ownerState.size === 'large' && {
|
||||
padding: theme.spacing(1.75, 5.25)
|
||||
})
|
||||
}
|
||||
: {
|
||||
...(ownerState.size === 'small' && {
|
||||
padding: theme.spacing(2, 3.5)
|
||||
}),
|
||||
...(ownerState.size === 'medium' && {
|
||||
padding: theme.spacing(2, 4.5)
|
||||
}),
|
||||
...(ownerState.size === 'large' && {
|
||||
padding: theme.spacing(2, 5.5)
|
||||
})
|
||||
})
|
||||
})
|
||||
}),
|
||||
contained: ({ ownerState }) => ({
|
||||
boxShadow: 'var(--mui-customShadows-xs)',
|
||||
...(!ownerState.disabled && {
|
||||
'&:hover, &.Mui-focusVisible': {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
},
|
||||
'&:active': {
|
||||
boxShadow: 'none'
|
||||
}
|
||||
})
|
||||
}),
|
||||
sizeSmall: ({ theme }) => ({
|
||||
lineHeight: 1.38462,
|
||||
fontSize: theme.typography.body2.fontSize,
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)'
|
||||
}),
|
||||
sizeLarge: {
|
||||
fontSize: '1.0625rem',
|
||||
lineHeight: 1.529412,
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-lg)'
|
||||
},
|
||||
startIcon: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
marginInlineEnd: theme.spacing(1.5)
|
||||
}
|
||||
: {
|
||||
...(ownerState.size === 'medium'
|
||||
? {
|
||||
marginInlineEnd: theme.spacing(2)
|
||||
}
|
||||
: {
|
||||
marginInlineEnd: theme.spacing(2.5)
|
||||
})
|
||||
}),
|
||||
...iconStyles(ownerState.size)
|
||||
}),
|
||||
endIcon: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
marginInlineStart: theme.spacing(1.5)
|
||||
}
|
||||
: {
|
||||
...(ownerState.size === 'medium'
|
||||
? {
|
||||
marginInlineStart: theme.spacing(2)
|
||||
}
|
||||
: {
|
||||
marginInlineStart: theme.spacing(2.5)
|
||||
})
|
||||
}),
|
||||
...iconStyles(ownerState.size)
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'text', color: 'primary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-primary-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'secondary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'error' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-error-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'warning' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-warning-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'info' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-info-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'success' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-success-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'primary' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-primary-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-primary-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'secondary' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-secondary-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
borderColor: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'error' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-error-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-error-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-error-main)',
|
||||
borderColor: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'warning' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-warning-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-warning-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-warning-main)',
|
||||
borderColor: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'info' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-info-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-info-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-info-main)',
|
||||
borderColor: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'success' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-success-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-success-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-success-main)',
|
||||
borderColor: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'primary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-primary-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-primary-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'secondary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-secondary-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'error' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-error-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-error-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'warning' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-warning-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-warning-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'info' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-info-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-info-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'success' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-success-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-success-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default button
|
||||
@@ -0,0 +1,91 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const card = (skin: Skin): Theme['components'] => {
|
||||
return {
|
||||
MuiCard: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
variant: 'outlined'
|
||||
})
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ ownerState }) => ({
|
||||
...(ownerState.variant !== 'outlined' && {
|
||||
boxShadow: 'var(--mui-customShadows-md)'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiCardHeader: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiCardContent-root, & + .MuiCardActions-root': {
|
||||
paddingBlockStart: 0
|
||||
},
|
||||
'& + .MuiCollapse-root .MuiCardContent-root:first-child, & + .MuiCollapse-root .MuiCardActions-root:first-child':
|
||||
{
|
||||
paddingBlockStart: 0
|
||||
}
|
||||
}),
|
||||
subheader: ({ theme }) => ({
|
||||
...theme.typography.subtitle1,
|
||||
color: 'rgb(var(--mui-palette-text-primaryChannel) / 0.55)'
|
||||
}),
|
||||
action: ({ theme }) => ({
|
||||
...theme.typography.body1,
|
||||
color: 'var(--mui-palette-text-disabled)',
|
||||
marginBlock: 0,
|
||||
marginInlineEnd: 0,
|
||||
'& .MuiIconButton-root': {
|
||||
color: 'inherit'
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiCardContent: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
color: 'var(--mui-palette-text-secondary)',
|
||||
'&:last-child': {
|
||||
paddingBlockEnd: theme.spacing(5)
|
||||
},
|
||||
'& + .MuiCardHeader-root, & + .MuiCardContent-root, & + .MuiCardActions-root': {
|
||||
paddingBlockStart: 0
|
||||
},
|
||||
'& + .MuiCollapse-root .MuiCardHeader-root:first-child, & + .MuiCollapse-root .MuiCardContent-root:first-child, & + .MuiCollapse-root .MuiCardActions-root:first-child':
|
||||
{
|
||||
paddingBlockStart: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiCardActions: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'&:where(.card-actions-dense)': {
|
||||
padding: theme.spacing(2.5),
|
||||
'& .MuiButton-text': {
|
||||
paddingInline: theme.spacing(2.5)
|
||||
}
|
||||
},
|
||||
'& + .MuiCardHeader-root, & + .MuiCardContent-root, & + .MuiCardActions-root': {
|
||||
paddingBlockStart: 0
|
||||
},
|
||||
'& + .MuiCollapse-root .MuiCardHeader-root:first-child, & + .MuiCollapse-root .MuiCardContent-root:first-child, & + .MuiCollapse-root .MuiCardActions-root:first-child':
|
||||
{
|
||||
paddingBlockStart: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default card
|
||||
@@ -0,0 +1,94 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const Icon = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path
|
||||
d='M8 4h8a4 4 0 0 1 4 4v8a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4V8a4 4 0 0 1 4-4Z'
|
||||
stroke='var(--mui-palette-text-secondary)'
|
||||
strokeWidth='2'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const IndeterminateIcon = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path d='M3 8a5 5 0 0 1 5-5h8a5 5 0 0 1 5 5v8a5 5 0 0 1-5 5H8a5 5 0 0 1-5-5V8Z' fill='currentColor' />
|
||||
<path d='M8.5 11.5h7v1h-7v-1Z' fill='var(--mui-palette-common-white)' />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const CheckedIcon = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path d='M3 8a5 5 0 0 1 5-5h8a5 5 0 0 1 5 5v8a5 5 0 0 1-5 5H8a5 5 0 0 1-5-5V8Z' fill='currentColor' />
|
||||
<path
|
||||
d='m11 13.586 4.596-4.597.707.707L11 15l-3.182-3.182.707-.707L11 13.586Z'
|
||||
fill='var(--mui-palette-common-white)'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const checkbox: Theme['components'] = {
|
||||
MuiCheckbox: {
|
||||
defaultProps: {
|
||||
icon: <Icon />,
|
||||
indeterminateIcon: <IndeterminateIcon />,
|
||||
checkedIcon: <CheckedIcon />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
padding: theme.spacing(1),
|
||||
'& svg': {
|
||||
fontSize: '1.25rem'
|
||||
}
|
||||
}
|
||||
: {
|
||||
padding: theme.spacing(1.5),
|
||||
'& svg': {
|
||||
fontSize: '1.5rem'
|
||||
}
|
||||
}),
|
||||
'&.Mui-checked:not(.Mui-disabled) svg': {
|
||||
filter: 'drop-shadow(var(--mui-customShadows-xs))'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
'&:not(.Mui-checked)': {
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorPrimary': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorSecondary': {
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorError': {
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorWarning': {
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorInfo': {
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorSuccess': {
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default checkbox
|
||||
@@ -0,0 +1,190 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const chip: Theme['components'] = {
|
||||
MuiChip: {
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'tonal', color: 'primary' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-primary-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-primary-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'secondary' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-secondary-lightOpacity)',
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'error' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-error-lightOpacity)',
|
||||
color: 'var(--mui-palette-error-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-error-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-error-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-error-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'warning' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-warning-lightOpacity)',
|
||||
color: 'var(--mui-palette-warning-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-warning-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-warning-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-warning-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'info' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-info-lightOpacity)',
|
||||
color: 'var(--mui-palette-info-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-info-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-info-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-info-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'success' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-success-lightOpacity)',
|
||||
color: 'var(--mui-palette-success-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-success-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-success-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-success-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
styleOverrides: {
|
||||
root: ({ ownerState, theme }) => ({
|
||||
...theme.typography.body2,
|
||||
fontWeight: theme.typography.fontWeightMedium,
|
||||
|
||||
'& .MuiChip-deleteIcon': {
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
fontSize: '1rem',
|
||||
marginInlineEnd: theme.spacing(1),
|
||||
marginInlineStart: theme.spacing(-2)
|
||||
}
|
||||
: {
|
||||
fontSize: '1.25rem',
|
||||
marginInlineEnd: theme.spacing(2),
|
||||
marginInlineStart: theme.spacing(-3)
|
||||
})
|
||||
},
|
||||
'& .MuiChip-avatar, & .MuiChip-icon': {
|
||||
'& i, & svg': {
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
fontSize: 13
|
||||
}
|
||||
: {
|
||||
fontSize: 15
|
||||
})
|
||||
},
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
height: 16,
|
||||
width: 16,
|
||||
marginInlineStart: theme.spacing(1),
|
||||
marginInlineEnd: theme.spacing(-2)
|
||||
}
|
||||
: {
|
||||
height: 20,
|
||||
width: 20,
|
||||
marginInlineStart: theme.spacing(2),
|
||||
marginInlineEnd: theme.spacing(-3)
|
||||
})
|
||||
}
|
||||
}),
|
||||
label: ({ ownerState, theme }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
paddingInline: theme.spacing(3)
|
||||
}
|
||||
: {
|
||||
paddingInline: theme.spacing(4)
|
||||
})
|
||||
}),
|
||||
iconMedium: {
|
||||
fontSize: '1.25rem'
|
||||
},
|
||||
iconSmall: {
|
||||
fontSize: '1rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default chip
|
||||
@@ -0,0 +1,67 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const dialog = (skin: Skin): Theme['components'] => ({
|
||||
MuiDialog: {
|
||||
styleOverrides: {
|
||||
paper: ({ theme }) => ({
|
||||
...(skin !== 'bordered'
|
||||
? {
|
||||
boxShadow: 'var(--mui-customShadows-xl)'
|
||||
}
|
||||
: {
|
||||
boxShadow: 'none'
|
||||
}),
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
'&:not(.MuiDialog-paperFullScreen)': {
|
||||
margin: theme.spacing(6)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiDialogTitle: {
|
||||
defaultProps: {
|
||||
variant: 'h5'
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiDialogActions-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiDialogContent: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiDialogContent-root, & + .MuiDialogActions-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiDialogActions: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'& .MuiButtonBase-root:not(:first-of-type)': {
|
||||
marginInlineStart: theme.spacing(4)
|
||||
},
|
||||
'&:where(.dialog-actions-dense)': {
|
||||
padding: theme.spacing(2.5),
|
||||
'& .MuiButton-text': {
|
||||
paddingInline: theme.spacing(2.5)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default dialog
|
||||
@@ -0,0 +1,26 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const drawer = (skin: Skin): Theme['components'] => ({
|
||||
MuiDrawer: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
PaperProps: {
|
||||
elevation: 0
|
||||
}
|
||||
})
|
||||
},
|
||||
styleOverrides: {
|
||||
paper: {
|
||||
...(skin !== 'bordered' && {
|
||||
boxShadow: 'var(--mui-customShadows-lg)'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default drawer
|
||||
@@ -0,0 +1,68 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const fab: Theme['components'] = {
|
||||
MuiFab: {
|
||||
variants: [
|
||||
{
|
||||
props: { color: 'default' },
|
||||
style: {
|
||||
color: 'rgb(var(--mui-mainColorChannels-light) / 0.9)',
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-grey-A100)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'primary' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-primary-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'secondary' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'error' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-error-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'warning' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-warning-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'info' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-info-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'success' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-success-dark)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default fab
|
||||
@@ -0,0 +1,22 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const formControlLabel: Theme['components'] = {
|
||||
MuiFormControlLabel: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
marginInlineStart: theme.spacing(-2)
|
||||
}),
|
||||
label: {
|
||||
'&, &.Mui-disabled': {
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default formControlLabel
|
||||
@@ -0,0 +1,140 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
const iconButton: Theme['components'] = {
|
||||
MuiIconButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiSvgIcon-root, & i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
},
|
||||
sizeSmall: ({ theme }) => ({
|
||||
padding: theme.spacing(1.75),
|
||||
fontSize: '1.25rem'
|
||||
}),
|
||||
sizeMedium: ({ theme }) => ({
|
||||
padding: theme.spacing(2),
|
||||
fontSize: '1.375rem'
|
||||
}),
|
||||
sizeLarge: ({ theme }) => ({
|
||||
padding: theme.spacing(2.25),
|
||||
fontSize: '1.5rem'
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { color: 'default' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': {
|
||||
backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)'
|
||||
}
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-action-active)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'primary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-primary-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'secondary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'error' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-error-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-error-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'warning' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-warning-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-warning-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'info' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-info-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-info-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'success' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-success-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-success-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default iconButton
|
||||
@@ -0,0 +1,83 @@
|
||||
// Override Imports
|
||||
import Accordion from './accordion'
|
||||
import Alerts from './alerts'
|
||||
import Autocomplete from './autocomplete'
|
||||
import avatar from './avatar'
|
||||
import backdrop from './backdrop'
|
||||
import badges from './badges'
|
||||
import breadcrumbs from './breadcrumbs'
|
||||
import button from './button'
|
||||
import buttonGroup from './button-group'
|
||||
import card from './card'
|
||||
import Checkbox from './checkbox'
|
||||
import chip from './chip'
|
||||
import dialog from './dialog'
|
||||
import drawer from './drawer'
|
||||
import fab from './fab'
|
||||
import formControlLabel from './form-control-label'
|
||||
import iconButton from './icon-button'
|
||||
import input from './input'
|
||||
import list from './list'
|
||||
import menu from './menu'
|
||||
import pagination from './pagination'
|
||||
import paper from './paper'
|
||||
import popover from './popover'
|
||||
import progress from './progress'
|
||||
import Radio from './radio'
|
||||
import Rating from './rating'
|
||||
import Select from './select'
|
||||
import slider from './slider'
|
||||
import snackbar from './snackbar'
|
||||
import switchOverrides from './switch'
|
||||
import tablePagination from './table-pagination'
|
||||
import tabs from './tabs'
|
||||
import timeline from './timeline'
|
||||
import toggleButton from './toggle-button'
|
||||
import tooltip from './tooltip'
|
||||
import typography from './typography'
|
||||
|
||||
const overrides = () => {
|
||||
const skin = 'default'
|
||||
|
||||
return Object.assign(
|
||||
{},
|
||||
Accordion(skin),
|
||||
Alerts,
|
||||
Autocomplete(skin),
|
||||
avatar,
|
||||
backdrop,
|
||||
badges,
|
||||
breadcrumbs,
|
||||
button,
|
||||
buttonGroup,
|
||||
card(skin),
|
||||
Checkbox,
|
||||
chip,
|
||||
dialog(skin),
|
||||
drawer(skin),
|
||||
fab,
|
||||
formControlLabel,
|
||||
iconButton,
|
||||
input,
|
||||
list,
|
||||
menu(skin),
|
||||
pagination,
|
||||
paper,
|
||||
popover(skin),
|
||||
progress,
|
||||
Radio,
|
||||
Rating,
|
||||
Select,
|
||||
slider,
|
||||
snackbar(skin),
|
||||
switchOverrides,
|
||||
tablePagination,
|
||||
tabs,
|
||||
timeline,
|
||||
toggleButton,
|
||||
tooltip,
|
||||
typography
|
||||
)
|
||||
}
|
||||
|
||||
export default overrides
|
||||
@@ -0,0 +1,112 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const input: Theme['components'] = {
|
||||
MuiFormControl: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:has(.MuiRadio-root) .MuiFormHelperText-root, &:has(.MuiCheckbox-root) .MuiFormHelperText-root, &:has(.MuiSwitch-root) .MuiFormHelperText-root':
|
||||
{
|
||||
marginInline: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiInputBase: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
lineHeight: 1.6,
|
||||
'&.MuiInput-underline': {
|
||||
'&:before': {
|
||||
borderColor: 'var(--mui-palette-customColors-inputBorder)'
|
||||
},
|
||||
'&:not(.Mui-disabled, .Mui-error):hover:before': {
|
||||
borderColor: 'var(--mui-palette-action-active)'
|
||||
}
|
||||
},
|
||||
'&.Mui-disabled .MuiInputAdornment-root, &.Mui-disabled .MuiInputAdornment-root > *': {
|
||||
color: 'var(--mui-palette-action-disabled)'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiFilledInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:before': {
|
||||
borderBottom: '1px solid var(--mui-palette-text-secondary)'
|
||||
},
|
||||
'&.Mui-disabled:before': {
|
||||
borderBottomStyle: 'solid'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiInputLabel: {
|
||||
styleOverrides: {
|
||||
shrink: ({ ownerState }) => ({
|
||||
...(ownerState.variant === 'outlined' && {
|
||||
color: 'var(--mui-palette-text-secondary)',
|
||||
transform: 'translate(14px, -8px) scale(0.867)'
|
||||
}),
|
||||
...(ownerState.variant === 'filled' && {
|
||||
transform: 'translate(12px, 7px) scale(0.867)'
|
||||
}),
|
||||
...(ownerState.variant === 'standard' && {
|
||||
transform: 'translate(0, -1.5px) scale(0.867)'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiOutlinedInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:not(.Mui-focused):not(.Mui-error):not(.Mui-disabled):hover .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: 'var(--mui-palette-action-active)'
|
||||
},
|
||||
'&.Mui-disabled .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: 'var(--mui-palette-action-disabledBackground)'
|
||||
}
|
||||
},
|
||||
input: ({ theme, ownerState }) => ({
|
||||
...(ownerState?.size === 'medium' && {
|
||||
'&:not(.MuiInputBase-inputMultiline, .MuiInputBase-inputAdornedStart)': {
|
||||
paddingBlock: theme.spacing(4)
|
||||
},
|
||||
height: '1.5em'
|
||||
}),
|
||||
'& ~ .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: 'var(--mui-palette-customColors-inputBorder)'
|
||||
}
|
||||
}),
|
||||
notchedOutline: {
|
||||
'& legend': {
|
||||
fontSize: '0.867em'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiInputAdornment: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
'& i, & svg': {
|
||||
fontSize: '1.25rem'
|
||||
},
|
||||
'& *': {
|
||||
color: 'inherit !important'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiFormHelperText: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
lineHeight: 1,
|
||||
letterSpacing: 'unset'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default input
|
||||
@@ -0,0 +1,81 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const list: Theme['components'] = {
|
||||
MuiListItem: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
gap: theme.spacing(4)
|
||||
}),
|
||||
padding: ({ theme, ownerState }) => ({
|
||||
...(!ownerState.dense && {
|
||||
paddingBlock: theme.spacing(2),
|
||||
paddingInlineStart: theme.spacing(5)
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiListItemAvatar: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
minWidth: 'unset'
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiListItemIcon: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
minWidth: 0,
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
fontSize: '1.375rem',
|
||||
'& > svg, & > i': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiListItemButton: {
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
gap: theme.spacing(4),
|
||||
...(!ownerState.dense && {
|
||||
paddingBlock: theme.spacing(2)
|
||||
}),
|
||||
paddingInlineStart: theme.spacing(5),
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
'&:hover, &.Mui-focused, &.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
},
|
||||
'& .MuiTypography-root': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'& + .MuiListItemSecondaryAction-root .MuiIconButton-root': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiListItemText: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
margin: 0
|
||||
},
|
||||
primary: {
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiListSubheader: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
...theme.typography.subtitle2,
|
||||
paddingBlock: 10,
|
||||
paddingInline: theme.spacing(5)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default list
|
||||
@@ -0,0 +1,57 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const menu = (skin: Skin): Theme['components'] => ({
|
||||
MuiMenu: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
slotProps: {
|
||||
paper: {
|
||||
elevation: 0
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
styleOverrides: {
|
||||
paper: ({ theme }) => ({
|
||||
marginBlockStart: theme.spacing(0.5),
|
||||
...(skin !== 'bordered' && {
|
||||
boxShadow: 'var(--mui-customShadows-lg)'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiMenuItem: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
paddingBlock: theme.spacing(2),
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
'& i, & svg': {
|
||||
fontSize: '1.375rem'
|
||||
},
|
||||
'& .MuiListItemIcon-root': {
|
||||
minInlineSize: 0
|
||||
},
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
'& .MuiListItemIcon-root': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'&:hover, &.Mui-focused, &.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
}
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
color: 'var(--mui-palette-text-disabled)',
|
||||
opacity: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default menu
|
||||
@@ -0,0 +1,172 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const pagination: Theme['components'] = {
|
||||
MuiPagination: {
|
||||
styleOverrides: {
|
||||
ul: {
|
||||
rowGap: 6
|
||||
}
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'text', color: 'primary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-primary-main)',
|
||||
color: 'var(--mui-palette-primary-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'secondary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)',
|
||||
color: 'var(--mui-palette-secondary-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'standard' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
borderColor: 'var(--mui-palette-action-selected)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'primary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
backgroundColor: 'rgb(var(--mui-palette-primary-mainChannel) / var(--mui-palette-action-activatedOpacity))',
|
||||
borderColor: 'rgba(var(--mui-palette-primary-mainChannel) / 0.5)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'secondary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
backgroundColor:
|
||||
'rgb(var(--mui-palette-secondary-mainChannel) / var(--mui-palette-action-activatedOpacity))',
|
||||
borderColor: 'rgba(var(--mui-palette-secondary-mainChannel) / 0.5)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root:not(.MuiPaginationItem-ellipsis)': {
|
||||
backgroundColor: 'var(--mui-palette-action-selected)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'standard' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
}
|
||||
},
|
||||
'& .MuiPaginationItem-root:hover:not(.Mui-selected):not(.MuiPaginationItem-ellipsis)': {
|
||||
backgroundColor: 'var(--mui-palette-action-focus)'
|
||||
},
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'primary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-primary-main)',
|
||||
color: 'var(--mui-palette-primary-contrastText)',
|
||||
'&:not(.Mui-disabled)': {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--mui-palette-primary-dark)'
|
||||
}
|
||||
},
|
||||
'& .MuiPaginationItem-root:hover:not(.Mui-selected):not(.MuiPaginationItem-ellipsis)': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-primary-main)',
|
||||
color: 'var(--mui-palette-primary-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'secondary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)',
|
||||
color: 'var(--mui-palette-secondary-contrastText)',
|
||||
'&:not(.Mui-disabled)': {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-dark)'
|
||||
}
|
||||
},
|
||||
'& .MuiPaginationItem-root:hover:not(.Mui-selected):not(.MuiPaginationItem-ellipsis)': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-mainOpacity)',
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
},
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)',
|
||||
color: 'var(--mui-palette-secondary-contrastText)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
MuiPaginationItem: {
|
||||
styleOverrides: {
|
||||
root: ({ ownerState }) => ({
|
||||
...(ownerState.size === 'medium' && {
|
||||
height: '2.375rem',
|
||||
minWidth: '2.375rem'
|
||||
}),
|
||||
...(ownerState.shape !== 'rounded' && {
|
||||
borderRadius: '50px'
|
||||
}),
|
||||
'&.Mui-selected.Mui-disabled': {
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
opacity: 0.45
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45
|
||||
},
|
||||
...(ownerState.shape === 'rounded' &&
|
||||
ownerState.size === 'small' && {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)'
|
||||
}),
|
||||
...(ownerState.shape === 'rounded' &&
|
||||
ownerState.size === 'large' && {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-lg)'
|
||||
})
|
||||
}),
|
||||
sizeSmall: {
|
||||
height: '2.125rem',
|
||||
minWidth: '2.125rem'
|
||||
},
|
||||
sizeLarge: {
|
||||
height: '2.625rem',
|
||||
minWidth: '2.625rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default pagination
|
||||
@@ -0,0 +1,14 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const paper: Theme['components'] = {
|
||||
MuiPaper: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundImage: 'none'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default paper
|
||||
@@ -0,0 +1,21 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const popover = (skin: Skin): Theme['components'] => ({
|
||||
MuiPopover: {
|
||||
styleOverrides: {
|
||||
paper: {
|
||||
...(skin === 'bordered'
|
||||
? { boxShadow: 'none', border: '1px solid var(--mui-palette-divider)' }
|
||||
: {
|
||||
boxShadow: 'var(--mui-customShadows-sm)'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default popover
|
||||
@@ -0,0 +1,18 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const progress: Theme['components'] = {
|
||||
MuiLinearProgress: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
height: 6,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
'& .MuiLinearProgress-bar': {
|
||||
borderRadius: theme.shape.borderRadius
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default progress
|
||||
@@ -0,0 +1,81 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const IconChecked = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path
|
||||
d='M12 18.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13Z'
|
||||
fill='var(--mui-palette-common-white)'
|
||||
stroke='currentColor'
|
||||
strokeWidth='5'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const UncheckedIcon = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path d='M12 20a8 8 0 1 1 0-16 8 8 0 0 1 0 16Z' stroke='var(--mui-palette-text-secondary)' strokeWidth='2' />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const radio: Theme['components'] = {
|
||||
MuiRadio: {
|
||||
defaultProps: {
|
||||
icon: <UncheckedIcon />,
|
||||
checkedIcon: <IconChecked />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
padding: theme.spacing(1),
|
||||
'& svg': {
|
||||
fontSize: '1.25rem'
|
||||
}
|
||||
}
|
||||
: {
|
||||
padding: theme.spacing(1.5),
|
||||
'& svg': {
|
||||
fontSize: '1.5rem'
|
||||
}
|
||||
}),
|
||||
'&.Mui-checked:not(.Mui-disabled) svg': {
|
||||
filter: 'drop-shadow(var(--mui-customShadows-xs))'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
'&:not(.Mui-checked)': {
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorPrimary': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorSecondary': {
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorError': {
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorWarning': {
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorInfo': {
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorSuccess': {
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default radio
|
||||
@@ -0,0 +1,35 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const rating: Theme['components'] = {
|
||||
MuiRating: {
|
||||
defaultProps: {
|
||||
emptyIcon: <i className='ri-star-line' />,
|
||||
icon: <i className='ri-star-fill' />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: {
|
||||
gap: '2px',
|
||||
color: 'var(--mui-palette-warning-main)',
|
||||
'& i, & svg': {
|
||||
flexShrink: 0
|
||||
},
|
||||
'& .MuiRating-decimal > label:first-of-type, & .MuiRating-decimal > span:first-of-type': {
|
||||
zIndex: 1
|
||||
}
|
||||
},
|
||||
sizeSmall: {
|
||||
'& .MuiRating-icon i, & .MuiRating-icon svg': {
|
||||
fontSize: '1.25rem'
|
||||
}
|
||||
},
|
||||
sizeLarge: {
|
||||
'& .MuiRating-icon i, & .MuiRating-icon svg': {
|
||||
fontSize: '1.75rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default rating
|
||||
@@ -0,0 +1,61 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const SelectIcon = () => {
|
||||
return <i className='ri-arrow-down-s-line' />
|
||||
}
|
||||
|
||||
const iconStyles = (theme: Theme) => ({
|
||||
userSelect: 'none',
|
||||
display: 'inline-block',
|
||||
fill: 'currentColor',
|
||||
flexShrink: 0,
|
||||
transition: theme.transitions.create('fill', {
|
||||
duration: theme.transitions.duration.shorter
|
||||
}),
|
||||
fontSize: '1.25rem',
|
||||
position: 'absolute',
|
||||
right: '1rem',
|
||||
top: 'calc(50% - 0.5em)',
|
||||
pointerEvents: 'none'
|
||||
})
|
||||
|
||||
const select: Theme['components'] = {
|
||||
MuiSelect: {
|
||||
defaultProps: {
|
||||
IconComponent: SelectIcon
|
||||
},
|
||||
styleOverrides: {
|
||||
select: ({ theme, ownerState }) => ({
|
||||
...(ownerState.variant === 'outlined' && {
|
||||
minHeight: '1.5em'
|
||||
}),
|
||||
'&[aria-expanded="true"] ~ i, &[aria-expanded="true"] ~ svg': {
|
||||
transform: 'rotate(180deg)'
|
||||
},
|
||||
'& ~ i, & ~ svg': iconStyles(theme as Theme),
|
||||
'&.MuiInputBase-inputSizeSmall': {
|
||||
'& ~ i, & ~ svg': {
|
||||
height: '1.375rem',
|
||||
width: '1.375rem'
|
||||
}
|
||||
},
|
||||
'&:not(aria-label="Without label") ~ .MuiOutlinedInput-notchedOutline > legend > span': {
|
||||
paddingInline: '5px'
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiNativeSelect: {
|
||||
styleOverrides: {
|
||||
select: ({ theme }) => ({
|
||||
'& + i, & + svg': iconStyles(theme as Theme)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default select
|
||||
@@ -0,0 +1,100 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const slider: Theme['components'] = {
|
||||
MuiSlider: {
|
||||
styleOverrides: {
|
||||
root: ({ ownerState }) => ({
|
||||
boxSizing: 'border-box',
|
||||
...(ownerState.orientation === 'horizontal'
|
||||
? ownerState.size !== 'small'
|
||||
? { height: 6 }
|
||||
: { height: 4 }
|
||||
: ownerState.size !== 'small'
|
||||
? { width: 6 }
|
||||
: { width: 4 }),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: `var(--mui-palette-${ownerState.color}-main)`
|
||||
}
|
||||
}),
|
||||
thumb: ({ ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
height: 14,
|
||||
width: 14,
|
||||
border: '2px solid currentColor',
|
||||
'&:hover, &.Mui-focusVisible': {
|
||||
boxShadow: `0 0 0 7px var(--mui-palette-${ownerState.color}-lightOpacity)`
|
||||
},
|
||||
'&.Mui-active.Mui-focusVisible': {
|
||||
boxShadow: `0 0 0 10px var(--mui-palette-${ownerState.color}-lightOpacity)`
|
||||
}
|
||||
}
|
||||
: {
|
||||
height: 22,
|
||||
width: 22,
|
||||
border: '4px solid currentColor'
|
||||
}),
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
...(!ownerState.disabled && {
|
||||
boxShadow: 'var(--mui-customShadows-sm)'
|
||||
}),
|
||||
'&:before': {
|
||||
boxShadow: 'none'
|
||||
},
|
||||
'&:after': {
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
height: 28,
|
||||
width: 28
|
||||
}
|
||||
: {
|
||||
height: 38,
|
||||
width: 38
|
||||
})
|
||||
},
|
||||
'&:hover, &.Mui-focusVisible': {
|
||||
boxShadow: `0 0 0 8px var(--mui-palette-${ownerState.color}-lightOpacity)`
|
||||
},
|
||||
'&.Mui-active.Mui-focusVisible': {
|
||||
boxShadow: `0 0 0 13px var(--mui-palette-${ownerState.color}-lightOpacity)`
|
||||
}
|
||||
}),
|
||||
rail: ({ ownerState }) => ({
|
||||
opacity: 1,
|
||||
color: `var(--mui-palette-${ownerState.color}-lightOpacity)`,
|
||||
...(ownerState.track === 'inverted' && {
|
||||
backgroundColor: `var(--mui-palette-${ownerState.color}-main)`
|
||||
})
|
||||
}),
|
||||
valueLabel: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
...theme.typography.caption,
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)',
|
||||
padding: theme.spacing(1, 2)
|
||||
}
|
||||
: {
|
||||
...theme.typography.body2,
|
||||
fontWeight: theme.typography.fontWeightMedium,
|
||||
borderRadius: 'var(--mui-shape-borderRadius)',
|
||||
padding: theme.spacing(1, 2.5)
|
||||
}),
|
||||
color: 'var(--mui-palette-customColors-tooltipText)',
|
||||
backgroundColor: 'var(--mui-palette-Tooltip-bg)',
|
||||
'&:before': {
|
||||
display: 'none'
|
||||
}
|
||||
}),
|
||||
track: ({ theme, ownerState }) => ({
|
||||
...(ownerState.track === 'inverted' && {
|
||||
backgroundColor: `color-mix(in srgb, ${theme.palette[ownerState.color || 'primary'].main} 16%, var(--mui-palette-background-paper))`,
|
||||
borderColor: `color-mix(in srgb, ${theme.palette[ownerState.color || 'primary'].main} 16%, var(--mui-palette-background-paper))`
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default slider
|
||||
@@ -0,0 +1,27 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const snackbar = (skin: Skin): Theme['components'] => ({
|
||||
MuiSnackbarContent: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(0, 4),
|
||||
...(skin !== 'bordered'
|
||||
? {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
: {
|
||||
boxShadow: 'none'
|
||||
}),
|
||||
'& .MuiSnackbarContent-message': {
|
||||
paddingBlock: theme.spacing(3)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default snackbar
|
||||
@@ -0,0 +1,69 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const switchOverrides: Theme['components'] = {
|
||||
MuiSwitch: {
|
||||
defaultProps: {
|
||||
disableRipple: true
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
'&:has(.Mui-disabled)': {
|
||||
opacity: 0.45
|
||||
},
|
||||
...(ownerState.size !== 'small'
|
||||
? {
|
||||
width: 46,
|
||||
height: 36,
|
||||
padding: theme.spacing(2.25, 2)
|
||||
}
|
||||
: {
|
||||
width: 42,
|
||||
height: 30,
|
||||
padding: theme.spacing(1.75, 2),
|
||||
'& .MuiSwitch-thumb': {
|
||||
width: 12,
|
||||
height: 12
|
||||
},
|
||||
'& .MuiSwitch-switchBase': {
|
||||
padding: 7,
|
||||
left: 3,
|
||||
'&.Mui-checked': {
|
||||
left: -3
|
||||
}
|
||||
}
|
||||
})
|
||||
}),
|
||||
switchBase: {
|
||||
top: 2,
|
||||
left: 1,
|
||||
'&.Mui-checked': {
|
||||
left: -7,
|
||||
color: 'var(--mui-palette-common-white)',
|
||||
'& + .MuiSwitch-track': {
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
'&.Mui-disabled + .MuiSwitch-track': {
|
||||
opacity: 1
|
||||
},
|
||||
'&:hover:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'transparent'
|
||||
}
|
||||
},
|
||||
thumb: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
},
|
||||
track: {
|
||||
opacity: 1,
|
||||
borderRadius: 10,
|
||||
backgroundColor: 'var(--mui-palette-action-focus)',
|
||||
boxShadow: `0 0 4px rgb(0 0 0 / 0.16) inset`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default switchOverrides
|
||||
@@ -0,0 +1,42 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const tablePagination: Theme['components'] = {
|
||||
MuiTablePagination: {
|
||||
styleOverrides: {
|
||||
toolbar: ({ theme }) => ({
|
||||
paddingInlineEnd: `${theme.spacing(3)} !important`
|
||||
}),
|
||||
select: ({ theme }) => ({
|
||||
...theme.typography.body1,
|
||||
paddingInlineStart: 0,
|
||||
'& ~ i, & ~ svg': {
|
||||
fontSize: 20,
|
||||
right: '2px !important',
|
||||
color: 'var(--mui-palette-action-active)'
|
||||
}
|
||||
}),
|
||||
selectLabel: ({ theme }) => ({
|
||||
...theme.typography.body1,
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
}),
|
||||
input: ({ theme }) => ({
|
||||
marginInlineEnd: theme.spacing(6)
|
||||
}),
|
||||
displayedRows: ({ theme }) => ({
|
||||
...theme.typography.body1
|
||||
}),
|
||||
actions: ({ theme }) => ({
|
||||
marginInlineStart: theme.spacing(6),
|
||||
'& .Mui-disabled': {
|
||||
color: 'var(--mui-palette-action-active)'
|
||||
},
|
||||
'& .MuiIconButton-root:last-of-type': {
|
||||
marginInlineStart: theme.spacing(2)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default tablePagination
|
||||
@@ -0,0 +1,92 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const tabs: Theme['components'] = {
|
||||
MuiTabs: {
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
minBlockSize: 38,
|
||||
...(ownerState.orientation === 'horizontal'
|
||||
? {
|
||||
borderBlockEnd: '1px solid var(--mui-palette-divider)'
|
||||
}
|
||||
: {
|
||||
borderInlineEnd: '1px solid var(--mui-palette-divider)'
|
||||
}),
|
||||
'& .MuiTab-root:hover': {
|
||||
...(ownerState.orientation === 'horizontal'
|
||||
? {
|
||||
paddingBlockEnd: theme.spacing(1.5),
|
||||
...(ownerState.textColor === 'secondary'
|
||||
? {
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
borderBlockEnd: '2px solid var(--mui-palette-secondary-lightOpacity)'
|
||||
}
|
||||
: {
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
borderBlockEnd: '2px solid var(--mui-palette-primary-lightOpacity)'
|
||||
})
|
||||
}
|
||||
: {
|
||||
paddingInlineEnd: theme.spacing(5),
|
||||
...(ownerState.textColor === 'secondary'
|
||||
? {
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
borderInlineEnd: '2px solid var(--mui-palette-secondary-mainOpacity)'
|
||||
}
|
||||
: {
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
borderInlineEnd: '2px solid var(--mui-palette-primary-mainOpacity)'
|
||||
})
|
||||
}),
|
||||
'& .MuiTabScrollButton-root': {
|
||||
borderRadius: theme.shape.borderRadius
|
||||
}
|
||||
},
|
||||
'& ~ .MuiTabPanel-root': {
|
||||
...(ownerState.orientation === 'horizontal'
|
||||
? {
|
||||
paddingBlockStart: theme.spacing(5)
|
||||
}
|
||||
: {
|
||||
paddingInlineStart: theme.spacing(5)
|
||||
})
|
||||
}
|
||||
}),
|
||||
vertical: {
|
||||
minWidth: 131,
|
||||
'& .MuiTab-root': {
|
||||
minWidth: 130
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTab: {
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
lineHeight: 1.4667,
|
||||
padding: theme.spacing(2, 5.5),
|
||||
minBlockSize: 38,
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
'& > .MuiTab-iconWrapper': {
|
||||
fontSize: '1.125rem',
|
||||
...(ownerState.iconPosition === 'start' && {
|
||||
marginInlineEnd: theme.spacing(1.5)
|
||||
}),
|
||||
...(ownerState.iconPosition === 'end' && {
|
||||
marginInlineStart: theme.spacing(1.5)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiTabPanel: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default tabs
|
||||
@@ -0,0 +1,161 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const timeline: Theme['components'] = {
|
||||
MuiTimeline: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTimelineDot: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
margin: theme.spacing(3, 0),
|
||||
boxShadow: 'none',
|
||||
'&:has(> i), &:has(> svg)': {
|
||||
padding: 6
|
||||
},
|
||||
'& > svg, & > i': {
|
||||
fontSize: '1.25rem'
|
||||
},
|
||||
'&:has(svg)': {
|
||||
width: 32,
|
||||
height: 32,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'outlined' },
|
||||
style: {
|
||||
padding: 5,
|
||||
'& + .MuiTimelineConnector-root': {
|
||||
backgroundColor: 'transparent',
|
||||
borderInlineStart: '1px dashed var(--mui-palette-divider)'
|
||||
},
|
||||
'&:has(+ .MuiTimelineConnector-root)': {
|
||||
marginBlock: '0.625rem'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'grey' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px rgb(var(--mui-mainColorChannels-light) / 0.04)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'primary' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-primary-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'secondary' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-secondary-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'error' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-error-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'warning' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-warning-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'info' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-info-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'success' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-success-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal' },
|
||||
style: {
|
||||
border: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'grey' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-action-selected)',
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'primary' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'secondary' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-secondary-lightOpacity)',
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'error' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-error-lightOpacity)',
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'warning' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-warning-lightOpacity)',
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'info' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-info-lightOpacity)',
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'success' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-success-lightOpacity)',
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
MuiTimelineConnector: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
width: 1,
|
||||
backgroundColor: 'var(--mui-palette-divider)'
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTimelineContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
paddingBottom: '1rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default timeline
|
||||
@@ -0,0 +1,34 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const toggleButton: Theme['components'] = {
|
||||
MuiToggleButtonGroup: {
|
||||
styleOverrides: {
|
||||
root: ({ ownerState }) => ({
|
||||
...(ownerState.size === 'small' && {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)'
|
||||
}),
|
||||
...(ownerState.size === 'large' && {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-lg)'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiToggleButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:not(.Mui-selected):not(.Mui-disabled)': {
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
}
|
||||
},
|
||||
sizeSmall: {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)'
|
||||
},
|
||||
sizeLarge: {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-lg)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default toggleButton
|
||||
@@ -0,0 +1,32 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const tooltip: Theme['components'] = {
|
||||
MuiTooltip: {
|
||||
styleOverrides: {
|
||||
popper: {
|
||||
'&[data-popper-placement*="bottom"] .MuiTooltip-tooltip': {
|
||||
marginTop: '6px !important'
|
||||
},
|
||||
'&[data-popper-placement*="top"] .MuiTooltip-tooltip': {
|
||||
marginBottom: '6px !important'
|
||||
},
|
||||
'&[data-popper-placement*="left"] .MuiTooltip-tooltip': {
|
||||
marginRight: '6px !important'
|
||||
},
|
||||
'&[data-popper-placement*="right"] .MuiTooltip-tooltip': {
|
||||
marginLeft: '6px !important'
|
||||
}
|
||||
},
|
||||
tooltip: ({ theme }) => ({
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)',
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
lineHeight: 1.539,
|
||||
color: 'var(--mui-palette-customColors-tooltipText)',
|
||||
paddingInline: theme.spacing(3)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default tooltip
|
||||
@@ -0,0 +1,68 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const typography: Theme['components'] = {
|
||||
MuiTypography: {
|
||||
styleOverrides: {
|
||||
gutterBottom: ({ theme }) => ({
|
||||
marginBottom: theme.spacing(2)
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'h1' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h2' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h3' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h4' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h5' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h6' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'subtitle1' },
|
||||
style: { color: 'rgb(var(--mui-palette-text-primaryChannel) / 0.55)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'subtitle2' },
|
||||
style: { color: 'rgb(var(--mui-palette-text-primaryChannel) / 0.55)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'body1' },
|
||||
style: { color: 'var(--mui-palette-text-secondary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'body2' },
|
||||
style: { color: 'var(--mui-palette-text-secondary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'button' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'caption' },
|
||||
style: { color: 'var(--mui-palette-text-disabled)', display: 'inline-block' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'overline' },
|
||||
style: { color: 'var(--mui-palette-text-primary)', display: 'inline-block' }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default typography
|
||||
@@ -0,0 +1,39 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { SystemMode } from '@core/types'
|
||||
|
||||
const shadows = (mode: SystemMode): Theme['shadows'] => {
|
||||
const color = `var(--mui-mainColorChannels-${mode}Shadow)`
|
||||
|
||||
return [
|
||||
'none',
|
||||
`0px 2px 1px -1px rgb(${color} / 0.2),0px 1px 1px 0px rgb(${color} / 0.14),0px 1px 3px 0px rgb(${color} / 0.12)`,
|
||||
`0px 3px 1px -2px rgb(${color} / 0.2),0px 2px 2px 0px rgb(${color} / 0.14),0px 1px 5px 0px rgb(${color} / 0.12)`,
|
||||
`0px 3px 3px -2px rgb(${color} / 0.2),0px 3px 4px 0px rgb(${color} / 0.14),0px 1px 8px 0px rgb(${color} / 0.12)`,
|
||||
`0px 2px 4px -1px rgb(${color} / 0.2),0px 4px 5px 0px rgb(${color} / 0.14),0px 1px 10px 0px rgb(${color} / 0.12)`,
|
||||
`0px 3px 5px -1px rgb(${color} / 0.2),0px 5px 8px 0px rgb(${color} / 0.14),0px 1px 14px 0px rgb(${color} / 0.12)`,
|
||||
`0px 3px 5px -1px rgb(${color} / 0.2),0px 6px 10px 0px rgb(${color} / 0.14),0px 1px 18px 0px rgb(${color} / 0.12)`,
|
||||
`0px 4px 5px -2px rgb(${color} / 0.2),0px 7px 10px 1px rgb(${color} / 0.14),0px 2px 16px 1px rgb(${color} / 0.12)`,
|
||||
`0px 5px 5px -3px rgb(${color} / 0.2),0px 8px 10px 1px rgb(${color} / 0.14),0px 3px 14px 2px rgb(${color} / 0.12)`,
|
||||
`0px 5px 6px -3px rgb(${color} / 0.2),0px 9px 12px 1px rgb(${color} / 0.14),0px 3px 16px 2px rgb(${color} / 0.12)`,
|
||||
`0px 6px 6px -3px rgb(${color} / 0.2),0px 10px 14px 1px rgb(${color} / 0.14),0px 4px 18px 3px rgb(${color} / 0.12)`,
|
||||
`0px 6px 7px -4px rgb(${color} / 0.2),0px 11px 15px 1px rgb(${color} / 0.14),0px 4px 20px 3px rgb(${color} / 0.12)`,
|
||||
`0px 7px 8px -4px rgb(${color} / 0.2),0px 12px 17px 2px rgb(${color} / 0.14),0px 5px 22px 4px rgb(${color} / 0.12)`,
|
||||
`0px 7px 8px -4px rgb(${color} / 0.2),0px 13px 19px 2px rgb(${color} / 0.14),0px 5px 24px 4px rgb(${color} / 0.12)`,
|
||||
`0px 7px 9px -4px rgb(${color} / 0.2),0px 14px 21px 2px rgb(${color} / 0.14),0px 5px 26px 4px rgb(${color} / 0.12)`,
|
||||
`0px 8px 9px -5px rgb(${color} / 0.2),0px 15px 22px 2px rgb(${color} / 0.14),0px 6px 28px 5px rgb(${color} / 0.12)`,
|
||||
`0px 8px 10px -5px rgb(${color} / 0.2),0px 16px 24px 2px rgb(${color} / 0.14),0px 6px 30px 5px rgb(${color} / 0.12)`,
|
||||
`0px 8px 11px -5px rgb(${color} / 0.2),0px 17px 26px 2px rgb(${color} / 0.14),0px 6px 32px 5px rgb(${color} / 0.12)`,
|
||||
`0px 9px 11px -5px rgb(${color} / 0.2),0px 18px 28px 2px rgb(${color} / 0.14),0px 7px 34px 6px rgb(${color} / 0.12)`,
|
||||
`0px 9px 12px -6px rgb(${color} / 0.2),0px 19px 29px 2px rgb(${color} / 0.14),0px 7px 36px 6px rgb(${color} / 0.12)`,
|
||||
`0px 10px 13px -6px rgb(${color} / 0.2),0px 20px 31px 3px rgb(${color} / 0.14),0px 8px 38px 7px rgb(${color} / 0.12)`,
|
||||
`0px 10px 13px -6px rgb(${color} / 0.2),0px 21px 33px 3px rgb(${color} / 0.14),0px 8px 40px 7px rgb(${color} / 0.12)`,
|
||||
`0px 10px 14px -6px rgb(${color} / 0.2),0px 22px 35px 3px rgb(${color} / 0.14),0px 8px 42px 7px rgb(${color} / 0.12)`,
|
||||
`0px 11px 14px -7px rgb(${color} / 0.2),0px 23px 36px 3px rgb(${color} / 0.14),0px 9px 44px 8px rgb(${color} / 0.12)`,
|
||||
`0px 11px 15px -7px rgb(${color} / 0.2),0px 24px 38px 3px rgb(${color} / 0.14),0px 9px 46px 8px rgb(${color} / 0.12)`
|
||||
]
|
||||
}
|
||||
|
||||
export default shadows
|
||||
@@ -0,0 +1,5 @@
|
||||
const spacing = {
|
||||
spacing: (factor: number) => `${0.25 * factor}rem`
|
||||
}
|
||||
|
||||
export default spacing
|
||||
@@ -0,0 +1,88 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const typography = (fontFamily: string): Theme['typography'] =>
|
||||
({
|
||||
fontFamily:
|
||||
typeof fontFamily === 'undefined' || fontFamily === ''
|
||||
? [
|
||||
'Inter',
|
||||
'sans-serif',
|
||||
'-apple-system',
|
||||
'BlinkMacSystemFont',
|
||||
'"Segoe UI"',
|
||||
'Roboto',
|
||||
'"Helvetica Neue"',
|
||||
'Arial',
|
||||
'sans-serif',
|
||||
'"Apple Color Emoji"',
|
||||
'"Segoe UI Emoji"',
|
||||
'"Segoe UI Symbol"'
|
||||
].join(',')
|
||||
: fontFamily,
|
||||
fontSize: 13.125,
|
||||
h1: {
|
||||
fontSize: '2.875rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.478261
|
||||
},
|
||||
h2: {
|
||||
fontSize: '2.375rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.47368421
|
||||
},
|
||||
h3: {
|
||||
fontSize: '1.75rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.5
|
||||
},
|
||||
h4: {
|
||||
fontSize: '1.5rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.58334
|
||||
},
|
||||
h5: {
|
||||
fontSize: '1.125rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.5556
|
||||
},
|
||||
h6: {
|
||||
fontSize: '0.9375rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.46667
|
||||
},
|
||||
subtitle1: {
|
||||
fontSize: '0.9375rem',
|
||||
lineHeight: 1.46667
|
||||
},
|
||||
subtitle2: {
|
||||
fontSize: '0.8125rem',
|
||||
fontWeight: 400,
|
||||
lineHeight: 1.53846154
|
||||
},
|
||||
body1: {
|
||||
fontSize: '0.9375rem',
|
||||
lineHeight: 1.46667
|
||||
},
|
||||
body2: {
|
||||
fontSize: '0.8125rem',
|
||||
lineHeight: 1.53846154
|
||||
},
|
||||
button: {
|
||||
fontSize: '0.9375rem',
|
||||
lineHeight: 1.46667,
|
||||
textTransform: 'none'
|
||||
},
|
||||
caption: {
|
||||
fontSize: '0.8125rem',
|
||||
lineHeight: 1.38462,
|
||||
letterSpacing: '0.4px'
|
||||
},
|
||||
overline: {
|
||||
fontSize: '0.75rem',
|
||||
lineHeight: 1.16667,
|
||||
letterSpacing: '0.8px'
|
||||
}
|
||||
}) as Theme['typography']
|
||||
|
||||
export default typography
|
||||
@@ -0,0 +1,16 @@
|
||||
// React Imports
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
export type Skin = 'default' | 'bordered'
|
||||
|
||||
export type Mode = 'light' | 'dark'
|
||||
|
||||
export type SystemMode = 'light' | 'dark'
|
||||
|
||||
export type Direction = 'ltr' | 'rtl'
|
||||
|
||||
export type ChildrenType = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export type ThemeColor = 'primary' | 'secondary' | 'error' | 'warning' | 'info' | 'success'
|
||||
@@ -0,0 +1,18 @@
|
||||
export type SystemConfig = {
|
||||
id: string;
|
||||
sessionCleanupIntervalMinutes: number;
|
||||
invoiceGenerationDayOfMonth: number;
|
||||
tokenExpirationMinutes: number;
|
||||
tokenCleanupIntervalMinutes: number;
|
||||
profilePictureUpdateIntervalDays: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type UpdateSystemConfigDto = {
|
||||
sessionCleanupIntervalMinutes?: number;
|
||||
invoiceGenerationDayOfMonth?: number;
|
||||
tokenExpirationMinutes?: number;
|
||||
tokenCleanupIntervalMinutes?: number;
|
||||
profilePictureUpdateIntervalDays?: number;
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import 'server-only'
|
||||
|
||||
// Next Imports
|
||||
import { cookies } from 'next/headers'
|
||||
|
||||
// Type Imports
|
||||
import type { Settings } from '@core/contexts/settingsContext'
|
||||
import type { SystemMode } from '@core/types'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
export const getSettingsFromCookie = (): Settings => {
|
||||
const cookieStore = cookies()
|
||||
|
||||
const cookieName = themeConfig.settingsCookieName
|
||||
|
||||
return JSON.parse(cookieStore.get(cookieName)?.value || '{}')
|
||||
}
|
||||
|
||||
export const getMode = () => {
|
||||
const settingsCookie = getSettingsFromCookie()
|
||||
|
||||
// Get mode from cookie or fallback to theme config
|
||||
const _mode = settingsCookie.mode || themeConfig.mode
|
||||
|
||||
return _mode
|
||||
}
|
||||
|
||||
export const getSystemMode = (): SystemMode => {
|
||||
const mode = getMode()
|
||||
|
||||
return mode
|
||||
}
|
||||
|
||||
export const getServerMode = () => {
|
||||
const mode = getMode()
|
||||
|
||||
return mode
|
||||
}
|
||||
Reference in New Issue
Block a user