Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/hlxsites/hsf-commonmoves in…
Browse files Browse the repository at this point in the history
…to feature/savedprops
  • Loading branch information
kailasnadh790 committed May 23, 2024
2 parents 3b8441b + 47a33b1 commit c61914b
Show file tree
Hide file tree
Showing 9 changed files with 396 additions and 9 deletions.
176 changes: 176 additions & 0 deletions blocks/economic-data/economic-data.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
.economic-data.block {
margin: 0;
padding: 20px;
box-sizing: border-box;
}

.economic-data .accordion-header {
border-top: 1px solid var(--grey);
cursor: pointer;
padding: 16px 30px 16px 0;
position: relative;
display: inline-block;
font-family: var(--font-family-georgia);
font-weight: var(--font-weight-semibold);
line-height: 26px;
margin: 0 5px 0 0;
font-size: 22px;
width: 100%;
}

.economic-data .accordion .accordion-header::after {
border-color: var(--body-color) transparent transparent transparent;
border-style: solid;
border-width: 6px 5px 0;
content: '';
margin-top: -5px;
position: absolute;
right: 8px;
top: 50%;
transition: transform .3s linear;
transform: rotate(0);
}

.economic-data .accordion .accordion-header:not(.active)::after {
transform: rotate(90deg);
transition: transform .3s linear;
}

.economic-data .accordion-content {
display: none;
padding-bottom: 60px;
}

.economic-data .accordion-header.active + .accordion-content {
display: block;
}

.economic-data .container {
display: flex;
flex-direction: column;
}

.economic-data .row {
display: flex;
flex-wrap: wrap;
border-bottom: 1px solid #ccc;
padding: 10px 0;
}

.economic-data.block .accordion-content .row:last-child {
border-bottom: none;
}

.economic-data .cell {
padding: 10px 10px 10px 0;
box-sizing: border-box;
}

.economic-data .cell-header {
font-weight: bold;
text-transform: uppercase;
font-size: var(--body-font-size-xs);
line-height: var(--line-height-xs);
letter-spacing: var(--letter-spacing-xs);
}

.economic-data .cell-1 {
width: 100%;
text-transform: uppercase;
font-size: 14px;
}

.economic-data .cell-1.cell-header {
padding: 0;
}

.economic-data .cell-2, .economic-data .cell-3, .economic-data .cell-4 {
width: 33.33%;
}

.economic-data .progress-bar {
width: calc(100% - 60px);
background-color: #f3f3f3;
height: 5px;
margin-left: 50px;
margin-top: -12px;
position: relative;
}

.economic-data .progress-owner, .progress-renter {
height: 100%;
position: absolute;
top: 0;
}

.economic-data .progress-owner {
background-color: var(--primary-color);
left: 0;
}

.economic-data .progress-renter {
background-color: var(--light-grey);
right: 0;
}

.economic-data .tooltip {
position: relative;
display: inline-block;
height: 19px;
width: 19px;
margin-left: 5px;
}

.economic-data .tooltip .icon-info-circle-dark {
display: none;
}

.economic-data .tooltip .tooltiptext {
visibility: hidden;
width: 290px;
background-color: var(--black);
color: var(--white);
text-align: left;
padding: 14px 18px;
position: absolute;
z-index: 1;
top: 100%;
left: 0;
margin: 12px 0 0 -10px;
font-family: var(--font-family-proxima);
font-size: var(--body-font-size-s);
letter-spacing: var(--letter-spacing-s);
line-height: var(--line-height-s);
}

.economic-data .tooltip:hover .icon-info-circle {
display: none;
}

.economic-data .tooltip:hover .icon-info-circle-dark {
display: block;
}

.economic-data .tooltip:hover .tooltiptext {
visibility: visible;
}

.economic-data .tooltip .tooltiptext::before {
content: '';
position: absolute;
bottom: 100%;
left: 8px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent var(--black) transparent;
}

