Skip to content
This repository has been archived by the owner on Dec 7, 2020. It is now read-only.

Commit

Permalink
Merge pull request #155 from uktrade/feature/address-search
Browse files Browse the repository at this point in the history
Add address search
  • Loading branch information
rafenden authored Sep 16, 2019
2 parents 37b4db5 + 314d80c commit a2b1ea0
Show file tree
Hide file tree
Showing 13 changed files with 4,913 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ typings/
# IDE
.idea/
.history*
.vscode

# Production build
dist/
Expand Down
58 changes: 58 additions & 0 deletions src/address-search/AddressSearch.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useState } from 'react'
import PropTypes from 'prop-types'
import Button from '@govuk-react/button'
import Select from '@govuk-react/select'
import InputField from '@govuk-react/input-field'

const UNKNOWN = 'unknown'

const AddressSearch = ({
error,
addressList,
onAddressSearch,
}) => {
const [postCode, setPostCode] = useState(null)

const onAddressSearchClick = (evt) => {
evt.preventDefault()
onAddressSearch(postCode || UNKNOWN)
}

return (
<>
<div>
<InputField
name="postcode"
type="text"
error={error}
onChange={evt => setPostCode(evt.target.value)}
/>
<Button onClick={onAddressSearchClick}>Find UK Address</Button>
</div>
{ addressList && (
<Select name="address" label="Select an address">
{
addressList.map((value, index) => {
return <option key={value.id} value={index}>{ value.address1 }</option>
})
}
</Select>
)}

{error && <p>{error}</p>}
</>
)
}

AddressSearch.propTypes = {
error: PropTypes.string,
addressList: PropTypes.array,
onAddressSearch: PropTypes.func.isRequired,
}

AddressSearch.defaultProps = {
error: null,
addressList: null,
}

export default AddressSearch
44 changes: 44 additions & 0 deletions src/address-search/AddressSearchWithDataProvider.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useState, useEffect } from 'react'
import PropTypes from 'prop-types'

import AddressSearch from './AddressSearch'

const ERROR_MSG_400 = 'Enter a valid postcode'
const ERROR_MSG_500 = 'An error occurred while searching for an address'

const AddressSearchWithDataProvider = ({ getAddress }) => {
const [addressList, setAddressList] = useState(null)
const [error, setError] = useState(null)
const [postcode, setPostcode] = useState(null)

const getAddressList = async () => {
setError(null)
setAddressList(null)

try {
setAddressList(await getAddress(postcode))
} catch ({ response }) {
setError(response.status === 400 ? ERROR_MSG_400 : ERROR_MSG_500)
}
}

useEffect(() => {
if (postcode) {
getAddressList()
}
}, [postcode])

return (
<AddressSearch
addressList={addressList}
error={error}
onAddressSearch={setPostcode}
/>
)
}

AddressSearchWithDataProvider.propTypes = {
getAddress: PropTypes.func.isRequired,
}

