aboutsummaryrefslogtreecommitdiffstats
path: root/web/app/bookmarks
diff options
context:
space:
mode:
Diffstat (limited to 'web/app/bookmarks')
-rw-r--r--web/app/bookmarks/components/AddLink.tsx40
-rw-r--r--web/app/bookmarks/components/LinkCard.tsx19
-rw-r--r--web/app/bookmarks/components/LinksGrid.tsx21
-rw-r--r--web/app/bookmarks/page.tsx11
4 files changed, 91 insertions, 0 deletions
diff --git a/web/app/bookmarks/components/AddLink.tsx b/web/app/bookmarks/components/AddLink.tsx
new file mode 100644
index 00000000..54cf9137
--- /dev/null
+++ b/web/app/bookmarks/components/AddLink.tsx
@@ -0,0 +1,40 @@
+"use client";
+
+import APIClient from "@/lib/api";
+import { useRouter } from "next/navigation";
+import { useState } from "react";
+
+export default function AddLink() {
+ const router = useRouter();
+ const [link, setLink] = useState("");
+
+ const bookmarkLink = async () => {
+ const [_resp, error] = await APIClient.bookmarkLink(link);
+ if (error) {
+ alert(error.message);
+ return;
+ }
+ router.refresh();
+ };
+
+ return (
+ <div className="p-4">
+ <input
+ type="text"
+ placeholder="Link"
+ value={link}
+ onChange={(val) => setLink(val.target.value)}
+ onKeyUp={async (event) => {
+ if (event.key == "Enter") {
+ bookmarkLink();
+ setLink("");
+ }
+ }}
+ className="w-10/12 px-4 py-2 border rounded-md focus:outline-none focus:border-blue-300"
+ />
+ <button className="w-2/12 px-1 py-2" onClick={bookmarkLink}>
+ Submit
+ </button>
+ </div>
+ );
+}
diff --git a/web/app/bookmarks/components/LinkCard.tsx b/web/app/bookmarks/components/LinkCard.tsx
new file mode 100644
index 00000000..103f97ef
--- /dev/null
+++ b/web/app/bookmarks/components/LinkCard.tsx
@@ -0,0 +1,19 @@
+import { ZBookmarkedLink } from "@/lib/types/api/links";
+import Link from "next/link";
+
+export default async function LinkCard({ link }: { link: ZBookmarkedLink }) {
+ return (
+ <Link href={link.url} className="border rounded-md hover:border-blue-300">
+ <div className="p-4">
+ <h2 className="text-lg font-semibold">
+ {link.details?.favicon && (
+ // eslint-disable-next-line @next/next/no-img-element
+ <img alt="" width="10" height="10" src={link.details?.favicon} />
+ )}
+ {link.details?.title ?? link.id}
+ </h2>
+ <p className="text-gray-600">{link.details?.description ?? link.url}</p>
+ </div>
+ </Link>
+ );
+}
diff --git a/web/app/bookmarks/components/LinksGrid.tsx b/web/app/bookmarks/components/LinksGrid.tsx
new file mode 100644
index 00000000..83aaca80
--- /dev/null
+++ b/web/app/bookmarks/components/LinksGrid.tsx
@@ -0,0 +1,21 @@
+import { getServerSession } from "next-auth";
+import { redirect } from "next/navigation";
+import { authOptions } from "@/lib/auth";
+import { getLinks } from "@/lib/services/links";
+import LinkCard from "./LinkCard";
+
+export default async function LinksGrid() {
+ const session = await getServerSession(authOptions);
+ if (!session) {
+ redirect("/");
+ }
+ const links = await getLinks(session.user.id);
+
+ return (
+ <div className="container mx-auto mt-8 grid gap-4 grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
+ {links.map((l) => (
+ <LinkCard key={l.id} link={l} />
+ ))}
+ </div>
+ );
+}
diff --git a/web/app/bookmarks/page.tsx b/web/app/bookmarks/page.tsx
new file mode 100644
index 00000000..f0efa2e4
--- /dev/null
+++ b/web/app/bookmarks/page.tsx
@@ -0,0 +1,11 @@
+import AddLink from "./components/AddLink";
+import LinksGrid from "./components/LinksGrid";
+
+export default async function Bookmarks() {
+ return (
+ <>
+ <AddLink />
+ <LinksGrid />
+ </>
+ );
+}