@media (min-width: 900px) {
.economic-data .cell-1 {
width: 25%;
}

.economic-data .cell-2, .economic-data .cell-3, .economic-data .cell-4 {
width: 25%;
}
}
174 changes: 174 additions & 0 deletions blocks/economic-data/economic-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { getDetails, getEconomicDetails } from '../../scripts/apis/creg/creg.js';
import { div, span } from '../../scripts/dom-helpers.js';
import { decorateIcons } from '../../scripts/aem.js';

const keys = [
'ListPriceUS',
'StreetName',
'City',
'StateOrProvince',
'PostalCode',
'Latitude',
'Longitude',
'LotSizeAcres',
'LotSizeSquareFeet',
'LivingAreaUnits',
'Media',
'SmallMedia',
'PropId',
'OpenHouses',
'CourtesyOf',
];

function pick(obj, ...args) {
return args.reduce((res, key) => ({ ...res, [key]: obj[key] }), { });
}

function toggleAccordion(event) {
const content = event.target;
content.classList.toggle('active');
}

/**
* Retrieves the property ID from the current URL path.
* @returns {string|null} The property ID if found in the URL path, or null if not found.
*/
function getPropIdFromPath() {
const url = window.location.pathname;
const match = url.match(/pid-(\d+)/);
if (match && match[1]) {
return match[1];
}
return null;
}

async function getPropertyByPropId(propId) {
const resp = await getDetails(propId);
return resp[0];
}

async function getSocioEconomicData(latitude, longitude) {
const resp = await getEconomicDetails(latitude, longitude);
return resp[0];
}

function getHeaderLabels(title) {
switch (title.toLowerCase()) {
case 'occupancy':
return 'Occupancy';
case 'housing trends':
return 'Housing Trends';
case 'economic data':
return 'Economic Data';
default:
return 'Untitled';
}
}

function getColumnHeader(title, index) {
switch (title.toLowerCase()) {
case 'occupancy':
return ['Owned', 'Rented', 'Vacant'][index - 1];
case 'housing trends':
return ['Home Appreciation', 'Median Age'][index - 1];
case 'economic data':
return ['Median House. Income', 'Unemployment', 'Cost of Living Index'][index - 1];
default:
return '';
}
}

function getDataValue(item, title, index) {
switch (title.toLowerCase()) {
case 'occupancy':
if (index === 1) {
return `${item.ownerOccupiedPercent}%`;
}
if (index === 2) {
return `${item.renterOccupiedPercent}%`;
}
return `${item.vacancyPercent}%`;
case 'housing trends':
if (index === 1) {
return `${item.homeValueAppreciationPercent}%`;
}
return `${item.medianHomeAge}`;
case 'economic data':
if (index === 1) {
return `${item.medianIncome}`;
}
return `${item.unemploymentPercent}%`;
default:
return '';
}
}

