@mui/material/styles#useTheme TypeScript Examples

The following examples show how to use @mui/material/styles#useTheme. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DrawerLayout.tsx    From react-component-library with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
DrawerLayoutRender: React.ForwardRefRenderFunction<unknown, DrawerLayoutProps> = (
    props: DrawerLayoutProps,
    ref: any
) => {
    const { children, drawer, classes, ...otherDivProps } = props;
    const theme = useTheme();
    const [padding, setPadding] = useState<number | string>(0);
    const [drawerOpen, setDrawerOpen] = useState(false);
    const defaultClasses = useStyles();

    const style: CSSProperties = { paddingLeft: 0, paddingRight: 0 };
    style.paddingLeft = theme.direction === 'ltr' ? padding : 0;
    style.paddingRight = theme.direction === 'rtl' ? padding : 0;

    return (
        <DrawerLayoutContext.Provider
            value={{
                setPadding,
                setDrawerOpen,
            }}
        >
            <div
                ref={ref}
                className={clsx(defaultClasses.root, classes.root, {
                    [defaultClasses.expanded]: !drawerOpen,
                    [classes.expanded]: !drawerOpen,
                })}
                {...otherDivProps}
            >
                <div className={clsx(defaultClasses.drawer, classes.drawer)}>{drawer}</div>
                <div className={clsx(defaultClasses.content, classes.content)} style={style}>
                    {children}
                </div>
            </div>
        </DrawerLayoutContext.Provider>
    );
}
Example #2
Source File: FormGroup.tsx    From ui-schema with MIT License 6 votes vote down vote up
FormGroupBase: React.ComponentType<WidgetProps<MuiWidgetBinding> & WithValue> = (props) => {
    const {storeKeys, widgets} = props
    const {WidgetRenderer} = widgets
    const {spacing} = useTheme()
    let {schema} = props
    // deleting the `widget` to directly use `PluginStack` for nesting
    // with `widget` it would lead to an endless loop
    // using e.g. default `object` renderer then
    // @ts-ignore
    schema = schema.delete('widget')
    return <FormControl
        component="fieldset"
        style={{
            display: 'block',
            marginBottom: spacing(1),
        }}
    >
        <FormLabel component="legend">
            <TransTitle schema={schema} storeKeys={storeKeys}/>
        </FormLabel>
        <MuiFormGroup
            style={{
                marginTop: spacing(1),
                marginBottom: spacing(1),
            }}
        >
            <WidgetRenderer {...props} schema={schema}/>
        </MuiFormGroup>
        {/*<FormHelperText>Be careful</FormHelperText>*/}
    </FormControl>
}
Example #3
Source File: index.tsx    From next-typescript-materialui-jest-starter with MIT License 6 votes vote down vote up
Home = () => {
  const theme = useTheme();
  const hello = "Hello";
  return (
    <>
      <div style={{ color: theme.palette.primary.main }}>{hello}</div>
      <Button name="Click Me" color="primary" />
      <Example />
    </>
  );
}
Example #4
Source File: DesktopSideBar.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 6 votes vote down vote up
export default function DesktopSideBar({ navBarItems }: IProps) {
    const location = useLocation();
    const theme = useTheme();

    const iconFor = (path: string, IconComponent: any, SelectedIconComponent: any) => {
        if (location.pathname === path) return <SelectedIconComponent sx={{ color: 'primary.main' }} fontSize="large" />;
        return <IconComponent sx={{ color: (theme.palette.mode === 'dark') ? 'grey.A400' : 'grey.600' }} fontSize="large" />;
    };

    return (
        <SideNavBarContainer>
            {
                // eslint-disable-next-line react/destructuring-assignment
                navBarItems.map(({
                    path, title, IconComponent, SelectedIconComponent,
                }: NavbarItem) => (
                    <Link to={path} style={{ color: 'inherit', textDecoration: 'none' }} key={path}>
                        <ListItem disableRipple button key={title}>
                            <ListItemIcon sx={{ minWidth: '0' }}>
                                <Tooltip placement="right" title={title}>
                                    {iconFor(path, IconComponent, SelectedIconComponent)}
                                </Tooltip>
                            </ListItemIcon>
                        </ListItem>
                    </Link>
                ))
            }
        </SideNavBarContainer>
    );
}
Example #5
Source File: QueuedAttachmentGeneric.tsx    From airmessage-web with Apache License 2.0 6 votes vote down vote up
export default function QueuedAttachmentGeneric(props: {queueData: QueuedAttachmentProps}) {
	const theme = useTheme();
	
	return (
		<QueuedAttachment queueData={props.queueData}>
			<div className={styles.content} style={{backgroundColor: theme.palette.background.default}}>
				<InsertDriveFileRounded />
			</div>
		</QueuedAttachment>
	);
}
Example #6
Source File: EmptyView.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 6 votes vote down vote up
export default function EmptyView({ message, messageExtra }: IProps) {
    const theme = useTheme();
    const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm'));

    return (
        <Box sx={{
            position: 'absolute',
            left: `calc(50% + ${isMobileWidth ? '0px' : theme.spacing(8 / 2)})`,
            top: '50%',
            transform: 'translate(-50%, -50%)',
            textAlign: 'center',
        }}
        >
            <Typography variant="h3" gutterBottom>
                {getRandomErrorFace()}
            </Typography>
            <Typography variant="h5">
                {message}
            </Typography>
            {messageExtra}
        </Box>
    );
}
Example #7
Source File: Profiler.tsx    From NekoMaid with MIT License 6 votes vote down vote up
Pie: React.FC<{ title: string, data: any[], formatter?: any }> = React.memo(({ title, data, formatter }) => <Grid item sm={6} xs={12}>
  <Card>
    <CardHeader title={title} />
    <Divider />
    {data.length
      ? <ReactECharts style={{ height: 300 }} theme={useTheme().palette.mode === 'dark' ? 'dark' : undefined} option={{
        backgroundColor: 'rgba(0, 0, 0, 0)',
        itemStyle: {
          borderRadius: 5,
          borderColor: 'rgba(0, 0, 0, 0)',
          borderWidth: 4
        },
        tooltip: {
          trigger: 'item',
          formatter
        },
        series: [{
          type: 'pie',
          radius: '50%',
          data,
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          }
        }]
      }} />
      : <CardContent><Empty /></CardContent>}
  </Card>
