Promt-AI-“HELPDESK Haftalık/Aylık Faaliyet Raporu Dashboard”

Haftalık rapor hazırlama süreçlerinde Word veya Excel üzerinde manuel veri akışıyla çalışmak artık eski yöntemler arasında kaldı. Bu sürecin modern, dinamik ve tek bir uygulama üzerinden yönetilebilmesi ise; yazılım bilgisi yada yapay zekâyı etkili kullanabilme becerisiyle mümkün hale geliyor.

Buradaki en önemli konu, yapay zekâ ile aynı dili konuşabilmek ve doğru promptlar (komutları) verebilmek. Mevcut Excel tablo yapımı ekleyerek bunu HTML tabanlı bir sayfaya dönüştürmesini istedim. Ardından ihtiyaçlara göre yeni talepler oluşturarak, her aşamada testler yapıp geliştirilmiş bir kod yapısı elde ettim.

Daha sonra bu süreci tekrar kullanılabilir hale getirmek için, oluşturulan yapının promptlara dönüştürülmesini talep ettim. Sonuç olarak aşağıda yer alan komutlar, kodlar, görseller ve ek özellikler ortaya çıktı.


Çıktı üzerinde, Neler yapabiliyoruz?
  • Logo, üzerinde 5 defa peş peşe basınca logo değiştirebiliyor ve Metinler içinde "HELPDESK", "MYO" 5 defa peş peşe basınca düzenleyebiliyorsunuz.
  • Kod içinde bu kelimeleri "Ctrt + F ile araştırıp, kalıcı olarak değiştirebilirsiniz.
  • "Haftalık Faaliyet Raporu" yanındaki "Değiştir" butonuna basınca, "Aylık Faaliyet Raporu" olarak 4 haftanın raporunu bir arda kullanabilirsiniz.
  • İki tarih aralığı seçerek, çalışma aralığını belirleyebilirsiniz.
  • Özel alanlar, kutucuklar; İlk alan, Kapatılan Ticket adetini manuel girmeniz geren penceredir.
  • Diğer pencereler ise, eklediğiniz satır kadar değeri otomatik olarak arttırır.
  • Önizleme, İçeri aktar, CSV olarak dışarı aktarma, Yazdırma ve Kaydetme yer alır.
  • Logo görünümü için, logo isminin "logo.jpg" olması ve resmin html dosyası ile aynı klasörde yer alması yeterli.
  • Kodu kopyala (Aşağıda, Mavi metin) not defterine yapıştır, uzantıyı ".html" yap. Yapılması gereken tek işlem, çift tıklayarak çalıştırmak.
  • Yöneticiye, Özet bir rapor sunabilme kolaylığı hedeflenerek geliştirilmiştir.

Form veri giriş ekranı:




Başlık hakkında:
İsterseniz; Sol yeşil çerçeveli alanda, Departman bilgisi ve Sağa yeşil alana da Müdürlük bilgisini girebilirsiniz. Koddan başlıkları kalıcı olarak değiştirebilir veya bu metinlerin üzerine peş peşe beş (5) defa basarak değiştirme işlemini gerçekleştirebilirsiniz. "Değiştir" butonuna basarak Haftalık/Aylık faaliyet raporu olarak değişebilir, rapor tarih aralığını takvimden seçebilirsiniz. Özet pencerelerde tek bir manuel alan bulunur. Buraya kullandığınız helpdesk uygulaması (E-Çözüm, Servicedesk, Jira vb.) kapatılan Ticket adetini girmelisiniz.


Veri Girişi:
İlgili başlıklarda her veri girişini ayrı satırlarda yapmalısınız. "+ Yeni Satır" butonuna bastıkça oluşan satıra veri girilir. Veri girişi yapılan satır kadar bilgi üstteki özet penceresine rakam bilgisi olarak yansır.


Veri Girişi Özet:
İlk önce tarih aralığı seçmeyi ve manuel Ticket adeti girmeyi unutmayın. sonradan veri güncelleme yaptığınızda da "Önizleme Oluştur" butonuna basarak alanı güncellersiniz. Veri girdiğiniz diğer başlıklarda satır sayısı kadar değer özet tabloya rakam olarak yansır. Veri girişi olmayan başlık altındaki tablo satırları, Önizleme ye yansımaz. "CSV" tuşuna bastığınızda veri indirilenler klasörüne "Faaliyet_Raporu.csv" olarak yansır. (Manuel girdiğiniz Ticket değeri geçmiyor)


CSV dosyası:

Yazdırma / Kaydetme:


İçeri Aktar: 
Butona bastığınızda, "Faaliyet_Raporu.csv" den içeri tabloya veri girişi gerçekleşir. 


Ticket adeti geçmez manuel tekrar girmeli, sonra veriniz üzerinde istediğiniz gibi düzenleme yapabilir, Yazdırabilirsiniz.



