your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import { Alert, Button, Input, Modal, Subheading } from '@foxui/core';
3 import type { CreationModalComponentProps } from '../types';
4 import { getZoomLevel } from '.';
5
6 let { item = $bindable(), oncreate, oncancel }: CreationModalComponentProps = $props();
7
8 let isFetchingLocation = $state(false);
9
10 let errorMessage = $state('');
11
12 let search = $state('');
13
14 async function fetchLocation() {
15 errorMessage = '';
16 isFetchingLocation = true;
17
18 try {
19 const response = await fetch('/api/geocoding?q=' + encodeURIComponent(search));
20 if (response.ok) {
21 const data = await response.json();
22
23 if (!data.lat || !data.lon) throw new Error('lat or lon not found');
24
25 item.cardData.lat = data.lat;
26 item.cardData.lon = data.lon;
27 item.cardData.name = data.display_name?.split(',')[0] || search;
28 item.cardData.type = data.class || 'city';
29 item.cardData.zoom = Math.max(getZoomLevel(data.class), getZoomLevel(data.type));
30 } else {
31 throw new Error('response not ok');
32 }
33 } catch {
34 errorMessage = "Couldn't find that location!";
35 return false;
36 } finally {
37 isFetchingLocation = false;
38 }
39 return true;
40 }
41</script>
42
43<Modal open={true} closeButton={false}>
44 <form
45 onsubmit={async () => {
46 if (await fetchLocation()) oncreate();
47 }}
48 class="flex flex-col gap-2"
49 >
50 <Subheading>Enter a address or city</Subheading>
51 <Input bind:value={search} class="mt-4" />
52
53 {#if errorMessage}
54 <Alert type="error" title="Failed to create map card"><span>{errorMessage}</span></Alert>
55 {/if}
56
57 <p class="mt-2 text-xs">
58 Geocoding by <a
59 href="https://nominatim.openstreetmap.org/"
60 class="text-accent-800 dark:text-accent-300"
61 target="_blank">Nominatim</a
62 >
63 / ©
64 <a
65 href="https://www.openstreetmap.org/copyright"
66 class="text-accent-800 dark:text-accent-300"
67 target="_blank">OpenStreetMap contributors</a
68 >
69 </p>
70
71 <div class="mt-4 flex justify-end gap-2">
72 <Button onclick={oncancel} variant="ghost">Cancel</Button>
73 <Button type="submit" disabled={isFetchingLocation}
74 >{isFetchingLocation ? 'Creating...' : 'Create'}</Button
75 >
76 </div>
77 </form>
78</Modal>