Compare commits
No commits in common. "fashion-logica" and "master" have entirely different histories.
fashion-lo
...
master
58
.gitignore
vendored
@ -1,42 +1,42 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# Compiled output
|
||||
angular/dist
|
||||
angular/tmp
|
||||
angular/out-tsc
|
||||
angular/bazel-out
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
/bazel-out
|
||||
|
||||
# Node
|
||||
angular/node_modules
|
||||
angular/npm-debug.log
|
||||
angular/yarn-error.log
|
||||
/node_modules
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# IDEs and editors
|
||||
angular/.idea/
|
||||
angular/.project
|
||||
angular/.classpath
|
||||
angular/.c9/
|
||||
angular/*.launch
|
||||
angular/.settings/
|
||||
angular/*.sublime-workspace
|
||||
.idea/
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# Visual Studio Code
|
||||
angular/.vscode/*
|
||||
angular/!.vscode/settings.json
|
||||
angular/!.vscode/tasks.json
|
||||
angular/!.vscode/launch.json
|
||||
angular/!.vscode/extensions.json
|
||||
angular/.history/*
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# Miscellaneous
|
||||
angular/.angular/cache
|
||||
angular/.sass-cache/
|
||||
angular/connect.lock
|
||||
angular/coverage
|
||||
angular/libpeerconnection.log
|
||||
angular/testem.log
|
||||
angular/typings
|
||||
/.angular/cache
|
||||
.sass-cache/
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System files
|
||||
angular/.DS_Store
|
||||
angular/Thumbs.db
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
4
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
|
||||
"recommendations": ["angular.ng-template"]
|
||||
}
|
||||
20
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "ng serve",
|
||||
"type": "pwa-chrome",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "npm: start",
|
||||
"url": "http://localhost:4200/"
|
||||
},
|
||||
{
|
||||
"name": "ng test",
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "npm: test",
|
||||
"url": "http://localhost:9876/debug.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
42
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "start",
|
||||
"isBackground": true,
|
||||
"problemMatcher": {
|
||||
"owner": "typescript",
|
||||
"pattern": "$tsc",
|
||||
"background": {
|
||||
"activeOnStart": true,
|
||||
"beginsPattern": {
|
||||
"regexp": "(.*?)"
|
||||
},
|
||||
"endsPattern": {
|
||||
"regexp": "bundle generation complete"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "test",
|
||||
"isBackground": true,
|
||||
"problemMatcher": {
|
||||
"owner": "typescript",
|
||||
"pattern": "$tsc",
|
||||
"background": {
|
||||
"activeOnStart": true,
|
||||
"beginsPattern": {
|
||||
"regexp": "(.*?)"
|
||||
},
|
||||
"endsPattern": {
|
||||
"regexp": "bundle generation complete"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
33
Jenkinsfile
vendored
@ -1,33 +0,0 @@
|
||||
env.HL_BUILD_MODE = "jenkins"
|
||||
|
||||
node('Lithium'){
|
||||
|
||||
stage('get new version to repo') {
|
||||
checkout scm
|
||||
if (lastCommitIsBumpCommit()) {
|
||||
currentBuild.result = 'ABORTED'
|
||||
error('Последний коммит - результат сборки jenkins')
|
||||
}
|
||||
sh "git checkout ${env.BRANCH_NAME}"
|
||||
sh "git checkout -- ."
|
||||
|
||||
sh "git pull"
|
||||
//sh "git submodule update --init --recursive"
|
||||
//sh "git submodule update --remote --merge"
|
||||
}
|
||||
stage("build and publish"){
|
||||
dir('angular'){
|
||||
sh label: '', script: 'npm i'
|
||||
sh label: '', script: 'npm run build'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean lastCommitIsBumpCommit() {
|
||||
lastCommit = sh([script: 'git log -1', returnStdout: true])
|
||||
if (lastCommit.contains("Author: jenkins")) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
{
|
||||
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
@ -11,7 +10,6 @@
|
||||
"style": "scss"
|
||||
}
|
||||
},
|
||||
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
@ -19,8 +17,8 @@
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "/var/www/html/lk.crm4retail.ru/fashion-logica",
|
||||
"baseHref": "/",
|
||||
"outputPath": "/var/www/lk/fashion-logica",
|
||||
"baseHref": "/fashion-logica/",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
@ -30,9 +28,7 @@
|
||||
"src/favicon.ico",
|
||||
"src/assets",
|
||||
"src/manifest.webmanifest",
|
||||
"src/firebase-messaging-sw.js",
|
||||
"src/sw-master.js",
|
||||
"src/sw-custom.js"
|
||||
"src/firebase-messaging-sw.js"
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/primeng/resources/themes/bootstrap4-light-blue/theme.css",
|
||||
@ -1,24 +0,0 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { MessageService } from 'primeng/api';
|
||||
|
||||
@Component({
|
||||
selector: 'app-footer-buttons',
|
||||
templateUrl: './footer-buttons.component.html',
|
||||
styleUrls: ['./footer-buttons.component.scss']
|
||||
})
|
||||
export class FooterButtonsComponent implements OnInit {
|
||||
@Input() token!: string;
|
||||
@Input() isPermissionNotifications!: boolean;
|
||||
@Output() requestingPermission = new EventEmitter<null>();
|
||||
public deviceType: 'ios' | 'android' | null = null;
|
||||
|
||||
constructor(
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
requestPermission() {
|
||||
this.requestingPermission.emit(null)
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
import { DownloadAppDirective } from './download-app.directive';
|
||||
|
||||
describe('DownloadAppDirective', () => {
|
||||
it('should create an instance', () => {
|
||||
const directive = new DownloadAppDirective();
|
||||
expect(directive).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@ -1,85 +0,0 @@
|
||||
import {
|
||||
Directive,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
OnInit,
|
||||
Renderer2,
|
||||
} from '@angular/core';
|
||||
import { MessageService } from 'primeng/api';
|
||||
|
||||
@Directive({
|
||||
selector: '[appDownloadApp]',
|
||||
})
|
||||
export class DownloadAppDirective implements OnInit {
|
||||
public deviceType: 'ios' | 'android' | null = null;
|
||||
public deferredPrompt: any;
|
||||
|
||||
constructor(
|
||||
private messageService: MessageService,
|
||||
public renderer: Renderer2,
|
||||
private el: ElementRef
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getTypeDevice();
|
||||
if (this.deviceType === 'ios') {
|
||||
this.el.nativeElement.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:beforeinstallprompt', ['$event'])
|
||||
onBeforeInstallPrompt(e: any) {
|
||||
e.preventDefault();
|
||||
this.deferredPrompt = e;
|
||||
if (this.deferredPrompt) {
|
||||
this.el.nativeElement.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:appinstalled', ['$event'])
|
||||
onAppInstalled(e: any) {
|
||||
// Prevent Chrome 67 and earlier from automatically showing the prompt
|
||||
e.preventDefault();
|
||||
// Stash the event so it can be triggered later.
|
||||
this.deferredPrompt = e;
|
||||
this.el.nativeElement.style.display = 'none';
|
||||
}
|
||||
|
||||
getTypeDevice() {
|
||||
const userAgent = window.navigator.userAgent.toLowerCase();
|
||||
const ios = /iphone|ipod|ipad/.test(userAgent);
|
||||
this.deviceType = ios ? 'ios' : 'android';
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
downloadApp(event: MouseEvent) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (this.deviceType === 'ios') {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary: `Для установки нажмите на кнопку поделиться в Вашем браузере и выберите пункт 'На экран «Домой»'`,
|
||||
life: 5000,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!this.deferredPrompt) {
|
||||
this.messageService.add({
|
||||
severity: 'error',
|
||||
summary: 'Не поддерживается в Вашем браузере!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.deferredPrompt.prompt();
|
||||
this.deferredPrompt.userChoice.then((res: any) => {
|
||||
if (res.outcome === 'accepted') {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary: 'Спасибо за установку!',
|
||||
});
|
||||
}
|
||||
this.deferredPrompt = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,192 +0,0 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import {
|
||||
orderStatuses,
|
||||
PageList,
|
||||
PageListWithBonus,
|
||||
} from 'src/app/app.constants';
|
||||
import {
|
||||
BonusProgramAccount,
|
||||
Page,
|
||||
Purchase,
|
||||
Transaction,
|
||||
} from 'src/app/interface/data';
|
||||
import { JsonrpcService, RpcService } from 'src/app/services/jsonrpc.service';
|
||||
import * as moment from 'moment-timezone';
|
||||
import * as barcode from 'jsbarcode';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { AppleWalletService } from 'src/app/services/apple-wallet.service';
|
||||
import { CookiesService } from 'src/app/services/cookies.service';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { MessageService } from 'primeng/api';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bonus-program',
|
||||
templateUrl: './bonus-program.component.html',
|
||||
styleUrls: ['./bonus-program.component.scss'],
|
||||
})
|
||||
export class BonusProgramComponent implements OnInit {
|
||||
public accountData!: BonusProgramAccount;
|
||||
public purchases: Purchase[] = [];
|
||||
public loadingBonuses: boolean = false;
|
||||
readonly orderStatuses = orderStatuses;
|
||||
readonly moment = moment;
|
||||
readonly pageList = environment.hasBonusProgram
|
||||
? PageListWithBonus
|
||||
: PageList;
|
||||
public currentPage: Page = this.pageList[1];
|
||||
public userName: string = '';
|
||||
public deviceType: 'ios' | 'android' | null = null;
|
||||
public bonuses: number = 0
|
||||
|
||||
constructor(
|
||||
private jsonrpc: JsonrpcService,
|
||||
private appleWallet: AppleWalletService,
|
||||
private cookiesService: CookiesService,
|
||||
@Inject(DOCUMENT) private document: Document,
|
||||
private http: HttpClient,
|
||||
private messageService: MessageService,
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getAccountData();
|
||||
this.getTypeDevice();
|
||||
}
|
||||
|
||||
getTypeDevice() {
|
||||
const userAgent = window.navigator.userAgent.toLowerCase();
|
||||
const ios = /iphone|ipod|ipad/.test(userAgent);
|
||||
this.deviceType = ios ? 'ios' : 'android';
|
||||
}
|
||||
|
||||
async getAccountData(): Promise<void> {
|
||||
this.loadingBonuses = true;
|
||||
|
||||
this.jsonrpc
|
||||
.rpc(
|
||||
{
|
||||
method: 'getAdditionalInfo',
|
||||
params: [],
|
||||
},
|
||||
RpcService.authService,
|
||||
true
|
||||
)
|
||||
.subscribe({
|
||||
next: (res) => {
|
||||
this.userName = res?.data?.first_name;
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error: ', err);
|
||||
},
|
||||
});
|
||||
|
||||
const getAccount = await lastValueFrom(
|
||||
this.jsonrpc.rpc(
|
||||
{
|
||||
method: 'GetAccounts',
|
||||
params: [],
|
||||
},
|
||||
RpcService.bonusService
|
||||
)
|
||||
);
|
||||
|
||||
this.accountData = getAccount && getAccount['Cards'][0];
|
||||
this.bonuses = this.accountData.BonusProgramAccounts?.reduce((previous, {Bonuses}) => {
|
||||
return previous + Bonuses
|
||||
}, 0) || this.accountData.Bonuses
|
||||
this.loadingBonuses = false;
|
||||
if (this.accountData) {
|
||||
barcode('#barcode')
|
||||
.options({ font: 'OCR-B' }) // Will affect all barcodes
|
||||
.EAN13(`${this.accountData.CardNumber}`.padStart(12, '0'), {
|
||||
fontSize: 18,
|
||||
textMargin: 0,
|
||||
})
|
||||
.render();
|
||||
}
|
||||
const getTransactions = (
|
||||
await lastValueFrom(
|
||||
this.jsonrpc.rpc(
|
||||
{
|
||||
method: 'GetAccountTransactions',
|
||||
params: [],
|
||||
},
|
||||
RpcService.bonusService
|
||||
)
|
||||
)
|
||||
)
|
||||
if (!getTransactions) {
|
||||
this.messageService.add({severity:'error', summary:'Произошла ошибка, попробуйте позже'});
|
||||
return
|
||||
}
|
||||
const transactions: Transaction[] = getTransactions && getTransactions['Transactions'];
|
||||
|
||||
const getPurchases = (
|
||||
await lastValueFrom(
|
||||
this.jsonrpc.rpc(
|
||||
{
|
||||
method: 'GetAccountPurchase',
|
||||
params: [],
|
||||
},
|
||||
RpcService.bonusService
|
||||
)
|
||||
)
|
||||
)
|
||||
if (!getPurchases) {
|
||||
this.messageService.add({severity:'error', summary:'Произошла ошибка, попробуйте позже'});
|
||||
return
|
||||
}
|
||||
const purchases: Purchase[] = getPurchases && getPurchases['Purchases'];
|
||||
|
||||
this.purchases = purchases && purchases.map<Purchase>((purchase) => {
|
||||
const id = purchase.ID.slice(0, 36).toLowerCase();
|
||||
purchase.Transactions = transactions.filter((transaction) => {
|
||||
const same = transaction.Purchase === id;
|
||||
transaction.HasPurchase = same;
|
||||
return same;
|
||||
});
|
||||
return purchase;
|
||||
});
|
||||
transactions && transactions.forEach((transaction) => {
|
||||
if (!transaction.HasPurchase) {
|
||||
this.purchases.push({
|
||||
ID: transaction.ID,
|
||||
PurchaseDate: transaction.Date,
|
||||
Transactions: [transaction],
|
||||
IsSingleTransaction: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
this.purchases = this.purchases && this.purchases.sort((a, b) => {
|
||||
return moment(a.PurchaseDate).date() - moment(b.PurchaseDate).date();
|
||||
});
|
||||
}
|
||||
|
||||
async addCardToWallet(e: any) {
|
||||
e.preventDefault();
|
||||
const token = this.cookiesService.getItem('token');
|
||||
const accountData = (
|
||||
await lastValueFrom(
|
||||
this.jsonrpc.rpc(
|
||||
{
|
||||
method: 'getTokenData',
|
||||
params: [],
|
||||
},
|
||||
RpcService.authService,
|
||||
true
|
||||
)
|
||||
)
|
||||
).data;
|
||||
if (token && accountData.user_id) {
|
||||
this.appleWallet.generateCard(token, accountData.user_id).subscribe({
|
||||
next: (res: any) => {
|
||||
this.document.location.href = res.url;
|
||||
},
|
||||
error: (err) => {
|
||||
console.log('Error: ', err);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
.show-more-orders {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
color: #09467f;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.woocommerce-MyAccount-content {
|
||||
max-width: 400px;
|
||||
margin-left: calc(50vw - 200px);
|
||||
}
|
||||
.woocommerce-orders-table {
|
||||
border: 2px solid #dee2e6;
|
||||
border-bottom: 0;
|
||||
border-radius: 0.25rem;
|
||||
border-collapse: separate;
|
||||
text-align: left;
|
||||
margin-top: 8px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
thead {
|
||||
display: none;
|
||||
}
|
||||
.woocommerce-orders-table {
|
||||
&__cell {
|
||||
padding: 0.7rem 1.5rem;
|
||||
border-bottom: 2px solid #dee2e6;
|
||||
text-align: right !important;
|
||||
display: block;
|
||||
&::before {
|
||||
content: attr(data-title) ": ";
|
||||
font-weight: 700;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
&__row {
|
||||
display: block;
|
||||
&:nth-child(even) {
|
||||
background: #ebebeb;
|
||||
}
|
||||
}
|
||||
// &__cell-order-actions::before {
|
||||
// display: none;
|
||||
// }
|
||||
&__cell-order-actions {
|
||||
&.red-color {
|
||||
color: #ed0000;
|
||||
}
|
||||
&.green-color {
|
||||
color: #00a700;
|
||||
}
|
||||
}
|
||||
&__cell-order-number a {
|
||||
text-decoration: none;
|
||||
color: #009688;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-button {
|
||||
display: inline-block;
|
||||
color: #ffffff;
|
||||
background-color: #009688;
|
||||
padding: 13px;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.no-orders {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
<div class="not-found-page">
|
||||
<app-navbar></app-navbar>
|
||||
<div class="not-found-page__container">
|
||||
<h1>404</h1>
|
||||
<p>Упс, что-то пошло не так!</p>
|
||||
<button (click)="routeHome()">Вернуться на главную</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -1,28 +0,0 @@
|
||||
:host {
|
||||
.not-found-page {
|
||||
&__container {
|
||||
text-align: center;
|
||||
margin-top: 32px;
|
||||
h1 {
|
||||
font-size: 108px;
|
||||
font-weight: 600;
|
||||
color: #09467f;
|
||||
}
|
||||
p {
|
||||
margin: 16px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
button {
|
||||
background-color: #09467f;
|
||||
color: #fff;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
margin: 0 auto;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NotFoundComponent } from './not-found.component';
|
||||
|
||||
describe('NotFoundComponent', () => {
|
||||
let component: NotFoundComponent;
|
||||
let fixture: ComponentFixture<NotFoundComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ NotFoundComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(NotFoundComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@ -1,20 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-not-found',
|
||||
templateUrl: './not-found.component.html',
|
||||
styleUrls: ['./not-found.component.scss']
|
||||
})
|
||||
export class NotFoundComponent implements OnInit {
|
||||
|
||||
constructor(private router: Router) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
routeHome() {
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from 'src/environments/environment';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AppleWalletService {
|
||||
private url: string = environment.appleWalletEndpoint;
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
) {}
|
||||
|
||||
generateCard(token: string, user_id: string) {
|
||||
let headers = new HttpHeaders();
|
||||
headers = headers.set('Authorization', environment.appleWalletSecret);
|
||||
const options = {
|
||||
headers: headers,
|
||||
};
|
||||
return this.http.get(`${this.url}/client/${environment.clientName}/passUrl/${user_id}/token/${token}`, options)
|
||||
}
|
||||
|
||||
reloadCard(user_id:string) {
|
||||
let headers = new HttpHeaders();
|
||||
headers = headers.set('Authorization', environment.appleWalletSecret);
|
||||
const options = {
|
||||
headers: headers,
|
||||
};
|
||||
const body = {
|
||||
text: '',
|
||||
isUpdateCard: true
|
||||
}
|
||||
return this.http.post(`${this.url}/sendNotification/${user_id}`, body, options)
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 203 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
@ -1,24 +0,0 @@
|
||||
import packageJson from '../../package.json';
|
||||
|
||||
export const environment = {
|
||||
production: true,
|
||||
appAuthEndpoint: 'https://auth.crm4retail.ru/tnt',
|
||||
appBonusEndpoint: 'https://customerapi2.mi.crm4retail.ru/json.rpc/',
|
||||
appWPEndpoint: 'http://213.239.210.240:4500/wp-json/woofood/v1/',
|
||||
hasBonusProgram: true,
|
||||
systemId: 'g6zyv8tj53w28ov7cl',
|
||||
defaultUrl: 'https://fashionlogica.lk.crm4retail.ru',
|
||||
firebase: {
|
||||
apiKey: "AIzaSyCnKvln5itnrBj62POCPHxshAN_Vmd0zds",
|
||||
authDomain: "fashionlogicanotification.firebaseapp.com",
|
||||
projectId: "fashionlogicanotification",
|
||||
storageBucket: "fashionlogicanotification.appspot.com",
|
||||
messagingSenderId: "99855572145",
|
||||
appId: "1:99855572145:web:7548c189d61b3bcc92d690",
|
||||
measurementId: "G-RQF97ZK7R1"
|
||||
},
|
||||
version: packageJson.version,
|
||||
appleWalletEndpoint: 'https://apple-push-notifications.it-retail.tech/apns/api',
|
||||
appleWalletSecret: 'Token F5mbzEERAznGKVbB6l',
|
||||
clientName: 'fashionlogica'
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
import packageJson from '../../package.json';
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
appAuthEndpoint: 'https://auth.crm4retail.ru/tnt',
|
||||
appBonusEndpoint: 'https://customerapi2.mi.crm4retail.ru/json.rpc/',
|
||||
appWPEndpoint: 'http://192.168.0.179:4200/wp-json/woofood/v1/',
|
||||
hasBonusProgram: true,
|
||||
systemId: 'g6zyv8tj53w28ov7cl',
|
||||
defaultUrl: 'http://192.168.0.179:4200',
|
||||
firebase: {
|
||||
apiKey: 'AIzaSyCnKvln5itnrBj62POCPHxshAN_Vmd0zds',
|
||||
authDomain: 'fashionlogicanotification.firebaseapp.com',
|
||||
projectId: 'fashionlogicanotification',
|
||||
storageBucket: 'fashionlogicanotification.appspot.com',
|
||||
messagingSenderId: '99855572145',
|
||||
appId: '1:99855572145:web:7548c189d61b3bcc92d690',
|
||||
measurementId: 'G-RQF97ZK7R1',
|
||||
},
|
||||
version: packageJson.version,
|
||||
appleWalletEndpoint: 'http://192.168.0.179:4200/apns/api',
|
||||
appleWalletSecret: 'Token F5mbzEERAznGKVbB6l',
|
||||
clientName: 'fashionlogica'
|
||||
};
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
14
angular/src/firebase-messaging-sw.js
vendored
@ -1,14 +0,0 @@
|
||||
importScripts('https://www.gstatic.com/firebasejs/3.6.9/firebase-app.js');
|
||||
importScripts('https://www.gstatic.com/firebasejs/3.6.9/firebase-messaging.js');
|
||||
|
||||
firebase.initializeApp({
|
||||
apiKey: "AIzaSyCnKvln5itnrBj62POCPHxshAN_Vmd0zds",
|
||||
authDomain: "fashionlogicanotification.firebaseapp.com",
|
||||
projectId: "fashionlogicanotification",
|
||||
storageBucket: "fashionlogicanotification.appspot.com",
|
||||
messagingSenderId: "99855572145",
|
||||
appId: "1:99855572145:web:7548c189d61b3bcc92d690",
|
||||
measurementId: "G-RQF97ZK7R1"
|
||||
});
|
||||
|
||||
const messaging = firebase.messaging();
|
||||
8
angular/src/sw-custom.js
vendored
@ -1,8 +0,0 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
self.addEventListener("notificationclick", (event) => {
|
||||
event.notification.close();
|
||||
console.log("notification details: ", event.notification);
|
||||
});
|
||||
})();
|
||||
2
angular/src/sw-master.js
vendored
@ -1,2 +0,0 @@
|
||||
importScripts('./ngsw-worker.js');
|
||||
importScripts('./sw-custom.js');
|
||||
4
angular/package-lock.json → package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "fashion-logica",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "fashion-logica",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@angular/animations": "^14.0.0",
|
||||
"@angular/cdk": "^14.2.1",
|
||||
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "fashion-logica",
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve --host 192.168.0.14",
|
||||
"start": "ng serve --host 192.168.0.179",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test"
|
||||
@ -6,5 +6,5 @@ import { Component } from '@angular/core';
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Fashionlogica';
|
||||
title = 'fashion-logica';
|
||||
}
|
||||
@ -49,7 +49,7 @@ export const PageListWithBonus: Page[] = [
|
||||
description: '',
|
||||
resName: 'ref-system',
|
||||
onSideBar: true,
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
export const orderStatuses: OrderStatus = {
|
||||
@ -32,8 +32,6 @@ import { QRCodeModule } from 'angularx-qrcode';
|
||||
import { ShareButtonsModule } from 'ngx-sharebuttons/buttons';
|
||||
import { ShareIconsModule } from 'ngx-sharebuttons/icons';
|
||||
import { MessagingService } from './services/messaging.service';
|
||||
import { NotFoundComponent } from './pages/not-found/not-found.component';
|
||||
import { DownloadAppDirective } from './directives/download-app.directive';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -49,9 +47,7 @@ import { DownloadAppDirective } from './directives/download-app.directive';
|
||||
OrderInfoComponent,
|
||||
FooterButtonsComponent,
|
||||
UserDataComponent,
|
||||
RefSystemComponent,
|
||||
NotFoundComponent,
|
||||
DownloadAppDirective
|
||||
RefSystemComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@ -60,8 +56,7 @@ import { DownloadAppDirective } from './directives/download-app.directive';
|
||||
{
|
||||
path: '**',
|
||||
component: MainComponent
|
||||
},
|
||||
// { path: '**', component: NotFoundComponent }
|
||||
}
|
||||
]),
|
||||
InputMaskModule,
|
||||
ProgressSpinnerModule,
|
||||
@ -69,7 +64,7 @@ import { DownloadAppDirective } from './directives/download-app.directive';
|
||||
HttpClientModule,
|
||||
BrowserAnimationsModule,
|
||||
BrowserModule,
|
||||
ServiceWorkerModule.register('/sw-master.js', {
|
||||
ServiceWorkerModule.register('ngsw-worker.js', {
|
||||
enabled: environment.production,
|
||||
// Register the ServiceWorker as soon as the application is stable
|
||||
// or after 30 seconds (whichever comes first).
|
||||
@ -1,11 +1,12 @@
|
||||
<div class="footer-buttons-container">
|
||||
<!-- <button
|
||||
<!-- *ngIf="deferredPrompt && token?.length" -->
|
||||
<button
|
||||
*ngIf="((deviceType == 'android' && deferredPrompt) || deviceType == 'ios') && token?.length"
|
||||
class="footer-buttons-container__button download"
|
||||
(click)="downloadPWA()"
|
||||
>
|
||||
<img src="./assets/download.svg" alt="download" />
|
||||
</button> -->
|
||||
</button>
|
||||
<button
|
||||
*ngIf="!isPermissionNotifications && token?.length"
|
||||
class="footer-buttons-container__button"
|
||||
@ -0,0 +1,46 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { MessageService } from 'primeng/api';
|
||||
|
||||
@Component({
|
||||
selector: 'app-footer-buttons',
|
||||
templateUrl: './footer-buttons.component.html',
|
||||
styleUrls: ['./footer-buttons.component.scss']
|
||||
})
|
||||
export class FooterButtonsComponent implements OnInit {
|
||||
@Input() deferredPrompt: any;
|
||||
@Input() token!: string;
|
||||
@Input() isPermissionNotifications!: boolean;
|
||||
@Output() downloadingPWA = new EventEmitter<null>();
|
||||
@Output() requestingPermission = new EventEmitter<null>();
|
||||
public deviceType: 'ios' | 'android' | null = null;
|
||||
|
||||
constructor(
|
||||
private messageService: MessageService,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getTypeDevice()
|
||||
}
|
||||
|
||||
getTypeDevice() {
|
||||
const userAgent = window.navigator.userAgent.toLowerCase()
|
||||
const ios = /iphone|ipod|ipad/.test( userAgent );
|
||||
this.deviceType = ios ? 'ios' : 'android'
|
||||
}
|
||||
|
||||
downloadPWA() {
|
||||
if (this.deviceType === 'ios') {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary: `Для установки нажмите на кнопку поделиться в Вашем браузере и выберите пункт 'На экран «Домой»'`,
|
||||
sticky: true
|
||||
});
|
||||
return
|
||||
}
|
||||
this.downloadingPWA.emit(null)
|
||||
}
|
||||
|
||||
requestPermission() {
|
||||
this.requestingPermission.emit(null)
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,4 @@
|
||||
<div
|
||||
[ngClass]="{
|
||||
woocommerce: true,
|
||||
'auth-page': currentPage.code === PageCode.Auth
|
||||
}"
|
||||
>
|
||||
<div class="woocommerce">
|
||||
<div
|
||||
*ngIf="currentPage.code !== PageCode.Auth"
|
||||
class="top-left-attribute"
|
||||
@ -45,7 +40,6 @@
|
||||
>
|
||||
<div class="container">
|
||||
<img
|
||||
style="width: 36px"
|
||||
src="{{ './assets/menu-icons/' + page.resName + '.png' }}"
|
||||
alt="Иконка меню"
|
||||
/>
|
||||
@ -56,22 +50,6 @@
|
||||
</div>
|
||||
</li>
|
||||
</ng-container>
|
||||
<li
|
||||
class="woocommerce-MyAccount-navigation-link download-app"
|
||||
appDownloadApp
|
||||
>
|
||||
<div class="container">
|
||||
<img
|
||||
style="width: 36px"
|
||||
src="./assets/menu-icons/download-app.png"
|
||||
alt="Иконка меню"
|
||||
/>
|
||||
<div class="menu-item-info">
|
||||
<a href="#">Установить приложение</a>
|
||||
<!-- <p>{{ page.description }}</p> -->
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="woocommerce-MyAccount-navigation-link"
|
||||
(click)="logout($event)"
|
||||
@ -88,7 +66,8 @@
|
||||
<span
|
||||
class="version"
|
||||
[ngClass]="{
|
||||
version: true
|
||||
version: true,
|
||||
bottom: currentPage.code === PageCode.Auth
|
||||
}"
|
||||
>
|
||||
v{{ version }}
|
||||
@ -2,19 +2,11 @@
|
||||
.woocommerce {
|
||||
min-height: calc(100vh - 39px);
|
||||
padding: 20px 18px;
|
||||
|
||||
&.auth-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
nav {
|
||||
margin-bottom: 24px;
|
||||
margin-top: 26px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
ul {
|
||||
max-width: 400px;
|
||||
width: 100%;
|
||||
@ -22,7 +14,6 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
|
||||
li {
|
||||
padding: 12px;
|
||||
width: 100%;
|
||||
@ -34,29 +25,20 @@
|
||||
box-shadow: 0px 0px 5px rgb(0 0 0 / 15%);
|
||||
color: #000;
|
||||
border-radius: 15px;
|
||||
|
||||
&.is-active {
|
||||
border: solid #09467f 1px;
|
||||
// display: none;
|
||||
}
|
||||
|
||||
&.first {
|
||||
// border-radius: 7px 0 0 7px;
|
||||
}
|
||||
|
||||
&.download-app {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
.menu-item-info {
|
||||
margin-left: 16px;
|
||||
|
||||
&>a {
|
||||
& > a {
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
@ -66,8 +48,7 @@
|
||||
display: block;
|
||||
text-align-last: left;
|
||||
}
|
||||
|
||||
&>p {
|
||||
& > p {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
@ -77,13 +58,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li:nth-child(odd) {
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.top-left-attribute {
|
||||
width: 10px;
|
||||
height: 5px;
|
||||
@ -92,9 +71,12 @@
|
||||
position: absolute;
|
||||
top: 69px;
|
||||
}
|
||||
|
||||
.version {
|
||||
opacity: 0.5;
|
||||
&.bottom {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,6 @@ import { ExitComponent } from '../../components/exit/exit.component';
|
||||
import { DialogService, DynamicDialogRef } from 'primeng/dynamicdialog';
|
||||
import { JsonrpcService, RpcService } from 'src/app/services/jsonrpc.service';
|
||||
import { MessageService } from 'primeng/api';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-account',
|
||||
@ -71,24 +70,10 @@ export class AccountComponent implements OnInit {
|
||||
this.currentPage = this.pageList[1];
|
||||
}
|
||||
|
||||
async refSystem() {
|
||||
const additionalInfo = (await lastValueFrom(
|
||||
this.jsonRpcService.rpc({
|
||||
method: 'getAdditionalInfo',
|
||||
params: []
|
||||
}, RpcService.authService, true)
|
||||
)).data
|
||||
refSystem() {
|
||||
this.route.queryParams.subscribe((params) => {
|
||||
if (params['refUserId']) {
|
||||
if (additionalInfo.refSystem?.code.length) {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary:
|
||||
'Вы уже зарегестрированы в реферальной программе!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.refSystemId = params['refUserId'];
|
||||
if (params['refCardNumber']) {
|
||||
this.refSystemId = params['refCardNumber'];
|
||||
this.jsonRpcService
|
||||
.rpc(
|
||||
{
|
||||
@ -108,7 +93,7 @@ export class AccountComponent implements OnInit {
|
||||
next: () => {
|
||||
this.router.navigate([], {
|
||||
queryParams: {
|
||||
refUserId: null,
|
||||
refCardNumber: null,
|
||||
},
|
||||
queryParamsHandling: 'merge',
|
||||
});
|
||||
@ -132,10 +117,6 @@ export class AccountComponent implements OnInit {
|
||||
|
||||
changePage(event: MouseEvent, page: Page): void {
|
||||
event.preventDefault();
|
||||
if (page.resName === 'download-app') {
|
||||
|
||||
return
|
||||
}
|
||||
this.currentPage = page;
|
||||
// let params = new HttpParams();
|
||||
// params = params.append('activePage', this.currentPage.code);
|
||||
@ -40,7 +40,7 @@
|
||||
></p-progressSpinner>
|
||||
</button>
|
||||
</p>
|
||||
<div class="decoration-pattern"></div>
|
||||
<div class="decoration-pattern" style="background: url('./assets/card-decorative-pattern.png') no-repeat;"></div>
|
||||
</form>
|
||||
</ng-container>
|
||||
<ng-template #confirmPhoneField>
|
||||
@ -54,7 +54,8 @@
|
||||
class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide"
|
||||
>
|
||||
<label for="code">
|
||||
Введите 4 цифры из смс, которое пришло на Ваш номер телефона
|
||||
Введите 4 последних цифры позвонившего вам номера телефона. На звонок
|
||||
отвечать не нужно.
|
||||
</label>
|
||||
<input
|
||||
pInputText
|
||||
@ -93,6 +94,6 @@
|
||||
<p style="color: red; margin: 0" *ngIf="errorConfirmCode">
|
||||
Пароль введен неверно
|
||||
</p>
|
||||
<div class="decoration-pattern"></div>
|
||||
<div class="decoration-pattern" style="background: url('./assets/card-decorative-pattern.png') no-repeat;"></div>
|
||||
</form>
|
||||
</ng-template>
|
||||
@ -102,8 +102,5 @@
|
||||
.decoration-pattern {
|
||||
width: calc(100% - 24px);
|
||||
height: 34px;
|
||||
background-image: url('../../../../assets/card-decorative-pattern.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
@ -11,19 +11,22 @@
|
||||
<!-- <div class="imgs-row"></div>
|
||||
<div class="imgs-row" style="background-position-x: -22px;"></div>
|
||||
<div class="imgs-row"></div> -->
|
||||
<img src="./assets/card-decorative-pattern.png" alt="" />
|
||||
<img src="./assets/card-decorative-pattern.svg" alt="" />
|
||||
</div>
|
||||
<div class="card-container__content">
|
||||
<div class="info">
|
||||
<div *ngIf="accountData" class="row">
|
||||
<span class="key">Имя</span>
|
||||
<span class="value">{{
|
||||
userName && userName.length ? userName : 'Не задано'
|
||||
<span class="value" *ngIf="userName.length">{{
|
||||
userName
|
||||
}}</span>
|
||||
<span class="value" *ngIf="!userName.length"
|
||||
>Не задано</span
|
||||
>
|
||||
</div>
|
||||
<div *ngIf="accountData" class="row">
|
||||
<span class="key">Баланс карты</span>
|
||||
<span class="value">{{ bonuses }}</span>
|
||||
<span class="value">{{ accountData.Bonuses }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-container__barcode-container">
|
||||
@ -44,5 +47,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button *ngIf="deviceType == 'ios'" class="add-to-wallet" (click)="addCardToWallet($event)">Добавить в Apple Wallet</button>
|
||||
</div>
|
||||
@ -3,14 +3,14 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
& > h2 {
|
||||
&>h2 {
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
& > p {
|
||||
&>p {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
@ -154,12 +154,12 @@
|
||||
}
|
||||
|
||||
&.active_back {
|
||||
> .card-content__front {
|
||||
>.card-content__front {
|
||||
transform: rotateY(180deg);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
> .card-content__back {
|
||||
>.card-content__back {
|
||||
opacity: 1;
|
||||
transform: rotateY(0deg);
|
||||
}
|
||||
@ -196,16 +196,5 @@
|
||||
font-size: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.add-to-wallet {
|
||||
height: 36px;
|
||||
border-radius: 8px;
|
||||
background: #09467f;
|
||||
border-color: #09467f;
|
||||
color: #fff;
|
||||
max-width: 400px;
|
||||
width: 100%;
|
||||
margin: 12px auto 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
104
src/app/pages/account/bonus-program/bonus-program.component.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { orderStatuses, PageList, PageListWithBonus } from 'src/app/app.constants';
|
||||
import { BonusProgramAccount, Page, Purchase, Transaction } from 'src/app/interface/data';
|
||||
import { JsonrpcService, RpcService } from 'src/app/services/jsonrpc.service';
|
||||
import * as moment from 'moment-timezone';
|
||||
import * as barcode from 'jsbarcode';
|
||||
import { environment } from 'src/environments/environment';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bonus-program',
|
||||
templateUrl: './bonus-program.component.html',
|
||||
styleUrls: ['./bonus-program.component.scss']
|
||||
})
|
||||
export class BonusProgramComponent implements OnInit {
|
||||
|
||||
public accountData!: BonusProgramAccount;
|
||||
public purchases: Purchase[] = [];
|
||||
public loadingBonuses: boolean = false;
|
||||
readonly orderStatuses = orderStatuses;
|
||||
readonly moment = moment;
|
||||
readonly pageList = environment.hasBonusProgram ? PageListWithBonus : PageList;
|
||||
public currentPage: Page = this.pageList[1];
|
||||
public userName: string = '';
|
||||
|
||||
constructor(
|
||||
private jsonrpc: JsonrpcService,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getAccountData();
|
||||
}
|
||||
|
||||
async getAccountData(): Promise<void>{
|
||||
this.loadingBonuses = true;
|
||||
|
||||
this.jsonrpc.rpc({
|
||||
method: 'getAdditionalInfo',
|
||||
params: []
|
||||
}, RpcService.authService, true).subscribe({
|
||||
next: (res) => {
|
||||
this.userName = res.data.first_name
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error: ', err)
|
||||
}
|
||||
});
|
||||
|
||||
this.accountData = (await lastValueFrom(
|
||||
this.jsonrpc.rpc({
|
||||
method: 'GetAccounts',
|
||||
params: []
|
||||
},
|
||||
RpcService.bonusService
|
||||
)))['Cards'][0];
|
||||
this.loadingBonuses = false;
|
||||
|
||||
barcode("#barcode")
|
||||
.options({font: "OCR-B"}) // Will affect all barcodes
|
||||
.EAN13(`${this.accountData.CardNumber}`.padStart(12, "0"), {fontSize: 18, textMargin: 0})
|
||||
.render();
|
||||
const transactions: Transaction[] = (await lastValueFrom(
|
||||
this.jsonrpc.rpc(
|
||||
{
|
||||
method: 'GetAccountTransactions',
|
||||
params: []
|
||||
},
|
||||
RpcService.bonusService
|
||||
)))['Transactions'];
|
||||
|
||||
const purchases: Purchase[] = (await lastValueFrom(
|
||||
this.jsonrpc.rpc(
|
||||
{
|
||||
method: 'GetAccountPurchase',
|
||||
params: []
|
||||
},
|
||||
RpcService.bonusService
|
||||
)))['Purchases'];
|
||||
|
||||
this.purchases = purchases.map<Purchase>((purchase) => {
|
||||
const id = purchase.ID.slice(0,36).toLowerCase();
|
||||
purchase.Transactions = transactions.filter((transaction) => {
|
||||
const same = transaction.Purchase === id;
|
||||
transaction.HasPurchase = same;
|
||||
return same;
|
||||
});
|
||||
return purchase;
|
||||
});
|
||||
transactions.forEach((transaction) => {
|
||||
if(!transaction.HasPurchase){
|
||||
this.purchases.push({
|
||||
ID: transaction.ID,
|
||||
PurchaseDate: transaction.Date,
|
||||
Transactions: [transaction],
|
||||
IsSingleTransaction: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
this.purchases = this.purchases.sort((a,b) => {
|
||||
return moment(a.PurchaseDate).date() - moment(b.PurchaseDate).date();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -67,7 +67,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<p
|
||||
*ngIf="purchases?.length !== purchasesShortArray?.length"
|
||||
*ngIf="purchases.length !== purchasesShortArray.length"
|
||||
class="show-more-orders"
|
||||
(click)="getMoreOrders()"
|
||||
>
|
||||
@ -75,13 +75,12 @@
|
||||
</p>
|
||||
<p-progressSpinner
|
||||
*ngIf="ordersLoadingStatus"
|
||||
[style]="{ display: 'block' }"
|
||||
[style]="{ width: '100%' }"
|
||||
strokeWidth="2"
|
||||
styleClass="angular-spinner"
|
||||
></p-progressSpinner>
|
||||
<p
|
||||
*ngIf="purchases?.length === 0 && !ordersLoadingStatus"
|
||||
class="no-orders"
|
||||
*ngIf="purchases.length === 0 && !ordersLoadingStatus"
|
||||
style="width: 100%; text-align: center"
|
||||
>
|
||||
Нет заказов
|
||||
70
src/app/pages/account/orders/orders.component.scss
Normal file
@ -0,0 +1,70 @@
|
||||
.show-more-orders {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
color: #09467f;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.woocommerce-MyAccount-content {
|
||||
max-width: 400px;
|
||||
margin-left: calc(50vw - 200px);
|
||||
}
|
||||
.woocommerce-orders-table {
|
||||
border: 2px solid #dee2e6;
|
||||
border-bottom: 0;
|
||||
border-radius: 0.25rem;
|
||||
border-collapse: separate;
|
||||
text-align: left;
|
||||
margin-top: 8px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
thead {
|
||||
display: none;
|
||||
}
|
||||
.woocommerce-orders-table {
|
||||
&__cell {
|
||||
padding: 0.7rem 1.5rem;
|
||||
border-bottom: 2px solid #dee2e6;
|
||||
text-align: right!important;
|
||||
display: block;
|
||||
&::before {
|
||||
content: attr(data-title) ": ";
|
||||
font-weight: 700;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
&__row {
|
||||
display: block;
|
||||
&:nth-child(even) {
|
||||
background: #ebebeb;
|
||||
}
|
||||
}
|
||||
// &__cell-order-actions::before {
|
||||
// display: none;
|
||||
// }
|
||||
&__cell-order-actions {
|
||||
&.red-color {
|
||||
color: #ed0000;
|
||||
}
|
||||
&.green-color {
|
||||
color: #00a700
|
||||
}
|
||||
}
|
||||
&__cell-order-number a {
|
||||
text-decoration: none;
|
||||
color: #009688;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-button {
|
||||
display: inline-block;
|
||||
color: #ffffff;
|
||||
background-color: #009688;
|
||||
padding: 13px;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
@ -5,12 +5,11 @@ import { Purchase } from 'src/app/interface/data';
|
||||
import * as moment from 'moment-timezone';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { JsonrpcService, RpcService } from 'src/app/services/jsonrpc.service';
|
||||
import { MessageService } from 'primeng/api';
|
||||
|
||||
@Component({
|
||||
selector: 'app-orders',
|
||||
templateUrl: './orders.component.html',
|
||||
styleUrls: ['./orders.component.scss'],
|
||||
styleUrls: ['./orders.component.scss']
|
||||
})
|
||||
export class OrdersComponent implements OnInit {
|
||||
@Input() handleHttpError!: (error: HttpErrorResponse) => void;
|
||||
@ -24,31 +23,24 @@ export class OrdersComponent implements OnInit {
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private jsonrpc: JsonrpcService,
|
||||
private messageService: MessageService,
|
||||
) {}
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getOrders();
|
||||
this.getOrders()
|
||||
}
|
||||
|
||||
async getOrders() {
|
||||
const getPurchases = await lastValueFrom(
|
||||
async getOrders(){
|
||||
const purchases: Purchase[] = (await lastValueFrom(
|
||||
this.jsonrpc.rpc(
|
||||
{
|
||||
method: 'GetAccountPurchase',
|
||||
params: [],
|
||||
params: []
|
||||
},
|
||||
RpcService.bonusService
|
||||
)
|
||||
);
|
||||
if (!getPurchases) {
|
||||
this.messageService.add({severity:'error', summary:'Произошла ошибка, попробуйте позже'});
|
||||
return
|
||||
}
|
||||
const purchases: Purchase[] = getPurchases && getPurchases['Purchases'];
|
||||
)))['Purchases'];
|
||||
|
||||
this.purchases = purchases && purchases.map<Purchase>((purchase) => {
|
||||
const id = purchase.ID.slice(0, 36).toLowerCase();
|
||||
this.purchases = purchases.map<Purchase>((purchase) => {
|
||||
const id = purchase.ID.slice(0,36).toLowerCase();
|
||||
// purchase.Transactions = transactions.filter((transaction) => {
|
||||
// const same = transaction.Purchase === id;
|
||||
// transaction.HasPurchase = same;
|
||||
@ -56,7 +48,7 @@ export class OrdersComponent implements OnInit {
|
||||
// });
|
||||
return purchase;
|
||||
});
|
||||
this.purchasesShortArray = this.purchases && this.purchases.slice(0, this.lastViewOrder);
|
||||
this.purchasesShortArray = this.purchases.slice(0, this.lastViewOrder)
|
||||
this.ordersLoadingStatus = false;
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
img {
|
||||
height: 26px;
|
||||
}
|
||||
@ -26,7 +25,6 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@ import { environment } from 'src/environments/environment';
|
||||
styleUrls: ['./ref-system.component.scss']
|
||||
})
|
||||
export class RefSystemComponent implements OnInit {
|
||||
public refUrl: string = `${environment.defaultUrl}/?refUserId=`
|
||||
public refUrl: string = `${environment.defaultUrl}/?refCardNumber=`
|
||||
public loading: boolean = true;
|
||||
|
||||
constructor(
|
||||
@ -21,18 +21,13 @@ export class RefSystemComponent implements OnInit {
|
||||
|
||||
async ngOnInit() {
|
||||
const accountData = (await lastValueFrom(
|
||||
this.jsonrpc
|
||||
.rpc(
|
||||
{
|
||||
method: 'getTokenData',
|
||||
params: [],
|
||||
},
|
||||
RpcService.authService,
|
||||
true
|
||||
)
|
||||
)).data
|
||||
|
||||
this.refUrl += accountData.user_id
|
||||
this.jsonrpc.rpc({
|
||||
method: 'GetAccounts',
|
||||
params: []
|
||||
},
|
||||
RpcService.bonusService
|
||||
)))['Cards'][0]
|
||||
this.refUrl += accountData.CardNumber
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
@ -40,30 +35,30 @@ export class RefSystemComponent implements OnInit {
|
||||
if (navigator.share) {
|
||||
navigator.share({
|
||||
title: document.title,
|
||||
text: "Fashionlogica",
|
||||
text: "Fashion Logica",
|
||||
url: this.refUrl
|
||||
})
|
||||
.then(() => console.log('Successful share'))
|
||||
.catch((error) => {
|
||||
console.log('Error sharing:', error)
|
||||
});
|
||||
.then(() => console.log('Successful share'))
|
||||
.catch((error) => {
|
||||
console.log('Error sharing:', error)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
copyUrl() {
|
||||
navigator.clipboard.writeText(this.refUrl)
|
||||
.then(() => {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary: 'Ссылка скопирована!',
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
this.messageService.add({
|
||||
severity: 'error',
|
||||
summary: 'Произошла ошибка!',
|
||||
});
|
||||
.then(() => {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary: 'Ссылка скопирована!',
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
this.messageService.add({
|
||||
severity: 'error',
|
||||
summary: 'Произошла ошибка!',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -75,12 +75,12 @@
|
||||
<div class="decoration-pattern">
|
||||
<img
|
||||
style="height: 34px"
|
||||
src="./assets/card-decorative-pattern.png"
|
||||
src="./assets/card-decorative-pattern.svg"
|
||||
alt=""
|
||||
/>
|
||||
<img
|
||||
style="height: 16px; margin-left: 2px"
|
||||
src="./assets/card-decorative-pattern.png"
|
||||
src="./assets/card-decorative-pattern.svg"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
@ -1,9 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { MessageService } from 'primeng/api';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { UserDataForm } from 'src/app/interface/data';
|
||||
import { AppleWalletService } from 'src/app/services/apple-wallet.service';
|
||||
import { JsonrpcService, RpcService } from 'src/app/services/jsonrpc.service';
|
||||
|
||||
@Component({
|
||||
@ -23,8 +21,6 @@ export class UserDataComponent implements OnInit {
|
||||
constructor(
|
||||
private jsonRpcService: JsonrpcService,
|
||||
private messageService: MessageService,
|
||||
private appleWallet: AppleWalletService,
|
||||
private jsonrpc: JsonrpcService,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
@ -34,14 +30,6 @@ export class UserDataComponent implements OnInit {
|
||||
params: []
|
||||
}, RpcService.authService, true).subscribe({
|
||||
next: (res) => {
|
||||
if (res.code === 45) {
|
||||
this.messageService.add({severity:'warn', summary:'Данные не найдены, заполните их на этой странице'});
|
||||
return
|
||||
}
|
||||
if (!res.data) {
|
||||
this.messageService.add({severity:'error', summary:'Произошла ошибка, попробуйте позже'});
|
||||
return
|
||||
}
|
||||
const { first_name, birthdate, gender } = res.data
|
||||
this.userData = { first_name, birthdate, gender }
|
||||
this.createUserDataForm({...this.userData})
|
||||
@ -71,29 +59,8 @@ export class UserDataComponent implements OnInit {
|
||||
method: 'updateAdditionalInfo',
|
||||
params: [this.userData]
|
||||
}, RpcService.authService, true).subscribe({
|
||||
next: async () => {
|
||||
next: () => {
|
||||
this.messageService.add({severity:'custom', summary:'Данные успешно обновлены!'});
|
||||
const accountData = (await lastValueFrom(
|
||||
this.jsonrpc
|
||||
.rpc(
|
||||
{
|
||||
method: 'getTokenData',
|
||||
params: [],
|
||||
},
|
||||
RpcService.authService,
|
||||
true
|
||||
)
|
||||
)).data
|
||||
if (accountData.user_id) {
|
||||
this.appleWallet.reloadCard(accountData.user_id).subscribe({
|
||||
next: (value) => {
|
||||
console.log(value);
|
||||
},
|
||||
error: (err) => {
|
||||
console.error(err);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error: ', err)
|
||||
@ -1,7 +1,7 @@
|
||||
<div class="main-container">
|
||||
<app-navbar></app-navbar>
|
||||
<p-toast position="top-center"></p-toast>
|
||||
<app-footer-buttons [token]="token"
|
||||
[isPermissionNotifications]="isPermissionNotifications"
|
||||
<app-footer-buttons [token]="token" [deferredPrompt]="deferredPrompt"
|
||||
[isPermissionNotifications]="isPermissionNotifications" (downloadingPWA)="downloadPWA()"
|
||||
(requestingPermission)="requestPermission()"></app-footer-buttons>
|
||||
</div>
|
||||
@ -24,6 +24,7 @@ export class MainComponent implements OnInit {
|
||||
private cardComponent!: ComponentRef<CardComponent>;
|
||||
private accountComponent!: ComponentRef<AccountComponent>;
|
||||
public messagingToken!: string | null;
|
||||
public deferredPrompt: any;
|
||||
public isPermissionNotifications: boolean = false;
|
||||
public token = '';
|
||||
public message: any;
|
||||
@ -31,12 +32,20 @@ export class MainComponent implements OnInit {
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private viewContainerRef: ViewContainerRef,
|
||||
private afMessaging: AngularFireMessaging,
|
||||
public el: ElementRef,
|
||||
public renderer: Renderer2,
|
||||
private messagingService: MessagingService,
|
||||
private messageService: MessageService,
|
||||
private messagingService: MessagingService,
|
||||
private cookiesService: CookiesService,
|
||||
) {
|
||||
renderer.listen('window', 'appinstalled', (evt) => {
|
||||
console.log('INSTALLED!!!');
|
||||
});
|
||||
renderer.listen('window', 'beforeinstallprompt', (e) => {
|
||||
e.preventDefault();
|
||||
this.deferredPrompt = e;
|
||||
});
|
||||
route.queryParams.subscribe((params) => {
|
||||
if (params['token']) {
|
||||
this.token = params['token']
|
||||
@ -52,20 +61,35 @@ export class MainComponent implements OnInit {
|
||||
// this.checkRequestPermission()
|
||||
}
|
||||
|
||||
downloadPWA() {
|
||||
if (!this.deferredPrompt) {
|
||||
this.messageService.add({
|
||||
severity: 'error',
|
||||
summary: 'Не поддерживается в Вашем браузере!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.deferredPrompt.prompt();
|
||||
this.deferredPrompt.userChoice.then((res: any) => {
|
||||
if (res.outcome === 'accepted') {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary: 'Спасибо за установку!',
|
||||
});
|
||||
console.log('User Accepted!!!');
|
||||
}
|
||||
this.deferredPrompt = null;
|
||||
});
|
||||
}
|
||||
|
||||
checkRequestPermission() {
|
||||
this.isPermissionNotifications =
|
||||
Notification.permission !== 'granted' ? false : true;
|
||||
}
|
||||
|
||||
requestPermission() {
|
||||
const userAgent = window.navigator.userAgent.toLowerCase();
|
||||
const ios = /iphone|ipod|ipad/.test(userAgent);
|
||||
if (ios) {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary: `Чтобы получать уведомления, добавьте карту в Apple Wallet`,
|
||||
life: 5000,
|
||||
});
|
||||
if ('safari' in window) {
|
||||
console.log('safari');
|
||||
|
||||
// var permissionData = window.safari.pushNotification.permission('web.com.example.domain');
|
||||
// $scope.checkRemotePermission(permissionData);
|
||||
@ -76,6 +100,20 @@ export class MainComponent implements OnInit {
|
||||
this.message = this.messagingService.currentMessage;
|
||||
}
|
||||
}
|
||||
// test function
|
||||
copyMessage(val: string | null) {
|
||||
const selBox = document.createElement('textarea');
|
||||
selBox.style.position = 'fixed';
|
||||
selBox.style.left = '0';
|
||||
selBox.style.top = '0';
|
||||
selBox.style.opacity = '0';
|
||||
if (val) selBox.value = val;
|
||||
document.body.appendChild(selBox);
|
||||
selBox.focus();
|
||||
selBox.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(selBox);
|
||||
}
|
||||
|
||||
appendCard(): void {
|
||||
const route = this.route.snapshot.url[0]?.path;
|
||||
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AngularFireMessaging } from '@angular/fire/compat/messaging';
|
||||
import { MessageService } from 'primeng/api';
|
||||
import { BehaviorSubject, lastValueFrom } from 'rxjs';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { JsonrpcService, RpcService } from './jsonrpc.service';
|
||||
|
||||
@Injectable()
|
||||
@ -19,29 +19,15 @@ export class MessagingService {
|
||||
});
|
||||
}
|
||||
|
||||
async updateToken(token: string | null) {
|
||||
updateToken(token: string | null) {
|
||||
if (!token) return;
|
||||
const additionalInfo = (await lastValueFrom(
|
||||
this.jsonRpcService.rpc({
|
||||
method: 'getAdditionalInfo',
|
||||
params: []
|
||||
}, RpcService.authService, true)
|
||||
)).data
|
||||
let tokens: string[] = []
|
||||
if (typeof additionalInfo['fmc-token'] === 'string') {
|
||||
tokens.push(additionalInfo['fmc-token'], token)
|
||||
} else if (typeof additionalInfo['fmc-token'] === 'object') {
|
||||
tokens = [...additionalInfo['fmc-token'], token]
|
||||
} else {
|
||||
tokens = [token]
|
||||
}
|
||||
this.jsonRpcService
|
||||
.rpc(
|
||||
{
|
||||
method: 'updateAdditionalInfo',
|
||||
params: [
|
||||
{
|
||||
'fmc-token': tokens,
|
||||
'fmc-token': token,
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -84,11 +70,6 @@ export class MessagingService {
|
||||
receiveMessage() {
|
||||
this.angularFireMessaging.messages.subscribe((payload: any) => {
|
||||
console.log('new message received. ', payload);
|
||||
const NotificationOptions = {
|
||||
body: payload.notification.body,
|
||||
data: payload.data,
|
||||
icon: payload.notification.icon
|
||||
}
|
||||
this.currentMessage.next(payload);
|
||||
});
|
||||
}
|
||||