@mui/material#Container TypeScript Examples

The following examples show how to use @mui/material#Container. 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: BlogEntryPreview.tsx    From firecms with MIT License 6 votes vote down vote up
function Text({ markdownText }: { markdownText: string }) {

    if (!markdownText)
        return <></>;

    return <Container maxWidth={"sm"}>
        <Box mt={6} mb={6}>
            <Markdown source={markdownText}/>
        </Box>
    </Container>;
}
Example #2
Source File: index.tsx    From ExpressLRS-Configurator with GNU General Public License v3.0 6 votes vote down vote up
MainLayout: FunctionComponent = (props) => {
  const { children } = props;
  return (
    <Box component="main" sx={styles.root}>
      <Sidebar />
      <Box sx={styles.content}>
        <Header />
        <Container sx={styles.main}>{children}</Container>
      </Box>
    </Box>
  );
}
Example #3
Source File: TemplateDetailPage.tsx    From fluttertemplates.dev with MIT License 6 votes vote down vote up
function TemplateDetailPage(params: TemplateCardProps) {
  return (
    <Container maxWidth="lg">
      <TemplatePageHead
        title={params.frontmatter.title}
        image={`https://fluttertemplates.dev/${params.frontmatter.image}`}
        id={params.id}
      />
      <RenderBody {...params} />
    </Container>
  );
}
Example #4
Source File: CommentList.tsx    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
function CommentList({postId}: ICommentList) {
  const [post] = usePostState({id: postId});
  const {data: commentStatData} = useCommentStatQuery({
    variables: {
      where: {postId},
    },
  });
  const {data: commentsData} = useCommentsQuery({
    variables: {
      where: {postId},
    },
  });

  const count = commentStatData?.commentStat?.count || 0;
  const comments = commentsData?.comments;

  return (
    <Container maxWidth="md">
      <Grid container direction="column" spacing={4}>
        <Grid item>
          <Typography>댓글 {count}개</Typography>
        </Grid>
        <Grid item>
          <CommentCreateFormModule post={post} />
        </Grid>
        {comments?.map(comment => {
          return (
            <Grid item>
              <CommentItemModule post={post} comment={comment} />
            </Grid>
          );
        })}
      </Grid>
    </Container>
  );
}
Example #5
Source File: ModalWrapper.tsx    From genshin-optimizer with MIT License 6 votes vote down vote up
ModalContainer = styled(Container)(({ theme }) => ({
  padding: 0,
  minHeight: "100%",
  display: "flex", flexDirection: "column", justifyContent: "center",
  pointerEvents: "none",
  "& > *": {
    pointerEvents: "auto"
  }
}))
Example #6
Source File: AppOverview.tsx    From mui-toolpad with MIT License 6 votes vote down vote up
export default function AppOverview({ dom }: AppOverviewProps) {
  const app = dom ? appDom.getApp(dom) : null;
  const { pages = [] } = dom && app ? appDom.getChildNodes(dom, app) : {};
  return (
    <Container>
      <Typography variant="h2">Pages</Typography>
      <Box
        sx={{
          my: 5,
          display: 'grid',
          gridTemplateColumns: {
            lg: 'repeat(4, 1fr)',
            md: 'repeat(3, 1fr)',
            sm: 'repeat(2, fr)',
            xs: 'repeat(1, fr)',
          },
          gap: 2,
        }}
      >
        {pages.map((page) => (
          <PageCard key={page.id} page={page} />
        ))}
      </Box>
    </Container>
  );
}
Example #7
Source File: Config.tsx    From NekoMaid with MIT License 6 votes vote down vote up
Config: React.FC = () => {
  return <Box sx={{ minHeight: '100%', py: 3 }}>
    <Toolbar />
    <Container maxWidth={false}>
      <Grid container spacing={3}>
        {configs.map((it, i) => <Grid key={i} item lg={4} md={12} xl={6} xs={12}>
          <Card>
            <CardHeader title={it.title} />
            <Divider />
            <it.component />
          </Card>
        </Grid>)}
      </Grid>
    </Container>
  </Box>
}
Example #8
Source File: AboutProjectPage.tsx    From frontend with MIT License 6 votes vote down vote up
export default function AboutProject() {
  const { t } = useTranslation()

  return (
    <Layout
      title={t('about-project:aboutPlatformTitle')}
      metaDescription={t('about-project:aboutPlatformDescription')}>
      <Container maxWidth="lg">
        <AboutPlatform />
        <WhatIsDone />
        <TechStack />
        <Timeline />
      </Container>
    </Layout>
  )
}
Example #9
Source File: app.tsx    From example with MIT License 6 votes vote down vote up
export function App() {
	return (
		<EnvironmentSelectorProvider>
			{(connector) => (
				<SdkConnectionProvider connector={connector}>
					<Box>
						<Header/>
						<Container maxWidth="xl" sx={{
							mt: 2,
							display: 'grid',
							gridTemplateColumns: 'minmax(250px, 20%)  1fr',
							gap: "20px"
						}}>
							<Box component="nav">
								<Navigation/>
							</Box>
							<Box component="main">
								<Routes>
									<Route path="/" element={<AboutPage/>}/>
									<Route path="about" element={<AboutPage/>}/>
									<Route path="connect" element={<ConnectPage/>}/>
									<Route path="deploy" element={<DeployPage/>}/>
									<Route path="mint" element={<MintPage/>}/>
									<Route path="sell" element={<SellPage/>}/>
									<Route path="buy" element={<BuyPage/>}/>
									<Route path="bid" element={<BidPage/>}/>
									<Route path="accept-bid" element={<AcceptBidPage/>}/>
									<Route path="*" element={<NotFoundPage/>}/>
								</Routes>
							</Box>
						</Container>
					</Box>
				</SdkConnectionProvider>
			)}
		</EnvironmentSelectorProvider>
	);
}
Example #10
Source File: index.tsx    From yearn-watch-legacy with GNU Affero General Public License v3.0 6 votes vote down vote up
Home = () => {
    const { network = DEFAULT_NETWORK } = useParams() as ParamTypes;
    const { vaults, loading, moreToLoad, error } = useAllVaults(network);

    return (
        <Container maxWidth="lg">
            <div style={{ marginTop: 20 }}>
                {error && (
                    <ErrorAlert
                        message={'Error while loading vaults:'}
                        details={error}
                    />
                )}
                {loading && (
                    <span>
                        <ProgressSpinnerBar label="vaults" />
                        <GlobalStylesLoading />
                    </span>
                )}
                {!loading && !error && (
                    <VaultsList
                        items={vaults}
                        moreToLoad={moreToLoad}
                        network={network}
                    />
                )}
            </div>
        </Container>
    );
}
Example #11
Source File: BlogEntryPreview.tsx    From firecms with MIT License 5 votes vote down vote up
/**
 * This is a sample view used to render the content of a blog entry.
 * It is bound to the data that is modified in the form.
 * @constructor
 */
