From 7eaff0040cd6f17959224da6ca4aa5520542ede3 Mon Sep 17 00:00:00 2001 From: Rotimi Best Date: Sun, 12 Jul 2026 22:46:25 +0100 Subject: [PATCH] fix(dashboard): make course list rows real links like cards (#743) Wrap list-view course rows in anchor tags so users can open courses in new tabs via right-click or modifier-click, matching the grid card layout. Falls back to button behavior when a custom explore click handler is set. Co-authored-by: Rotimi Best --- .../course/components/course-list-row.svelte | 78 +++++++++++++++---- 1 file changed, 62 insertions(+), 16 deletions(-) diff --git a/apps/dashboard/src/lib/features/course/components/course-list-row.svelte b/apps/dashboard/src/lib/features/course/components/course-list-row.svelte index a75a1ad7..7c9d1a31 100644 --- a/apps/dashboard/src/lib/features/course/components/course-list-row.svelte +++ b/apps/dashboard/src/lib/features/course/components/course-list-row.svelte @@ -5,6 +5,7 @@ import { Badge } from '@cio/ui/base/badge'; import { Button } from '@cio/ui/base/button'; import EllipsisVerticalIcon from '@lucide/svelte/icons/ellipsis-vertical'; + import { cn } from '@cio/ui/tools'; import { goto } from '$app/navigation'; import { resolve } from '$app/paths'; import { ContentType } from '@cio/utils/constants/content'; @@ -114,31 +115,55 @@ return `Updated ${d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}`; }); + const courseUrl = $derived.by(() => { + if (isExplore && onExploreClick) { + return undefined; + } + + if (isExplore) { + if (!slug.trim()) { + return undefined; + } + + return resolve(`/course/${slug}`, {}); + } + + if (isLMS) { + return resolve(`/courses/${id}/lessons?next=true`, {}); + } + + return resolve(`/courses/${id}`, {}); + }); + function handleRowClick() { if (isExplore && onExploreClick) { onExploreClick(); return; } - if (isExplore) { - goto(resolve(`/course/${slug}`, {})); + + if (!courseUrl) { return; } - if (isLMS) { - goto(resolve(`/courses/${id}/lessons?next=true`, {})); + + goto(courseUrl); + } + + function handleRowKeydown(event: KeyboardEvent) { + if (event.key !== 'Enter' && event.key !== ' ') { return; } - goto(resolve(`/courses/${id}`, {})); + + event.preventDefault(); + handleRowClick(); + } + + function stopRowNavigation(event: MouseEvent) { + event.preventDefault(); + event.stopPropagation(); } - +{#snippet rowContent()}
{ - e.stopPropagation(); + onclick={(event) => { + stopRowNavigation(event); onExploreClick?.(); }} > @@ -282,7 +307,7 @@ size="icon" class="size-8" aria-label={$t('courses.course_card.actions_menu_aria')} - onclick={(e) => e.stopPropagation()} + onclick={stopRowNavigation} > @@ -317,4 +342,25 @@
{/if} +{/snippet} + + + {#snippet child({ props })} + {#if courseUrl} + + {@render rowContent()} + + {:else} +
+ {@render rowContent()} +
+ {/if} + {/snippet}