Skip to content

Home Page (/)

The Home page is just a large version of the logo with a prompt below it to enter a stock ticker to access an analysis for that stock. It then displays a large version of the SearchBar component.

The search bar will be the main input component for the user. I’ll include it on the HomePage as well as the Header. It should send new requests to the /stock-analysisendpoint every time the user types into the search bar. It should then show the results of the query below the search bar. The user should then be able to click the suggestions generated. When clicked the search bar has to send a request with the ticker to /check-analysis. It should then show a modal with text and two buttons. The text should always be the message key from the API response. The buttons should differ based on the existing_analysis key. If it’s true the message key will look something like this: “There is an existing analysis for ‘aapl’ created on 2025-04-06 17:51:38.025720. Do you want to access it or create a new analysis?”

There should be an “Access Existing” and “Create New”. “Access Existing” should just navigate to /stock/{ticker} where {ticker} is the ticker the user clicked on. Create New should send a request to /generate-analysis said ticker.

If existing_analysis is false the message will look like this: “goog was not found in the database. Do you want to generate a new analysis for it?

The two buttons should be “Yes”and “No” with yes sending a request to /generate-analysis and “No” just closing the modal.

Every time the search bar’s content changes it will send an axios request to the /stock-query endpoint. This happens with a timeout of 300 ms so there’s a buffer between the requests. If the user clicks outside the bar at any time it will catch it using an event listener and hide the results.

Then comes the clicking of the search results. When clicked the component will send a request to /check-analysis as described. It will then look for the date in the message using regex and and format it appropriately if found. Then it will open the modal. Also since SearchBar re-renders a lot (every time the user changes the content) the handleResultClick is going to be created from scratch every time. To prevent that (so the performance doesn’t suffer) I wrapped handleResultClick in a useCallback function. useMemo doesn’t cut it here because if the individual results were optimized components, receiving a new function instance on every render would cause them to re-render unnecessarily.

Modal is it’s own component. It’s props include the basic setter functions again so it can return null when it’s not open and render when it is. They also include functions to run when the modal buttons are clicked. This way all functionality from the Modal component is set and controlled by the SearchBar component. Additionally the entire modal component is wrapped in a div with stopPropagation() so it doesn’t pass on any of the click events upwards.

handleAccessExisting navigates the user to /stock/{ticker}

handleGenerateAnalysis starts the analysis process. It send’s a request to /generate-analysis as specified above. Then it navigates to the AnalysisLoadingPage. Specifically: /loading-analysis/{data.task_id}/{currentTicker}