your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import { Alert, Button, Modal, Subheading } from '@foxui/core';
3 import type { CreationModalComponentProps } from '../../types';
4
5 let { item = $bindable(), oncreate, oncancel }: CreationModalComponentProps = $props();
6
7 let embedCode = $state('');
8 let errorMessage = $state('');
9
10 function parseEmbedCode(code: string): {
11 imageSrc: string | null;
12 linkHref: string | null;
13 } {
14 const normalized = code.replaceAll('&', '&');
15
16 const srcMatch = normalized.match(/src="(https:\/\/api\.producthunt\.com\/[^"]+)"/);
17 const imageSrc = srcMatch ? srcMatch[1] : null;
18
19 const hrefMatch = normalized.match(/href="(https:\/\/www\.producthunt\.com\/[^"]+)"/);
20 const linkHref = hrefMatch ? hrefMatch[1] : null;
21
22 return { imageSrc, linkHref };
23 }
24
25 function validate(): boolean {
26 errorMessage = '';
27
28 const { imageSrc, linkHref } = parseEmbedCode(embedCode);
29
30 if (!linkHref) {
31 errorMessage = 'Could not find a Product Hunt link in the embed code';
32 return false;
33 }
34
35 if (!imageSrc) {
36 errorMessage = 'Could not find a Product Hunt badge image in the embed code';
37 return false;
38 }
39
40 item.cardData.imageSrc = imageSrc;
41 item.cardData.linkHref = linkHref;
42
43 return true;
44 }
45</script>
46
47<Modal open={true} closeButton={false}>
48 <Subheading>Paste Product Hunt Embed Code</Subheading>
49
50 <textarea
51 bind:value={embedCode}
52 placeholder="<a href="https://www.producthunt.com/posts/your-product?..."
53 rows={5}
54 class="bg-base-100 dark:bg-base-800 border-base-300 dark:border-base-700 text-base-900 dark:text-base-100 w-full rounded-xl border px-3 py-2 font-mono text-sm"
55 ></textarea>
56
57 {#if errorMessage}
58 <Alert type="error" title="Invalid embed code"><span>{errorMessage}</span></Alert>
59 {/if}
60
61 <div class="mt-4 flex justify-end gap-2">
62 <Button onclick={oncancel} variant="ghost">Cancel</Button>
63 <Button
64 onclick={() => {
65 if (validate()) oncreate();
66 }}
67 >
68 Create
69 </Button>
70 </div>
71</Modal>