From 67c5d8ffcef76bc7275b2893dfbf02c5278bf01f Mon Sep 17 00:00:00 2001 From: John Ballesteros Date: Fri, 30 Aug 2024 14:09:08 +0800 Subject: [PATCH 1/4] feat/ai-grant-program-finder --- .../components/ai-grant-program-finder.tsx | 38 +++++++++- .../grant-list/grant-list-items.tsx | 52 ++++++++++++++ .../components/grant-list/grant-list.tsx | 62 +++++++--------- .../grant-list/use-ai-grant-list.ts | 56 +++++++++++++++ src/grants/core/atoms.ts | 4 ++ src/grants/core/query-keys.ts | 2 + src/grants/data/find-grant-program.ts | 70 +++++++++++++++++++ src/grants/hooks/use-ai-grant-finder-query.ts | 27 +++++++ src/grants/hooks/use-grant-list-query.ts | 5 +- 9 files changed, 277 insertions(+), 39 deletions(-) create mode 100644 src/grants/components/grant-list/grant-list-items.tsx create mode 100644 src/grants/components/grant-list/use-ai-grant-list.ts create mode 100644 src/grants/core/atoms.ts create mode 100644 src/grants/data/find-grant-program.ts create mode 100644 src/grants/hooks/use-ai-grant-finder-query.ts diff --git a/src/grants/components/ai-grant-program-finder.tsx b/src/grants/components/ai-grant-program-finder.tsx index 6da7c3ff..c099c806 100644 --- a/src/grants/components/ai-grant-program-finder.tsx +++ b/src/grants/components/ai-grant-program-finder.tsx @@ -1,14 +1,20 @@ 'use client'; +import { useState } from 'react'; import { createPortal } from 'react-dom'; import { Button, Textarea } from '@nextui-org/react'; +import { useAtom, useAtomValue } from 'jotai'; import { useIsMounted } from '@/shared/hooks/use-is-mounted'; import { useIsDesktop } from '@/shared/hooks/use-media-query'; import { AiIcon } from '@/shared/components/icons/ai-icon'; import { GRANTS_PORTAL_IDS } from '@/grants/core/constants'; +import { + aiGrantFinderPending, + aiGrantFinderQueryAtom, +} from '@/grants/core/atoms'; export const AiGrantProgramFinder = () => { const isMounted = useIsMounted(); @@ -21,6 +27,26 @@ export const AiGrantProgramFinder = () => { const portal = typeof window === 'undefined' ? null : document.getElementById(portalId); + const isPending = useAtomValue(aiGrantFinderPending); + const [aiQuery, setAiQuery] = useAtom(aiGrantFinderQueryAtom); + + const [aiQueryInput, setAiQueryInput] = useState(''); + const onChangeAiQuery: React.ChangeEventHandler = (e) => { + setAiQueryInput(e.target.value); + }; + + const onFind = () => { + setAiQuery(aiQueryInput); + }; + + const onClear = () => { + setAiQuery(''); + setAiQueryInput(''); + }; + + const buttonText = !!aiQuery && !isPending ? 'Reset' : 'Find'; + const onClick = aiQuery ? onClear : onFind; + if (!isMounted || !portal) return null; return createPortal( @@ -31,6 +57,9 @@ export const AiGrantProgramFinder = () => { application best