···11+import type { Metadata } from 'next';
22+33+export const metadata: Metadata = {
44+ title: 'Semble bookmarklet',
55+ description:
66+ 'Learn how to add our bookmarklet to your browser to quickly open any webpage in Semble.',
77+};
88+99+interface Props {
1010+ children: React.ReactNode;
1111+}
1212+1313+export default function Layout(props: Props) {
1414+ return props.children;
1515+}
+82-55
src/webapp/app/bookmarklet/page.tsx
···99 Code,
1010 Alert,
1111 Box,
1212+ Badge,
1313+ Image,
1214 Group,
1515+ Anchor,
1616+ CopyButton,
1317} from '@mantine/core';
1418import { useState } from 'react';
1519import { BiInfoCircle } from 'react-icons/bi';
2020+import SembleLogo from '@/assets/semble-logo.svg';
2121+import Link from 'next/link';
16221723export default function BookmarkletPage() {
1818- const [copied, setCopied] = useState(false);
1919-2024 const appUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://127.0.0.1:4000';
21252226 const bookmarkletCode = `javascript:(function(){
2327 const currentUrl = window.location.href;
2428 const sembleUrl = '${appUrl}/url?id=' + currentUrl;
2529 window.open(sembleUrl, '_blank');
2626- })();`;
2727-2828- const handleCopy = async () => {
2929- try {
3030- await navigator.clipboard.writeText(bookmarkletCode);
3131- setCopied(true);
3232- setTimeout(() => setCopied(false), 2000);
3333- } catch (err) {
3434- console.error('Failed to copy bookmarklet:', err);
3535- }
3636- };
3030+})();`;
37313832 // Create the bookmarklet link using dangerouslySetInnerHTML to bypass React's security check
3933 const createBookmarkletLink = () => {
4034 return {
4141- __html: `<a href="${bookmarkletCode}" style="text-decoration: none; padding: 8px 16px; background-color: var(--mantine-color-orange-6); color: white; border-radius: 4px; display: inline-flex; align-items: center; gap: 8px;"><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"/></svg>Open in Semble</a>`,
3535+ __html: `<a href="${bookmarkletCode}" style="text-decoration: none; padding: 8px 16px; background-color: var(--mantine-color-tangerine-6); color: white; border-radius: 100px; display: inline-flex; align-items: center; gap: 8px; font-weight: 600;"><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"/></svg>Open in Semble</a>`,
4236 };
4337 };
44384539 return (
4646- <Container size="md" py="xl">
4040+ <Container size="sm" p="md">
4741 <Stack gap="xl">
4848- <Stack gap="md">
4949- <Title order={1}>Semble Bookmarklet</Title>
5050- <Text size="lg" c="dimmed">
5151- Add this bookmarklet to your browser to quickly open any webpage in
5252- Semble.
5353- </Text>
4242+ <Stack gap="xs" align="center">
4343+ <Stack align="center" gap={'xs'}>
4444+ <Anchor component={Link} href={'/'}>
4545+ <Image
4646+ src={SembleLogo.src}
4747+ alt="Semble logo"
4848+ w={48}
4949+ h={64.5}
5050+ mx={'auto'}
5151+ />
5252+ <Badge size="sm">Alpha</Badge>
5353+ </Anchor>
5454+ </Stack>
5555+ <Stack gap={'xs'} align="center">
5656+ <Title order={1}>Semble Bookmarklet</Title>
5757+ <Title
5858+ order={2}
5959+ size="xl"
6060+ c="dimmed"
6161+ fw={600}
6262+ maw={500}
6363+ ta={'center'}
6464+ >
6565+ Add this bookmarklet to your browser to quickly open any webpage
6666+ in Semble.
6767+ </Title>
6868+ </Stack>
5469 </Stack>
55705656- <Alert icon={<BiInfoCircle />} title="How to install" color="orange">
7171+ <Alert title="How to install" color="grape">
5772 <Stack gap="sm">
5858- <Text>
5959- 1. Copy the bookmarklet code below or drag the button to your
6060- bookmarks bar
6161- </Text>
6262- <Text>
6363- {
6464- "2. When you're on any webpage, click the bookmarklet to open it in Semble"
6565- }
6666- </Text>
7373+ <Group gap={'xs'}>
7474+ <Badge size="md" color="grape" circle>
7575+ 1
7676+ </Badge>
7777+ <Text fw={500} c="grape">
7878+ Copy the bookmarklet code below or drag the button to your
7979+ bookmarks bar
8080+ </Text>
8181+ </Group>
8282+ <Group gap={'xs'}>
8383+ <Badge size="md" color="grape" circle>
8484+ 2
8585+ </Badge>
8686+8787+ <Text fw={500} c={'grape'}>
8888+ {
8989+ "When you're on any webpage, click the bookmarklet to open it in Semble"
9090+ }
9191+ </Text>
9292+ </Group>
6793 </Stack>
6894 </Alert>
69957096 <Stack gap="md">
7171- <Title order={2} size="h3">
7272- Method 1: Drag to Bookmarks Bar
7373- </Title>
7474- <Text c="dimmed">
7575- {"Drag this button directly to your browser's bookmarks bar:"}
7676- </Text>
9797+ <Stack gap={'xs'}>
9898+ <Title order={3}>Method 1: Drag to Bookmarks Bar</Title>
9999+ <Text c="dimmed" fw={500}>
100100+ {"Drag this button directly to your browser's bookmarks bar:"}
101101+ </Text>
102102+ </Stack>
77103 <Group>
78104 <Box dangerouslySetInnerHTML={createBookmarkletLink()} />
79105 </Group>
80106 </Stack>
8110782108 <Stack gap="md">
8383- <Title order={2} size="h3">
8484- Method 2: Copy Code
8585- </Title>
8686- <Text c="dimmed">
8787- Copy this code and create a new bookmark with it as the URL:
8888- </Text>
109109+ <Stack gap={'xs'}>
110110+ <Title order={3}>Method 2: Copy Code</Title>
111111+ <Text c="dimmed" fw={500}>
112112+ Copy this code and create a new bookmark with it as the URL:
113113+ </Text>
114114+ </Stack>
89115 <Box pos="relative">
90116 <Code
91117 block
···98124 >
99125 {bookmarkletCode}
100126 </Code>
101101- <Button
102102- size="xs"
103103- variant="light"
104104- onClick={handleCopy}
105105- style={{
106106- position: 'absolute',
107107- top: '8px',
108108- right: '8px',
109109- }}
110110- >
111111- {copied ? 'Copied!' : 'Copy'}
112112- </Button>
127127+ <CopyButton value={bookmarkletCode}>
128128+ {({ copied, copy }) => (
129129+ <Button
130130+ color="dark"
131131+ pos={'absolute'}
132132+ top={12}
133133+ right={12}
134134+ onClick={copy}
135135+ >
136136+ {copied ? 'Copied!' : 'Copy'}
137137+ </Button>
138138+ )}
139139+ </CopyButton>
113140 </Box>
114141 </Stack>
115142 </Stack>