Improve place details with icons

This commit is contained in:
Râu Cao 2026-01-21 16:10:22 +07:00
parent 3fcaa0bfa2
commit 01c3b5a1ac
Signed by: raucao
GPG Key ID: 37036C356E56CC51
3 changed files with 114 additions and 23 deletions

54
app/components/icon.gjs Normal file
View File

@ -0,0 +1,54 @@
import Component from '@glimmer/component';
import { htmlSafe } from '@ember/template';
import clock from 'feather-icons/dist/icons/clock.svg?raw';
import globe from 'feather-icons/dist/icons/globe.svg?raw';
import home from 'feather-icons/dist/icons/home.svg?raw';
import map from 'feather-icons/dist/icons/map.svg?raw';
import mapPin from 'feather-icons/dist/icons/map-pin.svg?raw';
import navigation from 'feather-icons/dist/icons/navigation.svg?raw';
import phone from 'feather-icons/dist/icons/phone.svg?raw';
import user from 'feather-icons/dist/icons/user.svg?raw';
import settings from 'feather-icons/dist/icons/settings.svg?raw';
const ICONS = {
clock,
globe,
home,
map,
mapPin,
navigation,
phone,
user,
settings
};
export default class IconComponent extends Component {
get svg() {
return ICONS[this.args.name];
}
get size() {
return this.args.size || 16;
}
get color() {
return this.args.color || '#888';
}
get style() {
return `width:${this.size}px;height:${this.size}px;color:${this.color}`;
}
get title() {
return this.args.title || '';
}
<template>
{{#if this.svg}}
<span class="icon" style={{this.style}} title={{this.title}}>
{{htmlSafe this.svg}}
</span>
{{/if}}
</template>
}

View File

@ -2,6 +2,7 @@ import Component from '@glimmer/component';
import { fn } from '@ember/helper';
import { on } from '@ember/modifier';
import capitalize from '../helpers/capitalize';
import Icon from '../components/icon';
export default class PlaceDetails extends Component {
get place() {
@ -129,55 +130,66 @@ export default class PlaceDetails extends Component {
<div class="meta-info">
{{#if this.cuisine}}
<p><strong>Cuisine:</strong> {{this.cuisine}}</p>
<p>
<strong>Cuisine:</strong>
{{this.cuisine}}
</p>
{{/if}}
{{#if this.openingHours}}
<p><strong>Open:</strong> {{this.openingHours}}</p>
<p class="content-with-icon">
<Icon @name="clock" @title="Opening hours" />
<span>{{this.openingHours}}</span>
</p>
{{/if}}
{{#if this.phone}}
<p><strong>Phone:</strong> <a href="tel:{{this.phone}}">{{this.phone}}</a></p>
<p class="content-with-icon">
<Icon @name="phone" @title="Phone" />
<span><a href="tel:{{this.phone}}">{{this.phone}}</a></span>
</p>
{{/if}}
{{#if this.website}}
<p>
<strong>Website:</strong>
<a href={{this.website}} target="_blank" rel="noopener noreferrer">
Visit Link
</a>
<p class="content-with-icon">
<Icon @name="globe" @title="Website" />
<span><a href={{this.website}} target="_blank" rel="noopener noreferrer">Website</a></span>
</p>
{{/if}}
{{#if this.wikipedia}}
<p>
<strong>Wikipedia:</strong>
<a href="https://wikipedia.org/wiki/{{this.wikipedia}}" target="_blank" rel="noopener noreferrer">
Article
</a>
<a href="https://wikipedia.org/wiki/{{this.wikipedia}}" target="_blank" rel="noopener noreferrer">Article</a>
</p>
{{/if}}
<hr class="meta-divider">
{{#if this.address}}
<p><strong>Address:</strong> {{this.address}}</p>
<p class="content-with-icon">
<Icon @name="home" @title="Address" />
<span>{{this.address}}</span>
</p>
{{/if}}
<p>
<strong>Geo:</strong>
<a href={{this.geoLink}} target="_blank" rel="noopener noreferrer">
{{this.visibleGeoLink}}
</a>
<p class="content-with-icon">
<Icon @name="mapPin" @title="Geo link" />
<span>
<a href={{this.geoLink}} target="_blank" rel="noopener noreferrer">
{{this.visibleGeoLink}}
</a>
</span>
</p>
{{#if this.osmUrl}}
<p>
<strong>OSM ID:</strong>
<a href={{this.osmUrl}} target="_blank" rel="noopener noreferrer">
{{this.place.osmId}}
</a>
<p class="content-with-icon">
<Icon @name="map" @title="OSM ID" />
<span>
<a href={{this.osmUrl}} target="_blank" rel="noopener noreferrer">
OpenStreetMap
</a>
</span>
</p>
{{/if}}
</div>

View File

@ -223,3 +223,28 @@ body {
.ol-touch .ol-control.ol-locate {
top: 5.5em; /* Adjust for touch devices where controls might be larger */
}
span.icon {
display: inline-block;
}
.icon {
flex-shrink: 0;
}
.icon svg {
width: 100%;
height: 100%;
stroke: currentColor;
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
.content-with-icon {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
}