UX: Kategori navigasyonunda öfke tıklamaları — node tıklamasında anında loading state yok (P2) #73
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
TL;DR
Kullanıcı araç detay sayfasında kategori ağacında ilerlerken her seviyede tıklamadan sonra 0–300 ms görsel geri bildirim boşluğu yaşıyor → tekrar tekrar tıklıyor → rage click. Bir gerçek kullanıcı oturumunda 22 tıklamanın 9'u (%41) rage click olarak işaretlendi, oturum 158 saniyede sıfır kategori sonucu görmeden sonlandı.
Otomatik insight: panel
cmpval1y6004ffcphova5oe0v(DeepSeek v4-flash, conf 0.85).Kanıt — gerçek session
019e837a-8296-792a-89f4-ad803bd2a1fcbbe9ddfc-4a35-428b-899f-0e8239863e57)ux_friction,frustrated_sessionPostHog timeline
$identify/dashboard/vehicles/d283a730…$pageview…/categories/8b47a42…parts_panel_viewed$pageview$pageview4eb19e0…$pageviewYorum: 13:58:24 → 14:00:14 arası 110 saniyelik dilimde tek bir pageview yok, yani 22 click'in büyük çoğunluğu o araç detay sayfasında — kategori ağacında / grid'inde gerçekleşmiş. İkinci kategori dakikalar içinde geri çıkılmış → kullanıcı doğru parçayı bulamadan ayrılmış.
Kod analizi — affordance neden zayıf
Üç görünüm (grid/tree/columns) hepsinde aynı pattern: click → router navigate veya child fetch arasında butonun kendisi disabled olmuyor, görünür state değişmiyor.
apps/web/src/components/categories/category-grid.tsx(varsayılan görünüm)navigateToCategory(L129-153) routernavigate({...})çağırıyor. Click ile next route render arası — özellikle ilk navigation sırasında parçalar ve schema-pics fetch ediliyorken — butonda hiçbir görsel değişim yok.prefetchingIdssadece arka plan prefetch için.apps/web/src/components/categories/category-tree.tsxSpinner mevcut ama:
disabledolmuyor → ikinci tıklama TanStack Query dedupe'a takılır (extra API yok), ama görsel olarak hiçbir şey değişmediği için kullanıcı yine "tıklamadım mı?" hissi yaşarapps/web/src/components/categories/category-columns.tsxRoot cause
Click → backend round-trip için per-button loading state'i tutmuyoruz veya tutsak da görsel ağırlığı yetersiz. Router transition için ek olarak hiçbir gösterge yok. Mobil/yavaş bağlantıda algılanan tepki süresi rage-click eşiğini (≥3 click içinde 1 s) kolayca aşıyor.
Quick fix (1–2 saatlik iş)
navigateToCategoryiçineuseTransitionekle veya tıklanancategoryId'yi localpendingIdstate'inde tut. Buton:disabled={pendingId === category.id}isLoading={pendingId === category.id || prefetchingIds.has(category.id)}— büyük (24×24+) ve kartın ortasına overlay olarak spinnerh-3.5→h-5) ve loading sırasında butonu disable et (disabled={loading}).aria-busy={loading}— assistive tech ve testler için.Uzun vadeli fix
/categories/tree/${id}zaten bunu yapıyor (vehicles_/$id/index.tsxL83-87), amacategory-tree.tsx::handleExpandhâlâ derin seviyeler için/categories/${id}/childrençağırıyor. Backend/categories/tree/${id}response'unu N-seviye derin dönecek şekilde genişlet (veya?depth=allquery'si ekle) → frontend'dekihandleExpandlazy fetch kolu tamamen ölü kalsın.onMouseEnter/onFocus'taqueryClient.prefetchQuery(["category-parts", id, categoryId])çağır (hover-prefetch). Şu an grid'deprefetchingIdsvar ama tetiği daha erken çek.Acceptance criteria
[disabled]vearia-busy="true"oluyor → URL değişimi sonrası temizleniyor.category-tree.tsxhandleExpand sırasında buttondisabledtrue olduğunu doğrula.Validation plan
Insight
cmpval1y6004ffcphova5oe0vpanel'de 14 gün validation window ile işaretli (validationStartedAtset edildikten sonra). Acceptance:sessions_metaüzerindeprojectKey='sase' AND tags @> '{frustrated_session}' AND startUrl ILIKE '%/vehicles/%'filtresinde rage-click oranı %50+ düşmeli (baseline 14 günde N session, validation sonu karşılaştır).posthog_eventsüzerindecategory_view_changedile$pageview(categories/) arası medyan delta süresi ölçülecek — fix sonrası medyan ≤ 1.5 s hedef.Etkilenen segment
affected_user_segment: authenticated kullanıcılar (bu session subscriptionTier'sız ama auth_user promotion reason'ı ile yükseldi)Bağlantılı
cmpv9q3ms004dfcphluw0z8bh(parts panel affordance — aynı kök sebep: panel/grid'de tıklama sonrası state belirsiz). Bu iki insight'ı tek epic altında konsolide etmeyi veya bu issue'yacmpv9q3ms…'i de related olarak eklemeyi öneriyorum.apps/web/src/components/categories/category-grid.tsx(L195-215, L129-153)apps/web/src/components/categories/category-tree.tsx(L82-108, L175-187)apps/web/src/components/categories/category-columns.tsx(L246-249)apps/api/src/categories/categories.controller.ts—/categories/tree/:idderinlik genişletme🤖 Generated from behavioral insight pipeline (DeepSeek v4-flash analysis of session
019e837a-8296-792a-89f4-ad803bd2a1fc).🤖 Fusion task opened:
FN-421Triage queue: https://fusion.semih.ai/tasks/FN-421
This comment was posted automatically by the
fusion-plugin-gitea-issuesbridge. A Fusion agent will update this issue when the task moves to in-progress, in-review, or done.✅ Çözüldü — quick fix uygulandı (dev'de canlı)
Üç görünümde de tıklama sonrası anında, belirgin loading state eklendi. Kök neden (click → navigate/fetch arası feedback boşluğu) issue'da önerilen quick-fix deseniyle giderildi.
Commit:
6bcb7ac—fix(web): instant loading feedback on category node clicks (#73)(branch:dev, dev.sase.tr'de canlı)Değişiklikler
category-grid.tsxpendingIdile anındadisabled+aria-busy; kartın ortasına 28px primary spinner overlay (her iki kart varyantında)category-tree.tsxdisabled+aria-busy; chevron-slot spinner'ı 14px → 20px, primary renkcategory-columns.tsxdisabled+aria-busy; aynı 20px primary spinnerAcceptance criteria
aria-busydisabled/aria-busy/spinner) — 5 yeni test geçiyorGerçek dashboard doğrulaması (mobil, authenticated)
VW Amarok aracında, signed better-auth oturumuyla dev.sase.tr üzerinde:
aria-busy=true,disabled=true, spinner 22×22px (chevron yerine primary spinner). ✅aria-busy=true,disabled=true, spinner 22×22px. ✅Not — grid (varsayılan görünüm) hakkında
Hedef kategori route'u in-component
useQuerykullanıyor (blocking loader yok), bu yüzden grid tıklamasında route hızla swap olup hedef sayfanın kendi skeleton'ı (SchemaViewer) feedback veriyor; grid pending-overlay yalnızca kısa router-transition boşluğunu kapatıyor. Overlay yine de deploy edilmiş + unit-test'li. İssue'nun uzun vade maddeleri (route-level hover-prefetch, View Transition API ile cross-fade, tree?depth=allile lazy fetch kolunu öldürme) ayrı bir takip için açık bırakılabilir — istenirsecmpv9q3ms…parts-panel insight'ı ile birlikte tek epic altında toplanabilir.🤖 Generated with Claude Code