<hr/>

<h2>
    <a name="the-kanban-board-drag-amp-drop-with-optimistic-ui" href="#the-kanban-board-drag-amp-drop-with-optimistic-ui">
    </a>
    Kanban Panosu: Sürükle & Bırak ile İyimser UI
</h2>

<p>Pano görevleri sütunlar halinde gruplar:</p>

<p>Bir kart başka bir sütuna bırakıldığında:</p>

<ol>
    <li>UI'yi hemen güncelle (iyimser)</li>
    <li><code>PATCH /tasks/{id}/status</code> isteği gönder</li>
    <li>Hata durumunda geri al</li>
</ol>

<div class="highlight js-code-highlight">
    <pre class="highlight typescript"><code>const previous = cloneColumns(columns.value);

const [task] = source.splice(index, 1);
task.status = targetStatus;
target.unshift(task);

router.patch(/tasks/${taskId}/status, { status: targetStatus }, {
preserveState: true,
preserveScroll: true,
onError: () => {
columns.value = previous;
},
});

<hr/>

<h2>
    <a name="adding-animations-vue-transitiongroup" href="#adding-animations-vue-transitiongroup">
    </a>
    Animasyonlar Eklemek (Vue TransitionGroup)
</h2>

<p>Sıralama ve sütun hareketlerini keyifli hale getirmek için listeyi <code>TransitionGroup</code> ile sardım:<br/></p>

<div class="highlight js-code-highlight">
    <pre class="highlight vue"><code><transitiongroup name="task" tag="div" class="space-y-3" move-class="task-move">

<p>CSS:<br/></p>

<div class="highlight js-code-highlight">
    <pre class="highlight css"><code>.task-enter-active,

.task-leave-active {
transition: opacity 180ms ease, transform 180ms ease;
}

.task-enter-from {
opacity: 0;
transform: translateY(8px) scale(0.98);
}

.task-leave-to {
opacity: 0;
transform: translateY(-8px) scale(0.98);
}

.task-move {
transition: transform 180ms ease;
}

<h3>
    <a name="drop-pulse-feedback" href="#drop-pulse-feedback">
    </a>
    Bırakma Darbe Geri Bildirimi
</h3>

<p>Ayrıca bir görev bırakıldığında küçük bir aydınlatma ekledim:</p>

<ul>
    <li>Bırakma işlevinde <code>droppedId</code> ayarla</li>
    <li>O kartta bir CSS animasyonu uygula</li>
</ul>

<p>Bu, UI'ye “tamamlanmış bir ürün” hissi veriyor ve çok az kodla sağlanıyor.</p>

<hr/>

<h2>
    <a name="tags-create-on-the-fly-attach-to-tasks" href="#tags-create-on-the-fly-attach-to-tasks">
    </a>
    Etiketler: Anında Oluştur + Görevlere Ekle
</h2>

<p>Kontrolcülerde, etiket kimliklerini senkronize ediyorum ve kullanıcı onları yazdığında “yeni etiketler” oluşturuyorum:<br/></p>

<div class="highlight js-code-highlight">
    <pre class="highlight php"><code>$tagIds = collect($data['tag_ids'] ?? [])
->filter()
->map(fn($id) => (int) $id)
->unique()
->values();

foreach (collect($data[‘new_tags’] ?? []) as $tagData) {
$name = trim((string) ($tagData[‘name’] ?? ”));
if ($name === ”) continue;

$tag = Tag::firstOrCreate(
[‘name’ => $name],
[‘color’ => $this->normalizeColor($tagData[‘color’] ?? null)]
);

$tagIds->push($tag->id);
}

$task->tags()->sync($tagIds->unique()->values()->all());

<p>UI üzerinde etiketler basit renkli rozetler şeklinde görüntüleniyor:<br/></p>

<div class="highlight js-code-highlight">
    <pre class="highlight vue"><code><span>


{{ tag.name }}

<hr/>

<h2>
    <a name="filtering-amp-sorting-in-index" href="#filtering-amp-sorting-in-index">
    </a>
    Filtreleme & Sıralama İndeksinde
</h2>

<p>Kullandığım filtreler:</p>

<ul>
    <li>arama <code>q</code></li>
    <li><code>status</code></li>
    <li><code>priority</code></li>
    <li><code>tag_id</code></li>
    <li><code>overdue</code></li>
    <li>sıralama <code>created_at</code> / <code>due_date</code></li>
    <li>yön <code>asc</code> / <code>desc</code></li>
    <li><code>per_page</code> 10 veya 15</li>
</ul>

<p>Laravel tarafında sorgu, kapsamlar kullanarak ve <code>withQueryString()</code> ile oluşturuluyor, böylece filtreler sayfalamada devam ediyor.</p>

<hr/>

<h2>
    <a name="what-id-build-next" href="#what-id-build-next">
    </a>
    Sırada Ne Yapacağım
</h2>

<p>CRUD + pano tamamlandıktan sonra, proje hızla gelişebilir:</p>

<ul>
    <li>📅 <strong>Takvim görünümü</strong> (son tarihler etkinlikler olarak)</li>
    <li>⌨️ <strong>Komut paleti</strong> (<code>Ctrl+K</code>)</li>
    <li>🧾 <strong>Etkinlik kaydı</strong> (görev taşındı, durum değişti)</li>
    <li>🔁 <strong>Yinelenen görevler</strong></li>
    <li>🧪 Daha fazla test + CI pipeline</li>
</ul>

<hr/>

<h2>
    <a name="final-thoughts" href="#final-thoughts">
    </a>
    Son Düşünceler
</h2>

<p>Laravel + Inertia, şunları istediğinizde harika bir kombinasyondur:</p>

<ul>
    <li>temiz bir arka uç (Eloquent, istekler, daha sonra politikalar)</li>
    <li>modern bir ön uç (Vue 3, TypeScript)</li>
    <li>ayrı bir API sürdürmenin yükünü olmadan</li>
</ul>

<p><strong>Kaynak kod:</strong> <a href="https://github.com/VincentCapek/task-board" target="_blank" rel="noopener noreferrer">https://github.com/VincentCapek/task-board</a></p>

Kaynak: Orijinal Makale

Bu Makaleyi Paylaş