diff options
Diffstat (limited to 'app/src/components/bookmark-list.tsx')
-rw-r--r-- | app/src/components/bookmark-list.tsx | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/app/src/components/bookmark-list.tsx b/app/src/components/bookmark-list.tsx new file mode 100644 index 0000000..6138e31 --- /dev/null +++ b/app/src/components/bookmark-list.tsx @@ -0,0 +1,109 @@ +"use client"; + +import { useState } from "react"; + +import { BookmarkStorageService } from "../lib/bookmark-storage"; +import { TwitterBookmark } from "../lib/twitter-api"; + +interface BookmarkListProps { + bookmarks: TwitterBookmark[]; +} + +function formatDate(dateString: string): string { + const date = new Date(dateString); + return date.toLocaleDateString("en-US", { + year: "numeric", + month: "short", + day: "numeric", + hour: "2-digit", + minute: "2-digit", + }); +} + +function truncateText(text: string, maxLength: number = 200): string { + if (text.length <= maxLength) return text; + return text.substring(0, maxLength) + "..."; +} + +export function BookmarkList({ bookmarks }: BookmarkListProps) { + if (bookmarks.length === 0) { + return ( + <div className="text-center py-8 text-gray-500"> + No bookmarks found. Click "Fetch Twitter Bookmarks" to load your + bookmarks. + </div> + ); + } + + return ( + <div className="space-y-4"> + <div className="text-sm text-gray-600 mb-4"> + Found {bookmarks.length} bookmark{bookmarks.length !== 1 ? "s" : ""} + </div> + + {bookmarks.map((bookmark) => ( + <BookmarkEntry bookmark={bookmark} key={bookmark.id} /> + ))} + </div> + ); +} + +function BookmarkEntry({ bookmark }: { bookmark: TwitterBookmark }) { + console.log({ bookmark }); + return ( + <div className="border border-gray-200 rounded-lg p-4 hover:shadow-md transition-shadow"> + <div className="flex items-start justify-between mb-2"> + <div className="flex-1"> + <div className="flex items-center gap-2 mb-1"> + <span className="font-semibold text-gray-900"> + @{bookmark.author.username} + </span> + <span className="text-sm text-gray-500">•</span> + <span className="text-sm text-gray-500"> + {formatDate(bookmark.createdAt)} + </span> + </div> + <div className="text-sm text-gray-700 mb-2"> + {truncateText(bookmark.text)} + </div> + <div className="flex flex-wrap"> + {bookmark.media.pics.map((p) => ( + <img width="400" src={p} /> + ))} + </div> + {bookmark.media.video.url && ( + <video src={bookmark.media.video.url} controls /> + )} + {bookmark.urls.length > 0 && ( + <div className="space-y-1"> + {bookmark.urls.map((url, index) => ( + <div key={index} className="text-xs"> + <a + href={url.expandedUrl} + target="_blank" + rel="noopener noreferrer" + className="text-blue-600 hover:underline" + > + {url.displayUrl} + </a> + </div> + ))} + </div> + )} + {bookmark.hashtags.length > 0 && ( + <div className="flex flex-wrap gap-1 mt-2"> + {bookmark.hashtags.map((tag, index) => ( + <span + key={index} + className="text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded" + > + #{tag} + </span> + ))} + </div> + )} + </div> + </div> + </div> + ); +} |