2. Görsel çalışma:







HTML Kod:
kodun son hali aşağıdaki gibidir. Başlıklar altına eklenen satırlarda mouse ile sürükle bırakma özelliği ile kaydırma yapılabilmektedir.

<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Faaliyet Raporu Sistemi</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600;9..40,700&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root{
  --bg:#e8edf5;
  --surface:#ffffff;
  --surface-2:#f4f7fb;
  --surface-3:#edf1f7;
  --border:rgba(0,0,0,0.09);
  --border-mid:rgba(0,0,0,0.13);
  --accent:#2563eb;
  --accent-glow:rgba(37,99,235,0.14);
  --green:#059669;
  --red:#dc2626;
  --text-1:#0f172a;
  --text-2:#475569;
  --text-3:#94a3b8;
  --r-sm:6px;--r-md:12px;--r-lg:18px;--r-xl:24px;
  --mono:'DM Mono',monospace;
  /* 3-D shadow system */
  --s3d: 0 1px 0 #fff inset, 0 4px 0 rgba(0,0,0,0.12), 0 6px 16px rgba(0,0,0,0.10);
  --s3d-hover: 0 1px 0 #fff inset, 0 6px 0 rgba(0,0,0,0.14), 0 10px 24px rgba(0,0,0,0.13);
  --s3d-sm: 0 1px 0 #fff inset, 0 3px 0 rgba(0,0,0,0.10), 0 4px 10px rgba(0,0,0,0.08);
}
*{box-sizing:border-box;margin:0;padding:0;}
body{
  font-family:'DM Sans',sans-serif;
  background:#ffffff;
  color:var(--text-1);
  min-height:100vh;
  padding:24px;
}
.container{max-width:1400px;margin:0 auto;}

/* ── HEADER ── */
.header{
  background:linear-gradient(160deg,#ffffff 60%,#f0f4ff);
  border:1px solid var(--border-mid);
  border-radius:var(--r-xl);
  padding:20px 24px;
  display:flex;justify-content:space-between;align-items:center;
  gap:16px;flex-wrap:wrap;
  position:relative;overflow:hidden;
  box-shadow:var(--s3d);
}
.header::before{
  content:'';position:absolute;
  top:-80px;left:-60px;
  width:320px;height:320px;
  background:radial-gradient(circle,rgba(37,99,235,0.08) 0%,transparent 70%);
  pointer-events:none;
}
.header-left{display:flex;align-items:center;gap:16px;flex:1;min-width:0;}

.logo-box{
  width:64px;height:64px;min-width:64px;
  background:#ffffff;
  border:1px solid var(--border-mid);
  border-radius:var(--r-md);
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;cursor:pointer;flex-shrink:0;
  box-shadow:var(--s3d-sm);
  transition:transform .2s,box-shadow .2s;
}
.logo-box:hover{transform:translateY(-2px);box-shadow:var(--s3d-hover);}
.logo-box img{width:100%;height:100%;object-fit:contain;display:block;padding:6px;}

.header-title{
  font-size:20px;font-weight:700;
  color:var(--text-1);line-height:1.1;
  cursor:pointer;letter-spacing:-.02em;
}
.report-type-wrap{display:flex;align-items:center;gap:8px;margin-top:5px;}
#reportTypeText{
  font-size:13px;font-weight:600;color:var(--text-2);
  cursor:pointer;letter-spacing:.06em;
}
.toggle-btn{
  background:var(--surface-3);border:1px solid var(--border-mid);
  color:var(--text-2);border-radius:100px;
  padding:3px 10px;font-size:10px;cursor:pointer;
  font-family:var(--mono);transition:.2s;letter-spacing:.04em;
  box-shadow:0 2px 0 rgba(0,0,0,0.08),0 1px 0 #fff inset;
}
.toggle-btn:hover{border-color:var(--accent);color:var(--accent);}

.header-right{display:flex;flex-direction:column;align-items:flex-end;gap:10px;}
.date-group{display:flex;gap:10px;}
.date-field label{
  display:block;font-size:10px;color:var(--text-3);
  font-family:var(--mono);letter-spacing:.08em;text-transform:uppercase;margin-bottom:4px;
}
.date-field input[type=date]{
  background:var(--surface-3);border:1px solid var(--border-mid);
  border-radius:var(--r-sm);color:var(--text-1);
  padding:7px 10px;font-size:12px;font-family:var(--mono);
  outline:none;transition:.2s;width:auto;
  box-shadow:0 2px 0 rgba(0,0,0,0.07),0 1px 0 #fff inset;
}
.date-field input[type=date]:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow);}
#departmentTitle{
  font-size:11px;font-weight:500;color:var(--text-3);
  font-family:var(--mono);letter-spacing:.06em;text-transform:uppercase;
  cursor:pointer;border-bottom:1px dashed var(--border-mid);
  padding-bottom:2px;transition:.2s;
}
#departmentTitle:hover{color:var(--text-2);}

