Added allLinksOfCollection to linksStore
Removed duplicated tags Fixed overflow for line added disclosure for tags in public collection
This commit is contained in:
+40
-25
@@ -18,7 +18,7 @@ export default function useLinks(
|
|||||||
searchByTextContent,
|
searchByTextContent,
|
||||||
}: LinkRequestQuery = { sort: 0 }
|
}: LinkRequestQuery = { sort: 0 }
|
||||||
) {
|
) {
|
||||||
const { links, setLinks, resetLinks, selectedLinks, setSelectedLinks } =
|
const { links, setLinks, resetLinks, selectedLinks, setSelectedLinks, setAllLinksOfCollection } =
|
||||||
useLinkStore();
|
useLinkStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -26,6 +26,34 @@ export default function useLinks(
|
|||||||
|
|
||||||
const { reachedBottom, setReachedBottom } = useDetectPageBottom();
|
const { reachedBottom, setReachedBottom } = useDetectPageBottom();
|
||||||
|
|
||||||
|
const getPath = (params?: LinkRequestQuery) => {
|
||||||
|
const buildQueryString = (params: LinkRequestQuery) => {
|
||||||
|
return Object.keys(params)
|
||||||
|
.filter((key) => params[key as keyof LinkRequestQuery] !== undefined)
|
||||||
|
.map(
|
||||||
|
(key) =>
|
||||||
|
`${encodeURIComponent(key)}=${encodeURIComponent(
|
||||||
|
params[key as keyof LinkRequestQuery] as string
|
||||||
|
)}`
|
||||||
|
)
|
||||||
|
.join("&");
|
||||||
|
};
|
||||||
|
let queryString = '';
|
||||||
|
if (params) {
|
||||||
|
queryString = buildQueryString(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
let basePath;
|
||||||
|
|
||||||
|
if (router.pathname === "/dashboard") basePath = "/api/v1/dashboard";
|
||||||
|
else if (router.pathname.startsWith("/public/collections/[id]")) {
|
||||||
|
queryString = queryString + "&collectionId=" + router.query.id;
|
||||||
|
basePath = "/api/v1/public/collections/links";
|
||||||
|
} else basePath = "/api/v1/links";
|
||||||
|
|
||||||
|
return `${basePath}?${queryString}`;
|
||||||
|
}
|
||||||
|
|
||||||
const getLinks = async (isInitialCall: boolean, cursor?: number) => {
|
const getLinks = async (isInitialCall: boolean, cursor?: number) => {
|
||||||
const params = {
|
const params = {
|
||||||
sort,
|
sort,
|
||||||
@@ -40,32 +68,10 @@ export default function useLinks(
|
|||||||
searchByTags,
|
searchByTags,
|
||||||
searchByTextContent,
|
searchByTextContent,
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildQueryString = (params: LinkRequestQuery) => {
|
|
||||||
return Object.keys(params)
|
|
||||||
.filter((key) => params[key as keyof LinkRequestQuery] !== undefined)
|
|
||||||
.map(
|
|
||||||
(key) =>
|
|
||||||
`${encodeURIComponent(key)}=${encodeURIComponent(
|
|
||||||
params[key as keyof LinkRequestQuery] as string
|
|
||||||
)}`
|
|
||||||
)
|
|
||||||
.join("&");
|
|
||||||
};
|
|
||||||
|
|
||||||
let queryString = buildQueryString(params);
|
|
||||||
|
|
||||||
let basePath;
|
|
||||||
|
|
||||||
if (router.pathname === "/dashboard") basePath = "/api/v1/dashboard";
|
|
||||||
else if (router.pathname.startsWith("/public/collections/[id]")) {
|
|
||||||
queryString = queryString + "&collectionId=" + router.query.id;
|
|
||||||
basePath = "/api/v1/public/collections/links";
|
|
||||||
} else basePath = "/api/v1/links";
|
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
const response = await fetch(`${basePath}?${queryString}`);
|
const response = await fetch(getPath(params));
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
@@ -74,6 +80,14 @@ export default function useLinks(
|
|||||||
if (response.ok) setLinks(data.response, isInitialCall);
|
if (response.ok) setLinks(data.response, isInitialCall);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getAllLinks = async () => {
|
||||||
|
const response = await fetch(getPath());
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (response.ok) setAllLinksOfCollection(data.response);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Save the selected links before resetting the links
|
// Save the selected links before resetting the links
|
||||||
// and then restore the selected links after resetting the links
|
// and then restore the selected links after resetting the links
|
||||||
@@ -81,6 +95,7 @@ export default function useLinks(
|
|||||||
resetLinks();
|
resetLinks();
|
||||||
|
|
||||||
setSelectedLinks(previouslySelected);
|
setSelectedLinks(previouslySelected);
|
||||||
|
getAllLinks();
|
||||||
getLinks(true);
|
getLinks(true);
|
||||||
}, [
|
}, [
|
||||||
router,
|
router,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import ViewDropdown from "@/components/ViewDropdown";
|
|||||||
import CardView from "@/components/LinkViews/Layouts/CardView";
|
import CardView from "@/components/LinkViews/Layouts/CardView";
|
||||||
import ListView from "@/components/LinkViews/Layouts/ListView";
|
import ListView from "@/components/LinkViews/Layouts/ListView";
|
||||||
import useTagStore from "@/store/tags";
|
import useTagStore from "@/store/tags";
|
||||||
|
import { Disclosure, Transition } from "@headlessui/react";
|
||||||
// import GridView from "@/components/LinkViews/Layouts/GridView";
|
// import GridView from "@/components/LinkViews/Layouts/GridView";
|
||||||
|
|
||||||
const cardVariants: Variants = {
|
const cardVariants: Variants = {
|
||||||
@@ -43,9 +44,11 @@ const cardVariants: Variants = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function PublicCollections() {
|
export default function PublicCollections() {
|
||||||
const { links } = useLinkStore();
|
const { links, allLinksOfCollection } = useLinkStore();
|
||||||
const tagsInCollection = links.map(l => l.tags).flat();
|
const tagsInCollection = allLinksOfCollection.map(l => l.tags).flat().filter((value, index, self) =>
|
||||||
|
index === self.findIndex((t) => (
|
||||||
|
t.name === value.name
|
||||||
|
)));
|
||||||
const { settings } = useLocalSettingsStore();
|
const { settings } = useLocalSettingsStore();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -101,7 +104,6 @@ export default function PublicCollections() {
|
|||||||
|
|
||||||
const [collection, setCollection] =
|
const [collection, setCollection] =
|
||||||
useState<CollectionIncludingMembersAndLinkCount>();
|
useState<CollectionIncludingMembersAndLinkCount>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (router.query.id) {
|
if (router.query.id) {
|
||||||
getPublicCollectionData(Number(router.query.id), setCollection);
|
getPublicCollectionData(Number(router.query.id), setCollection);
|
||||||
@@ -132,6 +134,14 @@ export default function PublicCollections() {
|
|||||||
[ViewMode.List]: ListView,
|
[ViewMode.List]: ListView,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [tagDisclosure, setTagDisclosure] = useState<boolean>(() => {
|
||||||
|
const storedValue = localStorage.getItem("tagDisclosureForPublicCollection" + collection?.id);
|
||||||
|
return storedValue ? storedValue === "true" : true;
|
||||||
|
});
|
||||||
|
useEffect(() => {
|
||||||
|
localStorage.setItem("tagDisclosureForPublicCollection" + collection?.id, tagDisclosure ? "true" : "false");
|
||||||
|
}, [tagDisclosure]);
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const LinkComponent = linkView[viewMode];
|
const LinkComponent = linkView[viewMode];
|
||||||
|
|
||||||
@@ -243,10 +253,31 @@ export default function PublicCollections() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{collection.tagsArePublic && tagsInCollection[0] && (
|
{collection.tagsArePublic && tagsInCollection[0] && (
|
||||||
<div>
|
<Disclosure defaultOpen={tagDisclosure}>
|
||||||
<p className="text-sm">Browse by topic</p>
|
<Disclosure.Button
|
||||||
<div className="flex gap-2 mt-2 mb-6">
|
onClick={() => {
|
||||||
<button onClick={() => handleTagSelection(undefined)}>
|
setTagDisclosure(!tagDisclosure);
|
||||||
|
}}
|
||||||
|
className="flex items-center justify-between w-full text-left mb-2 pl-2 font-bold text-neutral mt-5"
|
||||||
|
>
|
||||||
|
<p className="text-sm">Browse by topic</p>
|
||||||
|
<i
|
||||||
|
className={`bi-chevron-down ${
|
||||||
|
tagDisclosure ? "rotate-reverse" : "rotate"
|
||||||
|
}`}
|
||||||
|
></i>
|
||||||
|
</Disclosure.Button>
|
||||||
|
<Transition
|
||||||
|
enter="transition duration-100 ease-out"
|
||||||
|
enterFrom="transform opacity-0 -translate-y-3"
|
||||||
|
enterTo="transform opacity-100 translate-y-0"
|
||||||
|
leave="transition duration-100 ease-out"
|
||||||
|
leaveFrom="transform opacity-100 translate-y-0"
|
||||||
|
leaveTo="transform opacity-0 -translate-y-3"
|
||||||
|
>
|
||||||
|
<Disclosure.Panel>
|
||||||
|
<div className="flex gap-2 mt-2 mb-6 flex-wrap">
|
||||||
|
<button className="max-w-full" onClick={() => handleTagSelection(undefined)}>
|
||||||
<div
|
<div
|
||||||
className="
|
className="
|
||||||
bg-neutral-content/20 hover:bg-neutral/20 duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 rounded-md h-8"
|
bg-neutral-content/20 hover:bg-neutral/20 duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 rounded-md h-8"
|
||||||
@@ -263,7 +294,7 @@ export default function PublicCollections() {
|
|||||||
.map((e, i) => {
|
.map((e, i) => {
|
||||||
const active = router.query.q === e.name;
|
const active = router.query.q === e.name;
|
||||||
return (
|
return (
|
||||||
<button key={i} onClick={() => handleTagSelection(e)}>
|
<button className="max-w-full" key={i} onClick={() => handleTagSelection(e)}>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`
|
||||||
${
|
${
|
||||||
@@ -283,8 +314,9 @@ export default function PublicCollections() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Disclosure.Panel>
|
||||||
)}
|
</Transition>
|
||||||
|
</Disclosure>)}
|
||||||
{links[0] ? (
|
{links[0] ? (
|
||||||
<LinkComponent
|
<LinkComponent
|
||||||
links={links
|
links={links
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ type ResponseObject = {
|
|||||||
type LinkStore = {
|
type LinkStore = {
|
||||||
links: LinkIncludingShortenedCollectionAndTags[];
|
links: LinkIncludingShortenedCollectionAndTags[];
|
||||||
selectedLinks: LinkIncludingShortenedCollectionAndTags[];
|
selectedLinks: LinkIncludingShortenedCollectionAndTags[];
|
||||||
|
allLinksOfCollection: LinkIncludingShortenedCollectionAndTags[];
|
||||||
setLinks: (
|
setLinks: (
|
||||||
data: LinkIncludingShortenedCollectionAndTags[],
|
data: LinkIncludingShortenedCollectionAndTags[],
|
||||||
isInitialCall: boolean
|
isInitialCall: boolean
|
||||||
) => void;
|
) => void;
|
||||||
setSelectedLinks: (links: LinkIncludingShortenedCollectionAndTags[]) => void;
|
setSelectedLinks: (links: LinkIncludingShortenedCollectionAndTags[]) => void;
|
||||||
|
setAllLinksOfCollection: (links: LinkIncludingShortenedCollectionAndTags[]) => void;
|
||||||
addLink: (
|
addLink: (
|
||||||
body: LinkIncludingShortenedCollectionAndTags
|
body: LinkIncludingShortenedCollectionAndTags
|
||||||
) => Promise<ResponseObject>;
|
) => Promise<ResponseObject>;
|
||||||
@@ -39,6 +41,7 @@ type LinkStore = {
|
|||||||
const useLinkStore = create<LinkStore>()((set) => ({
|
const useLinkStore = create<LinkStore>()((set) => ({
|
||||||
links: [],
|
links: [],
|
||||||
selectedLinks: [],
|
selectedLinks: [],
|
||||||
|
allLinksOfCollection: [],
|
||||||
setLinks: async (data, isInitialCall) => {
|
setLinks: async (data, isInitialCall) => {
|
||||||
isInitialCall &&
|
isInitialCall &&
|
||||||
set(() => ({
|
set(() => ({
|
||||||
@@ -58,6 +61,7 @@ const useLinkStore = create<LinkStore>()((set) => ({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
setSelectedLinks: (links) => set({ selectedLinks: links }),
|
setSelectedLinks: (links) => set({ selectedLinks: links }),
|
||||||
|
setAllLinksOfCollection: (links) => set({allLinksOfCollection: links}),
|
||||||
addLink: async (body) => {
|
addLink: async (body) => {
|
||||||
const response = await fetch("/api/v1/links", {
|
const response = await fetch("/api/v1/links", {
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
|||||||
Reference in New Issue
Block a user