Skip to content

Commit 893bcce

Browse files
authored
feat: 各種エラー画面を追加 (#6274)
1 parent ba26009 commit 893bcce

23 files changed

Lines changed: 606 additions & 3 deletions
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use client'
2+
3+
import { useIntl } from '../../intl'
4+
5+
import { ErrorScreen } from './ErrorScreen'
6+
7+
import type { FC } from 'react'
8+
9+
type Props = {
10+
smarthrUrl: string
11+
}
12+
13+
export const AuthErrorScreen: FC<Props> = ({ smarthrUrl }) => {
14+
const { localize } = useIntl()
15+
16+
return (
17+
<ErrorScreen
18+
title={localize({
19+
id: 'smarthr-ui/AuthErrorScreen/title',
20+
defaultText: '認証で問題が発生しました',
21+
})}
22+
links={[
23+
{
24+
label: localize({
25+
id: 'smarthr-ui/ErrorScreen/smarthrLink',
26+
defaultText: 'SmartHR に戻る',
27+
}),
28+
url: smarthrUrl,
29+
},
30+
]}
31+
/>
32+
)
33+
}

packages/smarthr-ui/src/components/ErrorScreen/ErrorScreen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type AbstractProps = {
2828
type Props = AbstractProps & Omit<ComponentPropsWithoutRef<'div'>, keyof AbstractProps>
2929

3030
const classNameGenerator = tv({
31-
base: 'smarthr-ui-ErrorScreen shr-bg-background',
31+
base: 'smarthr-ui-ErrorScreen shr-box-border shr-bg-background shr-p-1.5',
3232
})
3333

3434
export const ErrorScreen: FC<Props> = ({ logo, title, links, children, className, ...rest }) => {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use client'
2+
3+
import { useIntl } from '../../intl'
4+
5+
import { ErrorScreen } from './ErrorScreen'
6+
7+
import type { FC } from 'react'
8+
9+
type Props = {
10+
homeUrl: string
11+
}
12+
13+
export const ForbiddenErrorScreen: FC<Props> = ({ homeUrl }) => {
14+
const { localize } = useIntl()
15+
16+
return (
17+
<ErrorScreen
18+
title={localize({
19+
id: 'smarthr-ui/ForbiddenErrorScreen/title',
20+
defaultText: 'このページを表示する権限がありません',
21+
})}
22+
links={[
23+
{
24+
label: localize({
25+
id: 'smarthr-ui/ErrorScreen/homeLink',
26+
defaultText: 'ホームに戻る',
27+
}),
28+
url: homeUrl,
29+
},
30+
]}
31+
>
32+
<p>
33+
{localize({
34+
id: 'smarthr-ui/ForbiddenErrorScreen/description',
35+
defaultText: '詳しくは、所属企業の担当者にお問い合わせください。',
36+
})}
37+
</p>
38+
</ErrorScreen>
39+
)
40+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use client'
2+
3+
import { useIntl } from '../../intl'
4+
5+
import { ErrorScreen } from './ErrorScreen'
6+
7+
import type { FC } from 'react'
8+
9+
type Props = {
10+
homeUrl: string
11+
}
12+
13+
export const NotFoundErrorScreen: FC<Props> = ({ homeUrl }) => {
14+
const { localize } = useIntl()
15+
16+
return (
17+
<ErrorScreen
18+
title={localize({
19+
id: 'smarthr-ui/NotFoundErrorScreen/title',
20+
defaultText: 'お探しのページは見つかりませんでした',
21+
})}
22+
links={[
23+
{
24+
label: localize({
25+
id: 'smarthr-ui/ErrorScreen/homeLink',
26+
defaultText: 'ホームに戻る',
27+
}),
28+
url: homeUrl,
29+
},
30+
]}
31+
>
32+
<p>
33+
{localize({
34+
id: 'smarthr-ui/NotFoundErrorScreen/description',
35+
defaultText:
36+
'お探しのページは一時的にアクセスができない状況にあるか、移動もしくは削除された可能性があります。',
37+
})}
38+
</p>
39+
</ErrorScreen>
40+
)
41+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use client'
2+
3+
import { useIntl } from '../../intl'
4+
import { Button } from '../Button'
5+
import { Center } from '../Layout'
6+
7+
import { ErrorScreen } from './ErrorScreen'
8+
9+
import type { FC } from 'react'
10+
11+
type Props = {
12+
onClickLogin: () => void
13+
isLoading: boolean
14+
}
15+
16+
export const UnauthorizedErrorScreen: FC<Props> = ({ onClickLogin, isLoading }) => {
17+
const { localize } = useIntl()
18+
19+
return (
20+
<ErrorScreen
21+
title={localize({
22+
id: 'smarthr-ui/UnauthorizedErrorScreen/title',
23+
defaultText: '一定時間操作がなかったためログアウトしました',
24+
})}
25+
>
26+
<p>
27+
{localize({
28+
id: 'smarthr-ui/UnauthorizedErrorScreen/description1',
29+
defaultText: '一定時間操作がなかったため、自動でログアウトしました。',
30+
})}
31+
<br />
32+
{localize({
33+
id: 'smarthr-ui/UnauthorizedErrorScreen/description2',
34+
defaultText: '指定のページにアクセスするには、再度ログインが必要です。',
35+
})}
36+
</p>
37+
<Center>
38+
<Button className="shr-mt-1.5" onClick={onClickLogin} loading={isLoading}>
39+
{localize({
40+
id: 'smarthr-ui/UnauthorizedErrorScreen/reLoginButton',
41+
defaultText: '再ログイン',
42+
})}
43+
</Button>
44+
</Center>
45+
</ErrorScreen>
46+
)
47+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
'use client'
2+
3+
import { Localizer, useIntl } from '../../intl'
4+
import { Stack } from '../Layout'
5+
import { HelpLink } from '../TextLink'
6+
7+
import { ErrorScreen } from './ErrorScreen'
8+
9+
import type { FC } from 'react'
10+
11+
type Props = {
12+
homeUrl: string
13+
}
14+
15+
export const UnexpectedErrorScreen: FC<Props> = ({ homeUrl }) => {
16+
const { localize } = useIntl()
17+
18+
return (
19+
<ErrorScreen
20+
title={localize({
21+
id: 'smarthr-ui/UnexpectedErrorScreen/title',
22+
defaultText: '予期しないエラーが発生しました',
23+
})}
24+
links={[
25+
{
26+
label: localize({
27+
id: 'smarthr-ui/ErrorScreen/homeLink',
28+
defaultText: 'ホームに戻る',
29+
}),
30+
url: homeUrl,
31+
},
32+
]}
33+
>
34+
<Stack className="shr-max-w-col6">
35+
<p>
36+
{localize({
37+
id: 'smarthr-ui/UnexpectedErrorScreen/apology',
38+
defaultText: '大変申し訳ございません。',
39+
})}
40+
<br />
41+
{localize({
42+
id: 'smarthr-ui/UnexpectedErrorScreen/possibleCause',
43+
defaultText:
44+
'一時的な通信の問題や、ご利用環境、アップロードしたファイルの内容などによりエラーが発生している可能性があります。',
45+
})}
46+
</p>
47+
<p>
48+
{localize({
49+
id: 'smarthr-ui/UnexpectedErrorScreen/pleaseRetry',
50+
defaultText: 'お手数ですが、以下をお試しください。',
51+
})}
52+
</p>
53+
<ol className="shr-ps-[1.5em]">
54+
<li>
55+
{localize({
56+
id: 'smarthr-ui/UnexpectedErrorScreen/retryItem1',
57+
defaultText: '少し時間をおいて、再度お試しください。',
58+
})}
59+
</li>
60+
<li>
61+
<Localizer
62+
id="smarthr-ui/UnexpectedErrorScreen/retryItem2"
63+
defaultText="{maintenanceLink}をご確認ください(情報の掲載まで時間がかかる場合があります)。"
64+
values={{
65+
maintenanceLink: (
66+
<HelpLink href="https://support.smarthr.jp/ja/info/status/page/1/">
67+
メンテナンス・障害情報
68+
</HelpLink>
69+
),
70+
}}
71+
/>
72+
</li>
73+
</ol>
74+
<p>
75+
{localize({
76+
id: 'smarthr-ui/UnexpectedErrorScreen/ifNotResolved',
77+
defaultText: '解消しない場合は、以下もご確認ください。',
78+
})}
79+
</p>
80+
<ul className="shr-ps-[1.5em]">
81+
<li>
82+
<Localizer
83+
id="smarthr-ui/UnexpectedErrorScreen/checkItem1"
84+
defaultText="{environmentLink}を満たしているかご確認ください。"
85+
values={{
86+
environmentLink: (
87+
<HelpLink href="https://support.smarthr.jp/ja/help/articles/360035170054/">
88+
SmartHRの動作環境
89+
</HelpLink>
90+
),
91+
}}
92+
/>
93+
</li>
94+
<li>
95+
<Localizer
96+
id="smarthr-ui/UnexpectedErrorScreen/checkItem2"
97+
defaultText="ブラウザのCookieとキャッシュの削除をお試しください。詳しくは、{cookieCacheLink}を参照してください。"
98+
values={{
99+
cookieCacheLink: (
100+
<HelpLink href="https://support.smarthr.jp/ja/help/articles/360026264433/">
101+
Q. ブラウザのCookieとキャッシュを削除するには?
102+
</HelpLink>
103+
),
104+
}}
105+
/>
106+
</li>
107+
</ul>
108+
<p>
109+
<Localizer
110+
id="smarthr-ui/UnexpectedErrorScreen/contactAdmin"
111+
defaultText="上記を確認しても解消しない場合は、社内の労務担当者など、SmartHRの管理者権限をお持ちの方に、{errorInfoLink}の情報を添えてご連絡ください。"
112+
values={{
113+
errorInfoLink: (
114+
<HelpLink href="https://support.smarthr.jp/ja/help/articles/360036353773/">
115+
エラー発生時に教えていただきたい内容
116+
</HelpLink>
117+
),
118+
}}
119+
/>
120+
</p>
121+
<p>
122+
<Localizer
123+
id="smarthr-ui/UnexpectedErrorScreen/adminContact"
124+
defaultText="SmartHRの管理者権限をお持ちの方は、{errorInfoLink}の情報を添えて、右下のチャットマークからお問い合わせください。"
125+
values={{
126+
errorInfoLink: (
127+
<HelpLink href="https://support.smarthr.jp/ja/help/articles/360036353773/">
128+
エラー発生時に教えていただきたい内容
129+
</HelpLink>
130+
),
131+
}}
132+
/>
133+
</p>
134+
</Stack>
135+
</ErrorScreen>
136+
)
137+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
export { ErrorScreen } from './ErrorScreen'
2+
export { UnauthorizedErrorScreen } from './UnauthorizedErrorScreen'
3+
export { ForbiddenErrorScreen } from './ForbiddenErrorScreen'
4+
export { NotFoundErrorScreen } from './NotFoundErrorScreen'
5+
export { UnexpectedErrorScreen } from './UnexpectedErrorScreen'
6+
export { AuthErrorScreen } from './AuthErrorScreen'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { AuthErrorScreen } from '../AuthErrorScreen'
2+
3+
import type { Meta, StoryObj } from '@storybook/react-vite'
4+
5+
export default {
6+
title: 'Components/ErrorScreen/AuthErrorScreen',
7+
component: AuthErrorScreen,
8+
render: (args) => <AuthErrorScreen {...args} />,
9+
args: {
10+
smarthrUrl: 'https://example.smarthr.jp',
11+
},
12+
parameters: {
13+
chromatic: { disableSnapshot: true },
14+
},
15+
} satisfies Meta<typeof AuthErrorScreen>
16+
17+
export const Playground: StoryObj<typeof AuthErrorScreen> = {
18+
args: {},
19+
}

packages/smarthr-ui/src/components/ErrorScreen/stories/ErrorScreen.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ResponseMessage } from '../../ResponseMessage'
22
import { SmartHRLogo } from '../../SmartHRLogo'
33
import { ErrorScreen } from '../ErrorScreen'
44

5-
import type { Meta, StoryObj } from '@storybook/react-webpack5'
5+
import type { Meta, StoryObj } from '@storybook/react-vite'
66

77
const logoOptions = {
88
デフォルト: undefined,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { ForbiddenErrorScreen } from '../ForbiddenErrorScreen'
2+
3+
import type { Meta, StoryObj } from '@storybook/react-vite'
4+
5+
export default {
6+
title: 'Components/ErrorScreen/ForbiddenErrorScreen',
7+
component: ForbiddenErrorScreen,
8+
render: (args) => <ForbiddenErrorScreen {...args} />,
9+
args: {
10+
homeUrl: '/',
11+
},
12+
parameters: {
13+
chromatic: { disableSnapshot: true },
14+
},
15+
} satisfies Meta<typeof ForbiddenErrorScreen>
16+
17+
export const Playground: StoryObj<typeof ForbiddenErrorScreen> = {
18+
args: {},
19+
}

0 commit comments

Comments
 (0)