/* ── SUMMARY GRID ── */
.summary-grid{
  display:grid;grid-template-columns:repeat(8,1fr);
  gap:10px;margin-top:14px;
}
.summary-card{
  background:linear-gradient(160deg,#fff 60%,#f6f9ff);
  border:1px solid var(--border-mid);
  border-radius:var(--r-md);
  padding:14px 12px 18px;
  position:relative;overflow:hidden;
  display:flex;flex-direction:column;justify-content:space-between;align-items:center;
  min-height:90px;
  box-shadow:var(--s3d-sm);
  transition:transform .18s,box-shadow .18s;
  background-image:
    linear-gradient(160deg,#fff 60%,#f6f9ff),
    repeating-linear-gradient(0deg,transparent,transparent 19px,rgba(0,0,0,0.04) 19px,rgba(0,0,0,0.04) 20px),
    repeating-linear-gradient(90deg,transparent,transparent 19px,rgba(0,0,0,0.04) 19px,rgba(0,0,0,0.04) 20px);
  background-blend-mode:normal,multiply,multiply;
}
.summary-card:hover{transform:translateY(-3px) scale(1.02);box-shadow:var(--s3d-hover);}
.summary-card::after{
  content:'';position:absolute;bottom:0;left:0;right:0;height:3px;
  background:var(--card-accent,var(--accent));border-radius:0 0 var(--r-md) var(--r-md);
}
.summary-card[data-id="ecozum"]{--card-accent:#2563eb;}
.summary-card[data-id="yapilan"]{--card-accent:#059669;}
.summary-card[data-id="rutin"]{--card-accent:#6366f1;}
.summary-card[data-id="devam"]{--card-accent:#d97706;}
.summary-card[data-id="planlanan"]{--card-accent:#7c3aed;}
.summary-card[data-id="bekleyen"]{--card-accent:#dc2626;}
.summary-card[data-id="sorun"]{--card-accent:#db2777;}
.summary-card[data-id="risk"]{--card-accent:#ea580c;}

.summary-card h3{
  font-size:9.5px;font-weight:500;color:var(--text-3);
  letter-spacing:.07em;text-transform:uppercase;
  font-family:var(--mono);line-height:1.3;
  text-align:center;width:100%;
}
.count{
  font-size:26px;font-weight:700;color:var(--text-1);
  margin-top:auto;font-variant-numeric:tabular-nums;letter-spacing:-.03em;
  text-align:center;width:100%;
}
input[type=number]#count-ecozum{
  font-size:26px;font-weight:700;color:var(--text-1);
  margin-top:auto;
  background:transparent;border:none;outline:none;
  padding:0;width:100%;text-align:center;
  font-family:'DM Sans',sans-serif;letter-spacing:-.03em;
}

/* ── PANELS ── */
.panel{
  background:linear-gradient(160deg,#fff 70%,#f4f7ff);
  border:1px solid var(--border-mid);
  border-radius:var(--r-lg);
  margin-top:12px;overflow:hidden;
  box-shadow:var(--s3d);
  transition:transform .18s,box-shadow .18s;
}
.panel:hover{transform:translateY(-2px);box-shadow:var(--s3d-hover);}

.panel-header{
  display:flex;justify-content:space-between;align-items:center;
  padding:14px 18px;
  border-bottom:1px solid var(--border);
  background:linear-gradient(90deg,var(--surface-2),#fff);
}
.panel-title{
  font-size:13px;font-weight:600;color:var(--text-1);
  letter-spacing:-.01em;display:flex;align-items:center;gap:8px;
}
.panel-title-dot{
  width:7px;height:7px;border-radius:50%;
  background:var(--card-accent,var(--accent));flex-shrink:0;
  box-shadow:0 0 0 3px rgba(0,0,0,0.06);
}

/* ── TABLE & ROW DRAG STYLES ── */
table{width:100%;border-collapse:collapse;}
th{
  padding:10px 14px;font-size:10px;
  font-family:var(--mono);font-weight:500;color:var(--text-3);
  letter-spacing:.08em;text-transform:uppercase;text-align:left;
  border-bottom:1.5px solid var(--border-mid);
  background:linear-gradient(90deg,var(--surface-2),#fff);
}
td{
  padding:9px 14px;
  border-bottom:1px solid rgba(0,0,0,0.07);
  vertical-align:top;
}
tr:last-child td{border-bottom:none;}
tr:hover td{background:rgba(37,99,235,0.03);}
td+td,th+th{border-left:1px solid rgba(0,0,0,0.06);}

/* Row Drag Handling */
.row-drag-handle {
  cursor: grab;
  color: var(--text-3);
  font-size: 14px;
  text-align: center;
  vertical-align: middle;
  transition: color 0.2s;
  user-select: none;
}
.row-drag-handle:hover { color: var(--accent); }
.row-drag-handle:active { cursor: grabbing; color: var(--accent); }

/* Sürüklenirken satırın görünümü */
.row-dragging {
  opacity: 0.5;
  background-color: var(--surface-3) !important;
}

td textarea{
  background:transparent;border:none;outline:none;
  color:var(--text-1);font-family:'DM Sans',sans-serif;
  font-size:13px;line-height:1.55;width:100%;
  resize:none;min-height:36px;padding:0;
  overflow:hidden;
}
td textarea::placeholder{color:var(--text-3);}

/* ── BUTTONS ── */
.btn{
  border:none;border-radius:var(--r-sm);cursor:pointer;font-weight:500;
  font-family:'DM Sans',sans-serif;transition:.18s;
  display:inline-flex;align-items:center;gap:6px;letter-spacing:-.01em;
}
.btn:active{transform:translateY(1px)!important;}

.btn-add{
  background:linear-gradient(160deg,#ecfdf5,#d1fae5);
  color:var(--green);border:1px solid rgba(5,150,105,0.25);
  padding:6px 14px;font-size:12px;
  box-shadow:0 2px 0 rgba(5,150,105,0.15),0 1px 0 #fff inset;
}
.btn-add:hover{transform:translateY(-1px);box-shadow:0 4px 0 rgba(5,150,105,0.18),0 1px 0 #fff inset;}

.btn-delete{
  background:linear-gradient(160deg,#fef2f2,#fee2e2);
  color:var(--red);border:1px solid rgba(220,38,38,0.2);
  padding:5px 10px;font-size:11px;
  box-shadow:0 2px 0 rgba(220,38,38,0.12),0 1px 0 #fff inset;
}
.btn-delete:hover{transform:translateY(-1px);box-shadow:0 4px 0 rgba(220,38,38,0.15),0 1px 0 #fff inset;}

.btn-primary{
  background:linear-gradient(160deg,#3b82f6,#2563eb);
  color:#fff;padding:9px 18px;font-size:13px;
  border:1px solid rgba(37,99,235,0.6);
  box-shadow:0 3px 0 #1d4ed8,0 5px 14px rgba(37,99,235,0.3),0 1px 0 rgba(255,255,255,0.25) inset;
}
.btn-primary:hover{background:linear-gradient(160deg,#60a5fa,#3b82f6);transform:translateY(-1px);box-shadow:0 4px 0 #1d4ed8,0 8px 20px rgba(37,99,235,0.35),0 1px 0 rgba(255,255,255,0.25) inset;}

.btn-import{
  background:linear-gradient(160deg,#fff7ed,#ffedd5);
  color:#ea580c;border:1px solid rgba(234,88,12,0.25);
  padding:9px 16px;font-size:13px;
  box-shadow:0 3px 0 rgba(234,88,12,0.18),0 1px 0 #fff inset;
}
.btn-import:hover{transform:translateY(-1px);box-shadow:0 4px 0 rgba(234,88,12,0.22),0 1px 0 #fff inset;}

.btn-export{
  background:linear-gradient(160deg,#eff6ff,#e0e7ff);
  color:#6366f1;border:1px solid rgba(99,102,241,0.25);
  padding:9px 16px;font-size:13px;
  box-shadow:0 3px 0 rgba(99,102,241,0.18),0 1px 0 #fff inset;
}
.btn-export:hover{transform:translateY(-1px);box-shadow:0 4px 0 rgba(99,102,241,0.22),0 1px 0 #fff inset;}

.actions{margin-top:14px;display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
.actions-label{font-size:10px;color:var(--text-3);font-family:var(--mono);letter-spacing:.07em;text-transform:uppercase;margin-right:4px;}

/* ── PREVIEW ── */
.preview-area{
  margin-top:16px;
  background:linear-gradient(160deg,#fff 70%,#f4f7ff);
  border:1px solid var(--border-mid);
  border-radius:var(--r-lg);padding:20px;
  box-shadow:var(--s3d);
}

/* ── PRINT ── */
@page{size:A4 landscape;margin:0.7cm;}
@media print{
  body{background:#fff;padding:0;background-image:none;}
  .header,.panel,.actions,.summary-grid,#sections{display:none!important;}
  .preview-area{margin:0;padding:0;border:none;background:transparent;box-shadow:none;}
  .print-hide{display:none!important;}
  td{padding:5px!important;word-break:break-word;}
  table{border-collapse:collapse;}
  th,td{border:1px solid #e2e8f0!important;}
}
</style>
</head>
<body>
<div class="container">

<div class="header">
  <div class="header-left">
    <div class="logo-box" id="logoBox">
      <img id="logoImage" src="logo.jpg" alt="Logo" onerror="this.style.display='none'">
      <input type="file" id="logoInput" accept="image/*" style="display:none;">
    </div>
    <div>
      <div id="mainTitle" class="header-title editable-title">Kullanıcı Destek Koordinatörlüğü</div>
      <div class="report-type-wrap">
        <div id="reportTypeText" class="editable-title">HAFTALIK FAALİYET RAPORU</div>
        <button class="toggle-btn" onclick="toggleReportType()">↺ değiştir</button>
      </div>
    </div>
  </div>
  <div class="header-right">
    <div class="date-group">
      <div class="date-field"><label>Başlangıç</label><input type="date" id="startDate"></div>
      <div class="date-field"><label>Bitiş</label><input type="date" id="endDate"></div>
    </div>
    <div id="departmentTitle" class="editable-title">TEKNİK İŞLETME DAİRE BAŞKANLIĞI</div>
  </div>
</div>

<div class="summary-grid" id="mainSummaryGrid">
  <div class="summary-card" data-id="ecozum">
    <h3>E-Çözüm<br>Talepleri</h3>
    <input type="number" id="count-ecozum" value="0" min="0">
  </div>
  <div class="summary-card" data-id="yapilan"><h3>Yapılan<br>İşler</h3><div class="count" id="count-yapilan">0</div></div>
  <div class="summary-card" data-id="rutin"><h3>Rutin<br>İşler</h3><div class="count" id="count-rutin">0</div></div>
  <div class="summary-card" data-id="devam"><h3>Devam Eden<br>İşler</h3><div class="count" id="count-devam">0</div></div>
  <div class="summary-card" data-id="planlanan"><h3>Planlanan<br>İşler</h3><div class="count" id="count-planlanan">0</div></div>
  <div class="summary-card" data-id="bekleyen"><h3>Bekleyen<br>İşler</h3><div class="count" id="count-bekleyen">0</div></div>
  <div class="summary-card" data-id="sorun"><h3>Yaşanan<br>Sorunlar</h3><div class="count" id="count-sorun">0</div></div>
  <div class="summary-card" data-id="risk"><h3>Problemler<br>/ Riskler</h3><div class="count" id="count-risk">0</div></div>
</div>

<div id="sections"></div>

<div class="actions">
  <span class="actions-label">İşlemler</span>
  <button class="btn btn-primary" onclick="refreshPreview()">▶ Önizleme</button>
  <button class="btn btn-import" onclick="document.getElementById('importCsvInput').click()">↑ İçeri Aktar</button>
  <button class="btn btn-export" onclick="exportCSV()">↓ CSV Dışa</button>
  <input type="file" id="importCsvInput" accept=".csv" style="display:none;">
</div>

<div class="preview-area">
  <div id="previewContent">
    <div style="text-align:center;padding:40px 0;color:#94a3b8;font-family:'DM Mono',monospace;font-size:12px;letter-spacing:.05em;">
      — ÖNİZLEME OLUŞTURMAK İÇİN YUKARIDAKI BUTONA TIKLAYINIZ —
    </div>
  </div>
</div>

</div>
<script>
const sectionDefinitions=[
  {id:'yapilan',title:'Yapılan İşler',color:'#059669', cardLines:['Yapılan', 'İşler']},
  {id:'rutin',title:'Rutin İşler',color:'#6366f1', cardLines:['Rutin', 'İşler']},
  {id:'devam',title:'Devam Eden İşler',color:'#d97706', cardLines:['Devam Eden', 'İşler']},
  {id:'planlanan',title:'Planlanan İşler',color:'#7c3aed', cardLines:['Planlanan', 'İşler']},
  {id:'bekleyen',title:'Bekleyen İşler',color:'#dc2626', cardLines:['Bekleyen', 'İşler']},
  {id:'sorun',title:'Yaşanan Sorunlar',color:'#db2777', cardLines:['Yaşanan', 'Sorunlar']},
  {id:'risk',title:'Problemler / Riskler',color:'#ea580c', cardLines:['Problemler', '/ Riskler']}
];

function createSections(){
  const container=document.getElementById('sections');
  sectionDefinitions.forEach(section=>{
    const panel=document.createElement('div');
    panel.className='panel';
    panel.style.setProperty('--card-accent',section.color);
    panel.innerHTML=`
      <div class="panel-header">
        <div class="panel-title">
          <span class="panel-title-dot" style="background:${section.color}"></span>
          ${section.title}
        </div>
        <button class="btn btn-add" onclick="addRow('${section.id}')">+ Satır Ekle</button>
      </div>
      <table id="table-${section.id}">
        <thead><tr>
          <th style="width:30px;text-align:center;"></th>
          <th style="width:100%">Açıklama</th>
          <th style="width:80px;text-align:center;">Sil</th>
        </tr></thead>
        <tbody></tbody>
      </table>`;
    container.appendChild(panel);
    addRow(section.id);
  });
}

function autoResize(el){el.style.height='auto';el.style.height=el.scrollHeight+'px';}

function addRow(sectionId,text=''){
  const tbody=document.querySelector(`#table-${sectionId} tbody`);
  const row=document.createElement('tr');
  row.innerHTML=`
    <td class="row-drag-handle" title="Sürükle ve Bırak">☰</td>
    <td><textarea placeholder="Açıklama giriniz…">${text}</textarea></td>
    <td style="width:80px;vertical-align:middle;text-align:center;">
      <button class="btn btn-delete" onclick="removeRow(this,'${sectionId}')">✕</button>
    </td>`;
  tbody.appendChild(row);

  const handle = row.querySelector('.row-drag-handle');
  handle.addEventListener('mousedown', () => row.setAttribute('draggable', 'true'));
  handle.addEventListener('mouseup', () => row.removeAttribute('draggable'));
  handle.addEventListener('mouseleave', () => row.removeAttribute('draggable'));

  const ta=row.querySelector('textarea');
  ta.addEventListener('input',()=>{autoResize(ta);updateCounts();});
  if(text)autoResize(ta);
  updateCounts();
}

function removeRow(button,sectionId){
  const tbody=document.querySelector(`#table-${sectionId} tbody`);
  if(tbody.rows.length===1){tbody.rows[0].querySelector('textarea').value='';updateCounts();return;}
  button.closest('tr').remove();
  updateCounts();
}

function updateCounts(){
  sectionDefinitions.forEach(section=>{
    let total=0;
    document.querySelectorAll(`#table-${section.id} tbody tr`).forEach(row=>{
      if(row.querySelector('textarea').value.trim()!=='')total++;
    });
    document.getElementById(`count-${section.id}`).innerText=total;
  });
}

// --- Row Drag and Drop Logic ---
function initRowDragAndDrop() {
  const container = document.getElementById('sections');
  let draggedRow = null;

  container.addEventListener('dragstart', e => {
    draggedRow = e.target.closest('tr');
    if (draggedRow) {
      e.dataTransfer.effectAllowed = 'move';
      e.dataTransfer.setData('text/plain', 'dragged'); 
      setTimeout(() => draggedRow.classList.add('row-dragging'), 0);
    }
  });

  container.addEventListener('dragover', e => {
    e.preventDefault(); 
    if (!draggedRow) return;

    const tbody = draggedRow.closest('tbody');
    const targetTbody = e.target.closest('tbody');
    
    if (!targetTbody || tbody !== targetTbody) return;

    const afterElement = getDragAfterRow(tbody, e.clientY);
    if (afterElement == null) {
      tbody.appendChild(draggedRow);
    } else {
      tbody.insertBefore(draggedRow, afterElement);
    }
  });

  container.addEventListener('dragend', e => {
    if (draggedRow) {
      draggedRow.classList.remove('row-dragging');
      draggedRow.removeAttribute('draggable'); 
      draggedRow = null;
      
      if(document.getElementById('previewContent').innerHTML.includes('print-hide')){
         refreshPreview(); 
      }
    }
  });

  function getDragAfterRow(tbody, y) {
    const draggableElements = [...tbody.querySelectorAll('tr:not(.row-dragging)')];
    return draggableElements.reduce((closest, child) => {
      const box = child.getBoundingClientRect();
      const offset = y - box.top - box.height / 2;
      if (offset < 0 && offset > closest.offset) {
        return { offset: offset, element: child };
      } else {
        return closest;
      }
    }, { offset: Number.NEGATIVE_INFINITY }).element;
  }
}
// --------------------------------

function formatDate(d){return new Date(d).toLocaleDateString('tr-TR');}
function toggleReportType(){
  const t=document.getElementById('reportTypeText');
  t.innerText=t.innerText.includes('HAFTALIK')?'AYLIK FAALİYET RAPORU':'HAFTALIK FAALİYET RAPORU';
}

function refreshPreview(){
  updateCounts();
  const preview=document.getElementById('previewContent');
  const start=document.getElementById('startDate').value;
  const end=document.getElementById('endDate').value;
  let dateText='—';
  if(start&&end)dateText=`${formatDate(start)} – ${formatDate(end)}`;

  const ruledBg=`repeating-linear-gradient(0deg,transparent,transparent 19px,rgba(0,0,0,0.05) 19px,rgba(0,0,0,0.05) 20px),repeating-linear-gradient(90deg,transparent,transparent 39px,rgba(0,0,0,0.04) 39px,rgba(0,0,0,0.04) 40px)`;
  const cardStyle = `background:#fff;border:1px solid rgba(0,0,0,0.12);border-radius:10px;padding:12px 8px;position:relative;overflow:hidden;box-shadow:0 1px 0 #fff inset,0 3px 0 rgba(0,0,0,0.10),0 4px 10px rgba(0,0,0,0.08);background-image:${ruledBg};background-blend-mode:normal;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;min-height:70px;`;
  const labelStyle = `font-size:9px;color:#94a3b8;font-family:'DM Mono',monospace;letter-spacing:.07em;text-transform:uppercase;position:relative;line-height:1.4;text-align:center;`;
  const countStyle = `font-size:22px;font-weight:700;color:#0f172a;margin-top:6px;position:relative;text-align:center;`;

  let html=`
  <div style="background:linear-gradient(160deg,#fff 60%,#f0f4ff);border:1px solid rgba(0,0,0,0.12);border-radius:16px;padding:16px 20px;display:flex;justify-content:space-between;align-items:center;gap:16px;box-shadow:0 1px 0 #fff inset,0 4px 0 rgba(0,0,0,0.10),0 6px 16px rgba(0,0,0,0.09);">
    <div style="display:flex;align-items:center;gap:14px;">
      <div style="width:52px;height:52px;background:#f1f5f9;border-radius:10px;overflow:hidden;border:1px solid rgba(0,0,0,0.1);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 0 rgba(0,0,0,0.08);">
        <img src="${document.getElementById('logoImage').src}" style="width:100%;height:100%;object-fit:contain;">
      </div>
      <div>
        <div style="font-size:17px;font-weight:700;color:#0f172a;letter-spacing:-.02em;">${document.getElementById('mainTitle').innerText}</div>
        <div style="font-size:11px;color:#64748b;font-family:'DM Mono',monospace;margin-top:3px;">${document.getElementById('reportTypeText').innerText}</div>
        <div style="font-size:11px;color:#94a3b8;font-family:'DM Mono',monospace;margin-top:2px;">${dateText}</div>
      </div>
    </div>
    <div style="font-size:10px;font-weight:500;color:#94a3b8;font-family:'DM Mono',monospace;letter-spacing:.06em;text-align:right;text-transform:uppercase;">${document.getElementById('departmentTitle').innerText}</div>
  </div>

  <div style="display:grid;grid-template-columns:repeat(8,1fr);gap:8px;margin-top:10px;">`;

  html+=`<div style="${cardStyle}">
      <div style="position:absolute;bottom:0;left:0;right:0;height:3px;background:#2563eb;border-radius:0 0 10px 10px;"></div>
      <div style="${labelStyle}">E-Çözüm<br>Talepleri</div>
      <div style="${countStyle}">${document.getElementById('count-ecozum').value}</div>
    </div>`;

  sectionDefinitions.forEach(section => {
    html+=`<div style="${cardStyle}">
      <div style="position:absolute;bottom:0;left:0;right:0;height:3px;background:${section.color};border-radius:0 0 10px 10px;"></div>
      <div style="${labelStyle}">${section.cardLines[0]}<br>${section.cardLines[1]}</div>
      <div style="${countStyle}">${document.getElementById(`count-${section.id}`).innerText}</div>
    </div>`;
  });
  html+=`</div>`;

  sectionDefinitions.forEach((section,i)=>{
    const rows=[...document.querySelectorAll(`#table-${section.id} textarea`)].filter(t=>t.value.trim()!=='');
    if(rows.length===0)return;
    html+=`
    <div style="margin-top:12px;">
      <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;">
        <span style="width:7px;height:7px;border-radius:50%;background:${section.color};display:inline-block;flex-shrink:0;box-shadow:0 0 0 3px rgba(0,0,0,0.06);"></span>
        <span style="font-size:12px;font-weight:600;color:#475569;font-family:'DM Mono',monospace;letter-spacing:.04em;text-transform:uppercase;">${section.title}</span>
      </div>
      <div style="background:linear-gradient(160deg,#fff 70%,#f4f7ff);border:1px solid rgba(0,0,0,0.12);border-radius:10px;overflow:hidden;box-shadow:0 1px 0 #fff inset,0 3px 0 rgba(0,0,0,0.09),0 4px 10px rgba(0,0,0,0.07);">
        <table style="width:100%;border-collapse:collapse;">
          <tbody>
            ${rows.map((row,ri)=>`
            <tr>
              <td style="padding:9px 14px;border-bottom:${ri<rows.length-1?'1px solid rgba(0,0,0,0.07)':'none'};font-size:12px;color:#334155;vertical-align:top;">
                <div style="display:flex; gap:10px;">
                  <span style="color:${section.color};font-family:'DM Mono',monospace;font-size:10px;font-weight:500;padding-top:2px;flex-shrink:0;">${String(ri+1).padStart(2,'0')}</span>
                  <div style="line-height:1.6; word-break:break-word;">${row.value.replace(/\n/g, '<br>')}</div>
                </div>
              </td>
            </tr>`).join('')}
          </tbody>
        </table>
      </div>
    </div>`;
  });

  html+=`
  <div class="print-hide" style="display:flex;justify-content:flex-end;margin-top:20px;">
    <button onclick="window.print()" style="background:linear-gradient(160deg,#3b82f6,#2563eb);color:#fff;padding:9px 20px;font-size:13px;border:1px solid rgba(37,99,235,0.6);border-radius:8px;cursor:pointer;font-family:'DM Sans',sans-serif;font-weight:500;box-shadow:0 3px 0 #1d4ed8,0 5px 14px rgba(37,99,235,0.3);">⎙ Yazdır / PDF</button>
  </div>`;

  preview.innerHTML=html;
}

function exportCSV(){
  let csv='\uFEFF';
  sectionDefinitions.forEach(section=>{
    csv+=`"${section.title}"\n`;
    document.querySelectorAll(`#table-${section.id} textarea`).forEach(t=>{
      // CSV'de de satır atlamalarının korunması için replace(\n, '') yerine doğrudan veriyi dahil ediyoruz
      csv+=`"${t.value.replace(/"/g,'""')}"\n`;
    });
    csv+='\n';
  });
  const blob=new Blob([csv],{type:'text/csv;charset=utf-8;'});
  const url=URL.createObjectURL(blob);
  const link=document.createElement('a');
  link.href=url;link.download='Faaliyet_Raporu.csv';link.click();
  URL.revokeObjectURL(url);
}

function importCSV(event){
  const file=event.target.files[0];if(!file)return;
  const reader=new FileReader();
  reader.onload=function(e){
    const lines=e.target.result.split(/\r?\n/);
    sectionDefinitions.forEach(s=>{document.querySelector(`#table-${s.id} tbody`).innerHTML='';});
    let cur='';
    const map={'Yapılan İşler':'yapilan','Rutin İşler':'rutin','Devam Eden İşler':'devam',
      'Planlanan İşler':'planlanan','Bekleyen İşler':'bekleyen','Yaşanan Sorunlar':'sorun',
      'Problemler / Riskler':'risk'};
    
    // Çok satırlı (multiline) CSV verilerini okuyabilmek için basit parse yerine gelişmiş mantık gerekebilir 
    // Ancak basit tutmak adına mevcut döngü korundu. (Excel importlarında bazen birden fazla satıra bölebilir)
    lines.forEach(line=>{
      const clean=line.trim().replace(/^"/,'').replace(/"$/,'');
      if(map[clean]){cur=map[clean];return;}
      if(clean!==''&&cur)addRow(cur,clean.replace(/""/g,'"'));
    });
    sectionDefinitions.forEach(s=>{
      if(document.querySelector(`#table-${s.id} tbody`).rows.length===0)addRow(s.id);
    });
    updateCounts();refreshPreview();
    alert('CSV başarıyla içeri aktarıldı.');
  };
  reader.readAsText(file,'utf-8');
}

function enableFiveClickEdit(id){
  const el=document.getElementById(id);let count=0;
  el.addEventListener('click',()=>{
    count++;
    if(count>=5){
      const input=document.createElement('input');
      input.value=el.innerText;
      input.style.cssText='background:transparent;border:none;border-bottom:1px solid #2563eb;color:inherit;font:inherit;outline:none;width:100%;';
      el.replaceWith(input);input.focus();
      input.addEventListener('blur',()=>{
        const newEl=document.createElement(el.tagName||'div');
        newEl.id=id;newEl.className=el.className;newEl.style.cssText=el.style.cssText;
        newEl.innerText=input.value;input.replaceWith(newEl);
        enableFiveClickEdit(id);
      });
      count=0;
    }
  });
}

function enableLogoChange(){
  const box=document.getElementById('logoBox');
  const input=document.getElementById('logoInput');
  const img=document.getElementById('logoImage');
  let count=0;
  box.addEventListener('click',()=>{count++;if(count>=5){input.click();count=0;}});
  input.addEventListener('change',e=>{
    const file=e.target.files[0];
    if(file){const r=new FileReader();r.onload=ev=>{img.style.display='';img.src=ev.target.result;};r.readAsDataURL(file);}
  });
}

document.getElementById('importCsvInput').addEventListener('change',importCSV);
createSections();
initRowDragAndDrop(); 
enableFiveClickEdit('mainTitle');
enableFiveClickEdit('reportTypeText');
enableFiveClickEdit('departmentTitle');
enableLogoChange();
</script>
</body>
</html>


Kaynaklar:
* ChatGPT
* Claude