merge release/environment-variables
9
.env
@ -1,2 +1,11 @@
|
||||
####### COMMON #######
|
||||
USE_DEV_COLORS=
|
||||
BASE_PATH=
|
||||
|
||||
####### USERS ########
|
||||
USERS_SUPER=["akalinina","vchikalkin"]
|
||||
|
||||
####### URLS ########
|
||||
URL_GET_USER_DIRECT=
|
||||
URL_CRM_GRAPHQL_DIRECT=
|
||||
URL_CORE_FINGAP_DIRECT=
|
||||
4
@packages/tools/common.ts
Normal file
@ -0,0 +1,4 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
export function isServer() {
|
||||
return typeof window === 'undefined';
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import { createGlobalStyle } from 'styled-components';
|
||||
|
||||
export const GlobalStyle = createGlobalStyle`
|
||||
:root {
|
||||
--color-background: rgb(240, 240, 240);
|
||||
--color-primary: ${process.env.NEXT_PUBLIC_COLOR_PRIMARY};
|
||||
--color-secondary: ${process.env.NEXT_PUBLIC_COLOR_SECONDARY};
|
||||
--color-tertiarty: ${process.env.NEXT_PUBLIC_COLOR_TERTIARTY};
|
||||
}
|
||||
`;
|
||||
17
Dockerfile
@ -16,23 +16,10 @@ WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
ARG NEXT_PUBLIC_BASE_PATH
|
||||
ARG NEXT_PUBLIC_COLOR_PRIMARY
|
||||
ARG NEXT_PUBLIC_COLOR_SECONDARY
|
||||
ARG NEXT_PUBLIC_COLOR_TERTIARTY
|
||||
ARG NEXT_PUBLIC_FAVICON
|
||||
ARG NEXT_TELEMETRY_DISABLED
|
||||
ARG NEXT_PUBLIC_URL_CRM_GRAPHQL_PROXY
|
||||
ARG NEXT_PUBLIC_URL_CRM_GRAPHQL_DIRECT
|
||||
ARG NEXT_PUBLIC_URL_GET_USER_PROXY
|
||||
ARG NEXT_PUBLIC_URL_GET_USER_DIRECT
|
||||
ARG NEXT_PUBLIC_URL_CORE_FINGAP_PROXY
|
||||
ARG NEXT_PUBLIC_URL_CORE_FINGAP_DIRECT
|
||||
|
||||
# Next.js collects completely anonymous telemetry data about general usage.
|
||||
# Learn more here: https://nextjs.org/telemetry
|
||||
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN yarn build
|
||||
|
||||
@ -45,7 +32,7 @@ WORKDIR /app
|
||||
|
||||
ENV NODE_ENV production
|
||||
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import type { QueryFunctionContext } from '@tanstack/react-query';
|
||||
import axios from 'axios';
|
||||
import getUrls from 'config/urls';
|
||||
import type { RequestFinGAP, ResponseFinGAP } from './types';
|
||||
|
||||
const { URL_CORE_FINGAP } = getUrls();
|
||||
|
||||
export async function calculateFinGAP(payload: RequestFinGAP, { signal }: QueryFunctionContext) {
|
||||
const { data } = await axios.post<ResponseFinGAP>(
|
||||
process.env.NEXT_PUBLIC_URL_CORE_FINGAP_PROXY!,
|
||||
payload,
|
||||
{
|
||||
signal,
|
||||
}
|
||||
);
|
||||
const { data } = await axios.post<ResponseFinGAP>(URL_CORE_FINGAP, payload, {
|
||||
signal,
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import type { AxiosRequestConfig } from 'axios';
|
||||
import axios from 'axios';
|
||||
import getUrls from 'config/urls';
|
||||
import { love } from './tools';
|
||||
import type { User } from './types';
|
||||
|
||||
// prettier-ignore
|
||||
const uri = typeof window === 'undefined'
|
||||
? process.env.NEXT_PUBLIC_URL_GET_USER_DIRECT
|
||||
: process.env.NEXT_PUBLIC_URL_GET_USER_PROXY;
|
||||
const { URL_GET_USER } = getUrls();
|
||||
|
||||
export async function getUser(config: AxiosRequestConfig) {
|
||||
const user = await axios.get<User>(uri!, config).then((res) => love(res.data));
|
||||
const user = await axios.get<User>(URL_GET_USER, config).then((res) => love(res.data));
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ module.exports = {
|
||||
client: {
|
||||
service: {
|
||||
name: 'crmgraphql',
|
||||
url: process.env.NEXT_PUBLIC_URL_CRM_GRAPHQL_DIRECT,
|
||||
url: process.env.URL_CRM_GRAPHQL_DIRECT,
|
||||
localSchemaFile: './graphql/crm.schema.graphql',
|
||||
},
|
||||
excludes: ['graphql/**/*'],
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { ApolloClient, InMemoryCache } from '@apollo/client';
|
||||
import getUrls from 'config/urls';
|
||||
import { isServer } from 'tools/common';
|
||||
|
||||
/** @type {import('@apollo/client').ApolloClient<NormalizedCacheObject>} */
|
||||
let apolloClient;
|
||||
|
||||
// prettier-ignore
|
||||
const uri = typeof window === 'undefined'
|
||||
? process.env.NEXT_PUBLIC_URL_CRM_GRAPHQL_DIRECT
|
||||
: process.env.NEXT_PUBLIC_URL_CRM_GRAPHQL_PROXY;
|
||||
const { URL_CRM_GRAPHQL } = getUrls();
|
||||
|
||||
function createApolloClient() {
|
||||
return new ApolloClient({
|
||||
ssrMode: typeof window === 'undefined',
|
||||
uri,
|
||||
ssrMode: isServer(),
|
||||
uri: URL_CRM_GRAPHQL,
|
||||
cache: new InMemoryCache(),
|
||||
});
|
||||
}
|
||||
@ -27,7 +26,7 @@ export default function initializeApollo(initialState = null) {
|
||||
_apolloClient.cache.restore(initialState);
|
||||
}
|
||||
// For SSG and SSR always create a new Apollo Client
|
||||
if (typeof window === 'undefined') return _apolloClient;
|
||||
if (isServer()) return _apolloClient;
|
||||
// Create the Apollo Client once in the client
|
||||
if (!apolloClient) apolloClient = _apolloClient;
|
||||
|
||||
|
||||
19
config/meta.jsx
Normal file
@ -0,0 +1,19 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import getUrls from 'config/urls';
|
||||
|
||||
const { BASE_PATH } = getUrls();
|
||||
|
||||
function buildPath(filePath) {
|
||||
return String.prototype.concat(BASE_PATH, filePath);
|
||||
}
|
||||
|
||||
export const metaFavicon = (
|
||||
<>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href={buildPath('/apple-touch-icon.png')} />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href={buildPath('/favicon-32x32.png')} />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href={buildPath('/favicon-16x16.png')} />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<link rel="mask-icon" href={buildPath('/safari-pinned-tab.svg')} color="#5bbad5" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
</>
|
||||
);
|
||||
16
config/schema/env.js
Normal file
@ -0,0 +1,16 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const { z } = require('zod');
|
||||
|
||||
const envSchema = z.object({
|
||||
USE_DEV_COLORS: z
|
||||
.unknown()
|
||||
.optional()
|
||||
.transform((val) => !!val),
|
||||
PORT: z.string().optional(),
|
||||
BASE_PATH: z.string().optional().default(''),
|
||||
URL_CRM_GRAPHQL_DIRECT: z.string(),
|
||||
URL_GET_USER_DIRECT: z.string(),
|
||||
URL_CORE_FINGAP_DIRECT: z.string(),
|
||||
});
|
||||
|
||||
module.exports = envSchema;
|
||||
20
config/schema/runtime-config.js
Normal file
@ -0,0 +1,20 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const envSchema = require('./env');
|
||||
|
||||
const publicRuntimeConfigSchema = envSchema.pick({
|
||||
BASE_PATH: true,
|
||||
USE_DEV_COLORS: true,
|
||||
});
|
||||
|
||||
const serverRuntimeConfigSchema = envSchema.pick({
|
||||
PORT: true,
|
||||
BASE_PATH: true,
|
||||
URL_CRM_GRAPHQL_DIRECT: true,
|
||||
URL_GET_USER_DIRECT: true,
|
||||
URL_CORE_FINGAP_DIRECT: true,
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
publicRuntimeConfigSchema,
|
||||
serverRuntimeConfigSchema,
|
||||
};
|
||||
36
config/urls.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import urls from 'constants/urls';
|
||||
import getConfig from 'next/config';
|
||||
import { isServer } from 'tools/common';
|
||||
import { publicRuntimeConfigSchema, serverRuntimeConfigSchema } from './schema/runtime-config';
|
||||
|
||||
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();
|
||||
|
||||
function getUrls() {
|
||||
if (isServer()) {
|
||||
const { URL_CRM_GRAPHQL_DIRECT, URL_GET_USER_DIRECT, URL_CORE_FINGAP_DIRECT, BASE_PATH, PORT } =
|
||||
serverRuntimeConfigSchema.parse(serverRuntimeConfig);
|
||||
|
||||
return {
|
||||
PORT,
|
||||
BASE_PATH,
|
||||
URL_CRM_GRAPHQL: URL_CRM_GRAPHQL_DIRECT,
|
||||
URL_GET_USER: URL_GET_USER_DIRECT,
|
||||
URL_CORE_FINGAP: URL_CORE_FINGAP_DIRECT,
|
||||
};
|
||||
}
|
||||
|
||||
const { BASE_PATH } = publicRuntimeConfigSchema.parse(publicRuntimeConfig);
|
||||
|
||||
function withBasePath(url: string) {
|
||||
return BASE_PATH + url;
|
||||
}
|
||||
|
||||
return {
|
||||
BASE_PATH,
|
||||
URL_CRM_GRAPHQL: withBasePath(urls.URL_CRM_GRAPHQL_PROXY),
|
||||
URL_GET_USER: withBasePath(urls.URL_GET_USER_PROXY),
|
||||
URL_CORE_FINGAP: withBasePath(urls.URL_CORE_FINGAP_PROXY),
|
||||
};
|
||||
}
|
||||
|
||||
export default getUrls;
|
||||
15
constants/colors.js
Normal file
@ -0,0 +1,15 @@
|
||||
const COLORS_PROD = {
|
||||
COLOR_PRIMARY: '#1C01A9',
|
||||
COLOR_SECONDARY: '#3A0185',
|
||||
COLOR_TERTIARTY: '#580161',
|
||||
};
|
||||
const COLORS_DEV = {
|
||||
COLOR_PRIMARY: '#BF3676',
|
||||
COLOR_SECONDARY: '#FD4047',
|
||||
COLOR_TERTIARTY: '#FF9112',
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
COLORS_PROD,
|
||||
COLORS_DEV,
|
||||
};
|
||||
5
constants/urls.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
URL_GET_USER_PROXY: '/api/auth/user',
|
||||
URL_CRM_GRAPHQL_PROXY: '/api/graphql/crm',
|
||||
URL_CORE_FINGAP_PROXY: '/api/core/fingap',
|
||||
};
|
||||
@ -1,3 +1,4 @@
|
||||
import getUrls from 'config/urls';
|
||||
import { rest } from 'msw';
|
||||
const _ = require('radash');
|
||||
|
||||
@ -22,11 +23,13 @@ const users = {
|
||||
},
|
||||
};
|
||||
|
||||
const { URL_GET_USER, URL_CORE_FINGAP, URL_CRM_GRAPHQL } = getUrls();
|
||||
|
||||
export const handlers = [
|
||||
rest.get(process.env.NEXT_PUBLIC_URL_GET_USER_DIRECT, (req, res, ctx) => {
|
||||
rest.get(URL_GET_USER, (req, res, ctx) => {
|
||||
return res(ctx.json(users.vchikalkin));
|
||||
}),
|
||||
rest.post(process.env.NEXT_PUBLIC_URL_CORE_FINGAP_PROXY, (req, res, ctx) => {
|
||||
rest.post(URL_CORE_FINGAP, (req, res, ctx) => {
|
||||
return res(
|
||||
ctx.json({
|
||||
sum: _.random(100000, 200000),
|
||||
@ -34,7 +37,7 @@ export const handlers = [
|
||||
})
|
||||
);
|
||||
}),
|
||||
// rest.post(process.env.NEXT_PUBLIC_URL_CRM_GRAPHQL_PROXY, (req, res, ctx) => {
|
||||
// rest.post(URL_CRM_GRAPHQL, (req, res, ctx) => {
|
||||
// return res(ctx.status(503));
|
||||
// }),
|
||||
];
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
if (typeof window === 'undefined') {
|
||||
const { isServer } = require('tools/common');
|
||||
|
||||
if (isServer()) {
|
||||
const { server } = require('./server');
|
||||
server.listen();
|
||||
} else {
|
||||
|
||||
@ -3,11 +3,28 @@
|
||||
const { withPlugins } = require('next-composed-plugins');
|
||||
const withLess = require('next-with-less');
|
||||
const withGraphQL = require('next-plugin-graphql');
|
||||
const fs = require('fs');
|
||||
const { COLORS_DEV, COLORS_PROD } = require('./constants/colors');
|
||||
const envSchema = require('./config/schema/env');
|
||||
const urls = require('./constants/urls');
|
||||
const { devices } = require('./@packages/ui/screens');
|
||||
const { publicRuntimeConfigSchema } = require('./config/schema/runtime-config');
|
||||
const { serverRuntimeConfigSchema } = require('./config/schema/runtime-config');
|
||||
|
||||
const env = envSchema.parse(process.env);
|
||||
|
||||
const favicons = fs.readdirSync('./public/favicon/prod');
|
||||
const faviconSubPath = env.USE_DEV_COLORS ? '/favicon/dev' : '/favicon/prod';
|
||||
function buildFaviconRewrite(source) {
|
||||
return {
|
||||
source,
|
||||
destination: String.prototype.concat(faviconSubPath, source),
|
||||
};
|
||||
}
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
basePath: process.env.NEXT_PUBLIC_BASE_PATH,
|
||||
basePath: env.BASE_PATH,
|
||||
output: 'standalone',
|
||||
swcMinify: true,
|
||||
reactStrictMode: true,
|
||||
@ -20,34 +37,37 @@ const nextConfig = {
|
||||
images: {
|
||||
deviceSizes: devices,
|
||||
},
|
||||
rewrites:
|
||||
process.env.NODE_ENV === 'development' &&
|
||||
async function rewrites() {
|
||||
return [
|
||||
{
|
||||
source: process.env.NEXT_PUBLIC_URL_CRM_GRAPHQL_PROXY,
|
||||
destination: process.env.NEXT_PUBLIC_URL_CRM_GRAPHQL_DIRECT,
|
||||
},
|
||||
{
|
||||
source: process.env.NEXT_PUBLIC_URL_GET_USER_PROXY,
|
||||
destination: process.env.NEXT_PUBLIC_URL_GET_USER_DIRECT,
|
||||
},
|
||||
{
|
||||
source: process.env.NEXT_PUBLIC_URL_CORE_FINGAP_PROXY,
|
||||
destination: process.env.NEXT_PUBLIC_URL_CORE_FINGAP_DIRECT,
|
||||
},
|
||||
];
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
{
|
||||
source: urls.URL_CRM_GRAPHQL_PROXY,
|
||||
destination: env.URL_CRM_GRAPHQL_DIRECT,
|
||||
},
|
||||
{
|
||||
source: urls.URL_GET_USER_PROXY,
|
||||
destination: env.URL_GET_USER_DIRECT,
|
||||
},
|
||||
{
|
||||
source: urls.URL_CORE_FINGAP_PROXY,
|
||||
destination: env.URL_CORE_FINGAP_DIRECT,
|
||||
},
|
||||
...favicons.map((fileName) => buildFaviconRewrite(`/${fileName}`)),
|
||||
];
|
||||
},
|
||||
publicRuntimeConfig: publicRuntimeConfigSchema.parse(env),
|
||||
serverRuntimeConfig: serverRuntimeConfigSchema.parse(env),
|
||||
};
|
||||
|
||||
const plugins = [withLess, withGraphQL];
|
||||
|
||||
const colorPrimary = env.USE_DEV_COLORS ? COLORS_DEV.COLOR_PRIMARY : COLORS_PROD.COLOR_PRIMARY;
|
||||
|
||||
const config = {
|
||||
...nextConfig,
|
||||
lessLoaderOptions: {
|
||||
lessOptions: {
|
||||
modifyVars: {
|
||||
'primary-color': process.env.NEXT_PUBLIC_COLOR_PRIMARY,
|
||||
'primary-color': colorPrimary,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -7,8 +7,8 @@ import 'normalize.css';
|
||||
import { useMemo } from 'react';
|
||||
import StoreProvider from 'stores/Provider';
|
||||
import { ThemeProvider } from 'styled-components';
|
||||
import { GlobalStyle } from 'styles/global-style';
|
||||
import { trpcClient } from 'trpc/client';
|
||||
import { GlobalStyle } from 'ui/colors';
|
||||
import { ConfigProvider, ru_RU } from 'ui/elements/config';
|
||||
import 'ui/elements/styles/antd.less';
|
||||
import theme from 'ui/theme';
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { metaFavicon } from 'config/meta';
|
||||
import Document, { Head, Html, Main, NextScript } from 'next/document';
|
||||
import { ServerStyleSheet } from 'styled-components';
|
||||
|
||||
@ -35,8 +36,7 @@ export default class MyDocument extends Document {
|
||||
<meta charSet="utf-8" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Лизинговый калькулятор Эволюция" />
|
||||
<link rel="icon" href={process.env.NEXT_PUBLIC_FAVICON} crossOrigin="use-credentials" />
|
||||
<link rel="apple-touch-icon" href="logo-100.png" crossOrigin="use-credentials" />
|
||||
{metaFavicon}
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
|
||||
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 9.4 KiB |
BIN
public/favicon/dev/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/favicon/dev/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
public/favicon/dev/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/favicon/dev/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
public/favicon/dev/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
public/favicon/dev/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
32
public/favicon/dev/safari-pinned-tab.svg
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="789.000000pt" height="789.000000pt" viewBox="0 0 789.000000 789.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,789.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M3119 7886 c-2 -2 -47 -6 -99 -10 -440 -29 -955 -160 -1375 -349
|
||||
-362 -164 -769 -429 -1038 -676 -20 -19 -51 -47 -69 -63 l-32 -28 25 -27 c37
|
||||
-42 53 -58 224 -238 88 -92 175 -184 194 -204 18 -20 101 -108 185 -195 83
|
||||
-87 159 -168 169 -180 10 -12 58 -62 107 -112 l87 -91 34 31 c869 811 2202
|
||||
938 3217 305 224 -139 480 -365 636 -559 305 -382 481 -807 542 -1310 9 -71 9
|
||||
-365 1 -452 -70 -706 -427 -1336 -999 -1764 -374 -279 -802 -448 -1288 -508
|
||||
-111 -14 -522 -15 -595 -2 -16 3 -66 10 -110 16 -504 71 -1019 317 -1388 663
|
||||
-43 40 -61 45 -74 23 -4 -8 -50 -59 -102 -113 -167 -175 -274 -287 -361 -379
|
||||
-47 -49 -157 -166 -246 -259 -199 -210 -249 -265 -249 -275 0 -9 157 -149 265
|
||||
-236 135 -109 321 -237 490 -336 96 -57 393 -208 407 -208 4 0 21 -7 36 -15
|
||||
32 -16 233 -93 322 -123 309 -104 655 -174 986 -199 189 -14 662 -8 765 11 10
|
||||
2 46 7 79 10 101 12 125 16 280 47 1512 300 2716 1413 3104 2869 35 131 72
|
||||
306 85 400 2 19 8 58 11 85 4 28 9 61 11 75 26 160 25 669 -2 885 -6 49 -33
|
||||
231 -40 271 -14 81 -79 334 -115 449 -402 1281 -1483 2296 -2814 2640 -225 58
|
||||
-366 83 -645 116 -85 10 -612 23 -621 15z"/>
|
||||
<path d="M3207 4984 c-309 -40 -582 -211 -749 -469 -118 -181 -169 -357 -169
|
||||
-575 0 -348 173 -670 464 -864 492 -327 1152 -192 1472 303 72 112 116 220
|
||||
151 376 12 52 13 308 2 365 -64 331 -254 592 -548 752 -181 98 -408 139 -623
|
||||
112z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
BIN
public/favicon/prod/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/favicon/prod/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
public/favicon/prod/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/favicon/prod/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 941 B |
BIN
public/favicon/prod/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
public/favicon/prod/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
48
public/favicon/prod/safari-pinned-tab.svg
Normal file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="789.000000pt" height="789.000000pt" viewBox="0 0 789.000000 789.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,789.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M3157 7885 c-1 -2 -54 -5 -117 -9 -100 -6 -205 -17 -290 -31 -14 -3
|
||||
-43 -7 -65 -10 -68 -10 -209 -37 -290 -56 -369 -85 -762 -240 -1094 -431 -46
|
||||
-26 -85 -48 -87 -48 -8 0 -234 -154 -330 -225 -111 -82 -295 -238 -346 -291
|
||||
l-27 -29 66 -70 c124 -131 388 -409 478 -504 50 -52 101 -106 115 -121 155
|
||||
-166 325 -340 330 -338 7 3 127 108 155 134 27 27 241 176 317 222 238 141
|
||||
499 245 763 306 108 24 128 28 230 41 28 4 61 9 75 11 36 6 225 17 295 17 127
|
||||
0 313 -14 427 -34 32 -6 70 -12 85 -15 16 -2 84 -18 152 -35 514 -127 1007
|
||||
-429 1334 -819 40 -47 75 -87 78 -90 3 -3 37 -50 76 -105 131 -188 227 -370
|
||||
304 -579 32 -88 85 -272 94 -326 3 -19 8 -42 10 -50 2 -8 7 -33 10 -55 3 -23
|
||||
8 -52 11 -65 18 -90 25 -418 11 -565 -55 -572 -304 -1093 -722 -1510 -213
|
||||
-213 -420 -361 -690 -494 -234 -115 -497 -201 -725 -236 -19 -3 -46 -7 -60
|
||||
-10 -22 -4 -60 -8 -195 -21 -55 -5 -353 -5 -390 0 -16 2 -61 7 -100 10 -98 9
|
||||
-327 50 -345 61 -3 2 -19 6 -34 9 -64 12 -243 70 -351 114 -83 35 -360 176
|
||||
-375 192 -3 3 -30 21 -60 40 -65 41 -51 31 -176 129 -56 43 -123 99 -150 125
|
||||
-27 25 -52 46 -55 46 -6 0 -50 -46 -329 -340 -85 -90 -175 -184 -200 -211 -25
|
||||
-26 -106 -111 -180 -190 -74 -79 -148 -157 -165 -174 -106 -110 -119 -126
|
||||
-109 -133 6 -4 47 -39 90 -79 303 -275 708 -535 1084 -697 36 -15 66 -27 68
|
||||
-27 1 1 17 -6 35 -15 33 -18 321 -120 359 -128 13 -3 72 -19 132 -35 129 -36
|
||||
282 -69 401 -86 22 -4 47 -8 55 -10 8 -2 43 -7 78 -10 35 -4 71 -8 80 -10 129
|
||||
-24 730 -24 882 0 14 3 50 7 80 10 61 6 79 9 195 30 44 8 91 16 105 19 14 2
|
||||
66 14 115 26 50 12 97 23 105 25 87 18 389 118 516 170 908 375 1640 1047
|
||||
2070 1905 120 239 217 490 270 695 1 6 12 46 23 90 12 44 23 90 26 103 2 12 6
|
||||
30 9 40 3 9 7 28 10 42 2 14 9 52 15 85 6 33 13 76 15 95 2 19 7 55 10 80 4
|
||||
25 8 61 11 80 26 207 26 621 -1 860 -13 126 -61 394 -83 468 -5 18 -10 33 -10
|
||||
35 1 7 -17 75 -43 162 -200 674 -573 1272 -1099 1760 -101 94 -130 118 -261
|
||||
220 -68 52 -128 99 -133 103 -29 23 -195 132 -201 132 -4 0 -15 6 -23 14 -9 8
|
||||
-32 23 -51 34 -19 11 -69 39 -110 62 -208 119 -540 261 -783 334 -126 38 -290
|
||||
81 -347 91 -19 3 -51 10 -70 15 -38 9 -66 14 -175 30 -121 18 -212 28 -315 36
|
||||
-71 6 -487 13 -493 9z"/>
|
||||
<path d="M3348 4996 c-1 -2 -41 -6 -88 -10 -110 -7 -139 -13 -235 -43 -293
|
||||
-92 -534 -309 -651 -585 -57 -135 -76 -223 -80 -378 -5 -192 21 -324 93 -476
|
||||
28 -58 82 -154 93 -164 3 -3 17 -21 32 -41 139 -186 385 -334 638 -384 108
|
||||
-21 340 -14 442 13 318 86 554 278 696 567 30 62 67 168 77 220 27 154 31 290
|
||||
10 420 -11 67 -64 214 -105 294 -164 312 -484 527 -830 557 -36 3 -70 7 -77 9
|
||||
-6 2 -13 2 -15 1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
19
public/site.webmanifest
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "",
|
||||
"short_name": "",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
import { createContext } from 'react';
|
||||
import { isServer } from 'tools/common';
|
||||
import RootStore from './root';
|
||||
|
||||
/** @type{RootStore} */
|
||||
@ -27,7 +28,7 @@ export function initializeStore(initialData) {
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof window === 'undefined') return _store;
|
||||
if (isServer()) return _store;
|
||||
if (!store) store = _store;
|
||||
|
||||
return _store;
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
/* eslint-disable import/no-cycle */
|
||||
import { enableStaticRendering } from 'mobx-react-lite';
|
||||
import { isServer } from 'tools/common';
|
||||
import CalculationStore from './calculation';
|
||||
import type { ProcessStore } from './process';
|
||||
import createProcessStore from './process';
|
||||
import ResultsStore from './results';
|
||||
import TablesStore from './tables';
|
||||
|
||||
enableStaticRendering(typeof window === 'undefined');
|
||||
enableStaticRendering(isServer());
|
||||
|
||||
export default class RootStore {
|
||||
$calculation: CalculationStore;
|
||||
|
||||
14
styles/colors.js
Normal file
@ -0,0 +1,14 @@
|
||||
import getConfig from 'next/config';
|
||||
import { publicRuntimeConfigSchema } from '../config/schema/runtime-config';
|
||||
import { COLORS_DEV, COLORS_PROD } from '../constants/colors';
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const { USE_DEV_COLORS } = publicRuntimeConfigSchema.parse(publicRuntimeConfig);
|
||||
|
||||
export default function getColors() {
|
||||
if (USE_DEV_COLORS) {
|
||||
return COLORS_DEV;
|
||||
}
|
||||
|
||||
return COLORS_PROD;
|
||||
}
|
||||
14
styles/global-style.js
Normal file
@ -0,0 +1,14 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import { createGlobalStyle } from 'styled-components';
|
||||
import getColors from './colors';
|
||||
|
||||
const { COLOR_PRIMARY, COLOR_SECONDARY, COLOR_TERTIARTY } = getColors();
|
||||
|
||||
export const GlobalStyle = createGlobalStyle`
|
||||
:root {
|
||||
--color-background: rgb(240, 240, 240);
|
||||
--color-primary: ${COLOR_PRIMARY};
|
||||
--color-secondary: ${COLOR_SECONDARY};
|
||||
--color-tertiarty: ${COLOR_TERTIARTY};
|
||||
}
|
||||
`;
|
||||
@ -1,22 +1,26 @@
|
||||
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
||||
import { createTRPCNext } from '@trpc/next';
|
||||
import getUrls from 'config/urls';
|
||||
import SuperJSON from 'superjson';
|
||||
import { isServer } from 'tools/common';
|
||||
import type { AppRouter } from './routers';
|
||||
|
||||
function getBaseUrl() {
|
||||
if (typeof window !== 'undefined') {
|
||||
return process.env.NEXT_PUBLIC_BASE_PATH ?? '';
|
||||
}
|
||||
const { BASE_PATH, PORT } = getUrls();
|
||||
|
||||
return `http://localhost:${process.env.PORT ?? 3000}${process.env.NEXT_PUBLIC_BASE_PATH ?? ''}`;
|
||||
function getBaseUrl() {
|
||||
if (!isServer()) return BASE_PATH;
|
||||
|
||||
return `http://localhost:${PORT ?? 3000}${BASE_PATH}`;
|
||||
}
|
||||
|
||||
const url = `${getBaseUrl()}/api/trpc`;
|
||||
|
||||
export const trpcClient = createTRPCNext<AppRouter>({
|
||||
config() {
|
||||
return {
|
||||
links: [
|
||||
httpBatchLink({
|
||||
url: `${getBaseUrl()}/api/trpc`,
|
||||
url,
|
||||
}),
|
||||
],
|
||||
transformer: SuperJSON,
|
||||
@ -28,7 +32,7 @@ export const trpcClient = createTRPCNext<AppRouter>({
|
||||
export const trpcPureClient = createTRPCProxyClient<AppRouter>({
|
||||
links: [
|
||||
httpBatchLink({
|
||||
url: `${getBaseUrl()}/api/trpc`,
|
||||
url,
|
||||
}),
|
||||
],
|
||||
transformer: SuperJSON,
|
||||
|
||||