From 86a21d1cecb5b91afa5e5f5c0fe514bb6beb150c Mon Sep 17 00:00:00 2001 From: "J.I. Cruz" <58642383+jicruz96@users.noreply.github.com> Date: Sat, 16 Aug 2025 19:24:02 -0400 Subject: [PATCH 1/6] pin chromadb to v0.5.4 (#1915) --- llm/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llm/requirements.txt b/llm/requirements.txt index 8187253d4..92dbdd75b 100644 --- a/llm/requirements.txt +++ b/llm/requirements.txt @@ -1,5 +1,5 @@ Flask==3.1.0 -chromadb==0.5.0 +chromadb==0.5.4 firebase-admin==6.7.0 firebase-functions==0.4.2 langchain-community==0.2.1 From aa04d45d2aeb0389e4707a38eb11bf021deafb85 Mon Sep 17 00:00:00 2001 From: "J.I. Cruz" <58642383+jicruz96@users.noreply.github.com> Date: Tue, 19 Aug 2025 20:24:35 -0400 Subject: [PATCH 2/6] Search component translations (#1883) * extract translate-able strings -- bill sort * rename billSearch.json to search.json and update refs * extract translate-able strings from TestimonyHit component * extract translate-able strings from search components * fix build error * extract translate-able strings from refinement components * fix/refactor useRefinements * remove unused hierarchical menu components * debug testimonyHit translations * remove unused CurrentCommitteeCard component and its associated stories * remove unused code from formatting.tsx * Revert "[1753] Replace custom routing with react-instantsearch-router-nextjs" * chore(transcriptions): Update firestore rules to allow read-only access to transcription paragraphs --------- Co-authored-by: Mephistic --- components/search/NoResults.tsx | 6 +- components/search/ResultCount.tsx | 7 +- components/search/SearchErrorBoundary.tsx | 14 +-- components/search/bills/BillSearch.tsx | 2 +- .../search/bills/useBillHierarchicalMenu.tsx | 17 ---- .../search/bills/useBillRefinements.tsx | 82 +++++++----------- components/search/bills/useBillSort.tsx | 14 +-- components/search/testimony/TestimonyHit.tsx | 33 ++++--- .../search/testimony/TestimonySearch.tsx | 86 +++++++++++-------- .../testimony/useTestimonyRefinements.tsx | 60 ++++++------- components/search/useHierarchicalMenu.tsx | 72 ---------------- components/search/useRefinements.tsx | 38 ++++---- pages/bills/index.tsx | 4 +- pages/testimony/index.tsx | 2 +- public/locales/en/billSearch.json | 7 -- public/locales/en/search.json | 36 ++++++++ public/locales/en/testimony.json | 4 + 17 files changed, 212 insertions(+), 272 deletions(-) delete mode 100644 components/search/bills/useBillHierarchicalMenu.tsx delete mode 100644 components/search/useHierarchicalMenu.tsx delete mode 100644 public/locales/en/billSearch.json create mode 100644 public/locales/en/search.json diff --git a/components/search/NoResults.tsx b/components/search/NoResults.tsx index d98a03b42..dcdfa33f4 100644 --- a/components/search/NoResults.tsx +++ b/components/search/NoResults.tsx @@ -19,11 +19,11 @@ const Container = styled.div` export const NoResults: React.FC> = ({ children }) => { - const { t } = useTranslation("common") + const { t } = useTranslation("search") return ( - {t("noResults")} -
Looks Pretty Empty Here
+ {t("no_results")} +
{t("looks_pretty_empty_here")}
{children}
) diff --git a/components/search/ResultCount.tsx b/components/search/ResultCount.tsx index 28ad52669..d7d83b730 100644 --- a/components/search/ResultCount.tsx +++ b/components/search/ResultCount.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from "next-i18next" import { useStats } from "react-instantsearch" import styled from "styled-components" @@ -13,7 +14,11 @@ export function ResultCount(props: any) { return ( - Showing {pageStart}-{pageEnd} of {nbHits} Results + {useTranslation("search").t("result_count", { + pageStart, + pageEnd, + nbHits + })} ) } diff --git a/components/search/SearchErrorBoundary.tsx b/components/search/SearchErrorBoundary.tsx index 8372464ca..020cecce4 100644 --- a/components/search/SearchErrorBoundary.tsx +++ b/components/search/SearchErrorBoundary.tsx @@ -1,9 +1,10 @@ import React, { ReactNode } from "react" import { Alert } from "react-bootstrap" +import { withTranslation, WithTranslation } from "next-i18next" -export class SearchErrorBoundary extends React.Component<{ - children?: ReactNode -}> { +class SearchErrorBoundaryBase extends React.Component< + { children?: ReactNode } & WithTranslation +> { state: { error: string | null } = { error: null } promiseRejectionHandler = (event: PromiseRejectionEvent) => { @@ -16,8 +17,7 @@ export class SearchErrorBoundary extends React.Component<{ if (this.state.error) { return ( - Something went wrong. Please try again. Original message:{" "} - {this.state.error} + {this.props.t("search_error", { error: this.state.error })} ) } @@ -44,3 +44,7 @@ export class SearchErrorBoundary extends React.Component<{ ) } } + +export const SearchErrorBoundary = withTranslation("search")( + SearchErrorBoundaryBase +) diff --git a/components/search/bills/BillSearch.tsx b/components/search/bills/BillSearch.tsx index faadd018e..e536e986a 100644 --- a/components/search/bills/BillSearch.tsx +++ b/components/search/bills/BillSearch.tsx @@ -147,7 +147,7 @@ const Layout: FC< const refinements = useBillRefinements() const status = useSearchStatus() - const { t } = useTranslation("billSearch") + const { t } = useTranslation("search") return ( diff --git a/components/search/bills/useBillHierarchicalMenu.tsx b/components/search/bills/useBillHierarchicalMenu.tsx deleted file mode 100644 index e2fbd7371..000000000 --- a/components/search/bills/useBillHierarchicalMenu.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { useHierarchicalMenu } from "../useHierarchicalMenu" - -export const useBillHierarchicalMenu = () => { - const baseProps = { limit: 500, searchable: true } - const propsList = [ - { - attribute: "topics.lvl0", - ...baseProps - }, - { - attribute: "topics.lvl1", - ...baseProps - } - ] - - return useHierarchicalMenu({ hierarchicalMenuProps: propsList }) -} diff --git a/components/search/bills/useBillRefinements.tsx b/components/search/bills/useBillRefinements.tsx index cbd560579..b42a16f81 100644 --- a/components/search/bills/useBillRefinements.tsx +++ b/components/search/bills/useBillRefinements.tsx @@ -1,7 +1,8 @@ import { generalCourts } from "functions/src/shared" import { RefinementListItem } from "instantsearch.js/es/connectors/refinement-list/connectRefinementList" -import { useCallback } from "react" +import { useMemo } from "react" import { useRefinements } from "../useRefinements" +import { useTranslation } from "next-i18next" // for legacy code purposes, things like: // @@ -17,58 +18,35 @@ import { useRefinements } from "../useRefinements" // searchablePlaceholder: "Legislative Session", export const useBillRefinements = () => { - const baseProps = { limit: 500, searchable: true } - const propsList = [ - { - transformItems: useCallback( - (i: RefinementListItem[]) => - i - .map(i => ({ - ...i, - label: generalCourts[i.value as any]?.Name ?? i.label - })) - .sort((a, b) => Number(b.value) - Number(a.value)), - [] - ), - attribute: "court", - searchablePlaceholder: "Legislative Session", - ...baseProps - }, - { - attribute: "currentCommittee", - ...baseProps, - searchablePlaceholder: "Current Committee" - }, - { - attribute: "city", - searchablePlaceholder: "City", - ...baseProps - }, - { - attribute: "primarySponsor", - ...baseProps, - searchablePlaceholder: "Primary Sponsor" - }, - { - attribute: "cosponsors", - ...baseProps, - searchablePlaceholder: "Cosponsor" - } - ] - - const hierarchicalPropsList = [ - { - attribute: "topics.lvl0", - ...baseProps - }, - { - attribute: "topics.lvl1", - ...baseProps - } - ] + const { t } = useTranslation("search") return useRefinements({ - hierarchicalMenuProps: hierarchicalPropsList, - refinementProps: propsList + hierarchicalMenuProps: { attributes: ["topics.lvl0", "topics.lvl1"] }, + refinementProps: useMemo( + () => + [ + { + transformItems: (items: RefinementListItem[]) => + items + .map(i => ({ + ...i, + label: generalCourts[parseInt(i.value, 10)]?.Name ?? i.label + })) + .sort((a, b) => Number(b.value) - Number(a.value)), + + attribute: "court" + }, + { attribute: "currentCommittee" }, + { attribute: "city" }, + { attribute: "primarySponsor" }, + { attribute: "cosponsors" } + ].map(props => ({ + limit: 500, + searchable: true, + searchablePlaceholder: t(`refinements.bill.${props.attribute}`), + ...props + })), + [t] + ) }) } diff --git a/components/search/bills/useBillSort.tsx b/components/search/bills/useBillSort.tsx index fad2abedb..ca73c151e 100644 --- a/components/search/bills/useBillSort.tsx +++ b/components/search/bills/useBillSort.tsx @@ -1,31 +1,33 @@ import { useMemo, useRef } from "react" import { SortByWithConfigurationItem } from "../SortBy" +import { useTranslation } from "next-i18next" export const useBillSort = () => { const now = useRef(new Date().getTime()) + const { t } = useTranslation("search") // refer to // https://github.com/typesense/typesense-instantsearch-adapter#with-react-instantsearch const items: SortByWithConfigurationItem[] = useMemo( () => [ { - label: "Sort by Most Recent Testimony", + label: t("sort_by.most_recent_testimony"), value: "bills/sort/latestTestimonyAt:desc" }, { - label: "Sort by Relevance", + label: t("sort_by.relevance"), value: "bills/sort/_text_match:desc,testimonyCount:desc" }, { - label: "Sort by Testimony Count", + label: t("sort_by.testimony_count"), value: "bills/sort/testimonyCount:desc" }, { - label: "Sort by Cosponsor Count", + label: t("sort_by.cosponsor_count"), value: "bills/sort/cosponsorCount:desc" }, { - label: "Sort by Next Hearing Date", + label: t("sort_by.next_hearing_date"), value: "bills/sort/nextHearingAt:asc", configure: { numericRefinements: { @@ -36,7 +38,7 @@ export const useBillSort = () => { } } ], - [] + [t] ) return items } diff --git a/components/search/testimony/TestimonyHit.tsx b/components/search/testimony/TestimonyHit.tsx index 52fe8996d..51f9c599d 100644 --- a/components/search/testimony/TestimonyHit.tsx +++ b/components/search/testimony/TestimonyHit.tsx @@ -1,6 +1,6 @@ import { Hit } from "instantsearch.js" import Link from "next/link" -import { useTranslation } from "next-i18next" +import { Trans, useTranslation } from "next-i18next" import { Image } from "react-bootstrap" import { useMediaQuery } from "usehooks-ts" @@ -25,8 +25,6 @@ export const TestimonyHit = ({ hit }: { hit: Hit }) => { } const TestimonyResult = ({ hit }: { hit: Hit }) => { - const { t } = useTranslation(["auth"]) - const date = new Date( parseInt(hit.publishedAt.toString()) ).toLocaleDateString("en-US", { @@ -37,12 +35,6 @@ const TestimonyResult = ({ hit }: { hit: Hit }) => { const { loading, error, result: bill } = useBill(hit.court, hit.billId) const committee = bill?.currentCommittee const isOrg = hit.authorRole === "organization" - const writtenBy = - isOrg || hit.public ? ( - {hit.fullName} - ) : ( - hit.fullName - ) const { user } = useAuth() const { followOrg } = useFlags() const isCurrentUser = user?.uid === hit.authorUid @@ -67,12 +59,25 @@ const TestimonyResult = ({ hit }: { hit: Hit }) => { > {t("profileIcon")} - Written by {writtenBy} + + + ) : ( + <> + ) + ]} + /> + {hit.public && !isCurrentUser && followOrg && user && ( @@ -95,7 +100,11 @@ const TestimonyResult = ({ hit }: { hit: Hit }) => {
{/* */} {/* */} -

Bill #{formatBillId(hit.billId)}

+

+ {useTranslation("testimony").t("testimonyHit.bill", { + billId: formatBillId(hit.billId) + })} +

{/*
*/} {/* */} {committee && ( diff --git a/components/search/testimony/TestimonySearch.tsx b/components/search/testimony/TestimonySearch.tsx index e77b42645..c32010444 100644 --- a/components/search/testimony/TestimonySearch.tsx +++ b/components/search/testimony/TestimonySearch.tsx @@ -12,7 +12,7 @@ import { } from "components/EditProfilePage/StyledEditProfileComponents" import { currentGeneralCourt } from "functions/src/shared" import { SortByItem } from "instantsearch.js/es/connectors/sort-by/connectSortBy" -import { useState } from "react" +import { useState, useMemo } from "react" import { TabContainer, TabPane } from "react-bootstrap" import styled from "styled-components" import TypesenseInstantSearchAdapter from "typesense-instantsearch-adapter" @@ -27,6 +27,7 @@ import { useRouting } from "../useRouting" import { TestimonyHit } from "./TestimonyHit" import { useTestimonyRefinements } from "./useTestimonyRefinements" import { FollowContext, OrgFollowStatus } from "components/shared/FollowContext" +import { useTranslation } from "next-i18next" const searchClient = new TypesenseInstantSearchAdapter({ server: getServerConfig(), @@ -36,41 +37,49 @@ const searchClient = new TypesenseInstantSearchAdapter({ } }).searchClient -const items: SortByItem[] = [ - { - label: "Sort by New -> Old", - value: "publishedTestimony/sort/publishedAt:desc" - }, - { - label: "Sort by Old -> New", - value: "publishedTestimony/sort/publishedAt:asc" - }, - { - label: "Sort by Relevance", - value: "publishedTestimony/sort/_text_match:desc,publishedAt:desc" - } -] - -export const initialSortByValue = items[0].value +export const useTestimonySort = () => { + const { t } = useTranslation("search") + const items: SortByItem[] = useMemo( + () => [ + { + label: t("sort_by.newest"), + value: "publishedTestimony/sort/publishedAt:desc" + }, + { + label: t("sort_by.oldest"), + value: "publishedTestimony/sort/publishedAt:asc" + }, + { + label: t("sort_by.relevance"), + value: "publishedTestimony/sort/_text_match:desc,publishedAt:desc" + } + ], + [t] + ) + return items +} -export const TestimonySearch = () => ( - - - - - - -) +export const TestimonySearch = () => { + const initialSortByValue = useTestimonySort()[0].value + return ( + + + + + + + ) +} const RefinementRow = styled.div` display: inline-flex; @@ -100,6 +109,7 @@ const Layout = () => { const refinements = useTestimonyRefinements() const status = useSearchStatus() const { indexUiState, setIndexUiState } = useInstantSearch() + const { t } = useTranslation("search") const onTabClick = (t: Tab) => { setKey(t) @@ -157,7 +167,7 @@ const Layout = () => { - + {refinements.show} { /> {status === "empty" ? ( - Your search has yielded zero results! + {t("zero_results")}
- Try another search term + {t("another_term")}
) : ( diff --git a/components/search/testimony/useTestimonyRefinements.tsx b/components/search/testimony/useTestimonyRefinements.tsx index 4642073a0..932356df5 100644 --- a/components/search/testimony/useTestimonyRefinements.tsx +++ b/components/search/testimony/useTestimonyRefinements.tsx @@ -1,41 +1,31 @@ import { RefinementListItem } from "instantsearch.js/es/connectors/refinement-list/connectRefinementList" import { useRefinements } from "../useRefinements" -import { useCallback } from "react" +import { useMemo } from "react" +import { useTranslation } from "next-i18next" export const useTestimonyRefinements = () => { - const baseProps = { limit: 500, searchable: true } - const propsList = [ - { - transformItems: useCallback( - (i: RefinementListItem[]) => i.filter(i => i.label !== "private"), - [] - ), - attribute: "authorDisplayName", - ...baseProps, - searchablePlaceholder: "Author Name" - }, - { - attribute: "court", - ...baseProps, - searchablePlaceholder: "Court" - }, - { - attribute: "position", - ...baseProps, - searchablePlaceholder: "Position" - }, - { - attribute: "billId", - ...baseProps, - searchablePlaceholder: "Bill" - }, - { - attribute: "authorRole", - ...baseProps, - searchable: false, - hidden: true - } - ] + const { t } = useTranslation("search") - return useRefinements({ refinementProps: propsList }) + return useRefinements({ + refinementProps: useMemo( + () => + [ + { + transformItems: (i: RefinementListItem[]) => + i.filter(i => i.label !== "private"), + attribute: "authorDisplayName" + }, + { attribute: "court" }, + { attribute: "position" }, + { attribute: "billId" }, + { attribute: "authorRole", searchable: false, hidden: true } + ].map(props => ({ + limit: 500, + searchable: true, + searchablePlaceholder: t(`refinements.testimony.${props.attribute}`), + ...props + })), + [t] + ) + }) } diff --git a/components/search/useHierarchicalMenu.tsx b/components/search/useHierarchicalMenu.tsx deleted file mode 100644 index 755c9736d..000000000 --- a/components/search/useHierarchicalMenu.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { useTranslation } from "next-i18next" -import { useInstantSearch } from "react-instantsearch" -import { faFilter } from "@fortawesome/free-solid-svg-icons" -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" -import { useCallback, useState } from "react" -import styled from "styled-components" -import { useMediaQuery } from "usehooks-ts" -import { Button, Offcanvas } from "../bootstrap" -import { SearchContainer } from "./SearchContainer" -import { MultiselectHierarchicalMenu } from "./HierarchicalMenuWidget" -export const FilterButton = styled(Button)` - font-size: 1rem; - line-height: 1rem; - min-height: 2rem; - padding: 0.25rem 0.5rem 0.25rem 0.5rem; - align-self: flex-start; -` -const useHasRefinements = () => { - const { results } = useInstantSearch() - const refinements = results.getRefinements() - return refinements.length !== 0 -} - -export const useHierarchicalMenu = ({ - hierarchicalMenuProps -}: { - hierarchicalMenuProps: any[] -}) => { - const inline = useMediaQuery("(min-width: 768px)") - const [show, setShow] = useState(false) - const handleClose = useCallback(() => setShow(false), []) - const handleOpen = useCallback(() => setShow(true), []) - - const hierarchicalMenu = ( - <> - - - ) - const hasRefinements = useHasRefinements() - - const { t } = useTranslation("billSearch") - - return { - options: inline ? ( -
{hierarchicalMenu}
- ) : ( - - - {t("topics")} - - - {hierarchicalMenu} - - - ), - show: inline ? null : ( - - {t("topics")} - - ) - } -} diff --git a/components/search/useRefinements.tsx b/components/search/useRefinements.tsx index c07374160..c26da8322 100644 --- a/components/search/useRefinements.tsx +++ b/components/search/useRefinements.tsx @@ -1,12 +1,19 @@ import { useTranslation } from "next-i18next" -import { RefinementList, useInstantSearch } from "react-instantsearch" +import { + RefinementList, + RefinementListProps, + useInstantSearch +} from "react-instantsearch" import { faFilter } from "@fortawesome/free-solid-svg-icons" import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { useCallback, useState } from "react" import styled from "styled-components" import { useMediaQuery } from "usehooks-ts" import { Button, Offcanvas } from "../bootstrap" -import { MultiselectHierarchicalMenu } from "./HierarchicalMenuWidget" +import { + MultiselectHierarchicalMenu, + MultiselectHierarchicalMenuParams +} from "./HierarchicalMenuWidget" import { SearchContainer } from "./SearchContainer" export const FilterButton = styled(Button)` @@ -27,8 +34,8 @@ export const useRefinements = ({ hierarchicalMenuProps, refinementProps }: { - hierarchicalMenuProps?: any[] - refinementProps: any[] + hierarchicalMenuProps?: MultiselectHierarchicalMenuParams + refinementProps: RefinementListProps[] }) => { const inline = useMediaQuery("(min-width: 768px)") const [show, setShow] = useState(false) @@ -38,29 +45,20 @@ export const useRefinements = ({ const refinements = ( <> {refinementProps.map((p, i) => ( - + ))} ) - let hierarchicalMenu = <> - - if (hierarchicalMenuProps) { - hierarchicalMenu = ( - <> - - - ) - } + const hierarchicalMenu = hierarchicalMenuProps ? ( + + ) : ( + <> + ) const hasRefinements = useHasRefinements() - const { t } = useTranslation("billSearch") + const { t } = useTranslation("search") return { options: inline ? ( diff --git a/pages/bills/index.tsx b/pages/bills/index.tsx index b44a18305..183722e5f 100644 --- a/pages/bills/index.tsx +++ b/pages/bills/index.tsx @@ -7,7 +7,7 @@ import { createGetStaticTranslationProps } from "components/translations" export default createPage({ titleI18nKey: "navigation.browseBills", Page: () => { - const { t } = useTranslation("billSearch") + const { t } = useTranslation("search") return ( @@ -20,7 +20,7 @@ export default createPage({ export const getStaticProps = createGetStaticTranslationProps([ "auth", - "billSearch", + "search", "common", "footer", "testimony" diff --git a/pages/testimony/index.tsx b/pages/testimony/index.tsx index a782d9963..3a3c074fe 100644 --- a/pages/testimony/index.tsx +++ b/pages/testimony/index.tsx @@ -20,7 +20,7 @@ export default createPage({ export const getStaticProps = createGetStaticTranslationProps([ "auth", - "billSearch", + "search", "common", "footer", "testimony", diff --git a/public/locales/en/billSearch.json b/public/locales/en/billSearch.json deleted file mode 100644 index 7d9e4c1a4..000000000 --- a/public/locales/en/billSearch.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "another_term" : "Try another search term", - "browse_bills" : "Browse Bills", - "filter" : "Filter", - "topics" : "Topics", - "zero_results" : "Your search has yielded zero results!" -} \ No newline at end of file diff --git a/public/locales/en/search.json b/public/locales/en/search.json new file mode 100644 index 000000000..8562bdf6b --- /dev/null +++ b/public/locales/en/search.json @@ -0,0 +1,36 @@ +{ + "another_term": "Try another search term", + "browse_bills": "Browse Bills", + "filter": "Filter", + "topics": "Topics", + "zero_results": "Your search has yielded zero results!", + "refinements": { + "bill": { + "court": "Legislative Session", + "currentCommittee": "Current Committee", + "city": "City", + "primarySponsor": "Primary Sponsor", + "cosponsors": "Cosponsor" + }, + "testimony": { + "authorDisplayName": "Author Name", + "court": "Legislative Session", + "position": "Position", + "billId": "Bill", + "authorRole": "Author Role" + } + }, + "sort_by": { + "most_recent_testimony": "Sort by Most Recent Testimony", + "newest": "Sort by Old -> New", + "oldest": "Sort by New -> Old", + "relevance": "Sort by Relevance", + "testimony_count": "Sort by Testimony Count", + "cosponsor_count": "Sort by Cosponsor Count", + "next_hearing_date": "Sort by Next Hearing Date" + }, + "no_results": "No Results", + "looks_pretty_empty_here": "Looks Pretty Empty Here", + "result_count": "Showing {{pageStart}}-{{pageEnd}} of {{nbHits}} Results", + "search_error": "Something went wrong. Please try again. Original message: {{error}}" +} diff --git a/public/locales/en/testimony.json b/public/locales/en/testimony.json index 3641724f6..f0ad58828 100644 --- a/public/locales/en/testimony.json +++ b/public/locales/en/testimony.json @@ -38,6 +38,10 @@ "label": "Verify Your Email" } }, + "testimonyHit": { + "writtenBy": "Written by <0>{{author}}", + "bill": "Bill #{{billId}}" + }, "testimonyDetail": { "what": "What", "says": "says", From 1e154d01ac43c9a2aa60708640ea385d0c048714 Mon Sep 17 00:00:00 2001 From: rockyroed Date: Thu, 21 Aug 2025 00:44:36 +0800 Subject: [PATCH 3/6] fix: swap arrow icons --- components/HearingsScheduled/HearingsScheduled.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/HearingsScheduled/HearingsScheduled.tsx b/components/HearingsScheduled/HearingsScheduled.tsx index 723c4ff48..1474afcec 100644 --- a/components/HearingsScheduled/HearingsScheduled.tsx +++ b/components/HearingsScheduled/HearingsScheduled.tsx @@ -219,8 +219,8 @@ export const HearingsScheduled = () => { wrap={false} activeIndex={monthIndex} onSelect={handleSelect} - prevIcon={