{product.description}
- )} + {(() => { + const desc = + (productDescriptions[slug] as string) || product.description; + if (!desc) return null; + return ( +{line}
+ ))} +diff --git a/CHANGELOG.md b/CHANGELOG.md index 71b5e887..bc2580b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -510,3 +510,72 @@ and this project adheres to [Semantic Versioning](https://semver.org/). - Reduced database load for quiz pages via Redis caching - Improved frontend loading experience during navigation + +## [1.0.0] - 2026-02-14 + +### Added + +- Complete production-ready DevLovers platform: + - Interactive Home with redesigned Hero and Features sections + - Full Quiz learning cycle: play, results, review, and dashboard history + - Quiz integrity system with violations counter and status badges + - Breadcrumb navigation for quiz review flow +- Dashboard improvements: + - Quiz Results history with scores, percentages, and mastery status + - User avatars with automatic fallback generation +- Q&A improvements: + - Next.js category enhancements and optimized loader behavior + - Configurable pagination size (10–100 items) with URL persistence +- Leaderboard enhancements: + - User avatars in podium and table rows + - Improved layout consistency across devices +- Platform transparency: + - Public `/humans.txt` with team and project information +- Observability & monitoring: + - Full Sentry integration for production error and performance tracking +- CI & supply-chain security: + - Safe-chain dependency protection in GitHub Actions +- Shop & payments: + - Monobank acquiring flow (UAH-only, feature-gated) + - Webhook verification, idempotent processing, and admin operations + - Internal Monobank janitor jobs for payment state consistency + +### Changed + +- Home page redesigned with improved UX, animations, and full localization +- Header and navigation refined with contextual behavior and loading states +- Quiz UX improvements: + - Unified result thresholds (Study / Review / Mastered) + - Locale switch now preserves result screen + - Auto-scroll to Next action after answering +- Mobile experience significantly improved across: + - Dashboard + - Leaderboard + - AI Word Helper +- SEO & social sharing: + - Localized Open Graph and Twitter metadata + - MetadataBase configuration for correct preview URLs +- Product experience: + - Multi-language product descriptions + - Improved rendering and formatting + +### Fixed + +- Points mismatch between dashboard and leaderboard +- Locale redirect issues for dashboard and quiz result pages +- Review cache isolation to prevent cross-user data leakage +- Quiz result locale switch losing state +- Multiple Tailwind v4 canonical class warnings +- Various mobile layout and interaction issues + +### Security + +- CI dependency scanning with Safe-chain +- OAuth and environment configuration stabilization +- Internal operational endpoints protected with secret-based access + +### Infrastructure + +- Redis caching for quiz questions and review data +- Environment configuration cleanup and standardization +- Improved build stability and dependency management diff --git a/frontend/app/[locale]/dashboard/page.tsx b/frontend/app/[locale]/dashboard/page.tsx index be15de5f..84effb5b 100644 --- a/frontend/app/[locale]/dashboard/page.tsx +++ b/frontend/app/[locale]/dashboard/page.tsx @@ -3,6 +3,7 @@ import { getTranslations } from 'next-intl/server'; import { PostAuthQuizSync } from '@/components/auth/PostAuthQuizSync'; import { ExplainedTermsCard } from '@/components/dashboard/ExplainedTermsCard'; import { ProfileCard } from '@/components/dashboard/ProfileCard'; +import { QuizResultsSection } from '@/components/dashboard/QuizResultsSection'; import { QuizSavedBanner } from '@/components/dashboard/QuizSavedBanner'; import { StatsCard } from '@/components/dashboard/StatsCard'; import { DynamicGridBackground } from '@/components/shared/DynamicGridBackground'; @@ -64,8 +65,10 @@ export default async function DashboardPage({ : null; const userForDisplay = { + id: user.id, name: user.name ?? null, email: user.email ?? '', + image: user.image ?? null, role: user.role ?? null, points: user.points, createdAt: user.createdAt ?? null, @@ -114,6 +117,9 @@ export default async function DashboardPage({
{product.description}
- )} + {(() => { + const desc = + (productDescriptions[slug] as string) || product.description; + if (!desc) return null; + return ( +{line}
+ ))} +