From ee45b1e45bcc7741d6401218ca51decb82887ec7 Mon Sep 17 00:00:00 2001 From: v-byte-cpu <65545655+v-byte-cpu@users.noreply.github.com> Date: Sat, 6 Jun 2026 21:19:09 +0400 Subject: [PATCH] feat(decks): refresh due badge and study CTA layout --- .../decks/components/DeckCard.test.tsx | 10 ++- ui/src/features/decks/components/DeckCard.tsx | 81 ++++++++++--------- .../decks/components/DeckDetailPageView.tsx | 8 +- .../features/decks/pages/DetailPage.test.tsx | 8 ++ 4 files changed, 60 insertions(+), 47 deletions(-) diff --git a/ui/src/features/decks/components/DeckCard.test.tsx b/ui/src/features/decks/components/DeckCard.test.tsx index 1d8f241..206f044 100644 --- a/ui/src/features/decks/components/DeckCard.test.tsx +++ b/ui/src/features/decks/components/DeckCard.test.tsx @@ -226,7 +226,8 @@ describe('DeckCard', () => { expect(screen.getByRole('button', { name: 'Review' })).toHaveClass('bg-card') expect(screen.getByText('0%')).toBeInTheDocument() - expect(screen.getByText('Due Today').nextElementSibling).toHaveTextContent('0') + expect(screen.getByText(/Due Today:/)).toHaveClass('sr-only') + expect(screen.getByText('0')).toHaveClass('type-metric') expect(screen.queryByText('-3')).not.toBeInTheDocument() expect(screen.queryByText(/NaN|Infinity/)).not.toBeInTheDocument() }) @@ -251,8 +252,11 @@ describe('DeckCard', () => { await user.click(screen.getByRole('button', { name: 'Open Biology deck' })) expect(onOpen).toHaveBeenCalledWith(baseDeck) - const dueMetadata = screen.getByText('Due').closest('div') - expect(dueMetadata).toHaveClass('flex-col') + const dueLabel = screen.getByText(/Due Today:/) + expect(dueLabel).toHaveClass('sr-only') + const dueMetadata = screen.getByText('18').closest('div') + expect(dueMetadata).toHaveClass('items-center', 'gap-1.5') + expect(dueMetadata).not.toHaveClass('flex-col') expect(dueMetadata).not.toHaveClass('rounded-full') expect(dueMetadata).not.toHaveClass('bg-muted') expect(screen.getByText('18')).toHaveClass('text-xs') diff --git a/ui/src/features/decks/components/DeckCard.tsx b/ui/src/features/decks/components/DeckCard.tsx index 02f86f7..d46013b 100644 --- a/ui/src/features/decks/components/DeckCard.tsx +++ b/ui/src/features/decks/components/DeckCard.tsx @@ -1,5 +1,5 @@ import { useNavigate } from '@tanstack/react-router' -import { ArrowRight, Pencil, Trash2 } from 'lucide-react' +import { ArrowRight, Clock3, Pencil, Trash2 } from 'lucide-react' import { useTranslation } from 'react-i18next' import { LazyIconGlyph } from '@shared/components/icons/IconGlyph' @@ -53,6 +53,7 @@ export const DeckCard = ({ const openDeckLabel = t(($) => $.decks.actions.openDeck, { title: deckTitle }) const deckActionsLabel = t(($) => $.decks.actions.actionMenu, { title: deckTitle }) const reviewLabel = t(($) => $.common.actions.review) + const dueTodayA11yLabel = t(($) => $.decks.labels.dueToday) const openDeck = () => { onOpen(deck) @@ -107,11 +108,14 @@ export const DeckCard = ({ />
-
-
- - {t(($) => $.decks.labels.due)} - +
+
+
-
- -
- , - label: t(($) => $.common.actions.edit), - onSelect: () => { - onEdit(deck) - }, - }, - { - icon: , - label: t(($) => $.common.actions.delete), - onSelect: () => onDelete(deck), - tone: 'danger', +
+ , + label: t(($) => $.common.actions.edit), + onSelect: () => { + onEdit(deck) }, - ]} - triggerFocusSurface="card" - /> -
+ }, + { + icon: , + label: t(($) => $.common.actions.delete), + onSelect: () => onDelete(deck), + tone: 'danger', + }, + ]} + triggerFocusSurface="card" + />
-
-
- - {t(($) => $.decks.labels.dueToday)} - -

- {dueTodayLabel} -

+
+
+
+
+
) @@ -445,9 +445,3 @@ const DeckMasteryLabel = () => { return t(($) => $.decks.labels.mastery) } - -const DeckStudyNowLabel = ({ to }: { to: string }) => { - const { t } = useTranslation() - - return {t(($) => $.decks.actions.studyNow)} -} diff --git a/ui/src/features/decks/pages/DetailPage.test.tsx b/ui/src/features/decks/pages/DetailPage.test.tsx index 786d68e..e3fc618 100644 --- a/ui/src/features/decks/pages/DetailPage.test.tsx +++ b/ui/src/features/decks/pages/DetailPage.test.tsx @@ -266,6 +266,14 @@ describe('DeckDetailPage', () => { expect(await screen.findByText(deckDescription)).toBeInTheDocument() const studyNowLinks = screen.getAllByRole('link', { name: 'Study now' }) expect(studyNowLinks).toHaveLength(1) + expect(studyNowLinks[0]).toHaveClass( + 'type-action', + 'h-12', + 'w-full', + 'rounded-full', + 'bg-primary', + 'text-primary-foreground', + ) const createButton = await screen.findByRole('button', { name: 'Create' }) const deckActions = await screen.findByRole('button', { name: 'World History actions' })