Skip to content

Feat/i18n support - #146

Open
oscar24357 wants to merge 6 commits into
ToluLabs:mainfrom
oscar24357:feat/i18n-support
Open

Feat/i18n support#146
oscar24357 wants to merge 6 commits into
ToluLabs:mainfrom
oscar24357:feat/i18n-support

Conversation

@oscar24357

@oscar24357 oscar24357 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

closes #131

Greptile Summary

This PR adds English/Spanish i18n support via next-intl, introduces a LangSwitcher component, a LocaleProvider context, and a tag-driven release workflow with commitlint enforcement. The English and Spanish message catalogues are complete and the infrastructure files (lib/i18n.ts, lib/locale-context.tsx, LangSwitcher.tsx) are well-structured.

  • Widespread merge artifacts across six page files — the i18n strings were inserted at the top of each rendering block but the original hardcoded strings were not removed, producing duplicate rendered content, unclosed JSX elements, duplicate JSX attributes, and malformed ternary chains that prevent compilation.
  • frontend/app/layout.tsx duplicates the entire render tree and frontend/i18n.ts hard-codes defaultLocale for the server config, so even after compile errors are resolved, server-rendered content will always render in English regardless of user preference.
  • frontend/components/SiteNav.tsx and two page files have duplicate named imports / duplicate prop attributes that are TypeScript compile errors independent of the runtime issues.

Confidence Score: 1/5

Not safe to merge — six page files have unclosed JSX elements, duplicate JSX attributes, or malformed ternary chains that block compilation entirely.

The i18n strings were inserted alongside the original hardcoded strings rather than replacing them. Across apps/page.tsx, apps/[id]/page.tsx, holder/page.tsx, issuer/page.tsx, verify/page.tsx, and SiteNav.tsx there are compile-blocking issues: duplicate placeholder and title JSX attributes, unclosed ternary expressions inside button children, an unclosed simulation-info div that swallows subsequent layout nodes, and a ternary chain that terminates early leaving dangling fragments outside the JSX expression. The full-page duplicate render tree in layout.tsx and the hard-coded server locale in i18n.ts are additional correctness issues that would surface immediately after the compile errors are resolved.

Files Needing Attention: Every modified page file needs attention: app/apps/page.tsx, app/apps/[id]/page.tsx, app/holder/page.tsx, app/issuer/page.tsx, app/verify/page.tsx, app/layout.tsx, and components/SiteNav.tsx.

Important Files Changed

