update global (texte + logo)
This commit is contained in:
34
Linkwarden/hooks/useCollectivePermissions.ts
Normal file
34
Linkwarden/hooks/useCollectivePermissions.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import useAccountStore from "@/store/account";
|
||||
import useCollectionStore from "@/store/collections";
|
||||
import { Member } from "@/types/global";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function useCollectivePermissions(collectionIds: number[]) {
|
||||
const { collections } = useCollectionStore();
|
||||
|
||||
const { account } = useAccountStore();
|
||||
|
||||
const [permissions, setPermissions] = useState<Member | true>();
|
||||
useEffect(() => {
|
||||
for (const collectionId of collectionIds) {
|
||||
const collection = collections.find((e) => e.id === collectionId);
|
||||
|
||||
if (collection) {
|
||||
let getPermission: Member | undefined = collection.members.find(
|
||||
(e) => e.userId === account.id
|
||||
);
|
||||
|
||||
if (
|
||||
getPermission?.canCreate === false &&
|
||||
getPermission?.canUpdate === false &&
|
||||
getPermission?.canDelete === false
|
||||
)
|
||||
getPermission = undefined;
|
||||
|
||||
setPermissions(account.id === collection.ownerId || getPermission);
|
||||
}
|
||||
}
|
||||
}, [account, collections, collectionIds]);
|
||||
|
||||
return permissions;
|
||||
}
|
26
Linkwarden/hooks/useDetectPageBottom.tsx
Normal file
26
Linkwarden/hooks/useDetectPageBottom.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
const useDetectPageBottom = () => {
|
||||
const [reachedBottom, setReachedBottom] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const totalHeight = document.documentElement.scrollHeight;
|
||||
const scrolledHeight = window.scrollY + window.innerHeight;
|
||||
|
||||
if (scrolledHeight >= totalHeight) {
|
||||
setReachedBottom(true);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("scroll", handleScroll);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return { reachedBottom, setReachedBottom };
|
||||
};
|
||||
|
||||
export default useDetectPageBottom;
|
32
Linkwarden/hooks/useInitialData.tsx
Normal file
32
Linkwarden/hooks/useInitialData.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import useCollectionStore from "@/store/collections";
|
||||
import { useEffect } from "react";
|
||||
import { useSession } from "next-auth/react";
|
||||
import useTagStore from "@/store/tags";
|
||||
import useAccountStore from "@/store/account";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
|
||||
export default function useInitialData() {
|
||||
const { status, data } = useSession();
|
||||
const { setCollections } = useCollectionStore();
|
||||
const { setTags } = useTagStore();
|
||||
// const { setLinks } = useLinkStore();
|
||||
const { account, setAccount } = useAccountStore();
|
||||
const { setSettings } = useLocalSettingsStore();
|
||||
|
||||
useEffect(() => {
|
||||
setSettings();
|
||||
if (status === "authenticated") {
|
||||
// Get account info
|
||||
setAccount(data?.user.id as number);
|
||||
}
|
||||
}, [status, data]);
|
||||
|
||||
// Get the rest of the data
|
||||
useEffect(() => {
|
||||
if (account.id && (!process.env.NEXT_PUBLIC_STRIPE || account.username)) {
|
||||
setCollections();
|
||||
setTags();
|
||||
// setLinks();
|
||||
}
|
||||
}, [account]);
|
||||
}
|
103
Linkwarden/hooks/useLinks.tsx
Normal file
103
Linkwarden/hooks/useLinks.tsx
Normal file
@ -0,0 +1,103 @@
|
||||
import { LinkRequestQuery } from "@/types/global";
|
||||
import { useEffect, useState } from "react";
|
||||
import useDetectPageBottom from "./useDetectPageBottom";
|
||||
import { useRouter } from "next/router";
|
||||
import useLinkStore from "@/store/links";
|
||||
|
||||
export default function useLinks(
|
||||
{
|
||||
sort,
|
||||
collectionId,
|
||||
tagId,
|
||||
pinnedOnly,
|
||||
searchQueryString,
|
||||
searchByName,
|
||||
searchByUrl,
|
||||
searchByDescription,
|
||||
searchByTags,
|
||||
searchByTextContent,
|
||||
}: LinkRequestQuery = { sort: 0 }
|
||||
) {
|
||||
const { links, setLinks, resetLinks, selectedLinks, setSelectedLinks } =
|
||||
useLinkStore();
|
||||
const router = useRouter();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const { reachedBottom, setReachedBottom } = useDetectPageBottom();
|
||||
|
||||
const getLinks = async (isInitialCall: boolean, cursor?: number) => {
|
||||
const params = {
|
||||
sort,
|
||||
cursor,
|
||||
collectionId,
|
||||
tagId,
|
||||
pinnedOnly,
|
||||
searchQueryString,
|
||||
searchByName,
|
||||
searchByUrl,
|
||||
searchByDescription,
|
||||
searchByTags,
|
||||
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);
|
||||
|
||||
const response = await fetch(`${basePath}?${queryString}`);
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
setIsLoading(false);
|
||||
|
||||
if (response.ok) setLinks(data.response, isInitialCall);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Save the selected links before resetting the links
|
||||
// and then restore the selected links after resetting the links
|
||||
const previouslySelected = selectedLinks;
|
||||
resetLinks();
|
||||
|
||||
setSelectedLinks(previouslySelected);
|
||||
getLinks(true);
|
||||
}, [
|
||||
router,
|
||||
sort,
|
||||
searchQueryString,
|
||||
searchByName,
|
||||
searchByUrl,
|
||||
searchByDescription,
|
||||
searchByTextContent,
|
||||
searchByTags,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (reachedBottom) getLinks(false, links?.at(-1)?.id);
|
||||
|
||||
setReachedBottom(false);
|
||||
}, [reachedBottom]);
|
||||
|
||||
return { isLoading };
|
||||
}
|
20
Linkwarden/hooks/useOnScreen.tsx
Normal file
20
Linkwarden/hooks/useOnScreen.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { RefObject, useEffect, useMemo, useState } from "react";
|
||||
|
||||
export default function useOnScreen(ref: RefObject<HTMLElement>) {
|
||||
const [isIntersecting, setIntersecting] = useState(false);
|
||||
|
||||
const observer = useMemo(
|
||||
() =>
|
||||
new IntersectionObserver(([entry]) =>
|
||||
setIntersecting(entry.isIntersecting)
|
||||
),
|
||||
[ref]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
observer.observe(ref.current as HTMLElement);
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
return isIntersecting;
|
||||
}
|
32
Linkwarden/hooks/usePermissions.tsx
Normal file
32
Linkwarden/hooks/usePermissions.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import useAccountStore from "@/store/account";
|
||||
import useCollectionStore from "@/store/collections";
|
||||
import { Member } from "@/types/global";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function usePermissions(collectionId: number) {
|
||||
const { collections } = useCollectionStore();
|
||||
|
||||
const { account } = useAccountStore();
|
||||
|
||||
const [permissions, setPermissions] = useState<Member | true>();
|
||||
useEffect(() => {
|
||||
const collection = collections.find((e) => e.id === collectionId);
|
||||
|
||||
if (collection) {
|
||||
let getPermission: Member | undefined = collection.members.find(
|
||||
(e) => e.userId === account.id
|
||||
);
|
||||
|
||||
if (
|
||||
getPermission?.canCreate === false &&
|
||||
getPermission?.canUpdate === false &&
|
||||
getPermission?.canDelete === false
|
||||
)
|
||||
getPermission = undefined;
|
||||
|
||||
setPermissions(account.id === collection.ownerId || getPermission);
|
||||
}
|
||||
}, [account, collections, collectionId]);
|
||||
|
||||
return permissions;
|
||||
}
|
56
Linkwarden/hooks/useSort.tsx
Normal file
56
Linkwarden/hooks/useSort.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import {
|
||||
CollectionIncludingMembersAndLinkCount,
|
||||
LinkIncludingShortenedCollectionAndTags,
|
||||
Sort,
|
||||
} from "@/types/global";
|
||||
import { SetStateAction, useEffect } from "react";
|
||||
|
||||
type Props<
|
||||
T extends
|
||||
| CollectionIncludingMembersAndLinkCount
|
||||
| LinkIncludingShortenedCollectionAndTags,
|
||||
> = {
|
||||
sortBy: Sort;
|
||||
|
||||
data: T[];
|
||||
setData: (value: SetStateAction<T[]>) => void;
|
||||
};
|
||||
|
||||
export default function useSort<
|
||||
T extends
|
||||
| CollectionIncludingMembersAndLinkCount
|
||||
| LinkIncludingShortenedCollectionAndTags,
|
||||
>({ sortBy, data, setData }: Props<T>) {
|
||||
useEffect(() => {
|
||||
const dataArray = [...data];
|
||||
|
||||
if (sortBy === Sort.NameAZ)
|
||||
setData(dataArray.sort((a, b) => a.name.localeCompare(b.name)));
|
||||
else if (sortBy === Sort.DescriptionAZ)
|
||||
setData(
|
||||
dataArray.sort((a, b) => a.description.localeCompare(b.description))
|
||||
);
|
||||
else if (sortBy === Sort.NameZA)
|
||||
setData(dataArray.sort((a, b) => b.name.localeCompare(a.name)));
|
||||
else if (sortBy === Sort.DescriptionZA)
|
||||
setData(
|
||||
dataArray.sort((a, b) => b.description.localeCompare(a.description))
|
||||
);
|
||||
else if (sortBy === Sort.DateNewestFirst)
|
||||
setData(
|
||||
dataArray.sort(
|
||||
(a, b) =>
|
||||
new Date(b.createdAt as string).getTime() -
|
||||
new Date(a.createdAt as string).getTime()
|
||||
)
|
||||
);
|
||||
else if (sortBy === Sort.DateOldestFirst)
|
||||
setData(
|
||||
dataArray.sort(
|
||||
(a, b) =>
|
||||
new Date(a.createdAt as string).getTime() -
|
||||
new Date(b.createdAt as string).getTime()
|
||||
)
|
||||
);
|
||||
}, [sortBy, data]);
|
||||
}
|
25
Linkwarden/hooks/useWindowDimensions.tsx
Normal file
25
Linkwarden/hooks/useWindowDimensions.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
export default function useWindowDimensions() {
|
||||
const [dimensions, setDimensions] = useState({
|
||||
height: window.innerHeight,
|
||||
width: window.innerWidth,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
function handleResize() {
|
||||
setDimensions({
|
||||
height: window.innerHeight,
|
||||
width: window.innerWidth,
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return dimensions;
|
||||
}
|
Reference in New Issue
Block a user