Add API monorepo
Change-Id: I39aa1707744bb86c4bc9113157bbf815bb3fe33a
This commit is contained in:
parent
b87cff043a
commit
5246efb027
56 changed files with 251 additions and 22 deletions
10
source/ui/src/api/emptyApi.ts
Normal file
10
source/ui/src/api/emptyApi.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
// @ts-nocheck
|
||||
import { createApi } from '@reduxjs/toolkit/query/react';
|
||||
|
||||
import { baseQuery } from '@prokyon/api/query';
|
||||
|
||||
export const emptyApi = createApi({
|
||||
baseQuery: baseQuery({ baseUrl: process.env.ENDPOINT_URL as string }),
|
||||
tagTypes: [],
|
||||
endpoints: () => ({}),
|
||||
});
|
66
source/ui/src/app/app.tsx
Normal file
66
source/ui/src/app/app.tsx
Normal file
|
@ -0,0 +1,66 @@
|
|||
// @ts-nocheck
|
||||
import React, { FC } from 'react';
|
||||
import { Route, Switch } from 'wouter';
|
||||
|
||||
import { useAuth } from '@prokyon/auth/hook/useAuth';
|
||||
import Section from '@prokyon/components/Section';
|
||||
import { Skeleton } from '@prokyon/components/Skeleton';
|
||||
import { MenuItem } from '@prokyon/components/Skeleton/types';
|
||||
|
||||
import { WelcomePage } from 'pages/WelcomePage';
|
||||
|
||||
import { buildRoute, Routes } from './routes';
|
||||
|
||||
const topMenu: MenuItem[][] = [
|
||||
[
|
||||
{ label: 'Routa', href: buildRoute('root') },
|
||||
],
|
||||
[
|
||||
// authenticated
|
||||
],
|
||||
];
|
||||
|
||||
const userMenu: MenuItem[][] = [
|
||||
[
|
||||
// public
|
||||
],
|
||||
[
|
||||
// authenticated
|
||||
],
|
||||
];
|
||||
|
||||
export const App: FC = () => {
|
||||
const { authenticated } = useAuth();
|
||||
|
||||
return (
|
||||
<Skeleton
|
||||
items={{
|
||||
logo: <>Many</>,
|
||||
top: authenticated ? topMenu[1] : topMenu[0],
|
||||
user: authenticated ? userMenu[1] : userMenu[0],
|
||||
}}
|
||||
components={{
|
||||
footer: (
|
||||
<div className="text-center footer">
|
||||
<Section>
|
||||
Tento web používá pouze technické cookie. Monitorování návštěvnosti je zcela anonymní a je prováděno na straně
|
||||
provozovatele webu.
|
||||
</Section>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
{authenticated ? (
|
||||
<Switch>
|
||||
<Route>404!</Route>
|
||||
</Switch>
|
||||
) : (
|
||||
<Switch>
|
||||
<Route path={Routes.root} component={WelcomePage} />
|
||||
<Route>404!</Route>
|
||||
</Switch>
|
||||
)}
|
||||
</Skeleton>
|
||||
);
|
||||
};
|
||||
|
41
source/ui/src/app/assets/html/index.ejs
Normal file
41
source/ui/src/app/assets/html/index.ejs
Normal file
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="https://fonts.googleapis.com/css?family=Ubuntu:400,700&subset=cyrillic-ext" rel="stylesheet">
|
||||
<title>$(AppName)</title>
|
||||
<meta name="robots" content="index,follow">
|
||||
|
||||
<style>
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #666;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
<% if (htmlWebpackPlugin.options.env.websiteId) { %>
|
||||
<script async src="https://wa.romanjaros.dev/script.js"
|
||||
data-website-id="<%= htmlWebpackPlugin.options.env.websiteId %>">
|
||||
</script>
|
||||
<% } %>
|
||||
|
||||
</html>
|
0
source/ui/src/app/assets/public/.gitkeep
Normal file
0
source/ui/src/app/assets/public/.gitkeep
Normal file
16
source/ui/src/app/routes.ts
Normal file
16
source/ui/src/app/routes.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
// @ts-nocheck
|
||||
import { DotNestedKeys } from '@prokyon/localization/types';
|
||||
|
||||
export const Routes = {
|
||||
root: '/'
|
||||
};
|
||||
|
||||
export const buildRoute = (route: DotNestedKeys<typeof Routes>) => {
|
||||
let path = '';
|
||||
let obj: Record<string, any> = Routes;
|
||||
route.split('.').forEach((key: any) => {
|
||||
path += obj[key]?.base ?? obj[key];
|
||||
obj = obj[key];
|
||||
});
|
||||
return path;
|
||||
};
|
34
source/ui/src/app/store.ts
Normal file
34
source/ui/src/app/store.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// @ts-nocheck
|
||||
// import generated apis
|
||||
|
||||
import { AnyAction, combineReducers, configureStore, ThunkDispatch } from '@reduxjs/toolkit';
|
||||
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import authReducer from '@prokyon/auth/slice';
|
||||
import { AUTH_REDUCER_NAME } from '@prokyon/auth/types';
|
||||
import { ROOT_REDUCER_NAME } from '@prokyon/constants/redux';
|
||||
|
||||
import { emptyApi } from '../api/emptyApi';
|
||||
|
||||
type prokyonReducer = {
|
||||
[AUTH_REDUCER_NAME]: typeof authReducer;
|
||||
};
|
||||
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
[ROOT_REDUCER_NAME]: combineReducers<prokyonReducer>({
|
||||
[AUTH_REDUCER_NAME]: authReducer,
|
||||
}),
|
||||
[emptyApi.reducerPath]: emptyApi.reducer,
|
||||
},
|
||||
middleware: (gDM) => [...gDM({ serializableCheck: false }).concat([emptyApi.middleware])],
|
||||
devTools: process.env.NODE_ENV === 'development'
|
||||
});
|
||||
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
export type AppDispatch = ThunkDispatch<RootState, unknown, AnyAction>;
|
||||
|
||||
export const useAppDispatch: () => AppDispatch = useDispatch;
|
||||
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
||||
|
||||
export default store;
|
0
source/ui/src/components/.gitkeep
Normal file
0
source/ui/src/components/.gitkeep
Normal file
0
source/ui/src/constants/.gitkeep
Normal file
0
source/ui/src/constants/.gitkeep
Normal file
0
source/ui/src/features/.gitkeep
Normal file
0
source/ui/src/features/.gitkeep
Normal file
0
source/ui/src/hooks/.gitkeep
Normal file
0
source/ui/src/hooks/.gitkeep
Normal file
25
source/ui/src/index.tsx
Normal file
25
source/ui/src/index.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
// @ts-nocheck
|
||||
import 'types/global';
|
||||
import 'localization/locale';
|
||||
import 'utils/yup';
|
||||
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { ModalWrapper } from '@prokyon/components/Modal/context';
|
||||
import { ToasterWrapper } from '@prokyon/components/Toaster/context';
|
||||
|
||||
import { App } from './app/app';
|
||||
import store from './app/store';
|
||||
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<ModalWrapper>
|
||||
<ToasterWrapper>
|
||||
<App />
|
||||
</ToasterWrapper>
|
||||
</ModalWrapper>
|
||||
</Provider>,
|
||||
document.getElementById('app')
|
||||
);
|
5
source/ui/src/localization/dictionary/csCZ.ts
Normal file
5
source/ui/src/localization/dictionary/csCZ.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
// @ts-nocheck
|
||||
import { Dictionary } from 'localization/schema';
|
||||
|
||||
export const csCZ: Dictionary = {
|
||||
};
|
7
source/ui/src/localization/locale.ts
Normal file
7
source/ui/src/localization/locale.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
// @ts-nocheck
|
||||
import { lang } from '@prokyon/localization/init';
|
||||
|
||||
import { csCZ } from './dictionary/csCZ';
|
||||
|
||||
lang.addResource('cs', csCZ);
|
||||
lang.setLocale('cs');
|
11
source/ui/src/localization/message.ts
Normal file
11
source/ui/src/localization/message.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// @ts-nocheck
|
||||
import { t as pT } from '@prokyon/localization/message';
|
||||
import { Dictionary as prokyonDictionary, DotNestedKeys } from '@prokyon/localization/types';
|
||||
|
||||
import { Dictionary } from './schema';
|
||||
|
||||
type FullDictionary = prokyonDictionary & Dictionary;
|
||||
|
||||
export function t(key: DotNestedKeys<FullDictionary>, variables?: Record<string, any>) {
|
||||
return pT<FullDictionary>(key, variables);
|
||||
}
|
2
source/ui/src/localization/schema.ts
Normal file
2
source/ui/src/localization/schema.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export type Dictionary = {
|
||||
};
|
12
source/ui/src/pages/WelcomePage.tsx
Normal file
12
source/ui/src/pages/WelcomePage.tsx
Normal file
|
@ -0,0 +1,12 @@
|
|||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
import Section from '@prokyon/components/Section';
|
||||
|
||||
export const WelcomePage = () => {
|
||||
return (
|
||||
<div className="welcome">
|
||||
Seedling app generator.
|
||||
</div>
|
||||
);
|
||||
};
|
8
source/ui/src/styles/components/component.js
Normal file
8
source/ui/src/styles/components/component.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
const component = () => ({
|
||||
});
|
||||
|
||||
module.exports = ({ addComponents, theme }) => {
|
||||
addComponents(component(theme));
|
||||
};
|
||||
|
||||
module.exports.component = component;
|
11
source/ui/src/styles/global.css
Normal file
11
source/ui/src/styles/global.css
Normal file
|
@ -0,0 +1,11 @@
|
|||
@import '@prokyon/styles/global.css';
|
||||
|
||||
@import "./variables.css";
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700&display=swap');
|
||||
|
||||
body {
|
||||
@apply bg-white text-black text-sm;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-weight: lighter;
|
||||
}
|
4
source/ui/src/styles/postcss.config.js
Normal file
4
source/ui/src/styles/postcss.config.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
const postcss = require('@prokyon/styles/postcss.config');
|
||||
const configPath = require.resolve('./tailwind.config.js');
|
||||
|
||||
module.exports = postcss({ tailwindConfigFile: configPath });
|
23
source/ui/src/styles/tailwind.config.js
Normal file
23
source/ui/src/styles/tailwind.config.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
const path = require('path');
|
||||
|
||||
const plugin = require('tailwindcss/plugin');
|
||||
|
||||
module.exports = {
|
||||
presets: [require('@prokyon/styles/tailwind.config')],
|
||||
content: [
|
||||
path.resolve(__dirname + '../../**/*.{js,ts,tsx}'),
|
||||
path.resolve(__dirname + '../../../node_modules/@prokyon/**/*.{js,ts,tsx}'),
|
||||
],
|
||||
safelist: require('@prokyon/styles/tailwind.config').safelist,
|
||||
theme: {
|
||||
extend: require('./theme'),
|
||||
},
|
||||
variants: {
|
||||
extend: {
|
||||
borderWidth: ['last'],
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
plugin(require('./components/component')),
|
||||
],
|
||||
};
|
10
source/ui/src/styles/theme.js
Normal file
10
source/ui/src/styles/theme.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const { pallete } = require('@prokyon/styles/utils/color');
|
||||
|
||||
module.exports = {
|
||||
colors: {
|
||||
disabled: pallete('disabled'),
|
||||
},
|
||||
borderWidth: {
|
||||
1: '1px',
|
||||
},
|
||||
};
|
5
source/ui/src/styles/variables.css
Normal file
5
source/ui/src/styles/variables.css
Normal file
|
@ -0,0 +1,5 @@
|
|||
:root {
|
||||
--color-h: 0;
|
||||
--color-s: 0%;
|
||||
--color-l: 0%;
|
||||
}
|
0
source/ui/src/types/global.ts
Normal file
0
source/ui/src/types/global.ts
Normal file
8
source/ui/src/types/yup.d.ts
vendored
Normal file
8
source/ui/src/types/yup.d.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
// @ts-nocheck
|
||||
import { StringSchema } from 'yup';
|
||||
|
||||
declare module 'yup' {
|
||||
interface StringSchema {
|
||||
// place custom Yup definition of validation
|
||||
}
|
||||
}
|
10
source/ui/src/utils/yup.ts
Normal file
10
source/ui/src/utils/yup.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
// @ts-nocheck
|
||||
// place import for custom Yup validations
|
||||
|
||||
import * as Yup from 'yup';
|
||||
|
||||
Yup.setLocale({
|
||||
mixed: {
|
||||
required: 'Prosím, vyplňtě toto pole.',
|
||||
},
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue