merge project/eslint-rules

This commit is contained in:
vchikalkin 2023-08-01 15:23:30 +03:00
parent 18927d3074
commit 6be2af972c
38 changed files with 2399 additions and 546 deletions

View File

@ -1,10 +1,11 @@
module.exports = { module.exports = {
root: true, root: true,
// This tells ESLint to load the config from the package `eslint-config-custom`
extends: ["custom/common"],
settings: { settings: {
next: { next: {
rootDir: ["apps/*/"], rootDir: ['apps/*/'],
},
react: {
version: 'detect',
}, },
}, },
}; };

23
.vscode/settings.json vendored
View File

@ -8,5 +8,26 @@
"**/Thumbs.db": true, "**/Thumbs.db": true,
"**/node_modules": true "**/node_modules": true
}, },
"explorerExclude.backup": {} "explorerExclude.backup": null,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.fixAll.eslint": true,
"source.removeUnusedImports": true
},
"workbench.editor.labelFormat": "short",
"eslint.workingDirectories": [
{ "directory": "apps/web", "changeProcessCWD": true }
],
"eslint.validate": [
"javascript",
"javascriptreact",
"json",
"typescript",
"typescriptreact",
"yaml"
],
"eslint.lintTask.enable": true
} }

4
apps/api/.env Normal file
View File

@ -0,0 +1,4 @@
SECRET=secret
TOKEN_TTL=3600
CACHE_TTL=3600
COOKIE_TOKEN_NAME=token

View File

@ -1,61 +1,12 @@
module.exports = { module.exports = {
parser: '@typescript-eslint/parser', root: true,
extends: [
'@vchikalkin/eslint-config-awesome/typescript/config',
'@vchikalkin/eslint-config-awesome/typescript/rules',
],
parserOptions: { parserOptions: {
project: 'tsconfig.json', project: './tsconfig.json',
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,
sourceType: 'module', sourceType: 'module',
}, },
plugins: ['@typescript-eslint/eslint-plugin', 'prettier', 'unicorn'],
extends: [
'prettier',
'airbnb-base',
'airbnb-typescript/base',
'plugin:@typescript-eslint/recommended',
'plugin:unicorn/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'linebreak-style': ['error', 'windows'],
'comma-dangle': 'off',
'@typescript-eslint/comma-dangle': ['off'],
'import/extensions': 'off',
'object-curly-newline': [
'warn',
{
ObjectExpression: 'always',
ObjectPattern: { multiline: true },
ImportDeclaration: 'never',
ExportDeclaration: { multiline: true, minProperties: 3 },
},
],
'lines-between-class-members': 'off',
'@typescript-eslint/lines-between-class-members': ['off'],
indent: 'off',
'@typescript-eslint/indent': ['off'],
'newline-before-return': 'warn',
'@typescript-eslint/consistent-type-imports': 'error',
// Airbnb prefers forEach
'unicorn/no-array-for-each': 'off',
'unicorn/prevent-abbreviations': 'off',
'unicorn/no-null': 'off',
'unicorn/prefer-node-protocol': 'off',
'unicorn/no-array-reduce': 'off',
'unicorn/prefer-module': 'off',
'unicorn/text-encoding-identifier-case': 'off',
'import/no-unresolved': 'warn',
'import/prefer-default-export': 'off',
'class-methods-use-this': 'off',
},
}; };

View File

