Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Place card shows website and phone number when available #268

Merged
merged 3 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions services/frontend/www-app/src/components/PlaceCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,25 @@
<div class="text-subtitle1">
{{ primaryName() }}
</div>
<div class="text" v-if="secondaryName()">
{{ secondaryName() }}
</div>
</q-card-section>
<q-card-section>
<travel-mode-bar :to-place="place" />
</q-card-section>
<q-card-section>
<place-field
v-if="secondaryName()"
:copy-text="secondaryName()!"
icon="location_on"
>
{{ secondaryName() }}
</place-field>
<place-field v-if="website()" :copy-text="website()!" icon="public">
<a :href="website()">{{ website() }}</a>
</place-field>
<place-field v-if="phone()" :copy-text="phone()!" icon="phone">
<a :href="'tel:' + phone()">{{ phone() }}</a>
</place-field>
</q-card-section>
</template>

<script lang="ts">
Expand All @@ -18,6 +30,7 @@ import Place from 'src/models/Place';
import { formatLngLatAsLatLng } from 'src/utils/format';
import { defineComponent } from 'vue';
import TravelModeBar from './TravelModeBar.vue';
import PlaceField from './PlaceField.vue';

export default defineComponent({
name: 'PlaceCard',
Expand All @@ -39,13 +52,20 @@ export default defineComponent({
return i18n.global.t('dropped_pin');
},
secondaryName(): string | undefined {
// TODO: use pelias label?
if (this.place.name && this.place.address) {
return this.place.address;
} else {
return formatLngLatAsLatLng(this.place.point);
}
},
website(): string | undefined {
return this.place.website;
},
phone(): string | undefined {
return this.place.phone;
},
},
components: { TravelModeBar },
components: { TravelModeBar, PlaceField },
});
</script>
39 changes: 39 additions & 0 deletions services/frontend/www-app/src/components/PlaceField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<template>
<q-item class="row items-center" style="padding: 0">
<q-icon class="col-1" size="sm" :name="icon" />
<q-item-label class="col-" style="padding-left: 8px; padding-right: 8px">
<slot />
</q-item-label>
<q-btn
class="col-1"
icon="content_copy"
unelevated
:ripple="false"
size="sm"
@click="copyToClipboard(copyText)"
/>
</q-item>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
name: 'PlaceField',
props: {
icon: {
type: String,
required: true,
},
copyText: {
type: String,
required: true,
},
},
methods: {
copyToClipboard(text: string): void {
navigator.clipboard.writeText(text);
},
},
});
</script>
47 changes: 34 additions & 13 deletions services/frontend/www-app/src/models/Place.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ export class PlaceStorage {
}
}

type PlaceProperties = {
countryCode?: string;
name?: string;
address?: string;
phone?: string;
website?: string;
};

/// Wrapper around a pelias response
export default class Place {
id: PlaceId;
Expand All @@ -128,21 +136,23 @@ export default class Place {
countryCode?: string;
public address?: string | null;
name?: string;
public phone?: string;
public website?: string;

constructor(
id: PlaceId,
point: LngLat,
bbox?: LngLatBounds,
countryCode?: string,
name?: string,
address?: string
props: PlaceProperties = {}
) {
this.id = id;
this.point = point;
this.bbox = bbox;
this.countryCode = countryCode;
this.name = name;
this.address = address;
this.countryCode = props.countryCode;
this.name = props.name;
this.address = props.address;
this.phone = props.phone;
this.website = props.website;
}

static fromFeature(id: PlaceId, feature: GeoJSON.Feature): Place {
Expand Down Expand Up @@ -197,17 +207,28 @@ export default class Place {
const name = feature.properties?.name;
console.assert(name, 'no name found for feature', feature);

const place = new Place(id, location, bbox, countryCode, name, address);
// "addendum": {
// "osm": {
// "website": "https://www.adasbooks.com",
// "phone": "+1 206 322 1058",
// "opening_hours": "Su-Th 08:00-21:00; Fr-Sa 08:00-22:00"
// }
// }
const website = feature.properties?.addendum?.osm?.website;
const phone = feature.properties?.addendum?.osm?.phone;

const place = new Place(id, location, bbox, {
countryCode,
name,
address,
website,
phone,
});
return place;
}

static bareLocation(location: LngLat) {
return new Place(
PlaceId.location(location),
location,
undefined,
undefined
);
return new Place(PlaceId.location(location), location);
}

public serializedId(): string {
Expand Down