diff --git a/src/app/api/templates/[templateId]/route.js b/src/app/api/templates/[templateId]/route.js index 4489249..c42ffc1 100644 --- a/src/app/api/templates/[templateId]/route.js +++ b/src/app/api/templates/[templateId]/route.js @@ -1,8 +1,116 @@ import { NextRequest, NextResponse } from "next/server"; import { unlink } from "fs/promises"; +import fs from "fs"; import path from "path"; import db from "@/lib/db"; +export async function PUT(request, { params }) { + try { + const { templateId } = params; + const formData = await request.formData(); + + const templateName = formData.get("templateName")?.toString().trim(); + const description = formData.get("description")?.toString().trim(); + const file = formData.get("file"); + + if (!templateName) { + return NextResponse.json( + { error: "Template name is required" }, + { status: 400 } + ); + } + + // Check if template exists + const existingTemplate = db.prepare(` + SELECT * FROM docx_templates WHERE template_id = ? AND is_active = 1 + `).get(templateId); + + if (!existingTemplate) { + return NextResponse.json( + { error: "Template not found" }, + { status: 404 } + ); + } + + let updateData = { + template_name: templateName, + description: description || null, + updated_at: new Date().toISOString() + }; + + // If a new file is provided, handle file replacement + if (file && file.size > 0) { + // Validate file type + if (!file.name.toLowerCase().endsWith('.docx')) { + return NextResponse.json( + { error: "Only .docx files are allowed" }, + { status: 400 } + ); + } + + // Validate file size (10MB limit) + if (file.size > 10 * 1024 * 1024) { + return NextResponse.json( + { error: "File size must be less than 10MB" }, + { status: 400 } + ); + } + + // Delete old file + try { + const oldFilePath = path.join(process.cwd(), "public", existingTemplate.file_path); + await unlink(oldFilePath); + } catch (fileError) { + console.warn("Could not delete old template file:", fileError); + } + + // Save new file + const fileExtension = path.extname(file.name); + const fileName = `${Date.now()}-${Math.random().toString(36).substring(2)}${fileExtension}`; + const filePath = path.join(process.cwd(), "public", "templates", fileName); + + // Ensure templates directory exists + const templatesDir = path.join(process.cwd(), "public", "templates"); + try { + await fs.promises.access(templatesDir); + } catch { + await fs.promises.mkdir(templatesDir, { recursive: true }); + } + + const buffer = Buffer.from(await file.arrayBuffer()); + await fs.promises.writeFile(filePath, buffer); + + updateData.file_path = `/templates/${fileName}`; + updateData.original_filename = file.name; + updateData.file_size = file.size; + } + + // Update database + const updateFields = Object.keys(updateData).map(key => `${key} = ?`).join(', '); + const updateValues = Object.values(updateData); + + db.prepare(` + UPDATE docx_templates + SET ${updateFields} + WHERE template_id = ? + `).run([...updateValues, templateId]); + + // Get updated template + const updatedTemplate = db.prepare(` + SELECT * FROM docx_templates WHERE template_id = ? + `).get(templateId); + + return NextResponse.json(updatedTemplate); + + } catch (error) { + console.error("Template update error:", error); + return NextResponse.json( + { error: "Failed to update template" }, + { status: 500 } + ); + } +} + export async function DELETE(request, { params }) { try { const { templateId } = params; diff --git a/src/app/templates/page.js b/src/app/templates/page.js index b942860..88eccfc 100644 --- a/src/app/templates/page.js +++ b/src/app/templates/page.js @@ -40,6 +40,12 @@ export default function TemplatesPage() { setTemplates(prev => prev.filter(t => t.template_id !== templateId)); }; + const handleTemplateUpdated = (updatedTemplate) => { + setTemplates(prev => prev.map(t => + t.template_id === updatedTemplate.template_id ? updatedTemplate : t + )); + }; + if (loading) { return ( @@ -83,6 +89,7 @@ export default function TemplatesPage() { diff --git a/src/components/TemplateEditForm.js b/src/components/TemplateEditForm.js new file mode 100644 index 0000000..41f362c --- /dev/null +++ b/src/components/TemplateEditForm.js @@ -0,0 +1,143 @@ +"use client"; + +import { useState, useRef, useEffect } from "react"; +import Button from "@/components/ui/Button"; + +export default function TemplateEditForm({ template, onTemplateUpdated, onCancel }) { + const [updating, setUpdating] = useState(false); + const [formData, setFormData] = useState({ + templateName: "", + description: "", + }); + const fileInputRef = useRef(null); + + useEffect(() => { + if (template) { + setFormData({ + templateName: template.template_name || "", + description: template.description || "", + }); + } + }, [template]); + + const handleSubmit = async (e) => { + e.preventDefault(); + + if (!formData.templateName.trim()) { + alert("Proszę podać nazwę szablonu"); + return; + } + + setUpdating(true); + + try { + const updateData = new FormData(); + updateData.append("templateName", formData.templateName); + updateData.append("description", formData.description); + + const file = fileInputRef.current?.files[0]; + if (file) { + updateData.append("file", file); + } + + const response = await fetch(`/api/templates/${template.template_id}`, { + method: "PUT", + body: updateData, + }); + + if (response.ok) { + const updatedTemplate = await response.json(); + onTemplateUpdated(updatedTemplate); + } else { + const error = await response.json(); + alert(`Błąd podczas aktualizacji: ${error.error}`); + } + } catch (error) { + console.error("Update error:", error); + alert("Błąd podczas aktualizacji szablonu"); + } finally { + setUpdating(false); + } + }; + + const handleInputChange = (e) => { + const { name, value } = e.target; + setFormData(prev => ({ + ...prev, + [name]: value + })); + }; + + if (!template) { + return null; + } + + return ( +
+
+ + +
+ +
+ +