️(frontend) structure 5xx error alerts

Use h1/p for 500/502/503; pass status from doc and version views.
This commit is contained in:
Cyril
2026-03-25 11:53:47 +01:00
parent ff176d67ae
commit 31fea43729
7 changed files with 68 additions and 0 deletions

View File

@@ -12,6 +12,10 @@ and this project adheres to
- 🐛(frontend) abort check media status unmount #2194 - 🐛(frontend) abort check media status unmount #2194
- ✨(backend) order pinned documents by last updated at #2028 - ✨(backend) order pinned documents by last updated at #2028
### Changed
- ♿️(frontend) structure correctly 5xx error alerts #2128
## [v4.8.6] - 2026-04-08 ## [v4.8.6] - 2026-04-08
### Added ### Added

View File

@@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next';
import styled from 'styled-components'; import styled from 'styled-components';
import { Box, Text, TextType } from '@/components'; import { Box, Text, TextType } from '@/components';
import { useHttpErrorMessages } from '@/hooks';
const AlertStyled = styled(Alert)` const AlertStyled = styled(Alert)`
& .c__button--tertiary:hover { & .c__button--tertiary:hover {
@@ -16,6 +17,7 @@ interface TextErrorsProps extends TextType {
defaultMessage?: string; defaultMessage?: string;
icon?: ReactNode; icon?: ReactNode;
canClose?: boolean; canClose?: boolean;
status?: number;
} }
export const TextErrors = ({ export const TextErrors = ({
@@ -23,6 +25,7 @@ export const TextErrors = ({
defaultMessage, defaultMessage,
icon, icon,
canClose = false, canClose = false,
status,
...textProps ...textProps
}: TextErrorsProps) => { }: TextErrorsProps) => {
return ( return (
@@ -35,6 +38,7 @@ export const TextErrors = ({
<TextOnlyErrors <TextOnlyErrors
causes={causes} causes={causes}
defaultMessage={defaultMessage} defaultMessage={defaultMessage}
status={status}
{...textProps} {...textProps}
/> />
</AlertStyled> </AlertStyled>
@@ -44,9 +48,39 @@ export const TextErrors = ({
export const TextOnlyErrors = ({ export const TextOnlyErrors = ({
causes, causes,
defaultMessage, defaultMessage,
status,
...textProps ...textProps
}: TextErrorsProps) => { }: TextErrorsProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const httpError = useHttpErrorMessages(status);
if (httpError) {
return (
<Box $direction="column" $gap="0.2rem">
<Text
as="h1"
$theme="error"
$textAlign="center"
$margin="0"
$size="1rem"
$weight="unset"
{...textProps}
>
{httpError.title}
</Text>
<Text
as="p"
$theme="error"
$textAlign="center"
$margin="0"
$size="0.875rem"
{...textProps}
>
{httpError.detail}
</Text>
</Box>
);
}
return ( return (
<Box $direction="column" $gap="0.2rem"> <Box $direction="column" $gap="0.2rem">

View File

@@ -58,6 +58,7 @@ export const DocVersionEditor = ({
<Box $margin="large" className="--docs--doc-version-editor-error"> <Box $margin="large" className="--docs--doc-version-editor-error">
<TextErrors <TextErrors
causes={error.cause} causes={error.cause}
status={error.status}
icon={ icon={
error.status === 502 ? ( error.status === 502 ? (
<Text <Text

View File

@@ -62,6 +62,7 @@ const VersionListState = ({
> >
<TextErrors <TextErrors
causes={error.cause} causes={error.cause}
status={error.status}
icon={ icon={
error.status === 502 ? ( error.status === 502 ? (
<Icon iconName="wifi_off" $theme="danger" /> <Icon iconName="wifi_off" $theme="danger" />

View File

@@ -1,4 +1,5 @@
export * from './useClipboard'; export * from './useClipboard';
export * from './useCmdK'; export * from './useCmdK';
export * from './useDate'; export * from './useDate';
export * from './useHttpErrorMessages';
export * from './useKeyboardAction'; export * from './useKeyboardAction';

View File

@@ -0,0 +1,26 @@
import { useTranslation } from 'react-i18next';
export const useHttpErrorMessages = (status?: number) => {
const { t } = useTranslation();
const messages: Record<number, { title: string; detail: string }> = {
500: {
title: t('500 - Internal Server Error'),
detail: t('The server met an unexpected condition.'),
},
502: {
title: t('502 - Bad Gateway'),
detail: t(
'The server received an invalid response. Please check your connection and try again.',
),
},
503: {
title: t('503 - Service Unavailable'),
detail: t(
'The service is temporarily unavailable. Please try again later.',
),
},
};
return status ? messages[status] : undefined;
};

View File

@@ -220,6 +220,7 @@ const DocPage = ({ id }: DocProps) => {
<Box $margin="large"> <Box $margin="large">
<TextErrors <TextErrors
causes={error.cause} causes={error.cause}
status={error.status}
icon={ icon={
error.status === 502 ? ( error.status === 502 ? (
<Icon iconName="wifi_off" $theme="danger" $withThemeInherited /> <Icon iconName="wifi_off" $theme="danger" $withThemeInherited />