Filename Overview
frontend/app/apps/page.tsx i18n strings added but old hardcoded text not removed; unclosed subtitle div (previously flagged) and duplicate placeholder attribute on the search input (compile error)
frontend/app/apps/[id]/page.tsx Unclosed {!activeWallet && ( expression (previously flagged) plus a new unclosed ternary inside the action button's children — both prevent compilation
frontend/app/holder/page.tsx Multiple merge artifacts: duplicate title prop on button (compile error), duplicated expiry text rendered twice, unclosed JSX div and sibling-expression errors (previously flagged)
frontend/app/issuer/page.tsx Duplicate useState import (previously flagged), duplicate heading renders two eyebrow+h1 pairs, and the new simulation banner div is never closed — nesting swallows the rest of the layout
frontend/app/layout.tsx Duplicate render tree (previously flagged) — new LocaleProvider/WalletProvider tree prepended without removing the original ToastProvider/WalletProvider tree; globals.css imported twice
frontend/app/verify/page.tsx Duplicate redirectAfterIssue body (previously flagged), ternary chain short-circuits early causing income/accreditation/employment labels to break, and duplicate Plaid balance display spans
frontend/app/verifier/page.tsx Core i18n wiring is correct; several strings ("Proved", "Needed", "Prove eligibility to deposit", footer paragraph) remain hardcoded English and were not translated
frontend/app/page.tsx Home page i18n looks correct; STEPS moved inside the component to access t(), STATS_VALUES refactored to use translation keys — clean change
frontend/lib/locale-context.tsx if (!messages) return null causes a full-page blank on first render while messages load (previously flagged); locale hydration from localStorage is otherwise correct
frontend/i18n.ts Server-side getRequestConfig hard-codes defaultLocale ("en") and never reads the user's actual locale (previously flagged) — server-rendered strings always render in English
frontend/components/LangSwitcher.tsx New EN/ES toggle component — clean, accessible with aria-pressed, consumes LocaleContext correctly
frontend/components/SiteNav.tsx Duplicate named imports IconBook2 and IconCode (previously flagged) — compile error
frontend/lib/i18n.ts Clean locale/storage helpers; browser-language auto-detection and localStorage persistence are correct
frontend/messages/en.json Comprehensive English message catalogue covering all UI namespaces; ICU placeholder syntax is consistent
.github/workflows/release.yml New tag-driven release workflow: generates CHANGELOG, creates GitHub Release, and publishes SDK to npm; git push origin HEAD:main from the release job could conflict with branch protection rules requiring PRs

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Browser Request] --> B[layout.tsx]
    B --> C{LocaleProvider}
    C -->|useEffect: loads messages| D[localStorage / navigator.language]
    D --> E[import messages/locale.json]
    E --> F{messages loaded?}
    F -->|null return null| G[Blank page flash]
    F -->|messages set| H[NextIntlClientProvider]
    H --> I[WalletProvider]
    I --> J[SiteNav + LangSwitcher]
    I --> K[Page children]
    B --> L[Original ToastProvider tree still present]
    L --> M[Duplicate SiteNav]
    L --> N[Duplicate main/footer]
Loading

Comments Outside Diff (1)

  1. frontend/app/issuer/page.tsx, line 179-200 (link)

    P0 Unclosed simulation-info <div> — JSX structural error

    The new i18n simulation banner opens <div style={{...}}> at line 179 but is never closed with </div>. The original <div ...> at line 182 starts immediately inside it as a child. The outer div swallows all subsequent sibling content until something forces the JSX tree to fail, producing either a parse error or deeply mis-nested markup at runtime.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: frontend/app/issuer/page.tsx
    Line: 179-200
    
    Comment:
    **Unclosed simulation-info `<div>` — JSX structural error**
    
    The new i18n simulation banner opens `<div style={{...}}>` at line 179 but is never closed with `</div>`. The original `<div ...>` at line 182 starts immediately inside it as a child. The outer div swallows all subsequent sibling content until something forces the JSX tree to fail, producing either a parse error or deeply mis-nested markup at runtime.
    
    ---
    
    For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

    Fix in Codex Fix in Claude Code Fix in Cursor

Fix All in Codex Fix All in Claude Code Fix All in Cursor

Prompt To Fix All With AI
### Issue 1
frontend/app/apps/[id]/page.tsx:263-267
**Unclosed ternary in button children — parse error**

Line 263 opens `{eligible ? protocol.actionLabel : (` but the false-branch parenthesis is never closed. On line 265 a second standalone `{isPreview ? ...}` expression follows immediately as a sibling, without the first ternary having ended. This makes the button's `children` a malformed JSX expression that the TypeScript parser rejects. The new i18n button block (lines 263–264) and the legacy `isPreview` conditional (lines 265–267) must be reconciled into a single expression. This is separate from the `{!activeWallet && (` unclosed expression already flagged at line 187.

### Issue 2
frontend/app/issuer/page.tsx:179-200
**Unclosed simulation-info `<div>` — JSX structural error**

The new i18n simulation banner opens `<div style={{...}}>` at line 179 but is never closed with `</div>`. The original `<div ...>` at line 182 starts immediately inside it as a child. The outer div swallows all subsequent sibling content until something forces the JSX tree to fail, producing either a parse error or deeply mis-nested markup at runtime.

### Issue 3
frontend/app/verify/page.tsx:690-707
**Ternary chain short-circuits early — `income`, `accreditation`, and `employment` labels broken**

Lines 698–699 introduce a new terminal ternary arm `: m.claim}` that closes the entire JSX expression at line 699. The old branches for `income > $...` (line 700), `accreditation` (lines 701–703), and `employment` (lines 704–707) now sit outside the closed `{ }` as dangling JSX fragments that start with `?`, which is a syntax error. Even if the parser somehow tolerates the structure, any credential with `key === "income"` no longer shows a threshold label — it falls to `m.claim` (the raw claim type) instead. Additionally the new `funds` branch on line 691 writes `balance > ${...}` without the `$` currency prefix, whereas the original on line 693 correctly wrote `balance > $${...}`.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (5): Last reviewed commit: "Merge branch 'main' into feat/i18n-suppo..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

@oscar24357 is attempting to deploy a commit to the psalmuel01's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jul 26, 2026

Copy link
Copy Markdown

@oscar24357 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Comment thread frontend/components/SiteNav.tsx
Comment thread frontend/app/issuer/page.tsx
Comment thread frontend/app/holder/page.tsx
Comment thread frontend/i18n.ts
@oscar24357

Copy link
Copy Markdown
Contributor Author

hello maintainer, can you please assign the point for me on drips

Comment thread frontend/app/holder/page.tsx
@oscar24357

Copy link
Copy Markdown
Contributor Author

Hello maintainer, good evening. Can you please award this points to me on drips..thank you

@oscar24357

Copy link
Copy Markdown
Contributor Author

can you please give me the point to this too

Comment thread frontend/app/apps/[id]/page.tsx
Comment on lines 690 to 707
@@ -638,8 +707,19 @@ function VerifyInner() {
: m.claim}

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.

P0 Ternary chain short-circuits early — income, accreditation, and employment labels broken

Lines 698–699 introduce a new terminal ternary arm : m.claim} that closes the entire JSX expression at line 699. The old branches for income > $... (line 700), accreditation (lines 701–703), and employment (lines 704–707) now sit outside the closed { } as dangling JSX fragments that start with ?, which is a syntax error. Even if the parser somehow tolerates the structure, any credential with key === "income" no longer shows a threshold label — it falls to m.claim (the raw claim type) instead. Additionally the new funds branch on line 691 writes balance > ${...} without the $ currency prefix, whereas the original on line 693 correctly wrote balance > $${...}.

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/app/verify/page.tsx
Line: 690-707

Comment:
**Ternary chain short-circuits early — `income`, `accreditation`, and `employment` labels broken**

Lines 698–699 introduce a new terminal ternary arm `: m.claim}` that closes the entire JSX expression at line 699. The old branches for `income > $...` (line 700), `accreditation` (lines 701–703), and `employment` (lines 704–707) now sit outside the closed `{ }` as dangling JSX fragments that start with `?`, which is a syntax error. Even if the parser somehow tolerates the structure, any credential with `key === "income"` no longer shows a threshold label — it falls to `m.claim` (the raw claim type) instead. Additionally the new `funds` branch on line 691 writes `balance > ${...}` without the `$` currency prefix, whereas the original on line 693 correctly wrote `balance > $${...}`.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex Fix in Claude Code Fix in Cursor

@oscar24357

Copy link
Copy Markdown
Contributor Author

hello boss, can you award this points to me on drips please, thank you

@Psalmuel01

Copy link
Copy Markdown
Collaborator

ci failing, and greptile score is 1/5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Internationalization (i18n): extract UI strings and add language switching

2 participants