</Grid>)
Example #8
Source File: MessageModifierTapbackRow.tsx    From airmessage-web with Apache License 2.0 6 votes vote down vote up
function MessageModifierTapback(props: {type: TapbackType, count: number}) {
	const theme = useTheme();
	const iconColor = theme.palette.text.secondary;
	
	let icon: JSX.Element;
	switch(props.type) {
		case TapbackType.Love:
			icon = <TapbackLoveIcon className={styles.icon} style={{color: iconColor}} />;
			break;
		case TapbackType.Like:
			icon = <TapbackLikeIcon className={styles.icon} style={{color: iconColor}} />;
			break;
		case TapbackType.Dislike:
			icon = <TapbackDislikeIcon className={styles.icon} style={{color: iconColor}} />;
			break;
		case TapbackType.Laugh:
			icon = <TapbackLaughIcon className={styles.icon} style={{color: iconColor}} />;
			break;
		case TapbackType.Emphasis:
			icon = <TapbackEmphasisIcon className={styles.icon} style={{color: iconColor}} />;
			break;
		case TapbackType.Question:
			icon = <TapbackQuestionIcon className={styles.icon} style={{color: iconColor}} />;
			break;
	}
	
	return (
		<div className={styles.tapback} style={{backgroundColor: theme.palette.messageIncoming.main, borderColor: theme.palette.background.default}}>
			{icon}
			{props.count > 1 && <span className={styles.label} style={{color: iconColor}}>{props.count}</span>}
		</div>
	);
}
Example #9
Source File: Empty.tsx    From NekoMaid with MIT License 6 votes vote down vote up
EmptyIcon: React.FC<React.SVGProps<SVGSVGElement>> = props => {
  return <svg
    width='121'
    height='100'
    viewBox='0 0 184 152'
    xmlns='http://www.w3.org/2000/svg'
    {...props}
    style={{
      ...(props.style || {}),
      filter: useTheme().palette.mode === 'dark'
        ? 'brightness(0.7) drop-shadow(rgba(255, 255, 255, 0.2) 1px 3px 6px)'
        : 'drop-shadow(rgba(0, 0, 0, 0.1) 2px 4px 4px)'
    }}
  >
    <g fill='none' fillRule='evenodd'>
      <g transform='translate(24 31.67)'>
        <path fill='#aeb8c2' d='M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z' />
        <path fill='#f5f5f7' d='M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z' />
        <path fill='#dce0e6' d='M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z' />
      </g>
      <path fill='#dce0e6' d='M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z' />
      <g fill='#fff' transform='translate(149.65 15.383)'>
        <ellipse cx='20.654' cy='3.167' rx='2.849' ry='2.815' />
        <path d='M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z' />
      </g>
    </g>
  </svg>
}
Example #10
Source File: VerticalTabs.tsx    From console with GNU Affero General Public License v3.0 5 votes vote down vote up
VerticalTabs = ({
  children,
  classes,
  selectedTab = "0",
  routes,
  isRouteTabs,
}: VerticalTabsProps) => {
  const [value, setValue] = React.useState(selectedTab);

  const theme = useTheme();
  const isSmallScreen = useMediaQuery(theme.breakpoints.down("md"));

  const handleChange = (event: React.SyntheticEvent, newValue: string) => {
    setValue(newValue);
  };

  const headerList: TabProps[] = [];
  const contentList: React.ReactNode[] = [];

  if (!children) return null;

  children.forEach((child) => {
    headerList.push(child.tabConfig);
    contentList.push(child.content);
  });

  return (
    <TabContext value={`${value}`}>
      <Box className={classes.tabsContainer}>
        <Box className={classes.tabsHeaderContainer}>
          <TabList
            onChange={handleChange}
            orientation={isSmallScreen ? "horizontal" : "vertical"}
            variant={isSmallScreen ? "scrollable" : "standard"}
            scrollButtons="auto"
            className={classes.tabList}
          >
            {headerList.map((item, index) => {
              if (item) {
                return (
                  <Tab
                    className={classes.tabHeader}
                    key={`v-tab-${index}`}
                    value={`${index}`}
                    style={tabStripStyle}
                    {...item}
                    disableRipple
                    disableTouchRipple
                    focusRipple={true}
                  />
                );
              }
              return null;
            })}
          </TabList>
        </Box>

        <Box className={classes.tabContentContainer}>
          {!isRouteTabs
            ? contentList.map((item, index) => {
                return (
                  <TabPanel
                    classes={{ ...classes.tabPanel }}
                    key={`v-tab-p-${index}`}
                    value={`${index}`}
                  >
                    {item ? item : null}
                  </TabPanel>
                );
              })
            : null}
          {isRouteTabs ? (
            <div className={classes.tabPanel}>{routes}</div>
          ) : null}
        </Box>
      </Box>
    </TabContext>
  );
}
Example #11
Source File: index.tsx    From yearn-watch-legacy with GNU Affero General Public License v3.0 5 votes vote down vote up
headCells: HeadCell<StrategyTVLListItem>[] = [
    {
        numeric: false,
        disablePadding: false,
        align: 'center',
        label: 'Strategy Name',
        format: (item: GenericListItem) => {
            const theme = useTheme();
            return (
                <Link
                    style={{
                        color:
                            theme.palette.mode === 'light' ? 'blue' : '#ce93d8',
                    }}
                    to={`/network/${item.network}/vault/${item.vault}/strategy/${item.strategy}`}
                    target="_blank"
                >
                    {`${item.name} (${extractAddress(
                        item.strategy as string
                    )})`}
                </Link>
            );
        },
    },
    {
        numeric: true,
        disablePadding: false,
        align: 'center',
        label: 'Activation',
        format: (item: GenericListItem) => {
            return <div>{new Date(item.activation).toUTCString()}</div>;
        },
    },
    {
        id: 'estimatedTotalAssetsUsdcNumber',
        numeric: true,
        disablePadding: false,
        align: 'center',
        label: 'TVL (MM)',
    },
    {
        id: 'totalTvlPercentage',
        numeric: true,
        disablePadding: false,
        align: 'center',
        label: 'TVL %',
    },
    {
        id: 'debtOutstandingUsdcNumber',
        numeric: true,
        disablePadding: false,
        align: 'center',
        label: 'Debt Outstanding (MM)',
        getStyle: (item: StrategyTVLListItem) => {
            const hasHighDebtToAssetsRatio =
                item.debtOutstandingUsdcNumber >
                HIGH_DEBT_TO_ASSETS_RATIO * item.estimatedTotalAssetsUsdcNumber;
            return hasHighDebtToAssetsRatio
                ? {
                      backgroundColor: '#f5f514',
                  }
                : {};
        },
    },
    {
        id: 'tvlImpact',
        numeric: true,
        disablePadding: false,
        align: 'center',
        label: 'TVL Impact (5-1 Extreme-Low)',
    },
]
Example #12
Source File: Dashboard.tsx    From NekoMaid with MIT License 5 votes vote down vote up
WorldMap: React.FC<{ players: Player[] }> = React.memo(({ players }) => {
  const theme = useTheme()
  const his = useHistory()
  const globalData = useGlobalData()
  const [, update] = useState(0)
  if (!mapAdded) {
    const node = document.createElement('script')
    node.type = 'text/javascript'
    node.src = 'http://api.map.baidu.com/getscript?v=3.0&ak=' + (globalData.bMapKey || '8G2uX6PFlYK3XCdcWYxH5sPVEA9K88QT')
    node.onload = () => {
      mapLoaded = true
      update(id => id + 1)
    }
    document.body.appendChild(node)
    mapAdded = true
  }

  return mapLoaded
    ? <ReactECharts
      style={{ height: 750, maxHeight: '100vh' }}
      onEvents={{
        click ({ data: { name } }: { data: { name: string } }) {
          if (players.some(it => it.name === name)) his.push('/NekoMaid/playerList/' + name)
        }
      }}
      option={{
        backgroundColor: 'rgba(0, 0, 0, 0)',
        tooltip: { trigger: 'item' },
        bmap: {
          center: [104.114129, 37.550339],
          zoom: 3,
          roam: true,
          mapStyle: theme.palette.mode === 'dark' ? { styleJson } : undefined
        },
        series: [{
          type: 'effectScatter',
          coordinateSystem: 'bmap',
          data: players.filter(it => it.loc).map(it => ({ name: it.name, value: [it.loc![0], it.loc![1]], ip: it.ip })),
          label: {
            formatter: '{b}',
            position: 'right',
            show: true
          },
          tooltip: {
            trigger: 'item',
            formatter: ({ data }: any) => 'IP: ' + data.ip
          },
          encode: { value: 2 },
          showEffectOn: 'emphasis',
          rippleEffect: { brushType: 'stroke' },
          symbolSize: 10,
          itemStyle: {
            color: theme.palette.primary.main,
            shadowBlur: 4
          },
          hoverAnimation: true
        }]
      }}
    />
    : <></>
})
Example #13
Source File: App.tsx    From sapio-studio with Mozilla Public License 2.0 5 votes vote down vote up
function ContractViewer(props: {
    model: DiagramModel;
    engine: DiagramEngine;
    current_contract: ContractModel;
}) {
    const dispatch = useDispatch();
    const entity_id: EntityType = useSelector(selectEntityToView);
    const show = useSelector(selectShouldViewEntity);
    const theme = useTheme();
    const timing_simulator_enabled = useSelector(selectSimIsShowing);
    const details = entity_id[0] !== 'NULL' && show;
    const { model, engine, current_contract } = props;
    React.useEffect(() => {
        if (entity_id[0] === 'TXN')
            jump_to_entity(
                model,
                engine,
                TXIDAndWTXIDMap.get_by_txid_s(
                    current_contract.txid_map,
                    entity_id[1]
                ) ?? null
            );
        else if (entity_id[0] === 'UTXO')
            jump_to_entity(
                model,
                engine,
                TXIDAndWTXIDMap.get_by_txid_s(
                    current_contract.txid_map,
                    entity_id[1].hash
                )?.utxo_models[entity_id[1].nIn] ?? null
            );
    }, [entity_id]);

    return (
        <>
            <div className="main-container">
                <DemoCanvasWidget
                    engine={engine}
                    model={model}
                    background={theme.palette.background.paper}
                    color={theme.palette.divider}
                >
                    <CanvasWidget engine={engine as any} key={'main'} />
                </DemoCanvasWidget>
            </div>
            <Collapse in={details}>
                <CurrentlyViewedEntity current_contract={current_contract} />
            </Collapse>
            <div className="area-overlays">
                <Collapse in={timing_simulator_enabled}>
                    <SimulationController
                        contract={current_contract}
                        engine={engine}
                        hide={() => dispatch(toggle_showing())}
                    />
                </Collapse>
            </div>
        </>
    );
}
Example #14
Source File: EditorJSWidget.tsx    From ui-schema with MIT License 5 votes vote down vote up
EditorJSWidget = (
    {
        schema, storeKeys,
        showValidity, valid, errors,
        required, tools, hideTitle,
    }: WidgetProps & RichContentProps
): React.ReactElement => {
    const uid = useUID()
    const [focused, setFocused] = React.useState(false)
    const [ready, setReady] = React.useState(false)
    const [empty, setEmpty] = React.useState(true)
    const dense = schema.getIn(['view', 'dense']) as boolean
    const theme = useTheme()
    const styles = useEditorStyles(theme, {dense})

    return <FormControl sx={styles.wrapper}>
        {!hideTitle && !schema.getIn(['view', 'hideTitle']) ?
            <InputLabel
                focused={focused} shrink={focused || !empty}
                margin={dense ? 'dense' : undefined}
                error={!valid}
            >
                <TransTitle schema={schema} storeKeys={storeKeys}/>
            </InputLabel> : null}

        <Box
            sx={styles.editor}
            className={clsx(
                inputClasses.underline,
                focused ? inputClasses.focused : null
            )}
        >
            <EditorJS
                uid={uid}
                ready={ready}
                onFocus={() => setFocused(true)}
                onBlur={() => setFocused(false)}
                onReady={() => setReady(true)}
                onEmptyChange={(e) => setEmpty(e)}
                storeKeys={storeKeys}
                tools={tools}
                required={Boolean(schema.get('deleteOnEmpty') || required)}
            />
        </Box>

        <ValidityHelperText
            /* only pass down errors which are not for a specific sub-schema */
            errors={errors}
            showValidity={showValidity}
            schema={schema}
        />
    </FormControl>
}
Example #15
Source File: CategorySelect.tsx    From mojito_pdm with Creative Commons Attribution Share Alike 4.0 International 5 votes vote down vote up
CategorySelect: React.FC = () => {
    const theme = useTheme()
    const [category, setCategory] = useRecoilState(CarState.categorySearch)

    const handleChange = (event: SelectChangeEvent) => {
        setCategory(event.target.value)
    };

    return (
        <>
            <div>
                <FormControl variant="outlined" sx={{margin: theme.spacing(1), minWidth: 240}} color="error">
                    <InputLabel sx={{color: "white"}}>Category</InputLabel>
                    <Select sx={{color: "white"}}
                            labelId="demo-simple-select-outlined-label"
                            id="demo-simple-select-outlined"
                            value={category}
                            onChange={handleChange}
                            label="Category"
                    >
                        <MenuItem value="">
                            <em>All</em>
                        </MenuItem>
                        <MenuItem value={"Sports"}>Sports</MenuItem>
                        <MenuItem value={"Compacts"}>Compacts</MenuItem>
                        <MenuItem value={"Muscle"}>Muscle</MenuItem>
                        <MenuItem value={"Sedan"}>Sedan</MenuItem>
                        <MenuItem value={"Coupe"}>Coupé</MenuItem>
                        <MenuItem value={"Super"}>Super</MenuItem>
                        <MenuItem value={"SUV"}>SUV</MenuItem>
                        <MenuItem value={"Vans"}>Vans</MenuItem>
                        <MenuItem value={"Offroad"}>Offroad</MenuItem>
                        <MenuItem value={"Sports Classics"}>Sports Classics</MenuItem>
                        <MenuItem value={"Motorcycles"}>Motorcycles</MenuItem>
                    </Select>
                </FormControl>
            </div>
        </>
    )
}
Example #16
Source File: SoftDivider.tsx    From airmessage-web with Apache License 2.0 5 votes vote down vote up
export default function SoftDivider(props: {vertical?: boolean}) {
	const color = useTheme().palette.divider;
	
	return (
		<div className={props.vertical ? styles.vertical : styles.horizontal} style={{backgroundColor: color}} />
	);
}
Example #17
Source File: VehCard.tsx    From mojito_pdm with Creative Commons Attribution Share Alike 4.0 International 5 votes vote down vote up
VehCard: React.FC<Car> = ({
    name,
    brand,
    description,
    brandLogo,
    image,
    price,
    category,
    spawncode,
    trunkspace,
    performance
}) => {
    const theme = useTheme();
    const [open, setOpen] = useState(false)
    const testDrive = async () => {
        await fetchNui("test_drive", {vehicle: spawncode})
    }

    // Functions
    const handleOpen = () => setOpen(true)
    const handleClose = () => setOpen(false)

    return (
        <Card sx={{
            boxShadow: theme.shadows[3],
            margin: theme.spacing(2)
        }} variant="outlined">
            <CardHeader
                avatar={<img height={40} style={{maxWidth: 100, maxHeight: 40}} src={brandLogo} alt={brand}/>}
                title={name}
                subheader={category}
            />
            <CardMedia style={{height: "150px"}} image={image}/>
            <CardActions>
                <Tooltip TransitionComponent={Zoom} sx={{maxWidth: 120}} arrow title="Test drive this vehicle">
                    <Button
                        size="small"
                        variant={theme.palette.mode === "dark" ? "contained" : "outlined"}
                        color="primary"
                        startIcon={<DirectionsCarIcon/>}
                        onClick={testDrive}
                        disableElevation
                    >
                        TEST DRIVE
                    </Button>
                </Tooltip>
                <Tooltip TransitionComponent={Zoom} arrow sx={{maxWidth: 120}}
                         title="View more information about this vehicle">
                    <Button
                        size="small"
                        variant={theme.palette.mode === "dark" ? "contained" : "outlined"}
                        color="primary"
                        startIcon={<AssignmentIcon/>}
                        onClick={handleOpen}
                        disableElevation
                    >
                        MORE INFO
                    </Button>
                </Tooltip>
                <Modal
                    open={open}
                    onClose={handleClose}
                >
                    {<ModalBody
                        name={name}
                        brand={brand}
                        description={description}
                        price={price}
                        trunkspace={trunkspace}
                        setOpen={setOpen}
                        performance={performance}
                        spawncode={spawncode}
                    />}
                </Modal>
            </CardActions>
        </Card>
    )
}
Example #18
Source File: DefaultNavBar.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 5 votes vote down vote up
export default function DefaultNavBar() {
    const { title, action, override } = useContext(NavBarContext);
    const { darkTheme } = useContext(DarkTheme);

    const theme = useTheme();
    const history = useHistory();

    const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm'));
    const isMainRoute = navbarItems.some(({ path }) => path === history.location.pathname);

    // Allow default navbar to be overrided
    if (override.status) return override.value;

    let navbar = <></>;
    if (isMobileWidth) {
        if (isMainRoute) {
            navbar = <MobileBottomBar navBarItems={navbarItems.filter((it) => it.show !== 'desktop')} />;
        }
    } else {
        navbar = <DesktopSideBar navBarItems={navbarItems.filter((it) => it.show !== 'mobile')} />;
    }

    return (
        <Box sx={{ flexGrow: 1 }}>
            <AppBar position="fixed" color={darkTheme ? 'default' : 'primary'}>
                <Toolbar>
                    {
                        !navbarItems.some(({ path }) => path === history.location.pathname)
                            && (
                                <IconButton
                                    edge="start"
                                    sx={{ marginRight: theme.spacing(2) }}
                                    color="inherit"
                                    aria-label="menu"
                                    disableRipple
                                    // when page is opened in new tab backbutton will
                                    // take you to the library
                                    onClick={() => (history.length === 1 ? history.push('/library') : history.goBack())}
                                    size="large"
                                >
                                    <ArrowBack />
                                </IconButton>
                            )
                    }
                    <Typography variant={isMobileWidth ? 'h6' : 'h5'} sx={{ flexGrow: 1 }}>
                        {title}
                    </Typography>
                    {action}
                </Toolbar>
            </AppBar>
            {navbar}
        </Box>
    );
}
Example #19
Source File: MessageInput.tsx    From airmessage-web with Apache License 2.0 5 votes vote down vote up
export default function MessageInput(props: Props) {
	const theme = useTheme();
	const colorBG = theme.palette.messageIncoming.main;
	
	const {
		onMessageChange: propsOnMessageChange,
		onMessageSubmit: propsOnMessageSubmit,
		message: propsMessage,
		attachments: propsAttachments,
		onAttachmentAdd: propsOnAttachmentAdd
	} = props;
	
	const handleChange = useCallback((event: ChangeEvent<HTMLTextAreaElement>) => {
		propsOnMessageChange(event.target.value);
	}, [propsOnMessageChange]);
	
	const submitInput = useCallback(() => {
		propsOnMessageSubmit(propsMessage, propsAttachments);
	}, [propsOnMessageSubmit, propsMessage, propsAttachments]);
	
	const handleKeyPress = useCallback((event: React.KeyboardEvent<HTMLElement>) => {
		if(!event.shiftKey && event.key === "Enter") {
			event.preventDefault();
			submitInput();
		}
	}, [submitInput]);
	
	const handlePaste = useCallback((event: React.ClipboardEvent<HTMLElement>) => {
		propsOnAttachmentAdd(Array.from(event.clipboardData.files));
	}, [propsOnAttachmentAdd]);
	
	return (
		<div className={styles.root} style={{backgroundColor: colorBG}}>
			<Flipper flipKey={props.attachments.map(attachment => attachment.id).join(" ")}>
				{props.attachments.length > 0 &&
					<div className={styles.attachmentqueue}>
						{props.attachments.map((file) => {
							const queueData: QueuedAttachmentProps = {
								file: file.file,
								onRemove: () => props.onAttachmentRemove(file)
							};
							
							let component: React.ReactNode;
							if(file.file.type.startsWith("image/")) component = <QueuedAttachmentImage queueData={queueData} />;
							else component = <QueuedAttachmentGeneric queueData={queueData} />;
							
							return (<Flipped flipId={"attachmentqueue-" + file.id} key={file.id} onAppear={onAttachmentAppear} onExit={onAttachmentExit}>
								{component}
							</Flipped>);
						})}
					</div>
				}
				<div className={styles.control}>
					<InputBase className={styles.textfield} maxRows="5" multiline fullWidth autoFocus placeholder={props.placeholder} value={props.message} onChange={handleChange} onKeyPress={handleKeyPress} onPaste={handlePaste} />
					<IconButton size="small" color="primary" disabled={props.message.trim() === "" && props.attachments.length === 0} onClick={submitInput}><PushIcon /></IconButton>
				</div>
			</Flipper>
		</div>
	);
}
Example #20
Source File: MobileBottomBar.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 5 votes vote down vote up
export default function MobileBottomBar({ navBarItems }: IProps) {
    const location = useLocation();
    const theme = useTheme();

    const iconFor = (path: string, IconComponent: any, SelectedIconComponent: any) => {
        if (location.pathname === path) return <SelectedIconComponent sx={{ color: 'primary.main' }} fontSize="medium" />;
        return <IconComponent sx={{ color: (theme.palette.mode === 'dark') ? 'grey.A400' : 'grey.600' }} fontSize="medium" />;
    };

    return (
        <BottomNavContainer>
            {
                navBarItems.map((
                    {
                        path, title, IconComponent, SelectedIconComponent,
                    }: NavbarItem,
                ) => (
                    <Link to={path} key={path}>
                        <ListItem disableRipple button sx={{ justifyContent: 'center', padding: '8px' }} key={title}>
                            <Box
                                display="flex"
                                flexDirection="column"
                                alignItems="center"
                            >
                                {iconFor(path, IconComponent, SelectedIconComponent)}
                                <Box sx={{
                                    fontSize: '0.65rem',
                                    // eslint-disable-next-line no-nested-ternary
                                    color: location.pathname === path
                                        ? 'primary.main'
                                        : ((theme.palette.mode === 'dark')
                                            ? 'grey.A400'
                                            : 'grey.600'),
                                }}
                                >
                                    {title}
                                </Box>
                            </Box>
                        </ListItem>
                    </Link>
                ))
            }
        </BottomNavContainer>
    );
}
Example #21
Source File: Files.tsx    From NekoMaid with MIT License 4 votes vote down vote up
Editor: React.FC<{ plugin: Plugin, editorRef: React.Ref<UnControlled>, loading: { '!#LOADING'?: boolean },
  dirs: Record<string, boolean>, refresh: () => void }> = React.memo(({ plugin, editorRef, loading, dirs, refresh }) => {
    const doc = (editorRef as any).current?.editor?.doc
    const theme = useTheme()
    const his = useHistory()
    const lnText = useRef('')
    const path = useLocation().pathname.replace(/^\/NekoMaid\/files\/?/, '')
    const [text, setText] = useState<string | null>(null)
    const [error, setError] = useState('')
    const [saving, setSaving] = useState(false)
    const [notUndo, setNotUndo] = useState(true)
    const [notRedo, setNotRedo] = useState(true)
    const [notSave, setNotSave] = useState(true)
    const [isNewFile, setIsNewFile] = useState(false)
    useEffect(() => {
      setText(null)
      setError('')
      setIsNewFile(false)
      lnText.current = ''
      if (!path || dirs[path] || path.endsWith('/')) return
      loading['!#LOADING'] = true
      plugin.emit('files:content', (data: number | string | null) => {
        loading['!#LOADING'] = false
        switch (data) {
          case null: return setError(lang.files.unsupportedFormat)
          case 0: return setError(lang.files.notExists)
          case 1:
            setIsNewFile(true)
            setText('')
            setNotSave(true)
            break
          case 2: return his.replace('./')
          case 3: return setError(lang.files.tooBig)
          default:
            if (typeof data !== 'string') return
            setText(data)
            lnText.current = data.replace(/\r/g, '')
            setNotSave(true)
        }
      }, path)
    }, [path])
    return <Card sx={{
      position: 'relative',
      '& .CodeMirror-dialog, .CodeMirror-scrollbar-filler': { backgroundColor: theme.palette.background.paper + '!important' }
    }}>
      <CardHeader
        title={<span style={{ fontWeight: 'normal' }}>
          {lang.files.editor}{path && ': ' + path}{path && isNewFile && <span className='bold'> ({lang.files.newFile})</span>}</span>}
        sx={{ position: 'relative' }}
        action={!error && path && text != null
          ? <Box sx={cardActionStyles}>
            <Tooltip title={lang.files.undo}>
              <span><IconButton size='small' disabled={notUndo} onClick={() => doc?.undo()}><Undo /></IconButton></span>
            </Tooltip>
            <Tooltip title={lang.files.undo}>
              <span><IconButton size='small' disabled={notRedo} onClick={() => doc?.redo()}><Redo /></IconButton></span>
            </Tooltip>
            <Tooltip title={lang.files.save}>{saving
              ? <CircularProgress size={24} sx={{ margin: '5px' }} />
              : <span><IconButton
              size='small'
              disabled={notSave}
              onClick={() => {
                if (!doc) return
                setSaving(true)
                const data = doc.getValue(text?.includes('\r\n') ? '\r\n' : '\n')
                plugin.emit('files:update', (res: boolean) => {
                  setSaving(false)
                  if (!res) failed()
                  lnText.current = data.replace(/\r/g, '')
                  setText(data)
                  setNotSave(true)
                  if (isNewFile) {
                    setIsNewFile(false)
                    success()
                    refresh()
                  }
                }, path, data)
              }}
            ><Save /></IconButton></span>}</Tooltip>
          </Box>
          : undefined}
      />
      <Divider />
      {(error || !path) && <CardContent><Empty title={error || lang.files.notSelected} /></CardContent>}
      <div style={{ position: text == null ? 'absolute' : undefined }}>
        <UnControlled
          ref={editorRef}
          value={text == null ? EMPTY : text}
          options={{
            phrases: lang.codeMirrorPhrases,
            mode: text == null ? '' : getMode(path),
            theme: theme.palette.mode === 'dark' ? 'material' : 'one-light',
            lineNumbers: true
          }}
          onChange={(_: any, { removed }: { removed: string[] }, newText: string) => {
            setNotSave(lnText.current === newText)
            if (removed?.[0] === EMPTY) doc?.clearHistory()
            const histroy = doc?.historySize()
            if (!histroy) return
            setNotUndo(!histroy.undo)
            setNotRedo(!histroy.redo)
          }}
        />
      </div>
    </Card>
  })
