From 63a58292d5d4fa2bfb1c3c9af03678ceefa2a7b1 Mon Sep 17 00:00:00 2001 From: Supichai Pothong Date: Tue, 17 Oct 2023 02:29:58 +0700 Subject: [PATCH] [update] settings menu --- src/app/@config/menus.ts | 29 ++++ src/app/app-routing.module.ts | 13 ++ src/app/auth/login/login.component.ts | 3 +- src/app/core/base/base-list.ts | 4 +- src/app/core/service/common/banner.service.ts | 16 ++ .../service/{manage => common}/kyc.service.ts | 0 .../core/service/common/promotion.service.ts | 16 ++ src/app/pages/@layouts/layouts.component.html | 2 +- .../manage/kyc/container/kyc/kyc.container.ts | 2 +- .../transactions/transactions.container.ts | 2 +- src/app/pages/setting/banner/banner.module.ts | 37 +++++ .../container/banner/banner.container.html | 6 + .../container/banner/banner.container.scss | 0 .../container/banner/banner.container.spec.ts | 23 +++ .../container/banner/banner.container.ts | 78 ++++++++++ .../presenter/dialog/dialog.component.html | 99 ++++++++++++ .../presenter/dialog/dialog.component.scss | 0 .../presenter/dialog/dialog.component.spec.ts | 23 +++ .../presenter/dialog/dialog.component.ts | 143 ++++++++++++++++++ .../banner/presenter/list/list.component.html | 83 ++++++++++ .../banner/presenter/list/list.component.scss | 0 .../presenter/list/list.component.spec.ts | 23 +++ .../banner/presenter/list/list.component.ts | 32 ++++ src/app/pages/setting/banner/router/router.ts | 16 ++ .../promotion/promotion.container.html | 6 + .../promotion/promotion.container.scss | 0 .../promotion/promotion.container.spec.ts | 23 +++ .../promotion/promotion.container.ts | 78 ++++++++++ .../presenter/dialog/dialog.component.html | 99 ++++++++++++ .../presenter/dialog/dialog.component.scss | 0 .../presenter/dialog/dialog.component.spec.ts | 23 +++ .../presenter/dialog/dialog.component.ts | 143 ++++++++++++++++++ .../presenter/list/list.component.html | 83 ++++++++++ .../presenter/list/list.component.scss | 0 .../presenter/list/list.component.spec.ts | 23 +++ .../presenter/list/list.component.ts | 33 ++++ .../setting/promotion/promotion.module.ts | 37 +++++ .../pages/setting/promotion/router/router.ts | 16 ++ src/styles/app.scss | 4 + 39 files changed, 1213 insertions(+), 5 deletions(-) create mode 100644 src/app/core/service/common/banner.service.ts rename src/app/core/service/{manage => common}/kyc.service.ts (100%) create mode 100644 src/app/core/service/common/promotion.service.ts create mode 100644 src/app/pages/setting/banner/banner.module.ts create mode 100644 src/app/pages/setting/banner/container/banner/banner.container.html create mode 100644 src/app/pages/setting/banner/container/banner/banner.container.scss create mode 100644 src/app/pages/setting/banner/container/banner/banner.container.spec.ts create mode 100644 src/app/pages/setting/banner/container/banner/banner.container.ts create mode 100644 src/app/pages/setting/banner/presenter/dialog/dialog.component.html create mode 100644 src/app/pages/setting/banner/presenter/dialog/dialog.component.scss create mode 100644 src/app/pages/setting/banner/presenter/dialog/dialog.component.spec.ts create mode 100644 src/app/pages/setting/banner/presenter/dialog/dialog.component.ts create mode 100644 src/app/pages/setting/banner/presenter/list/list.component.html create mode 100644 src/app/pages/setting/banner/presenter/list/list.component.scss create mode 100644 src/app/pages/setting/banner/presenter/list/list.component.spec.ts create mode 100644 src/app/pages/setting/banner/presenter/list/list.component.ts create mode 100644 src/app/pages/setting/banner/router/router.ts create mode 100644 src/app/pages/setting/promotion/container/promotion/promotion.container.html create mode 100644 src/app/pages/setting/promotion/container/promotion/promotion.container.scss create mode 100644 src/app/pages/setting/promotion/container/promotion/promotion.container.spec.ts create mode 100644 src/app/pages/setting/promotion/container/promotion/promotion.container.ts create mode 100644 src/app/pages/setting/promotion/presenter/dialog/dialog.component.html create mode 100644 src/app/pages/setting/promotion/presenter/dialog/dialog.component.scss create mode 100644 src/app/pages/setting/promotion/presenter/dialog/dialog.component.spec.ts create mode 100644 src/app/pages/setting/promotion/presenter/dialog/dialog.component.ts create mode 100644 src/app/pages/setting/promotion/presenter/list/list.component.html create mode 100644 src/app/pages/setting/promotion/presenter/list/list.component.scss create mode 100644 src/app/pages/setting/promotion/presenter/list/list.component.spec.ts create mode 100644 src/app/pages/setting/promotion/presenter/list/list.component.ts create mode 100644 src/app/pages/setting/promotion/promotion.module.ts create mode 100644 src/app/pages/setting/promotion/router/router.ts diff --git a/src/app/@config/menus.ts b/src/app/@config/menus.ts index 9342f41..88c5f35 100644 --- a/src/app/@config/menus.ts +++ b/src/app/@config/menus.ts @@ -55,4 +55,33 @@ export const MENU: MENU[] = [ }, ] }, + { + name: 'Setting', + link: 'setting', + permission: 'setting', + icon: 'bi bi-gear-fill', + params: [], + badge: '', + type: 'collapsable', + children: [ + { + name: 'Banner', + link: 'setting/banner', + permission: 'banner', + type: 'link', + icon: '', + params: [], + badge: '', + }, + { + name: 'Promotion', + link: 'setting/promotion', + permission: 'promotion', + type: 'link', + icon: '', + params: [], + badge: '', + }, + ] + }, ]; diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 2eb2d39..0a01bd6 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -44,6 +44,19 @@ const routes: Routes = [ }, ] }, + { + path: 'setting', + children: [ + { + path: 'banner', + loadChildren: () => import('./pages/setting/banner/banner.module').then(m => m.BannerModule) + }, + { + path: 'promotion', + loadChildren: () => import('./pages/setting/promotion/promotion.module').then(m => m.PromotionModule) + }, + ] + }, { path: 'not-found', loadChildren: () => import('./pages/errors/errors.module').then(m => m.ErrorsModule) diff --git a/src/app/auth/login/login.component.ts b/src/app/auth/login/login.component.ts index 0f89546..d33815c 100644 --- a/src/app/auth/login/login.component.ts +++ b/src/app/auth/login/login.component.ts @@ -38,7 +38,8 @@ export class LoginComponent implements OnInit { async onSubmit(form: any) { if (!form.valid) return false; try { - await lastValueFrom(this.authService.login(this.dataForm)); + const result = await lastValueFrom(this.authService.login(this.dataForm)); + this.appService.setAuth(result); return this.router.navigate(['/pages']); } catch (err) { return this.appService.message(EAction.ERROR, EText.NO_DATA); diff --git a/src/app/core/base/base-list.ts b/src/app/core/base/base-list.ts index a39f4cd..f8aaaaf 100644 --- a/src/app/core/base/base-list.ts +++ b/src/app/core/base/base-list.ts @@ -5,7 +5,7 @@ import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { environment } from 'src/environments/environment'; import { map, startWith } from 'rxjs/operators'; - +import { CDialogConfig, IDialogConfig } from 'src/app/@common/interface/Dialog'; export interface ResultPageEvent { @@ -25,6 +25,8 @@ export interface CustomeEventPage extends PageEvent { @Directive() export class BaseList { + + dialogConfig: IDialogConfig = CDialogConfig; protected INT_PAGING:CustomeEventPage = { length: 0, pageIndex: 0, diff --git a/src/app/core/service/common/banner.service.ts b/src/app/core/service/common/banner.service.ts new file mode 100644 index 0000000..f329598 --- /dev/null +++ b/src/app/core/service/common/banner.service.ts @@ -0,0 +1,16 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { BaseService } from 'src/app/core/base/base-service'; + +@Injectable({ + providedIn: 'root' +}) +export class BannerService extends BaseService{ + + constructor( + public http: HttpClient + ) { + super('/common/banner', http) + } + +} diff --git a/src/app/core/service/manage/kyc.service.ts b/src/app/core/service/common/kyc.service.ts similarity index 100% rename from src/app/core/service/manage/kyc.service.ts rename to src/app/core/service/common/kyc.service.ts diff --git a/src/app/core/service/common/promotion.service.ts b/src/app/core/service/common/promotion.service.ts new file mode 100644 index 0000000..b3792b2 --- /dev/null +++ b/src/app/core/service/common/promotion.service.ts @@ -0,0 +1,16 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { BaseService } from 'src/app/core/base/base-service'; + +@Injectable({ + providedIn: 'root' +}) +export class PromotionService extends BaseService{ + + constructor( + public http: HttpClient + ) { + super('/common/promotionwwwwwwwwwwww', http) + } + +} diff --git a/src/app/pages/@layouts/layouts.component.html b/src/app/pages/@layouts/layouts.component.html index 5107033..6c969fc 100644 --- a/src/app/pages/@layouts/layouts.component.html +++ b/src/app/pages/@layouts/layouts.component.html @@ -97,7 +97,7 @@
-
{{auth?.name || '-'}}
+
{{auth?.user_name_th || '-'}}
{{auth?.email || '-' }}
diff --git a/src/app/pages/manage/kyc/container/kyc/kyc.container.ts b/src/app/pages/manage/kyc/container/kyc/kyc.container.ts index 2148044..4a165ba 100644 --- a/src/app/pages/manage/kyc/container/kyc/kyc.container.ts +++ b/src/app/pages/manage/kyc/container/kyc/kyc.container.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; -import { KycService } from 'src/app/core/service/manage/kyc.service'; +import { KycService } from 'src/app/core/service/common/kyc.service'; @Component({ selector: 'app-kyc', diff --git a/src/app/pages/report/transactions/container/transactions/transactions.container.ts b/src/app/pages/report/transactions/container/transactions/transactions.container.ts index 1921bd4..bfa0329 100644 --- a/src/app/pages/report/transactions/container/transactions/transactions.container.ts +++ b/src/app/pages/report/transactions/container/transactions/transactions.container.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; -import { KycService } from 'src/app/core/service/manage/kyc.service'; +import { KycService } from 'src/app/core/service/common/kyc.service'; @Component({ selector: 'app-transactions', diff --git a/src/app/pages/setting/banner/banner.module.ts b/src/app/pages/setting/banner/banner.module.ts new file mode 100644 index 0000000..39ccf66 --- /dev/null +++ b/src/app/pages/setting/banner/banner.module.ts @@ -0,0 +1,37 @@ +import { NgOptimizedImage } from "@angular/common"; +import { RouterModule, Routes } from "@angular/router"; +import { AppSharedModule } from "src/app/app.shared"; +import { NgModule } from "@angular/core"; +import { ListComponent } from "./presenter/list/list.component"; +import { BannerRouter } from "./router/router"; +import { BannerContainer } from "./container/banner/banner.container"; +import { DialogComponent } from './presenter/dialog/dialog.component'; + + +const routes: Routes = [ + { + path: '', + component: BannerRouter, + children: [ + { + path: '', + component: BannerContainer + } + ] + } +] + +@NgModule({ + declarations: [ + BannerRouter, + BannerContainer, + ListComponent, + DialogComponent + ], + imports: [ + AppSharedModule, + NgOptimizedImage, + RouterModule.forChild(routes) + ] +}) +export class BannerModule { } diff --git a/src/app/pages/setting/banner/container/banner/banner.container.html b/src/app/pages/setting/banner/container/banner/banner.container.html new file mode 100644 index 0000000..74d1dd6 --- /dev/null +++ b/src/app/pages/setting/banner/container/banner/banner.container.html @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/src/app/pages/setting/banner/container/banner/banner.container.scss b/src/app/pages/setting/banner/container/banner/banner.container.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/setting/banner/container/banner/banner.container.spec.ts b/src/app/pages/setting/banner/container/banner/banner.container.spec.ts new file mode 100644 index 0000000..1dfa9ca --- /dev/null +++ b/src/app/pages/setting/banner/container/banner/banner.container.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BannerContainer } from './banner.container'; + +describe('BannerContainer', () => { + let component: BannerContainer; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ BannerContainer ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BannerContainer); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/setting/banner/container/banner/banner.container.ts b/src/app/pages/setting/banner/container/banner/banner.container.ts new file mode 100644 index 0000000..f18f36b --- /dev/null +++ b/src/app/pages/setting/banner/container/banner/banner.container.ts @@ -0,0 +1,78 @@ +import { Component } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { Observable, catchError, filter, of, switchMap, tap, throwError } from 'rxjs'; +import { CDialogConfig, IDialogConfig } from 'src/app/@common/interface/Dialog'; +import { EAction, EText } from 'src/app/@config/app'; +import { BannerService } from 'src/app/core/service/common/banner.service'; +import { DialogComponent } from '../../presenter/dialog/dialog.component'; +import { AppService } from 'src/app/app.service'; + +@Component({ + selector: 'app-banner', + templateUrl: './banner.container.html', + styleUrls: ['./banner.container.scss'] +}) +export class BannerContainer { + dialogConfig: IDialogConfig = CDialogConfig + banner$ = new Observable(); + constructor( + private bannerService: BannerService, + private dialog: MatDialog, + private appService: AppService + ) { + this.banner$ = this.bannerService.getAll(); + } + + add(){ + this.dialogConfig.data.action = EAction.CREATE; + const dialogRef = this.dialog.open(DialogComponent,this.dialogConfig); + dialogRef.afterClosed().pipe( + switchMap((res) => { + if(res === 'success'){ + return this.banner$ = this.bannerService.getAll().pipe( + catchError((err) => { + this.appService.message(EAction.ERROR, EText.ERROR); + return throwError(() => err) + }) + ) + } + }) + ).subscribe() + } + + edit(uid){ + this.dialogConfig.data.action = EAction.UPDATE; + this.dialogConfig.data.ids = uid + const dialogRef = this.dialog.open(DialogComponent,this.dialogConfig); + const edit$ = dialogRef.afterClosed().pipe( + switchMap((res) => { + if(res === 'success'){ + return this.banner$ = this.bannerService.getAll().pipe( + catchError((err) => { + this.appService.message(EAction.ERROR, EText.ERROR); + return throwError(() => err) + }) + ) + } + }) + ) + return edit$.subscribe(); + } + + delete(uid){ + const delete$ = this.appService.confirm(EAction.DELETE).pipe( + filter((res) => res.isConfirmed), + switchMap(() => { + return this.bannerService.deleteData(uid).pipe( + tap(() => this.appService.message(EAction.SUCCESS, EText.DELETE)), + tap(() => this.banner$ = this.bannerService.getAll()), + catchError((err) => { + this.appService.message(EAction.SUCCESS, EText.DELETE); + return throwError(() => err) + }) + ) + }) + ); + return delete$.subscribe(); + } +} diff --git a/src/app/pages/setting/banner/presenter/dialog/dialog.component.html b/src/app/pages/setting/banner/presenter/dialog/dialog.component.html new file mode 100644 index 0000000..1659cdd --- /dev/null +++ b/src/app/pages/setting/banner/presenter/dialog/dialog.component.html @@ -0,0 +1,99 @@ +
+
+
+

Banner

+ clear +
+
+
+ +
+
+ ชื่อรายการ + + + + +
+
+ +
+
+ Link + + + + +
+
+ +
+
+ คำอธิบาย + + + + +
+
+ +
+
+ วันเริ่มต้น/สิ้นสุด + + + + + + + + + + +
+
+ +
+
+ แนบรูป +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + +
+
+ +
+
+ +
+
+ Open/Close + + +
+
+
+
+ +
+
+ + \ No newline at end of file diff --git a/src/app/pages/setting/banner/presenter/dialog/dialog.component.scss b/src/app/pages/setting/banner/presenter/dialog/dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/setting/banner/presenter/dialog/dialog.component.spec.ts b/src/app/pages/setting/banner/presenter/dialog/dialog.component.spec.ts new file mode 100644 index 0000000..feb64ee --- /dev/null +++ b/src/app/pages/setting/banner/presenter/dialog/dialog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DialogComponent } from './dialog.component'; + +describe('DialogComponent', () => { + let component: DialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ DialogComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/setting/banner/presenter/dialog/dialog.component.ts b/src/app/pages/setting/banner/presenter/dialog/dialog.component.ts new file mode 100644 index 0000000..7803205 --- /dev/null +++ b/src/app/pages/setting/banner/presenter/dialog/dialog.component.ts @@ -0,0 +1,143 @@ +import { Location } from '@angular/common'; +import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { catchError, tap, throwError } from 'rxjs'; +import { IDialogConfigData } from 'src/app/@common/interface/Dialog'; +import { EAction, EText } from 'src/app/@config/app'; +import { AppService } from 'src/app/app.service'; +import { BaseForm } from 'src/app/core/base/base-form'; +import { BannerService } from 'src/app/core/service/common/banner.service'; + +@Component({ + selector: 'app-dialog', + templateUrl: './dialog.component.html', + styleUrls: ['./dialog.component.scss'] +}) +export class DialogComponent extends BaseForm implements OnInit { + data = false; + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public dialog: IDialogConfigData, + public router: Router, + public activatedRoute: ActivatedRoute, + public fb: FormBuilder, + public location: Location, + public bannerService: BannerService, + public appService: AppService, + public cdr: ChangeDetectorRef + ) { + super(router, activatedRoute, fb, location) + } + + ngOnInit(): void { + if (this.dialog.action === EAction.UPDATE){ + this.state = 'edit'; + this.getData(); + } + } + + createForm(): FormGroup { + return this.fb.group({ + status_id: null, + created_by: null, + created_datetime: null, + updated_by: null, + updated_datetime: null, + owner_agency_uid: null, + banner_uid: null, + name: [null, Validators.required], + link: [null, Validators.required], + description: null, + start_date: [null, Validators.required], + end_date: [null, Validators.required], + file_name: null, + file_url: [null], + is_use: false + }) + } + + getData() { + if (!this.dialog.ids) this.appService.message(EAction.INFO, EText.NO_DATA); + this.bannerService.get(this.dialog.ids).pipe( + tap((res) => this.form.patchValue(res)), + tap(() => this.cdr.detectChanges()), + catchError((err) => { + this.appService.message(EAction.ERROR, EText.ERROR); + return throwError(() => err) + }) + ).subscribe() + } + + save() { + const form = this.form.getRawValue(); + const save$ = this.state === 'edit' ? this.bannerService.update2(form) : this.bannerService.add(form); + return save$.pipe( + tap(() => this.appService.message(EAction.SUCCESS, EText.UPDATE)), + tap(() => this.dialogRef.close('success')), + catchError((err) => { + this.appService.message(EAction.ERROR, EText.ERROR); + return throwError(() => err) + }) + ).subscribe() + } + + // async onSubmit(form: any) { + // if (!form.valid) return false; + + // const sweetalert = await lastValueFrom(this.appService.confirm(EAction.CREATE)); + // if (!sweetalert.isConfirmed) return; + + // this.dataForm.images = this.attachments?.[0] ? this.attachments.join(",") : null; + + // this.dataForm.pageAction = 'financePaying'; + // return await this.onUpdate(); + + // } + + + // async onUpdate() { + // try { + // await lastValueFrom(this.appService.post(`${this.api.quotation}/update/${this.ids}`, this.dataForm)); + // await this.appService.message(EAction.SUCCESS, EText.UPDATE); + // await this.router.navigate(["/pages/finance/paying/list", this.action]); + // } catch (err) { + // this.appService.message(EAction.ERROR, EText.ERROR); + + // } + // } + + async onAttachments($event: any) { + const file = $event.target.files[0]; + if (!file) return; + const formData = new FormData(); + formData.append("ref", 'images'); + formData.append("file", file); + // try { + // const res = await lastValueFrom(this.appService.post(`${API.attachments}/images`, formData)); + // this.dataForm.sellerPaymentImages = res.fileName; + // this.uploadFile.nativeElement.value = null; + // this.changeDetectorRef.detectChanges(); + // } catch (e) { + // this.appService.message(EText.ERROR); + // } + } + + async onRemoveAttachments() { + // const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE)); + // if (!sweetalert.isConfirmed) return; + // this.dataForm.paymentImages = null; + // this.changeDetectorRef.detectChanges(); + } + + async onAttachmentsView() { + // const dialogConfig = deepCopy(this.dialogConfig); + // dialogConfig.data.action = EAction.POPUP; + // dialogConfig.data.title = 'ไฟล์แนบ'; + // dialogConfig.data.type = 'images'; + // dialogConfig.data.images = this.dataForm.sellerPaymentImages; + // const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig); + // const afterClosed = await lastValueFrom(dialogRef.afterClosed()); + } +} diff --git a/src/app/pages/setting/banner/presenter/list/list.component.html b/src/app/pages/setting/banner/presenter/list/list.component.html new file mode 100644 index 0000000..f06adf7 --- /dev/null +++ b/src/app/pages/setting/banner/presenter/list/list.component.html @@ -0,0 +1,83 @@ +
+ +
+
+
+ + + + +
+
+ +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ลำดับ{{getIndex(i)}}ชื่อรายการ + {{item.name}} + Link{{item.link}}คำอธิบาย{{item.description}}วันเริ่มต้น{{item.start_date | date : 'dd/MM/YYYY'}}วันสิ้นสุด{{item.weight | date : 'dd/MM/YYYY'}}สถานะ{{item.is_use === true? 'Open' : 'Close'}}เครื่องมือ +
+
+ +
+
+ +
+
+
+
+ + +
+
\ No newline at end of file diff --git a/src/app/pages/setting/banner/presenter/list/list.component.scss b/src/app/pages/setting/banner/presenter/list/list.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/setting/banner/presenter/list/list.component.spec.ts b/src/app/pages/setting/banner/presenter/list/list.component.spec.ts new file mode 100644 index 0000000..54ae348 --- /dev/null +++ b/src/app/pages/setting/banner/presenter/list/list.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ListComponent } from './list.component'; + +describe('ListComponent', () => { + let component: ListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ListComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/setting/banner/presenter/list/list.component.ts b/src/app/pages/setting/banner/presenter/list/list.component.ts new file mode 100644 index 0000000..9ebd16f --- /dev/null +++ b/src/app/pages/setting/banner/presenter/list/list.component.ts @@ -0,0 +1,32 @@ +import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; +import { DialogComponent } from '../dialog/dialog.component'; +import { BaseList } from 'src/app/core/base/base-list'; +import { EAction } from 'src/app/@config/app'; +import { filter, lastValueFrom, switchMap, tap } from 'rxjs'; +import { MatDialog } from '@angular/material/dialog'; + +@Component({ + selector: 'app-list', + templateUrl: './list.component.html', + styleUrls: ['./list.component.scss'] +}) +export class ListComponent extends BaseList implements OnChanges { + @Input() bannerList: any = []; + @Output() add = new EventEmitter(); + @Output() edit = new EventEmitter(); + constructor() { + super() + } + + ngOnChanges(){ + this.bannerList = this.updateMatTable(this.bannerList? this.bannerList : []) + } + + onAdd() { + this.add.emit() + } + + onEdit(uid){ + this.edit.emit(uid) + } +} diff --git a/src/app/pages/setting/banner/router/router.ts b/src/app/pages/setting/banner/router/router.ts new file mode 100644 index 0000000..a5e02d4 --- /dev/null +++ b/src/app/pages/setting/banner/router/router.ts @@ -0,0 +1,16 @@ +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-banner-router', + template: '', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class BannerRouter implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} + diff --git a/src/app/pages/setting/promotion/container/promotion/promotion.container.html b/src/app/pages/setting/promotion/container/promotion/promotion.container.html new file mode 100644 index 0000000..305fd32 --- /dev/null +++ b/src/app/pages/setting/promotion/container/promotion/promotion.container.html @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/src/app/pages/setting/promotion/container/promotion/promotion.container.scss b/src/app/pages/setting/promotion/container/promotion/promotion.container.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/setting/promotion/container/promotion/promotion.container.spec.ts b/src/app/pages/setting/promotion/container/promotion/promotion.container.spec.ts new file mode 100644 index 0000000..c8f530c --- /dev/null +++ b/src/app/pages/setting/promotion/container/promotion/promotion.container.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PromotionContainer } from './promotion.container'; + +describe('PromotionContainer', () => { + let component: PromotionContainer; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PromotionContainer ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PromotionContainer); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/setting/promotion/container/promotion/promotion.container.ts b/src/app/pages/setting/promotion/container/promotion/promotion.container.ts new file mode 100644 index 0000000..af833cc --- /dev/null +++ b/src/app/pages/setting/promotion/container/promotion/promotion.container.ts @@ -0,0 +1,78 @@ +import { Component } from '@angular/core'; +import { Observable, catchError, filter, switchMap, tap, throwError } from 'rxjs'; +import { IDialogConfig, CDialogConfig } from 'src/app/@common/interface/Dialog'; +import { EAction, EText } from 'src/app/@config/app'; +import { PromotionService } from 'src/app/core/service/common/promotion.service'; +import { MatDialog } from '@angular/material/dialog'; +import { AppService } from 'src/app/app.service'; +import { DialogComponent } from '../../presenter/dialog/dialog.component'; + +@Component({ + selector: 'app-promotion', + templateUrl: './promotion.container.html', + styleUrls: ['./promotion.container.scss'] +}) +export class PromotionContainer { + dialogConfig: IDialogConfig = CDialogConfig + promotion$ = new Observable(); + constructor( + private promotionSerivce: PromotionService, + private dialog: MatDialog, + private appService: AppService + ) { + this.promotion$ = this.promotionSerivce.getAll(); + } + + add(){ + this.dialogConfig.data.action = EAction.CREATE; + const dialogRef = this.dialog.open(DialogComponent,this.dialogConfig); + dialogRef.afterClosed().pipe( + switchMap((res) => { + if(res === 'success'){ + return this.promotion$ = this.promotionSerivce.getAll().pipe( + catchError((err) => { + this.appService.message(EAction.ERROR, EText.ERROR); + return throwError(() => err) + }) + ) + } + }) + ).subscribe() + } + + edit(uid){ + this.dialogConfig.data.action = EAction.UPDATE; + this.dialogConfig.data.ids = uid + const dialogRef = this.dialog.open(DialogComponent,this.dialogConfig); + const edit$ = dialogRef.afterClosed().pipe( + switchMap((res) => { + if(res === 'success'){ + return this.promotion$ = this.promotionSerivce.getAll().pipe( + catchError((err) => { + this.appService.message(EAction.ERROR, EText.ERROR); + return throwError(() => err) + }) + ) + } + }) + ) + return edit$.subscribe() + } + + delete(uid){ + const delete$ = this.appService.confirm(EAction.DELETE).pipe( + filter((res) => res.isConfirmed), + switchMap(() => { + return this.promotionSerivce.deleteData(uid).pipe( + tap(() => this.appService.message(EAction.SUCCESS, EText.DELETE)), + tap(() => this.promotion$ = this.promotionSerivce.getAll()), + catchError((err) => { + this.appService.message(EAction.SUCCESS, EText.DELETE); + return throwError(() => err) + }) + ) + }) + ); + return delete$.subscribe() + } +} diff --git a/src/app/pages/setting/promotion/presenter/dialog/dialog.component.html b/src/app/pages/setting/promotion/presenter/dialog/dialog.component.html new file mode 100644 index 0000000..1994f9c --- /dev/null +++ b/src/app/pages/setting/promotion/presenter/dialog/dialog.component.html @@ -0,0 +1,99 @@ +
+
+
+

Promotion

+ clear +
+
+
+ +
+
+ ชื่อรายการ + + + + +
+
+ +
+
+ Link + + + + +
+
+ +
+
+ คำอธิบาย + + + + +
+
+ +
+
+ วันเริ่มต้น/สิ้นสุด + + + + + + + + + + +
+
+ +
+
+ แนบรูป +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + +
+
+ +
+
+ +
+
+ Open/Close + + +
+
+
+
+ +
+
+ + \ No newline at end of file diff --git a/src/app/pages/setting/promotion/presenter/dialog/dialog.component.scss b/src/app/pages/setting/promotion/presenter/dialog/dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/setting/promotion/presenter/dialog/dialog.component.spec.ts b/src/app/pages/setting/promotion/presenter/dialog/dialog.component.spec.ts new file mode 100644 index 0000000..feb64ee --- /dev/null +++ b/src/app/pages/setting/promotion/presenter/dialog/dialog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DialogComponent } from './dialog.component'; + +describe('DialogComponent', () => { + let component: DialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ DialogComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/setting/promotion/presenter/dialog/dialog.component.ts b/src/app/pages/setting/promotion/presenter/dialog/dialog.component.ts new file mode 100644 index 0000000..a47fe17 --- /dev/null +++ b/src/app/pages/setting/promotion/presenter/dialog/dialog.component.ts @@ -0,0 +1,143 @@ +import { Location } from '@angular/common'; +import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { catchError, tap, throwError } from 'rxjs'; +import { IDialogConfigData } from 'src/app/@common/interface/Dialog'; +import { EAction, EText } from 'src/app/@config/app'; +import { AppService } from 'src/app/app.service'; +import { BaseForm } from 'src/app/core/base/base-form'; +import { PromotionService } from 'src/app/core/service/common/promotion.service'; + +@Component({ + selector: 'app-dialog', + templateUrl: './dialog.component.html', + styleUrls: ['./dialog.component.scss'] +}) +export class DialogComponent extends BaseForm implements OnInit { + data = false; + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public dialog: IDialogConfigData, + public router: Router, + public activatedRoute: ActivatedRoute, + public fb: FormBuilder, + public location: Location, + public promotionService: PromotionService, + public appService: AppService, + public cdr: ChangeDetectorRef + ) { + super(router, activatedRoute, fb, location) + } + + ngOnInit(): void { + if (this.dialog.action === EAction.UPDATE){ + this.state = 'edit'; + this.getData(); + } + } + + createForm(): FormGroup { + return this.fb.group({ + status_id: null, + created_by: null, + created_datetime: null, + updated_by: null, + updated_datetime: null, + owner_agency_uid: null, + promotion_uid: null, + name: [null, Validators.required], + link: [null, Validators.required], + description: null, + start_date: [null, Validators.required], + end_date: [null, Validators.required], + file_name: null, + file_url: [null], + is_use: false + }) + } + + getData() { + if (!this.dialog.ids) this.appService.message(EAction.INFO, EText.NO_DATA); + this.promotionService.get(this.dialog.ids).pipe( + tap((res) => this.form.patchValue(res)), + tap(() => this.cdr.detectChanges()), + catchError((err) => { + this.appService.message(EAction.ERROR, EText.ERROR); + return throwError(() => err) + }) + ).subscribe() + } + + save() { + const form = this.form.getRawValue(); + const save$ = this.state === 'edit' ? this.promotionService.update2(form) : this.promotionService.add(form); + return save$.pipe( + tap(() => this.appService.message(EAction.SUCCESS, EText.UPDATE)), + tap(() => this.dialogRef.close('success')), + catchError((err) => { + this.appService.message(EAction.ERROR, EText.ERROR); + return throwError(() => err) + }) + ).subscribe() + } + + // async onSubmit(form: any) { + // if (!form.valid) return false; + + // const sweetalert = await lastValueFrom(this.appService.confirm(EAction.CREATE)); + // if (!sweetalert.isConfirmed) return; + + // this.dataForm.images = this.attachments?.[0] ? this.attachments.join(",") : null; + + // this.dataForm.pageAction = 'financePaying'; + // return await this.onUpdate(); + + // } + + + // async onUpdate() { + // try { + // await lastValueFrom(this.appService.post(`${this.api.quotation}/update/${this.ids}`, this.dataForm)); + // await this.appService.message(EAction.SUCCESS, EText.UPDATE); + // await this.router.navigate(["/pages/finance/paying/list", this.action]); + // } catch (err) { + // this.appService.message(EAction.ERROR, EText.ERROR); + + // } + // } + + async onAttachments($event: any) { + const file = $event.target.files[0]; + if (!file) return; + const formData = new FormData(); + formData.append("ref", 'images'); + formData.append("file", file); + // try { + // const res = await lastValueFrom(this.appService.post(`${API.attachments}/images`, formData)); + // this.dataForm.sellerPaymentImages = res.fileName; + // this.uploadFile.nativeElement.value = null; + // this.changeDetectorRef.detectChanges(); + // } catch (e) { + // this.appService.message(EText.ERROR); + // } + } + + async onRemoveAttachments() { + // const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE)); + // if (!sweetalert.isConfirmed) return; + // this.dataForm.paymentImages = null; + // this.changeDetectorRef.detectChanges(); + } + + async onAttachmentsView() { + // const dialogConfig = deepCopy(this.dialogConfig); + // dialogConfig.data.action = EAction.POPUP; + // dialogConfig.data.title = 'ไฟล์แนบ'; + // dialogConfig.data.type = 'images'; + // dialogConfig.data.images = this.dataForm.sellerPaymentImages; + // const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig); + // const afterClosed = await lastValueFrom(dialogRef.afterClosed()); + } +} diff --git a/src/app/pages/setting/promotion/presenter/list/list.component.html b/src/app/pages/setting/promotion/presenter/list/list.component.html new file mode 100644 index 0000000..bfe4aed --- /dev/null +++ b/src/app/pages/setting/promotion/presenter/list/list.component.html @@ -0,0 +1,83 @@ +
+ +
+
+
+ + + + +
+
+ +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ลำดับ{{getIndex(i)}}ชื่อรายการ + {{item.name}} + Link{{item.link}}คำอธิบาย{{item.description}}วันเริ่มต้น{{item.start_date | date : 'dd/MM/YYYY'}}วันสิ้นสุด{{item.weight | date : 'dd/MM/YYYY'}}สถานะ{{item.is_use === true? 'Open' : 'Close'}}เครื่องมือ +
+
+ +
+
+ +
+
+
+
+ + +
+
\ No newline at end of file diff --git a/src/app/pages/setting/promotion/presenter/list/list.component.scss b/src/app/pages/setting/promotion/presenter/list/list.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/setting/promotion/presenter/list/list.component.spec.ts b/src/app/pages/setting/promotion/presenter/list/list.component.spec.ts new file mode 100644 index 0000000..54ae348 --- /dev/null +++ b/src/app/pages/setting/promotion/presenter/list/list.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ListComponent } from './list.component'; + +describe('ListComponent', () => { + let component: ListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ListComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/setting/promotion/presenter/list/list.component.ts b/src/app/pages/setting/promotion/presenter/list/list.component.ts new file mode 100644 index 0000000..5f0c6bf --- /dev/null +++ b/src/app/pages/setting/promotion/presenter/list/list.component.ts @@ -0,0 +1,33 @@ +import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; +import { BaseList } from 'src/app/core/base/base-list'; + +@Component({ + selector: 'app-list', + templateUrl: './list.component.html', + styleUrls: ['./list.component.scss'] +}) +export class ListComponent extends BaseList implements OnChanges { + @Input() promotionList: any = []; + @Output() add = new EventEmitter(); + @Output() edit = new EventEmitter(); + @Output() delete = new EventEmitter(); + constructor() { + super() + } + + ngOnChanges(){ + this.promotionList = this.updateMatTable(this.promotionList? this.promotionList : []) + } + + onAdd(){ + this.add.emit() + } + + onEdit(uid: string){ + this.edit.emit(uid) + } + + onDelete(uid){ + this.delete.emit(uid) + } +} diff --git a/src/app/pages/setting/promotion/promotion.module.ts b/src/app/pages/setting/promotion/promotion.module.ts new file mode 100644 index 0000000..02bbe16 --- /dev/null +++ b/src/app/pages/setting/promotion/promotion.module.ts @@ -0,0 +1,37 @@ +import { NgOptimizedImage } from "@angular/common"; +import { RouterModule, Routes } from "@angular/router"; +import { AppSharedModule } from "src/app/app.shared"; +import { NgModule } from "@angular/core"; +import { ListComponent } from "./presenter/list/list.component"; +import { PromotionRouter } from "./router/router"; +import { PromotionContainer } from "./container/promotion/promotion.container"; +import { DialogComponent } from './presenter/dialog/dialog.component'; + + +const routes: Routes = [ + { + path: '', + component: PromotionRouter, + children: [ + { + path: '', + component: PromotionContainer + } + ] + } +] + +@NgModule({ + declarations: [ + PromotionRouter, + PromotionContainer, + ListComponent, + DialogComponent + ], + imports: [ + AppSharedModule, + NgOptimizedImage, + RouterModule.forChild(routes) + ] +}) +export class PromotionModule { } diff --git a/src/app/pages/setting/promotion/router/router.ts b/src/app/pages/setting/promotion/router/router.ts new file mode 100644 index 0000000..f2edc60 --- /dev/null +++ b/src/app/pages/setting/promotion/router/router.ts @@ -0,0 +1,16 @@ +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-promotion-router', + template: '', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PromotionRouter implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} + diff --git a/src/styles/app.scss b/src/styles/app.scss index 3a11197..5d0c5e5 100644 --- a/src/styles/app.scss +++ b/src/styles/app.scss @@ -91,6 +91,10 @@ h3, h4 { margin: 0; } +mat-label{ + color: #3D8A8B +} + // -------------------------------------------------------------------------------- // material // --------------------------------------------------------------------------------