diff --git a/app/components/place-details.gjs b/app/components/place-details.gjs index 26794f0..664a8fc 100644 --- a/app/components/place-details.gjs +++ b/app/components/place-details.gjs @@ -155,6 +155,15 @@ export default class PlaceDetails extends Component { ); } + if (type === 'whatsapp') { + return htmlSafe( + parts.map((p) => { + const safeTel = p.replace(/[\s-]+/g, ''); + return `${p}`; + }).join('
') + ); + } + if (type === 'url') { return htmlSafe( parts @@ -184,6 +193,17 @@ export default class PlaceDetails extends Component { return this.formatMultiLine(rawValues.join(';'), 'phone'); } + get whatsapp() { + const rawValues = [ + this.tags.whatsapp, + this.tags['contact:whatsapp'], + ].filter(Boolean); + + if (rawValues.length === 0) return null; + + return this.formatMultiLine(rawValues.join(';'), 'whatsapp'); + } + get email() { const val = this.tags.email || this.tags['contact:email']; return this.formatMultiLine(val, 'email'); @@ -358,6 +378,15 @@ export default class PlaceDetails extends Component {

{{/if}} + {{#if this.whatsapp}} +

+ + + {{this.whatsapp}} + +

+ {{/if}} + {{#if this.website}}

diff --git a/app/icons/whatsapp.svg b/app/icons/whatsapp.svg index 85109bf..1e0b1b5 100644 --- a/app/icons/whatsapp.svg +++ b/app/icons/whatsapp.svg @@ -1,4 +1,4 @@ - - + + diff --git a/app/utils/icons.js b/app/utils/icons.js index 2168d15..78348fe 100644 --- a/app/utils/icons.js +++ b/app/utils/icons.js @@ -110,6 +110,7 @@ import womensAndMensRestroomSymbol from '@waysidemapping/pinhead/dist/icons/wome import loadingRing from '../icons/270-ring.svg?raw'; import nostrich from '../icons/nostrich-2.svg?raw'; import remotestorage from '../icons/remotestorage.svg?raw'; +import whatsapp from '../icons/whatsapp.svg?raw'; import wikipedia from '../icons/wikipedia.svg?raw'; const ICONS = { @@ -218,6 +219,7 @@ const ICONS = { 'village-buildings': villageBuildings, 'wall-hanging-with-mountains-and-sun': wallHangingWithMountainsAndSun, 'womens-and-mens-restroom-symbol': womensAndMensRestroomSymbol, + whatsapp, wikipedia, parking_p: parkingP, car, @@ -229,6 +231,7 @@ const ICONS = { const FILLED_ICONS = [ 'fork-and-knife', 'wikipedia', + 'whatsapp', 'cup-and-saucer', 'coffee-bean', 'shopping-basket', diff --git a/tests/integration/components/place-details-test.gjs b/tests/integration/components/place-details-test.gjs index 9cefb7e..c7abab0 100644 --- a/tests/integration/components/place-details-test.gjs +++ b/tests/integration/components/place-details-test.gjs @@ -295,4 +295,41 @@ module('Integration | Component | place-details', function (hooks) { assert.dom(links[1]).hasText('+1 000 000 0000'); assert.dom(links[2]).hasText('+1 987 654 3210'); }); + + test('it formats whatsapp tags into wa.me links', async function (assert) { + const place = { + title: 'Chat Shop', + osmTags: { + 'contact:whatsapp': '+1 234-567 8900', + whatsapp: '+44 987 654 321', // Also tests multiple values + }, + }; + + await render(); + + const metaInfos = Array.from( + this.element.querySelectorAll('.meta-info .content-with-icon') + ); + const whatsappBlock = metaInfos.find((el) => { + const iconSpan = el.querySelector('span.icon[title="WhatsApp"]'); + return !!iconSpan; + }); + + assert.ok(whatsappBlock, 'WhatsApp block is rendered'); + + const links = whatsappBlock.querySelectorAll('a[href^="https://wa.me/"]'); + assert.strictEqual( + links.length, + 2, + 'Rendered exactly 2 WhatsApp links' + ); + + // Verify it stripped the dashes and spaces for the wa.me URL + assert.strictEqual(links[0].getAttribute('href'), 'https://wa.me/+44987654321'); + assert.strictEqual(links[1].getAttribute('href'), 'https://wa.me/+12345678900'); + + // Verify it kept the dashes and spaces for the visible text + assert.dom(links[0]).hasText('+44 987 654 321'); + assert.dom(links[1]).hasText('+1 234-567 8900'); + }); });