@ -18,7 +18,8 @@
"test:watch": "jest --watch", "test:watch": "jest --watch",
"test:cov": "jest --coverage", "test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json" "test:e2e": "jest --config ./test/jest-e2e.json",
"lint:fix": "eslint --fix"
}, },
"dependencies": { "dependencies": {
"@fastify/cookie": "^8.0.0", "@fastify/cookie": "^8.0.0",
@ -46,15 +47,8 @@
"@types/ldap-authentication": "^2.2.0", "@types/ldap-authentication": "^2.2.0",
"@types/node": "^16.0.0", "@types/node": "^16.0.0",
"@types/supertest": "^2.0.11", "@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0", "@vchikalkin/eslint-config-awesome": "^1.1.1",
"@typescript-eslint/parser": "^5.0.0", "eslint": "^8.46.0",
"eslint": "^8.28.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-unicorn": "^43.0.2",
"jest": "28.1.2", "jest": "28.1.2",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"source-map-support": "^0.5.20", "source-map-support": "^0.5.20",

View File

@ -1,7 +1,7 @@
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
import { AppController } from './app.controller'; import { AppController } from './app.controller';
import { AppService } from './app.service'; import { AppService } from './app.service';
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
describe('AppController', () => { describe('AppController', () => {
let appController: AppController; let appController: AppController;

View File

@ -1,5 +1,5 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { Controller, Get } from '@nestjs/common';
@Controller() @Controller()
export class AppController { export class AppController {

View File

@ -1,14 +1,16 @@
import { Global, Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import { AppController } from './app.controller'; import { AppController } from './app.controller';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module'; import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { LdapModule } from './ldap/ldap.module'; import { LdapModule } from './ldap/ldap.module';
import { UsersModule } from './users/users.module';
import { Global, Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
@Global() @Global()
@Module({ @Module({
controllers: [AppController],
exports: [JwtModule],
imports: [ imports: [
ConfigModule.forRoot({ ConfigModule.forRoot({
isGlobal: true, isGlobal: true,
@ -23,8 +25,7 @@ import { LdapModule } from './ldap/ldap.module';
UsersModule, UsersModule,
LdapModule, LdapModule,
], ],
controllers: [AppController],
providers: [AppService], providers: [AppService],
exports: [JwtModule],
}) })
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class AppModule {} export class AppModule {}

View File

@ -1,7 +1,7 @@
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
import { AuthController } from './auth.controller'; import { AuthController } from './auth.controller';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
describe('AuthController', () => { describe('AuthController', () => {
let controller: AuthController; let controller: AuthController;

View File

@ -1,10 +1,10 @@
/* eslint-disable class-methods-use-this */ /* eslint-disable class-methods-use-this */
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import { Body, Controller, Get, HttpException, HttpStatus, Post, Req, Res } from '@nestjs/common';
import { FastifyReply, FastifyRequest } from 'fastify';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { COOKIE_TOKEN_NAME } from './lib/constants'; import { COOKIE_TOKEN_NAME } from './lib/constants';
import { Credentials } from './types/request'; import { Credentials } from './types/request';
import { Body, Controller, Get, HttpException, HttpStatus, Post, Req, Res } from '@nestjs/common';
import { FastifyReply, FastifyRequest } from 'fastify';
@Controller() @Controller()
export class AuthController { export class AuthController {

View File

@ -1,12 +1,13 @@
import { Module } from '@nestjs/common';
import { LdapModule } from '../ldap/ldap.module'; import { LdapModule } from '../ldap/ldap.module';
import { UsersModule } from '../users/users.module'; import { UsersModule } from '../users/users.module';
import { AuthController } from './auth.controller'; import { AuthController } from './auth.controller';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { Module } from '@nestjs/common';
@Module({ @Module({
imports: [UsersModule, LdapModule],
controllers: [AuthController], controllers: [AuthController],
imports: [UsersModule, LdapModule],
providers: [AuthService], providers: [AuthService],
}) })
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class AuthModule {} export class AuthModule {}

View File

@ -1,6 +1,6 @@
import { AuthService } from './auth.service';
import type { TestingModule } from '@nestjs/testing'; import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing'; import { Test } from '@nestjs/testing';
import { AuthService } from './auth.service';
describe('AuthService', () => { describe('AuthService', () => {
let service: AuthService; let service: AuthService;

View File

@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { LdapService } from '../ldap/ldap.service'; import { LdapService } from '../ldap/ldap.service';
import { UsersCache } from '../users/users.cache'; import { UsersCache } from '../users/users.cache';
import type { DecodedToken, TokenPayload } from './types/jwt'; import type { DecodedToken, TokenPayload } from './types/jwt';
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable() @Injectable()
export class AuthService { export class AuthService {
@ -19,8 +19,8 @@ export class AuthService {
await this.usersCache.addUser(username, user); await this.usersCache.addUser(username, user);
const payload: TokenPayload = { const payload: TokenPayload = {
username,
domain: process.env.LDAP_DOMAIN, domain: process.env.LDAP_DOMAIN,
username,
}; };
return this.jwtService.sign(payload); return this.jwtService.sign(payload);

View File

@ -1,8 +1,9 @@
import { Module } from '@nestjs/common';
import { LdapService } from './ldap.service'; import { LdapService } from './ldap.service';
import { Module } from '@nestjs/common';
@Module({ @Module({
providers: [LdapService],
exports: [LdapService], exports: [LdapService],
providers: [LdapService],
}) })
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class LdapModule {} export class LdapModule {}

View File

@ -1,6 +1,6 @@
import { LdapService } from './ldap.service';
import type { TestingModule } from '@nestjs/testing'; import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing'; import { Test } from '@nestjs/testing';
import { LdapService } from './ldap.service';
describe('LdapService', () => { describe('LdapService', () => {
let service: LdapService; let service: LdapService;

View File

@ -1,22 +1,22 @@
import type { User } from '../types/user';
import type { LdapUser } from './types/user';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import type { AuthenticationOptions } from 'ldap-authentication'; import type { AuthenticationOptions } from 'ldap-authentication';
import { authenticate } from 'ldap-authentication'; import { authenticate } from 'ldap-authentication';
import type { User } from '../types/user';
import type { LdapUser } from './types/user';
@Injectable() @Injectable()
export class LdapService { export class LdapService {
async authenticate(login: string, password?: string) { async authenticate(login: string, password?: string) {
const options: AuthenticationOptions = { const options: AuthenticationOptions = {
adminDn: process.env.LDAP_BIND_DN,
adminPassword: process.env.LDAP_BIND_CREDENTIALS,
ldapOpts: { ldapOpts: {
url: process.env.LDAP_URL, url: process.env.LDAP_URL,
}, },
adminDn: process.env.LDAP_BIND_DN,
adminPassword: process.env.LDAP_BIND_CREDENTIALS,
userSearchBase: process.env.LDAP_BASE,
usernameAttribute: process.env.LDAP_ATTRIBUTE,
username: login,
userPassword: password, userPassword: password,
userSearchBase: process.env.LDAP_BASE,
username: login,
usernameAttribute: process.env.LDAP_ATTRIBUTE,
verifyUserExists: password === undefined, verifyUserExists: password === undefined,
}; };
@ -29,13 +29,13 @@ export class LdapService {
}: LdapUser = await authenticate(options); }: LdapUser = await authenticate(options);
const user: User = { const user: User = {
username,
domain: process.env.LDAP_DOMAIN,
displayName,
department, department,
position: title, displayName,
mail, domain: process.env.LDAP_DOMAIN,
domainName: `${process.env.LDAP_DOMAIN}\\${username}`, domainName: `${process.env.LDAP_DOMAIN}\\${username}`,
mail,
position: title,
username,
}; };
return user; return user;

View File

@ -1,63 +1,63 @@
export type LdapUser = { export type LdapUser = {
dn: string; accountExpires: string;
controls: any[];
objectClass: string[];
cn: string;
sn: string;
c: string;
title: string;
physicalDeliveryOfficeName: string;
givenName: string;
distinguishedName: string;
instanceType: string;
whenCreated: string;
whenChanged: string;
displayName: string;
uSNCreated: string;
memberOf: string[];
uSNChanged: string;
co: string;
department: string;
proxyAddresses: string[];
name: string;
objectGUID: string;
userAccountControl: string;
badPwdCount: string;
codePage: string;
countryCode: string;
employeeID: string;
badPasswordTime: string; badPasswordTime: string;
badPwdCount: string;
c: string;
cn: string;
co: string;
codePage: string;
controls: unknown[];
countryCode: string;
dSCorePropagationData: string[];
department: string;
displayName: string;
distinguishedName: string;
dn: string;
employeeID: string;
extensionAttribute1: string;
extensionAttribute13: string;
extensionAttribute2: string;
givenName: string;
instanceType: string;
lastLogoff: string; lastLogoff: string;
lastLogon: string; lastLogon: string;
pwdLastSet: string; lastLogonTimestamp: string;
primaryGroupID: string; legacyExchangeDN: string;
objectSid: string; lockoutTime: string;
accountExpires: string;
logonCount: string; logonCount: string;
'mS-DS-ConsistencyGuid': string;
mail: string;
mailNickname: string;
memberOf: string[];
middleName: string;
'msDS-KeyCredentialLink': string;
msExchMailboxGuid: string;
msExchPoliciesIncluded: string[];
msExchRecipientDisplayType: string;
msExchRecipientTypeDetails: string;
msExchRemoteRecipientType: string;
msExchUMDtmfMap: string[];
msExchVersion: string;
name: string;
objectCategory: string;
objectClass: string[];
objectGUID: string;
objectSid: string;
physicalDeliveryOfficeName: string;
preferredLanguage: string;
primaryGroupID: string;
proxyAddresses: string[];
pwdLastSet: string;
sAMAccountName: string; sAMAccountName: string;
sAMAccountType: string; sAMAccountType: string;
showInAddressBook: string[]; showInAddressBook: string[];
legacyExchangeDN: string; sn: string;
userPrincipalName: string;
lockoutTime: string;
objectCategory: string;
dSCorePropagationData: string[];
'mS-DS-ConsistencyGuid': string;
lastLogonTimestamp: string;
'msDS-KeyCredentialLink': string;
mail: string;
middleName: string;
preferredLanguage: string;
extensionAttribute2: string;
msExchVersion: string;
msExchRecipientDisplayType: string;
msExchRecipientTypeDetails: string;
extensionAttribute1: string;
msExchMailboxGuid: string;
targetAddress: string; targetAddress: string;
msExchPoliciesIncluded: string[]; title: string;
extensionAttribute13: string; uSNChanged: string;
mailNickname: string; uSNCreated: string;
msExchRemoteRecipientType: string; userAccountControl: string;
msExchUMDtmfMap: string[]; userPrincipalName: string;
whenChanged: string;
whenCreated: string;
}; };

View File

@ -1,9 +1,9 @@
/* eslint-disable unicorn/prefer-top-level-await */ /* eslint-disable unicorn/prefer-top-level-await */
import fastifyCookie from '@fastify/cookie'; import { AppModule } from './app.module';
import { fastifyCookie } from '@fastify/cookie';
import { NestFactory } from '@nestjs/core'; import { NestFactory } from '@nestjs/core';
import type { NestFastifyApplication } from '@nestjs/platform-fastify'; import type { NestFastifyApplication } from '@nestjs/platform-fastify';
import { FastifyAdapter } from '@nestjs/platform-fastify'; import { FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>( const app = await NestFactory.create<NestFastifyApplication>(

View File

@ -1,9 +1,9 @@
export type User = { export type User = {
displayName: string;
username: string;
department: string; department: string;
position: string; displayName: string;
mail: string;
domain: string; domain: string;
domainName: string; domainName: string;
mail: string;
position: string;
username: string;
}; };

View File

@ -1,14 +1,12 @@
import type { User } from '../types/user';
import { CACHE_MANAGER, Inject, Injectable } from '@nestjs/common'; import { CACHE_MANAGER, Inject, Injectable } from '@nestjs/common';
import { Cache } from 'cache-manager'; import { Cache } from 'cache-manager';
import type { User } from '../types/user';
@Injectable() @Injectable()
export class UsersCache { export class UsersCache {
constructor(@Inject(CACHE_MANAGER) private readonly cacheManager: Cache) {} constructor(@Inject(CACHE_MANAGER) private readonly cacheManager: Cache) {}
async getUser(username: string) { async getUser(username: string) {
const user = (await this.cacheManager.get(username)) as User; return (await this.cacheManager.get(username)) as User;
return user;
} }
async addUser(username: string, user: User) { async addUser(username: string, user: User) {

View File

@ -1,7 +1,7 @@
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
import { UsersController } from './users.controller'; import { UsersController } from './users.controller';
import { UsersService } from './users.service'; import { UsersService } from './users.service';
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
describe('UsersController', () => { describe('UsersController', () => {
let controller: UsersController; let controller: UsersController;

View File

@ -1,9 +1,9 @@
/* eslint-disable class-methods-use-this */ /* eslint-disable class-methods-use-this */
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import { Controller, Get, Req, Res } from '@nestjs/common';
import { FastifyReply, FastifyRequest } from 'fastify';
import { COOKIE_TOKEN_NAME } from '../auth/lib/constants'; import { COOKIE_TOKEN_NAME } from '../auth/lib/constants';
import { UsersService } from './users.service'; import { UsersService } from './users.service';
import { Controller, Get, Req, Res } from '@nestjs/common';
import { FastifyReply, FastifyRequest } from 'fastify';
@Controller() @Controller()
export class UsersController { export class UsersController {

View File

@ -1,23 +1,24 @@
import { CacheModule, Module } from '@nestjs/common';
import * as redisStore from 'cache-manager-ioredis';
import type { RedisOptions } from 'ioredis';
import { LdapModule } from '../ldap/ldap.module'; import { LdapModule } from '../ldap/ldap.module';
import { UsersCache } from './users.cache'; import { UsersCache } from './users.cache';
import { UsersController } from './users.controller'; import { UsersController } from './users.controller';
import { UsersService } from './users.service'; import { UsersService } from './users.service';
import { CacheModule, Module } from '@nestjs/common';
import * as redisStore from 'cache-manager-ioredis';
import type { RedisOptions } from 'ioredis';
@Module({ @Module({
controllers: [UsersController],
exports: [UsersCache],
imports: [ imports: [
CacheModule.register<RedisOptions>({ CacheModule.register<RedisOptions>({
store: redisStore,
host: process.env.REDIS_HOST, host: process.env.REDIS_HOST,
port: Number.parseInt(process.env.REDIS_PORT, 10) || 6379, port: Number.parseInt(process.env.REDIS_PORT, 10) || 6379,
store: redisStore,
ttl: Number.parseInt(process.env.CACHE_TTL, 10), ttl: Number.parseInt(process.env.CACHE_TTL, 10),
}), }),
LdapModule, LdapModule,
], ],
controllers: [UsersController],
providers: [UsersService, UsersCache], providers: [UsersService, UsersCache],
exports: [UsersCache],
}) })
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class UsersModule {} export class UsersModule {}

View File

@ -1,6 +1,6 @@
import { UsersService } from './users.service';
import type { TestingModule } from '@nestjs/testing'; import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing'; import { Test } from '@nestjs/testing';
import { UsersService } from './users.service';
describe('UsersService', () => { describe('UsersService', () => {
let service: UsersService; let service: UsersService;

View File

@ -1,8 +1,8 @@
import type { DecodedToken } from '../auth/types/jwt';
import { LdapService } from '../ldap/ldap.service';
import { UsersCache } from './users.cache';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt'; import { JwtService } from '@nestjs/jwt';
import { LdapService } from '../ldap/ldap.service';
import type { DecodedToken } from '../auth/types/jwt';
import { UsersCache } from './users.cache';
@Injectable() @Injectable()
export class UsersService { export class UsersService {

View File

@ -1,8 +1,8 @@
import { AppModule } from '../src/app.module';
import type { INestApplication } from '@nestjs/common';
import type { TestingModule } from '@nestjs/testing'; import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing'; import { Test } from '@nestjs/testing';
import type { INestApplication } from '@nestjs/common';
import * as request from 'supertest'; import * as request from 'supertest';
import { AppModule } from '../src/app.module';
describe('AppController (e2e)', () => { describe('AppController (e2e)', () => {
let app: INestApplication; let app: INestApplication;
@ -16,8 +16,5 @@ describe('AppController (e2e)', () => {
await app.init(); await app.init();
}); });
it('/ (GET)', () => request(app.getHttpServer()) it('/ (GET)', () => request(app.getHttpServer()).get('/').expect(200).expect('Hello World!'));
.get('/')
.expect(200)
.expect('Hello World!'));
}); });

10
apps/web/.eslintrc.js Normal file
View File

@ -0,0 +1,10 @@
module.exports = {
extends: [
'@vchikalkin/eslint-config-awesome/next-typescript/config',
'@vchikalkin/eslint-config-awesome/next-typescript/rules',
],
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: __dirname,
},
};

View File

@ -1,3 +0,0 @@
{
"extends": "next/core-web-vitals"
}

View File

@ -1,18 +1,18 @@
import Input from 'elements/Input';
import Button from 'elements/Button';
import styles from './Form.module.scss'; import styles from './Form.module.scss';
import { H3 } from 'elements/H';
import { useRouter } from 'next/router';
import Error from 'elements/Error';
import getConfig from 'next/config';
import axios from 'axios'; import axios from 'axios';
import Button from 'elements/Button';
import Error from 'elements/Error';
import { H3 } from 'elements/H';
import Input from 'elements/Input';
import getConfig from 'next/config';
import { useRouter } from 'next/router';
import { useState } from 'react'; import { useState } from 'react';
const { publicRuntimeConfig: config } = getConfig(); const { publicRuntimeConfig: config } = getConfig();
export default function Form() { export default function Form() {
const router = useRouter(); const router = useRouter();
const [hasError, setError] = useState(false); const [hasError, setHasError] = useState(false);
const error = hasError ? <Error>Неверный логин или пароль</Error> : null; const error = hasError ? <Error>Неверный логин или пароль</Error> : null;
return ( return (
@ -31,7 +31,7 @@ export default function Form() {
router.reload(); router.reload();
}) })
.catch(() => { .catch(() => {
setError(true); setHasError(true);
}); });
}} }}
> >

View File

@ -1,6 +1,6 @@
import Form from './Form'; import Form from './Form';
import Logo from 'elements/Logo';
import styles from './Login.module.scss'; import styles from './Login.module.scss';
import Logo from 'elements/Logo';
export default function Login() { export default function Login() {
return ( return (

View File

@ -1,3 +1,4 @@
/* eslint-disable react/button-has-type */
import styles from './Button.module.css'; import styles from './Button.module.css';
type ButtonProps = JSX.IntrinsicElements['button']; type ButtonProps = JSX.IntrinsicElements['button'];

View File

@ -1,5 +1,5 @@
import logo from 'public/assets/images/logo-primary.svg';
import Image from 'next/image'; import Image from 'next/image';
import logo from 'public/assets/images/logo-primary.svg';
export default function Logo() { export default function Logo() {
return <Image src={logo} alt="logo" width={154} />; return <Image src={logo} alt="logo" width={154} />;

View File

@ -6,7 +6,8 @@
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint" "lint": "next lint",
"lint:fix": "next lint -- --fix"
}, },
"dependencies": { "dependencies": {
"@fontsource/montserrat": "^4.5.13", "@fontsource/montserrat": "^4.5.13",
@ -14,13 +15,15 @@
"@types/react": "18.0.25", "@types/react": "18.0.25",
"@types/react-dom": "18.0.9", "@types/react-dom": "18.0.9",
"axios": "^1.2.1", "axios": "^1.2.1",
"eslint": "8.28.0",
"eslint-config-next": "13.0.5",
"next": "13.0.5", "next": "13.0.5",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"sass": "^1.56.1", "sass": "^1.56.1",
"typescript": "4.9.3" "typescript": "4.9.3"
},
"devDependencies": {
"@vchikalkin/eslint-config-awesome": "^1.1.1",
"eslint": "^8.46.0"
} }
} }

View File

@ -1,9 +1,10 @@
import type { AppProps } from 'next/app'; /* eslint-disable react/no-unknown-property */
import 'normalize.css'; import 'normalize.css';
import Head from 'next/head';
import '@fontsource/montserrat/400.css'; import '@fontsource/montserrat/400.css';
import '@fontsource/montserrat/600.css'; import '@fontsource/montserrat/600.css';
import '@fontsource/montserrat/700.css'; import '@fontsource/montserrat/700.css';
import type { AppProps } from 'next/app';
import Head from 'next/head';
export default function App({ Component, pageProps }: AppProps) { export default function App({ Component, pageProps }: AppProps) {
return ( return (

View File

@ -1,6 +1,6 @@
import Head from 'next/head';
import Login from 'components/Login'; import Login from 'components/Login';
import getConfig from 'next/config'; import getConfig from 'next/config';
import Head from 'next/head';
const { publicRuntimeConfig: config } = getConfig(); const { publicRuntimeConfig: config } = getConfig();

View File

@ -3,13 +3,14 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"workspaces": [ "workspaces": [
"apps/*", "apps/*"
"packages/*"
], ],
"scripts": { "scripts": {
"build": "turbo run build", "build": "turbo run build",
"dev": "turbo run dev --parallel", "dev": "turbo run dev --parallel",
"lint": "turbo run lint", "lint": "turbo run lint",
"lint:fix": "turbo run lint:fix",
"clean": "turbo run clean",
"format": "prettier --write \"**/*.{ts,tsx,md}\"" "format": "prettier --write \"**/*.{ts,tsx,md}\""
}, },
"devDependencies": { "devDependencies": {

View File

@ -2,13 +2,23 @@
"$schema": "https://turbo.build/schema.json", "$schema": "https://turbo.build/schema.json",
"pipeline": { "pipeline": {
"build": { "build": {
"dependsOn": ["^build"], "outputs": ["dist/**", ".next/**", "public/dist/**"],
"outputs": ["dist/**", ".next/**"] "dependsOn": ["^build"]
}, },
"lint": { "lint": {
"dependsOn": ["^build"],
"cache": false,
"outputs": []
},
"lint:fix": {
"dependsOn": ["^build"],
"outputs": [] "outputs": []
}, },
"dev": { "dev": {
"cache": false,
"persistent": true
},
"clean": {
"cache": false "cache": false
} }
} }

2512
yarn.lock

File diff suppressed because it is too large Load Diff