create-alistt69-kit 0.1.14 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/features/eslint/files/eslint.config.mjs +1 -1
- package/src/features/react-router/files/src/app/App.tsx +7 -4
- package/src/features/react-router/files/src/app/layouts/app/index.tsx +30 -27
- package/src/features/react-router/files/src/app/providers/error-boundary/lib/provider/index.tsx +44 -0
- package/src/features/react-router/files/src/app/providers/error-boundary/ui/error-screen/index.tsx +151 -0
- package/src/features/react-router/files/src/app/providers/index.ts +7 -0
- package/src/features/react-router/files/src/app/providers/router/lib/provider/index.tsx +10 -0
- package/src/features/react-router/files/src/app/providers/router/{config/router.tsx → lib/router/index.tsx} +4 -4
- package/src/features/react-router/files/src/index.tsx +19 -0
- package/src/templates/base/src/app/providers/error-boundary/lib/provider/index.tsx +44 -0
- package/src/templates/base/src/app/providers/error-boundary/ui/error-screen/index.tsx +151 -0
- package/src/templates/base/src/app/providers/index.ts +5 -0
- package/src/templates/base/src/index.tsx +5 -2
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
2
|
import Logo from '../../public/create-alistt69-kit-logo.svg';
|
|
3
|
-
import { appRouter } from './providers/router/config/router';
|
|
4
3
|
import styles from './styles.module.scss';
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
interface AppProps {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function App({ children }: AppProps) {
|
|
7
10
|
return (
|
|
8
11
|
<div className={styles.app_wrapper}>
|
|
9
12
|
<div className={styles.created_by_section}>
|
|
@@ -12,7 +15,7 @@ function App() {
|
|
|
12
15
|
created by create-alistt69-kit
|
|
13
16
|
</p>
|
|
14
17
|
</div>
|
|
15
|
-
|
|
18
|
+
{children}
|
|
16
19
|
</div>
|
|
17
20
|
);
|
|
18
21
|
}
|
|
@@ -1,36 +1,39 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import { NavLink, Outlet } from 'react-router-dom';
|
|
3
|
+
import { AppErrorBoundary } from '@/app/providers';
|
|
3
4
|
import styles from './styles.module.scss';
|
|
4
5
|
|
|
5
6
|
export default function AppLayout() {
|
|
6
7
|
return (
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
8
|
+
<AppErrorBoundary>
|
|
9
|
+
<div className={styles.layout_wrapper}>
|
|
10
|
+
<aside className={styles.sidebar}>
|
|
11
|
+
<nav>
|
|
12
|
+
<NavLink
|
|
13
|
+
className={({ isActive }) => clsx({
|
|
14
|
+
[styles.active]: isActive,
|
|
15
|
+
})}
|
|
16
|
+
to="/"
|
|
17
|
+
>
|
|
18
|
+
Main
|
|
19
|
+
</NavLink>
|
|
20
|
+
</nav>
|
|
21
|
+
<nav>
|
|
22
|
+
<NavLink
|
|
23
|
+
className={({ isActive }) => clsx({
|
|
24
|
+
[styles.active]: isActive,
|
|
25
|
+
})}
|
|
26
|
+
to="/error-route"
|
|
27
|
+
>
|
|
28
|
+
Error
|
|
29
|
+
</NavLink>
|
|
30
|
+
</nav>
|
|
31
|
+
</aside>
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
<main>
|
|
34
|
+
<Outlet />
|
|
35
|
+
</main>
|
|
36
|
+
</div>
|
|
37
|
+
</AppErrorBoundary>
|
|
35
38
|
);
|
|
36
39
|
}
|
package/src/features/react-router/files/src/app/providers/error-boundary/lib/provider/index.tsx
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Component, ErrorInfo, ReactNode } from 'react';
|
|
2
|
+
import ErrorScreen from '../../ui/error-screen';
|
|
3
|
+
|
|
4
|
+
type ErrorBoundaryProps = {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type ErrorBoundaryState = {
|
|
9
|
+
hasError: boolean;
|
|
10
|
+
error: Error | null;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
14
|
+
constructor(props: ErrorBoundaryProps) {
|
|
15
|
+
super(props);
|
|
16
|
+
this.state = { hasError: false, error: null };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static getDerivedStateFromError(error: Error) {
|
|
20
|
+
return {
|
|
21
|
+
hasError: true,
|
|
22
|
+
error,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
27
|
+
console.error('ErrorBoundary caught:', error, errorInfo);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public render(): ReactNode {
|
|
31
|
+
if (this.state.hasError) {
|
|
32
|
+
return (
|
|
33
|
+
<ErrorScreen
|
|
34
|
+
errorMessage={this.state.error?.message}
|
|
35
|
+
onRetry={() => window.location.reload()}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return this.props.children;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default ErrorBoundary;
|
package/src/features/react-router/files/src/app/providers/error-boundary/ui/error-screen/index.tsx
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
type ErrorScreenProps = {
|
|
2
|
+
title?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
errorMessage?: string;
|
|
5
|
+
onRetry?: () => void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
function ErrorScreen({
|
|
9
|
+
title = 'Something went wrong',
|
|
10
|
+
description = 'An unexpected error occurred. Try again or reload the page.',
|
|
11
|
+
errorMessage,
|
|
12
|
+
onRetry,
|
|
13
|
+
}: ErrorScreenProps) {
|
|
14
|
+
return (
|
|
15
|
+
<main
|
|
16
|
+
style={{
|
|
17
|
+
minHeight: '100vh',
|
|
18
|
+
display: 'grid',
|
|
19
|
+
placeItems: 'center',
|
|
20
|
+
padding: '24px',
|
|
21
|
+
background:
|
|
22
|
+
'radial-gradient(circle at top, rgba(255,255,255,0.06), transparent 40%), #0b0d12',
|
|
23
|
+
color: '#f5f7fa',
|
|
24
|
+
}}
|
|
25
|
+
>
|
|
26
|
+
<section
|
|
27
|
+
style={{
|
|
28
|
+
width: '100%',
|
|
29
|
+
maxWidth: '560px',
|
|
30
|
+
padding: '32px',
|
|
31
|
+
borderRadius: '24px',
|
|
32
|
+
border: '1px solid rgba(255,255,255,0.08)',
|
|
33
|
+
background: 'rgba(255,255,255,0.04)',
|
|
34
|
+
backdropFilter: 'blur(12px)',
|
|
35
|
+
boxShadow: '0 20px 80px rgba(0,0,0,0.35)',
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
<div
|
|
39
|
+
style={{
|
|
40
|
+
width: '56px',
|
|
41
|
+
height: '56px',
|
|
42
|
+
borderRadius: '16px',
|
|
43
|
+
display: 'grid',
|
|
44
|
+
placeItems: 'center',
|
|
45
|
+
fontSize: '28px',
|
|
46
|
+
background: 'rgba(255,255,255,0.08)',
|
|
47
|
+
marginBottom: '20px',
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
⚠️
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<h1
|
|
54
|
+
style={{
|
|
55
|
+
margin: 0,
|
|
56
|
+
fontSize: '32px',
|
|
57
|
+
lineHeight: 1.1,
|
|
58
|
+
fontWeight: 700,
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
{title}
|
|
62
|
+
</h1>
|
|
63
|
+
|
|
64
|
+
<p
|
|
65
|
+
style={{
|
|
66
|
+
marginTop: '12px',
|
|
67
|
+
marginBottom: 0,
|
|
68
|
+
fontSize: '16px',
|
|
69
|
+
lineHeight: 1.6,
|
|
70
|
+
color: 'rgba(245,247,250,0.78)',
|
|
71
|
+
}}
|
|
72
|
+
>
|
|
73
|
+
{description}
|
|
74
|
+
</p>
|
|
75
|
+
|
|
76
|
+
{errorMessage ? (
|
|
77
|
+
<pre
|
|
78
|
+
style={{
|
|
79
|
+
marginTop: '20px',
|
|
80
|
+
padding: '16px',
|
|
81
|
+
overflowX: 'auto',
|
|
82
|
+
borderRadius: '16px',
|
|
83
|
+
background: 'rgba(0,0,0,0.28)',
|
|
84
|
+
border: '1px solid rgba(255,255,255,0.08)',
|
|
85
|
+
color: '#ffb4b4',
|
|
86
|
+
fontSize: '13px',
|
|
87
|
+
lineHeight: 1.5,
|
|
88
|
+
whiteSpace: 'pre-wrap',
|
|
89
|
+
wordBreak: 'break-word',
|
|
90
|
+
}}
|
|
91
|
+
>
|
|
92
|
+
{errorMessage}
|
|
93
|
+
</pre>
|
|
94
|
+
) : null}
|
|
95
|
+
|
|
96
|
+
<div
|
|
97
|
+
style={{
|
|
98
|
+
display: 'flex',
|
|
99
|
+
gap: '12px',
|
|
100
|
+
flexWrap: 'wrap',
|
|
101
|
+
marginTop: '24px',
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
{onRetry ? (
|
|
105
|
+
<button
|
|
106
|
+
type="button"
|
|
107
|
+
onClick={onRetry}
|
|
108
|
+
style={buttonPrimaryStyle}
|
|
109
|
+
>
|
|
110
|
+
Try again
|
|
111
|
+
</button>
|
|
112
|
+
) : null}
|
|
113
|
+
|
|
114
|
+
<button
|
|
115
|
+
type="button"
|
|
116
|
+
onClick={() => window.location.reload()}
|
|
117
|
+
style={buttonSecondaryStyle}
|
|
118
|
+
>
|
|
119
|
+
Reload page
|
|
120
|
+
</button>
|
|
121
|
+
</div>
|
|
122
|
+
</section>
|
|
123
|
+
</main>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const buttonBaseStyle: React.CSSProperties = {
|
|
128
|
+
appearance: 'none',
|
|
129
|
+
border: 'none',
|
|
130
|
+
cursor: 'pointer',
|
|
131
|
+
borderRadius: '14px',
|
|
132
|
+
padding: '12px 16px',
|
|
133
|
+
fontSize: '14px',
|
|
134
|
+
fontWeight: 600,
|
|
135
|
+
transition: 'transform 0.15s ease, opacity 0.15s ease',
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const buttonPrimaryStyle: React.CSSProperties = {
|
|
139
|
+
...buttonBaseStyle,
|
|
140
|
+
background: '#ffffff',
|
|
141
|
+
color: '#0b0d12',
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const buttonSecondaryStyle: React.CSSProperties = {
|
|
145
|
+
...buttonBaseStyle,
|
|
146
|
+
background: 'rgba(255,255,255,0.08)',
|
|
147
|
+
color: '#f5f7fa',
|
|
148
|
+
border: '1px solid rgba(255,255,255,0.1)',
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export default ErrorScreen;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createBrowserRouter, createRoutesFromElements, Route } from 'react-router-dom';
|
|
2
|
-
import { Error } from '
|
|
3
|
-
import { Main } from '
|
|
4
|
-
import AppLayout from '
|
|
2
|
+
import { Error } from '../../../../../pages/error';
|
|
3
|
+
import { Main } from '../../../../../pages/main';
|
|
4
|
+
import AppLayout from '../../../../layouts/app';
|
|
5
5
|
|
|
6
|
-
export const
|
|
6
|
+
export const router = createBrowserRouter(
|
|
7
7
|
createRoutesFromElements(
|
|
8
8
|
<Route path="/" element={<AppLayout />}>
|
|
9
9
|
<Route index element={<Main />} />
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { StrictMode } from 'react';
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import App from '@/app/App';
|
|
4
|
+
import { AppRouter } from '@/app/providers';
|
|
5
|
+
import './styles/index.scss';
|
|
6
|
+
|
|
7
|
+
const container = document.getElementById('root');
|
|
8
|
+
|
|
9
|
+
if (!container) {
|
|
10
|
+
throw new Error('Root container not found');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
createRoot(container).render(
|
|
14
|
+
<StrictMode>
|
|
15
|
+
<App>
|
|
16
|
+
<AppRouter />
|
|
17
|
+
</App>
|
|
18
|
+
</StrictMode>,
|
|
19
|
+
);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Component, ErrorInfo, ReactNode } from 'react';
|
|
2
|
+
import ErrorScreen from '../../ui/error-screen';
|
|
3
|
+
|
|
4
|
+
type ErrorBoundaryProps = {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type ErrorBoundaryState = {
|
|
9
|
+
hasError: boolean;
|
|
10
|
+
error: Error | null;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
14
|
+
constructor(props: ErrorBoundaryProps) {
|
|
15
|
+
super(props);
|
|
16
|
+
this.state = { hasError: false, error: null };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static getDerivedStateFromError(error: Error) {
|
|
20
|
+
return {
|
|
21
|
+
hasError: true,
|
|
22
|
+
error,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
27
|
+
console.error('ErrorBoundary caught:', error, errorInfo);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public render(): ReactNode {
|
|
31
|
+
if (this.state.hasError) {
|
|
32
|
+
return (
|
|
33
|
+
<ErrorScreen
|
|
34
|
+
errorMessage={this.state.error?.message}
|
|
35
|
+
onRetry={() => window.location.reload()}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return this.props.children;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default ErrorBoundary;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
type ErrorScreenProps = {
|
|
2
|
+
title?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
errorMessage?: string;
|
|
5
|
+
onRetry?: () => void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
function ErrorScreen({
|
|
9
|
+
title = 'Something went wrong',
|
|
10
|
+
description = 'An unexpected error occurred. Try again or reload the page.',
|
|
11
|
+
errorMessage,
|
|
12
|
+
onRetry,
|
|
13
|
+
}: ErrorScreenProps) {
|
|
14
|
+
return (
|
|
15
|
+
<main
|
|
16
|
+
style={{
|
|
17
|
+
minHeight: '100vh',
|
|
18
|
+
display: 'grid',
|
|
19
|
+
placeItems: 'center',
|
|
20
|
+
padding: '24px',
|
|
21
|
+
background:
|
|
22
|
+
'radial-gradient(circle at top, rgba(255,255,255,0.06), transparent 40%), #0b0d12',
|
|
23
|
+
color: '#f5f7fa',
|
|
24
|
+
}}
|
|
25
|
+
>
|
|
26
|
+
<section
|
|
27
|
+
style={{
|
|
28
|
+
width: '100%',
|
|
29
|
+
maxWidth: '560px',
|
|
30
|
+
padding: '32px',
|
|
31
|
+
borderRadius: '24px',
|
|
32
|
+
border: '1px solid rgba(255,255,255,0.08)',
|
|
33
|
+
background: 'rgba(255,255,255,0.04)',
|
|
34
|
+
backdropFilter: 'blur(12px)',
|
|
35
|
+
boxShadow: '0 20px 80px rgba(0,0,0,0.35)',
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
<div
|
|
39
|
+
style={{
|
|
40
|
+
width: '56px',
|
|
41
|
+
height: '56px',
|
|
42
|
+
borderRadius: '16px',
|
|
43
|
+
display: 'grid',
|
|
44
|
+
placeItems: 'center',
|
|
45
|
+
fontSize: '28px',
|
|
46
|
+
background: 'rgba(255,255,255,0.08)',
|
|
47
|
+
marginBottom: '20px',
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
⚠️
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<h1
|
|
54
|
+
style={{
|
|
55
|
+
margin: 0,
|
|
56
|
+
fontSize: '32px',
|
|
57
|
+
lineHeight: 1.1,
|
|
58
|
+
fontWeight: 700,
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
{title}
|
|
62
|
+
</h1>
|
|
63
|
+
|
|
64
|
+
<p
|
|
65
|
+
style={{
|
|
66
|
+
marginTop: '12px',
|
|
67
|
+
marginBottom: 0,
|
|
68
|
+
fontSize: '16px',
|
|
69
|
+
lineHeight: 1.6,
|
|
70
|
+
color: 'rgba(245,247,250,0.78)',
|
|
71
|
+
}}
|
|
72
|
+
>
|
|
73
|
+
{description}
|
|
74
|
+
</p>
|
|
75
|
+
|
|
76
|
+
{errorMessage ? (
|
|
77
|
+
<pre
|
|
78
|
+
style={{
|
|
79
|
+
marginTop: '20px',
|
|
80
|
+
padding: '16px',
|
|
81
|
+
overflowX: 'auto',
|
|
82
|
+
borderRadius: '16px',
|
|
83
|
+
background: 'rgba(0,0,0,0.28)',
|
|
84
|
+
border: '1px solid rgba(255,255,255,0.08)',
|
|
85
|
+
color: '#ffb4b4',
|
|
86
|
+
fontSize: '13px',
|
|
87
|
+
lineHeight: 1.5,
|
|
88
|
+
whiteSpace: 'pre-wrap',
|
|
89
|
+
wordBreak: 'break-word',
|
|
90
|
+
}}
|
|
91
|
+
>
|
|
92
|
+
{errorMessage}
|
|
93
|
+
</pre>
|
|
94
|
+
) : null}
|
|
95
|
+
|
|
96
|
+
<div
|
|
97
|
+
style={{
|
|
98
|
+
display: 'flex',
|
|
99
|
+
gap: '12px',
|
|
100
|
+
flexWrap: 'wrap',
|
|
101
|
+
marginTop: '24px',
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
{onRetry ? (
|
|
105
|
+
<button
|
|
106
|
+
type="button"
|
|
107
|
+
onClick={onRetry}
|
|
108
|
+
style={buttonPrimaryStyle}
|
|
109
|
+
>
|
|
110
|
+
Try again
|
|
111
|
+
</button>
|
|
112
|
+
) : null}
|
|
113
|
+
|
|
114
|
+
<button
|
|
115
|
+
type="button"
|
|
116
|
+
onClick={() => window.location.reload()}
|
|
117
|
+
style={buttonSecondaryStyle}
|
|
118
|
+
>
|
|
119
|
+
Reload page
|
|
120
|
+
</button>
|
|
121
|
+
</div>
|
|
122
|
+
</section>
|
|
123
|
+
</main>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const buttonBaseStyle: React.CSSProperties = {
|
|
128
|
+
appearance: 'none',
|
|
129
|
+
border: 'none',
|
|
130
|
+
cursor: 'pointer',
|
|
131
|
+
borderRadius: '14px',
|
|
132
|
+
padding: '12px 16px',
|
|
133
|
+
fontSize: '14px',
|
|
134
|
+
fontWeight: 600,
|
|
135
|
+
transition: 'transform 0.15s ease, opacity 0.15s ease',
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const buttonPrimaryStyle: React.CSSProperties = {
|
|
139
|
+
...buttonBaseStyle,
|
|
140
|
+
background: '#ffffff',
|
|
141
|
+
color: '#0b0d12',
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const buttonSecondaryStyle: React.CSSProperties = {
|
|
145
|
+
...buttonBaseStyle,
|
|
146
|
+
background: 'rgba(255,255,255,0.08)',
|
|
147
|
+
color: '#f5f7fa',
|
|
148
|
+
border: '1px solid rgba(255,255,255,0.1)',
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export default ErrorScreen;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { StrictMode } from 'react';
|
|
2
2
|
import { createRoot } from 'react-dom/client';
|
|
3
|
-
import App from '
|
|
3
|
+
import App from '@/app/App';
|
|
4
|
+
import { AppErrorBoundary } from '@/app/providers';
|
|
4
5
|
import './styles/index.scss';
|
|
5
6
|
|
|
6
7
|
const container = document.getElementById('root');
|
|
@@ -11,6 +12,8 @@ if (!container) {
|
|
|
11
12
|
|
|
12
13
|
createRoot(container).render(
|
|
13
14
|
<StrictMode>
|
|
14
|
-
<
|
|
15
|
+
<AppErrorBoundary>
|
|
16
|
+
<App />
|
|
17
|
+
</AppErrorBoundary>
|
|
15
18
|
</StrictMode>,
|
|
16
19
|
);
|