From 908e6c2b72e548003c8af7bef1c38da158b7a152 Mon Sep 17 00:00:00 2001 From: SomiVista Date: Thu, 3 Sep 2026 21:04:19 +0300 Subject: [PATCH] feat(ui): rebuild Session history on subturtle-ui MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rebuilds /sessions as the design's timeline: a date and duration column, a rail with a per-mode node, and a card carrying the type icon, bundle title, Voice/Text badge, dialog count and chevron. List logic is unchanged — the same list-live-sessions RPC and pagination, useInlineFeatureLock('session_history'), the try/catch that flips to locked, isPracticeSession and goToBundles. - Search and an All / Voice / Text StSegmentedControl narrow the current page. The RPC paginates server-side and takes no query arguments, so both filters are deliberately client-side over the loaded rows. - StPagination replaces pilotui's Pagination. It is app-local, not in ui/: the design system defines no pagination component, so this is a composition of its tokens rather than a library primitive — the same call InlineNotice records. - States: populated, empty, no-match, locked and loading. Locked replaces FeatureLocked on this page only, showing three withheld rows and the upgrade path instead of the list. Two fixes found along the way: The Voice/Text badge keyed off `session._isText`, a field nothing in the codebase ever assigned, so the Text badge could never render. It now reads `metadata.mode`, which the practice pages do write. The timeline's date and duration are formatted for the column rather than the visitor's locale: en-US would render "Aug 12, 02:20 PM" and break the fixed width. formatSessionDuration keeps its precise "8m 0s" form for the session detail page; a list scanned at a glance reads "8 min". Co-Authored-By: Claude Opus 5 --- frontend/components/common/StPagination.vue | 55 +++ frontend/locales/en.json | 27 +- frontend/pages/sessions/index.vue | 432 ++++++++++++-------- 3 files changed, 341 insertions(+), 173 deletions(-) create mode 100644 frontend/components/common/StPagination.vue diff --git a/frontend/components/common/StPagination.vue b/frontend/components/common/StPagination.vue new file mode 100644 index 00000000..cd7e3ddc --- /dev/null +++ b/frontend/components/common/StPagination.vue @@ -0,0 +1,55 @@ + + + diff --git a/frontend/locales/en.json b/frontend/locales/en.json index eb9aeb31..809c47d4 100644 --- a/frontend/locales/en.json +++ b/frontend/locales/en.json @@ -495,11 +495,11 @@ "title": "Study" }, "live-session": { - "no-sessions": "No Sessions Yet", - "no-sessions-description": "You haven't started any practice sessions yet. Start a live session from a phrase bundle to practice your language skills and come back here to see your session history.", + "no-sessions": "No sessions yet", + "no-sessions-description": "Practise a bundle with the AI coach and every session you run will be listed here.", "start-session": "Start session", "start-first-session": "Start Your First Session", - "6-months-expiry": "Each session will expire in 6 months", + "6-months-expiry": "Every session stays here for six months.", "session-history": "Session history", "session-details": "Session Details", "dialogs": "dialogs", @@ -551,7 +551,21 @@ "unlimited": "Unlimited" }, "start-a-session": "Start a session", - "repeat-last": "Repeat your last session" + "repeat-last": "Repeat your last session", + "history-overline": "LIVE SESSIONS", + "6-months-removal": "Sessions older than six months are removed automatically.", + "new-session": "New session", + "search-sessions": "Search sessions", + "n-dialogs": "{n} dialogs", + "showing-count": "Showing {shown} of {total}.", + "transcript-locked": "Transcript locked", + "no-matches": "No sessions match", + "no-matches-description": "Nothing on this page matches that search and filter.", + "filter": { + "all": "All" + }, + "n-minutes": "{n} min", + "under-a-minute": "under a min" }, "profile": { "profile": "Profile", @@ -806,5 +820,10 @@ "system": "System", "resolved": "{mode} · {resolved}", "aria": "Theme: {current}. Switch to {next}." + }, + "pagination": { + "prev": "Prev", + "next": "Next", + "page-of": "Page {page} of {total}" } } diff --git a/frontend/pages/sessions/index.vue b/frontend/pages/sessions/index.vue index be9d4314..121e239d 100644 --- a/frontend/pages/sessions/index.vue +++ b/frontend/pages/sessions/index.vue @@ -1,190 +1,284 @@