-
-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
app(IN-941): Search page alerts #1182
base: dev
Are you sure you want to change the base?
Changes from 99 commits
4364c13
9b9875c
ac4221b
40598eb
4f834a3
b531d61
18e8976
aa9b9dc
a6def0e
3541264
cb38c78
981d651
f0f4a3b
1fc8cdb
abafc40
8faeb20
03023a9
7b71fbd
a2338f0
18b2915
ea37be5
171f56a
0812bc5
db6503f
1270e46
288705a
6d1b9f3
98205f3
3d64306
22f43da
c51d503
7d86903
e8d0c24
fa78947
c6a4d78
045b747
563259b
50223a9
62441be
f1a45d9
9ae63e3
640193f
7841e80
4dcb3ab
c0a24cb
91c5d39
1f3c3a0
c367eb7
85a65e3
a650d1d
1fa9cd0
529d029
914c4a9
0ebad05
1792e3d
8e93bd1
40d2433
f62ade6
3193b46
6744e14
f4ef6a8
9172728
dd58a33
ba5257b
e7f2264
b90e7d8
2ceae23
f7e16dd
69c1452
ff59167
0d4b97e
3968a3e
9995efe
b05e0d0
bc0941f
419c039
a43ef77
3ff8f60
5ba4e46
aa8f4f8
d4f2875
f1e34a2
6ebfd7c
14f43d4
4db914d
7acf791
38928ea
4a7f4ba
72cb89b
0b1aeec
a9a1d6e
4308735
475030d
39415d0
f4e9277
a3307cb
e7b56bb
9969e7f
bf83dcb
4a157dc
74c1ee8
d1660ff
d7ce6d4
807bf0d
83fe74d
8e701ff
61aa216
bc80afe
6c10984
d464dd7
9cf88ea
151173e
812c70e
44a327a
1529af8
d8a1abd
8f01aea
84b92d5
985da6d
069f289
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,8 @@ import { z } from 'zod' | |
|
||
import { SearchParamsSchema } from '@weareinreach/api/schemas/routes/search' | ||
import { type ApiOutput, trpcServerClient } from '@weareinreach/api/trpc' | ||
import { CountryAlertBanner } from '@weareinreach/ui/components/core/AlertBanner/CountryAlertBanner.stories' | ||
import { StateAlertBanner } from '@weareinreach/ui/components/core/AlertBanner/StateAlertBanner.stories' | ||
import { Pagination } from '@weareinreach/ui/components/core/Pagination' | ||
import { SearchBox } from '@weareinreach/ui/components/core/SearchBox' | ||
import { SearchResultCard } from '@weareinreach/ui/components/core/SearchResultCard' | ||
|
@@ -177,6 +179,16 @@ const SearchResults = () => { | |
} | ||
}, [data, loadingPage]) | ||
|
||
const [stateInUS, setStateInUS] = useState<string>('') | ||
|
||
useEffect(() => { | ||
if (searchState.searchTerm?.slice(-3) == 'USA') { | ||
setStateInUS(searchState.searchTerm?.split(', ')[1] || '') | ||
} else { | ||
setStateInUS('') | ||
} | ||
}, [searchState.searchTerm]) | ||
|
||
JoeKarow marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+181
to
+190
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refine logic to determine state from search term. Consider using a more robust method to parse the location information from the search term, as the current method may not handle all cases effectively. |
||
useEffect( | ||
() => { | ||
if (typeof router.query.page === 'string' && searchState.page !== router.query.page) { | ||
|
@@ -227,31 +239,20 @@ const SearchResults = () => { | |
<Head> | ||
<title>{t('page-title.base', { ns: 'common', title: '$t(page-title.search-results)' })}</title> | ||
</Head> | ||
{showAlertMessage && ( | ||
<Box className={classes.banner}> | ||
<Text variant={variants.Text.utility1white}> | ||
<Trans | ||
i18nKey='alerts.search-page-legislative-map' | ||
ns='common' | ||
components={{ | ||
ATLink: ( | ||
<Link | ||
external | ||
variant={variants.Link.inheritStyle} | ||
href='https://www.erininthemorning.com/p/anti-trans-legislative-risk-assessment-43a' | ||
target='_blank' | ||
></Link> | ||
), | ||
}} | ||
/> | ||
</Text> | ||
</Box> | ||
{showCountryAlertMessage && ( | ||
<CountryAlertBanner | ||
variant={variants.Text.utility1white} | ||
variantInheritStyle={variants.Link.inheritStyle} | ||
></CountryAlertBanner> | ||
)} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we extract the banner code out in to a separate component? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes good call, I'll work on that this week! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would the banners go in the story book as components? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, you can create it in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved the banners to components although my folder structure may be a bit different, was having an issue with imports There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I fixed part of it - you were trying to move the component in to a storybook file ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't touch the implementation on this page though -- that still needs to be done |
||
<Grid.Col | ||
xs={12} | ||
sm={12} | ||
pb={30} | ||
{...(showAlertMessage ? { mt: { base: 80, xs: 80, sm: 20, md: 20, lg: 20, xl: 40 } } : {})} | ||
{...(showCountryAlertMessage || showStateAlertMessage | ||
? { mt: { base: 80, xs: 80, sm: 20, md: 20, lg: 20, xl: 40 } } | ||
: {})} | ||
> | ||
<Group spacing={20} w='100%' className={classes.searchControls}> | ||
<Group maw={{ md: '50%', base: '100%' }} w='100%'> | ||
|
@@ -263,7 +264,11 @@ const SearchResults = () => { | |
/> | ||
</Group> | ||
<Group noWrap w={{ base: '100%', md: '50%' }}> | ||
<ServiceFilter resultCount={resultCount} isFetching={searchIsFetching} /> | ||
<ServiceFilter | ||
resultCount={resultCount} | ||
isFetching={searchIsFetching} | ||
current={searchState.services} | ||
/> | ||
{/* @ts-expect-error `component` prop not needed.. */} | ||
<MoreFilter resultCount={resultCount} isFetching={searchIsFetching}> | ||
{t('more.filters')} | ||
|
@@ -287,6 +292,26 @@ const SearchResults = () => { | |
loadingManager={{ setLoading: setLoadingPage, isLoading: loadingPage }} | ||
/> | ||
</Grid.Col> | ||
<> | ||
<Grid.Col xs={12} sm={8} md={8}> | ||
{data?.resultCount === 0 && crisisResults ? ( | ||
<NoResults crisisData={crisisResults} /> | ||
) : ( | ||
<> | ||
<StateAlertBanner | ||
stateInUS={stateInUS} | ||
variantInheritStyle={variants.Link.inheritStyle} | ||
variantBlack={variants.Text.utility1} | ||
variantWhite={variants.Text.utility1white} | ||
infoColor={theme.other.colors.secondary.cornflower} | ||
warningColor={theme.fn.lighten(theme.other.colors.tertiary.pink, 0.3)} | ||
></StateAlertBanner> | ||
{resultDisplay} | ||
<Pagination total={getSearchResultPageCount(data?.resultCount)} /> | ||
</> | ||
)} | ||
</Grid.Col> | ||
</> | ||
<Grid.Col xs={12} sm={8} md={8}> | ||
{data?.resultCount === 0 && crisisResults ? ( | ||
<NoResults crisisData={crisisResults} /> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { prisma, Prisma } from '@weareinreach/db' | ||
import { handleError } from '~api/lib/errorHandler' | ||
import { type TRPCHandlerParams } from '~api/types/handler' | ||
|
||
import { type TLocationBasedAlertBannerSchema } from './query.LocationBasedAlertBanner.schema' | ||
|
||
export const LocationBasedAlertBanner = async ({ | ||
input, | ||
}: TRPCHandlerParams<TLocationBasedAlertBannerSchema>) => { | ||
try { | ||
const { lat, lon } = input | ||
const matchedAreas = await prisma.$queryRaw<MatchedAreaResults>(Prisma.sql` | ||
SELECT id from "GeoData" g WHERE ST_CoveredBy(ST_Point(${lon}, ${lat}, 4326), g.geo) | ||
`) | ||
const geoIds = matchedAreas.map(({ id }) => id) | ||
|
||
const alerts = await prisma.locationAlert.findMany({ | ||
where: { | ||
active: true, | ||
OR: [{ country: { geoDataId: { in: geoIds } } }, { govDist: { geoDataId: { in: geoIds } } }], | ||
}, | ||
select: { | ||
id: true, | ||
level: true, | ||
text: { select: { tsKey: { select: { ns: true, key: true, text: true } } } }, | ||
}, | ||
}) | ||
|
||
const formatted = alerts.map( | ||
({ | ||
id, | ||
level, | ||
text: { | ||
tsKey: { key, ns, text }, | ||
}, | ||
}) => ({ id, level, i18nKey: key, ns, defaultText: text }) | ||
) | ||
return formatted | ||
} catch (error) { | ||
handleError(error) | ||
} | ||
} | ||
export default LocationBasedAlertBanner | ||
|
||
type MatchedAreaResults = { | ||
id: string | ||
}[] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { z } from 'zod' | ||
|
||
export const ZLocationBasedAlertBannerSchema = z.object({ | ||
lat: z.number(), | ||
lon: z.number(), | ||
}) | ||
export type TLocationBasedAlertBannerSchema = z.infer<typeof ZLocationBasedAlertBannerSchema> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
-- CreateEnum | ||
CREATE TYPE "LocationAlertLevel" AS ENUM( | ||
'INFO', | ||
'WARN', | ||
'CRITICAL' | ||
); | ||
|
||
-- CreateTable | ||
CREATE TABLE "LocationAlert"( | ||
"id" text NOT NULL, | ||
"active" boolean NOT NULL DEFAULT TRUE, | ||
"textId" text NOT NULL, | ||
"level" "LocationAlertLevel" NOT NULL, | ||
"countryId" text, | ||
"govDistId" text, | ||
CONSTRAINT "LocationAlert_pkey" PRIMARY KEY ("id") | ||
); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "LocationAlert_countryId_textId_idx" ON | ||
"LocationAlert"("countryId", "textId"); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "LocationAlert_govDistId_textId_idx" ON | ||
"LocationAlert"("govDistId", "textId"); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "LocationAlert_active_countryId_textId_idx" ON | ||
"LocationAlert"("active", "countryId", "textId"); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "LocationAlert_active_govDistId_textId_idx" ON | ||
"LocationAlert"("active", "govDistId", "textId"); | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "LocationAlert" | ||
ADD CONSTRAINT "LocationAlert_textId_fkey" FOREIGN KEY ("textId") | ||
REFERENCES "FreeText"("id") ON DELETE CASCADE ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "LocationAlert" | ||
ADD CONSTRAINT "LocationAlert_countryId_fkey" FOREIGN KEY ("countryId") | ||
REFERENCES "Country"("id") ON DELETE CASCADE ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "LocationAlert" | ||
ADD CONSTRAINT "LocationAlert_govDistId_fkey" FOREIGN KEY ("govDistId") | ||
REFERENCES "GovDist"("id") ON DELETE CASCADE ON UPDATE CASCADE; | ||
|
||
-- Custom constraint | ||
ALTER TABLE "LocationAlert" | ||
ADD CONSTRAINT "LocationAlert_Location_CUSTOM" CHECK | ||
((num_nonnulls("countryId", "govDistId") = 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect import of alert banners from Storybook files.
Committable suggestion