diff --git a/frontend/bun.lockb b/frontend/bun.lockb index dbe073b..d4a3e76 100755 Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ diff --git a/frontend/fly.toml b/frontend/fly.toml index e0541f3..68fa937 100644 --- a/frontend/fly.toml +++ b/frontend/fly.toml @@ -18,4 +18,4 @@ primary_region = 'iad' [[vm]] size = 'shared-cpu-1x' - memory = '512mb' + memory = '256mb' diff --git a/frontend/package.json b/frontend/package.json index c1a0577..09e79ea 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,7 +20,6 @@ "@sveltejs/kit": "^2.5.5", "@sveltejs/vite-plugin-svelte": "^3.0.2", "@types/pg": "^8.11.6", - "@types/qrcode": "^1.5.5", "autoprefixer": "^10.4.14", "bun-types": "^1.0.11", "drizzle-kit": "^0.23.1", @@ -57,7 +56,7 @@ "oslo": "^1.2.0", "pg": "^8.11.5", "postgres": "^3.4.3", - "qrcode": "^1.5.3", + "qr-code-styling": "^1.6.0-rc.1", "resend": "^3.4.0", "svelte-sonner": "^0.3.10", "sveltekit-superforms": "^2.12.2", diff --git a/frontend/src/hooks.server.ts b/frontend/src/hooks.server.ts index 11fd186..5f11c4c 100644 --- a/frontend/src/hooks.server.ts +++ b/frontend/src/hooks.server.ts @@ -6,11 +6,9 @@ export const handle: Handle = async ({ event, resolve }) => { const pathname = event.url.pathname - const protected_api = ['/api/logout'] - if ( pathname.startsWith('/dashboard') || - protected_api.includes(pathname) + pathname.startsWith('/api') ) { if (!sessionId) { redirect(303, '/login') diff --git a/frontend/src/lib/components/ui/sonner/sonner.svelte b/frontend/src/lib/components/ui/sonner/sonner.svelte index 14c1d94..485bb13 100644 --- a/frontend/src/lib/components/ui/sonner/sonner.svelte +++ b/frontend/src/lib/components/ui/sonner/sonner.svelte @@ -10,6 +10,8 @@ - import QRCode from 'qrcode' import { Button } from '$lib/components/ui/button' import { toast } from 'svelte-sonner' import * as DropdownMenu from '$lib/components/ui/dropdown-menu' import { Badge } from '$lib/components/ui/badge' + import QRCodeStyling from 'qr-code-styling' export let background = '#fff' export let color = '#000' @@ -34,23 +34,28 @@ } async function generateQrCode() { - try { - image = await QRCode.toDataURL(value, { - errorCorrectionLevel: 'L', - margin: 1, - scale: 20, - color: { - light: background, - dark: color, - }, - }) - } catch (e) { - image = await QRCode.toDataURL(value, { + const qrcodestyling = new QRCodeStyling({ + data: value, + width: 300, + height: 300, + margin: 10, + qrOptions: { errorCorrectionLevel: 'L', - margin: 1, - scale: 20, - }) - } + typeNumber: 0, + }, + backgroundOptions: { + color: background, + }, + dotsOptions: { + color: color, + }, + cornersSquareOptions: { + type: 'square', + }, + }) + const blob = await qrcodestyling.getRawData() + if (!blob) return + image = URL.createObjectURL(blob) } $: { @@ -60,25 +65,28 @@ } -
+
{value} {value} -
- +
+ + + Standard + Standard - With Color + href={`/url/${code}/qr?color=true`} + target="_blank"> + With Color +
diff --git a/frontend/src/routes/(app)/dashboard/projects/[id]/links/[linkid]/qr/(components)/qr.svelte b/frontend/src/routes/(app)/dashboard/projects/[id]/links/[linkid]/qr/(components)/qr.svelte index 93f4885..4936525 100644 --- a/frontend/src/routes/(app)/dashboard/projects/[id]/links/[linkid]/qr/(components)/qr.svelte +++ b/frontend/src/routes/(app)/dashboard/projects/[id]/links/[linkid]/qr/(components)/qr.svelte @@ -1,9 +1,9 @@ -
+
{value} {value} -
- +
+ + + Standard + Standard - With Color + href={`/url/${code}/qr?color=true`} + target="_blank"> + With Color +
diff --git a/frontend/src/routes/(app)/dashboard/projects/[id]/settings/(components)/DemoQR.svelte b/frontend/src/routes/(app)/dashboard/projects/[id]/settings/(components)/DemoQR.svelte index 4c64199..3b80f19 100644 --- a/frontend/src/routes/(app)/dashboard/projects/[id]/settings/(components)/DemoQR.svelte +++ b/frontend/src/routes/(app)/dashboard/projects/[id]/settings/(components)/DemoQR.svelte @@ -1,6 +1,6 @@ + +
+
+
+
404
+
Invalid Url
+
+ +
+
diff --git a/frontend/src/routes/api/shortener/[id]/qr/+server.ts b/frontend/src/routes/(public)/url/[id]/qr/+page.server.ts similarity index 50% rename from frontend/src/routes/api/shortener/[id]/qr/+server.ts rename to frontend/src/routes/(public)/url/[id]/qr/+page.server.ts index 06d62b1..7f51d19 100644 --- a/frontend/src/routes/api/shortener/[id]/qr/+server.ts +++ b/frontend/src/routes/(public)/url/[id]/qr/+page.server.ts @@ -1,17 +1,16 @@ import { db } from '$lib/db' -import type { RequestHandler } from './$types' -import QRCode from 'qrcode' import { redirect } from '@sveltejs/kit' import { env } from '$env/dynamic/public' +import type { PageServerLoad } from './$types' const shortenerUrl = env.PUBLIC_SHORTENER_URL -export const GET: RequestHandler = async (event) => { - const shortenerId = event.params.id +export const load = (async (event) => { + const { id } = event.params const color = event.url.searchParams.get('color') const shortener = await db.query.shortener.findFirst({ - where: (shortener, { eq }) => eq(shortener.code, shortenerId), + where: (shortener, { eq }) => eq(shortener.code, id), with: { user: { with: { @@ -23,23 +22,25 @@ export const GET: RequestHandler = async (event) => { }) if (!shortener) { - redirect(303, '/') + redirect(301, `/dashboard/links`) } - let colorSetting = {} + let colorSetting: { + color: { background: string | null; foreground: string | null } + } | null = null if (color === 'true') { if (shortener.project) { colorSetting = { color: { - light: shortener.project.qr_background, - dark: shortener.project.qr_foreground, + background: shortener.project.qr_background, + foreground: shortener.project.qr_foreground, }, } } else if (shortener.user.setting) { colorSetting = { color: { - light: shortener.user.setting.qr_background, - dark: shortener.user.setting.qr_foreground, + background: shortener.user.setting.qr_background, + foreground: shortener.user.setting.qr_foreground, }, } } @@ -50,17 +51,5 @@ export const GET: RequestHandler = async (event) => { ? shortener.project.custom_domain || shortenerUrl : shortenerUrl - const image = await QRCode.toBuffer(url + '/' + shortenerId, { - type: 'png', - errorCorrectionLevel: 'L', - margin: 1, - scale: 20, - ...colorSetting, - }) - - return new Response(image, { - headers: { - 'Content-Type': 'image/png', - }, - }) -} + return { shortener, url, colorSetting, shortenerId: id } +}) satisfies PageServerLoad diff --git a/frontend/src/routes/(public)/url/[id]/qr/+page.svelte b/frontend/src/routes/(public)/url/[id]/qr/+page.svelte new file mode 100644 index 0000000..30111a8 --- /dev/null +++ b/frontend/src/routes/(public)/url/[id]/qr/+page.svelte @@ -0,0 +1,79 @@ + + + + + + {data.url + '/' + data.shortenerId} + + {data.url + + + diff --git a/frontend/src/routes/(landing)/[...catchall]/+page.svelte b/frontend/src/routes/[...catchall]/+page.svelte similarity index 85% rename from frontend/src/routes/(landing)/[...catchall]/+page.svelte rename to frontend/src/routes/[...catchall]/+page.svelte index 55acd07..4156e69 100644 --- a/frontend/src/routes/(landing)/[...catchall]/+page.svelte +++ b/frontend/src/routes/[...catchall]/+page.svelte @@ -3,7 +3,7 @@ import Button from '$lib/components/ui/button/button.svelte' -
+
404