@undp/create-app 0.0.1

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.
Files changed (41) hide show
  1. package/bin/generateFiles.js +65 -0
  2. package/bin/generateTemplates/copyTemplate.js +18 -0
  3. package/bin/generateTemplates/generateIndexHtml.js +15 -0
  4. package/bin/generateTemplates/generatePackageJson.js +105 -0
  5. package/bin/generateTemplates/generateReadme.js +143 -0
  6. package/bin/generateTemplates/generateStyleCss.js +6 -0
  7. package/bin/generateTemplates/index.js +6 -0
  8. package/bin/generateTemplates/templates/basic/App.txt +32 -0
  9. package/bin/generateTemplates/templates/basic/AppWithContainer.txt +32 -0
  10. package/bin/generateTemplates/templates/basic/main.txt +10 -0
  11. package/bin/generateTemplates/templates/configFiles/.prettierrc +10 -0
  12. package/bin/generateTemplates/templates/configFiles/eslint.config.js +97 -0
  13. package/bin/generateTemplates/templates/configFiles/icon.txt +1 -0
  14. package/bin/generateTemplates/templates/configFiles/staticwebapp.config.json +44 -0
  15. package/bin/generateTemplates/templates/configFiles/tailwind.config.js +7 -0
  16. package/bin/generateTemplates/templates/configFiles/tsconfig.json +29 -0
  17. package/bin/generateTemplates/templates/configFiles/tsconfig.node.json +9 -0
  18. package/bin/generateTemplates/templates/configFiles/vite-env.txt +1 -0
  19. package/bin/generateTemplates/templates/configFiles/vite.config.ts.txt +109 -0
  20. package/bin/generateTemplates/templates/configFiles/viteWithoutPostCss.config.ts.txt +58 -0
  21. package/bin/generateTemplates/templates/css/fonts.css +213 -0
  22. package/bin/generateTemplates/templates/query/App.txt +57 -0
  23. package/bin/generateTemplates/templates/query/AppWithContainer.txt +67 -0
  24. package/bin/generateTemplates/templates/query/main.txt +29 -0
  25. package/bin/generateTemplates/templates/router/App.txt +30 -0
  26. package/bin/generateTemplates/templates/router/components/Footer.txt +20 -0
  27. package/bin/generateTemplates/templates/router/components/Header.txt +29 -0
  28. package/bin/generateTemplates/templates/router/main.txt +60 -0
  29. package/bin/generateTemplates/templates/router/routes/About.txt +28 -0
  30. package/bin/generateTemplates/templates/router+query/App.txt +30 -0
  31. package/bin/generateTemplates/templates/router+query/components/Footer.txt +20 -0
  32. package/bin/generateTemplates/templates/router+query/components/Header.txt +29 -0
  33. package/bin/generateTemplates/templates/router+query/integration/tanstack-query.txt +27 -0
  34. package/bin/generateTemplates/templates/router+query/main.txt +69 -0
  35. package/bin/generateTemplates/templates/router+query/routes/queryDemo.txt +56 -0
  36. package/bin/index.js +57 -0
  37. package/bin/promptUser.js +96 -0
  38. package/bin/utils/createFolders.js +11 -0
  39. package/bin/utils/index.js +2 -0
  40. package/bin/utils/printSuccess.js +23 -0
  41. package/package.json +32 -0
