| </div> | </div> | ||||
| </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"> | <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> | <p class="lead" data-i18n="CERTIFICATION">CHỨNG CHỈ CHỨNG NHẬN</p> | ||||
| </div> | </div> | ||||
| <div class="cert-image"> | <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> | <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> | ||||
| <!-- <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> | ||||
| </div> | </div> |
| <main id="main"> | |||||
| <main id="main" *ngIf="(data$ | async) as data"> | |||||
| <div class="main-inner"> | <div class="main-inner"> | ||||
| <div class="block-style-02"> | <div class="block-style-02"> | ||||
| <div class="box"> | <div class="box"> | ||||
| <span data-i18n="product history">Lịch sử sản phẩm</span> | <span data-i18n="product history">Lịch sử sản phẩm</span> | ||||
| <br/> | <br/> | ||||
| <small data-name="generation.productName"> | <small data-name="generation.productName"> | ||||
| {{ '' || 'Không xác định' }} | |||||
| {{ data?.tbCodeDTO?.productName || 'Không xác định' }} | |||||
| </small> | </small> | ||||
| </h3> | </h3> | ||||
| <button class="btn btn-link position-absolute btn-close" (click)="tab = 'origin'; tabChange.emit(tab)"> | <button class="btn btn-link position-absolute btn-close" (click)="tab = 'origin'; tabChange.emit(tab)"> | ||||
| <i class="fa fa-times" aria-hidden="true"></i> | <i class="fa fa-times" aria-hidden="true"></i> | ||||
| </button> | </button> | ||||
| </div> | </div> | ||||
| @for (time of [1,2,3,4,5]; track time) { | |||||
| @for (time of data.timelines; track time){ | |||||
| <div class="box-body timeline"> | <div class="box-body timeline"> | ||||
| <div data-section="group"> | <div data-section="group"> | ||||
| <div class="time-label"> | <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> | </div> | ||||
| <br> | <br> | ||||
| </div> | </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> | </div> | ||||
| </div> | |||||
| </li> | |||||
| </div> | |||||
| } | |||||
| <ul class="timeline" data-name="actions"></ul> | |||||
| </li> | |||||
| </div> | |||||
| } | |||||
| } | |||||
| </div> | </div> | ||||
| } | } | ||||
| </div> | </div> |
| import { Component, EventEmitter, Input, Output } from '@angular/core'; | 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({ | @Component({ | ||||
| selector: 'app-timeline', | selector: 'app-timeline', | ||||
| standalone: true, | standalone: true, | ||||
| imports: [ | imports: [ | ||||
| DatePipe | |||||
| DatePipe, | |||||
| NgOptimizedImage, | |||||
| RouterLink, | |||||
| AsyncPipe, | |||||
| CommonModule | |||||
| ], | ], | ||||
| templateUrl: './timeline.component.html', | templateUrl: './timeline.component.html', | ||||
| styleUrl: './timeline.component.scss' | styleUrl: './timeline.component.scss' | ||||
| export class TimelineComponent { | export class TimelineComponent { | ||||
| @Input() tab: 'info' | 'origin' | 'timeline' = 'info'; | @Input() tab: 'info' | 'origin' | 'timeline' = 'info'; | ||||
| @Output() tabChange = new EventEmitter<'info' | 'origin' | 'timeline'>(); | @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) {} | |||||
| } | } |
| constructor(private httpClient: HttpClient) {} | constructor(private httpClient: HttpClient) {} | ||||
| getData(id: string): Observable<any> { | 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; | |||||
| })); | })); | ||||
| } | } | ||||
| #otsTab li { | #otsTab li { | ||||
| flex: 1; | flex: 1; | ||||
| background-color: #eeeeee; | background-color: #eeeeee; | ||||
| cursor: pointer; | |||||
| } | } | ||||
| #otsTab li a { | #otsTab li a { |