ChemPal Documentation - v1.7.0
    Preparing search index...
    • AboutModal component that displays information about the application. Shows the application title, description, and contributor information in a modal dialog.

      The contributor list is loaded from src/data/contributors.json; entries render in the order they appear in that file. Static layout styles (positioning, text alignment, contributor font size) live in the sibling AboutModal.module.scss. Theme-dependent styles (palette, spacing, radius, shadow, typography scale) live in the AboutModalBox / AboutContributorItem styled components in StyledComponents.ts.

      Parameters

      • props: { aboutOpen: boolean; setAboutOpen: (open: boolean) => void }

        Component props.

        • aboutOpen - Whether the modal is open.
        • setAboutOpen - Setter to close the modal.

      Returns Element

      <AboutModal aboutOpen={isOpen} setAboutOpen={setIsOpen} />
      
      export default function AboutModal({
      aboutOpen,
      setAboutOpen,
      }: {
      aboutOpen: boolean;
      setAboutOpen: (open: boolean) => void;
      }) {
      // Trusted static build-time JSON whose shape matches Contributor.
      const entries = __APP_CONTRIBUTORS__;
      const themeContext = useContext(ThemeContext);
      const [updateIcon, setUpdateIcon] = useState<React.ReactNode>(
      <BrowserUpdatedIcon sx={{ fontSize: 16 }} />,
      );
      const logoSrc =
      themeContext?.mode === 'dark'
      ? '/static/images/logo/ChemPal-logo-inverted.svg'
      : '/static/images/logo/ChemPal-logo.svg';

      const handleCheckForUpdates = () => {
      void (async () => {
      try {
      const update = await getAvailableUpdate();
      setUpdateIcon(
      update ? (
      <BrowserUpdatedIcon sx={{ fontSize: 16, color: 'warning.main' }} />
      ) : (
      <CheckCircleIcon sx={{ fontSize: 16, color: 'success.main' }} />
      ),
      );
      } catch (error) {
      console.error('Failed to check for updates:', { error });
      setUpdateIcon(
      <SignalWifiConnectedNoInternet4Icon sx={{ fontSize: 16, color: 'error.main' }} />,
      );
      }
      })();
      };
      return (
      <Modal
      data-testid="about-modal"
      open={aboutOpen}
      onClose={() => setAboutOpen(false)}
      aria-labelledby="application-title"
      aria-describedby="application-description"
      >
      <AboutModalBox className={styles['about-box']} onClick={(e) => e.stopPropagation()}>
      <img src={logoSrc} alt={i18n('about_logo_alt')} className={styles['about-logo']} />
      <Typography
      id="application-title"
      variant="h6"
      component="h2"
      className={styles['about-title']}
      >
      {i18n('about_title')}
      </Typography>
      <Typography
      variant="subtitle2"
      gutterBottom
      sx={{ alignItems: 'center', textAlign: 'center' }}
      >
      {__APP_VERSION__}{' '}
      <Link
      href="#"
      onClick={handleCheckForUpdates}
      sx={{ marginLeft: 1, verticalAlign: 'top' }}
      >
      {updateIcon}
      </Link>
      </Typography>

      <AboutModalLinkContainer>
      <AboutModalLink
      data-testid="github-button"
      href={__APP_REPOSITORY__}
      target="_blank"
      title={i18n('about_repository_link_title')}
      rel="noopener noreferrer"
      >
      <GitHubIcon />
      </AboutModalLink>
      <AboutModalLink
      data-testid="homepage-button"
      href={__APP_HOMEPAGE__}
      target="_blank"
      title={i18n('about_homepage_link_title')}
      rel="noopener noreferrer"
      >
      <WebIcon />
      </AboutModalLink>
      <AboutModalLink
      data-testid="wiki-button"
      href={__APP_WIKI__}
      target="_blank"
      title={i18n('about_wiki_link_title')}
      rel="noopener noreferrer"
      >
      <ArticleIcon />
      </AboutModalLink>
      <AboutModalLink
      data-testid="privacy-button"
      href={__APP_PRIVACY__}
      target="_blank"
      title={i18n('about_privacy_link_title')}
      rel="noopener noreferrer"
      >
      <PrivacyTipIcon />
      </AboutModalLink>
      <AboutModalLink
      data-testid="bugs-button"
      href={__APP_BUGS__}
      target="_blank"
      title={i18n('about_bugs_link_title')}
      rel="noopener noreferrer"
      onClick={(e: React.MouseEvent) => {
      // Open the prefilled report dialog instead of the bare issues page.
      e.preventDefault();
      void showReportDialog();
      }}
      >
      <BugReportIcon />
      </AboutModalLink>
      </AboutModalLinkContainer>
      <Typography
      id="application-description"
      variant="subtitle2"
      gutterBottom
      sx={{ mt: 0.5, display: 'block' }}
      >
      {i18n('about_description')}
      </Typography>
      <Divider sx={{ color: 'primary.main', my: 2 }}>
      <Typography variant="overline" gutterBottom sx={{ display: 'block' }}>
      {i18n('about_contributors')}
      </Typography>
      </Divider>

      <Stack
      direction="row"
      useFlexGap
      className={styles['about-contributor-stack']}
      sx={{ gap: 2 }}
      >
      {entries.map((entry) => (
      <AboutContributorItem key={entry.name}>
      <Link data-testid={entry.name} href={entry.url}>
      <Typography
      sx={{ color: 'text.secondary' }}
      className={styles['about-contributor-link']}
      >
      {entry.name}
      </Typography>
      </Link>
      </AboutContributorItem>
      ))}
      </Stack>
      </AboutModalBox>
      </Modal>
      );
      }