feat: added links update functionality

This commit is contained in:
Daniel 2023-03-28 18:41:34 +03:30
parent b9567ca3c2
commit e41c492675
6 changed files with 107 additions and 28 deletions

View File

@ -27,7 +27,7 @@ export default function ({ onChange, defaultValue }: Props) {
return ( return (
<CreatableSelect <CreatableSelect
isClearable isClearable={false}
onChange={onChange} onChange={onChange}
options={options} options={options}
styles={styles} styles={styles}

View File

@ -16,6 +16,8 @@ export default function EditLink({ toggleLinkModal, link }: Props) {
const { updateLink } = useLinkStore(); const { updateLink } = useLinkStore();
const shortendURL = new URL(link.url).host.toLowerCase();
const setTags = (e: any) => { const setTags = (e: any) => {
const tagNames = e.map((e: any) => { const tagNames = e.map((e: any) => {
return { name: e.label }; return { name: e.label };
@ -40,8 +42,9 @@ export default function EditLink({ toggleLinkModal, link }: Props) {
return ( return (
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
<p className="font-bold text-sky-300 mb-2 text-center">New Link</p> <p className="font-bold text-sky-300 mb-2 text-center">Edit Link</p>
<p>{shortendURL}</p>
<p>{link.title}</p>
<div className="flex gap-5 items-center justify-between"> <div className="flex gap-5 items-center justify-between">
<p className="text-sm font-bold text-sky-300">Name</p> <p className="text-sm font-bold text-sky-300">Name</p>
<input <input
@ -55,19 +58,6 @@ export default function EditLink({ toggleLinkModal, link }: Props) {
/> />
</div> </div>
<div className="flex gap-5 items-center justify-between">
<p className="text-sm font-bold text-sky-300">URL</p>
<input
value={currentLink.url}
onChange={(e) =>
setCurrentLink({ ...currentLink, url: e.target.value })
}
type="text"
placeholder="e.g. http://example.com/"
className="w-60 rounded-md p-3 border-sky-100 border-solid border text-sm outline-none focus:border-sky-500 duration-100"
/>
</div>
<div className="flex gap-5 items-center justify-between"> <div className="flex gap-5 items-center justify-between">
<p className="text-sm font-bold text-sky-300">Tags</p> <p className="text-sm font-bold text-sky-300">Tags</p>
<TagSelection <TagSelection

View File

@ -36,7 +36,7 @@ export default function () {
}; };
return ( return (
<div className="fixed bg-gray-100 top-0 bottom-0 left-0 w-80 p-2 overflow-y-auto hide-scrollbar border-solid border-r-sky-100 border z-20"> <div className="fixed bg-gray-100 top-0 bottom-0 left-0 w-80 p-2 overflow-y-auto border-solid border-r-sky-100 border z-20">
<p className="p-2 text-sky-500 font-bold text-xl mb-5 leading-4"> <p className="p-2 text-sky-500 font-bold text-xl mb-5 leading-4">
Linkwarden Linkwarden
</p> </p>

View File

@ -0,0 +1,63 @@
import { prisma } from "@/lib/api/db";
import { ExtendedLink } from "@/types/global";
import { Link, UsersAndCollections } from "@prisma/client";
import hasAccessToCollection from "@/lib/api/hasAccessToCollection";
export default async function (link: ExtendedLink, userId: number) {
if (!link) return { response: "Please choose a valid link.", status: 401 };
const collectionIsAccessible = await hasAccessToCollection(
userId,
link.collectionId
);
const memberHasAccess = collectionIsAccessible?.members.some(
(e: UsersAndCollections) => e.userId === userId && e.canUpdate
);
if (!(collectionIsAccessible?.ownerId === userId || memberHasAccess))
return { response: "Collection is not accessible.", status: 401 };
const updatedLink: Link = await prisma.link.update({
where: {
id: link.id,
},
data: {
name: link.name,
collection: {
connectOrCreate: {
where: {
name_ownerId: {
ownerId: link.collection.ownerId,
name: link.collection.name,
},
},
create: {
name: link.collection.name,
ownerId: userId,
},
},
},
tags: {
connectOrCreate: link.tags.map((tag) => ({
where: {
name_ownerId: {
name: tag.name,
ownerId: link.collection.ownerId,
},
},
create: {
name: tag.name,
owner: {
connect: {
id: link.collection.ownerId,
},
},
},
})),
},
},
});
return { response: updatedLink, status: 200 };
}

View File

@ -4,6 +4,7 @@ import { authOptions } from "pages/api/auth/[...nextauth]";
import getLinks from "@/lib/api/controllers/links/getLinks"; import getLinks from "@/lib/api/controllers/links/getLinks";
import postLink from "@/lib/api/controllers/links/postLink"; import postLink from "@/lib/api/controllers/links/postLink";
import deleteLink from "@/lib/api/controllers/links/deleteLink"; import deleteLink from "@/lib/api/controllers/links/deleteLink";
import updateLink from "@/lib/api/controllers/links/updateLink";
export default async function (req: NextApiRequest, res: NextApiResponse) { export default async function (req: NextApiRequest, res: NextApiResponse) {
const session = await getServerSession(req, res, authOptions); const session = await getServerSession(req, res, authOptions);
@ -25,5 +26,12 @@ export default async function (req: NextApiRequest, res: NextApiResponse) {
return res.status(deleted.status).json({ return res.status(deleted.status).json({
response: deleted.response, response: deleted.response,
}); });
} else if (req.method === "PUT") {
console.log("AAAAAAAAAAAAAAAAAAAAAAaa");
const updated = await updateLink(req.body, session.user.id);
return res.status(updated.status).json({
response: updated.response,
});
} }
} }

View File

@ -33,20 +33,38 @@ const useLinkStore = create<LinkStore>()((set) => ({
console.log(data); console.log(data);
if (response.ok) if (response.ok) {
set((state) => ({ set((state) => ({
links: [...state.links, data.response], links: [...state.links, data.response],
})); }));
useTagStore.getState().setTags();
useTagStore.getState().setTags(); useCollectionStore.getState().setCollections();
useCollectionStore.getState().setCollections(); }
return response.ok; return response.ok;
}, },
updateLink: (link) => updateLink: async (link) => {
set((state) => ({ console.log(link);
links: state.links.map((e) => (e.id === link.id ? link : e)),
})), const response = await fetch("/api/routes/links", {
body: JSON.stringify(link),
headers: {
"Content-Type": "application/json",
},
method: "PUT",
});
const data = await response.json();
console.log(data);
if (response.ok) {
set((state) => ({
links: state.links.map((e) => (e.id === link.id ? link : e)),
}));
useTagStore.getState().setTags();
}
},
removeLink: async (link) => { removeLink: async (link) => {
const response = await fetch("/api/routes/links", { const response = await fetch("/api/routes/links", {
body: JSON.stringify(link), body: JSON.stringify(link),
@ -58,12 +76,12 @@ const useLinkStore = create<LinkStore>()((set) => ({
const data = await response.json(); const data = await response.json();
if (response.ok) if (response.ok) {
set((state) => ({ set((state) => ({
links: state.links.filter((e) => e.id !== link.id), links: state.links.filter((e) => e.id !== link.id),
})); }));
useTagStore.getState().setTags();
useTagStore.getState().setTags(); }
return response.ok; return response.ok;
}, },