aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-02-17 13:13:21 +0000
committerClaude <noreply@anthropic.com>2026-02-17 13:13:21 +0000
commit3fc28ecfc649ac1b3223d68f1e08a96e46de59d2 (patch)
tree50c20100a34f67a2f2afdfdb606ecdf4bf9fa0b2
parentee165ad0b3ac0bc5bb01b327238818d15faa6e4b (diff)
downloadkioku-3fc28ecfc649ac1b3223d68f1e08a96e46de59d2.tar.gz
kioku-3fc28ecfc649ac1b3223d68f1e08a96e46de59d2.tar.zst
kioku-3fc28ecfc649ac1b3223d68f1e08a96e46de59d2.zip
feat(cards): display FSRS difficulty level in card browse view
Show per-card difficulty (D: X.X) in the card list alongside existing metrics (reps, lapses). Hidden for unreviewed cards (difficulty = 0). https://claude.ai/code/session_019XoFbra6drKrZpHASUzKDq
-rw-r--r--src/client/pages/DeckCardsPage.test.tsx18
-rw-r--r--src/client/pages/DeckCardsPage.tsx5
2 files changed, 23 insertions, 0 deletions
diff --git a/src/client/pages/DeckCardsPage.test.tsx b/src/client/pages/DeckCardsPage.test.tsx
index 16916df..58107d4 100644
--- a/src/client/pages/DeckCardsPage.test.tsx
+++ b/src/client/pages/DeckCardsPage.test.tsx
@@ -327,6 +327,24 @@ describe("DeckCardsPage", () => {
expect(screen.getByText("1 lapses")).toBeDefined();
});
+ it("displays difficulty for reviewed cards", () => {
+ renderWithProviders({
+ initialDeck: mockDeck,
+ initialCards: mockCards,
+ });
+
+ expect(screen.getByText("D: 5.0")).toBeDefined();
+ });
+
+ it("does not show difficulty for new cards", () => {
+ renderWithProviders({
+ initialDeck: mockDeck,
+ initialCards: mockCards,
+ });
+
+ expect(screen.queryByText("D: 0.0")).toBeNull();
+ });
+
it("does not show description if deck has none", () => {
const deckWithoutDescription = { ...mockDeck, description: null };
renderWithProviders({
diff --git a/src/client/pages/DeckCardsPage.tsx b/src/client/pages/DeckCardsPage.tsx
index 2b2ca88..8c839da 100644
--- a/src/client/pages/DeckCardsPage.tsx
+++ b/src/client/pages/DeckCardsPage.tsx
@@ -162,6 +162,11 @@ function NoteGroupCard({
{card.lapses > 0 && (
<span className="text-muted">{card.lapses} lapses</span>
)}
+ {card.difficulty > 0 && (
+ <span className="text-muted">
+ D: {card.difficulty.toFixed(1)}
+ </span>
+ )}
</div>
))}
</div>