Skip to content

(SP: 1) [Frontend] Remove Contacts References#211

Merged
ViktorSvertoka merged 3 commits into
developfrom
chore/remove-contacts-page-references
Jan 25, 2026
Merged

(SP: 1) [Frontend] Remove Contacts References#211
ViktorSvertoka merged 3 commits into
developfrom
chore/remove-contacts-page-references

Conversation

@ViktorSvertoka
Copy link
Copy Markdown
Member

@ViktorSvertoka ViktorSvertoka commented Jan 25, 2026

Summary

  • Removed Contacts navigation label and translations.
  • Cleared Contacts page metadata strings.
  • Removed dashboard link to the deleted Contacts page.
  • Updated project structure docs.

CLOSES: #210

Summary by CodeRabbit

  • New Features

    • Added GROQ_API_KEY environment variable configuration support.
  • Tests

    • Added comprehensive test suites for Q&A components and functionality, including accordion lists, word helper explanations, code blocks, pagination, and selection behavior.
    • Updated test configuration to include Q&A and API endpoints coverage.
  • Removals

    • Removed Contacts page and all related navigation links and translations.

✏️ Tip: You can customize this high-level summary in your review settings.

@ViktorSvertoka ViktorSvertoka self-assigned this Jan 25, 2026
@ViktorSvertoka ViktorSvertoka added the refactor Code restructuring without functional changes label Jan 25, 2026
@netlify
Copy link
Copy Markdown

netlify Bot commented Jan 25, 2026

Deploy Preview for develop-devlovers ready!

Name Link
🔨 Latest commit 887392d
🔍 Latest deploy log https://app.netlify.com/projects/develop-devlovers/deploys/69768ccc956b510008a3f788
😎 Deploy Preview https://deploy-preview-211--develop-devlovers.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 25, 2026

📝 Walkthrough

Walkthrough

This PR removes the entire contacts page, eliminates related navigation references and translations across all locales, and adds comprehensive test coverage for Q&A components and the questions API route handler. The contacts feature is completely deleted from the frontend.

Changes

