Files

683 lines
24 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends("admin.master")
@section("title", "User Guide")
@section("content")
@php
// Tüm işlemleri sayfa içinde yapıyoruz - hiç external dependency yok
use App\Types;
use Illuminate\Support\Facades\Request;
if(!isset($contents)) {
$contents = \App\Contents::where("kid","main")->orderBy("s","ASC")->get();
}
// Auth kontrolü - basit ve güvenli
$user = null;
try {
$user = Auth::user();
} catch (\Exception $e) {
// Auth hatası durumunda devam et
}
// URL'den module parametresini al - daha güvenli yöntem
$currentPath = $_SERVER['REQUEST_URI'] ?? '';
$pathParts = explode('/', trim($currentPath, '/'));
$moduleSlug = null;
// URL pattern: /admin/user-guide/{module}
$userGuideIndex = array_search('user-guide', $pathParts);
if ($userGuideIndex !== false && isset($pathParts[$userGuideIndex + 1])) {
$moduleSlug = $pathParts[$userGuideIndex + 1];
}
$allModules = collect();
$currentModule = null;
$content = '';
try {
// Guide klasöründeki .md dosyalarını direkt oku
$guideDirectory = resource_path('views/guide');
$guideFiles = [];
if (is_dir($guideDirectory)) {
$files = scandir($guideDirectory);
foreach ($files as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'md') {
$slug = pathinfo($file, PATHINFO_FILENAME);
$filePath = $guideDirectory . '/' . $file;
$guideFiles[] = [
'slug' => $slug,
'modified_time' => file_exists($filePath) ? filemtime($filePath) : 0
];
}
}
}
// Her .md dosyası için modül objesi oluştur
$allModules = collect($guideFiles)->map(function($fileInfo) {
$slug = $fileInfo['slug'];
// Types tablosundan bilgi almaya çalış, yoksa default oluştur
$typeModule = null;
try {
$typeModule = Types::where('slug', $slug)->first();
} catch (\Exception $e) {
// Types tablosu hatası durumunda devam et
}
// Modül objesi oluştur
$module = (object)[
'id' => $typeModule->id ?? 'guide_' . md5($slug),
'slug' => $slug,
'title' => $typeModule->title ?? ucwords(str_replace(['-', '_'], ' ', $slug)),
'icon' => $typeModule->icon ?? 'default',
'kid' => null, // Hepsini ana modül olarak göster
'subModules' => collect([]), // Alt modül yok
'enabled' => true,
'from_guide' => true, // Guide'dan geldiğini belirt
'modified_time' => $fileInfo['modified_time']
];
return $module;
})->sortByDesc('modified_time');
// Tüm modülleri (guide'dan gelen) tek listede de tutalım
$allModulesList = $allModules;
if ($moduleSlug) {
// Spesifik modül sayfası - hem ana hem alt modüllerde ara
$currentModule = $allModulesList->where('slug', $moduleSlug)->first();
if ($currentModule) {
$markdownPath = resource_path("views/guide/{$moduleSlug}.md");
if (file_exists($markdownPath)) {
$content = file_get_contents($markdownPath);
} else {
$moduleType = $currentModule->kid ? 'Sub-module' : 'Module';
$content = "# {$currentModule->title} Documentation\n\n_{$moduleType} Documentation_\n\n## Overview\n\nThis module provides functionality for {$currentModule->title} management.\n\n## Features\n\n- CRUD operations\n- Data validation\n- Excel import/export\n- Advanced filtering\n- Real-time updates\n\n## Getting Started\n\n1. Navigate to the module from the admin menu\n2. Use the DataGrid to view existing records\n3. Click 'Add New' to create records\n4. Use filters to find specific data\n5. Export data to Excel when needed\n\n## DataGrid Features\n\n- **Sorting**: Click column headers to sort\n- **Filtering**: Use filter row to narrow results\n- **Pagination**: Navigate through large datasets\n- **Selection**: Select multiple rows for bulk operations\n\n## Common Tasks\n\n### Adding New Records\n1. Click the 'Add' button in the toolbar\n2. Fill in the required fields\n3. Click 'Save' to create the record\n\n### Editing Records\n1. Double-click on a row or use the edit button\n2. Modify the fields as needed\n3. Click 'Save' to update\n\n### Bulk Operations\n1. Select multiple rows using checkboxes\n2. Choose an action from the bulk operations menu\n3. Confirm the operation\n\n## Support\n\nFor technical support, please contact the development team.";
}
} else {
$content = "# Module Not Found\n\nThe requested module '{$moduleSlug}' could not be found.";
}
}
} catch (\Exception $e) {
// Hata durumunda da guide klasöründen direkt oku
$guideDirectory = resource_path('views/guide');
$guideFiles = [];
if (is_dir($guideDirectory)) {
$files = scandir($guideDirectory);
foreach ($files as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'md') {
$slug = pathinfo($file, PATHINFO_FILENAME);
$filePath = $guideDirectory . '/' . $file;
$guideFiles[] = [
'slug' => $slug,
'modified_time' => file_exists($filePath) ? filemtime($filePath) : 0
];
}
}
}
// Her .md dosyası için basit modül objesi oluştur
$allModules = collect($guideFiles)->map(function($fileInfo) {
return (object)[
'id' => 'guide_' . md5($fileInfo['slug']),
'slug' => $fileInfo['slug'],
'title' => ucwords(str_replace(['-', '_'], ' ', $fileInfo['slug'])),
'icon' => 'default',
'kid' => null,
'subModules' => collect([]),
'enabled' => true,
'from_guide' => true,
'modified_time' => $fileInfo['modified_time']
];
})->sortByDesc('modified_time');
$allModulesList = $allModules;
if ($moduleSlug) {
$currentModule = $allModules->where('slug', $moduleSlug)->first();
if ($currentModule) {
$content = "# {$currentModule->title} Documentation\n\nComplete documentation for {$currentModule->title} module.\n\n## Overview\n\nThis module provides functionality for {$currentModule->title} management.\n\n## Features\n\n- CRUD operations\n- Data validation\n- Excel import/export\n- Advanced filtering";
}
}
}
@endphp
{{-- Her zaman sidebar layout kullan --}}
<div class="content">
<div class="row">
<div class="col-md-3">
<!-- Sidebar with module list -->
<div class="block">
<div class="block-header block-header-default">
<h3 class="block-title">
<i class="fa fa-list"></i> All Modules
</h3>
</div>
<div class="block-content">
<!-- Search Bar -->
<div class="mb-3">
<div class="input-group">
<input type="text"
class="form-control"
id="moduleSearch"
placeholder="Search modules..."
autocomplete="off">
<div class="input-group-append">
<span class="input-group-text">
<i class="fa fa-search"></i>
</span>
</div>
</div>
</div>
<div class="nav flex-column" id="moduleList">
@foreach($allModules as $mod)
<a class="nav-link module-link {{$currentModule && $mod->slug == $currentModule->slug ? 'active' : ''}}"
href="{{url('admin/user-guide/'.$mod->slug)}}"
data-title="{{strtolower($mod->title)}}"
data-slug="{{$mod->slug}}">
<i class="fa fa-file-text mr-2"></i>
{{$mod->title}}
</a>
@endforeach
</div>
</div>
</div>
</div>
<div class="col-md-9">
@if($currentModule)
<!-- Module Documentation Content -->
<div class="block">
<div class="block-header block-header-default">
<h3 class="block-title">
<i class="fa fa-file-text mr-2"></i>
{{$currentModule->title}} - Documentation
</h3>
<div class="block-options">
<a href="{{url('admin/types/'.$currentModule->slug)}}" class="btn btn-sm btn-primary">
<i class="fa fa-link"></i> Open Module
</a>
</div>
</div>
<div class="block-content">
<div class="markdown-content">
{!! \Illuminate\Support\Str::markdown($content) !!}
</div>
</div>
</div>
@else
<!-- Welcome Content -->
<div class="block">
<div class="block-header block-header-default">
<h3 class="block-title">
<i class="fa fa-book mr-2"></i> User Guide - Module Documentation
</h3>
<div class="block-options">
<button class="btn btn-sm btn-info" onclick="toggleGuideInfo()">
<i class="fa fa-info-circle"></i> How to Use
</button>
</div>
</div>
<div class="block-content">
<div class="alert alert-info" id="guideInfo">
<i class="fa fa-info-circle"></i>
<strong>Welcome to the User Guide!</strong><br>
This comprehensive documentation covers all modules in the Stellar QC QA application.
Select any module from the left sidebar to view detailed documentation including CRUD operations,
DataGrid configurations, field relationships, and usage instructions.
<div class="mt-3" id="extraInfo" style="display: none;">
<hr>
<h6><i class="fa fa-lightbulb-o"></i> Tips:</h6>
<ul class="mb-0">
<li>Each module documentation includes step-by-step instructions</li>
<li>Use the search feature in the sidebar to quickly find specific modules</li>
<li>Documentation includes both basic usage and advanced features</li>
<li>Screenshots and examples are provided where applicable</li>
</ul>
</div>
</div>
<!-- Module Count Info -->
<div class="alert alert-light text-center">
<i class="fa fa-book"></i>
<strong>{{$allModules->count()}}</strong> documented modules available
<span class="ml-3">
<i class="fa fa-file-text"></i> {{$allModules->count()}} total guides
</span>
<span class="ml-3">
<i class="fa fa-folder-o"></i> From guide directory
</span>
<span class="ml-3">
<i class="fa fa-clock-o"></i> Last updated: {{date('Y-m-d H:i')}}
</span>
</div>
<!-- Quick Module Grid -->
<div class="row">
@foreach($allModules->take(6) as $module)
<div class="col-md-6 mb-3">
<div class="card module-card-mini">
<div class="card-body p-3">
<h6 class="card-title mb-2">
<i class="fa fa-file-text mr-2 text-primary"></i>
{{$module->title}}
</h6>
<p class="card-text text-muted small mb-2">
Documentation for {{$module->title}} module
</p>
<a href="{{url('admin/user-guide/'.$module->slug)}}"
class="btn btn-sm btn-outline-primary">
<i class="fa fa-book"></i> View Guide
</a>
</div>
</div>
</div>
@endforeach
</div>
@if($allModules->count() > 6)
<div class="text-center mt-3">
<p class="text-muted">
<i class="fa fa-arrow-left"></i> Use the sidebar to see all {{$allModules->count()}} modules
</p>
</div>
@endif
</div>
</div>
@endif
</div>
</div>
</div>
<style>
.card {
transition: transform 0.2s, box-shadow 0.2s;
border: 1px solid #e1e5e9;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
}
.card-body {
padding: 1.5rem;
}
.nav-link {
color: #495057;
border-radius: 4px;
margin-bottom: 2px;
padding: 0.5rem 0.75rem;
transition: all 0.3s ease;
}
.nav-link:hover {
background-color: #f8f9fa;
color: #007bff;
text-decoration: none;
transform: translateX(2px);
}
.nav-link.active {
background-color: #007bff;
color: white;
box-shadow: 0 2px 4px rgba(0,123,255,0.3);
}
.module-card-mini {
transition: transform 0.2s, box-shadow 0.2s;
border: 1px solid #e1e5e9;
}
.module-card-mini:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.markdown-content {
line-height: 1.6;
}
.markdown-content h1 {
font-size: 2rem;
margin-bottom: 1rem;
color: #343a40;
border-bottom: 2px solid #e9ecef;
padding-bottom: 0.5rem;
}
.markdown-content h2 {
font-size: 1.5rem;
margin-top: 2rem;
margin-bottom: 1rem;
color: #495057;
}
.markdown-content h3 {
font-size: 1.25rem;
margin-top: 1.5rem;
margin-bottom: 0.75rem;
color: #6c757d;
}
.markdown-content pre {
background-color: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 4px;
padding: 1rem;
margin: 1rem 0;
overflow-x: auto;
}
.markdown-content code {
background-color: #f8f9fa;
padding: 0.2rem 0.4rem;
border-radius: 3px;
font-size: 0.875rem;
}
.markdown-content table {
width: 100%;
margin: 1rem 0;
border-collapse: collapse;
}
.markdown-content table th,
.markdown-content table td {
border: 1px solid #dee2e6;
padding: 0.75rem;
text-align: left;
}
.markdown-content table th {
background-color: #f8f9fa;
font-weight: 600;
}
.markdown-content blockquote {
border-left: 4px solid #007bff;
padding-left: 1rem;
margin: 1rem 0;
color: #6c757d;
background-color: #f8f9fa;
padding: 1rem;
border-radius: 0 4px 4px 0;
}
.markdown-content ul, .markdown-content ol {
padding-left: 2rem;
margin: 1rem 0;
}
.markdown-content li {
margin-bottom: 0.5rem;
}
.module-card {
cursor: pointer;
}
.module-card:hover .card-title {
color: #007bff;
}
.fa-3x {
font-size: 3em;
}
/* Search Bar Styles */
.input-group-focus {
box-shadow: 0 0 8px rgba(0, 123, 255, 0.25);
border-radius: 0.375rem;
}
.input-group-focus .form-control {
border-color: #007bff;
}
.input-group-focus .input-group-text {
border-color: #007bff;
background-color: #e7f3ff;
color: #007bff;
}
#moduleSearch {
transition: all 0.3s ease;
border-right: none;
}
#moduleSearch:focus {
box-shadow: none;
border-color: #007bff;
}
.input-group-text {
background-color: #f8f9fa;
border-left: none;
}
/* Search Results Animation */
#searchResults {
animation: fadeInDown 0.3s ease-out;
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Module Card Transition */
.module-card {
transition: opacity 0.3s ease, transform 0.2s ease;
}
.module-card[style*="opacity: 0.5"] {
transform: scale(0.95);
}
/* Input Group Button Hover */
.input-group-append .btn:hover {
background-color: #dc3545;
border-color: #dc3545;
color: white;
}
/* Responsive Search Bar */
@media (max-width: 768px) {
.input-group-lg .form-control {
font-size: 1rem;
}
#moduleSearch {
font-size: 0.9rem;
}
}
.mermaid {
background: white;
padding: 0;
border-radius: 8px;
margin: 2rem 0;
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
overflow: hidden; /* Taşmaları gizle */
border: 1px solid #e1e5e9;
}
.mermaid svg {
cursor: grab;
}
.mermaid svg.svg-pan-zoom-control-icons {
cursor: pointer;
}
</style>
<script>
function toggleGuideInfo() {
const extraInfo = document.getElementById('extraInfo');
if (extraInfo.style.display === 'none') {
extraInfo.style.display = 'block';
} else {
extraInfo.style.display = 'none';
}
}
function filterSidebarModules(searchTerm) {
const moduleLinks = document.querySelectorAll('.module-link');
const searchLower = searchTerm.toLowerCase();
let visibleCount = 0;
moduleLinks.forEach(link => {
const title = link.getAttribute('data-title') || '';
const slug = link.getAttribute('data-slug') || '';
const isVisible = searchTerm === '' ||
title.includes(searchLower) ||
slug.includes(searchLower);
if (isVisible) {
link.style.display = 'block';
visibleCount++;
} else {
link.style.display = 'none';
}
});
return visibleCount;
}
// Sidebar search and interactions
document.addEventListener('DOMContentLoaded', function() {
// Arama input eventi
const searchInput = document.getElementById('moduleSearch');
if (searchInput) {
// Gerçek zamanlı arama
searchInput.addEventListener('input', function(e) {
filterSidebarModules(e.target.value);
});
// Klavye kısayolları
searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
e.preventDefault();
searchInput.value = '';
filterSidebarModules('');
searchInput.blur();
}
});
// Focus efektleri
searchInput.addEventListener('focus', function() {
this.closest('.input-group').classList.add('input-group-focus');
});
searchInput.addEventListener('blur', function() {
this.closest('.input-group').classList.remove('input-group-focus');
});
}
// Module card mini click handlers
const moduleCardMinis = document.querySelectorAll('.module-card-mini');
moduleCardMinis.forEach(card => {
card.addEventListener('click', function(e) {
if (e.target.tagName !== 'A' && e.target.tagName !== 'I') {
const link = this.querySelector('a[href]');
if (link) {
window.location.href = link.href;
}
}
});
});
});
</script>
@endsection
<!-- Mermaid JS for Flowcharts -->
<script src="https://cdn.jsdelivr.net/npm/mermaid/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>
document.addEventListener("DOMContentLoaded", function() {
// Markdown code blocks for mermaid usually render as <pre><code class="language-mermaid">
// We need to convert them to <div class="mermaid"> for mermaid.js to pick them up
const mermaidBlocks = document.querySelectorAll('pre code.language-mermaid');
if (mermaidBlocks.length > 0) {
mermaidBlocks.forEach(block => {
const pre = block.parentElement;
const content = block.textContent;
const div = document.createElement('div');
div.classList.add('mermaid');
div.textContent = content;
// Animasyonlu geçiş için opacity ayarla
div.style.opacity = '0';
div.style.transition = 'opacity 0.5s ease';
pre.replaceWith(div);
});
// Initialize mermaid
mermaid.initialize({
startOnLoad: false, // Manuel başlatacağız
theme: 'base',
securityLevel: 'loose',
themeVariables: {
primaryColor: '#e7f3ff',
primaryTextColor: '#007bff',
primaryBorderColor: '#007bff',
lineColor: '#5c6c7c',
secondaryColor: '#f8f9fa',
tertiaryColor: '#fff',
},
flowchart: {
curve: 'basis',
useMaxWidth: false // Zoom için genişlik sınırlamasını kaldır
}
});
// Mermaid çizimini başlat ve sonrasında pan-zoom ekle
mermaid.run({
querySelector: '.mermaid'
}).then(() => {
// Render sonrası görünür yap ve zoom ekle
document.querySelectorAll('.mermaid').forEach(div => {
div.style.opacity = '1';
const svg = div.querySelector('svg');
if (svg) {
// SVG boyutlarını ayarla
svg.style.width = '100%';
svg.style.height = '600px'; // Varsayılan yükseklik
svg.style.maxWidth = '100%';
// Pan-Zoom özelliğini ekle
svgPanZoom(svg, {
zoomEnabled: true,
controlIconsEnabled: true,
fit: true,
center: true,
minZoom: 0.5,
maxZoom: 10,
zoomScaleSensitivity: 0.2
});
}
});
});
}
});
</script>