function generateDataTable(block, title, socioEconData) {
// Create the accordion structure
const accordion = div({ class: 'accordion' },
div({ class: 'accordion-header', onclick: (e) => toggleAccordion(e) }, getHeaderLabels(title), div({ class: 'tooltip' },
span({ class: 'icon icon-info-circle' }),
span({ class: 'icon icon-info-circle-dark' }),
span({ class: 'tooltiptext' }, `${socioEconData.citation}`),
),
),
div({ class: 'accordion-content' },
div({ id: `${title.toLowerCase().replace(' ', '-')}-data-container`, class: 'container', role: 'grid' }),
),
);
block.appendChild(accordion);

const container = document.getElementById(`${title.toLowerCase().replace(' ', '-')}-data-container`);

// Create header row
const headerRow = div({ class: 'row', role: 'row' },
div({ class: 'cell cell-1 cell-header', role: 'columnheader' }),
div({ class: 'cell cell-2 cell-header', role: 'columnheader' }, getColumnHeader(title, 1)),
div({ class: 'cell cell-3 cell-header', role: 'columnheader' }, getColumnHeader(title, 2)),
div({ class: 'cell cell-4 cell-header', role: 'columnheader' }, getColumnHeader(title, 3) ? getColumnHeader(title, 3) : ''),
);
container.appendChild(headerRow);

// Create data rows
socioEconData.data.forEach((item) => {
const dataRow = div({ class: 'row', role: 'row' },
div({ class: 'cell cell-1', role: 'cell' },
div({ role: 'presentation' }, `${item.level.charAt(0).toUpperCase() + item.level.slice(1)}: ${item.label}`),
),
div({ class: 'cell cell-2', role: 'cell' },
getDataValue(item, title, 1),
title.toLowerCase() === 'occupancy'
? div({ class: 'progress-bar' },
span({ class: 'progress-owner', style: `width: ${item.ownerOccupiedPercent}%` }),
span({ class: 'progress-renter', style: `width: ${100 - item.ownerOccupiedPercent}%` }),
) : '',
),
div({ class: 'cell cell-3', role: 'cell' }, getDataValue(item, title, 2)),
div({ class: 'cell cell-4', role: 'cell' }, title.toLowerCase() === 'housing trends' ? '' : getDataValue(item, title, 3)),
);

container.appendChild(dataRow);
});
}

export default async function decorate(block) {
let property = {};
let propId = getPropIdFromPath(); // assumes the listing page pathname ends with the propId
// TODO: remove this test propId
if (!propId) propId = '370882966';

const propertyData = await getPropertyByPropId(propId);
if (propertyData) {
property = pick(propertyData, ...keys);
if (property.Latitude && property.Longitude) {
const socioEconData = await getSocioEconomicData(property.Latitude, property.Longitude);
if (socioEconData) {
generateDataTable(block, 'Occupancy', socioEconData);
generateDataTable(block, 'Housing Trends', socioEconData);
generateDataTable(block, 'Economic Data', socioEconData);
}
}
}
decorateIcons(block);
window.property = property;
}
12 changes: 5 additions & 7 deletions blocks/hero/hero.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,15 @@ function rotateImage(images) {

export default async function decorate(block) {
// check if it has a video
const video = block.querySelector('a[href*=".mp4"]');
const videoWrapper = video && video.closest('div');
videoWrapper.classList.add('video-wrapper');
const videoLink = videoWrapper?.firstElementChild;
// transform link into a video tag
const videoLink = block.querySelector('a[href*=".mp4"]');
let videoWrapper;
if (videoLink) {
const parent = videoLink.parentElement;
videoWrapper = document.createElement('div');
videoWrapper.classList.add('video-wrapper');
const videoHref = videoLink.href;
videoLink.remove();
setTimeout(() => {
decorateVideo(parent, videoHref);
decorateVideo(videoWrapper, videoHref);
}, 3000);
}

Expand Down
2 changes: 1 addition & 1 deletion blocks/info-mouseover/info-mouseover.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default async function decorate(block) {
const heading = block.closest('.section').querySelector('h1,h2,h3,h4,h5,h6');

const icon = document.createElement('span');
icon.classList.add('icon', 'icon-info_circle');
icon.classList.add('icon', 'icon-info-circle');

positionIcon(heading, icon);
block.append(icon);
Expand Down
2 changes: 1 addition & 1 deletion blocks/profile/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ function showNotification(type, iconHtml, message, message2) {
}

function showError(err) {
showNotification('error', '<img src="/icons/info_circle.svg" aria-hidden="true" alt="Error" class="info-circle">', i18n('There was a problem processing your request.'), i18n(err));
showNotification('error', '<img src="/icons/info-circle.svg" aria-hidden="true" alt="Error" class="info-circle">', i18n('There was a problem processing your request.'), i18n(err));
}

function showSuccess(message) {
Expand Down
Loading

0 comments on commit c61914b

Please sign in to comment.