your personal website on atproto - mirror blento.app
at remove-extra-buttons 98 lines 3.0 kB view raw
1<script lang="ts"> 2 import { Alert, Button, Input, Modal, Subheading } from '@foxui/core'; 3 import type { CreationModalComponentProps } from '../types'; 4 5 const EVENT_COLLECTION = 'community.lexicon.calendar.event'; 6 7 let { item = $bindable(), oncreate, oncancel }: CreationModalComponentProps = $props(); 8 9 let isValidating = $state(false); 10 let errorMessage = $state(''); 11 let eventUrl = $state(''); 12 13 function parseEventUrl(url: string): { did: string; rkey: string } | null { 14 // Match smokesignal.events URLs: https://smokesignal.events/{did}/{rkey} 15 const smokesignalMatch = url.match(/^https?:\/\/smokesignal\.events\/(did:[^/]+)\/([^/?#]+)/); 16 if (smokesignalMatch) { 17 return { did: smokesignalMatch[1], rkey: smokesignalMatch[2] }; 18 } 19 20 // Match AT URIs: at://{did}/community.lexicon.calendar.event/{rkey} 21 const atUriMatch = url.match(/^at:\/\/(did:[^/]+)\/([^/]+)\/([^/?#]+)/); 22 if (atUriMatch && atUriMatch[2] === EVENT_COLLECTION) { 23 return { did: atUriMatch[1], rkey: atUriMatch[3] }; 24 } 25 26 return null; 27 } 28 29 async function validateAndCreate() { 30 errorMessage = ''; 31 isValidating = true; 32 33 try { 34 const parsed = parseEventUrl(eventUrl.trim()); 35 36 if (!parsed) { 37 throw new Error('Invalid URL format'); 38 } 39 40 // Validate the event exists by fetching it 41 const response = await fetch( 42 `https://smokesignal.events/xrpc/community.lexicon.calendar.GetEvent?repository=${encodeURIComponent(parsed.did)}&record_key=${encodeURIComponent(parsed.rkey)}` 43 ); 44 45 if (!response.ok) { 46 throw new Error('Event not found'); 47 } 48 49 // Store as AT URI 50 item.cardData.uri = `at://${parsed.did}/${EVENT_COLLECTION}/${parsed.rkey}`; 51 52 return true; 53 } catch (err) { 54 errorMessage = 55 err instanceof Error && err.message === 'Event not found' 56 ? "Couldn't find that event. Please check the URL and try again." 57 : 'Invalid URL. Please enter a valid smokesignal.events URL or AT URI.'; 58 return false; 59 } finally { 60 isValidating = false; 61 } 62 } 63</script> 64 65<Modal open={true} closeButton={false}> 66 <form 67 onsubmit={async () => { 68 if (await validateAndCreate()) oncreate(); 69 }} 70 class="flex flex-col gap-2" 71 > 72 <Subheading>Enter a Smoke Signal event URL</Subheading> 73 <Input 74 bind:value={eventUrl} 75 placeholder="https://smokesignal.events/did:.../..." 76 class="mt-4" 77 /> 78 79 {#if errorMessage} 80 <Alert type="error" title="Failed to create event card"><span>{errorMessage}</span></Alert> 81 {/if} 82 83 <p class="text-base-500 dark:text-base-400 mt-2 text-xs"> 84 Paste a URL from <a 85 href="https://smokesignal.events" 86 class="text-accent-800 dark:text-accent-300" 87 target="_blank">smokesignal.events</a 88 > or an AT URI for a calendar event. 89 </p> 90 91 <div class="mt-4 flex justify-end gap-2"> 92 <Button onclick={oncancel} variant="ghost">Cancel</Button> 93 <Button type="submit" disabled={isValidating || !eventUrl.trim()} 94 >{isValidating ? 'Creating...' : 'Create'}</Button 95 > 96 </div> 97 </form> 98</Modal>