diff --git a/components/ModalContent/EditCollectionSharingModal.tsx b/components/ModalContent/EditCollectionSharingModal.tsx
index 5763b5d..9f84cb1 100644
--- a/components/ModalContent/EditCollectionSharingModal.tsx
+++ b/components/ModalContent/EditCollectionSharingModal.tsx
@@ -15,6 +15,7 @@ import { dropdownTriggerer } from "@/lib/client/utils";
import { useTranslation } from "next-i18next";
import { useUpdateCollection } from "@/hooks/store/collections";
import { useUser } from "@/hooks/store/user";
+import CopyButton from "../CopyButton";
type Props = {
onClose: Function;
@@ -133,19 +134,9 @@ export default function EditCollectionSharingModal({
{collection.isPublic && (
{t("sharable_link_guide")}
-
{
- try {
- navigator.clipboard
- .writeText(publicCollectionURL)
- .then(() => toast.success(t("copied")));
- } catch (err) {
- console.log(err);
- }
- }}
- className="w-full hide-scrollbar overflow-x-auto whitespace-nowrap rounded-md p-2 bg-base-200 border-neutral-content border-solid border outline-none hover:border-primary dark:hover:border-primary duration-100 cursor-text"
- >
+
{publicCollectionURL}
+
)}
diff --git a/components/ModalContent/LinkDetailModal.tsx b/components/ModalContent/LinkDetailModal.tsx
new file mode 100644
index 0000000..2e6308a
--- /dev/null
+++ b/components/ModalContent/LinkDetailModal.tsx
@@ -0,0 +1,145 @@
+import React, { useEffect, useState } from "react";
+import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
+import getPublicUserData from "@/lib/client/getPublicUserData";
+import { useTranslation } from "next-i18next";
+import { useUser } from "@/hooks/store/user";
+import { useGetLink } from "@/hooks/store/links";
+import Drawer from "../Drawer";
+import LinkDetails from "../LinkDetails";
+import Link from "next/link";
+import usePermissions from "@/hooks/usePermissions";
+import { useRouter } from "next/router";
+
+type Props = {
+ onClose: Function;
+ onEdit: Function;
+ link: LinkIncludingShortenedCollectionAndTags;
+};
+
+export default function LinkDetailModal({ onClose, onEdit, link }: Props) {
+ const { t } = useTranslation();
+ const getLink = useGetLink();
+ const { data: user = {} } = useUser();
+
+ const [collectionOwner, setCollectionOwner] = useState({
+ id: null as unknown as number,
+ name: "",
+ username: "",
+ image: "",
+ archiveAsScreenshot: undefined as unknown as boolean,
+ archiveAsMonolith: undefined as unknown as boolean,
+ archiveAsPDF: undefined as unknown as boolean,
+ });
+
+ useEffect(() => {
+ const fetchOwner = async () => {
+ if (link.collection.ownerId !== user.id) {
+ const owner = await getPublicUserData(
+ link.collection.ownerId as number
+ );
+ setCollectionOwner(owner);
+ } else if (link.collection.ownerId === user.id) {
+ setCollectionOwner({
+ id: user.id as number,
+ name: user.name,
+ username: user.username as string,
+ image: user.image as string,
+ archiveAsScreenshot: user.archiveAsScreenshot as boolean,
+ archiveAsMonolith: user.archiveAsScreenshot as boolean,
+ archiveAsPDF: user.archiveAsPDF as boolean,
+ });
+ }
+ };
+
+ fetchOwner();
+ }, [link.collection.ownerId]);
+
+ const isReady = () => {
+ return (
+ link &&
+ (collectionOwner.archiveAsScreenshot === true
+ ? link.pdf && link.pdf !== "pending"
+ : true) &&
+ (collectionOwner.archiveAsMonolith === true
+ ? link.monolith && link.monolith !== "pending"
+ : true) &&
+ (collectionOwner.archiveAsPDF === true
+ ? link.pdf && link.pdf !== "pending"
+ : true) &&
+ link.readable &&
+ link.readable !== "pending"
+ );
+ };
+
+ useEffect(() => {
+ (async () => {
+ await getLink.mutateAsync({
+ id: link.id as number,
+ });
+ })();
+
+ let interval: any;
+
+ if (!isReady()) {
+ interval = setInterval(async () => {
+ await getLink.mutateAsync({
+ id: link.id as number,
+ });
+ }, 5000);
+ } else {
+ if (interval) {
+ clearInterval(interval);
+ }
+ }
+
+ return () => {
+ if (interval) {
+ clearInterval(interval);
+ }
+ };
+ }, [link?.monolith]);
+
+ const permissions = usePermissions(link.collection.id as number);
+
+ const router = useRouter();
+
+ const isPublicRoute = router.pathname.startsWith("/public") ? true : false;
+
+ return (
+
+ onClose()}
+ >
+
+
+
+
+
+ {permissions === true ||
+ (permissions?.canUpdate && (
+ <>
+
+
+
+
+
{
+ onEdit();
+ onClose();
+ }}
+ >
+ {t("edit_link")}
+
+
+ >
+ ))}
+
+
+ );
+}
diff --git a/components/ModalContent/NewLinkModal.tsx b/components/ModalContent/NewLinkModal.tsx
index 0c00086..61ee8bc 100644
--- a/components/ModalContent/NewLinkModal.tsx
+++ b/components/ModalContent/NewLinkModal.tsx
@@ -61,7 +61,7 @@ export default function NewLinkModal({ onClose }: Props) {
};
useEffect(() => {
- if (router.query.id) {
+ if (router.pathname.startsWith("/collections/") && router.query.id) {
const currentCollection = collections.find(
(e) => e.id == Number(router.query.id)
);
diff --git a/components/ModalContent/NewTokenModal.tsx b/components/ModalContent/NewTokenModal.tsx
index 4d39aec..5c57012 100644
--- a/components/ModalContent/NewTokenModal.tsx
+++ b/components/ModalContent/NewTokenModal.tsx
@@ -7,6 +7,7 @@ import { dropdownTriggerer } from "@/lib/client/utils";
import Button from "../ui/Button";
import { useTranslation } from "next-i18next";
import { useAddToken } from "@/hooks/store/tokens";
+import CopyButton from "../CopyButton";
type Props = {
onClose: Function;
@@ -68,21 +69,14 @@ export default function NewTokenModal({ onClose }: Props) {
{t("access_token_created")}
{t("token_creation_notice")}
-
{}}
- className="w-full"
- />
-
+
) : (
<>
diff --git a/components/ModalContent/PreservedFormatsModal.tsx b/components/ModalContent/PreservedFormatsModal.tsx
index 5a0983c..d883a21 100644
--- a/components/ModalContent/PreservedFormatsModal.tsx
+++ b/components/ModalContent/PreservedFormatsModal.tsx
@@ -91,14 +91,14 @@ export default function PreservedFormatsModal({ onClose, link }: Props) {
useEffect(() => {
(async () => {
- await getLink.mutateAsync(link.id as number);
+ await getLink.mutateAsync({ id: link.id as number });
})();
let interval: NodeJS.Timeout | null = null;
if (!isReady()) {
interval = setInterval(async () => {
- await getLink.mutateAsync(link.id as number);
+ await getLink.mutateAsync({ id: link.id as number });
}, 5000);
} else {
if (interval) {
@@ -124,7 +124,7 @@ export default function PreservedFormatsModal({ onClose, link }: Props) {
toast.dismiss(load);
if (response.ok) {
- await getLink.mutateAsync(link?.id as number);
+ await getLink.mutateAsync({ id: link.id as number });
toast.success(t("link_being_archived"));
} else toast.error(data.response);
diff --git a/components/ModalContent/UploadFileModal.tsx b/components/ModalContent/UploadFileModal.tsx
index 7cb6fda..1627bb1 100644
--- a/components/ModalContent/UploadFileModal.tsx
+++ b/components/ModalContent/UploadFileModal.tsx
@@ -70,7 +70,7 @@ export default function UploadFileModal({ onClose }: Props) {
useEffect(() => {
setOptionsExpanded(false);
- if (router.query.id) {
+ if (router.pathname.startsWith("/collections/") && router.query.id) {
const currentCollection = collections.find(
(e) => e.id == Number(router.query.id)
);
diff --git a/components/PreserverdFormatRow.tsx b/components/PreserverdFormatRow.tsx
index 58ee648..7919807 100644
--- a/components/PreserverdFormatRow.tsx
+++ b/components/PreserverdFormatRow.tsx
@@ -49,11 +49,9 @@ export default function PreservedFormatRow({
};
return (
-
+
@@ -61,7 +59,7 @@ export default function PreservedFormatRow({
{downloadable || false ? (
handleDownload()}
- className="btn btn-sm btn-square"
+ className="btn btn-sm btn-square btn-ghost"
>
@@ -72,9 +70,9 @@ export default function PreservedFormatRow({
isPublic ? "/public" : ""
}/preserved/${link?.id}?format=${format}`}
target="_blank"
- className="btn btn-sm btn-square"
+ className="btn btn-sm btn-square btn-ghost"
>
-
+
diff --git a/components/ReadableView.tsx b/components/ReadableView.tsx
index 073e879..18477a0 100644
--- a/components/ReadableView.tsx
+++ b/components/ReadableView.tsx
@@ -46,13 +46,6 @@ export default function ReadableView({ link }: Props) {
const router = useRouter();
const getLink = useGetLink();
- const { data: collections = [] } = useCollections();
-
- const collection = useMemo(() => {
- return collections.find(
- (e) => e.id === link.collection.id
- ) as CollectionIncludingMembersAndLinkCount;
- }, [collections, link]);
useEffect(() => {
const fetchLinkContent = async () => {
@@ -73,7 +66,7 @@ export default function ReadableView({ link }: Props) {
}, [link]);
useEffect(() => {
- if (link) getLink.mutateAsync(link?.id as number);
+ if (link) getLink.mutateAsync({ id: link.id as number });
let interval: NodeJS.Timeout | null = null;
if (
@@ -88,7 +81,10 @@ export default function ReadableView({ link }: Props) {
!link?.monolith)
) {
interval = setInterval(
- () => getLink.mutateAsync(link.id as number),
+ () =>
+ getLink.mutateAsync({
+ id: link.id as number,
+ }),
5000
);
} else {
@@ -242,13 +238,6 @@ export default function ReadableView({ link }: Props) {
{link?.name ?
{unescapeString(link?.description)}
: undefined}
-
-
diff --git a/components/SortDropdown.tsx b/components/SortDropdown.tsx
index 7dee461..af9ed5f 100644
--- a/components/SortDropdown.tsx
+++ b/components/SortDropdown.tsx
@@ -3,6 +3,8 @@ import { Sort } from "@/types/global";
import { dropdownTriggerer } from "@/lib/client/utils";
import { TFunction } from "i18next";
import useLocalSettingsStore from "@/store/localSettings";
+import { resetInfiniteQueryPagination } from "@/hooks/store/links";
+import { useQueryClient } from "@tanstack/react-query";
type Props = {
sortBy: Sort;
@@ -12,6 +14,7 @@ type Props = {
export default function SortDropdown({ sortBy, setSort, t }: Props) {
const { updateSettings } = useLocalSettingsStore();
+ const queryClient = useQueryClient();
useEffect(() => {
updateSettings({ sortBy });
@@ -39,7 +42,10 @@ export default function SortDropdown({ sortBy, setSort, t }: Props) {
name="sort-radio"
className="radio checked:bg-primary"
checked={sortBy === Sort.DateNewestFirst}
- onChange={() => setSort(Sort.DateNewestFirst)}
+ onChange={() => {
+ resetInfiniteQueryPagination(queryClient, ["links"]);
+ setSort(Sort.DateNewestFirst);
+ }}
/>
{t("date_newest_first")}
@@ -57,7 +63,10 @@ export default function SortDropdown({ sortBy, setSort, t }: Props) {
name="sort-radio"
className="radio checked:bg-primary"
checked={sortBy === Sort.DateOldestFirst}
- onChange={() => setSort(Sort.DateOldestFirst)}
+ onChange={() => {
+ resetInfiniteQueryPagination(queryClient, ["links"]);
+ setSort(Sort.DateOldestFirst);
+ }}
/>
{t("date_oldest_first")}
@@ -75,7 +84,10 @@ export default function SortDropdown({ sortBy, setSort, t }: Props) {
name="sort-radio"
className="radio checked:bg-primary"
checked={sortBy === Sort.NameAZ}
- onChange={() => setSort(Sort.NameAZ)}
+ onChange={() => {
+ resetInfiniteQueryPagination(queryClient, ["links"]);
+ setSort(Sort.NameAZ);
+ }}
/>
{t("name_az")}
@@ -91,7 +103,10 @@ export default function SortDropdown({ sortBy, setSort, t }: Props) {
name="sort-radio"
className="radio checked:bg-primary"
checked={sortBy === Sort.NameZA}
- onChange={() => setSort(Sort.NameZA)}
+ onChange={() => {
+ resetInfiniteQueryPagination(queryClient, ["links"]);
+ setSort(Sort.NameZA);
+ }}
/>
{t("name_za")}
@@ -107,7 +122,10 @@ export default function SortDropdown({ sortBy, setSort, t }: Props) {
name="sort-radio"
className="radio checked:bg-primary"
checked={sortBy === Sort.DescriptionAZ}
- onChange={() => setSort(Sort.DescriptionAZ)}
+ onChange={() => {
+ resetInfiniteQueryPagination(queryClient, ["links"]);
+ setSort(Sort.DescriptionAZ);
+ }}
/>
{t("description_az")}
@@ -125,7 +143,10 @@ export default function SortDropdown({ sortBy, setSort, t }: Props) {
name="sort-radio"
className="radio checked:bg-primary"
checked={sortBy === Sort.DescriptionZA}
- onChange={() => setSort(Sort.DescriptionZA)}
+ onChange={() => {
+ resetInfiniteQueryPagination(queryClient, ["links"]);
+ setSort(Sort.DescriptionZA);
+ }}
/>
{t("description_za")}
diff --git a/hooks/store/links.tsx b/hooks/store/links.tsx
index 4702ff4..6d2177f 100644
--- a/hooks/store/links.tsx
+++ b/hooks/store/links.tsx
@@ -159,20 +159,23 @@ const useUpdateLink = () => {
return data.response;
},
onSuccess: (data) => {
- queryClient.setQueryData(["dashboardData"], (oldData: any) => {
- if (!oldData) return undefined;
- return oldData.map((e: any) => (e.id === data.id ? data : e));
- });
+ // queryClient.setQueryData(["dashboardData"], (oldData: any) => {
+ // if (!oldData) return undefined;
+ // return oldData.map((e: any) => (e.id === data.id ? data : e));
+ // });
- queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
- if (!oldData) return undefined;
- return {
- pages: oldData.pages.map((page: any) =>
- page.map((item: any) => (item.id === data.id ? data : item))
- ),
- pageParams: oldData.pageParams,
- };
- });
+ // queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
+ // if (!oldData) return undefined;
+ // return {
+ // pages: oldData.pages.map((page: any) =>
+ // page.map((item: any) => (item.id === data.id ? data : item))
+ // ),
+ // pageParams: oldData.pageParams,
+ // };
+ // });
+
+ queryClient.invalidateQueries({ queryKey: ["links"] }); // Temporary workaround
+ queryClient.invalidateQueries({ queryKey: ["dashboardData"] }); // Temporary workaround
queryClient.invalidateQueries({ queryKey: ["collections"] });
queryClient.invalidateQueries({ queryKey: ["tags"] });
@@ -222,9 +225,21 @@ const useDeleteLink = () => {
const useGetLink = () => {
const queryClient = useQueryClient();
+ const router = useRouter();
+
return useMutation({
- mutationFn: async (id: number) => {
- const response = await fetch(`/api/v1/links/${id}`);
+ mutationFn: async ({
+ id,
+ isPublicRoute = router.pathname.startsWith("/public") ? true : undefined,
+ }: {
+ id: number;
+ isPublicRoute?: boolean;
+ }) => {
+ const path = isPublicRoute
+ ? `/api/v1/public/links/${id}`
+ : `/api/v1/links/${id}`;
+
+ const response = await fetch(path);
const data = await response.json();
if (!response.ok) throw new Error(data.response);
@@ -247,7 +262,20 @@ const useGetLink = () => {
};
});
- queryClient.invalidateQueries({ queryKey: ["publicLinks"] });
+ queryClient.setQueriesData(
+ { queryKey: ["publicLinks"] },
+ (oldData: any) => {
+ if (!oldData) return undefined;
+ return {
+ pages: oldData.pages.map((page: any) =>
+ page.map((item: any) => (item.id === data.id ? data : item))
+ ),
+ pageParams: oldData.pageParams,
+ };
+ }
+ );
+
+ // queryClient.invalidateQueries({ queryKey: ["publicLinks"] });
},
});
};
@@ -398,14 +426,13 @@ const useBulkEditLinks = () => {
return data.response;
},
onSuccess: (data, { links, newData, removePreviousTags }) => {
- queryClient.setQueryData(["dashboardData"], (oldData: any) => {
- if (!oldData) return undefined;
- return oldData.map((e: any) =>
- data.find((d: any) => d.id === e.id) ? data : e
- );
- });
-
- // TODO: Fix this
+ // TODO: Fix these
+ // queryClient.setQueryData(["dashboardData"], (oldData: any) => {
+ // if (!oldData) return undefined;
+ // return oldData.map((e: any) =>
+ // data.find((d: any) => d.id === e.id) ? data : e
+ // );
+ // });
// queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
// if (!oldData) return undefined;
// return {
@@ -417,6 +444,7 @@ const useBulkEditLinks = () => {
// };
// });
queryClient.invalidateQueries({ queryKey: ["links"] }); // Temporary workaround
+ queryClient.invalidateQueries({ queryKey: ["dashboardData"] }); // Temporary workaround
queryClient.invalidateQueries({ queryKey: ["collections"] });
queryClient.invalidateQueries({ queryKey: ["tags"] });
@@ -425,6 +453,22 @@ const useBulkEditLinks = () => {
});
};
+const resetInfiniteQueryPagination = async (
+ queryClient: any,
+ queryKey: any
+) => {
+ queryClient.setQueriesData({ queryKey }, (oldData: any) => {
+ if (!oldData) return undefined;
+
+ return {
+ pages: oldData.pages.slice(0, 1),
+ pageParams: oldData.pageParams.slice(0, 1),
+ };
+ });
+
+ await queryClient.invalidateQueries(queryKey);
+};
+
export {
useLinks,
useAddLink,
@@ -434,4 +478,5 @@ export {
useUploadFile,
useGetLink,
useBulkEditLinks,
+ resetInfiniteQueryPagination,
};
diff --git a/lib/client/getPublicCollectionData.ts b/lib/client/getPublicCollectionData.ts
index a8a74a3..c87abd1 100644
--- a/lib/client/getPublicCollectionData.ts
+++ b/lib/client/getPublicCollectionData.ts
@@ -1,12 +1,4 @@
-import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
-import { Dispatch, SetStateAction } from "react";
-
-const getPublicCollectionData = async (
- collectionId: number,
- setData: Dispatch<
- SetStateAction
- >
-) => {
+const getPublicCollectionData = async (collectionId: number) => {
const res = await fetch("/api/v1/public/collections/" + collectionId);
if (res.status === 400)
@@ -14,8 +6,6 @@ const getPublicCollectionData = async (
const data = await res.json();
- setData(data.response);
-
return data;
};
diff --git a/lib/client/icons.ts b/lib/client/icons.ts
new file mode 100644
index 0000000..2083bd0
--- /dev/null
+++ b/lib/client/icons.ts
@@ -0,0 +1,18 @@
+import * as Icons from "@phosphor-icons/react";
+import { icons as iconData } from "@phosphor-icons/core";
+import { IconEntry as CoreEntry } from "@phosphor-icons/core";
+
+interface IconEntry extends CoreEntry {
+ Icon: Icons.Icon;
+}
+
+export const icons: ReadonlyArray = iconData.map((entry) => ({
+ ...entry,
+ Icon: Icons[entry.pascal_name as keyof typeof Icons] as Icons.Icon,
+}));
+
+if (process.env.NODE_ENV === "development") {
+ console.log(`${icons.length} icons`);
+}
+
+export const iconCount = Intl.NumberFormat("en-US").format(icons.length * 6);
diff --git a/package.json b/package.json
index 6a592e9..0e72474 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "linkwarden",
- "version": "v2.7.0",
+ "version": "v2.8.0",
"main": "index.js",
"repository": "https://github.com/linkwarden/linkwarden.git",
"author": "Daniel31X13 ",
@@ -25,6 +25,8 @@
"@aws-sdk/client-s3": "^3.379.1",
"@headlessui/react": "^1.7.15",
"@mozilla/readability": "^0.4.4",
+ "@phosphor-icons/core": "^2.1.1",
+ "@phosphor-icons/react": "^2.1.7",
"@prisma/client": "^4.16.2",
"@stripe/stripe-js": "^1.54.1",
"@tanstack/react-query": "^5.51.15",
@@ -50,6 +52,7 @@
"eslint-config-next": "13.4.9",
"formidable": "^3.5.1",
"framer-motion": "^10.16.4",
+ "fuse.js": "^7.0.0",
"handlebars": "^4.7.8",
"himalaya": "^1.1.0",
"i18next": "^23.11.5",
@@ -76,7 +79,7 @@
"socks-proxy-agent": "^8.0.2",
"stripe": "^12.13.0",
"tailwind-merge": "^2.3.0",
- "vaul": "^0.8.8",
+ "vaul": "^0.9.1",
"zustand": "^4.3.8"
},
"devDependencies": {
@@ -92,7 +95,7 @@
"postcss": "^8.4.26",
"prettier": "3.1.1",
"prisma": "^4.16.2",
- "tailwindcss": "^3.3.3",
+ "tailwindcss": "^3.4.10",
"ts-node": "^10.9.2",
"typescript": "4.9.4"
}
diff --git a/pages/dashboard.tsx b/pages/dashboard.tsx
index 1d9192c..e0b107f 100644
--- a/pages/dashboard.tsx
+++ b/pages/dashboard.tsx
@@ -114,14 +114,14 @@ export default function Dashboard() {
-
+
diff --git a/pages/links/[id].tsx b/pages/links/[id].tsx
new file mode 100644
index 0000000..cfa8785
--- /dev/null
+++ b/pages/links/[id].tsx
@@ -0,0 +1,41 @@
+import LinkDetails from "@/components/LinkDetails";
+import { useGetLink } from "@/hooks/store/links";
+import { useRouter } from "next/router";
+import { useEffect, useState } from "react";
+import getServerSideProps from "@/lib/client/getServerSideProps";
+
+const Index = () => {
+ const router = useRouter();
+ const { id } = router.query;
+
+ useState;
+
+ const getLink = useGetLink();
+
+ useEffect(() => {
+ getLink.mutate({ id: Number(id) });
+ }, []);
+
+ return (
+
+ {getLink.data ? (
+
+ ) : (
+
+ )}
+
+ );
+};
+
+export default Index;
+
+export { getServerSideProps };
diff --git a/pages/preserved/[id].tsx b/pages/preserved/[id].tsx
index c5806ff..de21605 100644
--- a/pages/preserved/[id].tsx
+++ b/pages/preserved/[id].tsx
@@ -20,7 +20,7 @@ export default function Index() {
useEffect(() => {
const fetchLink = async () => {
if (router.query.id) {
- await getLink.mutateAsync(Number(router.query.id));
+ await getLink.mutateAsync({ id: Number(router.query.id) });
}
};
diff --git a/pages/public/collections/[id].tsx b/pages/public/collections/[id].tsx
index 98153cb..4c5f777 100644
--- a/pages/public/collections/[id].tsx
+++ b/pages/public/collections/[id].tsx
@@ -20,7 +20,6 @@ import EditCollectionSharingModal from "@/components/ModalContent/EditCollection
import { useTranslation } from "next-i18next";
import getServerSideProps from "@/lib/client/getServerSideProps";
import LinkListOptions from "@/components/LinkListOptions";
-import { useCollections } from "@/hooks/store/collections";
import { usePublicLinks } from "@/hooks/store/publicLinks";
import Links from "@/components/LinkViews/Links";
@@ -29,8 +28,6 @@ export default function PublicCollections() {
const { settings } = useLocalSettingsStore();
- const { data: collections = [] } = useCollections();
-
const router = useRouter();
const [collectionOwner, setCollectionOwner] = useState<
@@ -66,25 +63,22 @@ export default function PublicCollections() {
useEffect(() => {
if (router.query.id) {
- getPublicCollectionData(Number(router.query.id), setCollection).then(
- (res) => {
- if (res.status === 400) {
- router.push("/dashboard");
- }
+ getPublicCollectionData(Number(router.query.id)).then((res) => {
+ if (res.status === 400) {
+ router.push("/dashboard");
+ } else {
+ setCollection(res.response);
}
- );
+ });
}
- }, [collections]);
+ }, []);
useEffect(() => {
- const fetchOwner = async () => {
- if (collection) {
- const owner = await getPublicUserData(collection.ownerId as number);
- setCollectionOwner(owner);
- }
- };
-
- fetchOwner();
+ if (collection) {
+ getPublicUserData(collection.ownerId as number).then((owner) =>
+ setCollectionOwner(owner)
+ );
+ }
}, [collection]);
const [editCollectionSharingModal, setEditCollectionSharingModal] =
@@ -233,9 +227,7 @@ export default function PublicCollections() {
placeholderCount={1}
useData={data}
/>
- {!data.isLoading && links && !links[0] && (
-
{t("collection_is_empty")}
- )}
+ {!data.isLoading && links && !links[0] &&
{t("nothing_found")}
}
{/*
List created with Linkwarden.
diff --git a/pages/public/links/[id].tsx b/pages/public/links/[id].tsx
new file mode 100644
index 0000000..cfa8785
--- /dev/null
+++ b/pages/public/links/[id].tsx
@@ -0,0 +1,41 @@
+import LinkDetails from "@/components/LinkDetails";
+import { useGetLink } from "@/hooks/store/links";
+import { useRouter } from "next/router";
+import { useEffect, useState } from "react";
+import getServerSideProps from "@/lib/client/getServerSideProps";
+
+const Index = () => {
+ const router = useRouter();
+ const { id } = router.query;
+
+ useState;
+
+ const getLink = useGetLink();
+
+ useEffect(() => {
+ getLink.mutate({ id: Number(id) });
+ }, []);
+
+ return (
+
+ {getLink.data ? (
+
+ ) : (
+
+ )}
+
+ );
+};
+
+export default Index;
+
+export { getServerSideProps };
diff --git a/pages/public/preserved/[id].tsx b/pages/public/preserved/[id].tsx
index 2f415ae..31544b0 100644
--- a/pages/public/preserved/[id].tsx
+++ b/pages/public/preserved/[id].tsx
@@ -6,10 +6,9 @@ import {
} from "@/types/global";
import ReadableView from "@/components/ReadableView";
import getServerSideProps from "@/lib/client/getServerSideProps";
-import { useGetLink, useLinks } from "@/hooks/store/links";
+import { useGetLink } from "@/hooks/store/links";
export default function Index() {
- const { links } = useLinks();
const getLink = useGetLink();
const [link, setLink] = useState
();
@@ -19,18 +18,14 @@ export default function Index() {
useEffect(() => {
const fetchLink = async () => {
if (router.query.id) {
- await getLink.mutateAsync(Number(router.query.id));
+ const get = await getLink.mutateAsync({ id: Number(router.query.id) });
+ setLink(get);
}
};
fetchLink();
}, []);
- useEffect(() => {
- if (links && links[0])
- setLink(links.find((e) => e.id === Number(router.query.id)));
- }, [links]);
-
return (
{/*
@@ -39,6 +34,12 @@ export default function Index() {
{link && Number(router.query.format) === ArchivedFormat.readability && (
)}
+ {link && Number(router.query.format) === ArchivedFormat.monolith && (
+
+ )}
{link && Number(router.query.format) === ArchivedFormat.pdf && (