diff --git a/CHANGELOG.md b/CHANGELOG.md index c1a640b7..3a14408d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -306,3 +306,97 @@ and this project adheres to [Semantic Versioning](https://semver.org/). - Improved stability of text selection detection for AI helper - Fixed locale duplication and routing edge cases - Reduced visual overlap issues on small mobile screens + +## [0.5.3] - 2026-02-04 + +### Added + +- Quiz performance improvements: + - Redis-based answer verification replacing AES encryption + - Server-side quiz cache initialization to reduce verification latency + - Debug endpoints for inspecting and clearing quiz caches (development only) +- Caching & data layer: + - Persistent Redis caching for static Quiz and Q&A data (TTL removed) + - Cache-aside strategy for quiz answers and Q&A content +- Internationalization & accessibility: + - Translations for blog categories, CTA variants, and UI components (en / uk / pl) + - Improved aria-label coverage for navigation, cart, theme toggle, and search +- Developer experience: + - Finalized ESLint Flat Config for frontend + - Stable Prettier + Tailwind class sorting workflow + - Consistent format-on-save behavior across the team + +### Changed + +- Quiz system refactor: + - Simplified answer verification flow using Redis lookups + - Improved guest session restoration after quiz completion + - Language switch now preserves quiz results for guest users +- Layout & UI refinements: + - Removed duplicate padding on quiz routes + - Improved mobile alignment for Quiz Rules and headers + - Refined leaderboard component structure and lint stability +- Shop module cleanup: + - Normalized component naming (PascalCase) + - Reorganized test structure under domain boundaries + - Unified active-state and hover styling across shop routes +- Blog UI improvements: + - Fixed mobile paddings and spacing consistency + - Improved responsive header and layout behavior + +### Fixed + +- Fixed mobile layout misalignment on quiz pages +- Fixed guest language switch issues on quiz result screen +- Improved WCAG color contrast compliance across quiz UI +- Fixed ESLint, Prettier, and test configuration inconsistencies +- Removed unused files, dead code, and outdated utilities +- Improved reliability of quiz session restoration and state handling + +## [0.5.4] - 2026-02-05 + +### Added + +- Quiz SEO & performance improvements: + - Dynamic metadata generation for quizzes list and quiz detail pages + - i18n-aware meta titles and descriptions (en / uk / pl) + - Browserslist configuration targeting modern browsers +- Quiz content updates: + - Expanded JavaScript Fundamentals quiz from 10 to 40 questions +- Dashboard UI improvements: + - New DynamicGridBackground for cleaner visual hierarchy + - Refined ProfileCard and StatsCard layouts +- Accessibility & i18n: + - Improved aria-label coverage across navigation and UI controls + - Refined English, Polish, and Ukrainian UI copy and punctuation + +### Changed + +- Quiz UX refinements: + - Countdown timer animation stabilized on tab switch and session restore + - Emoji replaced with icon-based indicators for consistent styling + - Anti-cheat logic improved to distinguish touch vs mouse events +- Q&A experience improvements: + - Pagination scroll now targets section instead of page top + - Mobile tap lock resolved by clearing text selection on interaction +- Home & layout updates: + - Improved code card sizing and responsive behavior + - Online users counter repositioned for better mobile UX +- Shop UX refinements: + - Canonicalized legacy “View all” filters + - Improved cart CTA behavior and badge layering +- Blog & CMS: + - Refactored blog image rendering and filtering logic + - Improved pagination state handling +- Styling & consistency: + - Fixed Tailwind v4 canonical class warnings + - Unified token-based styling across dashboard, 404 page, and controls + +### Fixed + +- Fixed mobile anti-cheat false positives on quiz pages +- Removed render-blocking Font Awesome CSS +- Fixed quiz timer progress bar desynchronization +- Improved table text contrast in dark mode +- Fixed cart badge overlay issues in header +- Resolved multiple mobile spacing and padding inconsistencies diff --git a/frontend/.browserslistrc b/frontend/.browserslistrc new file mode 100644 index 00000000..80ab2621 --- /dev/null +++ b/frontend/.browserslistrc @@ -0,0 +1 @@ +defaults and fully supports es6-module \ No newline at end of file diff --git a/frontend/app/[locale]/blog/[slug]/PostDetails.tsx b/frontend/app/[locale]/blog/[slug]/PostDetails.tsx index f16b593a..733b2723 100644 --- a/frontend/app/[locale]/blog/[slug]/PostDetails.tsx +++ b/frontend/app/[locale]/blog/[slug]/PostDetails.tsx @@ -84,7 +84,6 @@ function renderPortableTextSpans( const text = child?.text || ''; if (!text) return null; const marks = child?.marks || []; - const linkKey = marks.find(mark => linkMap.has(mark)); let node: React.ReactNode = marks.length === 0 ? linkifyText(text) : text; @@ -280,11 +279,14 @@ function renderPortableText( if (block?._type === 'image' && block?.url) { nodes.push( - {postTitle ); i += 1; diff --git a/frontend/app/[locale]/dashboard/page.tsx b/frontend/app/[locale]/dashboard/page.tsx index 3e5a23a3..d601fa17 100644 --- a/frontend/app/[locale]/dashboard/page.tsx +++ b/frontend/app/[locale]/dashboard/page.tsx @@ -4,6 +4,7 @@ import { PostAuthQuizSync } from '@/components/auth/PostAuthQuizSync'; import { ProfileCard } from '@/components/dashboard/ProfileCard'; import { QuizSavedBanner } from '@/components/dashboard/QuizSavedBanner'; import { StatsCard } from '@/components/dashboard/StatsCard'; +import { DynamicGridBackground } from '@/components/shared/DynamicGridBackground'; import { getUserQuizStats } from '@/db/queries/quiz'; import { getUserProfile } from '@/db/queries/users'; import { redirect } from '@/i18n/routing'; @@ -75,42 +76,35 @@ export default async function DashboardPage({ }; const outlineBtnStyles = - 'inline-flex items-center justify-center rounded-full border border-slate-200 dark:border-slate-700 bg-white/50 dark:bg-slate-900/50 backdrop-blur-sm px-6 py-2 text-sm font-medium text-slate-600 dark:text-slate-300 transition-colors hover:bg-white hover:text-sky-600 dark:hover:bg-slate-800 dark:hover:text-sky-400'; + 'inline-flex items-center justify-center rounded-full border border-gray-200 dark:border-white/10 bg-white/50 dark:bg-neutral-900/50 backdrop-blur-sm px-6 py-2 text-sm font-medium text-gray-600 dark:text-gray-300 transition-colors hover:bg-white hover:text-(--accent-primary) dark:hover:bg-neutral-800 dark:hover:text-(--accent-primary)'; return ( -
+
-
+ + + ); } diff --git a/frontend/app/[locale]/layout.tsx b/frontend/app/[locale]/layout.tsx index cd9cafba..16875f9a 100644 --- a/frontend/app/[locale]/layout.tsx +++ b/frontend/app/[locale]/layout.tsx @@ -10,7 +10,6 @@ import { AppChrome } from '@/components/header/AppChrome'; import { MainSwitcher } from '@/components/header/MainSwitcher'; import { CookieBanner } from '@/components/shared/CookieBanner'; import Footer from '@/components/shared/Footer'; -import { OnlineCounterPopup } from '@/components/shared/OnlineCounterPopup'; import { ThemeProvider } from '@/components/theme/ThemeProvider'; import { locales } from '@/i18n/config'; import { getCurrentUser } from '@/lib/auth'; @@ -73,7 +72,6 @@ export default async function LocaleLayout({ {children} -