@angay/pdf-upload
Version:
Angular library for uploading and handling PDF files
119 lines (113 loc) • 14.6 kB
JavaScript
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