Skip to content

Commit

Permalink
Add mapbox autocomplete (#77)
Browse files Browse the repository at this point in the history
* mapbox token added locally

* autocomplete added

* search bar style update

* added clear icon

* responsive styling updateed

* prettier format update

* search-bar test updated
  • Loading branch information
mantuok authored Nov 11, 2024
1 parent 9a14a86 commit 34a5d38
Show file tree
Hide file tree
Showing 11 changed files with 1,076 additions and 72 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ node_modules
# Mac
.DS_Store
/.next/

# Sensitive config
.env.development.local
29 changes: 18 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,23 @@ To learn more about Next.js, take a look at the following resources:

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

***
---

# Docker

This project uses Docker and Docker Compose to run the application, which includes the frontend, backend, and postgres database.

## Prerequisites

- **Docker**: Make sure Docker is installed on your machine. [Get Docker](https://docs.docker.com/get-docker/).
- **Docker Compose**: Ensure Docker Compose is installed (usually included with Docker Desktop).
- **Docker Compose**: Ensure Docker Compose is installed (usually included with Docker Desktop).

## Starting the Application

1. **Run Docker Compose**: From the project root directory (where the docker-compose.yml file is located), run:
```docker-compose up -d```
This will:
`docker-compose up -d`
This will:

- Build the necessary Docker images (if not already built).
- Start all services defined in the docker-compose.yml file (e.g., frontend, backend, database).

Expand All @@ -63,24 +66,28 @@ This will:
- The Postgres instance with PostGIS extension is accessible at http://localhost:5432.

## Shutting Down the Application

To stop and shut down the application:

1. **Stop Docker Compose**: In the same directory where the `docker-compose.yml` file is located, press `Ctrl + C` in the terminal where the app is running.

2. **Bring Down the Containers**: If you want to stop and remove the containers completely, run:
```docker-compose down```
`docker-compose down`
This will:
- Stop all services.
- Remove the containers, but it will **not** delete volumes (so the database data will persist).
- Stop all services.
- Remove the containers, but it will **not** delete volumes (so the database data will persist).

***
# Configuration of environment variables
The ```.env.local``` file contains environment variables used in the application to configure settings for both the backend and frontend components. If it contains sensitive information, ```.env.local``` should not be checked into version control for security reasons. Right now there is no sensitive information but later secret management tools will be introduced.
---

# Configuration of environment variables

The `.env.local` file contains environment variables used in the application to configure settings for both the backend and frontend components. If it contains sensitive information, `.env.local` should not be checked into version control for security reasons. Right now there is no sensitive information but later secret management tools will be introduced.
The file is organized into three main sections:
- **Postgres Environment Variables**. This section contains the credentials to connect to the PostgreSQL database, such as the username, password, and the name of the database.
- **Backend Environment Variables**. These variables are used by the backend (i.e., FastAPI) to configure its behavior and to connect to the database and the frontend application.
- **Frontend Environment Variables**. This section contains the base URL for API calls to the backend and ```NODE_ENV``` variable that determines in which environment the Node.js application is running.
***

# Disclaimer
#### Some versions of this code contain a streamlit app that uses an imprecise measure which may introduce errors in the output. The streamlit app should not be relied upon to determine any property’s safety or compliance with the soft story program. Please consult DataSF for most up to date information.

#### Some versions of this code contain a streamlit app that uses an imprecise measure which may introduce errors in the output. The streamlit app should not be relied upon to determine any property’s safety or compliance with the soft story program. Please consult DataSF for most up to date information.
51 changes: 51 additions & 0 deletions app/components/__tests__/search-bar.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { render, fireEvent, screen } from "@testing-library/react";
import SearchBar from "../search-bar";
import "@testing-library/jest-dom";

jest.mock("@mapbox/search-js-react", () => ({
AddressAutofill: ({ children, onRetrieve }) => (
<div onClick={() => onRetrieve({ features: [{ place_name: "Mock Address" }] })}>
{children}
</div>
),
}));

describe("SearchBar Component", () => {
it("renders search input and icons correctly", () => {
render(<SearchBar />);

const input = screen.getByPlaceholderText("Search San Francisco address");
const searchIcon = screen.getByTestId("search-icon");
const clearIcon = screen.getByTestId("clear-icon");

expect(input).toBeInTheDocument();
expect(searchIcon).toBeInTheDocument();
expect(clearIcon).toBeInTheDocument();
expect(searchIcon).toHaveStyle({ color: "rgb(23, 25, 35" });
});

it("updates address state when typing", () => {
render(<SearchBar />);
const input = screen.getByPlaceholderText("Search San Francisco address");

fireEvent.change(input, { target: { value: "123 Main St" } });
expect(input.value).toBe("123 Main St");
});

it("clears the address field when clear icon is clicked", () => {
render(<SearchBar />);
const input = screen.getByPlaceholderText("Search San Francisco address");
const clearIcon = screen.getByTestId("clear-icon");

fireEvent.change(input, { target: { value: "123 Main St" } });
fireEvent.click(clearIcon);
expect(input.value).toBe("");
});

it("calls handleRetrieve and updates fullAddress on retrieve event", () => {
render(<SearchBar />);
const input = screen.getByPlaceholderText("Search San Francisco address");

fireEvent.click(input);
});
});
27 changes: 0 additions & 27 deletions app/components/__tests__/search-bar.test.tsx

This file was deleted.

84 changes: 84 additions & 0 deletions app/components/search-bar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"use client";

import { useState } from "react";
import {
Input,
InputGroup,
InputLeftElement,
InputRightElement,
} from "@chakra-ui/react";
import { IoSearchSharp } from "react-icons/io5";
import { RxCross2 } from "react-icons/rx";
import { AddressAutofill } from "@mapbox/search-js-react";

const SearchBar = () => {
const [address, setAddress] = useState("");
const [fullAddress, setFullAddress] = useState(null);

const handleClearClick = () => {
console.log(address);
console.log(fullAddress);
setAddress("");
};

const handleRetrieve = (event) => {
const addressData = event.features[0];
setFullAddress(addressData);
};

return (
<form>
<AddressAutofill
accessToken={process.env.NEXT_PUBLIC_MAPBOX_TOKEN}
onRetrieve={handleRetrieve}
>
<InputGroup
maxW={{ base: "303px", sm: "303px", md: "371px", lg: "417px" }}
size={{ base: "md", md: "lg", xl: "lg" }}
data-testid="search-bar"
>
<InputLeftElement>
<IoSearchSharp
color="grey.900"
fontSize="1.1em"
data-testid="search-icon"
/>
</InputLeftElement>
<Input
placeholder="Search San Francisco address"
fontSize={{ base: "md", sm: "md", md: "md", lg: "lg" }}
p={{
base: "0 10px 0 35px",
sm: "0 10px 0 35px",
md: "0 10px 0 48px",
lg: "0 10px 0 48px",
}}
borderRadius="50"
bgColor="white"
focusBorderColor="yellow"
type="text"
name="address-1"
value={address}
onChange={(event) => setAddress(event.target.value)}
_hover={{
borderColor: "yellow",
_placeholder: { color: "grey.900" },
}}
_invalid={{ borderColor: "red" }}
autoComplete="address-line1"
/>
<InputRightElement>
<RxCross2
color="grey.900"
fontSize="1.1em"
data-testid="clear-icon"
onClick={handleClearClick}
/>
</InputRightElement>
</InputGroup>
</AddressAutofill>
</form>
);
};

export default SearchBar;
29 changes: 0 additions & 29 deletions app/components/search-bar.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ services:
- .env.local
volumes:
- db-data:/var/lib/postgresql/data
- ./backend/database:/docker-entrypoint-initdb.d # Mount the SQL scripts directory
- ./backend/database:/docker-entrypoint-initdb.d # Mount the SQL scripts directory
ports:
- 5432:5432
healthcheck:
Expand Down
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ const nextConfig = {
},
};

module.exports = nextConfig;
module.exports = nextConfig;
Loading

0 comments on commit 34a5d38

Please sign in to comment.