refactor account store + much smoother collection listing updates
This commit is contained in:
parent
d1ed33b532
commit
5c5dd967c4
|
@ -5,12 +5,12 @@ import ProfilePhoto from "./ProfilePhoto";
|
||||||
import usePermissions from "@/hooks/usePermissions";
|
import usePermissions from "@/hooks/usePermissions";
|
||||||
import useLocalSettingsStore from "@/store/localSettings";
|
import useLocalSettingsStore from "@/store/localSettings";
|
||||||
import getPublicUserData from "@/lib/client/getPublicUserData";
|
import getPublicUserData from "@/lib/client/getPublicUserData";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import EditCollectionModal from "./ModalContent/EditCollectionModal";
|
import EditCollectionModal from "./ModalContent/EditCollectionModal";
|
||||||
import EditCollectionSharingModal from "./ModalContent/EditCollectionSharingModal";
|
import EditCollectionSharingModal from "./ModalContent/EditCollectionSharingModal";
|
||||||
import DeleteCollectionModal from "./ModalContent/DeleteCollectionModal";
|
import DeleteCollectionModal from "./ModalContent/DeleteCollectionModal";
|
||||||
import { dropdownTriggerer } from "@/lib/client/utils";
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
collection: CollectionIncludingMembersAndLinkCount;
|
collection: CollectionIncludingMembersAndLinkCount;
|
||||||
|
@ -20,7 +20,7 @@ type Props = {
|
||||||
export default function CollectionCard({ collection, className }: Props) {
|
export default function CollectionCard({ collection, className }: Props) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { settings } = useLocalSettingsStore();
|
const { settings } = useLocalSettingsStore();
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
|
||||||
const formattedDate = new Date(collection.createdAt as string).toLocaleString(
|
const formattedDate = new Date(collection.createdAt as string).toLocaleString(
|
||||||
"en-US",
|
"en-US",
|
||||||
|
@ -45,18 +45,18 @@ export default function CollectionCard({ collection, className }: Props) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchOwner = async () => {
|
const fetchOwner = async () => {
|
||||||
if (collection && collection.ownerId !== account.id) {
|
if (collection && collection.ownerId !== user.id) {
|
||||||
const owner = await getPublicUserData(collection.ownerId as number);
|
const owner = await getPublicUserData(collection.ownerId as number);
|
||||||
setCollectionOwner(owner);
|
setCollectionOwner(owner);
|
||||||
} else if (collection && collection.ownerId === account.id) {
|
} else if (collection && collection.ownerId === user.id) {
|
||||||
setCollectionOwner({
|
setCollectionOwner({
|
||||||
id: account.id as number,
|
id: user.id as number,
|
||||||
name: account.name,
|
name: user.name,
|
||||||
username: account.username as string,
|
username: user.username as string,
|
||||||
image: account.image as string,
|
image: user.image as string,
|
||||||
archiveAsScreenshot: account.archiveAsScreenshot as boolean,
|
archiveAsScreenshot: user.archiveAsScreenshot as boolean,
|
||||||
archiveAsMonolith: account.archiveAsMonolith as boolean,
|
archiveAsMonolith: user.archiveAsMonolith as boolean,
|
||||||
archiveAsPDF: account.archiveAsPDF as boolean,
|
archiveAsPDF: user.archiveAsPDF as boolean,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,10 +13,10 @@ import { Collection } from "@prisma/client";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
|
import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import { useCollections, useUpdateCollection } from "@/hooks/store/collections";
|
import { useCollections, useUpdateCollection } from "@/hooks/store/collections";
|
||||||
|
import { useUpdateUser, useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
interface ExtendedTreeItem extends TreeItem {
|
interface ExtendedTreeItem extends TreeItem {
|
||||||
data: Collection;
|
data: Collection;
|
||||||
|
@ -25,54 +25,56 @@ interface ExtendedTreeItem extends TreeItem {
|
||||||
const CollectionListing = () => {
|
const CollectionListing = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const updateCollection = useUpdateCollection();
|
const updateCollection = useUpdateCollection();
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
const { account, updateAccount } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
const updateUser = useUpdateUser();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const currentPath = router.asPath;
|
const currentPath = router.asPath;
|
||||||
|
|
||||||
|
const [tree, setTree] = useState<TreeData | undefined>();
|
||||||
|
|
||||||
const initialTree = useMemo(() => {
|
const initialTree = useMemo(() => {
|
||||||
if (collections.length > 0) {
|
if (
|
||||||
|
// !tree &&
|
||||||
|
collections.length > 0
|
||||||
|
) {
|
||||||
return buildTreeFromCollections(
|
return buildTreeFromCollections(
|
||||||
collections,
|
collections,
|
||||||
router,
|
router,
|
||||||
account.collectionOrder
|
user.collectionOrder
|
||||||
);
|
);
|
||||||
}
|
} else return undefined;
|
||||||
return undefined;
|
}, [collections, user, router]);
|
||||||
}, [collections, router]);
|
|
||||||
|
|
||||||
const [tree, setTree] = useState(initialTree);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// if (!tree)
|
||||||
setTree(initialTree);
|
setTree(initialTree);
|
||||||
}, [initialTree]);
|
}, [initialTree]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (account.username) {
|
if (user.username) {
|
||||||
if (
|
if (
|
||||||
(!account.collectionOrder || account.collectionOrder.length === 0) &&
|
(!user.collectionOrder || user.collectionOrder.length === 0) &&
|
||||||
collections.length > 0
|
collections.length > 0
|
||||||
)
|
)
|
||||||
updateAccount({
|
updateUser.mutate({
|
||||||
...account,
|
...user,
|
||||||
collectionOrder: collections
|
collectionOrder: collections
|
||||||
.filter(
|
.filter(
|
||||||
(e) =>
|
(e) =>
|
||||||
e.parentId === null ||
|
e.parentId === null ||
|
||||||
!collections.find((i) => i.id === e.parentId)
|
!collections.find((i) => i.id === e.parentId)
|
||||||
) // Filter out collections with non-null parentId
|
) // Filter out collections with non-null parentId
|
||||||
.map((e) => e.id as number), // Use "as number" to assert that e.id is a number
|
.map((e) => e.id as number),
|
||||||
});
|
});
|
||||||
else {
|
else {
|
||||||
const newCollectionOrder: number[] = [
|
const newCollectionOrder: number[] = [...(user.collectionOrder || [])];
|
||||||
...(account.collectionOrder || []),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Start with collections that are in both account.collectionOrder and collections
|
// Start with collections that are in both account.collectionOrder and collections
|
||||||
const existingCollectionIds = collections.map((c) => c.id as number);
|
const existingCollectionIds = collections.map((c) => c.id as number);
|
||||||
const filteredCollectionOrder = account.collectionOrder.filter((id) =>
|
const filteredCollectionOrder = user.collectionOrder.filter((id: any) =>
|
||||||
existingCollectionIds.includes(id)
|
existingCollectionIds.includes(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -80,7 +82,7 @@ const CollectionListing = () => {
|
||||||
collections.forEach((collection) => {
|
collections.forEach((collection) => {
|
||||||
if (
|
if (
|
||||||
!filteredCollectionOrder.includes(collection.id as number) &&
|
!filteredCollectionOrder.includes(collection.id as number) &&
|
||||||
(!collection.parentId || collection.ownerId === account.id)
|
(!collection.parentId || collection.ownerId === user.id)
|
||||||
) {
|
) {
|
||||||
filteredCollectionOrder.push(collection.id as number);
|
filteredCollectionOrder.push(collection.id as number);
|
||||||
}
|
}
|
||||||
|
@ -89,10 +91,10 @@ const CollectionListing = () => {
|
||||||
// check if the newCollectionOrder is the same as the old one
|
// check if the newCollectionOrder is the same as the old one
|
||||||
if (
|
if (
|
||||||
JSON.stringify(newCollectionOrder) !==
|
JSON.stringify(newCollectionOrder) !==
|
||||||
JSON.stringify(account.collectionOrder)
|
JSON.stringify(user.collectionOrder)
|
||||||
) {
|
) {
|
||||||
updateAccount({
|
updateUser.mutateAsync({
|
||||||
...account,
|
...user,
|
||||||
collectionOrder: newCollectionOrder,
|
collectionOrder: newCollectionOrder,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -140,9 +142,9 @@ const CollectionListing = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(movedCollection?.ownerId !== account.id &&
|
(movedCollection?.ownerId !== user.id &&
|
||||||
destination.parentId !== source.parentId) ||
|
destination.parentId !== source.parentId) ||
|
||||||
(destinationCollection?.ownerId !== account.id &&
|
(destinationCollection?.ownerId !== user.id &&
|
||||||
destination.parentId !== "root")
|
destination.parentId !== "root")
|
||||||
) {
|
) {
|
||||||
return toast.error(t("cant_change_collection_you_dont_own"));
|
return toast.error(t("cant_change_collection_you_dont_own"));
|
||||||
|
@ -150,7 +152,7 @@ const CollectionListing = () => {
|
||||||
|
|
||||||
setTree((currentTree) => moveItemOnTree(currentTree!, source, destination));
|
setTree((currentTree) => moveItemOnTree(currentTree!, source, destination));
|
||||||
|
|
||||||
const updatedCollectionOrder = [...account.collectionOrder];
|
const updatedCollectionOrder = [...user.collectionOrder];
|
||||||
|
|
||||||
if (source.parentId !== destination.parentId) {
|
if (source.parentId !== destination.parentId) {
|
||||||
await updateCollection.mutateAsync({
|
await updateCollection.mutateAsync({
|
||||||
|
@ -174,8 +176,8 @@ const CollectionListing = () => {
|
||||||
|
|
||||||
updatedCollectionOrder.splice(destination.index, 0, movedCollectionId);
|
updatedCollectionOrder.splice(destination.index, 0, movedCollectionId);
|
||||||
|
|
||||||
await updateAccount({
|
await updateUser.mutateAsync({
|
||||||
...account,
|
...user,
|
||||||
collectionOrder: updatedCollectionOrder,
|
collectionOrder: updatedCollectionOrder,
|
||||||
});
|
});
|
||||||
} else if (
|
} else if (
|
||||||
|
@ -184,8 +186,8 @@ const CollectionListing = () => {
|
||||||
) {
|
) {
|
||||||
updatedCollectionOrder.splice(destination.index, 0, movedCollectionId);
|
updatedCollectionOrder.splice(destination.index, 0, movedCollectionId);
|
||||||
|
|
||||||
await updateAccount({
|
updateUser.mutate({
|
||||||
...account,
|
...user,
|
||||||
collectionOrder: updatedCollectionOrder,
|
collectionOrder: updatedCollectionOrder,
|
||||||
});
|
});
|
||||||
} else if (
|
} else if (
|
||||||
|
@ -195,8 +197,8 @@ const CollectionListing = () => {
|
||||||
) {
|
) {
|
||||||
updatedCollectionOrder.splice(source.index, 1);
|
updatedCollectionOrder.splice(source.index, 1);
|
||||||
|
|
||||||
await updateAccount({
|
await updateUser.mutateAsync({
|
||||||
...account,
|
...user,
|
||||||
collectionOrder: updatedCollectionOrder,
|
collectionOrder: updatedCollectionOrder,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,7 @@ export default function CollectionSelection({
|
||||||
showDefaultValue = true,
|
showDefaultValue = true,
|
||||||
creatable = true,
|
creatable = true,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,12 @@ import Link from "next/link";
|
||||||
import LinkIcon from "./LinkComponents/LinkIcon";
|
import LinkIcon from "./LinkComponents/LinkIcon";
|
||||||
import useOnScreen from "@/hooks/useOnScreen";
|
import useOnScreen from "@/hooks/useOnScreen";
|
||||||
import { generateLinkHref } from "@/lib/client/generateLinkHref";
|
import { generateLinkHref } from "@/lib/client/generateLinkHref";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import usePermissions from "@/hooks/usePermissions";
|
import usePermissions from "@/hooks/usePermissions";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
|
import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import { useCollections } from "@/hooks/store/collections";
|
import { useCollections } from "@/hooks/store/collections";
|
||||||
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
link: LinkIncludingShortenedCollectionAndTags;
|
link: LinkIncludingShortenedCollectionAndTags;
|
||||||
|
@ -34,10 +34,9 @@ export default function LinkCard({ link, flipDropdown, editMode }: Props) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const viewMode = localStorage.getItem("viewMode") || "card";
|
const viewMode = localStorage.getItem("viewMode") || "card";
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
|
||||||
const { links, getLink, setSelectedLinks, selectedLinks } = useLinkStore();
|
const { links, getLink, setSelectedLinks, selectedLinks } = useLinkStore();
|
||||||
|
|
||||||
|
@ -133,7 +132,7 @@ export default function LinkCard({ link, flipDropdown, editMode }: Props) {
|
||||||
<div
|
<div
|
||||||
className="rounded-2xl cursor-pointer h-full flex flex-col justify-between"
|
className="rounded-2xl cursor-pointer h-full flex flex-col justify-between"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
!editMode && window.open(generateLinkHref(link, account), "_blank")
|
!editMode && window.open(generateLinkHref(link, user), "_blank")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -9,9 +9,9 @@ import DeleteLinkModal from "@/components/ModalContent/DeleteLinkModal";
|
||||||
import PreservedFormatsModal from "@/components/ModalContent/PreservedFormatsModal";
|
import PreservedFormatsModal from "@/components/ModalContent/PreservedFormatsModal";
|
||||||
import useLinkStore from "@/store/links";
|
import useLinkStore from "@/store/links";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import { dropdownTriggerer } from "@/lib/client/utils";
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
link: LinkIncludingShortenedCollectionAndTags;
|
link: LinkIncludingShortenedCollectionAndTags;
|
||||||
|
@ -39,7 +39,7 @@ export default function LinkActions({
|
||||||
const [deleteLinkModal, setDeleteLinkModal] = useState(false);
|
const [deleteLinkModal, setDeleteLinkModal] = useState(false);
|
||||||
const [preservedFormatsModal, setPreservedFormatsModal] = useState(false);
|
const [preservedFormatsModal, setPreservedFormatsModal] = useState(false);
|
||||||
|
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
|
||||||
const { removeLink, updateLink } = useLinkStore();
|
const { removeLink, updateLink } = useLinkStore();
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ export default function LinkActions({
|
||||||
|
|
||||||
const response = await updateLink({
|
const response = await updateLink({
|
||||||
...link,
|
...link,
|
||||||
pinnedBy: isAlreadyPinned ? undefined : [{ id: account.id }],
|
pinnedBy: isAlreadyPinned ? undefined : [{ id: user.id }],
|
||||||
});
|
});
|
||||||
|
|
||||||
toast.dismiss(load);
|
toast.dismiss(load);
|
||||||
|
|
|
@ -11,12 +11,12 @@ import LinkCollection from "@/components/LinkViews/LinkComponents/LinkCollection
|
||||||
import LinkIcon from "@/components/LinkViews/LinkComponents/LinkIcon";
|
import LinkIcon from "@/components/LinkViews/LinkComponents/LinkIcon";
|
||||||
import { isPWA } from "@/lib/client/utils";
|
import { isPWA } from "@/lib/client/utils";
|
||||||
import { generateLinkHref } from "@/lib/client/generateLinkHref";
|
import { generateLinkHref } from "@/lib/client/generateLinkHref";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import usePermissions from "@/hooks/usePermissions";
|
import usePermissions from "@/hooks/usePermissions";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
|
import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import { useCollections } from "@/hooks/store/collections";
|
import { useCollections } from "@/hooks/store/collections";
|
||||||
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
link: LinkIncludingShortenedCollectionAndTags;
|
link: LinkIncludingShortenedCollectionAndTags;
|
||||||
|
@ -33,10 +33,9 @@ export default function LinkCardCompact({
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
const { links, setSelectedLinks, selectedLinks } = useLinkStore();
|
const { links, setSelectedLinks, selectedLinks } = useLinkStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -121,7 +120,7 @@ export default function LinkCardCompact({
|
||||||
<div
|
<div
|
||||||
className="flex items-center cursor-pointer w-full"
|
className="flex items-center cursor-pointer w-full"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
!editMode && window.open(generateLinkHref(link, account), "_blank")
|
!editMode && window.open(generateLinkHref(link, user), "_blank")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="shrink-0">
|
<div className="shrink-0">
|
||||||
|
|
|
@ -15,12 +15,12 @@ import Link from "next/link";
|
||||||
import LinkIcon from "./LinkComponents/LinkIcon";
|
import LinkIcon from "./LinkComponents/LinkIcon";
|
||||||
import useOnScreen from "@/hooks/useOnScreen";
|
import useOnScreen from "@/hooks/useOnScreen";
|
||||||
import { generateLinkHref } from "@/lib/client/generateLinkHref";
|
import { generateLinkHref } from "@/lib/client/generateLinkHref";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import usePermissions from "@/hooks/usePermissions";
|
import usePermissions from "@/hooks/usePermissions";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
|
import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import { useCollections } from "@/hooks/store/collections";
|
import { useCollections } from "@/hooks/store/collections";
|
||||||
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
link: LinkIncludingShortenedCollectionAndTags;
|
link: LinkIncludingShortenedCollectionAndTags;
|
||||||
|
@ -33,9 +33,8 @@ type Props = {
|
||||||
export default function LinkMasonry({ link, flipDropdown, editMode }: Props) {
|
export default function LinkMasonry({ link, flipDropdown, editMode }: Props) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
const { data: user = [] } = useUser();
|
||||||
const { account } = useAccountStore();
|
|
||||||
|
|
||||||
const { links, getLink, setSelectedLinks, selectedLinks } = useLinkStore();
|
const { links, getLink, setSelectedLinks, selectedLinks } = useLinkStore();
|
||||||
|
|
||||||
|
@ -131,7 +130,7 @@ export default function LinkMasonry({ link, flipDropdown, editMode }: Props) {
|
||||||
<div
|
<div
|
||||||
className="rounded-2xl cursor-pointer"
|
className="rounded-2xl cursor-pointer"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
!editMode && window.open(generateLinkHref(link, account), "_blank")
|
!editMode && window.open(generateLinkHref(link, user), "_blank")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="relative rounded-t-2xl overflow-hidden">
|
<div className="relative rounded-t-2xl overflow-hidden">
|
||||||
|
|
|
@ -3,7 +3,6 @@ import TextInput from "@/components/TextInput";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { CollectionIncludingMembersAndLinkCount, Member } from "@/types/global";
|
import { CollectionIncludingMembersAndLinkCount, Member } from "@/types/global";
|
||||||
import getPublicUserData from "@/lib/client/getPublicUserData";
|
import getPublicUserData from "@/lib/client/getPublicUserData";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import usePermissions from "@/hooks/usePermissions";
|
import usePermissions from "@/hooks/usePermissions";
|
||||||
import ProfilePhoto from "../ProfilePhoto";
|
import ProfilePhoto from "../ProfilePhoto";
|
||||||
import addMemberToCollection from "@/lib/client/addMemberToCollection";
|
import addMemberToCollection from "@/lib/client/addMemberToCollection";
|
||||||
|
@ -11,6 +10,7 @@ import Modal from "../Modal";
|
||||||
import { dropdownTriggerer } from "@/lib/client/utils";
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import { useUpdateCollection } from "@/hooks/store/collections";
|
import { useUpdateCollection } from "@/hooks/store/collections";
|
||||||
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onClose: Function;
|
onClose: Function;
|
||||||
|
@ -46,7 +46,7 @@ export default function EditCollectionSharingModal({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
const permissions = usePermissions(collection.id as number);
|
const permissions = usePermissions(collection.id as number);
|
||||||
|
|
||||||
const currentURL = new URL(document.URL);
|
const currentURL = new URL(document.URL);
|
||||||
|
@ -158,7 +158,7 @@ export default function EditCollectionSharingModal({
|
||||||
onKeyDown={(e) =>
|
onKeyDown={(e) =>
|
||||||
e.key === "Enter" &&
|
e.key === "Enter" &&
|
||||||
addMemberToCollection(
|
addMemberToCollection(
|
||||||
account.username as string,
|
user.username as string,
|
||||||
memberUsername || "",
|
memberUsername || "",
|
||||||
collection,
|
collection,
|
||||||
setMemberState,
|
setMemberState,
|
||||||
|
@ -170,7 +170,7 @@ export default function EditCollectionSharingModal({
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
addMemberToCollection(
|
addMemberToCollection(
|
||||||
account.username as string,
|
user.username as string,
|
||||||
memberUsername || "",
|
memberUsername || "",
|
||||||
collection,
|
collection,
|
||||||
setMemberState,
|
setMemberState,
|
||||||
|
|
|
@ -4,8 +4,6 @@ import { HexColorPicker } from "react-colorful";
|
||||||
import { Collection } from "@prisma/client";
|
import { Collection } from "@prisma/client";
|
||||||
import Modal from "../Modal";
|
import Modal from "../Modal";
|
||||||
import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
|
import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import { useSession } from "next-auth/react";
|
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import { useCreateCollection } from "@/hooks/store/collections";
|
import { useCreateCollection } from "@/hooks/store/collections";
|
||||||
|
|
||||||
|
@ -24,8 +22,6 @@ export default function NewCollectionModal({ onClose, parent }: Props) {
|
||||||
} as Partial<Collection>;
|
} as Partial<Collection>;
|
||||||
|
|
||||||
const [collection, setCollection] = useState<Partial<Collection>>(initial);
|
const [collection, setCollection] = useState<Partial<Collection>>(initial);
|
||||||
const { setAccount } = useAccountStore();
|
|
||||||
const { data } = useSession();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCollection(initial);
|
setCollection(initial);
|
||||||
|
|
|
@ -43,8 +43,7 @@ export default function NewLinkModal({ onClose }: Props) {
|
||||||
const [submitLoader, setSubmitLoader] = useState(false);
|
const [submitLoader, setSubmitLoader] = useState(false);
|
||||||
const [optionsExpanded, setOptionsExpanded] = useState(false);
|
const [optionsExpanded, setOptionsExpanded] = useState(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const setCollection = (e: any) => {
|
const setCollection = (e: any) => {
|
||||||
if (e?.__isNew__) e.value = null;
|
if (e?.__isNew__) e.value = null;
|
||||||
|
|
|
@ -16,10 +16,10 @@ import {
|
||||||
screenshotAvailable,
|
screenshotAvailable,
|
||||||
} from "@/lib/shared/getArchiveValidity";
|
} from "@/lib/shared/getArchiveValidity";
|
||||||
import PreservedFormatRow from "@/components/PreserverdFormatRow";
|
import PreservedFormatRow from "@/components/PreserverdFormatRow";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import getPublicUserData from "@/lib/client/getPublicUserData";
|
import getPublicUserData from "@/lib/client/getPublicUserData";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import { BeatLoader } from "react-spinners";
|
import { BeatLoader } from "react-spinners";
|
||||||
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onClose: Function;
|
onClose: Function;
|
||||||
|
@ -30,7 +30,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const { getLink } = useLinkStore();
|
const { getLink } = useLinkStore();
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
const [link, setLink] =
|
const [link, setLink] =
|
||||||
useState<LinkIncludingShortenedCollectionAndTags>(activeLink);
|
useState<LinkIncludingShortenedCollectionAndTags>(activeLink);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -49,20 +49,20 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchOwner = async () => {
|
const fetchOwner = async () => {
|
||||||
if (link.collection.ownerId !== account.id) {
|
if (link.collection.ownerId !== user.id) {
|
||||||
const owner = await getPublicUserData(
|
const owner = await getPublicUserData(
|
||||||
link.collection.ownerId as number
|
link.collection.ownerId as number
|
||||||
);
|
);
|
||||||
setCollectionOwner(owner);
|
setCollectionOwner(owner);
|
||||||
} else if (link.collection.ownerId === account.id) {
|
} else if (link.collection.ownerId === user.id) {
|
||||||
setCollectionOwner({
|
setCollectionOwner({
|
||||||
id: account.id as number,
|
id: user.id as number,
|
||||||
name: account.name,
|
name: user.name,
|
||||||
username: account.username as string,
|
username: user.username as string,
|
||||||
image: account.image as string,
|
image: user.image as string,
|
||||||
archiveAsScreenshot: account.archiveAsScreenshot as boolean,
|
archiveAsScreenshot: user.archiveAsScreenshot as boolean,
|
||||||
archiveAsMonolith: account.archiveAsScreenshot as boolean,
|
archiveAsMonolith: user.archiveAsScreenshot as boolean,
|
||||||
archiveAsPDF: account.archiveAsPDF as boolean,
|
archiveAsPDF: user.archiveAsPDF as boolean,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,8 +49,7 @@ export default function UploadFileModal({ onClose }: Props) {
|
||||||
const [submitLoader, setSubmitLoader] = useState(false);
|
const [submitLoader, setSubmitLoader] = useState(false);
|
||||||
const [optionsExpanded, setOptionsExpanded] = useState(false);
|
const [optionsExpanded, setOptionsExpanded] = useState(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const setCollection = (e: any) => {
|
const setCollection = (e: any) => {
|
||||||
if (e?.__isNew__) e.value = null;
|
if (e?.__isNew__) e.value = null;
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import useLocalSettingsStore from "@/store/localSettings";
|
import useLocalSettingsStore from "@/store/localSettings";
|
||||||
import { dropdownTriggerer } from "@/lib/client/utils";
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
import ProfilePhoto from "./ProfilePhoto";
|
import ProfilePhoto from "./ProfilePhoto";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { signOut } from "next-auth/react";
|
import { signOut } from "next-auth/react";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
export default function ProfileDropdown() {
|
export default function ProfileDropdown() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { settings, updateSettings } = useLocalSettingsStore();
|
const { settings, updateSettings } = useLocalSettingsStore();
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
|
||||||
const isAdmin = account.id === Number(process.env.NEXT_PUBLIC_ADMIN || 1);
|
const isAdmin = user.id === Number(process.env.NEXT_PUBLIC_ADMIN || 1);
|
||||||
|
|
||||||
const handleToggle = () => {
|
const handleToggle = () => {
|
||||||
const newTheme = settings.theme === "dark" ? "light" : "dark";
|
const newTheme = settings.theme === "dark" ? "light" : "dark";
|
||||||
|
@ -27,7 +27,7 @@ export default function ProfileDropdown() {
|
||||||
className="btn btn-circle btn-ghost"
|
className="btn btn-circle btn-ghost"
|
||||||
>
|
>
|
||||||
<ProfilePhoto
|
<ProfilePhoto
|
||||||
src={account.image ? account.image : undefined}
|
src={user.image ? user.image : undefined}
|
||||||
priority={true}
|
priority={true}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -46,8 +46,7 @@ export default function ReadableView({ link }: Props) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const { getLink } = useLinkStore();
|
const { getLink } = useLinkStore();
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const collection = useMemo(() => {
|
const collection = useMemo(() => {
|
||||||
return collections.find(
|
return collections.find(
|
||||||
|
|
|
@ -22,8 +22,7 @@ export default function Sidebar({ className }: { className?: string }) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const { tags } = useTagStore();
|
const { tags } = useTagStore();
|
||||||
const [active, setActive] = useState("");
|
const [active, setActive] = useState("");
|
||||||
|
|
|
@ -6,12 +6,10 @@ import toast from "react-hot-toast";
|
||||||
const useCollections = () => {
|
const useCollections = () => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["collections"],
|
queryKey: ["collections"],
|
||||||
queryFn: async (): Promise<{
|
queryFn: async (): Promise<CollectionIncludingMembersAndLinkCount[]> => {
|
||||||
response: CollectionIncludingMembersAndLinkCount[];
|
|
||||||
}> => {
|
|
||||||
const response = await fetch("/api/v1/collections");
|
const response = await fetch("/api/v1/collections");
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return data;
|
return data.response;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -21,11 +19,11 @@ const useCreateCollection = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (data: any) => {
|
mutationFn: async (body: any) => {
|
||||||
const load = toast.loading(t("creating"));
|
const load = toast.loading(t("creating"));
|
||||||
|
|
||||||
const response = await fetch("/api/v1/collections", {
|
const response = await fetch("/api/v1/collections", {
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(body),
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
|
@ -34,14 +32,18 @@ const useCreateCollection = () => {
|
||||||
|
|
||||||
toast.dismiss(load);
|
toast.dismiss(load);
|
||||||
|
|
||||||
return response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!response.ok) throw new Error(data.response);
|
||||||
|
|
||||||
|
return data.response;
|
||||||
},
|
},
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast.success(t("created"));
|
toast.success(t("created"));
|
||||||
return queryClient.setQueryData(["collections"], (oldData: any) => {
|
return queryClient.setQueryData(["collections"], (oldData: any) => {
|
||||||
return {
|
console.log([...oldData, data]);
|
||||||
response: [...oldData.response, data.response],
|
|
||||||
};
|
return [...oldData, data];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
@ -55,33 +57,43 @@ const useUpdateCollection = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (data: any) => {
|
mutationFn: async (body: any) => {
|
||||||
const load = toast.loading(t("updating_collection"));
|
const load = toast.loading(t("updating_collection"));
|
||||||
|
|
||||||
const response = await fetch(`/api/v1/collections/${data.id}`, {
|
const response = await fetch(`/api/v1/collections/${body.id}`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(body),
|
||||||
});
|
});
|
||||||
|
|
||||||
toast.dismiss(load);
|
toast.dismiss(load);
|
||||||
|
|
||||||
return response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!response.ok) throw new Error(data.response);
|
||||||
|
|
||||||
|
return data.response;
|
||||||
},
|
},
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
{
|
{
|
||||||
toast.success(t("updated"));
|
toast.success(t("updated"));
|
||||||
return queryClient.setQueryData(["collections"], (oldData: any) => {
|
return queryClient.setQueryData(["collections"], (oldData: any) => {
|
||||||
return {
|
return oldData.map((collection: any) =>
|
||||||
response: oldData.response.map((collection: any) =>
|
collection.id === data.id ? data : collection
|
||||||
collection.id === data.response.id ? data.response : collection
|
);
|
||||||
),
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// onMutate: async (data) => {
|
||||||
|
// await queryClient.cancelQueries({ queryKey: ["collections"] });
|
||||||
|
// queryClient.setQueryData(["collections"], (oldData: any) => {
|
||||||
|
// return oldData.map((collection: any) =>
|
||||||
|
// collection.id === data.id ? data : collection
|
||||||
|
// )
|
||||||
|
// });
|
||||||
|
// },
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error(error.message);
|
toast.error(error.message);
|
||||||
},
|
},
|
||||||
|
@ -105,16 +117,16 @@ const useDeleteCollection = () => {
|
||||||
|
|
||||||
toast.dismiss(load);
|
toast.dismiss(load);
|
||||||
|
|
||||||
return response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!response.ok) throw new Error(data.response);
|
||||||
|
|
||||||
|
return data.response;
|
||||||
},
|
},
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast.success(t("deleted"));
|
toast.success(t("deleted"));
|
||||||
return queryClient.setQueryData(["collections"], (oldData: any) => {
|
return queryClient.setQueryData(["collections"], (oldData: any) => {
|
||||||
return {
|
return oldData.filter((collection: any) => collection.id !== data.id);
|
||||||
response: oldData.response.filter(
|
|
||||||
(collection: any) => collection.id !== data.response.id
|
|
||||||
),
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
|
import toast from "react-hot-toast";
|
||||||
|
import { useTranslation } from "next-i18next";
|
||||||
|
import { useSession } from "next-auth/react";
|
||||||
|
|
||||||
|
const useUser = () => {
|
||||||
|
const { data } = useSession();
|
||||||
|
|
||||||
|
const userId = data?.user.id;
|
||||||
|
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["user"],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await fetch(`/api/v1/users/${userId}`);
|
||||||
|
if (!response.ok) throw new Error("Failed to fetch user data.");
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
return data.response;
|
||||||
|
},
|
||||||
|
enabled: !!userId,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const useUpdateUser = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async (user: any) => {
|
||||||
|
const load = toast.loading(t("applying_settings"));
|
||||||
|
|
||||||
|
const response = await fetch(`/api/v1/users/${user.id}`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(user),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
toast.dismiss(load);
|
||||||
|
|
||||||
|
if (!response.ok) throw new Error(data.response);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
onSuccess: (data) => {
|
||||||
|
toast.success(t("settings_applied"));
|
||||||
|
queryClient.setQueryData(["user"], data.response);
|
||||||
|
},
|
||||||
|
onMutate: async (user) => {
|
||||||
|
await queryClient.cancelQueries({ queryKey: ["user"] });
|
||||||
|
queryClient.setQueryData(["user"], (oldData: any) => {
|
||||||
|
return { ...oldData, ...user };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(error.message);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export { useUser, useUpdateUser };
|
|
@ -1,13 +1,12 @@
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import { Member } from "@/types/global";
|
import { Member } from "@/types/global";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useCollections } from "./store/collections";
|
import { useCollections } from "./store/collections";
|
||||||
|
import { useUser } from "./store/users";
|
||||||
|
|
||||||
export default function useCollectivePermissions(collectionIds: number[]) {
|
export default function useCollectivePermissions(collectionIds: number[]) {
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
|
||||||
const [permissions, setPermissions] = useState<Member | true>();
|
const [permissions, setPermissions] = useState<Member | true>();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -16,7 +15,7 @@ export default function useCollectivePermissions(collectionIds: number[]) {
|
||||||
|
|
||||||
if (collection) {
|
if (collection) {
|
||||||
let getPermission: Member | undefined = collection.members.find(
|
let getPermission: Member | undefined = collection.members.find(
|
||||||
(e) => e.userId === account.id
|
(e) => e.userId === user.id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -26,10 +25,10 @@ export default function useCollectivePermissions(collectionIds: number[]) {
|
||||||
)
|
)
|
||||||
getPermission = undefined;
|
getPermission = undefined;
|
||||||
|
|
||||||
setPermissions(account.id === collection.ownerId || getPermission);
|
setPermissions(user.id === collection.ownerId || getPermission);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [account, collections, collectionIds]);
|
}, [user, collections, collectionIds]);
|
||||||
|
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,29 @@
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import useTagStore from "@/store/tags";
|
import useTagStore from "@/store/tags";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import useLocalSettingsStore from "@/store/localSettings";
|
import useLocalSettingsStore from "@/store/localSettings";
|
||||||
|
import { useUser } from "./store/users";
|
||||||
|
|
||||||
export default function useInitialData() {
|
export default function useInitialData() {
|
||||||
const { status, data } = useSession();
|
const { status, data } = useSession();
|
||||||
// const { setCollections } = useCollectionStore();
|
// const { setCollections } = useCollectionStore();
|
||||||
const { setTags } = useTagStore();
|
const { setTags } = useTagStore();
|
||||||
// const { setLinks } = useLinkStore();
|
// const { setLinks } = useLinkStore();
|
||||||
const { account, setAccount } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
const { setSettings } = useLocalSettingsStore();
|
const { setSettings } = useLocalSettingsStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSettings();
|
setSettings();
|
||||||
if (status === "authenticated") {
|
|
||||||
// Get account info
|
|
||||||
setAccount(data?.user.id as number);
|
|
||||||
}
|
|
||||||
}, [status, data]);
|
}, [status, data]);
|
||||||
|
|
||||||
// Get the rest of the data
|
// Get the rest of the data
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (account.id && (!process.env.NEXT_PUBLIC_STRIPE || account.username)) {
|
if (user.id && (!process.env.NEXT_PUBLIC_STRIPE || user.username)) {
|
||||||
// setCollections();
|
// setCollections();
|
||||||
setTags();
|
setTags();
|
||||||
// setLinks();
|
// setLinks();
|
||||||
}
|
}
|
||||||
}, [account]);
|
}, [user]);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import { Member } from "@/types/global";
|
import { Member } from "@/types/global";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useCollections } from "./store/collections";
|
import { useCollections } from "./store/collections";
|
||||||
|
import { useUser } from "./store/users";
|
||||||
|
|
||||||
export default function usePermissions(collectionId: number) {
|
export default function usePermissions(collectionId: number) {
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
|
||||||
const [permissions, setPermissions] = useState<Member | true>();
|
const [permissions, setPermissions] = useState<Member | true>();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -15,7 +14,7 @@ export default function usePermissions(collectionId: number) {
|
||||||
|
|
||||||
if (collection) {
|
if (collection) {
|
||||||
let getPermission: Member | undefined = collection.members.find(
|
let getPermission: Member | undefined = collection.members.find(
|
||||||
(e) => e.userId === account.id
|
(e) => e.userId === user.id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -25,9 +24,9 @@ export default function usePermissions(collectionId: number) {
|
||||||
)
|
)
|
||||||
getPermission = undefined;
|
getPermission = undefined;
|
||||||
|
|
||||||
setPermissions(account.id === collection.ownerId || getPermission);
|
setPermissions(user.id === collection.ownerId || getPermission);
|
||||||
}
|
}
|
||||||
}, [account, collections, collectionId]);
|
}, [user, collections, collectionId]);
|
||||||
|
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { ReactNode, useEffect, useState } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import useInitialData from "@/hooks/useInitialData";
|
import useInitialData from "@/hooks/useInitialData";
|
||||||
import useAccountStore from "@/store/account";
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
@ -14,7 +14,7 @@ export default function AuthRedirect({ children }: Props) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { status } = useSession();
|
const { status } = useSession();
|
||||||
const [shouldRenderChildren, setShouldRenderChildren] = useState(false);
|
const [shouldRenderChildren, setShouldRenderChildren] = useState(false);
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
|
||||||
useInitialData();
|
useInitialData();
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export default function AuthRedirect({ children }: Props) {
|
||||||
const isUnauthenticated = status === "unauthenticated";
|
const isUnauthenticated = status === "unauthenticated";
|
||||||
const isPublicPage = router.pathname.startsWith("/public");
|
const isPublicPage = router.pathname.startsWith("/public");
|
||||||
const hasInactiveSubscription =
|
const hasInactiveSubscription =
|
||||||
account.id && !account.subscription?.active && stripeEnabled;
|
user.id && !user.subscription?.active && stripeEnabled;
|
||||||
|
|
||||||
// There are better ways of doing this... but this one works for now
|
// There are better ways of doing this... but this one works for now
|
||||||
const routes = [
|
const routes = [
|
||||||
|
@ -63,7 +63,7 @@ export default function AuthRedirect({ children }: Props) {
|
||||||
setShouldRenderChildren(true);
|
setShouldRenderChildren(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [status, account, router.pathname]);
|
}, [status, user, router.pathname]);
|
||||||
|
|
||||||
function redirectTo(destination: string) {
|
function redirectTo(destination: string) {
|
||||||
router.push(destination).then(() => setShouldRenderChildren(true));
|
router.push(destination).then(() => setShouldRenderChildren(true));
|
||||||
|
|
|
@ -12,7 +12,6 @@ import useLinks from "@/hooks/useLinks";
|
||||||
import usePermissions from "@/hooks/usePermissions";
|
import usePermissions from "@/hooks/usePermissions";
|
||||||
import NoLinksFound from "@/components/NoLinksFound";
|
import NoLinksFound from "@/components/NoLinksFound";
|
||||||
import useLocalSettingsStore from "@/store/localSettings";
|
import useLocalSettingsStore from "@/store/localSettings";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import getPublicUserData from "@/lib/client/getPublicUserData";
|
import getPublicUserData from "@/lib/client/getPublicUserData";
|
||||||
import EditCollectionModal from "@/components/ModalContent/EditCollectionModal";
|
import EditCollectionModal from "@/components/ModalContent/EditCollectionModal";
|
||||||
import EditCollectionSharingModal from "@/components/ModalContent/EditCollectionSharingModal";
|
import EditCollectionSharingModal from "@/components/ModalContent/EditCollectionSharingModal";
|
||||||
|
@ -26,6 +25,7 @@ import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import LinkListOptions from "@/components/LinkListOptions";
|
import LinkListOptions from "@/components/LinkListOptions";
|
||||||
import { useCollections } from "@/hooks/store/collections";
|
import { useCollections } from "@/hooks/store/collections";
|
||||||
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -34,8 +34,7 @@ export default function Index() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const { links } = useLinkStore();
|
const { links } = useLinkStore();
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const [sortBy, setSortBy] = useState<Sort>(Sort.DateNewestFirst);
|
const [sortBy, setSortBy] = useState<Sort>(Sort.DateNewestFirst);
|
||||||
|
|
||||||
|
@ -52,7 +51,7 @@ export default function Index() {
|
||||||
);
|
);
|
||||||
}, [router, collections]);
|
}, [router, collections]);
|
||||||
|
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
|
||||||
const [collectionOwner, setCollectionOwner] = useState({
|
const [collectionOwner, setCollectionOwner] = useState({
|
||||||
id: null as unknown as number,
|
id: null as unknown as number,
|
||||||
|
@ -66,20 +65,20 @@ export default function Index() {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchOwner = async () => {
|
const fetchOwner = async () => {
|
||||||
if (activeCollection && activeCollection.ownerId !== account.id) {
|
if (activeCollection && activeCollection.ownerId !== user.id) {
|
||||||
const owner = await getPublicUserData(
|
const owner = await getPublicUserData(
|
||||||
activeCollection.ownerId as number
|
activeCollection.ownerId as number
|
||||||
);
|
);
|
||||||
setCollectionOwner(owner);
|
setCollectionOwner(owner);
|
||||||
} else if (activeCollection && activeCollection.ownerId === account.id) {
|
} else if (activeCollection && activeCollection.ownerId === user.id) {
|
||||||
setCollectionOwner({
|
setCollectionOwner({
|
||||||
id: account.id as number,
|
id: user.id as number,
|
||||||
name: account.name,
|
name: user.name,
|
||||||
username: account.username as string,
|
username: user.username as string,
|
||||||
image: account.image as string,
|
image: user.image as string,
|
||||||
archiveAsScreenshot: account.archiveAsScreenshot as boolean,
|
archiveAsScreenshot: user.archiveAsScreenshot as boolean,
|
||||||
archiveAsMonolith: account.archiveAsScreenshot as boolean,
|
archiveAsMonolith: user.archiveAsScreenshot as boolean,
|
||||||
archiveAsPDF: account.archiveAsPDF as boolean,
|
archiveAsPDF: user.archiveAsPDF as boolean,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,8 +13,7 @@ import { useCollections } from "@/hooks/store/collections";
|
||||||
|
|
||||||
export default function Collections() {
|
export default function Collections() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
const [sortBy, setSortBy] = useState<Sort>(Sort.DateNewestFirst);
|
const [sortBy, setSortBy] = useState<Sort>(Sort.DateNewestFirst);
|
||||||
const [sortedCollections, setSortedCollections] = useState(collections);
|
const [sortedCollections, setSortedCollections] = useState(collections);
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,7 @@ import { useCollections } from "@/hooks/store/collections";
|
||||||
|
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
const { links } = useLinkStore();
|
const { links } = useLinkStore();
|
||||||
const { tags } = useTagStore();
|
const { tags } = useTagStore();
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,7 @@ export default function PublicCollections() {
|
||||||
|
|
||||||
const { settings } = useLocalSettingsStore();
|
const { settings } = useLocalSettingsStore();
|
||||||
|
|
||||||
const { data: { response: collections } = { response: [] } } =
|
const { data: collections = [] } = useCollections();
|
||||||
useCollections();
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import { AccountSettings } from "@/types/global";
|
import { AccountSettings } from "@/types/global";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import SettingsLayout from "@/layouts/SettingsLayout";
|
import SettingsLayout from "@/layouts/SettingsLayout";
|
||||||
|
@ -17,6 +16,7 @@ import Button from "@/components/ui/Button";
|
||||||
import { i18n } from "next-i18next.config";
|
import { i18n } from "next-i18next.config";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||||
|
import { useUpdateUser, useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER;
|
const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER;
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ export default function Account() {
|
||||||
const [emailChangeVerificationModal, setEmailChangeVerificationModal] =
|
const [emailChangeVerificationModal, setEmailChangeVerificationModal] =
|
||||||
useState(false);
|
useState(false);
|
||||||
const [submitLoader, setSubmitLoader] = useState(false);
|
const [submitLoader, setSubmitLoader] = useState(false);
|
||||||
const { account, updateAccount } = useAccountStore();
|
const { data: account = [] } = useUser();
|
||||||
|
const updateUser = useUpdateUser();
|
||||||
const [user, setUser] = useState<AccountSettings>(
|
const [user, setUser] = useState<AccountSettings>(
|
||||||
!objectIsEmpty(account)
|
!objectIsEmpty(account)
|
||||||
? account
|
? account
|
||||||
|
@ -78,25 +79,22 @@ export default function Account() {
|
||||||
|
|
||||||
const submit = async (password?: string) => {
|
const submit = async (password?: string) => {
|
||||||
setSubmitLoader(true);
|
setSubmitLoader(true);
|
||||||
const load = toast.loading(t("applying_settings"));
|
|
||||||
|
|
||||||
const response = await updateAccount({
|
await updateUser.mutateAsync(
|
||||||
...user,
|
{
|
||||||
// @ts-ignore
|
...user,
|
||||||
password: password ? password : undefined,
|
password: password ? password : undefined,
|
||||||
});
|
},
|
||||||
|
{
|
||||||
toast.dismiss(load);
|
onSuccess: (data) => {
|
||||||
|
if (data.response.email !== user.email) {
|
||||||
if (response.ok) {
|
toast.success(t("email_change_request"));
|
||||||
const emailChanged = account.email !== user.email;
|
setEmailChangeVerificationModal(false);
|
||||||
|
}
|
||||||
toast.success(t("settings_applied"));
|
},
|
||||||
if (emailChanged) {
|
|
||||||
toast.success(t("email_change_request"));
|
|
||||||
setEmailChangeVerificationModal(false);
|
|
||||||
}
|
}
|
||||||
} else toast.error(response.data as string);
|
);
|
||||||
|
|
||||||
setSubmitLoader(false);
|
setSubmitLoader(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import SettingsLayout from "@/layouts/SettingsLayout";
|
import SettingsLayout from "@/layouts/SettingsLayout";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import SubmitButton from "@/components/SubmitButton";
|
import SubmitButton from "@/components/SubmitButton";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import TextInput from "@/components/TextInput";
|
import TextInput from "@/components/TextInput";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||||
|
import { useUpdateUser, useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
export default function Password() {
|
export default function Password() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -13,7 +13,8 @@ export default function Password() {
|
||||||
const [oldPassword, setOldPassword] = useState("");
|
const [oldPassword, setOldPassword] = useState("");
|
||||||
const [newPassword, setNewPassword] = useState("");
|
const [newPassword, setNewPassword] = useState("");
|
||||||
const [submitLoader, setSubmitLoader] = useState(false);
|
const [submitLoader, setSubmitLoader] = useState(false);
|
||||||
const { account, updateAccount } = useAccountStore();
|
const { data: account = [] } = useUser();
|
||||||
|
const updateUser = useUpdateUser();
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
if (newPassword === "" || oldPassword === "") {
|
if (newPassword === "" || oldPassword === "") {
|
||||||
|
@ -23,23 +24,19 @@ export default function Password() {
|
||||||
|
|
||||||
setSubmitLoader(true);
|
setSubmitLoader(true);
|
||||||
|
|
||||||
const load = toast.loading(t("applying_changes"));
|
await updateUser.mutateAsync(
|
||||||
|
{
|
||||||
const response = await updateAccount({
|
...account,
|
||||||
...account,
|
newPassword,
|
||||||
newPassword,
|
oldPassword,
|
||||||
oldPassword,
|
},
|
||||||
});
|
{
|
||||||
|
onSuccess: () => {
|
||||||
toast.dismiss(load);
|
setNewPassword("");
|
||||||
|
setOldPassword("");
|
||||||
if (response.ok) {
|
},
|
||||||
toast.success(t("settings_applied"));
|
}
|
||||||
setNewPassword("");
|
);
|
||||||
setOldPassword("");
|
|
||||||
} else {
|
|
||||||
toast.error(response.data as string);
|
|
||||||
}
|
|
||||||
|
|
||||||
setSubmitLoader(false);
|
setSubmitLoader(false);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import SettingsLayout from "@/layouts/SettingsLayout";
|
import SettingsLayout from "@/layouts/SettingsLayout";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import useAccountStore from "@/store/account";
|
|
||||||
import SubmitButton from "@/components/SubmitButton";
|
import SubmitButton from "@/components/SubmitButton";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import Checkbox from "@/components/Checkbox";
|
import Checkbox from "@/components/Checkbox";
|
||||||
|
@ -8,12 +7,14 @@ import useLocalSettingsStore from "@/store/localSettings";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import getServerSideProps from "@/lib/client/getServerSideProps"; // Import getServerSideProps for server-side data fetching
|
import getServerSideProps from "@/lib/client/getServerSideProps"; // Import getServerSideProps for server-side data fetching
|
||||||
import { LinksRouteTo } from "@prisma/client";
|
import { LinksRouteTo } from "@prisma/client";
|
||||||
|
import { useUpdateUser, useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
export default function Appearance() {
|
export default function Appearance() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { updateSettings } = useLocalSettingsStore();
|
const { updateSettings } = useLocalSettingsStore();
|
||||||
const [submitLoader, setSubmitLoader] = useState(false);
|
const [submitLoader, setSubmitLoader] = useState(false);
|
||||||
const { account, updateAccount } = useAccountStore();
|
const { data: account = [] } = useUser();
|
||||||
|
const updateUser = useUpdateUser();
|
||||||
const [user, setUser] = useState(account);
|
const [user, setUser] = useState(account);
|
||||||
|
|
||||||
const [preventDuplicateLinks, setPreventDuplicateLinks] = useState<boolean>(
|
const [preventDuplicateLinks, setPreventDuplicateLinks] = useState<boolean>(
|
||||||
|
@ -73,17 +74,8 @@ export default function Appearance() {
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
setSubmitLoader(true);
|
setSubmitLoader(true);
|
||||||
|
|
||||||
const load = toast.loading(t("applying_changes"));
|
await updateUser.mutateAsync({ ...user });
|
||||||
|
|
||||||
const response = await updateAccount({ ...user });
|
|
||||||
|
|
||||||
toast.dismiss(load);
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
toast.success(t("settings_applied"));
|
|
||||||
} else {
|
|
||||||
toast.error(response.data as string);
|
|
||||||
}
|
|
||||||
setSubmitLoader(false);
|
setSubmitLoader(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Plan } from "@/types/global";
|
||||||
import Button from "@/components/ui/Button";
|
import Button from "@/components/ui/Button";
|
||||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||||
import { Trans, useTranslation } from "next-i18next";
|
import { Trans, useTranslation } from "next-i18next";
|
||||||
import useAccountStore from "@/store/account";
|
import { useUser } from "@/hooks/store/users";
|
||||||
|
|
||||||
const stripeEnabled = process.env.NEXT_PUBLIC_STRIPE === "true";
|
const stripeEnabled = process.env.NEXT_PUBLIC_STRIPE === "true";
|
||||||
|
|
||||||
|
@ -20,11 +20,11 @@ export default function Subscribe() {
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const { account } = useAccountStore();
|
const { data: user = [] } = useUser();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hasInactiveSubscription =
|
const hasInactiveSubscription =
|
||||||
account.id && !account.subscription?.active && stripeEnabled;
|
user.id && !user.subscription?.active && stripeEnabled;
|
||||||
|
|
||||||
if (session.status === "authenticated" && !hasInactiveSubscription) {
|
if (session.status === "authenticated" && !hasInactiveSubscription) {
|
||||||
router.push("/dashboard");
|
router.push("/dashboard");
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
import { create } from "zustand";
|
|
||||||
import { AccountSettings } from "@/types/global";
|
|
||||||
|
|
||||||
type ResponseObject = {
|
|
||||||
ok: boolean;
|
|
||||||
data: Omit<AccountSettings, "password"> | object | string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type AccountStore = {
|
|
||||||
account: AccountSettings;
|
|
||||||
setAccount: (id: number) => void;
|
|
||||||
updateAccount: (user: AccountSettings) => Promise<ResponseObject>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const useAccountStore = create<AccountStore>()((set) => ({
|
|
||||||
account: {} as AccountSettings,
|
|
||||||
setAccount: async (id) => {
|
|
||||||
const response = await fetch(`/api/v1/users/${id}`);
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if (response.ok) set({ account: { ...data.response } });
|
|
||||||
},
|
|
||||||
updateAccount: async (user) => {
|
|
||||||
const response = await fetch(`/api/v1/users/${user.id}`, {
|
|
||||||
method: "PUT",
|
|
||||||
body: JSON.stringify(user),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if (response.ok) set({ account: { ...data.response } });
|
|
||||||
|
|
||||||
return { ok: response.ok, data: data.response };
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
export default useAccountStore;
|
|
Ŝarĝante…
Reference in New Issue