| @@ -35,16 +35,18 @@ | |||
| </div> | |||
| </div> | |||
| <div class="box" *ngIf="data?.customer?.certificationImage"> | |||
| <div class="box"> | |||
| <ng-container *ngIf="data?.customer?.certificationImage"> | |||
| <div class="box-head-02" data-name="authorisedUnit.certifications" data-type="visible"> | |||
| <p class="lead" data-i18n="CERTIFICATION">CHỨNG CHỈ CHỨNG NHẬN</p> | |||
| </div> | |||
| <div class="cert-image"> | |||
| <a href="https://nhatky.aztrace.vn/upload/{{ data?.customer?.certificationImage }}" target="_blank"><img src="https://nhatky.aztrace.vn/upload/{{ data?.customer?.certificationImage }}" alt="Giấy chứng nhận" /></a> | |||
| </div> | |||
| <!-- <div class="box-footer " style="background-color: inherit">--> | |||
| <!-- <a (click)="tab = 'timeline'; tabChange.emit(tab)" class="btn btn-theme btn-block mt-3" data-i18n="see product history">Xem lịch sử cập nhật sản phẩm</a>--> | |||
| <!-- <!–<a href="unit.html" class="btn btn-theme btn-block mt-3">Xem đơn vị phân phối</a>–>--> | |||
| <!-- </div>--> | |||
| </ng-container> | |||
| <div class="box-footer " style="background-color: inherit" *ngIf="data?.activityTimeline && data?.activityTimeline.activities.length"> | |||
| <a (click)="tab = 'timeline'; tabChange.emit(tab)" class="btn btn-theme btn-block mt-3" data-i18n="see product history">Xem lịch sử cập nhật sản phẩm</a> | |||
| <!--<a href="unit.html" class="btn btn-theme btn-block mt-3">Xem đơn vị phân phối</a>--> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -1,4 +1,4 @@ | |||
| <main id="main"> | |||
| <main id="main" *ngIf="(data$ | async) as data"> | |||
| <div class="main-inner"> | |||
| <div class="block-style-02"> | |||
| <div class="box"> | |||
| @@ -7,46 +7,46 @@ | |||
| <span data-i18n="product history">Lịch sử sản phẩm</span> | |||
| <br/> | |||
| <small data-name="generation.productName"> | |||
| {{ '' || 'Không xác định' }} | |||
| {{ data?.tbCodeDTO?.productName || 'Không xác định' }} | |||
| </small> | |||
| </h3> | |||
| <button class="btn btn-link position-absolute btn-close" (click)="tab = 'origin'; tabChange.emit(tab)"> | |||
| <i class="fa fa-times" aria-hidden="true"></i> | |||
| </button> | |||
| </div> | |||
| @for (time of [1,2,3,4,5]; track time) { | |||
| @for (time of data.timelines; track time){ | |||
| <div class="box-body timeline"> | |||
| <div data-section="group"> | |||
| <div class="time-label"> | |||
| <span class="bg-green">{{ data.date | date : 'dd/MM/yyyy' }}</span> | |||
| <span class="bg-green">{{ time | date : 'dd/MM/yyyy' }}</span> | |||
| </div> | |||
| <br> | |||
| </div> | |||
| @for (item of [1,2,3,4,5]; track item) { | |||
| <div data-section="item"> | |||
| <li class="item bg-blue" [class.active]="false" [class.transport]="false" [class.exwarehouse]="false"> | |||
| <div class="inner"> | |||
| <div class="content"> | |||
| <div class="content-row"> | |||
| <h3 class="head mb-0"> | |||
| {{ data.title }} | |||
| <span class="time"><i class="far fa-clock"></i> {{ data.time }}</span> | |||
| <span class="address ml-1"><a href="#"><i class="fas fa-home"></i> {{ data.creator }}</a> </span> | |||
| </h3> | |||
| <small class="text-muted mb-1"> | |||
| <a href="https://maps.google.com/?q={{ data.term }}" target="_blank" class="location"> | |||
| <i class="fas fa-location-arrow"></i> {{ data.scanAddress }}</a> | |||
| </small> | |||
| <br/> | |||
| <span>{{ data.description }}</span> | |||
| {{ data.metas }} | |||
| @for (item of data.activities; track item){ | |||
| @if( time === item.date) { | |||
| <div data-section="item"> | |||
| <li class="item bg-blue" [class.active]="false" [class.transport]="false" [class.exwarehouse]="false"> | |||
| <div class="inner"> | |||
| <div class="content"> | |||
| <div class="content-row"> | |||
| <h3 class="head mb-0"> | |||
| {{ item.activityTypeDescription }} | |||
| <span class="time"><i class="far fa-clock"></i> {{ item.executeDate | date : 'HH:mm' }}</span> | |||
| <span class="address ml-1"><i class="fas fa-user"></i> {{ item.createdByName }}</span> | |||
| </h3> | |||
| <small class="text-muted mb-1"> | |||
| <span class="location"> | |||
| <i class="fas fa-location-arrow"></i> {{ item.location }}</span> | |||
| </small> | |||
| <br/> | |||
| <span>{{ item.description }}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </li> | |||
| </div> | |||
| } | |||
| <ul class="timeline" data-name="actions"></ul> | |||
| </li> | |||
| </div> | |||
| } | |||
| } | |||
| </div> | |||
| } | |||
| </div> | |||
| @@ -1,11 +1,18 @@ | |||
| import { Component, EventEmitter, Input, Output } from '@angular/core'; | |||
| import { DatePipe } from "@angular/common"; | |||
| import {AsyncPipe, CommonModule, DatePipe, NgOptimizedImage} from "@angular/common"; | |||
| import {ActivatedRoute, Router, RouterLink} from "@angular/router"; | |||
| import {ApiService} from "../../shared/services/api.service"; | |||
| @Component({ | |||
| selector: 'app-timeline', | |||
| standalone: true, | |||
| imports: [ | |||
| DatePipe | |||
| DatePipe, | |||
| NgOptimizedImage, | |||
| RouterLink, | |||
| AsyncPipe, | |||
| CommonModule | |||
| ], | |||
| templateUrl: './timeline.component.html', | |||
| styleUrl: './timeline.component.scss' | |||
| @@ -13,18 +20,6 @@ import { DatePipe } from "@angular/common"; | |||
| export class TimelineComponent { | |||
| @Input() tab: 'info' | 'origin' | 'timeline' = 'info'; | |||
| @Output() tabChange = new EventEmitter<'info' | 'origin' | 'timeline'>(); | |||
| @Input() data: any = { | |||
| date: new Date(), | |||
| content: 'This is a timeline content', | |||
| iconClass: 'fa fa-clock-o', | |||
| title: 'Timeline Title', | |||
| time: '12:00', | |||
| creator: 'John Doe', | |||
| term: '2 days ago', | |||
| scanAddress: 'https://www.google.com', | |||
| description: 'This is a timeline description', | |||
| metas: 'test meta', | |||
| label: 'test label', | |||
| value: 'test value', | |||
| } | |||
| data$ = this.api$.data$; | |||
| constructor(private api$: ApiService) {} | |||
| } | |||
| @@ -10,8 +10,25 @@ export class ApiService { | |||
| constructor(private httpClient: HttpClient) {} | |||
| getData(id: string): Observable<any> { | |||
| return this.httpClient.get(`${this.apuUrl}/tb-code-details/scan/${id}`).pipe(tap((res) => { | |||
| this.data$.next(res); | |||
| return this.httpClient.get(`${this.apuUrl}/tb-code-details/scan/${id}`).pipe(tap((res: any) => { | |||
| const data = res; | |||
| data['timelines'] = []; | |||
| if (data.activities){ | |||
| data.activities.sort(function(a: any,b: any){ | |||
| // @ts-ignore | |||
| return new Date(b.executeDate) - new Date(a.executeDate); | |||
| }); | |||
| data.activities.forEach((item: any) => { | |||
| const date = item.executeDate.split('T')[0]; | |||
| item['date'] = date; | |||
| const index = data['timelines'].findIndex((itm: any) => itm === date); | |||
| if (index === -1) { | |||
| data['timelines'].push(date); | |||
| } | |||
| }) | |||
| } | |||
| this.data$.next(data); | |||
| return res; | |||
| })); | |||
| } | |||
| @@ -263,6 +263,7 @@ img { | |||
| #otsTab li { | |||
| flex: 1; | |||
| background-color: #eeeeee; | |||
| cursor: pointer; | |||
| } | |||
| #otsTab li a { | |||