export default AddressSearchWithDataProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"Addresses": [
"101 Ditchling Road, , , , , Brighton, East Sussex",
"103 Ditchling Road, , , , , Brighton, East Sussex",
"105 Ditchling Road, , , , , Brighton, East Sussex",
"109a Ditchling Road, , , , , Brighton, East Sussex",
"109b Ditchling Road, , , , , Brighton, East Sussex",
"111 Ditchling Road, , , , , Brighton, East Sussex",
"111a Ditchling Road, , , , , Brighton, East Sussex",
"111B Ditchling Road, , , , , Brighton, East Sussex",
"113 Ditchling Road, , , , , Brighton, East Sussex",
"115 Ditchling Road, , , , , Brighton, East Sussex",
"115a Ditchling Road, , , , , Brighton, East Sussex",
"117a Ditchling Road, , , , , Brighton, East Sussex",
"117b Ditchling Road, , , , , Brighton, East Sussex",
"117c Ditchling Road, , , , , Brighton, East Sussex",
"119 Ditchling Road, , , , , Brighton, East Sussex",
"119A Ditchling Road, , , , , Brighton, East Sussex",
"121 Ditchling Road, , , , , Brighton, East Sussex",
"121A Ditchling Road, , , , , Brighton, East Sussex",
"123 Ditchling Road, , , , , Brighton, East Sussex",
"123a Ditchling Road, , , , , Brighton, East Sussex",
"125 Ditchling Road, , , , , Brighton, East Sussex",
"125a Ditchling Road, , , , , Brighton, East Sussex",
"127 Ditchling Road, , , , , Brighton, East Sussex",
"127a Ditchling Road, , , , , Brighton, East Sussex",
"129 Ditchling Road, , , , , Brighton, East Sussex",
"129a Ditchling Road, , , , , Brighton, East Sussex",
"131 Ditchling Road, , , , , Brighton, East Sussex",
"131a Ditchling Road, , , , , Brighton, East Sussex",
"133 Ditchling Road, , , , , Brighton, East Sussex",
"137 Ditchling Road, , , , , Brighton, East Sussex",
"137a Ditchling Road, , , , , Brighton, East Sussex",
"139 Ditchling Road, , , , , Brighton, East Sussex",
"139a Ditchling Road, , , , , Brighton, East Sussex",
"141 Ditchling Road, , , , , Brighton, East Sussex",
"97 Ditchling Road, , , , , Brighton, East Sussex",
"99 Ditchling Road, , , , , Brighton, East Sussex",
"First Floor Flat, 107 Ditchling Road, , , , Brighton, East Sussex",
"Flat, 101 Ditchling Road, , , , Brighton, East Sussex",
"Flat, 103 Ditchling Road, , , , Brighton, East Sussex",
"Flat, 105 Ditchling Road, , , , Brighton, East Sussex",
"Flat, 97 Ditchling Road, , , , Brighton, East Sussex",
"Flat 1, 109 Ditchling Road, , , , Brighton, East Sussex",
"Flat 1, 119 Ditchling Road, , , , Brighton, East Sussex",
"Flat 1, 137 Ditchling Road, , , , Brighton, East Sussex",
"Flat 1-6, 109 Ditchling Road, , , , Brighton, East Sussex",
"Flat 2, 109 Ditchling Road, , , , Brighton, East Sussex",
"Flat 2, 119 Ditchling Road, , , , Brighton, East Sussex",
"Flat 2, 131 Ditchling Road, , , , Brighton, East Sussex",
"Flat 2, 137 Ditchling Road, , , , Brighton, East Sussex",
"Flat 3, 109 Ditchling Road, , , , Brighton, East Sussex",
"Flat 3, 119 Ditchling Road, , , , Brighton, East Sussex",
"Flat 3, 131 Ditchling Road, , , , Brighton, East Sussex",
"Flat 4, 109 Ditchling Road, , , , Brighton, East Sussex",
"Flat 4, 119 Ditchling Road, , , , Brighton, East Sussex",
"Flat 4, 131 Ditchling Road, , , , Brighton, East Sussex",
"Flat 5, 109 Ditchling Road, , , , Brighton, East Sussex",
"Flat 6, 109 Ditchling Road, , , , Brighton, East Sussex",
"Ground Floor Flat, 107 Ditchling Road, , , , Brighton, East Sussex",
"Rear Flat, 107 Ditchling Road, , , , Brighton, East Sussex",
"Smart House, Ditchling Road, , , , Brighton, East Sussex",
"Upper Maisonette, 123 Ditchling Road, , , , Brighton, East Sussex"
]
}
3 changes: 3 additions & 0 deletions src/address-search/__fixtures__/bad-request-400.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Message": "Bad Request"
}
7 changes: 7 additions & 0 deletions src/address-search/__fixtures__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import addressSearch from './address-search-postcode-BN1-4SE'
import badRequest from './bad-request-400'

export {
addressSearch,
badRequest,
}
61 changes: 61 additions & 0 deletions src/address-search/__mocks__/address-search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import MockAdapter from 'axios-mock-adapter'
import axios from 'axios'

import {
addressSearch,
badRequest,
} from '../__fixtures__'

export function setupSuccessMocks(apiEndpoint) {
const mock = new MockAdapter(axios)
mock
.onGet(apiEndpoint)
.reply(200, addressSearch)
}

export function setupBadRequest(apiEndpoint) {
const mock = new MockAdapter(axios)
mock
.onGet(apiEndpoint)
.reply(400, badRequest)
}

export function setupErrorMocks(apiEndpoint) {
const mock = new MockAdapter(axios)
mock
.onGet(apiEndpoint)
.reply(500)
}

export function mockAddressVariation1(apiEndpoint) {
const mock = new MockAdapter(axios)
mock
.onGet(apiEndpoint)
.reply(200, {
Addresses: [
'zero, one, two, , , five, six',
],
})
}

export function mockAddressVariation2(apiEndpoint) {
const mock = new MockAdapter(axios)
mock
.onGet(apiEndpoint)
.reply(200, {
Addresses: [
'zero, one, two, , , , ',
],
})
}

export function mockAddressVariation3(apiEndpoint) {
const mock = new MockAdapter(axios)
mock
.onGet(apiEndpoint)
.reply(200, {
Addresses: [
'zero, one, , , , five, ',
],
})
}
20 changes: 20 additions & 0 deletions src/address-search/__stories__/AddressSearch.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
import { addDecorator, storiesOf } from '@storybook/react'
import { withKnobs, text } from '@storybook/addon-knobs'

import addressSearch from '../data-providers/AddressSearch'
import AddressSearchWithDataProvider from '../AddressSearchWithDataProvider'

const BASE_URL = 'https://api.getAddress.io/v2/uk'

addDecorator(withKnobs)

storiesOf('Address search', module)
.add('Data Hub address search', () => {
const API_KEY = text('API KEY', 'YOUR_GETADDRESS_IO_API_KEY')
return (
<AddressSearchWithDataProvider
getAddress={addressSearch(BASE_URL, API_KEY)}
/>
)
})
Loading

0 comments on commit a2b1ea0

Please sign in to comment.