Update error handling and UI design across multiple files

Enhanced error handling in documentation and blog pages, to ensure smoother running and user experience. This also includes additional UI updates related to font selection, layout arrangement, and interactive elements on error pages, marketing pages, and general site navigation components. Moreover, a "contact us" feature has been added to error pages to help users seek assistance more conveniently.
This commit is contained in:
gbuomprisco
2024-07-18 09:18:16 +02:00
parent 56dfcb872b
commit 1876bbd9e4
17 changed files with 129 additions and 54 deletions

View File

@@ -7,7 +7,7 @@ import appConfig from '~/config/app.config';
export function SiteFooter() {
return (
<footer className={'mt-auto py-8 2xl:py-16 relative w-full site-footer'}>
<footer className={'site-footer relative mt-auto w-full py-8 2xl:py-16'}>
<div className={'container'}>
<div className={'flex flex-col space-y-8 lg:flex-row lg:space-y-0'}>
<div

View File

@@ -9,7 +9,7 @@ export function SiteHeader(props: { user?: User | null }) {
return (
<div
className={
'sticky top-0 z-10 w-full bg-background/80 backdrop-blur-md dark:bg-background/50 py-2 site-header'
'site-header sticky top-0 z-10 w-full bg-background/80 py-2 backdrop-blur-md dark:bg-background/50'
}
>
<div className={'container'}>

View File

@@ -12,8 +12,7 @@ const getClassName = (path: string, currentPathName: string) => {
return cn(
`text-sm font-medium px-2.5 py-2 border rounded-lg border-transparent transition-colors duration-100`,
{
'dark:text-gray-300 dark:hover:text-white':
!isActive,
'dark:text-gray-300 dark:hover:text-white': !isActive,
'dark:text-white text-current': isActive,
},
);

View File

@@ -33,7 +33,7 @@ const links = {
Contact: {
label: 'marketing:contact',
path: '/contact',
}
},
};
export function SiteNavigation() {
@@ -48,7 +48,11 @@ export function SiteNavigation() {
return (
<>
<div className={'hidden items-center justify-center md:flex'}>
<NavigationMenu className={'border border-gray-100 dark:border-primary/10 rounded-full py-2 px-4'}>
<NavigationMenu
className={
'rounded-full border border-gray-100 px-4 py-2 dark:border-primary/10'
}
>
<NavigationMenuList className={'space-x-1'}>
{NavItems}
</NavigationMenuList>

View File

@@ -8,11 +8,19 @@ export function SitePageHeader(props: {
return (
<div className={cn('border-b py-8 xl:py-10 2xl:py-12', props.className)}>
<div className={'container flex flex-col space-y-2 lg:space-y-4'}>
<h1 className={'font-medium font-heading text-3xl xl:text-5xl dark:text-white tracking-tight'}>
<h1
className={
'font-heading text-3xl font-medium tracking-tight dark:text-white xl:text-5xl'
}
>
{props.title}
</h1>
<h2 className={'text-lg text-muted-foreground 2xl:text-2xl tracking-tight'}>
<h2
className={
'text-lg tracking-tight text-muted-foreground 2xl:text-2xl'
}
>
{props.subtitle}
</h2>
</div>

View File

@@ -12,7 +12,11 @@ export function PostHeader({ post }: { post: Cms.ContentItem }) {
<div className={'flex flex-1 flex-col'}>
<div className={cn('border-b py-8')}>
<div className={'mx-auto flex max-w-3xl flex-col space-y-4'}>
<h1 className={'font-heading text-3xl font-semibold xl:text-5xl dark:text-white'}>
<h1
className={
'font-heading text-3xl font-semibold dark:text-white xl:text-5xl'
}
>
{title}
</h1>

View File

@@ -1,6 +1,7 @@
import { cache } from 'react';
import { createCmsClient } from '@kit/cms';
import { getLogger } from '@kit/shared/logger';
import { If } from '@kit/ui/if';
import { Trans } from '@kit/ui/trans';
@@ -24,8 +25,10 @@ export const generateMetadata = async () => {
const getContentItems = cache(
async (language: string | undefined, limit: number, offset: number) => {
const client = await createCmsClient();
const logger = await getLogger();
return client.getContentItems({
try {
return await client.getContentItems({
collection: 'posts',
limit,
offset,
@@ -33,6 +36,11 @@ const getContentItems = cache(
sortBy: 'publishedAt',
sortDirection: 'desc',
});
} catch (error) {
logger.error({ error }, 'Failed to load blog posts');
return { total: 0, items: [] };
}
},
);

View File

@@ -1,6 +1,7 @@
import { cache } from 'react';
import { createCmsClient } from '@kit/cms';
import { getLogger } from '@kit/shared/logger';
/**
* @name getDocs
@@ -11,12 +12,19 @@ export const getDocs = cache(docsLoader);
async function docsLoader(language: string | undefined) {
const cms = await createCmsClient();
const logger = await getLogger();
const { items: pages } = await cms.getContentItems({
try {
const data = await cms.getContentItems({
collection: 'documentation',
language,
limit: 500,
});
return pages;
return data.items;
} catch (error) {
logger.error({ error }, 'Failed to load documentation pages');
return [];
}
}

View File

@@ -11,7 +11,7 @@ async function DocsLayout({ children }: React.PropsWithChildren) {
const pages = await getDocs(resolvedLanguage);
return (
<div className={'flex container'}>
<div className={'container flex'}>
<DocsNavigation pages={buildDocumentationTree(pages)} />
{children}

View File

@@ -98,7 +98,9 @@ function Home() {
<Heading
level={3}
className={'font-sans font-normal text-muted-foreground tracking-normal'}
className={
'font-sans font-normal tracking-normal text-muted-foreground'
}
>
Secure and Easy-to-Use Authentication for Your SaaS Website
and API
@@ -147,7 +149,9 @@ function Home() {
<Heading
level={3}
className={'font-sans font-normal text-muted-foreground tracking-normal'}
className={
'font-sans font-normal tracking-normal text-muted-foreground'
}
>
A fantastic dashboard to manage your SaaS business
</Heading>
@@ -174,7 +178,9 @@ function Home() {
<Heading
level={3}
className={'font-sans font-normal text-muted-foreground tracking-normal'}
className={
'font-sans font-normal tracking-normal text-muted-foreground'
}
>
A powerful billing system for your SaaS business
</Heading>
@@ -300,7 +306,7 @@ function MainCallToActionButton() {
return (
<div className={'flex space-x-4'}>
<Button
className={'h-12 px-4 rounded-xl text-base font-semibold'}
className={'h-12 rounded-xl px-4 text-base font-semibold'}
asChild
>
<Link href={'/auth/sign-up'}>
@@ -321,7 +327,7 @@ function MainCallToActionButton() {
<Button
variant={'link'}
className={'h-12 px-4 rounded-xl text-base font-semibold'}
className={'h-12 rounded-xl px-4 text-base font-semibold'}
asChild
>
<Link href={'/contact'}>

View File

@@ -1,6 +1,8 @@
'use client';
import { ArrowLeft } from 'lucide-react';
import Link from 'next/link';
import { ArrowLeft, MessageCircle } from 'lucide-react';
import { useCaptureException } from '@kit/monitoring/hooks';
import { Button } from '@kit/ui/button';
@@ -27,32 +29,44 @@ const ErrorPage = ({
'container m-auto flex w-full flex-1 flex-col items-center justify-center'
}
>
<div className={'flex flex-col items-center space-y-16'}>
<div className={'flex flex-col items-center space-y-8'}>
<div>
<h1 className={'font-heading text-9xl font-extrabold'}>
<h1 className={'font-heading text-9xl font-semibold'}>
<Trans i18nKey={'common:errorPageHeading'} />
</h1>
</div>
<div className={'flex flex-col items-center space-y-8'}>
<div className={'flex flex-col items-center space-y-2.5'}>
<div
className={
'flex max-w-xl flex-col items-center space-y-1 text-center'
}
>
<div>
<Heading level={1}>
<Heading level={2}>
<Trans i18nKey={'common:genericError'} />
</Heading>
</div>
<p className={'text-muted-foreground'}>
<p className={'text-lg text-muted-foreground'}>
<Trans i18nKey={'common:genericErrorSubHeading'} />
</p>
</div>
<div>
<Button variant={'outline'} onClick={reset}>
<div className={'flex space-x-4'}>
<Button className={'w-full'} variant={'default'} onClick={reset}>
<ArrowLeft className={'mr-2 h-4'} />
<Trans i18nKey={'common:goBack'} />
</Button>
<Button className={'w-full'} variant={'outline'} asChild>
<Link href={'/contact'}>
<MessageCircle className={'mr-2 h-4'} />
<Trans i18nKey={'common:contactUs'} />
</Link>
</Button>
</div>
</div>
</div>

View File

@@ -1,6 +1,8 @@
'use client';
import { ArrowLeft } from 'lucide-react';
import Link from 'next/link';
import { ArrowLeft, MessageCircle } from 'lucide-react';
import { useCaptureException } from '@kit/monitoring/hooks';
import { Button } from '@kit/ui/button';
@@ -29,32 +31,48 @@ const GlobalErrorPage = ({
'container m-auto flex w-full flex-1 flex-col items-center justify-center'
}
>
<div className={'flex flex-col items-center space-y-16'}>
<div className={'flex flex-col items-center space-y-8'}>
<div>
<h1 className={'font-heading text-9xl font-extrabold'}>
<h1 className={'font-heading text-9xl font-semibold'}>
<Trans i18nKey={'common:errorPageHeading'} />
</h1>
</div>
<div className={'flex flex-col items-center space-y-8'}>
<div className={'flex flex-col items-center space-y-2.5'}>
<div
className={
'flex max-w-xl flex-col items-center space-y-1 text-center'
}
>
<div>
<Heading level={1}>
<Heading level={2}>
<Trans i18nKey={'common:genericError'} />
</Heading>
</div>
<p className={'text-muted-foreground'}>
<p className={'text-lg text-muted-foreground'}>
<Trans i18nKey={'common:genericErrorSubHeading'} />
</p>
</div>
<div>
<Button variant={'outline'} onClick={reset}>
<Button
className={'w-full'}
variant={'default'}
onClick={reset}
>
<ArrowLeft className={'mr-2 h-4'} />
<Trans i18nKey={'common:goBack'} />
</Button>
<Button className={'w-full'} variant={'outline'} asChild>
<Link href={'/contact'}>
<MessageCircle className={'mr-2 h-4'} />
<Trans i18nKey={'common:contactUs'} />
</Link>
</Button>
</div>
</div>
</div>

View File

@@ -31,7 +31,9 @@ async function getGitHash() {
try {
return await getHashFromProcess();
} catch (error) {
console.warn(`[WARN] Could not find git hash: ${JSON.stringify(error)}. You may want to provide a fallback.`);
console.warn(
`[WARN] Could not find git hash: ${JSON.stringify(error)}. You may want to provide a fallback.`,
);
return '';
}

View File

@@ -211,7 +211,7 @@ function PricingItem(
<Price>
{lineItem
? formatCurrency(props.product.currency, lineItem.cost)
: props.plan.label ?? <Trans i18nKey={'billing:custom'} />}
: (props.plan.label ?? <Trans i18nKey={'billing:custom'} />)}
</Price>
<If condition={props.plan.name}>
@@ -444,7 +444,7 @@ function DefaultCheckoutButton(
<Link className={'w-full'} href={linkHref}>
<Button
size={'lg'}
className={'border-primary w-full border rounded-lg'}
className={'border-primary w-full rounded-lg border'}
variant={props.highlighted ? 'default' : 'outline'}
>
<span>

View File

@@ -27,7 +27,7 @@ export function EmailPasswordSignUpContainer({
defaultValues,
onSignUp,
emailRedirectTo,
displayTermsCheckbox
displayTermsCheckbox,
}: EmailPasswordSignUpContainerProps) {
const { captchaToken, resetCaptchaToken } = useCaptchaToken();

View File

@@ -28,7 +28,11 @@ export function createI18nSettings({
lowerCaseLng: true as const,
fallbackNS: ns,
missingInterpolationHandler: (text, value, options) => {
console.debug(`Missing interpolation value for key: ${text}`, value, options);
console.debug(
`Missing interpolation value for key: ${text}`,
value,
options,
);
},
ns,
react: {

View File

@@ -12,7 +12,7 @@ export function Heading({
return (
<h1
className={cn(
`scroll-m-20 font-heading text-3xl lg:text-4xl font-bold tracking-tight dark:text-white`,
`scroll-m-20 font-heading text-3xl font-bold tracking-tight dark:text-white lg:text-4xl`,
className,
)}
>
@@ -23,7 +23,7 @@ export function Heading({
return (
<h2
className={cn(
`scroll-m-20 pb-2 font-heading text-2xl lg:text-3xl font-semibold tracking-tight transition-colors first:mt-0`,
`scroll-m-20 pb-2 font-heading text-2xl font-semibold tracking-tight transition-colors first:mt-0 lg:text-3xl`,
className,
)}
>
@@ -34,7 +34,7 @@ export function Heading({
return (
<h3
className={cn(
'scroll-m-20 font-heading text-xl lg:text-2xl font-semibold tracking-tight',
'scroll-m-20 font-heading text-xl font-semibold tracking-tight lg:text-2xl',
className,
)}
>
@@ -45,7 +45,7 @@ export function Heading({
return (
<h4
className={cn(
'scroll-m-20 font-heading text-lg lg:text-xl font-semibold tracking-tight',
'scroll-m-20 font-heading text-lg font-semibold tracking-tight lg:text-xl',
className,
)}
>
@@ -56,7 +56,7 @@ export function Heading({
return (
<h5
className={cn(
'scroll-m-20 font-heading text-base lg:text-lg font-medium',
'scroll-m-20 font-heading text-base font-medium lg:text-lg',
className,
)}
>