mirror of
https://github.com/D4M13N-D3V/comissions-app-ui.git
synced 2025-03-13 07:45:07 +00:00
feat: new templates
This commit is contained in:
parent
13bd42ecbd
commit
481bcd2d6c
@ -146,7 +146,7 @@ function AppAppBar({ user }: AppAppBarProps) {
|
||||
variant="contained"
|
||||
size="small"
|
||||
component="a"
|
||||
href="/api/auth/login"
|
||||
href="/dashboard"
|
||||
startIcon={<OpenInNew />}
|
||||
>
|
||||
Dashboard
|
||||
|
53
components/Old/artistDashboardRequest.tsx
Normal file
53
components/Old/artistDashboardRequest.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import * as React from 'react';
|
||||
import { useEffect, useState } from "react";
|
||||
import { Grid, Card, CardContent, Typography } from '@mui/material';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import Box from '@mui/material/Box';
|
||||
|
||||
|
||||
const ArtistDashboardRequest = () => {
|
||||
const [sellerRequestData, setSellerRequestData] = useState(null);
|
||||
|
||||
const getData = async () => {
|
||||
const response = await fetch('/api/artist/request');
|
||||
const sellerProfile = await response.json();
|
||||
setSellerRequestData(sellerProfile);
|
||||
}
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
|
||||
let formattedTime = ""
|
||||
if (sellerRequestData) {
|
||||
const date = new Date(sellerRequestData["requestDate"]);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
}
|
||||
|
||||
return (
|
||||
(sellerRequestData ? (
|
||||
|
||||
<Card sx={{ minWidth: 275 }}>
|
||||
<CardContent>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Request Status
|
||||
</Typography>
|
||||
{(sellerRequestData["accepted"] ? (
|
||||
<Typography variant="body2" color="text.warning" component="div">Accepted</Typography>
|
||||
) : (
|
||||
<Typography variant="h6" color="text.warning" component="div">Pending</Typography>
|
||||
))}
|
||||
<Typography variant="body2" color="text.secondary" component="div">Request submitted on {formattedTime ?? ''}</Typography>
|
||||
</CardContent>
|
||||
</Card>) : (
|
||||
|
||||
<Box sx={{textAlign:"center", paddingTop:"5%"}}>
|
||||
<Typography variant="h4" sx={{textAlign:"center"}}>
|
||||
Loading
|
||||
</Typography>
|
||||
<Box sx={{ paddingTop: 5 }} />
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
))
|
||||
)
|
||||
}
|
||||
export default ArtistDashboardRequest
|
@ -3,7 +3,7 @@ import {ImageList, Box, Typography, CircularProgress} from '@mui/material';
|
||||
import { useEffect, useState } from "react";
|
||||
import ArtistPortfolioImage from './artistPortfolioImage';
|
||||
|
||||
const ArtistPortfolio = ({artistId}) => {
|
||||
const ArtistPortfolio = ({masonry,columns,artistId}) => {
|
||||
const [portfolioData, setPortfolioData] = useState([]);
|
||||
const [loading, setLoading] = useState(true); // State for loading indicator
|
||||
useEffect(() => {
|
||||
@ -26,11 +26,19 @@ const ArtistPortfolio = ({artistId}) => {
|
||||
</Box>
|
||||
) :
|
||||
(
|
||||
<ImageList cols={2} rowHeight={200} sx={{maxHeight:400}}>
|
||||
(masonry) ? (
|
||||
<ImageList variant="masonry" gap={8} cols={columns} sx={{overflowY:"scroll", maxWidth:"100%"}} >
|
||||
{portfolioData.map((item) => (
|
||||
<ArtistPortfolioImage artistId={artistId} itemId={item.id} />
|
||||
))}
|
||||
</ImageList>
|
||||
):(
|
||||
<ImageList gap={8} cols={columns} >
|
||||
{portfolioData.map((item) => (
|
||||
<ArtistPortfolioImage artistId={artistId} itemId={item.id} />
|
||||
))}
|
||||
</ImageList>
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
@ -14,7 +14,7 @@ const ArtistPortfolioImage = ({artistId,itemId}) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<ImageListItem key={itemId }>
|
||||
<ImageListItem key={itemId } >
|
||||
<img
|
||||
srcSet={process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers/${artistId}/Portfolio/${itemId}`}
|
||||
src={process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers/${artistId}/Portfolio/${itemId}`}
|
@ -4,7 +4,6 @@ import { useEffect, useState } from "react";
|
||||
import EditableArtistPortfolioImage from './editableArtistPortfolioImage';
|
||||
import FileOpenIcon from '@mui/icons-material/FileOpen';
|
||||
import { Grid } from '@mui/material';
|
||||
|
||||
const EditableArtistPortfolio = ({ artistId }) => {
|
||||
const [portfolioData, setPortfolioData] = useState([]);
|
||||
const [loading, setLoading] = useState(true); // State for loading indicator
|
@ -1,5 +1,5 @@
|
||||
import Head from "next/head";
|
||||
import Header from "./header";
|
||||
import Header from "../header";
|
||||
|
||||
type LayoutProps = {
|
||||
user?: any;
|
218
components/Onboarding.tsx
Normal file
218
components/Onboarding.tsx
Normal file
@ -0,0 +1,218 @@
|
||||
import * as React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Stepper from '@mui/material/Stepper';
|
||||
import Step from '@mui/material/Step';
|
||||
import StepLabel from '@mui/material/StepLabel';
|
||||
import StepContent from '@mui/material/StepContent';
|
||||
import Button from '@mui/material/Button';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Grid from '@mui/material/Grid'
|
||||
import TextField from '@mui/material/TextField';
|
||||
import ArtistDashboardRequest from '../components/Old/artistDashboardRequest';
|
||||
import ArtistPortfolio from '../components/Old/artistPortfolio';
|
||||
import EditableArtistPortfolio from '../components/Old/editableArtistPortfolio';
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import CurrencyTextField from '@lupus-ai/mui-currency-textfield';
|
||||
import {Card, CardContent, CardHeader, Divider } from '@mui/material';
|
||||
|
||||
|
||||
const steps = [
|
||||
{
|
||||
label: 'Request Access As Artist',
|
||||
description: `In order to start selling your art on our platform, you need to request access. Please include links to your social media and tag or DM us on the platform (@RequestDotBox). We may reach out for further verification and examples of your work.`,
|
||||
},
|
||||
{
|
||||
label: 'Onboard On Stripe',
|
||||
description:
|
||||
'Our platform uses Stripe as a payment processor. You will be required to onboard with them with all of your payout information and business information.',
|
||||
},
|
||||
{
|
||||
label: 'Setup Your Portfolio',
|
||||
description: `This is where you can setup your initial portfolio. You can upload any image format file to your portfolio. It will be automatically displayed on your artist page. You can add and remove from this later.`,
|
||||
},
|
||||
];
|
||||
|
||||
export default function Onboarding() {
|
||||
const [activeStep, setActiveStep] = React.useState(0);
|
||||
const [sellerRequestData, setSellerRequestData] = React.useState(null);
|
||||
const [profileData, setSellerProfileData] = React.useState(null);
|
||||
const [isStripeOnboarded, setIsStripeOnboarded] = React.useState(false);
|
||||
const [onBoardUrl, setOnBoardUrl] = React.useState("");
|
||||
|
||||
|
||||
|
||||
const handleNext = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep - 1);
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setActiveStep(0);
|
||||
};
|
||||
|
||||
const getData = async () => {
|
||||
const onboardCheckRequest = await fetch('/api/artist/onboarded', { method: "GET" });
|
||||
const onboardCheckResponse = await onboardCheckRequest.json();
|
||||
setIsStripeOnboarded(onboardCheckResponse["onboarded"]);
|
||||
const onboardUrlRequest = await fetch('/api/artist/onboardurl', { method: "GET" });
|
||||
const onboardUrlResponse = await onboardUrlRequest.json();
|
||||
setOnBoardUrl(onboardUrlResponse["onboardUrl"]);
|
||||
const response = await fetch('/api/artist/request');
|
||||
const sellerRequest = await response.json();
|
||||
setSellerRequestData(sellerRequest);
|
||||
const profileResponse = await fetch('/api/artist/profile');
|
||||
const sellerProfile = await profileResponse.json();
|
||||
setSellerProfileData(sellerProfile);
|
||||
|
||||
setTimeout(getData, 5000); // Poll every 5 seconds (adjust as needed)
|
||||
}
|
||||
React.useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
|
||||
const requestButton = () => {
|
||||
fetch('/api/artist/newRequest').then((response) => {
|
||||
if (response.ok) {
|
||||
fetch('/api/artist/request').then((requestResponse) => {
|
||||
requestResponse.json().then((sellerRequest) => {
|
||||
setSellerRequestData(sellerRequest);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let formattedTime = ""
|
||||
if (sellerRequestData) {
|
||||
const date = new Date(sellerRequestData["requestDate"]);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
}
|
||||
|
||||
return (
|
||||
<Card sx={{ width:"100%", padding:"2%" }}>
|
||||
<Stepper activeStep={activeStep} orientation="vertical">
|
||||
{steps.map((step, index) => (
|
||||
<Step key={step.label}>
|
||||
<StepLabel
|
||||
optional={
|
||||
index === 2 ? (
|
||||
<Typography variant="caption">Last step</Typography>
|
||||
) : null
|
||||
}
|
||||
>
|
||||
{step.label}
|
||||
</StepLabel>
|
||||
{(index==0) ? (
|
||||
<StepContent>
|
||||
<Grid container >
|
||||
<Grid item xs={12} lg={12}>
|
||||
<Typography>{step.description}</Typography>
|
||||
</Grid>
|
||||
{(sellerRequestData && Object.keys(sellerRequestData).length>0) ? (
|
||||
<Grid item xs={12} lg={12} sx={{paddingTop:"2%"}}>
|
||||
<ArtistDashboardRequest/>
|
||||
</Grid>
|
||||
):(
|
||||
<Grid item xs={12} lg={12}>
|
||||
<TextField fullWidth rows={4} multiline label="Application Message" variant="outlined" />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
<Box sx={{ mb: 2 ,paddingTop:"2%"}}>
|
||||
<div>
|
||||
{(sellerRequestData && Object.keys(sellerRequestData).length>0) ? (
|
||||
(sellerRequestData["accepted"]) ? (
|
||||
<Button variant="contained" onClick={handleNext}>
|
||||
Continue
|
||||
</Button>
|
||||
) : (
|
||||
|
||||
<Button variant="contained" disabled>
|
||||
Request Pending
|
||||
</Button> )
|
||||
):
|
||||
(
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={requestButton}
|
||||
sx={{ mt: 1, mr: 1 }}
|
||||
>
|
||||
Request Access
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Box>
|
||||
</StepContent>
|
||||
): null}
|
||||
{(index==1) ? (
|
||||
<StepContent>
|
||||
<Grid container>
|
||||
<Grid item xs={12} lg={12}>
|
||||
<Typography>{step.description}</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<div>
|
||||
{isStripeOnboarded==true ? (
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleNext}
|
||||
sx={{ mt: 1, mr: 1 }}
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
):(
|
||||
|
||||
<Button
|
||||
color='success'
|
||||
variant="contained"
|
||||
href={onBoardUrl}
|
||||
sx={{ mt: 1, mr: 1 }}
|
||||
>
|
||||
ONBOARD WITH STRIPE
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Box>
|
||||
</StepContent>
|
||||
): null}
|
||||
{(index==2) ? (
|
||||
<StepContent>
|
||||
<Grid container>
|
||||
<Grid item xs={12} lg={12}>
|
||||
<Typography>{step.description}</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} lg={12}>
|
||||
<EditableArtistPortfolio artistId={profileData ? profileData["id"] : null}/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<div>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleNext}
|
||||
sx={{ mt: 1, mr: 1 }}
|
||||
>
|
||||
{index === steps.length - 1 ? 'Finish' : 'Continue'}
|
||||
</Button>
|
||||
</div>
|
||||
</Box>
|
||||
</StepContent>
|
||||
): null}
|
||||
</Step>
|
||||
))}
|
||||
</Stepper>
|
||||
{activeStep === steps.length && (
|
||||
<Paper square elevation={0} sx={{ p: 3 }}>
|
||||
<Typography>We are setting up your account please wait.</Typography>
|
||||
</Paper>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
33
components/Orders.tsx
Normal file
33
components/Orders.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import * as React from 'react';
|
||||
import { DataGrid, GridColDef, GridValueGetterParams } from '@mui/x-data-grid';
|
||||
import { Button } from '@mui/material';
|
||||
|
||||
const columns: GridColDef[] = [
|
||||
{ field: 'id', headerName: 'ID', width: 70 },
|
||||
{ field: 'artist', headerName: 'Artist', width: 130 },
|
||||
{ field: 'status', headerName: 'Status', width: 130 },
|
||||
{ field: 'action', headerName: 'Action', width: 180, renderCell: (params) => {
|
||||
return (<Button variant="outlined" color="primary" fullWidth>View More</Button>);
|
||||
}},
|
||||
];
|
||||
|
||||
const rows = [
|
||||
{ id: 1, artist:'Neroshi', status: 'Pending'},
|
||||
];
|
||||
|
||||
export default function Orders() {
|
||||
return (
|
||||
<div style={{ height: 400, width: '100%' }}>
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
initialState={{
|
||||
pagination: {
|
||||
paginationModel: { page: 0, pageSize: 5 },
|
||||
},
|
||||
}}
|
||||
pageSizeOptions={[5, 10]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { useEffect, useState } from "react";
|
||||
import { Grid, Card, CardContent, Typography } from '@mui/material';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import Box from '@mui/material/Box';
|
||||
|
||||
|
||||
const ArtistDashboardRequest = () => {
|
||||
const [sellerRequestData, setSellerRequestData] = useState(null);
|
||||
|
||||
const getData = async () => {
|
||||
const response = await fetch('/api/artist/profile');
|
||||
const sellerProfile = await response.json();
|
||||
setSellerRequestData(sellerProfile);
|
||||
}
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
|
||||
let formattedTime = ""
|
||||
if (sellerRequestData) {
|
||||
const date = new Date(sellerRequestData["requestDate"]);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
}
|
||||
|
||||
const requestButton = () => {
|
||||
fetch('/api/artist/newRequest').then((response) => {
|
||||
if (response.ok) {
|
||||
fetch('/api/artist/request').then((requestResponse) => {
|
||||
requestResponse.json().then((sellerRequest) => {
|
||||
setSellerRequestData(sellerRequest);
|
||||
getData();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
(sellerRequestData ? (
|
||||
<Grid item xs={12} sm={12} lg={4} sx={{ textAlign: "center" ,paddingTop:"1rem"}}>
|
||||
<Card sx={{ minWidth: 275 }}>
|
||||
<CardContent>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Request Status
|
||||
</Typography>
|
||||
{(sellerRequestData["accepted"] ? (
|
||||
<Typography variant="body2" color="text.warning" component="div">Accepted</Typography>
|
||||
) : (
|
||||
<Typography variant="h6" color="text.warning" component="div">Pending</Typography>
|
||||
))}
|
||||
<Typography variant="body2" color="text.secondary" component="div">Request submitted on {formattedTime ?? ''}</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>) : (
|
||||
|
||||
<Box sx={{textAlign:"center", paddingTop:"5%"}}>
|
||||
<Typography variant="h4" sx={{textAlign:"center"}}>
|
||||
Loading
|
||||
</Typography>
|
||||
<Box sx={{ paddingTop: 5 }} />
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
))
|
||||
)
|
||||
}
|
||||
export default ArtistDashboardRequest
|
36
configs/themeConfig.tsx
Normal file
36
configs/themeConfig.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
// ** MUI Imports
|
||||
import { PaletteMode } from '@mui/material'
|
||||
|
||||
// ** Types
|
||||
import { ContentWidth } from '../core/layouts/types'
|
||||
|
||||
type ThemeConfig = {
|
||||
mode: PaletteMode
|
||||
templateName: string
|
||||
routingLoader: boolean
|
||||
disableRipple: boolean
|
||||
navigationSize: number
|
||||
menuTextTruncate: boolean
|
||||
contentWidth: ContentWidth
|
||||
responsiveFontSizes: boolean
|
||||
}
|
||||
|
||||
const themeConfig: ThemeConfig = {
|
||||
// ** Layout Configs
|
||||
templateName: 'Request.Box' /* App Name */,
|
||||
mode: 'light' /* light | dark */,
|
||||
contentWidth: 'boxed' /* full | boxed */,
|
||||
|
||||
// ** Routing Configs
|
||||
routingLoader: true /* true | false */,
|
||||
|
||||
// ** Navigation (Menu) Configs
|
||||
menuTextTruncate: true /* true | false */,
|
||||
navigationSize: 260 /* Number in PX(Pixels) /*! Note: This is for Vertical navigation menu only */,
|
||||
|
||||
// ** Other Configs
|
||||
responsiveFontSizes: true /* true | false */,
|
||||
disableRipple: false /* true | false */
|
||||
}
|
||||
|
||||
export default themeConfig
|
@ -0,0 +1,54 @@
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Card from '@mui/material/Card'
|
||||
import Avatar from '@mui/material/Avatar'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
|
||||
// ** Icons Imports
|
||||
import DotsVertical from 'mdi-material-ui/DotsVertical'
|
||||
|
||||
// ** Types Imports
|
||||
import { CardStatsVerticalProps } from '../core/components/card-statistics/types'
|
||||
|
||||
const CardStatsVertical = (props: CardStatsVerticalProps) => {
|
||||
// ** Props
|
||||
const { title, subtitle, color, icon, stats, trend, trendNumber } = props
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Box sx={{ display: 'flex', marginBottom: 5.5, alignItems: 'flex-start', justifyContent: 'space-between' }}>
|
||||
<Avatar sx={{ boxShadow: 3, marginRight: 4, color: 'common.white', backgroundColor: `${color}.main` }}>
|
||||
{icon}
|
||||
</Avatar>
|
||||
<IconButton size='small' aria-label='settings' className='card-more-options' sx={{ color: 'text.secondary' }}>
|
||||
<DotsVertical />
|
||||
</IconButton>
|
||||
</Box>
|
||||
<Typography sx={{ fontWeight: 600, fontSize: '0.875rem' }}>{title}</Typography>
|
||||
<Box sx={{ marginTop: 1.5, display: 'flex', flexWrap: 'wrap', marginBottom: 1.5, alignItems: 'flex-start' }}>
|
||||
<Typography variant='h6' sx={{ mr: 2 }}>
|
||||
{stats}
|
||||
</Typography>
|
||||
<Typography
|
||||
component='sup'
|
||||
variant='caption'
|
||||
sx={{ color: trend === 'positive' ? 'success.main' : 'error.main' }}
|
||||
>
|
||||
{trendNumber}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Typography variant='caption'>{subtitle}</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default CardStatsVertical
|
||||
|
||||
CardStatsVertical.defaultProps = {
|
||||
color: 'primary',
|
||||
trend: 'positive'
|
||||
}
|
15
core/components/card-statistics/types.ts
Normal file
15
core/components/card-statistics/types.ts
Normal file
@ -0,0 +1,15 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** Types
|
||||
import { ThemeColor } from '../core/layouts/types'
|
||||
|
||||
export type CardStatsVerticalProps = {
|
||||
title: string
|
||||
stats: string
|
||||
icon: ReactNode
|
||||
subtitle: string
|
||||
color?: ThemeColor
|
||||
trendNumber: string
|
||||
trend?: 'positive' | 'negative'
|
||||
}
|
7
core/components/react-apexcharts/index.tsx
Normal file
7
core/components/react-apexcharts/index.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
// ** Next Import
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
// ! To avoid 'Window is not defined' error
|
||||
const ReactApexcharts = dynamic(() => import('react-apexcharts'), { ssr: false })
|
||||
|
||||
export default ReactApexcharts
|
47
core/components/scroll-to-top/index.tsx
Normal file
47
core/components/scroll-to-top/index.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Zoom from '@mui/material/Zoom'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import useScrollTrigger from '@mui/material/useScrollTrigger'
|
||||
|
||||
interface ScrollToTopProps {
|
||||
className?: string
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const ScrollToTopStyled = styled('div')(({ theme }) => ({
|
||||
zIndex: 11,
|
||||
position: 'fixed',
|
||||
right: theme.spacing(6),
|
||||
bottom: theme.spacing(10)
|
||||
}))
|
||||
|
||||
const ScrollToTop = (props: ScrollToTopProps) => {
|
||||
// ** Props
|
||||
const { children, className } = props
|
||||
|
||||
// ** init trigger
|
||||
const trigger = useScrollTrigger({
|
||||
threshold: 400,
|
||||
disableHysteresis: true
|
||||
})
|
||||
|
||||
const handleClick = () => {
|
||||
const anchor = document.querySelector('body')
|
||||
if (anchor) {
|
||||
anchor.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Zoom in={trigger}>
|
||||
<ScrollToTopStyled className={className} onClick={handleClick} role='presentation'>
|
||||
{children}
|
||||
</ScrollToTopStyled>
|
||||
</Zoom>
|
||||
)
|
||||
}
|
||||
|
||||
export default ScrollToTop
|
47
core/context/settingsContext.tsx
Normal file
47
core/context/settingsContext.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
// ** React Imports
|
||||
import { createContext, useState, ReactNode } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import { PaletteMode } from '@mui/material'
|
||||
|
||||
// ** ThemeConfig Import
|
||||
import themeConfig from '../../configs/themeConfig'
|
||||
|
||||
// ** Types Import
|
||||
import { ThemeColor, ContentWidth } from '../../core/layouts/types'
|
||||
|
||||
export type Settings = {
|
||||
mode: PaletteMode
|
||||
themeColor: ThemeColor
|
||||
contentWidth: ContentWidth
|
||||
}
|
||||
|
||||
export type SettingsContextValue = {
|
||||
settings: Settings
|
||||
saveSettings: (updatedSettings: Settings) => void
|
||||
}
|
||||
|
||||
const initialSettings: Settings = {
|
||||
themeColor: 'primary',
|
||||
mode: themeConfig.mode,
|
||||
contentWidth: themeConfig.contentWidth
|
||||
}
|
||||
|
||||
// ** Create Context
|
||||
export const SettingsContext = createContext<SettingsContextValue>({
|
||||
saveSettings: () => null,
|
||||
settings: initialSettings
|
||||
})
|
||||
|
||||
export const SettingsProvider = ({ children }: { children: ReactNode }) => {
|
||||
// ** State
|
||||
const [settings, setSettings] = useState<Settings>({ ...initialSettings })
|
||||
|
||||
const saveSettings = (updatedSettings: Settings) => {
|
||||
setSettings(updatedSettings)
|
||||
}
|
||||
|
||||
return <SettingsContext.Provider value={{ settings, saveSettings }}>{children}</SettingsContext.Provider>
|
||||
}
|
||||
|
||||
export const SettingsConsumer = SettingsContext.Consumer
|
4
core/hooks/useSettings.ts
Normal file
4
core/hooks/useSettings.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { useContext } from 'react'
|
||||
import { SettingsContext, SettingsContextValue } from '../../core/context/settingsContext'
|
||||
|
||||
export const useSettings = (): SettingsContextValue => useContext(SettingsContext)
|
40
core/layouts/BlankLayout.tsx
Normal file
40
core/layouts/BlankLayout.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
// ** MUI Imports
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Box, { BoxProps } from '@mui/material/Box'
|
||||
|
||||
// ** Types
|
||||
import { BlankLayoutProps } from './types'
|
||||
|
||||
// Styled component for Blank Layout component
|
||||
const BlankLayoutWrapper = styled(Box)<BoxProps>(({ theme }) => ({
|
||||
height: '100vh',
|
||||
|
||||
// For V1 Blank layout pages
|
||||
'& .content-center': {
|
||||
display: 'flex',
|
||||
minHeight: '100vh',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: theme.spacing(5)
|
||||
},
|
||||
|
||||
// For V2 Blank layout pages
|
||||
'& .content-right': {
|
||||
display: 'flex',
|
||||
minHeight: '100vh',
|
||||
overflowX: 'hidden',
|
||||
position: 'relative'
|
||||
}
|
||||
}))
|
||||
|
||||
const BlankLayout = ({ children }: BlankLayoutProps) => {
|
||||
return (
|
||||
<BlankLayoutWrapper className='layout-wrapper'>
|
||||
<Box className='app-content' sx={{ minHeight: '100vh', overflowX: 'hidden', position: 'relative' }}>
|
||||
{children}
|
||||
</Box>
|
||||
</BlankLayoutWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default BlankLayout
|
118
core/layouts/VerticalLayout.tsx
Normal file
118
core/layouts/VerticalLayout.tsx
Normal file
@ -0,0 +1,118 @@
|
||||
// ** React Imports
|
||||
import { useState } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Fab from '@mui/material/Fab'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Box, { BoxProps } from '@mui/material/Box'
|
||||
|
||||
// ** Icons Imports
|
||||
import ArrowUp from 'mdi-material-ui/ArrowUp'
|
||||
|
||||
// ** Theme Config Import
|
||||
import themeConfig from '../../configs/themeConfig'
|
||||
|
||||
// ** Type Import
|
||||
import { LayoutProps } from '../../core/layouts/types'
|
||||
|
||||
// ** Components
|
||||
import AppBar from './components/vertical/appBar'
|
||||
import Navigation from './components/vertical/navigation'
|
||||
import Footer from './components/shared-components/footer'
|
||||
import ScrollToTop from '../../core/components/scroll-to-top'
|
||||
|
||||
// ** Styled Component
|
||||
import DatePickerWrapper from '../../core/styles/libs/react-datepicker'
|
||||
|
||||
const VerticalLayoutWrapper = styled('div')({
|
||||
height: '100%',
|
||||
display: 'flex'
|
||||
})
|
||||
|
||||
const MainContentWrapper = styled(Box)<BoxProps>({
|
||||
flexGrow: 1,
|
||||
minWidth: 0,
|
||||
display: 'flex',
|
||||
minHeight: '100vh',
|
||||
flexDirection: 'column'
|
||||
})
|
||||
|
||||
const ContentWrapper = styled('main')(({ theme }) => ({
|
||||
flexGrow: 1,
|
||||
width: '100%',
|
||||
padding: theme.spacing(6),
|
||||
transition: 'padding .25s ease-in-out',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
paddingLeft: theme.spacing(4),
|
||||
paddingRight: theme.spacing(4)
|
||||
}
|
||||
}))
|
||||
|
||||
const VerticalLayout = (props: LayoutProps) => {
|
||||
// ** Props
|
||||
const { settings, children, scrollToTop } = props
|
||||
|
||||
// ** Vars
|
||||
const { contentWidth } = settings
|
||||
const navWidth = themeConfig.navigationSize
|
||||
|
||||
// ** States
|
||||
const [navVisible, setNavVisible] = useState<boolean>(false)
|
||||
|
||||
// ** Toggle Functions
|
||||
const toggleNavVisibility = () => setNavVisible(!navVisible)
|
||||
|
||||
return (
|
||||
<>
|
||||
<VerticalLayoutWrapper className='layout-wrapper'>
|
||||
{/* Navigation Menu */}
|
||||
<Navigation
|
||||
navWidth={navWidth}
|
||||
navVisible={navVisible}
|
||||
setNavVisible={setNavVisible}
|
||||
toggleNavVisibility={toggleNavVisibility}
|
||||
{...props}
|
||||
/>
|
||||
<MainContentWrapper className='layout-content-wrapper'>
|
||||
{/* AppBar Component */}
|
||||
<AppBar toggleNavVisibility={toggleNavVisibility} {...props} />
|
||||
|
||||
{/* Content */}
|
||||
<ContentWrapper
|
||||
className='layout-page-content'
|
||||
sx={{
|
||||
...(contentWidth === 'boxed' && {
|
||||
mx: 'auto',
|
||||
'@media (min-width:1440px)': { maxWidth: 1440 },
|
||||
'@media (min-width:1200px)': { maxWidth: '100%' }
|
||||
})
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ContentWrapper>
|
||||
|
||||
{/* Footer Component */}
|
||||
<Footer {...props} />
|
||||
|
||||
{/* Portal for React Datepicker */}
|
||||
<DatePickerWrapper sx={{ zIndex: 11 }}>
|
||||
<Box id='react-datepicker-portal'></Box>
|
||||
</DatePickerWrapper>
|
||||
</MainContentWrapper>
|
||||
</VerticalLayoutWrapper>
|
||||
|
||||
{/* Scroll to top button */}
|
||||
{scrollToTop ? (
|
||||
scrollToTop(props)
|
||||
) : (
|
||||
<ScrollToTop className='mui-fixed'>
|
||||
<Fab color='primary' size='small' aria-label='scroll back to top'>
|
||||
<ArrowUp />
|
||||
</Fab>
|
||||
</ScrollToTop>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerticalLayout
|
40
core/layouts/components/shared-components/ModeToggler.tsx
Normal file
40
core/layouts/components/shared-components/ModeToggler.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
// ** MUI Imports
|
||||
import { PaletteMode } from '@mui/material'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
|
||||
// ** Icons Imports
|
||||
import WeatherNight from 'mdi-material-ui/WeatherNight'
|
||||
import WeatherSunny from 'mdi-material-ui/WeatherSunny'
|
||||
|
||||
// ** Type Import
|
||||
import { Settings } from '../core/context/settingsContext'
|
||||
|
||||
interface Props {
|
||||
settings: Settings
|
||||
saveSettings: (values: Settings) => void
|
||||
}
|
||||
|
||||
const ModeToggler = (props: Props) => {
|
||||
// ** Props
|
||||
const { settings, saveSettings } = props
|
||||
|
||||
const handleModeChange = (mode: PaletteMode) => {
|
||||
saveSettings({ ...settings, mode })
|
||||
}
|
||||
|
||||
const handleModeToggle = () => {
|
||||
if (settings.mode === 'light') {
|
||||
handleModeChange('dark')
|
||||
} else {
|
||||
handleModeChange('light')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<IconButton color='inherit' aria-haspopup='true' onClick={handleModeToggle}>
|
||||
{settings.mode === 'dark' ? <WeatherSunny /> : <WeatherNight />}
|
||||
</IconButton>
|
||||
)
|
||||
}
|
||||
|
||||
export default ModeToggler
|
@ -0,0 +1,217 @@
|
||||
// ** React Imports
|
||||
import { useState, SyntheticEvent, Fragment, ReactNode } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Chip from '@mui/material/Chip'
|
||||
import Button from '@mui/material/Button'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import { styled, Theme } from '@mui/material/styles'
|
||||
import useMediaQuery from '@mui/material/useMediaQuery'
|
||||
import MuiMenu, { MenuProps } from '@mui/material/Menu'
|
||||
import MuiAvatar, { AvatarProps } from '@mui/material/Avatar'
|
||||
import MuiMenuItem, { MenuItemProps } from '@mui/material/MenuItem'
|
||||
import Typography, { TypographyProps } from '@mui/material/Typography'
|
||||
|
||||
// ** Icons Imports
|
||||
import BellOutline from 'mdi-material-ui/BellOutline'
|
||||
|
||||
// ** Third Party Components
|
||||
import PerfectScrollbarComponent from 'react-perfect-scrollbar'
|
||||
|
||||
// ** Styled Menu component
|
||||
const Menu = styled(MuiMenu)<MenuProps>(({ theme }) => ({
|
||||
'& .MuiMenu-paper': {
|
||||
width: 380,
|
||||
overflow: 'hidden',
|
||||
marginTop: theme.spacing(4),
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
width: '100%'
|
||||
}
|
||||
},
|
||||
'& .MuiMenu-list': {
|
||||
padding: 0
|
||||
}
|
||||
}))
|
||||
|
||||
// ** Styled MenuItem component
|
||||
const MenuItem = styled(MuiMenuItem)<MenuItemProps>(({ theme }) => ({
|
||||
paddingTop: theme.spacing(3),
|
||||
paddingBottom: theme.spacing(3),
|
||||
borderBottom: `1px solid ${theme.palette.divider}`
|
||||
}))
|
||||
|
||||
const styles = {
|
||||
maxHeight: 349,
|
||||
'& .MuiMenuItem-root:last-of-type': {
|
||||
border: 0
|
||||
}
|
||||
}
|
||||
|
||||
// ** Styled PerfectScrollbar component
|
||||
const PerfectScrollbar = styled(PerfectScrollbarComponent)({
|
||||
...styles
|
||||
})
|
||||
|
||||
// ** Styled Avatar component
|
||||
const Avatar = styled(MuiAvatar)<AvatarProps>({
|
||||
width: '2.375rem',
|
||||
height: '2.375rem',
|
||||
fontSize: '1.125rem'
|
||||
})
|
||||
|
||||
// ** Styled component for the title in MenuItems
|
||||
const MenuItemTitle = styled(Typography)<TypographyProps>(({ theme }) => ({
|
||||
fontWeight: 600,
|
||||
flex: '1 1 100%',
|
||||
overflow: 'hidden',
|
||||
fontSize: '0.875rem',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
marginBottom: theme.spacing(0.75)
|
||||
}))
|
||||
|
||||
// ** Styled component for the subtitle in MenuItems
|
||||
const MenuItemSubtitle = styled(Typography)<TypographyProps>({
|
||||
flex: '1 1 100%',
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis'
|
||||
})
|
||||
|
||||
const NotificationDropdown = () => {
|
||||
// ** States
|
||||
const [anchorEl, setAnchorEl] = useState<(EventTarget & Element) | null>(null)
|
||||
|
||||
// ** Hook
|
||||
const hidden = useMediaQuery((theme: Theme) => theme.breakpoints.down('lg'))
|
||||
|
||||
const handleDropdownOpen = (event: SyntheticEvent) => {
|
||||
setAnchorEl(event.currentTarget)
|
||||
}
|
||||
|
||||
const handleDropdownClose = () => {
|
||||
setAnchorEl(null)
|
||||
}
|
||||
|
||||
const ScrollWrapper = ({ children }: { children: ReactNode }) => {
|
||||
if (hidden) {
|
||||
return <Box sx={{ ...styles, overflowY: 'auto', overflowX: 'hidden' }}>{children}</Box>
|
||||
} else {
|
||||
return (
|
||||
<PerfectScrollbar options={{ wheelPropagation: false, suppressScrollX: true }}>{children}</PerfectScrollbar>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<IconButton color='inherit' aria-haspopup='true' onClick={handleDropdownOpen} aria-controls='customized-menu'>
|
||||
<BellOutline />
|
||||
</IconButton>
|
||||
<Menu
|
||||
anchorEl={anchorEl}
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={handleDropdownClose}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||
>
|
||||
<MenuItem disableRipple>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }}>
|
||||
<Typography sx={{ fontWeight: 600 }}>Notifications</Typography>
|
||||
<Chip
|
||||
size='small'
|
||||
label='8 New'
|
||||
color='primary'
|
||||
sx={{ height: 20, fontSize: '0.75rem', fontWeight: 500, borderRadius: '10px' }}
|
||||
/>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<ScrollWrapper>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<Avatar alt='Flora' src='/images/avatars/4.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>Congratulation Flora! 🎉</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>Won the monthly best seller badge</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
Today
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<Avatar sx={{ color: 'common.white', backgroundColor: 'primary.main' }}>VU</Avatar>
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>New user registered.</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>5 hours ago</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
Yesterday
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<Avatar alt='message' src='/images/avatars/5.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>New message received 👋🏻</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>You have 10 unread messages</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
11 Aug
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<img width={38} height={38} alt='paypal' src='/images/misc/paypal.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>Paypal</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>Received Payment</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
25 May
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<Avatar alt='order' src='/images/avatars/3.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>Revised Order 📦</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>New order revised from john</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
19 Mar
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<img width={38} height={38} alt='chart' src='/images/misc/chart.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>Finance report has been generated</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>25 hrs ago</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
27 Dec
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
</ScrollWrapper>
|
||||
<MenuItem
|
||||
disableRipple
|
||||
sx={{ py: 3.5, borderBottom: 0, borderTop: theme => `1px solid ${theme.palette.divider}` }}
|
||||
>
|
||||
<Button fullWidth variant='contained' onClick={handleDropdownClose}>
|
||||
Read All Notifications
|
||||
</Button>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default NotificationDropdown
|
162
core/layouts/components/shared-components/UserDropdown.tsx
Normal file
162
core/layouts/components/shared-components/UserDropdown.tsx
Normal file
@ -0,0 +1,162 @@
|
||||
// ** React Imports
|
||||
import { useState, SyntheticEvent, Fragment } from 'react'
|
||||
|
||||
// ** Next Import
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Menu from '@mui/material/Menu'
|
||||
import Badge from '@mui/material/Badge'
|
||||
import Avatar from '@mui/material/Avatar'
|
||||
import Divider from '@mui/material/Divider'
|
||||
import MenuItem from '@mui/material/MenuItem'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
|
||||
// ** Icons Imports
|
||||
import CogOutline from 'mdi-material-ui/CogOutline'
|
||||
import CurrencyUsd from 'mdi-material-ui/CurrencyUsd'
|
||||
import EmailOutline from 'mdi-material-ui/EmailOutline'
|
||||
import LogoutVariant from 'mdi-material-ui/LogoutVariant'
|
||||
import AccountOutline from 'mdi-material-ui/AccountOutline'
|
||||
import MessageOutline from 'mdi-material-ui/MessageOutline'
|
||||
import HelpCircleOutline from 'mdi-material-ui/HelpCircleOutline'
|
||||
|
||||
import { useUser } from '@auth0/nextjs-auth0/client'
|
||||
|
||||
// ** Styled Components
|
||||
const BadgeContentSpan = styled('span')(({ theme }) => ({
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: '50%',
|
||||
backgroundColor: theme.palette.success.main,
|
||||
boxShadow: `0 0 0 2px ${theme.palette.background.paper}`
|
||||
}))
|
||||
|
||||
const UserDropdown = () => {
|
||||
const { user, isLoading } = useUser();
|
||||
|
||||
// ** States
|
||||
const [anchorEl, setAnchorEl] = useState<Element | null>(null)
|
||||
|
||||
// ** Hooks
|
||||
const router = useRouter()
|
||||
|
||||
const handleDropdownOpen = (event: SyntheticEvent) => {
|
||||
setAnchorEl(event.currentTarget)
|
||||
}
|
||||
|
||||
const handleDropdownClose = (url?: string) => {
|
||||
if (url) {
|
||||
router.push(url)
|
||||
}
|
||||
setAnchorEl(null)
|
||||
}
|
||||
|
||||
const styles = {
|
||||
py: 2,
|
||||
px: 4,
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
color: 'text.primary',
|
||||
textDecoration: 'none',
|
||||
'& svg': {
|
||||
fontSize: '1.375rem',
|
||||
color: 'text.secondary'
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
(!isLoading && user) ? (
|
||||
<Fragment>
|
||||
<Badge
|
||||
overlap='circular'
|
||||
onClick={handleDropdownOpen}
|
||||
sx={{ ml: 2, cursor: 'pointer' }}
|
||||
badgeContent={<BadgeContentSpan />}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
>
|
||||
<Avatar
|
||||
alt={user.nickname}
|
||||
onClick={handleDropdownOpen}
|
||||
sx={{ width: 40, height: 40 }}
|
||||
src={user.picture}
|
||||
/>
|
||||
</Badge>
|
||||
<Menu
|
||||
anchorEl={anchorEl}
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={() => handleDropdownClose()}
|
||||
sx={{ '& .MuiMenu-paper': { width: 230, marginTop: 4 } }}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||
>
|
||||
<Box sx={{ pt: 2, pb: 3, px: 4 }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Badge
|
||||
overlap='circular'
|
||||
badgeContent={<BadgeContentSpan />}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
>
|
||||
<Avatar alt={user.nickname} src={user.picture} sx={{ width: '2.5rem', height: '2.5rem' }} />
|
||||
</Badge>
|
||||
<Box sx={{ display: 'flex', marginLeft: 3, alignItems: 'flex-start', flexDirection: 'column' }}>
|
||||
<Typography sx={{ fontWeight: 600 }}>{user.nickname}</Typography>
|
||||
<Typography variant='body2' sx={{ fontSize: '0.8rem', color: 'text.disabled' }}>
|
||||
Welcome back!
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
<Divider sx={{ mt: 0, mb: 1 }} />
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<AccountOutline sx={{ marginRight: 2 }} />
|
||||
Profile
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<EmailOutline sx={{ marginRight: 2 }} />
|
||||
Inbox
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<MessageOutline sx={{ marginRight: 2 }} />
|
||||
Chat
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<Divider />
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<CogOutline sx={{ marginRight: 2 }} />
|
||||
Settings
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<CurrencyUsd sx={{ marginRight: 2 }} />
|
||||
Pricing
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<HelpCircleOutline sx={{ marginRight: 2 }} />
|
||||
FAQ
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<Divider />
|
||||
<MenuItem sx={{ py: 2 }} onClick={() => handleDropdownClose('/api/auth/logout')}>
|
||||
<LogoutVariant sx={{ marginRight: 2, fontSize: '1.375rem', color: 'text.secondary' }} />
|
||||
Logout
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Fragment>
|
||||
): null
|
||||
)
|
||||
}
|
||||
|
||||
export default UserDropdown
|
@ -0,0 +1,18 @@
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Link from '@mui/material/Link'
|
||||
import { Theme } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import useMediaQuery from '@mui/material/useMediaQuery'
|
||||
|
||||
const FooterContent = () => {
|
||||
// ** Var
|
||||
const hidden = useMediaQuery((theme: Theme) => theme.breakpoints.down('md'))
|
||||
|
||||
return (
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default FooterContent
|
57
core/layouts/components/shared-components/footer/index.tsx
Normal file
57
core/layouts/components/shared-components/footer/index.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import { useTheme } from '@mui/material/styles'
|
||||
|
||||
// ** Type Import
|
||||
import { Settings } from '../core/context/settingsContext'
|
||||
|
||||
// ** Footer Content Component
|
||||
import FooterContent from './FooterContent'
|
||||
|
||||
interface Props {
|
||||
settings: Settings
|
||||
saveSettings: (values: Settings) => void
|
||||
footerContent?: (props?: any) => ReactNode
|
||||
}
|
||||
|
||||
const Footer = (props: Props) => {
|
||||
// ** Props
|
||||
const { settings, footerContent: userFooterContent } = props
|
||||
|
||||
// ** Hook
|
||||
const theme = useTheme()
|
||||
|
||||
// ** Vars
|
||||
const { contentWidth } = settings
|
||||
|
||||
return (
|
||||
<Box
|
||||
component='footer'
|
||||
className='layout-footer'
|
||||
sx={{
|
||||
zIndex: 10,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
className='footer-content-container'
|
||||
sx={{
|
||||
width: '100%',
|
||||
borderTopLeftRadius: 14,
|
||||
borderTopRightRadius: 14,
|
||||
padding: theme.spacing(4, 6),
|
||||
...(contentWidth === 'boxed' && { '@media (min-width:1440px)': { maxWidth: 1440 } })
|
||||
}}
|
||||
>
|
||||
{userFooterContent ? userFooterContent(props) : <FooterContent />}
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer
|
70
core/layouts/components/vertical/appBar/index.tsx
Normal file
70
core/layouts/components/vertical/appBar/index.tsx
Normal file
@ -0,0 +1,70 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import MuiAppBar, { AppBarProps } from '@mui/material/AppBar'
|
||||
import MuiToolbar, { ToolbarProps } from '@mui/material/Toolbar'
|
||||
|
||||
// ** Type Import
|
||||
import { Settings } from '../core/context/settingsContext'
|
||||
|
||||
interface Props {
|
||||
hidden: boolean
|
||||
settings: Settings
|
||||
toggleNavVisibility: () => void
|
||||
saveSettings: (values: Settings) => void
|
||||
verticalAppBarContent?: (props?: any) => ReactNode
|
||||
}
|
||||
|
||||
const AppBar = styled(MuiAppBar)<AppBarProps>(({ theme }) => ({
|
||||
transition: 'none',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: theme.spacing(0, 6),
|
||||
backgroundColor: 'transparent',
|
||||
color: theme.palette.text.primary,
|
||||
minHeight: theme.mixins.toolbar.minHeight,
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
paddingLeft: theme.spacing(4),
|
||||
paddingRight: theme.spacing(4)
|
||||
}
|
||||
}))
|
||||
|
||||
const Toolbar = styled(MuiToolbar)<ToolbarProps>(({ theme }) => ({
|
||||
width: '100%',
|
||||
borderBottomLeftRadius: 10,
|
||||
borderBottomRightRadius: 10,
|
||||
padding: `${theme.spacing(0)} !important`,
|
||||
minHeight: `${theme.mixins.toolbar.minHeight}px !important`,
|
||||
transition:
|
||||
'padding .25s ease-in-out, box-shadow .25s ease-in-out, backdrop-filter .25s ease-in-out, background-color .25s ease-in-out'
|
||||
}))
|
||||
|
||||
const LayoutAppBar = (props: Props) => {
|
||||
// ** Props
|
||||
const { settings, verticalAppBarContent: userVerticalAppBarContent } = props
|
||||
|
||||
// ** Hooks
|
||||
const theme = useTheme()
|
||||
|
||||
// ** Vars
|
||||
const { contentWidth } = settings
|
||||
|
||||
return (
|
||||
<AppBar elevation={0} color='default' className='layout-navbar' position='static'>
|
||||
<Toolbar
|
||||
className='navbar-content-container'
|
||||
sx={{
|
||||
...(contentWidth === 'boxed' && {
|
||||
'@media (min-width:1440px)': { maxWidth: `calc(1440px - ${theme.spacing(6)} * 2)` }
|
||||
})
|
||||
}}
|
||||
>
|
||||
{(userVerticalAppBarContent && userVerticalAppBarContent(props)) || null}
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
)
|
||||
}
|
||||
|
||||
export default LayoutAppBar
|
82
core/layouts/components/vertical/navigation/Drawer.tsx
Normal file
82
core/layouts/components/vertical/navigation/Drawer.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import MuiSwipeableDrawer, { SwipeableDrawerProps } from '@mui/material/SwipeableDrawer'
|
||||
|
||||
// ** Type Import
|
||||
import { Settings } from '../core/context/settingsContext'
|
||||
|
||||
interface Props {
|
||||
hidden: boolean
|
||||
navWidth: number
|
||||
settings: Settings
|
||||
navVisible: boolean
|
||||
children: ReactNode
|
||||
setNavVisible: (value: boolean) => void
|
||||
saveSettings: (values: Settings) => void
|
||||
}
|
||||
|
||||
const SwipeableDrawer = styled(MuiSwipeableDrawer)<SwipeableDrawerProps>({
|
||||
overflowX: 'hidden',
|
||||
transition: 'width .25s ease-in-out',
|
||||
'& ul': {
|
||||
listStyle: 'none'
|
||||
},
|
||||
'& .MuiListItem-gutters': {
|
||||
paddingLeft: 4,
|
||||
paddingRight: 4
|
||||
},
|
||||
'& .MuiDrawer-paper': {
|
||||
left: 'unset',
|
||||
right: 'unset',
|
||||
overflowX: 'hidden',
|
||||
transition: 'width .25s ease-in-out, box-shadow .25s ease-in-out'
|
||||
}
|
||||
})
|
||||
|
||||
const Drawer = (props: Props) => {
|
||||
// ** Props
|
||||
const { hidden, children, navWidth, navVisible, setNavVisible } = props
|
||||
|
||||
// ** Hook
|
||||
const theme = useTheme()
|
||||
|
||||
// Drawer Props for Mobile & Tablet screens
|
||||
const MobileDrawerProps = {
|
||||
open: navVisible,
|
||||
onOpen: () => setNavVisible(true),
|
||||
onClose: () => setNavVisible(false),
|
||||
ModalProps: {
|
||||
keepMounted: true // Better open performance on mobile.
|
||||
}
|
||||
}
|
||||
|
||||
// Drawer Props for Desktop screens
|
||||
const DesktopDrawerProps = {
|
||||
open: true,
|
||||
onOpen: () => null,
|
||||
onClose: () => null
|
||||
}
|
||||
|
||||
return (
|
||||
<SwipeableDrawer
|
||||
className='layout-vertical-nav'
|
||||
variant={hidden ? 'temporary' : 'permanent'}
|
||||
{...(hidden ? { ...MobileDrawerProps } : { ...DesktopDrawerProps })}
|
||||
PaperProps={{ sx: { width: navWidth } }}
|
||||
sx={{
|
||||
width: navWidth,
|
||||
'& .MuiDrawer-paper': {
|
||||
borderRight: 0,
|
||||
backgroundColor: theme.palette.background.default
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</SwipeableDrawer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Drawer
|
@ -0,0 +1,75 @@
|
||||
// ** React Import
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** Next Import
|
||||
import Link from 'next/link'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box, { BoxProps } from '@mui/material/Box'
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import Typography, { TypographyProps } from '@mui/material/Typography'
|
||||
|
||||
// ** Type Import
|
||||
import { Settings } from '../../../../../core/context/settingsContext'
|
||||
|
||||
// ** Configs
|
||||
import themeConfig from '../../../../../configs/themeConfig'
|
||||
|
||||
interface Props {
|
||||
hidden: boolean
|
||||
settings: Settings
|
||||
toggleNavVisibility: () => void
|
||||
saveSettings: (values: Settings) => void
|
||||
verticalNavMenuBranding?: (props?: any) => ReactNode
|
||||
}
|
||||
|
||||
// ** Styled Components
|
||||
const MenuHeaderWrapper = styled(Box)<BoxProps>(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingRight: theme.spacing(4.5),
|
||||
transition: 'padding .25s ease-in-out',
|
||||
minHeight: theme.mixins.toolbar.minHeight
|
||||
}))
|
||||
|
||||
const HeaderTitle = styled(Typography)<TypographyProps>(({ theme }) => ({
|
||||
fontWeight: 600,
|
||||
lineHeight: 'normal',
|
||||
textTransform: 'uppercase',
|
||||
color: theme.palette.text.primary,
|
||||
transition: 'opacity .25s ease-in-out, margin .25s ease-in-out'
|
||||
}))
|
||||
|
||||
const StyledLink = styled('a')({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
textDecoration: 'none'
|
||||
})
|
||||
|
||||
const VerticalNavHeader = (props: Props) => {
|
||||
// ** Props
|
||||
const { verticalNavMenuBranding: userVerticalNavMenuBranding } = props
|
||||
|
||||
// ** Hooks
|
||||
const theme = useTheme()
|
||||
|
||||
return (
|
||||
<MenuHeaderWrapper className='nav-header' sx={{ pl: 6 }}>
|
||||
{userVerticalNavMenuBranding ? (
|
||||
userVerticalNavMenuBranding(props)
|
||||
) : (
|
||||
<Link href='/' passHref>
|
||||
<StyledLink>
|
||||
<img width={30} height={25} src= "https://s6.imgcdn.dev/ttLwl.png"/>
|
||||
<HeaderTitle variant='h6' sx={{ ml: 3 }}>
|
||||
{themeConfig.templateName}
|
||||
</HeaderTitle>
|
||||
</StyledLink>
|
||||
</Link>
|
||||
)}
|
||||
</MenuHeaderWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerticalNavHeader
|
@ -0,0 +1,39 @@
|
||||
// ** Types Import
|
||||
import { Settings } from '../core/context/settingsContext'
|
||||
import { NavLink, NavSectionTitle, VerticalNavItemsType } from '../core/layouts/types'
|
||||
|
||||
// ** Custom Menu Components
|
||||
import VerticalNavLink from './VerticalNavLink'
|
||||
import VerticalNavSectionTitle from './VerticalNavSectionTitle'
|
||||
|
||||
interface Props {
|
||||
settings: Settings
|
||||
navVisible?: boolean
|
||||
groupActive: string[]
|
||||
currentActiveGroup: string[]
|
||||
verticalNavItems?: VerticalNavItemsType
|
||||
saveSettings: (values: Settings) => void
|
||||
setGroupActive: (value: string[]) => void
|
||||
setCurrentActiveGroup: (item: string[]) => void
|
||||
}
|
||||
|
||||
const resolveNavItemComponent = (item: NavLink | NavSectionTitle) => {
|
||||
if ((item as NavSectionTitle).sectionTitle) return VerticalNavSectionTitle
|
||||
|
||||
return VerticalNavLink
|
||||
}
|
||||
|
||||
const VerticalNavItems = (props: Props) => {
|
||||
// ** Props
|
||||
const { verticalNavItems } = props
|
||||
|
||||
const RenderMenuItems = verticalNavItems?.map((item: NavLink | NavSectionTitle, index: number) => {
|
||||
const TagName: any = resolveNavItemComponent(item)
|
||||
|
||||
return <TagName {...props} key={index} item={item} />
|
||||
})
|
||||
|
||||
return <>{RenderMenuItems}</>
|
||||
}
|
||||
|
||||
export default VerticalNavItems
|
136
core/layouts/components/vertical/navigation/VerticalNavLink.tsx
Normal file
136
core/layouts/components/vertical/navigation/VerticalNavLink.tsx
Normal file
@ -0,0 +1,136 @@
|
||||
// ** React Imports
|
||||
import { ElementType, ReactNode } from 'react'
|
||||
|
||||
// ** Next Imports
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
// ** MUI Imports
|
||||
import Chip from '@mui/material/Chip'
|
||||
import ListItem from '@mui/material/ListItem'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import Box, { BoxProps } from '@mui/material/Box'
|
||||
import ListItemIcon from '@mui/material/ListItemIcon'
|
||||
import ListItemButton, { ListItemButtonProps } from '@mui/material/ListItemButton'
|
||||
|
||||
// ** Configs Import
|
||||
import themeConfig from '../../../../../configs/themeConfig'
|
||||
|
||||
// ** Types
|
||||
import { NavLink } from '../../../../../core/layouts/types'
|
||||
import { Settings } from '../../../../../core/context/settingsContext'
|
||||
|
||||
// ** Custom Components Imports
|
||||
import UserIcon from '../../../../../layouts/components/UserIcon'
|
||||
|
||||
// ** Utils
|
||||
import { handleURLQueries } from '../../../../../core/layouts/utils'
|
||||
|
||||
interface Props {
|
||||
item: NavLink
|
||||
settings: Settings
|
||||
navVisible?: boolean
|
||||
toggleNavVisibility: () => void
|
||||
}
|
||||
|
||||
// ** Styled Components
|
||||
const MenuNavLink = styled(ListItemButton)<
|
||||
ListItemButtonProps & { component?: ElementType; target?: '_blank' | undefined }
|
||||
>(({ theme }) => ({
|
||||
width: '100%',
|
||||
borderTopRightRadius: 100,
|
||||
borderBottomRightRadius: 100,
|
||||
color: theme.palette.text.primary,
|
||||
padding: theme.spacing(2.25, 3.5),
|
||||
transition: 'opacity .25s ease-in-out',
|
||||
'&.active, &.active:hover': {
|
||||
boxShadow: theme.shadows[3],
|
||||
backgroundImage: `linear-gradient(98deg, ${theme.palette.customColors.primaryGradient}, ${theme.palette.primary.main} 94%)`
|
||||
},
|
||||
'&.active .MuiTypography-root, &.active .MuiSvgIcon-root': {
|
||||
color: `${theme.palette.common.white} !important`
|
||||
}
|
||||
}))
|
||||
|
||||
const MenuItemTextMetaWrapper = styled(Box)<BoxProps>({
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
transition: 'opacity .25s ease-in-out',
|
||||
...(themeConfig.menuTextTruncate && { overflow: 'hidden' })
|
||||
})
|
||||
|
||||
const VerticalNavLink = ({ item, navVisible, toggleNavVisibility }: Props) => {
|
||||
// ** Hooks
|
||||
const router = useRouter()
|
||||
|
||||
const IconTag: ReactNode = item.icon
|
||||
|
||||
const isNavLinkActive = () => {
|
||||
if (router.pathname === item.path || handleURLQueries(router, item.path)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
disablePadding
|
||||
className='nav-link'
|
||||
disabled={item.disabled || false}
|
||||
sx={{ mt: 1.5, px: '0 !important' }}
|
||||
>
|
||||
<Link passHref href={item.path === undefined ? '/' : `${item.path}`}>
|
||||
<MenuNavLink
|
||||
component={'a'}
|
||||
className={isNavLinkActive() ? 'active' : ''}
|
||||
{...(item.openInNewTab ? { target: '_blank' } : null)}
|
||||
onClick={e => {
|
||||
if (item.path === undefined) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
if (navVisible) {
|
||||
toggleNavVisibility()
|
||||
}
|
||||
}}
|
||||
sx={{
|
||||
pl: 5.5,
|
||||
...(item.disabled ? { pointerEvents: 'none' } : { cursor: 'pointer' })
|
||||
}}
|
||||
>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
mr: 2.5,
|
||||
color: 'text.primary',
|
||||
transition: 'margin .25s ease-in-out'
|
||||
}}
|
||||
>
|
||||
<UserIcon icon={IconTag} />
|
||||
</ListItemIcon>
|
||||
|
||||
<MenuItemTextMetaWrapper>
|
||||
<Typography {...(themeConfig.menuTextTruncate && { noWrap: true })}>{item.title}</Typography>
|
||||
{item.badgeContent ? (
|
||||
<Chip
|
||||
label={item.badgeContent}
|
||||
color={item.badgeColor || 'primary'}
|
||||
sx={{
|
||||
height: 20,
|
||||
fontWeight: 500,
|
||||
marginLeft: 1.25,
|
||||
'& .MuiChip-label': { px: 1.5, textTransform: 'capitalize' }
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</MenuItemTextMetaWrapper>
|
||||
</MenuNavLink>
|
||||
</Link>
|
||||
</ListItem>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerticalNavLink
|
@ -0,0 +1,72 @@
|
||||
// ** MUI Imports
|
||||
import Divider from '@mui/material/Divider'
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import Typography, { TypographyProps } from '@mui/material/Typography'
|
||||
import MuiListSubheader, { ListSubheaderProps } from '@mui/material/ListSubheader'
|
||||
|
||||
// ** Types
|
||||
import { NavSectionTitle } from '../core/layouts/types'
|
||||
|
||||
interface Props {
|
||||
item: NavSectionTitle
|
||||
}
|
||||
|
||||
// ** Styled Components
|
||||
const ListSubheader = styled((props: ListSubheaderProps) => <MuiListSubheader component='li' {...props} />)(
|
||||
({ theme }) => ({
|
||||
lineHeight: 1,
|
||||
display: 'flex',
|
||||
position: 'relative',
|
||||
marginTop: theme.spacing(7),
|
||||
marginBottom: theme.spacing(2),
|
||||
backgroundColor: 'transparent',
|
||||
transition: 'padding-left .25s ease-in-out'
|
||||
})
|
||||
)
|
||||
|
||||
const TypographyHeaderText = styled(Typography)<TypographyProps>(({ theme }) => ({
|
||||
fontSize: '0.75rem',
|
||||
lineHeight: 'normal',
|
||||
letterSpacing: '0.21px',
|
||||
textTransform: 'uppercase',
|
||||
color: theme.palette.text.disabled,
|
||||
fontWeight: theme.typography.fontWeightMedium
|
||||
}))
|
||||
|
||||
const VerticalNavSectionTitle = (props: Props) => {
|
||||
// ** Props
|
||||
const { item } = props
|
||||
|
||||
// ** Hook
|
||||
const theme = useTheme()
|
||||
|
||||
return (
|
||||
<ListSubheader
|
||||
className='nav-section-title'
|
||||
sx={{
|
||||
px: 0,
|
||||
py: 1.75,
|
||||
color: theme.palette.text.disabled,
|
||||
'& .MuiDivider-root:before, & .MuiDivider-root:after, & hr': {
|
||||
borderColor: `rgba(${theme.palette.customColors.main}, 0.12)`
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Divider
|
||||
textAlign='left'
|
||||
sx={{
|
||||
m: 0,
|
||||
width: '100%',
|
||||
lineHeight: 'normal',
|
||||
textTransform: 'uppercase',
|
||||
'&:before, &:after': { top: 7, transform: 'none' },
|
||||
'& .MuiDivider-wrapper': { px: 2.5, fontSize: '0.75rem', letterSpacing: '0.21px' }
|
||||
}}
|
||||
>
|
||||
<TypographyHeaderText noWrap>{item.sectionTitle}</TypographyHeaderText>
|
||||
</Divider>
|
||||
</ListSubheader>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerticalNavSectionTitle
|
153
core/layouts/components/vertical/navigation/index.tsx
Normal file
153
core/layouts/components/vertical/navigation/index.tsx
Normal file
@ -0,0 +1,153 @@
|
||||
// ** React Import
|
||||
import { ReactNode, useRef, useState } from 'react'
|
||||
|
||||
// ** MUI Import
|
||||
import List from '@mui/material/List'
|
||||
import Box, { BoxProps } from '@mui/material/Box'
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
|
||||
// ** Third Party Components
|
||||
import PerfectScrollbar from 'react-perfect-scrollbar'
|
||||
|
||||
// ** Type Import
|
||||
import { Settings } from '../../../../../core/context/settingsContext'
|
||||
import { VerticalNavItemsType } from '../../../../../core/layouts/types'
|
||||
|
||||
// ** Component Imports
|
||||
import Drawer from './Drawer'
|
||||
import VerticalNavItems from './VerticalNavItems'
|
||||
import VerticalNavHeader from './VerticalNavHeader'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from '../../../../../core/utils/hex-to-rgba'
|
||||
|
||||
interface Props {
|
||||
hidden: boolean
|
||||
navWidth: number
|
||||
settings: Settings
|
||||
children: ReactNode
|
||||
navVisible: boolean
|
||||
toggleNavVisibility: () => void
|
||||
setNavVisible: (value: boolean) => void
|
||||
verticalNavItems?: VerticalNavItemsType
|
||||
saveSettings: (values: Settings) => void
|
||||
verticalNavMenuContent?: (props?: any) => ReactNode
|
||||
afterVerticalNavMenuContent?: (props?: any) => ReactNode
|
||||
beforeVerticalNavMenuContent?: (props?: any) => ReactNode
|
||||
}
|
||||
|
||||
const StyledBoxForShadow = styled(Box)<BoxProps>({
|
||||
top: 50,
|
||||
left: -8,
|
||||
zIndex: 2,
|
||||
height: 75,
|
||||
display: 'none',
|
||||
position: 'absolute',
|
||||
pointerEvents: 'none',
|
||||
width: 'calc(100% + 15px)',
|
||||
'&.d-block': {
|
||||
display: 'block'
|
||||
}
|
||||
})
|
||||
|
||||
const Navigation = (props: Props) => {
|
||||
// ** Props
|
||||
const {
|
||||
hidden,
|
||||
afterVerticalNavMenuContent,
|
||||
beforeVerticalNavMenuContent,
|
||||
verticalNavMenuContent: userVerticalNavMenuContent
|
||||
} = props
|
||||
|
||||
// ** States
|
||||
const [groupActive, setGroupActive] = useState<string[]>([])
|
||||
const [currentActiveGroup, setCurrentActiveGroup] = useState<string[]>([])
|
||||
|
||||
// ** Ref
|
||||
const shadowRef = useRef(null)
|
||||
|
||||
// ** Hooks
|
||||
const theme = useTheme()
|
||||
|
||||
// ** Fixes Navigation InfiniteScroll
|
||||
const handleInfiniteScroll = (ref: HTMLElement) => {
|
||||
if (ref) {
|
||||
// @ts-ignore
|
||||
ref._getBoundingClientRect = ref.getBoundingClientRect
|
||||
|
||||
ref.getBoundingClientRect = () => {
|
||||
// @ts-ignore
|
||||
const original = ref._getBoundingClientRect()
|
||||
|
||||
return { ...original, height: Math.floor(original.height) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ** Scroll Menu
|
||||
const scrollMenu = (container: any) => {
|
||||
container = hidden ? container.target : container
|
||||
if (shadowRef && container.scrollTop > 0) {
|
||||
// @ts-ignore
|
||||
if (!shadowRef.current.classList.contains('d-block')) {
|
||||
// @ts-ignore
|
||||
shadowRef.current.classList.add('d-block')
|
||||
}
|
||||
} else {
|
||||
// @ts-ignore
|
||||
shadowRef.current.classList.remove('d-block')
|
||||
}
|
||||
}
|
||||
|
||||
const ScrollWrapper = hidden ? Box : PerfectScrollbar
|
||||
|
||||
return (
|
||||
<Drawer {...props}>
|
||||
<VerticalNavHeader {...props} />
|
||||
<StyledBoxForShadow
|
||||
ref={shadowRef}
|
||||
sx={{
|
||||
background: `linear-gradient(${theme.palette.background.default} 40%,${hexToRGBA(
|
||||
theme.palette.background.default,
|
||||
0.1
|
||||
)} 95%,${hexToRGBA(theme.palette.background.default, 0.05)})`
|
||||
}}
|
||||
/>
|
||||
<Box sx={{ height: '100%', position: 'relative', overflow: 'hidden' }}>
|
||||
{/* @ts-ignore */}
|
||||
<ScrollWrapper
|
||||
{...(hidden
|
||||
? {
|
||||
onScroll: (container: any) => scrollMenu(container),
|
||||
sx: { height: '100%', overflowY: 'auto', overflowX: 'hidden' }
|
||||
}
|
||||
: {
|
||||
options: { wheelPropagation: false },
|
||||
onScrollY: (container: any) => scrollMenu(container),
|
||||
containerRef: (ref: any) => handleInfiniteScroll(ref)
|
||||
})}
|
||||
>
|
||||
{beforeVerticalNavMenuContent ? beforeVerticalNavMenuContent(props) : null}
|
||||
<Box sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
|
||||
{userVerticalNavMenuContent ? (
|
||||
userVerticalNavMenuContent(props)
|
||||
) : (
|
||||
<List className='nav-items' sx={{ transition: 'padding .25s ease', pr: 4.5 }}>
|
||||
<VerticalNavItems
|
||||
groupActive={groupActive}
|
||||
setGroupActive={setGroupActive}
|
||||
currentActiveGroup={currentActiveGroup}
|
||||
setCurrentActiveGroup={setCurrentActiveGroup}
|
||||
{...props}
|
||||
/>
|
||||
</List>
|
||||
)}
|
||||
</Box>
|
||||
</ScrollWrapper>
|
||||
</Box>
|
||||
{afterVerticalNavMenuContent ? afterVerticalNavMenuContent(props) : null}
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Navigation
|
46
core/layouts/types.ts
Normal file
46
core/layouts/types.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { ReactNode } from 'react'
|
||||
import { Settings } from '../core/context/settingsContext'
|
||||
|
||||
export type ContentWidth = 'full' | 'boxed'
|
||||
|
||||
export type ThemeColor = 'primary' | 'secondary' | 'error' | 'warning' | 'info' | 'success'
|
||||
|
||||
export type NavLink = {
|
||||
path?: string
|
||||
title: string
|
||||
action?: string
|
||||
subject?: string
|
||||
disabled?: boolean
|
||||
badgeContent?: string
|
||||
externalLink?: boolean
|
||||
openInNewTab?: boolean
|
||||
icon?: string | string[] | ReactNode
|
||||
badgeColor?: 'default' | 'primary' | 'secondary' | 'success' | 'error' | 'warning' | 'info'
|
||||
}
|
||||
|
||||
export type NavSectionTitle = {
|
||||
sectionTitle: string
|
||||
action?: string
|
||||
subject?: string
|
||||
}
|
||||
|
||||
export type VerticalNavItemsType = (NavLink | NavSectionTitle)[]
|
||||
|
||||
export type LayoutProps = {
|
||||
hidden: boolean
|
||||
settings: Settings
|
||||
children: ReactNode
|
||||
verticalNavItems?: VerticalNavItemsType
|
||||
scrollToTop?: (props?: any) => ReactNode
|
||||
saveSettings: (values: Settings) => void
|
||||
footerContent?: (props?: any) => ReactNode
|
||||
verticalAppBarContent?: (props?: any) => ReactNode
|
||||
verticalNavMenuContent?: (props?: any) => ReactNode
|
||||
verticalNavMenuBranding?: (props?: any) => ReactNode
|
||||
afterVerticalNavMenuContent?: (props?: any) => ReactNode
|
||||
beforeVerticalNavMenuContent?: (props?: any) => ReactNode
|
||||
}
|
||||
|
||||
export type BlankLayoutProps = {
|
||||
children: ReactNode
|
||||
}
|
19
core/layouts/utils.ts
Normal file
19
core/layouts/utils.ts
Normal file
@ -0,0 +1,19 @@
|
||||
// ** Types
|
||||
import { NextRouter } from 'next/router'
|
||||
|
||||
/**
|
||||
* Check for URL queries as well for matching
|
||||
* Current URL & Item Path
|
||||
*
|
||||
* @param item
|
||||
* @param activeItem
|
||||
*/
|
||||
export const handleURLQueries = (router: NextRouter, path: string | undefined): boolean => {
|
||||
if (Object.keys(router.query).length && path) {
|
||||
const arr = Object.keys(router.query)
|
||||
|
||||
return router.asPath.includes(path) && router.asPath.includes(router.query[arr[0]] as string) && path !== '/'
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
103
core/styles/libs/react-apexcharts/index.ts
Normal file
103
core/styles/libs/react-apexcharts/index.ts
Normal file
@ -0,0 +1,103 @@
|
||||
// ** MUI imports
|
||||
import { styled } from '@mui/material/styles'
|
||||
|
||||
const ApexChartWrapper = styled('div')(({ theme }) => ({
|
||||
'& .apexcharts-canvas': {
|
||||
"& line[stroke='transparent']": {
|
||||
display: 'none'
|
||||
},
|
||||
'& .apexcharts-xaxis > line, & .apexcharts-yaxis > line': {
|
||||
stroke: theme.palette.divider
|
||||
},
|
||||
'& .apexcharts-xaxis-tick, & .apexcharts-yaxis-tick': {
|
||||
stroke: theme.palette.divider
|
||||
},
|
||||
'& .apexcharts-tooltip': {
|
||||
boxShadow: theme.shadows[3],
|
||||
borderColor: theme.palette.divider,
|
||||
background: theme.palette.background.paper,
|
||||
'& .apexcharts-tooltip-title': {
|
||||
fontWeight: 600,
|
||||
borderColor: theme.palette.divider,
|
||||
background: theme.palette.background.paper
|
||||
},
|
||||
'&.apexcharts-theme-dark': {
|
||||
'& .apexcharts-tooltip-text-label, & .apexcharts-tooltip-text-value': {
|
||||
color: theme.palette.common.white
|
||||
}
|
||||
},
|
||||
'& .bar-chart': {
|
||||
padding: theme.spacing(2, 2.5)
|
||||
}
|
||||
},
|
||||
'& .apexcharts-xaxistooltip': {
|
||||
borderColor: theme.palette.divider,
|
||||
background: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default,
|
||||
'& .apexcharts-xaxistooltip-text': {
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'&:after': {
|
||||
borderBottomColor: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default
|
||||
},
|
||||
'&:before': {
|
||||
borderBottomColor: theme.palette.divider
|
||||
}
|
||||
},
|
||||
'& .apexcharts-yaxistooltip': {
|
||||
borderColor: theme.palette.divider,
|
||||
background: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default,
|
||||
'& .apexcharts-yaxistooltip-text': {
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'&:after': {
|
||||
borderLeftColor: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default
|
||||
},
|
||||
'&:before': {
|
||||
borderLeftColor: theme.palette.divider
|
||||
}
|
||||
},
|
||||
'& .apexcharts-text, & .apexcharts-tooltip-text, & .apexcharts-datalabel-label, & .apexcharts-datalabel': {
|
||||
filter: 'none',
|
||||
fontWeight: 400,
|
||||
fill: theme.palette.text.primary,
|
||||
fontFamily: `${theme.typography.fontFamily} !important`
|
||||
},
|
||||
'& .apexcharts-pie-label': {
|
||||
filter: 'none',
|
||||
fill: theme.palette.common.white
|
||||
},
|
||||
'& .apexcharts-pie': {
|
||||
'& .apexcharts-datalabel-label, .apexcharts-datalabel-value': {
|
||||
fontSize: '1.5rem'
|
||||
}
|
||||
},
|
||||
'& .apexcharts-marker': {
|
||||
boxShadow: 'none'
|
||||
},
|
||||
'& .apexcharts-legend-series': {
|
||||
margin: `${theme.spacing(0.75, 2)} !important`,
|
||||
'& .apexcharts-legend-text': {
|
||||
marginLeft: theme.spacing(0.75),
|
||||
color: `${theme.palette.text.primary} !important`
|
||||
}
|
||||
},
|
||||
'& .apexcharts-xcrosshairs, & .apexcharts-ycrosshairs, & .apexcharts-gridline': {
|
||||
stroke: theme.palette.divider
|
||||
},
|
||||
'& .apexcharts-heatmap-rect': {
|
||||
stroke: theme.palette.mode === 'light' ? theme.palette.background.paper : theme.palette.background.default
|
||||
},
|
||||
'& .apexcharts-radialbar > g > g:first-of-type .apexcharts-radialbar-area': {
|
||||
stroke: theme.palette.background.default
|
||||
},
|
||||
'& .apexcharts-radar-series polygon': {
|
||||
stroke: theme.palette.divider,
|
||||
fill: theme.palette.background.paper
|
||||
},
|
||||
'& .apexcharts-radar-series line': {
|
||||
stroke: theme.palette.divider
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
export default ApexChartWrapper
|
361
core/styles/libs/react-datepicker/index.ts
Normal file
361
core/styles/libs/react-datepicker/index.ts
Normal file
@ -0,0 +1,361 @@
|
||||
// ** MUI imports
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Box, { BoxProps } from '@mui/material/Box'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from '../../../../core/utils/hex-to-rgba'
|
||||
|
||||
const DatePickerWrapper = styled(Box)<BoxProps>(({ theme }) => {
|
||||
return {
|
||||
'& .react-datepicker-popper': {
|
||||
zIndex: 5
|
||||
},
|
||||
'& .react-datepicker-wrapper': {
|
||||
width: '100%'
|
||||
},
|
||||
'& .react-datepicker': {
|
||||
border: 'none',
|
||||
boxShadow: theme.shadows[7],
|
||||
padding: theme.spacing(2, 0),
|
||||
color: theme.palette.text.primary,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
fontFamily: theme.typography.fontFamily,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
'& .react-datepicker__header': {
|
||||
padding: 0,
|
||||
border: 'none',
|
||||
fontWeight: 'normal',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
'& .react-datepicker__day-name': {
|
||||
margin: 0
|
||||
}
|
||||
},
|
||||
'& .react-datepicker-year-header': {
|
||||
lineHeight: 2.1,
|
||||
marginBottom: '0.5rem',
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'& .react-datepicker__triangle': {
|
||||
display: 'none'
|
||||
},
|
||||
'& > .react-datepicker__navigation': {
|
||||
top: theme.spacing(3),
|
||||
'&.react-datepicker__navigation--previous': {
|
||||
border: 'none',
|
||||
backgroundImage: `${"url('data:image/svg+xml,%3Csvg xmlns=\\'http://www.w3.org/2000/svg\\' style=\\'width:24px;height:24px\\' viewBox=\\'0 0 24 24\\'%3E%3Cpath fill=\\'currentColor\\' d=\\'M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z\\' /%3E%3C/svg%3E')"
|
||||
.replace('currentColor', theme.palette.text.secondary)
|
||||
.replace('#', '%23')}`,
|
||||
height: '24px',
|
||||
width: '24px',
|
||||
'& .react-datepicker__navigation-icon': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'&.react-datepicker__navigation--next': {
|
||||
border: 'none',
|
||||
backgroundImage: `${"url('data:image/svg+xml,%3Csvg xmlns=\\'http://www.w3.org/2000/svg\\' style=\\'width:24px;height:24px\\' viewBox=\\'0 0 24 24\\'%3E%3Cpath fill=\\'currentColor\\' d=\\'M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z\\' /%3E%3C/svg%3E')"
|
||||
.replace('currentColor', theme.palette.text.secondary)
|
||||
.replace('#', '%23')}`,
|
||||
height: '24px',
|
||||
width: '24px',
|
||||
'& .react-datepicker__navigation-icon': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'&.react-datepicker__navigation--next--with-time': {
|
||||
right: '122px'
|
||||
},
|
||||
'&:focus, &:active': {
|
||||
outline: 0
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__current-month': {
|
||||
lineHeight: 2.1,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 'normal',
|
||||
letterSpacing: '0.15px',
|
||||
marginBottom: theme.spacing(2),
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'& .react-datepicker__day-name': {
|
||||
lineHeight: 1.5,
|
||||
width: '2.25rem',
|
||||
fontSize: '0.75rem',
|
||||
letterSpacing: '0.4px',
|
||||
color: theme.palette.text.secondary
|
||||
},
|
||||
'& .react-datepicker__day': {
|
||||
margin: 0,
|
||||
width: '2.25rem',
|
||||
lineHeight: 2.75,
|
||||
height: '2.25rem',
|
||||
borderRadius: '50%',
|
||||
color: theme.palette.text.primary,
|
||||
'&.react-datepicker__day--selected, &.react-datepicker__day--keyboard-selected': {
|
||||
color: theme.palette.common.white,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
},
|
||||
'&.react-datepicker__day--in-range, &.react-datepicker__day--in-selecting-range': {
|
||||
borderRadius: 0,
|
||||
color: theme.palette.primary.main,
|
||||
backgroundColor: `${hexToRGBA(theme.palette.primary.main, 0.06)} !important`,
|
||||
'&:empty': {
|
||||
backgroundColor: 'transparent !important'
|
||||
}
|
||||
},
|
||||
'&.react-datepicker__day--selected.react-datepicker__day--in-selecting-range.react-datepicker__day--selecting-range-start, &.react-datepicker__day--selected.react-datepicker__day--range-start.react-datepicker__day--in-range, &.react-datepicker__day--range-start':
|
||||
{
|
||||
borderTopLeftRadius: '50%',
|
||||
borderBottomLeftRadius: '50%',
|
||||
color: theme.palette.common.white,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
},
|
||||
'&.react-datepicker__day--range-end': {
|
||||
borderTopRightRadius: '50%',
|
||||
borderBottomRightRadius: '50%',
|
||||
color: theme.palette.common.white,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
},
|
||||
'&:focus, &:active': {
|
||||
outline: 0
|
||||
},
|
||||
'&.react-datepicker__day--outside-month': {
|
||||
height: 'auto'
|
||||
},
|
||||
'&.react-datepicker__day--outside-month, &.react-datepicker__day--disabled:not(.react-datepicker__day--selected)':
|
||||
{
|
||||
color: theme.palette.text.disabled,
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent'
|
||||
}
|
||||
},
|
||||
'&.react-datepicker__day--highlighted, &.react-datepicker__day--highlighted:hover': {
|
||||
color: theme.palette.success.main,
|
||||
backgroundColor: hexToRGBA(theme.palette.success.main, 0.12)
|
||||
},
|
||||
'&.react-datepicker__day--today': {
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__header__dropdown': {
|
||||
'& .react-datepicker__month-dropdown-container:not(:last-child)': {
|
||||
marginRight: theme.spacing(8)
|
||||
},
|
||||
'& .react-datepicker__month-dropdown-container, & .react-datepicker__year-dropdown-container': {
|
||||
marginBottom: theme.spacing(4)
|
||||
},
|
||||
'& .react-datepicker__month-read-view--selected-month, & .react-datepicker__year-read-view--selected-year': {
|
||||
fontSize: '0.875rem',
|
||||
marginRight: theme.spacing(1),
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'& .react-datepicker__month-read-view:hover .react-datepicker__month-read-view--down-arrow, & .react-datepicker__year-read-view:hover .react-datepicker__year-read-view--down-arrow':
|
||||
{
|
||||
borderTopColor: theme.palette.text.secondary,
|
||||
borderRightColor: theme.palette.text.secondary
|
||||
},
|
||||
'& .react-datepicker__month-read-view--down-arrow, & .react-datepicker__year-read-view--down-arrow': {
|
||||
top: 4,
|
||||
borderTopColor: theme.palette.text.disabled,
|
||||
borderRightColor: theme.palette.text.disabled
|
||||
},
|
||||
'& .react-datepicker__month-dropdown, & .react-datepicker__year-dropdown': {
|
||||
paddingTop: theme.spacing(1.5),
|
||||
paddingBottom: theme.spacing(1.5),
|
||||
borderColor: theme.palette.divider,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
boxShadow: theme.palette.mode === 'light' ? theme.shadows[8] : theme.shadows[9]
|
||||
},
|
||||
'& .react-datepicker__month-option, & .react-datepicker__year-option': {
|
||||
paddingTop: theme.spacing(0.5),
|
||||
paddingBottom: theme.spacing(0.5),
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.action.hover
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__month-option.react-datepicker__month-option--selected_month': {
|
||||
backgroundColor: hexToRGBA(theme.palette.primary.main, 0.08),
|
||||
'&:hover': {
|
||||
backgroundColor: hexToRGBA(theme.palette.primary.main, 0.12)
|
||||
},
|
||||
'& .react-datepicker__month-option--selected': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__year-option.react-datepicker__year-option--selected_year': {
|
||||
backgroundColor: hexToRGBA(theme.palette.primary.main, 0.08),
|
||||
'&:hover': {
|
||||
backgroundColor: hexToRGBA(theme.palette.primary.main, 0.12)
|
||||
},
|
||||
'& .react-datepicker__year-option--selected': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__year-option': {
|
||||
// TODO: Remove some of the following styles for arrow in Year dropdown when react-datepicker give arrows in Year dropdown
|
||||
'& .react-datepicker__navigation--years-upcoming': {
|
||||
width: 9,
|
||||
height: 9,
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '3px 3px 0 0',
|
||||
transform: 'rotate(-45deg)',
|
||||
borderTopColor: theme.palette.text.disabled,
|
||||
borderRightColor: theme.palette.text.disabled,
|
||||
margin: `${theme.spacing(2.75)} auto ${theme.spacing(0)}`
|
||||
},
|
||||
'&:hover .react-datepicker__navigation--years-upcoming': {
|
||||
borderTopColor: theme.palette.text.secondary,
|
||||
borderRightColor: theme.palette.text.secondary
|
||||
},
|
||||
'& .react-datepicker__navigation--years-previous': {
|
||||
width: 9,
|
||||
height: 9,
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '0 0 3px 3px',
|
||||
transform: 'rotate(-45deg)',
|
||||
borderLeftColor: theme.palette.text.disabled,
|
||||
borderBottomColor: theme.palette.text.disabled,
|
||||
margin: `${theme.spacing(0)} auto ${theme.spacing(2.75)}`
|
||||
},
|
||||
'&:hover .react-datepicker__navigation--years-previous': {
|
||||
borderLeftColor: theme.palette.text.secondary,
|
||||
borderBottomColor: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__month': {
|
||||
marginTop: theme.spacing(3)
|
||||
},
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
'& .react-datepicker__month': {
|
||||
marginLeft: 0,
|
||||
marginRight: 0,
|
||||
marginBottom: 0
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__month, & .react-datepicker__year': {
|
||||
'& .react-datepicker__month-text, & .react-datepicker__year-text, & .react-datepicker__quarter-text': {
|
||||
height: '2rem',
|
||||
alignItems: 'center',
|
||||
display: 'inline-flex',
|
||||
justifyContent: 'center',
|
||||
'&:hover': {
|
||||
borderRadius: theme.shape.borderRadius
|
||||
},
|
||||
'&:focus, &:active': {
|
||||
outline: 0
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__quarter--selected, & .react-datepicker__year-text--selected, & .react-datepicker__month--selected, & .react-datepicker__quarter-text--keyboard-selected, & .react-datepicker__month-text--keyboard-selected, & .react-datepicker__year-text--keyboard-selected':
|
||||
{
|
||||
color: theme.palette.common.white,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
},
|
||||
'& .react-datepicker__week-number': {
|
||||
fontWeight: 600,
|
||||
color: theme.palette.text.primary
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__year-wrapper': {
|
||||
maxWidth: 205,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
'& .react-datepicker__input-time-container': {
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
'& .react-datepicker__today-button': {
|
||||
borderRadius: '1rem',
|
||||
margin: '0 1rem 0.3rem',
|
||||
color: theme.palette.common.white,
|
||||
backgroundColor: theme.palette.primary.main
|
||||
},
|
||||
|
||||
// ** Time Picker
|
||||
'& .react-datepicker__time-container': {
|
||||
borderLeftColor: theme.palette.divider
|
||||
},
|
||||
'&.react-datepicker--time-only, & .react-datepicker__time-container': {
|
||||
width: '7rem',
|
||||
padding: theme.spacing(1.2, 0),
|
||||
'& .react-datepicker-time__header': {
|
||||
marginBottom: theme.spacing(3),
|
||||
color: theme.palette.text.primary,
|
||||
fontSize: theme.typography.body2.fontSize
|
||||
},
|
||||
|
||||
'& .react-datepicker__time': {
|
||||
background: theme.palette.background.paper,
|
||||
'& .react-datepicker__time-box .react-datepicker__time-list-item--disabled': {
|
||||
color: theme.palette.text.disabled
|
||||
}
|
||||
},
|
||||
|
||||
'& .react-datepicker__time-list-item': {
|
||||
lineHeight: 1.75,
|
||||
height: 'auto !important',
|
||||
marginLeft: theme.spacing(3.2),
|
||||
marginRight: theme.spacing(1.2),
|
||||
color: theme.palette.text.primary,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
'&:focus, &:active': {
|
||||
outline: 0
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: `${theme.palette.action.hover} !important`
|
||||
},
|
||||
'&.react-datepicker__time-list-item--selected': {
|
||||
color: `${theme.palette.common.white} !important`,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
}
|
||||
},
|
||||
|
||||
'& .react-datepicker__time-box': {
|
||||
width: '100%'
|
||||
},
|
||||
'& .react-datepicker__time-list': {
|
||||
'&::-webkit-scrollbar': {
|
||||
width: 8
|
||||
},
|
||||
|
||||
/* Track */
|
||||
'&::-webkit-scrollbar-track': {
|
||||
background: theme.palette.background.paper
|
||||
},
|
||||
|
||||
/* Handle */
|
||||
'&::-webkit-scrollbar-thumb': {
|
||||
background: '#aaa',
|
||||
borderRadius: '10px'
|
||||
},
|
||||
|
||||
/* Handle on hover */
|
||||
'&::-webkit-scrollbar-thumb:hover': {
|
||||
background: '#999'
|
||||
}
|
||||
}
|
||||
},
|
||||
'&.react-datepicker--time-only .react-datepicker__time-container': {
|
||||
width: 'calc(7rem - 2px)'
|
||||
},
|
||||
'& .react-datepicker__day:hover, & .react-datepicker__month-text:hover, & .react-datepicker__quarter-text:hover, & .react-datepicker__year-text:hover':
|
||||
{
|
||||
backgroundColor: theme.palette.action.hover
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__close-icon': {
|
||||
paddingRight: theme.spacing(4),
|
||||
'&:after': {
|
||||
width: 'unset',
|
||||
height: 'unset',
|
||||
fontSize: '1.5rem',
|
||||
color: theme.palette.text.primary,
|
||||
backgroundColor: 'transparent !important'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default DatePickerWrapper
|
60
core/theme/ThemeComponent.tsx
Normal file
60
core/theme/ThemeComponent.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import CssBaseline from '@mui/material/CssBaseline'
|
||||
import GlobalStyles from '@mui/material/GlobalStyles'
|
||||
import { ThemeProvider, createTheme, responsiveFontSizes } from '@mui/material/styles'
|
||||
|
||||
// ** Type Imports
|
||||
import { Settings } from '../../core/context/settingsContext'
|
||||
|
||||
// ** Theme Config
|
||||
import themeConfig from '../../configs/themeConfig'
|
||||
|
||||
// ** Theme Override Imports
|
||||
import overrides from './overrides'
|
||||
import typography from './typography'
|
||||
|
||||
// ** Theme
|
||||
import themeOptions from './ThemeOptions'
|
||||
|
||||
// ** Global Styles
|
||||
import GlobalStyling from './globalStyles'
|
||||
|
||||
interface Props {
|
||||
settings: Settings
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const ThemeComponent = (props: Props) => {
|
||||
// ** Props
|
||||
const { settings, children } = props
|
||||
|
||||
// ** Merged ThemeOptions of Core and User
|
||||
const coreThemeConfig = themeOptions(settings)
|
||||
|
||||
// ** Pass ThemeOptions to CreateTheme Function to create partial theme without component overrides
|
||||
let theme = createTheme(coreThemeConfig)
|
||||
|
||||
// ** Continue theme creation and pass merged component overrides to CreateTheme function
|
||||
theme = createTheme(theme, {
|
||||
components: { ...overrides(theme) },
|
||||
typography: { ...typography(theme) }
|
||||
})
|
||||
|
||||
// ** Set responsive font sizes to true
|
||||
if (themeConfig.responsiveFontSizes) {
|
||||
theme = responsiveFontSizes(theme)
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<GlobalStyles styles={() => GlobalStyling(theme) as any} />
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default ThemeComponent
|
58
core/theme/ThemeOptions.ts
Normal file
58
core/theme/ThemeOptions.ts
Normal file
@ -0,0 +1,58 @@
|
||||
// ** MUI Theme Provider
|
||||
import { deepmerge } from '@mui/utils'
|
||||
import { ThemeOptions } from '@mui/material'
|
||||
|
||||
// ** Type Import
|
||||
import { Settings } from '../core/context/settingsContext'
|
||||
|
||||
// ** Theme Override Imports
|
||||
import palette from './palette'
|
||||
import spacing from './spacing'
|
||||
import shadows from './shadows'
|
||||
import breakpoints from './breakpoints'
|
||||
|
||||
const themeOptions = (settings: Settings): ThemeOptions => {
|
||||
// ** Vars
|
||||
const { mode, themeColor } = settings
|
||||
|
||||
const themeConfig = {
|
||||
palette: palette(mode, themeColor),
|
||||
typography: {
|
||||
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(',')
|
||||
},
|
||||
shadows: shadows(mode),
|
||||
...spacing,
|
||||
breakpoints: breakpoints(),
|
||||
shape: {
|
||||
borderRadius: 6
|
||||
},
|
||||
mixins: {
|
||||
toolbar: {
|
||||
minHeight: 64
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return deepmerge(themeConfig, {
|
||||
palette: {
|
||||
primary: {
|
||||
...themeConfig.palette[themeColor]
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default themeOptions
|
11
core/theme/breakpoints/index.ts
Normal file
11
core/theme/breakpoints/index.ts
Normal file
@ -0,0 +1,11 @@
|
||||
const breakpoints = () => ({
|
||||
values: {
|
||||
xs: 0,
|
||||
sm: 600,
|
||||
md: 900,
|
||||
lg: 1200,
|
||||
xl: 1536
|
||||
}
|
||||
})
|
||||
|
||||
export default breakpoints
|
47
core/theme/globalStyles.ts
Normal file
47
core/theme/globalStyles.ts
Normal file
@ -0,0 +1,47 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const GlobalStyles = (theme: Theme) => {
|
||||
return {
|
||||
'.ps__rail-y': {
|
||||
zIndex: 1,
|
||||
right: '0 !important',
|
||||
left: 'auto !important',
|
||||
'&:hover, &:focus, &.ps--clicking': {
|
||||
backgroundColor: theme.palette.mode === 'light' ? '#E4E5EB !important' : '#423D5D !important'
|
||||
},
|
||||
'& .ps__thumb-y': {
|
||||
right: '3px !important',
|
||||
left: 'auto !important',
|
||||
backgroundColor: theme.palette.mode === 'light' ? '#C2C4D1 !important' : '#504B6D !important'
|
||||
},
|
||||
'.layout-vertical-nav &': {
|
||||
'& .ps__thumb-y': {
|
||||
width: 4,
|
||||
backgroundColor: theme.palette.mode === 'light' ? '#C2C4D1 !important' : '#504B6D !important'
|
||||
},
|
||||
'&:hover, &:focus, &.ps--clicking': {
|
||||
backgroundColor: 'transparent !important',
|
||||
'& .ps__thumb-y': {
|
||||
width: 6
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
'#nprogress': {
|
||||
pointerEvents: 'none',
|
||||
'& .bar': {
|
||||
left: 0,
|
||||
top: 0,
|
||||
height: 3,
|
||||
width: '100%',
|
||||
zIndex: 2000,
|
||||
position: 'fixed',
|
||||
backgroundColor: theme.palette.primary.main
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GlobalStyles
|
49
core/theme/overrides/accordion.ts
Normal file
49
core/theme/overrides/accordion.ts
Normal file
@ -0,0 +1,49 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Accordion = (theme: Theme) => {
|
||||
return {
|
||||
MuiAccordion: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&.Mui-disabled': {
|
||||
backgroundColor: `rgba(${theme.palette.customColors.main}, 0.12)`
|
||||
},
|
||||
'&.Mui-expanded': {
|
||||
boxShadow: theme.shadows[3]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiAccordionSummary: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: `0 ${theme.spacing(5)}`,
|
||||
'& + .MuiCollapse-root': {
|
||||
'& .MuiAccordionDetails-root:first-child': {
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
content: {
|
||||
margin: `${theme.spacing(2.5)} 0`
|
||||
},
|
||||
expandIconWrapper: {
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiAccordionDetails: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiAccordionDetails-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Accordion
|
112
core/theme/overrides/alerts.ts
Normal file
112
core/theme/overrides/alerts.ts
Normal file
@ -0,0 +1,112 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
import { lighten, darken } from '@mui/material/styles'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from '../../../core/utils/hex-to-rgba'
|
||||
|
||||
const Alert = (theme: Theme) => {
|
||||
const getColor = theme.palette.mode === 'light' ? darken : lighten
|
||||
|
||||
return {
|
||||
MuiAlert: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 5,
|
||||
'& .MuiAlertTitle-root': {
|
||||
marginBottom: theme.spacing(1.6)
|
||||
},
|
||||
'& a': {
|
||||
color: 'inherit',
|
||||
fontWeight: 500
|
||||
}
|
||||
},
|
||||
standardSuccess: {
|
||||
color: getColor(theme.palette.success.main, 0.12),
|
||||
backgroundColor: hexToRGBA(theme.palette.success.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.success.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.success.main, 0.12)
|
||||
}
|
||||
},
|
||||
standardInfo: {
|
||||
color: getColor(theme.palette.info.main, 0.12),
|
||||
backgroundColor: hexToRGBA(theme.palette.info.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.info.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.info.main, 0.12)
|
||||
}
|
||||
},
|
||||
standardWarning: {
|
||||
color: getColor(theme.palette.warning.main, 0.12),
|
||||
backgroundColor: hexToRGBA(theme.palette.warning.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.warning.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.warning.main, 0.12)
|
||||
}
|
||||
},
|
||||
standardError: {
|
||||
color: getColor(theme.palette.error.main, 0.12),
|
||||
backgroundColor: hexToRGBA(theme.palette.error.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.error.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.error.main, 0.12)
|
||||
}
|
||||
},
|
||||
outlinedSuccess: {
|
||||
borderColor: theme.palette.success.main,
|
||||
color: getColor(theme.palette.success.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.success.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.success.main, 0.12)
|
||||
}
|
||||
},
|
||||
outlinedInfo: {
|
||||
borderColor: theme.palette.info.main,
|
||||
color: getColor(theme.palette.info.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.info.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.info.main, 0.12)
|
||||
}
|
||||
},
|
||||
outlinedWarning: {
|
||||
borderColor: theme.palette.warning.main,
|
||||
color: getColor(theme.palette.warning.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.warning.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.warning.main, 0.12)
|
||||
}
|
||||
},
|
||||
outlinedError: {
|
||||
borderColor: theme.palette.error.main,
|
||||
color: getColor(theme.palette.error.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.error.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.error.main, 0.12)
|
||||
}
|
||||
},
|
||||
filled: {
|
||||
fontWeight: 400
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Alert
|
30
core/theme/overrides/avatars.ts
Normal file
30
core/theme/overrides/avatars.ts
Normal file
@ -0,0 +1,30 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Avatar = (theme: Theme) => {
|
||||
return {
|
||||
MuiAvatar: {
|
||||
styleOverrides: {
|
||||
colorDefault: {
|
||||
color: theme.palette.text.secondary,
|
||||
backgroundColor: theme.palette.mode === 'light' ? theme.palette.grey[200] : theme.palette.grey[700]
|
||||
},
|
||||
rounded: {
|
||||
borderRadius: 5
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiAvatarGroup: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
justifyContent: 'flex-end',
|
||||
'.MuiCard-root & .MuiAvatar-root': {
|
||||
borderColor: theme.palette.background.paper
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Avatar
|
25
core/theme/overrides/backdrop.ts
Normal file
25
core/theme/overrides/backdrop.ts
Normal file
@ -0,0 +1,25 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from '../../../core/utils/hex-to-rgba'
|
||||
|
||||
const Backdrop = (theme: Theme) => {
|
||||
return {
|
||||
MuiBackdrop: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor:
|
||||
theme.palette.mode === 'light'
|
||||
? `rgba(${theme.palette.customColors.main}, 0.7)`
|
||||
: hexToRGBA(theme.palette.background.default, 0.7)
|
||||
},
|
||||
invisible: {
|
||||
backgroundColor: 'transparent'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Backdrop
|
53
core/theme/overrides/button.ts
Normal file
53
core/theme/overrides/button.ts
Normal file
@ -0,0 +1,53 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
// ** Theme Config Imports
|
||||
import themeConfig from '../../../configs/themeConfig'
|
||||
|
||||
const Button = (theme: Theme) => {
|
||||
return {
|
||||
MuiButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
fontWeight: 500,
|
||||
borderRadius: 5,
|
||||
lineHeight: 1.71,
|
||||
letterSpacing: '0.3px',
|
||||
padding: `${theme.spacing(1.875, 3)}`
|
||||
},
|
||||
contained: {
|
||||
boxShadow: theme.shadows[3],
|
||||
padding: `${theme.spacing(1.875, 5.5)}`
|
||||
},
|
||||
outlined: {
|
||||
padding: `${theme.spacing(1.625, 5.25)}`
|
||||
},
|
||||
sizeSmall: {
|
||||
padding: `${theme.spacing(1, 2.25)}`,
|
||||
'&.MuiButton-contained': {
|
||||
padding: `${theme.spacing(1, 3.5)}`
|
||||
},
|
||||
'&.MuiButton-outlined': {
|
||||
padding: `${theme.spacing(0.75, 3.25)}`
|
||||
}
|
||||
},
|
||||
sizeLarge: {
|
||||
padding: `${theme.spacing(2.125, 5.5)}`,
|
||||
'&.MuiButton-contained': {
|
||||
padding: `${theme.spacing(2.125, 6.5)}`
|
||||
},
|
||||
'&.MuiButton-outlined': {
|
||||
padding: `${theme.spacing(1.875, 6.25)}`
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiButtonBase: {
|
||||
defaultProps: {
|
||||
disableRipple: themeConfig.disableRipple
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Button
|
86
core/theme/overrides/card.ts
Normal file
86
core/theme/overrides/card.ts
Normal file
@ -0,0 +1,86 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Card = (theme: Theme) => {
|
||||
return {
|
||||
MuiCard: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
boxShadow: theme.shadows[6],
|
||||
'& .card-more-options': {
|
||||
marginTop: theme.spacing(-1),
|
||||
marginRight: theme.spacing(-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiCardHeader: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiCardContent-root, & + .MuiCollapse-root .MuiCardContent-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
'& .MuiCardHeader-subheader': {
|
||||
fontSize: '0.875rem'
|
||||
}
|
||||
},
|
||||
title: {
|
||||
lineHeight: 1,
|
||||
fontWeight: 500,
|
||||
fontSize: '1.25rem',
|
||||
letterSpacing: '0.0125em'
|
||||
},
|
||||
action: {
|
||||
marginTop: 0,
|
||||
marginRight: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiCardContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiCardContent-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
'&:last-of-type': {
|
||||
paddingBottom: theme.spacing(5)
|
||||
},
|
||||
'& + .MuiCardActions-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiCardActions: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'&.card-action-dense': {
|
||||
padding: theme.spacing(0, 2.5, 2.5),
|
||||
'.MuiCard-root .MuiCardMedia-root + &': {
|
||||
paddingTop: theme.spacing(2.5)
|
||||
},
|
||||
'.MuiCard-root &:first-of-type': {
|
||||
paddingTop: theme.spacing(5),
|
||||
paddingBottom: theme.spacing(5),
|
||||
'& + .MuiCardContent-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
'& + .MuiCardHeader-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .MuiButton-text': {
|
||||
paddingLeft: theme.spacing(2.5),
|
||||
paddingRight: theme.spacing(2.5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Card
|
22
core/theme/overrides/chip.ts
Normal file
22
core/theme/overrides/chip.ts
Normal file
@ -0,0 +1,22 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Chip = (theme: Theme) => {
|
||||
return {
|
||||
MuiChip: {
|
||||
styleOverrides: {
|
||||
outlined: {
|
||||
'&.MuiChip-colorDefault': {
|
||||
borderColor: `rgba(${theme.palette.customColors.main}, 0.22)`
|
||||
}
|
||||
},
|
||||
deleteIcon: {
|
||||
width: 18,
|
||||
height: 18
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Chip
|
64
core/theme/overrides/dateTimePicker.ts
Normal file
64
core/theme/overrides/dateTimePicker.ts
Normal file
@ -0,0 +1,64 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const DateTimePicker = (theme: Theme) => {
|
||||
return {
|
||||
MuiCalendarPicker: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& [role="presentation"]': {
|
||||
fontWeight: 400,
|
||||
'& .PrivatePickersFadeTransitionGroup-root + .PrivatePickersFadeTransitionGroup-root > div': {
|
||||
marginRight: 0
|
||||
},
|
||||
'& .MuiIconButton-sizeSmall': {
|
||||
padding: theme.spacing(0.5)
|
||||
},
|
||||
'& + div .MuiIconButton-root:not(.Mui-disabled)': {
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
},
|
||||
'& .PrivatePickersSlideTransition-root': {
|
||||
minHeight: 240
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiPickersDay: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
fontSize: '0.875rem'
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiClockPicker: {
|
||||
styleOverrides: {
|
||||
arrowSwitcher: {
|
||||
'& .MuiIconButton-root:not(.Mui-disabled)': {
|
||||
color: theme.palette.text.secondary
|
||||
},
|
||||
'& + div': {
|
||||
'& > div': {
|
||||
backgroundColor:
|
||||
theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default,
|
||||
'& ~ .MuiIconButton-root span.MuiTypography-caption': {
|
||||
color: 'inherit'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiMonthPicker: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& > .MuiTypography-root.Mui-selected': {
|
||||
fontSize: '1rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default DateTimePicker
|
107
core/theme/overrides/dialog.ts
Normal file
107
core/theme/overrides/dialog.ts
Normal file
@ -0,0 +1,107 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from '../../../core/utils/hex-to-rgba'
|
||||
|
||||
const Dialog = (theme: Theme) => {
|
||||
return {
|
||||
MuiDialog: {
|
||||
styleOverrides: {
|
||||
paper: {
|
||||
boxShadow: theme.shadows[6],
|
||||
'&:not(.MuiDialog-paperFullScreen)': {
|
||||
'@media (max-width:599px)': {
|
||||
margin: theme.spacing(4),
|
||||
width: `calc(100% - ${theme.spacing(8)})`,
|
||||
maxWidth: `calc(100% - ${theme.spacing(8)}) !important`
|
||||
}
|
||||
},
|
||||
'& > .MuiList-root': {
|
||||
paddingLeft: theme.spacing(1),
|
||||
paddingRight: theme.spacing(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiDialogTitle: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5)
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiDialogContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiDialogContent-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
'& + .MuiDialogActions-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
|
||||
// Styling for Mobile Date Picker starts
|
||||
'& .PrivatePickersToolbar-root': {
|
||||
padding: theme.spacing(4, 5),
|
||||
color: theme.palette.primary.contrastText,
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
'& .MuiTypography-root': {
|
||||
color: theme.palette.primary.contrastText
|
||||
},
|
||||
'& span.MuiTypography-overline': {
|
||||
fontSize: '1rem',
|
||||
lineHeight: '24px',
|
||||
letterSpacing: '0.15px'
|
||||
},
|
||||
'& ~ div[class^="css-"] > div[class^="css-"]': {
|
||||
marginTop: theme.spacing(6),
|
||||
marginBottom: theme.spacing(6),
|
||||
'& > div[class^="css-"]': {
|
||||
backgroundColor:
|
||||
theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default,
|
||||
'& ~ .MuiIconButton-root span.MuiTypography-caption': {
|
||||
color: 'inherit'
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .PrivateTimePickerToolbar-hourMinuteLabel': {
|
||||
alignItems: 'center',
|
||||
'& > .MuiButton-root span.MuiTypography-root': {
|
||||
fontWeight: 300,
|
||||
lineHeight: '72px',
|
||||
fontSize: '3.75rem',
|
||||
letterSpacing: '-0.5px'
|
||||
},
|
||||
'& > .MuiTypography-root': {
|
||||
color: hexToRGBA(theme.palette.primary.contrastText, 0.54),
|
||||
'& + .MuiButton-root > span.MuiTypography-root': {
|
||||
color: hexToRGBA(theme.palette.primary.contrastText, 0.54)
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .PrivateTimePickerToolbar-ampmSelection span.MuiTypography-root:not(.Mui-selected)': {
|
||||
color: hexToRGBA(theme.palette.primary.contrastText, 0.54)
|
||||
}
|
||||
}
|
||||
|
||||
// Styling for Mobile Date Picker ends
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiDialogActions: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'&.dialog-actions-dense': {
|
||||
padding: theme.spacing(2.5),
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Dialog
|
16
core/theme/overrides/divider.ts
Normal file
16
core/theme/overrides/divider.ts
Normal file
@ -0,0 +1,16 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Divider = (theme: Theme) => {
|
||||
return {
|
||||
MuiDivider: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
margin: `${theme.spacing(2)} 0`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Divider
|
88
core/theme/overrides/index.ts
Normal file
88
core/theme/overrides/index.ts
Normal file
@ -0,0 +1,88 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
// ** Overrides Imports
|
||||
import MuiCard from './card'
|
||||
import MuiChip from './chip'
|
||||
import MuiLink from './link'
|
||||
import MuiList from './list'
|
||||
import MuiMenu from './menu'
|
||||
import MuiTabs from './tabs'
|
||||
import MuiInput from './input'
|
||||
import MuiPaper from './paper'
|
||||
import MuiTable from './table'
|
||||
import MuiAlerts from './alerts'
|
||||
import MuiButton from './button'
|
||||
import MuiDialog from './dialog'
|
||||
import MuiRating from './rating'
|
||||
import MuiSelect from './select'
|
||||
import MuiAvatar from './avatars'
|
||||
import MuiDivider from './divider'
|
||||
import MuiPopover from './popover'
|
||||
import MuiTooltip from './tooltip'
|
||||
import MuiBackdrop from './backdrop'
|
||||
import MuiSnackbar from './snackbar'
|
||||
import MuiSwitches from './switches'
|
||||
import MuiTimeline from './timeline'
|
||||
import MuiAccordion from './accordion'
|
||||
import MuiPagination from './pagination'
|
||||
import MuiTypography from './typography'
|
||||
import MuiToggleButton from './toggleButton'
|
||||
import MuiDateTimePicker from './dateTimePicker'
|
||||
|
||||
const Overrides = (theme: Theme) => {
|
||||
const chip = MuiChip(theme)
|
||||
const list = MuiList(theme)
|
||||
const menu = MuiMenu(theme)
|
||||
const tabs = MuiTabs(theme)
|
||||
const cards = MuiCard(theme)
|
||||
const input = MuiInput(theme)
|
||||
const tables = MuiTable(theme)
|
||||
const alerts = MuiAlerts(theme)
|
||||
const button = MuiButton(theme)
|
||||
const rating = MuiRating(theme)
|
||||
const avatars = MuiAvatar(theme)
|
||||
const divider = MuiDivider(theme)
|
||||
const dialog = MuiDialog(theme)
|
||||
const popover = MuiPopover(theme)
|
||||
const tooltip = MuiTooltip(theme)
|
||||
const backdrop = MuiBackdrop(theme)
|
||||
const snackbar = MuiSnackbar(theme)
|
||||
const switches = MuiSwitches(theme)
|
||||
const timeline = MuiTimeline(theme)
|
||||
const accordion = MuiAccordion(theme)
|
||||
const pagination = MuiPagination(theme)
|
||||
const dateTimePicker = MuiDateTimePicker(theme)
|
||||
|
||||
return Object.assign(
|
||||
chip,
|
||||
list,
|
||||
menu,
|
||||
tabs,
|
||||
cards,
|
||||
input,
|
||||
alerts,
|
||||
button,
|
||||
dialog,
|
||||
rating,
|
||||
tables,
|
||||
avatars,
|
||||
divider,
|
||||
MuiLink,
|
||||
popover,
|
||||
tooltip,
|
||||
backdrop,
|
||||
MuiPaper,
|
||||
snackbar,
|
||||
switches,
|
||||
timeline,
|
||||
accordion,
|
||||
MuiSelect,
|
||||
pagination,
|
||||
MuiTypography,
|
||||
dateTimePicker,
|
||||
MuiToggleButton
|
||||
)
|
||||
}
|
||||
|
||||
export default Overrides
|
65
core/theme/overrides/input.ts
Normal file
65
core/theme/overrides/input.ts
Normal file
@ -0,0 +1,65 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const input = (theme: Theme) => {
|
||||
return {
|
||||
MuiInputLabel: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:before': {
|
||||
borderBottom: `1px solid rgba(${theme.palette.customColors.main}, 0.22)`
|
||||
},
|
||||
'&:hover:not(.Mui-disabled):before': {
|
||||
borderBottom: `1px solid rgba(${theme.palette.customColors.main}, 0.32)`
|
||||
},
|
||||
'&.Mui-disabled:before': {
|
||||
borderBottom: `1px solid ${theme.palette.text.disabled}`
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiFilledInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor: `rgba(${theme.palette.customColors.main}, 0.04)`,
|
||||
'&:hover:not(.Mui-disabled)': {
|
||||
backgroundColor: `rgba(${theme.palette.customColors.main}, 0.08)`
|
||||
},
|
||||
'&:before': {
|
||||
borderBottom: `1px solid rgba(${theme.palette.customColors.main}, 0.22)`
|
||||
},
|
||||
'&:hover:not(.Mui-disabled):before': {
|
||||
borderBottom: `1px solid rgba(${theme.palette.customColors.main}, 0.32)`
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiOutlinedInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:hover:not(.Mui-focused) .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: `rgba(${theme.palette.customColors.main}, 0.32)`
|
||||
},
|
||||
'&:hover.Mui-error .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: theme.palette.error.main
|
||||
},
|
||||
'& .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: `rgba(${theme.palette.customColors.main}, 0.22)`
|
||||
},
|
||||
'&.Mui-disabled .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: theme.palette.text.disabled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default input
|
9
core/theme/overrides/link.ts
Normal file
9
core/theme/overrides/link.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export default {
|
||||
MuiLink: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
textDecoration: 'none'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
44
core/theme/overrides/list.ts
Normal file
44
core/theme/overrides/list.ts
Normal file
@ -0,0 +1,44 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const List = (theme: Theme) => {
|
||||
return {
|
||||
MuiListItemIcon: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
minWidth: 0,
|
||||
marginRight: theme.spacing(2.25),
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiListItemAvatar: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
minWidth: 0,
|
||||
marginRight: theme.spacing(4)
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiListItemText: {
|
||||
styleOverrides: {
|
||||
dense: {
|
||||
'& .MuiListItemText-primary': {
|
||||
color: theme.palette.text.primary
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiListSubheader: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
fontWeight: 600,
|
||||
textTransform: 'uppercase',
|
||||
color: theme.palette.text.primary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default List
|
19
core/theme/overrides/menu.ts
Normal file
19
core/theme/overrides/menu.ts
Normal file
@ -0,0 +1,19 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Menu = (theme: Theme) => {
|
||||
return {
|
||||
MuiMenu: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiMenu-paper': {
|
||||
borderRadius: 5,
|
||||
boxShadow: theme.palette.mode === 'light' ? theme.shadows[8] : theme.shadows[9]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Menu
|
41
core/theme/overrides/pagination.ts
Normal file
41
core/theme/overrides/pagination.ts
Normal file
@ -0,0 +1,41 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from '../../../core/utils/hex-to-rgba'
|
||||
|
||||
const Pagination = (theme: Theme) => {
|
||||
return {
|
||||
MuiPaginationItem: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&.Mui-selected:not(.Mui-disabled):not(.MuiPaginationItem-textPrimary):not(.MuiPaginationItem-textSecondary):hover':
|
||||
{
|
||||
backgroundColor: `rgba(${theme.palette.customColors.main}, 0.12)`
|
||||
}
|
||||
},
|
||||
outlined: {
|
||||
borderColor: `rgba(${theme.palette.customColors.main}, 0.22)`
|
||||
},
|
||||
outlinedPrimary: {
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: hexToRGBA(theme.palette.primary.main, 0.12),
|
||||
'&:hover': {
|
||||
backgroundColor: `${hexToRGBA(theme.palette.primary.main, 0.2)} !important`
|
||||
}
|
||||
}
|
||||
},
|
||||
outlinedSecondary: {
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: hexToRGBA(theme.palette.secondary.main, 0.12),
|
||||
'&:hover': {
|
||||
backgroundColor: `${hexToRGBA(theme.palette.secondary.main, 0.2)} !important`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Pagination
|
9
core/theme/overrides/paper.ts
Normal file
9
core/theme/overrides/paper.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export default {
|
||||
MuiPaper: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundImage: 'none'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
core/theme/overrides/popover.ts
Normal file
18
core/theme/overrides/popover.ts
Normal file
@ -0,0 +1,18 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Popover = (theme: Theme) => {
|
||||
return {
|
||||
MuiPopover: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiPopover-paper': {
|
||||
boxShadow: theme.shadows[6]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Popover
|
16
core/theme/overrides/rating.ts
Normal file
16
core/theme/overrides/rating.ts
Normal file
@ -0,0 +1,16 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Rating = (theme: Theme) => {
|
||||
return {
|
||||
MuiRating: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
color: theme.palette.warning.main
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Rating
|
12
core/theme/overrides/select.ts
Normal file
12
core/theme/overrides/select.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export default {
|
||||
MuiSelect: {
|
||||
styleOverrides: {
|
||||
select: {
|
||||
minWidth: '6rem !important',
|
||||
'&.MuiTablePagination-select': {
|
||||
minWidth: '1rem !important'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
16
core/theme/overrides/snackbar.ts
Normal file
16
core/theme/overrides/snackbar.ts
Normal file
@ -0,0 +1,16 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Snackbar = (theme: Theme) => {
|
||||
return {
|
||||
MuiSnackbarContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor: theme.palette.mode === 'light' ? theme.palette.grey[900] : theme.palette.grey[100]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Snackbar
|
18
core/theme/overrides/switches.ts
Normal file
18
core/theme/overrides/switches.ts
Normal file
@ -0,0 +1,18 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Switch = (theme: Theme) => {
|
||||
return {
|
||||
MuiSwitch: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiSwitch-track': {
|
||||
backgroundColor: `rgb(${theme.palette.customColors.main})`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Switch
|
69
core/theme/overrides/table.ts
Normal file
69
core/theme/overrides/table.ts
Normal file
@ -0,0 +1,69 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Table = (theme: Theme) => {
|
||||
return {
|
||||
MuiTableContainer: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
boxShadow: theme.shadows[0],
|
||||
borderTopColor: theme.palette.divider
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTableHead: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
textTransform: 'uppercase',
|
||||
'& .MuiTableCell-head': {
|
||||
fontSize: '0.75rem',
|
||||
fontWeight: 600,
|
||||
letterSpacing: '0.13px'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTableBody: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiTableCell-body': {
|
||||
letterSpacing: '0.25px',
|
||||
color: theme.palette.text.secondary,
|
||||
'&:not(.MuiTableCell-sizeSmall):not(.MuiTableCell-paddingCheckbox):not(.MuiTableCell-paddingNone)': {
|
||||
paddingTop: theme.spacing(3.5),
|
||||
paddingBottom: theme.spacing(3.5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTableRow: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiTableCell-head:first-child, & .MuiTableCell-root:first-child ': {
|
||||
paddingLeft: theme.spacing(5)
|
||||
},
|
||||
'& .MuiTableCell-head:last-child, & .MuiTableCell-root:last-child': {
|
||||
paddingRight: theme.spacing(5)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTableCell: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderBottom: `1px solid ${theme.palette.divider}`,
|
||||
'& .MuiButton-root': {
|
||||
textTransform: 'uppercase',
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
},
|
||||
stickyHeader: {
|
||||
backgroundColor: theme.palette.customColors.tableHeaderBg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Table
|
30
core/theme/overrides/tabs.ts
Normal file
30
core/theme/overrides/tabs.ts
Normal file
@ -0,0 +1,30 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Tabs = (theme: Theme) => {
|
||||
return {
|
||||
MuiTabs: {
|
||||
styleOverrides: {
|
||||
vertical: {
|
||||
minWidth: 130,
|
||||
marginRight: theme.spacing(4),
|
||||
borderRight: `1px solid ${theme.palette.divider}`,
|
||||
'& .MuiTab-root': {
|
||||
minWidth: 130
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTab: {
|
||||
styleOverrides: {
|
||||
textColorSecondary: {
|
||||
'&.Mui-selected': {
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Tabs
|
83
core/theme/overrides/timeline.ts
Normal file
83
core/theme/overrides/timeline.ts
Normal file
@ -0,0 +1,83 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from '../../../core/utils/hex-to-rgba'
|
||||
|
||||
const Timeline = (theme: Theme) => {
|
||||
return {
|
||||
MuiTimelineItem: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:not(:last-of-type)': {
|
||||
'& .MuiTimelineContent-root': {
|
||||
marginBottom: theme.spacing(4)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTimelineConnector: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor: theme.palette.divider
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTimelineContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
marginTop: theme.spacing(0.5)
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTimelineDot: {
|
||||
styleOverrides: {
|
||||
filledPrimary: {
|
||||
boxShadow: `0 0 0 3px ${hexToRGBA(theme.palette.primary.main, 0.12)}`
|
||||
},
|
||||
filledSecondary: {
|
||||
boxShadow: `0 0 0 3px ${hexToRGBA(theme.palette.secondary.main, 0.12)}`
|
||||
},
|
||||
filledSuccess: {
|
||||
boxShadow: `0 0 0 3px ${hexToRGBA(theme.palette.success.main, 0.12)}`
|
||||
},
|
||||
filledError: {
|
||||
boxShadow: `0 0 0 3px ${hexToRGBA(theme.palette.error.main, 0.12)}`
|
||||
},
|
||||
filledWarning: {
|
||||
boxShadow: `0 0 0 3px ${hexToRGBA(theme.palette.warning.main, 0.12)}`
|
||||
},
|
||||
filledInfo: {
|
||||
boxShadow: `0 0 0 3px ${hexToRGBA(theme.palette.info.main, 0.12)}`
|
||||
},
|
||||
filledGrey: {
|
||||
boxShadow: `0 0 0 3px ${hexToRGBA(theme.palette.grey[400], 0.12)}`
|
||||
},
|
||||
outlinedPrimary: {
|
||||
'& svg': { color: theme.palette.primary.main }
|
||||
},
|
||||
outlinedSecondary: {
|
||||
'& svg': { color: theme.palette.secondary.main }
|
||||
},
|
||||
outlinedSuccess: {
|
||||
'& svg': { color: theme.palette.success.main }
|
||||
},
|
||||
outlinedError: {
|
||||
'& svg': { color: theme.palette.error.main }
|
||||
},
|
||||
outlinedWarning: {
|
||||
'& svg': { color: theme.palette.warning.main }
|
||||
},
|
||||
outlinedInfo: {
|
||||
'& svg': { color: theme.palette.info.main }
|
||||
},
|
||||
outlinedGrey: {
|
||||
'& svg': { color: theme.palette.grey[500] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Timeline
|
16
core/theme/overrides/toggleButton.ts
Normal file
16
core/theme/overrides/toggleButton.ts
Normal file
@ -0,0 +1,16 @@
|
||||
export default {
|
||||
MuiToggleButtonGroup: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 4
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiToggleButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
core/theme/overrides/tooltip.ts
Normal file
28
core/theme/overrides/tooltip.ts
Normal file
@ -0,0 +1,28 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from '../../../core/utils/hex-to-rgba'
|
||||
|
||||
const Tooltip = (theme: Theme) => {
|
||||
return {
|
||||
MuiTooltip: {
|
||||
styleOverrides: {
|
||||
tooltip: {
|
||||
backgroundColor:
|
||||
theme.palette.mode === 'light'
|
||||
? hexToRGBA(theme.palette.grey[900], 0.9)
|
||||
: hexToRGBA(theme.palette.grey[700], 0.9)
|
||||
},
|
||||
arrow: {
|
||||
color:
|
||||
theme.palette.mode === 'light'
|
||||
? hexToRGBA(theme.palette.grey[900], 0.9)
|
||||
: hexToRGBA(theme.palette.grey[700], 0.9)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Tooltip
|
16
core/theme/overrides/typography.ts
Normal file
16
core/theme/overrides/typography.ts
Normal file
@ -0,0 +1,16 @@
|
||||
// ** MUI Imports
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Typography = (theme: Theme) => {
|
||||
return {
|
||||
MuiTypography: {
|
||||
styleOverrides: {
|
||||
gutterBottom: {
|
||||
marginBottom: theme.spacing(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Typography
|
111
core/theme/palette/index.ts
Normal file
111
core/theme/palette/index.ts
Normal file
@ -0,0 +1,111 @@
|
||||
// ** Type Imports
|
||||
import { PaletteMode } from '@mui/material'
|
||||
import { ThemeColor } from '../core/layouts/types'
|
||||
|
||||
const DefaultPalette = (mode: PaletteMode, themeColor: ThemeColor) => {
|
||||
// ** Vars
|
||||
const lightColor = '58, 53, 65'
|
||||
const darkColor = '231, 227, 252'
|
||||
const mainColor = mode === 'light' ? lightColor : darkColor
|
||||
|
||||
const primaryGradient = () => {
|
||||
if (themeColor === 'primary') {
|
||||
return '#C6A7FE'
|
||||
} else if (themeColor === 'secondary') {
|
||||
return '#9C9FA4'
|
||||
} else if (themeColor === 'success') {
|
||||
return '#93DD5C'
|
||||
} else if (themeColor === 'error') {
|
||||
return '#FF8C90'
|
||||
} else if (themeColor === 'warning') {
|
||||
return '#FFCF5C'
|
||||
} else {
|
||||
return '#6ACDFF'
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
customColors: {
|
||||
main: mainColor,
|
||||
primaryGradient: primaryGradient(),
|
||||
tableHeaderBg: mode === 'light' ? '#F9FAFC' : '#3D3759'
|
||||
},
|
||||
common: {
|
||||
black: '#000',
|
||||
white: '#FFF'
|
||||
},
|
||||
mode: mode,
|
||||
primary: {
|
||||
light: '#9E69FD',
|
||||
main: '#9155FD',
|
||||
dark: '#804BDF',
|
||||
contrastText: '#FFF'
|
||||
},
|
||||
secondary: {
|
||||
light: '#9C9FA4',
|
||||
main: '#8A8D93',
|
||||
dark: '#777B82',
|
||||
contrastText: '#FFF'
|
||||
},
|
||||
success: {
|
||||
light: '#6AD01F',
|
||||
main: '#56CA00',
|
||||
dark: '#4CB200',
|
||||
contrastText: '#FFF'
|
||||
},
|
||||
error: {
|
||||
light: '#FF6166',
|
||||
main: '#FF4C51',
|
||||
dark: '#E04347',
|
||||
contrastText: '#FFF'
|
||||
},
|
||||
warning: {
|
||||
light: '#FFCA64',
|
||||
main: '#FFB400',
|
||||
dark: '#E09E00',
|
||||
contrastText: '#FFF'
|
||||
},
|
||||
info: {
|
||||
light: '#32BAFF',
|
||||
main: '#16B1FF',
|
||||
dark: '#139CE0',
|
||||
contrastText: '#FFF'
|
||||
},
|
||||
grey: {
|
||||
50: '#FAFAFA',
|
||||
100: '#F5F5F5',
|
||||
200: '#EEEEEE',
|
||||
300: '#E0E0E0',
|
||||
400: '#BDBDBD',
|
||||
500: '#9E9E9E',
|
||||
600: '#757575',
|
||||
700: '#616161',
|
||||
800: '#424242',
|
||||
900: '#212121',
|
||||
A100: '#D5D5D5',
|
||||
A200: '#AAAAAA',
|
||||
A400: '#616161',
|
||||
A700: '#303030'
|
||||
},
|
||||
text: {
|
||||
primary: `rgba(${mainColor}, 0.87)`,
|
||||
secondary: `rgba(${mainColor}, 0.68)`,
|
||||
disabled: `rgba(${mainColor}, 0.38)`
|
||||
},
|
||||
divider: `rgba(${mainColor}, 0.12)`,
|
||||
background: {
|
||||
paper: mode === 'light' ? '#FFF' : '#312D4B',
|
||||
default: mode === 'light' ? '#F4F5FA' : '#28243D'
|
||||
},
|
||||
action: {
|
||||
active: `rgba(${mainColor}, 0.54)`,
|
||||
hover: `rgba(${mainColor}, 0.04)`,
|
||||
selected: `rgba(${mainColor}, 0.08)`,
|
||||
disabled: `rgba(${mainColor}, 0.3)`,
|
||||
disabledBackground: `rgba(${mainColor}, 0.18)`,
|
||||
focus: `rgba(${mainColor}, 0.12)`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default DefaultPalette
|
63
core/theme/shadows/index.ts
Normal file
63
core/theme/shadows/index.ts
Normal file
@ -0,0 +1,63 @@
|
||||
// ** Theme Type Import
|
||||
import { PaletteMode, ThemeOptions } from '@mui/material'
|
||||
|
||||
const Shadows = (mode: PaletteMode): ThemeOptions['shadows'] => {
|
||||
if (mode === 'light') {
|
||||
return [
|
||||
'none',
|
||||
'0px 2px 1px -1px rgba(58, 53, 65, 0.2), 0px 1px 1px 0px rgba(58, 53, 65, 0.14), 0px 1px 3px 0px rgba(58, 53, 65, 0.12)',
|
||||
'0px 3px 1px -2px rgba(58, 53, 65, 0.2), 0px 2px 2px 0px rgba(58, 53, 65, 0.14), 0px 1px 5px 0px rgba(58, 53, 65, 0.12)',
|
||||
'0px 4px 8px -4px rgba(58, 53, 65, 0.42)',
|
||||
'0px 6px 18px -8px rgba(58, 53, 65, 0.56)',
|
||||
'0px 3px 5px -1px rgba(58, 53, 65, 0.2), 0px 5px 8px 0px rgba(58, 53, 65, 0.14), 0px 1px 14px 0px rgba(58, 53, 65, 0.12)',
|
||||
'0px 2px 10px 0px rgba(58, 53, 65, 0.1)',
|
||||
'0px 4px 5px -2px rgba(58, 53, 65, 0.2), 0px 7px 10px 1px rgba(58, 53, 65, 0.14), 0px 2px 16px 1px rgba(58, 53, 65, 0.12)',
|
||||
'0px 5px 5px -3px rgba(58, 53, 65, 0.2), 0px 8px 10px 1px rgba(58, 53, 65, 0.14), 0px 3px 14px 2px rgba(58, 53, 65, 0.12)',
|
||||
'0px 5px 6px -3px rgba(58, 53, 65, 0.2), 0px 9px 12px 1px rgba(58, 53, 65, 0.14), 0px 3px 16px 2px rgba(58, 53, 65, 0.12)',
|
||||
'0px 6px 6px -3px rgba(58, 53, 65, 0.2), 0px 10px 14px 1px rgba(58, 53, 65, 0.14), 0px 4px 18px 3px rgba(58, 53, 65, 0.12)',
|
||||
'0px 6px 7px -4px rgba(58, 53, 65, 0.2), 0px 11px 15px 1px rgba(58, 53, 65, 0.14), 0px 4px 20px 3px rgba(58, 53, 65, 0.12)',
|
||||
'0px 7px 8px -4px rgba(58, 53, 65, 0.2), 0px 12px 17px 2px rgba(58, 53, 65, 0.14), 0px 5px 22px 4px rgba(58, 53, 65, 0.12)',
|
||||
'0px 7px 8px -4px rgba(58, 53, 65, 0.2), 0px 13px 19px 2px rgba(58, 53, 65, 0.14), 0px 5px 24px 4px rgba(58, 53, 65, 0.12)',
|
||||
'0px 7px 9px -4px rgba(58, 53, 65, 0.2), 0px 14px 21px 2px rgba(58, 53, 65, 0.14), 0px 5px 26px 4px rgba(58, 53, 65, 0.12)',
|
||||
'0px 8px 9px -5px rgba(58, 53, 65, 0.2), 0px 15px 22px 2px rgba(58, 53, 65, 0.14), 0px 6px 28px 5px rgba(58, 53, 65, 0.12)',
|
||||
'0px 8px 10px -5px rgba(58, 53, 65, 0.2), 0px 16px 24px 2px rgba(58, 53, 65, 0.14), 0px 6px 30px 5px rgba(58, 53, 65, 0.12)',
|
||||
'0px 8px 11px -5px rgba(58, 53, 65, 0.2), 0px 17px 26px 2px rgba(58, 53, 65, 0.14), 0px 6px 32px 5px rgba(58, 53, 65, 0.12)',
|
||||
'0px 9px 11px -5px rgba(58, 53, 65, 0.2), 0px 18px 28px 2px rgba(58, 53, 65, 0.14), 0px 7px 34px 6px rgba(58, 53, 65, 0.12)',
|
||||
'0px 9px 12px -6px rgba(58, 53, 65, 0.2), 0px 19px 29px 2px rgba(58, 53, 65, 0.14), 0px 7px 36px 6px rgba(58, 53, 65, 0.12)',
|
||||
'0px 10px 13px -6px rgba(58, 53, 65, 0.2), 0px 20px 31px 3px rgba(58, 53, 65, 0.14), 0px 8px 38px 7px rgba(58, 53, 65, 0.12)',
|
||||
'0px 10px 13px -6px rgba(58, 53, 65, 0.2), 0px 21px 33px 3px rgba(58, 53, 65, 0.14), 0px 8px 40px 7px rgba(58, 53, 65, 0.12)',
|
||||
'0px 10px 14px -6px rgba(58, 53, 65, 0.2), 0px 22px 35px 3px rgba(58, 53, 65, 0.14), 0px 8px 42px 7px rgba(58, 53, 65, 0.12)',
|
||||
'0px 11px 14px -7px rgba(58, 53, 65, 0.2), 0px 23px 36px 3px rgba(58, 53, 65, 0.14), 0px 9px 44px 8px rgba(58, 53, 65, 0.12)',
|
||||
'0px 11px 15px -7px rgba(58, 53, 65, 0.2), 0px 24px 38px 3px rgba(58, 53, 65, 0.14), 0px 9px 46px 8px rgba(58, 53, 65, 0.12)'
|
||||
]
|
||||
} else {
|
||||
return [
|
||||
'none',
|
||||
'0px 2px 1px -1px rgba(19, 17, 32, 0.2), 0px 1px 1px 0px rgba(19, 17, 32, 0.14), 0px 1px 3px 0px rgba(19, 17, 32, 0.12)',
|
||||
'0px 3px 1px -2px rgba(19, 17, 32, 0.2), 0px 2px 2px 0px rgba(19, 17, 32, 0.14), 0px 1px 5px 0px rgba(19, 17, 32, 0.12)',
|
||||
'0px 4px 8px -4px rgba(19, 17, 32, 0.42)',
|
||||
'0px 6px 18px -8px rgba(19, 17, 32, 0.56)',
|
||||
'0px 3px 5px -1px rgba(19, 17, 32, 0.2), 0px 5px 8px rgba(19, 17, 32, 0.14), 0px 1px 14px rgba(19, 17, 32, 0.12)',
|
||||
'0px 2px 10px 0px rgba(19, 17, 32, 0.1)',
|
||||
'0px 4px 5px -2px rgba(19, 17, 32, 0.2), 0px 7px 10px 1px rgba(19, 17, 32, 0.14), 0px 2px 16px 1px rgba(19, 17, 32, 0.12)',
|
||||
'0px 5px 5px -3px rgba(19, 17, 32, 0.2), 0px 8px 10px 1px rgba(19, 17, 32, 0.14), 0px 3px 14px 2px rgba(19, 17, 32, 0.12)',
|
||||
'0px 5px 6px -3px rgba(19, 17, 32, 0.2), 0px 9px 12px 1px rgba(19, 17, 32, 0.14), 0px 3px 16px 2px rgba(19, 17, 32, 0.12)',
|
||||
'0px 6px 6px -3px rgba(19, 17, 32, 0.2), 0px 10px 14px 1px rgba(19, 17, 32, 0.14), 0px 4px 18px 3px rgba(19, 17, 32, 0.12)',
|
||||
'0px 6px 7px -4px rgba(19, 17, 32, 0.2), 0px 11px 15px 1px rgba(19, 17, 32, 0.14), 0px 4px 20px 3px rgba(19, 17, 32, 0.12)',
|
||||
'0px 7px 8px -4px rgba(19, 17, 32, 0.2), 0px 12px 17px 2px rgba(19, 17, 32, 0.14), 0px 5px 22px 4px rgba(19, 17, 32, 0.12)',
|
||||
'0px 7px 8px -4px rgba(19, 17, 32, 0.2), 0px 13px 19px 2px rgba(19, 17, 32, 0.14), 0px 5px 24px 4px rgba(19, 17, 32, 0.12)',
|
||||
'0px 7px 9px -4px rgba(19, 17, 32, 0.2), 0px 14px 21px 2px rgba(19, 17, 32, 0.14), 0px 5px 26px 4px rgba(19, 17, 32, 0.12)',
|
||||
'0px 8px 9px -5px rgba(19, 17, 32, 0.2), 0px 15px 22px 2px rgba(19, 17, 32, 0.14), 0px 6px 28px 5px rgba(19, 17, 32, 0.12)',
|
||||
'0px 8px 10px -5px rgba(19, 17, 32, 0.2), 0px 16px 24px 2px rgba(19, 17, 32, 0.14), 0px 6px 30px 5px rgba(19, 17, 32, 0.12)',
|
||||
'0px 8px 11px -5px rgba(19, 17, 32, 0.2), 0px 17px 26px 2px rgba(19, 17, 32, 0.14), 0px 6px 32px 5px rgba(19, 17, 32, 0.12)',
|
||||
'0px 9px 11px -5px rgba(19, 17, 32, 0.2), 0px 18px 28px 2px rgba(19, 17, 32, 0.14), 0px 7px 34px 6px rgba(19, 17, 32, 0.12)',
|
||||
'0px 9px 12px -6px rgba(19, 17, 32, 0.2), 0px 19px 29px 2px rgba(19, 17, 32, 0.14), 0px 7px 36px 6px rgba(19, 17, 32, 0.12)',
|
||||
'0px 10px 13px -6px rgba(19, 17, 32, 0.2), 0px 20px 31px 3px rgba(19, 17, 32, 0.14), 0px 8px 38px 7px rgba(19, 17, 32, 0.12)',
|
||||
'0px 10px 13px -6px rgba(19, 17, 32, 0.2), 0px 21px 33px 3px rgba(19, 17, 32, 0.14), 0px 8px 40px 7px rgba(19, 17, 32, 0.12)',
|
||||
'0px 10px 14px -6px rgba(19, 17, 32, 0.2), 0px 22px 35px 3px rgba(19, 17, 32, 0.14), 0px 8px 42px 7px rgba(19, 17, 32, 0.12)',
|
||||
'0px 11px 14px -7px rgba(19, 17, 32, 0.2), 0px 23px 36px 3px rgba(19, 17, 32, 0.14), 0px 9px 44px 8px rgba(19, 17, 32, 0.12)',
|
||||
'0px 11px 15px -7px rgba(19, 17, 32, 0.2), 0px 24px 38px 3px rgba(19, 17, 32, 0.14), 0px 9px 46px 8px rgba(19, 17, 32, 0.12)'
|
||||
]
|
||||
}
|
||||
}
|
||||
export default Shadows
|
3
core/theme/spacing/index.ts
Normal file
3
core/theme/spacing/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
spacing: (factor: number) => `${0.25 * factor}rem`
|
||||
}
|
18
core/theme/types.ts
Normal file
18
core/theme/types.ts
Normal file
@ -0,0 +1,18 @@
|
||||
declare module '@mui/material/styles' {
|
||||
interface Palette {
|
||||
customColors: {
|
||||
main: string
|
||||
tableHeaderBg: string
|
||||
primaryGradient: string
|
||||
}
|
||||
}
|
||||
interface PaletteOptions {
|
||||
customColors?: {
|
||||
main?: string
|
||||
tableHeaderBg?: string
|
||||
primaryGradient?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {}
|
67
core/theme/typography/index.ts
Normal file
67
core/theme/typography/index.ts
Normal file
@ -0,0 +1,67 @@
|
||||
// ** Theme Type Import
|
||||
import { Theme } from '@mui/material/styles'
|
||||
|
||||
const Typography = (theme: Theme) => {
|
||||
return {
|
||||
h1: {
|
||||
fontWeight: 500,
|
||||
letterSpacing: '-1.5px',
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
h2: {
|
||||
fontWeight: 500,
|
||||
letterSpacing: '-0.5px',
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
h3: {
|
||||
fontWeight: 500,
|
||||
letterSpacing: 0,
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
h4: {
|
||||
fontWeight: 500,
|
||||
letterSpacing: '0.25px',
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
h5: {
|
||||
fontWeight: 500,
|
||||
letterSpacing: 0,
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
h6: {
|
||||
letterSpacing: '0.15px',
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
subtitle1: {
|
||||
letterSpacing: '0.15px',
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
subtitle2: {
|
||||
letterSpacing: '0.1px',
|
||||
color: theme.palette.text.secondary
|
||||
},
|
||||
body1: {
|
||||
letterSpacing: '0.15px',
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
body2: {
|
||||
lineHeight: 1.5,
|
||||
letterSpacing: '0.15px',
|
||||
color: theme.palette.text.secondary
|
||||
},
|
||||
button: {
|
||||
letterSpacing: '0.3px',
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
caption: {
|
||||
letterSpacing: '0.4px',
|
||||
color: theme.palette.text.secondary
|
||||
},
|
||||
overline: {
|
||||
letterSpacing: '1px',
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Typography
|
5
core/utils/create-emotion-cache.ts
Normal file
5
core/utils/create-emotion-cache.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import createCache from '@emotion/cache'
|
||||
|
||||
export const createEmotionCache = () => {
|
||||
return createCache({ key: 'css' })
|
||||
}
|
16
core/utils/hex-to-rgba.ts
Normal file
16
core/utils/hex-to-rgba.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
** Hex color to RGBA color
|
||||
*/
|
||||
export const hexToRGBA = (hexCode: string, opacity: number) => {
|
||||
let hex = hexCode.replace('#', '')
|
||||
|
||||
if (hex.length === 3) {
|
||||
hex = `${hex[0]}${hex[0]}${hex[1]}${hex[1]}${hex[2]}${hex[2]}`
|
||||
}
|
||||
|
||||
const r = parseInt(hex.substring(0, 2), 16)
|
||||
const g = parseInt(hex.substring(2, 4), 16)
|
||||
const b = parseInt(hex.substring(4, 6), 16)
|
||||
|
||||
return `rgba(${r}, ${g}, ${b}, ${opacity})`
|
||||
}
|
77
layouts/UserLayout.tsx
Normal file
77
layouts/UserLayout.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import { Theme } from '@mui/material/styles'
|
||||
import useMediaQuery from '@mui/material/useMediaQuery'
|
||||
|
||||
// ** Layout Imports
|
||||
// !Do not remove this Layout import
|
||||
import VerticalLayout from '../core/layouts/VerticalLayout'
|
||||
|
||||
// ** Navigation Imports
|
||||
import VerticalNavItems from '../navigation/vertical'
|
||||
|
||||
// ** Component Import
|
||||
import UpgradeToProButton from './components/UpgradeToProButton'
|
||||
import VerticalAppBarContent from './components/vertical/AppBarContent'
|
||||
|
||||
// ** Hook Import
|
||||
import { useSettings } from '../core/hooks/useSettings'
|
||||
|
||||
interface Props {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const UserLayout = ({ children }: Props) => {
|
||||
// ** Hooks
|
||||
const { settings, saveSettings } = useSettings()
|
||||
|
||||
/**
|
||||
* The below variable will hide the current layout menu at given screen size.
|
||||
* The menu will be accessible from the Hamburger icon only (Vertical Overlay Menu).
|
||||
* You can change the screen size from which you want to hide the current layout menu.
|
||||
* Please refer useMediaQuery() hook: https://mui.com/components/use-media-query/,
|
||||
* to know more about what values can be passed to this hook.
|
||||
* ! Do not change this value unless you know what you are doing. It can break the template.
|
||||
*/
|
||||
const hidden = useMediaQuery((theme: Theme) => theme.breakpoints.down('lg'))
|
||||
|
||||
const UpgradeToProImg = () => {
|
||||
return (
|
||||
<Box sx={{ mx: 'auto' }}>
|
||||
<a
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
href='https://themeselection.com/products/materio-mui-react-nextjs-admin-template/'
|
||||
>
|
||||
<img width={230} alt='upgrade to premium' src={`/images/misc/upgrade-banner-${settings.mode}.png`} />
|
||||
</a>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<VerticalLayout
|
||||
hidden={hidden}
|
||||
settings={settings}
|
||||
saveSettings={saveSettings}
|
||||
verticalNavItems={VerticalNavItems()} // Navigation Items
|
||||
verticalAppBarContent={(
|
||||
props // AppBar Content
|
||||
) => (
|
||||
<VerticalAppBarContent
|
||||
hidden={hidden}
|
||||
settings={settings}
|
||||
saveSettings={saveSettings}
|
||||
toggleNavVisibility={props.toggleNavVisibility}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</VerticalLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default UserLayout
|
111
layouts/components/UpgradeToProButton.tsx
Normal file
111
layouts/components/UpgradeToProButton.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
// ** React Import
|
||||
import { useState } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Fade from '@mui/material/Fade'
|
||||
import Paper from '@mui/material/Paper'
|
||||
import Button from '@mui/material/Button'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
|
||||
// ** Third Party Imports
|
||||
import { usePopper } from 'react-popper'
|
||||
|
||||
const BuyNowButton = () => {
|
||||
// ** States
|
||||
const [open, setOpen] = useState<boolean>(false)
|
||||
const [popperElement, setPopperElement] = useState(null)
|
||||
const [referenceElement, setReferenceElement] = useState(null)
|
||||
|
||||
const { styles, attributes, update } = usePopper(referenceElement, popperElement, {
|
||||
placement: 'top-end'
|
||||
})
|
||||
|
||||
const handleOpen = () => {
|
||||
setOpen(true)
|
||||
update ? update() : null
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
className='upgrade-to-pro-button mui-fixed'
|
||||
sx={{ right: theme => theme.spacing(20), bottom: theme => theme.spacing(10), zIndex: 11, position: 'fixed' }}
|
||||
>
|
||||
<Button
|
||||
component='a'
|
||||
target='_blank'
|
||||
variant='contained'
|
||||
onMouseEnter={handleOpen}
|
||||
onMouseLeave={handleClose}
|
||||
ref={(e: any) => setReferenceElement(e)}
|
||||
href='https://themeselection.com/products/materio-mui-react-nextjs-admin-template/'
|
||||
sx={{
|
||||
backgroundColor: '#ff3e1d',
|
||||
boxShadow: '0 1px 20px 1px #ff3e1d',
|
||||
'&:hover': {
|
||||
boxShadow: 'none',
|
||||
backgroundColor: '#e6381a'
|
||||
}
|
||||
}}
|
||||
>
|
||||
Upgrade To Pro
|
||||
</Button>
|
||||
<Fade in={open} timeout={700}>
|
||||
<Box
|
||||
style={styles.popper}
|
||||
ref={setPopperElement}
|
||||
{...attributes.popper}
|
||||
onMouseEnter={handleOpen}
|
||||
onMouseLeave={handleClose}
|
||||
sx={{ pb: 4, minWidth: theme => (theme.breakpoints.down('sm') ? 400 : 300) }}
|
||||
>
|
||||
<Paper elevation={9} sx={{ borderRadius: 1, overflow: 'hidden' }}>
|
||||
<a
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
href='https://themeselection.com/products/materio-mui-react-nextjs-admin-template/'
|
||||
>
|
||||
<img width='100%' alt='materio-pro-banner' src='/images/misc/materio-pro-banner.png' />
|
||||
</a>
|
||||
<CardContent>
|
||||
<Typography sx={{ mb: 4 }} variant='h6'>
|
||||
Materio - React Admin Template
|
||||
</Typography>
|
||||
<Typography sx={{ mb: 4 }} variant='body2'>
|
||||
Materio Admin is the most developer friendly & highly customizable Admin Dashboard Template based on MUI
|
||||
and NextJS.
|
||||
</Typography>
|
||||
<Typography sx={{ mb: 4 }} variant='body2'>
|
||||
Click on below buttons to explore PRO version.
|
||||
</Typography>
|
||||
<Button
|
||||
component='a'
|
||||
sx={{ mr: 4 }}
|
||||
target='_blank'
|
||||
variant='contained'
|
||||
href='https://demos.themeselection.com/materio-mui-react-nextjs-admin-template/landing/'
|
||||
>
|
||||
Demo
|
||||
</Button>
|
||||
<Button
|
||||
component='a'
|
||||
target='_blank'
|
||||
variant='outlined'
|
||||
href='https://themeselection.com/products/materio-mui-react-nextjs-admin-template/'
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Fade>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default BuyNowButton
|
29
layouts/components/UserIcon.tsx
Normal file
29
layouts/components/UserIcon.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import { SvgIconProps } from '@mui/material'
|
||||
|
||||
interface UserIconProps {
|
||||
iconProps?: SvgIconProps
|
||||
icon: string | ReactNode
|
||||
}
|
||||
|
||||
const UserIcon = (props: UserIconProps) => {
|
||||
// ** Props
|
||||
const { icon, iconProps } = props
|
||||
|
||||
const IconTag = icon
|
||||
|
||||
let styles
|
||||
|
||||
/* styles = {
|
||||
color: 'red',
|
||||
fontSize: '2rem'
|
||||
} */
|
||||
|
||||
// @ts-ignore
|
||||
return <IconTag {...iconProps} style={{ ...styles }} />
|
||||
}
|
||||
|
||||
export default UserIcon
|
79
layouts/components/vertical/AppBarContent.tsx
Normal file
79
layouts/components/vertical/AppBarContent.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import { Theme } from '@mui/material/styles'
|
||||
import TextField from '@mui/material/TextField'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import useMediaQuery from '@mui/material/useMediaQuery'
|
||||
import InputAdornment from '@mui/material/InputAdornment'
|
||||
import {
|
||||
NovuProvider,
|
||||
PopoverNotificationCenter,
|
||||
NotificationBell,
|
||||
} from '@novu/notification-center';
|
||||
|
||||
|
||||
// ** Icons Imports
|
||||
import Menu from 'mdi-material-ui/Menu'
|
||||
import Magnify from 'mdi-material-ui/Magnify'
|
||||
|
||||
// ** Type Import
|
||||
import { Settings } from '../../../core/context/settingsContext'
|
||||
|
||||
// ** Components
|
||||
import ModeToggler from '../../../core/layouts/components/shared-components/ModeToggler'
|
||||
import UserDropdown from '../../../core/layouts/components/shared-components/UserDropdown'
|
||||
import NotificationDropdown from '../../../core/layouts/components/shared-components/NotificationDropdown'
|
||||
|
||||
interface Props {
|
||||
hidden: boolean
|
||||
settings: Settings
|
||||
toggleNavVisibility: () => void
|
||||
saveSettings: (values: Settings) => void
|
||||
}
|
||||
|
||||
const AppBarContent = (props: Props) => {
|
||||
// ** Props
|
||||
const { hidden, settings, saveSettings, toggleNavVisibility } = props
|
||||
|
||||
// ** Hook
|
||||
const hiddenSm = useMediaQuery((theme: Theme) => theme.breakpoints.down('sm'))
|
||||
|
||||
return (
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<Box className='actions-left' sx={{ mr: 2, display: 'flex', alignItems: 'center' }}>
|
||||
{hidden ? (
|
||||
<IconButton
|
||||
color='inherit'
|
||||
onClick={toggleNavVisibility}
|
||||
sx={{ ml: -2.75, ...(hiddenSm ? {} : { mr: 3.5 }) }}
|
||||
>
|
||||
<Menu />
|
||||
</IconButton>
|
||||
) : null}
|
||||
<TextField
|
||||
size='small'
|
||||
sx={{ '& .MuiOutlinedInput-root': { borderRadius: 4 } }}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position='start'>
|
||||
<Magnify fontSize='small' />
|
||||
</InputAdornment>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<Box className='actions-right' sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<ModeToggler settings={settings} saveSettings={saveSettings} />
|
||||
|
||||
<NovuProvider subscriberId={'on-boarding-subscriber-id-123'} applicationIdentifier={'9SKjzgN_odAF'}>
|
||||
<PopoverNotificationCenter colorScheme={'light'}>
|
||||
{({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
|
||||
</PopoverNotificationCenter>
|
||||
</NovuProvider>
|
||||
<UserDropdown />
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default AppBarContent
|
82
navigation/vertical/index.ts
Normal file
82
navigation/vertical/index.ts
Normal file
@ -0,0 +1,82 @@
|
||||
// ** Icon imports
|
||||
import Login from 'mdi-material-ui/Login'
|
||||
import Table from 'mdi-material-ui/Table'
|
||||
import CubeOutline from 'mdi-material-ui/CubeOutline'
|
||||
import HomeOutline from 'mdi-material-ui/HomeOutline'
|
||||
import FormatLetterCase from 'mdi-material-ui/FormatLetterCase'
|
||||
import AccountCogOutline from 'mdi-material-ui/AccountCogOutline'
|
||||
import CreditCardOutline from 'mdi-material-ui/CreditCardOutline'
|
||||
import AccountPlusOutline from 'mdi-material-ui/AccountPlusOutline'
|
||||
import AlertCircleOutline from 'mdi-material-ui/AlertCircleOutline'
|
||||
import GoogleCirclesExtended from 'mdi-material-ui/GoogleCirclesExtended'
|
||||
|
||||
// ** Type import
|
||||
import { VerticalNavItemsType } from '../../core/layouts/types'
|
||||
import { BankTransfer, PageFirst } from 'mdi-material-ui'
|
||||
import { DocumentScanner, FileOpen, Settings } from '@mui/icons-material'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
const navigation = (): VerticalNavItemsType => {
|
||||
const [isStripeOnboarded, setIsStripeOnboarded] = useState(false);
|
||||
|
||||
const getData = async () => {
|
||||
const onboardCheckRequest = await fetch('/api/artist/onboarded', { method: "GET" });
|
||||
const onboardCheckResponse = await onboardCheckRequest.json();
|
||||
setIsStripeOnboarded(onboardCheckResponse["onboarded"]);
|
||||
}
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
|
||||
if(isStripeOnboarded){
|
||||
|
||||
return [
|
||||
{
|
||||
sectionTitle: 'General'
|
||||
},
|
||||
{
|
||||
title: 'Dashboard',
|
||||
icon: HomeOutline,
|
||||
path: '/dashboard'
|
||||
},
|
||||
{
|
||||
title: 'Account Settings',
|
||||
icon: Settings,
|
||||
path: '/artist/settings'
|
||||
},
|
||||
{
|
||||
sectionTitle: 'Artist'
|
||||
},
|
||||
{
|
||||
title: 'Payout Portal',
|
||||
icon: BankTransfer,
|
||||
path: '/payoutportal'
|
||||
},
|
||||
{
|
||||
title: 'Page Settings',
|
||||
icon: DocumentScanner,
|
||||
path: '/dashboard/artist/pagesettings'
|
||||
},
|
||||
{
|
||||
title: 'Preview Page',
|
||||
icon: FileOpen,
|
||||
path: '/artist/pagesettings'
|
||||
}
|
||||
]
|
||||
}
|
||||
else{
|
||||
|
||||
return [
|
||||
{
|
||||
sectionTitle: 'General'
|
||||
},
|
||||
{
|
||||
title: 'Dashboard',
|
||||
icon: HomeOutline,
|
||||
path: '/dashboard'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default navigation
|
432
package-lock.json
generated
432
package-lock.json
generated
@ -7,6 +7,7 @@
|
||||
"dependencies": {
|
||||
"@auth0/nextjs-auth0": "^2.2.0",
|
||||
"@emotion/react": "^11.11.3",
|
||||
"@emotion/server": "^11.11.0",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@fontsource/roboto": "^5.0.8",
|
||||
"@lupus-ai/mui-currency-textfield": "^1.0.3",
|
||||
@ -16,12 +17,20 @@
|
||||
"@mui/x-data-grid": "^6.19.4",
|
||||
"@mui/x-date-pickers": "^6.19.4",
|
||||
"@novu/notification-center": "^0.22.0",
|
||||
"apexcharts": "^3.45.2",
|
||||
"dayjs": "^1.11.10",
|
||||
"formidable": "^3.5.1",
|
||||
"mdi-material-ui": "^7.8.0",
|
||||
"mui-color-input": "^2.0.2",
|
||||
"next": "latest",
|
||||
"nprogress": "^0.2.0",
|
||||
"openapi-typescript-fetch": "^1.1.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-apexcharts": "^1.4.1",
|
||||
"react-datepicker": "^6.1.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-perfect-scrollbar": "^1.5.8",
|
||||
"react-popper": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.0.0",
|
||||
@ -128,6 +137,14 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ctrl/tinycolor": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.0.3.tgz",
|
||||
"integrity": "sha512-e9nEVehVJwkymQpkGhdSNzLT2Lr9UTTby+JePq4Z2SxBbOQjY7pLgSouAaXvfaGQVSAaY0U4eJdwfSDmCbItcw==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin": {
|
||||
"version": "11.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
|
||||
@ -223,6 +240,25 @@
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/server": {
|
||||
"version": "11.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/server/-/server-11.11.0.tgz",
|
||||
"integrity": "sha512-6q89fj2z8VBTx9w93kJ5n51hsmtYuFPtZgnc1L8VzRx9ti4EU6EyvF6Nn1H1x3vcCQCF7u2dB2lY4AYJwUW4PA==",
|
||||
"dependencies": {
|
||||
"@emotion/utils": "^1.2.1",
|
||||
"html-tokenize": "^2.0.0",
|
||||
"multipipe": "^1.0.2",
|
||||
"through": "^2.3.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/css": "^11.0.0-rc.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@emotion/css": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/sheet": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
|
||||
@ -1290,6 +1326,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.8.tgz",
|
||||
"integrity": "sha512-c/hzNDBh7eRF+KbCf+OoZxKbnkpaK/cKp9iLQWqB7muXtM+MtL9SUUH8vCFcLn6dH1Qm05jiexK0ofWY7TfOhQ=="
|
||||
},
|
||||
"node_modules/@yr/monotone-cubic-spline": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
|
||||
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.11.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
@ -1321,6 +1362,20 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/apexcharts": {
|
||||
"version": "3.45.2",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.45.2.tgz",
|
||||
"integrity": "sha512-PpuM4sJWy70sUh5U1IFn1m1p45MdHSChLUNnqEoUUUHSU2IHZugFrsVNhov1S8Q0cvfdrCRCvdBtHGSs6PSAWQ==",
|
||||
"dependencies": {
|
||||
"@yr/monotone-cubic-spline": "^1.0.3",
|
||||
"svg.draggable.js": "^2.2.2",
|
||||
"svg.easing.js": "^2.0.0",
|
||||
"svg.filter.js": "^2.0.2",
|
||||
"svg.pathmorphing.js": "^0.1.3",
|
||||
"svg.resize.js": "^1.4.3",
|
||||
"svg.select.js": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/aria-hidden": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
|
||||
@ -1375,6 +1430,11 @@
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz",
|
||||
"integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg=="
|
||||
},
|
||||
"node_modules/busboy": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||
@ -1449,6 +1509,11 @@
|
||||
"validator": "^13.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
|
||||
},
|
||||
"node_modules/client-only": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||
@ -1499,6 +1564,11 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
|
||||
},
|
||||
"node_modules/cosmiconfig": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
|
||||
@ -1519,6 +1589,15 @@
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.3.1.tgz",
|
||||
"integrity": "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/kossnocorp"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.10",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
|
||||
@ -1574,6 +1653,41 @@
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/duplexer2": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
|
||||
"integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
|
||||
"dependencies": {
|
||||
"readable-stream": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/duplexer2/node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
|
||||
},
|
||||
"node_modules/duplexer2/node_modules/readable-stream": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/duplexer2/node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-client": {
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz",
|
||||
@ -1716,6 +1830,21 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/html-tokenize": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/html-tokenize/-/html-tokenize-2.0.1.tgz",
|
||||
"integrity": "sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w==",
|
||||
"dependencies": {
|
||||
"buffer-from": "~0.1.1",
|
||||
"inherits": "~2.0.1",
|
||||
"minimist": "~1.2.5",
|
||||
"readable-stream": "~1.0.27-1",
|
||||
"through2": "~0.4.1"
|
||||
},
|
||||
"bin": {
|
||||
"html-tokenize": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
|
||||
@ -1767,6 +1896,11 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
|
||||
},
|
||||
"node_modules/joi": {
|
||||
"version": "17.12.1",
|
||||
"resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz",
|
||||
@ -1844,6 +1978,15 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/mdi-material-ui": {
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/mdi-material-ui/-/mdi-material-ui-7.8.0.tgz",
|
||||
"integrity": "sha512-jLZKGDZ94Mav4c3r8Cyehqs1dHOviXuIm7vGGCIyxIf4UsWNiveQTCoCrKG2K63IWCHcMg0EfjLFqh4LGaYvoQ==",
|
||||
"peerDependencies": {
|
||||
"@mui/material": "^5.0.0 || ^5.0.0-rc.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
@ -1863,11 +2006,49 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/mui-color-input": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/mui-color-input/-/mui-color-input-2.0.2.tgz",
|
||||
"integrity": "sha512-jDwoX7j8C6Q10Kr1fRB2HCqm4VS1Q97PZnPd/2sIH3R9B+yNzhyCYFQsJj/CdV1jte2UudUOopLiJkeBZCK5WQ==",
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^4.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.5.0",
|
||||
"@emotion/styled": "^11.3.0",
|
||||
"@mui/material": "^5.0.0",
|
||||
"@types/react": "^18.0.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/multipipe": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/multipipe/-/multipipe-1.0.2.tgz",
|
||||
"integrity": "sha512-6uiC9OvY71vzSGX8lZvSqscE7ft9nPupJ8fMjrCNRAUy2LREUW42UL+V/NTrogr6rFgRydUrCX4ZitfpSNkSCQ==",
|
||||
"dependencies": {
|
||||
"duplexer2": "^0.1.2",
|
||||
"object-assign": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.7",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
||||
@ -1930,6 +2111,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/nprogress": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
|
||||
"integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@ -1946,6 +2132,11 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/object-keys": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
|
||||
"integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw=="
|
||||
},
|
||||
"node_modules/oidc-token-hash": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz",
|
||||
@ -2026,6 +2217,11 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/perfect-scrollbar": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.5.tgz",
|
||||
"integrity": "sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g=="
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
@ -2058,6 +2254,11 @@
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
@ -2089,6 +2290,48 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-apexcharts": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz",
|
||||
"integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"apexcharts": "^3.41.0",
|
||||
"react": ">=0.13"
|
||||
}
|
||||
},
|
||||
"node_modules/react-datepicker": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-6.1.0.tgz",
|
||||
"integrity": "sha512-8uz+hAOpvHqZGvD4Ky1hJ0/tLI4S9B0Gu9LV7LtLxRKXODs/xrxEay0aMVp7AW9iizTeImZh/6aA00fFaRZpJw==",
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "^0.26.2",
|
||||
"classnames": "^2.2.6",
|
||||
"date-fns": "^3.3.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-onclickoutside": "^6.13.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0 || ^17 || ^18",
|
||||
"react-dom": "^16.9.0 || ^17 || ^18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-datepicker/node_modules/@floating-ui/react": {
|
||||
"version": "0.26.9",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.9.tgz",
|
||||
"integrity": "sha512-p86wynZJVEkEq2BBjY/8p2g3biQ6TlgT4o/3KgFKyTWoJLU1GZ8wpctwRqtkEl2tseYA+kw7dBAIDFcednfI5w==",
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom": "^2.0.8",
|
||||
"@floating-ui/utils": "^0.2.1",
|
||||
"tabbable": "^6.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
@ -2101,6 +2344,11 @@
|
||||
"react": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-fast-compare": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
|
||||
},
|
||||
"node_modules/react-infinite-scroll-component": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz",
|
||||
@ -2117,6 +2365,46 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/react-onclickoutside": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz",
|
||||
"integrity": "sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A==",
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://github.com/Pomax/react-onclickoutside/blob/master/FUNDING.md"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.5.x || ^16.x || ^17.x || ^18.x",
|
||||
"react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x"
|
||||
}
|
||||
},
|
||||
"node_modules/react-perfect-scrollbar": {
|
||||
"version": "1.5.8",
|
||||
"resolved": "https://registry.npmjs.org/react-perfect-scrollbar/-/react-perfect-scrollbar-1.5.8.tgz",
|
||||
"integrity": "sha512-bQ46m70gp/HJtiBOF3gRzBISSZn8FFGNxznTdmTG8AAwpxG1bJCyn7shrgjEvGSQ5FJEafVEiosY+ccER11OSA==",
|
||||
"dependencies": {
|
||||
"perfect-scrollbar": "^1.5.0",
|
||||
"prop-types": "^15.6.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.3.3",
|
||||
"react-dom": ">=16.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/react-popper": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
|
||||
"integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
|
||||
"dependencies": {
|
||||
"react-fast-compare": "^3.0.1",
|
||||
"warning": "^4.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@popperjs/core": "^2.0.0",
|
||||
"react": "^16.8.0 || ^17 || ^18",
|
||||
"react-dom": "^16.8.0 || ^17 || ^18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-textarea-autosize": {
|
||||
"version": "8.3.4",
|
||||
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz",
|
||||
@ -2148,6 +2436,17 @@
|
||||
"react-dom": ">=16.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.14.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||
@ -2182,6 +2481,11 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.23.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
|
||||
@ -2253,6 +2557,11 @@
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
|
||||
},
|
||||
"node_modules/styled-jsx": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
|
||||
@ -2302,6 +2611,89 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.draggable.js": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz",
|
||||
"integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.easing.js": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz",
|
||||
"integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==",
|
||||
"dependencies": {
|
||||
"svg.js": ">=2.3.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.filter.js": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz",
|
||||
"integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.js": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz",
|
||||
"integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
|
||||
},
|
||||
"node_modules/svg.pathmorphing.js": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz",
|
||||
"integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.resize.js": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz",
|
||||
"integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.6.5",
|
||||
"svg.select.js": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.resize.js/node_modules/svg.select.js": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz",
|
||||
"integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.select.js": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz",
|
||||
"integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.6.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tabbable": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
|
||||
@ -2315,6 +2707,20 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
|
||||
},
|
||||
"node_modules/through2": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz",
|
||||
"integrity": "sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==",
|
||||
"dependencies": {
|
||||
"readable-stream": "~1.0.17",
|
||||
"xtend": "~2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
@ -2429,6 +2835,11 @@
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/validator": {
|
||||
"version": "13.11.0",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz",
|
||||
@ -2437,6 +2848,14 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webfontloader": {
|
||||
"version": "1.6.28",
|
||||
"resolved": "https://registry.npmjs.org/webfontloader/-/webfontloader-1.6.28.tgz",
|
||||
@ -2475,6 +2894,17 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xtend": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
|
||||
"integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==",
|
||||
"dependencies": {
|
||||
"object-keys": "~0.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
|
11
package.json
11
package.json
@ -8,6 +8,7 @@
|
||||
"dependencies": {
|
||||
"@auth0/nextjs-auth0": "^2.2.0",
|
||||
"@emotion/react": "^11.11.3",
|
||||
"@emotion/server": "^11.11.0",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@fontsource/roboto": "^5.0.8",
|
||||
"@lupus-ai/mui-currency-textfield": "^1.0.3",
|
||||
@ -17,12 +18,20 @@
|
||||
"@mui/x-data-grid": "^6.19.4",
|
||||
"@mui/x-date-pickers": "^6.19.4",
|
||||
"@novu/notification-center": "^0.22.0",
|
||||
"apexcharts": "^3.45.2",
|
||||
"dayjs": "^1.11.10",
|
||||
"formidable": "^3.5.1",
|
||||
"mdi-material-ui": "^7.8.0",
|
||||
"mui-color-input": "^2.0.2",
|
||||
"next": "latest",
|
||||
"nprogress": "^0.2.0",
|
||||
"openapi-typescript-fetch": "^1.1.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-apexcharts": "^1.4.1",
|
||||
"react-datepicker": "^6.1.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-perfect-scrollbar": "^1.5.8",
|
||||
"react-popper": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.0.0",
|
||||
|
65
pages/401.tsx
Normal file
65
pages/401.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** Next Import
|
||||
import Link from 'next/link'
|
||||
|
||||
// ** MUI Components
|
||||
import Button from '@mui/material/Button'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import Box, { BoxProps } from '@mui/material/Box'
|
||||
|
||||
// ** Layout Import
|
||||
import BlankLayout from '../core/layouts/BlankLayout'
|
||||
|
||||
// ** Demo Imports
|
||||
import FooterIllustrations from '../views/pages/misc/FooterIllustrations'
|
||||
|
||||
// ** Styled Components
|
||||
const BoxWrapper = styled(Box)<BoxProps>(({ theme }) => ({
|
||||
[theme.breakpoints.down('md')]: {
|
||||
width: '90vw'
|
||||
}
|
||||
}))
|
||||
|
||||
const Img = styled('img')(({ theme }) => ({
|
||||
marginBottom: theme.spacing(10),
|
||||
[theme.breakpoints.down('lg')]: {
|
||||
height: 450,
|
||||
marginTop: theme.spacing(10)
|
||||
},
|
||||
[theme.breakpoints.down('md')]: {
|
||||
height: 400
|
||||
},
|
||||
[theme.breakpoints.up('lg')]: {
|
||||
marginTop: theme.spacing(13)
|
||||
}
|
||||
}))
|
||||
|
||||
const Error401 = () => {
|
||||
return (
|
||||
<Box className='content-center'>
|
||||
<Box sx={{ p: 5, display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<BoxWrapper>
|
||||
<Typography variant='h1'>401</Typography>
|
||||
<Typography variant='h5' sx={{ mb: 1, fontSize: '1.5rem !important' }}>
|
||||
You are not authorized! 🔐
|
||||
</Typography>
|
||||
<Typography variant='body2'>You don′t have permission to access this page. Go Home!</Typography>
|
||||
</BoxWrapper>
|
||||
<Img height='487' alt='error-illustration' src='/images/pages/401.png' />
|
||||
<Link passHref href='/'>
|
||||
<Button component='a' variant='contained' sx={{ px: 5.5 }}>
|
||||
Back to Home
|
||||
</Button>
|
||||
</Link>
|
||||
</Box>
|
||||
<FooterIllustrations />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
Error401.getLayout = (page: ReactNode) => <BlankLayout>{page}</BlankLayout>
|
||||
|
||||
export default Error401
|
74
pages/404.tsx
Normal file
74
pages/404.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** Next Import
|
||||
import Link from 'next/link'
|
||||
|
||||
// ** MUI Components
|
||||
import Button from '@mui/material/Button'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import Box, { BoxProps } from '@mui/material/Box'
|
||||
|
||||
// ** Layout Import
|
||||
import BlankLayout from '../core/layouts/BlankLayout'
|
||||
|
||||
// ** Demo Imports
|
||||
import FooterIllustrations from '../views/pages/misc/FooterIllustrations'
|
||||
|
||||
// ** Styled Components
|
||||
const BoxWrapper = styled(Box)<BoxProps>(({ theme }) => ({
|
||||
[theme.breakpoints.down('md')]: {
|
||||
width: '90vw'
|
||||
}
|
||||
}))
|
||||
|
||||
const Img = styled('img')(({ theme }) => ({
|
||||
marginBottom: theme.spacing(10),
|
||||
[theme.breakpoints.down('lg')]: {
|
||||
height: 450,
|
||||
marginTop: theme.spacing(10)
|
||||
},
|
||||
[theme.breakpoints.down('md')]: {
|
||||
height: 400
|
||||
},
|
||||
[theme.breakpoints.up('lg')]: {
|
||||
marginTop: theme.spacing(13)
|
||||
}
|
||||
}))
|
||||
|
||||
const TreeIllustration = styled('img')(({ theme }) => ({
|
||||
left: 0,
|
||||
bottom: '5rem',
|
||||
position: 'absolute',
|
||||
[theme.breakpoints.down('lg')]: {
|
||||
bottom: 0
|
||||
}
|
||||
}))
|
||||
|
||||
const Error404 = () => {
|
||||
return (
|
||||
<Box className='content-center'>
|
||||
<Box sx={{ p: 5, display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<BoxWrapper>
|
||||
<Typography variant='h1'>404</Typography>
|
||||
<Typography variant='h5' sx={{ mb: 1, fontSize: '1.5rem !important' }}>
|
||||
Page Not Found ⚠️
|
||||
</Typography>
|
||||
<Typography variant='body2'>We couldn′t find the page you are looking for.</Typography>
|
||||
</BoxWrapper>
|
||||
<Img height='487' alt='error-illustration' src='/images/pages/404.png' />
|
||||
<Link passHref href='/'>
|
||||
<Button variant='contained' sx={{ px: 5.5 }}>
|
||||
Back to Home
|
||||
</Button>
|
||||
</Link>
|
||||
</Box>
|
||||
<FooterIllustrations image={<TreeIllustration alt='tree' src='/images/pages/tree.png' />} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
Error404.getLayout = (page: ReactNode) => <BlankLayout>{page}</BlankLayout>
|
||||
|
||||
export default Error404
|
74
pages/500.tsx
Normal file
74
pages/500.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** Next Import
|
||||
import Link from 'next/link'
|
||||
|
||||
// ** MUI Components
|
||||
import Button from '@mui/material/Button'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import Box, { BoxProps } from '@mui/material/Box'
|
||||
|
||||
// ** Layout Import
|
||||
import BlankLayout from '../core/layouts/BlankLayout'
|
||||
|
||||
// ** Demo Imports
|
||||
import FooterIllustrations from '../views/pages/misc/FooterIllustrations'
|
||||
|
||||
// ** Styled Components
|
||||
const BoxWrapper = styled(Box)<BoxProps>(({ theme }) => ({
|
||||
[theme.breakpoints.down('md')]: {
|
||||
width: '90vw'
|
||||
}
|
||||
}))
|
||||
|
||||
const Img = styled('img')(({ theme }) => ({
|
||||
marginBottom: theme.spacing(10),
|
||||
[theme.breakpoints.down('lg')]: {
|
||||
height: 450,
|
||||
marginTop: theme.spacing(10)
|
||||
},
|
||||
[theme.breakpoints.down('md')]: {
|
||||
height: 400
|
||||
},
|
||||
[theme.breakpoints.up('lg')]: {
|
||||
marginTop: theme.spacing(13)
|
||||
}
|
||||
}))
|
||||
|
||||
const TreeIllustration = styled('img')(({ theme }) => ({
|
||||
left: 0,
|
||||
bottom: '5rem',
|
||||
position: 'absolute',
|
||||
[theme.breakpoints.down('lg')]: {
|
||||
bottom: 0
|
||||
}
|
||||
}))
|
||||
|
||||
const Error500 = () => {
|
||||
return (
|
||||
<Box className='content-center'>
|
||||
<Box sx={{ p: 5, display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<BoxWrapper>
|
||||
<Typography variant='h1'>500</Typography>
|
||||
<Typography variant='h5' sx={{ mb: 1, fontSize: '1.5rem !important' }}>
|
||||
Internal server error 👨🏻💻
|
||||
</Typography>
|
||||
<Typography variant='body2'>Oops, something went wrong!</Typography>
|
||||
</BoxWrapper>
|
||||
<Img height='487' alt='error-illustration' src='/images/pages/500.png' />
|
||||
<Link passHref href='/'>
|
||||
<Button component='a' variant='contained' sx={{ px: 5.5 }}>
|
||||
Back to Home
|
||||
</Button>
|
||||
</Link>
|
||||
</Box>
|
||||
<FooterIllustrations image={<TreeIllustration alt='tree' src='/images/pages/tree-3.png' />} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
Error500.getLayout = (page: ReactNode) => <BlankLayout>{page}</BlankLayout>
|
||||
|
||||
export default Error500
|
124
pages/_app.tsx
124
pages/_app.tsx
@ -1,38 +1,104 @@
|
||||
// ** Next Imports
|
||||
import Head from 'next/head'
|
||||
import { Router } from 'next/router'
|
||||
import type { NextPage } from 'next'
|
||||
import type { AppProps } from 'next/app'
|
||||
|
||||
// ** Loader Import
|
||||
import NProgress from 'nprogress'
|
||||
|
||||
import { UserProvider } from "@auth0/nextjs-auth0/client";
|
||||
import '@fontsource/roboto/300.css';
|
||||
import '@fontsource/roboto/400.css';
|
||||
import '@fontsource/roboto/500.css';
|
||||
import '@fontsource/roboto/700.css';
|
||||
import { createTheme } from '@mui/material/styles';
|
||||
import { green, purple } from '@mui/material/colors';
|
||||
import { ThemeProvider } from "@emotion/react";
|
||||
// ** Emotion Imports
|
||||
import { CacheProvider } from '@emotion/react'
|
||||
import type { EmotionCache } from '@emotion/cache'
|
||||
|
||||
const theme = createTheme({
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#1D3555',
|
||||
},
|
||||
secondary: {
|
||||
main: '#E5BEED'
|
||||
},
|
||||
background: {
|
||||
default: '#3D3E46',
|
||||
paper: '#FAFAFF'
|
||||
}
|
||||
},
|
||||
})
|
||||
// ** Config Imports
|
||||
import themeConfig from '../configs/themeConfig'
|
||||
|
||||
// ** Component Imports
|
||||
import UserLayout from '../layouts/UserLayout'
|
||||
import ThemeComponent from '../core/theme/ThemeComponent'
|
||||
|
||||
// ** Contexts
|
||||
import { SettingsConsumer, SettingsProvider } from '../core/context/settingsContext'
|
||||
|
||||
// ** Utils Imports
|
||||
import { createEmotionCache } from '../core/utils/create-emotion-cache'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
// ** React Perfect Scrollbar Style
|
||||
import 'react-perfect-scrollbar/dist/css/styles.css'
|
||||
|
||||
// ** Global css styles
|
||||
import '../styles/globals.css'
|
||||
|
||||
// ** Extend App Props with Emotion
|
||||
type ExtendedAppProps = AppProps & {
|
||||
Component: NextPage
|
||||
emotionCache: EmotionCache
|
||||
}
|
||||
|
||||
const clientSideEmotionCache = createEmotionCache()
|
||||
|
||||
// ** Pace Loader
|
||||
if (themeConfig.routingLoader) {
|
||||
Router.events.on('routeChangeStart', () => {
|
||||
NProgress.start()
|
||||
})
|
||||
Router.events.on('routeChangeError', () => {
|
||||
NProgress.done()
|
||||
})
|
||||
Router.events.on('routeChangeComplete', () => {
|
||||
NProgress.done()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export default function App({ Component, pageProps }) {
|
||||
// optionally pass the 'user' prop from pages that require server-side
|
||||
// rendering to prepopulate the 'useUser' hook.
|
||||
|
||||
// ** Configure JSS & ClassName
|
||||
const App = (props: ExtendedAppProps) => {
|
||||
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props
|
||||
|
||||
const { user } = pageProps;
|
||||
// Variables
|
||||
const getLayout = Component.getLayout ?? (page => <UserLayout>{page}</UserLayout>)
|
||||
|
||||
const [isRootPath, setIsRootPath] = useState<boolean>(true);
|
||||
|
||||
const router = useRouter();
|
||||
useEffect(() => {
|
||||
setIsRootPath(router.pathname === '/');
|
||||
}, [router.pathname]);
|
||||
|
||||
return (
|
||||
<UserProvider user={user}>
|
||||
<ThemeProvider theme={theme}>
|
||||
<Component {...pageProps} />
|
||||
</ThemeProvider>
|
||||
<UserProvider user={user}>
|
||||
<CacheProvider value={emotionCache}>
|
||||
<Head>
|
||||
<title>{`Request.Box`}</title>
|
||||
<meta
|
||||
name='description'
|
||||
content={`Request.Box is a platform for artists to allow their followered to request art pieces while allowing the artist complete control of the terms and timeframe.`}
|
||||
/>
|
||||
<meta name='keywords' content='Art, Commission, Skeb, Artwork, Freelance, Illustration, Vtuber, Vtubing, Vtuber Rigging, Illustration' />
|
||||
<meta name='viewport' content='initial-scale=1, width=device-width' />
|
||||
</Head>
|
||||
|
||||
<SettingsProvider>
|
||||
<SettingsConsumer>
|
||||
{({ settings }) => {{
|
||||
if (isRootPath) {
|
||||
return <ThemeComponent settings={settings}><Component {...pageProps} /> </ThemeComponent>
|
||||
} else {
|
||||
return <ThemeComponent settings={settings}>{getLayout(<Component {...pageProps} />)}</ThemeComponent>;
|
||||
}
|
||||
}}}
|
||||
</SettingsConsumer>
|
||||
</SettingsProvider>
|
||||
</CacheProvider>
|
||||
</UserProvider>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
70
pages/_document.tsx
Normal file
70
pages/_document.tsx
Normal file
@ -0,0 +1,70 @@
|
||||
// ** React Import
|
||||
import { Children } from 'react'
|
||||
|
||||
// ** Next Import
|
||||
import Document, { Html, Head, Main, NextScript } from 'next/document'
|
||||
|
||||
// ** Emotion Imports
|
||||
import createEmotionServer from '@emotion/server/create-instance'
|
||||
|
||||
// ** Utils Imports
|
||||
import { createEmotionCache } from '../core/utils/create-emotion-cache'
|
||||
|
||||
class CustomDocument extends Document {
|
||||
render() {
|
||||
return (
|
||||
<Html lang='en'>
|
||||
<Head>
|
||||
<link rel='preconnect' href='https://fonts.googleapis.com' />
|
||||
<link rel='preconnect' href='https://fonts.gstatic.com' />
|
||||
<link
|
||||
rel='stylesheet'
|
||||
href='https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'
|
||||
/>
|
||||
<link rel='apple-touch-icon' sizes='180x180' href='/images/apple-touch-icon.png' />
|
||||
<link rel='shortcut icon' href='/images/favicon.png' />
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CustomDocument.getInitialProps = async ctx => {
|
||||
const originalRenderPage = ctx.renderPage
|
||||
const cache = createEmotionCache()
|
||||
const { extractCriticalToChunks } = createEmotionServer(cache)
|
||||
|
||||
ctx.renderPage = () =>
|
||||
originalRenderPage({
|
||||
enhanceApp: App => props =>
|
||||
(
|
||||
<App
|
||||
{...props} // @ts-ignore
|
||||
emotionCache={cache}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
const initialProps = await Document.getInitialProps(ctx)
|
||||
const emotionStyles = extractCriticalToChunks(initialProps.html)
|
||||
const emotionStyleTags = emotionStyles.styles.map(style => {
|
||||
return (
|
||||
<style
|
||||
key={style.key}
|
||||
dangerouslySetInnerHTML={{ __html: style.css }}
|
||||
data-emotion={`${style.key} ${style.ids.join(' ')}`}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
return {
|
||||
...initialProps,
|
||||
styles: [...Children.toArray(initialProps.styles), ...emotionStyleTags]
|
||||
}
|
||||
}
|
||||
|
||||
export default CustomDocument
|
103
pages/account-settings/index.tsx
Normal file
103
pages/account-settings/index.tsx
Normal file
@ -0,0 +1,103 @@
|
||||
// ** React Imports
|
||||
import { SyntheticEvent, useState } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Card from '@mui/material/Card'
|
||||
import TabList from '@mui/lab/TabList'
|
||||
import TabPanel from '@mui/lab/TabPanel'
|
||||
import TabContext from '@mui/lab/TabContext'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import MuiTab, { TabProps } from '@mui/material/Tab'
|
||||
|
||||
// ** Icons Imports
|
||||
import AccountOutline from 'mdi-material-ui/AccountOutline'
|
||||
import LockOpenOutline from 'mdi-material-ui/LockOpenOutline'
|
||||
import InformationOutline from 'mdi-material-ui/InformationOutline'
|
||||
|
||||
// ** Demo Tabs Imports
|
||||
import TabInfo from '../../views/account-settings/TabInfo'
|
||||
import TabAccount from '../../views/account-settings/TabAccount'
|
||||
import TabSecurity from '../../views/account-settings/TabSecurity'
|
||||
|
||||
// ** Third Party Styles Imports
|
||||
import 'react-datepicker/dist/react-datepicker.css'
|
||||
|
||||
const Tab = styled(MuiTab)<TabProps>(({ theme }) => ({
|
||||
[theme.breakpoints.down('md')]: {
|
||||
minWidth: 100
|
||||
},
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
minWidth: 67
|
||||
}
|
||||
}))
|
||||
|
||||
const TabName = styled('span')(({ theme }) => ({
|
||||
lineHeight: 1.71,
|
||||
fontSize: '0.875rem',
|
||||
marginLeft: theme.spacing(2.4),
|
||||
[theme.breakpoints.down('md')]: {
|
||||
display: 'none'
|
||||
}
|
||||
}))
|
||||
|
||||
const AccountSettings = () => {
|
||||
// ** State
|
||||
const [value, setValue] = useState<string>('account')
|
||||
|
||||
const handleChange = (event: SyntheticEvent, newValue: string) => {
|
||||
setValue(newValue)
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<TabContext value={value}>
|
||||
<TabList
|
||||
onChange={handleChange}
|
||||
aria-label='account-settings tabs'
|
||||
sx={{ borderBottom: theme => `1px solid ${theme.palette.divider}` }}
|
||||
>
|
||||
<Tab
|
||||
value='account'
|
||||
label={
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<AccountOutline />
|
||||
<TabName>Account</TabName>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Tab
|
||||
value='security'
|
||||
label={
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<LockOpenOutline />
|
||||
<TabName>Security</TabName>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Tab
|
||||
value='info'
|
||||
label={
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<InformationOutline />
|
||||
<TabName>Info</TabName>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
</TabList>
|
||||
|
||||
<TabPanel sx={{ p: 0 }} value='account'>
|
||||
<TabAccount />
|
||||
</TabPanel>
|
||||
<TabPanel sx={{ p: 0 }} value='security'>
|
||||
<TabSecurity />
|
||||
</TabPanel>
|
||||
<TabPanel sx={{ p: 0 }} value='info'>
|
||||
<TabInfo />
|
||||
</TabPanel>
|
||||
</TabContext>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default AccountSettings
|
@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useUser } from "@auth0/nextjs-auth0/client";
|
||||
import Layout from "../../components/layout";
|
||||
import Layout from "../../components/OLd/layout";
|
||||
|
||||
const ApiProfile = () => {
|
||||
const { user, isLoading } = useUser();
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { withPageAuthRequired } from "@auth0/nextjs-auth0";
|
||||
import Layout from "../../components/layout";
|
||||
import Layout from "../../components/OLd/layout";
|
||||
import { User } from "../../interfaces";
|
||||
|
||||
type ProfileProps = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Layout from "../../components/layout";
|
||||
import Layout from "../../components/OLd/layout";
|
||||
import { useUser } from "@auth0/nextjs-auth0/client";
|
||||
import { Box, Grid, Card, CardContent, Typography, List, Button, CircularProgress, Tooltip } from "@mui/material";
|
||||
import { useState, useEffect } from "react";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Layout from "../../../components/layout";
|
||||
import Layout from "../../../components/OLd/layout";
|
||||
import { useUser } from "@auth0/nextjs-auth0/client";
|
||||
import { Box, Grid, Typography, Button, CircularProgress, TextField} from "@mui/material";
|
||||
import { useState, useEffect } from "react";
|
||||
|
@ -1,201 +0,0 @@
|
||||
import { useUser } from "@auth0/nextjs-auth0/client";
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
import Tabs from '@mui/material/Tabs';
|
||||
import Tab from '@mui/material/Tab';
|
||||
import { Grid, Button, Typography, TextField, Box, CircularProgress, IconButton } from "@mui/material";
|
||||
import { useState, useEffect,useRef } from "react";
|
||||
import Card from '@mui/material/Card';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
import CardActions from '@mui/material/CardActions';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import SwipeableViews from '../components/swipableView';
|
||||
import { DataGrid, GridColDef, GridValueGetterParams } from '@mui/x-data-grid';
|
||||
|
||||
import ThumbsUpDownIcon from '@mui/icons-material/ThumbsUpDown';
|
||||
import EditableArtistPortfolio from "../components/editableArtistPortfolio";
|
||||
import Popover from '@mui/material/Popover';
|
||||
import ArtistDashboardRequest from "../components/artistDashboardRequest";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const SellerDashoard = (ctx) => {
|
||||
const { user, isLoading } = useUser();
|
||||
const [sellerData, setSellerData] = useState([]);
|
||||
const [loading, setLoading] = useState(true); // State for loading indicator
|
||||
const [isOnboarded, setIsOnboarded] = useState(false);
|
||||
const [onBoardUrl, setOnBoardUrl] = useState("");
|
||||
const [tabValue, setTabValue] = useState(1);
|
||||
|
||||
const getData = async () => {
|
||||
const response = await fetch('/api/artist/profile');
|
||||
const sellerProfile = await response.json();
|
||||
setSellerData(sellerProfile);
|
||||
const onboardCheckRequest = await fetch('/api/artist/onboarded', { method: "GET" });
|
||||
const onboardCheckResponse = await onboardCheckRequest.json();
|
||||
setIsOnboarded(onboardCheckResponse["onboarded"]);
|
||||
const onboardUrlRequest = await fetch('/api/artist/onboardurl', { method: "GET" });
|
||||
const onboardUrlResponse = await onboardUrlRequest.json();
|
||||
setOnBoardUrl(onboardUrlResponse["onboardUrl"]);
|
||||
|
||||
setLoading(false); // Once data is fetched, set loading to false
|
||||
}
|
||||
|
||||
|
||||
|
||||
const handleChange = (event: React.SyntheticEvent, newValue: number) => {
|
||||
setTabValue(newValue);
|
||||
};
|
||||
|
||||
const handleChangeIndex = (index: number) => {
|
||||
setTabValue(index);
|
||||
};
|
||||
|
||||
interface TabPanelProps {
|
||||
children?: React.ReactNode;
|
||||
dir?: string;
|
||||
index: number;
|
||||
value: number;
|
||||
}
|
||||
|
||||
function TabPanel(props: TabPanelProps) {
|
||||
const { children, value, index, ...other } = props;
|
||||
|
||||
return (
|
||||
<div
|
||||
role="tabpanel"
|
||||
hidden={value !== index}
|
||||
id={`full-width-tabpanel-${index}`}
|
||||
aria-labelledby={`full-width-tab-${index}`}
|
||||
{...other}
|
||||
>
|
||||
{value === index && (
|
||||
<Box sx={{ p: 3 }}>
|
||||
<Typography>{children}</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function a11yProps(index: number) {
|
||||
return {
|
||||
id: `full-width-tab-${index}`,
|
||||
'aria-controls': `full-width-tabpanel-${index}`,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
const theme = useTheme();
|
||||
const columns: GridColDef[] = [
|
||||
{ field: 'requestor', headerName: 'User', width: 150 },
|
||||
{ field: 'message', headerName: 'Message', width: 280 },
|
||||
{ field: 'amount', headerName: 'Amount', width: 50 },
|
||||
{
|
||||
field: "action",
|
||||
headerName: "Action",
|
||||
sortable: false,
|
||||
renderCell: (params) => {
|
||||
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
||||
const open = Boolean(anchorEl);
|
||||
const id = open ? 'simple-popover' : undefined;
|
||||
const buttonRef = useRef(null);
|
||||
|
||||
const accept = (e) => {
|
||||
return alert("TEST");
|
||||
};
|
||||
|
||||
const decline = (e) => {
|
||||
return alert("TEST");
|
||||
};
|
||||
|
||||
const handleClick = (e) => {
|
||||
setAnchorEl(e.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
console.log(params)
|
||||
return (
|
||||
<>
|
||||
<Button ref={buttonRef} startIcon={<ThumbsUpDownIcon/>} color="success" onClick={handleClick}></Button>
|
||||
<Popover
|
||||
id={params["requestor"]+"-"+params["amount"]}
|
||||
open={open}
|
||||
anchorEl={buttonRef.current}
|
||||
onClose={handleClose}
|
||||
transformOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'left',
|
||||
}}
|
||||
>
|
||||
<Button size="small" color="success" variant="contained" onClick={accept}>Accept</Button>
|
||||
<Button size="small" color="error" variant="contained" onClick={decline}>Decline</Button>
|
||||
</Popover>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
];
|
||||
const rows = [
|
||||
{ id: 1, requestor: 'Snow', message: 'This is a test message!', amount: 35.00 },
|
||||
{ id: 2, requestor: 'Lannister', message: 'This is a test message!', amount: 42.00 },
|
||||
{ id: 3, requestor: 'Lannister', message: 'This is a test message!', amount: 45.00 },
|
||||
{ id: 4, requestor: 'Stark', message: 'This is a test message!', amount: 16.00 },
|
||||
{ id: 5, requestor: 'Targaryen', message: 'This is a test message!', amount: 150.00 },
|
||||
{ id: 6, requestor: 'Melisandre', message: "This is a test message!", amount: 150.00 },
|
||||
{ id: 7, requestor: 'Clifford', message: 'This is a test message!', amount: 44.00 },
|
||||
{ id: 8, requestor: 'Frances', message: 'This is a test message!', amount: 36.00 },
|
||||
{ id: 9, requestor: 'Roxie', message: 'This is a test message!', amount: 65.00 },
|
||||
];
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{loading ? ( // Render loading indicator if loading is true
|
||||
<Box sx={{ textAlign: "center", paddingTop: 20 }}>
|
||||
<Typography variant="h4" sx={{ textAlign: "center" }}>
|
||||
Loading
|
||||
</Typography>
|
||||
<Box sx={{ paddingTop: 5 }} />
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
) : (
|
||||
<Grid container >
|
||||
{(Object.keys(sellerData).length > 0 ? (
|
||||
<>
|
||||
<Grid item container sx={{ textAlign: "center" }}>
|
||||
<Grid item xs={12} sm={2} sx={{ textAlign: "center" }}>
|
||||
<Button color="primary" variant="contained" href="../">
|
||||
Back
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={8} sx={{ textAlign: "center" }}>
|
||||
<Typography variant="h4">
|
||||
Artist Dashboard
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={2} sx={{ textAlign: "center" }}>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ArtistDashboardRequest/>
|
||||
</>
|
||||
|
||||
) : (
|
||||
<></>
|
||||
))}
|
||||
<Grid item container xs={12} sm={12}>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)};
|
||||
</>);
|
||||
}
|
||||
export default SellerDashoard;
|
83
pages/cards/index.tsx
Normal file
83
pages/cards/index.tsx
Normal file
@ -0,0 +1,83 @@
|
||||
// ** MUI Imports
|
||||
import Grid from '@mui/material/Grid'
|
||||
import Typography from '@mui/material/Typography'
|
||||
|
||||
// ** Demo Components Imports
|
||||
import CardUser from '../views/cards/CardUser'
|
||||
import CardImgTop from '../views/cards/CardImgTop'
|
||||
import CardMobile from '../views/cards/CardMobile'
|
||||
import CardSupport from '../views/cards/CardSupport'
|
||||
import CardTwitter from '../views/cards/CardTwitter'
|
||||
import CardFacebook from '../views/cards/CardFacebook'
|
||||
import CardLinkedIn from '../views/cards/CardLinkedIn'
|
||||
import CardAppleWatch from '../views/cards/CardAppleWatch'
|
||||
import CardMembership from '../views/cards/CardMembership'
|
||||
import CardInfluencer from '../views/cards/CardInfluencer'
|
||||
import CardNavigation from '../views/cards/CardNavigation'
|
||||
import CardWithCollapse from '../views/cards/CardWithCollapse'
|
||||
import CardVerticalRatings from '../views/cards/CardVerticalRatings'
|
||||
import CardNavigationCenter from '../views/cards/CardNavigationCenter'
|
||||
import CardHorizontalRatings from '../views/cards/CardHorizontalRatings'
|
||||
|
||||
const CardBasic = () => {
|
||||
return (
|
||||
<Grid container spacing={6}>
|
||||
<Grid item xs={12} sx={{ paddingBottom: 4 }}>
|
||||
<Typography variant='h5'>Basic Cards</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardImgTop />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardUser />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardWithCollapse />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<CardMobile />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<CardHorizontalRatings />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardAppleWatch />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={8}>
|
||||
<CardMembership />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardInfluencer />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardVerticalRatings />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardSupport />
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ pb: 4, pt: theme => `${theme.spacing(17.5)} !important` }}>
|
||||
<Typography variant='h5'>Navigation Cards</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<CardNavigation />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<CardNavigationCenter />
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ pb: 4, pt: theme => `${theme.spacing(17.5)} !important` }}>
|
||||
<Typography variant='h5'>Solid Cards</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardTwitter />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardFacebook />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardLinkedIn />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default CardBasic
|
385
pages/dashboard/artist/pagesettings.tsx
Normal file
385
pages/dashboard/artist/pagesettings.tsx
Normal file
@ -0,0 +1,385 @@
|
||||
import { withPageAuthRequired } from "@auth0/nextjs-auth0/client";
|
||||
import Grid from '@mui/material/Grid';
|
||||
import Card from '@mui/material/Card';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
import Button from '@mui/material/Button';
|
||||
import { Accordion, Typography } from "@mui/material";
|
||||
import { useEffect, useState } from "react";
|
||||
import Switch from '@mui/material/Switch';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import { MuiColorInput } from 'mui-color-input'
|
||||
import { AccordionSummary } from "@mui/material";
|
||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||
import AccordionDetails from '@mui/material/AccordionDetails';
|
||||
import Slider from '@mui/material/Slider';
|
||||
import ArtistPortfolio from '../../../components/Old/artistPortfolio';
|
||||
|
||||
const Profile = () => {
|
||||
|
||||
const [profileData, setSellerProfileData] = useState(null);
|
||||
|
||||
const [backgroundColor, setBackgroundColor] = useState('rgb(126, 115, 115)');
|
||||
|
||||
const [headerColor, setHeaderColor] = useState('rgb(194, 187, 187)');
|
||||
const [headerIsImage, setHeaderImage] = useState(false);
|
||||
const [headerImageUrl, setHeaderImageUrl] = useState('');
|
||||
const [headerText, setHeaderText] = useState('Shop');
|
||||
const [headerSize, setHeaderSize] = useState(5);
|
||||
const headerVariant = [
|
||||
'h6', // Size 1
|
||||
'h5', // Size 2
|
||||
'h4', // Size 3
|
||||
'h3', // Size 4
|
||||
'h2', // Size 5
|
||||
'h1', // Size 6
|
||||
][headerSize - 1] || 'h6';
|
||||
|
||||
|
||||
const [bioColor, setBioColor] = useState('rgb(186, 186, 186)');
|
||||
const [bioBgColor, setBioBgColor] = useState('rgb(103, 97, 97)');
|
||||
const [bioHeaderColor, setBioHeaderColor] = useState('rgb(255, 255, 255)');
|
||||
const [bioHeaderIsImage, setBioHeaderImage] = useState(false);
|
||||
const [bioHeaderImageUrl, setBioHeaderImageUrl] = useState('');
|
||||
const [bioHeaderText, setBioHeaderText] = useState('Biography');
|
||||
const [bioHeaderSize, setBioHeaderSize] = useState(3);
|
||||
const [bioSize, setBioSize] = useState(1);
|
||||
const bioHeaderVariant = [
|
||||
'h6', // Size 1
|
||||
'h5', // Size 2
|
||||
'h4', // Size 3
|
||||
'h3', // Size 4
|
||||
'h2', // Size 5
|
||||
'h1', // Size 6
|
||||
][bioHeaderSize - 1] || 'h6';
|
||||
const bioVariant = [
|
||||
'h6', // Size 1
|
||||
'h5', // Size 2
|
||||
'h4', // Size 3
|
||||
'h3', // Size 4
|
||||
'h2', // Size 5
|
||||
'h1', // Size 6
|
||||
][bioSize - 1] || 'h6';
|
||||
|
||||
const [portfolioBgColor, setPortfolioBgColor] = useState('rgb(78, 73, 73)');
|
||||
const [portfolioColumns, setPotrfolioColumns] = useState(2);
|
||||
const [portfolioWoven, setPortfolioWoven] = useState(true);
|
||||
const [portfolioShouldScroll, setPortfolioShouldScroll] = useState(true);
|
||||
const [portfolioSize, setPortfolioSize] = useState(25);
|
||||
|
||||
const getData = async () => {
|
||||
const profileResponse = await fetch('/api/artist/profile');
|
||||
const sellerProfile = await profileResponse.json();
|
||||
setSellerProfileData(sellerProfile);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, []);
|
||||
|
||||
const handleBackgroundColorChange = (newValue) => {
|
||||
setBackgroundColor(newValue)
|
||||
}
|
||||
|
||||
const handleHeaderTextChange = (e) => {
|
||||
setHeaderText(e.target.value)
|
||||
}
|
||||
|
||||
const handleHeaderImageUrl = (e) => {
|
||||
setHeaderImageUrl(e.target.value)
|
||||
}
|
||||
const handleHeaderImageToggle = (e) => {
|
||||
setHeaderImage(e.target.checked)
|
||||
};
|
||||
|
||||
const handleHeaderSize = (e, newValue) => {
|
||||
setHeaderSize(newValue)
|
||||
}
|
||||
|
||||
const handleHeaderColorChange = (newValue) => {
|
||||
setHeaderColor(newValue)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const handleBioHeaderTextChange = (e) => {
|
||||
setBioHeaderText(e.target.value)
|
||||
}
|
||||
|
||||
const handleBioHeaderImageUrl = (e) => {
|
||||
setBioHeaderImageUrl(e.target.value)
|
||||
}
|
||||
const handleBioHeaderImageToggle = (e) => {
|
||||
setBioHeaderImage(e.target.checked)
|
||||
};
|
||||
|
||||
const handleBioHeaderSize = (e, newValue) => {
|
||||
setBioHeaderSize(newValue)
|
||||
}
|
||||
const handleBioSize = (e, newValue) => {
|
||||
setBioSize(newValue)
|
||||
}
|
||||
|
||||
const handleBioHeaderColorChange = (newValue) => {
|
||||
setBioHeaderColor(newValue)
|
||||
}
|
||||
const handleBioColorChange = (newValue) => {
|
||||
setBioColor(newValue)
|
||||
}
|
||||
|
||||
const handleBioBgColorChange = (newValue) => {
|
||||
setBioBgColor(newValue)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const handlePortfolioBgColor = (newValue) => {
|
||||
setPortfolioBgColor(newValue)
|
||||
}
|
||||
|
||||
const handlePortfolioColumns = (e, newValue) => {
|
||||
setPotrfolioColumns(newValue)
|
||||
}
|
||||
const handlePortfolioWoven = (e) => {
|
||||
setPortfolioWoven(e.target.checked)
|
||||
};
|
||||
const handlePortfolioShouldScroll = (e) => {
|
||||
setPortfolioShouldScroll(e.target.checked)
|
||||
console.log(portfolioShouldScroll)
|
||||
};
|
||||
const handlePortfolioSize = (e, newValue) => {
|
||||
setPortfolioSize(newValue)
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={4}>
|
||||
<Card >
|
||||
<CardContent>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12} md={9}>
|
||||
<Typography variant="h6" >
|
||||
Customize Your Page
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={3}>
|
||||
<Button variant="contained" size="large">
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<Divider/>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<Accordion defaultExpanded>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls="panel1-content"
|
||||
>
|
||||
<Typography>Background</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={12}>
|
||||
<MuiColorInput fullWidth value={backgroundColor} onChange={handleBackgroundColorChange} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<Accordion defaultExpanded>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls="panel1-content"
|
||||
>
|
||||
<Typography>Header</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={12}>
|
||||
<TextField disabled={headerIsImage} variant="outlined" fullWidth label="Header Text" onChange={handleHeaderTextChange} value={headerText} size="small"></TextField>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={10}>
|
||||
<TextField variant="outlined" fullWidth label="Image Url" size="small" onChange={handleHeaderImageUrl}></TextField>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={2}>
|
||||
<Switch checked={headerIsImage} onChange={handleHeaderImageToggle} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<MuiColorInput disabled={headerIsImage} label="Color" fullWidth value={headerColor} onChange={handleHeaderColorChange} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={3}>
|
||||
<Typography variant="body1" >
|
||||
Text Size
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={9}>
|
||||
<Slider disabled={headerIsImage} value={headerSize} onChange={handleHeaderSize} aria-label="Size" defaultValue={6} step={1} marks min={1} max={6} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<Accordion defaultExpanded>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls="panel1-content"
|
||||
>
|
||||
<Typography>Biography</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={12}>
|
||||
<TextField disabled={bioHeaderIsImage} variant="outlined" fullWidth label="Header Text" onChange={handleBioHeaderTextChange} value={bioHeaderText} size="small"></TextField>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={10}>
|
||||
<TextField variant="outlined" fullWidth label="Header Image Url" size="small" value={bioHeaderImageUrl} onChange={handleBioHeaderImageUrl}></TextField>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={2}>
|
||||
<Switch checked={bioHeaderIsImage} onChange={handleBioHeaderImageToggle} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<MuiColorInput disabled={bioHeaderIsImage} label="Header Text Color" fullWidth value={bioHeaderColor} onChange={handleBioHeaderColorChange} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<MuiColorInput label="Background Color" fullWidth value={bioBgColor} onChange={handleBioBgColorChange} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<MuiColorInput label="Text Color" fullWidth value={bioColor} onChange={handleBioColorChange} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={5}>
|
||||
<Typography variant="body1" >
|
||||
Header Size
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={7}>
|
||||
<Slider disabled={bioHeaderIsImage} value={bioHeaderSize} onChange={handleBioHeaderSize} aria-label="Size" defaultValue={6} step={1} marks min={1} max={6} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={5}>
|
||||
<Typography variant="body1" >
|
||||
Text Size
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={7}>
|
||||
<Slider value={bioSize} onChange={handleBioSize} aria-label="Size" defaultValue={6} step={1} marks min={1} max={6} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<Accordion defaultExpanded>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls="panel1-content"
|
||||
>
|
||||
<Typography>Portfolio</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={12}>
|
||||
<MuiColorInput label="Background Color" fullWidth value={portfolioBgColor} onChange={handlePortfolioBgColor} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={10}>
|
||||
<Typography variant="body1" >
|
||||
Masonry Layout Enabled
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={2 }>
|
||||
<Switch checked={portfolioWoven} onChange={handlePortfolioWoven} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={5}>
|
||||
<Typography variant="body1" >
|
||||
Columns
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={7}>
|
||||
<Slider value={portfolioColumns} onChange={handlePortfolioColumns} aria-label="Size" defaultValue={6} step={1} marks min={1} max={5} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={10}>
|
||||
<Typography variant="body1" >
|
||||
Enable Scrolling
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={2 }>
|
||||
<Switch checked={portfolioShouldScroll} onChange={handlePortfolioShouldScroll} />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={4}>
|
||||
<Typography variant="body1" >
|
||||
Max Size
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={8}>
|
||||
<Slider disabled={!portfolioShouldScroll} value={portfolioSize} onChange={handlePortfolioSize} aria-label="Size" defaultValue={5} step={5} marks min={1} max={100} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={8}>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12} md={12}>
|
||||
<Card sx={{backgroundColor:backgroundColor}}>
|
||||
<CardContent>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12} md={12} sx={{textAlign:"center"}}>
|
||||
{(headerIsImage) ? (
|
||||
<img src={headerImageUrl} alt="Header Image" />
|
||||
) : (
|
||||
<Typography variant={headerVariant} color={headerColor}>
|
||||
{headerText}
|
||||
</Typography>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12} sx={{textAlign:"center", marginTop:"2%"}}>
|
||||
<Card sx={{backgroundColor:bioBgColor}}>
|
||||
<CardContent>
|
||||
{(bioHeaderIsImage) ? (
|
||||
<img src={bioHeaderImageUrl} alt="Header Image" />
|
||||
) : (
|
||||
<Typography variant={bioHeaderVariant} color={bioHeaderColor}>
|
||||
{bioHeaderText}
|
||||
</Typography>
|
||||
)}
|
||||
<Typography variant={bioVariant} color={bioColor} > {(profileData ? profileData["biography"]:null)}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12} sx={{textAlign:"center", marginTop:"2%"}}>
|
||||
<Card sx={{backgroundColor:portfolioBgColor}}>
|
||||
{(portfolioShouldScroll)?(
|
||||
<CardContent sx={{height:`${portfolioSize}rem`, overflowY:"scroll",}}>
|
||||
{(profileData ? (
|
||||
<ArtistPortfolio masonry={portfolioWoven} columns={portfolioColumns} artistId={profileData["id"]} />
|
||||
):null)}
|
||||
</CardContent>
|
||||
):(
|
||||
<CardContent >
|
||||
{(profileData ? (
|
||||
<ArtistPortfolio masonry={portfolioWoven} columns={portfolioColumns} artistId={profileData["id"]} />
|
||||
):null)}
|
||||
</CardContent>
|
||||
)}
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
// Protected route, checking user authentication client-side.(CSR)
|
||||
export default withPageAuthRequired(Profile);
|
121
pages/dashboard/index.tsx
Normal file
121
pages/dashboard/index.tsx
Normal file
@ -0,0 +1,121 @@
|
||||
// ** MUI Imports
|
||||
import Grid from '@mui/material/Grid'
|
||||
|
||||
// ** Icons Imports
|
||||
import Poll from 'mdi-material-ui/Poll'
|
||||
import CurrencyUsd from 'mdi-material-ui/CurrencyUsd'
|
||||
import HelpCircleOutline from 'mdi-material-ui/HelpCircleOutline'
|
||||
import BriefcaseVariantOutline from 'mdi-material-ui/BriefcaseVariantOutline'
|
||||
|
||||
// ** Custom Components Imports
|
||||
import CardStatisticsVerticalComponent from '../../core/components/card-statistics/card-stats-vertical'
|
||||
|
||||
|
||||
// ** Styled Component Import
|
||||
import ApexChartWrapper from '../../core/styles/libs/react-apexcharts'
|
||||
import { Card, Typography } from '@mui/material'
|
||||
import { withApiAuthRequired } from "@auth0/nextjs-auth0";
|
||||
import { withPageAuthRequired } from '@auth0/nextjs-auth0/client'
|
||||
import Button from '@mui/material/Button'
|
||||
import { CardContent } from '@mui/material'
|
||||
import Onboarding from '../../components/Onboarding'
|
||||
import { useState } from 'react'
|
||||
import { useEffect } from 'react'
|
||||
import { isObject } from 'util'
|
||||
import Orders from '../../components/Orders'
|
||||
|
||||
|
||||
|
||||
const Dashboard = () => {
|
||||
const [profileData, setSellerProfileData] = useState(null);
|
||||
const [requestData, setSellerRequestData] = useState(null);
|
||||
|
||||
const [onboarding, setOnboarding] = useState(false);
|
||||
const [onboarded, setOnboarded] = useState(false);
|
||||
|
||||
const setOnboardingTrue = () => {
|
||||
setOnboarding(true);
|
||||
}
|
||||
|
||||
const getData = async () => {
|
||||
const profileResponse = await fetch('/api/artist/profile');
|
||||
const sellerProfile = await profileResponse.json();
|
||||
setSellerProfileData(sellerProfile);
|
||||
const requestResponse = await fetch('/api/artist/request');
|
||||
const sellerRequest = await requestResponse.json();
|
||||
setSellerRequestData(sellerRequest);
|
||||
setTimeout(getData, 5000); // Poll every 5 seconds (adjust as needed)
|
||||
|
||||
|
||||
if(sellerRequest != null && Object.keys(sellerRequest).length>0){
|
||||
setOnboarding(true)
|
||||
}
|
||||
if(sellerProfile!=null && Object.keys(sellerProfile).length>0 && sellerRequest["accepted"]){
|
||||
setOnboarded(true)
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
return (
|
||||
|
||||
<ApexChartWrapper>
|
||||
<Grid container spacing={6}>
|
||||
|
||||
<Grid item xs={12} md={6}>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Grid container>
|
||||
<Grid item xs={12} md={12} sx={{textAlign:"center"}}>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
My Orders
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<Orders />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
|
||||
{( onboarding==true && onboarded==false) ? (
|
||||
<Grid item xs={12} md={6}>
|
||||
<Onboarding />
|
||||
</Grid>
|
||||
):(
|
||||
(onboarded) ? (
|
||||
<Grid item xs={12} md={6}>
|
||||
<Card sx={{textAlign:"center", width:"100%"}}>
|
||||
<CardContent>
|
||||
<Grid container>
|
||||
<Grid item xs={12} md={12}>
|
||||
<Typography>
|
||||
THIS IS A TEST
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
) : (
|
||||
<Grid item xs={12} md={6}>
|
||||
<Card sx={{textAlign:"center", width:"100%"}}>
|
||||
<CardContent>
|
||||
<Grid container>
|
||||
<Grid item xs={12} md={12}>
|
||||
<Button color="primary" fullWidth variant="contained" onClick={setOnboardingTrue}>Become An Artist</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
)
|
||||
)}
|
||||
</Grid>
|
||||
</ApexChartWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default withPageAuthRequired(Dashboard)
|
37
pages/form-layouts/index.tsx
Normal file
37
pages/form-layouts/index.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
// ** MUI Imports
|
||||
import Grid from '@mui/material/Grid'
|
||||
|
||||
// ** Styled Component
|
||||
import DatePickerWrapper from '../../core/styles/libs/react-datepicker'
|
||||
|
||||
// ** Demo Components Imports
|
||||
import FormLayoutsBasic from '../../views/form-layouts/FormLayoutsBasic'
|
||||
import FormLayoutsIcons from '../../views/form-layouts/FormLayoutsIcons'
|
||||
import FormLayoutsSeparator from '../../views/form-layouts/FormLayoutsSeparator'
|
||||
import FormLayoutsAlignment from '../../views/form-layouts/FormLayoutsAlignment'
|
||||
|
||||
// ** Third Party Styles Imports
|
||||
import 'react-datepicker/dist/react-datepicker.css'
|
||||
|
||||
const FormLayouts = () => {
|
||||
return (
|
||||
<DatePickerWrapper>
|
||||
<Grid container spacing={6}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<FormLayoutsBasic />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<FormLayoutsIcons />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormLayoutsSeparator />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormLayoutsAlignment />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DatePickerWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormLayouts
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user