modify page content

parent aaa29fd3
// @mui
import { styled } from '@mui/material/styles';
import { Divider } from '@mui/material';
// components
import Page from '../components/Page';
import { AboutHero, AboutWhat, AboutTeam, AboutVision, AboutTestimonials } from '../sections/about';
// ----------------------------------------------------------------------
const RootStyle = styled('div')(({ theme }) => ({
paddingTop: theme.spacing(8),
[theme.breakpoints.up('md')]: {
paddingTop: theme.spacing(11),
},
}));
// ----------------------------------------------------------------------
export default function About() {
return (
<Page title="About us">
<RootStyle>
<AboutHero />
<AboutWhat />
<AboutVision />
<Divider orientation="vertical" sx={{ my: 10, mx: 'auto', width: 2, height: 40 }} />
<AboutTeam />
<AboutTestimonials />
</RootStyle>
</Page>
);
}
// @mui
import { styled } from '@mui/material/styles';
// components
import Page from '../components/Page';
// sections
import {
HomeHero,
HomeMinimal,
HomeDarkMode,
HomeLookingFor,
HomeColorPresets,
HomePricingPlans,
HomeAdvertisement,
HomeCleanInterfaces,
HomeHugePackElements,
} from '../sections/home';
// ----------------------------------------------------------------------
const ContentStyle = styled('div')(({ theme }) => ({
overflow: 'hidden',
position: 'relative',
backgroundColor: theme.palette.background.default,
}));
// ----------------------------------------------------------------------
export default function HomePage() {
return (
<Page title="The starting point for your next project">
<HomeHero />
<ContentStyle>
<HomeMinimal />
<HomeHugePackElements />
<HomeDarkMode />
<HomeColorPresets />
<HomeCleanInterfaces />
<HomePricingPlans />
<HomeLookingFor />
<HomeAdvertisement />
</ContentStyle>
</Page>
);
}
import { m } from "framer-motion";
import * as React from "react";
// @mui
import { styled } from "@mui/material/styles";
import { Box, Button } from "@mui/material";
import Grid from "@mui/material/Grid";
import Paper from "@mui/material/Paper";
import Stack from "@mui/material/Stack";
import IconButton from "@mui/material/IconButton";
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
// components
import Image from "src/components/Image";
// ----------------------------------------------------------------------
const Item = styled(Paper)(({ theme }) => ({
...theme.typography.body2,
padding: theme.spacing(1),
textAlign: "left",
color: theme.palette.text,
}));
const ContentStyle = styled("div")(({ theme }) => ({
maxWidth: "100%",
margin: "auto",
display: "flex",
justifyContent: "center",
flexDirection: "column",
padding: theme.spacing(12, 0, 2, 0),
}));
function Textf(props) {
return (
<Box style={{ backgroundColor: "#ECD1EC", borderRadius: "5%" }}>
<Grid
container
direction="row"
justifyContent="space-around"
alignItems="flex-start"
>
<Grid item sm={5}>
<h3 style={{ paddingTop: "10px" }}> {props.sub}</h3>
</Grid>
<Grid item sm={3}>
<Image
style={{ width: 100, height: 100 }}
src="/assets/illustrations/illustration_login.png"
/>
</Grid>
</Grid>
<Box style={{ textAlign: "center" }}>
<p>{props.des}</p>
</Box>
<Box style={{ textAlign: "right" }}>
<IconButton aria-label="submit" style={{ padding: "10px" }}>
<ArrowForwardIcon />
</IconButton>
</Box>
</Box>
);
}
// ----------------------------------------------------------------------
export default function HomeBody() {
return (
<container>
<ContentStyle sx={{ textAlign: "center", alignItems: "center" }}>
<m.div>
<Grid
container
direction="row"
justifyContent="center"
alignItems="center"
style={{ paddingBottom: "100px" }}
>
<Grid item sm={8}>
<Item>
<h1>
We Are Ready To Help {"&"} Take Care Your Breast Canser Health{" "}
</h1>
<p>
{" "}
Trusted guidance when us most. Because no one should face
breast cancer alone.
</p>
<Box style={{ textAlign: "left", padding: "20px" }}>
<Button variant="outlined" href="#">
{" "}
About us
</Button>
</Box>
</Item>
</Grid>
<Grid item sm={4}>
<Item>
<Image
style={{ width: 200, height: 200 }}
src="/assets/illustrations/illustration_login.png"
/>
</Item>
</Grid>
</Grid>
<Grid
container
direction="row"
justifyContent="center"
alignItems="center"
style={{ paddingBottom: "100px" }}
>
<Grid item sm={6}>
<Item>
<Stack spacing={2}>
<Item>
<Image
style={{ width: 200, height: 200 }}
src="/assets/illustrations/illustration_login.png"
/>
</Item>
<Item>
{" "}
<Image
style={{ width: 200, height: 200 }}
src="/assets/illustrations/illustration_login.png"
/>
</Item>
</Stack>
</Item>
</Grid>
<Grid item sm={6}>
<Item>
<h1>
We Are Ready To Help {"&"} Take Care Your Breast Canser Health{" "}
</h1>
<p>
{" "}
Lorem Ipsum is simply dummy text of the printing and
typesetting industry. <br />
Lorem Ipsum has been the industry's standard dummy text ever
since the <br />
1500s, when an unknown printer took a galley of type and
scrambled it to make a type specimen book.
</p>
<Box style={{ textAlign: "left", padding: "20px" }}>
<Button variant="contained" href="#">
{" "}
Learn More
</Button>
</Box>
</Item>
</Grid>
</Grid>
<Grid
container
direction="row"
justifyContent="center"
alignItems="center"
style={{ paddingBottom: "20px" }}
>
<Grid item sm={8}>
<Item>
<h3>About You</h3>
<h1>We Are Provide Modern Service Care... </h1>
<p>
{" "}
Lorem Ipsum is simply dummy text of the printing and
typesetting industry. <br />
Lorem Ipsum has been the industry's standard dummy text
ever.Lorem Ipsum is <br />
simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the <br /> industry's standard dummy text
ever
</p>
</Item>
</Grid>
<Grid item sm={4}>
<Item>
<Image
style={{ width: 200, height: 200 }}
src="/assets/illustrations/illustration_login.png"
/>
</Item>
</Grid>
</Grid>
<Stack direction="row" spacing={2}>
<Item>
<Textf
sub="Concerned about my risk "
des=" Lorem Ipsum is simply dummy text of "
/>
</Item>
<Item>
<Textf
sub="Concerned about my risk "
des=" Lorem Ipsum is simply dummy text of "
/>
</Item>
<Item>
<Textf
sub="Concerned about my risk "
des=" Lorem Ipsum is simply dummy text of "
/>
</Item>
</Stack>
</m.div>
</ContentStyle>
</container>
);
}
import * as React from "react";
import Grid from "@mui/material/Grid";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
import IconButton from "@mui/material/IconButton";
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
import { Box, Typography, Container } from "@mui/material";
import SocialsButton from "src/components/SocialsButton";
function BottomLinks(props) {
return (
<Box>
<li
style={{
float: "left",
listStyle: "none",
padding: "0 5px 10px 0",
}}
>
<a
href="#"
style={{
color: "black",
textDecoration: "none",
}}
>
<strong> {props.name}</strong>
</a>
</li>
</Box>
);
}
export default function RowAndColumnSpacing() {
return (
<Box sx={{ backgroundColor: "#E2E2E2" }}>
<Grid
container
direction="row"
justifyContent="center"
alignItems="center"
minHeight="5px"
>
<Grid item sm={5}>
<h2>
<b>
People with breastcancer need answers,guidance,and community.
<br />
You can help.
</b>
</h2>
<Box sx={{ padding: "10px", textAlign: "left" }}>
<Button variant="contained">Donete</Button>
</Box>
<Box>
<BottomLinks name="Polices |" />
<BottomLinks name="Privacy |" />
<BottomLinks name="Term of Use |" />
<BottomLinks name="Site map" />
</Box>
</Grid>
<Grid item sm={5}>
<Box>
<h2>
<b>Stay informed mail with us</b>
</h2>
<p>
<b>
By submitting my email, I agree to receive newsletter from
Breastcancer.org
</b>
</p>
</Box>
<Box>
<TextField
id="filled-multiline-flexible"
label="Email"
multiline
maxRows={4}
variant="standard"
/>
<IconButton aria-label="submit" style={{ paddingTop: "20px" }}>
<ArrowForwardIcon />
</IconButton>
</Box>
<SocialsButton sx={{ mx: 0.5 }} />
<Typography
component="p"
variant="body2"
sx={{
paddingTop: "20px",
fontSize: 13,
textAlign: { xs: "left", md: "left" },
}}
>
© 2022 Breastcancer.org- All rights reserved
</Typography>
</Grid>
</Grid>
</Box>
);
}
import { useLocation } from "react-router-dom";
import { Link as RouterLink } from "react-router-dom";
// @mui
import { styled, useTheme } from "@mui/material/styles";
import { Box, Button, AppBar, Toolbar, Container } from "@mui/material";
// hooks
import useOffSetTop from "../../hooks/useOffSetTop";
import useResponsive from "../../hooks/useResponsive";
// utils
import cssStyles from "../../utils/cssStyles";
// config
import { HEADER } from "../../config";
// components
import Logo from "../../components/Logo";
import Label from "../../components/Label";
//
import { PATH_AUTH } from "src/routes/paths";
import MenuDesktop from "src/layouts/main/MenuDesktop";
import MenuMobile from "src/layouts/main/MenuMobile";
import navConfig from "src/layouts/main/MenuConfig";
// ----------------------------------------------------------------------
const ToolbarStyle = styled(Toolbar)(({ theme }) => ({
height: HEADER.MOBILE_HEIGHT,
transition: theme.transitions.create(["height", "background-color"], {
easing: theme.transitions.easing.easeInOut,
duration: theme.transitions.duration.shorter,
}),
[theme.breakpoints.up("md")]: {
height: HEADER.MAIN_DESKTOP_HEIGHT,
},
}));
const ToolbarShadowStyle = styled("div")(({ theme }) => ({
left: 0,
right: 0,
bottom: 0,
height: 24,
zIndex: -1,
margin: "auto",
borderRadius: "50%",
position: "absolute",
width: `calc(100% - 48px)`,
boxShadow: theme.customShadows.z8,
}));
// ----------------------------------------------------------------------
export default function HomeHeader() {
const isOffset = useOffSetTop(HEADER.MAIN_DESKTOP_HEIGHT);
const theme = useTheme();
const { pathname } = useLocation();
const isDesktop = useResponsive("up", "md");
const isHome = pathname === "/";
return (
<AppBar sx={{ boxShadow: 0, bgcolor: "transparent" }}>
<ToolbarStyle
disableGutters
sx={{
...(isOffset && {
...cssStyles(theme).bgBlur(),
height: { md: HEADER.MAIN_DESKTOP_HEIGHT - 16 },
}),
}}
>
<Container
sx={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
}}
>
{/* <Logo /> */}
<Label color="info" sx={{ ml: 1 }}>
HOPE
</Label>
<Box sx={{ flexGrow: 1 }} />
{isDesktop && (
<MenuDesktop
isOffset={isOffset}
isHome={isHome}
navConfig={navConfig}
/>
)}
<Button
variant="contained"
target="_blank"
rel="noopener"
to={PATH_AUTH.login}
component={RouterLink}
>
Login
</Button>
{!isDesktop && (
<MenuMobile
isOffset={isOffset}
isHome={isHome}
navConfig={navConfig}
/>
)}
</Container>
</ToolbarStyle>
{isOffset && <ToolbarShadowStyle />}
</AppBar>
);
}
import React from "react";
import HomeHeader from "./HomeHeader";
import HomeBody from "./HomeBody";
import HomeFooter from "./HomeFooter";
import { Box } from "@mui/material";
export default function HomeIndex() {
return (
<Box>
<HomeHeader />
<HomeBody />
<HomeFooter />
</Box>
);
}
import { Link as RouterLink } from "react-router-dom";
// @mui
import { styled } from "@mui/material/styles";
import { Card, Stack, Link, Container, Typography } from "@mui/material";
// routes
import { PATH_AUTH } from "../../routes/paths";
// hooks
import useResponsive from "../../hooks/useResponsive";
// components
import Page from "../../components/Page";
import Logo from "../../components/Logo";
import { Grid, Box } from "@mui/material";
// sections
import { LoginForm } from "../../sections/auth/login";
import Label from "src/components/Label";
// ----------------------------------------------------------------------
const RootStyle = styled("div")(({ theme }) => ({
[theme.breakpoints.up("md")]: {
display: "flex",
},
}));
const ContentStyle = styled("div")(({ theme }) => ({
maxWidth: 500,
margin: "auto",
minHeight: "100vh",
display: "flex",
justifyContent: "center",
flexDirection: "column",
}));
// ----------------------------------------------------------------------
export default function Login() {
const smUp = useResponsive("up", "sm");
const mdUp = useResponsive("up", "md");
return (
<Page title="Login">
<RootStyle>
<Box sx={{ padding: "20px" }}>
<Label color="info" sx={{ ml: 1 }}>
HOPE
</Label>
</Box>
<Grid
container
direction="row"
justifyContent="space-around"
alignItems="center"
>
<Grid item sm={5} sx={{ textAlign: "center" }}>
<Typography
variant="h3"
sx={{ px: 5, mt: 10, mb: 5 }}
textAlign="center"
>
Log in to our <br /> community
</Typography>
Not a member of the community? {""}
<Link
variant="subtitle2"
component={RouterLink}
to={PATH_AUTH.register}
>
Join Now
</Link>
</Grid>
<Grid item sm={5} sx={{ textAlign: "center" }}>
<ContentStyle>
<LoginForm />
</ContentStyle>
</Grid>
</Grid>
</RootStyle>
</Page>
);
}
// @mui
import { styled } from '@mui/material/styles';
import { Box, Link, Container, Typography } from '@mui/material';
// layouts
import LogoOnlyLayout from '../../layouts/LogoOnlyLayout';
// components
import Page from '../../components/Page';
// sections
import { NewPasswordForm } from '../../sections/auth/new-password';
// assets
import { SentIcon } from '../../assets';
// ----------------------------------------------------------------------
const ContentStyle = styled('div')(({ theme }) => ({
maxWidth: 480,
margin: 'auto',
minHeight: '100vh',
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
padding: theme.spacing(12, 0),
}));
// ----------------------------------------------------------------------
export default function NewPassword() {
return (
<Page title="New Password">
<LogoOnlyLayout />
<Container>
<ContentStyle sx={{ textAlign: 'center' }}>
<SentIcon sx={{ mb: 5, mx: 'auto', height: 120 }} />
<Typography variant="h3" gutterBottom>
Request sent successfully!
</Typography>
<Typography sx={{ color: 'text.secondary' }}>
We've sent a 6-digit confirmation email to your email.
<br />
Please enter the code in below box to verify your email.
</Typography>
<Box sx={{ mt: 5, mb: 3 }}>
<NewPasswordForm />
</Box>
<Typography variant="body2">
Don’t have a code? &nbsp;
<Link variant="subtitle2" onClick={() => {}}>
Resend code
</Link>
</Typography>
</ContentStyle>
</Container>
</Page>
);
}
import { Link as RouterLink } from "react-router-dom";
// @mui
import { styled } from "@mui/material/styles";
import { Box, Link, Container, Typography } from "@mui/material";
// hooks
import useResponsive from "../../hooks/useResponsive";
// routes
import { PATH_AUTH } from "../../routes/paths";
// components
import Page from "../../components/Page";
// sections
import { RegisterForm } from "../../sections/auth/register";
import { Icon } from "@iconify/react";
import Grid from "@mui/material/Grid";
import Label from "src/components/Label";
// ----------------------------------------------------------------------
const RootStyle = styled("div")(({ theme }) => ({
[theme.breakpoints.up("md")]: {
display: "flex",
},
}));
const ContentStyle = styled("div")(({ theme }) => ({
maxWidth: 480,
margin: "auto",
minHeight: "100vh",
display: "flex",
justifyContent: "center",
flexDirection: "column",
padding: theme.spacing(12, 0),
}));
// ----------------------------------------------------------------------
export default function Register() {
const smUp = useResponsive("up", "sm");
const mdUp = useResponsive("up", "md");
return (
<Page title="Register">
<RootStyle>
{/* <Box sx={{}}>
<Label color="secondary" sx={{ ml: 1 }}>
HOPE
</Label>
</Box> */}
<Grid
container
direction="row"
justifyContent="space-around"
alignItems="center"
>
<Grid item sm={4}>
<Typography
variant="h3"
sx={{ px: 5, mt: 10, mb: 5 }}
textAlign="center"
>
Join our <br />
community
</Typography>
<hr />
<Box>
<ul>
<Icon icon="arcticons:nrf-connect" inline={true} /> Connect with
community members for support and practical information{" "}
</ul>{" "}
<br />
<ul>
<Icon icon="ic:outline-saved-search" inline={true} /> Get
answers to your questions from people with shared experience{" "}
</ul>
<br />
<ul>
<Icon icon="mdi:paper-text-outline" inline={true} /> Information
peronalized for you. delivered directly to you
</ul>
<br />
<Typography variant="body2" sx={{ mt: { md: -2 } }}>
<br />
<Link
variant="subtitle2"
component={RouterLink}
to={PATH_AUTH.register}
>
Watch a message
</Link>{" "}
from the Breastcancer.org community
</Typography>
</Box>
</Grid>
<Grid item sm={6} sx={{ padding: "40px 0 20px 0" }}>
<RegisterForm />
</Grid>
</Grid>
</RootStyle>
</Page>
);
}
import { Link as RouterLink } from 'react-router-dom';
// @mui
import { styled } from '@mui/material/styles';
import { Button, Container, Typography } from '@mui/material';
// layouts
import LogoOnlyLayout from '../../layouts/LogoOnlyLayout';
// routes
import { PATH_AUTH } from '../../routes/paths';
// components
import Page from '../../components/Page';
// sections
import { ResetPasswordForm } from '../../sections/auth/reset-password';
// ----------------------------------------------------------------------
const ContentStyle = styled('div')(({ theme }) => ({
maxWidth: 480,
margin: 'auto',
minHeight: '100vh',
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
padding: theme.spacing(12, 0),
}));
// ----------------------------------------------------------------------
export default function ResetPassword() {
return (
<Page title="Reset Password">
<LogoOnlyLayout />
<Container>
<ContentStyle sx={{ textAlign: 'center' }}>
<Typography variant="h3" paragraph>
Forgot your password?
</Typography>
<Typography sx={{ color: 'text.secondary', mb: 5 }}>
Please enter the email address associated with your account and We will email you a link to reset your
password.
</Typography>
<ResetPasswordForm />
<Button fullWidth size="large" component={RouterLink} to={PATH_AUTH.login} sx={{ mt: 1 }}>
Back
</Button>
</ContentStyle>
</Container>
</Page>
);
}
// @mui
import { styled } from '@mui/material/styles';
import { Box, Link, Container, Typography } from '@mui/material';
// layouts
import LogoOnlyLayout from '../../layouts/LogoOnlyLayout';
// components
import Page from '../../components/Page';
// sections
import { VerifyCodeForm } from '../../sections/auth/verify-code';
// ----------------------------------------------------------------------
const ContentStyle = styled('div')(({ theme }) => ({
maxWidth: 480,
margin: 'auto',
minHeight: '100vh',
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
padding: theme.spacing(12, 0),
}));
// ----------------------------------------------------------------------
export default function VerifyCode() {
return (
<Page title="Verify Code">
<LogoOnlyLayout />
<Container>
<ContentStyle sx={{ textAlign: 'center' }}>
<Typography variant="h3" paragraph>
Please check your email!
</Typography>
<Typography sx={{ color: 'text.secondary' }}>
We have emailed a 6-digit confirmation code to acb@domain, please enter the code in below box to verify your
email.
</Typography>
<Box sx={{ mt: 5, mb: 3 }}>
<VerifyCodeForm />
</Box>
<Typography variant="body2">
Dont have a code? &nbsp;
<Link variant="subtitle2" onClick={() => {}}>
Resend code
</Link>
</Typography>
</ContentStyle>
</Container>
</Page>
);
}
// @mui
import { Container } from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import { BlogNewPostForm } from '../../sections/@dashboard/blog';
// ----------------------------------------------------------------------
export default function BlogNewPost() {
const { themeStretch } = useSettings();
return (
<Page title="Blog: New Post">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Create a new post"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'Blog', href: PATH_DASHBOARD.blog.root },
{ name: 'New Post' },
]}
/>
<BlogNewPostForm />
</Container>
</Page>
);
}
import { useEffect, useState, useCallback } from 'react';
import { sentenceCase } from 'change-case';
import { useParams } from 'react-router-dom';
// @mui
import { Box, Card, Divider, Container, Typography, Pagination } from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
import useIsMountedRef from '../../hooks/useIsMountedRef';
// utils
import axios from '../../utils/axios';
// components
import Page from '../../components/Page';
import Markdown from '../../components/Markdown';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
import { SkeletonPost } from '../../components/skeleton';
// sections
import {
BlogPostHero,
BlogPostTags,
BlogPostRecent,
BlogPostCommentList,
BlogPostCommentForm,
} from '../../sections/@dashboard/blog';
// ----------------------------------------------------------------------
export default function BlogPost() {
const { themeStretch } = useSettings();
const isMountedRef = useIsMountedRef();
const { title } = useParams();
const [recentPosts, setRecentPosts] = useState([]);
const [post, setPost] = useState(null);
const [error, setError] = useState(null);
const getPost = useCallback(async () => {
try {
const response = await axios.get('/api/blog/post', {
params: { title },
});
if (isMountedRef.current) {
setPost(response.data.post);
}
} catch (error) {
console.error(error);
setError(error.message);
}
}, [isMountedRef, title]);
const getRecentPosts = useCallback(async () => {
try {
const response = await axios.get('/api/blog/posts/recent', {
params: { title },
});
if (isMountedRef.current) {
setRecentPosts(response.data.recentPosts);
}
} catch (error) {
console.error(error);
}
}, [isMountedRef, title]);
useEffect(() => {
getPost();
getRecentPosts();
}, [getRecentPosts, getPost]);
return (
<Page title="Blog: Post Details">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Post Details"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'Blog', href: PATH_DASHBOARD.blog.root },
{ name: sentenceCase(title) },
]}
/>
{post && (
<Card>
<BlogPostHero post={post} />
<Box sx={{ p: { xs: 3, md: 5 } }}>
<Typography variant="h6" sx={{ mb: 5 }}>
{post.description}
</Typography>
<Markdown children={post.body} />
<Box sx={{ my: 5 }}>
<Divider />
<BlogPostTags post={post} />
<Divider />
</Box>
<Box sx={{ display: 'flex', mb: 2 }}>
<Typography variant="h4">Comments</Typography>
<Typography variant="subtitle2" sx={{ color: 'text.disabled' }}>
({post.comments.length})
</Typography>
</Box>
<BlogPostCommentList post={post} />
<Box sx={{ mb: 5, mt: 3, display: 'flex', justifyContent: 'flex-end' }}>
<Pagination count={8} color="primary" />
</Box>
<BlogPostCommentForm />
</Box>
</Card>
)}
{!post && !error && <SkeletonPost />}
{error && <Typography variant="h6">404 {error}!</Typography>}
<BlogPostRecent posts={recentPosts} />
</Container>
</Page>
);
}
import orderBy from 'lodash/orderBy';
import { Link as RouterLink } from 'react-router-dom';
import { useEffect, useCallback, useState } from 'react';
// @mui
import { Grid, Button, Container, Stack } from '@mui/material';
// hooks
import useSettings from '../../hooks/useSettings';
import useIsMountedRef from '../../hooks/useIsMountedRef';
// utils
import axios from '../../utils/axios';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// components
import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
import { SkeletonPostItem } from '../../components/skeleton';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import { BlogPostCard, BlogPostsSort, BlogPostsSearch } from '../../sections/@dashboard/blog';
// ----------------------------------------------------------------------
const SORT_OPTIONS = [
{ value: 'latest', label: 'Latest' },
{ value: 'popular', label: 'Popular' },
{ value: 'oldest', label: 'Oldest' },
];
// ----------------------------------------------------------------------
const applySort = (posts, sortBy) => {
if (sortBy === 'latest') {
return orderBy(posts, ['createdAt'], ['desc']);
}
if (sortBy === 'oldest') {
return orderBy(posts, ['createdAt'], ['asc']);
}
if (sortBy === 'popular') {
return orderBy(posts, ['view'], ['desc']);
}
return posts;
};
export default function BlogPosts() {
const { themeStretch } = useSettings();
const isMountedRef = useIsMountedRef();
const [posts, setPosts] = useState([]);
const [filters, setFilters] = useState('latest');
const sortedPosts = applySort(posts, filters);
const getAllPosts = useCallback(async () => {
try {
const response = await axios.get('/api/blog/posts/all');
if (isMountedRef.current) {
setPosts(response.data.posts);
}
} catch (error) {
console.error(error);
}
}, [isMountedRef]);
useEffect(() => {
getAllPosts();
}, [getAllPosts]);
const handleChangeSort = (value) => {
if (value) {
setFilters(value);
}
};
return (
<Page title="Blog: Posts">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Blog"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'Blog', href: PATH_DASHBOARD.blog.root },
{ name: 'Posts' },
]}
action={
<Button
variant="contained"
component={RouterLink}
to={PATH_DASHBOARD.blog.new}
startIcon={<Iconify icon={'eva:plus-fill'} />}
>
New Post
</Button>
}
/>
<Stack mb={5} direction="row" alignItems="center" justifyContent="space-between">
<BlogPostsSearch />
<BlogPostsSort query={filters} options={SORT_OPTIONS} onSort={handleChangeSort} />
</Stack>
<Grid container spacing={3}>
{(!posts.length ? [...Array(12)] : sortedPosts).map((post, index) =>
post ? (
<Grid key={post.id} item xs={12} sm={6} md={(index === 0 && 6) || 3}>
<BlogPostCard post={post} index={index} />
</Grid>
) : (
<SkeletonPostItem key={index} />
)
)}
</Grid>
</Container>
</Page>
);
}
import FullCalendar from '@fullcalendar/react'; // => request placed at the top
import listPlugin from '@fullcalendar/list';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import timelinePlugin from '@fullcalendar/timeline';
import interactionPlugin from '@fullcalendar/interaction';
//
import { useState, useRef, useEffect } from 'react';
// @mui
import { Card, Button, Container, DialogTitle } from '@mui/material';
// redux
import { useDispatch, useSelector } from '../../redux/store';
import { getEvents, openModal, closeModal, updateEvent, selectEvent, selectRange } from '../../redux/slices/calendar';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
import useResponsive from '../../hooks/useResponsive';
// components
import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
import { DialogAnimate } from '../../components/animate';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import { CalendarForm, CalendarStyle, CalendarToolbar } from '../../sections/@dashboard/calendar';
// ----------------------------------------------------------------------
const selectedEventSelector = (state) => {
const { events, selectedEventId } = state.calendar;
if (selectedEventId) {
return events.find((_event) => _event.id === selectedEventId);
}
return null;
};
export default function Calendar() {
const { themeStretch } = useSettings();
const dispatch = useDispatch();
const isDesktop = useResponsive('up', 'sm');
const calendarRef = useRef(null);
const [date, setDate] = useState(new Date());
const [view, setView] = useState(isDesktop ? 'dayGridMonth' : 'listWeek');
const selectedEvent = useSelector(selectedEventSelector);
const { events, isOpenModal, selectedRange } = useSelector((state) => state.calendar);
useEffect(() => {
dispatch(getEvents());
}, [dispatch]);
useEffect(() => {
const calendarEl = calendarRef.current;
if (calendarEl) {
const calendarApi = calendarEl.getApi();
const newView = isDesktop ? 'dayGridMonth' : 'listWeek';
calendarApi.changeView(newView);
setView(newView);
}
}, [isDesktop]);
const handleClickToday = () => {
const calendarEl = calendarRef.current;
if (calendarEl) {
const calendarApi = calendarEl.getApi();
calendarApi.today();
setDate(calendarApi.getDate());
}
};
const handleChangeView = (newView) => {
const calendarEl = calendarRef.current;
if (calendarEl) {
const calendarApi = calendarEl.getApi();
calendarApi.changeView(newView);
setView(newView);
}
};
const handleClickDatePrev = () => {
const calendarEl = calendarRef.current;
if (calendarEl) {
const calendarApi = calendarEl.getApi();
calendarApi.prev();
setDate(calendarApi.getDate());
}
};
const handleClickDateNext = () => {
const calendarEl = calendarRef.current;
if (calendarEl) {
const calendarApi = calendarEl.getApi();
calendarApi.next();
setDate(calendarApi.getDate());
}
};
const handleSelectRange = (arg) => {
const calendarEl = calendarRef.current;
if (calendarEl) {
const calendarApi = calendarEl.getApi();
calendarApi.unselect();
}
dispatch(selectRange(arg.start, arg.end));
};
const handleSelectEvent = (arg) => {
dispatch(selectEvent(arg.event.id));
};
const handleResizeEvent = async ({ event }) => {
try {
dispatch(
updateEvent(event.id, {
allDay: event.allDay,
start: event.start,
end: event.end,
})
);
} catch (error) {
console.error(error);
}
};
const handleDropEvent = async ({ event }) => {
try {
dispatch(
updateEvent(event.id, {
allDay: event.allDay,
start: event.start,
end: event.end,
})
);
} catch (error) {
console.error(error);
}
};
const handleAddEvent = () => {
dispatch(openModal());
};
const handleCloseModal = () => {
dispatch(closeModal());
};
return (
<Page title="Calendar">
<Container maxWidth={themeStretch ? false : 'xl'}>
<HeaderBreadcrumbs
heading="Calendar"
links={[{ name: 'Dashboard', href: PATH_DASHBOARD.root }, { name: 'Calendar' }]}
moreLink="https://fullcalendar.io/docs/react"
action={
<Button
variant="contained"
startIcon={<Iconify icon={'eva:plus-fill'} width={20} height={20} />}
onClick={handleAddEvent}
>
New Event
</Button>
}
/>
<Card>
<CalendarStyle>
<CalendarToolbar
date={date}
view={view}
onNextDate={handleClickDateNext}
onPrevDate={handleClickDatePrev}
onToday={handleClickToday}
onChangeView={handleChangeView}
/>
<FullCalendar
weekends
editable
droppable
selectable
events={events}
ref={calendarRef}
rerenderDelay={10}
initialDate={date}
initialView={view}
dayMaxEventRows={3}
eventDisplay="block"
headerToolbar={false}
allDayMaintainDuration
eventResizableFromStart
select={handleSelectRange}
eventDrop={handleDropEvent}
eventClick={handleSelectEvent}
eventResize={handleResizeEvent}
height={isDesktop ? 720 : 'auto'}
plugins={[listPlugin, dayGridPlugin, timelinePlugin, timeGridPlugin, interactionPlugin]}
/>
</CalendarStyle>
</Card>
<DialogAnimate open={isOpenModal} onClose={handleCloseModal}>
<DialogTitle>{selectedEvent ? 'Edit Event' : 'Add Event'}</DialogTitle>
<CalendarForm event={selectedEvent || {}} range={selectedRange} onCancel={handleCloseModal} />
</DialogAnimate>
</Container>
</Page>
);
}
import { useEffect } from 'react';
// @mui
import { Card, Container } from '@mui/material';
// redux
import { useDispatch } from '../../redux/store';
import { getConversations, getContacts } from '../../redux/slices/chat';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
import { ChatSidebar, ChatWindow } from '../../sections/@dashboard/chat';
// ----------------------------------------------------------------------
export default function Chat() {
const { themeStretch } = useSettings();
const dispatch = useDispatch();
useEffect(() => {
dispatch(getConversations());
dispatch(getContacts());
}, [dispatch]);
return (
<Page title="Chat">
<Container maxWidth={themeStretch ? false : 'xl'}>
<HeaderBreadcrumbs
heading="Chat"
links={[{ name: 'Dashboard', href: PATH_DASHBOARD.root }, { name: 'Chat' }]}
/>
<Card sx={{ height: '72vh', display: 'flex' }}>
<ChatSidebar />
<ChatWindow />
</Card>
</Container>
</Page>
);
}
import PropTypes from 'prop-types';
import { useEffect } from 'react';
// @mui
import { styled } from '@mui/material/styles';
import { Box, Grid, Step, Stepper, Container, StepLabel, StepConnector } from '@mui/material';
// redux
import { useDispatch, useSelector } from '../../redux/store';
import { getCart, createBilling } from '../../redux/slices/product';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useIsMountedRef from '../../hooks/useIsMountedRef';
import useSettings from '../../hooks/useSettings';
// components
import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import {
CheckoutCart,
CheckoutPayment,
CheckoutOrderComplete,
CheckoutBillingAddress,
} from '../../sections/@dashboard/e-commerce/checkout';
// ----------------------------------------------------------------------
const STEPS = ['Cart', 'Billing & address', 'Payment'];
const QontoConnector = styled(StepConnector)(({ theme }) => ({
top: 10,
left: 'calc(-50% + 20px)',
right: 'calc(50% + 20px)',
'& .MuiStepConnector-line': {
borderTopWidth: 2,
borderColor: theme.palette.divider,
},
'&.Mui-active, &.Mui-completed': {
'& .MuiStepConnector-line': {
borderColor: theme.palette.primary.main,
},
},
}));
QontoStepIcon.propTypes = {
active: PropTypes.bool,
completed: PropTypes.bool,
};
function QontoStepIcon({ active, completed }) {
return (
<Box
sx={{
zIndex: 9,
width: 24,
height: 24,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: active ? 'primary.main' : 'text.disabled',
}}
>
{completed ? (
<Iconify icon={'eva:checkmark-fill'} sx={{ zIndex: 1, width: 20, height: 20, color: 'primary.main' }} />
) : (
<Box
sx={{
width: 8,
height: 8,
borderRadius: '50%',
backgroundColor: 'currentColor',
}}
/>
)}
</Box>
);
}
export default function EcommerceCheckout() {
const { themeStretch } = useSettings();
const dispatch = useDispatch();
const isMountedRef = useIsMountedRef();
const { checkout } = useSelector((state) => state.product);
const { cart, billing, activeStep } = checkout;
const isComplete = activeStep === STEPS.length;
useEffect(() => {
if (isMountedRef.current) {
dispatch(getCart(cart));
}
}, [dispatch, isMountedRef, cart]);
useEffect(() => {
if (activeStep === 1) {
dispatch(createBilling(null));
}
}, [dispatch, activeStep]);
return (
<Page title="Ecommerce: Checkout">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Checkout"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{
name: 'E-Commerce',
href: PATH_DASHBOARD.eCommerce.root,
},
{ name: 'Checkout' },
]}
/>
<Grid container justifyContent={isComplete ? 'center' : 'flex-start'}>
<Grid item xs={12} md={8} sx={{ mb: 5 }}>
<Stepper alternativeLabel activeStep={activeStep} connector={<QontoConnector />}>
{STEPS.map((label) => (
<Step key={label}>
<StepLabel
StepIconComponent={QontoStepIcon}
sx={{
'& .MuiStepLabel-label': {
typography: 'subtitle2',
color: 'text.disabled',
},
}}
>
{label}
</StepLabel>
</Step>
))}
</Stepper>
</Grid>
</Grid>
{!isComplete ? (
<>
{activeStep === 0 && <CheckoutCart />}
{activeStep === 1 && <CheckoutBillingAddress />}
{activeStep === 2 && billing && <CheckoutPayment />}
</>
) : (
<CheckoutOrderComplete open={isComplete} />
)}
</Container>
</Page>
);
}
import { useEffect } from 'react';
import { paramCase } from 'change-case';
import { useParams, useLocation } from 'react-router-dom';
// @mui
import { Container } from '@mui/material';
// redux
import { useDispatch, useSelector } from '../../redux/store';
import { getProducts } from '../../redux/slices/product';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
import ProductNewEditForm from '../../sections/@dashboard/e-commerce/ProductNewEditForm';
// ----------------------------------------------------------------------
export default function EcommerceProductCreate() {
const { themeStretch } = useSettings();
const dispatch = useDispatch();
const { pathname } = useLocation();
const { name } = useParams();
const { products } = useSelector((state) => state.product);
const isEdit = pathname.includes('edit');
const currentProduct = products.find((product) => paramCase(product.name) === name);
useEffect(() => {
dispatch(getProducts());
}, [dispatch]);
return (
<Page title="Ecommerce: Create a new product">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading={!isEdit ? 'Create a new product' : 'Edit product'}
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{
name: 'E-Commerce',
href: PATH_DASHBOARD.eCommerce.root,
},
{ name: !isEdit ? 'New product' : name },
]}
/>
<ProductNewEditForm isEdit={isEdit} currentProduct={currentProduct} />
</Container>
</Page>
);
}
import { sentenceCase } from 'change-case';
import { useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
// @mui
import { alpha, styled } from '@mui/material/styles';
import { Box, Tab, Card, Grid, Divider, Container, Typography } from '@mui/material';
import { TabContext, TabList, TabPanel } from '@mui/lab';
// redux
import { useDispatch, useSelector } from '../../redux/store';
import { getProduct, addCart, onGotoStep } from '../../redux/slices/product';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// components
import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
import Markdown from '../../components/Markdown';
import { SkeletonProduct } from '../../components/skeleton';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import {
ProductDetailsSummary,
ProductDetailsReview,
ProductDetailsCarousel,
} from '../../sections/@dashboard/e-commerce/product-details';
import CartWidget from '../../sections/@dashboard/e-commerce/CartWidget';
// ----------------------------------------------------------------------
const PRODUCT_DESCRIPTION = [
{
title: '100% Original',
description: 'Chocolate bar candy canes ice cream toffee cookie halvah.',
icon: 'ic:round-verified',
},
{
title: '10 Day Replacement',
description: 'Marshmallow biscuit donut dragée fruitcake wafer.',
icon: 'eva:clock-fill',
},
{
title: 'Year Warranty',
description: 'Cotton candy gingerbread cake I love sugar sweet.',
icon: 'ic:round-verified-user',
},
];
const IconWrapperStyle = styled('div')(({ theme }) => ({
margin: 'auto',
display: 'flex',
borderRadius: '50%',
alignItems: 'center',
width: theme.spacing(8),
justifyContent: 'center',
height: theme.spacing(8),
marginBottom: theme.spacing(3),
color: theme.palette.primary.main,
backgroundColor: `${alpha(theme.palette.primary.main, 0.08)}`,
}));
// ----------------------------------------------------------------------
export default function EcommerceProductDetails() {
const { themeStretch } = useSettings();
const dispatch = useDispatch();
const [value, setValue] = useState('1');
const { name = '' } = useParams();
const { product, error, checkout } = useSelector((state) => state.product);
useEffect(() => {
dispatch(getProduct(name));
}, [dispatch, name]);
const handleAddCart = (product) => {
dispatch(addCart(product));
};
const handleGotoStep = (step) => {
dispatch(onGotoStep(step));
};
return (
<Page title="Ecommerce: Product Details">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Product Details"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{
name: 'E-Commerce',
href: PATH_DASHBOARD.eCommerce.root,
},
{
name: 'Shop',
href: PATH_DASHBOARD.eCommerce.shop,
},
{ name: sentenceCase(name) },
]}
/>
<CartWidget />
{product && (
<>
<Card>
<Grid container>
<Grid item xs={12} md={6} lg={7}>
<ProductDetailsCarousel product={product} />
</Grid>
<Grid item xs={12} md={6} lg={5}>
<ProductDetailsSummary
product={product}
cart={checkout.cart}
onAddCart={handleAddCart}
onGotoStep={handleGotoStep}
/>
</Grid>
</Grid>
</Card>
<Grid container sx={{ my: 8 }}>
{PRODUCT_DESCRIPTION.map((item) => (
<Grid item xs={12} md={4} key={item.title}>
<Box sx={{ my: 2, mx: 'auto', maxWidth: 280, textAlign: 'center' }}>
<IconWrapperStyle>
<Iconify icon={item.icon} width={36} height={36} />
</IconWrapperStyle>
<Typography variant="subtitle1" gutterBottom>
{item.title}
</Typography>
<Typography sx={{ color: 'text.secondary' }}>{item.description}</Typography>
</Box>
</Grid>
))}
</Grid>
<Card>
<TabContext value={value}>
<Box sx={{ px: 3, bgcolor: 'background.neutral' }}>
<TabList onChange={(e, value) => setValue(value)}>
<Tab disableRipple value="1" label="Description" />
<Tab
disableRipple
value="2"
label={`Review (${product.reviews.length})`}
sx={{ '& .MuiTab-wrapper': { whiteSpace: 'nowrap' } }}
/>
</TabList>
</Box>
<Divider />
<TabPanel value="1">
<Box sx={{ p: 3 }}>
<Markdown children={product.description} />
</Box>
</TabPanel>
<TabPanel value="2">
<ProductDetailsReview product={product} />
</TabPanel>
</TabContext>
</Card>
</>
)}
{!product && <SkeletonProduct />}
{error && <Typography variant="h6">404 Product not found</Typography>}
</Container>
</Page>
);
}
import { paramCase } from 'change-case';
import { useState, useEffect } from 'react';
import { useNavigate, Link as RouterLink } from 'react-router-dom';
// @mui
import {
Box,
Card,
Table,
Button,
Switch,
Tooltip,
TableBody,
Container,
IconButton,
TableContainer,
TablePagination,
FormControlLabel,
} from '@mui/material';
// redux
import { useDispatch, useSelector } from '../../redux/store';
import { getProducts } from '../../redux/slices/product';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
import useTable, { getComparator, emptyRows } from '../../hooks/useTable';
// components
import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
import Scrollbar from '../../components/Scrollbar';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
import {
TableNoData,
TableSkeleton,
TableEmptyRows,
TableHeadCustom,
TableSelectedActions,
} from '../../components/table';
// sections
import { ProductTableRow, ProductTableToolbar } from '../../sections/@dashboard/e-commerce/product-list';
// ----------------------------------------------------------------------
const TABLE_HEAD = [
{ id: 'name', label: 'Product', align: 'left' },
{ id: 'createdAt', label: 'Create at', align: 'left' },
{ id: 'inventoryType', label: 'Status', align: 'center', width: 180 },
{ id: 'price', label: 'Price', align: 'right' },
{ id: '' },
];
// ----------------------------------------------------------------------
export default function EcommerceProductList() {
const {
dense,
page,
order,
orderBy,
rowsPerPage,
setPage,
//
selected,
setSelected,
onSelectRow,
onSelectAllRows,
//
onSort,
onChangeDense,
onChangePage,
onChangeRowsPerPage,
} = useTable({
defaultOrderBy: 'createdAt',
});
const { themeStretch } = useSettings();
const navigate = useNavigate();
const dispatch = useDispatch();
const { products, isLoading } = useSelector((state) => state.product);
const [tableData, setTableData] = useState([]);
const [filterName, setFilterName] = useState('');
useEffect(() => {
dispatch(getProducts());
}, [dispatch]);
useEffect(() => {
if (products.length) {
setTableData(products);
}
}, [products]);
const handleFilterName = (filterName) => {
setFilterName(filterName);
setPage(0);
};
const handleDeleteRow = (id) => {
const deleteRow = tableData.filter((row) => row.id !== id);
setSelected([]);
setTableData(deleteRow);
};
const handleDeleteRows = (selected) => {
const deleteRows = tableData.filter((row) => !selected.includes(row.id));
setSelected([]);
setTableData(deleteRows);
};
const handleEditRow = (id) => {
navigate(PATH_DASHBOARD.eCommerce.edit(paramCase(id)));
};
const dataFiltered = applySortFilter({
tableData,
comparator: getComparator(order, orderBy),
filterName,
});
const denseHeight = dense ? 60 : 80;
const isNotFound = (!dataFiltered.length && !!filterName) || (!isLoading && !dataFiltered.length);
return (
<Page title="Ecommerce: Product List">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Product List"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{
name: 'E-Commerce',
href: PATH_DASHBOARD.eCommerce.root,
},
{ name: 'Product List' },
]}
action={
<Button
variant="contained"
startIcon={<Iconify icon="eva:plus-fill" />}
component={RouterLink}
to={PATH_DASHBOARD.eCommerce.new}
>
New Product
</Button>
}
/>
<Card>
<ProductTableToolbar filterName={filterName} onFilterName={handleFilterName} />
<Scrollbar>
<TableContainer sx={{ minWidth: 960, position: 'relative' }}>
{selected.length > 0 && (
<TableSelectedActions
dense={dense}
numSelected={selected.length}
rowCount={tableData.length}
onSelectAllRows={(checked) =>
onSelectAllRows(
checked,
tableData.map((row) => row.id)
)
}
actions={
<Tooltip title="Delete">
<IconButton color="primary" onClick={() => handleDeleteRows(selected)}>
<Iconify icon={'eva:trash-2-outline'} />
</IconButton>
</Tooltip>
}
/>
)}
<Table size={dense ? 'small' : 'medium'}>
<TableHeadCustom
order={order}
orderBy={orderBy}
headLabel={TABLE_HEAD}
rowCount={tableData.length}
numSelected={selected.length}
onSort={onSort}
onSelectAllRows={(checked) =>
onSelectAllRows(
checked,
tableData.map((row) => row.id)
)
}
/>
<TableBody>
{(isLoading ? [...Array(rowsPerPage)] : dataFiltered)
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row, index) =>
row ? (
<ProductTableRow
key={row.id}
row={row}
selected={selected.includes(row.id)}
onSelectRow={() => onSelectRow(row.id)}
onDeleteRow={() => handleDeleteRow(row.id)}
onEditRow={() => handleEditRow(row.name)}
/>
) : (
!isNotFound && <TableSkeleton key={index} sx={{ height: denseHeight }} />
)
)}
<TableEmptyRows height={denseHeight} emptyRows={emptyRows(page, rowsPerPage, tableData.length)} />
<TableNoData isNotFound={isNotFound} />
</TableBody>
</Table>
</TableContainer>
</Scrollbar>
<Box sx={{ position: 'relative' }}>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={dataFiltered.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={onChangePage}
onRowsPerPageChange={onChangeRowsPerPage}
/>
<FormControlLabel
control={<Switch checked={dense} onChange={onChangeDense} />}
label="Dense"
sx={{ px: 3, py: 1.5, top: 0, position: { md: 'absolute' } }}
/>
</Box>
</Card>
</Container>
</Page>
);
}
// ----------------------------------------------------------------------
function applySortFilter({ tableData, comparator, filterName }) {
const stabilizedThis = tableData.map((el, index) => [el, index]);
stabilizedThis.sort((a, b) => {
const order = comparator(a[0], b[0]);
if (order !== 0) return order;
return a[1] - b[1];
});
tableData = stabilizedThis.map((el) => el[0]);
if (filterName) {
tableData = tableData.filter((item) => item.name.toLowerCase().indexOf(filterName.toLowerCase()) !== -1);
}
return tableData;
}
import { useEffect, useState } from 'react';
import orderBy from 'lodash/orderBy';
// form
import { useForm } from 'react-hook-form';
// @mui
import { Container, Typography, Stack } from '@mui/material';
// redux
import { useDispatch, useSelector } from '../../redux/store';
import { getProducts, filterProducts } from '../../redux/slices/product';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
import { FormProvider } from '../../components/hook-form';
// sections
import {
ShopTagFiltered,
ShopProductSort,
ShopProductList,
ShopFilterSidebar,
ShopProductSearch,
} from '../../sections/@dashboard/e-commerce/shop';
import CartWidget from '../../sections/@dashboard/e-commerce/CartWidget';
// ----------------------------------------------------------------------
export default function EcommerceShop() {
const { themeStretch } = useSettings();
const dispatch = useDispatch();
const [openFilter, setOpenFilter] = useState(false);
const { products, sortBy, filters } = useSelector((state) => state.product);
const filteredProducts = applyFilter(products, sortBy, filters);
const defaultValues = {
gender: filters.gender,
category: filters.category,
colors: filters.colors,
priceRange: filters.priceRange,
rating: filters.rating,
};
const methods = useForm({
defaultValues,
});
const { reset, watch, setValue } = methods;
const values = watch();
const isDefault =
!values.priceRange &&
!values.rating &&
values.gender.length === 0 &&
values.colors.length === 0 &&
values.category === 'All';
useEffect(() => {
dispatch(getProducts());
}, [dispatch]);
useEffect(() => {
dispatch(filterProducts(values));
}, [dispatch, values]);
const handleOpenFilter = () => {
setOpenFilter(true);
};
const handleCloseFilter = () => {
setOpenFilter(false);
};
const handleResetFilter = () => {
reset();
handleCloseFilter();
};
const handleRemoveGender = (value) => {
const newValue = filters.gender.filter((item) => item !== value);
setValue('gender', newValue);
};
const handleRemoveCategory = () => {
setValue('category', 'All');
};
const handleRemoveColor = (value) => {
const newValue = filters.colors.filter((item) => item !== value);
setValue('colors', newValue);
};
const handleRemovePrice = () => {
setValue('priceRange', '');
};
const handleRemoveRating = () => {
setValue('rating', '');
};
return (
<Page title="Ecommerce: Shop">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Shop"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{
name: 'E-Commerce',
href: PATH_DASHBOARD.eCommerce.root,
},
{ name: 'Shop' },
]}
/>
<Stack
spacing={2}
direction={{ xs: 'column', sm: 'row' }}
alignItems={{ sm: 'center' }}
justifyContent="space-between"
sx={{ mb: 2 }}
>
<ShopProductSearch />
<Stack direction="row" spacing={1} flexShrink={0} sx={{ my: 1 }}>
<FormProvider methods={methods}>
<ShopFilterSidebar
onResetAll={handleResetFilter}
isOpen={openFilter}
onOpen={handleOpenFilter}
onClose={handleCloseFilter}
/>
</FormProvider>
<ShopProductSort />
</Stack>
</Stack>
<Stack sx={{ mb: 3 }}>
{!isDefault && (
<>
<Typography variant="body2" gutterBottom>
<strong>{filteredProducts.length}</strong>
&nbsp;Products found
</Typography>
<ShopTagFiltered
filters={filters}
isShowReset={!isDefault && !openFilter}
onRemoveGender={handleRemoveGender}
onRemoveCategory={handleRemoveCategory}
onRemoveColor={handleRemoveColor}
onRemovePrice={handleRemovePrice}
onRemoveRating={handleRemoveRating}
onResetAll={handleResetFilter}
/>
</>
)}
</Stack>
<ShopProductList products={filteredProducts} loading={!products.length && isDefault} />
<CartWidget />
</Container>
</Page>
);
}
// ----------------------------------------------------------------------
function applyFilter(products, sortBy, filters) {
// SORT BY
if (sortBy === 'featured') {
products = orderBy(products, ['sold'], ['desc']);
}
if (sortBy === 'newest') {
products = orderBy(products, ['createdAt'], ['desc']);
}
if (sortBy === 'priceDesc') {
products = orderBy(products, ['price'], ['desc']);
}
if (sortBy === 'priceAsc') {
products = orderBy(products, ['price'], ['asc']);
}
// FILTER PRODUCTS
if (filters.gender.length > 0) {
products = products.filter((product) => filters.gender.includes(product.gender));
}
if (filters.category !== 'All') {
products = products.filter((product) => product.category === filters.category);
}
if (filters.colors.length > 0) {
products = products.filter((product) => product.colors.some((color) => filters.colors.includes(color)));
}
if (filters.priceRange) {
products = products.filter((product) => {
if (filters.priceRange === 'below') {
return product.price < 25;
}
if (filters.priceRange === 'between') {
return product.price >= 25 && product.price <= 75;
}
return product.price > 75;
});
}
if (filters.rating) {
products = products.filter((product) => {
const convertRating = (value) => {
if (value === 'up4Star') return 4;
if (value === 'up3Star') return 3;
if (value === 'up2Star') return 2;
return 1;
};
return product.totalRating > convertRating(filters.rating);
});
}
return products;
}
// @mui
import { useTheme } from '@mui/material/styles';
import { Grid, Container, Typography } from '@mui/material';
// hooks
import useSettings from '../../hooks/useSettings';
// _mock_
import { _analyticPost, _analyticOrderTimeline, _analyticTraffic } from '../../_mock';
// components
import Page from '../../components/Page';
// sections
import {
AnalyticsTasks,
AnalyticsNewsUpdate,
AnalyticsOrderTimeline,
AnalyticsCurrentVisits,
AnalyticsWebsiteVisits,
AnalyticsTrafficBySite,
AnalyticsWidgetSummary,
AnalyticsCurrentSubject,
AnalyticsConversionRates,
} from '../../sections/@dashboard/general/analytics';
// ----------------------------------------------------------------------
export default function GeneralAnalytics() {
const theme = useTheme();
const { themeStretch } = useSettings();
return (
<Page title="General: Analytics">
<Container maxWidth={themeStretch ? false : 'xl'}>
<Typography variant="h4" sx={{ mb: 5 }}>
Hi, Welcome back
</Typography>
<Grid container spacing={3}>
<Grid item xs={12} sm={6} md={3}>
<AnalyticsWidgetSummary title="Weekly Sales" total={714000} icon={'ant-design:android-filled'} />
</Grid>
<Grid item xs={12} sm={6} md={3}>
<AnalyticsWidgetSummary title="New Users" total={1352831} color="info" icon={'ant-design:apple-filled'} />
</Grid>
<Grid item xs={12} sm={6} md={3}>
<AnalyticsWidgetSummary
title="Item Orders"
total={1723315}
color="warning"
icon={'ant-design:windows-filled'}
/>
</Grid>
<Grid item xs={12} sm={6} md={3}>
<AnalyticsWidgetSummary title="Bug Reports" total={234} color="error" icon={'ant-design:bug-filled'} />
</Grid>
<Grid item xs={12} md={6} lg={8}>
<AnalyticsWebsiteVisits
title="Website Visits"
subheader="(+43%) than last year"
chartLabels={[
'01/01/2003',
'02/01/2003',
'03/01/2003',
'04/01/2003',
'05/01/2003',
'06/01/2003',
'07/01/2003',
'08/01/2003',
'09/01/2003',
'10/01/2003',
'11/01/2003',
]}
chartData={[
{
name: 'Team A',
type: 'column',
fill: 'solid',
data: [23, 11, 22, 27, 13, 22, 37, 21, 44, 22, 30],
},
{
name: 'Team B',
type: 'area',
fill: 'gradient',
data: [44, 55, 41, 67, 22, 43, 21, 41, 56, 27, 43],
},
{
name: 'Team C',
type: 'line',
fill: 'solid',
data: [30, 25, 36, 30, 45, 35, 64, 52, 59, 36, 39],
},
]}
/>
</Grid>
<Grid item xs={12} md={6} lg={4}>
<AnalyticsCurrentVisits
title="Current Visits"
chartData={[
{ label: 'America', value: 4344 },
{ label: 'Asia', value: 5435 },
{ label: 'Europe', value: 1443 },
{ label: 'Africa', value: 4443 },
]}
chartColors={[
theme.palette.primary.main,
theme.palette.chart.blue[0],
theme.palette.chart.violet[0],
theme.palette.chart.yellow[0],
]}
/>
</Grid>
<Grid item xs={12} md={6} lg={8}>
<AnalyticsConversionRates
title="Conversion Rates"
subheader="(+43%) than last year"
chartData={[
{ label: 'Italy', value: 400 },
{ label: 'Japan', value: 430 },
{ label: 'China', value: 448 },
{ label: 'Canada', value: 470 },
{ label: 'France', value: 540 },
{ label: 'Germany', value: 580 },
{ label: 'South Korea', value: 690 },
{ label: 'Netherlands', value: 1100 },
{ label: 'United States', value: 1200 },
{ label: 'United Kingdom', value: 1380 },
]}
/>
</Grid>
<Grid item xs={12} md={6} lg={4}>
<AnalyticsCurrentSubject
title="Current Subject"
chartLabels={['English', 'History', 'Physics', 'Geography', 'Chinese', 'Math']}
chartData={[
{ name: 'Series 1', data: [80, 50, 30, 40, 100, 20] },
{ name: 'Series 2', data: [20, 30, 40, 80, 20, 80] },
{ name: 'Series 3', data: [44, 76, 78, 13, 43, 10] },
]}
chartColors={[...Array(6)].map(() => theme.palette.text.secondary)}
/>
</Grid>
<Grid item xs={12} md={6} lg={8}>
<AnalyticsNewsUpdate title="News Update" list={_analyticPost} />
</Grid>
<Grid item xs={12} md={6} lg={4}>
<AnalyticsOrderTimeline title="Order Timeline" list={_analyticOrderTimeline} />
</Grid>
<Grid item xs={12} md={6} lg={4}>
<AnalyticsTrafficBySite title="Traffic by Site" list={_analyticTraffic} />
</Grid>
<Grid item xs={12} md={6} lg={8}>
<AnalyticsTasks
title="Tasks"
list={[
{ id: '1', label: 'Create FireStone Logo' },
{ id: '2', label: 'Add SCSS and JS files if required' },
{ id: '3', label: 'Stakeholder Meeting' },
{ id: '4', label: 'Scoping & Estimations' },
{ id: '5', label: 'Sprint Showcase' },
]}
/>
</Grid>
</Grid>
</Container>
</Page>
);
}
// @mui
import { useTheme } from '@mui/material/styles';
import { Container, Grid, Stack, Button } from '@mui/material';
// hooks
import useAuth from '../../hooks/useAuth';
import useSettings from '../../hooks/useSettings';
// _mock_
import { _appFeatured, _appAuthors, _appInstalled, _appRelated, _appInvoices } from '../../_mock';
// components
import Page from '../../components/Page';
// sections
import {
AppWidget,
AppWelcome,
AppFeatured,
AppNewInvoice,
AppTopAuthors,
AppTopRelated,
AppAreaInstalled,
AppWidgetSummary,
AppCurrentDownload,
AppTopInstalledCountries,
} from '../../sections/@dashboard/general/app';
// assets
import { SeoIllustration } from '../../assets';
// ----------------------------------------------------------------------
export default function GeneralApp() {
const { user } = useAuth();
const theme = useTheme();
const { themeStretch } = useSettings();
return (
<Page title="General: App">
<Container maxWidth={themeStretch ? false : 'xl'}>
<Grid container spacing={3}>
<Grid item xs={12} md={8}>
<AppWelcome
title={`Welcome back! \n ${user?.displayName}`}
description="If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything."
img={
<SeoIllustration
sx={{
p: 3,
width: 360,
margin: { xs: 'auto', md: 'inherit' },
}}
/>
}
action={<Button variant="contained">Go Now</Button>}
/>
</Grid>
<Grid item xs={12} md={4}>
<AppFeatured list={_appFeatured} />
</Grid>
<Grid item xs={12} md={4}>
<AppWidgetSummary
title="Total Active Users"
percent={2.6}
total={18765}
chartColor={theme.palette.primary.main}
chartData={[5, 18, 12, 51, 68, 11, 39, 37, 27, 20]}
/>
</Grid>
<Grid item xs={12} md={4}>
<AppWidgetSummary
title="Total Installed"
percent={0.2}
total={4876}
chartColor={theme.palette.chart.blue[0]}
chartData={[20, 41, 63, 33, 28, 35, 50, 46, 11, 26]}
/>
</Grid>
<Grid item xs={12} md={4}>
<AppWidgetSummary
title="Total Downloads"
percent={-0.1}
total={678}
chartColor={theme.palette.chart.red[0]}
chartData={[8, 9, 31, 8, 16, 37, 8, 33, 46, 31]}
/>
</Grid>
<Grid item xs={12} md={6} lg={4}>
<AppCurrentDownload
title="Current Download"
chartColors={[
theme.palette.primary.lighter,
theme.palette.primary.light,
theme.palette.primary.main,
theme.palette.primary.dark,
]}
chartData={[
{ label: 'Mac', value: 12244 },
{ label: 'Window', value: 53345 },
{ label: 'iOS', value: 44313 },
{ label: 'Android', value: 78343 },
]}
/>
</Grid>
<Grid item xs={12} md={6} lg={8}>
<AppAreaInstalled
title="Area Installed"
subheader="(+43%) than last year"
chartLabels={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']}
chartData={[
{
year: '2019',
data: [
{ name: 'Asia', data: [10, 41, 35, 51, 49, 62, 69, 91, 148] },
{ name: 'America', data: [10, 34, 13, 56, 77, 88, 99, 77, 45] },
],
},
{
year: '2020',
data: [
{ name: 'Asia', data: [148, 91, 69, 62, 49, 51, 35, 41, 10] },
{ name: 'America', data: [45, 77, 99, 88, 77, 56, 13, 34, 10] },
],
},
]}
/>
</Grid>
<Grid item xs={12} lg={8}>
<AppNewInvoice
title="New Invoice"
tableData={_appInvoices}
tableLabels={[
{ id: 'id', label: 'Invoice ID' },
{ id: 'category', label: 'Category' },
{ id: 'price', label: 'Price' },
{ id: 'status', label: 'Status' },
{ id: '' },
]}
/>
</Grid>
<Grid item xs={12} md={6} lg={4}>
<AppTopRelated title="Top Related Applications" list={_appRelated} />
</Grid>
<Grid item xs={12} md={6} lg={4}>
<AppTopInstalledCountries title="Top Installed Countries" list={_appInstalled} />
</Grid>
<Grid item xs={12} md={6} lg={4}>
<AppTopAuthors title="Top Authors" list={_appAuthors} />
</Grid>
<Grid item xs={12} md={6} lg={4}>
<Stack spacing={3}>
<AppWidget title="Conversion" total={38566} icon={'eva:person-fill'} chartData={48} />
<AppWidget title="Applications" total={55566} icon={'eva:email-fill'} color="warning" chartData={75} />
</Stack>
</Grid>
</Grid>
</Container>
</Page>
);
}
// @mui
import { useTheme } from '@mui/material/styles';
import { Grid, Container, Stack } from '@mui/material';
// hooks
import useSettings from '../../hooks/useSettings';
// _mock_
import { _bankingContacts, _bankingCreditCard, _bankingRecentTransitions } from '../../_mock';
// components
import Page from '../../components/Page';
// sections
import {
BankingContacts,
BankingWidgetSummary,
BankingInviteFriends,
BankingQuickTransfer,
BankingCurrentBalance,
BankingBalanceStatistics,
BankingRecentTransitions,
BankingExpensesCategories,
} from '../../sections/@dashboard/general/banking';
// ----------------------------------------------------------------------
export default function GeneralBanking() {
const theme = useTheme();
const { themeStretch } = useSettings();
return (
<Page title="General: Banking">
<Container maxWidth={themeStretch ? false : 'xl'}>
<Grid container spacing={3}>
<Grid item xs={12} md={7}>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={3}>
<BankingWidgetSummary
title="Income"
icon={'eva:diagonal-arrow-left-down-fill'}
percent={2.6}
total={18765}
chartData={[111, 136, 76, 108, 74, 54, 57, 84]}
/>
<BankingWidgetSummary
title="Expenses"
color="warning"
icon={'eva:diagonal-arrow-right-up-fill'}
percent={-0.5}
total={8938}
chartData={[111, 136, 76, 108, 74, 54, 57, 84]}
/>
</Stack>
</Grid>
<Grid item xs={12} md={5}>
<BankingCurrentBalance list={_bankingCreditCard} />
</Grid>
<Grid item xs={12} md={8}>
<Stack spacing={3}>
<BankingBalanceStatistics
title="Balance Statistics"
subheader="(+43% Income | +12% Expense) than last year"
chartLabels={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']}
chartData={[
{
year: 'Week',
data: [
{ name: 'Income', data: [10, 41, 35, 151, 49, 62, 69, 91, 48] },
{ name: 'Expenses', data: [10, 34, 13, 56, 77, 88, 99, 77, 45] },
],
},
{
year: 'Month',
data: [
{ name: 'Income', data: [148, 91, 69, 62, 49, 51, 35, 41, 10] },
{ name: 'Expenses', data: [45, 77, 99, 88, 77, 56, 13, 34, 10] },
],
},
{
year: 'Year',
data: [
{ name: 'Income', data: [76, 42, 29, 41, 27, 138, 117, 86, 63] },
{ name: 'Expenses', data: [80, 55, 34, 114, 80, 130, 15, 28, 55] },
],
},
]}
/>
<BankingExpensesCategories
title="Expenses Categories"
chartData={[
{ label: 'Category 1', value: 14 },
{ label: 'Category 2', value: 23 },
{ label: 'Category 3', value: 21 },
{ label: 'Category 4', value: 17 },
{ label: 'Category 5', value: 15 },
{ label: 'Category 6', value: 10 },
{ label: 'Category 7', value: 12 },
{ label: 'Category 8', value: 17 },
{ label: 'Category 9', value: 21 },
]}
chartColors={[
theme.palette.primary.main,
theme.palette.info.darker,
theme.palette.chart.yellow[0],
theme.palette.chart.blue[0],
theme.palette.chart.red[0],
theme.palette.chart.violet[2],
theme.palette.chart.violet[0],
theme.palette.success.darker,
theme.palette.chart.green[0],
]}
/>
<BankingRecentTransitions
title="Recent Transitions"
tableData={_bankingRecentTransitions}
tableLabels={[
{ id: 'description', label: 'Description' },
{ id: 'date', label: 'Date' },
{ id: 'amount', label: 'Amount' },
{ id: 'status', label: 'Status' },
{ id: '' },
]}
/>
</Stack>
</Grid>
<Grid item xs={12} md={4}>
<Stack spacing={3}>
<BankingQuickTransfer title="Quick Transfer" list={_bankingContacts} />
<BankingContacts title="Contacts" subheader="You have 122 contacts" list={_bankingContacts.slice(-5)} />
<BankingInviteFriends
price="$50"
title={`Invite friends \n and earn`}
description="Praesent egestas tristique nibh. Duis lobortis massa imperdiet quam."
img="/assets/illustrations/illustration_invite.png"
/>
</Stack>
</Grid>
</Grid>
</Container>
</Page>
);
}
// @mui
import { useTheme } from '@mui/material/styles';
import { Grid, Container } from '@mui/material';
// hooks
import useSettings from '../../hooks/useSettings';
// _mock_
import { _bookings, _bookingNew, _bookingsOverview, _bookingReview } from '../../_mock';
// components
import Page from '../../components/Page';
// sections
import {
BookingDetails,
BookingBookedRoom,
BookingTotalIncomes,
BookingRoomAvailable,
BookingNewestBooking,
BookingWidgetSummary,
BookingCheckInWidgets,
BookingCustomerReviews,
BookingReservationStats,
} from '../../sections/@dashboard/general/booking';
// assets
import { BookingIllustration, CheckInIllustration, CheckOutIllustration } from '../../assets';
// ----------------------------------------------------------------------
export default function GeneralBooking() {
const theme = useTheme();
const { themeStretch } = useSettings();
return (
<Page title="General: Banking">
<Container maxWidth={themeStretch ? false : 'xl'}>
<Grid container spacing={3}>
<Grid item xs={12} md={4}>
<BookingWidgetSummary title="Total Booking" total={714000} icon={<BookingIllustration />} />
</Grid>
<Grid item xs={12} md={4}>
<BookingWidgetSummary title="Check In" total={311000} icon={<CheckInIllustration />} />
</Grid>
<Grid item xs={12} md={4}>
<BookingWidgetSummary title="Check Out" total={124000} icon={<CheckOutIllustration />} />
</Grid>
<Grid item xs={12} md={8}>
<Grid container spacing={3}>
<Grid item xs={12} md={6}>
<BookingTotalIncomes total={18765} percent={2.6} chartData={[111, 136, 76, 108, 74, 54, 57, 84]} />
</Grid>
<Grid item xs={12} md={6}>
<BookingBookedRoom title="Booked Room" data={_bookingsOverview} />
</Grid>
<Grid item xs={12} md={12}>
<BookingCheckInWidgets
chartData={[
{ label: 'Check In', percent: 72, total: 38566 },
{ label: 'Check Out', percent: 64, total: 18472 },
]}
/>
</Grid>
</Grid>
</Grid>
<Grid item xs={12} md={4}>
<BookingRoomAvailable
title="Room Available"
data={[
{ label: 'Sold out', value: 120 },
{ label: 'Available', value: 66 },
]}
chartColors={[[theme.palette.primary.light, theme.palette.primary.main]]}
/>
</Grid>
<Grid item xs={12} md={8}>
<BookingReservationStats
title="Reservation Stats"
subheader="(+43% Check In | +12% Check Out) than last year"
chartLabels={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']}
chartData={[
{
year: 'Week',
data: [
{ name: 'Check In', data: [10, 41, 35, 151, 49, 62, 69, 91, 48] },
{ name: 'Check Out', data: [10, 34, 13, 56, 77, 88, 99, 77, 45] },
],
},
{
year: 'Month',
data: [
{ name: 'Check In', data: [148, 91, 69, 62, 49, 51, 35, 41, 10] },
{ name: 'Check Out', data: [45, 77, 99, 88, 77, 56, 13, 34, 10] },
],
},
{
year: 'Year',
data: [
{ name: 'Check In', data: [76, 42, 29, 41, 27, 138, 117, 86, 63] },
{ name: 'Check Out', data: [80, 55, 34, 114, 80, 130, 15, 28, 55] },
],
},
]}
/>
</Grid>
<Grid item xs={12} md={4}>
<BookingCustomerReviews
title="Customer Reviews"
subheader={`${_bookingReview.length} Reviews`}
list={_bookingReview}
/>
</Grid>
<Grid item xs={12}>
<BookingNewestBooking title="Newest Booking" subheader="12 Booking" list={_bookingNew} />
</Grid>
<Grid item xs={12}>
<BookingDetails
title="Booking Details"
tableData={_bookings}
tableLabels={[
{ id: 'booker', label: 'Booker' },
{ id: 'checkIn', label: 'Check In' },
{ id: 'checkOut', label: 'Check Out' },
{ id: 'status', label: 'Status' },
{ id: 'phone', label: 'Phone' },
{ id: 'roomType', label: 'Room Type' },
{ id: '' },
]}
/>
</Grid>
</Grid>
</Container>
</Page>
);
}
// @mui
import { useTheme } from '@mui/material/styles';
import { Container, Grid, Button } from '@mui/material';
// hooks
import useAuth from '../../hooks/useAuth';
import useSettings from '../../hooks/useSettings';
// _mock_
import {
_ecommerceNewProducts,
_ecommerceSalesOverview,
_ecommerceBestSalesman,
_ecommerceLatestProducts,
} from '../../_mock';
// components
import Page from '../../components/Page';
// sections
import {
EcommerceNewProducts,
EcommerceYearlySales,
EcommerceBestSalesman,
EcommerceSaleByGender,
EcommerceWidgetSummary,
EcommerceSalesOverview,
EcommerceLatestProducts,
EcommerceCurrentBalance,
} from '../../sections/@dashboard/general/e-commerce';
import { AppWelcome } from '../../sections/@dashboard/general/app';
// assets
import { MotivationIllustration } from '../../assets';
// ----------------------------------------------------------------------
export default function GeneralEcommerce() {
const { user } = useAuth();
const theme = useTheme();
const { themeStretch } = useSettings();
return (
<Page title="General: E-commerce">
<Container maxWidth={themeStretch ? false : 'xl'}>
<Grid container spacing={3}>
<Grid item xs={12} md={8}>
<AppWelcome
title={`Congratulations! \n ${user?.displayName}`}
description="Best seller of the month You have done 57.6% more sales today."
img={
<MotivationIllustration
sx={{
p: 3,
width: 360,
margin: { xs: 'auto', md: 'inherit' },
}}
/>
}
action={<Button variant="contained">Go Now</Button>}
/>
</Grid>
<Grid item xs={12} md={4}>
<EcommerceNewProducts list={_ecommerceNewProducts} />
</Grid>
<Grid item xs={12} md={4}>
<EcommerceWidgetSummary
title="Product Sold"
percent={2.6}
total={765}
chartColor={theme.palette.primary.main}
chartData={[22, 8, 35, 50, 82, 84, 77, 12, 87, 43]}
/>
</Grid>
<Grid item xs={12} md={4}>
<EcommerceWidgetSummary
title="Total Balance"
percent={-0.1}
total={18765}
chartColor={theme.palette.chart.green[0]}
chartData={[56, 47, 40, 62, 73, 30, 23, 54, 67, 68]}
/>
</Grid>
<Grid item xs={12} md={4}>
<EcommerceWidgetSummary
title="Sales Profit"
percent={0.6}
total={4876}
chartColor={theme.palette.chart.red[0]}
chartData={[40, 70, 75, 70, 50, 28, 7, 64, 38, 27]}
/>
</Grid>
<Grid item xs={12} md={6} lg={4}>
<EcommerceSaleByGender
title="Sale By Gender"
total={2324}
chartData={[
{ label: 'Mens', value: 44 },
{ label: 'Womens', value: 75 },
]}
chartColors={[
[theme.palette.primary.light, theme.palette.primary.main],
[theme.palette.warning.light, theme.palette.warning.main],
]}
/>
</Grid>
<Grid item xs={12} md={6} lg={8}>
<EcommerceYearlySales
title="Yearly Sales"
subheader="(+43%) than last year"
chartLabels={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']}
chartData={[
{
year: '2019',
data: [
{ name: 'Total Income', data: [10, 41, 35, 151, 49, 62, 69, 91, 48] },
{ name: 'Total Expenses', data: [10, 34, 13, 56, 77, 88, 99, 77, 45] },
],
},
{
year: '2020',
data: [
{ name: 'Total Income', data: [148, 91, 69, 62, 49, 51, 35, 41, 10] },
{ name: 'Total Expenses', data: [45, 77, 99, 88, 77, 56, 13, 34, 10] },
],
},
]}
/>
</Grid>
<Grid item xs={12} md={6} lg={8}>
<EcommerceSalesOverview title="Sales Overview" data={_ecommerceSalesOverview} />
</Grid>
<Grid item xs={12} md={6} lg={4}>
<EcommerceCurrentBalance title="Current Balance" currentBalance={187650} sentAmount={25500} />
</Grid>
<Grid item xs={12} md={6} lg={8}>
<EcommerceBestSalesman
title="Best Salesman"
tableData={_ecommerceBestSalesman}
tableLabels={[
{ id: 'seller', label: 'Seller' },
{ id: 'product', label: 'Product' },
{ id: 'country', label: 'Country', align: 'center' },
{ id: 'total', label: 'Total' },
{ id: 'rank', label: 'Rank', align: 'right' },
]}
/>
</Grid>
<Grid item xs={12} md={6} lg={4}>
<EcommerceLatestProducts title="Latest Products" list={_ecommerceLatestProducts} />
</Grid>
</Grid>
</Container>
</Page>
);
}
// @mui
import { Container } from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import InvoiceNewEditForm from '../../sections/@dashboard/invoice/new-edit-form';
// ----------------------------------------------------------------------
export default function InvoiceCreate() {
const { themeStretch } = useSettings();
return (
<Page title="Invoices: Create a new invoice">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Create a new invoice"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'Invoices', href: PATH_DASHBOARD.invoice.list },
{ name: 'New invoice' },
]}
/>
<InvoiceNewEditForm />
</Container>
</Page>
);
}
import { useParams } from 'react-router-dom';
// @mui
import { Container } from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// _mock_
import { _invoices } from '../../_mock';
// hooks
import useSettings from '../../hooks/useSettings';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import Invoice from '../../sections/@dashboard/invoice/details';
// ----------------------------------------------------------------------
export default function InvoiceDetails() {
const { themeStretch } = useSettings();
const { id } = useParams();
const invoice = _invoices.find((invoice) => invoice.id === id);
return (
<Page title="Invoice: View">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Invoice Details"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{
name: 'Invoices',
href: PATH_DASHBOARD.invoice.root,
},
{ name: `INV-${invoice?.invoiceNumber}` || '' },
]}
/>
<Invoice invoice={invoice} />
</Container>
</Page>
);
}
import { useParams } from 'react-router-dom';
// @mui
import { Container } from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// _mock_
import { _invoices } from '../../_mock';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import InvoiceNewEditForm from '../../sections/@dashboard/invoice/new-edit-form';
// ----------------------------------------------------------------------
export default function InvoiceEdit() {
const { themeStretch } = useSettings();
const { id } = useParams();
const currentInvoice = _invoices.find((invoice) => invoice.id === id);
return (
<Page title="Invoices: Edit">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Edit invoice"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'Invoices', href: PATH_DASHBOARD.invoice.list },
{ name: `INV-${currentInvoice?.invoiceNumber}` || '' },
]}
/>
<InvoiceNewEditForm isEdit currentInvoice={currentInvoice} />
</Container>
</Page>
);
}
This diff is collapsed.
import { useEffect } from 'react';
// @mui
import { Container, Stack } from '@mui/material';
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
// redux
import { useDispatch, useSelector } from '../../redux/store';
import { getBoard, persistColumn, persistCard } from '../../redux/slices/kanban';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
import { SkeletonKanbanColumn } from '../../components/skeleton';
// sections
import { KanbanColumn, KanbanColumnAdd } from '../../sections/@dashboard/kanban';
// ----------------------------------------------------------------------
export default function Kanban() {
const dispatch = useDispatch();
const { board } = useSelector((state) => state.kanban);
useEffect(() => {
dispatch(getBoard());
}, [dispatch]);
const onDragEnd = (result) => {
// Reorder card
const { destination, source, draggableId, type } = result;
if (!destination) return;
if (destination.droppableId === source.droppableId && destination.index === source.index) return;
if (type === 'column') {
const newColumnOrder = Array.from(board.columnOrder);
newColumnOrder.splice(source.index, 1);
newColumnOrder.splice(destination.index, 0, draggableId);
dispatch(persistColumn(newColumnOrder));
return;
}
const start = board.columns[source.droppableId];
const finish = board.columns[destination.droppableId];
if (start.id === finish.id) {
const updatedCardIds = [...start.cardIds];
updatedCardIds.splice(source.index, 1);
updatedCardIds.splice(destination.index, 0, draggableId);
const updatedColumn = {
...start,
cardIds: updatedCardIds,
};
dispatch(
persistCard({
...board.columns,
[updatedColumn.id]: updatedColumn,
})
);
return;
}
const startCardIds = [...start.cardIds];
startCardIds.splice(source.index, 1);
const updatedStart = {
...start,
cardIds: startCardIds,
};
const finishCardIds = [...finish.cardIds];
finishCardIds.splice(destination.index, 0, draggableId);
const updatedFinish = {
...finish,
cardIds: finishCardIds,
};
dispatch(
persistCard({
...board.columns,
[updatedStart.id]: updatedStart,
[updatedFinish.id]: updatedFinish,
})
);
};
return (
<Page title="Kanban" sx={{ height: 1 }}>
<Container maxWidth={false} sx={{ height: 1 }}>
<HeaderBreadcrumbs
heading="Kanban"
links={[
{
name: 'Dashboard',
href: PATH_DASHBOARD.root,
},
{ name: 'Kanban' },
]}
/>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="all-columns" direction="horizontal" type="column">
{(provided) => (
<Stack
{...provided.droppableProps}
ref={provided.innerRef}
direction="row"
alignItems="flex-start"
spacing={3}
sx={{ height: 'calc(100% - 32px)', overflowY: 'hidden' }}
>
{!board.columnOrder.length ? (
<SkeletonKanbanColumn />
) : (
board.columnOrder.map((columnId, index) => (
<KanbanColumn index={index} key={columnId} column={board.columns[columnId]} />
))
)}
{provided.placeholder}
<KanbanColumnAdd />
</Stack>
)}
</Droppable>
</DragDropContext>
</Container>
</Page>
);
}
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
// @mui
import { Container, Card } from '@mui/material';
// redux
import { useDispatch } from '../../redux/store';
import { getLabels } from '../../redux/slices/mail';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
import { MailList, MailDetails, MailSidebar, MailCompose } from '../../sections/@dashboard/mail';
// ----------------------------------------------------------------------
export default function Mail() {
const { themeStretch } = useSettings();
const dispatch = useDispatch();
const { mailId } = useParams();
const [openSidebar, setOpenSidebar] = useState(false);
const [openCompose, setOpenCompose] = useState(false);
useEffect(() => {
dispatch(getLabels());
}, [dispatch]);
return (
<Page title="Mail">
<Container maxWidth={themeStretch ? false : 'xl'}>
<HeaderBreadcrumbs
heading="Mail"
links={[
{
name: 'Dashboard',
href: PATH_DASHBOARD.root,
},
{ name: 'Mail' },
]}
/>
<Card sx={{ height: { md: '72vh' }, display: { md: 'flex' } }}>
<MailSidebar
isOpenSidebar={openSidebar}
onCloseSidebar={() => setOpenSidebar(false)}
onOpenCompose={() => setOpenCompose(true)}
/>
{mailId ? <MailDetails /> : <MailList onOpenSidebar={() => setOpenSidebar(true)} />}
<MailCompose isOpenCompose={openCompose} onCloseCompose={() => setOpenCompose(false)} />
</Card>
</Container>
</Page>
);
}
import { useState } from 'react';
// @mui
import { Box, Card, Container, Typography, CardHeader, ToggleButton, ToggleButtonGroup } from '@mui/material';
// hooks
import useSettings from '../../hooks/useSettings';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// guards
import RoleBasedGuard from '../../guards/RoleBasedGuard';
// ----------------------------------------------------------------------
export default function PermissionDenied() {
const { themeStretch } = useSettings();
const [role, setRole] = useState('admin');
const handleChangeRole = (event, newRole) => {
if (newRole !== null) {
setRole(newRole);
}
};
return (
<Page title="Permission Denied">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Permission Denied"
links={[
{
name: 'Dashboard',
href: PATH_DASHBOARD.root,
},
{ name: 'Permission Denied' },
]}
/>
<ToggleButtonGroup exclusive value={role} onChange={handleChangeRole} color="primary" sx={{ mb: 5 }}>
<ToggleButton value="admin" aria-label="admin role">
isAdmin
</ToggleButton>
<ToggleButton value="user" aria-label="user role">
isUser
</ToggleButton>
</ToggleButtonGroup>
<RoleBasedGuard hasContent roles={[role]}>
<Box
sx={{
display: 'grid',
gap: 3,
gridTemplateColumns: 'repeat(2, 1fr)',
}}
>
{[...Array(8)].map((_, index) => (
<Card key={index}>
<CardHeader title={`Card ${index + 1}`} subheader="Proin viverra ligula" />
<Typography sx={{ p: 3, color: 'text.secondary' }}>
Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. In enim justo, rhoncus ut, imperdiet
a, venenatis vitae, justo. Vestibulum fringilla pede sit amet augue.
</Typography>
</Card>
))}
</Box>
</RoleBasedGuard>
</Container>
</Page>
);
}
import { capitalCase } from 'change-case';
// @mui
import { Container, Tab, Box, Tabs } from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useTabs from '../../hooks/useTabs';
import useSettings from '../../hooks/useSettings';
// _mock_
import { _userPayment, _userAddressBook, _userInvoices, _userAbout } from '../../_mock';
// components
import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import {
AccountGeneral,
AccountBilling,
AccountSocialLinks,
AccountNotifications,
AccountChangePassword,
} from '../../sections/@dashboard/user/account';
// ----------------------------------------------------------------------
export default function UserAccount() {
const { themeStretch } = useSettings();
const { currentTab, onChangeTab } = useTabs('general');
const ACCOUNT_TABS = [
{
value: 'general',
icon: <Iconify icon={'ic:round-account-box'} width={20} height={20} />,
component: <AccountGeneral />,
},
{
value: 'billing',
icon: <Iconify icon={'ic:round-receipt'} width={20} height={20} />,
component: <AccountBilling cards={_userPayment} addressBook={_userAddressBook} invoices={_userInvoices} />,
},
{
value: 'notifications',
icon: <Iconify icon={'eva:bell-fill'} width={20} height={20} />,
component: <AccountNotifications />,
},
{
value: 'social_links',
icon: <Iconify icon={'eva:share-fill'} width={20} height={20} />,
component: <AccountSocialLinks myProfile={_userAbout} />,
},
{
value: 'change_password',
icon: <Iconify icon={'ic:round-vpn-key'} width={20} height={20} />,
component: <AccountChangePassword />,
},
];
return (
<Page title="User: Account Settings">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Account"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'User', href: PATH_DASHBOARD.user.root },
{ name: 'Account Settings' },
]}
/>
<Tabs
allowScrollButtonsMobile
variant="scrollable"
scrollButtons="auto"
value={currentTab}
onChange={onChangeTab}
>
{ACCOUNT_TABS.map((tab) => (
<Tab disableRipple key={tab.value} label={capitalCase(tab.value)} icon={tab.icon} value={tab.value} />
))}
</Tabs>
<Box sx={{ mb: 5 }} />
{ACCOUNT_TABS.map((tab) => {
const isMatched = tab.value === currentTab;
return isMatched && <Box key={tab.value}>{tab.component}</Box>;
})}
</Container>
</Page>
);
}
// @mui
import { Container, Box } from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// _mock_
import { _userCards } from '../../_mock';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import { UserCard } from '../../sections/@dashboard/user/cards';
// ----------------------------------------------------------------------
export default function UserCards() {
const { themeStretch } = useSettings();
return (
<Page title="User: Cards">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="User Cards"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'User', href: PATH_DASHBOARD.user.root },
{ name: 'Cards' },
]}
/>
<Box
sx={{
display: 'grid',
gap: 3,
gridTemplateColumns: {
xs: 'repeat(1, 1fr)',
sm: 'repeat(2, 1fr)',
md: 'repeat(3, 1fr)',
},
}}
>
{_userCards.map((user) => (
<UserCard key={user.id} user={user} />
))}
</Box>
</Container>
</Page>
);
}
import { paramCase, capitalCase } from 'change-case';
import { useParams, useLocation } from 'react-router-dom';
// @mui
import { Container } from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useSettings from '../../hooks/useSettings';
// _mock_
import { _userList } from '../../_mock';
// components
import Page from '../../components/Page';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import UserNewEditForm from '../../sections/@dashboard/user/UserNewEditForm';
// ----------------------------------------------------------------------
export default function UserCreate() {
const { themeStretch } = useSettings();
const { pathname } = useLocation();
const { name = '' } = useParams();
const isEdit = pathname.includes('edit');
const currentUser = _userList.find((user) => paramCase(user.name) === name);
return (
<Page title="User: Create a new user">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading={!isEdit ? 'Create a new user' : 'Edit user'}
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'User', href: PATH_DASHBOARD.user.list },
{ name: !isEdit ? 'New user' : capitalCase(name) },
]}
/>
<UserNewEditForm isEdit={isEdit} currentUser={currentUser} />
</Container>
</Page>
);
}
import { paramCase } from 'change-case';
import { useState } from 'react';
import { Link as RouterLink, useNavigate } from 'react-router-dom';
// @mui
import {
Box,
Tab,
Tabs,
Card,
Table,
Switch,
Button,
Tooltip,
Divider,
TableBody,
Container,
IconButton,
TableContainer,
TablePagination,
FormControlLabel,
} from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useTabs from '../../hooks/useTabs';
import useSettings from '../../hooks/useSettings';
import useTable, { getComparator, emptyRows } from '../../hooks/useTable';
// _mock_
import { _userList } from '../../_mock';
// components
import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
import Scrollbar from '../../components/Scrollbar';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
import { TableEmptyRows, TableHeadCustom, TableNoData, TableSelectedActions } from '../../components/table';
// sections
import { UserTableToolbar, UserTableRow } from '../../sections/@dashboard/user/list';
// ----------------------------------------------------------------------
const STATUS_OPTIONS = ['all', 'active', 'banned'];
const ROLE_OPTIONS = [
'all',
'ux designer',
'full stack designer',
'backend developer',
'project manager',
'leader',
'ui designer',
'ui/ux designer',
'front end developer',
'full stack developer',
];
const TABLE_HEAD = [
{ id: 'name', label: 'Name', align: 'left' },
{ id: 'company', label: 'Company', align: 'left' },
{ id: 'role', label: 'Role', align: 'left' },
{ id: 'isVerified', label: 'Verified', align: 'center' },
{ id: 'status', label: 'Status', align: 'left' },
{ id: '' },
];
// ----------------------------------------------------------------------
export default function UserList() {
const {
dense,
page,
order,
orderBy,
rowsPerPage,
setPage,
//
selected,
setSelected,
onSelectRow,
onSelectAllRows,
//
onSort,
onChangeDense,
onChangePage,
onChangeRowsPerPage,
} = useTable();
const { themeStretch } = useSettings();
const navigate = useNavigate();
const [tableData, setTableData] = useState(_userList);
const [filterName, setFilterName] = useState('');
const [filterRole, setFilterRole] = useState('all');
const { currentTab: filterStatus, onChangeTab: onChangeFilterStatus } = useTabs('all');
const handleFilterName = (filterName) => {
setFilterName(filterName);
setPage(0);
};
const handleFilterRole = (event) => {
setFilterRole(event.target.value);
};
const handleDeleteRow = (id) => {
const deleteRow = tableData.filter((row) => row.id !== id);
setSelected([]);
setTableData(deleteRow);
};
const handleDeleteRows = (selected) => {
const deleteRows = tableData.filter((row) => !selected.includes(row.id));
setSelected([]);
setTableData(deleteRows);
};
const handleEditRow = (id) => {
navigate(PATH_DASHBOARD.user.edit(paramCase(id)));
};
const dataFiltered = applySortFilter({
tableData,
comparator: getComparator(order, orderBy),
filterName,
filterRole,
filterStatus,
});
const denseHeight = dense ? 52 : 72;
const isNotFound =
(!dataFiltered.length && !!filterName) ||
(!dataFiltered.length && !!filterRole) ||
(!dataFiltered.length && !!filterStatus);
return (
<Page title="User: List">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="User List"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'User', href: PATH_DASHBOARD.user.root },
{ name: 'List' },
]}
action={
<Button
variant="contained"
component={RouterLink}
to={PATH_DASHBOARD.user.new}
startIcon={<Iconify icon={'eva:plus-fill'} />}
>
New User
</Button>
}
/>
<Card>
<Tabs
allowScrollButtonsMobile
variant="scrollable"
scrollButtons="auto"
value={filterStatus}
onChange={onChangeFilterStatus}
sx={{ px: 2, bgcolor: 'background.neutral' }}
>
{STATUS_OPTIONS.map((tab) => (
<Tab disableRipple key={tab} label={tab} value={tab} />
))}
</Tabs>
<Divider />
<UserTableToolbar
filterName={filterName}
filterRole={filterRole}
onFilterName={handleFilterName}
onFilterRole={handleFilterRole}
optionsRole={ROLE_OPTIONS}
/>
<Scrollbar>
<TableContainer sx={{ minWidth: 800, position: 'relative' }}>
{selected.length > 0 && (
<TableSelectedActions
dense={dense}
numSelected={selected.length}
rowCount={tableData.length}
onSelectAllRows={(checked) =>
onSelectAllRows(
checked,
tableData.map((row) => row.id)
)
}
actions={
<Tooltip title="Delete">
<IconButton color="primary" onClick={() => handleDeleteRows(selected)}>
<Iconify icon={'eva:trash-2-outline'} />
</IconButton>
</Tooltip>
}
/>
)}
<Table size={dense ? 'small' : 'medium'}>
<TableHeadCustom
order={order}
orderBy={orderBy}
headLabel={TABLE_HEAD}
rowCount={tableData.length}
numSelected={selected.length}
onSort={onSort}
onSelectAllRows={(checked) =>
onSelectAllRows(
checked,
tableData.map((row) => row.id)
)
}
/>
<TableBody>
{dataFiltered.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((row) => (
<UserTableRow
key={row.id}
row={row}
selected={selected.includes(row.id)}
onSelectRow={() => onSelectRow(row.id)}
onDeleteRow={() => handleDeleteRow(row.id)}
onEditRow={() => handleEditRow(row.name)}
/>
))}
<TableEmptyRows height={denseHeight} emptyRows={emptyRows(page, rowsPerPage, tableData.length)} />
<TableNoData isNotFound={isNotFound} />
</TableBody>
</Table>
</TableContainer>
</Scrollbar>
<Box sx={{ position: 'relative' }}>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={dataFiltered.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={onChangePage}
onRowsPerPageChange={onChangeRowsPerPage}
/>
<FormControlLabel
control={<Switch checked={dense} onChange={onChangeDense} />}
label="Dense"
sx={{ px: 3, py: 1.5, top: 0, position: { md: 'absolute' } }}
/>
</Box>
</Card>
</Container>
</Page>
);
}
// ----------------------------------------------------------------------
function applySortFilter({ tableData, comparator, filterName, filterStatus, filterRole }) {
const stabilizedThis = tableData.map((el, index) => [el, index]);
stabilizedThis.sort((a, b) => {
const order = comparator(a[0], b[0]);
if (order !== 0) return order;
return a[1] - b[1];
});
tableData = stabilizedThis.map((el) => el[0]);
if (filterName) {
tableData = tableData.filter((item) => item.name.toLowerCase().indexOf(filterName.toLowerCase()) !== -1);
}
if (filterStatus !== 'all') {
tableData = tableData.filter((item) => item.status === filterStatus);
}
if (filterRole !== 'all') {
tableData = tableData.filter((item) => item.role === filterRole);
}
return tableData;
}
import { capitalCase } from 'change-case';
import { useState } from 'react';
// @mui
import { styled } from '@mui/material/styles';
import { Tab, Box, Card, Tabs, Container } from '@mui/material';
// routes
import { PATH_DASHBOARD } from '../../routes/paths';
// hooks
import useAuth from '../../hooks/useAuth';
import useTabs from '../../hooks/useTabs';
import useSettings from '../../hooks/useSettings';
// _mock_
import { _userAbout, _userFeeds, _userFriends, _userGallery, _userFollowers } from '../../_mock';
// components
import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
// sections
import {
Profile,
ProfileCover,
ProfileFriends,
ProfileGallery,
ProfileFollowers,
} from '../../sections/@dashboard/user/profile';
// ----------------------------------------------------------------------
const TabsWrapperStyle = styled('div')(({ theme }) => ({
zIndex: 9,
bottom: 0,
width: '100%',
display: 'flex',
position: 'absolute',
backgroundColor: theme.palette.background.paper,
[theme.breakpoints.up('sm')]: {
justifyContent: 'center',
},
[theme.breakpoints.up('md')]: {
justifyContent: 'flex-end',
paddingRight: theme.spacing(3),
},
}));
// ----------------------------------------------------------------------
export default function UserProfile() {
const { themeStretch } = useSettings();
const { user } = useAuth();
const { currentTab, onChangeTab } = useTabs('profile');
const [findFriends, setFindFriends] = useState('');
const handleFindFriends = (value) => {
setFindFriends(value);
};
const PROFILE_TABS = [
{
value: 'profile',
icon: <Iconify icon={'ic:round-account-box'} width={20} height={20} />,
component: <Profile myProfile={_userAbout} posts={_userFeeds} />,
},
{
value: 'followers',
icon: <Iconify icon={'eva:heart-fill'} width={20} height={20} />,
component: <ProfileFollowers followers={_userFollowers} />,
},
{
value: 'friends',
icon: <Iconify icon={'eva:people-fill'} width={20} height={20} />,
component: <ProfileFriends friends={_userFriends} findFriends={findFriends} onFindFriends={handleFindFriends} />,
},
{
value: 'gallery',
icon: <Iconify icon={'ic:round-perm-media'} width={20} height={20} />,
component: <ProfileGallery gallery={_userGallery} />,
},
];
return (
<Page title="User: Profile">
<Container maxWidth={themeStretch ? false : 'lg'}>
<HeaderBreadcrumbs
heading="Profile"
links={[
{ name: 'Dashboard', href: PATH_DASHBOARD.root },
{ name: 'User', href: PATH_DASHBOARD.user.root },
{ name: user?.displayName || '' },
]}
/>
<Card
sx={{
mb: 3,
height: 280,
position: 'relative',
}}
>
<ProfileCover myProfile={_userAbout} />
<TabsWrapperStyle>
<Tabs
allowScrollButtonsMobile
variant="scrollable"
scrollButtons="auto"
value={currentTab}
onChange={onChangeTab}
>
{PROFILE_TABS.map((tab) => (
<Tab disableRipple key={tab.value} value={tab.value} icon={tab.icon} label={capitalCase(tab.value)} />
))}
</Tabs>
</TabsWrapperStyle>
</Card>
{PROFILE_TABS.map((tab) => {
const isMatched = tab.value === currentTab;
return isMatched && <Box key={tab.value}>{tab.component}</Box>;
})}
</Container>
</Page>
);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment