Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

Commit

Permalink
[Issue #167] Fix search page string translation (#169)
Browse files Browse the repository at this point in the history
## Summary
Fixes #167 

### Time to review: __5 mins__

## Changes proposed
Updated most search strings on Search page to use correct next-intl
translation components
Added strings to Messages file

## Context for reviewers
Updated the unit tests as well because they were not inheriting context
due to improper import path from non-global context source

## Additional information
<img width="1583" alt="Screenshot 2024-08-07 at 1 36 18 PM"
src="https://github.com/user-attachments/assets/1b613d26-cbd0-4d0e-b831-0380c6f72af6">
  • Loading branch information
btabaska authored Aug 8, 2024
1 parent 9eb8aa2 commit 779de85
Show file tree
Hide file tree
Showing 22 changed files with 201 additions and 75 deletions.
12 changes: 6 additions & 6 deletions frontend/src/app/[locale]/search/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ interface searchParamsTypes {

function Search({ searchParams }: { searchParams: searchParamsTypes }) {
unstable_setRequestLocale("en");
const t = useTranslations("Process");
const t = useTranslations("Search");
const convertedSearchParams = convertSearchParamsToProperTypes(searchParams);
const {
agency,
Expand All @@ -71,7 +71,7 @@ function Search({ searchParams }: { searchParams: searchParamsTypes }) {

return (
<>
<PageSEO title={t("page_title")} description={t("meta_description")} />
<PageSEO title={t("title")} description={t("meta_description")} />
<BetaAlert />
<Breadcrumbs breadcrumbList={SEARCH_CRUMBS} />
<SearchCallToAction />
Expand All @@ -85,25 +85,25 @@ function Search({ searchParams }: { searchParams: searchParamsTypes }) {
<SearchOpportunityStatus query={status} />
<SearchFilterAccordion
filterOptions={fundingOptions}
title="Funding instrument"
title={t("accordion.titles.funding")}
queryParamKey="fundingInstrument"
query={fundingInstrument}
/>
<SearchFilterAccordion
filterOptions={eligibilityOptions}
title="Eligibility"
title={t("accordion.titles.eligibility")}
queryParamKey="eligibility"
query={eligibility}
/>
<SearchFilterAccordion
filterOptions={agencyOptions}
title="Agency"
title={t("accordion.titles.agency")}
queryParamKey="agency"
query={agency}
/>
<SearchFilterAccordion
filterOptions={categoryOptions}
title="Category"
title={t("accordion.titles.category")}
queryParamKey="category"
query={category}
/>
Expand Down
15 changes: 10 additions & 5 deletions frontend/src/components/search/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Icon } from "@trussworks/react-uswds";
import { QueryContext } from "src/app/[locale]/search/QueryProvider";
import { useContext } from "react";
import { useSearchParamUpdater } from "src/hooks/useSearchParamUpdater";
import { useTranslations } from "next-intl";

interface SearchBarProps {
query: string | null | undefined;
Expand All @@ -16,16 +17,20 @@ export default function SearchBar({ query }: SearchBarProps) {
updateQueryParams("", "query", queryTerm, false);
};

const t = useTranslations("Search");

return (
<div className="margin-top-5 margin-bottom-2">
<label
htmlFor="query"
className="font-sans-lg display-block margin-bottom-2"
>
<span className="text-bold">Search terms </span>
<small className="display-inline-block">
Enter keywords, opportunity numbers, or assistance listing numbers
</small>
{t.rich("bar.label", {
strong: (chunks) => <span className="text-bold">{chunks}</span>,
small: (chunks) => (
<small className="display-inline-block">{chunks}</small>
),
})}
</label>
<div className="usa-search usa-search--big" role="search">
<input
Expand All @@ -40,7 +45,7 @@ export default function SearchBar({ query }: SearchBarProps) {
}}
/>
<button className="usa-button" type="submit" onClick={handleSubmit}>
<span className="usa-search__submit-text">Search </span>
<span className="usa-search__submit-text">{t("bar.button")} </span>
<Icon.Search
className="usa-search__submit-icon"
size={4}
Expand Down
11 changes: 7 additions & 4 deletions frontend/src/components/search/SearchCallToAction.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { GridContainer } from "@trussworks/react-uswds";
import React from "react";
import { useTranslations } from "next-intl";

const SearchCallToAction: React.FC = () => {
const t = useTranslations("Search");

return (
<>
{/* <BetaAlert /> */}
<GridContainer>
<h1 className="margin-0 tablet-lg:font-sans-xl desktop-lg:font-sans-2xl">
Search funding opportunities
{t("callToAction.title")}
</h1>
<p className="font-serif-md tablet-lg:font-serif-lg usa-intro margin-top-2">
We’re incrementally improving this experimental search page. How can
we make it easier to discover grants that are right for you? Let us
know at <a href="mailto:[email protected]">[email protected]</a>.
{t.rich("callToAction.description", {
mail: (chunks) => <a href="mailto:simpler@grants.gov">{chunks}</a>,
})}
</p>
</GridContainer>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"use client";
import { useTranslations } from "next-intl";

interface SearchFilterToggleAllProps {
isAllSelected: boolean;
Expand All @@ -13,6 +14,8 @@ const SearchFilterToggleAll: React.FC<SearchFilterToggleAllProps> = ({
isAllSelected,
isNoneSelected,
}) => {
const t = useTranslations("Search");

return (
<div className="grid-row">
<div className="grid-col-fill">
Expand All @@ -24,7 +27,7 @@ const SearchFilterToggleAll: React.FC<SearchFilterToggleAllProps> = ({
}}
disabled={isAllSelected}
>
Select All
{t("filterToggleAll.select")}
</button>
</div>
<div className="grid-col-fill text-right">
Expand All @@ -36,7 +39,7 @@ const SearchFilterToggleAll: React.FC<SearchFilterToggleAllProps> = ({
}}
disabled={isNoneSelected}
>
Clear All
{t("filterToggleAll.clear")}
</button>
</div>
</div>
Expand Down
37 changes: 29 additions & 8 deletions frontend/src/components/search/SearchOpportunityStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Checkbox } from "@trussworks/react-uswds";
import { QueryContext } from "src/app/[locale]/search/QueryProvider";
import { useContext } from "react";
import { useSearchParamUpdater } from "src/hooks/useSearchParamUpdater";
import { useTranslations } from "next-intl";

interface StatusOption {
id: string;
Expand All @@ -14,13 +15,6 @@ interface SearchOpportunityStatusProps {
query: Set<string>;
}

const statusOptions: StatusOption[] = [
{ id: "status-forecasted", label: "Forecasted", value: "forecasted" },
{ id: "status-posted", label: "Posted", value: "posted" },
{ id: "status-closed", label: "Closed", value: "closed" },
{ id: "status-archived", label: "Archived", value: "archived" },
];

export default function SearchOpportunityStatus({
query,
}: SearchOpportunityStatusProps) {
Expand All @@ -33,9 +27,36 @@ export default function SearchOpportunityStatus({
updateQueryParams(updated, "status", queryTerm);
};

const t = useTranslations("Search");

const statusOptions: StatusOption[] = [
{
id: "status-forecasted",
label: t("opportunityStatus.label.forecasted"),
value: "forecasted",
},
{
id: "status-posted",
label: t("opportunityStatus.label.posted"),
value: "posted",
},
{
id: "status-closed",
label: t("opportunityStatus.label.closed"),
value: "closed",
},
{
id: "status-archived",
label: t("opportunityStatus.label.archived"),
value: "archived",
},
];

return (
<>
<h2 className="margin-bottom-1 font-sans-xs">Opportunity status</h2>
<h2 className="margin-bottom-1 font-sans-xs">
{t("opportunityStatus.title")}
</h2>
<div className="grid-row flex-wrap">
{statusOptions.map((option) => {
return (
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/components/search/SearchResultsHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import SearchSortyBy from "./SearchSortBy";
import { QueryContext } from "src/app/[locale]/search/QueryProvider";
import { useContext } from "react";
import { useTranslations } from "next-intl";

export default function SearchResultsHeader({
sortby,
Expand All @@ -23,10 +24,13 @@ export default function SearchResultsHeader({
"tablet-lg:margin-bottom-0",
];
if (loading) gridRowClasses.push("opacity-50");

const t = useTranslations("Search");

return (
<div className="grid-row">
<h2 className={gridRowClasses.join(" ")}>
{total && <>{total} Opportunities</>}
{t("resultsHeader.message", { count: total })}
</h2>
<div className="tablet-lg:grid-col-auto">
<SearchSortyBy
Expand Down
19 changes: 7 additions & 12 deletions frontend/src/components/search/SearchResultsListFetch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import SearchErrorAlert from "src/components/search/error/SearchErrorAlert";
import SearchResultsListItem from "src/components/search/SearchResultsListItem";
import { getSearchFetcher } from "src/services/search/searchfetcher/SearchFetcherUtil";
import { QueryParamData } from "src/services/search/searchfetcher/SearchFetcher";
import { getTranslations } from "next-intl/server";

interface ServerPageProps {
searchParams: QueryParamData;
Expand All @@ -13,6 +14,7 @@ export default async function SearchResultsListFetch({
const searchFetcher = getSearchFetcher();
const searchResults = await searchFetcher.fetchOpportunities(searchParams);
const maxPaginationError = null;
const t = await getTranslations("Search");

if (searchResults.status_code !== 200) {
return <SearchErrorAlert />;
Expand All @@ -21,12 +23,11 @@ export default async function SearchResultsListFetch({
if (searchResults.data.length === 0) {
return (
<div>
<h2>Your search did not return any results.</h2>
<h2>{t("resultsListFetch.title")}</h2>
<ul>
<li>{"Check any terms you've entered for typos"}</li>
<li>Try different keywords</li>
<li>{"Make sure you've selected the right statuses"}</li>
<li>Try resetting filters or selecting fewer options</li>
{t.rich("resultsListFetch.body", {
li: (chunks) => <li>{chunks}</li>,
})}
</ul>
</div>
);
Expand All @@ -35,13 +36,7 @@ export default async function SearchResultsListFetch({
return (
<ul className="usa-list--unstyled">
{/* TODO #1485: show proper USWDS error */}
{maxPaginationError && (
<h4>
{
"You''re trying to access opportunity results that are beyond the last page of data."
}
</h4>
)}
{maxPaginationError && <h4>{t("resultsListFetch.paginationError")}</h4>}
{searchResults.data.map((opportunity) => (
<li key={opportunity?.opportunity_id}>
<SearchResultsListItem opportunity={opportunity} />
Expand Down
21 changes: 12 additions & 9 deletions frontend/src/components/search/SearchResultsListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { AgencyNamyLookup } from "src/utils/search/generateAgencyNameLookup";
import { formatDate } from "src/utils/dateUtil";
import { Opportunity } from "src/types/search/searchResponseTypes";
import { useTranslations } from "next-intl";

interface SearchResultsListItemProps {
opportunity: Opportunity;
Expand All @@ -19,6 +20,8 @@ export default function SearchResultsListItem({
? "https://grants.gov"
: "https://test.grants.gov";

const t = useTranslations("Search");

const metadataBorderClasses = `
display-block
tablet:display-inline-block
Expand Down Expand Up @@ -56,7 +59,7 @@ export default function SearchResultsListItem({
<div className="grid-col tablet:order-1 overflow-hidden font-body-xs">
{opportunity.opportunity_status === "archived" && (
<span className={metadataBorderClasses}>
<strong>Archived:</strong>{" "}
<strong>{t("resultsListItem.status.archived")}</strong>
{opportunity?.summary?.archive_date
? formatDate(opportunity?.summary?.archive_date)
: "--"}
Expand All @@ -66,7 +69,7 @@ export default function SearchResultsListItem({
opportunity?.opportunity_status === "closed") &&
opportunity?.summary?.close_date && (
<span className={metadataBorderClasses}>
<strong>Closed:</strong>{" "}
<strong>{t("resultsListItem.status.closed")}</strong>
{opportunity?.summary?.close_date
? formatDate(opportunity?.summary?.close_date)
: "--"}
Expand All @@ -75,7 +78,7 @@ export default function SearchResultsListItem({
{opportunity?.opportunity_status === "posted" && (
<span className={metadataBorderClasses}>
<span className="usa-tag bg-accent-warm-dark">
<strong>Closing:</strong>{" "}
<strong>{t("resultsListItem.status.posted")}</strong>
<span className="text-no-uppercase">
{opportunity?.summary?.close_date
? formatDate(opportunity?.summary?.close_date)
Expand All @@ -87,20 +90,20 @@ export default function SearchResultsListItem({
{opportunity?.opportunity_status === "forecasted" && (
<span className={metadataBorderClasses}>
<span className="usa-tag">
<strong>Forecasted</strong>
<strong>{t("resultsListItem.status.forecasted")}</strong>
</span>
</span>
)}
<span className={metadataBorderClasses}>
<strong>Posted:</strong>{" "}
<strong>{t("resultsListItem.summary.posted")}</strong>
{opportunity?.summary?.post_date
? formatDate(opportunity?.summary?.post_date)
: "--"}
</span>
</div>
<div className="grid-col tablet:order-3 overflow-hidden font-body-xs">
<span className={metadataBorderClasses}>
<strong>Agency:</strong>{" "}
<strong>{t("resultsListItem.summary.agency")}</strong>
{opportunity?.summary?.agency_name &&
opportunity?.summary?.agency_code &&
agencyNameLookup
Expand All @@ -109,7 +112,7 @@ export default function SearchResultsListItem({
: "--"}
</span>
<span className={metadataBorderClasses}>
<strong>Opportunity Number:</strong>{" "}
<strong>{t("resultsListItem.opportunity_number")}</strong>
{opportunity?.opportunity_number}
</span>
</div>
Expand All @@ -121,15 +124,15 @@ export default function SearchResultsListItem({
<span
className={`${metadataBorderClasses} desktop:display-block text-right desktop:margin-right-0 desktop:padding-right-0`}
>
<strong>Award Ceiling:</strong>{" "}
<strong>{t("resultsListItem.award_ceiling")}</strong>
<span className="desktop:display-block desktop:font-sans-lg text-ls-neg-3 text-right">
${opportunity?.summary?.award_ceiling?.toLocaleString() || "--"}
</span>
</span>
<span
className={`${metadataBorderClasses} desktop:display-block text-right desktop:margin-right-0 desktop:padding-right-0`}
>
<strong>Floor:</strong> $
<strong>{t("resultsListItem.floor")}</strong>
{opportunity?.summary?.award_floor?.toLocaleString() || "--"}
</span>
</div>
Expand Down
Loading

0 comments on commit 779de85

Please sign in to comment.