123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- import {Fragment} from 'react';
- import styled from '@emotion/styled';
- import Hook from 'sentry/components/hook';
- import ExternalLink from 'sentry/components/links/externalLink';
- import {IconSentry} from 'sentry/icons';
- import {t} from 'sentry/locale';
- import ConfigStore from 'sentry/stores/configStore';
- import {useLegacyStore} from 'sentry/stores/useLegacyStore';
- import space from 'sentry/styles/space';
- import getDynamicText from 'sentry/utils/getDynamicText';
- type Props = {
- className?: string;
- };
- function BaseFooter({className}: Props) {
- const {isSelfHosted, version, privacyUrl, termsUrl, demoMode} =
- useLegacyStore(ConfigStore);
- return (
- <footer className={className}>
- <LeftLinks>
- {isSelfHosted && (
- <Fragment>
- {'Sentry '}
- {getDynamicText({
- fixed: 'Acceptance Test',
- value: version.current,
- })}
- <Build>
- {getDynamicText({
- fixed: 'test',
- value: version.build.substring(0, 7),
- })}
- </Build>
- </Fragment>
- )}
- {privacyUrl && <FooterLink href={privacyUrl}>{t('Privacy Policy')}</FooterLink>}
- {termsUrl && <FooterLink href={termsUrl}>{t('Terms of Use')}</FooterLink>}
- </LeftLinks>
- <LogoLink />
- <RightLinks>
- {!isSelfHosted && (
- <FooterLink href="https://status.sentry.io/">{t('Service Status')}</FooterLink>
- )}
- <FooterLink href="/api/">{t('API')}</FooterLink>
- <FooterLink href="/docs/">{t('Docs')}</FooterLink>
- <FooterLink href="https://github.com/getsentry/sentry">
- {t('Contribute')}
- </FooterLink>
- {isSelfHosted && !demoMode && (
- <FooterLink href="/out/">{t('Migrate to SaaS')}</FooterLink>
- )}
- </RightLinks>
- <Hook name="footer" />
- </footer>
- );
- }
- const LeftLinks = styled('div')`
- display: grid;
- grid-auto-flow: column;
- grid-auto-columns: max-content;
- align-items: center;
- justify-self: flex-start;
- gap: ${space(2)};
- `;
- const RightLinks = styled('div')`
- display: grid;
- grid-auto-flow: column;
- grid-auto-columns: max-content;
- align-items: center;
- justify-self: flex-end;
- gap: ${space(2)};
- `;
- const FooterLink = styled(ExternalLink)`
- color: ${p => p.theme.subText};
- &.focus-visible {
- outline: none;
- box-shadow: ${p => p.theme.blue300} 0 2px 0;
- }
- `;
- const LogoLink = styled(props => (
- <ExternalLink href="https://sentry.io/welcome/" tabIndex={-1} {...props}>
- <IconSentry size="lg" />
- </ExternalLink>
- ))`
- display: flex;
- align-items: center;
- margin: 0 auto;
- color: ${p => p.theme.subText};
- `;
- const Build = styled('span')`
- font-size: ${p => p.theme.fontSizeRelativeSmall};
- color: ${p => p.theme.subText};
- font-weight: bold;
- margin-left: ${space(1)};
- `;
- const Footer = styled(BaseFooter)`
- display: grid;
- grid-template-columns: 1fr 1fr 1fr;
- color: ${p => p.theme.subText};
- font-size: ${p => p.theme.fontSizeMedium};
- border-top: 1px solid ${p => p.theme.border};
- align-content: center;
- padding: ${space(2)} ${space(4)};
- margin-top: auto; /* pushes footer to the bottom of the page when loading */
- @media (max-width: ${p => p.theme.breakpoints.medium}) {
- padding: ${space(2)};
- }
- @media (max-width: ${p => p.theme.breakpoints.small}) {
- display: none;
- }
- `;
- export default Footer;
|