667 lines
37 KiB
PHP
667 lines
37 KiB
PHP
<!DOCTYPE html>
|
||
<html lang="tr" class="scroll-smooth">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||
<meta name="robots" content="noindex, nofollow">
|
||
<title>{{ $project->title }} - Canlı Proje Takip Portalı | Trunçgil Teknoloji</title>
|
||
|
||
<!-- Google Fonts: Inter & Outfit -->
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||
|
||
<!-- Tailwind CSS -->
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
|
||
<script>
|
||
tailwind.config = {
|
||
darkMode: 'class',
|
||
theme: {
|
||
extend: {
|
||
fontFamily: {
|
||
sans: ['Inter', 'sans-serif'],
|
||
display: ['Outfit', 'sans-serif'],
|
||
},
|
||
colors: {
|
||
brand: {
|
||
50: '#fff7ed',
|
||
100: '#ffedd5',
|
||
500: '#f97316',
|
||
600: '#ea580c',
|
||
700: '#c2410c',
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style type="text/css">
|
||
.glass-header {
|
||
background: rgba(255, 255, 255, 0.8);
|
||
backdrop-filter: blur(12px);
|
||
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
||
}
|
||
.dark .glass-header {
|
||
background: rgba(15, 23, 42, 0.8);
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||
}
|
||
.glass-card {
|
||
background: rgba(255, 255, 255, 0.7);
|
||
backdrop-filter: blur(8px);
|
||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||
}
|
||
.dark .glass-card {
|
||
background: rgba(30, 41, 59, 0.7);
|
||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||
}
|
||
.mermaid-container {
|
||
background: #ffffff;
|
||
border-radius: 16px;
|
||
margin: 1.5rem 0;
|
||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.05);
|
||
overflow: hidden;
|
||
position: relative;
|
||
}
|
||
.dark .mermaid-container {
|
||
background: #0f172a;
|
||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||
}
|
||
.mermaid-toolbar {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 10px 16px;
|
||
background: rgba(248, 250, 252, 0.9);
|
||
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
||
}
|
||
.dark .mermaid-toolbar {
|
||
background: rgba(15, 23, 42, 0.9);
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||
}
|
||
.mermaid-canvas {
|
||
width: 100%;
|
||
height: 480px;
|
||
position: relative;
|
||
overflow: hidden;
|
||
cursor: grab;
|
||
}
|
||
.mermaid-canvas:active { cursor: grabbing; }
|
||
|
||
/* Mermaid Theme Customization */
|
||
.mermaid svg .task {
|
||
fill: #ea580c !important;
|
||
stroke: #c2410c !important;
|
||
rx: 6px !important;
|
||
ry: 6px !important;
|
||
}
|
||
.mermaid svg .task0, .mermaid svg .task2 {
|
||
fill: #ea580c !important;
|
||
stroke: #c2410c !important;
|
||
}
|
||
.mermaid svg .task1, .mermaid svg .task3 {
|
||
fill: #ef4444 !important;
|
||
stroke: #b91c1c !important;
|
||
}
|
||
.mermaid svg .taskText {
|
||
fill: #ffffff !important;
|
||
font-family: 'Inter', sans-serif !important;
|
||
font-weight: 600 !important;
|
||
}
|
||
.mermaid svg .section0, .mermaid svg .section2 {
|
||
fill: rgba(234, 88, 12, 0.08) !important;
|
||
}
|
||
.dark .mermaid svg .section0, .dark .mermaid svg .section2 {
|
||
fill: rgba(234, 88, 12, 0.18) !important;
|
||
}
|
||
.mermaid svg .section1, .mermaid svg .section3 {
|
||
fill: rgba(239, 68, 68, 0.08) !important;
|
||
}
|
||
.dark .mermaid svg .section1, .dark .mermaid svg .section3 {
|
||
fill: rgba(239, 68, 68, 0.18) !important;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 min-h-screen font-sans transition-colors duration-300">
|
||
|
||
<!-- Header Navigation -->
|
||
<header class="sticky top-0 z-40 w-full glass-header">
|
||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-18 flex items-center justify-between py-4">
|
||
|
||
<!-- Logos -->
|
||
<div class="flex items-center gap-3">
|
||
<a href="https://www.truncgil.com.tr" target="_blank" class="flex items-center gap-2">
|
||
<img src="{{ asset('logos/truncgil-yatay.svg') }}" alt="Trunçgil Teknoloji" class="h-8 w-auto dark:hidden">
|
||
<img src="{{ asset('logos/truncgil-yatay-dark.svg') }}" alt="Trunçgil Teknoloji" class="h-8 w-auto hidden dark:block">
|
||
</a>
|
||
<div class="h-6 w-px bg-slate-300 dark:bg-slate-700"></div>
|
||
<div class="flex flex-col">
|
||
<span class="text-xs font-bold uppercase tracking-wider text-orange-600 dark:text-orange-400">Canlı Proje Takip Portalı</span>
|
||
<span class="text-sm font-semibold text-slate-700 dark:text-slate-200 line-clamp-1">{{ $project->client_name }}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Right Controls -->
|
||
<div class="flex items-center gap-3">
|
||
@if($project->proposal)
|
||
<a href="{{ route('proposals.show', $project->proposal->slug) }}" target="_blank" class="px-3.5 py-1.5 rounded-xl bg-orange-50 dark:bg-orange-950/40 text-orange-600 dark:text-orange-400 border border-orange-200 dark:border-orange-800/40 text-xs font-bold hover:bg-orange-100 transition-all flex items-center gap-1.5">
|
||
<i data-lucide="file-text" class="w-3.5 h-3.5"></i>
|
||
<span>Sözleşme / Teklif</span>
|
||
</a>
|
||
@endif
|
||
|
||
<button id="theme-toggle" class="p-2 rounded-xl border border-slate-200 dark:border-slate-800 hover:bg-slate-100 dark:hover:bg-slate-800 transition-all">
|
||
<i data-lucide="sun" id="theme-toggle-light-icon" class="w-4 h-4 text-amber-500 hidden"></i>
|
||
<i data-lucide="moon" id="theme-toggle-dark-icon" class="w-4 h-4 text-slate-600 hidden"></i>
|
||
</button>
|
||
</div>
|
||
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Main Container -->
|
||
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-8">
|
||
|
||
<!-- Hero Section & Progress Banner -->
|
||
<div class="relative overflow-hidden rounded-3xl bg-gradient-to-br from-slate-900 via-slate-800 to-orange-950 text-white p-6 sm:p-10 shadow-2xl border border-slate-800">
|
||
<div class="absolute -top-24 -right-24 w-96 h-96 bg-orange-600/20 rounded-full blur-3xl pointer-events-none"></div>
|
||
|
||
<div class="relative z-10 grid grid-cols-1 lg:grid-cols-12 gap-8 items-center">
|
||
<!-- Left: Title & Info -->
|
||
<div class="lg:col-span-8 space-y-4">
|
||
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-orange-500/20 border border-orange-500/30 text-orange-300 text-xs font-bold uppercase tracking-wider">
|
||
<span class="w-2 h-2 rounded-full bg-orange-400 animate-ping"></span>
|
||
<span>MÜŞTERİ CANLI TAKİP PANELİ</span>
|
||
</div>
|
||
|
||
<h1 class="text-2xl sm:text-4xl font-extrabold font-display leading-tight text-white">
|
||
{{ $project->title }}
|
||
</h1>
|
||
|
||
<p class="text-sm sm:text-base text-slate-300 font-medium">
|
||
Bu ekran, <strong>{{ $project->client_name }}</strong> projesine ait iş takvimini, tamamlanan hizmet modüllerini ve canlı Kanban görev akışını şeffaf biçimde sunmaktadır.
|
||
</p>
|
||
|
||
<!-- Meta Tags -->
|
||
<div class="flex flex-wrap items-center gap-4 text-xs font-semibold pt-2 text-slate-300">
|
||
@if($project->start_date)
|
||
<div class="flex items-center gap-1.5 bg-slate-800/80 px-3 py-1.5 rounded-xl border border-slate-700">
|
||
<i data-lucide="calendar" class="w-3.5 h-3.5 text-orange-400"></i>
|
||
<span>Başlangıç: {{ $project->start_date->format('d.m.Y') }}</span>
|
||
</div>
|
||
@endif
|
||
|
||
@if($project->target_date)
|
||
<div class="flex items-center gap-1.5 bg-slate-800/80 px-3 py-1.5 rounded-xl border border-slate-700">
|
||
<i data-lucide="flag" class="w-3.5 h-3.5 text-rose-400"></i>
|
||
<span>Hedef Bitiş: {{ $project->target_date->format('d.m.Y') }}</span>
|
||
</div>
|
||
@endif
|
||
|
||
<div class="flex items-center gap-1.5 bg-orange-500/20 px-3 py-1.5 rounded-xl border border-orange-500/40 text-orange-300">
|
||
<i data-lucide="key" class="w-3.5 h-3.5"></i>
|
||
<span>Müşteri PIN: <strong>{{ $project->client_access_code }}</strong></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Right: Progress Meter -->
|
||
<div class="lg:col-span-4 flex flex-col items-center justify-center p-6 bg-slate-800/60 backdrop-blur-md rounded-2xl border border-slate-700/60 shadow-inner">
|
||
<span class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-2">GENEL PROJE İLERLEMESİ</span>
|
||
|
||
<!-- Progress Donut/Bar -->
|
||
<div class="text-5xl font-extrabold font-display text-transparent bg-clip-text bg-gradient-to-r from-orange-400 to-rose-400 mb-3">
|
||
%{{ $project->progress_percent }}
|
||
</div>
|
||
|
||
<div class="w-full bg-slate-700 h-3 rounded-full overflow-hidden mb-3">
|
||
<div class="bg-gradient-to-r from-orange-500 to-rose-500 h-full rounded-full transition-all duration-1000 shadow-lg shadow-orange-500/50" style="width: {{ $project->progress_percent }}%"></div>
|
||
</div>
|
||
|
||
<span class="text-xs text-slate-300 font-medium text-center">
|
||
@if($project->progress_percent >= 100)
|
||
🎉 Proje %100 Başarıyla Tamamlandı!
|
||
@elseif($project->progress_percent >= 50)
|
||
⚡ Proje Geliştirmeleri Hızla Devam Ediyor
|
||
@else
|
||
🚀 Faz 1 Çalışmaları Başlatıldı
|
||
@endif
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Interactive Section Tabs -->
|
||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||
<a href="#gantt-section" class="glass-card p-4 rounded-2xl hover:border-orange-500/50 transition-all flex items-center gap-3">
|
||
<div class="w-10 h-10 rounded-xl bg-orange-500/10 text-orange-600 dark:text-orange-400 flex items-center justify-center font-bold">
|
||
<i data-lucide="gantt-chart-square" class="w-5 h-5"></i>
|
||
</div>
|
||
<div>
|
||
<h4 class="text-sm font-bold text-slate-900 dark:text-white">İş Takvimi (Gantt)</h4>
|
||
<p class="text-xs text-slate-500">12 Haftalık Zaman Çizelgesi</p>
|
||
</div>
|
||
</a>
|
||
|
||
<a href="#modules-section" class="glass-card p-4 rounded-2xl hover:border-orange-500/50 transition-all flex items-center gap-3">
|
||
<div class="w-10 h-10 rounded-xl bg-rose-500/10 text-rose-600 dark:text-rose-400 flex items-center justify-center font-bold">
|
||
<i data-lucide="layers" class="w-5 h-5"></i>
|
||
</div>
|
||
<div>
|
||
<h4 class="text-sm font-bold text-slate-900 dark:text-white">Hizmet Modülleri</h4>
|
||
<p class="text-xs text-slate-500">{{ $project->modules->where('status', 'completed')->count() }} / {{ $project->modules->count() }} Modül Bitti</p>
|
||
</div>
|
||
</a>
|
||
|
||
<a href="#kanban-section" class="glass-card p-4 rounded-2xl hover:border-orange-500/50 transition-all flex items-center gap-3">
|
||
<div class="w-10 h-10 rounded-xl bg-amber-500/10 text-amber-600 dark:text-amber-400 flex items-center justify-center font-bold">
|
||
<i data-lucide="kanban-square" class="w-5 h-5"></i>
|
||
</div>
|
||
<div>
|
||
<h4 class="text-sm font-bold text-slate-900 dark:text-white">Kanban Panosu</h4>
|
||
<p class="text-xs text-slate-500">{{ $project->tasks->count() }} Adet Görev Kartı</p>
|
||
</div>
|
||
</a>
|
||
|
||
<a href="#updates-section" class="glass-card p-4 rounded-2xl hover:border-orange-500/50 transition-all flex items-center gap-3">
|
||
<div class="w-10 h-10 rounded-xl bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 flex items-center justify-center font-bold">
|
||
<i data-lucide="activity" class="w-5 h-5"></i>
|
||
</div>
|
||
<div>
|
||
<h4 class="text-sm font-bold text-slate-900 dark:text-white">Canlı Log Akışı</h4>
|
||
<p class="text-xs text-slate-500">{{ $project->updates->count() }} İlerleme Duyurusu</p>
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
<!-- Section 1: Gantt Chart -->
|
||
<section id="gantt-section" class="glass-card rounded-3xl p-6 sm:p-8 space-y-4">
|
||
<div class="flex items-center justify-between border-b border-slate-200 dark:border-slate-800 pb-4">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-8 h-8 rounded-xl bg-orange-600 text-white flex items-center justify-center font-bold">
|
||
<i data-lucide="calendar" class="w-4 h-4"></i>
|
||
</div>
|
||
<div>
|
||
<h2 class="text-lg font-bold text-slate-900 dark:text-white font-display">1. İş Takvimi ve Gantt Çizelgesi</h2>
|
||
<p class="text-xs text-slate-500">Proje aşamalarının ve geliştirme süreçlerinin zamansal planı</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Mermaid Gantt Container -->
|
||
<div class="mermaid-container no-print">
|
||
<div class="mermaid-toolbar">
|
||
<span class="text-xs font-bold uppercase tracking-wider text-slate-400">GANTT ZAMAN ÇİZELGESİ</span>
|
||
<div class="ml-auto flex items-center gap-2">
|
||
<button onclick="zoomGantt('out')" class="p-1.5 rounded-lg border border-slate-200 dark:border-slate-800 hover:bg-slate-100 dark:hover:bg-slate-800 text-xs font-bold">Zoom -</button>
|
||
<span id="gantt-zoom-pct" class="text-xs font-mono text-slate-500">100%</span>
|
||
<button onclick="zoomGantt('in')" class="p-1.5 rounded-lg border border-slate-200 dark:border-slate-800 hover:bg-slate-100 dark:hover:bg-slate-800 text-xs font-bold">Zoom +</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mermaid-canvas" id="gantt-canvas">
|
||
<div class="mermaid w-full h-full">
|
||
gantt
|
||
title {{ $project->title }} (İş Takvimi)
|
||
dateFormat YYYY-MM-DD
|
||
section Faz 1: İş Takip & WhatsApp Otomasyonu
|
||
Backend REST API & Veritabanı :a1, 2026-08-01, 21d
|
||
Flutter Responsive Kanban Board :a2, after a1, 21d
|
||
WhatsApp API & AI NLP Parser :a3, after a2, 14d
|
||
AI Görsel Analiz & PDF Raporlama :a4, after a3, 14d
|
||
section Faz 2: CMS Migrasyonu & Web Sync
|
||
Citrus CMS Migrasyonu & Formlar :b1, 2026-10-10, 7d
|
||
Portfolyo Web Sync & Nihai Testler :b2, after b1, 7d
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Section 2: Modules Completion Matrix -->
|
||
<section id="modules-section" class="glass-card rounded-3xl p-6 sm:p-8 space-y-6">
|
||
<div class="flex items-center justify-between border-b border-slate-200 dark:border-slate-800 pb-4">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-8 h-8 rounded-xl bg-rose-600 text-white flex items-center justify-center font-bold">
|
||
<i data-lucide="check-square" class="w-4 h-4"></i>
|
||
</div>
|
||
<div>
|
||
<h2 class="text-lg font-bold text-slate-900 dark:text-white font-display">2. Hizmet Modülleri İlerleme Matrisi</h2>
|
||
<p class="text-xs text-slate-500">Sözleşmedeki hizmet kalemlerinin tamamlanma ve gidişat durumları</p>
|
||
</div>
|
||
</div>
|
||
<span class="text-xs font-bold px-3 py-1 rounded-full bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300">
|
||
Toplam {{ $project->modules->count() }} Modül
|
||
</span>
|
||
</div>
|
||
|
||
<!-- Modules Grid -->
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
@forelse($project->modules as $module)
|
||
<div class="p-5 rounded-2xl border transition-all duration-300 {{ $module->status === 'completed' ? 'bg-emerald-50/40 dark:bg-emerald-950/20 border-emerald-500/30' : ($module->status === 'in_progress' ? 'bg-orange-50/40 dark:bg-orange-950/20 border-orange-500/30' : 'bg-slate-100/50 dark:bg-slate-800/40 border-slate-200 dark:border-slate-800') }}">
|
||
<div class="flex items-start justify-between gap-3 mb-3">
|
||
<div class="flex items-center gap-2.5">
|
||
@if($module->status === 'completed')
|
||
<div class="w-6 h-6 rounded-full bg-emerald-500 text-white flex items-center justify-center flex-shrink-0">
|
||
<i data-lucide="check" class="w-3.5 h-3.5"></i>
|
||
</div>
|
||
@elseif($module->status === 'in_progress')
|
||
<div class="w-6 h-6 rounded-full bg-orange-500 text-white flex items-center justify-center flex-shrink-0 animate-pulse">
|
||
<i data-lucide="play" class="w-3 h-3"></i>
|
||
</div>
|
||
@else
|
||
<div class="w-6 h-6 rounded-full bg-slate-300 dark:bg-slate-700 text-slate-600 dark:text-slate-400 flex items-center justify-center flex-shrink-0">
|
||
<i data-lucide="clock" class="w-3.5 h-3.5"></i>
|
||
</div>
|
||
@endif
|
||
<h3 class="font-bold text-slate-900 dark:text-white text-base">
|
||
{{ $module->title }}
|
||
</h3>
|
||
</div>
|
||
|
||
<span class="text-xs font-extrabold px-2.5 py-1 rounded-lg {{ $module->status === 'completed' ? 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400' : ($module->status === 'in_progress' ? 'bg-orange-500/10 text-orange-600 dark:text-orange-400' : 'bg-slate-200 dark:bg-slate-700 text-slate-600 dark:text-slate-400') }}">
|
||
@if($module->status === 'completed') TAMAMLANDI @elseif($module->status === 'in_progress') DEVAM EDİYOR @else BEKLİYOR @endif
|
||
</span>
|
||
</div>
|
||
|
||
@if($module->description)
|
||
<p class="text-xs text-slate-600 dark:text-slate-400 leading-relaxed mb-3 pl-8">
|
||
{{ $module->description }}
|
||
</p>
|
||
@endif
|
||
|
||
<div class="flex items-center justify-between text-xs font-semibold pt-2 border-t border-slate-200/60 dark:border-slate-800/60 pl-8">
|
||
<span class="text-slate-500">Ağırlık: %{{ $module->weight_percent }}</span>
|
||
@if($module->start_date && $module->end_date)
|
||
<span class="text-slate-400">{{ $module->start_date->format('d.m') }} - {{ $module->end_date->format('d.m.Y') }}</span>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
@empty
|
||
<div class="col-span-full text-center py-8 text-slate-400 text-sm">
|
||
Henüz tanımlanmış modül bulunmamaktadır.
|
||
</div>
|
||
@endforelse
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Section 3: Live Kanban Board -->
|
||
<section id="kanban-section" class="glass-card rounded-3xl p-6 sm:p-8 space-y-6">
|
||
<div class="flex items-center justify-between border-b border-slate-200 dark:border-slate-800 pb-4">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-8 h-8 rounded-xl bg-amber-600 text-white flex items-center justify-center font-bold">
|
||
<i data-lucide="kanban-square" class="w-4 h-4"></i>
|
||
</div>
|
||
<div>
|
||
<h2 class="text-lg font-bold text-slate-900 dark:text-white font-display">3. Canlı Kanban Görev Panosu</h2>
|
||
<p class="text-xs text-slate-500">Mühendislik ekibinin anlık görev statüleri ve çalışma kartları</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 4 Column Kanban Board -->
|
||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
||
|
||
<!-- Column 1: To Do -->
|
||
<div class="bg-slate-100/70 dark:bg-slate-800/50 rounded-2xl p-4 space-y-3">
|
||
<div class="flex items-center justify-between pb-2 border-b border-slate-200 dark:border-slate-700">
|
||
<span class="text-xs font-bold uppercase tracking-wider text-slate-600 dark:text-slate-400 flex items-center gap-1.5">
|
||
<span class="w-2 h-2 rounded-full bg-slate-400"></span> Yapılacaklar
|
||
</span>
|
||
<span class="text-xs font-extrabold px-2 py-0.5 rounded-full bg-slate-200 dark:bg-slate-700 text-slate-600 dark:text-slate-300">
|
||
{{ $project->tasks->where('status', 'todo')->count() }}
|
||
</span>
|
||
</div>
|
||
|
||
@forelse($project->tasks->where('status', 'todo') as $task)
|
||
<div class="p-3.5 bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800 shadow-sm space-y-2">
|
||
<h4 class="text-xs font-bold text-slate-900 dark:text-white">{{ $task->title }}</h4>
|
||
@if($task->description)
|
||
<p class="text-[11px] text-slate-500 line-clamp-2">{{ $task->description }}</p>
|
||
@endif
|
||
<div class="flex items-center justify-between text-[10px] font-semibold text-slate-400 pt-1">
|
||
<span>{{ $task->assigned_person ?? 'Atanmadı' }}</span>
|
||
<span class="px-2 py-0.5 rounded bg-slate-100 dark:bg-slate-800 uppercase">{{ $task->priority }}</span>
|
||
</div>
|
||
</div>
|
||
@empty
|
||
<p class="text-xs text-slate-400 italic text-center py-4">Görev yok</p>
|
||
@endforelse
|
||
</div>
|
||
|
||
<!-- Column 2: In Progress -->
|
||
<div class="bg-orange-50/60 dark:bg-orange-950/20 rounded-2xl p-4 space-y-3 border border-orange-500/20">
|
||
<div class="flex items-center justify-between pb-2 border-b border-orange-200 dark:border-orange-800/40">
|
||
<span class="text-xs font-bold uppercase tracking-wider text-orange-600 dark:text-orange-400 flex items-center gap-1.5">
|
||
<span class="w-2 h-2 rounded-full bg-orange-500 animate-ping"></span> Devam Edenler
|
||
</span>
|
||
<span class="text-xs font-extrabold px-2 py-0.5 rounded-full bg-orange-200 dark:bg-orange-900/60 text-orange-700 dark:text-orange-300">
|
||
{{ $project->tasks->where('status', 'in_progress')->count() }}
|
||
</span>
|
||
</div>
|
||
|
||
@forelse($project->tasks->where('status', 'in_progress') as $task)
|
||
<div class="p-3.5 bg-white dark:bg-slate-900 rounded-xl border border-orange-200 dark:border-orange-900/40 shadow-sm space-y-2">
|
||
<h4 class="text-xs font-bold text-slate-900 dark:text-white">{{ $task->title }}</h4>
|
||
@if($task->description)
|
||
<p class="text-[11px] text-slate-500 line-clamp-2">{{ $task->description }}</p>
|
||
@endif
|
||
<div class="flex items-center justify-between text-[10px] font-semibold text-orange-600 dark:text-orange-400 pt-1">
|
||
<span>{{ $task->assigned_person ?? 'Yazılım Ekibi' }}</span>
|
||
<span class="px-2 py-0.5 rounded bg-orange-100 dark:bg-orange-950 uppercase">{{ $task->priority }}</span>
|
||
</div>
|
||
</div>
|
||
@empty
|
||
<p class="text-xs text-slate-400 italic text-center py-4">Görev yok</p>
|
||
@endforelse
|
||
</div>
|
||
|
||
<!-- Column 3: Review -->
|
||
<div class="bg-amber-50/60 dark:bg-amber-950/20 rounded-2xl p-4 space-y-3 border border-amber-500/20">
|
||
<div class="flex items-center justify-between pb-2 border-b border-amber-200 dark:border-amber-800/40">
|
||
<span class="text-xs font-bold uppercase tracking-wider text-amber-600 dark:text-amber-400 flex items-center gap-1.5">
|
||
<span class="w-2 h-2 rounded-full bg-amber-500"></span> Kontrol / Test
|
||
</span>
|
||
<span class="text-xs font-extrabold px-2 py-0.5 rounded-full bg-amber-200 dark:bg-amber-900/60 text-amber-700 dark:text-amber-300">
|
||
{{ $project->tasks->where('status', 'review')->count() }}
|
||
</span>
|
||
</div>
|
||
|
||
@forelse($project->tasks->where('status', 'review') as $task)
|
||
<div class="p-3.5 bg-white dark:bg-slate-900 rounded-xl border border-amber-200 dark:border-amber-900/40 shadow-sm space-y-2">
|
||
<h4 class="text-xs font-bold text-slate-900 dark:text-white">{{ $task->title }}</h4>
|
||
@if($task->description)
|
||
<p class="text-[11px] text-slate-500 line-clamp-2">{{ $task->description }}</p>
|
||
@endif
|
||
<div class="flex items-center justify-between text-[10px] font-semibold text-amber-600 dark:text-amber-400 pt-1">
|
||
<span>{{ $task->assigned_person ?? 'Test Ekibi' }}</span>
|
||
<span class="px-2 py-0.5 rounded bg-amber-100 dark:bg-amber-950 uppercase">{{ $task->priority }}</span>
|
||
</div>
|
||
</div>
|
||
@empty
|
||
<p class="text-xs text-slate-400 italic text-center py-4">Görev yok</p>
|
||
@endforelse
|
||
</div>
|
||
|
||
<!-- Column 4: Done -->
|
||
<div class="bg-emerald-50/60 dark:bg-emerald-950/20 rounded-2xl p-4 space-y-3 border border-emerald-500/20">
|
||
<div class="flex items-center justify-between pb-2 border-b border-emerald-200 dark:border-emerald-800/40">
|
||
<span class="text-xs font-bold uppercase tracking-wider text-emerald-600 dark:text-emerald-400 flex items-center gap-1.5">
|
||
<span class="w-2 h-2 rounded-full bg-emerald-500"></span> Tamamlananlar
|
||
</span>
|
||
<span class="text-xs font-extrabold px-2 py-0.5 rounded-full bg-emerald-200 dark:bg-emerald-900/60 text-emerald-700 dark:text-emerald-300">
|
||
{{ $project->tasks->where('status', 'done')->count() }}
|
||
</span>
|
||
</div>
|
||
|
||
@forelse($project->tasks->where('status', 'done') as $task)
|
||
<div class="p-3.5 bg-white dark:bg-slate-900 rounded-xl border border-emerald-200 dark:border-emerald-900/40 shadow-sm space-y-2 opacity-90">
|
||
<h4 class="text-xs font-bold text-slate-900 dark:text-white line-through decoration-emerald-500">{{ $task->title }}</h4>
|
||
@if($task->description)
|
||
<p class="text-[11px] text-slate-500 line-clamp-2">{{ $task->description }}</p>
|
||
@endif
|
||
<div class="flex items-center justify-between text-[10px] font-semibold text-emerald-600 dark:text-emerald-400 pt-1">
|
||
<span>Tamamlandı</span>
|
||
<i data-lucide="check-circle-2" class="w-3.5 h-3.5 text-emerald-500"></i>
|
||
</div>
|
||
</div>
|
||
@empty
|
||
<p class="text-xs text-slate-400 italic text-center py-4">Görev yok</p>
|
||
@endforelse
|
||
</div>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Section 4: Live Activity Log Stream -->
|
||
<section id="updates-section" class="glass-card rounded-3xl p-6 sm:p-8 space-y-6">
|
||
<div class="flex items-center justify-between border-b border-slate-200 dark:border-slate-800 pb-4">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-8 h-8 rounded-xl bg-emerald-600 text-white flex items-center justify-center font-bold">
|
||
<i data-lucide="message-square" class="w-4 h-4"></i>
|
||
</div>
|
||
<div>
|
||
<h2 class="text-lg font-bold text-slate-900 dark:text-white font-display">4. Canlı İlerleme Duyuruları & Log Akışı</h2>
|
||
<p class="text-xs text-slate-500">Yazılım yöneticisinden gelen canlı proje güncellemeleri</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Timeline Stream -->
|
||
<div class="relative pl-6 border-l-2 border-orange-500/30 space-y-8 my-4">
|
||
@forelse($project->updates as $update)
|
||
<div class="relative group">
|
||
<!-- Bullet Dot -->
|
||
<div class="absolute -left-[31px] top-0 w-4 h-4 rounded-full bg-orange-600 border-4 border-slate-50 dark:border-slate-900 shadow-md"></div>
|
||
|
||
<div class="p-5 rounded-2xl bg-slate-100/60 dark:bg-slate-800/40 border border-slate-200 dark:border-slate-800 space-y-2">
|
||
<div class="flex items-center justify-between gap-4">
|
||
<h3 class="text-sm font-bold text-slate-900 dark:text-white">
|
||
{{ $update->title }}
|
||
</h3>
|
||
<span class="text-[11px] font-semibold text-slate-400">
|
||
{{ $update->created_at->format('d.m.Y H:i') }}
|
||
</span>
|
||
</div>
|
||
|
||
<p class="text-xs text-slate-600 dark:text-slate-300 leading-relaxed whitespace-pre-line">
|
||
{{ $update->content }}
|
||
</p>
|
||
|
||
@if($update->progress_percent_at_update !== null)
|
||
<div class="pt-2 flex items-center gap-2 text-xs font-semibold text-orange-600 dark:text-orange-400">
|
||
<i data-lucide="trending-up" class="w-3.5 h-3.5"></i>
|
||
<span>Güncelleme Anındaki İlerleme: %{{ $update->progress_percent_at_update }}</span>
|
||
</div>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
@empty
|
||
<div class="text-center py-6 text-slate-400 text-sm italic">
|
||
Henüz yayınlanmış bir duyuru bulunmamaktadır.
|
||
</div>
|
||
@endforelse
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
|
||
<!-- Corporate Footer -->
|
||
<footer class="mt-16 border-t border-slate-200 dark:border-slate-800 py-8 text-center text-xs text-slate-500">
|
||
<div class="max-w-7xl mx-auto px-4 space-y-2">
|
||
<p>© {{ date('Y') }} <strong>Trunçgil Teknoloji Sanayi ve Ticaret Ltd. Şti.</strong> — Gaziantep Teknopark</p>
|
||
<p class="text-[11px] text-slate-400">Tüm geliştirmeler 4691 Sayılı Teknoloji Geliştirme Bölgeleri Kanunu Ar-Ge standartlarında yürütülmektedir.</p>
|
||
</div>
|
||
</footer>
|
||
|
||
<!-- JS Libraries -->
|
||
<script src="https://cdn.jsdelivr.net/npm/mermaid@10.8.0/dist/mermaid.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/lucide@0.321.0/dist/umd/lucide.min.js"></script>
|
||
|
||
<script>
|
||
// Init Lucide Icons
|
||
lucide.createIcons();
|
||
|
||
// Dark Mode Controller
|
||
var themeToggleBtn = document.getElementById('theme-toggle');
|
||
var themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
|
||
var themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
|
||
|
||
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||
document.documentElement.classList.add('dark');
|
||
themeToggleLightIcon.classList.remove('hidden');
|
||
} else {
|
||
document.documentElement.classList.remove('dark');
|
||
themeToggleDarkIcon.classList.remove('hidden');
|
||
}
|
||
|
||
themeToggleBtn.addEventListener('click', function() {
|
||
themeToggleDarkIcon.classList.toggle('hidden');
|
||
themeToggleLightIcon.classList.toggle('hidden');
|
||
if (document.documentElement.classList.contains('dark')) {
|
||
document.documentElement.classList.remove('dark');
|
||
localStorage.setItem('color-theme', 'light');
|
||
} else {
|
||
document.documentElement.classList.add('dark');
|
||
localStorage.setItem('color-theme', 'dark');
|
||
}
|
||
});
|
||
|
||
// Mermaid Init
|
||
const isDark = document.documentElement.classList.contains('dark');
|
||
mermaid.initialize({
|
||
startOnLoad: true,
|
||
theme: 'base',
|
||
securityLevel: 'loose',
|
||
themeVariables: {
|
||
fontFamily: 'Inter, sans-serif',
|
||
darkMode: isDark,
|
||
background: isDark ? '#0f172a' : '#ffffff',
|
||
primaryColor: '#ea580c',
|
||
primaryTextColor: '#ffffff',
|
||
primaryBorderColor: '#c2410c',
|
||
lineColor: '#ea580c',
|
||
secondaryColor: '#ef4444',
|
||
secondaryTextColor: '#ffffff',
|
||
tertiaryColor: isDark ? '#1e293b' : '#fff7ed',
|
||
sectionBkgColor: isDark ? 'rgba(234, 88, 12, 0.15)' : 'rgba(234, 88, 12, 0.07)',
|
||
sectionBkgColor2: isDark ? 'rgba(239, 68, 68, 0.15)' : 'rgba(239, 68, 68, 0.07)',
|
||
gridColor: isDark ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.08)',
|
||
todayLineColor: '#ef4444'
|
||
}
|
||
});
|
||
|
||
let ganttPanZoom = null;
|
||
setTimeout(() => {
|
||
const svg = document.querySelector('#gantt-canvas svg');
|
||
if (svg) {
|
||
svg.style.width = '100%';
|
||
svg.style.height = '100%';
|
||
if (!svg.id) svg.id = 'gantt-svg';
|
||
try {
|
||
ganttPanZoom = svgPanZoom('#' + svg.id, {
|
||
zoomEnabled: true,
|
||
panEnabled: true,
|
||
fit: true,
|
||
center: true,
|
||
minZoom: 0.3,
|
||
maxZoom: 8,
|
||
onZoom: function(z) {
|
||
document.getElementById('gantt-zoom-pct').textContent = Math.round(z * 100) + '%';
|
||
}
|
||
});
|
||
} catch(e) {}
|
||
}
|
||
}, 300);
|
||
|
||
function zoomGantt(type) {
|
||
if (!ganttPanZoom) return;
|
||
if (type === 'in') ganttPanZoom.zoomIn();
|
||
else ganttPanZoom.zoomOut();
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|