Ürün Kabul - Hasar Tespit Tutanağı


HTML Kod:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Ürün Kabul-Hasar Tespit Tutanağı</title>
<style>
    * { margin:0; padding:0; box-sizing:border-box; font-family:'Segoe UI',sans-serif; }
    :root { --primary:#2563eb; --bg:#f3f4f6; --text:#111827; --border:#dbe4ee; }
    body { background:var(--bg); color:var(--text); padding:20px; }
    
    .container { width: 100%; max-width: 100%; margin: auto; overflow-x: hidden; } 
    
    .section-box { background:#fff; border:1px solid var(--border); border-radius:12px; margin-bottom:12px; }

    /* HEADER BÖLÜMÜ */
    .main-header { 
        padding: 12px 15px; 
        display: grid; 
        grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); 
        align-items: center; 
        box-shadow: 0 2px 4px rgba(0,0,0,.05); 
        gap: 10px;
    }
    
    .header-left { 
        display: flex; 
        align-items: center; 
        gap: 12px; 
        overflow: hidden;
    }
    .logo-wrapper { 
        width: 50px; 
        height: 50px; 
        border: 1px solid var(--border); 
        border-radius: 10px; 
        display: flex; 
        align-items: center; 
        justify-content: center; 
        flex-shrink: 0; 
        cursor: pointer; 
    }
    .logo-wrapper img { width: 90%; height: 90%; object-fit: contain; }
    
    .header-center { 
        align-self: center; 
        text-align: center; 
    }
    
    .main-title { 
        font-size: clamp(12px, 1.8vw, 18px); 
        font-weight: 800; 
        line-height: 1.2; 
        outline: none; 
        white-space: nowrap; 
    }
    
    .header-right { 
        display: flex; 
        flex-direction: column; 
        align-items: flex-end; 
        justify-content: center; 
        gap: 4px; 
        overflow: hidden;
    }
    
    /* Her İki Yan Metin İçin Ortak Sınıf */
    .side-text { 
        font-size: 10px; 
        font-weight: 700; 
        color: #64748b; 
        white-space: nowrap; 
        overflow: hidden; 
        text-overflow: ellipsis;
        line-height: 1.3; 
    }

    /* Orta Alan - Div Textarea */
    .main-panel { padding:20px; }
    .editable-text { 
        width: 100%; 
        padding: 5px; 
        outline: none; 
        background: transparent;
        font-size: 16px; 
        min-height: 50px;
        text-align: center; 
        line-height: 1.5; 
        word-wrap: break-word; 
        text-indent: 40px; 
    }
    
    /* Tablo Yapıştırma Alanı (Sayfa Sınırları) */
    .paste-area {
        min-height: 60px;
        width: 100%;
        max-width: 794px; 
        padding: 10px;
        margin: 30px auto 15px auto; 
        
        border-top: 1px dashed var(--border);
        border-bottom: 1px dashed var(--border);
        border-left: 2px dashed #ef4444; 
        border-right: 2px dashed #ef4444; 
        border-radius: 4px;
        
        outline: none;
        background: transparent;
        font-size: 14px;
        position: relative;
        overflow-x: auto; 
    }
    
    .paste-area::before {
        content: "◄ A4 Sayfa Sınırı ►";
        position: absolute;
        top: -25px;
        left: 50%;
        transform: translateX(-50%);
        font-size: 12px;
        color: #ef4444;
        font-weight: 700;
        pointer-events: none;
    }

    .paste-area:empty::after {
        content: attr(data-placeholder);
        color: #94a3b8;
        font-style: italic;
        display: block;
        text-align: center; 
        margin-top: 10px;
    }
    
    .paste-area:focus { border-color: var(--primary); }
    
    /* TABLO DÜZENLEMELERİ (Genişlik Aşımını Önleme) */
    .paste-area table { 
        border-collapse: collapse !important; 
        width: 100% !important; 
        max-width: 100% !important;
        margin: 5px auto !important; 
        background-color: #fff !important; 
        table-layout: fixed !important; 
        word-break: break-word !important;
    }
    .paste-area th, .paste-area td { 
        border: 1px solid #94a3b8 !important; 
        padding: 6px !important; 
        word-break: break-word !important; 
        overflow-wrap: break-word !important; 
        white-space: normal !important; 
        position: relative; 
        max-width: 100% !important;
        box-sizing: border-box !important;
    }
    
    /* Resim Alanı */
    .image-gallery { display:flex; flex-wrap:wrap; justify-content:center; gap:10px; width:100%; margin-top: 10px; }
    .img-thumb { 
        max-width: 100%; width: auto; height: auto; max-height: 300px; 
        object-fit: contain; border-radius:8px; border:1px solid var(--border); cursor:pointer; 
    }

    .actions { display:flex; gap:10px; justify-content:center; margin-bottom:15px; }
    .btn { border:none; padding:10px 20px; border-radius:10px; font-weight:600; cursor:pointer; color:#fff; transition: opacity 0.2s; }
    .btn:hover { opacity: 0.9; }
    .btn-primary { background:var(--primary); }
    .btn-success { background:#16a34a; }
    .btn-light { background: #e5e7eb; color: #374151; }
    .btn-light:hover { background: #d1d5db; }

    /* İmza Alanı */
    .signature-container { margin-bottom: 12px; }
    .signature-controls { display: flex; justify-content: flex-end; gap: 10px; margin-bottom: 10px; }
    .signature-grid { display:flex; justify-content:space-evenly; gap: 15px; padding:15px; flex-wrap: wrap; }
    .signature-box { padding:5px; text-align:center; flex: 1; min-width: 180px; max-width: 300px; }
    
    .editable-title { font-size:11px; font-weight:bold; min-height:16px; outline:none; margin-bottom: 2px; }
    .editable-title:focus { border-bottom: 1px dashed var(--primary); }
    .edit-name { border:none; background:transparent; text-align:center; width:100%; font-weight:bold; cursor:pointer; padding:5px; }
    .edit-name:focus { outline:none; border:1px solid var(--primary); border-radius:4px; }
    .sig-line { color:#94a3b8; font-size:11px; margin-top:5px; border-top:1px solid var(--border); display:inline-block; padding:0 30px; }

    /* Yazdırma (Print) Kuralları */
    @media print {
        @page { size: portrait; margin: 1cm; } 
        body { background:#fff; padding:0; }
        .container { max-width: 100% !important; overflow: hidden !important; }
        .actions, .btn, .signature-controls { display:none !important; }
        .section-box { border:1px solid #ccc; box-shadow:none; margin-bottom: 5px; }
        .signature-grid { flex-wrap: nowrap; gap: 10px; }
        
        .editable-text {
            text-align: justify !important;
            text-indent: 40px !important;
        }

        .paste-area:empty { display: none !important; }
        
        .main-header { display: grid !important; grid-template-columns: 1fr auto 1fr !important; align-items: center !important; }
        .main-title { font-size: 18px !important; white-space: nowrap !important; }
        
        .paste-area::before { display: none !important; }
        .paste-area { border: none !important; padding: 0 !important; margin: 5px 0 !important; overflow: hidden !important; width: 100% !important; max-width: 100% !important; }
        
        /* KESİN ÇÖZÜM: Yazdırırken tablonun ve hücrelerin taşması tamamen engellendi */
        .paste-area table { 
            width: 100% !important; 
            max-width: 100% !important;
            min-width: 0 !important;
            table-layout: fixed !important; 
        }
        .paste-area th, .paste-area td { 
            border: 1px solid #000 !important; 
            font-size: 11px !important; 
            width: auto !important;
            max-width: 100% !important;
            min-width: 0 !important; 
            word-break: break-word !important;
            overflow-wrap: break-word !important; 
            white-space: normal !important;
        }
        
        .image-gallery { gap: 5px; }
        .img-thumb {
            max-width: 48% !important; 
            max-height: 250px !important;
            page-break-inside: avoid; 
        }
    }
</style>
</head>
<body>

<div class="container">
    <div class="section-box main-header">
        <div class="header-left">
            <div class="logo-wrapper" id="logoWrapper"><img id="logoImage" src="logo.jpg" alt="Logo" onerror="this.style.display='none'"></div>
            <input type="file" id="logoInput" hidden accept="image/*">
            <div class="side-text">Helpdesk</div>
        </div>
        <div class="header-center">
            <div class="main-title" contenteditable="true">ÜRÜN KABUL<br>HASAR TESPİT TUTANAĞI</div>
        </div>
        <div class="header-right">
            <input type="date" id="tarih" style="border:1px solid var(--border); padding:2px; border-radius:6px; font-size: 11px; height: 24px;">
            <div class="side-text">MYO MÜDÜRLÜĞÜ</div>
        </div>
    </div>

    <div class="section-box main-panel">
        <div id="metinAlani" contenteditable="true" class="editable-text">
Ürün kabul alanında gerçekleştirilen teslim alma işlemleri sırasında yapılan kontrollerde, sevkiyat içerisinde bulunan bazı kolilerde <strong>ezilme ve ambalaj deformasyonu</strong> olduğu tespit edilmiştir.<br><br>
Hasar tespit edilen koliler kayıt altına alınmış, durum fotoğraf ile belgelenmiştir. Hasar tespit edilen koliler ayrılarak inceleme sürecine alınmış ve ürün içeriklerine yönelik kontrol çalışmaları başlatılmıştır.
        </div>
        
        <div id="tableContainer" class="paste-area" contenteditable="true" data-placeholder="Excel veya Word'den kopyaladığınız tabloyu buraya yapıştırabilirsiniz..."></div>

        <button class="btn btn-primary" onclick="imageInput.click()">+ Resim Ekle</button>
        <input type="file" id="imageInput" accept="image/*" multiple hidden>
        <div id="imageGallery" class="image-gallery"></div>
    </div>

    <div class="actions">
        <button class="btn btn-success" onclick="window.print()">Yazdır / PDF</button>
    </div>

    <div class="signature-container">
        <div class="signature-controls">
            <button class="btn btn-light" onclick="addSignature()" style="padding: 5px 15px; font-size: 14px;">+ İmza Ekle</button>
            <button class="btn btn-light" onclick="removeSignature()" style="padding: 5px 15px; font-size: 14px;">- İmza Çıkar</button>
        </div>
        
        <div class="section-box signature-grid" id="signatureGrid">
            <div class="signature-box">
                <div class="editable-title" contenteditable="true"></div>
                <input type="text" class="edit-name" value="İsim Soyisim" readonly 
                       ondblclick="this.readOnly=false;" onblur="this.readOnly=true;">
                <div class="sig-line">İmza</div>
            </div>
        </div>
    </div>
</div>

<script>
    const tarih = document.getElementById('tarih');
    tarih.value = new Date().toISOString().split('T')[0];

    const imageInput = document.getElementById('imageInput');
    const imageGallery = document.getElementById('imageGallery');
    imageInput.addEventListener('change', (e) => {
        for (let file of e.target.files) {
            const reader = new FileReader();
            reader.onload = (ev) => {
                const img = document.createElement('img');
                img.src = ev.target.result;
                img.className = 'img-thumb';
                
                img.onclick = () => {
                    if(confirm('Bu resmi silmek istediğinize emin misiniz?')) img.remove();
                };
                
                imageGallery.appendChild(img);
            };
            reader.readAsDataURL(file);
        }
    });

    const logoWrapper = document.getElementById('logoWrapper');
    const logoInput = document.getElementById('logoInput');
    const logoImage = document.getElementById('logoImage');

    logoWrapper.onclick = () => logoInput.click();
    logoInput.onchange = (e) => {
        const reader = new FileReader();
        reader.onload = (ev) => logoImage.src = ev.target.result;
        reader.readAsDataURL(e.target.files[0]);
    };

    function addSignature() {
        const grid = document.getElementById('signatureGrid');
        const box = document.createElement('div');
        box.className = 'signature-box';
        
        box.innerHTML = `
            <div class="editable-title" contenteditable="true"></div>
            <input type="text" class="edit-name" value="İsim Soyisim" readonly 
                   ondblclick="this.readOnly=false;" onblur="this.readOnly=true;">
            <div class="sig-line">İmza</div>
        `;
        grid.appendChild(box);
    }

    function removeSignature() {
        const grid = document.getElementById('signatureGrid');
        if (grid.children.length > 1) {
            grid.removeChild(grid.lastElementChild);
        } else {
            alert('Formda en az bir imza alanı bulunmalıdır.');
        }
    }

    // --- YAPILAN TABLOYU SINIRA SIĞDIRMA VE TAŞMAYI ENGELLEME FONKSİYONU ---
    const tableContainer = document.getElementById('tableContainer');
    
    tableContainer.addEventListener('paste', function(e) {
        setTimeout(() => {
            const tables = tableContainer.querySelectorAll('table');
            tables.forEach(table => {
                table.removeAttribute('width');
                table.style.width = '100%';
                table.style.maxWidth = '100%';
                table.style.tableLayout = 'fixed';
                
                // Tablo içindeki tüm elementlerin harici genişlik değerlerini temizleyip sığmaya zorla
                const allElements = table.querySelectorAll('*');
                allElements.forEach(el => {
                    el.removeAttribute('width');
                    el.removeAttribute('height');
                    el.style.width = '';
                    el.style.maxWidth = '100%';
                    el.style.minWidth = '0';
                    el.style.wordBreak = 'break-word';
                    el.style.overflowWrap = 'break-word';
                });
            });
        }, 50);
    });

    // --- ÖZGÜR TABLO BOYUTLANDIRMA SİSTEMİ (ALAN İÇİNE HAPSEDİLDİ) ---
    let isResizing = false;
    let currentTarget = null;
    let startX, startY, startWidth, startHeight;
    let resizeType = ''; 

    tableContainer.addEventListener('mousemove', function(e) {
        if (isResizing) return;
        
        const table = e.target.closest('table');
        const cell = e.target.closest('td, th');
        
        if (table) {
            const tableRect = table.getBoundingClientRect();
            const isNearTableCorner = (e.clientX > tableRect.right - 20) && (e.clientY > tableRect.bottom - 20);
            
            if (isNearTableCorner) {
                if (cell) cell.style.cursor = 'nwse-resize';
                table.style.cursor = 'nwse-resize';
                return;
            }
        }

        if (cell) {
            const rect = cell.getBoundingClientRect();
            const nearRight = e.clientX > rect.right - 8;
            const nearBottom = e.clientY > rect.bottom - 8;
            
            if (nearRight && nearBottom) cell.style.cursor = 'nwse-resize';
            else if (nearRight) cell.style.cursor = 'col-resize';
            else if (nearBottom) cell.style.cursor = 'row-resize';
            else {
                cell.style.cursor = 'text';
                if (table) table.style.cursor = 'text';
            }
        }
    });

    tableContainer.addEventListener('mousedown', function(e) {
        const table = e.target.closest('table');
        const cell = e.target.closest('td, th');
        
        if (table) {
            const tableRect = table.getBoundingClientRect();
            const isNearTableCorner = (e.clientX > tableRect.right - 20) && (e.clientY > tableRect.bottom - 20);
            
            if (isNearTableCorner) {
                isResizing = true;
                currentTarget = table;
                resizeType = 'table';
                startX = e.clientX;
                startY = e.clientY;
                startWidth = table.offsetWidth;
                startHeight = table.offsetHeight;
                e.preventDefault();
                return;
            }
        }
        
        if (cell) {
            const rect = cell.getBoundingClientRect();
            const nearRight = e.clientX > rect.right - 8;
            const nearBottom = e.clientY > rect.bottom - 8;
            
            if (nearRight || nearBottom) {
                isResizing = true;
                currentTarget = cell;
                startX = e.clientX;
                startY = e.clientY;
                startWidth = currentTarget.offsetWidth;
                startHeight = currentTarget.offsetHeight;
                
                if (nearRight && nearBottom) resizeType = 'both';
                else if (nearRight) resizeType = 'col';
                else resizeType = 'row';
                
                e.preventDefault(); 
            }
        }
    });

    document.addEventListener('mousemove', function(e) {
        if (!isResizing || !currentTarget) return;
        
        const containerInnerWidth = tableContainer.clientWidth - 20;
        
        if (resizeType === 'table') {
            let newWidth = startWidth + (e.clientX - startX);
            newWidth = Math.min(containerInnerWidth, Math.max(100, newWidth)); 
            
            const newHeight = Math.max(50, startHeight + (e.clientY - startY));
            
            currentTarget.style.width = newWidth + 'px';
            currentTarget.style.minWidth = newWidth + 'px';
            currentTarget.style.maxWidth = containerInnerWidth + 'px'; 
            
            currentTarget.style.height = newHeight + 'px';
            currentTarget.style.minHeight = newHeight + 'px';
        } else {
            if (resizeType === 'col' || resizeType === 'both') {
                let newWidth = startWidth + (e.clientX - startX);
                newWidth = Math.min(containerInnerWidth, Math.max(30, newWidth));
                currentTarget.style.width = newWidth + 'px';
                currentTarget.style.minWidth = newWidth + 'px';
                currentTarget.style.maxWidth = containerInnerWidth + 'px'; 
            }
            if (resizeType === 'row' || resizeType === 'both') {
                let newHeight = startHeight + (e.clientY - startY);
                newHeight = Math.max(20, newHeight);
                currentTarget.style.height = newHeight + 'px';
                currentTarget.style.minHeight = newHeight + 'px';
            }
        }
    });

    document.addEventListener('mouseup', function() {
        isResizing = false;
        currentTarget = null;
        resizeType = '';
    });
</script>
</body>
</html>


Kaynaklar:
* Gemini