feat: fatura PDF, hizmet/yazılım atama dosya ekleri

- /print/invoices/[id] sayfası: A4 fatura yazdırma/PDF (AutoPrint + PrintActionBar)
- Fatura detayı header'ına PDF butonu eklendi (Yazdır yerine)
- Appwrite Storage: entity-attachments bucket (20MB, şifreli)
- Appwrite Tables: attachments collection (tenantId, entityType, entityId, fileId, name, size, mimeType)
- attachment-actions.ts: fetchAttachmentsAction, uploadAttachmentAction, deleteAttachmentAction
- AttachmentsPanel bileşeni: dosya yükleme/listeleme/silme, edit modunda görünür
- Hizmet ve yazılım atama form sheet'lerine AttachmentsPanel entegrasyonu
- /api/files/[attachmentId]: güvenli proxy indirme (tenant doğrulama + admin key ile Appwrite'a istek)
This commit is contained in:
kovakmedya
2026-05-07 20:22:17 +03:00
parent a0aec13b8c
commit 1299cd10ce
9 changed files with 695 additions and 4 deletions
@@ -2,7 +2,7 @@
import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { Loader2, Pencil, Printer, Trash2 } from "lucide-react";
import { FileDown, Loader2, Pencil, Trash2 } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
@@ -45,9 +45,13 @@ export function InvoiceHeaderActions({ invoice, customers }: Props) {
return (
<>
<div className="flex flex-wrap gap-2">
<Button variant="outline" size="sm" onClick={() => window.print()}>
<Printer className="size-3.5" />
Yazdır
<Button
variant="outline"
size="sm"
onClick={() => window.open(`/print/invoices/${invoice.id}`, "_blank")}
>
<FileDown className="size-3.5" />
PDF
</Button>
<Button variant="outline" size="sm" onClick={() => setEditOpen(true)}>
<Pencil className="size-3.5" />