@autobusal/providers 1.0.1 → 1.0.3
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/Notifications/Notifications.tsx +56 -0
- package/Providers.tsx +19 -37
- package/Queries/Queries.tsx +22 -0
- package/Queries/apiClient.ts +49 -0
- package/Setup/Preload.tsx +39 -0
- package/Setup/Setup.tsx +27 -0
- package/Setup/utilities/analytics.ts +9 -0
- package/Setup/utilities/languages.ts +25 -0
- package/Styles/GlobalStyles.ts +112 -0
- package/Styles/Styles.tsx +24 -0
- package/Styles/hooks/useSystemTheme.ts +18 -0
- package/index.ts +4 -3
- package/package.json +14 -2
- package/services.ts +32 -0
- package/types.ts +33 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Toaster } from 'react-hot-toast';
|
|
2
|
+
import useSystemTheme from '../Styles/hooks/useSystemTheme';
|
|
3
|
+
import { GetSettings } from '../services';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
children: JSX.Element
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Provider = ({ children }: Props): JSX.Element => {
|
|
10
|
+
const { data } = GetSettings();
|
|
11
|
+
|
|
12
|
+
const mode = useSystemTheme();
|
|
13
|
+
|
|
14
|
+
const ourTheme: any = data.colors[mode as keyof typeof data.colors];
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
{ children }
|
|
19
|
+
|
|
20
|
+
<Toaster
|
|
21
|
+
position="top-right"
|
|
22
|
+
gutter={ 12 }
|
|
23
|
+
toastOptions={{
|
|
24
|
+
style: {
|
|
25
|
+
padding: '6px 10px',
|
|
26
|
+
fontSize: data.theme.size.xs,
|
|
27
|
+
color: ourTheme.font.normal,
|
|
28
|
+
fontWeight: '700',
|
|
29
|
+
background: ourTheme.background.normal,
|
|
30
|
+
borderRadius: ourTheme.borderRadius,
|
|
31
|
+
boxShadow: ourTheme.boxShadow
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
success: {
|
|
35
|
+
style: {
|
|
36
|
+
background: ourTheme.font.success,
|
|
37
|
+
color: '#FFFFFF'
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
error: {
|
|
42
|
+
style: {
|
|
43
|
+
background: ourTheme.font.error,
|
|
44
|
+
color: '#FFFFFF'
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}}
|
|
48
|
+
containerStyle={{
|
|
49
|
+
top: '70px'
|
|
50
|
+
}}
|
|
51
|
+
/>
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default Provider;
|
package/Providers.tsx
CHANGED
|
@@ -1,45 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// import { Suspense } from 'react';
|
|
8
|
-
// import { ProviderStyles, ProviderQueries, ProviderNotifications, loadLanguages, loadAnalytics } from './providers';
|
|
9
|
-
// import { General } from '@components/Loading/Loading';
|
|
10
|
-
|
|
11
|
-
// ProviderStyles,
|
|
12
|
-
// ProviderQueries,
|
|
13
|
-
// ProviderNotifications,
|
|
14
|
-
// loadLanguages,
|
|
15
|
-
// loadAnalytics
|
|
16
|
-
|
|
17
|
-
// // load the languages
|
|
18
|
-
// loadLanguages();
|
|
19
|
-
|
|
20
|
-
// // load analytics
|
|
21
|
-
// loadAnalytics();
|
|
22
|
-
|
|
23
|
-
// const App = (): JSX.Element => (
|
|
24
|
-
// <ProviderStyles>
|
|
25
|
-
// <ProviderQueries>
|
|
26
|
-
// <ProviderNotifications>
|
|
27
|
-
// <Suspense fallback={ <General /> }>
|
|
28
|
-
// <Routing />
|
|
29
|
-
// </Suspense>
|
|
30
|
-
// </ProviderNotifications>
|
|
31
|
-
// </ProviderQueries>
|
|
32
|
-
// </ProviderStyles>
|
|
33
|
-
// );
|
|
1
|
+
import { Suspense } from 'react';
|
|
2
|
+
import Queries from './Queries/Queries';
|
|
3
|
+
import Styles from './Styles/Styles';
|
|
4
|
+
import Notifications from './Notifications/Notifications';
|
|
5
|
+
import Setup from './Setup/Setup';
|
|
34
6
|
|
|
35
7
|
interface Props {
|
|
8
|
+
type: 'normal' | 'whitelabel'
|
|
9
|
+
loading: JSX.Element
|
|
36
10
|
children: JSX.Element
|
|
37
11
|
}
|
|
38
12
|
|
|
39
|
-
const Providers = ({ children }: Props): JSX.Element => (
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
13
|
+
const Providers = ({ type, loading, children }: Props): JSX.Element => (
|
|
14
|
+
<Queries>
|
|
15
|
+
<Styles>
|
|
16
|
+
<Notifications>
|
|
17
|
+
<Setup type={ type }>
|
|
18
|
+
<Suspense fallback={ loading }>
|
|
19
|
+
{ children }
|
|
20
|
+
</Suspense>
|
|
21
|
+
</Setup>
|
|
22
|
+
</Notifications>
|
|
23
|
+
</Styles>
|
|
24
|
+
</Queries>
|
|
43
25
|
);
|
|
44
26
|
|
|
45
27
|
export default Providers;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
|
|
2
|
+
|
|
3
|
+
const queryClient = new QueryClient({
|
|
4
|
+
defaultOptions: {
|
|
5
|
+
queries: {
|
|
6
|
+
refetchOnWindowFocus: false,
|
|
7
|
+
retry: false
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
children: JSX.Element
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const Queries = ({ children }: Props): JSX.Element => (
|
|
17
|
+
<QueryClientProvider client={ queryClient }>
|
|
18
|
+
{ children }
|
|
19
|
+
</QueryClientProvider>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export default Queries;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
// import i18next from 'i18next';
|
|
3
|
+
// import { error } from '@utilities/notify';
|
|
4
|
+
|
|
5
|
+
const apiClient = axios.create({
|
|
6
|
+
baseURL: import.meta.env.VITE_API_OBT,
|
|
7
|
+
withCredentials: true
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
apiClient.interceptors.request.use(
|
|
11
|
+
config => {
|
|
12
|
+
// // const token = localStorage.getItem('token');
|
|
13
|
+
|
|
14
|
+
// // if (token !== null) {
|
|
15
|
+
// // config.headers.Authorization = token;
|
|
16
|
+
// // }
|
|
17
|
+
|
|
18
|
+
return config;
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
apiClient.interceptors.response.use(response => (
|
|
23
|
+
response
|
|
24
|
+
), err => {
|
|
25
|
+
console.log(err.response);
|
|
26
|
+
|
|
27
|
+
// if (err.response) {
|
|
28
|
+
// // if we have a 401, we go to the logout page
|
|
29
|
+
// // if (err.response.status === 401) {
|
|
30
|
+
// // alert(401);
|
|
31
|
+
// // }
|
|
32
|
+
|
|
33
|
+
// // @todo: how to handle 404?
|
|
34
|
+
|
|
35
|
+
// // if we have a 422 error, we display the message
|
|
36
|
+
// if (err.response.status === 422) {
|
|
37
|
+
// error(err.response.data.message);
|
|
38
|
+
// }
|
|
39
|
+
// } else if (err.request) {
|
|
40
|
+
// // if we have a 500 error, we display an error message
|
|
41
|
+
// error(i18next.t('server_error', { ns: 'general' }))
|
|
42
|
+
// } else {
|
|
43
|
+
// console.log('ERROR', err.message);
|
|
44
|
+
// }
|
|
45
|
+
|
|
46
|
+
return err;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export default apiClient;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Helmet } from 'react-helmet';
|
|
2
|
+
import { SettingsData } from '../types';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
data: SettingsData
|
|
6
|
+
children: JSX.Element
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// @todo: De adaugat din tema Favicons
|
|
10
|
+
const Preload = ({ data, children }: Props): JSX.Element => {
|
|
11
|
+
// we arrange the font family names before inserting them
|
|
12
|
+
const fontTitle = data.theme.fontFamily.title.replace(/\ /g, '+');
|
|
13
|
+
const fontContent = data.theme.fontFamily.content.replace(/\ /g, '+');
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<Helmet>
|
|
18
|
+
<title>{ data.preferences.company }</title>
|
|
19
|
+
|
|
20
|
+
{/* <!-- Favicons --> */}
|
|
21
|
+
{/* <link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" /> */}
|
|
22
|
+
{/* <link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" /> */}
|
|
23
|
+
{/* <link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" /> */}
|
|
24
|
+
{/* <link rel="manifest" href="/favicons/site.webmanifest" /> */}
|
|
25
|
+
{/* <link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5" /> */}
|
|
26
|
+
{/* <link rel="shortcut icon" href="/favicons/favicon.ico" /> */}
|
|
27
|
+
{/* <meta name="msapplication-TileColor" content="#ffffff" /> */}
|
|
28
|
+
{/* <meta name="msapplication-config" content="/favicons/browserconfig.xml" /> */}
|
|
29
|
+
{/* <meta name="theme-color" content="#ffffff" /> */}
|
|
30
|
+
|
|
31
|
+
<link href={ `https://fonts.googleapis.com/css2?family=${ fontTitle }:wght@700&family=${ fontContent }:wght@300;400;700&display=swap` } rel="stylesheet" />
|
|
32
|
+
</Helmet>
|
|
33
|
+
|
|
34
|
+
{ children }
|
|
35
|
+
</>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default Preload;
|
package/Setup/Setup.tsx
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import Preload from './Preload';
|
|
2
|
+
import languages from './utilities/languages';
|
|
3
|
+
import analytics from './utilities/analytics';
|
|
4
|
+
import { GetSettings, GetMenu } from '../services';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
type: 'normal' | 'whitelabel'
|
|
8
|
+
children: JSX.Element
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const Setup = ({ type, children }: Props): JSX.Element => {
|
|
12
|
+
const { data } = GetSettings();
|
|
13
|
+
|
|
14
|
+
GetMenu();
|
|
15
|
+
|
|
16
|
+
languages(type, data.preferences.languages.default);
|
|
17
|
+
|
|
18
|
+
analytics(data.preferences.googleAnalyticsID);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Preload data={ data }>
|
|
22
|
+
{ children }
|
|
23
|
+
</Preload>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default Setup;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
import Backend from 'i18next-http-backend';
|
|
3
|
+
import { initReactI18next } from 'react-i18next';
|
|
4
|
+
|
|
5
|
+
const languages = (type: string, defaultLanguage: string): void => {
|
|
6
|
+
const currentLanguage = localStorage.getItem('language');
|
|
7
|
+
|
|
8
|
+
i18next
|
|
9
|
+
.use(Backend)
|
|
10
|
+
.use(initReactI18next)
|
|
11
|
+
.init({
|
|
12
|
+
interpolation: {
|
|
13
|
+
escapeValue: false
|
|
14
|
+
},
|
|
15
|
+
lng: currentLanguage ?? defaultLanguage,
|
|
16
|
+
fallbackLng: defaultLanguage,
|
|
17
|
+
debug: true,
|
|
18
|
+
backend: {
|
|
19
|
+
loadPath: `${ import.meta.env.VITE_API_OBT }/languages/${ type }/{{lng}}/{{ns}}.json`
|
|
20
|
+
},
|
|
21
|
+
ns: 'general'
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default languages;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createGlobalStyle } from 'styled-components';
|
|
2
|
+
|
|
3
|
+
const GlobalStyles = createGlobalStyle`
|
|
4
|
+
* {
|
|
5
|
+
outline: none;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
html {
|
|
10
|
+
height: 100%;
|
|
11
|
+
font-family: sans-serif;
|
|
12
|
+
-webkit-text-size-adjust: 100%;
|
|
13
|
+
-ms-text-size-adjust: 100%;
|
|
14
|
+
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
body {
|
|
18
|
+
height: 100%;
|
|
19
|
+
margin: 0;
|
|
20
|
+
padding: 0;
|
|
21
|
+
font-family: '${props => props.theme.fontFamily.content}', sans-serif;
|
|
22
|
+
color: ${ props => props.theme.font.normal };
|
|
23
|
+
font-size: ${ props => props.theme.size.m };
|
|
24
|
+
line-height: ${ props => props.theme.lineHeight.content };
|
|
25
|
+
background: ${ props => props.theme.background.normal };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#root {
|
|
29
|
+
width: 100%;
|
|
30
|
+
height: 100%;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
a {
|
|
34
|
+
color: ${ props => props.theme.font.normal };
|
|
35
|
+
text-decoration: none;
|
|
36
|
+
|
|
37
|
+
&:hover {
|
|
38
|
+
text-decoration: underline;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
button {
|
|
43
|
+
all: unset;
|
|
44
|
+
box-sizing: border-box;
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
h1, h2, h3, h4, h5, h6 {
|
|
49
|
+
display: block;
|
|
50
|
+
margin: 0 0 20px 0;
|
|
51
|
+
padding: 0;
|
|
52
|
+
font-weight: 700;
|
|
53
|
+
line-height: ${ props => props.theme.lineHeight.title };
|
|
54
|
+
font-family: ${ props => props.theme.fontFamily.title };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
h1 {
|
|
58
|
+
font-size: ${ props => props.theme.size.xxl };
|
|
59
|
+
}
|
|
60
|
+
h2, h3 {
|
|
61
|
+
font-size: ${ props => props.theme.size.xl };
|
|
62
|
+
}
|
|
63
|
+
h4, h5, h6 {
|
|
64
|
+
font-size: ${ props => props.theme.size.l };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
input[type='text'], input[type='number'], input[type='email'], input[type='password'], textarea, select {
|
|
68
|
+
display: block;
|
|
69
|
+
width: 100%;
|
|
70
|
+
height: 38px;
|
|
71
|
+
padding: 0 10px;
|
|
72
|
+
font-size: ${ props => props.theme.size.m };
|
|
73
|
+
font-weight: 700;
|
|
74
|
+
color: ${ props => props.theme.font.normal };
|
|
75
|
+
background: ${ props => props.theme.background.normal };
|
|
76
|
+
border: 1px solid ${ props => props.theme.font.faded };
|
|
77
|
+
border-radius: ${ props => props.theme.borderRadius };
|
|
78
|
+
-webkit-appearance: none;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
input[type='checkbox'] {
|
|
82
|
+
-webkit-appearance: checkbox;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
input[type='radio'] {
|
|
86
|
+
display: inline-block;
|
|
87
|
+
margin-right: 5px;
|
|
88
|
+
-webkit-appearance: radio;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
select {
|
|
92
|
+
padding: 0 10px;
|
|
93
|
+
font-size: ${ props => props.theme.size.m };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
textarea {
|
|
97
|
+
min-height: 120px;
|
|
98
|
+
resize: vertical;
|
|
99
|
+
padding: 10px;
|
|
100
|
+
font-family: '${props => props.theme.fontFamily.content}', sans-serif;
|
|
101
|
+
font-size: ${ props => props.theme.size.s };
|
|
102
|
+
line-height: ${ props => props.theme.lineHeight.title };
|
|
103
|
+
font-weight: 700;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
p {
|
|
107
|
+
padding: 0;
|
|
108
|
+
margin: 0;
|
|
109
|
+
}
|
|
110
|
+
`;
|
|
111
|
+
|
|
112
|
+
export default GlobalStyles;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ThemeProvider } from 'styled-components';
|
|
2
|
+
import useSystemTheme from './hooks/useSystemTheme';
|
|
3
|
+
import GlobalStyles from './GlobalStyles';
|
|
4
|
+
import { GetSettings } from '../services';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
children: JSX.Element
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const Styles = ({ children }: Props): JSX.Element => {
|
|
11
|
+
const { data } = GetSettings();
|
|
12
|
+
|
|
13
|
+
const mode = useSystemTheme();
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<ThemeProvider theme={ { ...data.colors[mode as keyof typeof data.colors], ...data.theme } }>
|
|
17
|
+
<GlobalStyles />
|
|
18
|
+
|
|
19
|
+
{ children }
|
|
20
|
+
</ThemeProvider>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default Styles;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
const useSystemTheme = (): string => {
|
|
4
|
+
const queryDarkMode = window.matchMedia("(prefers-color-scheme: dark)");
|
|
5
|
+
|
|
6
|
+
const [ theme, setTheme ] = useState<string>(queryDarkMode.matches ? 'dark' : 'light');
|
|
7
|
+
|
|
8
|
+
// setup a listener to respond to future changes of the system theme
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
queryDarkMode.addEventListener('change', (event: MediaQueryListEvent) => {
|
|
11
|
+
setTheme(event.matches ? 'dark' : 'light');
|
|
12
|
+
})
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return theme;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default useSystemTheme;
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autobusal/providers",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"type": "module"
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@tanstack/react-query": "^5.17.19",
|
|
8
|
+
"axios": "^1.6.5",
|
|
9
|
+
"i18next": "^23.7.18",
|
|
10
|
+
"i18next-http-backend": "^2.4.2",
|
|
11
|
+
"react-ga4": "^2.1.0",
|
|
12
|
+
"react-helmet": "^6.1.0",
|
|
13
|
+
"react-hot-toast": "^2.4.1",
|
|
14
|
+
"react-i18next": "^14.0.1",
|
|
15
|
+
"styled-components": "^6.1.8"
|
|
16
|
+
}
|
|
5
17
|
}
|
package/services.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useSuspenseQuery, UseSuspenseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import apiClient from './Queries/apiClient';
|
|
3
|
+
import { SettingsData, MenuData } from './types';
|
|
4
|
+
|
|
5
|
+
export const GetSettings = (): UseSuspenseQueryResult<SettingsData> => (
|
|
6
|
+
useSuspenseQuery({
|
|
7
|
+
queryKey: ['get-settings'],
|
|
8
|
+
queryFn: async () => (
|
|
9
|
+
await apiClient
|
|
10
|
+
.get('/api/settings/get')
|
|
11
|
+
.then(response => (
|
|
12
|
+
response.data
|
|
13
|
+
))
|
|
14
|
+
.catch(() => {})
|
|
15
|
+
),
|
|
16
|
+
staleTime: Infinity
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const GetMenu = (): UseSuspenseQueryResult<MenuData> => (
|
|
21
|
+
useSuspenseQuery({
|
|
22
|
+
queryKey: ['get-menu'],
|
|
23
|
+
queryFn: async () => (
|
|
24
|
+
await apiClient
|
|
25
|
+
.get('/api/menu/get')
|
|
26
|
+
.then(response => (
|
|
27
|
+
response.data
|
|
28
|
+
))
|
|
29
|
+
.catch(() => {})
|
|
30
|
+
)
|
|
31
|
+
})
|
|
32
|
+
);
|
package/types.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface SettingsData {
|
|
2
|
+
preferences: {
|
|
3
|
+
company: string
|
|
4
|
+
logo: string
|
|
5
|
+
|
|
6
|
+
googleAnalyticsID: string | null
|
|
7
|
+
|
|
8
|
+
languages: {
|
|
9
|
+
available: string[]
|
|
10
|
+
default: string
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
theme: {
|
|
15
|
+
fontFamily: any
|
|
16
|
+
lineHeight: any
|
|
17
|
+
size: any
|
|
18
|
+
borderRadius: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
colors: {
|
|
22
|
+
light: any
|
|
23
|
+
dark: any
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface MenuData {
|
|
28
|
+
id: number
|
|
29
|
+
name: string
|
|
30
|
+
link: string
|
|
31
|
+
new: 'yes' | 'no'
|
|
32
|
+
children: MenuData[]
|
|
33
|
+
}
|