Compare commits
2 commits
99831ff824
...
1a17cb4f5d
Author | SHA1 | Date | |
---|---|---|---|
1a17cb4f5d | |||
89e8068306 |
63 changed files with 3177 additions and 659 deletions
|
@ -1,3 +1 @@
|
|||
FROM local/nodejs/dev:18
|
||||
|
||||
USER node
|
|
@ -3,7 +3,7 @@
|
|||
"workspaceFolder": "/home/project/seedling",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"service": "seedling",
|
||||
"postCreateCommand": "sudo chown node:node -R /home/project",
|
||||
"postCreateCommand": "sudo chown iamuser:iamuser /home/project",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
|
|
|
@ -12,7 +12,7 @@ services:
|
|||
context: .
|
||||
container_name: seedling
|
||||
volumes:
|
||||
- ../:/home/project/seedling
|
||||
- ../:/home/project/seedling:delegated
|
||||
- node_modules:/home/project/seedling/node_modules
|
||||
- pnpm-store:/home/project/seedling/.pnpm-store
|
||||
command: sleep infinity
|
1
.eslintignore
Normal file
1
.eslintignore
Normal file
|
@ -0,0 +1 @@
|
|||
source/
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,9 +1,9 @@
|
|||
build/
|
||||
dist/
|
||||
app/
|
||||
node_modules/
|
||||
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
.pnpm/
|
||||
node_modules/
|
||||
.pnpm-store/
|
||||
output/
|
||||
|
|
26
create.js
26
create.js
|
@ -7,14 +7,14 @@ const argv = require('minimist')(process.argv.slice(2));
|
|||
const appName = argv.name ?? 'app';
|
||||
const appPort = argv.port ?? '0';
|
||||
|
||||
const defaultContextDir = './';
|
||||
const defaultContextDir = '.';
|
||||
const rootDir = __dirname;
|
||||
const contextDir = `${argv._[0]}/` ?? defaultContextDir;
|
||||
const contextDir = `${argv._[0] ?? defaultContextDir}`;
|
||||
|
||||
// create app folder
|
||||
const appsDir = `${contextDir}/apps`;
|
||||
const uiDir = `${contextDir}/apps/${appName}-ui`;
|
||||
const apiDir = `${contextDir}/apps/${appName}-rest`;
|
||||
const restDir = `${contextDir}/apps/${appName}-rest`;
|
||||
|
||||
// prepare structure folders
|
||||
if (!fs.existsSync(uiDir)) {
|
||||
|
@ -24,8 +24,8 @@ if (!fs.existsSync(uiDir)) {
|
|||
fs.mkdirSync(appsDir);
|
||||
fs.mkdirSync(uiDir);
|
||||
fs.mkdirSync(`${uiDir}/src`);
|
||||
fs.mkdirSync(apiDir);
|
||||
fs.mkdirSync(`${apiDir}/src`);
|
||||
fs.mkdirSync(restDir);
|
||||
fs.mkdirSync(`${restDir}/src`);
|
||||
}
|
||||
|
||||
// copy folder content
|
||||
|
@ -38,7 +38,7 @@ try {
|
|||
force: true,
|
||||
recursive: true,
|
||||
});
|
||||
fs.cpSync(`${rootDir}/source/rest/`, apiDir, {
|
||||
fs.cpSync(`${rootDir}/source/rest/`, restDir, {
|
||||
force: true,
|
||||
recursive: true,
|
||||
});
|
||||
|
@ -55,29 +55,29 @@ fs.renameSync(`${contextDir}/gitignore`, `${contextDir}/.gitignore`);
|
|||
fs.renameSync(`${contextDir}/prettierrc`, `${contextDir}/.prettierrc`);
|
||||
fs.renameSync(`${contextDir}/.tsconfig.json`, `${contextDir}/tsconfig.json`);
|
||||
fs.renameSync(`${uiDir}/.tsconfig.json`, `${uiDir}/tsconfig.json`);
|
||||
fs.renameSync(`${apiDir}/.tsconfig.json`, `${apiDir}/tsconfig.json`);
|
||||
fs.renameSync(`${restDir}/.tsconfig.json`, `${restDir}/tsconfig.json`);
|
||||
|
||||
// replace in files
|
||||
replaceInFiles.sync({
|
||||
files: `./${contextDir}/**/*.{ts,tsx}`,
|
||||
from: /\/\/.\@ts\-nocheck\n/gm,
|
||||
files: [`${contextDir}/**/*`, `${contextDir}/.devcontainer/*`],
|
||||
from: /\/\/.@ts-nocheck\n/gm,
|
||||
to: '',
|
||||
});
|
||||
replaceInFiles.sync({
|
||||
files: `./${contextDir}/**/*`,
|
||||
files: [`${contextDir}/**/*`, `${contextDir}/.devcontainer/*`],
|
||||
from: /\$\(appName\)/gm,
|
||||
to: appName,
|
||||
});
|
||||
replaceInFiles.sync({
|
||||
files: `./${contextDir}/**/*`,
|
||||
files: [`${contextDir}/**/*`, `${contextDir}/.devcontainer/*`],
|
||||
from: /\$\(AppName\)/gm,
|
||||
to: appName.charAt(0).toUpperCase() + appName.slice(1),
|
||||
});
|
||||
replaceInFiles.sync({
|
||||
files: `./${contextDir}/**/*`,
|
||||
files: [`${contextDir}/**/*`, `${contextDir}/.devcontainer/*`],
|
||||
from: /\$\(appPort\)/gm,
|
||||
to: appPort,
|
||||
});
|
||||
|
||||
// install deps
|
||||
execSync(`pnpm i`, { cwd: `./${contextDir}` })
|
||||
execSync(`pnpm i`, { cwd: `${contextDir}` });
|
||||
|
|
|
@ -8,11 +8,10 @@
|
|||
},
|
||||
"scripts": {
|
||||
"create": "pnpm ci:build",
|
||||
"ci:build": "node create.js --name app --port 90 ./app",
|
||||
"ci:build": "node create.js --name app --port 90 ./output",
|
||||
"release": "pnpm version --no-git-tag-version"
|
||||
},
|
||||
"dependencies": {
|
||||
"app": "link:app",
|
||||
"minimist": "1.2.8",
|
||||
"replace-in-file": "7.0.2"
|
||||
},
|
||||
|
|
1
source/common/.devcontainer/Dockerfile
Normal file
1
source/common/.devcontainer/Dockerfile
Normal file
|
@ -0,0 +1 @@
|
|||
FROM local/nodejs/dev:18
|
7
source/common/.devcontainer/devcontainer.json
Normal file
7
source/common/.devcontainer/devcontainer.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "$(appName)",
|
||||
"workspaceFolder": "/home/project/$(appName)",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"service": "$(appName)",
|
||||
"postCreateCommand": "sudo chown iamuser:iamuser -R /home/project",
|
||||
}
|
18
source/common/.devcontainer/docker-compose.yml
Normal file
18
source/common/.devcontainer/docker-compose.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
version: "3"
|
||||
|
||||
name: $(appName)
|
||||
|
||||
volumes:
|
||||
node_modules:
|
||||
pnpm-store:
|
||||
|
||||
services:
|
||||
seedling:
|
||||
build:
|
||||
context: .
|
||||
container_name: $(appName)
|
||||
volumes:
|
||||
- ../:/home/project/$(appName)
|
||||
- node_modules:/home/project/seedling/node_modules
|
||||
- pnpm-store:/home/project/seedling/.pnpm-store
|
||||
command: sleep infinity
|
1
source/common/.env
Normal file
1
source/common/.env
Normal file
|
@ -0,0 +1 @@
|
|||
COMPOSE_PROJECT_NAME=$(appName)
|
|
@ -7,15 +7,16 @@
|
|||
"emitDecoratorMetadata": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"allowJs": true,
|
||||
"outDir": "build",
|
||||
"module": "commonjs",
|
||||
"module": "esnext",
|
||||
"target": "es6",
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"./node_modules",
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
build/
|
||||
dist/
|
||||
node_modules/
|
||||
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
node_modules/
|
||||
.pnpm-store/
|
|
@ -4,7 +4,7 @@
|
|||
"author": "Roman Jaroš",
|
||||
"license": "ISC",
|
||||
"scripts": {
|
||||
"dev": "pnpm -r dev",
|
||||
"dev": "pnpm -r --parallel --stream dev",
|
||||
"test": "pnpm -r test",
|
||||
"test:e2e": "pnpm -r test:e2e"
|
||||
},
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier"
|
||||
"prettier",
|
||||
"next/core-web-vitals"
|
||||
],
|
||||
"plugins": [
|
||||
"react",
|
||||
|
|
|
@ -1,51 +1,28 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"api/*": [
|
||||
"./src/api/*"
|
||||
],
|
||||
"app/*": [
|
||||
"./src/app/*"
|
||||
],
|
||||
"components/*": [
|
||||
"./src/components/*"
|
||||
],
|
||||
"constants/*": [
|
||||
"./src/constants/*"
|
||||
],
|
||||
"features/*": [
|
||||
"./src/features/*"
|
||||
],
|
||||
"hooks/*": [
|
||||
"./src/hooks/*"
|
||||
],
|
||||
"localization/*": [
|
||||
"./src/localization/*"
|
||||
],
|
||||
"pages/*": [
|
||||
"./src/pages/*"
|
||||
],
|
||||
"utils/*": [
|
||||
"./src/utils/*"
|
||||
],
|
||||
"types/*": [
|
||||
"./src/types/*"
|
||||
]
|
||||
},
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"types": [
|
||||
"node",
|
||||
"jest",
|
||||
"./src/types/yup"
|
||||
]
|
||||
"jest"
|
||||
],
|
||||
"strict": false,
|
||||
"noEmit": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"include": [
|
||||
"./src/**/*.ts",
|
||||
"./src/**/*.tsx",
|
||||
"./types/modules.d.ts",
|
||||
"src/styles/theme.js"
|
||||
".next/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"./node_modules",
|
||||
|
|
|
@ -1 +1,36 @@
|
|||
# $(AppName)
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
ENDPOINT_BASE_URL=""
|
|
@ -1 +0,0 @@
|
|||
ENDPOINT_BASE_URL=""
|
|
@ -1,12 +1,27 @@
|
|||
FROM nginx:1.25.3-alpine
|
||||
FROM node:18-alpine3.19
|
||||
|
||||
RUN mkdir app
|
||||
RUN mkdir -p /run/nginx
|
||||
RUN apk add --no-cache libc6-compat
|
||||
|
||||
COPY build /app
|
||||
COPY docker/nginx/conf.d/ /etc/nginx/conf.d/
|
||||
WORKDIR /app
|
||||
|
||||
EXPOSE 80
|
||||
ENV NODE_ENV production
|
||||
ENV PORT 3000
|
||||
|
||||
VOLUME [ "/etc/nginx/conf.d" ]
|
||||
ENTRYPOINT ["nginx", "-g", "daemon off;"]
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 nextjs
|
||||
|
||||
COPY .next/ .next/
|
||||
COPY public/ public/
|
||||
COPY node_modules/ node_modules/
|
||||
COPY package.json package.json
|
||||
COPY next.config.js next.config.js
|
||||
|
||||
RUN chown -R nextjs:nodejs .next
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["npm", "run", "start"]
|
|
@ -1,13 +0,0 @@
|
|||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
server_name _;
|
||||
|
||||
root /app;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
module.exports = {
|
||||
transform: {
|
||||
'^.+\\.(ts|tsx)$': 'ts-jest',
|
||||
},
|
||||
testRegex: '(/__tests__/.*|(-|/)(test))\\.(ts|tsx)?$',
|
||||
transformIgnorePatterns: ['<rootDir>/node_modules/.*'],
|
||||
testPathIgnorePatterns: ['.vscode'],
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
|
||||
moduleNameMapper: {
|
||||
'^app(.*)$': '<rootDir>/src/app/$1',
|
||||
'^api(.*)$': '<rootDir>/src/api/$1',
|
||||
'^components(.*)$': '<rootDir>/src/components/$1',
|
||||
'^constants(.*)$': '<rootDir>/src/constants/$1',
|
||||
'^features(.*)$': '<rootDir>/src/features/$1',
|
||||
'^hooks(.*)$': '<rootDir>/src/hooks/$1',
|
||||
'^localization(.*)$': '<rootDir>/src/localization/$1',
|
||||
'^pages(.*)$': '<rootDir>/src/pages/$1',
|
||||
'^types(.*)$': '<rootDir>/src/types/$1',
|
||||
'^utils(.*)$': '<rootDir>/src/utils/$1',
|
||||
},
|
||||
};
|
4
source/ui/next.config.js
Normal file
4
source/ui/next.config.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {};
|
||||
|
||||
module.exports = nextConfig;
|
|
@ -1,41 +0,0 @@
|
|||
/** @type {import('nightwatch').NightwatchOptions} */
|
||||
|
||||
module.exports = {
|
||||
src_folders: 'tests/.nightwatchjs/src',
|
||||
output_folder: 'tests/.nightwatchjs/output',
|
||||
page_objects_path: ['tests/.nightwatchjs/objects'],
|
||||
custom_commands_path: 'tests/.nightwatchjs/commands',
|
||||
use_xpath: true,
|
||||
end_session_on_fail: true,
|
||||
start_process: false,
|
||||
test_settings: {
|
||||
localhost: {
|
||||
launch_url: '',
|
||||
selenium_port: 4444,
|
||||
selenium_host: '10.2.0.4',
|
||||
screenshots: {
|
||||
enabled: true,
|
||||
on_failure: true,
|
||||
on_error: true,
|
||||
path: 'tests/.nightwatchjs/output',
|
||||
},
|
||||
desiredCapabilities: {
|
||||
browserName: 'chrome',
|
||||
chromeOptions: {
|
||||
args: ['no-sandbox'],
|
||||
},
|
||||
},
|
||||
},
|
||||
ci: {
|
||||
launch_url: '',
|
||||
selenium_port: 4444,
|
||||
selenium_host: '10.0.1.21',
|
||||
desiredCapabilities: {
|
||||
browserName: 'chrome',
|
||||
chromeOptions: {
|
||||
args: ['headless', 'no-sandbox'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
|
@ -5,48 +5,42 @@
|
|||
"license": "ISC",
|
||||
"scripts": {
|
||||
"ci:build": "pnpm build:prod",
|
||||
"ci:build:test": "pnpm build:test",
|
||||
"ci:test:e2e": "nightwatch --env ci",
|
||||
"dev": "webpack serve --config scripts/webpack-dev.js --env config=local",
|
||||
"lint": "eslint -c .eslintrc src/**/*.{ts,tsx}",
|
||||
"dev": "next dev",
|
||||
"start": "next start",
|
||||
"lint": "eslint src/**/*.{ts,tsx}",
|
||||
"lint:css": "stylelint src/**/*.ts",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"test:update": "jest -u",
|
||||
"test:e2e-build": "tsc -p tests/tsconfig.json -w",
|
||||
"test:e2e": "nightwatch --env localhost",
|
||||
"build:prod": "webpack --config scripts/webpack-prod.js",
|
||||
"build:test": "webpack --config scripts/webpack-dev.js --env config=test",
|
||||
"serve": "http-server-spa build index.html 3331",
|
||||
"build:prod": "next build",
|
||||
"codegen": "pnpm dlx @rtk-query/codegen-openapi openapi-config.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@procyon/api": "1.2.9",
|
||||
"@procyon/auth": "1.2.9",
|
||||
"@procyon/components": "1.2.9",
|
||||
"@procyon/constants": "1.2.9",
|
||||
"@procyon/forms": "1.2.9",
|
||||
"@procyon/localization": "1.2.9",
|
||||
"@procyon/styles": "1.2.9",
|
||||
"@procyon/types": "1.2.9",
|
||||
"@procyon/utils": "1.2.9",
|
||||
"@procyon/api": "1.2.10",
|
||||
"@procyon/auth": "1.2.10",
|
||||
"@procyon/components": "1.2.10",
|
||||
"@procyon/constants": "1.2.10",
|
||||
"@procyon/forms": "1.2.10",
|
||||
"@procyon/localization": "1.2.10",
|
||||
"@procyon/styles": "1.2.10",
|
||||
"@procyon/types": "1.2.10",
|
||||
"@procyon/utils": "1.2.10",
|
||||
"@reduxjs/toolkit": "2.0.1",
|
||||
"clsx": "2.0.0",
|
||||
"date-fns": "3.0.6",
|
||||
"history": "5.3.0",
|
||||
"next": "14.0.4",
|
||||
"ramda": "0.29.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-redux": "9.0.4",
|
||||
"typescript": "5.3.3",
|
||||
"wouter": "2.12.1",
|
||||
"yup": "1.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rtk-query/codegen-openapi": "1.2.0",
|
||||
"@types/enzyme": "3.10.16",
|
||||
"@types/jest": "29.5.11",
|
||||
"@types/nightwatch": "2.3.30",
|
||||
"@types/ramda": "0.29.9",
|
||||
"@types/react": "18.2.45",
|
||||
"@types/react-dom": "18.2.18",
|
||||
|
@ -55,41 +49,25 @@
|
|||
"@typescript-eslint/eslint-plugin": "6.15.0",
|
||||
"@typescript-eslint/parser": "6.15.0",
|
||||
"autoprefixer": "10.4.16",
|
||||
"case-sensitive-paths-webpack-plugin": "2.4.0",
|
||||
"clean-webpack-plugin": "4.0.0",
|
||||
"copy-webpack-plugin": "11.0.0",
|
||||
"css-loader": "6.8.1",
|
||||
"css-loader":"^6.8.1",
|
||||
"process": "0.11.10",
|
||||
"dotenv": "16.3.1",
|
||||
"eslint": "8.56.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-config-next": "14.0.4",
|
||||
"eslint-plugin-react": "7.33.2",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"eslint-plugin-simple-import-sort": "10.0.0",
|
||||
"eslint-plugin-typescript": "0.14.0",
|
||||
"eslint-plugin-typescript-sort-keys": "3.1.0",
|
||||
"file-loader": "6.2.0",
|
||||
"html-webpack-plugin": "5.6.0",
|
||||
"http-server-spa": "1.3.0",
|
||||
"jest": "29.7.0",
|
||||
"mini-css-extract-plugin": "2.7.6",
|
||||
"nightwatch": "3.3.5",
|
||||
"postcss": "8.4.32",
|
||||
"postcss-loader": "7.3.3",
|
||||
"prettier": "3.1.1",
|
||||
"tailwindcss": "3.4.0",
|
||||
"ts-node": "10.9.2",
|
||||
"ts-jest": "29.1.1",
|
||||
"ts-loader": "9.5.1",
|
||||
"ts-prune": "0.10.3",
|
||||
"tsconfig-paths": "4.2.0",
|
||||
"url-loader": "4.1.1",
|
||||
"webpack": "5.89.0",
|
||||
"webpack-bundle-analyzer": "4.10.1",
|
||||
"webpack-cli": "5.1.4",
|
||||
"webpack-dev-server": "4.15.1",
|
||||
"webpack-merge": "5.10.0"
|
||||
"ts-jest": "29.1.1"
|
||||
},
|
||||
"peerDependencies": {}
|
||||
}
|
2778
source/ui/pnpm-lock.yaml
generated
Normal file
2778
source/ui/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load diff
5
source/ui/postcss.config.js
Normal file
5
source/ui/postcss.config.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
const configPath = require.resolve('./src/styles/tailwind.config.ts');
|
||||
|
||||
module.exports = {
|
||||
plugins: ['postcss-import', 'tailwindcss/nesting', ['tailwindcss', configPath], 'autoprefixer'],
|
||||
};
|
|
@ -1,82 +0,0 @@
|
|||
require('ts-node/register');
|
||||
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const HtmlWebPackPlugin = require('html-webpack-plugin');
|
||||
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
|
||||
const __basedir = path.resolve(__dirname, '..');
|
||||
|
||||
module.exports = (env, args, myEnv) => ({
|
||||
entry: {
|
||||
app: [path.resolve(__basedir, 'src/index.tsx')],
|
||||
style: [path.resolve(__basedir, 'src/styles/global.css')],
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__basedir, 'build'),
|
||||
publicPath: '/',
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
api: path.resolve(__basedir, 'src/api'),
|
||||
app: path.resolve(__basedir, 'src/app'),
|
||||
components: path.resolve(__basedir, 'src/components'),
|
||||
constants: path.resolve(__basedir, 'src/constants'),
|
||||
features: path.resolve(__basedir, 'src/features'),
|
||||
hooks: path.resolve(__basedir, 'src/hooks'),
|
||||
localization: path.resolve(__basedir, 'src/localization'),
|
||||
pages: path.resolve(__basedir, 'src/pages'),
|
||||
utils: path.resolve(__basedir, 'src/utils'),
|
||||
types: path.resolve(__basedir, 'src/types'),
|
||||
},
|
||||
extensions: ['.ts', '.tsx', '.js', '.json'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
loader: 'ts-loader',
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
config: path.resolve(__basedir, 'src/styles/postcss.config.js'),
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].css',
|
||||
}),
|
||||
new HtmlWebPackPlugin({
|
||||
hash: true,
|
||||
filename: 'index.html', //target html
|
||||
template: path.resolve(__basedir, 'src/app/assets/html/index.ejs'), //source html
|
||||
env: {
|
||||
websiteId: process.env.WA_WEBSITE_ID,
|
||||
},
|
||||
}),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{ from: path.resolve(__basedir, 'src/app/assets/public'), to: './' },
|
||||
],
|
||||
}),
|
||||
new webpack.EnvironmentPlugin(myEnv),
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
}),
|
||||
new CaseSensitivePathsPlugin(),
|
||||
],
|
||||
});
|
|
@ -1,17 +0,0 @@
|
|||
const { merge } = require('webpack-merge');
|
||||
|
||||
const common = require('./webpack-common');
|
||||
const myEnv = require('dotenv').config({ path: 'config/local/.env' }).parsed;
|
||||
|
||||
module.exports = (env, args) => {
|
||||
return merge(common(env, args, myEnv), {
|
||||
mode: 'development',
|
||||
devtool: 'inline-source-map',
|
||||
devServer: {
|
||||
host: '0.0.0.0',
|
||||
port: '3330',
|
||||
hot: true,
|
||||
historyApiFallback: true,
|
||||
},
|
||||
});
|
||||
};
|
|
@ -1,16 +0,0 @@
|
|||
const { merge } = require('webpack-merge');
|
||||
|
||||
const myEnv = require('dotenv').config({ path: 'config/prod/.env' }).parsed;
|
||||
const common = require('./webpack-common');
|
||||
|
||||
// const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
||||
|
||||
module.exports = (env, args) => {
|
||||
return merge(common(env, args, myEnv), {
|
||||
mode: 'production',
|
||||
devtool: false,
|
||||
plugins: [
|
||||
// new BundleAnalyzerPlugin(),
|
||||
],
|
||||
});
|
||||
};
|
|
@ -1,66 +0,0 @@
|
|||
// @ts-nocheck
|
||||
import React, { FC } from 'react';
|
||||
import { Route, Switch } from 'wouter';
|
||||
|
||||
import { useAuth } from '@procyon/auth/hook/useAuth';
|
||||
import Section from '@procyon/components/Section';
|
||||
import { Skeleton } from '@procyon/components/Skeleton';
|
||||
import { MenuItem } from '@procyon/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>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
<!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>
|
28
source/ui/src/app/layout.tsx
Normal file
28
source/ui/src/app/layout.tsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
// @ts-nocheck
|
||||
import '../styles/global.css';
|
||||
|
||||
import type { Metadata } from 'next';
|
||||
import { Poppins } from 'next/font/google';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { ReduxProvider } from '../providers/Redux';
|
||||
import { SkeletonProvider } from '../providers/Skeleton';
|
||||
|
||||
const inter = Poppins({ weight: ['300', '500', '700'], display: 'swap', subsets: ['latin'] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `$(AppName)`,
|
||||
description: '',
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: Readonly<{ children: ReactNode }>) {
|
||||
return (
|
||||
<ReduxProvider>
|
||||
<html lang="en">
|
||||
<body className={inter.className}>
|
||||
<SkeletonProvider>{children}</SkeletonProvider>
|
||||
</body>
|
||||
</html>
|
||||
</ReduxProvider>
|
||||
);
|
||||
}
|
4
source/ui/src/app/next-page/page.tsx
Normal file
4
source/ui/src/app/next-page/page.tsx
Normal file
|
@ -0,0 +1,4 @@
|
|||
// @ts-nocheck
|
||||
export default function Page() {
|
||||
return <b>Next page</b>;
|
||||
}
|
25
source/ui/src/app/page.tsx
Normal file
25
source/ui/src/app/page.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
// @ts-nocheck
|
||||
|
||||
async function getData() {
|
||||
const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
|
||||
// The return value is *not* serialized
|
||||
// You can return Date, Map, Set, etc.
|
||||
|
||||
if (!res.ok) {
|
||||
// This will activate the closest `error.js` Error Boundary
|
||||
throw new Error('Failed to fetch data');
|
||||
}
|
||||
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export default async function Page() {
|
||||
const data = await getData();
|
||||
return (
|
||||
<>
|
||||
Welcome
|
||||
<br />
|
||||
<pre>{JSON.stringify(data, null, 4)}</pre>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// @ts-nocheck
|
||||
import { DotNestedKeys } from '@procyon/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;
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
// @ts-nocheck
|
||||
// import generated apis
|
||||
|
||||
import { AnyAction, combineReducers, configureStore, ThunkDispatch } from '@reduxjs/toolkit';
|
||||
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import authReducer from '@procyon/auth/slice';
|
||||
import { AUTH_REDUCER_NAME } from '@procyon/auth/types';
|
||||
import { ROOT_REDUCER_NAME } from '@procyon/constants/redux';
|
||||
|
||||
import { emptyApi } from '../api/emptyApi';
|
||||
|
||||
type procyonReducer = {
|
||||
[AUTH_REDUCER_NAME]: typeof authReducer;
|
||||
};
|
||||
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
[ROOT_REDUCER_NAME]: combineReducers<procyonReducer>({
|
||||
[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;
|
|
@ -1,25 +0,0 @@
|
|||
// @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 '@procyon/components/Modal/context';
|
||||
import { ToasterWrapper } from '@procyon/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')
|
||||
);
|
|
@ -1,6 +0,0 @@
|
|||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
export const WelcomePage = () => {
|
||||
return <div className="welcome">Seedling app generator.</div>;
|
||||
};
|
16
source/ui/src/providers/Redux.tsx
Normal file
16
source/ui/src/providers/Redux.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
// @ts-nocheck
|
||||
'use client';
|
||||
|
||||
import { useRef, ReactNode } from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { makeStore } from '../redux/store';
|
||||
|
||||
export function ReduxProvider({ children }: { children: ReactNode }) {
|
||||
const storeRef = useRef<ReturnType<typeof makeStore> | null>(null);
|
||||
if (!storeRef.current) {
|
||||
storeRef.current = makeStore();
|
||||
}
|
||||
|
||||
return <Provider store={storeRef.current}>{children}</Provider>;
|
||||
}
|
28
source/ui/src/providers/Skeleton.tsx
Normal file
28
source/ui/src/providers/Skeleton.tsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
// @ts-nocheck
|
||||
'use client';
|
||||
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Skeleton } from '@procyon/components/Skeleton';
|
||||
|
||||
export function SkeletonProvider({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<Skeleton
|
||||
onHref={(path) => router.push(path as string)}
|
||||
items={{
|
||||
logo: <>App</>,
|
||||
top: [
|
||||
{
|
||||
label: 'Home',
|
||||
href: '/',
|
||||
},
|
||||
{
|
||||
label: 'Next page',
|
||||
href: '/next-page',
|
||||
},
|
||||
],
|
||||
}}>
|
||||
{children}
|
||||
</Skeleton>
|
||||
);
|
||||
}
|
27
source/ui/src/redux/store.ts
Normal file
27
source/ui/src/redux/store.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
// @ts-nocheck
|
||||
import { combineReducers, configureStore } from '@reduxjs/toolkit';
|
||||
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import authReducer from '@procyon/auth/slice';
|
||||
|
||||
import { emptyApi } from './emptyApi';
|
||||
|
||||
export const makeStore = () =>
|
||||
configureStore({
|
||||
reducer: {
|
||||
procyon: combineReducers({
|
||||
auth: authReducer,
|
||||
}),
|
||||
[emptyApi.reducerPath]: emptyApi.reducer,
|
||||
},
|
||||
middleware: (gDM) => gDM().prepend(emptyApi.middleware),
|
||||
devTools: process.env.NODE_ENV === 'development',
|
||||
});
|
||||
|
||||
export type ReduxStore = ReturnType<typeof makeStore>;
|
||||
|
||||
export type RootState = ReturnType<ReduxStore['getState']>;
|
||||
export type AppDispatch = ReduxStore['dispatch'];
|
||||
|
||||
export const useAppDispatch: () => AppDispatch = useDispatch;
|
||||
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
|
@ -1,8 +0,0 @@
|
|||
const component = () => ({
|
||||
});
|
||||
|
||||
module.exports = ({ addComponents, theme }) => {
|
||||
addComponents(component(theme));
|
||||
};
|
||||
|
||||
module.exports.component = component;
|
9
source/ui/src/styles/components/component.ts
Normal file
9
source/ui/src/styles/components/component.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { PluginCreator } from 'tailwindcss/types/config';
|
||||
|
||||
const component = () => ({});
|
||||
|
||||
const creator: PluginCreator = ({ addComponents, theme }) => {
|
||||
addComponents({});
|
||||
};
|
||||
|
||||
export default creator;
|
|
@ -1,9 +1,5 @@
|
|||
@import '@procyon/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;
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
const postcss = require('@procyon/styles/postcss.config');
|
||||
const configPath = require.resolve('./tailwind.config.js');
|
||||
|
||||
module.exports = postcss({ tailwindConfigFile: configPath });
|
|
@ -1,23 +0,0 @@
|
|||
const path = require('path');
|
||||
|
||||
const plugin = require('tailwindcss/plugin');
|
||||
|
||||
module.exports = {
|
||||
presets: [require('@procyon/styles/tailwind.config')],
|
||||
content: [
|
||||
path.resolve(__dirname + '../../**/*.{js,ts,tsx}'),
|
||||
path.resolve(__dirname + '../../../node_modules/@procyon/**/*.{js,ts,tsx}'),
|
||||
],
|
||||
safelist: require('@procyon/styles/tailwind.config').safelist,
|
||||
theme: {
|
||||
extend: require('./theme'),
|
||||
},
|
||||
variants: {
|
||||
extend: {
|
||||
borderWidth: ['last'],
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
plugin(require('./components/component')),
|
||||
],
|
||||
};
|
18
source/ui/src/styles/tailwind.config.ts
Normal file
18
source/ui/src/styles/tailwind.config.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import type { Config } from 'tailwindcss';
|
||||
import plugin from 'tailwindcss/plugin';
|
||||
import path from 'path';
|
||||
|
||||
export default {
|
||||
presets: [require('@procyon/styles/tailwind.config')],
|
||||
content: [
|
||||
path.resolve(__dirname + '../../app/*.{js,ts,tsx}'),
|
||||
path.resolve(__dirname + '../../pages/*.{js,ts,tsx}'),
|
||||
path.resolve(__dirname + '../../components/*.{js,ts,tsx}'),
|
||||
path.resolve(__dirname + '../../../node_modules/@procyon/**/*.{js,ts,tsx}'),
|
||||
],
|
||||
safelist: require('@procyon/styles/tailwind.config').safelist,
|
||||
theme: {
|
||||
extend: require('./theme'),
|
||||
},
|
||||
plugins: [plugin(require('./components/component'))],
|
||||
} satisfies Config;
|
|
@ -1,10 +0,0 @@
|
|||
const { pallete } = require('@procyon/styles/utils/color');
|
||||
|
||||
module.exports = {
|
||||
colors: {
|
||||
disabled: pallete('disabled'),
|
||||
},
|
||||
borderWidth: {
|
||||
1: '1px',
|
||||
},
|
||||
};
|
12
source/ui/src/styles/theme.ts
Normal file
12
source/ui/src/styles/theme.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// @ts-nocheck
|
||||
|
||||
import palette from '@procyon/styles/palette';
|
||||
|
||||
module.exports = {
|
||||
colors: {
|
||||
...palette,
|
||||
},
|
||||
borderWidth: {
|
||||
1: '1px',
|
||||
},
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
:root {
|
||||
--color-h: 0;
|
||||
--color-s: 0%;
|
||||
--color-l: 0%;
|
||||
}
|
5
source/ui/src/types/next-env.d.ts
vendored
Normal file
5
source/ui/src/types/next-env.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
8
source/ui/src/types/yup.d.ts
vendored
8
source/ui/src/types/yup.d.ts
vendored
|
@ -1,8 +0,0 @@
|
|||
// @ts-nocheck
|
||||
import { StringSchema } from 'yup';
|
||||
|
||||
declare module 'yup' {
|
||||
interface StringSchema {
|
||||
// place custom Yup definition of validation
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
// @ts-nocheck
|
||||
// place import for custom Yup validations
|
||||
|
||||
import * as Yup from 'yup';
|
||||
import * as Yup from 'src/utils/yup';
|
||||
|
||||
Yup.setLocale({
|
||||
mixed: {
|
||||
|
|
9
source/ui/tests/nightwatchjs.d.ts
vendored
9
source/ui/tests/nightwatchjs.d.ts
vendored
|
@ -1,9 +0,0 @@
|
|||
import { Definition } from 'nightwatch';
|
||||
|
||||
declare module 'nightwatch' {
|
||||
interface NightwatchCustomPageObjects {
|
||||
}
|
||||
|
||||
export interface NightwatchCustomCommands {
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": ".nightwatchjs",
|
||||
"baseUrl": ".",
|
||||
"rootDir": ".",
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "commonjs",
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": false,
|
||||
"target": "es6",
|
||||
"lib": [
|
||||
"es6",
|
||||
],
|
||||
},
|
||||
"files": [
|
||||
"./nightwatchjs.d.ts"
|
||||
],
|
||||
"include": [
|
||||
"./**/*.ts",
|
||||
]
|
||||
}
|
Loading…
Add table
Reference in a new issue