From 9e2545da7b09a5c7b168af7ed99c662fa429525a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A2u=20Cao?=
Date: Sun, 12 Apr 2026 15:42:36 +0400
Subject: [PATCH 1/4] Add mobile phone numbers
---
app/components/place-details.gjs | 24 +++++++++----
.../components/place-details-test.gjs | 36 +++++++++++++++++++
2 files changed, 54 insertions(+), 6 deletions(-)
diff --git a/app/components/place-details.gjs b/app/components/place-details.gjs
index 2f27201..b3b362a 100644
--- a/app/components/place-details.gjs
+++ b/app/components/place-details.gjs
@@ -130,10 +130,14 @@ export default class PlaceDetails extends Component {
formatMultiLine(val, type) {
if (!val) return null;
- const parts = val
- .split(';')
- .map((s) => s.trim())
- .filter(Boolean);
+ const parts = [
+ ...new Set(
+ val
+ .split(';')
+ .map((s) => s.trim())
+ .filter(Boolean)
+ ),
+ ];
if (parts.length === 0) return null;
if (type === 'phone') {
@@ -165,8 +169,16 @@ export default class PlaceDetails extends Component {
}
get phone() {
- const val = this.tags.phone || this.tags['contact:phone'];
- return this.formatMultiLine(val, 'phone');
+ const rawValues = [
+ this.tags.phone,
+ this.tags['contact:phone'],
+ this.tags.mobile,
+ this.tags['contact:mobile'],
+ ].filter(Boolean);
+
+ if (rawValues.length === 0) return null;
+
+ return this.formatMultiLine(rawValues.join(';'), 'phone');
}
get email() {
diff --git a/tests/integration/components/place-details-test.gjs b/tests/integration/components/place-details-test.gjs
index d2d50a3..4956952 100644
--- a/tests/integration/components/place-details-test.gjs
+++ b/tests/integration/components/place-details-test.gjs
@@ -255,4 +255,40 @@ module('Integration | Component | place-details', function (hooks) {
assert.dom('.actions button').hasText('Save');
assert.dom('.actions button').doesNotHaveClass('btn-secondary');
});
+
+ test('it aggregates phone and mobile tags without duplicates', async function (assert) {
+ const place = {
+ title: 'Phone Shop',
+ osmTags: {
+ phone: '+1 234 567 8900',
+ 'contact:phone': '+1 234 567 8900; +1 000 000 0000',
+ mobile: '+1 987 654 3210',
+ 'contact:mobile': '+1 987 654 3210',
+ },
+ };
+
+ await render();
+
+ // Use specific selector for the phone block since there's no cuisine or opening_hours
+ const metaInfos = Array.from(
+ this.element.querySelectorAll('.meta-info .content-with-icon')
+ );
+ const phoneBlock = metaInfos.find((el) => {
+ const iconSpan = el.querySelector('span.icon[title="Phone"]');
+ return !!iconSpan;
+ });
+
+ assert.ok(phoneBlock, 'Phone block is rendered');
+
+ const links = phoneBlock.querySelectorAll('a[href^="tel:"]');
+ assert.strictEqual(
+ links.length,
+ 3,
+ 'Rendered exactly 3 unique phone links'
+ );
+
+ assert.dom(links[0]).hasText('+1 234 567 8900');
+ assert.dom(links[1]).hasText('+1 000 000 0000');
+ assert.dom(links[2]).hasText('+1 987 654 3210');
+ });
});
From ad3e6ea402d9a2a1a48a0280d1feeab00adeae0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A2u=20Cao?=
Date: Sun, 12 Apr 2026 15:47:22 +0400
Subject: [PATCH 2/4] Remove spaces and dashes from tel links
---
app/components/place-details.gjs | 5 ++++-
app/icons/whatsapp.svg | 4 ++++
tests/integration/components/place-details-test.gjs | 10 +++++++---
3 files changed, 15 insertions(+), 4 deletions(-)
create mode 100644 app/icons/whatsapp.svg
diff --git a/app/components/place-details.gjs b/app/components/place-details.gjs
index b3b362a..26794f0 100644
--- a/app/components/place-details.gjs
+++ b/app/components/place-details.gjs
@@ -142,7 +142,10 @@ export default class PlaceDetails extends Component {
if (type === 'phone') {
return htmlSafe(
- parts.map((p) => `${p}`).join('
')
+ parts.map((p) => {
+ const safeTel = p.replace(/[\s-]+/g, '');
+ return `${p}`;
+ }).join('
')
);
}
diff --git a/app/icons/whatsapp.svg b/app/icons/whatsapp.svg
new file mode 100644
index 0000000..85109bf
--- /dev/null
+++ b/app/icons/whatsapp.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/tests/integration/components/place-details-test.gjs b/tests/integration/components/place-details-test.gjs
index 4956952..9cefb7e 100644
--- a/tests/integration/components/place-details-test.gjs
+++ b/tests/integration/components/place-details-test.gjs
@@ -260,8 +260,8 @@ module('Integration | Component | place-details', function (hooks) {
const place = {
title: 'Phone Shop',
osmTags: {
- phone: '+1 234 567 8900',
- 'contact:phone': '+1 234 567 8900; +1 000 000 0000',
+ phone: '+1-234-567-8900',
+ 'contact:phone': '+1-234-567-8900; +1 000 000 0000',
mobile: '+1 987 654 3210',
'contact:mobile': '+1 987 654 3210',
},
@@ -287,7 +287,11 @@ module('Integration | Component | place-details', function (hooks) {
'Rendered exactly 3 unique phone links'
);
- assert.dom(links[0]).hasText('+1 234 567 8900');
+ assert.strictEqual(links[0].getAttribute('href'), 'tel:+12345678900');
+ assert.strictEqual(links[1].getAttribute('href'), 'tel:+10000000000');
+ assert.strictEqual(links[2].getAttribute('href'), 'tel:+19876543210');
+
+ assert.dom(links[0]).hasText('+1-234-567-8900');
assert.dom(links[1]).hasText('+1 000 000 0000');
assert.dom(links[2]).hasText('+1 987 654 3210');
});
From 344a3067fade77c0b848456b3bbb3fd580ba26ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A2u=20Cao?=
Date: Sun, 12 Apr 2026 16:06:02 +0400
Subject: [PATCH 3/4] Add WhatsApp numbers/links
---
app/components/place-details.gjs | 29 +++++++++++++++
app/icons/whatsapp.svg | 4 +-
app/utils/icons.js | 3 ++
.../components/place-details-test.gjs | 37 +++++++++++++++++++
4 files changed, 71 insertions(+), 2 deletions(-)
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 @@
-