UNPKG

@angay/pdf-upload

Version:

Angular library for uploading and handling PDF files

119 lines (113 loc) 14.6 kB
import * as i0 from '@angular/core'; import { Injectable, Component } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import * as i2 from '@angular/common'; import { CommonModule } from '@angular/common'; class PdfUploadService { constructor() { this.modalState = new BehaviorSubject({ isVisible: false }); this.modalState$ = this.modalState.asObservable(); } openModal() { return new Promise((resolve) => { this.modalState.next({ isVisible: true, resolve }); }); } closeModal(result = null) { const state = this.modalState.value; state.resolve?.(result); this.modalState.next({ isVisible: false }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PdfUploadService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PdfUploadService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PdfUploadService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); class PdfUploadComponent { constructor(cropperService) { this.cropperService = cropperService; this.isVisible = false; this.imageErr = ''; this.pdfFile = null; } ngOnInit() { // Subscribe to modal state updates this.cropperService.modalState$.subscribe((state) => { this.isVisible = state.isVisible; }); } fileChangeEvent(event) { const file = event.target.files?.[0]; if (file) { this.onFileSelect(file); } } onFileSelect(file) { if (file) { if (file.type !== 'application/pdf') { this.imageErr = 'Invalid file type. Please upload a PDF file.'; return; } if (file.size === 0) { this.imageErr = 'File is empty. Please upload a valid PDF file.'; return; } if (file.size > 2 * 1024 * 1024) { this.imageErr = 'File is too large. Please upload a PDF file smaller than 10MB.'; return; } this.imageErr = ''; this.pdfFile = file; } } previewPdf() { if (this.pdfFile) { const fileURL = URL.createObjectURL(this.pdfFile); window.open(fileURL, '_blank'); } } removePdf() { this.pdfFile = null; } onSavePdf() { this.cropperService.closeModal(this.pdfFile); this.pdfFile = null; } closeModal() { this.cropperService.closeModal(null); } onDragOver(event) { event.preventDefault(); } onDragLeave(event) { event.preventDefault(); } onDrop(event) { event.preventDefault(); if (event.dataTransfer?.files.length) { const file = event.dataTransfer.files[0]; this.onFileSelect(file); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PdfUploadComponent, deps: [{ token: PdfUploadService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: PdfUploadComponent, isStandalone: true, selector: "angay-pdf-modal", ngImport: i0, template: "<div class=\"modal fade\" tabindex=\"-1\" [class.show]=\"isVisible\" [style.display]=\"isVisible ? 'block' : 'none'\"\r\n role=\"dialog\">\r\n <div class=\"modal-dialog modal-lg\" role=\"document\">\r\n <div class=\"modal-content\">\r\n\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Upload PDF</h5>\r\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"closeModal()\"></button>\r\n </div>\r\n\r\n <div class=\"modal-body\">\r\n <!-- Upload Section -->\r\n @if(!pdfFile) {\r\n <div class=\"image-container cursor-pointer\">\r\n <input type=\"file\" #fileInput accept=\"application/pdf\" (change)=\"fileChangeEvent($event)\" hidden />\r\n <div class=\"upload-text\">\r\n <div class=\"upload-dropzone\" (dragover)=\"onDragOver($event)\" (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\">\r\n <p>Drag and drop the PDF here </p>\r\n <p>or</p>\r\n <i class=\"bi bi-file-earmark-pdf fs-2 text-danger\"></i>\r\n <p>Click to upload pdf</p>\r\n <button class=\"btn btn-sm btn-primary\" (click)=\"fileInput.click()\"><i\r\n class=\"bi bi-upload\"></i>Upload\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"pdf-upload-card\">\r\n <div class=\"pdf-icon\">\r\n <i class=\"bi bi-file-earmark-pdf-fill\"></i>\r\n </div>\r\n <div class=\"pdf-details\">\r\n <div class=\"file-name\">{{ pdfFile.name }}</div>\r\n <div class=\"file-meta\">{{ pdfFile.size | number }} bytes \u2022 PDF Document</div>\r\n\r\n <div class=\"file-status success\">\r\n <i class=\"bi bi-check-circle-fill\"></i> Uploaded successfully\r\n </div>\r\n </div>\r\n\r\n <div class=\"pdf-actions\">\r\n <button class=\"btn btn-sm btn-outline\" (click)=\"previewPdf()\"><i class=\"bi bi-eye\"></i></button>\r\n <button class=\"btn btn-sm btn-danger\" (click)=\"removePdf()\"><i class=\"bi bi-trash\"></i></button>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n <span class=\"p-3 text-center text-danger\">{{ imageErr }}</span>\r\n\r\n\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline\" (click)=\"closeModal()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-primary\" (click)=\"onSavePdf()\">Save</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Backdrop -->\r\n<div class=\"modal-backdrop fade\" [class.show]=\"isVisible\" *ngIf=\"isVisible\">\r\n</div>", styles: [".image-cropper-container{width:500px;height:400px;max-width:100%;margin:auto}.image-cropper-container img{width:100%;height:100%;object-fit:contain}.modal-dialog{max-width:800px;display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-body{overflow:auto}.image-container{margin:4rem;height:300px;border-radius:20px;border:2px dashed #d1d5db;display:flex;justify-content:center;align-items:center}.image-container:hover{border-color:var(--primary-color);background:#6b46c105}.modal-backdrop{-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background-color:#0006}.image-container{border:2px dashed #ccc;border-radius:8px;padding:2rem;text-align:center;transition:border-color .2s ease,background-color .2s ease}.image-container.dragging{border-color:var(--primary-color);background-color:#f0faff}.image-container .upload-text{color:#6b7280;font-weight:500}.pdf-upload-card{display:flex;align-items:center;gap:16px;padding:16px;background:#fff;border:1px solid #e5e7eb;border-radius:12px;box-shadow:0 2px 6px #0000000d;transition:all .3s ease}.pdf-upload-card:hover{border-color:#6366f1;box-shadow:0 4px 12px #6366f126}.pdf-upload-card .pdf-icon{font-size:40px;color:#ef4444;flex-shrink:0}.pdf-upload-card .pdf-details{flex:1}.pdf-upload-card .pdf-details .file-name{font-weight:600;font-size:15px;color:#111827}.pdf-upload-card .pdf-details .file-meta{font-size:13px;color:#6b7280;margin-bottom:4px}.pdf-upload-card .pdf-details .file-status{font-size:13px;display:flex;align-items:center;gap:6px}.pdf-upload-card .pdf-details .file-status.success{color:#16a34a}.pdf-upload-card .pdf-details .file-status.error{color:#dc2626}.pdf-upload-card .pdf-actions{display:flex;gap:8px}.pdf-upload-card .pdf-actions .btn{border-radius:8px;padding:4px 10px;font-size:13px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PdfUploadComponent, decorators: [{ type: Component, args: [{ selector: 'angay-pdf-modal', standalone: true, imports: [CommonModule], template: "<div class=\"modal fade\" tabindex=\"-1\" [class.show]=\"isVisible\" [style.display]=\"isVisible ? 'block' : 'none'\"\r\n role=\"dialog\">\r\n <div class=\"modal-dialog modal-lg\" role=\"document\">\r\n <div class=\"modal-content\">\r\n\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Upload PDF</h5>\r\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"closeModal()\"></button>\r\n </div>\r\n\r\n <div class=\"modal-body\">\r\n <!-- Upload Section -->\r\n @if(!pdfFile) {\r\n <div class=\"image-container cursor-pointer\">\r\n <input type=\"file\" #fileInput accept=\"application/pdf\" (change)=\"fileChangeEvent($event)\" hidden />\r\n <div class=\"upload-text\">\r\n <div class=\"upload-dropzone\" (dragover)=\"onDragOver($event)\" (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\">\r\n <p>Drag and drop the PDF here </p>\r\n <p>or</p>\r\n <i class=\"bi bi-file-earmark-pdf fs-2 text-danger\"></i>\r\n <p>Click to upload pdf</p>\r\n <button class=\"btn btn-sm btn-primary\" (click)=\"fileInput.click()\"><i\r\n class=\"bi bi-upload\"></i>Upload\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"pdf-upload-card\">\r\n <div class=\"pdf-icon\">\r\n <i class=\"bi bi-file-earmark-pdf-fill\"></i>\r\n </div>\r\n <div class=\"pdf-details\">\r\n <div class=\"file-name\">{{ pdfFile.name }}</div>\r\n <div class=\"file-meta\">{{ pdfFile.size | number }} bytes \u2022 PDF Document</div>\r\n\r\n <div class=\"file-status success\">\r\n <i class=\"bi bi-check-circle-fill\"></i> Uploaded successfully\r\n </div>\r\n </div>\r\n\r\n <div class=\"pdf-actions\">\r\n <button class=\"btn btn-sm btn-outline\" (click)=\"previewPdf()\"><i class=\"bi bi-eye\"></i></button>\r\n <button class=\"btn btn-sm btn-danger\" (click)=\"removePdf()\"><i class=\"bi bi-trash\"></i></button>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n <span class=\"p-3 text-center text-danger\">{{ imageErr }}</span>\r\n\r\n\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline\" (click)=\"closeModal()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-primary\" (click)=\"onSavePdf()\">Save</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Backdrop -->\r\n<div class=\"modal-backdrop fade\" [class.show]=\"isVisible\" *ngIf=\"isVisible\">\r\n</div>", styles: [".image-cropper-container{width:500px;height:400px;max-width:100%;margin:auto}.image-cropper-container img{width:100%;height:100%;object-fit:contain}.modal-dialog{max-width:800px;display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-body{overflow:auto}.image-container{margin:4rem;height:300px;border-radius:20px;border:2px dashed #d1d5db;display:flex;justify-content:center;align-items:center}.image-container:hover{border-color:var(--primary-color);background:#6b46c105}.modal-backdrop{-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background-color:#0006}.image-container{border:2px dashed #ccc;border-radius:8px;padding:2rem;text-align:center;transition:border-color .2s ease,background-color .2s ease}.image-container.dragging{border-color:var(--primary-color);background-color:#f0faff}.image-container .upload-text{color:#6b7280;font-weight:500}.pdf-upload-card{display:flex;align-items:center;gap:16px;padding:16px;background:#fff;border:1px solid #e5e7eb;border-radius:12px;box-shadow:0 2px 6px #0000000d;transition:all .3s ease}.pdf-upload-card:hover{border-color:#6366f1;box-shadow:0 4px 12px #6366f126}.pdf-upload-card .pdf-icon{font-size:40px;color:#ef4444;flex-shrink:0}.pdf-upload-card .pdf-details{flex:1}.pdf-upload-card .pdf-details .file-name{font-weight:600;font-size:15px;color:#111827}.pdf-upload-card .pdf-details .file-meta{font-size:13px;color:#6b7280;margin-bottom:4px}.pdf-upload-card .pdf-details .file-status{font-size:13px;display:flex;align-items:center;gap:6px}.pdf-upload-card .pdf-details .file-status.success{color:#16a34a}.pdf-upload-card .pdf-details .file-status.error{color:#dc2626}.pdf-upload-card .pdf-actions{display:flex;gap:8px}.pdf-upload-card .pdf-actions .btn{border-radius:8px;padding:4px 10px;font-size:13px}\n"] }] }], ctorParameters: () => [{ type: PdfUploadService }] }); /* * Public API Surface of pdf-upload */ /** * Generated bundle index. Do not edit. */ export { PdfUploadComponent, PdfUploadService }; //# sourceMappingURL=angay-pdf-upload.mjs.map