your personal website on atproto - mirror blento.app
at custom-domains 78 lines 2.2 kB view raw
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>