From c68e5099797d5b49ed6441ce04d7c77105327f73 Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Sun, 3 Aug 2025 23:35:06 -0700 Subject: feat(web): Add special cards for specific websites. Fixes #1344 --- .../preview/content-renderers/AmazonRenderer.tsx | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 apps/web/components/dashboard/preview/content-renderers/AmazonRenderer.tsx (limited to 'apps/web/components/dashboard/preview/content-renderers/AmazonRenderer.tsx') diff --git a/apps/web/components/dashboard/preview/content-renderers/AmazonRenderer.tsx b/apps/web/components/dashboard/preview/content-renderers/AmazonRenderer.tsx new file mode 100644 index 00000000..aaf33565 --- /dev/null +++ b/apps/web/components/dashboard/preview/content-renderers/AmazonRenderer.tsx @@ -0,0 +1,137 @@ +import { ShoppingCart } from "lucide-react"; + +import { BookmarkTypes, ZBookmark } from "@karakeep/shared/types/bookmarks"; + +import { ContentRenderer } from "./types"; + +function extractAmazonProductInfo( + url: string, +): { asin: string; domain: string } | null { + const patterns = [ + // Standard product URLs + /amazon\.([a-z.]+)\/.*\/dp\/([A-Z0-9]{10})/, + /amazon\.([a-z.]+)\/dp\/([A-Z0-9]{10})/, + // Shortened URLs + /amazon\.([a-z.]+)\/gp\/product\/([A-Z0-9]{10})/, + // Mobile URLs + /amazon\.([a-z.]+)\/.*\/product\/([A-Z0-9]{10})/, + // International variations + /amazon\.([a-z.]+)\/.*\/([A-Z0-9]{10})/, + ]; + + for (const pattern of patterns) { + const match = url.match(pattern); + if (match) { + return { + domain: match[1], + asin: match[2], + }; + } + } + return null; +} + +function canRenderAmazon(bookmark: ZBookmark): boolean { + if (bookmark.content.type !== BookmarkTypes.LINK) { + return false; + } + + const url = bookmark.content.url; + return extractAmazonProductInfo(url) !== null; +} + +function AmazonRendererComponent({ bookmark }: { bookmark: ZBookmark }) { + if (bookmark.content.type !== BookmarkTypes.LINK) { + return null; + } + + const productInfo = extractAmazonProductInfo(bookmark.content.url); + if (!productInfo) { + return null; + } + + const { title, description, imageUrl } = bookmark.content; + + return ( +
+
+ {/* Product Image */} + {imageUrl && ( +
+ {title +
+ )} + + {/* Product Info Card */} +
+ {/* Title */} + {title && ( +

{title}

+ )} + + {/* Description */} + {description && ( +

+ {description} +

+ )} + + {/* Product Details */} +
+
+ ASIN: + + {productInfo.asin} + +
+
+ Domain: + + amazon.{productInfo.domain} + +
+
+ + {/* Action Buttons */} +
+ + + View on Amazon + + + Direct Link + +
+ + {/* Amazon Disclaimer */} +

+ Product information from Amazon. Prices and availability may vary. +

+
+
+
+ ); +} + +export const amazonRenderer: ContentRenderer = { + id: "amazon", + name: "Amazon Product", + icon: ShoppingCart, + canRender: canRenderAmazon, + component: AmazonRendererComponent, + priority: 10, +}; -- cgit v1.2.3-70-g09d2