Skip to content
This repository was archived by the owner on Jul 20, 2026. It is now read-only.

Adapt to NGM Index v2 + rebrand to the Jawafdehi identity - #21

Merged
damo-da merged 2 commits into
mainfrom
documentsource-format
Jun 26, 2026
Merged

Adapt to NGM Index v2 + rebrand to the Jawafdehi identity#21
damo-da merged 2 commits into
mainfrom
documentsource-format

Conversation

@damo-da

@damo-da damo-da commented Jun 26, 2026

Copy link
Copy Markdown
Member

Pairs with the backend NGM Index v2 change (Jawafdehi/ngm#88). Two parts; check the Cloudflare branch preview for the visual.

1. Adapt index consumption to consolidated manuscripts

The backend now emits one consolidated manuscript per logical document with a roled links array (RAW/ALTERNATE/SOURCE_PAGE/MARKDOWN), a document_id, and a source_type; the old url/file_name remain as a back-compat alias.

  • Manuscript type extended; helpers fileLinks/linkByRole/primaryUrl/extFromUrl fall back to the legacy url, so old index snapshots still render during rollout.
  • Press releases: dropped the client-side group-by-press_id (the backend consolidates now); render each release's attachments from links, plus a Transcript (MARKDOWN) and Source (SOURCE_PAGE) chip when present. De-dup by press_id kept only to tolerate legacy snapshots.
  • Court orders: one row per case, all file links rendered.
  • Kanun Patrika / CIAA reports read links via primaryUrl.

2. Rebrand to the Jawafdehi identity + simplify the IA

  • Brand system: index.css retokenized to brand navy #0E1F3A / crimson #B5242C / warm white + the brand font stack; every generic-blue literal (CSS + inline styles) swept to brand tokens; hero gradient navy→crimson.
  • Identity: navy header with the Jawafdehi wordmark (logo-dark.svg) + an "NGM · Nepal Governance Modernization" tag, crimson active-nav underline, and a brand footer ("A project of Jawafdehi · CC BY-NC 4.0"). Landing rebuilt with a brand hero + FAQ-aligned copy.
  • IA: removed the Archive's redundant CIAA Dataset and Court Cases tabs (they duplicated the dedicated /dataset and /search pages). Nav is now Home · Court Cases · Archive · CIAA Cases · Status.

Verification

tsc -b + vite build clean; eslint 0 errors (only pre-existing exhaustive-deps warnings).

Follow-ups (not in this PR)

  • Deeper IA restructure (e.g. a unified Records hub / cross-source search) — a first pass is here; more possible.
  • Optionally link documents to the new per-document HTML landing pages via document_id.

🤖 Generated with Claude Code

damo-da and others added 2 commits June 26, 2026 03:37
The backend now emits one consolidated manuscript per logical document with a
roled `links` array (RAW/ALTERNATE/SOURCE_PAGE/MARKDOWN), a `document_id`, and a
`source_type`; the old `url`/`file_name` remain as a back-compat alias.

- Extend the Manuscript type with links/document_id/source_type and add
  fileLinks/linkByRole/primaryUrl/extFromUrl helpers that fall back to the legacy
  `url` (so old index snapshots still render during rollout).
- Press releases: drop the client-side group-by-press_id (the backend now
  consolidates); render each release's attachments from `links`, plus a
  transcript (MARKDOWN) and Source (SOURCE_PAGE) link when present. De-dup by
  press_id is kept only to tolerate legacy snapshots.
- Court orders: one row per case, rendering all its file links.
- Kanun Patrika / CIAA reports: read links via primaryUrl.

Typecheck + lint clean (only pre-existing exhaustive-deps warnings).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Align ngm.jawafdehi.org with the Jawafdehi brand and streamline the experience.

Brand design system:
- index.css tokens recolored to brand navy #0E1F3A / crimson #B5242C / warm white,
  brand font stack (Helvetica/Arial/Noto Sans Devanagari), navy-tinted shadows.
- Replace every generic-blue literal (App.css + inline styles across the pages and
  components) with brand tokens; hero gradient is navy -> crimson.

Identity:
- Navy header with the Jawafdehi wordmark (logo-dark.svg) + an "NGM · Nepal
  Governance Modernization" tag, crimson active-nav underline, and a brand footer
  ("A project of Jawafdehi", CC BY-NC 4.0).
- Landing rebuilt: brand hero + eyebrow, FAQ-aligned About copy, clear entry cards.

IA simplification:
- Drop the Archive's redundant "CIAA Cases Dataset" and "Court Cases" tabs (they
  duplicated the dedicated /dataset and /search pages); the Archive is now the
  document datasets only. Nav: Home · Court Cases · Archive · CIAA Cases · Status.

