feat: Improve PDF downloads in admin car detail modal

- Rename image PDF to {carName}_{carNumber}.pdf
- Add performance check PDF download button (blue, next to image PDF)
- Performance check PDF named {carName}_{carNumber}_성능점검표.pdf

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
AutonetSellCar Deploy
2026-03-27 18:00:06 +09:00
parent a8aced66a8
commit 958ea252bb

View File

@@ -4,7 +4,7 @@ import { useState, useEffect, useCallback } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
import Image from 'next/image';
import { Reorder, useDragControls } from 'framer-motion';
import api, { heroBannersApi, carmodooApi, vehicleRequestsApi, carsApi } from '@/lib/api';
import api, { heroBannersApi, carmodooApi, vehicleRequestsApi, carsApi, ccApi } from '@/lib/api';
import { translateCarName } from '@/lib/i18n';
import { jsPDF } from 'jspdf';
@@ -1317,7 +1317,8 @@ export default function CarsAdminPage() {
}
const carName = selectedCar.car_name.replace(/[^a-zA-Z0-9가-힣\s]/g, '').trim();
pdf.save(`${carName}_images.pdf`);
const carNumber = selectedCar.car_number?.replace(/\s/g, '') || 'unknown';
pdf.save(`${carName}_${carNumber}.pdf`);
} catch (error) {
console.error('PDF generation failed:', error);
alert('PDF generation failed. Please try again.');
@@ -1326,6 +1327,37 @@ export default function CarsAdminPage() {
}
};
const [perfPdfDownloading, setPerfPdfDownloading] = useState(false);
const handleDownloadPerformanceCheckPdf = async () => {
if (!selectedCar) return;
setPerfPdfDownloading(true);
try {
const blob = await ccApi.downloadPerformanceCheckPdf(selectedCar.id);
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
const carName = selectedCar.car_name.replace(/[^a-zA-Z0-9가-힣\s]/g, '').trim();
const carNumber = selectedCar.car_number?.replace(/\s/g, '') || 'unknown';
a.download = `${carName}_${carNumber}_성능점검표.pdf`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
} catch (error: any) {
console.error('Performance check PDF download failed:', error);
const status = error.response?.status;
if (status === 404) {
alert('Performance check PDF not available for this car.');
} else {
alert('Failed to download performance check PDF.');
}
} finally {
setPerfPdfDownloading(false);
}
};
const handleEditComment = () => {
if (dealerComment) {
setEditCommentData({
@@ -2737,12 +2769,12 @@ export default function CarsAdminPage() {
{/* Modal Header */}
<div className="sticky top-0 bg-white border-b border-gray-200 px-6 py-4 flex justify-between items-center z-10">
<h2 className="text-xl font-bold text-gray-800">{selectedCar.car_name}</h2>
<div className="flex items-center gap-3">
<div className="flex items-center gap-2">
{selectedCar.images && selectedCar.images.length > 0 && (
<button
onClick={handleDownloadImagesPdf}
disabled={pdfDownloading}
className="flex items-center gap-2 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:opacity-50 transition font-medium text-sm"
className="flex items-center gap-1.5 px-3 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:opacity-50 transition font-medium text-sm"
>
{pdfDownloading ? (
<>
@@ -2751,14 +2783,33 @@ export default function CarsAdminPage() {
</>
) : (
<>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
<span>PDF ({selectedCar.images.length})</span>
<span>Images PDF ({selectedCar.images.length})</span>
</>
)}
</button>
)}
<button
onClick={handleDownloadPerformanceCheckPdf}
disabled={perfPdfDownloading}
className="flex items-center gap-1.5 px-3 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 transition font-medium text-sm"
>
{perfPdfDownloading ? (
<>
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
<span>Downloading...</span>
</>
) : (
<>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<span>Performance Check</span>
</>
)}
</button>
<button
onClick={closeDetailModal}
className="text-gray-500 hover:text-gray-700"