781512399b
Build & Deploy / Build & Push Docker Image (push) Successful in 2m51s
Test / Type Check (all packages) (push) Successful in 52s
Build & Deploy / Deploy to VPS (push) Successful in 4s
Test / API Unit Tests (push) Successful in 49s
Test / Homepage Unit Tests (push) Successful in 44s
Test / Storefront Unit Tests (push) Successful in 39s
Test / Admin Unit Tests (push) Successful in 40s
Test / Dashboard Unit Tests (push) Successful in 40s
Test / API Integration Tests (push) Successful in 1m0s
179 lines
5.2 KiB
TypeScript
179 lines
5.2 KiB
TypeScript
import { StatusBadge } from '@/components/foundation/StatusBadge';
|
|
import { accountCreateUrl } from '@/lib/account-urls';
|
|
import { localizedModePath, type Locale } from '@/lib/localization/config';
|
|
import type { ShellMessages } from '@/lib/localization/messages';
|
|
import type { ThemePreference } from '@/lib/theme/config';
|
|
import Image from 'next/image';
|
|
import styles from './SiteFooter.module.css';
|
|
|
|
function signInUrl(locale: Locale, mode: ThemePreference): string {
|
|
return localizedModePath('sign-in', locale, mode);
|
|
}
|
|
|
|
interface SiteFooterProps {
|
|
locale: Locale;
|
|
mode: ThemePreference;
|
|
messages: ShellMessages;
|
|
}
|
|
|
|
function HashLink({
|
|
locale,
|
|
mode,
|
|
hash,
|
|
children,
|
|
}: {
|
|
locale: Locale;
|
|
mode: ThemePreference;
|
|
hash: string;
|
|
children: string;
|
|
}) {
|
|
return <a href={`${localizedModePath('home', locale, mode)}#${hash}`}>{children}</a>;
|
|
}
|
|
|
|
function PendingRouteLink({
|
|
locale,
|
|
mode,
|
|
routeId,
|
|
label,
|
|
pending,
|
|
}: {
|
|
locale: Locale;
|
|
mode: ThemePreference;
|
|
routeId: 'sign-in' | 'forgot-password' | 'privacy' | 'terms' | 'accessibility';
|
|
label: string;
|
|
pending: string;
|
|
}) {
|
|
return (
|
|
<a className={styles.legalLink} href={localizedModePath(routeId, locale, mode)}>
|
|
<span>{label}</span>
|
|
<StatusBadge>{pending}</StatusBadge>
|
|
</a>
|
|
);
|
|
}
|
|
|
|
function PendingItem({ label, pending }: { label: string; pending: string }) {
|
|
return (
|
|
<span className={styles.pendingItem} aria-disabled="true">
|
|
<span>{label}</span>
|
|
<StatusBadge>{pending}</StatusBadge>
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export function SiteFooter({ locale, mode, messages }: SiteFooterProps) {
|
|
const footer = messages.footer;
|
|
const year = new Date().getUTCFullYear();
|
|
|
|
return (
|
|
<footer className={styles.footer} aria-label={footer.landmarkLabel}>
|
|
<div className={styles.inner}>
|
|
<div className={styles.brandColumn}>
|
|
<div className={styles.brand}>
|
|
<Image
|
|
src="/rentaldrivego.png"
|
|
alt="RentalDriveGo"
|
|
width={40}
|
|
height={40}
|
|
unoptimized
|
|
className={styles.brandLogo}
|
|
/>
|
|
<span>RentalDriveGo</span>
|
|
</div>
|
|
<p className={styles.tagline}>{footer.tagline}</p>
|
|
<p className={styles.releaseNotice}>{footer.releaseNotice}</p>
|
|
</div>
|
|
|
|
<div className={styles.groups}>
|
|
<section className={styles.group} aria-labelledby="footer-product">
|
|
<h2 id="footer-product">{footer.groups.product}</h2>
|
|
<ul>
|
|
<li>
|
|
<HashLink locale={locale} mode={mode} hash="workflow">
|
|
{footer.links.workflow}
|
|
</HashLink>
|
|
</li>
|
|
<li>
|
|
<HashLink locale={locale} mode={mode} hash="modules">
|
|
{footer.links.modules}
|
|
</HashLink>
|
|
</li>
|
|
<li>
|
|
<HashLink locale={locale} mode={mode} hash="pricing">
|
|
{footer.links.pricing}
|
|
</HashLink>
|
|
</li>
|
|
<li>
|
|
<HashLink locale={locale} mode={mode} hash="faq">
|
|
{footer.links.faq}
|
|
</HashLink>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section className={styles.group} aria-labelledby="footer-company">
|
|
<h2 id="footer-company">{footer.groups.company}</h2>
|
|
<ul>
|
|
<li>
|
|
<PendingItem label={footer.links.contact} pending={footer.pending} />
|
|
</li>
|
|
<li>
|
|
<a href={accountCreateUrl(locale)}>{footer.links.demo}</a>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section className={styles.group} aria-labelledby="footer-account">
|
|
<h2 id="footer-account">{footer.groups.account}</h2>
|
|
<ul>
|
|
<li>
|
|
<a href={signInUrl(locale, mode)}>
|
|
{footer.links.login}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section className={styles.group} aria-labelledby="footer-legal">
|
|
<h2 id="footer-legal">{footer.groups.legal}</h2>
|
|
<ul>
|
|
<li>
|
|
<PendingRouteLink
|
|
locale={locale}
|
|
mode={mode}
|
|
routeId="privacy"
|
|
label={footer.links.privacy}
|
|
pending={footer.pending}
|
|
/>
|
|
</li>
|
|
<li>
|
|
<PendingRouteLink
|
|
locale={locale}
|
|
mode={mode}
|
|
routeId="terms"
|
|
label={footer.links.terms}
|
|
pending={footer.pending}
|
|
/>
|
|
</li>
|
|
<li>
|
|
<PendingRouteLink
|
|
locale={locale}
|
|
mode={mode}
|
|
routeId="accessibility"
|
|
label={footer.links.accessibility}
|
|
pending={footer.pending}
|
|
/>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
</div>
|
|
|
|
<div className={styles.bottom}>
|
|
<span>
|
|
{footer.copyrightPrefix} {year} RentalDriveGo
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
);
|
|
}
|