Merge pull request #22 from bluewave-labs/feat/section

Feat/section
This commit is contained in:
Veysel authored and GitHub committed 2024-05-11 10:58:24 -04:00
commit b93ae68395
7 files changed
+284 -30

No files matched your search

@@ -18,23 +18,47 @@ const levelConfig = {
variant: "contained",
color: "error",
},
imagePrimary: {
color: "primary",
variant: "text",
},
imageSecondary: {
color: "secondary",
variant: "text",
},
imageTertiary: {
color: "tertiary",
variant: "text",
},
};
/**
* @component
* @param {Object} props
* @param {'primary' | 'secondary' | 'tertiary' | 'error'} props.level - The level of the button
* @param {'primary' | 'secondary' | 'tertiary' | 'error' | 'imagePrimary' | 'imageSecondary' | 'imageTertiary'} props.level - The level of the button
* @param {string} props.label - The label of the button
* @param {React.ReactNode} props.img - Image for button
* @param {boolean} [props.disabled] - Whether the button is disabled
* @param {Object} prps.sx - Styles for the button
* @returns {JSX.Element}
* @example
* // Render an error button
* <Button level="error" label="Error" disabled />
* <Button level="error" label="Error" disabled sx={{marginTop: "1rem"}}/>
*/
const Button = ({ level, label, disabled }) => {
const Button = ({ level, label, disabled, img, sx }) => {
const { variant, color } = levelConfig[level];
return (
<MuiButton variant={variant} color={color} disabled={disabled}>
<MuiButton
variant={variant}
color={color}
disabled={disabled}
sx={{
textTransform: "none",
...sx,
}}
>
{img && img}
{label}
</MuiButton>
);
@@ -43,6 +67,8 @@ const Button = ({ level, label, disabled }) => {
Button.propTypes = {
level: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
img: PropTypes.node,
sx: PropTypes.object,
disabled: PropTypes.bool,
};
File renamed without changes.
@@ -1,6 +1,15 @@
import { Link as MuiLink, useTheme } from "@mui/material";
import PropTypes from "prop-types";
/**
* @component
* @param {Object} props
* @param {'primary' | 'secondary' | 'tertiary' | 'error'} props.level - The level of the link
* @param {string} props.label - The label of the link
* @param {string} props.url - The URL of the link
* @returns {JSX.Element}
*/
const Link = ({ level, label, url }) => {
const theme = useTheme();
@@ -22,14 +31,6 @@ const Link = ({ level, label, url }) => {
},
error: {},
};
/**
* @typedef {Object} Props
* @property {'primary' | 'secondary' | 'tertiary' | 'error'} level - The level of the link
* @property {string} label - The label of the link
* @property {string} url - The URL of the link
*/
const { sx, color } = levelConfig[level];
return (
<MuiLink href={url} sx={sx} color={color}>
+133
View File
@@ -0,0 +1,133 @@
import PropTypes from "prop-types";
import { useState, useEffect } from "react";
import {
Box,
Container,
useTheme,
Typography,
TextField,
Switch,
} from "@mui/material";
import MenuIcon from "@mui/icons-material/Menu";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
import Button from "../Button/Button";
import AddIcon from "@mui/icons-material/Add";
/**
* @component
* @param {Object} props
* @param { Array} props.montitors - Array of monitors associated with the section
* @returns {JSX.Element}
* @example
* // Renders a section component with a list of monitors
* <Section monitors={monitors} />
*/
const Section = ({ monitors }) => {
const [monitorStates, setMonitorStates] = useState(
monitors.map((monitor) => monitor.isActive)
);
useEffect(() => {
console.log("Monitor states updated", monitorStates);
// Update DB here
}, [monitorStates]);
const handleMonitor = (monitorIndex) => {
setMonitorStates((prevStates) => {
const newStates = [...prevStates];
newStates[monitorIndex] = !newStates[monitorIndex];
return newStates;
// Need to update DB with new monitor state
});
};
const theme = useTheme();
return (
<>
<Container
disableGutters
sx={{
border: `1px solid ${theme.palette.section.borderColor}`,
borderRadius: `${theme.shape.borderRadius}px`,
}}
>
<Box
sx={{
textAlign: "left",
padding: `${theme.spacing(2)}`,
bgcolor: `${theme.palette.section.bgColor}`,
borderBottom: `1px solid ${theme.palette.section.borderColor}`,
}}
>
<Typography>Section Name</Typography>
<TextField
placeholder="Service Name"
sx={{
"& input": {
width: "320px",
height: "34px",
padding: "10px 14px 10px 14px",
},
}}
/>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "start",
textAlign: "left",
padding: `${theme.spacing(2)}`,
gap: 2,
}}
>
<Typography>Servers List</Typography>
<Button level="primary" label="Add new" />
{monitors.map((monitor, index) => {
return (
<Box
key={monitor.id}
sx={{
boxSizing: "border-box",
width: "100%",
padding: "10px 14px 10px 14px",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
border: `1px solid ${theme.palette.section.borderColor}`,
borderRadius: `${theme.shape.borderRadius}px`,
bgcolor: `${theme.palette.section.bgColor}`,
}}
>
<MenuIcon
sx={{ color: `${theme.palette.section.borderColor}` }}
/>
<Switch
checked={monitorStates[index]}
onChange={() => handleMonitor(index)}
/>
<Typography sx={{ flexGrow: 1 }}>{monitor.name}</Typography>
<DeleteOutlineIcon
sx={{ color: `${theme.palette.section.borderColor}` }}
/>
</Box>
);
})}
</Box>
</Container>
<Button
sx={{ marginTop: theme.spacing(2) }}
level="imageSecondary"
label="Add new section"
img={<AddIcon />}
/>
</>
);
};
Section.propTypes = {
monitors: PropTypes.array,
};
export default Section;
+101 -18
View File
@@ -1,9 +1,8 @@
import React from "react";
import Button from "../../Components/Button";
import Link from "../../Components/Link";
import Button from "../../Components/Button/Button";
import Link from "../../Components/Link/Link";
import ColoredLabel from "../../Components/Label/ColoredLabel";
import {
Box,
useTheme,
Switch,
Checkbox,
@@ -19,11 +18,14 @@ import StatusLabel from "../../Components/Label/StautsLabel";
import Avatar from "../../Components/Avatar/Avatar";
import ProgressStepper from "../../Components/ProgressStepper/ProgressStepper";
import avatarImage from "../../assets/Images/avatar_placeholder.png";
import Section from "../../Components/Section/Section";
import { DataGrid } from "@mui/x-data-grid";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import AddIcon from "@mui/icons-material/Add";
import Divider from "@mui/material/Divider";
const cols = [
{
@@ -84,6 +86,12 @@ const steps = [
{ label: "Invite your team", content: "Start collaborating with your team" },
];
const monitors = [
{ id: 0, name: "Google", isActive: true },
{ id: 1, name: "Yahoo", isActive: false },
{ id: 2, name: "Reddit", isActive: true },
];
const Demo = () => {
const [radio, setRadio] = React.useState(1);
const [tab, setTab] = React.useState("departments");
@@ -105,17 +113,82 @@ const Demo = () => {
alert(event.target.checked ? `${type} checked` : `${type} unchecked`);
};
const links = [
{
name: "Buttons",
url: "#buttons",
},
{
name: "Disabled Buttons",
url: "#disabled-buttons",
},
{
name: "Labels",
url: "#labels",
},
{
name: "Status Labels",
url: "#status-labels",
},
{
name: "Avatar",
url: "#avatar",
},
{
name: "Switches",
url: "#switches",
},
{
name: "Checkboxes",
url: "#checkboxes",
},
{
name: "Radio",
url: "#radio",
},
{
name: "Table",
url: "#table",
},
{
name: "Tabs",
url: "#tabs",
},
{
name: "Date Picker",
url: "#date-picker",
},
{
name: "Stepper",
url: "#stepper",
},
{
name: "Section",
url: "#section",
},
];
const theme = useTheme();
return (
<div>
<h4>Buttons</h4>
<ul style={{ listStyle: "none" }}>
{links.map((link) => (
<li key={link.url}>
<Link level="primary" label={link.name} url={link.url} />
</li>
))}
</ul>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="buttons">Buttons</h4>
<div>
<Button level="primary" label="Primary" />
<Button level="secondary" label="Secondary" />
<Button level="tertiary" label="Tertiary" />
<Button level="error" label="Error" />
<Button level="imageTertiary" label="Image Button" img={<AddIcon />} />
</div>
<h4>Disabled Buttons</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="disabled-buttons">Disabled Buttons</h4>
<div>
<Button level="primary" label="Primary" disabled />
<Button level="secondary" label="Secondary" disabled />
@@ -129,43 +202,48 @@ const Demo = () => {
url={"https://www.google.com"}
/>
</div>
<h4>Labels</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="labels">Labels</h4>
<div>
<ColoredLabel label="Label" color={theme.palette.labelGray.color} />
<ColoredLabel label="Label" color={theme.palette.labelPurple.color} />
<ColoredLabel label="Label" color={theme.palette.labelGreen.color} />
<ColoredLabel label="Label" color={theme.palette.labelOrange.color} />
</div>
<h4>Status Lables</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="status-labels">Status Lables</h4>
<div>
<StatusLabel status="Seen" />
<StatusLabel status="Waiting" />
<StatusLabel status="New" />
<StatusLabel status="Active" />
</div>
<h4>Avatar</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="avatar">Avatar</h4>
<div style={{ display: "flex" }}>
<Avatar src={avatarImage} firstName="Alex" lastName="Holliday" />
<Avatar firstName="Alex" lastName="Holliday" />
<Avatar src={avatarImage} firstName="Alex" lastName="Holliday" small />
<Avatar firstName="Alex" lastName="Holliday" small />
</div>
<h4>Switches</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="switches">Switches</h4>
<div>
<Switch onChange={(event) => change(event, "Switch")} />
<Switch size="small" />
<Switch disabled />
<Switch checked />
</div>
<h4>Checkboxes</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="checkboxes">Checkboxes</h4>
<div>
<Checkbox onChange={(event) => change(event, "Checkbox")} />
<Checkbox size="small" />
<Checkbox disabled />
<Checkbox checked />
</div>
<h4>Radio</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="radio">Radio</h4>
<div>
<FormControl>
<FormLabel>Demo Radio</FormLabel>
@@ -187,7 +265,8 @@ const Demo = () => {
</RadioGroup>
</FormControl>
</div>
<h4>Table</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="table">Table</h4>
<div style={{ width: "75vw" }}>
<DataGrid
autoHeight
@@ -201,7 +280,8 @@ const Demo = () => {
pageSizeOptions={[5, 10]}
/>
</div>
<h4>Tabs</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="tabs">Tabs</h4>
<div style={{ display: "flex", justifyContent: "center" }}>
{" "}
<Tabs value={tab} onChange={handleTab}>
@@ -211,19 +291,22 @@ const Demo = () => {
<Tab label="Approvals" value="approvals" />
</Tabs>
</div>
<h4>Date Picker</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="date-picker">Date Picker</h4>
<div>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DatePicker onChange={handleDate} />
</LocalizationProvider>
<h4>{date}</h4>
</div>
<h4>Stepper</h4>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="stepper">Stepper</h4>
<div>
<ProgressStepper steps={steps}></ProgressStepper>
</div>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="section">Section</h4>
<Section monitors={monitors} />
</div>
);
};
+11
View File
@@ -12,6 +12,10 @@ const labelGray = "#475467";
const labelPurple = "#6941C6";
const labelGreen = "#067647";
const labelRed = "#F04438";
//Section colros
const sectionBorder = "#D0D5DD";
const sectionBg = "#F8F9F8";
const theme = createTheme({
palette: {
primary: {
@@ -39,6 +43,13 @@ const theme = createTheme({
labelRed: {
color: labelRed,
},
section: {
borderColor: sectionBorder,
bgColor: sectionBg,
},
},
shape: {
borderRadius: 4,
},
});