Cohort / File(s) Summary
Environment Configuration
frontend/.env.example
Added GROQ_API_KEY environment variable.
Page Removal
frontend/app/[locale]/contacts/page.tsx
Deleted entire contacts page including generateMetadata and ContactsPage component exports.
Navigation Updates
frontend/app/[locale]/dashboard/page.tsx, frontend/lib/navigation.ts
Converted contacts link in dashboard from interactive Link to static span; removed { href: '/contacts', labelKey: 'contacts' } from SITE_LINKS array.
Translation Removals
frontend/messages/en.json, frontend/messages/pl.json, frontend/messages/uk.json
Removed navigation.contacts entry and root-level contacts translation block (metaTitle, metaDescription, title, subtitle, email, linkedin, github) from all locale files.
Test Suites: Q&A Components
frontend/components/tests/q&a/accordion-list.test.tsx, frontend/components/tests/q&a/ai-word-helper.test.tsx, frontend/components/tests/q&a/code-block.test.tsx, frontend/components/tests/q&a/floating-explain-button.test.tsx, frontend/components/tests/q&a/highlight-cached-terms.test.tsx, frontend/components/tests/q&a/pagination.test.tsx, frontend/components/tests/q&a/qa-section.test.tsx, frontend/components/tests/q&a/selectable-text.test.tsx
Added comprehensive unit test suites for AccordionList, AIWordHelper, CodeBlock, FloatingExplainButton, HighlightCachedTerms, Pagination, QaSection, and SelectableText components, covering rendering, interactions, error handling, and state management.
Test Suites: Q&A Types & Hooks
frontend/components/tests/q&a/types.test.ts, frontend/components/tests/q&a/use-qa-tabs.test.tsx
Added tests for qaConstants.supportedLocales and comprehensive test coverage for useQaTabs hook including pagination, category changes, and error handling.
Test Suites: API Route
frontend/lib/tests/q&a/questions-route.test.ts
Added unit tests for GET /api/questions/[category] route covering normal pagination, unknown categories, and error scenarios.
Configuration & Documentation
frontend/vitest.config.ts, frontend/project-structure.txt
Expanded Vitest coverage includes to add components/q&a/** and app/api/questions/**; removed contacts directory entry from project structure.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

testing

Suggested reviewers

  • AM1007

Poem

🐰 Hop away, old contacts page!
Tests now guard the Q&A stage,
With vitest config all aligned,
Translations cleaned, no traces left behind,
The GROQ key awaits its turn,
While coverage metrics brightly burn!

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes extensive Q&A test additions that are unrelated to the contacts removal objective stated in issue #210. Remove Q&A test files (accordion-list.test.tsx, ai-word-helper.test.tsx, code-block.test.tsx, floating-explain-button.test.tsx, highlight-cached-terms.test.tsx, pagination.test.tsx, qa-section.test.tsx, selectable-text.test.tsx, types.test.ts, use-qa-tabs.test.tsx, questions-route.test.ts) and vitest.config.ts changes, or create a separate PR for Q&A testing.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and accurately summarizes the main change: removing contacts-related references from the frontend.
Linked Issues check ✅ Passed All requirements from issue #210 are met: contacts translations removed, navigation label removed, dashboard link removed, and project structure updated.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@frontend/.env.example`:
- Around line 100-101: Add a final newline at end of file frontend/.env.example
so the GROQ_API_KEY= line is terminated by a trailing newline (i.e., ensure the
file ends with a blank line/linefeed) to satisfy dotenv-linter's EOF newline
check.

In `@frontend/components/tests/q`&a/accordion-list.test.tsx:
- Around line 98-120: The mock for HighlightCachedTerms normalizes text to
lowercase but still checks cachedTerms case-sensitively, causing mismatches
(e.g., 'HTML' vs 'html'); update the mock used in the test so the membership
check is case-insensitive by comparing normalized (lowercased/trimmed) text
against a lowercased version of the cachedTerms entries (or by normalizing
cachedTerms into a Set of lowercase values) before deciding to render the button
and call onTermClick, referencing the mock's parameter names text, cachedTerms,
normalized and the exported default mock component.

In `@frontend/components/tests/q`&a/use-qa-tabs.test.tsx:
- Around line 70-109: The tests for useQaTabs (specifically the cases exercising
handlePageChange and handleCategoryChange) currently assert fetchMock was called
but may be satisfied by the initial load; update each test to assert a second
fetch invocation and validate the last fetch call URL to ensure a new request
occurred: after invoking result.current.handlePageChange(2) and
handleCategoryChange('css'), wait for fetchMock to have been
calledTimes(initialCalls + 1) (or toHaveBeenCalledTimes(2) if initial is one),
then inspect fetchMock.mock.calls[fetchMock.mock.calls.length - 1][0] (or
equivalent) to assert it contains the expected query (?page=2 or ?category=css);
keep existing assertions for routerReplace and window.scrollTo.
- Around line 23-55: The test suite is leaving fetchMock call history between
tests; reset the mock to avoid cross-test bleed by calling fetchMock.mockClear()
(or fetchMock.mockReset()) in the beforeEach (or in afterEach) so each test
starts with a fresh call history; update the setup block that currently defines
fetchMock and calls vi.stubGlobal('fetch', fetchMock) to include
fetchMock.mockClear() (and keep vi.unstubAllGlobals() in afterEach) to ensure
isolation for functions named fetchMock, beforeEach, afterEach, vi.stubGlobal,
and vi.unstubAllGlobals.
🧹 Nitpick comments (3)
frontend/app/[locale]/dashboard/page.tsx (1)

97-97: Consider removing interactive hover affordances for non-clickable text.
The span is non-interactive now, but outlineBtnStyles still adds hover effects that imply clickability. Consider a non-interactive style variant to avoid misleading UX.

frontend/lib/tests/q&a/questions-route.test.ts (1)

96-115: Missing assertion for console.error invocation.

The test creates a consoleSpy but never asserts that console.error was called. This weakens the test's verification of error handling behavior.

Proposed fix
     expect(res.status).toBe(500);
     expect(data.items).toEqual([]);
     expect(data.total).toBe(0);
     expect(data.totalPages).toBe(0);
+    expect(consoleSpy).toHaveBeenCalled();
     consoleSpy.mockRestore();
frontend/components/tests/q&a/qa-section.test.tsx (1)

10-19: Shared mutable state between tests may cause flakiness.

The qaState object is mutated directly in each test (lines 53, 60) without resetting it in beforeEach. If tests run in parallel or in a different order, they may interfere with each other.

Proposed fix: Reset state before each test
+const defaultQaState = {
+  active: 'git',
+  currentPage: 1,
+  handleCategoryChange: vi.fn(),
+  handlePageChange: vi.fn(),
+  isLoading: false,
+  items: [] as unknown[],
+  localeKey: 'en',
+  totalPages: 0,
+};
+
 const qaState = {
   active: 'git',
   currentPage: 1,
   handleCategoryChange: vi.fn(),
   handlePageChange: vi.fn(),
   isLoading: false,
   items: [] as unknown[],
   localeKey: 'en',
   totalPages: 0,
 };

 // ... mocks ...

 describe('QaSection', () => {
+  beforeEach(() => {
+    Object.assign(qaState, defaultQaState);
+  });
+
   it('renders empty state when no questions', () => {

Also applies to: 51-67

Comment thread frontend/.env.example
Comment on lines +100 to +101

GROQ_API_KEY= No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add trailing newline to satisfy dotenv-linter.
The linter reports no blank line at EOF. Add a final newline to clear the warning.

🧰 Tools
🪛 dotenv-linter (4.0.0)

[warning] 101-101: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)

🤖 Prompt for AI Agents
In `@frontend/.env.example` around lines 100 - 101, Add a final newline at end of
file frontend/.env.example so the GROQ_API_KEY= line is terminated by a trailing
newline (i.e., ensure the file ends with a blank line/linefeed) to satisfy
dotenv-linter's EOF newline check.

Comment on lines +98 to +120
vi.mock('@/components/q&a/HighlightCachedTerms', () => ({
__esModule: true,
default: ({
text,
cachedTerms,
onTermClick,
}: {
text: string;
cachedTerms: Set<string>;
onTermClick: (term: string) => void;
}) => {
const normalized = text.toLowerCase().trim();
if (!cachedTerms.has(normalized)) {
return <span>{text}</span>;
}

return (
<button type="button" onClick={() => onTermClick(text)}>
{text}
</button>
);
},
}));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, locate and read the test file
fd "accordion-list.test.tsx" --type f

Repository: DevLoversTeam/devlovers.net

Length of output: 124


🏁 Script executed:

# Read the test file to see the full context around the mocked HighlightCachedTerms
cat -n frontend/components/tests/q&a/accordion-list.test.tsx | sed -n '1,130p'

Repository: DevLoversTeam/devlovers.net

Length of output: 202


🏁 Script executed:

# Also check the setup of getCachedTermsMock and how it's used
cat -n frontend/components/tests/q&a/accordion-list.test.tsx | sed -n '1,30p'

Repository: DevLoversTeam/devlovers.net

Length of output: 202


🏁 Script executed:

# Read lines around the "cached term clicked" test (174-196)
cat -n frontend/components/tests/q&a/accordion-list.test.tsx | sed -n '170,200p'

Repository: DevLoversTeam/devlovers.net

Length of output: 202


🏁 Script executed:

# Find and read the real HighlightCachedTerms component implementation
fd "HighlightCachedTerms" --type f | grep -v test | grep -v node_modules

Repository: DevLoversTeam/devlovers.net

Length of output: 119


🏁 Script executed:

# Try to run the specific test
cd frontend && npm test -- accordion-list.test.tsx --run 2>&1 | head -100

Repository: DevLoversTeam/devlovers.net

Length of output: 158


🏁 Script executed:

# Read the test file with proper quoting
cat -n 'frontend/components/tests/q&a/accordion-list.test.tsx' | head -130

Repository: DevLoversTeam/devlovers.net

Length of output: 3995


🏁 Script executed:

# Read lines around the HighlightCachedTerms mock (98-120)
cat -n 'frontend/components/tests/q&a/accordion-list.test.tsx' | sed -n '98,125p'

Repository: DevLoversTeam/devlovers.net

Length of output: 920


🏁 Script executed:

# Read the setup at the start of the test file
cat -n 'frontend/components/tests/q&a/accordion-list.test.tsx' | sed -n '1,50p'

Repository: DevLoversTeam/devlovers.net

Length of output: 1773


🏁 Script executed:

# Read the cached term clicked test (174-196)
cat -n 'frontend/components/tests/q&a/accordion-list.test.tsx' | sed -n '174,200p'

Repository: DevLoversTeam/devlovers.net

Length of output: 910


🏁 Script executed:

# Read the real HighlightCachedTerms component
cat -n 'frontend/components/q&a/HighlightCachedTerms.tsx'

Repository: DevLoversTeam/devlovers.net

Length of output: 3305


Fix case-sensitivity mismatch in HighlightCachedTerms mock to match real component behavior.

The mock normalizes text to lowercase (line 109) but performs a case-sensitive lookup against the cachedTerms Set, which contains original-case values. The real component uses case-insensitive regex matching ('gi' flag). In the "cached term clicked" test, cachedTerms contains 'HTML' while the mock checks for 'html', causing the match to fail and the component to render a plain <span> instead of a clickable button. This means onTermClick is never invoked, and the test assertion on line 195 should fail.

Normalize the comparison to be case-insensitive:

Proposed fix
 vi.mock('@/components/q&a/HighlightCachedTerms', () => ({
   __esModule: true,
   default: ({
     text,
     cachedTerms,
     onTermClick,
   }: {
     text: string;
     cachedTerms: Set<string>;
     onTermClick: (term: string) => void;
   }) => {
     const normalized = text.toLowerCase().trim();
-    if (!cachedTerms.has(normalized)) {
+    const hasMatch = Array.from(cachedTerms).some(
+      (t) => t.toLowerCase().trim() === normalized
+    );
+    if (!hasMatch) {
       return <span>{text}</span>;
     }

     return (
       <button type="button" onClick={() => onTermClick(text)}>
         {text}
       </button>
     );
   },
 }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
vi.mock('@/components/q&a/HighlightCachedTerms', () => ({
__esModule: true,
default: ({
text,
cachedTerms,
onTermClick,
}: {
text: string;
cachedTerms: Set<string>;
onTermClick: (term: string) => void;
}) => {
const normalized = text.toLowerCase().trim();
if (!cachedTerms.has(normalized)) {
return <span>{text}</span>;
}
return (
<button type="button" onClick={() => onTermClick(text)}>
{text}
</button>
);
},
}));
vi.mock('@/components/q&a/HighlightCachedTerms', () => ({
__esModule: true,
default: ({
text,
cachedTerms,
onTermClick,
}: {
text: string;
cachedTerms: Set<string>;
onTermClick: (term: string) => void;
}) => {
const normalized = text.toLowerCase().trim();
const hasMatch = Array.from(cachedTerms).some(
(t) => t.toLowerCase().trim() === normalized
);
if (!hasMatch) {
return <span>{text}</span>;
}
return (
<button type="button" onClick={() => onTermClick(text)}>
{text}
</button>
);
},
}));
🤖 Prompt for AI Agents
In `@frontend/components/tests/q`&a/accordion-list.test.tsx around lines 98 - 120,
The mock for HighlightCachedTerms normalizes text to lowercase but still checks
cachedTerms case-sensitively, causing mismatches (e.g., 'HTML' vs 'html');
update the mock used in the test so the membership check is case-insensitive by
comparing normalized (lowercased/trimmed) text against a lowercased version of
the cachedTerms entries (or by normalizing cachedTerms into a Set of lowercase
values) before deciding to render the button and call onTermClick, referencing
the mock's parameter names text, cachedTerms, normalized and the exported
default mock component.

Comment on lines +23 to +55
const fetchMock = vi.fn();

beforeEach(() => {
fetchMock.mockResolvedValue({
ok: true,
json: async () => ({
items: [
{
id: 'q1',
categoryId: 'cat-1',
sortOrder: 1,
difficulty: null,
question: 'Question 1',
answerBlocks: [],
locale: 'en',
},
],
total: 1,
page: 1,
totalPages: 1,
locale: 'en',
}),
});
vi.stubGlobal('fetch', fetchMock);
vi.stubGlobal('scrollTo', vi.fn());
routerReplace.mockClear();
searchParamsValue = new URLSearchParams();
});

afterEach(() => {
vi.unstubAllGlobals();
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Reset fetchMock between tests to avoid cross-test bleed.
Right now, call history persists across tests, which can mask failures. Clearing the mock in beforeEach keeps tests isolated.

🔧 Suggested change
   beforeEach(() => {
+    fetchMock.mockClear();
     fetchMock.mockResolvedValue({
       ok: true,
       json: async () => ({
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const fetchMock = vi.fn();
beforeEach(() => {
fetchMock.mockResolvedValue({
ok: true,
json: async () => ({
items: [
{
id: 'q1',
categoryId: 'cat-1',
sortOrder: 1,
difficulty: null,
question: 'Question 1',
answerBlocks: [],
locale: 'en',
},
],
total: 1,
page: 1,
totalPages: 1,
locale: 'en',
}),
});
vi.stubGlobal('fetch', fetchMock);
vi.stubGlobal('scrollTo', vi.fn());
routerReplace.mockClear();
searchParamsValue = new URLSearchParams();
});
afterEach(() => {
vi.unstubAllGlobals();
});
const fetchMock = vi.fn();
beforeEach(() => {
fetchMock.mockClear();
fetchMock.mockResolvedValue({
ok: true,
json: async () => ({
items: [
{
id: 'q1',
categoryId: 'cat-1',
sortOrder: 1,
difficulty: null,
question: 'Question 1',
answerBlocks: [],
locale: 'en',
},
],
total: 1,
page: 1,
totalPages: 1,
locale: 'en',
}),
});
vi.stubGlobal('fetch', fetchMock);
vi.stubGlobal('scrollTo', vi.fn());
routerReplace.mockClear();
searchParamsValue = new URLSearchParams();
});
afterEach(() => {
vi.unstubAllGlobals();
});
🤖 Prompt for AI Agents
In `@frontend/components/tests/q`&a/use-qa-tabs.test.tsx around lines 23 - 55, The
test suite is leaving fetchMock call history between tests; reset the mock to
avoid cross-test bleed by calling fetchMock.mockClear() (or
fetchMock.mockReset()) in the beforeEach (or in afterEach) so each test starts
with a fresh call history; update the setup block that currently defines
fetchMock and calls vi.stubGlobal('fetch', fetchMock) to include
fetchMock.mockClear() (and keep vi.unstubAllGlobals() in afterEach) to ensure
isolation for functions named fetchMock, beforeEach, afterEach, vi.stubGlobal,
and vi.unstubAllGlobals.

Comment on lines +70 to +109
it('updates page and URL on page change', async () => {
const { result } = renderHook(() => useQaTabs());

await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});

act(() => {
result.current.handlePageChange(2);
});

await waitFor(() => {
expect(fetchMock).toHaveBeenCalled();
});

expect(routerReplace).toHaveBeenCalledWith('/q&a?page=2', {
scroll: false,
});
expect(window.scrollTo).toHaveBeenCalled();
});

it('updates category and URL on category change', async () => {
const { result } = renderHook(() => useQaTabs());

await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});

act(() => {
result.current.handleCategoryChange('css');
});

await waitFor(() => {
expect(fetchMock).toHaveBeenCalled();
});

expect(routerReplace).toHaveBeenCalledWith('/q&a?category=css', {
scroll: false,
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Ensure page/category changes trigger a new fetch.
waitFor(() => expect(fetchMock).toHaveBeenCalled()) can pass due to the initial load. Assert a second call and verify the last URL to avoid false positives.

🔧 Suggested change
   it('updates page and URL on page change', async () => {
     const { result } = renderHook(() => useQaTabs());

     await waitFor(() => {
       expect(result.current.isLoading).toBe(false);
     });

+    const initialCalls = fetchMock.mock.calls.length;
     act(() => {
       result.current.handlePageChange(2);
     });

     await waitFor(() => {
-      expect(fetchMock).toHaveBeenCalled();
+      expect(fetchMock).toHaveBeenCalledTimes(initialCalls + 1);
     });
+    expect(fetchMock).toHaveBeenLastCalledWith(
+      '/api/questions/git?page=2&limit=10&locale=en',
+      expect.objectContaining({ signal: expect.any(AbortSignal) })
+    );

     expect(routerReplace).toHaveBeenCalledWith('/q&a?page=2', {
       scroll: false,
     });
     expect(window.scrollTo).toHaveBeenCalled();
   });

   it('updates category and URL on category change', async () => {
     const { result } = renderHook(() => useQaTabs());

     await waitFor(() => {
       expect(result.current.isLoading).toBe(false);
     });

+    const initialCalls = fetchMock.mock.calls.length;
     act(() => {
       result.current.handleCategoryChange('css');
     });

     await waitFor(() => {
-      expect(fetchMock).toHaveBeenCalled();
+      expect(fetchMock).toHaveBeenCalledTimes(initialCalls + 1);
     });
+    expect(fetchMock).toHaveBeenLastCalledWith(
+      '/api/questions/css?page=1&limit=10&locale=en',
+      expect.objectContaining({ signal: expect.any(AbortSignal) })
+    );

     expect(routerReplace).toHaveBeenCalledWith('/q&a?category=css', {
       scroll: false,
     });
   });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it('updates page and URL on page change', async () => {
const { result } = renderHook(() => useQaTabs());
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
act(() => {
result.current.handlePageChange(2);
});
await waitFor(() => {
expect(fetchMock).toHaveBeenCalled();
});
expect(routerReplace).toHaveBeenCalledWith('/q&a?page=2', {
scroll: false,
});
expect(window.scrollTo).toHaveBeenCalled();
});
it('updates category and URL on category change', async () => {
const { result } = renderHook(() => useQaTabs());
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
act(() => {
result.current.handleCategoryChange('css');
});
await waitFor(() => {
expect(fetchMock).toHaveBeenCalled();
});
expect(routerReplace).toHaveBeenCalledWith('/q&a?category=css', {
scroll: false,
});
});
it('updates page and URL on page change', async () => {
const { result } = renderHook(() => useQaTabs());
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
const initialCalls = fetchMock.mock.calls.length;
act(() => {
result.current.handlePageChange(2);
});
await waitFor(() => {
expect(fetchMock).toHaveBeenCalledTimes(initialCalls + 1);
});
expect(fetchMock).toHaveBeenLastCalledWith(
'/api/questions/git?page=2&limit=10&locale=en',
expect.objectContaining({ signal: expect.any(AbortSignal) })
);
expect(routerReplace).toHaveBeenCalledWith('/q&a?page=2', {
scroll: false,
});
expect(window.scrollTo).toHaveBeenCalled();
});
it('updates category and URL on category change', async () => {
const { result } = renderHook(() => useQaTabs());
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
const initialCalls = fetchMock.mock.calls.length;
act(() => {
result.current.handleCategoryChange('css');
});
await waitFor(() => {
expect(fetchMock).toHaveBeenCalledTimes(initialCalls + 1);
});
expect(fetchMock).toHaveBeenLastCalledWith(
'/api/questions/css?page=1&limit=10&locale=en',
expect.objectContaining({ signal: expect.any(AbortSignal) })
);
expect(routerReplace).toHaveBeenCalledWith('/q&a?category=css', {
scroll: false,
});
});
🤖 Prompt for AI Agents
In `@frontend/components/tests/q`&a/use-qa-tabs.test.tsx around lines 70 - 109,
The tests for useQaTabs (specifically the cases exercising handlePageChange and
handleCategoryChange) currently assert fetchMock was called but may be satisfied
by the initial load; update each test to assert a second fetch invocation and
validate the last fetch call URL to ensure a new request occurred: after
invoking result.current.handlePageChange(2) and handleCategoryChange('css'),
wait for fetchMock to have been calledTimes(initialCalls + 1) (or
toHaveBeenCalledTimes(2) if initial is one), then inspect
fetchMock.mock.calls[fetchMock.mock.calls.length - 1][0] (or equivalent) to
assert it contains the expected query (?page=2 or ?category=css); keep existing
assertions for routerReplace and window.scrollTo.

@ViktorSvertoka ViktorSvertoka merged commit c94beb3 into develop Jan 25, 2026
9 checks passed
@ViktorSvertoka ViktorSvertoka deleted the chore/remove-contacts-page-references branch January 25, 2026 21:43
ViktorSvertoka added a commit that referenced this pull request Jan 25, 2026
* (SP: 1) [Security] Enforce origin posture for shop APIs (admin/checkout same-origin; internal/webhooks non-browser) + docs

* (SP: 1) [DB] Align stripe_events.order_id FK CASCADE across schema and migrations

* feat(i18n): localize quiz anti-cheat, header and blog filters (#175)

* feat(Blog): Adding last published post to the blog and category page, recommended posts, Changing styles to one unified format, Bug fixes

* Update leaderboard-style

* Update leaderboard-style

* teat(Blog): fix of hover on author, fix of the line

* (SP: 3) [Observability] Extend structured logging + correlation IDs across all shop routes; purge console.*; enforce explicit error codes

* (SP: 1) [Admin][Security] Add safe product delete (PRODUCT_IN_USE) + mobile cards UI; tighten env/docs, locale normalization, cache-control, and logging semantics

* fix: npm installing

* (SP: 1) [Admin] Align products list in use checks with DB column names (order_items/inventory_moves)

* fix:Update leaderboard: fixed background

* fix: remove email from CurrentUser type to prevent PII exposure

* refactor: align leaderboard UI with brand style (fixed bg, css vars, podium glow)

* (SP: 1) [Frontend] About Us Page. Fixed game, topics, mobile layout

- Fixed mobile tabs in FeaturesSection (icon-only on mobile)
- Fixed game bugs: collision detection, animation, scoring system
- Added multiple obstacle types with level progression
- Improved game sizing for mobile while preserving desktop
- Updated TopicsSection with local SVG icons and hover borders
- Made DynamicGridBackground static grid opt-in via showStaticGrid prop
- Limited SponsorsWall to display max 10 sponsors
- Optimized CommunitySection button layout for mobile

* refactor: update accent color hover effects to Footer

- Update Footer links to use --accent-primary on hover
- Update ThemeToggle icons to use --accent-primary on hover
- Both components adapt colors to light/dark theme

* refactor: improve accessibility

- Add focus-visible styles for keyboard navigation accessibility

* (SP: 1) [Shop] Fix Stripe checkout success redirect (remove duplicate locale /uk/uk) (#186)

* fix:leaderboard  update leaderboard-style (#187)

* fix:leaderboard update leaderboard-style on mobile (#188)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

---------

Co-authored-by: Viktor Svertoka <victor.svertoka@gmail.com>

* (SP: 1) [Frontend] Changing hero headline on shop main page (#190)

* (SP: 1) [Shop] Fix checkout redirect 404 by removing duplicate locale in in-app routes and Stripe return_url

* (SP: 1) [Shop] Fix locale cart page and orderid page

* (SP: 1) [Frontend] Changin hero headline on shop main page

* (SP: 1) [Frontend] Fix styles shop home page, buttons (#191)

* Feature/leaderboard style update (#192)

* (SP: 7) [UI] Quiz UI polish: tabs styling, category accents, color scheme (#181, #193, #194) (#195)

* Sanity (#196)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* (SP: 3) [AI] Add AI word helper with Groq integration (#200)

* (SP: 3) [AI] Add AI word helper with Groq integration

- Implement Groq API with Llama 3.1 70B model
- Add text selection detection on Q&A page
- Create floating "Explain" button
- Build draggable modal with 3-language support (uk/en/pl)
- Add localStorage caching for instant repeated lookups
- Implement guest CTA (login/signup)
- Add rate limiting (10 requests/min)
- Auth-gated feature (registered users only)

Components:
- SelectableText: Detects text selection
- FloatingExplainButton: Appears on selection
- AIWordHelper: Main modal with explanations

* (SP: 1) i18n: fix Polish locale and set EN as default

* Sanity (#202)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* Sanity (#203)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* (SP: 3) [Frontend] Refactor Header UI and navigation states (#201)

* (SP: 3) [Frontend] Refactor Header UI and navigation states

- Add icon to the language switcher

- Add GitHub icon with stars indicator (frontend only)

- Update logo styles

- Improve touch interaction styles

- Verify correct placement and alignment of all header components

- Make mobile header modal full-screen

- Disable background scroll when mobile menu is open

- Highlight active navigation item

- Update navigation styles:

- Highlight Shop link when user is on Home pages
- Highlight Home link when user is on Shop pages
- Style changes only, no routing or logic changes

* fix CodeRabbit

* update HeaderButton styles

* fix: add accessibility for HeaderButton

* (SP: 3) [Testing] Vitest config + unit + integration tests for quiz module (#204)

* feat(quiz-ui): quiz UI polish - tabs, category accents, color scheme (issues #181, #193, #194)

- Refactor QaTabButton to shared CategoryTabButton component
- Add category accent colors to QuizCard, buttons, progress indicators
- Standardize colors with CSS variables, traffic light timer
- Add DynamicGridBackground to quizzes list page
- Border-only answer feedback, semi-transparent progress styles

* docs: update .gitignore

* fix(quiz): align disqualification threshold with warning banner

Changed violationsCount > 3 to >= 3 in QuizResult points block
to match the warning banner threshold at line 124.

* feat(quiz-testing): add quiz unit tests

- Configure Vitest for quiz module
- Add test factories and setup utilities
- Add quiz-crypto tests (13 tests)
- Add quiz-session tests (12 tests)

* test(quiz): add integration tests for verify-answer API and useAntiCheat hook (#199)

- verify-answer.test.ts: 8 tests for API endpoint
  - Correct/wrong answer verification
  - Validation errors (missing fields, tampered data)
  - Security: rejects modified encrypted answers

- quiz-anticheat.test.ts: 10 tests for useAntiCheat hook
  - Detects copy, paste, context-menu, tab-switch events
  - Respects isActive flag
  - Reset and cleanup functionality

Total quiz tests: 52 (9 setup + 25 unit + 18 integration)

* test(quiz): expand test coverage to 90%+ with hooks, API routes, and UI flow

Add 28 new tests covering:
- useQuizSession hook (6 tests)
- useQuizGuards hook (8 tests)
- guest-quiz storage (5 tests)
- guest-result API route (5 tests)
- quiz-slug API route (3 tests)
- QuizContainer UI flow (1 test)

Coverage: 35% -> 90.94% (quiz scope)
Tests: 52 -> 80

* chore: remove coverage-quiz from git, add to .gitignore

* chore: add coverage-quiz to .gitignore, fix quiz guards test

* Feature/leaderboard style update (#206)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* fix(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* test(q&a): add comprehensive qa tests and coverage setup (#208)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* (SP: 1) [Frontend] Remove Contacts References (#211)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* chore(nav): remove contacts page references

* Sanity (#209)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* chore(release): update changelog for v0.5.0

* chore(release): v0.5.0

---------

Co-authored-by: liudmylasovetovs <milkaegik@gmail.com>
Co-authored-by: Tetiana Zorii <131365289+TiZorii@users.noreply.github.com>
Co-authored-by: Anna <komrakova.anna@gmail.com>
Co-authored-by: AlinaRyabova <alinavr7@gmail.com>
Co-authored-by: Yevhenii Datsenko <yevheniydatsenko@gmail.com>
Co-authored-by: YNazymko12 <yulychka12@gmail.com>
Co-authored-by: liudmylasovetovs <127711697+liudmylasovetovs@users.noreply.github.com>
Co-authored-by: AlinaRyabova <115992255+AlinaRyabova@users.noreply.github.com>
Co-authored-by: Lesia Soloviova <106915140+LesiaUKR@users.noreply.github.com>
Co-authored-by: Yuliia Nazymko <122815071+YNazymko12@users.noreply.github.com>
ViktorSvertoka added a commit that referenced this pull request Jan 31, 2026
* (SP: 1) [Security] Enforce origin posture for shop APIs (admin/checkout same-origin; internal/webhooks non-browser) + docs

* (SP: 1) [DB] Align stripe_events.order_id FK CASCADE across schema and migrations

* feat(i18n): localize quiz anti-cheat, header and blog filters (#175)

* feat(Blog): Adding last published post to the blog and category page, recommended posts, Changing styles to one unified format, Bug fixes

* Update leaderboard-style

* Update leaderboard-style

* teat(Blog): fix of hover on author, fix of the line

* (SP: 3) [Observability] Extend structured logging + correlation IDs across all shop routes; purge console.*; enforce explicit error codes

* (SP: 1) [Admin][Security] Add safe product delete (PRODUCT_IN_USE) + mobile cards UI; tighten env/docs, locale normalization, cache-control, and logging semantics

* fix: npm installing

* (SP: 1) [Admin] Align products list in use checks with DB column names (order_items/inventory_moves)

* fix:Update leaderboard: fixed background

* fix: remove email from CurrentUser type to prevent PII exposure

* refactor: align leaderboard UI with brand style (fixed bg, css vars, podium glow)

* (SP: 1) [Frontend] About Us Page. Fixed game, topics, mobile layout

- Fixed mobile tabs in FeaturesSection (icon-only on mobile)
- Fixed game bugs: collision detection, animation, scoring system
- Added multiple obstacle types with level progression
- Improved game sizing for mobile while preserving desktop
- Updated TopicsSection with local SVG icons and hover borders
- Made DynamicGridBackground static grid opt-in via showStaticGrid prop
- Limited SponsorsWall to display max 10 sponsors
- Optimized CommunitySection button layout for mobile

* refactor: update accent color hover effects to Footer

- Update Footer links to use --accent-primary on hover
- Update ThemeToggle icons to use --accent-primary on hover
- Both components adapt colors to light/dark theme

* refactor: improve accessibility

- Add focus-visible styles for keyboard navigation accessibility

* (SP: 1) [Shop] Fix Stripe checkout success redirect (remove duplicate locale /uk/uk) (#186)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard  update leaderboard-style (#187)

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix:leaderboard update leaderboard-style on mobile (#188)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

---------

Co-authored-by: Viktor Svertoka <victor.svertoka@gmail.com>

* (SP: 1) [Frontend] Changing hero headline on shop main page (#190)

* (SP: 1) [Shop] Fix checkout redirect 404 by removing duplicate locale in in-app routes and Stripe return_url

* (SP: 1) [Shop] Fix locale cart page and orderid page

* (SP: 1) [Frontend] Changin hero headline on shop main page

* (SP: 1) [Frontend] Fix styles shop home page, buttons (#191)

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* Feature/leaderboard style update (#192)

* (SP: 7) [UI] Quiz UI polish: tabs styling, category accents, color scheme (#181, #193, #194) (#195)

* Sanity (#196)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* (SP: 3) [AI] Add AI word helper with Groq integration (#200)

* (SP: 3) [AI] Add AI word helper with Groq integration

- Implement Groq API with Llama 3.1 70B model
- Add text selection detection on Q&A page
- Create floating "Explain" button
- Build draggable modal with 3-language support (uk/en/pl)
- Add localStorage caching for instant repeated lookups
- Implement guest CTA (login/signup)
- Add rate limiting (10 requests/min)
- Auth-gated feature (registered users only)

Components:
- SelectableText: Detects text selection
- FloatingExplainButton: Appears on selection
- AIWordHelper: Main modal with explanations

* (SP: 1) i18n: fix Polish locale and set EN as default

* Sanity (#202)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* Sanity (#203)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* (SP: 3) [Frontend] Refactor Header UI and navigation states (#201)

* (SP: 3) [Frontend] Refactor Header UI and navigation states

- Add icon to the language switcher

- Add GitHub icon with stars indicator (frontend only)

- Update logo styles

- Improve touch interaction styles

- Verify correct placement and alignment of all header components

- Make mobile header modal full-screen

- Disable background scroll when mobile menu is open

- Highlight active navigation item

- Update navigation styles:

- Highlight Shop link when user is on Home pages
- Highlight Home link when user is on Shop pages
- Style changes only, no routing or logic changes

* fix CodeRabbit

* update HeaderButton styles

* fix: add accessibility for HeaderButton

* (SP: 3) [Testing] Vitest config + unit + integration tests for quiz module (#204)

* feat(quiz-ui): quiz UI polish - tabs, category accents, color scheme (issues #181, #193, #194)

- Refactor QaTabButton to shared CategoryTabButton component
- Add category accent colors to QuizCard, buttons, progress indicators
- Standardize colors with CSS variables, traffic light timer
- Add DynamicGridBackground to quizzes list page
- Border-only answer feedback, semi-transparent progress styles

* docs: update .gitignore

* fix(quiz): align disqualification threshold with warning banner

Changed violationsCount > 3 to >= 3 in QuizResult points block
to match the warning banner threshold at line 124.

* feat(quiz-testing): add quiz unit tests

- Configure Vitest for quiz module
- Add test factories and setup utilities
- Add quiz-crypto tests (13 tests)
- Add quiz-session tests (12 tests)

* test(quiz): add integration tests for verify-answer API and useAntiCheat hook (#199)

- verify-answer.test.ts: 8 tests for API endpoint
  - Correct/wrong answer verification
  - Validation errors (missing fields, tampered data)
  - Security: rejects modified encrypted answers

- quiz-anticheat.test.ts: 10 tests for useAntiCheat hook
  - Detects copy, paste, context-menu, tab-switch events
  - Respects isActive flag
  - Reset and cleanup functionality

Total quiz tests: 52 (9 setup + 25 unit + 18 integration)

* test(quiz): expand test coverage to 90%+ with hooks, API routes, and UI flow

Add 28 new tests covering:
- useQuizSession hook (6 tests)
- useQuizGuards hook (8 tests)
- guest-quiz storage (5 tests)
- guest-result API route (5 tests)
- quiz-slug API route (3 tests)
- QuizContainer UI flow (1 test)

Coverage: 35% -> 90.94% (quiz scope)
Tests: 52 -> 80

* chore: remove coverage-quiz from git, add to .gitignore

* chore: add coverage-quiz to .gitignore, fix quiz guards test

* fix(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* Feature/leaderboard style update (#206)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* fix(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* test(q&a): add comprehensive qa tests and coverage setup (#208)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* (SP: 1) [Frontend] Remove Contacts References (#211)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* chore(nav): remove contacts page references

* Sanity (#209)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* chore(release): update changelog for v0.5.0

* chore(release): v0.5.0

* [Refactor] Code Quality Improvements: Accessibility, Mobile Support, … (#213)

* fix(leaderboard): adjust podium heights for better visibility on desktop

* Feature/leaderboard style update (#214)

* fix(leaderboard): fix layout centering

* feat(Blog) (#216)

* feat(Blog) (#218)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* feat(Blog): added tests

* feat(Blog): fix for big post on the post page, added tests

* feat(Blog): resolving comments

* feat(Blog): fixed hover for social links icins - dark theme

* (SP: 1) feat(i18n): translate 404 error page (#217)

- Add 404 translations (uk/en/pl)
- Implement [Global/Local/Combined] strategy
- Add helpful navigation links

* (SP: 2) [Frontend] Refactor Home HeroSection and Footer stylestor/home (#221)

* (SP:1) fix: 404 page layout (#219)

- 404 translations (uk/en/pl)
- Implement Global strategy

* feat(Blog) (#222)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* feat(Blog): added tests

* feat(Blog): fix for big post on the post page, added tests

* feat(Blog): resolving comments

* feat(Blog): fixed hover for social links icins - dark theme

* feat(Blog): bringing the style on the blog page to a single site style

* feat(blog): aligning syles

* feat(blog): resolving comment from CodeRabbit

* feat(blog):fix comment for deployment

* Update AI model from 'llama-3.3-70b-versatile' to 'llama3-70b-8192' (#223)

* (SP 2) [Frontend] Update Features section content and improve mobile UX (#224)

* (SP 2) [Frontend] Update Features section content and improve mobile UX

- Features Section: Refined feature content and visuals.
- Mobile UX: Improved responsive layout and scaling for feature cards and interactive elements.
- Visual Enhancements: Added dynamic particle background effects to the Pricing section.

* fix(review): address accessibility, security, and performance feedback

* fix(review): resolve accessibility and hydration issues

* fix(perf): implement frame-rate independent animations

* fix(review): address accessibility, security, and performance feedback

* fix(review): enable SSR for features section and support HiDPI canvas

* fix(review): correct HiDPI logic for particle canvas measurements

* (SP:3) feat(i18n): add UA and PL translations for shop/admin pages

Add comprehensive i18n support for shop and admin sections in 3 languages (en, uk,
  pl).

  Translation coverage:
  - Shop pages: main page, products, cart, checkout, orders
  - Admin pages: dashboard, products management, orders management
  - Navigation: header, mobile menu, category links
  - Product components: cards, filters, sort, badges (NEW/SALE)
  - Category names: Apparel, Lifestyle, Collectibles
  - All UI buttons, labels, and actions

  Key changes:
  - Added ~250+ translation keys to messages/en.json, messages/uk.json,
  messages/pl.json
  - Updated 20+ components to use useTranslations() and getTranslations()
  - Implemented color translation in cart and product detail pages
  - Translated hero message
  - Added badge translations

* fix(i18n): correct translation keys and localization in shop pages

  - Replace confusing error.order with success.orderLabel in checkout success page
  heading
  - Localize boolean stockRestored display (yes/no instead of true/false) in order
  details
  - Fix active state detection for shop category links in mobile menu using search
  params
  - Add missing translation keys (orderLabel, yes, no) to all locales (en, uk, pl)

* fix(netlify): resolve AI API crash and 404 locale/theme issues

AI fixes:
  - Extract getClientIp to separate file (avoid db import crash)
  - Add missing zod dependency to package.json

  404 page fixes:
  - Use NEXT_LOCALE cookie for locale detection on Netlify
  - Add theme detection script in root layout
  - Update styling with hero background and gradient text

* Update frontend/app/not-found.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* (SP:3) feat(i18n): translate about page and auth form validation messages

  - Add about page translations (EN, UK, PL)
  - Add auth.fields.validation translations for form errors

* fix(api): resolve Netlify 503 errors and harden AI explain endpoint

 - Use dynamic import for groq-sdk (Netlify compatibility)                                                    - Bypass rate limiting for unknown IPs (serverless safety)
  - Safe JSON parsing with request.text() + empty body check
  - Fix ReferenceError: remove undefined errorMessage variable
  - Remove sensitive debug info from client responses
  - Add i18n keys: pricing.heading, sponsors.ctaAriaLabel

* feat(api): add GET health check endpoint for ai-explain

* chore(release): v0.5.1

---------

Co-authored-by: liudmylasovetovs <milkaegik@gmail.com>
Co-authored-by: Tetiana Zorii <131365289+TiZorii@users.noreply.github.com>
Co-authored-by: Anna <komrakova.anna@gmail.com>
Co-authored-by: AlinaRyabova <alinavr7@gmail.com>
Co-authored-by: Yevhenii Datsenko <yevheniydatsenko@gmail.com>
Co-authored-by: YNazymko12 <yulychka12@gmail.com>
Co-authored-by: liudmylasovetovs <127711697+liudmylasovetovs@users.noreply.github.com>
Co-authored-by: AlinaRyabova <115992255+AlinaRyabova@users.noreply.github.com>
Co-authored-by: Lesia Soloviova <106915140+LesiaUKR@users.noreply.github.com>
Co-authored-by: Yuliia Nazymko <122815071+YNazymko12@users.noreply.github.com>
Co-authored-by: Yevhenii Datsenko <134847096+yevheniidatsenko@users.noreply.github.com>
Co-authored-by: tetiana zorii <tanyusha.zoriy@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@ViktorSvertoka ViktorSvertoka mentioned this pull request Jan 31, 2026
20 tasks
ViktorSvertoka added a commit that referenced this pull request Jan 31, 2026
* (SP: 1) [Security] Enforce origin posture for shop APIs (admin/checkout same-origin; internal/webhooks non-browser) + docs

* (SP: 1) [DB] Align stripe_events.order_id FK CASCADE across schema and migrations

* feat(i18n): localize quiz anti-cheat, header and blog filters (#175)

* feat(Blog): Adding last published post to the blog and category page, recommended posts, Changing styles to one unified format, Bug fixes

* Update leaderboard-style

* Update leaderboard-style

* teat(Blog): fix of hover on author, fix of the line

* (SP: 3) [Observability] Extend structured logging + correlation IDs across all shop routes; purge console.*; enforce explicit error codes

* (SP: 1) [Admin][Security] Add safe product delete (PRODUCT_IN_USE) + mobile cards UI; tighten env/docs, locale normalization, cache-control, and logging semantics

* fix: npm installing

* (SP: 1) [Admin] Align products list in use checks with DB column names (order_items/inventory_moves)

* fix:Update leaderboard: fixed background

* fix: remove email from CurrentUser type to prevent PII exposure

* refactor: align leaderboard UI with brand style (fixed bg, css vars, podium glow)

* (SP: 1) [Frontend] About Us Page. Fixed game, topics, mobile layout

- Fixed mobile tabs in FeaturesSection (icon-only on mobile)
- Fixed game bugs: collision detection, animation, scoring system
- Added multiple obstacle types with level progression
- Improved game sizing for mobile while preserving desktop
- Updated TopicsSection with local SVG icons and hover borders
- Made DynamicGridBackground static grid opt-in via showStaticGrid prop
- Limited SponsorsWall to display max 10 sponsors
- Optimized CommunitySection button layout for mobile

* refactor: update accent color hover effects to Footer

- Update Footer links to use --accent-primary on hover
- Update ThemeToggle icons to use --accent-primary on hover
- Both components adapt colors to light/dark theme

* refactor: improve accessibility

- Add focus-visible styles for keyboard navigation accessibility

* (SP: 1) [Shop] Fix Stripe checkout success redirect (remove duplicate locale /uk/uk) (#186)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard  update leaderboard-style (#187)

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix:leaderboard update leaderboard-style on mobile (#188)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

---------



* (SP: 1) [Frontend] Changing hero headline on shop main page (#190)

* (SP: 1) [Shop] Fix checkout redirect 404 by removing duplicate locale in in-app routes and Stripe return_url

* (SP: 1) [Shop] Fix locale cart page and orderid page

* (SP: 1) [Frontend] Changin hero headline on shop main page

* (SP: 1) [Frontend] Fix styles shop home page, buttons (#191)

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* Feature/leaderboard style update (#192)

* (SP: 7) [UI] Quiz UI polish: tabs styling, category accents, color scheme (#181, #193, #194) (#195)

* Sanity (#196)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* (SP: 3) [AI] Add AI word helper with Groq integration (#200)

* (SP: 3) [AI] Add AI word helper with Groq integration

- Implement Groq API with Llama 3.1 70B model
- Add text selection detection on Q&A page
- Create floating "Explain" button
- Build draggable modal with 3-language support (uk/en/pl)
- Add localStorage caching for instant repeated lookups
- Implement guest CTA (login/signup)
- Add rate limiting (10 requests/min)
- Auth-gated feature (registered users only)

Components:
- SelectableText: Detects text selection
- FloatingExplainButton: Appears on selection
- AIWordHelper: Main modal with explanations

* (SP: 1) i18n: fix Polish locale and set EN as default

* Sanity (#202)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* Sanity (#203)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* (SP: 3) [Frontend] Refactor Header UI and navigation states (#201)

* (SP: 3) [Frontend] Refactor Header UI and navigation states

- Add icon to the language switcher

- Add GitHub icon with stars indicator (frontend only)

- Update logo styles

- Improve touch interaction styles

- Verify correct placement and alignment of all header components

- Make mobile header modal full-screen

- Disable background scroll when mobile menu is open

- Highlight active navigation item

- Update navigation styles:

- Highlight Shop link when user is on Home pages
- Highlight Home link when user is on Shop pages
- Style changes only, no routing or logic changes

* fix CodeRabbit

* update HeaderButton styles

* fix: add accessibility for HeaderButton

* (SP: 3) [Testing] Vitest config + unit + integration tests for quiz module (#204)

* feat(quiz-ui): quiz UI polish - tabs, category accents, color scheme (issues #181, #193, #194)

- Refactor QaTabButton to shared CategoryTabButton component
- Add category accent colors to QuizCard, buttons, progress indicators
- Standardize colors with CSS variables, traffic light timer
- Add DynamicGridBackground to quizzes list page
- Border-only answer feedback, semi-transparent progress styles

* docs: update .gitignore

* fix(quiz): align disqualification threshold with warning banner

Changed violationsCount > 3 to >= 3 in QuizResult points block
to match the warning banner threshold at line 124.

* feat(quiz-testing): add quiz unit tests

- Configure Vitest for quiz module
- Add test factories and setup utilities
- Add quiz-crypto tests (13 tests)
- Add quiz-session tests (12 tests)

* test(quiz): add integration tests for verify-answer API and useAntiCheat hook (#199)

- verify-answer.test.ts: 8 tests for API endpoint
  - Correct/wrong answer verification
  - Validation errors (missing fields, tampered data)
  - Security: rejects modified encrypted answers

- quiz-anticheat.test.ts: 10 tests for useAntiCheat hook
  - Detects copy, paste, context-menu, tab-switch events
  - Respects isActive flag
  - Reset and cleanup functionality

Total quiz tests: 52 (9 setup + 25 unit + 18 integration)

* test(quiz): expand test coverage to 90%+ with hooks, API routes, and UI flow

Add 28 new tests covering:
- useQuizSession hook (6 tests)
- useQuizGuards hook (8 tests)
- guest-quiz storage (5 tests)
- guest-result API route (5 tests)
- quiz-slug API route (3 tests)
- QuizContainer UI flow (1 test)

Coverage: 35% -> 90.94% (quiz scope)
Tests: 52 -> 80

* chore: remove coverage-quiz from git, add to .gitignore

* chore: add coverage-quiz to .gitignore, fix quiz guards test

* fix(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* Feature/leaderboard style update (#206)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* fix(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* test(q&a): add comprehensive qa tests and coverage setup (#208)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* (SP: 1) [Frontend] Remove Contacts References (#211)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* chore(nav): remove contacts page references

* Sanity (#209)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* chore(release): update changelog for v0.5.0

* chore(release): v0.5.0

* [Refactor] Code Quality Improvements: Accessibility, Mobile Support, … (#213)

* fix(leaderboard): adjust podium heights for better visibility on desktop

* Feature/leaderboard style update (#214)

* fix(leaderboard): fix layout centering

* feat(Blog) (#216)

* feat(Blog) (#218)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* feat(Blog): added tests

* feat(Blog): fix for big post on the post page, added tests

* feat(Blog): resolving comments

* feat(Blog): fixed hover for social links icins - dark theme

* (SP: 1) feat(i18n): translate 404 error page (#217)

- Add 404 translations (uk/en/pl)
- Implement [Global/Local/Combined] strategy
- Add helpful navigation links

* (SP: 2) [Frontend] Refactor Home HeroSection and Footer stylestor/home (#221)

* (SP:1) fix: 404 page layout (#219)

- 404 translations (uk/en/pl)
- Implement Global strategy

* feat(Blog) (#222)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* feat(Blog): added tests

* feat(Blog): fix for big post on the post page, added tests

* feat(Blog): resolving comments

* feat(Blog): fixed hover for social links icins - dark theme

* feat(Blog): bringing the style on the blog page to a single site style

* feat(blog): aligning syles

* feat(blog): resolving comment from CodeRabbit

* feat(blog):fix comment for deployment

* Update AI model from 'llama-3.3-70b-versatile' to 'llama3-70b-8192' (#223)

* (SP 2) [Frontend] Update Features section content and improve mobile UX (#224)

* (SP 2) [Frontend] Update Features section content and improve mobile UX

- Features Section: Refined feature content and visuals.
- Mobile UX: Improved responsive layout and scaling for feature cards and interactive elements.
- Visual Enhancements: Added dynamic particle background effects to the Pricing section.

* fix(review): address accessibility, security, and performance feedback

* fix(review): resolve accessibility and hydration issues

* fix(perf): implement frame-rate independent animations

* fix(review): address accessibility, security, and performance feedback

* fix(review): enable SSR for features section and support HiDPI canvas

* fix(review): correct HiDPI logic for particle canvas measurements

* (SP:3) feat(i18n): add UA and PL translations for shop/admin pages

Add comprehensive i18n support for shop and admin sections in 3 languages (en, uk,
  pl).

  Translation coverage:
  - Shop pages: main page, products, cart, checkout, orders
  - Admin pages: dashboard, products management, orders management
  - Navigation: header, mobile menu, category links
  - Product components: cards, filters, sort, badges (NEW/SALE)
  - Category names: Apparel, Lifestyle, Collectibles
  - All UI buttons, labels, and actions

  Key changes:
  - Added ~250+ translation keys to messages/en.json, messages/uk.json,
  messages/pl.json
  - Updated 20+ components to use useTranslations() and getTranslations()
  - Implemented color translation in cart and product detail pages
  - Translated hero message
  - Added badge translations

* fix(i18n): correct translation keys and localization in shop pages

  - Replace confusing error.order with success.orderLabel in checkout success page
  heading
  - Localize boolean stockRestored display (yes/no instead of true/false) in order
  details
  - Fix active state detection for shop category links in mobile menu using search
  params
  - Add missing translation keys (orderLabel, yes, no) to all locales (en, uk, pl)

* fix(netlify): resolve AI API crash and 404 locale/theme issues

AI fixes:
  - Extract getClientIp to separate file (avoid db import crash)
  - Add missing zod dependency to package.json

  404 page fixes:
  - Use NEXT_LOCALE cookie for locale detection on Netlify
  - Add theme detection script in root layout
  - Update styling with hero background and gradient text

* Update frontend/app/not-found.tsx



* (SP:3) feat(i18n): translate about page and auth form validation messages

  - Add about page translations (EN, UK, PL)
  - Add auth.fields.validation translations for form errors

* fix(api): resolve Netlify 503 errors and harden AI explain endpoint

 - Use dynamic import for groq-sdk (Netlify compatibility)                                                    - Bypass rate limiting for unknown IPs (serverless safety)
  - Safe JSON parsing with request.text() + empty body check
  - Fix ReferenceError: remove undefined errorMessage variable
  - Remove sensitive debug info from client responses
  - Add i18n keys: pricing.heading, sponsors.ctaAriaLabel

* feat(api): add GET health check endpoint for ai-explain

* chore(release): v0.5.1

---------

Co-authored-by: liudmylasovetovs <milkaegik@gmail.com>
Co-authored-by: Tetiana Zorii <131365289+TiZorii@users.noreply.github.com>
Co-authored-by: Anna <komrakova.anna@gmail.com>
Co-authored-by: AlinaRyabova <alinavr7@gmail.com>
Co-authored-by: Yevhenii Datsenko <yevheniydatsenko@gmail.com>
Co-authored-by: YNazymko12 <yulychka12@gmail.com>
Co-authored-by: liudmylasovetovs <127711697+liudmylasovetovs@users.noreply.github.com>
Co-authored-by: AlinaRyabova <115992255+AlinaRyabova@users.noreply.github.com>
Co-authored-by: Lesia Soloviova <106915140+LesiaUKR@users.noreply.github.com>
Co-authored-by: Yuliia Nazymko <122815071+YNazymko12@users.noreply.github.com>
Co-authored-by: Yevhenii Datsenko <134847096+yevheniidatsenko@users.noreply.github.com>
Co-authored-by: tetiana zorii <tanyusha.zoriy@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Code restructuring without functional changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(SP: 1) [Frontend] Remove Contacts References

1 participant