- Added a file input for PDF uploads with validation for file type and size. - Implemented file size formatting and user feedback for selected files. - Created upload and cancel methods with placeholder for future API integration. feat: Create PaymentForm.vue for handling payments - Developed a form for entering payment details including date, amount, method, and notes. - Integrated currency formatting and dropdown for payment methods. - Implemented save and cancel actions with API call for saving payment data. docs: Add documentation for dynamic plugin menus and permissions - Provided guidelines for defining menu items and permissions in plugins. - Explained the process for synchronizing permissions and integrating menus in the frontend. - Included examples and best practices for plugin development. feat: Add database migrations for invoices, invoice items, and payments - Created migration scripts to define the database schema for invoices, invoice items, and payments. - Established foreign key relationships between invoices and related entities. feat: Implement command for synchronizing plugin permissions - Developed a console command to synchronize plugin permissions with the database. - Added options for dry-run and force synchronization for unlicensed modules. feat: Create API controller for plugin menu items - Implemented API endpoints to retrieve plugin menu items in both flat and grouped formats. - Ensured access control with role-based permissions for API access. feat: Develop service for managing plugin menu items - Created a service to collect and manage menu items from installed plugins. - Implemented methods for retrieving flat and grouped menu items for frontend use. feat: Add service for synchronizing plugin permissions - Developed a service to handle the synchronization of plugin permissions with the database. - Included logic for creating and updating permission modules based on plugin definitions.
103 lines
2.8 KiB
Vue
103 lines
2.8 KiB
Vue
<template>
|
|
<div class="pdf-upload-form">
|
|
<Message severity="info">
|
|
PDF-Upload Funktionalität (Phase 1 MVP - wird in späteren Phasen implementiert)
|
|
</Message>
|
|
|
|
<div class="grid p-fluid mt-3">
|
|
<div class="col-12">
|
|
<p>
|
|
<strong>Rechnung:</strong> {{ invoice?.invoiceNumber }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- File Upload -->
|
|
<div class="col-12">
|
|
<label for="pdfFile">PDF-Datei hochladen</label>
|
|
<input
|
|
id="pdfFile"
|
|
type="file"
|
|
accept="application/pdf"
|
|
@change="handleFileChange"
|
|
class="p-inputtext p-component"
|
|
/>
|
|
<small class="text-muted">Nur PDF-Dateien erlaubt (max. 10 MB)</small>
|
|
</div>
|
|
|
|
<div class="col-12" v-if="selectedFile">
|
|
<Message severity="success">
|
|
Datei ausgewählt: {{ selectedFile.name }} ({{ formatFileSize(selectedFile.size) }})
|
|
</Message>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="flex gap-2 mt-4">
|
|
<Button label="Hochladen" icon="pi pi-upload" @click="upload" :disabled="!selectedFile" />
|
|
<Button label="Abbrechen" icon="pi pi-times" severity="secondary" text @click="cancel" />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from 'vue'
|
|
import Button from 'primevue/button'
|
|
import Message from 'primevue/message'
|
|
|
|
const props = defineProps({
|
|
invoice: Object
|
|
})
|
|
|
|
const emit = defineEmits(['save', 'cancel'])
|
|
|
|
const selectedFile = ref(null)
|
|
|
|
const handleFileChange = (event) => {
|
|
const file = event.target.files[0]
|
|
if (file && file.type === 'application/pdf') {
|
|
selectedFile.value = file
|
|
} else {
|
|
alert('Bitte wählen Sie eine PDF-Datei aus.')
|
|
event.target.value = ''
|
|
}
|
|
}
|
|
|
|
const formatFileSize = (bytes) => {
|
|
if (bytes < 1024) return bytes + ' B'
|
|
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB'
|
|
return (bytes / (1024 * 1024)).toFixed(2) + ' MB'
|
|
}
|
|
|
|
const upload = async () => {
|
|
if (!selectedFile.value) return
|
|
|
|
const formData = new FormData()
|
|
formData.append('pdf', selectedFile.value)
|
|
formData.append('invoiceId', props.invoice.id)
|
|
|
|
// TODO: Implement upload endpoint
|
|
// await fetch('/api/invoices/upload-pdf', {
|
|
// method: 'POST',
|
|
// body: formData
|
|
// })
|
|
|
|
alert('PDF-Upload wird in Phase 2 implementiert. Für Phase 1 MVP können Sie den Pfad manuell in der Datenbank setzen.')
|
|
|
|
emit('save')
|
|
}
|
|
|
|
const cancel = () => {
|
|
emit('cancel')
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.pdf-upload-form {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.text-muted {
|
|
color: var(--text-color-secondary);
|
|
}
|
|
</style>
|