Example #22
Source File: DownloadQueue.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 4 votes vote down vote up
export default function DownloadQueue() {
    const [, setWsClient] = useState<WebSocket>();
    const [queueState, setQueueState] = useState<IQueue>(initialQueue);
    const { queue, status } = queueState;

    const history = useHistory();

    const theme = useTheme();

    const { setTitle, setAction } = useContext(NavbarContext);

    const toggleQueueStatus = () => {
        if (status === 'Stopped') {
            client.get('/api/v1/downloads/start');
        } else {
            client.get('/api/v1/downloads/stop');
        }
    };

    useEffect(() => {
        setTitle('Download Queue');

        setAction(() => {
            if (status === 'Stopped') {
                return (
                    <IconButton onClick={toggleQueueStatus} size="large">
                        <PlayArrowIcon />
                    </IconButton>
                );
            }
            return (
                <IconButton onClick={toggleQueueStatus} size="large">
                    <PauseIcon />
                </IconButton>
            );
        });
    }, [status]);

    useEffect(() => {
        const wsc = new WebSocket(`${baseWebsocketUrl}/api/v1/downloads`);
        wsc.onmessage = (e) => {
            setQueueState(JSON.parse(e.data));
        };

        setWsClient(wsc);
    }, []);

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const onDragEnd = (result: DropResult) => {
    };

    if (queue.length === 0) {
        return <EmptyView message="No downloads" />;
    }

    return (
        <>
            <DragDropContext onDragEnd={onDragEnd}>
                <Droppable droppableId="droppable">
                    {(provided) => (
                        <List ref={provided.innerRef}>
                            {queue.map((item, index) => (
                                <Draggable
                                    key={`${item.mangaId}-${item.chapterIndex}`}
                                    draggableId={`${item.mangaId}-${item.chapterIndex}`}
                                    index={index}
                                >
                                    {(provided, snapshot) => (
                                        <ListItem
                                            ContainerProps={{ ref: provided.innerRef } as any}
                                            sx={{
                                                display: 'flex',
                                                justifyContent: 'flex-start',
                                                alignItems: 'flex-start',
                                                padding: 2,
                                                margin: '10px',
                                                '&:hover': {
                                                    backgroundColor: 'action.hover',
                                                    transition: 'background-color 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
                                                },
                                                '&:active': {
                                                    backgroundColor: 'action.selected',
                                                    transition: 'background-color 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
                                                },
                                            }}
                                            onClick={() => history.push(`/manga/${item.chapter.mangaId}`)}
                                            {...provided.draggableProps}
                                            {...provided.dragHandleProps}
                                            style={getItemStyle(
                                                snapshot.isDragging,
                                                provided.draggableProps.style,
                                                theme.palette,
                                            )}
                                            ref={provided.innerRef}
                                        >
                                            <ListItemIcon sx={{ margin: 'auto 0' }}>
                                                <DragHandleIcon />
                                            </ListItemIcon>
                                            <Box sx={{ display: 'flex' }}>
                                                <Box sx={{ display: 'flex', flexDirection: 'column' }}>
                                                    <Typography variant="h5" component="h2">
                                                        {item.manga.title}
                                                    </Typography>
                                                    <Typography variant="caption" display="block" gutterBottom>
                                                        {`${item.chapter.name} `
                                                        + `(${(item.progress * 100).toFixed(2)}%)`
                                                        + ` => state: ${item.state}`}
                                                    </Typography>
                                                </Box>
                                            </Box>
                                            <IconButton
                                                sx={{ marginLeft: 'auto' }}
                                                onClick={(e) => {
                                                    // deleteCategory(index);
                                                    // prevent parent tags from getting the event
                                                    e.stopPropagation();
                                                }}
                                                size="large"
                                            >
                                                <DeleteIcon />
                                            </IconButton>
                                        </ListItem>
                                    )}
                                </Draggable>

                            ))}
                            {provided.placeholder}
                        </List>
                    )}
                </Droppable>
            </DragDropContext>
        </>
    );
}
Example #23
Source File: Profiler.tsx    From NekoMaid with MIT License 4 votes vote down vote up
Timings: React.FC = React.memo(() => {
  const plugin = usePlugin()
  const theme = useTheme()
  const { isTimingsV1 } = useGlobalData()
  const [status, setStatus] = useState(false)
  const [data, setData] = useState<TimingsData | null>(null)
  useEffect(() => {
    const off = plugin.emit('profiler:timingsStatus', setStatus).on('profiler:timings', setData)
    return () => { off() }
  }, [])

  const [tree, entitiesTick, tilesTick] = useMemo(() => {
    if (!data) return []
    const entitiesTickMap: Record<string, { value: number, name: string, count: number }> = {}
    const tilesTickMap: Record<string, { value: number, name: string, count: number }> = {}
    const map: Record<number, [number, number, number, [number, number, number][] | undefined] | undefined> = { }
    data.data.forEach(it => (map[it[0]] = it))
    const createNode = (id: number, percent: number) => {
      const cur = map[id]
      if (!cur) return
      map[id] = undefined
      const [, count, time] = cur
      const handler = data.handlers[id] || [0, lang.unknown]
      const handlerName = data.groups[handler[0]] || lang.unknown
      const name = handler[1]
      const children = cur[cur.length - 1]

      if (isTimingsV1) {
        if (name.startsWith('tickEntity - ')) {
          const came = name.slice(13).replace(/^Entity(Mob)?/, '')
          const entity = decamelize(came)
          const node = entitiesTickMap[entity]
          if (node) {
            node.count += count
            node.value += time
          } else entitiesTickMap[entity] = { count, value: time, name: minecraft['entity.minecraft.' + entity] || came }
        } else if (name.startsWith('tickTileEntity - ')) {
          const came = name.slice(17).replace(/^TileEntity(Mob)?/, '')
          const entity = decamelize(came)
          const node = tilesTickMap[entity]
          if (node) {
            node.count += count
            node.value += time
          } else tilesTickMap[entity] = { count, value: time, name: minecraft['block.minecraft.' + entity] || came }
        }
      } else {
        if (name.startsWith('tickEntity - ') && name.endsWith('ick')) {
          const res = ENTITY_TYPE.exec(name)
          if (res) {
            const node = entitiesTickMap[res[1]]
            if (node) {
              node.count += count
              node.value += time
            } else entitiesTickMap[res[1]] = { count, value: time, name: minecraft['entity.minecraft.' + res[1]] || res[1] }
          }
        } else if (name.startsWith('tickTileEntity - ')) {
          const arr = name.split('.')
          const came = arr[arr.length - 1].replace(/^TileEntity(Mob)?/, '')
          const tile = decamelize(came)
          const node = tilesTickMap[tile]
          if (node) {
            node.count += count
            node.value += time
          } else tilesTickMap[tile] = { count, value: time, name: minecraft['block.minecraft.' + tile] || came }
        }
      }

      return <TreeItem
        key={id}
        nodeId={id.toString()}
        label={<Box sx={{
          '& .info, .count': { color: 'transparent' },
          '&:hover .count': { color: 'inherit' },
          '&:hover .info': {
            color: theme.palette.primary.contrastText,
            textShadow: theme.palette.mode === 'light'
              ? '#000 1px 0 0, #000 0 1px 0, #000 -1px 0 0, #000 0 -1px 0'
              : '#fff 1px 0 0, #fff 0 1px 0, #fff -1px 0 0, #fff 0 -1px 0'
          }
        }}>
          <Box sx={{
            position: 'relative',
            zIndex: 2,
            display: 'flex',
            alignItems: 'center'
          }}>
            {handlerName !== 'Minecraft' && <><Typography color='primary' component='span'>
              {isTimingsV1 ? 'Bukkit' : lang.plugin + ':' + handlerName}</Typography>::</>}
            {name}&nbsp;
            <Typography variant='caption' className='count'>({lang.profiler.timingsCount}: {count})</Typography>
          </Box>
          <Box className='info' sx={{
            position: 'absolute',
            height: 10,
            right: 0,
            top: '50%',
            marginTop: '-5px',
            minWidth: 40,
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center'
          }}>
            <Typography variant='caption' sx={{ position: 'absolute' }}>({Math.round(100 * percent)}%)</Typography>
            <div style={{ width: 100 * percent + 'px' }} className='bar' />
          </Box>
        </Box>}
      >{Array.isArray(children) && children.sort((a, b) => b[2] - a[2]).map(it => createNode(it[0], percent * (it[2] / time)))}</TreeItem>
    }
    // eslint-disable-next-line react/jsx-key
    return [<TreeView defaultCollapseIcon={<ExpandMore />} defaultExpandIcon={<ChevronRight />} defaultExpanded={['1']}>
      {createNode(1, 1)}
    </TreeView>, Object.values(entitiesTickMap), Object.values(tilesTickMap)]
  }, [data])

  return <Container maxWidth={false} sx={{ py: 3 }}>
    <Grid container spacing={3}>
      <Grid item xs={12}>
        <Card>
          <CardHeader title='Timings' sx={{ position: 'relative' }} action={<FormControlLabel
            control={<Switch checked={status} onChange={e => plugin.emit('profiler:timingsStatus', setStatus, e.target.checked)} />}
            label={minecraft['addServer.resourcePack.enabled']}
            sx={cardActionStyles}
          />} />
          <Divider />
          {status
            ? <Box sx={{
              position: 'relative',
              minHeight: data ? undefined : 300,
              '& .bar': { backgroundColor: theme.palette.primary.main, height: 10, marginLeft: 'auto', borderRadius: 2 }
            }}>
              <CircularLoading loading={!data} />
              {tree}
            </Box>
            : <CardContent><Empty title={lang.profiler.timingsNotStarted} /></CardContent>}
        </Card>
      </Grid>
      {data && <Pie title={lang.profiler.entitiesTick} data={entitiesTick!} formatter={countFormatter} />}
      {data && <Pie title={lang.profiler.tilesTick} data={tilesTick!} formatter={countFormatter} />}
    </Grid>
  </Container>
})
Example #24
Source File: BidOverWriteComponent.tsx    From professor-prebid with Apache License 2.0 4 votes vote down vote up
BidOverWriteComponent = ({ prebid, debugConfigState, setDebugConfigState }: BidOverWriteComponentProps): JSX.Element => {
  const theme = useTheme();

  const [detectedBidderNames, setDetectedBidderNames] = useState<string[]>([]);
  const [detectedAdUnitCodes, setDetectedAdUnitCodes] = useState<string[]>([]);

  const [bidsOverwriteEnabled, setBidOverwriteEnabled] = useState<boolean>(false);
  const [cpm, setCpm] = React.useState(20.0);

  const [selectedBidders, setSelectedBidders] = React.useState<string[]>(debugConfigState?.bidders || []);
  const [selectedAdUnitCodes, setSelectedAdUnitCodes] = React.useState<string[]>(debugConfigState?.bids?.map((bid) => bid.adUnitCode) || []);

  const handleAdunitSelectionChange = (event: SelectChangeEvent<string[]>) => {
    const selectedAdUnitCodesArray = typeof event.target.value === 'string' ? event.target.value.split(',') : event.target.value;
    updateDebugConfig(selectedAdUnitCodesArray, selectedBidders, cpm);
  };

  const handleBidderSelectionChange = (event: SelectChangeEvent<string[]>) => {
    const selectedBiddersArray = typeof event.target.value === 'string' ? event.target.value.split(',') : event.target.value;
    updateDebugConfig(selectedAdUnitCodes, selectedBiddersArray, cpm);
  };

  const handleBidOverWriteEnabledChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setBidOverwriteEnabled(event.target.checked);
    if (!event.target.checked) {
      setDebugConfigState({ ...debugConfigState, bids: undefined });
    }
  };

  const handleCpmChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    updateDebugConfig(selectedAdUnitCodes, selectedBidders, Number(event.target.value));
  };

  const updateDebugConfig = (selectedAdUnitCodes: string[], selectedBidders: string[], cpm: number): void => {
    const bids: IPrebidDebugConfigBid[] = [];
    if (selectedAdUnitCodes.length === 0) {
      selectedBidders.forEach((bidder: string) => {
        bids.push({ bidder, cpm });
      });
    } else {
      selectedAdUnitCodes.forEach((adUnitCode: string) => {
        selectedBidders.forEach((bidder: string) => {
          bids.push({ adUnitCode, bidder, cpm });
        });
      });
    }
    if (bids.length > 0) {
      setDebugConfigState({ ...debugConfigState, bids });
    } else {
      setDebugConfigState({ ...debugConfigState, bids: undefined });
    }
  };

  useEffect(() => {
    if (!bidsOverwriteEnabled) {
      setBidOverwriteEnabled(!!Array.isArray(debugConfigState?.bids));
    }
    setCpm(debugConfigState?.bids?.length > 0 ? Number(debugConfigState?.bids[0].cpm) : 20.0);
    setSelectedBidders(debugConfigState?.bids?.map((item) => item.bidder).filter((v, i, a) => a.indexOf(v) === i) || []);
    setSelectedAdUnitCodes(
      debugConfigState?.bids
        ?.map((item) => item.adUnitCode)
        // .filter((i) => i)
        .filter((v, i, a) => v && a.indexOf(v) === i) || []
    );
  }, [bidsOverwriteEnabled, debugConfigState?.bids]);

  useEffect(() => {
    const events = prebid.events?.filter((event) => ['auctionInit', 'auctionEnd'].includes(event.eventType)) || [];
    const bidderNamesSet = events.reduce((previousValue, currentValue) => {
      const adUnitsArray = (currentValue as IPrebidAuctionEndEventData).args.adUnits || [];
      adUnitsArray.forEach((adUnit) => adUnit.bids.forEach((bid) => previousValue.add(bid.bidder)));
      return previousValue;
    }, new Set<string>());
    setDetectedBidderNames(Array.from(bidderNamesSet));

    const adUnitCodesSet = events.reduce((previousValue, currentValue) => {
      const adUnitsCodesArray = (currentValue as IPrebidAuctionEndEventData).args.adUnitCodes || [];
      adUnitsCodesArray.forEach((adUnitCode) => previousValue.add(adUnitCode));
      return previousValue;
    }, new Set<string>());
    setDetectedAdUnitCodes(Array.from(adUnitCodesSet));
  }, [prebid.events]);

  logger.log(`[PopUp][BidOverWriteComponent]: render `, detectedBidderNames, bidsOverwriteEnabled, cpm);

  return (
    <React.Fragment>
      <Grid item md={1} xs={1}>
        <Box sx={{ alignContent: 'center', [theme.breakpoints.down('sm')]: { transform: 'rotate(90deg)' } }}>
          <FormControl>
            <FormControlLabel label="" control={<Switch checked={bidsOverwriteEnabled} onChange={handleBidOverWriteEnabledChange} />} />
          </FormControl>
        </Box>
      </Grid>

      <Grid item md={2} xs={2}>
        <FormControl sx={{ height: 1 }}>
          <Box component="form" noValidate autoComplete="off" sx={{ height: 1 }}>
            <TextField
              sx={{ height: 1, '& div': { height: 1 } }}
              type="number"
              label="cpm"
              value={cpm}
              onChange={handleCpmChange}
              variant="outlined"
              disabled={!bidsOverwriteEnabled}
            />
          </Box>
        </FormControl>
      </Grid>
      <Grid item md={4.5} xs={4.5}>
        <FormControl sx={{ height: 1, width: 1, '& .MuiOutlinedInput-root': { height: 1, alignItems: 'baseline' } }}>
          <InputLabel>Select Bidder(s)</InputLabel>
          <Select
            multiple
            name="bidders"
            value={selectedBidders}
            onChange={handleBidderSelectionChange}
            input={<OutlinedInput label="Detected Bidders" />}
            renderValue={(selected) => (
              <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
                {selected.map((value, index) => (
                  <Chip key={index} label={value} />
                ))}
              </Box>
            )}
            MenuProps={MenuProps}
            disabled={!bidsOverwriteEnabled}
          >
            {detectedBidderNames.map((name, index) => (
              <MenuItem key={index} value={name} style={getStyles(name, selectedBidders, theme)}>
                {name}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
      </Grid>
      <Grid item md={4.5} xs={4.5}>
        <FormControl sx={{ height: 1, width: 1, '& .MuiOutlinedInput-root': { height: 1, alignItems: 'baseline' } }}>
          <InputLabel>Select AdUnitCode(s)</InputLabel>
          <Select
            multiple
            name="adUnitCodes"
            value={selectedAdUnitCodes}
            onChange={handleAdunitSelectionChange}
            input={<OutlinedInput label="Detected AdUnit(s)" />}
            renderValue={(selected) => (
              <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
                {selected.map((value, index) => (
                  <Chip key={index} label={value} />
                ))}
              </Box>
            )}
            MenuProps={MenuProps}
            disabled={!bidsOverwriteEnabled || selectedBidders.length === 0}
          >
            {detectedAdUnitCodes.map((name, index) => (
              <MenuItem key={index} value={name} style={getStyles(name, selectedAdUnitCodes, theme)}>
                {name}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
      </Grid>
    </React.Fragment>
  );
}
Example #25
Source File: TablePaginationActions.tsx    From ui-schema with MIT License 4 votes vote down vote up
TablePaginationActions: React.ComponentType<TablePaginationActionsProps> = (props) => {
    const theme = useTheme()
    const {
        count, page, rowsPerPage, onPageChange,
        backIconButtonProps: backIconButtonPropsTmp, nextIconButtonProps: nextIconButtonPropsTmp,
    } = props

    const btnSize = backIconButtonPropsTmp?.size
    // @ts-ignore
    const {noFirstPageButton, ...backIconButtonProps} = backIconButtonPropsTmp || {}
    // @ts-ignore
    const {noLastPageButton, ...nextIconButtonProps} = nextIconButtonPropsTmp || {}

    const handleFirstPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
        onPageChange(event, 0)
    }

    const handleBackButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
        onPageChange(event, page - 1)
    }

    const handleNextButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
        onPageChange(event, page + 1)
    }

    const handleLastPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
        onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1))
    }

    const iconStyle = {
        padding: btnSize === 'small' ? 2 : undefined,
    }

    return (
        <div style={{flexShrink: 0, marginLeft: theme.spacing(2.5)}}>
            {noFirstPageButton ? null :
                <IconButton
                    onClick={handleFirstPageButtonClick}
                    disabled={page === 0}
                    size={btnSize}
                >
                    <AccessTooltipIcon title={<Trans text={'pagination.first-page'}/>}>
                        {theme.direction === 'rtl' ? <LastPageIcon style={iconStyle}/> : <FirstPageIcon style={iconStyle}/>}
                    </AccessTooltipIcon>
                </IconButton>}
            <IconButton
                onClick={handleBackButtonClick} disabled={page === 0}
                size={btnSize}
                {...backIconButtonProps}
            >
                <AccessTooltipIcon title={<Trans text={'pagination.prev-page'}/>}>
                    {theme.direction === 'rtl' ? <KeyboardArrowRight style={iconStyle}/> : <KeyboardArrowLeft style={iconStyle}/>}
                </AccessTooltipIcon>
            </IconButton>
            <IconButton
                onClick={handleNextButtonClick}
                disabled={page >= Math.ceil(count / rowsPerPage) - 1}
                style={{
                    padding: btnSize === 'small' ? 2 : undefined,
                }}
                size={btnSize}
                {...nextIconButtonProps}
            >
                <AccessTooltipIcon title={<Trans text={'pagination.next-page'}/>}>
                    {theme.direction === 'rtl' ? <KeyboardArrowLeft style={iconStyle}/> : <KeyboardArrowRight style={iconStyle}/>}
                </AccessTooltipIcon>
            </IconButton>
            {noLastPageButton ? null :
                <IconButton
                    onClick={handleLastPageButtonClick}
                    disabled={page >= Math.ceil(count / rowsPerPage) - 1}
                    size={btnSize}
                    style={{
                        padding: btnSize === 'small' ? 2 : undefined,
                    }}
                >
                    <AccessTooltipIcon title={<Trans text={'pagination.last-page'}/>}>
                        {theme.direction === 'rtl' ? <FirstPageIcon style={iconStyle}/> : <LastPageIcon style={iconStyle}/>}
                    </AccessTooltipIcon>
                </IconButton>}
        </div>
    )
}
Example #26
Source File: ChapterCard.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 4 votes vote down vote up
export default function ChapterCard(props: IProps) {
    const theme = useTheme();

    const {
        chapter, triggerChaptersUpdate, downloadStatusString, showChapterNumber,
    } = props;

    const dateStr = chapter.uploadDate && new Date(chapter.uploadDate).toLocaleDateString();

    const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);

    const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
        // prevent parent tags from getting the event
        event.stopPropagation();
        event.preventDefault();

        setAnchorEl(event.currentTarget);
    };

    const handleClose = () => {
        setAnchorEl(null);
    };

    const sendChange = (key: string, value: any) => {
        handleClose();

        const formData = new FormData();
        formData.append(key, value);
        if (key === 'read') { formData.append('lastPageRead', '1'); }
        client.patch(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`, formData)
            .then(() => triggerChaptersUpdate());
    };

    const downloadChapter = () => {
        client.get(`/api/v1/download/${chapter.mangaId}/chapter/${chapter.index}`);
        handleClose();
    };

    const deleteChapter = () => {
        client.delete(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`)
            .then(() => triggerChaptersUpdate());

        handleClose();
    };

    const readChapterColor = theme.palette.mode === 'dark' ? '#acacac' : '#b0b0b0';

    return (
        <>
            <li>
                <Card
                    sx={{
                        margin: '10px',
                        ':hover': {
                            backgroundColor: 'action.hover',
                            transition: 'background-color 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
                            cursor: 'pointer',
                        },
                        ':active': {
                            backgroundColor: 'action.selected',
                            transition: 'background-color 100ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
                        },
                    }}
                >
                    <Link
                        to={`/manga/${chapter.mangaId}/chapter/${chapter.index}`}
                        style={{
                            textDecoration: 'none',
                            color: chapter.read ? readChapterColor : theme.palette.text.primary,
                        }}
                    >
                        <CardContent
                            sx={{
                                display: 'flex',
                                justifyContent: 'space-between',
                                alignItems: 'center',
                                padding: 2,
                            }}
                        >
                            <Box sx={{ display: 'flex' }}>
                                <div style={{ display: 'flex', flexDirection: 'column' }}>
                                    <Typography variant="h5" component="h2">
                                        <span style={{ color: theme.palette.primary.dark }}>
                                            {chapter.bookmarked && <BookmarkIcon />}
                                        </span>
                                        { showChapterNumber ? `Chapter ${chapter.chapterNumber}` : chapter.name}
                                    </Typography>
                                    <Typography variant="caption" display="block" gutterBottom>
                                        {chapter.scanlator}
                                        {chapter.scanlator && ' '}
                                        {dateStr}
                                        {downloadStatusString}
                                    </Typography>
                                </div>
                            </Box>

                            <IconButton aria-label="more" onClick={handleClick} size="large">
                                <MoreVertIcon />
                            </IconButton>
                        </CardContent>
                    </Link>
                    <Menu
                        anchorEl={anchorEl}
                        keepMounted
                        open={Boolean(anchorEl)}
                        onClose={handleClose}
                    >
                        {downloadStatusString.endsWith('Downloaded')
                             && <MenuItem onClick={deleteChapter}>Delete</MenuItem>}
                        {downloadStatusString.length === 0
                         && <MenuItem onClick={downloadChapter}>Download</MenuItem> }
                        <MenuItem onClick={() => sendChange('bookmarked', !chapter.bookmarked)}>
                            {chapter.bookmarked && 'Remove bookmark'}
                            {!chapter.bookmarked && 'Bookmark'}
                        </MenuItem>
                        <MenuItem onClick={() => sendChange('read', !chapter.read)}>
                            {`Mark as ${chapter.read ? 'unread' : 'read'}`}
                        </MenuItem>
                        <MenuItem onClick={() => sendChange('markPrevRead', true)}>
                            Mark previous as Read
                        </MenuItem>
                    </Menu>
                </Card>
            </li>
        </>
    );
}
Example #27
Source File: AircraftInfoOverlay.tsx    From react-flight-tracker with MIT License 4 votes vote down vote up
AircraftInfoOverlay: React.FC<Props> = (props) => {

  // External hooks
  const theme = useTheme();

  // States
  const [lastPositionPastSeconds, setLastPositionPastSeconds] = useState(0);

  // Refs
  const updateIntverlIDRef = useRef(0);
  const lastPositionPastSecondsRef = useRef(lastPositionPastSeconds);
  lastPositionPastSecondsRef.current = lastPositionPastSeconds;

  // Effects
  useEffect(() => {

    // Mount

    // Unmount
    return () => {

      clearInterval(updateIntverlIDRef.current);
    }
  }, []);
  useEffect(() => {

    if (!props.selectedAircraft || !props.selectedAircraft.stateVector) {

      clearInterval(updateIntverlIDRef.current);
      return;
    }

    clearInterval(updateIntverlIDRef.current);

    const lastPositionSeconds = props.selectedAircraft.stateVector.time_position ? props.selectedAircraft.stateVector.time_position : Math.floor(Date.now() / 1000);
    setLastPositionPastSeconds(Math.floor(Date.now() / 1000) - lastPositionSeconds);

    updateIntverlIDRef.current = window.setInterval(handleUpdate, 1000);

  }, [props.selectedAircraft?.stateVector]);

  const handleUpdate = () => {

    setLastPositionPastSeconds(lastPositionPastSecondsRef.current + 1);
  };

  const renderHeader = () => {

    if (!props.selectedAircraft)
      return undefined;

    if (!props.selectedAircraft.stateVector)
      return undefined;

    const stateVector = props.selectedAircraft.stateVector;

    // Get altitude
    var altitude = stateVector.geo_altitude;
    if ((altitude === null) || (altitude < 0))
      altitude = stateVector.baro_altitude;
    if ((altitude === null) || (altitude < 0))
      altitude = 0;

    // Get vertical rate
    const verticalRate = stateVector.vertical_rate ? stateVector.vertical_rate : 0;

    // Get true track
    const trueTrack = stateVector.true_track ? stateVector.true_track : 0.0;

    const FlightIcon = getIcon(stateVector.on_ground, verticalRate, altitude);

    return (

      <React.Fragment>

        <Box
          sx={{
            width: '100%',
            display: 'flex',
            flexDirection: 'row',
            alignItems: 'center',
            alignContent: 'center'
          }}>

          <Box
            sx={{
              backgroundColor: theme.palette.primary.main,
              borderRadius: '50%',
              width: 48,
              height: 48,
              display: 'flex',
              alignItems: 'center',
              alignContent: 'center',
              justifyItems: 'center',
              justifyContent: 'center',
              textAlign: 'center'
            }}>

            <FlightIcon
              css={(theme) => ({
                fill: theme.palette.primary.contrastText,
                width: 32,
                height: 32,
                transform: `rotate(${getRotation(trueTrack, verticalRate, altitude!)}deg)`
              })} />
          </Box>

          <Box
            sx={{
              flex: 'auto',
              marginLeft: 1,
              marginRight: 1,
              display: 'flex',
              flexDirection: 'column',
              alignItems: 'flex-start',
              alignContent: 'flex-start'
            }}>
            <Typography
              variant='h6'>
              {stateVector.callsign ? stateVector.callsign : '?'}
            </Typography>
            <Typography
              variant='body1'>
              {stateVector.origin_country}
            </Typography>
          </Box>

          <IconButton
            aria-label="close"
            onClick={() => {

              if (!props.selectedAircraft)
                return;

              if (!props.selectedAircraft.stateVector)
                return undefined;

              if (props.onRelease)
                props.onRelease(props.selectedAircraft.stateVector.icao24)
            }}>
            <CloseIcon color='error' />
          </IconButton>

        </Box>

        <Box
          sx={{
            width: '100%',
            height: 2,
            marginTop: 1,
            marginBottom: 2,
            backgroundColor: (theme) => theme.palette.primary.main
          }} />

      </React.Fragment>
    );
  };

  const renderFlightData = () => {

    if (!props.selectedAircraft)
      return undefined;

    if (!props.selectedAircraft.stateVector)
      return undefined;

    const stateVector = props.selectedAircraft.stateVector;

    var options: Intl.DateTimeFormatOptions = {
      year: 'numeric', month: 'numeric', day: 'numeric',
      hour: 'numeric', minute: 'numeric', second: 'numeric'
    };

    var lastPositionTime = '?';
    if (stateVector.time_position !== null) {

      var date = new Date(stateVector.time_position * 1000);
      lastPositionTime = new Intl.DateTimeFormat('de-CH', options).format(date)
    }

    var lastContactTime = '?';
    if (stateVector.last_contact !== null) {

      var lastContactDate = new Date(stateVector.last_contact * 1000);
      lastContactTime = new Intl.DateTimeFormat('de-CH', options).format(lastContactDate)
    }

    // Get altitude
    const barometricAltitude = stateVector.baro_altitude ? stateVector.baro_altitude : 0;
    const geometricAltitude = stateVector.geo_altitude ? stateVector.geo_altitude : 0;
    var altitude = stateVector.geo_altitude;
    if ((altitude === null) || (altitude < 0))
      altitude = stateVector.baro_altitude;
    if ((altitude === null) || (altitude < 0))
      altitude = 0;

    // Get velocity
    const velocity = stateVector.velocity ? stateVector.velocity : -1;

    // Get vertical rate
    const verticalRate = stateVector.vertical_rate ? stateVector.vertical_rate : 0.0;

    // Get true track
    const trueTrack = stateVector.true_track ? stateVector.true_track : 0.0;

    var textContainerStyle: SxProps<Theme> = {
      width: '100%',
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'flex-start',
      alignContent: 'flex-start'
    };

    var spaceStyle: SxProps<Theme> = {
      height: 8,
      minHeight: 8
    };

    return (

      <React.Fragment>

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Last contact'}
          </Typography>
          <Typography
            variant='body1'>
            {`${lastContactTime} [${lastPositionPastSeconds.toString()}s]`}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Last position update'}
          </Typography>
          <Typography
            variant='body1'>
            {`${lastPositionTime} [${lastPositionPastSeconds.toString()}s]`}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Barometric altitude'}
          </Typography>
          <Typography
            variant='body1'>
            {`${getFormattedValue(barometricAltitude, 1)} m [${getFormattedValue(barometricAltitude * 3.28084, 1)} ft.]`}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Geometric altitude'}
          </Typography>
          <Typography
            variant='body1'>
            {`${getFormattedValue(geometricAltitude, 1)} m [${getFormattedValue(geometricAltitude * 3.28084, 1)} ft.]`}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Velocity'}
          </Typography>
          <Typography
            variant='body1'>
            {`${getFormattedValue(velocity * 3.6, 1)} km/h [${getFormattedValue(velocity, 1)} m/s]`}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Longitude / Latitude'}
          </Typography>
          <Typography
            variant='body1'>
            {`${getFormattedValue(stateVector.longitude ? stateVector.longitude : -1, 3)} ° / ${getFormattedValue(stateVector.latitude ? stateVector.latitude : -1, 3)} °`}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Rotation'}
          </Typography>
          <Typography
            variant='body1'>
            {`${getFormattedValue(trueTrack, 1)} °`}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Vertical rate'}
          </Typography>
          <Typography
            variant='body1'>
            {`${getFormattedValue(verticalRate, 1)} m/s`}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Status'}
          </Typography>
          <Typography
            variant='body1'>
            {getStatusText(stateVector.on_ground, verticalRate, altitude)}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'ICAO24'}
          </Typography>
          <Typography
            variant='body1'>
            {stateVector.icao24}
          </Typography>
        </Box>

        <Box sx={spaceStyle} />

        <Box
          sx={textContainerStyle}>
          <Typography
            variant='body2'>
            {'Transpondercode [Squawk]'}
          </Typography>
          <Typography
            variant='body1'>
            {stateVector.squawk ? stateVector.squawk : -1}
          </Typography>
        </Box>

      </React.Fragment>
    );
  };

  if (!props.selectedAircraft)
    return (

      <Box
        sx={{
          position: 'relative',
          minWidth: 268,
          minHeight: 84,
          height: '100%',
          backgroundColor: theme.palette.background.paper,
          borderRadius: 2,
          boxShadow: 5,
          opacity: 0.9,
          display: 'flex',
          flexDirection: 'column',
          alignContent: 'center',
          alignItems: 'center',
          justifyContent: 'center',
          justifyItems: 'center'
        }}>

        <Indicator1
          color={theme.palette.primary.main} />
      </Box>
    );

  return (

    <Box
      sx={{
        position: 'relative',
        minWidth: 268,
        height: 'auto',
        width: 'auto',
        backgroundColor: theme.palette.background.paper,
        borderRadius: 2,
        boxShadow: 5,
        opacity: 0.9,
        padding: theme.spacing(1)
      }}>

      {renderHeader()}
      {renderFlightData()}
    </Box>
  );
}
Example #28
Source File: ModalBody.tsx    From mojito_pdm with Creative Commons Attribution Share Alike 4.0 International 4 votes vote down vote up
ModalBody: React.FC<Modal> = ({name, brand, description, price, trunkspace, setOpen, performance, spawncode}) => {
    const [modalStyle] = useState(getModalStyle)
    const theme = useTheme()
    const [pDialogueOpen, setpDialogueOpen] = useState(false) // Purchase Dialogue
    const [fDialogueOpen, setfDialogueOpen] = useState(false) // Finance Dialogue
    const {visible} = useVisibility()

    useEffect(() => {
        if (visible) return
        setOpen(false)
    }, [visible, setOpen])

    const handleClose = () => {
        setOpen(false)
    }
    const handlepDialogueClose = () => {
        setpDialogueOpen(false)
    }

    const handlefDialogueClose = () => {
        setfDialogueOpen(false)
    }

    const buyEnabled = useRecoilValue(GlobalState.canBuy)

    return (
        <>
            <div style={{
                ...modalStyle,
                position: "absolute",
                width: 600,
                backgroundColor: theme.palette.background.paper,
                boxShadow: theme.shadows[7],
                padding: theme.spacing(2, 4, 3),
                color: theme.palette.mode === "dark" ? "white" : "black"
            }}>
                <h2>{`${brand} ${name}`}</h2>
                <h4>
                    Price: {price} <br/>
                    Trunk Space: {trunkspace}
                </h4>
                {performance &&
                <Typography>
                    Power <LinearProgress value={performance.power} variant="determinate"/>
                    Acceleration <LinearProgress value={performance.acceleration} variant="determinate"/>
                    Handling <LinearProgress value={performance.handling} variant="determinate"/>
                    Top Speed <LinearProgress value={performance.topspeed} variant="determinate"/>
                </Typography>
                }
                <p>
                    {description}
                </p>
                <Stack direction="row" spacing={2}>
                    <Button size="small" variant="outlined" color="error" onClick={handleClose}>Close</Button>
                    { buyEnabled && <Button size="small" variant="outlined" color="primary" onClick={() => setpDialogueOpen(true)}> Buy </Button> }
                    { buyEnabled && <Button size="small" variant="outlined" color="primary" onClick={() => setfDialogueOpen(true)}> Finance </Button> }
                </Stack>
                <Dialog
                    open={pDialogueOpen}
                    TransitionComponent={Transition}
                    keepMounted
                    onClose={handlepDialogueClose}
                >
                    <PurchaseDialogueBody
                        spawncode={spawncode}
                        price={price}
                        setDialogueOpen={setpDialogueOpen}
                        setModalOpen={setOpen}
                    />
                </Dialog>
                <Dialog
                    open={fDialogueOpen}
                    TransitionComponent={Transition}
                    keepMounted
                    onClose={handlefDialogueClose}
                    fullWidth
                    maxWidth={"xs"}
                >
                    <FinanceDialogueBody
                        spawncode={spawncode}
                        price={price}
                        setDialogueOpen={setfDialogueOpen}
                        setModalOpen={setOpen}
                    />
                </Dialog>
            </div>
        </>
    )
}
Example #29
Source File: LicensePlans.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
LicensePlans = ({
  licenseInfo,
  setLicenseModal,
  operatorMode,
}: IRegisterStatus) => {
  const theme = useTheme();
  const isSmallScreen = useMediaQuery(theme.breakpoints.down("sm"));

  let currentPlan = !licenseInfo
    ? "community"
    : licenseInfo?.plan?.toLowerCase();

  const isCommunityPlan = currentPlan === LICENSE_PLANS.COMMUNITY;
  const isStandardPlan = currentPlan === LICENSE_PLANS.STANDARD;
  const isEnterprisePlan = currentPlan === LICENSE_PLANS.ENTERPRISE;

  const isPaidPlan = PAID_PLANS.includes(currentPlan);

  /*In smaller screen use tabbed view to show features*/
  const [xsPlanView, setXsPlanView] = useState("");
  let isXsViewCommunity = xsPlanView === LICENSE_PLANS.COMMUNITY;
  let isXsViewStandard = xsPlanView === LICENSE_PLANS.STANDARD;
  let isXsViewEnterprise = xsPlanView === LICENSE_PLANS.ENTERPRISE;

  const getCommunityPlanHeader = () => {
    return (
      <PlanHeader
        isActive={isCommunityPlan}
        isXsViewActive={isXsViewCommunity}
        title={"community"}
        onClick={isSmallScreen ? onPlanClick : null}
      >
        <Box className="title-block">
          <Box className="title-main">
            <div className="iconContainer">
              <ConsoleAgpl />
            </div>
          </Box>
        </Box>
      </PlanHeader>
    );
  };

  const getStandardPlanHeader = () => {
    return (
      <PlanHeader
        isActive={isStandardPlan}
        isXsViewActive={isXsViewStandard}
        title={"Standard"}
        onClick={isSmallScreen ? onPlanClick : null}
      >
        <Box className="title-block">
          <Box className="title-main">
            <div className="iconContainer">
              <ConsoleStandard />
            </div>
          </Box>
        </Box>
      </PlanHeader>
    );
  };

  const getEnterpriseHeader = () => {
    return (
      <PlanHeader
        isActive={isEnterprisePlan}
        isXsViewActive={isXsViewEnterprise}
        title={"Enterprise"}
        onClick={isSmallScreen ? onPlanClick : null}
      >
        <Box className="title-block">
          <Box className="title-main">
            <div className="iconContainer">
              <ConsoleEnterprise />
            </div>
          </Box>
        </Box>
      </PlanHeader>
    );
  };

  const getButton = (
    link: string,
    btnText: string,
    variant: any,
    plan: string
  ) => {
    let linkToNav =
      currentPlan !== "community" ? "https://subnet.min.io" : link;
    return (
      <Button
        variant={variant}
        color="primary"
        target="_blank"
        rel="noopener noreferrer"
        sx={{
          marginTop: "12px",
          width: "80%",
          "&.MuiButton-contained": {
            padding: 0,
            paddingLeft: "8px",
            paddingRight: "8px",
          },
        }}
        href={linkToNav}
        disabled={
          currentPlan !== LICENSE_PLANS.COMMUNITY && currentPlan !== plan
        }
        onClick={(e) => {
          e.preventDefault();

          window.open(
            `${linkToNav}?ref=${operatorMode ? "op" : "con"}`,
            "_blank"
          );
        }}
      >
        {btnText}
      </Button>
    );
  };

  const onPlanClick = (plan: string) => {
    setXsPlanView(plan);
  };

  useEffect(() => {
    if (isSmallScreen) {
      setXsPlanView(currentPlan || "community");
    } else {
      setXsPlanView("");
    }
  }, [isSmallScreen, currentPlan]);

  const linkTracker = `?ref=${operatorMode ? "op" : "con"}`;

  const featureList = FEATURE_ITEMS;
  return (
    <Fragment>
      <Box
        sx={{
          border: "1px solid #eaeaea",
          borderTop: "0px",
          marginBottom: "45px",
          "&::-webkit-scrollbar": {
            width: "5px",
            height: "5px",
          },
          "&::-webkit-scrollbar-track": {
            background: "#F0F0F0",
            borderRadius: 0,
            boxShadow: "inset 0px 0px 0px 0px #F0F0F0",
          },
          "&::-webkit-scrollbar-thumb": {
            background: "#777474",
            borderRadius: 0,
          },
          "&::-webkit-scrollbar-thumb:hover": {
            background: "#5A6375",
          },
        }}
      >
        <Box
          className={"title-blue-bar"}
          sx={{
            height: "8px",
            borderBottom: "8px solid rgb(6 48 83)",
          }}
        />
        <Box
          className={isPaidPlan ? "paid-plans-only" : ""}
          sx={{
            display: "grid",

            margin: "0 1.5rem 0 1.5rem",

            gridTemplateColumns: {
              sm: "1fr 1fr 1fr 1fr",
              xs: "1fr 1fr 1fr",
            },

            "&.paid-plans-only": {
              display: "grid",
              gridTemplateColumns: "1fr 1fr 1fr",
            },

            "& .features-col": {
              flex: 1,
              minWidth: "260px",

              "@media (max-width: 600px)": {
                display: "none",
              },
            },

            "& .xs-only": {
              display: "none",
            },

            "& .button-box": {
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              padding: "5px 0px 25px 0px",
              borderLeft: "1px solid #eaeaea",
            },
            "& .plan-header": {
              height: "99px",
              borderBottom: "1px solid #eaeaea",
            },
            "& .feature-title": {
              height: "25px",
              paddingLeft: "26px",
              fontSize: "14px",
              background: "#E5E5E5",

              "@media (max-width: 600px)": {
                "& .feature-title-info .xs-only": {
                  display: "block",
                },
              },
            },
            "& .feature-name": {
              minHeight: "60px",
              padding: "5px",
              borderBottom: "1px solid #eaeaea",
              display: "flex",
              alignItems: "center",
              paddingLeft: "26px",
              fontSize: "14px",
              fontWeight: 600,
            },
            "& .feature-item": {
              display: "flex",
              flexFlow: "column",
              alignItems: "center",
              justifyContent: "center",
              minHeight: "60px",
              padding: "0 15px 0 15px",
              borderBottom: "1px solid #eaeaea",
              borderLeft: " 1px solid #eaeaea",
              fontSize: "14px",
              "& .link-text": {
                color: "#2781B0",
              },

              "&.icon-yes": {
                width: "15px",
                height: "15px",
              },
            },

            "& .feature-item-info": {
              flex: 1,
              display: "flex",
              flexFlow: "column",
              alignItems: "center",
              justifyContent: "space-around",
              textAlign: "center",

              "@media (max-width: 600px)": {
                display: "flex",
                flexFlow: "row",
                alignItems: "center",
                justifyContent: "space-between",
                width: "100%",
                "& .xs-only": {
                  display: "block",
                  flex: 1,
                },
                "& .plan-feature": {
                  flex: 1,
                  textAlign: "center",
                  paddingRight: "10px",
                },
              },
            },

            "& .plan-col": {
              minWidth: "260px",
              flex: 1,
            },

            "& .active-plan-col": {
              background: "#FDFDFD 0% 0% no-repeat padding-box",
              boxShadow: " 0px 3px 20px #00000038",

              "& .plan-header": {
                backgroundColor: "#2781B0",
              },

              "& .feature-title": {
                background: "#F7F7F7",
              },
            },
          }}
        >
          <Box className="features-col">
            {featureList.map((fi) => {
              const featureTitleRow = fi.featureTitleRow;
              const isHeader = fi.isHeader;

              if (isHeader) {
                if (isPaidPlan) {
                  return (
                    <Box
                      key={fi.desc}
                      className="plan-header"
                      sx={{
                        fontSize: "14px",
                        paddingLeft: "26px",
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "flex-start",

                        "& .link-text": {
                          color: "#2781B0",
                        },

                        "& .min-icon": {
                          marginRight: "10px",
                          color: "#2781B0",
                          fill: "#2781B0",
                        },
                      }}
                    >
                      <LicenseDocIcon />
                      <a
                        href={`https://subnet.min.io/terms-and-conditions/${currentPlan}`}
                        rel="noreferrer noopener"
                        className={"link-text"}
                      >
                        View License agreement <br />
                        for the registered plan.
                      </a>
                    </Box>
                  );
                }

                return (
                  <Box
                    key={fi.desc}
                    className={`plan-header`}
                    sx={{
                      fontSize: "14px",
                      fontWeight: 600,
                      paddingLeft: "26px",
                      display: "flex",
                      alignItems: "center",
                      justifyContent: "flex-start",
                    }}
                  >
                    {fi.label}
                  </Box>
                );
              }
              if (featureTitleRow) {
                return (
                  <Box
                    key={fi.desc}
                    className="feature-title"
                    sx={{
                      fontSize: "14px",
                      fontWeight: 600,
                      textTransform: "uppercase",
                    }}
                  >
                    <div>{getRenderValue(fi.desc)} </div>
                  </Box>
                );
              }
              return (
                <Box key={fi.desc} className="feature-name" style={fi.style}>
                  <div>{getRenderValue(fi.desc)} </div>
                </Box>
              );
            })}
          </Box>
          {!isPaidPlan ? (
            <Box
              className={`plan-col ${
                isCommunityPlan ? "active-plan-col" : "non-active-plan-col"
              }`}
            >
              {COMMUNITY_PLAN_FEATURES.map((fi, idx) => {
                const featureLabel = featureList[idx].desc;
                const { featureTitleRow, isHeader, isOssLicenseLink } = fi;

                if (isHeader) {
                  return getCommunityPlanHeader();
                }
                if (featureTitleRow) {
                  return (
                    <FeatureTitleRowCmp
                      key={fi.id}
                      featureLabel={featureLabel}
                    />
                  );
                }

                if (isOssLicenseLink) {
                  return (
                    <Box
                      key={fi.id}
                      className="feature-item"
                      sx={{
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                      }}
                    >
                      <a
                        href={"https://www.gnu.org/licenses/agpl-3.0.en.html"}
                        rel="noreferrer noopener"
                        className={"link-text"}
                        onClick={(e) => {
                          e.preventDefault();
                          e.stopPropagation();
                          setLicenseModal && setLicenseModal(true);
                        }}
                      >
                        GNU AGPL v3
                      </a>
                    </Box>
                  );
                }
                return (
                  <PricingFeatureItem
                    key={fi.id}
                    featureLabel={featureLabel}
                    label={fi.label}
                    detail={fi.detail}
                    xsLabel={fi.xsLabel}
                    style={fi.style}
                  />
                );
              })}
              <Box className="button-box">
                {getButton(
                  `https://slack.min.io${linkTracker}`,
                  "Join Slack",
                  "outlined",
                  LICENSE_PLANS.COMMUNITY
                )}
              </Box>
            </Box>
          ) : null}
          <Box
            className={`plan-col ${
              isStandardPlan ? "active-plan-col" : "non-active-plan-col"
            }`}
          >
            {STANDARD_PLAN_FEATURES.map((fi, idx) => {
              const featureLabel = featureList[idx].desc;
              const featureTitleRow = fi.featureTitleRow;
              const isHeader = fi.isHeader;

              if (isHeader) {
                return getStandardPlanHeader();
              }
              if (featureTitleRow) {
                return (
                  <FeatureTitleRowCmp key={fi.id} featureLabel={featureLabel} />
                );
              }
              return (
                <PricingFeatureItem
                  key={fi.id}
                  featureLabel={featureLabel}
                  label={fi.label}
                  detail={fi.detail}
                  xsLabel={fi.xsLabel}
                  style={fi.style}
                />
              );
            })}

            <Box className="button-box">
              {getButton(
                `https://min.io/signup${linkTracker}`,
                !PAID_PLANS.includes(currentPlan)
                  ? "Subscribe"
                  : "Login to SUBNET",
                "contained",
                LICENSE_PLANS.STANDARD
              )}
            </Box>
          </Box>
          <Box
            className={`plan-col ${
              isEnterprisePlan ? "active-plan-col" : "non-active-plan-col"
            }`}
          >
            {ENTERPRISE_PLAN_FEATURES.map((fi, idx) => {
              const featureLabel = featureList[idx].desc;
              const { featureTitleRow, isHeader, yesIcon } = fi;

              if (isHeader) {
                return getEnterpriseHeader();
              }

              if (featureTitleRow) {
                return (
                  <FeatureTitleRowCmp key={fi.id} featureLabel={featureLabel} />
                );
              }

              if (yesIcon) {
                return (
                  <Box className="feature-item">
                    <Box className="feature-item-info">
                      <div className="xs-only"></div>
                      <Box className="plan-feature">
                        <CheckCircleIcon />
                      </Box>
                    </Box>
                  </Box>
                );
              }
              return (
                <PricingFeatureItem
                  key={fi.id}
                  featureLabel={featureLabel}
                  label={fi.label}
                  detail={fi.detail}
                  style={fi.style}
                />
              );
            })}
            <Box className="button-box">
              {getButton(
                `https://min.io/signup${linkTracker}`,
                !PAID_PLANS.includes(currentPlan)
                  ? "Subscribe"
                  : "Login to SUBNET",
                "contained",
                LICENSE_PLANS.ENTERPRISE
              )}
            </Box>
          </Box>
        </Box>
      </Box>
    </Fragment>
  );
}