From 7b741afa0683f929b979e463eb91b9f288c481b1 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Tue, 7 May 2024 21:03:34 +0300 Subject: [PATCH] fix permits UI and content upload/delete API --- pages/api/content/[subfolder].ts | 197 +++++++++++-------------------- pages/permits.tsx | 28 +++-- 2 files changed, 85 insertions(+), 140 deletions(-) diff --git a/pages/api/content/[subfolder].ts b/pages/api/content/[subfolder].ts index 2984aa9..780be31 100644 --- a/pages/api/content/[subfolder].ts +++ b/pages/api/content/[subfolder].ts @@ -1,12 +1,72 @@ -import path from 'path'; -import { promises as fs } from 'fs'; -import express from 'express'; - import type { NextApiRequest, NextApiResponse } from 'next'; -import nc from 'next-connect'; +import { promises as fs } from 'fs'; +import path from 'path'; +import multer from 'multer'; +import sharp from 'sharp'; +import { createRouter } from 'next-connect'; -const handler = nc({ - onError: (err, req, res, next) => { + +// Generalized Multer configuration +const storage = multer.diskStorage({ + destination: (req, file, cb) => { + const uploadPath = path.join(process.cwd(), 'public/content', req.query.subfolder as string); + fs.mkdir(uploadPath, { recursive: true }).then(() => cb(null, uploadPath)).catch(cb); + }, + filename: (req, file, cb) => { + const prefix = req.body.prefix || path.parse(file.originalname).name; + cb(null, `${prefix}${path.extname(file.originalname)}`); + } +}); + +const fileFilter = (req, file, cb) => { + // Accept PDFs only + if (file.mimetype === 'application/pdf') { + cb(null, true); + } else { + cb(new Error('Only PDF files are allowed!'), false); + } +}; + +const upload = multer({ storage, fileFilter }); + +const router = createRouter(); + +router.use(upload.array('file')); + +router.post((req, res) => { + console.log(req.files); // Log files to see if PDFs are included + if (req.files.length === 0) { + return res.status(400).json({ error: 'No files were uploaded.' }); + } + // Process uploaded files, assume images are being resized and saved + res.json({ message: 'Files uploaded successfully', files: req.files }); +}); + +router.get(async (req, res) => { + // Implement functionality to list files + const directory = path.join(process.cwd(), 'public/content', req.query.subfolder as string); + try { + const files = await fs.readdir(directory); + const imageUrls = files.map(file => `/content/${req.query.subfolder}/${file}`); + res.json({ imageUrls }); + } catch (err) { + res.status(500).json({ error: 'Internal Server Error', details: err.message }); + } +}); + +router.delete(async (req, res) => { + // Implement functionality to delete a file + const filePath = path.join(process.cwd(), 'public/content', req.query.subfolder as string, req.query.file as string); + try { + await fs.unlink(filePath); + res.send('File deleted successfully.'); + } catch (error) { + res.status(500).send('Failed to delete the file.'); + } +}); + +export default router.handler({ + onError: (err, req, res) => { console.error(err.stack); res.status(500).end('Something broke!'); }, @@ -15,131 +75,8 @@ const handler = nc({ } }); -handler.use((req: NextApiRequest, res: NextApiResponse, next) => { - const subfolder = req.query.subfolder as string; - const upload = createUploadMiddleware(subfolder).array('image'); - upload(req, res, (err) => { - if (err) { - return res.status(500).json({ error: 'Failed to upload files.', details: err.message }); - } - next(); - }); -}); - -handler.post((req: NextApiRequest, res: NextApiResponse) => { - // Process uploaded files - // Example response - res.json({ message: 'Files uploaded successfully', files: req.files }); -}); - -handler.get((req: NextApiRequest, res: NextApiResponse) => { - // Handle listing files - //listFiles(req, res, req.subfolder); - listFiles(req, res, req.query.subfolder as string); -}); - -handler.delete((req: NextApiRequest, res: NextApiResponse) => { - // Handle deleting files - deleteFile(req, res, req.query.subfolder as string); -}); - export const config = { api: { bodyParser: false, }, }; - -export default handler; - -// ------------------------------------------------------------ -//handling file uploads -import multer from 'multer'; -import sharp from 'sharp'; - -// Generalized Multer configuration -export const createUploadMiddleware = (folder: string) => { - const storage = multer.diskStorage({ - destination: (req, file, cb) => { - const uploadPath = path.join(process.cwd(), 'public/content', folder); - if (!fs.existsSync(uploadPath)) { - fs.mkdirSync(uploadPath, { recursive: true }); - } - cb(null, uploadPath); - }, - filename: (req, file, cb) => { - const prefix = req.body.prefix || path.parse(file.originalname).name; - cb(null, `${prefix}${path.extname(file.originalname)}`); - } - }); - return multer({ storage }); -}; - -async function processFiles(req, res, folder) { - if (!req.files || req.files.length === 0) { - return res.status(400).json({ error: 'No files uploaded.' }); - } - - const uploadDir = path.join(process.cwd(), 'public/content', folder); - const thumbDir = path.join(uploadDir, "thumb"); - - if (!fs.existsSync(thumbDir)) { - fs.mkdirSync(thumbDir, { recursive: true }); - } - - try { - const processedFiles = await Promise.all(req.files.map(async (file) => { - const originalPath = path.join(uploadDir, file.filename); - const thumbPath = path.join(thumbDir, file.filename); - - await sharp(file.path) - .resize({ width: 1920, fit: sharp.fit.inside, withoutEnlargement: true }) - .jpeg({ quality: 80 }) - .toFile(originalPath); - - await sharp(file.path) - .resize(320, 320, { fit: sharp.fit.inside, withoutEnlargement: true }) - .toFile(thumbPath); - - fs.unlinkSync(file.path); // Remove temp file - - return { - originalUrl: `/content/${folder}/${file.filename}`, - thumbUrl: `/content/${folder}/thumb/${file.filename}` - }; - })); - - res.json(processedFiles); - } catch (error) { - console.error('Error processing files:', error); - res.status(500).json({ error: 'Error processing files.' }); - } -} - -// List files in a directory -async function listFiles(req, res, folder) { - const directory = path.join(process.cwd(), 'public/content', folder); - - try { - const files = await fs.promises.readdir(directory); - const imageUrls = files.map(file => `${req.protocol}://${req.get('host')}/content/${folder}/${file}`); - res.json({ imageUrls }); - } catch (err) { - console.error('Error reading uploads directory:', err); - res.status(500).json({ error: 'Internal Server Error' }); - } -} - -// Delete a file -async function deleteFile(req, res, folder) { - const filename = req.query.file; - if (!filename) { - return res.status(400).send('Filename is required.'); - } - try { - const filePath = path.join(process.cwd(), 'public/content', folder, filename); - await fs.unlink(filePath); - res.status(200).send('File deleted successfully.'); - } catch (error) { - res.status(500).send('Failed to delete the file.'); - } -} \ No newline at end of file diff --git a/pages/permits.tsx b/pages/permits.tsx index f25c3d6..5f28dc3 100644 --- a/pages/permits.tsx +++ b/pages/permits.tsx @@ -44,17 +44,25 @@ const PDFViewerPage = ({ pdfFiles }) => {

Разрешителни

- - {files.map((file, index) => ( -
- - {file.name} - - +
+
+ За да качите файл кликнете на бутона по-долу и изберете файл от вашия компютър.
- ))} + +
+ Съществуващи файлове: +
+ {files.map((file, index) => ( +
+ + {file.name} + + +
+ ))} +
{/* Adjust the 100px based on your header/footer size */}