Fix/poplayout warning (#194)

* fix(auth): use redirect instead of router

* fix(auth): use router for after render redirects

* fix(anims): forward ref in file component

* fix(anims): forward ref in document item

* fix(CI)
This commit is contained in:
!MAD! 2023-05-29 15:56:49 +05:30 committed by GitHub
parent 989f8de4ca
commit 3769795f9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 130 additions and 114 deletions

View File

@ -3,7 +3,14 @@ import Spinner from "@/app/components/ui/Spinner";
import { useSupabase } from "@/app/supabase-provider";
import { useToast } from "@/lib/hooks/useToast";
import axios from "axios";
import { Dispatch, SetStateAction, Suspense, useState } from "react";
import {
Dispatch,
RefObject,
SetStateAction,
Suspense,
forwardRef,
useState,
} from "react";
import Button from "../../components/ui/Button";
import { AnimatedCard } from "../../components/ui/Card";
import Modal from "../../components/ui/Modal";
@ -15,83 +22,86 @@ interface DocumentProps {
setDocuments: Dispatch<SetStateAction<Document[]>>;
}
const DocumentItem = ({ document, setDocuments }: DocumentProps) => {
const [isDeleting, setIsDeleting] = useState(false);
const { publish } = useToast();
const { session } = useSupabase();
if (!session) {
throw new Error("User session not found");
}
const deleteDocument = async (name: string) => {
setIsDeleting(true);
try {
await axios.delete(
`${process.env.NEXT_PUBLIC_BACKEND_URL}/explore/${name}`,
{
headers: {
Authorization: `Bearer ${session.access_token}`,
},
}
);
setDocuments((docs) => docs.filter((doc) => doc.name !== name)); // Optimistic update
publish({ variant: "success", text: `${name} deleted.` });
} catch (error) {
console.error(`Error deleting ${name}`, error);
const DocumentItem = forwardRef(
({ document, setDocuments }: DocumentProps, forwardedRef) => {
const [isDeleting, setIsDeleting] = useState(false);
const { publish } = useToast();
const { session } = useSupabase();
if (!session) {
throw new Error("User session not found");
}
setIsDeleting(false);
};
return (
<AnimatedCard
initial={{ x: -64, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: 64, opacity: 0 }}
layout
className="flex flex-col sm:flex-row sm:items-center justify-between w-full p-5 gap-5"
>
<p className="text-lg leading-tight max-w-sm">{document.name}</p>
<div className="flex gap-2 self-end">
{/* VIEW MODAL */}
<Modal
title={document.name}
desc={""}
Trigger={<Button className="">View</Button>}
>
<Suspense fallback={<Spinner />}>
{/* @ts-expect-error TODO: check if DocumentData component can be sync */}
<DocumentData documentName={document.name} />
</Suspense>
</Modal>
const deleteDocument = async (name: string) => {
setIsDeleting(true);
try {
await axios.delete(
`${process.env.NEXT_PUBLIC_BACKEND_URL}/explore/${name}`,
{
headers: {
Authorization: `Bearer ${session.access_token}`,
},
}
);
setDocuments((docs) => docs.filter((doc) => doc.name !== name)); // Optimistic update
publish({ variant: "success", text: `${name} deleted.` });
} catch (error) {
console.error(`Error deleting ${name}`, error);
}
setIsDeleting(false);
};
{/* DELETE MODAL */}
<Modal
title={"Confirm"}
desc={`Do you really want to delete?`}
Trigger={
<Button isLoading={isDeleting} variant={"danger"} className="">
Delete
</Button>
}
CloseTrigger={
<Button
variant={"danger"}
isLoading={isDeleting}
onClick={() => {
deleteDocument(document.name);
}}
className="self-end"
>
Delete forever
</Button>
}
>
<p>{document.name}</p>
</Modal>
</div>
</AnimatedCard>
);
};
return (
<AnimatedCard
initial={{ x: -64, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: 64, opacity: 0 }}
layout
ref={forwardedRef as RefObject<HTMLDivElement>}
className="flex flex-col sm:flex-row sm:items-center justify-between w-full p-5 gap-5"
>
<p className="text-lg leading-tight max-w-sm">{document.name}</p>
<div className="flex gap-2 self-end">
{/* VIEW MODAL */}
<Modal
title={document.name}
desc={""}
Trigger={<Button className="">View</Button>}
>
<Suspense fallback={<Spinner />}>
{/* @ts-expect-error TODO: check if DocumentData component can be sync */}
<DocumentData documentName={document.name} />
</Suspense>
</Modal>
{/* DELETE MODAL */}
<Modal
title={"Confirm"}
desc={`Do you really want to delete?`}
Trigger={
<Button isLoading={isDeleting} variant={"danger"} className="">
Delete
</Button>
}
CloseTrigger={
<Button
variant={"danger"}
isLoading={isDeleting}
onClick={() => {
deleteDocument(document.name);
}}
className="self-end"
>
Delete forever
</Button>
}
>
<p>{document.name}</p>
</Modal>
</div>
</AnimatedCard>
);
}
);
DocumentItem.displayName = "DocumentItem";
export default DocumentItem;

View File

@ -41,7 +41,7 @@ export default function ExplorePage() {
setIsPending(false);
};
fetchDocuments();
}, []);
}, [session.access_token]);
return (
<main>

View File

@ -61,7 +61,7 @@ export const useCrawler = () => {
} finally {
setCrawling(false);
}
}, [session.access_token]);
}, [session.access_token, publish]);
return {
isCrawling,

View File

@ -1,41 +1,47 @@
import { motion } from "framer-motion";
import { Dispatch, SetStateAction } from "react";
import { Dispatch, RefObject, SetStateAction, forwardRef } from "react";
import { MdClose } from "react-icons/md";
export const FileComponent = ({
file,
setFiles,
}: {
interface FileComponentProps {
file: File;
setFiles: Dispatch<SetStateAction<File[]>>;
}) => {
return (
<motion.div
initial={{ x: "-10%", opacity: 0 }}
animate={{ x: "0%", opacity: 1 }}
exit={{ x: "10%", opacity: 0 }}
layout
className="relative flex flex-row gap-1 py-2 dark:bg-black border-b last:border-none border-black/10 dark:border-white/25 leading-none px-6 overflow-hidden"
>
<div className="flex flex-1">
<div className="flex flex-col">
<span className="overflow-ellipsis overflow-hidden whitespace-nowrap">
{file.name}
</span>
<span className="text-xs opacity-50 overflow-hidden text-ellipsis">
{(file.size / 1000).toFixed(3)} kb
</span>
</div>
</div>
<button
role="remove file"
className="text-xl text-red-500 text-ellipsis absolute top-0 h-full right-0 flex items-center justify-center bg-white dark:bg-black p-3 shadow-md aspect-square"
onClick={() =>
setFiles((files) => files.filter((f) => f.name !== file.name))
}
}
const FileComponent = forwardRef(
({ file, setFiles }: FileComponentProps, forwardedRef) => {
return (
<motion.div
initial={{ x: "-10%", opacity: 0 }}
animate={{ x: "0%", opacity: 1 }}
exit={{ x: "10%", opacity: 0 }}
layout
ref={forwardedRef as RefObject<HTMLDivElement>}
className="relative flex flex-row gap-1 py-2 dark:bg-black border-b last:border-none border-black/10 dark:border-white/25 leading-none px-6 overflow-hidden"
>
<MdClose />
</button>
</motion.div>
);
};
<div className="flex flex-1">
<div className="flex flex-col">
<span className="overflow-ellipsis overflow-hidden whitespace-nowrap">
{file.name}
</span>
<span className="text-xs opacity-50 overflow-hidden text-ellipsis">
{(file.size / 1000).toFixed(3)} kb
</span>
</div>
</div>
<button
role="remove file"
className="text-xl text-red-500 text-ellipsis absolute top-0 h-full right-0 flex items-center justify-center bg-white dark:bg-black p-3 shadow-md aspect-square"
onClick={() =>
setFiles((files) => files.filter((f) => f.name !== file.name))
}
>
<MdClose />
</button>
</motion.div>
);
}
);
FileComponent.displayName = "FileComponent";
export default FileComponent;

View File

@ -45,7 +45,7 @@ export const useFileUploader = () => {
});
}
},
[session.access_token]
[session.access_token, publish]
);
const onDrop = (acceptedFiles: File[], fileRejections: FileRejection[]) => {

View File

@ -2,7 +2,7 @@
import { AnimatePresence } from "framer-motion";
import Button from "../../../components/ui/Button";
import Card from "../../../components/ui/Card";
import { FileComponent } from "./components/FileComponent";
import FileComponent from "./components/FileComponent";
import { useFileUploader } from "./hooks/useFileUploader";
export const FileUploader = (): JSX.Element => {