@@ -0,0 +1,9 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "allowSyntheticDefaultImports": true
7
+ },
8
+ "include": ["vite.config.ts"]
9
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,109 @@
1
+ import path from 'path';
2
+
3
+ import { defineConfig } from 'vite';
4
+ import react from '@vitejs/plugin-react';
5
+ import eslint from '@nabla/vite-plugin-eslint';
6
+ import { AtRule } from 'postcss';
7
+ import { visualizer } from 'rollup-plugin-visualizer';
8
+ import postcssNested from 'postcss-nested';
9
+ import tailwindcss from '@tailwindcss/postcss';
10
+ import { viteStaticCopy } from 'vite-plugin-static-copy';
11
+
12
+ export default defineConfig({
13
+ plugins: [
14
+ react({
15
+ babel: {
16
+ plugins: ['babel-plugin-react-compiler'],
17
+ },
18
+ }),
19
+ eslint(),
20
+ visualizer({ filename: 'stats.html', open: true }),
21
+ viteStaticCopy({
22
+ targets: [{ src: 'staticwebapp.config.json', dest: '' }],
23
+ }),
24
+ ],
25
+ css: {
26
+ postcss: {
27
+ plugins: [
28
+ postcssNested(),
29
+ tailwindcss(),
30
+ {
31
+ postcssPlugin: 'remove-layers', // If you want to flatten layers except base layer
32
+ AtRule: {
33
+ layer(rule) {
34
+ if (rule.params !== 'base') {
35
+ rule.each(child => {
36
+ rule.parent.insertAfter(rule, child);
37
+ });
38
+ rule.remove();
39
+ }
40
+ },
41
+ },
42
+ },
43
+ {
44
+ postcssPlugin: 'wrap-with-undp-container', // If you want to wrap all the class in .undp-container
45
+ OnceExit(root) {
46
+ const skipSelectors = ['html', 'body', ':root', ':host'];
47
+ root.walkRules(rule => {
48
+ if (rule.parent && rule.parent.type === 'atrule') {
49
+ const parent = rule.parent as AtRule;
50
+ if (parent.name === 'keyframes' || parent.name === 'supports') {
51
+ return;
52
+ }
53
+ }
54
+ rule.selectors = rule.selectors.map(selector => {
55
+ if (selector.startsWith('.undp-container')) return selector;
56
+ if (skipSelectors.some(skip => selector.startsWith(skip)))
57
+ return selector;
58
+ return `.undp-container ${selector}`;
59
+ });
60
+ });
61
+ },
62
+ },
63
+ {
64
+ postcssPlugin: 'move-media-queries-last', // If you want to reorder media queries to the end
65
+ OnceExit(root) {
66
+ const mediaQueries = [];
67
+
68
+ // Collect all media queries
69
+ root.walkAtRules('media', mediaRule => {
70
+ mediaQueries.push(mediaRule.clone());
71
+ mediaRule.remove();
72
+ });
73
+
74
+ // Append them at the end
75
+ mediaQueries.forEach(mediaQuery => {
76
+ root.append(mediaQuery);
77
+ });
78
+ },
79
+ },
80
+ ],
81
+ },
82
+ },
83
+ build: {
84
+ manifest: true,
85
+ cssCodeSplit: false,
86
+ rollupOptions: {
87
+ output: {
88
+ manualChunks(id) {
89
+ if (id.includes('node_modules/react')) return 'react';
90
+ if (id.includes('@undp/design-system-react')) return 'undp';
91
+ if (id.includes('@undp/data-viz')) return 'undp';
92
+ },
93
+ chunkFileNames: '[name]-[hash].js',
94
+ assetFileNames: '[name].[ext]',
95
+ entryFileNames: '[name].js',
96
+ },
97
+ treeshake: true,
98
+ },
99
+ },
100
+ server: {
101
+ cors: {
102
+ origin: '*',
103
+ methods: ['GET'],
104
+ preflightContinue: false,
105
+ optionsSuccessStatus: 204,
106
+ },
107
+ },
108
+ resolve: { alias: { '@': path.resolve(__dirname, './src') } },
109
+ });
@@ -0,0 +1,58 @@
1
+ import path from 'path';
2
+
3
+ import { defineConfig } from 'vite';
4
+ import react from '@vitejs/plugin-react';
5
+ import eslint from '@nabla/vite-plugin-eslint';
6
+ import { visualizer } from 'rollup-plugin-visualizer';
7
+ import postcssNested from 'postcss-nested';
8
+ import tailwindcss from '@tailwindcss/postcss';
9
+ import { viteStaticCopy } from 'vite-plugin-static-copy';
10
+
11
+ export default defineConfig({
12
+ plugins: [
13
+ react({
14
+ babel: {
15
+ plugins: ['babel-plugin-react-compiler'],
16
+ },
17
+ }),
18
+ eslint(),
19
+ visualizer({ filename: 'stats.html', open: true }),
20
+ viteStaticCopy({
21
+ targets: [{ src: 'staticwebapp.config.json', dest: '' }],
22
+ }),
23
+ ],
24
+ css: {
25
+ postcss: {
26
+ plugins: [
27
+ postcssNested(),
28
+ tailwindcss(),
29
+ ],
30
+ },
31
+ },
32
+ build: {
33
+ manifest: true,
34
+ cssCodeSplit: false,
35
+ rollupOptions: {
36
+ output: {
37
+ manualChunks(id) {
38
+ if (id.includes('node_modules/react')) return 'react';
39
+ if (id.includes('@undp/design-system-react')) return 'undp';
40
+ if (id.includes('@undp/data-viz')) return 'undp';
41
+ },
42
+ chunkFileNames: '[name]-[hash].js',
43
+ assetFileNames: '[name].[ext]',
44
+ entryFileNames: '[name].js',
45
+ },
46
+ treeshake: true,
47
+ },
48
+ },
49
+ server: {
50
+ cors: {
51
+ origin: '*',
52
+ methods: ['GET'],
53
+ preflightContinue: false,
54
+ optionsSuccessStatus: 204,
55
+ },
56
+ },
57
+ resolve: { alias: { '@': path.resolve(__dirname, './src') } },
58
+ });
@@ -0,0 +1,213 @@
1
+ @font-face {
2
+ font-display: swap;
3
+ font-family: 'ProximaNova';
4
+ font-style: normal;
5
+ font-weight: 100;
6
+ src: url('./fonts/proximanova-thin-webfont.woff2') format('woff2');
7
+ }
8
+
9
+ @font-face {
10
+ font-display: swap;
11
+ font-family: 'ProximaNova';
12
+ font-style: italic;
13
+ font-weight: 100;
14
+ src: url('./fonts/proximanova-thinit-webfont.woff2') format('woff2');
15
+ }
16
+
17
+ @font-face {
18
+ font-display: swap;
19
+ font-family: 'ProximaNova';
20
+ font-style: normal;
21
+ font-weight: 200;
22
+ src: url('./fonts/proximanova-light-webfont.woff2') format('woff2');
23
+ }
24
+
25
+ @font-face {
26
+ font-display: swap;
27
+ font-family: 'ProximaNova';
28
+ font-style: italic;
29
+ font-weight: 200 300;
30
+ src: url('./fonts/proximanova-lightit-webfont.woff2') format('woff2');
31
+ }
32
+
33
+ @font-face {
34
+ font-display: swap;
35
+ font-family: 'ProximaNova';
36
+ font-style: normal;
37
+ font-weight: 400;
38
+ src: url('./fonts/proximanova-regular-webfont.woff2') format('woff2');
39
+ }
40
+
41
+ @font-face {
42
+ font-display: swap;
43
+ font-family: 'ProximaNova';
44
+ font-style: italic;
45
+ font-weight: 400;
46
+ src: url('./fonts/proximanova-regularit-webfont.woff2') format('woff2');
47
+ }
48
+
49
+ @font-face {
50
+ font-display: swap;
51
+ font-family: 'ProximaNova';
52
+ font-style: normal;
53
+ font-weight: 500;
54
+ src: url('./fonts/proximanova-medium-webfont.woff2') format('woff2');
55
+ }
56
+
57
+ @font-face {
58
+ font-display: swap;
59
+ font-family: 'ProximaNova';
60
+ font-style: italic;
61
+ font-weight: 500;
62
+ src: url('./fonts/proximanova-mediumit-webfont.woff2') format('woff2');
63
+ }
64
+
65
+ @font-face {
66
+ font-display: swap;
67
+ font-family: 'ProximaNova';
68
+ font-style: normal;
69
+ font-weight: 600;
70
+ src: url('./fonts/proximanova-semibold-webfont-2.woff2') format('woff2');
71
+ }
72
+
73
+ @font-face {
74
+ font-display: swap;
75
+ font-family: 'ProximaNova';
76
+ font-style: italic;
77
+ font-weight: 600;
78
+ src: url('./fonts/proximanova-semiboldit-webfont-2.woff2') format('woff2');
79
+ }
80
+
81
+ @font-face {
82
+ font-display: swap;
83
+ font-family: 'ProximaNova';
84
+ font-style: normal;
85
+ font-weight: 700;
86
+ src: url('./fonts/proximanova-bold-webfont.woff2') format('woff2');
87
+ }
88
+
89
+ @font-face {
90
+ font-display: swap;
91
+ font-family: 'ProximaNova';
92
+ font-style: italic;
93
+ font-weight: 700;
94
+ src: url('./fonts/proximanova-boldit-webfont.woff2') format('woff2');
95
+ }
96
+
97
+ @font-face {
98
+ font-display: swap;
99
+ font-family: 'ProximaNova';
100
+ font-style: normal;
101
+ font-weight: 800;
102
+ src: url('./fonts/proximanova-extrabold-webfont.woff2') format('woff2');
103
+ }
104
+
105
+ @font-face {
106
+ font-display: swap;
107
+ font-family: 'ProximaNova';
108
+ font-style: italic;
109
+ font-weight: 800;
110
+ src: url('./fonts/proximanova-extraboldit-webfont.woff2') format('woff2');
111
+ }
112
+
113
+ @font-face {
114
+ font-display: swap;
115
+ font-family: 'ProximaNova';
116
+ font-style: normal;
117
+ font-weight: 900;
118
+ src: url('./fonts/proximanova-black-webfont.woff2') format('woff2');
119
+ }
120
+
121
+ @font-face {
122
+ font-display: swap;
123
+ font-family: 'ProximaNova';
124
+ font-style: italic;
125
+ font-weight: 900;
126
+ src: url('./fonts/proximanova-blackit-webfont.woff2') format('woff2');
127
+ }
128
+
129
+ /* SohneBreit */
130
+ @font-face {
131
+ font-display: swap;
132
+ font-family: 'SohneBreit';
133
+ font-style: normal;
134
+ font-weight: 100 700;
135
+ src: url('./fonts/soehne-breit-web-dreiviertelfett.woff2') format('woff2');
136
+ unicode-range: U+0000-024F, U+1E00-1EFF, U+2000-206F, U+2070-209F;
137
+ }
138
+
139
+ @font-face {
140
+ font-display: swap;
141
+ font-family: 'SohneBreit';
142
+ font-style: italic;
143
+ font-weight: 100 700;
144
+ src: url('./fonts/soehne-breit-web-dreiviertelfett-kursiv.woff2')
145
+ format('woff2');
146
+ unicode-range: U+0000-024F, U+1E00-1EFF, U+2000-206F, U+2070-209F;
147
+ }
148
+
149
+ @font-face {
150
+ font-display: swap;
151
+ font-family: 'SohneBreit';
152
+ font-style: normal;
153
+ font-weight: 800 900;
154
+ src: url('./fonts/soehne-breit-web-fett.woff2') format('woff2');
155
+ unicode-range: U+0000-024F, U+1E00-1EFF, U+2000-206F, U+2070-209F;
156
+ }
157
+
158
+ @font-face {
159
+ font-display: swap;
160
+ font-family: 'SohneBreit';
161
+ font-style: italic;
162
+ font-weight: 800 900;
163
+ src: url('./fonts/soehne-breit-web-fett-kursiv.woff2') format('woff2');
164
+ unicode-range: U+0000-024F, U+1E00-1EFF, U+2000-20CF;
165
+ }
166
+
167
+ @font-face {
168
+ font-display: swap;
169
+ font-family: 'UNBangla';
170
+ font-style: normal;
171
+ font-weight: 100 300;
172
+ src: url('./fonts/UNBangla-Thin.woff2') format('woff2');
173
+ }
174
+
175
+ @font-face {
176
+ font-display: swap;
177
+ font-family: 'UNBangla';
178
+ font-style: italic;
179
+ font-weight: 100 300;
180
+ src: url('./fonts/UNBangla-ThinItalic.woff2') format('woff2');
181
+ }
182
+
183
+ @font-face {
184
+ font-display: swap;
185
+ font-family: 'UNBangla';
186
+ font-style: normal;
187
+ font-weight: 400;
188
+ src: url('./fonts/UNBangla-Regular.woff2') format('woff2');
189
+ }
190
+
191
+ @font-face {
192
+ font-display: swap;
193
+ font-family: 'UNBangla';
194
+ font-style: italic;
195
+ font-weight: 400;
196
+ src: url('./fonts/UNBangla-Italic.woff2') format('woff2');
197
+ }
198
+
199
+ @font-face {
200
+ font-display: swap;
201
+ font-family: 'UNBangla';
202
+ font-style: normal;
203
+ font-weight: 500 900;
204
+ src: url('./fonts/UNBangla-Bold.woff2') format('woff2');
205
+ }
206
+
207
+ @font-face {
208
+ font-display: swap;
209
+ font-family: 'UNBangla';
210
+ font-style: italic;
211
+ font-weight: 500 900;
212
+ src: url('./fonts/UNBangla-BoldItalic.woff2') format('woff2');
213
+ }
@@ -0,0 +1,57 @@
1
+ import { H3 } from '@undp/design-system-react';
2
+ import { useQuery } from '@tanstack/react-query';
3
+
4
+ import '@/styles/fonts.css';
5
+ import '@/styles/style.css';
6
+ import undpLogo from './assets/undp-logo-blue.svg';
7
+
8
+ function useTodoData() {
9
+ return useQuery({
10
+ queryKey: ['todos'],
11
+ queryFn: () =>
12
+ Promise.resolve([
13
+ { id: 1, name: 'Alice' },
14
+ { id: 2, name: 'Bob' },
15
+ { id: 3, name: 'Charlie' },
16
+ ]),
17
+ initialData: [],
18
+ });
19
+ }
20
+
21
+ function App() {
22
+ const { data, isLoading, isError } = useTodoData();
23
+
24
+ if (isLoading) return <Spinner size='lg' className='my-20 m-auto' />;
25
+
26
+ if (isError)
27
+ return (
28
+ <div className='px-4 mx-auto'>
29
+ <div>Error</div>
30
+ </div>
31
+ );
32
+ return (
33
+ <div className='m-5'>
34
+ <div>
35
+ <img
36
+ src={undpLogo}
37
+ className='logo react mb-8'
38
+ alt='React logo'
39
+ width='72px'
40
+ style={{ marginLeft: 'auto', marginRight: 'auto' }}
41
+ />
42
+ </div>
43
+ <H3 className='text-center'>
44
+ This is template for building visualization and frontend project
45
+ maintained by UNDP&apos;s DAI Hub.
46
+ <br />
47
+ <br />
48
+ Contact us at data@undp.org if you have any feedback or questions.
49
+ <br />
50
+ <br />
51
+ {data.length} elements in the query
52
+ </H3>
53
+ </div>
54
+ );
55
+ }
56
+
57
+ export default App;
@@ -0,0 +1,67 @@
1
+ import { H3 } from '@undp/design-system-react';
2
+ import { useQuery } from '@tanstack/react-query';
3
+
4
+ import '@/styles/fonts.css';
5
+ import '@/styles/style.css';
6
+ import undpLogo from './assets/undp-logo-blue.svg';
7
+
8
+ function useTodoData() {
9
+ return useQuery({
10
+ queryKey: ['todos'],
11
+ queryFn: () =>
12
+ Promise.resolve([
13
+ { id: 1, name: 'Alice' },
14
+ { id: 2, name: 'Bob' },
15
+ { id: 3, name: 'Charlie' },
16
+ ]),
17
+ initialData: [],
18
+ });
19
+ }
20
+
21
+ function App() {
22
+ const { data, isLoading, isError } = useTodoData();
23
+
24
+ if (isLoading)
25
+ return (
26
+ <div className='undp-container'>
27
+ <Spinner size='lg' className='my-20 m-auto' />
28
+ </div>
29
+ );
30
+
31
+ if (isError)
32
+ return (
33
+ <div className='undp-container'>
34
+ <div className='px-4 mx-auto'>
35
+ <div>Error</div>
36
+ </div>
37
+ </div>
38
+ );
39
+
40
+ return (
41
+ <div className='undp-container'>
42
+ <div className='m-5'>
43
+ <div>
44
+ <img
45
+ src={undpLogo}
46
+ className='logo react mb-8'
47
+ alt='React logo'
48
+ width='72px'
49
+ style={{ marginLeft: 'auto', marginRight: 'auto' }}
50
+ />
51
+ </div>
52
+ <H3 className='text-center'>
53
+ This is template for building visualization and frontend project
54
+ maintained by UNDP&apos;s DAI Hub.
55
+ <br />
56
+ <br />
57
+ Contact us at data@undp.org if you have any feedback or questions.
58
+ <br />
59
+ <br />
60
+ {data.length} elements in the query
61
+ </H3>
62
+ </div>
63
+ </div>
64
+ );
65
+ }
66
+
67
+ export default App;
@@ -0,0 +1,29 @@
1
+ import { StrictMode } from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
4
+
5
+ import './styles/fonts.css';
6
+ import './styles/style.css';
7
+
8
+ import App from './App';
9
+
10
+ const queryClient = new QueryClient({
11
+ defaultOptions: {
12
+ queries: {
13
+ staleTime: 1000 * 60 * 60 * 24, // how long fetched data is considered “fresh” before it becomes “stale” 🡢 24 hrs
14
+ gcTime: 1000 * 60 * 60 * 24, // how long inactive (unused) query data stays in memory before being deleted 🡢 24 hrs
15
+ },
16
+ },
17
+ });
18
+
19
+ const rootElement = document.getElementById('app');
20
+ if (rootElement && !rootElement.innerHTML) {
21
+ const root = ReactDOM.createRoot(rootElement);
22
+ root.render(
23
+ <StrictMode>
24
+ <QueryClientProvider client={queryClient}>
25
+ <App />
26
+ </QueryClientProvider>
27
+ </StrictMode>,
28
+ );
29
+ }
@@ -0,0 +1,30 @@
1
+ import { H3 } from '@undp/design-system-react';
2
+
3
+ import '@/styles/fonts.css';
4
+ import '@/styles/style.css';
5
+ import undpLogo from './assets/undp-logo-blue.svg';
6
+
7
+ function App() {
8
+ return (
9
+ <div className='m-5'>
10
+ <div>
11
+ <img
12
+ src={undpLogo}
13
+ className='logo react mb-8'
14
+ alt='React logo'
15
+ width='72px'
16
+ style={{ marginLeft: 'auto', marginRight: 'auto' }}
17
+ />
18
+ </div>
19
+ <H3 className='text-center'>
20
+ This is template for building visualization and frontend project
21
+ maintained by UNDP&apos;s DAI Hub.
22
+ <br />
23
+ <br />
24
+ Contact us at data@undp.org if you have any feedback or questions.
25
+ </H3>
26
+ </div>
27
+ );
28
+ }
29
+
30
+ export default App;
@@ -0,0 +1,20 @@
1
+ import {
2
+ Footer,
3
+ FooterLogoUnit,
4
+ FooterCopyrightUnit,
5
+ } from '@undp/design-system-react/Footer';
6
+
7
+
8
+
9
+ export default function Header() {
10
+ return (
11
+ <Footer>
12
+ <FooterLogoUnit>
13
+ subscribe to email
14
+ </FooterLogoUnit>
15
+ <FooterCopyrightUnit>
16
+ Footnote can be added here
17
+ </FooterCopyrightUnit>
18
+ </Footer>
19
+ )
20
+ }
@@ -0,0 +1,29 @@
1
+ import {
2
+ Header,
3
+ HeaderLogoUnit,
4
+ HeaderMainNavUnit,
5
+ HeaderMenuUnit,
6
+ } from '@undp/design-system-react/Header';
7
+ import { Link } from '@tanstack/react-router';
8
+
9
+ export default function Header() {
10
+ return (
11
+ <Header>
12
+ <HeaderLogoUnit
13
+ hyperlink="./"
14
+ siteName="Site name"
15
+ siteSubName="Sub-site name"
16
+ />
17
+ <HeaderMainNavUnit>
18
+ <HeaderMenuUnit>
19
+ <Link to='/'>
20
+ Home
21
+ </Link>
22
+ <Link to='/about'>
23
+ About
24
+ </Link>
25
+ </HeaderMenuUnit>
26
+ </HeaderMainNavUnit>
27
+ </Header>
28
+ )
29
+ }
@@ -0,0 +1,60 @@
1
+ import { StrictMode } from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import {
4
+ Outlet,
5
+ RouterProvider,
6
+ createRootRoute,
7
+ createRoute,
8
+ createRouter,
9
+ } from '@tanstack/react-router';
10
+
11
+ import About from './routes/About.tsx';
12
+ import Header from './components/Header';
13
+ import Footer from './components/Footer';
14
+
15
+ import './styles/fonts.css';
16
+ import './styles/style.css';
17
+
18
+ import App from './App';
19
+
20
+ const rootRoute = createRootRoute({
21
+ component: () => (
22
+ <>
23
+ <Header />
24
+ <Outlet />
25
+ <Footer />
26
+ </>
27
+ ),
28
+ });
29
+
30
+ const indexRoute = createRoute({
31
+ getParentRoute: () => rootRoute,
32
+ path: '/',
33
+ component: App,
34
+ });
35
+
36
+ const routeTree = rootRoute.addChildren([indexRoute, About(rootRoute)]);
37
+
38
+ const router = createRouter({
39
+ routeTree,
40
+ defaultPreload: 'intent',
41
+ scrollRestoration: true,
42
+ defaultStructuralSharing: true,
43
+ defaultPreloadStaleTime: 0,
44
+ });
45
+
46
+ declare module '@tanstack/react-router' {
47
+ interface Register {
48
+ router: typeof router;
49
+ }
50
+ }
51
+
52
+ const rootElement = document.getElementById('app');
53
+ if (rootElement && !rootElement.innerHTML) {
54
+ const root = ReactDOM.createRoot(rootElement);
55
+ root.render(
56
+ <StrictMode>
57
+ <RouterProvider router={router} />
58
+ </StrictMode>,
59
+ );
60
+ }