Commit 5eacc6c2 by Natthaphat

เพิ่ม เมนู รายการเอกสารรอการอนุมัติ ของ myPortal

parent 8797a543
......@@ -128,6 +128,31 @@ export const admin: Routes = [
loadComponent: () =>
import('./myportal/set-excel-reports/excel-report-toggle/excel-report-toggle.component').then((m) => m.ExcelReportToggleComponent),
},
{
path: 'management',
loadComponent: () =>
import('./myportal/management/management.component').then((m) => m.ManagementComponent),
},
{
path: 'portal-category-list-approve',
loadComponent: () =>
import('./myportal/management/portal-category-list-approve/portal-category-list-approve.component').then((m) => m.PortalCategoryListApproveComponent),
},
{
path: 'approve-excel',
loadComponent: () =>
import('./myportal/management/portal-category-list-approve/approve-excel/approve-excel.component').then((m) => m.ApproveExcelComponent),
},
{
path: 'approve-doc',
loadComponent: () =>
import('./myportal/management/portal-category-list-approve/approve-doc/approve-doc.component').then((m) => m.ApproveDocComponent),
},
{
path: 'approve-course',
loadComponent: () =>
import('./myportal/management/portal-category-list-approve/approve-course/approve-course.component').then((m) => m.ApproveCourseComponent),
},
//////////////emp/////////////////
{
path: 'emp/department',
......
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ManagementComponent } from './management.component';
describe('ManagementComponent', () => {
let component: ManagementComponent;
let fixture: ComponentFixture<ManagementComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ManagementComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ManagementComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-management',
templateUrl: './management.component.html',
styleUrls: ['./management.component.css']
})
export class ManagementComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
import { Component, OnInit } from '@angular/core';
import { NgbModal, NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';
import { CourseModel } from '../../../../../models/course.model';
import { CourseService } from '../../../../../services/course.service';
import { OpenImageComponent } from '../../../open-image/open-image.component';
import { ConfirmModalComponent } from '../../../confirm-modal/confirm-modal.component';
import { AlertModalComponent } from '../../../alert-modal/alert-modal.component';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { NgSelectModule } from '@ng-select/ng-select';
import { SharedModule } from '../../../../../../shared/shared.module';
import { MatDialogModule } from '@angular/material/dialog';
import { TranslateModule } from '@ngx-translate/core';
import { firstValueFrom } from 'rxjs';
declare var require: any
import FileSaver from 'file-saver';
@Component({
selector: 'app-approve-course',
templateUrl: './approve-course.component.html',
styleUrls: ['./approve-course.component.scss'],
standalone: true,
imports: [
CommonModule,
FormsModule,
RouterModule,
NgSelectModule,
SharedModule,
MatDialogModule,
TranslateModule,
NgbPaginationModule,
],
})
export class ApproveCourseComponent implements OnInit {
page = 0;
pageSize = 10;
listCourse: CourseModel[] = []
search: string = ''
pagedItems: CourseModel[] = [];
pageIndex: number = 0;
itemsPerPage: number = 10;
constructor(private modalService: NgbModal, private courseService: CourseService) {
}
get totalItems(): number {
return this.search == ''
? this.listCourse.length
: this.filterListCourse().length;
}
get totalPages(): number {
return Math.ceil(this.totalItems / this.itemsPerPage);
}
get totalPagesArray(): number[] {
return Array(this.totalPages).fill(0);
}
goToPage(index: number): void {
if (index < 0 || index >= this.totalPages) return;
this.pageIndex = index;
this.updatePagedItems();
}
updatePagedItems() {
const data: CourseModel[] = this.search === '' ? this.listCourse : this.filterListCourse();
const start = this.pageIndex * this.itemsPerPage;
const end = start + this.itemsPerPage;
this.pagedItems = data.slice(start, end);
}
openEmployeeModal(image: string) {
const modalRef = this.modalService.open(OpenImageComponent, {
centered: true,
windowClass: 'my-dialog-img-preview'
})
modalRef.componentInstance.linkImage = image
modalRef.result.then(result => {
}, reason => {
this.modalService.dismissAll()
})
}
async downloadFile(logId: string) {
try {
const data = await this.courseService.downloadFile(logId).toPromise();
if (data) {
FileSaver.saveAs(new Blob([data]), "file_download.json");
}
} catch (error) {
console.error('Error loading data:', error);
}
}
filterListCourse() {
return this.listCourse.filter(x => x.thName.toLowerCase().includes(this.search.toLowerCase()) || x.engName.toLowerCase().includes(this.search.toLowerCase()))
}
async getListCourse() {
try {
const data = await firstValueFrom(this.courseService.getListCourse('0'));
this.listCourse = data.map(x => new CourseModel(x))
} catch (error) {
console.error('Error loading data:', error);
}
}
onApprove(item: CourseModel) {
const modalRef = this.modalService.open(ConfirmModalComponent, {
centered: true,
backdrop: 'static',
})
modalRef.componentInstance.message = 'คุณต้องการอนุมัติข้อมูลหรือไม่'
modalRef.result.then(result => {
item.status = 1
this.courseService.approve(item).subscribe(result => {
if (result) {
this.modalService.dismissAll()
this.openAlertModal('บันทึกข้อมูลสำเร็จ')
this.getListCourse();
} else {
this.openAlertModal('ไม่สามารถบันทึกข้อมูลได้')
}
}, error => {
this.openAlertModal(error.message)
})
}, reject => { })
}
onCancelApprove(item: CourseModel) {
const modalRef = this.modalService.open(ConfirmModalComponent, {
centered: true,
backdrop: 'static',
})
modalRef.componentInstance.message = 'คุณต้องการไม่อนุมัติข้อมูลหรือไม่'
modalRef.result.then(result => {
item.status = 2
this.courseService.approve(item).subscribe(result => {
if (result) {
this.openAlertModal('บันทึกข้อมูลสำเร็จ')
this.getListCourse();
} else {
this.openAlertModal('ไม่สามารถบันทึกข้อมูลได้')
}
}, error => {
this.openAlertModal(error.message)
})
}, reject => { })
}
ngOnInit() {
this.getListCourse();
}
deleteFile(item: CourseModel) {
const modalRef = this.modalService.open(ConfirmModalComponent, {
centered: true,
backdrop: 'static',
})
modalRef.componentInstance.message = 'คุณต้องการลบข้อมูลหรือไม่'
modalRef.result.then(result => {
this.courseService.deleteCourse(item).subscribe(result => {
if (result) {
this.openAlertModal('ลบข้อมูลสำเร็จ')
this.getListCourse();
} else {
this.openAlertModal('ไม่สามารถลบข้อมูลได้')
}
}, error => {
this.openAlertModal(error.message)
})
}, reject => { })
}
openAlertModal(message?: string) {
const modalRef = this.modalService.open(AlertModalComponent, {
centered: true,
backdrop: 'static'
})
modalRef.componentInstance.message = message ? message : ""
modalRef.result.then(result => {
// this.modalService.dismissAll()
}, reason => {
// this.modalService.dismissAll()
})
}
openLink(url: string) {
window.open(url, "_blank");
}
}
import { Component, OnInit } from '@angular/core';
import { NgbModal, NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';
import { OpenImageComponent } from '../../../open-image/open-image.component';
import { ConfirmModalComponent } from '../../../confirm-modal/confirm-modal.component';
import { AlertModalComponent } from '../../../alert-modal/alert-modal.component';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { NgSelectModule } from '@ng-select/ng-select';
import { SharedModule } from '../../../../../../shared/shared.module';
import { MatDialogModule } from '@angular/material/dialog';
import { TranslateModule } from '@ngx-translate/core';
import { DocumentModel } from '../../../../../models/document.model';
import { DocumentService } from '../../../../../services/document.service';
import { firstValueFrom } from 'rxjs';
declare var require: any
import FileSaver from 'file-saver';
@Component({
selector: 'app-approve-doc',
templateUrl: './approve-doc.component.html',
styleUrls: ['./approve-doc.component.scss'],
standalone: true,
imports: [
CommonModule,
FormsModule,
RouterModule,
NgSelectModule,
SharedModule,
MatDialogModule,
TranslateModule,
NgbPaginationModule,
],
})
export class ApproveDocComponent implements OnInit {
page = 0;
pageSize = 10;
listDoc: DocumentModel[] = []
search: string = ''
pagedItems: DocumentModel[] = [];
pageIndex: number = 0;
itemsPerPage: number = 10;
constructor(private modalService: NgbModal, private documentService: DocumentService) {
}
get totalItems(): number {
return this.search == ''
? this.listDoc.length
: this.filterListDoc().length;
}
get totalPages(): number {
return Math.ceil(this.totalItems / this.itemsPerPage);
}
get totalPagesArray(): number[] {
return Array(this.totalPages).fill(0);
}
goToPage(index: number): void {
if (index < 0 || index >= this.totalPages) return;
this.pageIndex = index;
this.updatePagedItems();
}
updatePagedItems() {
const data: DocumentModel[] = this.search === '' ? this.listDoc : this.filterListDoc();
const start = this.pageIndex * this.itemsPerPage;
const end = start + this.itemsPerPage;
this.pagedItems = data.slice(start, end);
}
openEmployeeModal(image: string) {
const modalRef = this.modalService.open(OpenImageComponent, {
centered: true,
windowClass: 'my-dialog-img-preview'
})
modalRef.componentInstance.linkImage = image
modalRef.result.then(result => {
}, reason => {
this.modalService.dismissAll()
})
}
async downloadFile(logId: string, lang: string) {
try {
const data = await this.documentService.downloadFile(logId, lang).toPromise();
if (data) {
FileSaver.saveAs(new Blob([data]), "file_download.doc");
}
} catch (error) {
console.error('Error loading data:', error);
}
}
openLink(url: string) {
window.open(url, "_blank");
}
filterListDoc() {
return this.listDoc.filter(x => x.thName.toLowerCase().includes(this.search.toLowerCase()) || x.engName.toLowerCase().includes(this.search.toLowerCase()))
}
async getListDoc() {
try {
const data = await firstValueFrom(this.documentService.getListDoc('0'));
this.listDoc = data.map(x => new DocumentModel(x))
} catch (error) {
console.error('Error loading data:', error);
}
}
onApprove(item: DocumentModel) {
const modalRef = this.modalService.open(ConfirmModalComponent, {
centered: true,
backdrop: 'static',
})
modalRef.componentInstance.message = 'คุณต้องการอนุมัติข้อมูลหรือไม่'
modalRef.result.then(result => {
item.status = 1
this.documentService.approve(item).subscribe(result => {
if (result) {
this.modalService.dismissAll()
this.openAlertModal('บันทึกข้อมูลสำเร็จ')
this.getListDoc();
} else {
this.openAlertModal('ไม่สามารถบันทึกข้อมูลได้')
}
}, error => {
this.openAlertModal(error.message)
})
}, reject => { })
}
onCancelApprove(item: DocumentModel) {
const modalRef = this.modalService.open(ConfirmModalComponent, {
centered: true,
backdrop: 'static',
})
modalRef.componentInstance.message = 'คุณต้องการไม่อนุมัติข้อมูลหรือไม่'
modalRef.result.then(result => {
item.status = 2
this.documentService.approve(item).subscribe(result => {
if (result) {
this.openAlertModal('บันทึกข้อมูลสำเร็จ')
this.getListDoc();
} else {
this.openAlertModal('ไม่สามารถบันทึกข้อมูลได้')
}
}, error => {
this.openAlertModal(error.message)
})
}, reject => { })
}
ngOnInit() {
this.getListDoc();
}
deleteFile(item: DocumentModel) {
const modalRef = this.modalService.open(ConfirmModalComponent, {
centered: true,
backdrop: 'static',
})
modalRef.componentInstance.message = 'คุณต้องการลบข้อมูลหรือไม่'
modalRef.result.then(result => {
this.documentService.deleteExcel(item).subscribe(result => {
if (result) {
this.openAlertModal('ลบข้อมูลสำเร็จ')
this.getListDoc();
} else {
this.openAlertModal('ไม่สามารถลบข้อมูลได้')
}
}, error => {
this.openAlertModal(error.message)
})
}, reject => { })
}
openAlertModal(message?: string) {
const modalRef = this.modalService.open(AlertModalComponent, {
centered: true,
backdrop: 'static'
})
modalRef.componentInstance.message = message ? message : ""
modalRef.result.then(result => {
// this.modalService.dismissAll()
}, reason => {
// this.modalService.dismissAll()
})
}
}
import { Component, OnInit } from '@angular/core';
import { NgbModal, NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';
import { OpenImageComponent } from '../../../open-image/open-image.component';
import { ConfirmModalComponent } from '../../../confirm-modal/confirm-modal.component';
import { AlertModalComponent } from '../../../alert-modal/alert-modal.component';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { NgSelectModule } from '@ng-select/ng-select';
import { SharedModule } from '../../../../../../shared/shared.module';
import { MatDialogModule } from '@angular/material/dialog';
import { TranslateModule } from '@ngx-translate/core';
import { ExcelModel } from '../../../../../models/excel.model';
import { ExcelService } from '../../../../../services/excel.service';
import { firstValueFrom } from 'rxjs';
declare var require: any
import FileSaver from 'file-saver';
import { TemplateModel } from '../../../../../models/template.model';
@Component({
selector: 'app-approve-excel',
templateUrl: './approve-excel.component.html',
styleUrls: ['./approve-excel.component.scss'],
standalone: true,
imports: [
CommonModule,
FormsModule,
RouterModule,
NgSelectModule,
SharedModule,
MatDialogModule,
TranslateModule,
NgbPaginationModule,
],
})
export class ApproveExcelComponent implements OnInit {
page = 0;
pageSize = 10;
listExcel: ExcelModel[] = []
search: string = ''
pagedItems: ExcelModel[] = [];
pageIndex: number = 0;
itemsPerPage: number = 10;
constructor(private modalService: NgbModal, private excelService: ExcelService) {
}
get totalItems(): number {
return this.search == ''
? this.listExcel.length
: this.filterListExcel().length;
}
get totalPages(): number {
return Math.ceil(this.totalItems / this.itemsPerPage);
}
get totalPagesArray(): number[] {
return Array(this.totalPages).fill(0);
}
goToPage(index: number): void {
if (index < 0 || index >= this.totalPages) return;
this.pageIndex = index;
this.updatePagedItems();
}
updatePagedItems() {
const data: ExcelModel[] = this.search === '' ? this.listExcel : this.filterListExcel();
const start = this.pageIndex * this.itemsPerPage;
const end = start + this.itemsPerPage;
this.pagedItems = data.slice(start, end);
}
openEmployeeModal(image: string) {
const modalRef = this.modalService.open(OpenImageComponent, {
centered: true,
windowClass: 'my-dialog-img-preview'
})
modalRef.componentInstance.linkImage = image
modalRef.result.then(result => {
}, reason => {
this.modalService.dismissAll()
})
}
async downloadFile(logId: string) {
try {
const data = await this.excelService.downloadFile(logId).toPromise();
if (data) {
FileSaver.saveAs(new Blob([data]), "file_download.xlsx");
}
} catch (error) {
console.error('Error loading data:', error);
}
}
filterListExcel() {
return this.listExcel.filter(x => x.thName.toLowerCase().includes(this.search.toLowerCase()) || x.engName.toLowerCase().includes(this.search.toLowerCase()))
}
async getListExcel() {
try {
const data = await firstValueFrom(this.excelService.getListExcel('0'));
this.listExcel = data.map(x => new ExcelModel(x));
} catch (error) {
console.error('Error loading data:', error);
this.listExcel = [];
}
}
onApprove(item: ExcelModel) {
const modalRef = this.modalService.open(ConfirmModalComponent, {
centered: true,
backdrop: 'static',
})
modalRef.componentInstance.message = 'คุณต้องการอนุมัติข้อมูลหรือไม่'
modalRef.result.then(result => {
item.status = 1
this.excelService.approve(item).subscribe(result => {
if (result) {
this.openAlertModal('บันทึกข้อมูลสำเร็จ')
this.getListExcel();
} else {
this.openAlertModal('ไม่สามารถบันทึกข้อมูลได้')
}
}, error => {
this.openAlertModal(error.message)
})
}, reject => { })
}
onCancelApprove(item: ExcelModel) {
const modalRef = this.modalService.open(ConfirmModalComponent, {
centered: true,
backdrop: 'static',
})
modalRef.componentInstance.message = 'คุณต้องการไม่อนุมัติข้อมูลหรือไม่'
modalRef.result.then(result => {
item.status = 2
this.excelService.approve(item).subscribe(result => {
if (result) {
this.modalService.dismissAll()
this.openAlertModal('บันทึกข้อมูลสำเร็จ')
this.getListExcel();
} else {
this.openAlertModal('ไม่สามารถบันทึกข้อมูลได้')
}
}, error => {
this.openAlertModal(error.message)
})
}, reject => { })
}
ngOnInit() {
this.getListExcel();
}
deleteFile(item: ExcelModel) {
const modalRef = this.modalService.open(ConfirmModalComponent, {
centered: true,
backdrop: 'static',
})
modalRef.componentInstance.message = 'คุณต้องการลบข้อมูลหรือไม่'
modalRef.result.then(result => {
this.excelService.deleteExcel(item).subscribe(result => {
if (result) {
this.openAlertModal('ลบข้อมูลสำเร็จ')
this.getListExcel();
} else {
this.openAlertModal('ไม่สามารถลบข้อมูลได้')
}
}, error => {
this.openAlertModal(error.message)
})
}, reject => { })
}
openAlertModal(message?: string) {
const modalRef = this.modalService.open(AlertModalComponent, {
centered: true,
backdrop: 'static'
})
modalRef.componentInstance.message = message ? message : ""
modalRef.result.then(result => {
// this.modalService.dismissAll()
}, reason => {
// this.modalService.dismissAll()
})
}
openLink(url: string) {
window.open(url, "_blank");
}
}
<app-page-header [title]="'รายการเอกสารรอการอนุมัติ'" [activeTitle]="'ผู้ดูแลระบบ'" [title1]="'รายการเอกสารรอการอนุมัติ'"></app-page-header>
<!-- <div class="row">
<div class="col-12">
<div class="card card-body">
<h4 class="card-title">รายการเอกสารรอการอนุมัติ</h4>
<div class="row justify-content-center">
<div class="col-md-4 " *ngFor="let c of testdata|slice: (page-1) * pageSize : (page-1) * pageSize + pageSize">
<div class="card border border-2">
<div class="card-body text-center">
<img src="{{ c.img }}" class="rounded-circle border p-1" width="100">
<h3 class="card-title mt-3 mb-0">{{c.name}}</h3>
</div>
<div class="d-flex justify-content-between bg-light border-top p-3">
<div>
<span class="align-middle">จำนวนเอกสาร {{ c.document }} ฉบับ</span>
</div>
<div >
<button class="btn btn-info btn-sm text-nowrap" (click)="openView(c.id)">รายละเอียด</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> -->
<div class="max-w-7xl mx-auto">
<div class="box p-4">
<h4 class="text-xl font-semibold text-gray-800 mb-6">รายการเอกสารรอการอนุมัติ</h4>
<!-- Flex แทน Grid -->
<div class="flex flex-wrap justify-center gap-6">
<div
class=" bg-white rounded-xl shadow-lg overflow-hidden transform hover:scale-105 transition duration-300 ease-in-out flex flex-col" style="width: 30%;"
*ngFor="let c of testdata | slice: (page-1) * pageSize : (page-1) * pageSize + pageSize"
>
<div class="p-8 text-center">
<div class="w-24 h-24 mx-auto rounded-full bg-green-100 flex items-center justify-center shadow-inner">
<img src="{{ c.img }}" class="" alt="" />
</div>
<h3 class="text-2xl font-bold text-gray-800 mt-6 mb-2">{{ c.name }}</h3>
</div>
<!-- Footer -->
<div class="mt-auto">
<div class="flex justify-between items-center bg-gray-50 border-t border-gray-200 p-4">
<div>
<span class="text-sm text-gray-700">จำนวนเอกสาร {{ c.document }} ฉบับ</span>
</div>
<div>
<button
class="bg-primary inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-md shadow-md transition duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"
(click)="openView(c.id)"
>
รายละเอียด
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { Component, OnInit } from "@angular/core";
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
import { FormBuilder, FormGroup, FormsModule, Validators } from "@angular/forms";
import { Router, RouterModule } from "@angular/router";
import { ExcelService } from "../../../../services/excel.service";
import { DocumentService } from "../../../../services/document.service";
import { CourseService } from "../../../../services/course.service";
import { CommonModule } from "@angular/common";
import { TranslateModule } from "@ngx-translate/core";
import { SharedModule } from "../../../../../shared/shared.module";
@Component({
selector: "app-portal-category-list-approve",
templateUrl: "./portal-category-list-approve.component.html",
styleUrls: ["./portal-category-list-approve.component.scss"],
standalone: true,
imports: [
CommonModule,
FormsModule,
RouterModule,
TranslateModule,
SharedModule,
],
})
export class PortalCategoryListApproveComponent implements OnInit {
constructor(
private modalService: NgbModal,
private router: Router,
private excelService: ExcelService, private documentService: DocumentService, private courseService: CourseService
) { }
page = 1;
pageSize = 7;
testdata: {
id: string
img: String;
name: String;
details: String;
document: String;
}[] = [];
ngOnInit() {
this.testdata = [
{
id: '1',
img: "assets/images/icons/excel.png",
name: "Excel",
details: "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
document: "0"
},
{
id: '2',
img: "assets/images/icons/document.png",
name: "Document",
details: "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
document: "0"
},
{
id: '3',
img: "assets/images/icons/course.png",
name: "Course",
details: "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
document: "0"
},
];
this.getListCount();
}
openView(id: string) {
if (id == '1') {
this.router.navigate(['/admin/approve-excel']);
} else if (id == '2') {
this.router.navigate(['/admin/approve-doc']);
} else if (id == '3') {
this.router.navigate(['/admin/approve-course']);
}
}
async getListCount() {
try {
const countExcel = await this.excelService.getCount().toPromise();
const countDoc = await this.documentService.getCount().toPromise();
const countCourse = await this.courseService.getCount().toPromise();
this.testdata.forEach((x, i) => {
if (i == 0) {
x.document = (countExcel ?? 0).toString();
} else if (i == 1) {
x.document = (countDoc ?? 0).toString();
} else if (i == 2) {
x.document = (countCourse ?? 0).toString();
}
});
} catch (error) {
console.error('Error loading data:', error);
}
}
openModal(targetModal: NgbModal) {
this.modalService.open(targetModal, {
centered: true,
backdrop: "static",
});
}
closeBtnClick() {
this.modalService.dismissAll();
}
routerLink(path: String, type: String) {
this.router.navigate([path, { type: type }])
}
}
......@@ -27,30 +27,39 @@
<div class="max-w-7xl mx-auto">
<div class="box p-4">
<h4 class="text-xl font-semibold text-gray-800 mb-6">รายการเอกสาร</h4>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
<div class="bg-white rounded-xl shadow-lg overflow-hidden transform hover:scale-105 transition duration-300 ease-in-out"
*ngFor="let c of testdata|slice: (page-1) * pageSize : (page-1) * pageSize + pageSize">
<!-- Flex แทน Grid -->
<div class="flex flex-wrap justify-center gap-6">
<div
class=" bg-white rounded-xl shadow-lg overflow-hidden transform hover:scale-105 transition duration-300 ease-in-out flex flex-col" style="width: 30%;"
*ngFor="let c of testdata | slice: (page-1) * pageSize : (page-1) * pageSize + pageSize"
>
<div class="p-8 text-center">
<div class="w-24 h-24 mx-auto rounded-full bg-green-100 flex items-center justify-center shadow-inner">
<img src="{{ c.img }}" class="" alt="">
<img src="{{ c.img }}" class="" alt="" />
</div>
<h3 class="text-2xl font-bold text-gray-800 mt-6 mb-2">{{c.name}}</h3>
<h3 class="text-2xl font-bold text-gray-800 mt-6 mb-2">{{ c.name }}</h3>
</div>
<div class="flex justify-between items-center bg-gray-50 border-t border-gray-200 p-4">
<div>
<span class="text-sm text-gray-700">จำนวนเอกสาร {{ c.document }} ฉบับ</span>
</div>
<div>
<button
class="bg-primary inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-md shadow-md transition duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"
(click)="openView(c.id)">
รายละเอียด
</button>
<!-- Footer -->
<div class="mt-auto">
<div class="flex justify-between items-center bg-gray-50 border-t border-gray-200 p-4">
<div>
<span class="text-sm text-gray-700">จำนวนเอกสาร {{ c.document }} ฉบับ</span>
</div>
<div>
<button
class="bg-primary inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-md shadow-md transition duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"
(click)="openView(c.id)"
>
รายละเอียด
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
</div>
......@@ -140,6 +140,16 @@ export class NavService implements OnDestroy {
},
{
icon: 'user',
path: '/admin/management',
title: 'การจัดการ',
type: 'sub',
children: [
{ path: '/admin/portal-category-list-approve', title: 'รายการรอการอนุมัติ', type: 'link' },
{ path: '/admin/approved-list', title: 'รายการผ่านการอนุมัติ', type: 'link' }
],
},
{
icon: 'user',
path: '/admin/set-excel-reports',
title: 'ตั้งรายงานเอ็กเซล',
type: 'sub',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment