Compare commits

...

10 Commits

Author SHA1 Message Date
Andrey f588583f73 qr-code generator 2024-09-02 09:30:56 +03:00
Boris Voropaev be0d57a6b9 navigation 2024-07-18 16:52:31 +03:00
Boris Voropaev f8bb93238e Merge branch 'master' of https://gitea.testnir.ru/NirGroup/nirssr 2024-07-17 10:59:42 +03:00
Boris Voropaev 799e9a131f routing 2024-07-17 10:59:36 +03:00
Andrey 5846e51958 bug fix 2024-07-12 09:02:38 +03:00
Boris Voropaev b61a30daca 404 2024-07-11 11:38:05 +03:00
Andrey 021ddf50c5 googleAnalytics 2024-07-09 17:29:57 +03:00
Andrey d8ff044f22 favicon YandexMetrika googleAnalytics 2024-06-21 16:59:05 +03:00
Boris Voropaev 225387d5ec bugfix 2024-06-21 16:48:35 +03:00
Boris Voropaev e8267eba5c favicon 2024-06-19 16:25:25 +03:00
25 changed files with 743 additions and 84 deletions

90
package-lock.json generated
View File

@ -18,7 +18,10 @@
"@angular/platform-server": "^18.0.0",
"@angular/router": "^18.0.0",
"@angular/ssr": "^18.0.0",
"angular-gtag": "^1.0.4",
"express": "^4.18.2",
"ng-yandex-metrika": "^17.1.2",
"ngx-google-analytics": "^14.0.1",
"rxjs": "~7.8.0",
"swiper": "^11.1.3",
"tslib": "^2.3.0",
@ -4366,6 +4369,24 @@
"ajv": "^8.8.2"
}
},
"node_modules/angular-gtag": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/angular-gtag/-/angular-gtag-1.0.4.tgz",
"integrity": "sha512-46A2B18yhjcdueXAWioLaHskX1jEINQL6esxtQe0VannCYuXqShf+LsnDlMCt45HQp6RdXQPEHaNL4cwBLJLuA==",
"dependencies": {
"tslib": "^1.7.1"
},
"peerDependencies": {
"@angular/common": ">=5.0.0",
"@angular/core": ">=5.0.0",
"@angular/router": ">=5.0.0"
}
},
"node_modules/angular-gtag/node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/ansi-colors": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
@ -5953,9 +5974,9 @@
}
},
"node_modules/engine.io": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz",
"integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==",
"version": "6.5.5",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz",
"integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==",
"dev": true,
"dependencies": {
"@types/cookie": "^0.4.1",
@ -5967,7 +5988,7 @@
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.11.0"
"ws": "~8.17.1"
},
"engines": {
"node": ">=10.2.0"
@ -8854,6 +8875,30 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
"node_modules/ng-yandex-metrika": {
"version": "17.1.2",
"resolved": "https://registry.npmjs.org/ng-yandex-metrika/-/ng-yandex-metrika-17.1.2.tgz",
"integrity": "sha512-2VZCjEpEJvnMqjZfsRRzloaOWEQXqy6npzOBupqcm0o9VFl/SeEa2dmJN6V0HpD7GGdUFl7T9MQguti1rB4N7A==",
"dependencies": {
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/common": "^17.0.0",
"@angular/compiler": "^17.0.0"
}
},
"node_modules/ngx-google-analytics": {
"version": "14.0.1",
"resolved": "https://registry.npmjs.org/ngx-google-analytics/-/ngx-google-analytics-14.0.1.tgz",
"integrity": "sha512-PfOtnshSyq15EKevKlFW9IRgH+dTtPG4Q9HJYksuRNYDzjce0eqK3Bf6hz0tAZdyqbzTCyx5g+NgWBfpqQfb2w==",
"dependencies": {
"tslib": "^2.4.0"
},
"peerDependencies": {
"@angular/common": ">=12.0.0",
"@angular/core": ">=12.0.0"
}
},
"node_modules/nice-napi": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
@ -10854,13 +10899,13 @@
}
},
"node_modules/socket.io-adapter": {
"version": "2.5.4",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz",
"integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==",
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
"integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
"dev": true,
"dependencies": {
"debug": "~4.3.4",
"ws": "~8.11.0"
"ws": "~8.17.1"
}
},
"node_modules/socket.io-parser": {
@ -12557,27 +12602,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/webpack-dev-server/node_modules/ws": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
"integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
"dev": true,
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/webpack-merge": {
"version": "5.10.0",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
@ -12823,16 +12847,16 @@
"dev": true
},
"node_modules/ws": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"dev": true,
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {

View File

@ -21,7 +21,10 @@
"@angular/platform-server": "^18.0.0",
"@angular/router": "^18.0.0",
"@angular/ssr": "^18.0.0",
"angular-gtag": "^1.0.4",
"express": "^4.18.2",
"ng-yandex-metrika": "^17.1.2",
"ngx-google-analytics": "^14.0.1",
"rxjs": "~7.8.0",
"swiper": "^11.1.3",
"tslib": "^2.3.0",

View File

@ -0,0 +1,24 @@
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {environment} from '../../environments/environment';
import {Observable} from "rxjs";
@Injectable({providedIn: 'root'})
export class AssetsService {
constructor(private http: HttpClient) {
}
upload(file: any, params?: any): Observable<any> {
let formData = new FormData();
formData.append('file', file);
for (let param in params) {
if (params.hasOwnProperty(param)) formData.append(param, params[param]);
}
return this.http.post<any>(`${environment.apiUrl}/api/assets`, formData, {reportProgress: true, observe: 'events'});
}
bookmark(id: string, registry: string, params?: any): Observable<any> {
return this.http.patch(`${environment.apiUrl}/api/assets/bookmark/${id}`, {registry: registry}, {params: params});
}
}

View File

@ -6,12 +6,13 @@
<img src="assets/img/nir_logo_top.svg">
</a>
<div class="nav-items" [class.nav-hide]="!navShow">
<a href="/about" routerLinkActive="active" >О нас</a>
<a href="automatization" routerLinkActive="active">Автоматизация</a>
<a href="sites" routerLinkActive="active">Сайты</a>
<a href="development" routerLinkActive="active">Разработка</a>
<a href="projects" routerLinkActive="active" >Проекты</a>
<a href="contacts" routerLinkActive="active" >Контакты</a>
<a href="/about/">О нас</a>
<a href="/automatization/">Автоматизация</a>
<a href="/sites/">Сайты</a>
<a href="/development/">Разработка</a>
<a href="/projects/">Проекты</a>
<a href="/contacts/">Контакты</a>
<a href routerLink="qr-code">Создай свой Qr-code</a>
<a href="tel:+74994900465" class="right tel">
<svg>
<use href="assets/ico/call_24.svg#ico"></use>
@ -66,6 +67,7 @@
<a href routerLink="development">Разработка</a>
<a href routerLink="projects">Проекты</a>
<a href routerLink="contacts">Контакты</a>
<a href routerLink="qr-code">Создай свой Qr-code</a>
</div>
<div class="footer-info">
<h4>Контакты</h4>

View File

@ -1,4 +1,4 @@
import { Component } from '@angular/core';
import {Component, OnInit} from '@angular/core';
import { CommonModule, DatePipe, ViewportScroller } from '@angular/common';
import { RouterOutlet, NavigationEnd, Router, RouterLink, RouterLinkActive } from '@angular/router';
import { RequestComponent } from './request/request.component';
@ -10,7 +10,7 @@ import { RequestComponent } from './request/request.component';
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
export class AppComponent implements OnInit{
title = 'NIR';
dateNow?: Date;

View File

@ -1,8 +1,9 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import {ApplicationConfig, importProvidersFrom, provideZoneChangeDetection} from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withFetch } from '@angular/common/http';
import { routes } from './app.routes';
import { provideClientHydration } from '@angular/platform-browser';
import {MetrikaModule} from "ng-yandex-metrika";
export const appConfig: ApplicationConfig = {
providers: [
@ -10,5 +11,10 @@ export const appConfig: ApplicationConfig = {
provideRouter(routes),
provideClientHydration(),
provideHttpClient(withFetch()),
importProvidersFrom(
MetrikaModule.forRoot([
{ id: 97262465, webvisor: true, accurateTrackBounce:true, clickmap:true, trackLinks:true, }
])
)
]
};

View File

@ -12,6 +12,9 @@ import { Tk023Component } from './projects/tk023/tk023.component';
import { Tk465Component } from './projects/tk465/tk465.component';
import { ScvgComponent } from './projects/scvg/scvg.component';
import { pipe_prodComponent } from './projects/pipe_prod/pipe_prod.component';
import { QrCodeComponent } from './qr-code/qr-code.component';
import { NotFoundComponentComponent } from './not-found-component/not-found-component.component';
export const routes: Routes = [
{path: "", component: HomeComponent},
@ -26,5 +29,7 @@ export const routes: Routes = [
{path:'projects/tk023', component: Tk023Component},
{path:'projects/tk465', component: Tk465Component},
{path:'projects/gazprom', component: ScvgComponent},
{path:'projects/pipe_prod', component: pipe_prodComponent}
{path:'projects/pipe_prod', component: pipe_prodComponent},
{path: 'qr-code', component: QrCodeComponent},
{path: '404', component: NotFoundComponentComponent},
];

View File

@ -0,0 +1,2 @@
<h1>404</h1>
страница не найдена

View File

@ -0,0 +1,8 @@
:host{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
min-height: 500px;
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NotFoundComponentComponent } from './not-found-component.component';
describe('NotFoundComponentComponent', () => {
let component: NotFoundComponentComponent;
let fixture: ComponentFixture<NotFoundComponentComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [NotFoundComponentComponent]
})
.compileComponents();
fixture = TestBed.createComponent(NotFoundComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,21 @@
import { Component, Inject, OnInit, Optional, PLATFORM_ID } from '@angular/core';
import { Request, Response } from 'express';
import { isPlatformServer } from '@angular/common';
@Component({
selector: 'app-not-found-component',
standalone: true,
imports: [],
templateUrl: './not-found-component.component.html',
styleUrl: './not-found-component.component.scss'
})
export class NotFoundComponentComponent {
// constructor(@Optional() @Inject(Request) private request: Request,
// @Optional() @Inject(Response) private response: Response,
// @Inject(PLATFORM_ID) private platformId: any){}
// ngOnInit() {
// if (isPlatformServer(this.platformId)) {
// this.response.status(404);
// }
// }
}

View File

@ -35,7 +35,7 @@
<h4 class="project-name">
ТК 023
</h4>
<a class="btn white" href="../projects/tk023">
<a class="btn white" href="/projects/tk023/">
Подробнее
</a>
</div>
@ -47,7 +47,7 @@
<h4 class="project-name">
ВНИИГАЗ-Сертификат
</h4>
<a class="btn white" href="../projects/vniigaz">
<a class="btn white" href="/projects/vniigaz/">
Подробнее
</a>
</div>
@ -59,7 +59,7 @@
<h4 class="project-name">
Газпром-ВНИИГАЗ
</h4>
<a class="btn white" href="../projects/gazprom">
<a class="btn white" href="/projects/gazprom/">
Подробнее
</a>
</div>
@ -71,7 +71,7 @@
<h4 class="project-name">
ТК 465
</h4>
<a class="btn white" href="../projects/tk465">
<a class="btn white" href="/projects/tk465/">
Подробнее
</a>
</div>
@ -83,7 +83,7 @@
<h4 class="project-name">
ФАУ ФЦС
</h4>
<a class="btn white" href="../projects/faufcs">
<a class="btn white" href="/projects/faufcs/">
Подробнее
</a>
</div>
@ -95,7 +95,7 @@
<h4 class="project-name">
ВНИИГАЗ-Сертификат
</h4>
<a class="btn white" href="projects/pipe_prod">
<a class="btn white" href="projects/pipe_prod/">
Подробнее
</a>
</div>

View File

@ -0,0 +1,200 @@
<div class="block">
<div class="container-fluid">
<div class="row inner">
<div class="col-md-7 col-lg-8 block-options">
<div class="accordion" [formGroup]="QrCodeForm">
<div class="pane" ng-class="{'active':editView==='content'}" style>
<div class="pane-header" ng-click="setEditView('content')">
<div class="icon"></div>
<h3 class="title">Введите текст или загрузите изображение</h3>
<div class="plus">
<i class="fa" aria-hidden="true"></i>
</div>
<div class="minus">
<i class="fa" aria-hidden="true"></i>
</div>
</div>
<div class="pane-content">
<div class="tab-content">
<div class="">
<div class="form-group">
<label for="qrcodeUrl">Ваш текст или картинка</label>
<textarea name="text" rows="3" class="form-control" formControlName="text" #text></textarea>
<small class="form-text text-mutted">Line breaks are allowed</small>
</div>
<div class="area" [class.hover]="dragOver">
<input #fileInput type="file" [id]="field.name" (change)="onFileInput($event)" />
<p>Перетащите сюда или <span (click)="fileInput.click()">выберите файл</span> в формате JPEG или PNG общим объемом не более 10 Мбайт.</p>
<div class="indicator" *ngIf="upload.file">
<div class="label">Загружается файл {{upload.file?.name}}</div>
<div class="progress"><div class="fill" [style.width]="upload.progress + '%'"></div></div>
</div>
</div>
<div class="values" *ngIf="asset">
<div class="item">
<div class="preview"><img [src]="asset.links?.thumb" alt="" /></div>
<button type="button" class="btn icon remove" (click)="clear()"></button>
</div>
</div>
</div>
<div class="values" *ngIf="asset">
<div class="item">
<div class="preview"><img [src]="asset.links?.thumb" alt="" /></div>
<button type="button" class="btn icon remove" (click)="clear()"></button>
</div>
</div>
</div>
</div>
</div>
<div class="pane" ng-class="{'active':editView==='colors'}" style>
<div class="pane-header" ng-click="setEditView('colors')">
<div class="icon"></div>
<h3 class="title">Выберите цвет</h3>
<div class="plus">
<i class="fa" aria-hidden="true"></i>
</div>
<div class="minus">
<i class="fa" aria-hidden="true"></i>
</div>
</div>
<div class="pane-content overflow-visible color-panel">
<label>Основной цвет</label>
<div class="color-group color-group-body">
<div class="form-check form-check-inline">
<label class="form-check-label">
<input class="form-check-input ng-valid ng-not-empty ng dirty ng-valid-parse ng-touched" type="radio" name="color-type" value="solid" formControlName="color-type" checked>
Сплошной
</label>
</div>
<div class="form-check form-check-inline">
<label class="form-check-label">
<input class="form-check-input ng-valid ng-not-empty ng dirty ng-valid-parse ng-touched" type="radio" name="color-type" value="gradient" formControlName="color-type">
Градиент
</label>
</div>
<div class="form-check form-check-inline">
<label class="form-check-label">
<input class="form-check-input ng-valid ng-not-empty ng dirty ng-valid-parse ng-touched" type="checkbox" name="eyeMode" value=true style formControlName="custom-eye-color" [defaultValue]=false>
Цвет глаз
</label>
</div>
<div class="row">
<div class="col-sm-6 col-lg-4 form-group">
<input type="color" formControlName="foreground-color">
</div>
</div>
<div class="row">
<div class="col-sm-6 col-lg-4 form-group">
<input type="color" formControlName="gradient-start">
</div>
<div class="col-sm-6 col-lg-4 form-group">
<input type="color" formControlName="gradient-end">
</div>
<div class="col-sm-6 col-lg-4 form-group">
<div class="input-group">
<span>
<button>Цвета местами</button>
</span>
<select formControlName="gradient-type" id="gradient-type">
<option value="vertical">Вертикальный</option>
<option value="horizontal">Горизонтальный</option>
<option value="diagonal">Диагональ сверху вниз</option>
<option value="inverse_diagonal">Диагональ снизу вверх</option>
<option value="radial">Крулый</option>
</select>
</div>
</div>
</div>
<div>
<label>Цвет глаз</label>
<div class="row">
<div class="col-sm-6 col-lg-4 form-group">
<input type="color" formControlName="inner-eye-color">
</div>
<div class="col-sm-6 col-lg-4 form-group">
<input type="color" formControlName="outside-eye-color">
</div>
<div class="col-sm-6 col-lg-4 form-group">
<span>
<button>Цвета местами</button>
</span>
<span>
<button>Копировать основной цвет</button>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6 col-lg-4">
<label>Цвет фона</label>
<div class="form-group color-group">
<input type="color" formControlName="background-color">
</div>
</div>
</div>
</div>
</div>
<div class="pane">
<div class="pane-header">
<div class="icon"></div>
<h3 class="title">Добавить изображение</h3>
<div class="plus">
<i class="fa" aria-hidden="true"></i>
</div>
<div class="minus">
<i class="fa" aria-hidden="true"></i>
</div>
</div>
<div class="pane-content">
<div class="area" [class.hover]="dragOver">
<input #fileInput type="file" [id]="field.name" (change)="onFileInput($event)" />
<p>Перетащите сюда или <span (click)="fileInput.click()">выберите файл</span> в формате JPEG или PNG общим объемом не более 10 Мбайт.</p>
<div class="indicator" *ngIf="upload.file">
<div class="label">Загружается файл {{upload.file?.name}}</div>
<div class="progress"><div class="fill" [style.width]="upload.progress + '%'"></div></div>
</div>
</div>
<div class="values" *ngIf="asset">
<div class="item">
<div class="preview"><img [src]="asset.links?.thumb" alt="" /></div>
<button type="button" class="btn icon remove" (click)="clear()"></button>
</div>
</div>
</div>
</div>
<div class="pane">
<div class="pane-header">
<div class="icon"></div>
<h3 class="title">Ручной дизайн</h3>
<div class="plus">
<i class="fa" aria-hidden="true"></i>
</div>
<div class="minus">
<i class="fa" aria-hidden="true"></i>
</div>
</div>
<div class="pane-content">
<input type="radio"/>Обычный
<input type="radio"/>Скругленные края
</div>
</div>
</div>
</div>
<div class="col-md-5 col-lg-4 block-download">
<div class="preview">
<p>Созданный QR-CODE</p>
</div>
<button class="btn primary submit" (click)="onSubmit()" [disabled]="QrCodeForm.invalid" >
отправить
</button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,194 @@
*,::after,::before {
box-sizing: border-box
}
textarea {
overflow: auto;
resize: vertical
}
.block {
box-shadow: 0 0 20px rgba(0,0,0,.25);
position: relative;
margin: 0 auto;
border-radius: 32px;
}
.container-fluid {
width: 100%;
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto
}
.row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-right: -15px;
margin-left: -15px
}
.block .block-options {
padding: 32px
}
.block .accordion .pane {
margin-bottom: 4px
}
.block .accordion .pane .pane-header {
cursor: pointer;
-webkit-transition: all .3s;
transition: all .3s;
background: #fff;
font-size: 1.1rem;
position: relative;
font-weight: 500;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
height: 48px;
box-shadow: 0 0 6px rgba(0,0,0,.05)
}
.block .accordion .pane .pane-header .title {
padding: 0 16px;
text-transform: uppercase;
font-size: 1rem;
margin: 0;
-webkit-flex-shrink: 1;
-webkit-flex-grow: 1;
flex-grow: 1;
flex-shrink: 1;
overflow: hidden;
white-space: nowrap;
line-height: 48px;
text-align: initial
}
.block .accordion .pane .pane-header .icon {
width: 48px;
text-align: center;
-webkit-flex-shrink: 0;
-webkit-flex-grow: 0;
flex-grow: 0;
flex-shrink: 0;
background: #f2f8fc;
line-height: 48px
}
.block .accordion .pane .pane-header .minus, .block .accordion .pane .pane-header .plus {
padding: 0 16px;
-webkit-flex-shrink: 0;
-webkit-flex-grow: 0;
flex-grow: 0;
flex-shrink: 0;
line-height: 48px;
color: rgba(111,120,127,.5);
font-size: .9rem
}
.block .accordion .pane .pane-header .minus {
display: none
}
.block .accordion .pane .pane-header:hover {
background-color: #f2f8fc;
box-shadow: none
}
.block.accordion .pane.active .pane-content {
padding: 1rem 0;
display: block;
opacity: 1;
visibility: visible;
max-height: 1400px;
overflow: visible;
-webkit-transition: all .5s ease-in-out 0s,opacity .25s ease-in-out .2s;
transition: all .5s ease-in-out 0s,opacity .25s ease-in-out .2s
}
.form-control {
display: block;
width: 100%;
padding: .375rem .75rem;
font-size: 1rem;
line-height: 1.5;
color: #495057;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: .25rem;
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out
}
.block .accordion .pane.active .pane-content {
padding: 1rem 0;
display: block;
opacity: 1;
visibility: visible;
max-height: 1400px;
overflow: visible;
-webkit-transition: all .5s ease-in-out 0s,opacity .25s ease-in-out .2s;
transition: all .5s ease-in-out 0s,opacity .25s ease-in-out .2s
}
.body .accordion .pane .pane-content .color-group label {
font-weight: 400
}
.block .accordion .pane .pane-content .color-group-body {
padding-bottom: 0
}
.form-check {
position: relative;
display: block;
padding-left: 1.25rem;
}
.form-check-inline {
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding-left: 0;
margin-right: .75rem;
}
.form-check-label {
cursor: pointer;
font-weight: 400;
}
.form-check-input {
vertical-align: middle;
}
.block .block-download {
background: #fff;
padding: 16px;
border-left: 1px solid rgba(0, 0, 0, .1);
border-radius: 0 5px 5px 0;
}
@media (min-width: 768px) {
.block .inner {
display:flex;
align-items: stretch
}
}
.fa {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { QrCodeComponent } from './qr-code.component';
describe('QrCodeComponent', () => {
let component: QrCodeComponent;
let fixture: ComponentFixture<QrCodeComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [QrCodeComponent]
})
.compileComponents();
fixture = TestBed.createComponent(QrCodeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,109 @@
import {Component, Input, OnInit} from '@angular/core';
import {Router} from "@angular/router";
import {FormBuilder, FormGroup, FormsModule, ReactiveFormsModule} from "@angular/forms";
import {NgIf} from "@angular/common";
import {FormsService} from "../_services/forms.service";
import {HttpEventType, HttpResponse} from "@angular/common/http";
import {AssetsService} from "../_services/assets.service";
@Component({
selector: 'qr-code',
standalone: true,
imports: [
FormsModule,
NgIf,
ReactiveFormsModule
],
templateUrl: './qr-code.component.html',
styleUrl: './qr-code.component.scss'
})
export class QrCodeComponent implements OnInit{
@Input() field!: any;
public asset: any;
public QrCodeForm: FormGroup;
public dragOver = false;
public upload: any = {file: null, progress: 0};
constructor(private formBuilder:FormBuilder, private formsService: FormsService, private assetsService: AssetsService){}
ngOnInit() {
this.QrCodeForm = this.formBuilder.group({
'text' : [''],
'format' : ['svg'],
'size' : [350],
'foreground-color' : ['#000000'],
'background-color' : ['#ffffff'],
'gradient-start' : ['#ffffff'],
'gradient-end' : ['#00A0FF'],
'gradient-type' : ['vertical'],
'color-type' : ['solid'],
'custom-eye-color' : [false],
'outside-eye-color' : ['#000000'],
'inner-eye-color' : ['#000000'],
'image' : []
});
}
onSubmit(){
this.QrCodeForm.markAllAsTouched();
if (this.QrCodeForm.valid)
this.formsService.save('model', 'QrCode', null, this.QrCodeForm.value).subscribe(res => {
}, error => {
console.log(error);
});
}
get initialValue() {
return this.field.value?.data[0];
}
get control() {
return this.QrCodeForm.controls[this.field.name];
}
get value() {
return this.control?.value || [];
}
set value(asset: any) {
this.asset = asset;
this.control?.setValue(asset?.id);
}
setValue(value: any) {
this.control.setValue(value);
this.control.markAsTouched();
}
clear() {
this.control.markAsTouched();
this.value = null;
}
onFileInput(event: any) {
this.uploadFiles(event.target.files);
event.target.value = null;
}
uploadFiles(files: any) {
for (let file of files) {
this.uploadFile(file);
}
}
uploadFile(file: File) {
this.upload.file = file;
this.assetsService.upload(file).subscribe((result) => {
if (result.type === HttpEventType.UploadProgress) {
this.upload.progress = Math.round(100 * result.loaded / result.total);
} else if (result instanceof HttpResponse) {
this.upload = {file: null, progress: 0};
this.value = result.body.data;
this.control.markAsTouched();
}
}, error => {
this.upload = {file: null, progress: 0};
alert(error.error.message);
});
}
}

View File

@ -2,7 +2,7 @@
<ng-content></ng-content>
</div>
<div class="block" [style.display]="hidden?'none':'block'">
<div class="block" [class.hidden]="hidden">
<form *ngIf="!success" [formGroup]="feedbackForm">
<div class="card">
<h3>Обратная связь</h3>

View File

@ -5,6 +5,7 @@
}
.block{
display: flex;
width: 100vw;
height: 100vh;
position:fixed;
@ -72,8 +73,13 @@
}
.hidden{
display: none;
}
@media screen and (max-width: 1024px){
.block{
display: block;
overflow-y: scroll;
display: block;
position: fixed;
@ -89,5 +95,9 @@
padding-bottom: 130px;
}
}
.hidden{
display: none;
}
}

View File

@ -3,6 +3,8 @@ import { FormsService } from '../_services/forms.service';
import {FormGroup, ReactiveFormsModule, FormBuilder, Validators} from "@angular/forms";
import {ActivatedRoute, Router} from "@angular/router";
import {NgIf} from "@angular/common";
import {Metrika} from "ng-yandex-metrika";
declare var gtag
@Component({
selector: 'request',
@ -22,7 +24,7 @@ export class RequestComponent implements OnInit {
public utmContent:string;
public utmTerm:string;
constructor(private formBuilder:FormBuilder, private formsService: FormsService, private router: ActivatedRoute) {
constructor(private formBuilder:FormBuilder, private formsService: FormsService, private router: ActivatedRoute, private metrika: Metrika) {
this.router.queryParams.subscribe(params =>{
this.utmSource = params['utm_source'];
this.utmMedium = params['utm_medium'];
@ -55,6 +57,9 @@ export class RequestComponent implements OnInit {
open(){
this.hidden = false;
this.success = false;
this.metrika.reachGoal('form-open').then();
gtag('event', 'form-open', {'event_name':'form-open',
'value': 'form-open' })
this.ngOnInit()
}
@ -68,6 +73,9 @@ export class RequestComponent implements OnInit {
this.feedbackForm.markAllAsTouched();
if (this.feedbackForm.valid)
this.formsService.save('model', 'feedback-form-support', null, this.feedbackForm.value).subscribe(res => {
this.metrika.reachGoal('form-sent').then();
gtag('event', 'form-sent', {'event_name':'form-sent',
'value': 'form-sent' })
this.success = true;
}, error => {
console.log(error);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 B

After

Width:  |  Height:  |  Size: 718 B

View File

@ -1,18 +1,4 @@
<<<<<<< HEAD
<svg width="192" height="192" viewBox="0 0 192 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="192" height="192" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M168 120V168H120V156H156V120H168ZM168 72V24H120V36H156V72H168ZM72 36V24H24V72H36V36H72ZM72 156H36V120H24V168H72V156Z" fill="#585858"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M60 60H84V84H108V60H132V84V108V132H108V108H84V132H60V108V84V60Z" fill="#585858"/>
=======
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="NIRlogo_200x200_favicon">
<rect width="200" height="200" fill="white"/>
<g id="Group">
<path id="Combined Shape" fill-rule="evenodd" clip-rule="evenodd" d="M20 80H30V95H50V80H60V95V105V120H50V105H30V120H20V105V95V80Z" fill="black"/>
<path id="Combined Shape_2" fill-rule="evenodd" clip-rule="evenodd" d="M140 90V100V110V120H150V110H165H165H165.002C167.977 110 170.635 109.325 172.858 108.094C175.08 106.864 176.866 105.078 178.096 102.856C179.327 100.633 180.002 97.9751 180.002 95C180.002 92.0249 179.327 89.3666 178.096 87.1444C176.866 84.9221 175.08 83.1361 172.858 81.9055C170.635 80.675 167.977 80 165.002 80C165.001 80 165.001 80 165 80H150H140V90ZM165 90H150V100H165C165 100 165 100 165 100C166.175 99.9999 167.137 99.7637 167.88 99.3524C168.514 99.0014 169.001 98.5142 169.352 97.8804C169.763 97.1375 170 96.175 170 95C170 93.825 169.763 92.8625 169.352 92.1196C169.001 91.4858 168.514 90.9986 167.88 90.6476C167.137 90.2363 166.175 90.0001 165 90C165 90 165 90 165 90Z" fill="black"/>
<path id="Subtract" fill-rule="evenodd" clip-rule="evenodd" d="M108.75 80L90 105V80H80V120H91.25L110 95V120H120V80H108.75Z" fill="black"/>
<path id="Combined Shape_3" fill-rule="evenodd" clip-rule="evenodd" d="M160 130V160H130V150H150V130H160ZM160 70V40H130V50H150V70H160ZM70 50V40H40V70H50V50H70ZM70 150H50V130H40V160H70V150Z" fill="black"/>
</g>
</g>
>>>>>>> 95638cd89c56dc0df814652a8e7d1cb399d10ef1
<rect width="192" height="192" fill="#1D45F0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M168 108V168H108V144H144V108H168ZM168 84V24H108V48H144V84H168ZM84 48V24H24V84H48V48H84ZM84 144H48V108H24V168H84V144Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 337 B

View File

@ -4,4 +4,5 @@ export const environment = {
clientId: 2,
clientSecret: 'YllFbaRHMP0kCJLb0UdCcOfpTzA23ea3AOdIfRMj',
domenUrl: 'http://localhost:4200',
googleAnalyticsId: 'G-B8183299MH',
};

View File

@ -4,4 +4,5 @@ export const environment = {
clientId: 2,
clientSecret: 'KIWaOS7ML1ZEUmgByFN5Cf9wf0pHFWjYJ5rmOboX',
domenUrl: 'https://nirgroup.ru',
googleAnalyticsId: 'G-B8183299MH',
};

View File

@ -2,10 +2,19 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>Render</title>
<title>НИР Груп создаем ИТ-инструменты под ваши задачи</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="assets/favicon.svg">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-B8183299MH"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'G-B8183299MH');
</script>
</head>
<body>
<app-root></app-root>