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