@mui/material#Grid TypeScript Examples

The following examples show how to use @mui/material#Grid. 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: index.tsx    From genshin-optimizer with MIT License 8 votes vote down vote up
export default function ArtifactInfoDisplay() {
  const { t } = useTranslation("artifact")
  return <Grid container spacing={1} >
    <Grid item xs={12} lg={5} xl={4}>
      <ImgFullwidth src={artifactcard} />
    </Grid>
    <Grid item xs={12} lg={7} xl={8}>
      <Trans t={t} i18nKey="info.section1">
        <Typography variant="h5">Substat rolls</Typography>
        <Typography gutterBottom>The <b>number of rolls</b> a substat has is shown to the left of the substat. As the number gets higher, the substat is more colorful:<Colors />.</Typography>

        <Typography variant="h5">Substat Roll Value</Typography>
        <Typography gutterBottom>The Roll Value(RV) of an subtat is a percentage of the current value over the highest potential 5<Stars stars={1} /> value. From the Image, the maximum roll value of CRIT DMG is 7.8%. In RV: <b>5.8/7.8 = 69.2%.</b></Typography>

        <Typography variant="h5">Current Roll Value vs. Maximum Roll Value</Typography>
        <Typography gutterBottom>When a 5<Stars stars={1} /> have 9(4+5) total rolls, with each of the rolls having the highest value, that is defined as a 900% RV artifact. However, most of the artifacts are not this lucky. The <b>Current RV</b> of an artifact is a percentage over that 100% artifact. The <b>Maximum RV</b> is the maximum possible RV an artifact can achieve, if the remaining artifact rolls from upgrades are the hightest possible value.</Typography>

        <Typography variant="h5">Locking an artifact</Typography>
        <Typography>By locking an artifact <FontAwesomeIcon icon={faBan} />, This artifact will not be picked up by the build generator for optimization. An equipped artifact is locked by default.</Typography>
      </Trans>
    </Grid>
    <Grid item xs={12} lg={6} xl={7} >
      <Trans t={t} i18nKey="info.section2">
        <Typography variant="h5">Artifact Editor</Typography>
        <Typography gutterBottom>A fully featured artifact editor, that can accept any 3<Stars stars={1} /> to 5<Stars stars={1} /> Artifact. When a substat is inputted, it can calculate the exact roll values. It will also make sure that you have the correct number of rolls in the artifact according to the level, along with other metrics of validation.</Typography>

        <Typography variant="h5">Scan screenshots</Typography>
        <Typography gutterBottom>Manual input is not your cup of tea? You can scan in your artifacts with screenshots! On the Artifact Editor, click the <SqBadge color="info">Show Me How!</SqBadge> button to learn more.</Typography>

        <Typography variant="h6">Automatic Artifact Scanner</Typography>
        <Typography gutterBottom>If you are playing Genshin on PC, you can download a tool that automatically scans all your artifacts for you, and you can then import that data in <FontAwesomeIcon icon={faCog} /> Database. <Link component={RouterLink} to="/scanner">Click here</Link> for a list of scanners that are compatible with GO.</Typography>

        <Typography variant="h5">Duplicate/Upgrade artifact detection</Typography>
        <Typography>Did you know GO can detect if you are adding a <b>duplicate</b> artifact that exists in the system? It can also detect if the current artifact in editor is an <b>upgrade</b> of an existing artifact as well. Once a duplicate/upgrade is detected, a preview will allow you to compare the two artifacts in question(See Image).</Typography>
      </Trans>
    </Grid>
    <Grid item xs={12} lg={6} xl={5}>
      <ImgFullwidth src={artifacteditor} />
    </Grid>
    <Grid item xs={12} lg={7} xl={6}>
      <ImgFullwidth src={artifactfilter} />
    </Grid>
    <Grid item xs={12} lg={5} xl={6}>
      <Trans t={t} i18nKey="info.section3">
        <Typography variant="h5">Artifact Inventory</Typography>
        <Typography gutterBottom>All your artifacts that you've added to GO is displayed here. The filters here allow you to further refine your view of your artifacts. </Typography>
        <Typography variant="h5">Example: Finding Fodder Artifacts</Typography>
        <Typography>By utilizing the artifact filter, and the artifact RV, you can quickly find artifacts to feed as food.</Typography>
        <Typography>In this example, the filters are set thusly: </Typography>
        <Typography component="div" >
          <ul>
            <li>Limit level to 0-8.</li>
            <li>Unlocked artifacts in Inventory.</li>
            <li>Removing the contribution of flat HP, flat DEF and Energy Recharge to RV calculations.</li>
            <li>Sorted by Ascending Max Roll Value.</li>
          </ul>
        </Typography>
        <Typography>This will filter the artifact Inventory by the lowest RV artifacts, for desired substats.</Typography>
      </Trans>
    </Grid>
  </Grid>
}
Example #2
Source File: index.tsx    From ExpressLRS-Configurator with GNU General Public License v3.0 7 votes vote down vote up
CardTitle: FunctionComponent<CardTitleProps> = memo(({ icon, title }) => {
  return (
    <CardContent>
      <Grid container spacing={1} alignItems="center">
        <Grid item>{icon}</Grid>
        <Grid item flexGrow={1}>
          <Typography variant="h6">{title}</Typography>
        </Grid>
      </Grid>
    </CardContent>
  );
})
Example #3
Source File: SkeletonComponent.tsx    From firecms with MIT License 6 votes vote down vote up
function renderArrayOfStrings() {
    return (
        <Grid>
            {
                [0, 1].map((value, index) => (
                    renderSkeletonText(index)
                ))}
        </Grid>
    );
}
Example #4
Source File: PluginList.tsx    From Cromwell with MIT License 6 votes vote down vote up
UpdateModalContent = (props: {
    pluginsUnderUpdate: Record<string, boolean>;
    update?: TCCSVersion;
    plugin?: TPluginEntity;
    info?: TPackageCromwellConfig;
    onStartUpdate: (plugin: TPluginEntity) => void;
    onClose: () => void;
}) => {
    const { update, plugin, info } = props;
    const isUnderUpdate = plugin?.name && props.pluginsUnderUpdate[plugin.name];

    return (
        <Grid item container xs={12} className={styles.updateModal}>
            <Grid item className={styles.updateHeader} >
                <h3 className={styles.updateTitle}>
                    <UpdateIcon style={{ marginRight: '7px' }} />
                    Update available</h3>
                <IconButton
                    style={{ marginRight: '-10px' }}
                    onClick={props.onClose}><CloseIcon /></IconButton>
            </Grid>
            <p>{info?.version ?? ''} {'>'} {update.version}</p>

            <div className={styles.changelogList}
                dangerouslySetInnerHTML={{ __html: update.changelog }}></div>
            <Button
                disabled={isUnderUpdate}
                color="primary"
                variant="contained"
                onClick={() => props.onStartUpdate(plugin)}
            >Update</Button>
        </Grid>
    )
}
Example #5
Source File: NativesPage.tsx    From GTAV-NativeDB with MIT License 6 votes vote down vote up
function Desktop() {
  return (
    <Grid sx={{ flex: 1, overflow: 'hidden' }} container>
      <Grid
        xl={4} md={5} sm={6} xs={12} item
        sx={{ overflow: 'hidden scroll', height: '100%' }}
      >
        <NativeInfo />
      </Grid>
      <Grid
        xl={8} md={7} sm={6} xs={12} item
      >
        <NativeList />
      </Grid>
    </Grid>
  )
}
Example #6
Source File: Content.tsx    From mojito_pdm with Creative Commons Attribution Share Alike 4.0 International 6 votes vote down vote up
Content: React.FC = () => {
    const filteredCars = useRecoilValue(CarState.filteredCars)

    return (
        <>
            <Grid container spacing={1}>
                {filteredCars.map((obj, index) => (
                    <Grid item xs={12} sm={4}>
                        <VehCard key={index} {...obj} />
                    </Grid>
                ))}
            </Grid>
        </>
    )
}
Example #7
Source File: TransferDetails.tsx    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
export default function TransferDetails({ group, transaction }) {
    return (
        <MobilePaper>
            <TransactionActions groupID={group.id} transaction={transaction} />
            <Divider sx={{ marginBottom: 1, marginTop: 1 }} />
            <Grid container>
                <Grid item xs={transaction.is_wip || transaction.files.length > 0 ? 6 : 12}>
                    <TransactionDescription group={group} transaction={transaction} />
                    <TransactionValue group={group} transaction={transaction} />
                    <TransactionBilledAt group={group} transaction={transaction} />

                    <TransactionCreditorShare
                        group={group}
                        transaction={transaction}
                        isEditing={transaction.is_wip}
                        label="From"
                    />

                    <TransactionDebitorShare
                        group={group}
                        transaction={transaction}
                        isEditing={transaction.is_wip}
                        label="To"
                    />
                </Grid>

                {(transaction.is_wip || transaction.files.length > 0) && (
                    <Grid item xs={6}>
                        <FileGallery transaction={transaction} />
                    </Grid>
                )}
            </Grid>
        </MobilePaper>
    );
}
Example #8
Source File: Code.tsx    From fluttertemplates.dev with MIT License 6 votes vote down vote up
function Code(params: CodeParams) {
  return (
    <div>
      {params.codeGistUrl && (
        <CodeBlock url={params.codeGistUrl} height="50vh" />
      )}

      {params.fullCodeUrl && (
        <Grid
          container
          direction="row"
          justifyContent="center"
          alignItems="center"
          style={{
            height: params.codeGistUrl ? "100%" : "70vh",
          }}
        >
          <Grid item>
            <a
              aria-label="Download Code"
              href={params.fullCodeUrl}
              target="_blank"
              rel="noopener noreferrer"
            >
              <CustomContainedButton
                label="Full Source Code"
                endIcon={<GitHub />}
              />
            </a>
          </Grid>
        </Grid>
      )}
    </div>
  );
}
Example #9
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 #10
Source File: App.tsx    From cli with Apache License 2.0 6 votes vote down vote up
Error = () => {
  return (
    <Box height="100vh" display="flex" align-items="center">
      <Grid
        container
        direction="row"
        justifyContent="center"
        alignItems="center"
      >
        <Grid item md={9} sm={11}>
          <div className="container">
            <Typography variant="h4" color="error">
              Invalid Environment variables
            </Typography>
            <Typography variant="body1">
              You should have a valid <code>.env</code> file at the root of this
              project. You can use <code>.env.example</code> as starting point
              and make sure to replace all placeholder variables
              <code>&#60;...&#62;</code> by the proper information for your
              organization.
            </Typography>
            <p>
              Refer to the project <b>README</b> file for more information.
            </p>
          </div>
        </Grid>
      </Grid>
    </Box>
  );
}
Example #11
Source File: CharacterCard.tsx    From genshin-optimizer with MIT License 6 votes vote down vote up
function Artifacts() {
  const { database } = useContext(DatabaseContext)
  const { data } = useContext(DataContext)
  const artifacts = useMemo(() =>
    allSlotKeys.map(k => [k, database._getArt(data.get(input.art[k].id).value ?? "")]),
    [data, database]) as Array<[SlotKey, ICachedArtifact | undefined]>;

  return <Grid direction="row" container spacing={0.75} columns={5}>
    {artifacts.map(([key, art]: [SlotKey, ICachedArtifact | undefined]) =>
      <Grid item key={key} xs={1}>
        <ArtifactCardPico artifactObj={art} slotKey={key} />
      </Grid>
    )}
  </Grid>
}
Example #12
Source File: LoadingComponent.tsx    From console with GNU Affero General Public License v3.0 6 votes vote down vote up
LoadingComponent = () => {
  return (
    <Grid
      container
      spacing={0}
      direction="column"
      alignItems="center"
      justifyContent="center"
      style={{ minHeight: "100vh" }}
    >
      <Grid item xs={3} style={{ textAlign: "center" }}>
        <Loader style={{ width: 35, height: 35 }} />
        <br />
        Loading...
      </Grid>
    </Grid>
  );
}
Example #13
Source File: MarketItem.tsx    From Cromwell with MIT License 5 votes vote down vote up
export default function MarketItem(props: PropsType) {
    const data = props?.data;
    const [installing, setInstalling] = useState(false);
    const [installed, setInstalled] = useState(!!(props.data?.name
        && props?.listItemProps?.installedModules?.find(inst => inst.name === props.data?.name)));

    const installModule = async () => {
        if (!props.listItemProps?.install || !data) return;

        setInstalling(true);
        const success = await props.listItemProps.install(data);
        if (success) setInstalled(true);
        setInstalling(false);
    }

    return (
        <Grid item xs={6} lg={4} className={styles.listItem}>
            <div className={clsx(styles.listItemContent, installing && styles.installing)}>
                {data?.image && (
                    <CardActionArea
                        onClick={() => props.listItemProps?.open(props.data)}
                        className={styles.cardActionArea}
                    >
                        <img src={data.image} className={styles.image} />
                    </CardActionArea>
                )}
                <div className={styles.caption}>
                    <Badge color="secondary" badgeContent={installed ? 'installed' : null}>
                        <Typography gutterBottom variant="h5" component="h3" className={styles.title}>
                            {data?.title ?? ''}
                        </Typography>
                    </Badge>
                    <p className={styles.version}>{data?.version ?? ''}</p>
                    <p className={styles.excerpt}>{data?.excerpt ?? ''}</p>
                </div>
                <div className={styles.actions}>
                    <Button
                        size="small" color="primary" variant="contained"
                        onClick={() => props.listItemProps?.open(props.data)}
                    >Open</Button>
                    <Button
                        disabled={installed || installing}
                        size="small" color="primary" variant="contained"
                        onClick={installModule}
                    >Install</Button>
                </div>
                {installing && (
                    <LinearProgress className={styles.updateProgress} />
                )}
            </div>
        </Grid>
    )
}
Example #14
Source File: ClearingAccountDetail.tsx    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function ClearingAccountDetail({ group, account }) {
    const classes = useStyles();
    const accounts = useRecoilValue(accountsSeenByUser(group.id));
    const balances = useRecoilValue(accountBalances(group.id));

    const [showAdvanced, setShowAdvanced] = useState(false);

    useEffect(() => {
        for (const share of Object.values(account.clearing_shares)) {
            if (share !== 1) {
                setShowAdvanced(true);
                break;
            }
        }
    }, [account]);

    const clearingShareValue = (accountID) => {
        return account.clearing_shares?.hasOwnProperty(accountID) ? account.clearing_shares[accountID] : 0;
    };

    return (
        <TableContainer>
            <Table>
                <TableHead>
                    <TableRow>
                        <TableCell>Account</TableCell>
                        {showAdvanced && <TableCell>Shares</TableCell>}
                        <TableCell width="100px" align="right">
                            Shared
                        </TableCell>
                    </TableRow>
                </TableHead>
                <TableBody>
                    {accounts
                        .filter((a) => balances[account.id].clearingResolution.hasOwnProperty(a.id))
                        .map((a) => (
                            <TableRow hover key={a.id}>
                                <TableCell className={classes.tableLinkCell}>
                                    {/*TODO: proper link*/}
                                    <Link className={classes.tableLink} to={`/groups/${group.id}/accounts/${a.id}`}>
                                        <Grid container direction="row" alignItems="center">
                                            <Grid item>
                                                {a.type === "personal" ? (
                                                    <PersonalAccountIcon />
                                                ) : (
                                                    <ClearingAccountIcon />
                                                )}
                                            </Grid>
                                            <Grid item sx={{ ml: 1 }}>
                                                <Typography variant="body2" component="span">
                                                    {a.name}
                                                </Typography>
                                            </Grid>
                                        </Grid>
                                    </Link>
                                </TableCell>
                                {showAdvanced && <TableCell width="50px">{clearingShareValue(a.id)}</TableCell>}
                                <TableCell width="100px" align="right">
                                    {balances[account.id].clearingResolution[a.id].toFixed(2)} {group.currency_symbol}
                                </TableCell>
                            </TableRow>
                        ))}
                </TableBody>
            </Table>
        </TableContainer>
    );
}
Example #15
Source File: AllStats.tsx    From your_spotify with GNU General Public License v3.0 5 votes vote down vote up
export default function AllStats() {
  const user = useSelector(selectUser);

  if (!user) {
    return null;
  }

  return (
    <div className={s.root}>
      <Header
        title="All stats"
        subtitle="You can find here all kind of stats based on the time span on the
          right"
      />
      <div className={s.content}>
        <Grid container spacing={2}>
          <Grid item xs={12} md={12} lg={6}>
            <BestArtistsBar className={s.chart} />
          </Grid>
          <Grid item xs={12} md={12} lg={6}>
            <ListeningRepartition className={s.chart} />
          </Grid>
          <Grid item xs={12} md={12} lg={6}>
            <ArtistListeningRepartition className={s.chart} />
          </Grid>
          <Grid item xs={12} md={12} lg={6}>
            <BestOfHour className={s.chart} />
          </Grid>
          <Grid item xs={12} md={12} lg={6}>
            <SongsListenedPer className={s.chart} />
          </Grid>
          <Grid item xs={12} md={12} lg={6}>
            <TimeListenedPer className={s.chart} />
          </Grid>
          <Grid item xs={12} md={12} lg={6}>
            <DifferentArtistListenedPer className={s.chart} />
          </Grid>
          <Grid item xs={12} md={12} lg={6}>
            <AverageAlbumReleaseDate className={s.chart} />
          </Grid>
          <Grid item xs={12} md={12} lg={6}>
            <AverageNumberArtistPer className={s.chart} />
          </Grid>
          <Grid item xs={12} md={12} lg={6}>
            <AverageSongPopularityPer className={s.chart} />
          </Grid>
        </Grid>
      </div>
    </div>
  );
}
Example #16
Source File: CustomIframe.tsx    From fluttertemplates.dev with MIT License 5 votes vote down vote up
export default function CustomIframe(props: CustomIframeProps) {
  const [isLoading, setIsLoading] = React.useState(true);

  useEffect(() => {
    setTimeout(() => {
      setIsLoading(false);
    }, 10000);
  }, []);

  return (
    <div
      style={{
        position: "relative",
        width: "100%",
        height: "100%",
      }}
    >
      {isLoading && props.showLoadingIndicator && (
        <Grid
          container
          direction="column"
          justifyContent="center"
          alignItems="center"
          style={{
            height: "100%",
            width: "100%",
            position: "absolute",
          }}
        >
          <CircularProgress size="1.5rem" thickness={8} color="secondary" />
        </Grid>
      )}
      <iframe
        src={props.url}
        style={{
          height: "100%",
          width: "100%",
          position: "absolute",
          border: "none",
          ...props.style,
        }}
      ></iframe>
    </div>
  );
}
Example #17
Source File: Hero.tsx    From cli with Apache License 2.0 5 votes vote down vote up
Hero: React.FunctionComponent<IHeroProps> = (props) => {
  return (
    <header className="App-header">
      <Grid className="logo-container">
        {props.logos.map((logo, idx) => (
          <img
            src={logo}
            key={'image-' + idx}
            className="App-logo"
            alt="logo"
          />
        ))}
      </Grid>

      <Typography variant="h5">{props.welcome}</Typography>
      <Typography variant="body1">
        This sample search page was built with{' '}
        <Anchor
          href="https://material-ui.com/getting-started/installation"
          value="Material-ui"
        />{' '}
        and the{' '}
        <Anchor
          href="https://docs.coveo.com/en/headless"
          value="Coveo Headless Library"
        />
        .<br></br>
      </Typography>
      <Typography variant="body1">
        Edit{' '}
        <b>
          <code>src/App.tsx</code>
        </b>{' '}
        and save to reload.
      </Typography>

      <Typography variant="subtitle1" component="h6">
        Customize your search page theme
      </Typography>
      <Typography variant="body1">
        You can customize your theme by modifying the{' '}
        <b>
          <code>src/theme.tsx</code>
        </b>
        . For more information about theme customization, visit{' '}
        <Anchor
          href="https://material-ui.com/customization/theming/"
          value="Material-ui theming"
        />
        .
      </Typography>

      <Typography variant="subtitle1" component="h6">
        Essential Links
      </Typography>
      <ul>
        <li key="item-link-headless">
          <Anchor
            href="https://docs.coveo.com/en/headless"
            value="Coveo Headless documentation"
          />
        </li>
        <li key="item-link-react">
          <Anchor href="https://reactjs.org" value="React documentation" />
        </li>
        <li key="item-link-material">
          <Anchor
            href="https://material-ui.com/"
            value="Material-ui Documentation"
          />
        </li>
      </ul>
    </header>
  );
}
Example #18
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 #19
Source File: DistributedOnly.tsx    From console with GNU Affero General Public License v3.0 5 votes vote down vote up
DistributedOnly = ({ iconComponent, entity }: IDistributedOnly) => {
  return (
    <Grid container alignItems={"center"}>
      <Grid item xs={12}>
        <HelpBox
          title={`${entity} not available`}
          iconComponent={iconComponent}
          help={
            <Box
              sx={{
                fontSize: "14px",
                display: "flex",
                border: "none",
                flexFlow: {
                  xs: "column",
                  md: "row",
                },
                "& a": {
                  color: (theme) => theme.colors.link,
                  textDecoration: "underline",
                },
              }}
            >
              <div>This feature is not available for a single-disk setup.</div>

              <div>
                Please deploy a server in{" "}
                <a
                  href="https://docs.min.io/minio/baremetal/installation/deploy-minio-distributed.html?ref=con"
                  target="_blank"
                  rel="noreferrer"
                >
                  Distributed Mode
                </a>{" "}
                to use this feature.
              </div>
            </Box>
          }
        />
      </Grid>
    </Grid>
  );
}
Example #20
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>
    );
}