export function BlogEntryPreview({ modifiedValues }: EntityCustomViewParams) {

    const storage = useStorageSource();

    const [headerUrl, setHeaderUrl] = useState<string | undefined>();
    useEffect(() => {
        if (modifiedValues?.header_image) {
            storage.getDownloadURL(modifiedValues.header_image)
                .then((res) => setHeaderUrl(res));
        }
    }, [storage, modifiedValues?.header_image]);

    return (
        <Box>

            {headerUrl && <img
                alt={"Header"}
                style={{
                    width: "100%",
                    maxHeight: "300px",
                    objectFit: "cover"
                }}
                src={headerUrl}
            />}

            <Container maxWidth={"md"} style={{
                alignItems: "center",
                justifyItems: "center",
                display: "flex",
                flexDirection: "column"
            }}>
                {modifiedValues?.name && <Typography variant={"h2"} style={{
                    marginTop: "40px",
                    marginBottom: "20px"
                }}>
                    {modifiedValues.name}
                </Typography>}

                {modifiedValues?.content && modifiedValues.content
                    .filter((e: any) => !!e)
                    .map(
                        (entry: any, index: number) => {
                            if (entry.type === "text")
                                return <Text key={`preview_text_${index}`}
                                             markdownText={entry.value}/>;
                            if (entry.type === "images")
                                return <Images key={`preview_images_${index}`}
                                               storagePaths={entry.value}/>;
                            if (entry.type === "products")
                                return <ProductGroupPreview
                                    key={`preview_products_${index}`}
                                    references={entry.value}/>;
                            return <ErrorView
                                error={"Unexpected value in blog entry"}/>
                        }
                    )}

            </Container>

        </Box>
    );

}
Example #12
Source File: GenerateCodePage.tsx    From GTAV-NativeDB with MIT License 5 votes vote down vote up
function GenerateCodePage() {
  const { language } = useParams<{ language: string }>()
  const history = useHistory()

  const onTabChange = useCallback((e: SyntheticEvent<Element, Event>, language: string) => {
    history.replace(language)
  }, [history])

  return (
    <Box sx={{ py: 2, overflow: 'hidden scroll', flexGrow: 1 }}>
      <Container maxWidth="lg">
        <Typography variant="h4" component="h1" gutterBottom>
          Generate Code
        </Typography>
        <Paper>
          <TabContext value={language}>
            <TabList onChange={onTabChange}>
              <Tab label="C++" value="cpp" />
              <Tab label="Rust" value="rs" />
              <Tab label="C# Enum" value="cs" />
              <Tab label="SHV.NET" value="shvdn" />
              <Tab label="RPH" value="rph" />
            </TabList>
            <Divider />
            <TabPanel value="cpp">
              <CPlusPlus />
            </TabPanel>
            <TabPanel value="rs">
              <Rust />
            </TabPanel>
            <TabPanel value="cs">
              <CSharpEnum />
            </TabPanel>
            <TabPanel value="shvdn">
              Soon&trade;
            </TabPanel>
            <TabPanel value="rph">
              Soon&trade;
            </TabPanel>
          </TabContext>
        </Paper>
      </Container>
    </Box>
  )
}
Example #13
Source File: Style.tsx    From multi-downloader-nx with MIT License 5 votes vote down vote up
Style: React.FC = ({children}) => {
  return <ThemeProvider theme={makeTheme('dark')}>
    <Container sx={{ mt: 3 }} maxWidth='xl'>
      <Box sx={{ position: 'fixed', height: '100%', width: '100%', zIndex: -500, backgroundColor: 'rgb(0, 30, 60)', top: 0, left: 0 }}/>
      {children}
    </Container>
  </ThemeProvider>;
}
Example #14
Source File: index.tsx    From fluttertemplates.dev with MIT License 5 votes vote down vote up
export default function TemplatesList({
  templates,
}: {
  templates: TemplateCardProps[];
}) {
  const router = useRouter();
  const [category, setCategory] = React.useState<string | undefined>();

  const { catId } = router.query;

  React.useEffect(() => {
    function getCat() {
      setTimeout(() => {
        const _cat = (router.query.catId ?? "all").toString();
        setCategory(_cat);
      }, 1000);
    }
    getCat();
  }, [router.query]);

  return (
    <Container maxWidth="lg">
      <HomePageHead />
      {!category && (
        <Grid
          container
          direction="column"
          justifyContent="center"
          alignItems="center"
          style={{
            minHeight: "40vh",
          }}
        >
          <Grid item>
            <CircularProgress size="1.5rem" thickness={8} color="secondary" />
          </Grid>
        </Grid>
      )}
      {category && (
        <TemplatesGrid
          templates={templates}
          limit={false}
          selectedCatId={catId as string}
        />
      )}
    </Container>
  );
}
Example #15
Source File: App.tsx    From genshin-optimizer with MIT License 5 votes vote down vote up
function App() {
  const [database, setDatabase] = useState(() => new ArtCharDatabase(new DBLocalStorage(localStorage)))
  const dbContextObj = useMemo(() => ({ database, setDatabase }), [database, setDatabase])
  return <React.StrictMode>
    {/* https://mui.com/guides/interoperability/#css-injection-order-2 */}
    <StyledEngineProvider injectFirst>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <DatabaseContext.Provider value={dbContextObj}>
          <HashRouter basename="/">
            <MatchTitle />
            <Grid container direction="column" minHeight="100vh">
              <Grid item >
                <Header anchor="back-to-top-anchor" />
              </Grid>
              <Container maxWidth="xl" sx={{ px: { xs: 0.5, sm: 1, md: 2 } }}>
                <Suspense fallback={<Skeleton variant="rectangular" sx={{ width: "100%", height: "100%" }} />}>
                  <Routes>
                    <Route index element={<PageHome />} />
                    <Route path="/artifacts" element={<PageArtifact />} />
                    <Route path="/weapons" element={<PageWeapon />} />
                    <Route path="/characters/*"  >
                      <Route index element={<PageCharacter />} />
                      <Route path=":characterKey/*" element={<CharacterDisplay />} />
                    </Route>
                    <Route path="/tools" element={<PageTools />} />
                    <Route path="/setting" element={<PageSettings />} />
                    <Route path="/doc/*" element={<PageDocumentation />} />
                    <Route path="/scanner" element={<PageScanner />} />
                  </Routes>
                </Suspense>
              </Container>
              {/* make sure footer is always at bottom */}
              <Grid item flexGrow={1} />
              <Grid item >
                <Footer />
              </Grid>
            </Grid>
            <ScrollTop >
              <Fab color="secondary" size="small" aria-label="scroll back to top">
                <KeyboardArrowUp />
              </Fab>
            </ScrollTop>
          </HashRouter>
        </DatabaseContext.Provider>
      </ThemeProvider>
    </StyledEngineProvider>
  </React.StrictMode>
}
Example #16
Source File: TLSCertificate.tsx    From console with GNU Affero General Public License v3.0 5 votes vote down vote up
TLSCertificate = ({
  classes,
  certificateInfo,
  onDelete = () => {},
}: ITLSCertificate) => {
  const certificates = certificateInfo.domains || [];
  return (
    <Chip
      key={certificateInfo.name}
      variant="outlined"
      color="primary"
      className={classes.certificateWrapper}
      label={
        <Container>
          <Grid item xs={1} className={classes.certificateIcon}>
            <CertificateIcon />
          </Grid>
          <Grid item xs={11} className={classes.certificateInfo}>
            <Typography variant="subtitle1" display="block" gutterBottom>
              {certificateInfo.name}
            </Typography>
            <Box className={classes.certificateExpiry}>
              <EventBusyIcon color="inherit" fontSize="small" />
              &nbsp;
              <span className={"label"}>Expiry:&nbsp;</span>
              <span>
                <Moment format="YYYY/MM/DD">{certificateInfo.expiry}</Moment>
              </span>
            </Box>
            <Divider />
            <br />
            <Box className={classes.certificateDomains}>
              <span className="label">{`${certificates.length} Domain (s):`}</span>
            </Box>
            <List className={classes.certificatesList}>
              {certificates.map((dom) => (
                <ListItem className={classes.certificatesListItem}>
                  <ListItemAvatar>
                    <LanguageIcon />
                  </ListItemAvatar>
                  <ListItemText primary={dom} />
                </ListItem>
              ))}
            </List>
          </Grid>
        </Container>
      }
      onDelete={onDelete}
    />
  );
}
Example #17
Source File: Home.tsx    From mui-toolpad with MIT License 5 votes vote down vote up
export default function Home() {
  const { data: apps = [], status, error } = client.useQuery('getApps', []);

  const [createDialogOpen, setCreateDialogOpen] = React.useState(false);

  const [deletedApp, setDeletedApp] = React.useState<null | App>(null);

  return (
    <ToolpadShell>
      <AppDeleteDialog app={deletedApp} onClose={() => setDeletedApp(null)} />
      <Container>
        <Typography variant="h2">Apps</Typography>
        <CreateAppDialog open={createDialogOpen} onClose={() => setCreateDialogOpen(false)} />

        <Toolbar disableGutters>
          <Button onClick={() => setCreateDialogOpen(true)}>Create New</Button>
        </Toolbar>

        <Box
          sx={{
            display: 'grid',
            gridTemplateColumns: {
              lg: 'repeat(4, 1fr)',
              md: 'repeat(3, 1fr)',
              sm: 'repeat(2, fr)',
              xs: 'repeat(1, fr)',
            },
            gap: 2,
          }}
        >
          {(() => {
            switch (status) {
              case 'loading':
                return <AppCard />;
              case 'error':
                return <Alert severity="error">{(error as Error)?.message}</Alert>;
              case 'success':
                return apps.length > 0
                  ? apps.map((app) => (
                      <AppCard key={app.id} app={app} onDelete={() => setDeletedApp(app)} />
                    ))
                  : 'No apps yet';
              default:
                return '';
            }
          })()}
        </Box>
      </Container>
    </ToolpadShell>
  );
}
Example #18
Source File: OpenInv.tsx    From NekoMaid with MIT License 5 votes vote down vote up
OpenInv: React.FC = () => {
  const plugin = usePlugin()
  const [inv, setInv] = useState<Array<Item | null>>([])
  const [ender, setEnder] = useState<Array<Item | null>>([])
  const { name: player } = useParams<{ name: string }>()
  useEffect(() => {
    if (player) plugin.emit('openInv:fetchInv', setInv, player).emit('openInv:fetchEnderChest', setEnder, player)
  }, [player])

  const mapToInv = (inv: Array<Item | null>, type: InvType) => {
    const update = (res: boolean) => {
      if (!res) failed()
      if (type === InvType.PLAYER) plugin.emit('openInv:fetchInv', setInv, player)
      else plugin.emit('openInv:fetchEnderChest', setEnder, player)
    }
    const updateWithAction = (res: boolean) => {
      action(res)
      if (type === InvType.PLAYER) plugin.emit('openInv:fetchInv', setInv, player)
      else plugin.emit('openInv:fetchEnderChest', setEnder, player)
    }
    return player
      ? inv.map((it, i) => <React.Fragment key={i}><ItemViewer
        item={it}
        data={{ type, solt: i, player }}
        onDrag={() => plugin.emit('openInv:set', update, type, player, i, null, -1)}
        onDrop={(item, obj) => plugin.emit('openInv:set', update, type,
          player, i, JSON.stringify(item), obj?.type === type && obj?.player === player ? obj.solt : -1)}
        onEdit={item => item !== false && plugin.emit('openInv:set', updateWithAction, type, player, i, item && JSON.stringify(item), -1)}
      />{!((i + 1) % 9) && <br />}</React.Fragment>)
      : <Empty title={lang.openInv.notSelected} />
  }

  return <Box sx={{ minHeight: '100%', py: 3 }}>
    <Toolbar />
    <Container maxWidth={false}>
      <Grid container spacing={3}>
        <Grid item lg={6} md={12} xl={6} xs={12}>
          <Card>
            <CardHeader
              title={lang.openInv.whosBackpack(player || minecraft['entity.minecraft.player'])}
              sx={{ position: 'relative' }}
              action={<IconButton
                size='small'
                disabled={!player}
                sx={cardActionStyles}
                onClick={() => {
                  success()
                  plugin.emit('openInv:fetchInv', setInv, player)
                }}
              ><Refresh /></IconButton>}
            />
            <Divider />
            <CardContent sx={{ whiteSpace: 'nowrap', overflowX: 'auto' }}>{mapToInv(inv, InvType.PLAYER)}</CardContent>
          </Card>
        </Grid>
        <Grid item lg={6} md={12} xl={6} xs={12}>
          <Card>
            <CardHeader
              title={lang.openInv.whosEnderChest(player || minecraft['entity.minecraft.player'])}
              sx={{ position: 'relative' }}
              action={<IconButton
                size='small'
                disabled={!player}
                sx={cardActionStyles}
                onClick={() => {
                  success()
                  plugin.emit('openInv:fetchEnderChest', setEnder, player)
                }}
              ><Refresh /></IconButton>}
            />
            <Divider />
            <CardContent sx={{ whiteSpace: 'nowrap', overflowX: 'auto' }}>{mapToInv(ender, InvType.ENDER_CHEST)}</CardContent>
          </Card>
        </Grid>
      </Grid>
    </Container>
  </Box>
}
Example #19
Source File: TeamMembersSection.tsx    From frontend with MIT License 5 votes vote down vote up
export default function TeamMembersSection() {
  const { t } = useTranslation()
  const navigationPrevRef = React.useRef(null)
  const navigationNextRef = React.useRef(null)

  return (
    <Container maxWidth="lg">
      <Heading
        textAlign="center"
        variant="h4"
        component="h2"
        fontFamily="Montserrat"
        color={theme.palette.primary.dark}
        paddingTop={theme.spacing(10)}
        paddingBottom={theme.spacing(7)}>
        {t('index:team-section.heading')}
      </Heading>
      <Typography textAlign="center" fontFamily="Montserrat" fontSize={16}>
        {t('index:team-section.content')}
      </Typography>
      <Grid
        container
        justifyContent="center"
        paddingTop={theme.spacing(7)}
        paddingBottom={theme.spacing(12)}>
        <Grid item xs={12} display="flex" alignItems="center" position="relative">
          <IconButton style={{ order: 1 }} ref={navigationPrevRef} aria-label="Previouos slide">
            <ChevronLeftIcon />
          </IconButton>
          <IconButton style={{ order: 3 }} ref={navigationNextRef} aria-label="Next slide">
            <ChevronRightIcon />
          </IconButton>
          <Swiper
            {...swiperOptions}
            style={{ marginLeft: theme.spacing(2), marginRight: theme.spacing(2), order: 2 }}
            navigation={{
              prevEl: navigationPrevRef.current,
              nextEl: navigationNextRef.current,
            }}
            onBeforeInit={(swiper) => {
              if (!swiper.params.navigation || swiper.params.navigation === true) {
                return
              }
              swiper.params.navigation.prevEl = navigationPrevRef.current
              swiper.params.navigation.nextEl = navigationNextRef.current
            }}>
            {data.map((member) => (
              <SwiperSlide key={member.title}>
                <MemberCard info={member} />
              </SwiperSlide>
            ))}
          </Swiper>
        </Grid>
        <Grid item xs={12} textAlign="center">
          <LinkButton
            href={staticUrls.blog}
            variant="outlined"
            endIcon={<ChevronRightIcon />}
            sx={{ marginTop: theme.spacing(8) }}>
            {t('index:team-section.meet-our-team')}
          </LinkButton>
        </Grid>
      </Grid>
    </Container>
  )
}
Example #20
Source File: app.tsx    From sdk with MIT License 5 votes vote down vote up
export function App() {
	return (
		<EnvironmentSelectorProvider>
			{(connector) => (
				<SdkConnectionProvider connector={connector}>
					<Box>
						<Header/>
						<Container maxWidth="xl" sx={{
							mt: 2,
							display: 'grid',
							gridTemplateColumns: 'minmax(250px, 20%)  1fr',
							gap: "20px"
						}}>
							<Box component="nav">
								<Navigation/>
							</Box>
							<Box component="main">
								<Routes>
									<Route path="/" element={<AboutPage/>}/>
									<Route path="about" element={<AboutPage/>}/>
									<Route path="connect" element={<ConnectPage/>}/>
									<Route path="deploy" element={<DeployPage/>}/>
									<Route path="mint" element={<MintPage/>}/>
									<Route path="sell" element={<SellPage/>}>
										<Route path=":itemId" element={<SellPage/>}/>
									</Route>
									<Route path="buy" element={<BuyPage/>}>
										<Route path=":orderId" element={<BuyPage/>}/>
									</Route>
									<Route path="bid" element={<BidPage/>}>
										<Route path=":itemId" element={<BidPage/>}/>
									</Route>
									<Route path="accept-bid" element={<AcceptBidPage/>}>
										<Route path=":orderId" element={<AcceptBidPage/>}/>
									</Route>
									<Route path="items" element={<ItemsPage/>}/>
									<Route path="*" element={<NotFoundPage/>}/>
								</Routes>
							</Box>
						</Container>
					</Box>
				</SdkConnectionProvider>
			)}
		</EnvironmentSelectorProvider>
	);
}
Example #21
Source File: index.tsx    From yearn-watch-legacy with GNU Affero General Public License v3.0 5 votes vote down vote up
HealthCheckReport = () => {
    const paramTypes = useParams() as ParamTypes;
    const { network = DEFAULT_NETWORK } = paramTypes;
    const {
        data: strategies,
        loading,
        moreToLoad,
        error,
    } = useHealthcheckStrategies(network);
    const classes = useStyles();

    return (
        <Container maxWidth="lg">
            <div style={{ marginTop: 20 }}>
                {error && (
                    <ErrorAlert
                        message={'Error while loading vaults:'}
                        details={error}
                    />
                )}
                {loading && (
                    <span>
                        <ProgressSpinnerBar />
                        <GlobalStylesLoading />
                    </span>
                )}
                {!loading && !error && (
                    <div className={classes.root}>
                        {moreToLoad && (
                            <ProgressSpinnerBar label="all strategies..." />
                        )}
                        <GenericList
                            headCells={headCells}
                            items={strategies}
                            title={'Strategies with HealthCheck issue'}
                            defaultOrder="desc"
                            defaultOrderBy="estimatedTotalAssetsUsdcNumber"
                            defaultRowsPerPage={20}
                        />
                    </div>
                )}
            </div>
        </Container>
    );
}
Example #22
Source File: FireCMSHomePage.tsx    From firecms with MIT License 4 votes vote down vote up
/**
 * Default entry view for the CMS under the path "/"
 * This components takes navigation as an input and renders cards
 * for each entry, including title and description.
 * @constructor
 * @category Components
 */
