From 6b56f5f91058b98a4921a649cf5813861a1647e0 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Wed, 8 Nov 2023 14:40:19 +0000 Subject: [PATCH 01/46] adjust how data comes through --- src/components/map/MapProperties.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/components/map/MapProperties.js b/src/components/map/MapProperties.js index c91e9b08..56335138 100644 --- a/src/components/map/MapProperties.js +++ b/src/components/map/MapProperties.js @@ -8,7 +8,7 @@ import LoadingData from "./LoadingData"; import { highlightProperty, setActiveProperty } from "../../actions/LandOwnershipActions"; const MapProperties = ({ center, map }) => { - const [propertiesArray, setPropertiesArray] = useState([]); + const [properties, setProperties] = useState([]); const [loadingProperties, setLoadingProperties] = useState(false); const displayActive = useSelector(state => state.landOwnership.displayActive); @@ -39,16 +39,13 @@ const MapProperties = ({ center, map }) => { getAuthHeader() ); - const properties = response.data.map((property) => { - const json = JSON.parse(property.geojson); - return { - ...property, - coordinates: json.coordinates[0] - } - }); + const newProperties = response.data.map((property) => ({ + ...property, + coordinates: property.geom.coordinates[0].map(coordinate => coordinate.reverse()) //mapbox wants [lng,lat] but db gives [lat,lng] + })); - if (properties.length > 0) - setPropertiesArray(properties); + if (newProperties.length > 0) + setProperties(newProperties); setLoadingProperties(false); } @@ -73,7 +70,7 @@ const MapProperties = ({ center, map }) => { const detailedPropertyFeatures = []; const basicPropertyFeatures = []; - propertiesArray.forEach(property => { + properties.forEach(property => { if (property.date_proprietor_added) detailedPropertyFeatures.push( Date: Thu, 9 Nov 2023 16:07:14 +0000 Subject: [PATCH 02/46] first commit, button component and search request --- src/components/common/Button.js | 11 ++ src/components/left-pane/PropertySection.js | 205 +++++++++++++------- 2 files changed, 143 insertions(+), 73 deletions(-) create mode 100644 src/components/common/Button.js diff --git a/src/components/common/Button.js b/src/components/common/Button.js new file mode 100644 index 00000000..ab07cbed --- /dev/null +++ b/src/components/common/Button.js @@ -0,0 +1,11 @@ +import React from "react"; + +const Button = ({ type, buttonAction }) => { + return ( + + ); +}; + +export default Button; diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 8ad0ce74..5618af7b 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -1,86 +1,145 @@ -import React from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import React from "react"; +import { useDispatch, useSelector } from "react-redux"; import { setActiveProperty } from "../../actions/LandOwnershipActions"; +import axios from "axios"; +import constants from "../../constants"; +import { getAuthHeader } from "../../utils/Auth"; +import Button from "../common/Button"; const PropertySection = ({ property }) => { - const dispatch = useDispatch(); - const activePropertyId = useSelector(state => state.landOwnership.activePropertyId); + const dispatch = useDispatch(); + const activePropertyId = useSelector( + (state) => state.landOwnership.activePropertyId + ); - const { - poly_id, - title_no, - proprietor_category_1, - property_address, - proprietor_name_1, - proprietor_1_address_1, - tenure, - date_proprietor_added - } = property; + const getOtherProperties = async () => { + const response = await axios.get( + `${constants.ROOT_URL}/api/search?proprietorName=` + proprietor_name_1, + getAuthHeader() + ); + const properties = response.data.map((property) => { + const json = JSON.parse(property.proprietor_name_1); + return { + ...property, + }; + }); - const open = poly_id === activePropertyId; + if (properties.length > 0) console.log(properties); + }; - return
-
{ - if (open) { - dispatch({ type: 'CLEAR_ACTIVE_PROPERTY' }); - } else { - dispatch(setActiveProperty(poly_id)); - } - }} + const { + poly_id, + title_no, + proprietor_category_1, + property_address, + proprietor_name_1, + proprietor_1_address_1, + tenure, + date_proprietor_added, + } = property; + + const open = poly_id === activePropertyId; + + return ( +
+
{ + if (open) { + dispatch({ type: "CLEAR_ACTIVE_PROPERTY" }); + } else { + dispatch(setActiveProperty(poly_id)); + } + }} + > +

-

Property {poly_id}

-
- -
-
- {open &&
+
+ - { - proprietor_category_1 && <> -

Property Address: {property_address}

-

Proprietor Category: {proprietor_category_1}

-

Proprietor Name: {proprietor_name_1}

-

Proprietor Address: {proprietor_1_address_1}

-

Tenure: {tenure}

-

Date Proprietor Added: {date_proprietor_added}

- - - } -

INSPIRE ID: {poly_id}

-

Title number: {title_no}

-

You can access these documents for a small fee by visiting the Land Registry website using the above IDs.

-
+
+ {open && ( +
+ {proprietor_category_1 && ( + <> +

Property Address: {property_address}

+

Proprietor Category: {proprietor_category_1}

+

Proprietor Name: {proprietor_name_1}

+

Proprietor Address: {proprietor_1_address_1}

+

Tenure: {tenure}

+

Date Proprietor Added: {date_proprietor_added}

+ + + )} +

+ INSPIRE ID: {poly_id} +

+

+ Title number: {title_no} +

+

+ You can access these documents for a small fee by visiting the{" "} + + Land Registry website + {" "} + using the above IDs. +

+ + payload: property, + }) + } + > + Clear property + + +
+ +
- } + )}
-} + ); +}; export default PropertySection; From 712b40d1605ade3ad762ba93c47dec9a1047feac Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Thu, 9 Nov 2023 18:01:55 +0000 Subject: [PATCH 03/46] tidied up basic call --- src/assets/styles/_buttons.scss | 19 ++++++++++--- src/components/common/Button.js | 4 +-- src/components/left-pane/PropertySection.js | 30 ++++++++++++--------- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/assets/styles/_buttons.scss b/src/assets/styles/_buttons.scss index dcf446ed..579f43b9 100644 --- a/src/assets/styles/_buttons.scss +++ b/src/assets/styles/_buttons.scss @@ -22,6 +22,17 @@ } } +.button-new { + width: 100%; + border-radius: 7px; + background-color: $primaryColor; + font-size: 12px; + padding: 10px 20px; + cursor: pointer; + text-align: center; + color: #fff; +} + .button-reg-disabled { opacity: 0.3; background: $buttonGreen; @@ -45,7 +56,7 @@ } .round-button-plus { - background-image: url('../img/icon-plus-small.svg'); + background-image: url("../img/icon-plus-small.svg"); background-size: 14px; background-position: center; background-repeat: no-repeat; @@ -90,7 +101,7 @@ margin-left: 0; height: 36px; width: 32px; - content: ' '; + content: " "; } .rounded-button-close { @@ -137,7 +148,7 @@ background-position: center; background-repeat: no-repeat; background-size: 65%; - background-image: url('../img/icon-menu-layers--white.svg'); + background-image: url("../img/icon-menu-layers--white.svg"); border-radius: 50%; z-index: 1000; position: fixed; @@ -155,7 +166,7 @@ background-position: center; background-repeat: no-repeat; background-size: 65%; - background-image: url('../img/icon-menu-key--white.svg'); + background-image: url("../img/icon-menu-key--white.svg"); border-radius: 50%; z-index: 1000; position: fixed; diff --git a/src/components/common/Button.js b/src/components/common/Button.js index ab07cbed..ffaebe74 100644 --- a/src/components/common/Button.js +++ b/src/components/common/Button.js @@ -1,8 +1,8 @@ import React from "react"; -const Button = ({ type, buttonAction }) => { +const Button = ({ buttonClass, type, children, buttonAction }) => { return ( - ); diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 5618af7b..a18e3c0a 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -13,18 +13,20 @@ const PropertySection = ({ property }) => { ); const getOtherProperties = async () => { - const response = await axios.get( - `${constants.ROOT_URL}/api/search?proprietorName=` + proprietor_name_1, - getAuthHeader() - ); - const properties = response.data.map((property) => { - const json = JSON.parse(property.proprietor_name_1); - return { - ...property, - }; - }); + try { + const response = await axios.get( + `${constants.ROOT_URL}/api/search?proprietorName=${proprietor_name_1}`, + getAuthHeader() + ); - if (properties.length > 0) console.log(properties); + if (response.data.length > 0) { + console.log(response.data); + } else { + console.log("No properties found"); + } + } catch (error) { + console.error("Error fetching properties:", error.message); + } }; const { @@ -132,7 +134,11 @@ const PropertySection = ({ property }) => {
-
From 265f402f46b9e0788b3231d348221962ffdef1ac Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Fri, 10 Nov 2023 16:54:47 +0000 Subject: [PATCH 04/46] hooked related products up to redux and returning results --- src/actions/LandOwnershipActions.js | 42 +- src/actions/MapActions.js | 546 +++++++++--------- src/assets/styles/_buttons.scss | 1 + src/components/left-pane/LeftPaneInfo.js | 82 +-- src/components/left-pane/PropertySection.js | 42 +- src/components/left-pane/RelatedProperties.js | 22 + src/components/map/MapProperties.js | 1 + src/reducers/RelatedPropertiesReducer.js | 23 + src/reducers/rootReducer.js | 2 + 9 files changed, 430 insertions(+), 331 deletions(-) create mode 100644 src/components/left-pane/RelatedProperties.js create mode 100644 src/reducers/RelatedPropertiesReducer.js diff --git a/src/actions/LandOwnershipActions.js b/src/actions/LandOwnershipActions.js index 57d3bee6..66047f1b 100644 --- a/src/actions/LandOwnershipActions.js +++ b/src/actions/LandOwnershipActions.js @@ -1,22 +1,44 @@ +import { getRequest } from "./RequestActions"; + export const highlightProperty = (property) => { - return dispatch => { + return (dispatch) => { dispatch({ type: "HIGHLIGHT_PROPERTY", - payload: property + payload: property, }); dispatch(setActiveProperty(property.poly_id)); - } -} + }; +}; export const setActiveProperty = (propertyId) => { - return dispatch => { + return (dispatch) => { dispatch({ type: "SET_ACTIVE_PROPERTY", - payload: propertyId + payload: propertyId, }); dispatch({ - type: 'SET_ACTIVE', - payload: 'Land Information' + type: "SET_ACTIVE", + payload: "Land Information", }); - } -} + }; +}; + +export const getRelatedProperties = (proprietorName) => { + return async (dispatch) => { + const relatedProperties = await dispatch( + getRequest(`/api/search?proprietorName=${proprietorName}`) + ); + + if (relatedProperties.length > 0) { + dispatch({ + type: "FETCH_PROPERTIES_SUCCESS", + payload: relatedProperties, + }); + } else { + dispatch({ + type: "FETCH_PROPERTIES_FAILURE", + payload: "No properties found", + }); + } + }; +}; diff --git a/src/actions/MapActions.js b/src/actions/MapActions.js index f55a22a0..5f164da7 100644 --- a/src/actions/MapActions.js +++ b/src/actions/MapActions.js @@ -1,344 +1,356 @@ -import { VERSION } from '../constants'; -import moment from 'moment'; -import { getRequest, postRequest } from './RequestActions'; -import { updateReadOnly } from './ReadOnlyActions'; +import { VERSION } from "../constants"; +import moment from "moment"; +import { getRequest, postRequest } from "./RequestActions"; +import { updateReadOnly } from "./ReadOnlyActions"; export const getMyMaps = () => { - return async dispatch => { - const mapsData = await dispatch(getRequest('/api/user/maps')); - if (mapsData) { - console.log("Got my maps", mapsData); - dispatch({ type: 'POPULATE_MY_MAPS', payload: mapsData }); - } else { - dispatch({ type: 'MY_MAPS_ERROR' }); - } + return async (dispatch) => { + const mapsData = await dispatch(getRequest("/api/user/maps")); + if (mapsData) { + console.log("Got my maps", mapsData); + dispatch({ type: "POPULATE_MY_MAPS", payload: mapsData }); + } else { + dispatch({ type: "MY_MAPS_ERROR" }); } -} + }; +}; /** Get my maps from backend and reload the current map */ const reloadCurrentMap = () => { - return async (dispatch, getState) => { - const currentMapId = getState().mapMeta.currentMapId; - if (currentMapId !== null) { - console.log("Reloading currently open map", currentMapId); - await dispatch(getMyMaps()); - dispatch(openMap(currentMapId)); - } + return async (dispatch, getState) => { + const currentMapId = getState().mapMeta.currentMapId; + if (currentMapId !== null) { + console.log("Reloading currently open map", currentMapId); + await dispatch(getMyMaps()); + dispatch(openMap(currentMapId)); } -} + }; +}; /** Get my maps from backend and load the map created most recently */ export const loadNewestMap = () => { - return async (dispatch, getState) => { - await dispatch(getMyMaps()); + return async (dispatch, getState) => { + await dispatch(getMyMaps()); - const myMaps = getState().myMaps.maps; + const myMaps = getState().myMaps.maps; - if (myMaps.length > 0) { - const newMap = myMaps[myMaps.length - 1]; - const newMapId = newMap.map.eid; + if (myMaps.length > 0) { + const newMap = myMaps[myMaps.length - 1]; + const newMapId = newMap.map.eid; - console.log("Opening newest map", newMapId); - dispatch(openMap(newMapId)); - } + console.log("Opening newest map", newMapId); + dispatch(openMap(newMapId)); } -} + }; +}; /** Open specified map (if it exists in My Maps) */ export const openMap = (mapId) => { - return (dispatch, getState) => { - const map = getState().myMaps.maps.find(item => item.map.eid === mapId); - if (map) { - const mapData = JSON.parse(map.map.data); - const isSnapshot = map.map.isSnapshot; - const lastModified = map.map.lastModified; - const writeAccess = map.access === 'WRITE'; - - dispatch({ - type: 'LOAD_MAP', - payload: { - data: mapData, - id: mapId, - isSnapshot: isSnapshot, - writeAccess: writeAccess, - lastModified: shortenTimestamp(lastModified) - } - }); - dispatch(updateReadOnly()); - - setTimeout(() => { - dispatch({ - type: 'CHANGE_MOVING_METHOD', - payload: 'flyTo' - }); - }, 1000); - - dispatch(postRequest('/api/user/map/view', { "eid": mapId })); - } + return (dispatch, getState) => { + const map = getState().myMaps.maps.find((item) => item.map.eid === mapId); + if (map) { + const mapData = JSON.parse(map.map.data); + const isSnapshot = map.map.isSnapshot; + const lastModified = map.map.lastModified; + const writeAccess = map.access === "WRITE"; + + dispatch({ + type: "LOAD_MAP", + payload: { + data: mapData, + id: mapId, + isSnapshot: isSnapshot, + writeAccess: writeAccess, + lastModified: shortenTimestamp(lastModified), + }, + }); + dispatch(updateReadOnly()); + + setTimeout(() => { + dispatch({ + type: "CHANGE_MOVING_METHOD", + payload: "flyTo", + }); + }, 1000); + + dispatch(postRequest("/api/user/map/view", { eid: mapId })); } -} + }; +}; export const deleteMap = (mapId) => { - return async (dispatch, getState) => { - const success = await dispatch(postRequest('/api/user/map/delete', { "eid": mapId })); - - if (success) { - const currentMapId = getState().mapMeta.currentMapId; - - if (mapId === currentMapId) { - dispatch(newMap()); - } - await dispatch(getMyMaps()); - } + return async (dispatch, getState) => { + const success = await dispatch( + postRequest("/api/user/map/delete", { eid: mapId }) + ); + + if (success) { + const currentMapId = getState().mapMeta.currentMapId; + + if (mapId === currentMapId) { + dispatch(newMap()); + } + await dispatch(getMyMaps()); } -} + }; +}; export const newMap = () => { - return (dispatch, getState) => { - dispatch({ type: 'NEW_MAP' }); - setTimeout(() => { - dispatch({ type: 'CHANGE_MOVING_METHOD', payload: 'flyTo' }) - }, 500); - dispatch(updateReadOnly()); - } -} + return (dispatch, getState) => { + dispatch({ type: "NEW_MAP" }); + setTimeout(() => { + dispatch({ type: "CHANGE_MOVING_METHOD", payload: "flyTo" }); + }, 500); + dispatch(updateReadOnly()); + }; +}; /** * If both 'copy' and 'snapshot' are false, we will save to existing map, or create a new map if it * is a new map. - * + * * @param {boolean} copy true if we are saving a copy of the current map * @param {boolean} snapshot true if we are saving a new snapshot of the current map * @param {string | undefined} name the name of the map that we want to save. If left undefined, we * will use the name of the existing map. * @return {boolean} true if save was successful. */ -export const saveCurrentMap = (copy = false, snapshot = false, name = undefined) => { - return async (dispatch, getState) => { - const map = getState().map; - const saveName = copy ? `Copy of ${map.name}` : name || map.name || 'Untitled Map'; - - const saveData = { - map: { - ...map, - name: saveName, - }, - drawings: getState().drawings, - markers: getState().markers, - mapLayers: { - landDataLayers: getState().mapLayers.landDataLayers, - myDataLayers: getState().dataGroups.activeGroups - }, - version: VERSION, - name: saveName, - - }; - - console.log(`Saving current map, copy:${copy} snapshot:${snapshot} data:`, saveData); - - const body = { - eid: (copy || snapshot) ? null : getState().mapMeta.currentMapId, - name: saveName, - data: JSON.stringify(saveData), - isSnapshot: snapshot || getState().mapMeta.isSnapshot - }; - - return await dispatch(saveMapRequest('/api/user/map/save', body)); - } -} +export const saveCurrentMap = ( + copy = false, + snapshot = false, + name = undefined +) => { + return async (dispatch, getState) => { + const map = getState().map; + const saveName = copy + ? `Copy of ${map.name}` + : name || map.name || "Untitled Map"; + + const saveData = { + map: { + ...map, + name: saveName, + }, + drawings: getState().drawings, + markers: getState().markers, + mapLayers: { + landDataLayers: getState().mapLayers.landDataLayers, + myDataLayers: getState().dataGroups.activeGroups, + }, + version: VERSION, + name: saveName, + }; + + console.log( + `Saving current map, copy:${copy} snapshot:${snapshot} data:`, + saveData + ); + + const body = { + eid: copy || snapshot ? null : getState().mapMeta.currentMapId, + name: saveName, + data: JSON.stringify(saveData), + isSnapshot: snapshot || getState().mapMeta.isSnapshot, + }; + + return await dispatch(saveMapRequest("/api/user/map/save", body)); + }; +}; /** Save the current map if it is saved, otherwise do nothing. Return false iff error when saving */ export const autoSave = () => { - return async (dispatch, getState) => { - if (getState().mapMeta.currentMapId) { - return await dispatch(saveCurrentMap()); - } - return true; + return async (dispatch, getState) => { + if (getState().mapMeta.currentMapId) { + return await dispatch(saveCurrentMap()); } -} + return true; + }; +}; /** Save the object data to a specified map. Return false iff failed to save to backend. */ export const saveObjectToMap = (type, data, mapId) => { - return async (dispatch, getState) => { - const copyToCurrentMap = mapId === getState().mapMeta.currentMapId; - - if (copyToCurrentMap) { - // First save current changes, in case there are any new, unsaved objects. - // Otherwise, they will later overwrite the object that is being copied. - // TODO: can remove this when saving to backend no longer overwrites all existing objects - const success = await dispatch(autoSave()); - if (!success) return false; - } - - const body = { - object: data, - eid: mapId, - }; - const success = await dispatch(saveMapRequest(`/api/user/map/save/${type}`, body)); - - if (success && copyToCurrentMap) { - // so that it appears on the current map - await dispatch(reloadCurrentMap()); - } - return success; + return async (dispatch, getState) => { + const copyToCurrentMap = mapId === getState().mapMeta.currentMapId; + + if (copyToCurrentMap) { + // First save current changes, in case there are any new, unsaved objects. + // Otherwise, they will later overwrite the object that is being copied. + // TODO: can remove this when saving to backend no longer overwrites all existing objects + const success = await dispatch(autoSave()); + if (!success) return false; } -} + + const body = { + object: data, + eid: mapId, + }; + const success = await dispatch( + saveMapRequest(`/api/user/map/save/${type}`, body) + ); + + if (success && copyToCurrentMap) { + // so that it appears on the current map + await dispatch(reloadCurrentMap()); + } + return success; + }; +}; /** Edit the specified object's name and description. Return false iff failed to save to backend. */ export const editMapObjectInfo = (type, uuid, newName, newDescription) => { - return async (dispatch, getState) => { - const payload = { - uuid, - name: newName, - description: newDescription, - }; - - dispatch({ - type: (type === "marker") ? 'RENAME_MARKER' : 'RENAME_POLYGON', - payload - }); - - // If we are working on a saved map - if (getState().mapMeta.currentMapId) { - return await dispatch(saveMapRequest(`/api/user/edit/${type}`, payload)); - } - return true; + return async (dispatch, getState) => { + const payload = { + uuid, + name: newName, + description: newDescription, + }; + + dispatch({ + type: type === "marker" ? "RENAME_MARKER" : "RENAME_POLYGON", + payload, + }); + + // If we are working on a saved map + if (getState().mapMeta.currentMapId) { + return await dispatch(saveMapRequest(`/api/user/edit/${type}`, payload)); } -} + return true; + }; +}; export const setLngLat = (lng, lat) => { - return async (dispatch, getState) => { - dispatch({ - type: 'SET_LNG_LAT', - payload: [lng, lat] - }); - - const currentMapId = getState().mapMeta.currentMapId; - // If map is saved, save to back-end - if (currentMapId) { - const body = { - eid: currentMapId, - lngLat: [lng, lat] - }; - await dispatch(saveMapRequest('/api/user/map/save/lngLat', body)); - } + return async (dispatch, getState) => { + dispatch({ + type: "SET_LNG_LAT", + payload: [lng, lat], + }); + + const currentMapId = getState().mapMeta.currentMapId; + // If map is saved, save to back-end + if (currentMapId) { + const body = { + eid: currentMapId, + lngLat: [lng, lat], + }; + await dispatch(saveMapRequest("/api/user/map/save/lngLat", body)); } -} + }; +}; export const setCurrentLocation = (lng, lat) => { - return dispatch => { - dispatch({ - type: 'SET_CURRENT_LOCATION', - payload: [lng, lat] - }); - } -} + return (dispatch) => { + dispatch({ + type: "SET_CURRENT_LOCATION", + payload: [lng, lat], + }); + }; +}; const saveMapZoom = (mapId, zoom) => { - return async dispatch => { - const body = { - eid: mapId, - zoom: zoom - }; - await dispatch(saveMapRequest('/api/user/map/save/zoom', body)); - } -} + return async (dispatch) => { + const body = { + eid: mapId, + zoom: zoom, + }; + await dispatch(saveMapRequest("/api/user/map/save/zoom", body)); + }; +}; export const zoomIn = () => { - return (dispatch, getState) => { - dispatch({ type: 'ZOOM_IN' }); - - // If map is saved, save current Zoom to back-end - const currentMapId = getState().mapMeta.currentMapId; - if (currentMapId) { - dispatch(saveMapZoom(currentMapId, getState().map.zoom)); - } + return (dispatch, getState) => { + dispatch({ type: "ZOOM_IN" }); + + // If map is saved, save current Zoom to back-end + const currentMapId = getState().mapMeta.currentMapId; + if (currentMapId) { + dispatch(saveMapZoom(currentMapId, getState().map.zoom)); } -} + }; +}; export const zoomOut = () => { - return (dispatch, getState) => { - dispatch({ type: 'ZOOM_OUT' }); - - // If map is saved, save current Zoom to back-end - const currentMapId = getState().mapMeta.currentMapId; - if (currentMapId) { - dispatch(saveMapZoom(currentMapId, getState().map.zoom)); - } + return (dispatch, getState) => { + dispatch({ type: "ZOOM_OUT" }); + + // If map is saved, save current Zoom to back-end + const currentMapId = getState().mapMeta.currentMapId; + if (currentMapId) { + dispatch(saveMapZoom(currentMapId, getState().map.zoom)); } -} + }; +}; export const setZoom = (zoom) => { - return (dispatch, getState) => { - dispatch({ - type: 'SET_ZOOM', - payload: zoom - }); - - // If map is saved, save current Zoom to back-end - const currentMapId = getState().mapMeta.currentMapId; - if (currentMapId) { - dispatch(saveMapZoom(currentMapId, getState().map.zoom)); - } + return (dispatch, getState) => { + dispatch({ + type: "SET_ZOOM", + payload: zoom, + }); + + // If map is saved, save current Zoom to back-end + const currentMapId = getState().mapMeta.currentMapId; + if (currentMapId) { + dispatch(saveMapZoom(currentMapId, getState().map.zoom)); } -} + }; +}; export const setSearchMarker = (lng, lat) => { - return dispatch => { - dispatch({ - type: 'SET_SEARCH_MARKER', - payload: [lng, lat], - }); - } -} + return (dispatch) => { + dispatch({ + type: "SET_SEARCH_MARKER", + payload: [lng, lat], + }); + }; +}; export const clearSearchMarker = () => { - return dispatch => { - dispatch({ type: 'CLEAR_SEARCH_MARKER' }); - } -} + return (dispatch) => { + dispatch({ type: "CLEAR_SEARCH_MARKER" }); + }; +}; /** * Make a POST request to the given API endpoint. Set the map saving and error state according to * what happens with the request. - * + * * @param {string} endpoint the API endpoint, starting '/api/' * @param {any} body the data to include in the POST request * @returns {boolean} whether the save was successful */ const saveMapRequest = (endpoint, body) => { - return async (dispatch, getState) => { - const currentSaveError = getState().mapMeta.saveError; - dispatch({ type: 'MAP_SAVING' }); - - const success = await dispatch(postRequest(endpoint, body)); - - if (success) { - dispatch({ - type: 'MAP_SAVED', - payload: { - timestamp: moment().format("HH:mm") - } - }); - - if (currentSaveError && endpoint !== '/api/user/map/save') { - console.log('There was previously a save error so save the whole map'); - dispatch(saveCurrentMap()); - } - - return true; - } - - dispatch({ type: 'MAP_SAVE_ERROR' }); - return false; + return async (dispatch, getState) => { + const currentSaveError = getState().mapMeta.saveError; + dispatch({ type: "MAP_SAVING" }); + + const success = await dispatch(postRequest(endpoint, body)); + + if (success) { + dispatch({ + type: "MAP_SAVED", + payload: { + timestamp: moment().format("HH:mm"), + }, + }); + + if (currentSaveError && endpoint !== "/api/user/map/save") { + console.log("There was previously a save error so save the whole map"); + dispatch(saveCurrentMap()); + } + + return true; } -} + + dispatch({ type: "MAP_SAVE_ERROR" }); + return false; + }; +}; const shortenTimestamp = (timestamp) => { - const isToday = moment(timestamp).isSame(moment(), 'day'); - if (isToday) { - return moment(timestamp).format("HH:mm"); - } else { - return moment(timestamp).format("DD/MM/YY"); - } -} + const isToday = moment(timestamp).isSame(moment(), "day"); + if (isToday) { + return moment(timestamp).format("HH:mm"); + } else { + return moment(timestamp).format("DD/MM/YY"); + } +}; diff --git a/src/assets/styles/_buttons.scss b/src/assets/styles/_buttons.scss index 579f43b9..4fef2d31 100644 --- a/src/assets/styles/_buttons.scss +++ b/src/assets/styles/_buttons.scss @@ -31,6 +31,7 @@ cursor: pointer; text-align: center; color: #fff; + border: none; } .button-reg-disabled { diff --git a/src/components/left-pane/LeftPaneInfo.js b/src/components/left-pane/LeftPaneInfo.js index 07de663d..7a18c6c6 100644 --- a/src/components/left-pane/LeftPaneInfo.js +++ b/src/components/left-pane/LeftPaneInfo.js @@ -1,44 +1,50 @@ -import React from 'react'; -import { useSelector } from 'react-redux'; -import LeftPaneTray from './LeftPaneTray'; -import MarkerSection from './MarkerSection'; -import PolygonSection from './PolygonSection'; -import PropertySection from './PropertySection'; +import React from "react"; +import { useSelector } from "react-redux"; +import LeftPaneTray from "./LeftPaneTray"; +import MarkerSection from "./MarkerSection"; +import PolygonSection from "./PolygonSection"; +import PropertySection from "./PropertySection"; const LeftPaneInfo = ({ onClose, open }) => { - const markers = useSelector(state => state.markers.markers); - const polygons = useSelector(state => state.drawings.polygons); - const properties = useSelector(state => state.landOwnership.highlightedProperties); + const markers = useSelector((state) => state.markers.markers); + const polygons = useSelector((state) => state.drawings.polygons); + const properties = useSelector( + (state) => state.landOwnership.highlightedProperties + ); + const otherProperties = useSelector( + (state) => state.relatedProperties.properties + ); - return - { - (polygons.length || markers.length || properties.length) ? ( - <> - {markers.map((marker, i) => - - )} - {polygons.map((polygon, i) => - - )} - {properties.map((property, i) => - - )} - - ) : ( -
- No drawn objects or selected properties. -
- ) - } + return ( + + {polygons.length || markers.length || properties.length ? ( + <> + {markers.map((marker, i) => ( + + ))} + {polygons.map((polygon, i) => ( + + ))} + {properties.map((property, i) => ( + + ))} + {otherProperties.map((property, i) => ( + + ))} + + ) : ( +
+ No drawn objects or selected properties. +
+ )}
-} + ); +}; export default LeftPaneInfo; diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index a18e3c0a..aeea3bcf 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -5,6 +5,7 @@ import axios from "axios"; import constants from "../../constants"; import { getAuthHeader } from "../../utils/Auth"; import Button from "../common/Button"; +import { getRelatedProperties } from "../../actions/LandOwnershipActions"; const PropertySection = ({ property }) => { const dispatch = useDispatch(); @@ -12,22 +13,22 @@ const PropertySection = ({ property }) => { (state) => state.landOwnership.activePropertyId ); - const getOtherProperties = async () => { - try { - const response = await axios.get( - `${constants.ROOT_URL}/api/search?proprietorName=${proprietor_name_1}`, - getAuthHeader() - ); + // const getOtherProperties = async () => { + // try { + // const response = await axios.get( + // `${constants.ROOT_URL}/api/search?proprietorName=${proprietor_name_1}`, + // getAuthHeader() + // ); - if (response.data.length > 0) { - console.log(response.data); - } else { - console.log("No properties found"); - } - } catch (error) { - console.error("Error fetching properties:", error.message); - } - }; + // if (response.data.length > 0) { + // console.log(response.data); + // } else { + // console.log("No properties found"); + // } + // } catch (error) { + // console.error("Error fetching properties:", error.message); + // } + // }; const { poly_id, @@ -134,12 +135,21 @@ const PropertySection = ({ property }) => {
- */} +
diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js new file mode 100644 index 00000000..3c1f3a99 --- /dev/null +++ b/src/components/left-pane/RelatedProperties.js @@ -0,0 +1,22 @@ +import React, { useEffect } from "react"; + +const RelatedProperties = ({ properties, error, getRelatedProperties }) => { + useEffect(() => { + getRelatedProperties(); + }, [getRelatedProperties]); + + return ( +
+ {error &&

{error}

} + {properties.length > 0 && ( +
    + {properties.map((property) => ( +
  • {property.property_address}
  • + ))} +
+ )} +
+ ); +}; + +export default RelatedProperties; diff --git a/src/components/map/MapProperties.js b/src/components/map/MapProperties.js index 56335138..7fd8953e 100644 --- a/src/components/map/MapProperties.js +++ b/src/components/map/MapProperties.js @@ -16,6 +16,7 @@ const MapProperties = ({ center, map }) => { const highlightedProperties = useSelector(state => state.landOwnership.highlightedProperties); const activePropertyId = useSelector(state => state.landOwnership.activePropertyId); const activeProperty = activePropertyId !== null ? highlightedProperties.find(p => p.poly_id === activePropertyId) : null; + const activePanel = useSelector(state => state.leftPane.active); diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js new file mode 100644 index 00000000..7f80581b --- /dev/null +++ b/src/reducers/RelatedPropertiesReducer.js @@ -0,0 +1,23 @@ +const INITIAL_STATE = { + properties: [], + error: null, +}; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case "FETCH_PROPERTIES_SUCCESS": + return { + ...state, + properties: action.payload, + error: null, + }; + case "FETCH_PROPERTIES_FAILURE": + return { + ...state, + properties: [], + error: action.payload, + }; + default: + return state; + } +}; diff --git a/src/reducers/rootReducer.js b/src/reducers/rootReducer.js index 368c4084..d0d36fc4 100644 --- a/src/reducers/rootReducer.js +++ b/src/reducers/rootReducer.js @@ -18,6 +18,7 @@ import MapMetaReducer from "./MapMetaReducer"; import LandOwnershipReducer from "./LandOwnershipReducer"; import DataGroupsReducer from "./DataGroupsReducer"; import ConnectivityReducer from "./ConnectivityReducer"; +import RelatedPropertiesReducer from "./RelatedPropertiesReducer"; const appReducer = combineReducers({ authentication: AuthenticationReducer, @@ -39,6 +40,7 @@ const appReducer = combineReducers({ landOwnership: LandOwnershipReducer, dataGroups: DataGroupsReducer, connectivity: ConnectivityReducer, + relatedProperties: RelatedPropertiesReducer, }); const rootReducer = (state, action) => { From 55a6848bcc14a8f31626827120881ab3385a62be Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Fri, 10 Nov 2023 20:31:30 +0000 Subject: [PATCH 05/46] results on related properties panel --- src/components/common/Tooltips.js | 11 ++++++++ src/components/left-pane/LeftPane.js | 20 ++++++++++++++ src/components/left-pane/LeftPaneInfo.js | 6 ----- .../left-pane/LeftPaneRelatedProperties.js | 25 +++++++++++++++++ src/components/left-pane/PropertySection.js | 27 ------------------- src/components/left-pane/RelatedProperties.js | 23 +++++++--------- 6 files changed, 65 insertions(+), 47 deletions(-) create mode 100644 src/components/left-pane/LeftPaneRelatedProperties.js diff --git a/src/components/common/Tooltips.js b/src/components/common/Tooltips.js index f821024d..4bb7e81b 100644 --- a/src/components/common/Tooltips.js +++ b/src/components/common/Tooltips.js @@ -59,6 +59,17 @@ const Tooltips = () => { > Land Information + + Related Properties + ); }; diff --git a/src/components/left-pane/LeftPane.js b/src/components/left-pane/LeftPane.js index 0b94b24c..5a607b7c 100644 --- a/src/components/left-pane/LeftPane.js +++ b/src/components/left-pane/LeftPane.js @@ -3,6 +3,7 @@ import { useDispatch, useSelector } from "react-redux"; import LeftPaneInfo from "./LeftPaneInfo"; import LeftPaneLandData from "./LeftPaneLandData"; import LeftPaneDrawingTools from "./LeftPaneDrawingTools"; +import LeftPaneRelatedProperties from "./LeftPaneRelatedProperties"; import analytics from "../../analytics"; import { autoSave } from "../../actions/MapActions"; import { isMobile } from "react-device-detect"; @@ -125,7 +126,22 @@ const LeftPane = ({ drawControl }) => { data-tip data-for="ttInfo" /> +
{ + analytics.event( + analytics._event.LEFT_PANE + " Related Properties", + "Open" + ); + clickIcon("Related Properties"); + }} + data-tip + data-for="ttRelatedProperties" + />
+ { // If not read only, render drawing tools !readOnly && ( @@ -143,6 +159,10 @@ const LeftPane = ({ drawControl }) => { open={open && active === "Land Information"} onClose={closeTray} /> + ); }; diff --git a/src/components/left-pane/LeftPaneInfo.js b/src/components/left-pane/LeftPaneInfo.js index 7a18c6c6..a2566974 100644 --- a/src/components/left-pane/LeftPaneInfo.js +++ b/src/components/left-pane/LeftPaneInfo.js @@ -11,9 +11,6 @@ const LeftPaneInfo = ({ onClose, open }) => { const properties = useSelector( (state) => state.landOwnership.highlightedProperties ); - const otherProperties = useSelector( - (state) => state.relatedProperties.properties - ); return ( @@ -28,9 +25,6 @@ const LeftPaneInfo = ({ onClose, open }) => { {properties.map((property, i) => ( ))} - {otherProperties.map((property, i) => ( - - ))} ) : (
{ + const otherProperties = useSelector( + (state) => state.relatedProperties.properties + ); + return ( + + {otherProperties.length ? ( + <> + {otherProperties.map((property, i) => ( + + ))} + + ) : ( +
No related Properties
+ )} +
+ ); +}; + +export default LeftPaneRelatedProperties; diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index aeea3bcf..16679c31 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -1,9 +1,6 @@ import React from "react"; import { useDispatch, useSelector } from "react-redux"; import { setActiveProperty } from "../../actions/LandOwnershipActions"; -import axios from "axios"; -import constants from "../../constants"; -import { getAuthHeader } from "../../utils/Auth"; import Button from "../common/Button"; import { getRelatedProperties } from "../../actions/LandOwnershipActions"; @@ -13,23 +10,6 @@ const PropertySection = ({ property }) => { (state) => state.landOwnership.activePropertyId ); - // const getOtherProperties = async () => { - // try { - // const response = await axios.get( - // `${constants.ROOT_URL}/api/search?proprietorName=${proprietor_name_1}`, - // getAuthHeader() - // ); - - // if (response.data.length > 0) { - // console.log(response.data); - // } else { - // console.log("No properties found"); - // } - // } catch (error) { - // console.error("Error fetching properties:", error.message); - // } - // }; - const { poly_id, title_no, @@ -135,13 +115,6 @@ const PropertySection = ({ property }) => {
- {/* */} + + {pageNumbers.map((number) => ( +
  • + +
  • + ))} +
  • + +
  • + + + )} +
    ) : (
    No related Properties
    From 9df58d5ebf3d5c671afd20e4e0059b5366322b09 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Thu, 16 Nov 2023 12:29:37 +0000 Subject: [PATCH 09/46] updated pagination prior to componantisation --- src/assets/styles/_left-pane.scss | 3 +- src/assets/styles/_pagination.scss | 20 ++++++ src/assets/styles/style.scss | 1 + src/components/common/Tooltips.js | 2 +- src/components/left-pane/LeftPane.js | 8 +-- .../left-pane/LeftPaneRelatedProperties.js | 68 ++++++++++++++----- 6 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 src/assets/styles/_pagination.scss diff --git a/src/assets/styles/_left-pane.scss b/src/assets/styles/_left-pane.scss index 0e2876be..451f9703 100644 --- a/src/assets/styles/_left-pane.scss +++ b/src/assets/styles/_left-pane.scss @@ -79,7 +79,8 @@ .left-pane-tray { left: 72px; position: fixed; - width: 250px; + // width: 250px; + width: 400px; bottom: 0; top: 68px; background-color: #f4f5f7; diff --git a/src/assets/styles/_pagination.scss b/src/assets/styles/_pagination.scss new file mode 100644 index 00000000..ebbb682f --- /dev/null +++ b/src/assets/styles/_pagination.scss @@ -0,0 +1,20 @@ +.pagination { + list-style: none; + display: flex; +} + +.page-item { + padding: 10px; + border: 1px solid $primaryColor; + cursor: pointer; +} + +.button-style { + background-color: transparent; + border: none; + cursor: pointer; +} + +.button-style:focus { + outline: none; +} diff --git a/src/assets/styles/style.scss b/src/assets/styles/style.scss index e9df45fb..552456f9 100644 --- a/src/assets/styles/style.scss +++ b/src/assets/styles/style.scss @@ -11,6 +11,7 @@ @import "my-account"; @import "properties"; @import "datalayers"; +@import "pagination"; html { text-rendering: optimizeLegibility; diff --git a/src/components/common/Tooltips.js b/src/components/common/Tooltips.js index 4bb7e81b..629ab529 100644 --- a/src/components/common/Tooltips.js +++ b/src/components/common/Tooltips.js @@ -68,7 +68,7 @@ const Tooltips = () => { delayShow={tooltipDelay} globalEventOff={isMobile ? "click" : undefined} > - Related Properties + Ownership Search ); diff --git a/src/components/left-pane/LeftPane.js b/src/components/left-pane/LeftPane.js index ef78e28e..3fb10efc 100644 --- a/src/components/left-pane/LeftPane.js +++ b/src/components/left-pane/LeftPane.js @@ -128,14 +128,14 @@ const LeftPane = ({ drawControl }) => { />
    { analytics.event( - analytics._event.LEFT_PANE + " Related Properties", + analytics._event.LEFT_PANE + " Ownership Search", "Open" ); - clickIcon("Related Properties"); + clickIcon("Ownership Search"); }} data-tip data-for="ttRelatedProperties" @@ -160,7 +160,7 @@ const LeftPane = ({ drawControl }) => { onClose={closeTray} /> diff --git a/src/components/left-pane/LeftPaneRelatedProperties.js b/src/components/left-pane/LeftPaneRelatedProperties.js index 19f2ff8f..58eb1ca0 100644 --- a/src/components/left-pane/LeftPaneRelatedProperties.js +++ b/src/components/left-pane/LeftPaneRelatedProperties.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import LeftPaneTray from "./LeftPaneTray"; import { useSelector } from "react-redux"; import RelatedProperties from "./RelatedProperties"; @@ -8,7 +8,10 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { (state) => state.relatedProperties.properties ); - const [currentPage, setCurrentPage] = React.useState(1); + const [currentPage, setCurrentPage] = useState(1); + const [pageNumberLimit, setPageNumberLimit] = useState(5); + const [maxPageNumberLimit, setMaxPageNumberLimit] = useState(5); + const [minPageNumberLimit, setMinPageNumberLimit] = useState(0); // Use a Set to store unique properties const uniqueProperties = new Set(); @@ -22,7 +25,7 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { const propertyCount = filteredProperties.length; - // Index range for pagination + // Pagination const indexOfLastProperty = currentPage * itemsPerPage; const indexOfFirstProperty = indexOfLastProperty - itemsPerPage; const currentProperties = filteredProperties.slice( @@ -39,11 +42,19 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { if (currentPage < noOfPages) { setCurrentPage(currentPage + 1); } + if (currentPage + 1 > maxPageNumberLimit) { + setMaxPageNumberLimit(maxPageNumberLimit + pageNumberLimit); + setMinPageNumberLimit(minPageNumberLimit + pageNumberLimit); + } }; const previousPage = () => { if (currentPage > 1) { setCurrentPage(currentPage - 1); } + if ((currentPage - 1) % pageNumberLimit === 0) { + setMaxPageNumberLimit(maxPageNumberLimit - pageNumberLimit); + setMinPageNumberLimit(minPageNumberLimit - pageNumberLimit); + } }; console.log("Items per page: ", itemsPerPage); @@ -51,7 +62,7 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { console.log("last Page: ", lastPage); return ( - + {filteredProperties.length ? ( <>
    {propertyCount} properties
    @@ -68,21 +79,42 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { onClick={previousPage} disabled={currentPage === firstPage} > - Previous + Prev - {pageNumbers.map((number) => ( -
  • - -
  • - ))} + {pageNumbers.length > maxPageNumberLimit && + currentPage > 5 && ( +
  • + … +
  • + )} + {pageNumbers.map((number) => { + if ( + number < maxPageNumberLimit + 1 && + number > minPageNumberLimit + ) { + return ( +
  • + +
  • + ); + } else { + return null; + } + })} + {pageNumbers.length > maxPageNumberLimit && + currentPage != lastPage && ( +
  • + … +
  • + )}
  • ) : ( -
    No related Properties
    +
    No Related Properties
    )} ); From f93c8af465affef7a54361d6a9b3644c48068249 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Thu, 16 Nov 2023 15:06:33 +0000 Subject: [PATCH 10/46] property search button opens ownership search tray --- src/components/left-pane/PropertySection.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 16679c31..4ba49aba 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -3,8 +3,9 @@ import { useDispatch, useSelector } from "react-redux"; import { setActiveProperty } from "../../actions/LandOwnershipActions"; import Button from "../common/Button"; import { getRelatedProperties } from "../../actions/LandOwnershipActions"; +import { isMobile } from "react-device-detect"; -const PropertySection = ({ property }) => { +const PropertySection = ({ property, active }) => { const dispatch = useDispatch(); const activePropertyId = useSelector( (state) => state.landOwnership.activePropertyId @@ -23,6 +24,17 @@ const PropertySection = ({ property }) => { const open = poly_id === activePropertyId; + const openTray = (tray) => { + active === tray + ? dispatch({ type: "CLOSE_TRAY" }) + : dispatch({ type: "SET_ACTIVE", payload: tray }); + }; + + const handleSearch = () => { + dispatch(getRelatedProperties(proprietor_name_1)); + openTray("Ownership Search"); + }; + return (
    { From b8e12077f6617687d7381ca9e75d3e14eeec6b9b Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Fri, 17 Nov 2023 15:08:31 +0000 Subject: [PATCH 11/46] basic result styling --- src/assets/styles/_left-pane.scss | 16 ++- src/assets/styles/_ownership-search.scss | 56 ++++++++ src/assets/styles/_pagination.scss | 23 ++- src/assets/styles/style.scss | 1 + src/components/common/Pagination.js | 97 +++++++++++++ .../left-pane/LeftPaneRelatedProperties.js | 132 ++++-------------- src/components/left-pane/PropertySection.js | 1 - src/components/left-pane/RelatedProperties.js | 40 +++++- 8 files changed, 248 insertions(+), 118 deletions(-) create mode 100644 src/assets/styles/_ownership-search.scss create mode 100644 src/components/common/Pagination.js diff --git a/src/assets/styles/_left-pane.scss b/src/assets/styles/_left-pane.scss index 451f9703..241e10d1 100644 --- a/src/assets/styles/_left-pane.scss +++ b/src/assets/styles/_left-pane.scss @@ -83,7 +83,8 @@ width: 400px; bottom: 0; top: 68px; - background-color: #f4f5f7; + // background-color: #f4f5f7; + background-color: #fff; box-shadow: 3px 0 6px 0 rgba(0, 0, 0, 0.16); z-index: 100000; transition: transform 500ms ease; @@ -94,8 +95,9 @@ .tray-top { width: 100%; - background-color: #e4e6ea; - border-bottom: solid 1px #d1d1d1; + // background-color: #e4e6ea; + // border-bottom: solid 1px #d1d1d1; + border-bottom: 1px solid #EEEEEE; } .tray-title { @@ -106,8 +108,10 @@ align-items: center; .title { - font-weight: bold; - margin-left: 42px; + // font-weight: bold; + margin-left: 20px; + font-size: 24px; + color: $primaryColor; } .close-tray { @@ -292,7 +296,7 @@ position: absolute; width: 100%; height: 58px; - background-color: #f4f5f7; + // background-color: #f4f5f7; display: flex; justify-content: center; align-items: center; diff --git a/src/assets/styles/_ownership-search.scss b/src/assets/styles/_ownership-search.scss new file mode 100644 index 00000000..3d145b64 --- /dev/null +++ b/src/assets/styles/_ownership-search.scss @@ -0,0 +1,56 @@ +.search-results-container { + width: 100%; + box-sizing: border-box; + position: relative; +} + +.property-count { + font-size: 13px; + margin-bottom: 20px; + padding-bottom: 20px; + border-bottom: 1px solid #eeeeee; + padding: 20px; +} + +.property-count--highlight { + color: $primaryColor; +} + +.search-result { + font-size: 13px; + margin-bottom: 20px; + padding: 0 20px; + display: flex; + & > i { + width: 18px; + display: block; + fill: #d4d2d2; + } +} + +.search-result__property-address { + margin: 0 0 5px; + padding: 0; +} + +.search-result__property { + margin: 0 0 5px 10px; + padding: 0; +} +.search-result__proprietor { +} + +.search-result__title-no { +} + +.icon-proprietor { + width: 18px; + height: 18px; + display: block; +} + +.icon-property { + width: 13px; + height: 18px; + display: block; +} diff --git a/src/assets/styles/_pagination.scss b/src/assets/styles/_pagination.scss index ebbb682f..281ffffb 100644 --- a/src/assets/styles/_pagination.scss +++ b/src/assets/styles/_pagination.scss @@ -4,15 +4,28 @@ } .page-item { - padding: 10px; - border: 1px solid $primaryColor; - cursor: pointer; + border: 0px solid $primaryColor; + display: block; + &.prev { + border-radius: 5px 0 0 5px; + } + &.next { + border-radius: 0 5px 5px 0; + } } -.button-style { - background-color: transparent; +.page-link { + margin: 0; + padding: 5px 10px; border: none; + color: $primaryColor; + background-color: transparent; cursor: pointer; + &.active { + background-color: $primaryColor; + color: #fff; + box-shadow: none; + } } .button-style:focus { diff --git a/src/assets/styles/style.scss b/src/assets/styles/style.scss index 552456f9..c676ba1c 100644 --- a/src/assets/styles/style.scss +++ b/src/assets/styles/style.scss @@ -11,6 +11,7 @@ @import "my-account"; @import "properties"; @import "datalayers"; +@import "ownership-search"; @import "pagination"; html { diff --git a/src/components/common/Pagination.js b/src/components/common/Pagination.js new file mode 100644 index 00000000..f5f20987 --- /dev/null +++ b/src/components/common/Pagination.js @@ -0,0 +1,97 @@ +import React, { useState } from "react"; + +const Pagination = ({ + pagesDisplayed, + currentPage, + setCurrentPage, + noOfPages, + itemsPerPage, +}) => { + const [pageNumberLimit, setPageNumberLimit] = useState(pagesDisplayed); + const [maxPageNumberLimit, setMaxPageNumberLimit] = useState(pagesDisplayed); + const [minPageNumberLimit, setMinPageNumberLimit] = useState(0); + + const pageNumbers = [...Array(noOfPages + 1).keys()].slice(1); + const lastPage = pageNumbers[pageNumbers.length - 1]; + const firstPage = pageNumbers[0]; + + const paginate = (pageNumber) => setCurrentPage(pageNumber); + const nextPage = () => { + if (currentPage < noOfPages) { + setCurrentPage(currentPage + 1); + } + if (currentPage + 1 > maxPageNumberLimit) { + setMaxPageNumberLimit(maxPageNumberLimit + pageNumberLimit); + setMinPageNumberLimit(minPageNumberLimit + pageNumberLimit); + } + }; + const previousPage = () => { + if (currentPage > 1) { + setCurrentPage(currentPage - 1); + } + if ((currentPage - 1) % pageNumberLimit === 0) { + setMaxPageNumberLimit(maxPageNumberLimit - pageNumberLimit); + setMinPageNumberLimit(minPageNumberLimit - pageNumberLimit); + } + }; + + console.log("Items per page: ", itemsPerPage); + console.log("first Page: ", firstPage); + console.log("last Page: ", lastPage); + + return ( + + ); +}; + +export default Pagination; diff --git a/src/components/left-pane/LeftPaneRelatedProperties.js b/src/components/left-pane/LeftPaneRelatedProperties.js index 58eb1ca0..d0358f7f 100644 --- a/src/components/left-pane/LeftPaneRelatedProperties.js +++ b/src/components/left-pane/LeftPaneRelatedProperties.js @@ -2,17 +2,13 @@ import React, { useState } from "react"; import LeftPaneTray from "./LeftPaneTray"; import { useSelector } from "react-redux"; import RelatedProperties from "./RelatedProperties"; +import Pagination from "../common/Pagination"; const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { const otherProperties = useSelector( (state) => state.relatedProperties.properties ); - const [currentPage, setCurrentPage] = useState(1); - const [pageNumberLimit, setPageNumberLimit] = useState(5); - const [maxPageNumberLimit, setMaxPageNumberLimit] = useState(5); - const [minPageNumberLimit, setMinPageNumberLimit] = useState(0); - // Use a Set to store unique properties const uniqueProperties = new Set(); @@ -25,113 +21,47 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { const propertyCount = filteredProperties.length; - // Pagination + // Pagination values + const [currentPage, setCurrentPage] = useState(1); + const noOfPages = Math.ceil(propertyCount / itemsPerPage); const indexOfLastProperty = currentPage * itemsPerPage; const indexOfFirstProperty = indexOfLastProperty - itemsPerPage; + // Chop up the properties array into pages const currentProperties = filteredProperties.slice( indexOfFirstProperty, indexOfLastProperty ); - const noOfPages = Math.ceil(propertyCount / itemsPerPage); - const pageNumbers = [...Array(noOfPages + 1).keys()].slice(1); - const lastPage = pageNumbers[pageNumbers.length - 1]; - const firstPage = pageNumbers[0]; - - const paginate = (pageNumber) => setCurrentPage(pageNumber); - const nextPage = () => { - if (currentPage < noOfPages) { - setCurrentPage(currentPage + 1); - } - if (currentPage + 1 > maxPageNumberLimit) { - setMaxPageNumberLimit(maxPageNumberLimit + pageNumberLimit); - setMinPageNumberLimit(minPageNumberLimit + pageNumberLimit); - } - }; - const previousPage = () => { - if (currentPage > 1) { - setCurrentPage(currentPage - 1); - } - if ((currentPage - 1) % pageNumberLimit === 0) { - setMaxPageNumberLimit(maxPageNumberLimit - pageNumberLimit); - setMinPageNumberLimit(minPageNumberLimit - pageNumberLimit); - } - }; - - console.log("Items per page: ", itemsPerPage); - console.log("first Page: ", firstPage); - console.log("last Page: ", lastPage); return ( - {filteredProperties.length ? ( - <> -
    {propertyCount} properties
    - {currentProperties.map((property, i) => ( - - ))} -
    +
    + {filteredProperties.length ? ( + <> +
    + + {currentProperties[0].proprietor_name_1} + {" "} + has{" "} + {propertyCount}{" "} + associated properties +
    + {currentProperties.map((property, i) => ( + + ))} {noOfPages > 1 && ( - + )} -
    - - ) : ( -
    No Related Properties
    - )} + + ) : ( +
    No Related Properties
    + )} +
    ); }; diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 4ba49aba..8de7df82 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -3,7 +3,6 @@ import { useDispatch, useSelector } from "react-redux"; import { setActiveProperty } from "../../actions/LandOwnershipActions"; import Button from "../common/Button"; import { getRelatedProperties } from "../../actions/LandOwnershipActions"; -import { isMobile } from "react-device-detect"; const PropertySection = ({ property, active }) => { const dispatch = useDispatch(); diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index 5232ad09..b0aaf5bd 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -1,12 +1,42 @@ import React from "react"; const RelatedProperties = ({ property }) => { - return ( -
    -

    {property.property_address}

    -

    {property.proprietor_name_1}

    -

    {property.title_no}

    +
    + + + + + +
    +

    {property.property_address}

    +
    + Title no: {property.title_no} +
    +
    + + {/*
    + + + + + + {property.proprietor_name_1} +
    */}
    ); }; From 956f8924ddc9f9093372636e0fb04b62be80279c Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Tue, 21 Nov 2023 09:36:19 +0000 Subject: [PATCH 12/46] cordinates for selected search property added to state, but no poly showing --- src/actions/LandOwnershipActions.js | 13 +++++ src/assets/styles/_ownership-search.scss | 1 + src/components/left-pane/RelatedProperties.js | 20 ++++++- src/components/map/MapboxMap.js | 18 +++++++ src/components/map/PropertySearchPoly.js | 52 +++++++++++++++++++ src/reducers/ShowPropertyPolyReducer.js | 19 +++++++ src/reducers/rootReducer.js | 2 + 7 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 src/components/map/PropertySearchPoly.js create mode 100644 src/reducers/ShowPropertyPolyReducer.js diff --git a/src/actions/LandOwnershipActions.js b/src/actions/LandOwnershipActions.js index 66047f1b..d17067d0 100644 --- a/src/actions/LandOwnershipActions.js +++ b/src/actions/LandOwnershipActions.js @@ -1,5 +1,7 @@ import { getRequest } from "./RequestActions"; +export const SHOW_PROPERTY_POLYGON = "SHOW_PROPERTY_POLYGON"; + export const highlightProperty = (property) => { return (dispatch) => { dispatch({ @@ -42,3 +44,14 @@ export const getRelatedProperties = (proprietorName) => { } }; }; + +export const showPropertyPolygon = (propertyCoordinates) => { + return (dispatch) => { + dispatch({ + type: SHOW_PROPERTY_POLYGON, + payload: propertyCoordinates, + }); + }; +}; + + diff --git a/src/assets/styles/_ownership-search.scss b/src/assets/styles/_ownership-search.scss index 3d145b64..357930e4 100644 --- a/src/assets/styles/_ownership-search.scss +++ b/src/assets/styles/_ownership-search.scss @@ -21,6 +21,7 @@ margin-bottom: 20px; padding: 0 20px; display: flex; + cursor: pointer; & > i { width: 18px; display: block; diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index b0aaf5bd..33b61ca8 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -1,8 +1,22 @@ import React from "react"; +import { useDispatch } from "react-redux"; +import { showPropertyPolygon } from "../../actions/LandOwnershipActions"; const RelatedProperties = ({ property }) => { + const dispatch = useDispatch(); + + const handlePropertyClick = () => { + dispatch(showPropertyPolygon(property.geom.coordinates[0])); + console.log("Property clicked", property.geom.coordinates); + console.log("title_no", property.title_no); + }; + return ( -
    +
    {
    -

    {property.property_address}

    +

    + {property.property_address} +

    Title no: {property.title_no}
    diff --git a/src/components/map/MapboxMap.js b/src/components/map/MapboxMap.js index 2d1f3040..580155b6 100644 --- a/src/components/map/MapboxMap.js +++ b/src/components/map/MapboxMap.js @@ -18,6 +18,7 @@ import mapSources from "../../data/mapSources"; import MapProperties from "./MapProperties"; import MapDataGroups from "./MapDataGroups"; import { autoSave, setLngLat, setZoom } from "../../actions/MapActions"; +import PropertySearchPoly from "./PropertySearchPoly"; // Create Map Component with settings const Map = ReactMapboxGl({ @@ -46,6 +47,20 @@ const MapboxMap = ({ user }) => { const propertiesDisplay = useSelector( (state) => state.landOwnership.displayActive ); + const propertyCoordinates = useSelector( + (state) => state.propertySearchPoly.propertyCoordinates + ); + + // Check the propertyCoordinates update propagates to the MapboxMap component + useEffect(() => { + if (propertyCoordinates.length > 0) { + console.log( + "Property coordinates exist - MapboxMap", + propertyCoordinates + ); + } + }, [propertyCoordinates]); + const [styleLoaded, setStyleLoaded] = useState(false); const [drawings, setDrawings] = useState(); const [redrawing, setRedrawing] = useState(false); @@ -271,6 +286,9 @@ const MapboxMap = ({ user }) => { // this is how the map moves automatically from one location to another (default is jumpTo, but we disable this temporarily when we load a new map) movingMethod={movingMethod} > + {/* Property Search Poly / No clue where this should go */} + {propertyCoordinates.length > 0 && } + {/* Map Layers (greenbelt etc.)*/} {/* Map Data Groups displaying My Data, except data group markers, which are in Markers to cluster together */} diff --git a/src/components/map/PropertySearchPoly.js b/src/components/map/PropertySearchPoly.js new file mode 100644 index 00000000..5a01ca5d --- /dev/null +++ b/src/components/map/PropertySearchPoly.js @@ -0,0 +1,52 @@ +import React, { useEffect } from "react"; +import { useSelector } from "react-redux"; +import { GeoJSONLayer } from "react-mapbox-gl"; + +const PropertySearchPoly = ({ property }) => { + const propertyCoordinates = useSelector( + (state) => state.propertySearchPoly.propertyCoordinates + ); + + const polyId = useSelector((state) => state.propertySearchPoly.polyId); + + const polygonData = { + geometry: { + coordinates: propertyCoordinates, + type: "Polygon", + }, + id: polyId, + properties: {}, + type: "Feature", + }; + + const polygonLayer = ( + + ); + + useEffect(() => { + console.log("Property coordinates exist!", propertyCoordinates, polyId); + console.log("Polygon Layer", polygonLayer); + }, [propertyCoordinates, polyId]); + + // Check if propertyCoordinates exist before rendering GeoJSONLayer + if (!propertyCoordinates || propertyCoordinates.length === 0) { + console.log("Property coordinates do not exist!"); + return null; + } + + return <>{polygonLayer}; +}; + +export default PropertySearchPoly; diff --git a/src/reducers/ShowPropertyPolyReducer.js b/src/reducers/ShowPropertyPolyReducer.js new file mode 100644 index 00000000..49ba2471 --- /dev/null +++ b/src/reducers/ShowPropertyPolyReducer.js @@ -0,0 +1,19 @@ +import { SHOW_PROPERTY_POLYGON } from "../actions/LandOwnershipActions"; + +const INITIAL_STATE = { + propertyCoordinates: [], + polyId: null, +}; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case SHOW_PROPERTY_POLYGON: + return { + ...state, + propertyCoordinates: action.payload, + polyId: action.payload.poly_id, + }; + default: + return state; + } +}; diff --git a/src/reducers/rootReducer.js b/src/reducers/rootReducer.js index d0d36fc4..b6afefd9 100644 --- a/src/reducers/rootReducer.js +++ b/src/reducers/rootReducer.js @@ -19,6 +19,7 @@ import LandOwnershipReducer from "./LandOwnershipReducer"; import DataGroupsReducer from "./DataGroupsReducer"; import ConnectivityReducer from "./ConnectivityReducer"; import RelatedPropertiesReducer from "./RelatedPropertiesReducer"; +import ShowPropertyPolyReducer from "./ShowPropertyPolyReducer"; const appReducer = combineReducers({ authentication: AuthenticationReducer, @@ -41,6 +42,7 @@ const appReducer = combineReducers({ dataGroups: DataGroupsReducer, connectivity: ConnectivityReducer, relatedProperties: RelatedPropertiesReducer, + propertySearchPoly: ShowPropertyPolyReducer, }); const rootReducer = (state, action) => { From eefa0c50b65e621889b2b99119d92b39c8288f15 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Tue, 21 Nov 2023 12:06:30 +0000 Subject: [PATCH 13/46] propertySection styling and left pane responsiveness --- src/assets/styles/_left-pane.scss | 24 +++- src/assets/styles/_properties.scss | 62 +++++++++- src/assets/styles/_variables.scss | 6 +- .../left-pane/LeftPaneRelatedProperties.js | 6 +- src/components/left-pane/PropertySection.js | 108 ++++++++++++------ 5 files changed, 160 insertions(+), 46 deletions(-) diff --git a/src/assets/styles/_left-pane.scss b/src/assets/styles/_left-pane.scss index 241e10d1..6a2b47a0 100644 --- a/src/assets/styles/_left-pane.scss +++ b/src/assets/styles/_left-pane.scss @@ -80,7 +80,7 @@ left: 72px; position: fixed; // width: 250px; - width: 400px; + width: calc(100vw - 72px); bottom: 0; top: 68px; // background-color: #f4f5f7; @@ -97,7 +97,7 @@ width: 100%; // background-color: #e4e6ea; // border-bottom: solid 1px #d1d1d1; - border-bottom: 1px solid #EEEEEE; + border-bottom: 1px solid #eeeeee; } .tray-title { @@ -183,9 +183,11 @@ } .tray-item-title { - width: 140px; + // width: 140px; padding-left: 48px; cursor: pointer; + width: calc(100% - 97px); + margin-right: 10px; } } @@ -313,7 +315,9 @@ } .tray-item-title { - width: 140px; + // width: 140px; + width: calc(100% - 97px); + margin-right: 10px; } transform-origin: 50% 50% 0px; @@ -364,3 +368,15 @@ a.mapboxgl-ctrl-logo { margin-top: 0; margin-left: 15px; } + +/* Desktop specific, as mobile first */ +@media screen and (min-width: 769px) { + .left-pane-tray { + width: 400px; + } + + .draggable-item .tray-item-title, + .tray-item .tray-item-title { + width: 302px; + } +} diff --git a/src/assets/styles/_properties.scss b/src/assets/styles/_properties.scss index 44278c0f..253108f0 100644 --- a/src/assets/styles/_properties.scss +++ b/src/assets/styles/_properties.scss @@ -1,8 +1,58 @@ -.property-id-number{ - cursor: pointer; - margin: 0; +.property-id-number { + cursor: pointer; + margin: 0; } -.highlighted{ - color: red; -} \ No newline at end of file +.highlighted { + color: red; +} + +.property-details { + height: auto; + width: 100%; + padding: 20px; + box-sizing: border-box; +} + +.property-details-title { + font-size: 24px; + color: $primaryColor; + margin-bottom: 20px; +} + +.property-details-section { + box-sizing: border-box; + border-top: 2px solid $midNeutral2; + padding: 20px 0; + font-size: 18px; +} + +.property-details-section__inner { + box-sizing: border-box; +} + +.property-details-section__title { + font-size: 18px; + color: $primaryColor; + margin: 0; +} + +.property-details-section__value, +.property-details-section__small-print { + color: $darkNeutral; +} + +.property-details-section__small-print { + font-size: 14px; +} + +/* Desktop specific, as mobile first */ +@media screen and (min-width: 769px) { + .property-details-section__inner { + display: flex; + + & > div { + width: 50%; + } + } +} diff --git a/src/assets/styles/_variables.scss b/src/assets/styles/_variables.scss index a63df68e..f53ef19b 100644 --- a/src/assets/styles/_variables.scss +++ b/src/assets/styles/_variables.scss @@ -44,8 +44,10 @@ $toolbarAccent: #e3e3e5; $trayBackground: #eff0f2; $trayAccent: #e5e7eb; -$neutral: #E9E7E7; -$midNeutral: #B1B1B1; +$neutral: #e9e7e7; +$darkNeutral: #707070; +$midNeutral: #b1b1b1; +$midNeutral2: #d4d2d2; $lightNeutral: #f5f5f5; /** Mixins **/ diff --git a/src/components/left-pane/LeftPaneRelatedProperties.js b/src/components/left-pane/LeftPaneRelatedProperties.js index d0358f7f..908a0778 100644 --- a/src/components/left-pane/LeftPaneRelatedProperties.js +++ b/src/components/left-pane/LeftPaneRelatedProperties.js @@ -59,7 +59,11 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { )} ) : ( -
    No Related Properties
    +
    + No Related Properties +
    )}
    diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 8de7df82..083ca006 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -77,43 +77,86 @@ const PropertySection = ({ property, active }) => {
    {open && ( -
    +
    {proprietor_category_1 && ( <> -

    Property Address: {property_address}

    -

    Proprietor Category: {proprietor_category_1}

    -

    Proprietor Name: {proprietor_name_1}

    -

    Proprietor Address: {proprietor_1_address_1}

    -

    Tenure: {tenure}

    -

    Date Proprietor Added: {date_proprietor_added}

    - +
    {property_address}
    +
    +
    + Proprietor Name: +
    +
    + {proprietor_name_1} +
    +
    +
    +
    + Proprietor Address: +
    +
    + {proprietor_1_address_1} +
    +
    +
    +
    +
    + Proprietor Category: +
    +
    + {proprietor_category_1} +
    +
    +
    +
    Tenure:
    +
    + {tenure} +
    +
    +
    +
    + Date Proprietor Added: +
    +
    + {date_proprietor_added} +
    +
    +
    )} -

    - INSPIRE ID: {poly_id} -

    -

    - Title number: {title_no} -

    -

    - You can access these documents for a small fee by visiting the{" "} - +

    +
    - Land Registry website - {" "} - using the above IDs. -

    +
    + Title Number: +
    +
    {title_no}
    +
    +
    +

    + You can access these documents for a small fee by visiting the{" "} + + Land Registry website + {" "} + using the above IDs. +

    +
    +
    + -
    - -
    +
    +
    + +
    )}
    From b2fe4daedc354de4694a36d2157b975cc8e765b4 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Wed, 22 Nov 2023 14:05:36 +0000 Subject: [PATCH 19/46] added selected property and style --- src/assets/styles/_ownership-search.scss | 14 ++- .../left-pane/LeftPaneRelatedProperties.js | 13 ++- src/components/left-pane/RelatedProperties.js | 101 +++++++++--------- 3 files changed, 74 insertions(+), 54 deletions(-) diff --git a/src/assets/styles/_ownership-search.scss b/src/assets/styles/_ownership-search.scss index 357930e4..843051c8 100644 --- a/src/assets/styles/_ownership-search.scss +++ b/src/assets/styles/_ownership-search.scss @@ -27,6 +27,15 @@ display: block; fill: #d4d2d2; } + &.active { + & h4 { + color: $primaryColor; + } + box-shadow: none; + & > i { + fill: $primaryColor; + } + } } .search-result__property-address { @@ -38,11 +47,6 @@ margin: 0 0 5px 10px; padding: 0; } -.search-result__proprietor { -} - -.search-result__title-no { -} .icon-proprietor { width: 18px; diff --git a/src/components/left-pane/LeftPaneRelatedProperties.js b/src/components/left-pane/LeftPaneRelatedProperties.js index b2f4c0e7..2c08cdbe 100644 --- a/src/components/left-pane/LeftPaneRelatedProperties.js +++ b/src/components/left-pane/LeftPaneRelatedProperties.js @@ -9,6 +9,7 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { (state) => state.relatedProperties.properties ); + const [activeProperty, setActiveProperty] = useState(null); // Use a Set to store unique properties const uniqueProperties = new Set(); @@ -32,6 +33,11 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { indexOfLastProperty ); + // Pass down the active property to the RelatedProperties component + const handlePropertyClick = (property) => { + setActiveProperty(property); + }; + return (
    @@ -47,7 +53,12 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { associated properties
    {currentProperties.map((property, i) => ( - + handlePropertyClick(property)} + /> ))} {noOfPages > 1 && ( { +const RelatedProperties = ({ property, isActive, onPropertyClick }) => { const dispatch = useDispatch(); - const [active, setActive] = useState(false); const lng = property.geom.coordinates[0][0][1]; const lat = property.geom.coordinates[0][0][0]; const handlePropertyClick = () => { + onPropertyClick(); dispatch(setLngLat(lng, lat)); dispatch(showPropertyPolygon(property.geom.coordinates[0])); - console.log("Property clicked", property.geom.coordinates); - console.log("title_no", property.title_no); - console.log("lat", lat); - console.log("lng", lng); - // setActive(!active); }; return ( -
    - - + {isActive ? ( +
    + + + + + +
    +

    + {property.property_address} +

    +
    + Title no: {property.title_no} +
    +
    +
    + ) : ( +
    - - - -
    -

    - {property.property_address} -

    -
    - Title no: {property.title_no} + + + + + +
    +

    + {property.property_address} +

    +
    + Title no: {property.title_no} +
    +
    -
    - - {/*
    - - - - - - {property.proprietor_name_1} -
    */} -
    + )} + ); }; From 3b0aae7b749040c2b45b3044f24eaa40d1c36e09 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Wed, 22 Nov 2023 15:08:21 +0000 Subject: [PATCH 20/46] loading added to the search panel --- src/actions/LandOwnershipActions.js | 31 ++++++++++++------- src/assets/styles/_ownership-search.scss | 16 ++++++++++ .../left-pane/LeftPaneRelatedProperties.js | 11 ++++++- src/reducers/RelatedPropertiesReducer.js | 8 +++++ 4 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/actions/LandOwnershipActions.js b/src/actions/LandOwnershipActions.js index d17067d0..f04e58f4 100644 --- a/src/actions/LandOwnershipActions.js +++ b/src/actions/LandOwnershipActions.js @@ -27,19 +27,28 @@ export const setActiveProperty = (propertyId) => { export const getRelatedProperties = (proprietorName) => { return async (dispatch) => { - const relatedProperties = await dispatch( - getRequest(`/api/search?proprietorName=${proprietorName}`) - ); + try { + dispatch({ type: "FETCH_PROPERTIES_LOADING" }); - if (relatedProperties.length > 0) { - dispatch({ - type: "FETCH_PROPERTIES_SUCCESS", - payload: relatedProperties, - }); - } else { + const relatedProperties = await dispatch( + getRequest(`/api/search?proprietorName=${proprietorName}`) + ); + + if (relatedProperties.length > 0) { + dispatch({ + type: "FETCH_PROPERTIES_SUCCESS", + payload: relatedProperties, + }); + } else { + dispatch({ + type: "FETCH_PROPERTIES_FAILURE", + payload: "No properties found", + }); + } + } catch (error) { dispatch({ type: "FETCH_PROPERTIES_FAILURE", - payload: "No properties found", + payload: "Error fetching properties", }); } }; @@ -53,5 +62,3 @@ export const showPropertyPolygon = (propertyCoordinates) => { }); }; }; - - diff --git a/src/assets/styles/_ownership-search.scss b/src/assets/styles/_ownership-search.scss index 843051c8..4a564e50 100644 --- a/src/assets/styles/_ownership-search.scss +++ b/src/assets/styles/_ownership-search.scss @@ -28,6 +28,7 @@ fill: #d4d2d2; } &.active { + cursor: default; & h4 { color: $primaryColor; } @@ -59,3 +60,18 @@ height: 18px; display: block; } + +.loading-spinner { + border: 6px solid $lightNeutral; /* Light grey */ + border-top: 6px solid $primaryColor; /* Blue */ + border-radius: 50%; + width: 20px; + height: 20px; + animation: spin 1s linear infinite; + margin: 0 auto; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} diff --git a/src/components/left-pane/LeftPaneRelatedProperties.js b/src/components/left-pane/LeftPaneRelatedProperties.js index 2c08cdbe..426a4039 100644 --- a/src/components/left-pane/LeftPaneRelatedProperties.js +++ b/src/components/left-pane/LeftPaneRelatedProperties.js @@ -9,6 +9,9 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { (state) => state.relatedProperties.properties ); + // Set loading state + const loading = useSelector((state) => state.relatedProperties.loading); + const [activeProperty, setActiveProperty] = useState(null); // Use a Set to store unique properties const uniqueProperties = new Set(); @@ -41,7 +44,13 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { return (
    - {filteredProperties.length ? ( + {loading ? ( +
    +
    +
    + ) : filteredProperties.length ? ( <>
    diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index fa07ba22..194efcaa 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -1,6 +1,7 @@ const INITIAL_STATE = { properties: [], error: null, + loading: false, }; export default (state = INITIAL_STATE, action) => { @@ -10,12 +11,19 @@ export default (state = INITIAL_STATE, action) => { ...state, properties: action.payload, error: null, + loading: false, }; case "FETCH_PROPERTIES_FAILURE": return { ...state, properties: [], error: action.payload, + loading: false, + }; + case "FETCH_PROPERTIES_LOADING": + return { + ...state, + loading: true, }; case "CLEAR_PROPERTIES": return INITIAL_STATE; From bb9c16f6445ccab3db00e27c5f1ac26f8a9e576a Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Thu, 23 Nov 2023 15:47:15 +0000 Subject: [PATCH 21/46] fix coordinate switching bug --- src/components/map/PropertySearchPoly.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/map/PropertySearchPoly.js b/src/components/map/PropertySearchPoly.js index f4dc21e9..12a9a839 100644 --- a/src/components/map/PropertySearchPoly.js +++ b/src/components/map/PropertySearchPoly.js @@ -11,7 +11,7 @@ const PropertySearchPoly = ({ property }) => { const polygonData = { geometry: { - coordinates: [propertyCoordinates.map((coord) => coord.reverse())], + coordinates: [propertyCoordinates.map((coord) => [coord[1], coord[0]])], //mapbox expects coords as lng,lat type: "Polygon", }, id: polyId, @@ -36,7 +36,7 @@ const PropertySearchPoly = ({ property }) => { ); useEffect(() => { - console.log("Property coordinates exist!", propertyCoordinates, polyId); + console.log("Property coordinates exist!", propertyCoordinates, polyId); console.log("Polygon Layer", polygonLayer); }, [propertyCoordinates, polyId]); From 59ac54349a7804819cd7a2fe2496cfed5fdb8bc0 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Fri, 24 Nov 2023 12:44:10 +0000 Subject: [PATCH 22/46] icon active visible if ownership active and zoomed in --- src/components/left-pane/LeftPane.js | 38 +++++++++++++++++----------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/components/left-pane/LeftPane.js b/src/components/left-pane/LeftPane.js index 3fb10efc..03ef59c9 100644 --- a/src/components/left-pane/LeftPane.js +++ b/src/components/left-pane/LeftPane.js @@ -7,6 +7,7 @@ import LeftPaneRelatedProperties from "./LeftPaneRelatedProperties"; import analytics from "../../analytics"; import { autoSave } from "../../actions/MapActions"; import { isMobile } from "react-device-detect"; +import constants from "../../constants"; const LeftPane = ({ drawControl }) => { const dispatch = useDispatch(); @@ -15,6 +16,11 @@ const LeftPane = ({ drawControl }) => { const profileMenuOpen = useSelector((state) => state.menu.profile); const currentMarker = useSelector((state) => state.markers.currentMarker); const activePolygon = useSelector((state) => state.drawings.activePolygon); + const zoom = useSelector((state) => state.map.zoom); + const propertyBoundriesZoom = constants.PROPERTY_BOUNDARIES_ZOOM_LEVEL; + const landOwnershipActive = useSelector( + (state) => state.landOwnership.displayActive + ); const closeTray = () => { dispatch({ type: "CLOSE_TRAY" }); @@ -126,22 +132,24 @@ const LeftPane = ({ drawControl }) => { data-tip data-for="ttInfo" /> -
    { - analytics.event( - analytics._event.LEFT_PANE + " Ownership Search", - "Open" - ); - clickIcon("Ownership Search"); - }} - data-tip - data-for="ttRelatedProperties" - /> + {/* display land ownership icon only if land ownship layer is active and zoomed-in to sufficient level */} + {zoom >= propertyBoundriesZoom && landOwnershipActive == true && ( +
    { + analytics.event( + analytics._event.LEFT_PANE + " Ownership Search", + "Open" + ); + clickIcon("Ownership Search"); + }} + data-tip + data-for="ttRelatedProperties" + /> + )}
    - { // If not read only, render drawing tools !readOnly && ( From 5df8a900621d3379293c8e605b21a555ae72e262 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Fri, 24 Nov 2023 14:35:21 +0000 Subject: [PATCH 23/46] proprietorName added to state, for relationship to clear properties --- src/actions/LandOwnershipActions.js | 11 ++++-- src/components/left-pane/LeftPane.js | 40 ++++++++++++--------- src/components/left-pane/PropertySection.js | 26 +++++++++----- src/reducers/RelatedPropertiesReducer.js | 22 +++++++++++- src/reducers/ShowPropertyPolyReducer.js | 4 +-- 5 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/actions/LandOwnershipActions.js b/src/actions/LandOwnershipActions.js index f04e58f4..a33cdd3a 100644 --- a/src/actions/LandOwnershipActions.js +++ b/src/actions/LandOwnershipActions.js @@ -1,7 +1,5 @@ import { getRequest } from "./RequestActions"; -export const SHOW_PROPERTY_POLYGON = "SHOW_PROPERTY_POLYGON"; - export const highlightProperty = (property) => { return (dispatch) => { dispatch({ @@ -54,10 +52,17 @@ export const getRelatedProperties = (proprietorName) => { }; }; +export const setProprietorName = (proprietorName) => { + return { + type: "SET_PROPRIETOR_NAME", + payload: proprietorName, + }; +}; + export const showPropertyPolygon = (propertyCoordinates) => { return (dispatch) => { dispatch({ - type: SHOW_PROPERTY_POLYGON, + type: "SHOW_PROPERTY_POLYGON", payload: propertyCoordinates, }); }; diff --git a/src/components/left-pane/LeftPane.js b/src/components/left-pane/LeftPane.js index 03ef59c9..5b8d354d 100644 --- a/src/components/left-pane/LeftPane.js +++ b/src/components/left-pane/LeftPane.js @@ -18,6 +18,9 @@ const LeftPane = ({ drawControl }) => { const activePolygon = useSelector((state) => state.drawings.activePolygon); const zoom = useSelector((state) => state.map.zoom); const propertyBoundriesZoom = constants.PROPERTY_BOUNDARIES_ZOOM_LEVEL; + const propertySearch = useSelector( + (state) => state.relatedProperties.properties + ); const landOwnershipActive = useSelector( (state) => state.landOwnership.displayActive ); @@ -132,23 +135,26 @@ const LeftPane = ({ drawControl }) => { data-tip data-for="ttInfo" /> - {/* display land ownership icon only if land ownship layer is active and zoomed-in to sufficient level */} - {zoom >= propertyBoundriesZoom && landOwnershipActive == true && ( -
    { - analytics.event( - analytics._event.LEFT_PANE + " Ownership Search", - "Open" - ); - clickIcon("Ownership Search"); - }} - data-tip - data-for="ttRelatedProperties" - /> - )} + {/* display land ownership icon only if land ownship layer is active, + zoomed-in to sufficient level and search is not empty */} + {zoom >= propertyBoundriesZoom && + landOwnershipActive == true && + propertySearch.length > 0 && ( +
    { + analytics.event( + analytics._event.LEFT_PANE + " Ownership Search", + "Open" + ); + clickIcon("Ownership Search"); + }} + data-tip + data-for="ttRelatedProperties" + /> + )}
    { // If not read only, render drawing tools diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index ed2c5502..2d125695 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -2,13 +2,19 @@ import React from "react"; import { useDispatch, useSelector } from "react-redux"; import { setActiveProperty } from "../../actions/LandOwnershipActions"; import Button from "../common/Button"; -import { getRelatedProperties } from "../../actions/LandOwnershipActions"; +import { + getRelatedProperties, + setProprietorName, +} from "../../actions/LandOwnershipActions"; const PropertySection = ({ property, active }) => { const dispatch = useDispatch(); const activePropertyId = useSelector( (state) => state.landOwnership.activePropertyId ); + const proprietorName = useSelector( + (state) => state.relatedProperties.proprietorName + ); const { poly_id, @@ -30,11 +36,20 @@ const PropertySection = ({ property, active }) => { }; const handleSearch = () => { - dispatch({ type: "CLEAR_PROPERTIES" }); + dispatch({ type: "CLEAR_PROPERTIES_AND_PROPRIETOR_NAME" }); dispatch(getRelatedProperties(proprietor_name_1)); + dispatch(setProprietorName(proprietor_name_1)); openTray("Ownership Search"); }; + const handleClear = () => { + dispatch({ type: "CLEAR_HIGHLIGHT", payload: property }); + // Clear properties if the property being cleared is the searched property + if (property.proprietor_name_1 === proprietorName) { + dispatch({ type: "CLEAR_PROPERTIES_AND_PROPRIETOR_NAME" }); + } + }; + return (
    {
    diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index 194efcaa..eb34c12a 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -2,6 +2,7 @@ const INITIAL_STATE = { properties: [], error: null, loading: false, + proprietorName: null, }; export default (state = INITIAL_STATE, action) => { @@ -26,7 +27,26 @@ export default (state = INITIAL_STATE, action) => { loading: true, }; case "CLEAR_PROPERTIES": - return INITIAL_STATE; + return { + ...state, + properties: [], + }; + case "SET_PROPRIETOR_NAME": + return { + ...state, + proprietorName: action.payload, + }; + case "CLEAR_PROPRIETOR_NAME": + return { + ...state, + proprietorName: null, + }; + case "CLEAR_PROPERTIES_AND_PROPRIETOR_NAME": + return { + ...state, + properties: [], + proprietorName: null, + }; default: return state; } diff --git a/src/reducers/ShowPropertyPolyReducer.js b/src/reducers/ShowPropertyPolyReducer.js index 49ba2471..0dcb402a 100644 --- a/src/reducers/ShowPropertyPolyReducer.js +++ b/src/reducers/ShowPropertyPolyReducer.js @@ -1,5 +1,3 @@ -import { SHOW_PROPERTY_POLYGON } from "../actions/LandOwnershipActions"; - const INITIAL_STATE = { propertyCoordinates: [], polyId: null, @@ -7,7 +5,7 @@ const INITIAL_STATE = { export default (state = INITIAL_STATE, action) => { switch (action.type) { - case SHOW_PROPERTY_POLYGON: + case "SHOW_PROPERTY_POLYGON": return { ...state, propertyCoordinates: action.payload, From 542f6cfd73019a095bd112a6de7702b101ea63fd Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Fri, 24 Nov 2023 14:49:11 +0000 Subject: [PATCH 24/46] removed unnecessary conditions --- src/components/left-pane/LeftPane.js | 43 +++++++++++----------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/components/left-pane/LeftPane.js b/src/components/left-pane/LeftPane.js index 5b8d354d..92e74248 100644 --- a/src/components/left-pane/LeftPane.js +++ b/src/components/left-pane/LeftPane.js @@ -7,7 +7,6 @@ import LeftPaneRelatedProperties from "./LeftPaneRelatedProperties"; import analytics from "../../analytics"; import { autoSave } from "../../actions/MapActions"; import { isMobile } from "react-device-detect"; -import constants from "../../constants"; const LeftPane = ({ drawControl }) => { const dispatch = useDispatch(); @@ -16,14 +15,9 @@ const LeftPane = ({ drawControl }) => { const profileMenuOpen = useSelector((state) => state.menu.profile); const currentMarker = useSelector((state) => state.markers.currentMarker); const activePolygon = useSelector((state) => state.drawings.activePolygon); - const zoom = useSelector((state) => state.map.zoom); - const propertyBoundriesZoom = constants.PROPERTY_BOUNDARIES_ZOOM_LEVEL; const propertySearch = useSelector( (state) => state.relatedProperties.properties ); - const landOwnershipActive = useSelector( - (state) => state.landOwnership.displayActive - ); const closeTray = () => { dispatch({ type: "CLOSE_TRAY" }); @@ -135,26 +129,23 @@ const LeftPane = ({ drawControl }) => { data-tip data-for="ttInfo" /> - {/* display land ownership icon only if land ownship layer is active, - zoomed-in to sufficient level and search is not empty */} - {zoom >= propertyBoundriesZoom && - landOwnershipActive == true && - propertySearch.length > 0 && ( -
    { - analytics.event( - analytics._event.LEFT_PANE + " Ownership Search", - "Open" - ); - clickIcon("Ownership Search"); - }} - data-tip - data-for="ttRelatedProperties" - /> - )} + {/* display land ownership icon only if search is not empty */} + {propertySearch.length > 0 && ( +
    { + analytics.event( + analytics._event.LEFT_PANE + " Ownership Search", + "Open" + ); + clickIcon("Ownership Search"); + }} + data-tip + data-for="ttRelatedProperties" + /> + )}
    { // If not read only, render drawing tools From cd1b2f38428a0f4262a6d5b3e568ba800ed54b82 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Fri, 24 Nov 2023 17:08:39 +0000 Subject: [PATCH 25/46] name updated to Property Boundaries --- src/components/left-pane/LeftPaneLandData.js | 233 ++++++++++++------- 1 file changed, 149 insertions(+), 84 deletions(-) diff --git a/src/components/left-pane/LeftPaneLandData.js b/src/components/left-pane/LeftPaneLandData.js index 32a7f82b..4bf5af57 100644 --- a/src/components/left-pane/LeftPaneLandData.js +++ b/src/components/left-pane/LeftPaneLandData.js @@ -1,98 +1,163 @@ -import React, { useState } from 'react'; +import React, { useState } from "react"; import { useSelector, useDispatch } from "react-redux"; -import LeftPaneTray from './LeftPaneTray'; -import LeftPaneToggle from './LeftPaneToggle'; -import Draggable from './Draggable'; -import LandDataLayerToggle from './LandDataLayerToggle' -import { toggleDataGroup } from '../../actions/DataGroupActions'; +import LeftPaneTray from "./LeftPaneTray"; +import LeftPaneToggle from "./LeftPaneToggle"; +import Draggable from "./Draggable"; +import LandDataLayerToggle from "./LandDataLayerToggle"; +import { toggleDataGroup } from "../../actions/DataGroupActions"; const DataLayersContainer = ({ children, title }) => { - const [expanded, setExpanded] = useState(true); + const [expanded, setExpanded] = useState(true); - return
    -
    setExpanded(!expanded)}> -

    {title}

    -
    - -
    + return ( +
    +
    setExpanded(!expanded)} + > +

    {title}

    +
    +
    - {expanded && children} +
    + {expanded && children}
    -} + ); +}; const LeftPaneLandData = ({ open, active, onClose }) => { - const dispatch = useDispatch(); + const dispatch = useDispatch(); - const userGroupTitlesAndIDs = useSelector((state) => state.dataGroups.userGroupTitlesAndIDs); - const dataGroupTitlesAndIDs = useSelector((state) => state.dataGroups.dataGroupTitlesAndIDs); - const activeGroups = useSelector((state) => state.dataGroups.activeGroups); - const landOwnershipActive = useSelector((state) => state.landOwnership.displayActive); + const userGroupTitlesAndIDs = useSelector( + (state) => state.dataGroups.userGroupTitlesAndIDs + ); + const dataGroupTitlesAndIDs = useSelector( + (state) => state.dataGroups.dataGroupTitlesAndIDs + ); + const activeGroups = useSelector((state) => state.dataGroups.activeGroups); + const landOwnershipActive = useSelector( + (state) => state.landOwnership.displayActive + ); - const description =

    - Want to add your own data to Land Explorer? Contact Us. + const description = ( +

    + Want to add your own data to Land Explorer?{" "} + + Contact Us. +

    + ); - return ( - - - - - - - - - - - - - - - dispatch({ type: "TOGGLE_PROPERTY_DISPLAY" })} - /> - - - - - - - - - - {userGroupTitlesAndIDs && userGroupTitlesAndIDs.map(userGroup => - - {dataGroupTitlesAndIDs && dataGroupTitlesAndIDs.filter(dataGroup => dataGroup.userGroupId == userGroup.id).map(dataGroup => - dispatch(toggleDataGroup(dataGroup.id))} - />)} - - )} - - ); -} + return ( + + + + + + + + + + + + + + + dispatch({ type: "TOGGLE_PROPERTY_DISPLAY" })} + /> + + + + + + + + + + {userGroupTitlesAndIDs && + userGroupTitlesAndIDs.map((userGroup) => ( + + {dataGroupTitlesAndIDs && + dataGroupTitlesAndIDs + .filter((dataGroup) => dataGroup.userGroupId == userGroup.id) + .map((dataGroup) => ( + dispatch(toggleDataGroup(dataGroup.id))} + /> + ))} + + ))} + + ); +}; export default LeftPaneLandData; From 958ca210c77b8f4ab14c15aba5a830c0f1639f39 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Tue, 28 Nov 2023 15:50:35 +0000 Subject: [PATCH 26/46] add terms of use to sign up --- src/pages/Register.js | 177 ++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 92 deletions(-) diff --git a/src/pages/Register.js b/src/pages/Register.js index 8e3d0d18..60a6767c 100644 --- a/src/pages/Register.js +++ b/src/pages/Register.js @@ -97,8 +97,8 @@ const Register = ({ updateBgImage }) => { ? organisationCommercialOther.value : organisationCommunityInterest.value : organisationSubType === "other" - ? organisationCommercialOther.value - : organisationCommercial.value; + ? organisationCommercialOther.value + : organisationCommercial.value; const request = { address: address1.value, @@ -150,13 +150,12 @@ const Register = ({ updateBgImage }) => { { @@ -170,13 +169,12 @@ const Register = ({ updateBgImage }) => { { /> { { { { { @@ -291,13 +284,12 @@ const Register = ({ updateBgImage }) => { { { { { { @@ -470,9 +458,8 @@ const Register = ({ updateBgImage }) => { )}
    { setAccountType("free"); }} @@ -485,9 +472,8 @@ const Register = ({ updateBgImage }) => {
    { /* disable the payment flow this.setState({ @@ -515,7 +501,14 @@ const Register = ({ updateBgImage }) => { href="/privacy-policy.pdf" > privacy policy - + {" "}and{" "} + + terms of use + . Date: Tue, 28 Nov 2023 17:05:48 +0000 Subject: [PATCH 27/46] add the license --- src/components/left-pane/PropertySection.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 2d125695..6e403198 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -170,6 +170,10 @@ const PropertySection = ({ property, active }) => { {" "} using the above IDs.

    +

    Information produced by HM Land Registry. © Crown copyright 2020.
    + Some data is displayed here for evaluation purposes only. For more information + click here +

    From d39bb7782ac785fc3935e9c2e9e60c548fbdf877 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Tue, 28 Nov 2023 17:17:12 +0000 Subject: [PATCH 28/46] add license info the related properties --- src/assets/styles/_properties.scss | 4 ++++ .../left-pane/LeftPaneRelatedProperties.js | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/assets/styles/_properties.scss b/src/assets/styles/_properties.scss index ed94a0a9..1fcfb9d0 100644 --- a/src/assets/styles/_properties.scss +++ b/src/assets/styles/_properties.scss @@ -46,6 +46,10 @@ font-size: 14px; } +.small-print-margin{ + margin: 0px 15px; +} + .property__clear-property { margin-top: 15px; display: flex; diff --git a/src/components/left-pane/LeftPaneRelatedProperties.js b/src/components/left-pane/LeftPaneRelatedProperties.js index 426a4039..dec02c5c 100644 --- a/src/components/left-pane/LeftPaneRelatedProperties.js +++ b/src/components/left-pane/LeftPaneRelatedProperties.js @@ -86,6 +86,22 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { No Related Properties
    )} +
    +

    + Information produced by HM Land Registry. +
    + © Crown copyright 2020 +
    + Some data is displayed here for evaluation purposes only. For more information + {" "} + click here + +

    +
    ); From 99a9af8234ab3dff96c305390f9e5738dec77080 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Wed, 29 Nov 2023 11:41:13 +0000 Subject: [PATCH 29/46] add a space --- src/components/left-pane/PropertySection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 6e403198..366f6d90 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -171,7 +171,7 @@ const PropertySection = ({ property, active }) => { using the above IDs.

    Information produced by HM Land Registry. © Crown copyright 2020.
    - Some data is displayed here for evaluation purposes only. For more information + Some data is displayed here for evaluation purposes only. For more information{" "} click here

    From 98046bcf377081b70f9f3cb9c2742fdd9244a828 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Wed, 29 Nov 2023 12:49:23 +0000 Subject: [PATCH 30/46] add icon and functionality --- src/assets/img/icon-goto.svg | 10 ++ src/assets/styles/_ownership-search.scss | 5 + src/components/left-pane/RelatedProperties.js | 94 ++++++++----------- 3 files changed, 53 insertions(+), 56 deletions(-) create mode 100644 src/assets/img/icon-goto.svg diff --git a/src/assets/img/icon-goto.svg b/src/assets/img/icon-goto.svg new file mode 100644 index 00000000..b8984439 --- /dev/null +++ b/src/assets/img/icon-goto.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/styles/_ownership-search.scss b/src/assets/styles/_ownership-search.scss index 4a564e50..cf809eea 100644 --- a/src/assets/styles/_ownership-search.scss +++ b/src/assets/styles/_ownership-search.scss @@ -47,6 +47,11 @@ .search-result__property { margin: 0 0 5px 10px; padding: 0; + flex-grow: 1; +} + +.search-result__goto-icon:hover{ + cursor: pointer; } .icon-proprietor { diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index d2619412..4dc32b78 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -11,65 +11,47 @@ const RelatedProperties = ({ property, isActive, onPropertyClick }) => { const handlePropertyClick = () => { onPropertyClick(); - dispatch(setLngLat(lng, lat)); dispatch(showPropertyPolygon(property.geom.coordinates[0])); }; - return ( - <> - {isActive ? ( -
    - - - - - -
    -

    - {property.property_address} -

    -
    - Title no: {property.title_no} -
    -
    -
    - ) : ( -
    - - - - - -
    -

    - {property.property_address} -

    -
    - Title no: {property.title_no} -
    -
    -
    - )} - - ); + const gotoProperty = () => { + dispatch(setLngLat(lng, lat)); + } + + return
    + + + + + +
    +

    + {property.property_address} +

    +
    + Title no: {property.title_no} +
    +
    + move map to property icon +
    + }; export default RelatedProperties; From 7b1caa608ad01e1ae869f401086438a94a388ab3 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Mon, 27 Nov 2023 14:51:48 +0000 Subject: [PATCH 31/46] Updates PropertySearchPoly to Layer and Feature --- src/actions/LandOwnershipActions.js | 9 ++++ src/components/left-pane/RelatedProperties.js | 3 ++ src/components/map/PropertySearchPoly.js | 48 ++++++++----------- src/reducers/RelatedPropertiesReducer.js | 13 ++++- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/actions/LandOwnershipActions.js b/src/actions/LandOwnershipActions.js index a33cdd3a..6a48d873 100644 --- a/src/actions/LandOwnershipActions.js +++ b/src/actions/LandOwnershipActions.js @@ -56,6 +56,15 @@ export const setProprietorName = (proprietorName) => { return { type: "SET_PROPRIETOR_NAME", payload: proprietorName, + } +}; + +export const setActivePropertyId = (propertyId) => { + return (dispatch) => { + dispatch({ + type: "SET_ACTIVE_PROPERTY_ID", + payload: propertyId, + }); }; }; diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index 4dc32b78..edbb1cee 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -2,6 +2,7 @@ import React, { useState } from "react"; import { useDispatch } from "react-redux"; import { showPropertyPolygon } from "../../actions/LandOwnershipActions"; import { setLngLat } from "../../actions/MapActions"; +import { setActivePropertyId } from "../../actions/LandOwnershipActions"; const RelatedProperties = ({ property, isActive, onPropertyClick }) => { const dispatch = useDispatch(); @@ -12,6 +13,8 @@ const RelatedProperties = ({ property, isActive, onPropertyClick }) => { const handlePropertyClick = () => { onPropertyClick(); dispatch(showPropertyPolygon(property.geom.coordinates[0])); + // dispatch(setActiveProperty(property.poly_id)); + dispatch(setActivePropertyId(property.poly_id)); }; const gotoProperty = () => { diff --git a/src/components/map/PropertySearchPoly.js b/src/components/map/PropertySearchPoly.js index 12a9a839..435ff24a 100644 --- a/src/components/map/PropertySearchPoly.js +++ b/src/components/map/PropertySearchPoly.js @@ -1,38 +1,19 @@ import React, { useEffect } from "react"; import { useSelector } from "react-redux"; -import { GeoJSONLayer } from "react-mapbox-gl"; +import { GeoJSONLayer, Feature, Layer } from "react-mapbox-gl"; const PropertySearchPoly = ({ property }) => { const propertyCoordinates = useSelector( (state) => state.propertySearchPoly.propertyCoordinates ); - - const polyId = useSelector((state) => state.propertySearchPoly.polyId); - - const polygonData = { - geometry: { - coordinates: [propertyCoordinates.map((coord) => [coord[1], coord[0]])], //mapbox expects coords as lng,lat - type: "Polygon", - }, - id: polyId, - properties: {}, - type: "Feature", - }; + const polyId = useSelector( + (state) => state.relatedProperties.activePropertyId + ); + + const coordinates = [propertyCoordinates.map((coord) => [coord[1], coord[0]])]; const polygonLayer = ( - + ); useEffect(() => { @@ -46,7 +27,20 @@ const PropertySearchPoly = ({ property }) => { return null; } - return <>{polygonLayer}; + return ( + <> + + {polygonLayer} + + + ); }; export default PropertySearchPoly; diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index eb34c12a..de0aea58 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -3,6 +3,7 @@ const INITIAL_STATE = { error: null, loading: false, proprietorName: null, + activePropertyId: null, }; export default (state = INITIAL_STATE, action) => { @@ -45,7 +46,17 @@ export default (state = INITIAL_STATE, action) => { return { ...state, properties: [], - proprietorName: null, + proprietorName: null + }; + case "SET_ACTIVE_PROPERTY_ID": + return { + ...state, + activePropertyId: action.payload, + }; + case "CLEAR_ACTIVE_PROPERTY_ID": + return { + ...state, + activePropertyId: null, }; default: return state; From 4866a9b14cb9a8e2555d635e06ad6f93fe8f0bbf Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Mon, 27 Nov 2023 15:20:26 +0000 Subject: [PATCH 32/46] property object added to state on selected property click --- src/actions/LandOwnershipActions.js | 8 ++++--- src/components/left-pane/RelatedProperties.js | 7 +++--- src/components/map/PropertySearchPoly.js | 24 ++++++++++++------- src/reducers/RelatedPropertiesReducer.js | 9 ++++--- src/reducers/ShowPropertyPolyReducer.js | 2 -- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/actions/LandOwnershipActions.js b/src/actions/LandOwnershipActions.js index 6a48d873..fb8a9d65 100644 --- a/src/actions/LandOwnershipActions.js +++ b/src/actions/LandOwnershipActions.js @@ -59,11 +59,13 @@ export const setProprietorName = (proprietorName) => { } }; -export const setActivePropertyId = (propertyId) => { +export const setActivePropertyId = (propertyId) => { } + +export const setSelectedProperty = (property) => { return (dispatch) => { dispatch({ - type: "SET_ACTIVE_PROPERTY_ID", - payload: propertyId, + type: "SET_SELECTED_PROPERTY", + payload: property, }); }; }; diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index edbb1cee..6ec3eb84 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -1,8 +1,7 @@ import React, { useState } from "react"; import { useDispatch } from "react-redux"; -import { showPropertyPolygon } from "../../actions/LandOwnershipActions"; +import { setSelectedProperty, showPropertyPolygon } from "../../actions/LandOwnershipActions"; import { setLngLat } from "../../actions/MapActions"; -import { setActivePropertyId } from "../../actions/LandOwnershipActions"; const RelatedProperties = ({ property, isActive, onPropertyClick }) => { const dispatch = useDispatch(); @@ -13,8 +12,8 @@ const RelatedProperties = ({ property, isActive, onPropertyClick }) => { const handlePropertyClick = () => { onPropertyClick(); dispatch(showPropertyPolygon(property.geom.coordinates[0])); - // dispatch(setActiveProperty(property.poly_id)); - dispatch(setActivePropertyId(property.poly_id)); + dispatch(setSelectedProperty(property)); + console.log("Selected Property", property); }; const gotoProperty = () => { diff --git a/src/components/map/PropertySearchPoly.js b/src/components/map/PropertySearchPoly.js index 435ff24a..b9e1cb29 100644 --- a/src/components/map/PropertySearchPoly.js +++ b/src/components/map/PropertySearchPoly.js @@ -1,25 +1,31 @@ import React, { useEffect } from "react"; import { useSelector } from "react-redux"; -import { GeoJSONLayer, Feature, Layer } from "react-mapbox-gl"; +import { Feature, Layer } from "react-mapbox-gl"; -const PropertySearchPoly = ({ property }) => { +const PropertySearchPoly = () => { const propertyCoordinates = useSelector( (state) => state.propertySearchPoly.propertyCoordinates ); - const polyId = useSelector( - (state) => state.relatedProperties.activePropertyId + const property = useSelector( + (state) => state.relatedProperties.selectedProperty ); - - const coordinates = [propertyCoordinates.map((coord) => [coord[1], coord[0]])]; + + const coordinates = [ + propertyCoordinates.map((coord) => [coord[1], coord[0]]), + ]; const polygonLayer = ( - + ); useEffect(() => { - console.log("Property coordinates exist!", propertyCoordinates, polyId); + console.log( + "Property coordinates exist!", + propertyCoordinates, + property.poly_id + ); console.log("Polygon Layer", polygonLayer); - }, [propertyCoordinates, polyId]); + }, [propertyCoordinates, property.poly_id]); // Check if propertyCoordinates exist before rendering GeoJSONLayer if (!propertyCoordinates || propertyCoordinates.length === 0) { diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index de0aea58..1e3cc057 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -4,6 +4,7 @@ const INITIAL_STATE = { loading: false, proprietorName: null, activePropertyId: null, + selectedProperty: null, }; export default (state = INITIAL_STATE, action) => { @@ -49,14 +50,16 @@ export default (state = INITIAL_STATE, action) => { proprietorName: null }; case "SET_ACTIVE_PROPERTY_ID": + return INITIAL_STATE; + case "SET_SELECTED_PROPERTY": return { ...state, - activePropertyId: action.payload, + selectedProperty: action.payload, }; - case "CLEAR_ACTIVE_PROPERTY_ID": + case "CLEAR_SELECTED_PROPERTY": return { ...state, - activePropertyId: null, + selectedProperty: null, }; default: return state; diff --git a/src/reducers/ShowPropertyPolyReducer.js b/src/reducers/ShowPropertyPolyReducer.js index 0dcb402a..e0984131 100644 --- a/src/reducers/ShowPropertyPolyReducer.js +++ b/src/reducers/ShowPropertyPolyReducer.js @@ -1,6 +1,5 @@ const INITIAL_STATE = { propertyCoordinates: [], - polyId: null, }; export default (state = INITIAL_STATE, action) => { @@ -9,7 +8,6 @@ export default (state = INITIAL_STATE, action) => { return { ...state, propertyCoordinates: action.payload, - polyId: action.payload.poly_id, }; default: return state; From 54d0d21f7dfcb1a359850004e166ea5d48d20464 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Mon, 27 Nov 2023 15:47:18 +0000 Subject: [PATCH 33/46] click event added to poly --- src/components/map/MapProperties.js | 150 +++++++++++++---------- src/components/map/PropertySearchPoly.js | 14 ++- src/reducers/RelatedPropertiesReducer.js | 4 +- 3 files changed, 100 insertions(+), 68 deletions(-) diff --git a/src/components/map/MapProperties.js b/src/components/map/MapProperties.js index 7fd8953e..91e1c3e2 100644 --- a/src/components/map/MapProperties.js +++ b/src/components/map/MapProperties.js @@ -1,24 +1,35 @@ import React, { useState, useEffect } from "react"; import { useSelector, useDispatch } from "react-redux"; -import { Layer, Feature } from 'react-mapbox-gl'; +import { Layer, Feature } from "react-mapbox-gl"; import axios from "axios"; import constants from "../../constants"; import { getAuthHeader } from "../../utils/Auth"; import LoadingData from "./LoadingData"; -import { highlightProperty, setActiveProperty } from "../../actions/LandOwnershipActions"; +import { + highlightProperty, + setActiveProperty, +} from "../../actions/LandOwnershipActions"; const MapProperties = ({ center, map }) => { const [properties, setProperties] = useState([]); const [loadingProperties, setLoadingProperties] = useState(false); - const displayActive = useSelector(state => state.landOwnership.displayActive); - const zoom = useSelector(state => state.map.zoom); - const highlightedProperties = useSelector(state => state.landOwnership.highlightedProperties); - const activePropertyId = useSelector(state => state.landOwnership.activePropertyId); - const activeProperty = activePropertyId !== null ? highlightedProperties.find(p => p.poly_id === activePropertyId) : null; - + const displayActive = useSelector( + (state) => state.landOwnership.displayActive + ); + const zoom = useSelector((state) => state.map.zoom); + const highlightedProperties = useSelector( + (state) => state.landOwnership.highlightedProperties + ); + const activePropertyId = useSelector( + (state) => state.landOwnership.activePropertyId + ); + const activeProperty = + activePropertyId !== null + ? highlightedProperties.find((p) => p.poly_id === activePropertyId) + : null; - const activePanel = useSelector(state => state.leftPane.active); + const activePanel = useSelector((state) => state.leftPane.active); const dispatch = useDispatch(); @@ -27,9 +38,8 @@ const MapProperties = ({ center, map }) => { setLoadingProperties(true); - const response = await axios - .get( - `${constants.ROOT_URL}/api/ownership?sw_lng=` + + const response = await axios.get( + `${constants.ROOT_URL}/api/ownership?sw_lng=` + mapBoundaries._sw.lng + "&sw_lat=" + mapBoundaries._sw.lat + @@ -37,82 +47,93 @@ const MapProperties = ({ center, map }) => { mapBoundaries._ne.lng + "&ne_lat=" + mapBoundaries._ne.lat, - getAuthHeader() - ); + getAuthHeader() + ); const newProperties = response.data.map((property) => ({ ...property, - coordinates: property.geom.coordinates[0].map(coordinate => coordinate.reverse()) //mapbox wants [lng,lat] but db gives [lat,lng] + coordinates: property.geom.coordinates[0].map((coordinate) => + coordinate.reverse() + ), //mapbox wants [lng,lat] but db gives [lat,lng] })); - if (newProperties.length > 0) - setProperties(newProperties); + if (newProperties.length > 0) setProperties(newProperties); setLoadingProperties(false); - } + }; useEffect(() => { if (displayActive && zoom >= constants.PROPERTY_BOUNDARIES_ZOOM_LEVEL) getProperties(); - }, [center, map, zoom, displayActive]) + }, [center, map, zoom, displayActive]); const onClickNewProperty = (property) => { - if (activePanel !== 'Drawing Tools') { + if (activePanel !== "Drawing Tools") { dispatch(highlightProperty(property)); } - } + }; const onClickHighlightedProperty = (property) => { - if (activePanel !== 'Drawing Tools') { + if (activePanel !== "Drawing Tools") { dispatch(setActiveProperty(property.poly_id)); } - } + }; const detailedPropertyFeatures = []; const basicPropertyFeatures = []; - properties.forEach(property => { + properties.forEach((property) => { if (property.date_proprietor_added) - detailedPropertyFeatures.push( onClickNewProperty(property)} - />) + detailedPropertyFeatures.push( + onClickNewProperty(property)} + /> + ); else - basicPropertyFeatures.push( onClickNewProperty(property)} - />) + basicPropertyFeatures.push( + onClickNewProperty(property)} + /> + ); }); - const highlightedPropertyFeatures = highlightedProperties.map(highlightedProperty => - onClickHighlightedProperty(highlightedProperty)} - /> + const highlightedPropertyFeatures = highlightedProperties.map( + (highlightedProperty) => ( + onClickHighlightedProperty(highlightedProperty)} + /> + ) ); // Add another polygon for the active property so it appears darker if (activeProperty) { - highlightedPropertyFeatures.push(); + highlightedPropertyFeatures.push( + + ); } - return <> - { - displayActive && zoom >= constants.PROPERTY_BOUNDARIES_ZOOM_LEVEL && ( + return ( + <> + {displayActive && zoom >= constants.PROPERTY_BOUNDARIES_ZOOM_LEVEL && ( <> - {loadingProperties && } + {loadingProperties && ( + + )} {detailedPropertyFeatures} @@ -121,24 +142,25 @@ const MapProperties = ({ center, map }) => { type={"fill"} paint={{ "fill-opacity": 0.15, - "fill-color": 'orange', - "fill-outline-color": 'green', + "fill-color": "orange", + "fill-outline-color": "green", }} > {basicPropertyFeatures} - ) - } - - {highlightedPropertyFeatures} - - ; -} + )} + + {highlightedPropertyFeatures} + + + ); +}; export default MapProperties; diff --git a/src/components/map/PropertySearchPoly.js b/src/components/map/PropertySearchPoly.js index b9e1cb29..724e4f0c 100644 --- a/src/components/map/PropertySearchPoly.js +++ b/src/components/map/PropertySearchPoly.js @@ -1,8 +1,10 @@ import React, { useEffect } from "react"; -import { useSelector } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; import { Feature, Layer } from "react-mapbox-gl"; +import { setActiveProperty } from "../../actions/LandOwnershipActions"; const PropertySearchPoly = () => { + const dispatch = useDispatch(); const propertyCoordinates = useSelector( (state) => state.propertySearchPoly.propertyCoordinates ); @@ -14,8 +16,16 @@ const PropertySearchPoly = () => { propertyCoordinates.map((coord) => [coord[1], coord[0]]), ]; + const handlePolygonClick = () => { + dispatch(setActiveProperty(property.poly_id)); + console.log("Polygon clicked!", property.poly_id); + }; const polygonLayer = ( - + ); useEffect(() => { diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index 1e3cc057..e60e09c7 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -4,7 +4,7 @@ const INITIAL_STATE = { loading: false, proprietorName: null, activePropertyId: null, - selectedProperty: null, + selectedProperty: [], }; export default (state = INITIAL_STATE, action) => { @@ -59,7 +59,7 @@ export default (state = INITIAL_STATE, action) => { case "CLEAR_SELECTED_PROPERTY": return { ...state, - selectedProperty: null, + selectedProperty: [], }; default: return state; From 531ab60e2f970428e5b2ccde4a12bc23f2dddf01 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Mon, 27 Nov 2023 16:49:11 +0000 Subject: [PATCH 34/46] selectProperty opens in info panel --- src/components/left-pane/LeftPaneInfo.js | 13 ++++++++++++- src/components/left-pane/RelatedProperties.js | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/left-pane/LeftPaneInfo.js b/src/components/left-pane/LeftPaneInfo.js index a2566974..480d06a7 100644 --- a/src/components/left-pane/LeftPaneInfo.js +++ b/src/components/left-pane/LeftPaneInfo.js @@ -11,10 +11,18 @@ const LeftPaneInfo = ({ onClose, open }) => { const properties = useSelector( (state) => state.landOwnership.highlightedProperties ); + const selectedProperties = useSelector( + (state) => state.relatedProperties.selectedProperty + ); + + console.log("LeftPaneInfo", properties, selectedProperties); return ( - {polygons.length || markers.length || properties.length ? ( + {polygons.length || + markers.length || + properties.length || + selectedProperties.length > 0 ? ( <> {markers.map((marker, i) => ( @@ -25,6 +33,9 @@ const LeftPaneInfo = ({ onClose, open }) => { {properties.map((property, i) => ( ))} + {selectedProperties.map((property, i) => ( + + ))} ) : (
    { const handlePropertyClick = () => { onPropertyClick(); dispatch(showPropertyPolygon(property.geom.coordinates[0])); - dispatch(setSelectedProperty(property)); + dispatch(setSelectedProperty([property])); console.log("Selected Property", property); }; From d4ef63eacd0b3f6a7246aa9ca1a9afa793e47e81 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Tue, 28 Nov 2023 16:07:24 +0000 Subject: [PATCH 35/46] multiple properties selectable, selected properties display in info panel --- src/components/left-pane/LeftPaneInfo.js | 3 +- .../left-pane/LeftPaneRelatedProperties.js | 15 +- src/components/left-pane/PropertySection.js | 1 + src/components/left-pane/RelatedProperties.js | 14 +- .../left-pane/RelatedPropertySection.js | 191 ++++++++++++++++++ src/reducers/RelatedPropertiesReducer.js | 13 +- 6 files changed, 226 insertions(+), 11 deletions(-) create mode 100644 src/components/left-pane/RelatedPropertySection.js diff --git a/src/components/left-pane/LeftPaneInfo.js b/src/components/left-pane/LeftPaneInfo.js index 480d06a7..74d9288c 100644 --- a/src/components/left-pane/LeftPaneInfo.js +++ b/src/components/left-pane/LeftPaneInfo.js @@ -4,6 +4,7 @@ import LeftPaneTray from "./LeftPaneTray"; import MarkerSection from "./MarkerSection"; import PolygonSection from "./PolygonSection"; import PropertySection from "./PropertySection"; +import RelatedPropertySection from "./RelatedPropertySection"; const LeftPaneInfo = ({ onClose, open }) => { const markers = useSelector((state) => state.markers.markers); @@ -34,7 +35,7 @@ const LeftPaneInfo = ({ onClose, open }) => { ))} {selectedProperties.map((property, i) => ( - + ))} ) : ( diff --git a/src/components/left-pane/LeftPaneRelatedProperties.js b/src/components/left-pane/LeftPaneRelatedProperties.js index dec02c5c..758dbb2b 100644 --- a/src/components/left-pane/LeftPaneRelatedProperties.js +++ b/src/components/left-pane/LeftPaneRelatedProperties.js @@ -12,7 +12,9 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { // Set loading state const loading = useSelector((state) => state.relatedProperties.loading); - const [activeProperty, setActiveProperty] = useState(null); + // Move to nested component - to allow multiple properties to be selected + // const [activeProperty, setActiveProperty] = useState(null); + // Use a Set to store unique properties const uniqueProperties = new Set(); @@ -36,10 +38,11 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { indexOfLastProperty ); + // Remove this function and move to nested component // Pass down the active property to the RelatedProperties component - const handlePropertyClick = (property) => { - setActiveProperty(property); - }; + // const handlePropertyClick = (property) => { + // setActiveProperty(property); + // }; return ( @@ -65,8 +68,8 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { handlePropertyClick(property)} + // isActive={property === activeProperty} + // onPropertyClick={() => handlePropertyClick(property)} /> ))} {noOfPages > 1 && ( diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 366f6d90..d93ecacc 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -49,6 +49,7 @@ const PropertySection = ({ property, active }) => { dispatch({ type: "CLEAR_PROPERTIES_AND_PROPRIETOR_NAME" }); } }; + console.log("PropertySection", property, [title_no]); return (
    diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index 7bbe4ddb..61109d1a 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -1,19 +1,27 @@ import React, { useState } from "react"; import { useDispatch } from "react-redux"; -import { setSelectedProperty, showPropertyPolygon } from "../../actions/LandOwnershipActions"; +import { + setSelectedProperty, + showPropertyPolygon, +} from "../../actions/LandOwnershipActions"; import { setLngLat } from "../../actions/MapActions"; -const RelatedProperties = ({ property, isActive, onPropertyClick }) => { +const RelatedProperties = ({ property }) => { + // const RelatedProperties = ({ property, isActive, onPropertyClick }) => { const dispatch = useDispatch(); + const [active, setActive] = useState(false); const lng = property.geom.coordinates[0][0][1]; const lat = property.geom.coordinates[0][0][0]; const handlePropertyClick = () => { - onPropertyClick(); + // onPropertyClick(); + // dispatch(setLngLat(lng, lat)); dispatch(showPropertyPolygon(property.geom.coordinates[0])); dispatch(setSelectedProperty([property])); + setActive(!active); console.log("Selected Property", property); + console.log("Active", active); }; const gotoProperty = () => { diff --git a/src/components/left-pane/RelatedPropertySection.js b/src/components/left-pane/RelatedPropertySection.js new file mode 100644 index 00000000..092f6b6a --- /dev/null +++ b/src/components/left-pane/RelatedPropertySection.js @@ -0,0 +1,191 @@ +import React from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { setActiveProperty } from "../../actions/LandOwnershipActions"; +import Button from "../common/Button"; +import { getRelatedProperties } from "../../actions/LandOwnershipActions"; + +const RelatedPropertySection = ({ property, active }) => { + const dispatch = useDispatch(); + const activePropertyId = useSelector( + (state) => state.landOwnership.activePropertyId + ); + + const { + poly_id, + title_no, + proprietor_category_1, + property_address, + proprietor_name_1, + proprietor_1_address_1, + tenure, + date_proprietor_added, + } = property[0]; + + const open = poly_id === activePropertyId; + + const openTray = (tray) => { + active === tray + ? dispatch({ type: "CLOSE_TRAY" }) + : dispatch({ type: "SET_ACTIVE", payload: tray }); + }; + + const handleSearch = () => { + dispatch({ type: "CLEAR_PROPERTIES" }); + dispatch(getRelatedProperties(proprietor_name_1)); + openTray("Ownership Search"); + }; + + console.log("PropertySection", property[0]); + + return ( +
    +
    { + if (open) { + dispatch({ type: "CLEAR_ACTIVE_PROPERTY" }); + } else { + dispatch(setActiveProperty(poly_id)); + } + }} + > +

    + Related Property {poly_id} +

    +
    + +
    +
    + {open && ( +
    + {proprietor_category_1 && ( + <> +
    {property_address}
    +
    +
    + Proprietor Name: +
    +
    + {proprietor_name_1} +
    +
    +
    +
    + Proprietor Address: +
    +
    + {proprietor_1_address_1} +
    +
    +
    +
    +
    + Proprietor Category: +
    +
    + {proprietor_category_1} +
    +
    +
    +
    Tenure:
    +
    + {tenure} +
    +
    +
    +
    + Date Proprietor Added: +
    +
    + {date_proprietor_added} +
    +
    +
    + + )} +
    +
    +
    + INSPIRE ID: +
    +
    {poly_id}
    +
    +
    +
    + Title Number: +
    +
    {title_no}
    +
    +
    +

    + You can access these documents for a small fee by visiting the{" "} + + Land Registry website + {" "} + using the above IDs. +

    +
    +
    + +
    + +
    +
    + +
    +
    + )} +
    + ); +}; + +export default RelatedPropertySection; diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index e60e09c7..1fbc8919 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -7,6 +7,9 @@ const INITIAL_STATE = { selectedProperty: [], }; +let propertyToAdd; +let selectedProperty; + export default (state = INITIAL_STATE, action) => { switch (action.type) { case "FETCH_PROPERTIES_SUCCESS": @@ -52,9 +55,17 @@ export default (state = INITIAL_STATE, action) => { case "SET_ACTIVE_PROPERTY_ID": return INITIAL_STATE; case "SET_SELECTED_PROPERTY": + // propertyToAdd = action.payload; + // if (!state.selectedProperty.some((p) => p.poly_id === propertyToAdd.poly_id)) { + // selectedProperty = state.selectedProperty.concat([propertyToAdd]); + // } + // return { + // ...state, + // selectedProperty, + // }; return { ...state, - selectedProperty: action.payload, + selectedProperty: [...state.selectedProperty, action.payload], }; case "CLEAR_SELECTED_PROPERTY": return { From 3fae9b6aaa006a1e28494ecad4f6a68351d815f0 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Tue, 28 Nov 2023 16:08:01 +0000 Subject: [PATCH 36/46] additions to previous commit --- src/components/left-pane/PropertySection.js | 1 + src/components/left-pane/RelatedPropertySection.js | 2 +- src/reducers/RelatedPropertiesReducer.js | 11 ----------- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index d93ecacc..86e6b475 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -50,6 +50,7 @@ const PropertySection = ({ property, active }) => { } }; console.log("PropertySection", property, [title_no]); + console.log("PropertySection", property); return (
    diff --git a/src/components/left-pane/RelatedPropertySection.js b/src/components/left-pane/RelatedPropertySection.js index 092f6b6a..356b5dc3 100644 --- a/src/components/left-pane/RelatedPropertySection.js +++ b/src/components/left-pane/RelatedPropertySection.js @@ -35,7 +35,7 @@ const RelatedPropertySection = ({ property, active }) => { openTray("Ownership Search"); }; - console.log("PropertySection", property[0]); + console.log("RelatedPropertySection", property[0]); return (
    diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index 1fbc8919..0c5c03b0 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -7,9 +7,6 @@ const INITIAL_STATE = { selectedProperty: [], }; -let propertyToAdd; -let selectedProperty; - export default (state = INITIAL_STATE, action) => { switch (action.type) { case "FETCH_PROPERTIES_SUCCESS": @@ -55,14 +52,6 @@ export default (state = INITIAL_STATE, action) => { case "SET_ACTIVE_PROPERTY_ID": return INITIAL_STATE; case "SET_SELECTED_PROPERTY": - // propertyToAdd = action.payload; - // if (!state.selectedProperty.some((p) => p.poly_id === propertyToAdd.poly_id)) { - // selectedProperty = state.selectedProperty.concat([propertyToAdd]); - // } - // return { - // ...state, - // selectedProperty, - // }; return { ...state, selectedProperty: [...state.selectedProperty, action.payload], From cc1ccbc56cd3bb3b726745ba9cbdfcd8317bbe24 Mon Sep 17 00:00:00 2001 From: ms0ur1s Date: Tue, 28 Nov 2023 19:08:19 +0000 Subject: [PATCH 37/46] remove related cleared property from selectedProperties --- src/components/left-pane/PropertySection.js | 1 + src/components/left-pane/RelatedProperties.js | 7 ++++++- .../left-pane/RelatedPropertySection.js | 14 ++++++++++++++ src/reducers/RelatedPropertiesReducer.js | 17 +++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 86e6b475..505d6262 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -48,6 +48,7 @@ const PropertySection = ({ property, active }) => { if (property.proprietor_name_1 === proprietorName) { dispatch({ type: "CLEAR_PROPERTIES_AND_PROPRIETOR_NAME" }); } + console.log("handleClear Property", property); }; console.log("PropertySection", property, [title_no]); console.log("PropertySection", property); diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index 61109d1a..25a112b5 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { useDispatch } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import { setSelectedProperty, showPropertyPolygon, @@ -11,6 +11,10 @@ const RelatedProperties = ({ property }) => { const dispatch = useDispatch(); const [active, setActive] = useState(false); + const activePropertyId = useSelector( + (state) => state.landOwnership.activePropertyId + ); + const lng = property.geom.coordinates[0][0][1]; const lat = property.geom.coordinates[0][0][0]; @@ -22,6 +26,7 @@ const RelatedProperties = ({ property }) => { setActive(!active); console.log("Selected Property", property); console.log("Active", active); + console.log("Active Property Id", activePropertyId); }; const gotoProperty = () => { diff --git a/src/components/left-pane/RelatedPropertySection.js b/src/components/left-pane/RelatedPropertySection.js index 356b5dc3..220ca58d 100644 --- a/src/components/left-pane/RelatedPropertySection.js +++ b/src/components/left-pane/RelatedPropertySection.js @@ -36,6 +36,20 @@ const RelatedPropertySection = ({ property, active }) => { }; console.log("RelatedPropertySection", property[0]); + const handleClear = () => { + // dispatch({ type: "CLEAR_HIGHLIGHT", payload: property[0] }); + // Clear properties if the property being cleared is the searched property + // if (property.proprietor_name_1 === proprietorName) { + // dispatch({ type: "CLEAR_PROPERTIES_AND_PROPRIETOR_NAME" }); + // } + dispatch({ + type: "CLEAR_SELECTED_PROPERTY", + payload: activePropertyId, + }); + console.log("handleClear RelatedProperty", property[0]); + }; + + console.log("RelatedPropertySection", property[0], activePropertyId); return (
    diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index 0c5c03b0..73d21074 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -7,6 +7,9 @@ const INITIAL_STATE = { selectedProperty: [], }; +let propertyToClear; +let selectedProperty; + export default (state = INITIAL_STATE, action) => { switch (action.type) { case "FETCH_PROPERTIES_SUCCESS": @@ -33,6 +36,20 @@ export default (state = INITIAL_STATE, action) => { ...state, properties: [], }; + case "SET_SELECTED_PROPERTY": + return { + ...state, + selectedProperty: [...state.selectedProperty, action.payload], + }; + case "CLEAR_SELECTED_PROPERTY": + propertyToClear = action.payload; + selectedProperty = state.selectedProperty.filter( + (property) => property[0].poly_id !== propertyToClear + ); + return { + ...state, + selectedProperty, + }; case "SET_PROPRIETOR_NAME": return { ...state, From 00a9aea0f673ef4948b5e8f5282d23ad0546b127 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:31:39 +0000 Subject: [PATCH 38/46] add multiple property selection --- src/actions/LandOwnershipActions.js | 9 +++++ src/components/left-pane/LeftPaneInfo.js | 7 ++-- src/components/left-pane/PropertySection.js | 3 +- src/components/left-pane/RelatedProperties.js | 23 ++++++++--- .../left-pane/RelatedPropertySection.js | 2 - src/components/map/MapboxMap.js | 7 ++-- src/components/map/PropertySearchPoly.js | 38 ++++++------------- src/reducers/RelatedPropertiesReducer.js | 4 +- 8 files changed, 49 insertions(+), 44 deletions(-) diff --git a/src/actions/LandOwnershipActions.js b/src/actions/LandOwnershipActions.js index fb8a9d65..7b357af5 100644 --- a/src/actions/LandOwnershipActions.js +++ b/src/actions/LandOwnershipActions.js @@ -70,6 +70,15 @@ export const setSelectedProperty = (property) => { }; }; +export const clearSelectedProperty = (property) => { + return (dispatch) => { + dispatch({ + type: "CLEAR_SELECTED_PROPERTY", + payload: property + }) + } +} + export const showPropertyPolygon = (propertyCoordinates) => { return (dispatch) => { dispatch({ diff --git a/src/components/left-pane/LeftPaneInfo.js b/src/components/left-pane/LeftPaneInfo.js index 74d9288c..e59a2913 100644 --- a/src/components/left-pane/LeftPaneInfo.js +++ b/src/components/left-pane/LeftPaneInfo.js @@ -16,14 +16,13 @@ const LeftPaneInfo = ({ onClose, open }) => { (state) => state.relatedProperties.selectedProperty ); - console.log("LeftPaneInfo", properties, selectedProperties); return ( {polygons.length || - markers.length || - properties.length || - selectedProperties.length > 0 ? ( + markers.length || + properties.length || + selectedProperties.length > 0 ? ( <> {markers.map((marker, i) => ( diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 505d6262..167b57d9 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -50,8 +50,7 @@ const PropertySection = ({ property, active }) => { } console.log("handleClear Property", property); }; - console.log("PropertySection", property, [title_no]); - console.log("PropertySection", property); + return (
    diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index 25a112b5..060f23f0 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -3,6 +3,7 @@ import { useDispatch, useSelector } from "react-redux"; import { setSelectedProperty, showPropertyPolygon, + clearSelectedProperty } from "../../actions/LandOwnershipActions"; import { setLngLat } from "../../actions/MapActions"; @@ -14,6 +15,7 @@ const RelatedProperties = ({ property }) => { const activePropertyId = useSelector( (state) => state.landOwnership.activePropertyId ); + const { selectedProperty } = useSelector(state => state.relatedProperties); const lng = property.geom.coordinates[0][0][1]; const lat = property.geom.coordinates[0][0][0]; @@ -21,12 +23,23 @@ const RelatedProperties = ({ property }) => { const handlePropertyClick = () => { // onPropertyClick(); // dispatch(setLngLat(lng, lat)); - dispatch(showPropertyPolygon(property.geom.coordinates[0])); - dispatch(setSelectedProperty([property])); + //dispatch(showPropertyPolygon(property.geom.coordinates[0])); + console.log(property); + console.log(selectedProperty) + console.log(selectedProperty.find(item => item[0].id === property.id)) + + if (selectedProperty.find(item => item[0].id === property.id)) { + console.log("clearing the property"); + dispatch(clearSelectedProperty([property])); + } + else + dispatch(setSelectedProperty([property])); + setActive(!active); - console.log("Selected Property", property); - console.log("Active", active); - console.log("Active Property Id", activePropertyId); + + //console.log("Selected Property", property); + //console.log("Active", active); + //console.log("Active Property Id", activePropertyId); }; const gotoProperty = () => { diff --git a/src/components/left-pane/RelatedPropertySection.js b/src/components/left-pane/RelatedPropertySection.js index 220ca58d..ed1d9b0d 100644 --- a/src/components/left-pane/RelatedPropertySection.js +++ b/src/components/left-pane/RelatedPropertySection.js @@ -35,7 +35,6 @@ const RelatedPropertySection = ({ property, active }) => { openTray("Ownership Search"); }; - console.log("RelatedPropertySection", property[0]); const handleClear = () => { // dispatch({ type: "CLEAR_HIGHLIGHT", payload: property[0] }); // Clear properties if the property being cleared is the searched property @@ -49,7 +48,6 @@ const RelatedPropertySection = ({ property, active }) => { console.log("handleClear RelatedProperty", property[0]); }; - console.log("RelatedPropertySection", property[0], activePropertyId); return (
    diff --git a/src/components/map/MapboxMap.js b/src/components/map/MapboxMap.js index acc98869..de2ccf42 100644 --- a/src/components/map/MapboxMap.js +++ b/src/components/map/MapboxMap.js @@ -50,6 +50,7 @@ const MapboxMap = ({ user }) => { const propertyCoordinates = useSelector( (state) => state.propertySearchPoly.propertyCoordinates ); + const { selectedProperty } = useSelector(state => state.relatedProperties); // Check the propertyCoordinates update propagates to the MapboxMap component useEffect(() => { @@ -268,8 +269,8 @@ const MapboxMap = ({ user }) => { baseLayer === "aerial" ? "#091324" : constants.USE_OS_TILES - ? "#aadeef" - : "#72b6e6", + ? "#aadeef" + : "#72b6e6", }} zoom={zoom} onZoomEnd={(map) => dispatch(setZoom([map.getZoom()]))} @@ -299,7 +300,7 @@ const MapboxMap = ({ user }) => { }} /> {/* Property Search Poly / No clue where this should go */} - {propertyCoordinates.length > 0 && ( + {selectedProperty.length > 0 && ( )} {/*For displaying the property boundaries*/} diff --git a/src/components/map/PropertySearchPoly.js b/src/components/map/PropertySearchPoly.js index 724e4f0c..4eef57f0 100644 --- a/src/components/map/PropertySearchPoly.js +++ b/src/components/map/PropertySearchPoly.js @@ -5,44 +5,30 @@ import { setActiveProperty } from "../../actions/LandOwnershipActions"; const PropertySearchPoly = () => { const dispatch = useDispatch(); - const propertyCoordinates = useSelector( - (state) => state.propertySearchPoly.propertyCoordinates - ); - const property = useSelector( - (state) => state.relatedProperties.selectedProperty - ); - const coordinates = [ - propertyCoordinates.map((coord) => [coord[1], coord[0]]), - ]; + const { selectedProperty } = useSelector(state => state.relatedProperties) + + console.log("prop", selectedProperty) - const handlePolygonClick = () => { + const handlePolygonClick = (property) => { dispatch(setActiveProperty(property.poly_id)); console.log("Polygon clicked!", property.poly_id); }; - const polygonLayer = ( - - ); - useEffect(() => { - console.log( - "Property coordinates exist!", - propertyCoordinates, - property.poly_id - ); - console.log("Polygon Layer", polygonLayer); - }, [propertyCoordinates, property.poly_id]); + const polygonLayer = selectedProperty.map(property => [coord[1], coord[0]])]} + key={property[0].poly_id} + onClick={() => handlePolygonClick(property[0])} + />) // Check if propertyCoordinates exist before rendering GeoJSONLayer - if (!propertyCoordinates || propertyCoordinates.length === 0) { + if (!selectedProperty || selectedProperty.length === 0) { console.log("Property coordinates do not exist!"); return null; } + console.log(polygonLayer) + return ( <> { case "CLEAR_SELECTED_PROPERTY": propertyToClear = action.payload; selectedProperty = state.selectedProperty.filter( - (property) => property[0].poly_id !== propertyToClear + (property) => property[0].poly_id !== propertyToClear[0].poly_id ); return { ...state, @@ -73,7 +73,7 @@ export default (state = INITIAL_STATE, action) => { ...state, selectedProperty: [...state.selectedProperty, action.payload], }; - case "CLEAR_SELECTED_PROPERTY": + case "CLEAR_ALL_SELECTED_PROPERTY": return { ...state, selectedProperty: [], From 2442e7862d569f136361d9bf7b0c100826ad924b Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:41:12 +0000 Subject: [PATCH 39/46] remove console logs --- src/components/left-pane/RelatedProperties.js | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index 060f23f0..93c3c2a4 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -2,7 +2,6 @@ import React, { useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { setSelectedProperty, - showPropertyPolygon, clearSelectedProperty } from "../../actions/LandOwnershipActions"; import { setLngLat } from "../../actions/MapActions"; @@ -11,23 +10,12 @@ const RelatedProperties = ({ property }) => { // const RelatedProperties = ({ property, isActive, onPropertyClick }) => { const dispatch = useDispatch(); const [active, setActive] = useState(false); - - const activePropertyId = useSelector( - (state) => state.landOwnership.activePropertyId - ); const { selectedProperty } = useSelector(state => state.relatedProperties); const lng = property.geom.coordinates[0][0][1]; const lat = property.geom.coordinates[0][0][0]; const handlePropertyClick = () => { - // onPropertyClick(); - // dispatch(setLngLat(lng, lat)); - //dispatch(showPropertyPolygon(property.geom.coordinates[0])); - console.log(property); - console.log(selectedProperty) - console.log(selectedProperty.find(item => item[0].id === property.id)) - if (selectedProperty.find(item => item[0].id === property.id)) { console.log("clearing the property"); dispatch(clearSelectedProperty([property])); @@ -36,10 +24,6 @@ const RelatedProperties = ({ property }) => { dispatch(setSelectedProperty([property])); setActive(!active); - - //console.log("Selected Property", property); - //console.log("Active", active); - //console.log("Active Property Id", activePropertyId); }; const gotoProperty = () => { @@ -47,7 +31,7 @@ const RelatedProperties = ({ property }) => { } return
    From bd94515ba47fd10160470908a60bda43bfca5f92 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:42:46 +0000 Subject: [PATCH 40/46] remove comment --- src/components/left-pane/RelatedProperties.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index 93c3c2a4..878433ff 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -7,7 +7,6 @@ import { import { setLngLat } from "../../actions/MapActions"; const RelatedProperties = ({ property }) => { - // const RelatedProperties = ({ property, isActive, onPropertyClick }) => { const dispatch = useDispatch(); const [active, setActive] = useState(false); const { selectedProperty } = useSelector(state => state.relatedProperties); From 5c07a1a30a4539780ad4109141fc2a0ecfad5e94 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:50:15 +0000 Subject: [PATCH 41/46] move the arrow to just turning it on --- src/components/left-pane/RelatedProperties.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index 878433ff..178e435c 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -15,10 +15,10 @@ const RelatedProperties = ({ property }) => { const lat = property.geom.coordinates[0][0][0]; const handlePropertyClick = () => { - if (selectedProperty.find(item => item[0].id === property.id)) { - console.log("clearing the property"); + const propertyIsSelected = selectedProperty.find(item => item[0].id === property.id); + + if (propertyIsSelected) dispatch(clearSelectedProperty([property])); - } else dispatch(setSelectedProperty([property])); @@ -32,9 +32,8 @@ const RelatedProperties = ({ property }) => { return
    - + { /> -
    +

    {property.property_address}

    From 69ae95db1f00714a75aabeb41f5c8e7f5acd5b24 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:48:39 +0000 Subject: [PATCH 42/46] add clear all button --- src/actions/LandOwnershipActions.js | 16 ++++++++++++++++ src/assets/styles/_left-pane.scss | 11 +++++++++++ src/assets/styles/_variables.scss | 1 + src/components/left-pane/LeftPaneInfo.js | 12 +++++++++++- src/components/left-pane/RelatedProperties.js | 6 +++--- src/reducers/LandOwnershipReducer.js | 6 ++++++ src/reducers/RelatedPropertiesReducer.js | 5 +++++ 7 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/actions/LandOwnershipActions.js b/src/actions/LandOwnershipActions.js index 7b357af5..de940fe9 100644 --- a/src/actions/LandOwnershipActions.js +++ b/src/actions/LandOwnershipActions.js @@ -10,6 +10,14 @@ export const highlightProperty = (property) => { }; }; +export const clearAllHighlightedProperties = () => { + return (dispatch) => { + dispatch({ + type: "CLEAR_ALL_HIGHLIGHTED_PROPERTIES" + }) + } +} + export const setActiveProperty = (propertyId) => { return (dispatch) => { dispatch({ @@ -79,6 +87,14 @@ export const clearSelectedProperty = (property) => { } } +export const clearAllSelectedProperties = () => { + return (dispatch) => { + dispatch({ + type: "CLEAR_ALL_SELECTED_PROPERTIES" + }) + } +} + export const showPropertyPolygon = (propertyCoordinates) => { return (dispatch) => { dispatch({ diff --git a/src/assets/styles/_left-pane.scss b/src/assets/styles/_left-pane.scss index 99375429..e7ce2256 100644 --- a/src/assets/styles/_left-pane.scss +++ b/src/assets/styles/_left-pane.scss @@ -381,3 +381,14 @@ a.mapboxgl-ctrl-logo { width: 286px; } } + +.clear-all{ + text-decoration: underline; + margin: 10px 20px; + font-size: 14px; + color: $blueAccent; +} + +.clear-all:hover{ + cursor: pointer; +} \ No newline at end of file diff --git a/src/assets/styles/_variables.scss b/src/assets/styles/_variables.scss index f53ef19b..1d57ca3e 100644 --- a/src/assets/styles/_variables.scss +++ b/src/assets/styles/_variables.scss @@ -37,6 +37,7 @@ $iphone6plus_l: "(min-device-width: 414px) and (max-device-width: 736px) and (-w $primaryColor: #27ae60; $secondaryColor: #78838f; $buttonGreen: #2ecc71; +$blueAccent: #4a7abe; $toolbarBackground: #fbfbfb; $toolbarAccent: #e3e3e5; diff --git a/src/components/left-pane/LeftPaneInfo.js b/src/components/left-pane/LeftPaneInfo.js index e59a2913..a1436414 100644 --- a/src/components/left-pane/LeftPaneInfo.js +++ b/src/components/left-pane/LeftPaneInfo.js @@ -1,10 +1,11 @@ import React from "react"; -import { useSelector } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; import LeftPaneTray from "./LeftPaneTray"; import MarkerSection from "./MarkerSection"; import PolygonSection from "./PolygonSection"; import PropertySection from "./PropertySection"; import RelatedPropertySection from "./RelatedPropertySection"; +import { clearAllSelectedProperties, clearAllHighlightedProperties } from "../../actions/LandOwnershipActions"; const LeftPaneInfo = ({ onClose, open }) => { const markers = useSelector((state) => state.markers.markers); @@ -16,9 +17,18 @@ const LeftPaneInfo = ({ onClose, open }) => { (state) => state.relatedProperties.selectedProperty ); + const dispatch = useDispatch(); + + const clearAll = () => { + console.log("clearing all") + dispatch(clearAllSelectedProperties()); + dispatch(clearAllHighlightedProperties()); + console.log(selectedProperties) + } return ( + {(selectedProperties.length > 0 || properties.length > 0) &&

    Clear all properties

    } {polygons.length || markers.length || properties.length || diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index 178e435c..f6c8b5a3 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React from "react"; import { useDispatch, useSelector } from "react-redux"; import { setSelectedProperty, @@ -8,7 +8,6 @@ import { setLngLat } from "../../actions/MapActions"; const RelatedProperties = ({ property }) => { const dispatch = useDispatch(); - const [active, setActive] = useState(false); const { selectedProperty } = useSelector(state => state.relatedProperties); const lng = property.geom.coordinates[0][0][1]; @@ -22,13 +21,14 @@ const RelatedProperties = ({ property }) => { else dispatch(setSelectedProperty([property])); - setActive(!active); }; const gotoProperty = () => { dispatch(setLngLat(lng, lat)); } + const active = selectedProperty.find(item => item[0].id === property.id); + return
    { highlightedProperties, activePropertyId: null }; + case "CLEAR_ALL_HIGHLIGHTED_PROPERTIES": + return { + ...state, + highlightedProperties: [], + activePropertyId: null + } case "SET_ACTIVE_PROPERTY": return { ...state, diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index 39740aa2..798904eb 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -50,6 +50,11 @@ export default (state = INITIAL_STATE, action) => { ...state, selectedProperty, }; + case "CLEAR_ALL_SELECTED_PROPERTIES": + return { + ...state, + selectedProperty: [] + } case "SET_PROPRIETOR_NAME": return { ...state, From e13384d4fe27d03ee50130f26e704ad847c8ee97 Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:44:29 +0000 Subject: [PATCH 43/46] add the new svg icons --- src/assets/img/icon-arrow-green.svg | 3 +++ src/assets/img/icon-arrow-grey.svg | 3 +++ src/assets/styles/_ownership-search.scss | 7 ++++++- src/components/left-pane/RelatedProperties.js | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 src/assets/img/icon-arrow-green.svg create mode 100644 src/assets/img/icon-arrow-grey.svg diff --git a/src/assets/img/icon-arrow-green.svg b/src/assets/img/icon-arrow-green.svg new file mode 100644 index 00000000..046bb5fc --- /dev/null +++ b/src/assets/img/icon-arrow-green.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/img/icon-arrow-grey.svg b/src/assets/img/icon-arrow-grey.svg new file mode 100644 index 00000000..e3323a6d --- /dev/null +++ b/src/assets/img/icon-arrow-grey.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/assets/styles/_ownership-search.scss b/src/assets/styles/_ownership-search.scss index cf809eea..efe85aa2 100644 --- a/src/assets/styles/_ownership-search.scss +++ b/src/assets/styles/_ownership-search.scss @@ -21,6 +21,7 @@ margin-bottom: 20px; padding: 0 20px; display: flex; + align-items: flex-start; cursor: pointer; & > i { width: 18px; @@ -45,11 +46,15 @@ } .search-result__property { - margin: 0 0 5px 10px; + margin: 0 10px 5px 10px; padding: 0; flex-grow: 1; } +.search-result__goto-icon{ + width: 25px; +} + .search-result__goto-icon:hover{ cursor: pointer; } diff --git a/src/components/left-pane/RelatedProperties.js b/src/components/left-pane/RelatedProperties.js index f6c8b5a3..e4c26438 100644 --- a/src/components/left-pane/RelatedProperties.js +++ b/src/components/left-pane/RelatedProperties.js @@ -54,7 +54,7 @@ const RelatedProperties = ({ property }) => {
    move map to property icon Date: Wed, 29 Nov 2023 17:59:04 +0000 Subject: [PATCH 44/46] add select all and clear all --- src/actions/LandOwnershipActions.js | 9 ++++++++ src/assets/styles/_ownership-search.scss | 1 - src/components/left-pane/LeftPaneInfo.js | 2 -- .../left-pane/LeftPaneRelatedProperties.js | 22 ++++++++++++------- src/reducers/RelatedPropertiesReducer.js | 7 ++++++ 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/actions/LandOwnershipActions.js b/src/actions/LandOwnershipActions.js index de940fe9..2857642c 100644 --- a/src/actions/LandOwnershipActions.js +++ b/src/actions/LandOwnershipActions.js @@ -87,6 +87,15 @@ export const clearSelectedProperty = (property) => { } } +export const setMultipleSelectedProperties = (properties) => { + return (dispatch) => { + dispatch({ + type: "SET_MULTIPLE_SELECTED_PROPERTIES", + payload: properties, + }); + }; +} + export const clearAllSelectedProperties = () => { return (dispatch) => { dispatch({ diff --git a/src/assets/styles/_ownership-search.scss b/src/assets/styles/_ownership-search.scss index efe85aa2..6c1915e0 100644 --- a/src/assets/styles/_ownership-search.scss +++ b/src/assets/styles/_ownership-search.scss @@ -6,7 +6,6 @@ .property-count { font-size: 13px; - margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #eeeeee; padding: 20px; diff --git a/src/components/left-pane/LeftPaneInfo.js b/src/components/left-pane/LeftPaneInfo.js index a1436414..f5722e1c 100644 --- a/src/components/left-pane/LeftPaneInfo.js +++ b/src/components/left-pane/LeftPaneInfo.js @@ -20,10 +20,8 @@ const LeftPaneInfo = ({ onClose, open }) => { const dispatch = useDispatch(); const clearAll = () => { - console.log("clearing all") dispatch(clearAllSelectedProperties()); dispatch(clearAllHighlightedProperties()); - console.log(selectedProperties) } return ( diff --git a/src/components/left-pane/LeftPaneRelatedProperties.js b/src/components/left-pane/LeftPaneRelatedProperties.js index 758dbb2b..6b581ebc 100644 --- a/src/components/left-pane/LeftPaneRelatedProperties.js +++ b/src/components/left-pane/LeftPaneRelatedProperties.js @@ -1,13 +1,15 @@ import React, { useState } from "react"; import LeftPaneTray from "./LeftPaneTray"; -import { useSelector } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; import RelatedProperties from "./RelatedProperties"; import Pagination from "../common/Pagination"; +import { clearAllSelectedProperties, setMultipleSelectedProperties } from "../../actions/LandOwnershipActions"; const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { const otherProperties = useSelector( (state) => state.relatedProperties.properties ); + const dispatch = useDispatch(); // Set loading state const loading = useSelector((state) => state.relatedProperties.loading); @@ -38,11 +40,13 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { indexOfLastProperty ); - // Remove this function and move to nested component - // Pass down the active property to the RelatedProperties component - // const handlePropertyClick = (property) => { - // setActiveProperty(property); - // }; + const selectAll = () => { + console.log(otherProperties) + dispatch(setMultipleSelectedProperties(otherProperties.map(property => [property]))) + } + const clearAll = () => { + dispatch(clearAllSelectedProperties()); + } return ( @@ -64,12 +68,14 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { {propertyCount}{" "} associated properties
    +

    Select all

    +

    Clear all

    {currentProperties.map((property, i) => ( handlePropertyClick(property)} + // isActive={property === activeProperty} + // onPropertyClick={() => handlePropertyClick(property)} /> ))} {noOfPages > 1 && ( diff --git a/src/reducers/RelatedPropertiesReducer.js b/src/reducers/RelatedPropertiesReducer.js index 798904eb..212e9d0c 100644 --- a/src/reducers/RelatedPropertiesReducer.js +++ b/src/reducers/RelatedPropertiesReducer.js @@ -41,6 +41,13 @@ export default (state = INITIAL_STATE, action) => { ...state, selectedProperty: [...state.selectedProperty, action.payload], }; + case "SET_MULTIPLE_SELECTED_PROPERTIES": + console.log(action.payload) + console.log(state.selectedProperty) + return { + ...state, + selectedProperty: [...state.selectedProperty, ...action.payload] + } case "CLEAR_SELECTED_PROPERTY": propertyToClear = action.payload; selectedProperty = state.selectedProperty.filter( From 895d02f6c792507bdb5a4fe50c740da7b800280e Mon Sep 17 00:00:00 2001 From: John Evans <38507954+King-Mob@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:47:18 +0000 Subject: [PATCH 45/46] comment out select all --- src/components/left-pane/LeftPaneRelatedProperties.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/left-pane/LeftPaneRelatedProperties.js b/src/components/left-pane/LeftPaneRelatedProperties.js index 6b581ebc..31d7fc65 100644 --- a/src/components/left-pane/LeftPaneRelatedProperties.js +++ b/src/components/left-pane/LeftPaneRelatedProperties.js @@ -41,7 +41,6 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { ); const selectAll = () => { - console.log(otherProperties) dispatch(setMultipleSelectedProperties(otherProperties.map(property => [property]))) } const clearAll = () => { @@ -68,7 +67,7 @@ const LeftPaneRelatedProperties = ({ onClose, open, itemsPerPage }) => { {propertyCount}{" "} associated properties
    -

    Select all

    + {/*

    Select all

    */}

    Clear all

    {currentProperties.map((property, i) => ( Date: Thu, 30 Nov 2023 09:54:51 +0000 Subject: [PATCH 46/46] add a check on ownership --- src/components/left-pane/PropertySection.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/components/left-pane/PropertySection.js b/src/components/left-pane/PropertySection.js index 167b57d9..977277e8 100644 --- a/src/components/left-pane/PropertySection.js +++ b/src/components/left-pane/PropertySection.js @@ -179,15 +179,16 @@ const PropertySection = ({ property, active }) => {
    -
    - -
    + {proprietor_category_1 && +
    + +
    }