Typecheck + production build clean; lint 0 errors (only pre-existing deps warnings).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@damo-da, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 16 minutes and 10 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b877cee5-856b-4d6e-a3ff-0e423f302433

📥 Commits

Reviewing files that changed from the base of the PR and between 4d0f8f2 and 75e8534.

📒 Files selected for processing (8)
  • src/App.css
  • src/components/CIAADatasetViewer.tsx
  • src/components/CourtCaseSearch.tsx
  • src/components/IndexViewer.tsx
  • src/components/Layout.tsx
  • src/index.css
  • src/pages/CaseDetailPage.tsx
  • src/pages/LandingPage.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch documentsource-format

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.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ngm-frontend 75e8534 Commit Preview URL

Branch Preview URL
Jun 26 2026, 03:55 AM

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the application's design system to align with the Jawafdehi brand identity, introducing a new color palette, typography, and layout adjustments. It also implements support for NGM Index v2 by introducing structured manuscript links and refactoring the navigation. The review feedback highlights opportunities to further align legacy hardcoded background colors with the new design system variables, fix WCAG accessibility issues regarding low text contrast on disabled buttons, and add defensive checks to prevent potential runtime crashes from malformed API payloads or undefined properties.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 226 to +229
background: '#f0f4ff',
borderRadius: '12px',
marginBottom: '1.5rem',
border: '2px solid #bfdbfe'
border: '2px solid var(--border-cool)'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The background color #f0f4ff is a hardcoded light blue from the legacy theme. To align with the new Jawafdehi brand identity and design system, this should be replaced with the var(--bg-tint) CSS variable.

Suggested change
background: '#f0f4ff',
borderRadius: '12px',
marginBottom: '1.5rem',
border: '2px solid #bfdbfe'
border: '2px solid var(--border-cool)'
background: 'var(--bg-tint)',
borderRadius: '12px',
marginBottom: '1.5rem',
border: '2px solid var(--border-cool)'

Comment on lines +322 to 323
background: !loading && caseNumber.trim() ? 'var(--navy)' : 'var(--border-cool)',
color: 'white',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