export function FireCMSHomePage() {

    const classes = useStyles();
    const navigationContext = useNavigation();
    if (!navigationContext.navigation)
        return <></>;

    const {
        navigationEntries,
        groups
    } = computeTopNavigation(navigationContext, false);

    const allGroups: Array<string | null> = [...groups];
    if (navigationEntries.filter(e => !e.group).length > 0) {
        allGroups.push(null);
    }

    function buildNavigationCard(entry: TopNavigationEntry) {
        return (
            <Grid item xs={12}
                  sm={6}
                  md={4}
                  key={`nav_${entry.group}_${entry.name}`}>
                <Paper variant={"outlined"}>

                    <CardActionArea
                        className={classes.card}
                        component={ReactLink}
                        to={entry.url}>
                        <CardContent
                            className={classes.flexGrow}>

                            <PlaylistPlayIcon color={"disabled"}/>
                            <Typography gutterBottom variant="h5"
                                        component="h2">
                                {entry.name}
                            </Typography>

                            {entry.description && <Typography variant="body2"
                                                              color="textSecondary"
                                                              component="div">
                                <Markdown source={entry.description}/>
                            </Typography>}
                        </CardContent>

                        <CardActions style={{ alignSelf: "flex-end" }}>
                            <Box p={1}>
                                <ArrowForwardIcon color="primary"/>
                            </Box>
                        </CardActions>

                    </CardActionArea>
                </Paper>
            </Grid>
        );
    }

    return (
        <Container>
            {allGroups.map((group, index) => (
                <Box mt={6} mb={6} key={`group_${index}`}>
                    {allGroups.length > 0 && <>
                        <Typography color={"textSecondary"}
                                    className={"weight-500"}>
                            {group?.toUpperCase() ?? "Collections".toUpperCase()}
                        </Typography>
                        <Divider/>
                    </>}

                    <Box mt={2}>
                        <Grid container spacing={2}>
                            {group && navigationEntries
                                .filter((entry) => entry.group === group)
                                .map((entry) => buildNavigationCard(entry))
                            }
                            {!group && navigationEntries
                                .filter((entry) => !entry.group)
                                .map((entry) => buildNavigationCard(entry))
                            }
                        </Grid>
                    </Box>
                </Box>
            ))}
        </Container>
    );
}
Example #23
Source File: Layout.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function Layout({ group = null, children, ...props }) {
    const authenticated = useRecoilValue(isAuthenticated);
    const [anchorEl, setAnchorEl] = useState(null);
    const theme: Theme = useTheme();
    const dotsMenuOpen = Boolean(anchorEl);
    const cfg = useRecoilValue(config);
    const location = useLocation();

    const [mobileOpen, setMobileOpen] = useState(true);

    const { window } = props;

    const handleProfileMenuOpen = (event) => {
        setAnchorEl(event.currentTarget);
    };

    const handleDotsMenuClose = (event) => {
        setAnchorEl(null);
    };

    const handleDrawerToggle = () => {
        setMobileOpen(!mobileOpen);
    };

    const drawer = (
        <div style={{ height: "100%" }}>
            <Toolbar />
            <Divider />
            {group != null && (
                <List sx={{ pb: 0 }}>
                    <ListItemLink
                        to={`/groups/${group.id}/`}
                        selected={
                            location.pathname === `/groups/${group.id}/` || location.pathname === `/groups/${group.id}`
                        }
                    >
                        <ListItemIcon>
                            <Paid />
                        </ListItemIcon>
                        <ListItemText primary="Transactions" />
                    </ListItemLink>
                    <ListItemLink
                        to={`/groups/${group.id}/balances`}
                        selected={location.pathname.startsWith(`/groups/${group.id}/balances`)}
                    >
                        <ListItemIcon>
                            <BarChart />
                        </ListItemIcon>
                        <ListItemText primary="Balances" />
                    </ListItemLink>
                    <ListItemLink
                        to={`/groups/${group.id}/accounts`}
                        selected={location.pathname.startsWith(`/groups/${group.id}/accounts`)}
                    >
                        <ListItemIcon>
                            <AccountBalance />
                        </ListItemIcon>
                        <ListItemText primary="Accounts" />
                    </ListItemLink>
                    <ListItemLink
                        to={`/groups/${group.id}/detail`}
                        selected={location.pathname.startsWith(`/groups/${group.id}/detail`)}
                    >
                        <ListItemIcon>
                            <AdminPanelSettings />
                        </ListItemIcon>
                        <ListItemText primary="Group Settings" />
                    </ListItemLink>
                    <ListItemLink
                        to={`/groups/${group.id}/members`}
                        selected={location.pathname.startsWith(`/groups/${group.id}/members`)}
                    >
                        <ListItemIcon>
                            <People />
                        </ListItemIcon>
                        <ListItemText primary="Group Members" />
                    </ListItemLink>
                    <ListItemLink
                        to={`/groups/${group.id}/invites`}
                        selected={location.pathname.startsWith(`/groups/${group.id}/invites`)}
                    >
                        <ListItemIcon>
                            <Mail />
                        </ListItemIcon>
                        <ListItemText primary="Group Invites" />
                    </ListItemLink>
                    <ListItemLink
                        to={`/groups/${group.id}/log`}
                        selected={location.pathname.startsWith(`/groups/${group.id}/log`)}
                    >
                        <ListItemIcon>
                            <Message />
                        </ListItemIcon>
                        <ListItemText primary="Group Log" />
                    </ListItemLink>
                    <Divider />
                </List>
            )}
            <SidebarGroupList group={group} />

            <Box
                sx={{
                    display: "flex",
                    position: "absolute",
                    width: "100%",
                    justifyContent: "center",
                    bottom: 0,
                    padding: 1,
                    borderTop: 1,
                    borderColor: theme.palette.divider,
                }}
            >
                {cfg.imprintURL && (
                    <Link href={cfg.imprintURL} target="_blank" sx={{ mr: 2 }}>
                        imprint
                    </Link>
                )}
                <Tooltip title="Source Code">
                    <Link sx={{ ml: 1 }} target="_blank" href={cfg.sourceCodeURL}>
                        <GitHub />
                    </Link>
                </Tooltip>
                {cfg.issueTrackerURL && (
                    <Tooltip title="Bug reports">
                        <Link sx={{ ml: 1 }} target="_blank" href={cfg.issueTrackerURL}>
                            <BugReport />
                        </Link>
                    </Tooltip>
                )}
            </Box>
        </div>
    );

    const container = window !== undefined ? () => window().document.body : undefined;

    return (
        <Box sx={{ display: "flex" }}>
            <CssBaseline />
            <AppBar
                position="fixed"
                sx={{
                    // width: {sm: `calc(100% - ${drawerWidth}px)`},
                    // ml: {sm: `${drawerWidth}px`},
                    zIndex: (theme) => theme.zIndex.drawer + 1,
                }}
            >
                <Toolbar>
                    <IconButton
                        color="inherit"
                        aria-label="open drawer"
                        onClick={handleDrawerToggle}
                        edge="start"
                        sx={{ mr: 2, display: { sm: "none" } }}
                    >
                        <MenuIcon />
                    </IconButton>
                    <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
                        Abrechnung
                    </Typography>
                    {authenticated ? (
                        <div>
                            <IconButton
                                aria-label="account of current user"
                                aria-controls="menu-appbar"
                                aria-haspopup="true"
                                onClick={handleProfileMenuOpen}
                                color="inherit"
                            >
                                <AccountCircleIcon />
                            </IconButton>
                            <Menu
                                id="menu-appbar"
                                open={dotsMenuOpen}
                                anchorOrigin={{
                                    vertical: "top",
                                    horizontal: "right",
                                }}
                                keepMounted
                                anchorEl={anchorEl}
                                transformOrigin={{
                                    vertical: "top",
                                    horizontal: "right",
                                }}
                                onClose={handleDotsMenuClose}
                            >
                                <MenuItem component={RouterLink} to="/profile">
                                    Profile
                                </MenuItem>
                                <MenuItem component={RouterLink} to="/profile/settings">
                                    Settings
                                </MenuItem>
                                <MenuItem component={RouterLink} to="/profile/sessions">
                                    Sessions
                                </MenuItem>
                                <MenuItem component={RouterLink} to="/profile/change-email">
                                    Change E-Mail
                                </MenuItem>
                                <MenuItem component={RouterLink} to="/profile/change-password">
                                    Change Password
                                </MenuItem>
                                <Divider />
                                <MenuItem component={RouterLink} to="/logout">
                                    <ListItemIcon>
                                        <Logout fontSize="small" />
                                    </ListItemIcon>
                                    <ListItemText>Sign out</ListItemText>
                                </MenuItem>
                            </Menu>
                        </div>
                    ) : (
                        <Button component={RouterLink} color="inherit" to="/login">
                            Login
                        </Button>
                    )}
                </Toolbar>
            </AppBar>

            {authenticated ? (
                <Box component="nav" sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }}>
                    <Drawer
                        container={container}
                        variant="temporary"
                        open={mobileOpen}
                        onClose={handleDrawerToggle}
                        ModalProps={{
                            keepMounted: true, // Better open performance on mobile.
                        }}
                        sx={{
                            display: { xs: "block", sm: "none" },
                            "& .MuiDrawer-paper": {
                                boxSizing: "border-box",
                                width: drawerWidth,
                            },
                        }}
                    >
                        {drawer}
                    </Drawer>
                    <Drawer
                        variant="permanent"
                        sx={{
                            flexShrink: 0,
                            display: { xs: "none", sm: "block" },
                            "& .MuiDrawer-paper": {
                                boxSizing: "border-box",
                                width: drawerWidth,
                            },
                        }}
                        open
                    >
                        {drawer}
                    </Drawer>
                </Box>
            ) : null}
            <Box
                component="main"
                sx={{
                    flexGrow: 1,
                    width: { sm: `calc(100% - ${drawerWidth}px)` },
                }}
            >
                <Toolbar />
                <Banner />
                <Container maxWidth="lg" sx={{ padding: { xs: 0, md: 1, lg: 3 } }}>
                    {children}
                </Container>
            </Box>
        </Box>
    );
}
Example #24
Source File: App.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 4 votes vote down vote up
export default function App() {
    const [darkTheme, setDarkTheme] = useLocalStorage<boolean>(
        'darkTheme',
        true,
    );

    const darkThemeContext = {
        darkTheme,
        setDarkTheme,
    };

    const theme = React.useMemo(
        () => createTheme({
            palette: {
                mode: darkTheme ? 'dark' : 'light',
            },
            components: {
                MuiCssBaseline: {
                    styleOverrides: `
                        *::-webkit-scrollbar {
                            width: 10px;
                            background: ${darkTheme ? '#222' : '#e1e1e1'};   
                        }
                        
                        *::-webkit-scrollbar-thumb {
                            background: ${darkTheme ? '#111' : '#aaa'};
                            border-radius: 5px;
                        }
                    `,
                },
            },
        }),
        [darkTheme],
    );

    return (
        <Router>
            <StyledEngineProvider injectFirst>
                <ThemeProvider theme={theme}>
                    <QueryParamProvider ReactRouterRoute={Route}>
                        <LibraryOptionsContextProvider>
                            <NavBarContextProvider>
                                <CssBaseline />
                                <DefaultNavBar />
                                <Container
                                    id="appMainContainer"
                                    maxWidth={false}
                                    disableGutters
                                    sx={{
                                        mt: 8,
                                        ml: { sm: 8 },
                                        mb: { xs: 8, sm: 0 },
                                        width: 'auto',
                                        overflow: 'auto',
                                    }}
                                >
                                    <Switch>
                                        {/* General Routes */}
                                        <Route
                                            exact
                                            path="/"
                                            render={() => (
                                                <Redirect to="/library" />
                                            )}
                                        />
                                        <Route path="/settings/about">
                                            <About />
                                        </Route>
                                        <Route path="/settings/categories">
                                            <Categories />
                                        </Route>
                                        <Route path="/settings/backup">
                                            <Backup />
                                        </Route>
                                        <Route path="/settings">
                                            <DarkTheme.Provider
                                                value={darkThemeContext}
                                            >
                                                <Settings />
                                            </DarkTheme.Provider>
                                        </Route>

                                        {/* Manga Routes */}

                                        <Route path="/sources/:sourceId/popular/">
                                            <SourceMangas popular />
                                        </Route>
                                        <Route path="/sources/:sourceId/latest/">
                                            <SourceMangas popular={false} />
                                        </Route>
                                        <Route path="/sources/:sourceId/configure/">
                                            <SourceConfigure />
                                        </Route>
                                        <Route path="/sources/all/search/">
                                            <SearchAll />
                                        </Route>
                                        <Route path="/downloads">
                                            <DownloadQueue />
                                        </Route>
                                        <Route path="/manga/:mangaId/chapter/:chapterNum">
                                            <></>
                                        </Route>
                                        <Route path="/manga/:id">
                                            <Manga />
                                        </Route>
                                        <Route path="/library">
                                            <Library />
                                        </Route>
                                        <Route path="/updates">
                                            <Updates />
                                        </Route>
                                        <Route path="/sources">
                                            <Sources />
                                        </Route>
                                        <Route path="/extensions">
                                            <Extensions />
                                        </Route>
                                        <Route path="/browse">
                                            <Browse />
                                        </Route>
                                    </Switch>
                                </Container>
                                <Switch>
                                    <Route
                                        path="/manga/:mangaId/chapter/:chapterIndex"
                                        // passing a key re-mounts the reader when changing chapters
                                        render={(props: any) => (
                                            <Reader
                                                key={
                                                    props.match.params
                                                        .chapterIndex
                                                }
                                            />
                                        )}
                                    />
                                </Switch>
                            </NavBarContextProvider>
                        </LibraryOptionsContextProvider>
                    </QueryParamProvider>
                </ThemeProvider>
            </StyledEngineProvider>
        </Router>
    );
}
Example #25
Source File: Header.tsx    From fluttertemplates.dev with MIT License 4 votes vote down vote up
export default function Header(props: HeaderProps) {
  const [drawer, setDrawer] = useState(false);

  const theme = useTheme();
  const _isNotMobile = useMediaQuery(theme.breakpoints.up("sm"));

  const toggleDrawer = () => () => {
    setDrawer(!drawer);
  };

  return (
    <AppBar
      position="sticky"
      elevation={0}
      style={{
        backgroundColor: theme.palette.primary.main,
      }}
    >
      <Toolbar>
        <Container maxWidth="lg">
          <Grid
            container
            direction="row"
            justifyContent="center"
            alignItems="center"
          >
            <Box sx={{ flexGrow: _isNotMobile ? 0 : 1 }}>
              <Button href="/" variant="text" color="inherit">
                <img
                  src="/favicon.svg"
                  alt="Flutter UI Templates Logo"
                  style={{
                    height: "2.5rem",
                    width: "2.5rem",
                    paddingRight: "0.5rem",
                  }}
                />
                {_isNotMobile && (
                  <Grid container>
                    <Typography
                      style={{
                        color: theme.palette.secondary.main,
                        textTransform: "capitalize",
                        maxLines: 1,
                        fontSize: "1.3rem",
                        fontWeight: "bold",
                        marginLeft: "4px",
                      }}
                    >
                      Flutter
                    </Typography>

                    <Typography
                      style={{
                        textTransform: "capitalize",
                        maxLines: 1,
                        fontSize: "1.3rem",
                        fontWeight: "bold",
                        marginLeft: "4px",
                      }}
                    >
                      Templates
                    </Typography>
                  </Grid>
                )}
              </Button>
            </Box>

            {_isNotMobile && (
              <Box sx={{ flexGrow: 1 }}>
                <Grid
                  container
                  direction="row"
                  justifyContent="flex-end"
                  alignItems="center"
                >
                  {commonNav.map((item, index) => (
                    <Grid item key={`nav_${index}`}>
                      {item}
                    </Grid>
                  ))}
                </Grid>
              </Box>
            )}

            <Grid item>
              <IconButton
                aria-label="Theme Toggle Button"
                onClick={props.onThemeChange}
              >
                {props.isDarkMode ? (
                  <Brightness7Rounded />
                ) : (
                  <NightsStayRounded />
                )}
              </IconButton>
            </Grid>

            {!_isNotMobile && (
              <Grid item>{displayMobile(drawer, toggleDrawer())}</Grid>
            )}
          </Grid>
        </Container>
      </Toolbar>
    </AppBar>
    // </div>
  );
}
Example #26
Source File: CommentItemModule.tsx    From bouncecode-cms with GNU General Public License v3.0 4 votes vote down vote up
function CommentItemModule({post, comment}: ICommentItemModule) {
  const [moreVert, setMoreVert] = React.useState(null);
  const openMoreVert = Boolean(moreVert);
  const toggleMoreVert = open => {
    return event => {
      if (open) {
        setMoreVert(event.currentTarget);
      } else {
        setMoreVert(null);
      }
    };
  };

  const [commentDrawer, setCommentDrawer] = React.useState(null);
  const toggleCommentDrawer = open => {
    return event => {
      if (
        event.type === 'keydown' &&
        (event.key === 'Tab' || event.key === 'Shift')
      ) {
        return;
      }

      setCommentDrawer(open);
    };
  };

  const [
    emotionMutation,
    {loading: emotionLoading},
  ] = useCommentEmotionMutation();
  const [
    undoEmotionMutation,
    {loading: undoEmotionLoading},
  ] = useCommentEmotionUndoMutation();
  const updateEmotion = emotion => {
    return () => {
      console.log(myEmotion);
      console.log(emotion);
      if (myEmotion === emotion.toLowerCase()) {
        undoEmotionMutation({
          variables: {
            where: {
              id: comment.id,
            },
          },
          refetchQueries: [
            {
              query: CommentMyEmotionDocument,
              variables: {where: {id: comment.id}},
            },
          ],
        });
      } else {
        emotionMutation({
          variables: {
            where: {
              id: comment.id,
            },
            data: {emotion},
          },
          refetchQueries: [
            {
              query: CommentMyEmotionDocument,
              variables: {where: {id: comment.id}},
            },
          ],
        });
      }
    };
  };

  const {
    data: myEmotionData,
    loading: myEmotionLoading,
  } = useCommentMyEmotionQuery({
    variables: {where: {id: comment.id}},
  });
  const myEmotion = myEmotionData?.commentMyEmotion?.emotion;

  return (
    <Grid container direction="column" spacing={1}>
      <Grid item>
        <Grid container spacing={2}>
          <Grid item>
            <Avatar></Avatar>
          </Grid>
          <Grid item xs>
            <Grid container direction="column" spacing={1}>
              <Grid item>
                <Grid container spacing={2} alignItems="center">
                  <Grid item>
                    <Typography variant="body2">
                      {comment.user.email}
                    </Typography>
                  </Grid>
                  <Grid item>
                    <Typography variant="caption">
                      {formatDistance(
                        new Date(comment.createdDate),
                        new Date(),
                        {addSuffix: true},
                      )}
                    </Typography>
                  </Grid>
                </Grid>
              </Grid>
              <Grid item>
                <Typography variant="body1">{comment.text}</Typography>
              </Grid>
              <Grid
                container
                justifyContent="space-between"
                alignItems="center">
                <Grid item>
                  <Grid container alignItems="center">
                    <Grid item>
                      <Button
                        variant="text"
                        size="small"
                        startIcon={<ThumbUpOutlined />}
                        onClick={updateEmotion('LIKE')}
                        disabled={
                          myEmotionLoading ||
                          emotionLoading ||
                          undoEmotionLoading
                        }>
                        {comment.like || ''}
                      </Button>
                    </Grid>
                    <Grid item>
                      <Button
                        variant="text"
                        size="small"
                        startIcon={<ThumbDownOutlined />}
                        onClick={updateEmotion('UNLIKE')}
                        disabled={
                          myEmotionLoading ||
                          emotionLoading ||
                          undoEmotionLoading
                        }>
                        {comment.unlike || ''}
                      </Button>
                    </Grid>
                    {post ? (
                      <Grid item>
                        <Button
                          variant="text"
                          size="small"
                          onClick={toggleCommentDrawer(true)}
                          disabled>
                          답글
                        </Button>
                        <Drawer
                          anchor="bottom"
                          open={commentDrawer}
                          onClose={toggleCommentDrawer(false)}>
                          <Container maxWidth="md">
                            <Box pt={2} pb={2}>
                              <CommentCreateFormModule />
                            </Box>
                          </Container>
                        </Drawer>
                      </Grid>
                    ) : (
                      undefined
                    )}
                  </Grid>
                </Grid>
                <Grid item>
                  <IconButton onClick={toggleMoreVert(true)} disabled>
                    <MoreVert fontSize="small" />
                  </IconButton>
                  <Menu
                    anchorEl={moreVert}
                    open={openMoreVert}
                    onClose={toggleMoreVert(false)}>
                    <MenuItem
                      // selected={option === 'Pyxis'}
                      onClick={toggleMoreVert(false)}>
                      <ListItemIcon>
                        <AssistantPhotoOutlined />
                      </ListItemIcon>
                      <Typography variant="inherit">신고</Typography>
                    </MenuItem>
                  </Menu>
                </Grid>
              </Grid>
              {/* {post ? (
                <Grid item>
                  <Grid container direction="column" spacing={2}>
                    <Grid item>
                      <Button
                        variant="text"
                        size="small"
                        startIcon={<KeyboardArrowDown />}>
                        답글 1개 보기
                      </Button>
                    </Grid>
                    <Grid item>
                      <CommentItemModule comment />
                    </Grid>
                  </Grid>
                </Grid>
              ) : (
                undefined
              )} */}
            </Grid>
          </Grid>
        </Grid>
      </Grid>
    </Grid>
  );
}
Example #27
Source File: BlockEditor.tsx    From NekoMaid with MIT License 4 votes vote down vote up
BlockEditor: React.FC = () => {
  const theme = useTheme()
  const plugin = usePlugin()
  const his = useHistory()
  const loc = useLocation()
  const globalData = useGlobalData()
  const drawerWidth = useDrawerWidth()
  const [block, setBlock] = useState<Block>()
  const [types, setTypes] = useState<string[]>([])
  const [worlds, setWorlds] = useState<string[]>([])
  const params = { world: '', x: 0, y: 0, z: 0 }
  if (loc.pathname.startsWith('/NekoMaid/block/')) {
    const arr = loc.pathname.split('/')
    if (arr.length > 6) {
      params.world = arr[3]
      params.x = +arr[4]
      params.y = +arr[5]
      params.z = +arr[6]
    } else his.push('/NekoMaid/block')
  }
  useEffect(() => {
    const off = plugin.emit('item:blocks', (types: string[], worlds: string[]) => {
      setTypes(types)
      setWorlds(worlds)
    })
      .on('block:select', (world, x, y, z) => his.push(`/NekoMaid/block/${world}/${x}/${y}/${z}`))
    return () => void off()
  }, [])
  const update = () => {
    if (params.world) {
      plugin.emit('block:fetch', (block: Block) => {
        if (!block) {
          failed()
          his.push('/NekoMaid/block')
          return
        }
        if (globalData.hasNBTAPI && block.nbt) block.nbt = stringify(parse(block.nbt), { pretty: true })
        setBlock(block)
      }, params.world, params.x, params.y, params.z)
    }
  }
  const updateWithAction = (res: boolean) => {
    action(res)
    update()
  }
  useEffect(update, [params.world, params.x, params.y, params.z])
  return <Box sx={{ minHeight: '100%', py: 3 }}>
    <Toolbar />
    <Container maxWidth={false}>
      <Grid container spacing={3} sx={{ width: { sm: `calc(100vw - ${drawerWidth}px - ${theme.spacing(3)})` } }}>
        <Grid item lg={6} md={12} xl={6} xs={12}>
          <Card sx={{ '& .CodeMirror-dialog, .CodeMirror-scrollbar-filler': { backgroundColor: theme.palette.background.paper + '!important' } }}>
            <CardHeader
              title={lang.blockEditor.title}
              sx={{ position: 'relative' }}
              action={<Box sx={cardActionStyles}>
                <IconButton
                  size='small'
                  disabled={!block || (!block.data && !block.nbt)}
                  onClick={() => block && plugin.emit('block:save', (res: boolean) => {
                    action(res)
                    update()
                  }, params.world, params.x, params.y, params.z, block.nbt || null, block.data || null)}
                ><Save /></IconButton>
                <IconButton
                  size='small'
                  disabled={!block}
                  onClick={() => {
                    update()
                    success()
                  }}
                ><Refresh /></IconButton>
              </Box>}
            />
            <Divider />
            {block
              ? <>
                <CardContent sx={{ display: 'flex', width: '100%', justifyContent: 'center' }}>
                  <ItemViewer item={{ type: block.type }} />
                  <Autocomplete
                    options={types}
                    sx={{ maxWidth: 300, marginLeft: 1, flexGrow: 1 }}
                    value={block.type}
                    onChange={(_, it) => it && plugin.emit('block:type', (res: boolean) => {
                      action(res)
                      update()
                    }, params.world, params.x, params.y, params.z, (block.type = it))}
                    getOptionLabel={it => {
                      const locatedName = getName(it.toLowerCase())
                      return (locatedName ? locatedName + ' ' : '') + it
                    }}
                    renderInput={(params) => <TextField {...params} label={lang.itemEditor.itemType} size='small' variant='standard' />}
                  />
                </CardContent>
                {block.data != null && <Accordion sx={{ '&::before': { opacity: '1!important' } }} disableGutters>
                  <AccordionSummary expandIcon={<ExpandMore />}><Typography>{lang.data}</Typography></AccordionSummary>
                  <AccordionDetails sx={{ padding: 0, '& .CodeMirror': { width: '100%', height: 350 } }}>
                    <UnControlled
                      value={block.data}
                      options={{
                        mode: 'javascript',
                        phrases: lang.codeMirrorPhrases,
                        theme: theme.palette.mode === 'dark' ? 'material' : 'one-light'
                      }}
                      onChange={(_: any, __: any, data: string) => (block.data = data)}
                    />
                  </AccordionDetails>
                </Accordion>}
                {block.nbt != null && <Accordion sx={{ '&::before': { opacity: '1!important', display: '!important' } }} disableGutters>
                  <AccordionSummary expandIcon={<ExpandMore />}><Typography>NBT</Typography></AccordionSummary>
                  <AccordionDetails sx={{ padding: 0, '& .CodeMirror': { width: '100%', height: 350 } }}>
                    <UnControlled
                      value={block.nbt}
                      options={{
                        mode: 'javascript',
                        phrases: lang.codeMirrorPhrases,
                        theme: theme.palette.mode === 'dark' ? 'material' : 'one-light'
                      }}
                      onChange={(_: any, __: any, data: string) => (block.nbt = data)}
                    />
                  </AccordionDetails>
                </Accordion>}
              </>
              : <CardContent>{worlds.length ? <BlockSelector worlds={worlds} /> : <Empty />}</CardContent>}
          </Card>
        </Grid>
        {block?.inventory?.length
          ? <Grid item lg={6} md={12} xl={6} xs={12}>
            <Card>
              <CardHeader
                title={minecraft[('container.' + block.inventoryType || '').toLowerCase()] || lang.blockEditor.container}
                sx={{ position: 'relative' }}
              />
              <Divider />
              <CardContent sx={{ whiteSpace: 'nowrap', overflowX: 'auto', textAlign: 'center' }}>
                {block.inventory.map((it, i) => <React.Fragment key={i}><ItemViewer
                  item={it}
                  data={{ type: InvType.BLOCK, solt: i, ...params }}
                  onDrag={() => plugin.emit('block:setItem', update, params.world, params.x, params.y, params.z, i, null, -1)}
                  onDrop={(item, obj) => plugin.emit('block:setItem', update, params.world, params.x, params.y, params.z, i,
                    JSON.stringify(item), compare(obj, params) ? obj.solt : -1)}
                  onEdit={item => item !== false && plugin.emit('block:setItem', updateWithAction, params.world, params.x, params.y,
                    params.z, i, item && JSON.stringify(item), -1)}
                />{!((i + 1) % 9) && <br />}</React.Fragment>)}
              </CardContent>
            </Card>
          </Grid>
          : undefined}
      </Grid>
    </Container>
  </Box>
}