Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions frontend/src/components/Analytics.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from "react";
import Grid from "@mui/material/Grid";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import CustomizedDataGrid from "./CustomizedDataGrid";

export default function Analytics() {
return (
<Box sx={{ width: "100%", maxWidth: { sm: "100%", md: "1700px" } }}>
<Typography component="h2" variant="h6" sx={{ mb: 2 }}>
Details
</Typography>
<Grid container spacing={2}>
<Grid size={{ xs: 12, lg: 12 }}>
<CustomizedDataGrid />
</Grid>
</Grid>
</Box>
);
}
17 changes: 17 additions & 0 deletions frontend/src/components/Chat.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Stack } from "@mui/material";

export default function Chat() {
return (
<Stack
sx={{
p: 2,
height: "100%",
width: "100%",
justifyContent: "center",
alignItems: "center",
}}
>
<h1>Chat</h1>
</Stack>
);
}
59 changes: 59 additions & 0 deletions frontend/src/components/CustomDatePicker.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import * as React from "react";
import dayjs, { Dayjs } from "dayjs";
import Button from "@mui/material/Button";
import CalendarTodayRoundedIcon from "@mui/icons-material/CalendarTodayRounded";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";

function ButtonField(props) {
const {
setOpen,
label,
id,
disabled,
InputProps: { ref } = {},
inputProps: { "aria-label": ariaLabel } = {},
} = props;

return (
<Button
variant="outlined"
id={id}
disabled={disabled}
ref={ref}
aria-label={ariaLabel}
size="small"
onClick={() => setOpen?.((prev) => !prev)}
startIcon={<CalendarTodayRoundedIcon fontSize="small" />}
sx={{ minWidth: "fit-content" }}
>
{label ? `${label}` : "Pick a date"}
</Button>
);
}

export default function CustomDatePicker() {
const [value, setValue] = React.useState(dayjs(new Date()));
const [open, setOpen] = React.useState(false);

return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DatePicker
value={value}
label={value == null ? null : value.format("MMM DD, YYYY")}
onChange={(newValue) => setValue(newValue)}
slots={{ field: ButtonField }}
slotProps={{
field: { setOpen },
nextIconButton: { size: "small" },
previousIconButton: { size: "small" },
}}
open={open}
onClose={() => setOpen(false)}
onOpen={() => setOpen(true)}
views={["day", "month", "year"]}
/>
</LocalizationProvider>
);
}
48 changes: 48 additions & 0 deletions frontend/src/components/CustomizedDataGrid.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as React from "react";
import { DataGrid } from "@mui/x-data-grid";
import { columns, rows } from "./internals/data/gridData";

export default function CustomizedDataGrid() {
return (
<DataGrid
autoSN
rows={rows}
columns={columns}
getRowClassName={(params) =>
params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd"
}
initialState={{
pagination: { paginationModel: { pageSize: 20 } },
}}
pageSizeOptions={[10, 20, 50]}
// disableColumnResize
density="compact"
slotProps={{
filterPanel: {
filterFormProps: {
logicOperatorInputProps: {
variant: "outlined",
size: "small",
},
columnInputProps: {
variant: "outlined",
size: "small",
sx: { mt: "auto" },
},
operatorInputProps: {
variant: "outlined",
size: "small",
sx: { mt: "auto" },
},
valueInputProps: {
InputComponentProps: {
variant: "outlined",
size: "small",
},
},
},
},
}}
/>
);
}
183 changes: 183 additions & 0 deletions frontend/src/components/CustomizedTreeView.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import * as React from "react";
import clsx from "clsx";
import { animated, useSpring } from "@react-spring/web";
// import { TransitionProps } from "@mui/material/transitions";
import Box from "@mui/material/Box";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Collapse from "@mui/material/Collapse";
import Typography from "@mui/material/Typography";
import { RichTreeView } from "@mui/x-tree-view/RichTreeView";
import { unstable_useTreeItem2 as useTreeItem2 } from "@mui/x-tree-view/useTreeItem2";
import {
TreeItem2Content,
TreeItem2IconContainer,
TreeItem2Label,
TreeItem2Root,
} from "@mui/x-tree-view/TreeItem2";
import { TreeItem2Icon } from "@mui/x-tree-view/TreeItem2Icon";
import { TreeItem2Provider } from "@mui/x-tree-view/TreeItem2Provider";
import { useTheme } from "@mui/material/styles";

const ITEMS = [
{
id: "1",
label: "Website",
children: [
{ id: "1.1", label: "Home", color: "green" },
{ id: "1.2", label: "Pricing", color: "green" },
{ id: "1.3", label: "About us", color: "green" },
{
id: "1.4",
label: "Blog",
children: [
{ id: "1.1.1", label: "Announcements", color: "blue" },
{ id: "1.1.2", label: "April lookahead", color: "blue" },
{ id: "1.1.3", label: "What's new", color: "blue" },
{ id: "1.1.4", label: "Meet the team", color: "blue" },
],
},
],
},
{
id: "2",
label: "Store",
children: [
{ id: "2.1", label: "All products", color: "green" },
{
id: "2.2",
label: "Categories",
children: [
{ id: "2.2.1", label: "Gadgets", color: "blue" },
{ id: "2.2.2", label: "Phones", color: "blue" },
{ id: "2.2.3", label: "Wearables", color: "blue" },
],
},
{ id: "2.3", label: "Bestsellers", color: "green" },
{ id: "2.4", label: "Sales", color: "green" },
],
},
{ id: "4", label: "Contact", color: "blue" },
{ id: "5", label: "Help", color: "blue" },
];

function DotIcon({ color }) {
return (
<Box sx={{ marginRight: 1, display: "flex", alignItems: "center" }}>
<svg width={6} height={6}>
<circle cx={3} cy={3} r={3} fill={color} />
</svg>
</Box>
);
}

const AnimatedCollapse = animated(Collapse);

function TransitionComponent(props) {
const style = useSpring({
to: {
opacity: props.in ? 1 : 0,
transform: `translate3d(0,${props.in ? 0 : 20}px,0)`,
},
});

return <AnimatedCollapse style={style} {...props} />;
}

function CustomLabel({ color, expandable, children, ...other }) {
const theme = useTheme();
const colors = {
blue: (theme.vars || theme).palette.primary.main,
green: (theme.vars || theme).palette.success.main,
};

const iconColor = color ? colors[color] : null;
return (
<TreeItem2Label {...other} sx={{ display: "flex", alignItems: "center" }}>
{iconColor && <DotIcon color={iconColor} />}
<Typography
className="labelText"
variant="body2"
sx={{ color: "text.primary" }}
>
{children}
</Typography>
</TreeItem2Label>
);
}

const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) {
const { id, itemId, label, disabled, children, ...other } = props;

const {
getRootProps,
getContentProps,
getIconContainerProps,
getLabelProps,
getGroupTransitionProps,
status,
publicAPI,
} = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref });

const item = publicAPI.getItem(itemId);
const color = item?.color;
return (
<TreeItem2Provider itemId={itemId}>
<TreeItem2Root {...getRootProps(other)}>
<TreeItem2Content
{...getContentProps({
className: clsx("content", {
expanded: status.expanded,
selected: status.selected,
focused: status.focused,
disabled: status.disabled,
}),
})}
>
{status.expandable && (
<TreeItem2IconContainer {...getIconContainerProps()}>
<TreeItem2Icon status={status} />
</TreeItem2IconContainer>
)}

<CustomLabel {...getLabelProps({ color })} />
</TreeItem2Content>
{children && (
<TransitionComponent
{...getGroupTransitionProps({ className: "groupTransition" })}
/>
)}
</TreeItem2Root>
</TreeItem2Provider>
);
});

export default function CustomizedTreeView() {
return (
<Card
variant="outlined"
sx={{ display: "flex", flexDirection: "column", gap: "8px", flexGrow: 1 }}
>
<CardContent>
<Typography component="h2" variant="subtitle2">
Product tree
</Typography>
<RichTreeView
items={ITEMS}
aria-label="pages"
multiSelect
defaultExpandedItems={["1", "1.1"]}
defaultSelectedItems={["1.1", "1.1.1"]}
sx={{
m: "0 -8px",
pb: "8px",
height: "fit-content",
flexGrow: 1,
overflowY: "auto",
}}
slots={{ item: CustomTreeItem }}
/>
</CardContent>
</Card>
);
}
42 changes: 42 additions & 0 deletions frontend/src/components/HighlightedCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as React from "react";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import ChevronRightRoundedIcon from "@mui/icons-material/ChevronRightRounded";
import InsightsRoundedIcon from "@mui/icons-material/InsightsRounded";
import useMediaQuery from "@mui/material/useMediaQuery";
import { useTheme } from "@mui/material/styles";

export default function HighlightedCard() {
const theme = useTheme();
const isSmallScreen = useMediaQuery(theme.breakpoints.down("sm"));

return (
<Card sx={{ height: "100%" }}>
<CardContent>
<InsightsRoundedIcon />
<Typography
component="h2"
variant="subtitle2"
gutterBottom
sx={{ fontWeight: "600" }}
>
Explore your data
</Typography>
<Typography sx={{ color: "text.secondary", mb: "8px" }}>
Uncover performance and usage insights with our data analysis tools.
</Typography>
<Button
variant="contained"
size="small"
color="primary"
endIcon={<ChevronRightRoundedIcon />}
fullWidth={isSmallScreen}
>
Get insights
</Button>
</CardContent>
</Card>
);
}
Loading