erp-platform/ui/src/views/supplychain/components/QuotationForm.tsx

697 lines
29 KiB
TypeScript
Raw Normal View History

2025-09-15 21:42:39 +00:00
import React, { useState } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
2025-09-15 09:31:47 +00:00
import {
FaArrowLeft,
FaSave,
FaTimes,
FaFileAlt,
FaCalendar,
FaDollarSign,
FaPlus,
FaTrash,
FaPaperclip,
2025-09-15 21:42:39 +00:00
} from 'react-icons/fa'
2025-09-15 09:31:47 +00:00
import {
MmQuotation,
QuotationStatusEnum,
RequestTypeEnum,
MmQuotationItem,
MmAttachment,
2025-09-15 21:42:39 +00:00
} from '../../../types/mm'
import { mockMaterials } from '../../../mocks/mockMaterials'
import { mockBusinessParties } from '../../../mocks/mockBusinessParties'
import { Container } from '@/components/shared'
2025-09-16 12:33:57 +00:00
import { ROUTES_ENUM } from '@/routes/route.constant'
2025-09-17 08:58:20 +00:00
import { getQuotationStatusText, getRequestTypeText } from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
2025-09-15 09:31:47 +00:00
const QuotationForm: React.FC = () => {
2025-09-15 21:42:39 +00:00
const { id } = useParams<{ id: string }>()
const navigate = useNavigate()
const isEdit = id !== undefined && id !== 'new'
const isView = window.location.pathname.includes('/view/')
2025-09-15 09:31:47 +00:00
const [formData, setFormData] = useState<Partial<MmQuotation>>({
2025-09-15 21:42:39 +00:00
quotationNumber: isEdit ? `TEK-2024-${id}` : '',
requestId: '',
requestTitle: '',
2025-09-15 09:31:47 +00:00
requestType: RequestTypeEnum.Material,
2025-09-15 21:42:39 +00:00
supplierId: '',
2025-09-15 09:31:47 +00:00
quotationDate: new Date(),
validUntil: new Date(),
status: QuotationStatusEnum.Draft,
totalAmount: 0,
2025-09-15 21:42:39 +00:00
currency: 'TRY',
paymentTerms: '',
deliveryTerms: '',
2025-09-15 09:31:47 +00:00
items: [],
attachments: [],
2025-09-15 21:42:39 +00:00
notes: '',
})
2025-09-15 09:31:47 +00:00
const handleInputChange = (
2025-09-15 21:42:39 +00:00
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
2025-09-15 09:31:47 +00:00
) => {
2025-09-15 21:42:39 +00:00
const { name, value, type } = e.target
2025-09-15 09:31:47 +00:00
setFormData((prev) => ({
...prev,
[name]:
2025-09-15 21:42:39 +00:00
type === 'number' ? parseFloat(value) || 0 : type === 'date' ? new Date(value) : value,
}))
}
2025-09-15 09:31:47 +00:00
const addQuotationItem = () => {
const newItem: MmQuotationItem = {
id: `item-${Date.now()}`,
2025-09-15 21:42:39 +00:00
materialCode: '',
materialName: '',
description: '',
2025-09-15 09:31:47 +00:00
quantity: 0,
2025-09-15 21:42:39 +00:00
unit: '',
2025-09-15 09:31:47 +00:00
unitPrice: 0,
totalPrice: 0,
specifications: [],
2025-09-15 21:42:39 +00:00
}
2025-09-15 09:31:47 +00:00
setFormData((prev) => ({
...prev,
items: [...(prev.items || []), newItem],
2025-09-15 21:42:39 +00:00
}))
}
2025-09-15 09:31:47 +00:00
const removeQuotationItem = (index: number) => {
setFormData((prev) => ({
...prev,
items: prev.items?.filter((_, i) => i !== index) || [],
2025-09-15 21:42:39 +00:00
}))
calculateTotal()
}
2025-09-15 09:31:47 +00:00
const updateQuotationItem = (
index: number,
field: keyof MmQuotationItem,
2025-09-15 21:42:39 +00:00
value: string | number | string[] | undefined,
2025-09-15 09:31:47 +00:00
) => {
setFormData((prev) => {
const updatedItems =
prev.items?.map((item, i) => {
if (i === index) {
2025-09-15 21:42:39 +00:00
const updatedItem = { ...item, [field]: value }
2025-09-15 09:31:47 +00:00
// Auto-calculate total price when quantity or unit price changes
2025-09-15 21:42:39 +00:00
if (field === 'quantity' || field === 'unitPrice') {
updatedItem.totalPrice = (updatedItem.quantity || 0) * (updatedItem.unitPrice || 0)
2025-09-15 09:31:47 +00:00
}
2025-09-15 21:42:39 +00:00
return updatedItem
2025-09-15 09:31:47 +00:00
}
2025-09-15 21:42:39 +00:00
return item
}) || []
2025-09-15 09:31:47 +00:00
return {
...prev,
items: updatedItems,
2025-09-15 21:42:39 +00:00
}
})
2025-09-15 09:31:47 +00:00
// Recalculate total amount
2025-09-15 21:42:39 +00:00
setTimeout(calculateTotal, 0)
}
2025-09-15 09:31:47 +00:00
const calculateTotal = () => {
2025-09-15 21:42:39 +00:00
const total = formData.items?.reduce((sum, item) => sum + (item.totalPrice || 0), 0) || 0
2025-09-15 09:31:47 +00:00
setFormData((prev) => ({
...prev,
totalAmount: total,
2025-09-15 21:42:39 +00:00
}))
}
2025-09-15 09:31:47 +00:00
const handleSpecificationsChange = (index: number, value: string) => {
2025-09-15 21:42:39 +00:00
const specifications = value.split('\n').filter((spec) => spec.trim() !== '')
updateQuotationItem(index, 'specifications', specifications)
}
2025-09-15 09:31:47 +00:00
const handleSubmit = (e: React.FormEvent) => {
2025-09-15 21:42:39 +00:00
e.preventDefault()
2025-09-15 09:31:47 +00:00
// TODO: Implement save logic
2025-09-15 21:42:39 +00:00
console.log('Saving quotation:', formData)
2025-09-16 12:33:57 +00:00
navigate(ROUTES_ENUM.protected.supplychain.quotations)
2025-09-15 21:42:39 +00:00
}
2025-09-15 09:31:47 +00:00
const handleCancel = () => {
2025-09-16 12:33:57 +00:00
navigate(ROUTES_ENUM.protected.supplychain.quotations)
2025-09-15 21:42:39 +00:00
}
2025-09-15 09:31:47 +00:00
2025-09-15 21:42:39 +00:00
const isReadOnly = isView
const pageTitle = isEdit ? 'Teklifi Düzenle' : isView ? 'Teklif Detayları' : 'Yeni Teklif'
2025-09-15 09:31:47 +00:00
return (
2025-09-15 21:42:39 +00:00
<Container>
<div className="space-y-2">
2025-09-15 09:31:47 +00:00
{/* Header */}
<div className="bg-white rounded-lg shadow-md p-2 mb-2">
<div className="flex items-center justify-between">
<div className="flex items-center">
<button
onClick={handleCancel}
className="mr-2 p-1.5 text-gray-400 hover:text-gray-600"
>
<FaArrowLeft />
</button>
2025-09-15 21:02:48 +00:00
<h2 className="text-2xl font-bold text-gray-900">{pageTitle}</h2>
2025-09-15 09:31:47 +00:00
</div>
<div className="flex space-x-2">
<button
onClick={handleCancel}
className="px-3 py-1.5 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 flex items-center"
>
<FaTimes className="mr-2" />
2025-09-15 21:42:39 +00:00
{isView ? 'Kapat' : 'İptal'}
2025-09-15 09:31:47 +00:00
</button>
{!isView && (
<button
onClick={handleSubmit}
className="px-3 py-1.5 bg-blue-600 text-white rounded-md hover:bg-blue-700 flex items-center"
>
<FaSave className="mr-2" />
Kaydet
</button>
)}
</div>
</div>
</div>
<form onSubmit={handleSubmit}>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
{/* Ana İçerik */}
<div className="lg:col-span-2">
{/* Temel Bilgiler */}
<div className="bg-white rounded-lg shadow-md p-4 mb-4">
<h3 className="text-base font-medium text-gray-900 mb-3 flex items-center">
<FaFileAlt className="mr-2 text-blue-600" />
Teklif Bilgileri
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700">
Teklif Numarası
</label>
<input
type="text"
name="quotationNumber"
2025-09-15 21:42:39 +00:00
value={formData.quotationNumber || ''}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
readOnly={isReadOnly || isEdit}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-sm font-medium text-gray-700">Talep ID</label>
2025-09-15 09:31:47 +00:00
<input
type="text"
name="requestId"
2025-09-15 21:42:39 +00:00
value={formData.requestId || ''}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
readOnly={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
required
/>
</div>
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-sm font-medium text-gray-700">Talep Başlığı</label>
2025-09-15 09:31:47 +00:00
<input
type="text"
name="requestTitle"
2025-09-15 21:42:39 +00:00
value={formData.requestTitle || ''}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
readOnly={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
required
/>
</div>
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-sm font-medium text-gray-700">Talep Tipi</label>
2025-09-15 09:31:47 +00:00
<select
name="requestType"
value={formData.requestType || RequestTypeEnum.Material}
onChange={handleInputChange}
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
2025-09-17 08:58:20 +00:00
{Object.values(RequestTypeEnum).map((type) => (
<option key={type} value={type}>
{getRequestTypeText(type)}
</option>
))}
2025-09-15 09:31:47 +00:00
</select>
</div>
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-sm font-medium text-gray-700">Tedarikçi</label>
2025-09-15 09:31:47 +00:00
<select
name="supplierId"
2025-09-15 21:42:39 +00:00
value={formData.supplierId || ''}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
required
>
<option value="">Tedarikçi Seçiniz</option>
{mockBusinessParties.map((supplier) => (
<option key={supplier.id} value={supplier.id}>
{supplier.name} ({supplier.code})
</option>
))}
</select>
</div>
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-sm font-medium text-gray-700">Tedarikçi Adı</label>
2025-09-15 09:31:47 +00:00
<input
type="text"
name="supplierName"
2025-09-15 21:42:39 +00:00
value={formData.supplier?.name || ''}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
readOnly={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
required
/>
</div>
<div>
<label className="flex items-center text-sm font-medium text-gray-700">
<FaCalendar className="mr-1" />
Teklif Tarihi
</label>
<input
type="date"
name="quotationDate"
value={
formData.quotationDate
2025-09-15 21:42:39 +00:00
? new Date(formData.quotationDate).toISOString().split('T')[0]
: ''
2025-09-15 09:31:47 +00:00
}
onChange={handleInputChange}
readOnly={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
<label className="flex items-center text-sm font-medium text-gray-700">
<FaCalendar className="mr-1" />
Geçerlilik Tarihi
</label>
<input
type="date"
name="validUntil"
value={
formData.validUntil
2025-09-15 21:42:39 +00:00
? new Date(formData.validUntil).toISOString().split('T')[0]
: ''
2025-09-15 09:31:47 +00:00
}
onChange={handleInputChange}
readOnly={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-sm font-medium text-gray-700">Para Birimi</label>
2025-09-15 09:31:47 +00:00
<select
name="currency"
2025-09-15 21:42:39 +00:00
value={formData.currency || 'TRY'}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
2025-09-17 08:58:20 +00:00
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
2025-09-15 09:31:47 +00:00
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700">
Ödeme Koşulları
</label>
<input
type="text"
name="paymentTerms"
2025-09-15 21:42:39 +00:00
value={formData.paymentTerms || ''}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
readOnly={isReadOnly}
placeholder="ör: 30 gün vadeli"
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700">
Teslimat Koşulları
</label>
<input
type="text"
name="deliveryTerms"
2025-09-15 21:42:39 +00:00
value={formData.deliveryTerms || ''}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
readOnly={isReadOnly}
placeholder="ör: 15 gün içinde teslim"
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700">
Teslimat Süresi (Gün)
</label>
<input
type="number"
name="deliveryTime"
2025-09-15 21:42:39 +00:00
value={formData.deliveryTime || ''}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
readOnly={isReadOnly}
min="0"
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
</div>
<div className="mt-4">
2025-09-15 21:42:39 +00:00
<label className="block text-sm font-medium text-gray-700">Notlar</label>
2025-09-15 09:31:47 +00:00
<textarea
name="notes"
2025-09-15 21:42:39 +00:00
value={formData.notes || ''}
2025-09-15 09:31:47 +00:00
onChange={handleInputChange}
readOnly={isReadOnly}
rows={2}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
</div>
{/* Teklif Kalemleri */}
<div className="bg-white rounded-lg shadow-md p-4">
<div className="flex items-center justify-between mb-3">
2025-09-15 21:42:39 +00:00
<h3 className="text-base font-medium text-gray-900">Teklif Kalemleri</h3>
2025-09-15 09:31:47 +00:00
{!isReadOnly && (
<button
type="button"
onClick={addQuotationItem}
className="px-2.5 py-1.5 bg-blue-600 text-white rounded-md hover:bg-blue-700 flex items-center"
>
<FaPlus className="mr-2" />
Kalem Ekle
</button>
)}
</div>
<div className="space-y-3">
{formData.items?.map((item, index) => (
2025-09-15 21:42:39 +00:00
<div key={item.id} className="border rounded-lg p-3 bg-gray-50">
2025-09-15 09:31:47 +00:00
<div className="flex items-center justify-between mb-2">
2025-09-15 21:42:39 +00:00
<span className="text-sm font-medium text-gray-700">Kalem {index + 1}</span>
2025-09-15 09:31:47 +00:00
{!isReadOnly && (
<button
type="button"
onClick={() => removeQuotationItem(index)}
className="text-red-600 hover:text-red-800"
>
<FaTrash />
</button>
)}
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2">
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-xs font-medium text-gray-600">Malzeme</label>
2025-09-15 09:31:47 +00:00
<select
value={item.materialCode}
onChange={(e) =>
2025-09-15 21:42:39 +00:00
updateQuotationItem(index, 'materialCode', e.target.value)
2025-09-15 09:31:47 +00:00
}
disabled={isReadOnly}
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value="">Malzeme Seçiniz</option>
{mockMaterials.map((material) => (
<option key={material.id} value={material.code}>
{material.name} ({material.code})
</option>
))}
</select>
</div>
<div>
<label className="block text-xs font-medium text-gray-600">
Malzeme Adı
</label>
<input
type="text"
value={item.materialName}
onChange={(e) =>
2025-09-15 21:42:39 +00:00
updateQuotationItem(index, 'materialName', e.target.value)
2025-09-15 09:31:47 +00:00
}
readOnly={isReadOnly}
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-600">
ıklama
</label>
<input
type="text"
value={item.description}
onChange={(e) =>
2025-09-15 21:42:39 +00:00
updateQuotationItem(index, 'description', e.target.value)
2025-09-15 09:31:47 +00:00
}
readOnly={isReadOnly}
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-xs font-medium text-gray-600">Miktar</label>
2025-09-15 09:31:47 +00:00
<input
type="number"
value={item.quantity}
onChange={(e) =>
updateQuotationItem(
index,
2025-09-15 21:42:39 +00:00
'quantity',
parseFloat(e.target.value) || 0,
2025-09-15 09:31:47 +00:00
)
}
readOnly={isReadOnly}
min="0"
step="0.01"
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-xs font-medium text-gray-600">Birim</label>
2025-09-15 09:31:47 +00:00
<input
type="text"
value={item.unit}
2025-09-15 21:42:39 +00:00
onChange={(e) => updateQuotationItem(index, 'unit', e.target.value)}
2025-09-15 09:31:47 +00:00
readOnly={isReadOnly}
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-600">
Birim Fiyat
</label>
<input
type="number"
value={item.unitPrice}
onChange={(e) =>
updateQuotationItem(
index,
2025-09-15 21:42:39 +00:00
'unitPrice',
parseFloat(e.target.value) || 0,
2025-09-15 09:31:47 +00:00
)
}
readOnly={isReadOnly}
min="0"
step="0.01"
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-600">
Toplam Fiyat
</label>
<input
type="number"
value={item.totalPrice}
readOnly
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1.5 bg-gray-100"
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-600">
Teslim Süresi (Gün)
</label>
<input
type="number"
2025-09-15 21:42:39 +00:00
value={item.leadTime || ''}
2025-09-15 09:31:47 +00:00
onChange={(e) =>
updateQuotationItem(
index,
2025-09-15 21:42:39 +00:00
'leadTime',
parseInt(e.target.value) || undefined,
2025-09-15 09:31:47 +00:00
)
}
readOnly={isReadOnly}
min="0"
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
<div className="md:col-span-2 lg:col-span-3">
<label className="block text-xs font-medium text-gray-600">
Spesifikasyonlar (her satıra bir spesifikasyon)
</label>
<textarea
2025-09-15 21:42:39 +00:00
value={item.specifications?.join('\n') || ''}
onChange={(e) => handleSpecificationsChange(index, e.target.value)}
2025-09-15 09:31:47 +00:00
readOnly={isReadOnly}
rows={1}
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
/>
</div>
</div>
</div>
))}
{formData.items?.length === 0 && (
<div className="text-center text-gray-500 text-sm py-6">
Henüz teklif kalemi eklenmedi
</div>
)}
</div>
</div>
</div>
{/* Yan Panel */}
<div className="space-y-4">
{/* Durum ve Tutar */}
<div className="bg-white rounded-lg shadow-md p-4">
2025-09-15 21:42:39 +00:00
<h3 className="text-base font-medium text-gray-900 mb-3">Durum Bilgileri</h3>
2025-09-15 09:31:47 +00:00
<div className="space-y-3">
<div>
2025-09-15 21:42:39 +00:00
<label className="block text-sm font-medium text-gray-700">Durum</label>
2025-09-15 09:31:47 +00:00
<select
name="status"
value={formData.status || QuotationStatusEnum.Draft}
onChange={handleInputChange}
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
2025-09-17 08:58:20 +00:00
{Object.values(QuotationStatusEnum).map((status) => (
<option key={status} value={status}>
{getQuotationStatusText(status)}
</option>
))}
2025-09-15 09:31:47 +00:00
</select>
</div>
<div>
<label className="flex items-center text-sm font-medium text-gray-700">
<FaDollarSign className="mr-1" />
Toplam Tutar
</label>
<div className="mt-1 text-base font-semibold text-green-600">
2025-09-15 21:42:39 +00:00
{formData.totalAmount?.toLocaleString()} {formData.currency}
2025-09-15 09:31:47 +00:00
</div>
</div>
</div>
</div>
{/* Değerlendirme (sadece görüntüleme) */}
{isView && formData.evaluationScore && (
<div className="bg-white rounded-lg shadow-md p-4">
2025-09-15 21:42:39 +00:00
<h3 className="text-base font-medium text-gray-900 mb-3">Değerlendirme</h3>
2025-09-15 09:31:47 +00:00
<div className="space-y-3">
<div>
2025-09-15 21:42:39 +00:00
<div className="text-sm font-medium text-gray-700">Değerlendirme Puanı</div>
2025-09-15 09:31:47 +00:00
<div className="text-base font-semibold text-blue-600">
{formData.evaluationScore}/100
</div>
</div>
{formData.evaluatedBy && (
<div>
2025-09-15 21:42:39 +00:00
<div className="text-sm font-medium text-gray-700">Değerlendiren</div>
<div className="text-sm text-gray-600">{formData.evaluatedBy}</div>
2025-09-15 09:31:47 +00:00
</div>
)}
{formData.evaluationComments && (
<div>
<div className="text-sm font-medium text-gray-700">
Değerlendirme Yorumları
</div>
<div className="text-sm text-gray-600 bg-gray-50 p-2 rounded">
{formData.evaluationComments}
</div>
</div>
)}
</div>
</div>
)}
{/* Ekler */}
<div className="bg-white rounded-lg shadow-md p-4">
<h3 className="text-base font-medium text-gray-900 mb-3 flex items-center">
<FaPaperclip className="mr-2 text-blue-600" />
Ekler
</h3>
{formData.attachments && formData.attachments.length > 0 ? (
<div className="space-y-2">
{formData.attachments.map((attachment: MmAttachment) => (
<div
key={attachment.id}
className="flex items-center justify-between p-1.5 bg-gray-50 rounded"
>
<div>
<div className="text-sm font-medium text-gray-900">
{attachment.fileName}
</div>
<div className="text-xs text-gray-500">
{(attachment.fileSize / 1024).toFixed(1)} KB
</div>
</div>
</div>
))}
</div>
) : (
<div className="text-center text-gray-500 text-sm py-3">
Henüz ek dosya yüklenmedi
</div>
)}
</div>
</div>
</div>
</form>
</div>
2025-09-15 21:42:39 +00:00
</Container>
)
}
2025-09-15 09:31:47 +00:00
2025-09-15 21:42:39 +00:00
export default QuotationForm