add ability to setShareLinkExpiresAt value

This commit is contained in:
MarconLP 2023-04-14 17:06:07 +02:00
parent cc4f2ad4ee
commit ea33309b76
No known key found for this signature in database
GPG key ID: A08A9C8B623F5EA5
5 changed files with 69 additions and 50 deletions

View file

@ -24,7 +24,7 @@ model Video {
userId String userId String
sharing Boolean @default(false) sharing Boolean @default(false)
delete_after_link_expires Boolean @default(false) delete_after_link_expires Boolean @default(false)
shareExpiryAt DateTime? shareLinkExpiresAt DateTime?
linkShareSeo Boolean @default(false) linkShareSeo Boolean @default(false)
user User @relation(fields: [userId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade)

View file

@ -1,14 +1,51 @@
import { Listbox, Transition } from "@headlessui/react"; import { Listbox, Transition } from "@headlessui/react";
import { Fragment, useState } from "react"; import { Fragment } from "react";
import { getTime } from "~/utils/getTime"; import { getTime } from "~/utils/getTime";
import { api } from "~/utils/api";
interface Props { interface Props {
shareExpiryAt: Date | null; shareLinkExpiresAt: Date | null;
videoId: string;
} }
export default function ExpireDateSelectMenu({ shareExpiryAt }: Props) { export default function ExpireDateSelectMenu({
const handleChange = (value) => { shareLinkExpiresAt,
videoId,
}: Props) {
const utils = api.useContext();
const setShareLinkExpiresAtMutation =
api.video.setShareLinkExpiresAt.useMutation({
onMutate: async ({ videoId, shareLinkExpiresAt }) => {
await utils.video.get.cancel();
const previousValue = utils.video.get.getData({ videoId });
if (previousValue) {
utils.video.get.setData(
{ videoId },
{ ...previousValue, shareLinkExpiresAt }
);
}
return { previousValue };
},
onError: (err, { videoId }, context) => {
if (context?.previousValue) {
utils.video.get.setData({ videoId }, context.previousValue);
}
console.error(err.message);
},
});
const handleChange = (value: string) => {
console.log("selecting value", value); console.log("selecting value", value);
const now = new Date();
now.setHours(now.getHours() + 1);
console.log(now);
setShareLinkExpiresAtMutation.mutate({
videoId,
shareLinkExpiresAt: now,
});
}; };
const availableExpireDates = [ const availableExpireDates = [
@ -21,12 +58,12 @@ export default function ExpireDateSelectMenu({ shareExpiryAt }: Props) {
return ( return (
<div> <div>
<Listbox value={shareExpiryAt} onChange={handleChange}> <Listbox value={shareLinkExpiresAt} onChange={handleChange}>
<div> <div>
<Listbox.Button className="h-6 rounded border border-solid border-[#d5d9df] bg-white px-[7px] font-medium"> <Listbox.Button className="h-6 rounded border border-solid border-[#d5d9df] bg-white px-[7px] font-medium">
<span className="block truncate"> <span className="block truncate">
{typeof shareExpiryAt === null {shareLinkExpiresAt
? getTime(shareExpiryAt) ? getTime(shareLinkExpiresAt)
: "Never expire"} : "Never expire"}
</span> </span>
</Listbox.Button> </Listbox.Button>

View file

@ -129,7 +129,8 @@ export function ShareModal({ video }: Props) {
<div className="flex h-6 items-center justify-between"> <div className="flex h-6 items-center justify-between">
<span>Expire link</span> <span>Expire link</span>
<ExpireDateSelectMenu <ExpireDateSelectMenu
shareExpiryAt={video.shareExpiryAt} videoId={video.id}
shareLinkExpiresAt={video.shareLinkExpiresAt}
/> />
</div> </div>
<div className="mt-3 flex h-6 items-center justify-between"> <div className="mt-3 flex h-6 items-center justify-between">

View file

@ -119,6 +119,28 @@ export const videoRouter = createTRPCRouter({
throw new TRPCError({ code: "FORBIDDEN" }); throw new TRPCError({ code: "FORBIDDEN" });
} }
return {
success: true,
updateVideo,
};
}),
setShareLinkExpiresAt: protectedProcedure
.input(z.object({ videoId: z.string(), shareLinkExpiresAt: z.date() }))
.mutation(async ({ ctx, input }) => {
const updateVideo = await ctx.prisma.video.updateMany({
where: {
id: input.videoId,
userId: ctx.session.user.id,
},
data: {
shareLinkExpiresAt: input.shareLinkExpiresAt,
},
});
if (updateVideo.count === 0) {
throw new TRPCError({ code: "FORBIDDEN" });
}
return { return {
success: true, success: true,
updateVideo, updateVideo,

View file

@ -1,41 +0,0 @@
import { type RefCallback, useRef, useCallback, useMemo } from "react";
import { createPopper, type Options } from "@popperjs/core";
/**
* Example implementation to use Popper: https://popper.js.org/
*/
export function usePopper(
options?: Partial<Options>
): [RefCallback<Element | null>, RefCallback<HTMLElement | null>] {
let reference = useRef<Element>(null);
let popper = useRef<HTMLElement>(null);
let cleanupCallback = useRef(() => {});
let instantiatePopper = useCallback(() => {
if (!reference.current) return;
if (!popper.current) return;
if (cleanupCallback.current) cleanupCallback.current();
cleanupCallback.current = createPopper(
reference.current,
popper.current,
options
).destroy;
}, [reference, popper, cleanupCallback, options]);
return useMemo(
() => [
(referenceDomNode) => {
reference.current = referenceDomNode;
instantiatePopper();
},
(popperDomNode) => {
popper.current = popperDomNode;
instantiatePopper();
},
],
[reference, popper, instantiatePopper]
);
}