When the search button is disabled, its background is set to var(--border-cool) (a very light gray, #DCE2EA), but the text color remains white. This results in a contrast ratio of 1.36:1, which is extremely low and violates WCAG accessibility standards. Setting the text color to var(--text-secondary) when disabled will ensure proper readability.

Suggested change
background: !loading && caseNumber.trim() ? 'var(--navy)' : 'var(--border-cool)',
color: 'white',
background: !loading && caseNumber.trim() ? 'var(--navy)' : 'var(--border-cool)',
color: !loading && caseNumber.trim() ? 'white' : 'var(--text-secondary)',

Comment on lines +98 to +100
function fileLinks(m: Manuscript): SourceLink[] {
const roled = (m.links ?? []).filter((l) => l.role === 'RAW' || l.role === 'ALTERNATE');
if (roled.length > 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Add a defensive check to ensure that elements within m.links are not null or undefined before accessing their role property. This prevents potential runtime crashes if the API returns malformed link arrays.

Suggested change
function fileLinks(m: Manuscript): SourceLink[] {
const roled = (m.links ?? []).filter((l) => l.role === 'RAW' || l.role === 'ALTERNATE');
if (roled.length > 0) {
function fileLinks(m: Manuscript): SourceLink[] {
const roled = (m.links ?? []).filter((l) => l && (l.role === 'RAW' || l.role === 'ALTERNATE'));

Comment on lines +107 to +108
function linkByRole(m: Manuscript, role: LinkRole): string | undefined {
return m.links?.find((l) => l.role === role)?.link;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Add a defensive check to ensure that elements within m.links are not null or undefined before accessing their role property.

Suggested change
function linkByRole(m: Manuscript, role: LinkRole): string | undefined {
return m.links?.find((l) => l.role === role)?.link;
function linkByRole(m: Manuscript, role: LinkRole): string | undefined {
return m.links?.find((l) => l && l.role === role)?.link;

Comment on lines +117 to +118
function extFromUrl(u: string): string {
return u.match(/\.([A-Za-z0-9]+)(?:[?#]|$)/)?.[1]?.toUpperCase() || 'FILE';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

If u is undefined, null, or not a string, calling u.match will throw a runtime TypeError. Adding a defensive type guard makes this helper robust against unexpected API payloads.

function extFromUrl(u: string | undefined | null): string {
    if (!u || typeof u !== 'string') return 'FILE';
    return u.match(/\.([A-Za-z0-9]+)(?:[?#]|$)/)?.[1]?.toUpperCase() || 'FILE';

Comment on lines +846 to 852
const key = hasValidPressId ? `press:${parsed}` : `file:${item.url}`;
const existing = byPressId.get(key);
if (!existing) {
byPressId.set(key, { ...item });
} else {
existing.links = [...fileLinks(existing), ...fileLinks(item)];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using item.url as the key for grouping can fail for NGM Index v2 manuscripts that only carry the links array and omit the legacy url property, causing them to group under "file:undefined". Using primaryUrl(item) is much more robust. Additionally, updating the map value by creating a new object rather than mutating existing in-place is a cleaner, safer pattern.

            const key = hasValidPressId ? `press:${parsed}` : `file:${primaryUrl(item)}`;
            const existing = byPressId.get(key);
            if (!existing) {
                byPressId.set(key, { ...item });
            } else {
                byPressId.set(key, {
                    ...existing,
                    links: [...fileLinks(existing), ...fileLinks(item)]
                });
            }

Comment on lines 1061 to +1064
background: '#f0f4ff',
borderRadius: '12px',
marginBottom: '1.5rem',
border: '2px solid #bfdbfe'
border: '2px solid var(--border-cool)'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The background color #f0f4ff is a hardcoded light blue from the legacy theme. To align with the new Jawafdehi brand identity and design system, this should be replaced with the var(--bg-tint) CSS variable.

Suggested change
background: '#f0f4ff',
borderRadius: '12px',
marginBottom: '1.5rem',
border: '2px solid #bfdbfe'
border: '2px solid var(--border-cool)'
background: 'var(--bg-tint)',
borderRadius: '12px',
marginBottom: '1.5rem',
border: '2px solid var(--border-cool)'

Comment on lines +1155 to 1156
background: courtFilters.selectedCourt && !isLoading ? 'var(--navy)' : 'var(--border-cool)',
color: 'white',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

When the search button is disabled, its background is set to var(--border-cool) (a very light gray, #DCE2EA), but the text color remains white. This results in a contrast ratio of 1.36:1, which is extremely low and violates WCAG accessibility standards. Setting the text color to var(--text-secondary) when disabled will ensure proper readability.

Suggested change
background: courtFilters.selectedCourt && !isLoading ? 'var(--navy)' : 'var(--border-cool)',
color: 'white',
background: courtFilters.selectedCourt && !isLoading ? 'var(--navy)' : 'var(--border-cool)',
color: courtFilters.selectedCourt && !isLoading ? 'white' : 'var(--text-secondary)',

@damo-da
damo-da merged commit 04e972d into main Jun 26, 2026
3 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant