paper-ai-release-24-07-21/components/PaperManagement.tsx

212 lines
7.2 KiB
TypeScript
Raw Normal View History

2024-02-08 10:28:52 +08:00
"use client";
import { useCallback, useState, useEffect } from "react";
//redux
import { useAppDispatch, useAppSelector } from "@/app/store";
import {
setEditorContent,
setReferencesRedux,
} from "@/app/store/slices/authSlice";
import {
setPaperNumberRedux,
setContentUpdatedFromNetwork,
2024-02-08 23:06:35 +08:00
setIsVip,
2024-02-08 10:28:52 +08:00
} from "@/app/store/slices/stateSlice";
//supabase
import { createClient } from "@/utils/supabase/client";
import {
getUser,
getUserPaperNumbers,
getUserPaper,
submitPaper,
deletePaper,
2024-02-08 15:47:25 +08:00
fetchUserVipStatus,
2024-02-08 10:28:52 +08:00
} from "@/utils/supabase/supabaseutils";
//动画
import { CSSTransition } from "react-transition-group";
2024-02-12 20:55:14 +08:00
// import { animated, useSpring } from "@react-spring/web";
2024-02-08 10:28:52 +08:00
//删除远程论文按钮
import ParagraphDeleteButton from "@/components/ParagraphDeleteInterface";
2024-02-08 15:47:25 +08:00
//vip充值按钮
import BuyVipButton from "@/components/BuyVipButton"; // 假设这是购买VIP的按钮组件
2024-02-12 20:55:14 +08:00
//i18n
import { useTranslation } from "@/app/i18n/client";
2024-02-08 10:28:52 +08:00
2024-02-12 20:55:14 +08:00
const PaperManagement = ({ lng }) => {
//i18n
const { t } = useTranslation(lng);
2024-02-08 10:28:52 +08:00
//supabase
const supabase = createClient();
//redux
const dispatch = useAppDispatch();
const paperNumberRedux = useAppSelector(
(state) => state.state.paperNumberRedux
);
const showPaperManagement = useAppSelector(
(state) => state.state.showPaperManagement
);
2024-02-08 23:06:35 +08:00
//vip状态
const isVip = useAppSelector((state) => state.state.isVip);
2024-02-08 15:47:25 +08:00
//获取的论文数量列表状态
2024-02-08 10:28:52 +08:00
const [paperNumbers, setPaperNumbers] = useState<string[]>([]);
//user id的状态设置
const [userId, setUserId] = useState<string>("");
2024-02-08 15:47:25 +08:00
//获取用户存储在云端的论文使用useCallback定义一个记忆化的函数来获取用户论文
2024-02-08 10:28:52 +08:00
const fetchPapers = useCallback(async () => {
2024-02-11 22:19:24 +08:00
const user = await getUser();
2024-02-08 10:28:52 +08:00
if (user && user.id) {
2024-02-10 13:25:43 +08:00
// console.log("user.id", user.id);
2024-02-08 15:47:25 +08:00
const numbers = await getUserPaperNumbers(user.id, supabase);
2024-02-08 10:28:52 +08:00
setPaperNumbers(numbers || []); // 直接在这里更新状态
setUserId(user.id);
}
}, [supabase]); // 依赖项数组中包含supabase因为它可能会影响到fetchPapers函数的结果
2024-02-08 15:47:25 +08:00
//获取用户VIP状态
const initFetchVipStatue = useCallback(async () => {
2024-02-08 15:47:25 +08:00
const user = await getUser();
if (user && user.id) {
const isVip = await fetchUserVipStatus(user.id);
return isVip;
2024-02-08 15:47:25 +08:00
}
}, [supabase]);
2024-02-08 15:47:25 +08:00
2024-02-08 10:28:52 +08:00
// 使用useEffect在组件挂载后立即获取数据
useEffect(() => {
const checkAndFetchPapers = async () => {
const isVip = await initFetchVipStatue();
dispatch(setIsVip(isVip));
console.log("isVip in initFetchVipStatue", isVip);
if (isVip) {
fetchPapers();
}
};
checkAndFetchPapers();
}, [supabase]);
2024-02-08 10:28:52 +08:00
const handlePaperClick = async (paperNumber: string) => {
2024-02-08 15:47:25 +08:00
const data = await getUserPaper(userId, paperNumber, supabase); // 假设这个函数异步获取论文内容
2024-02-08 10:28:52 +08:00
if (!data) {
throw new Error("查询出错");
}
console.log("paperNumber", paperNumber);
// 更新状态以反映选中的论文内容
dispatch(setEditorContent(data.paper_content)); // 更新 Redux store
dispatch(setReferencesRedux(JSON.parse(data.paper_reference))); // 清空引用列表
dispatch(setPaperNumberRedux(paperNumber)); // 更新当前论文编号
//从网络请求中更新editorContent时同时设置contentUpdatedFromNetwork为true
dispatch(setContentUpdatedFromNetwork(true)); // 更新 Redux store
};
2024-02-08 15:47:25 +08:00
function getNextPaperNumber(paperNumbers: string[]) {
if (paperNumbers.length === 0) {
return "1";
} else {
return String(Math.max(...paperNumbers.map(Number)) + 1);
}
}
2024-02-08 10:28:52 +08:00
const handleAddPaperClick = async () => {
// 添加一个新的空白论文
await submitPaper(
supabase,
"This is a blank page",
[],
2024-02-08 15:47:25 +08:00
getNextPaperNumber(paperNumbers)
2024-02-08 10:28:52 +08:00
);
// 重新获取论文列表
await fetchPapers();
};
// const animations = useSpring({
// opacity: showPaperManagement ? 1 : 0,
// from: { opacity: 0 },
// });
2024-02-08 10:28:52 +08:00
return (
<CSSTransition
in={showPaperManagement}
timeout={2000}
classNames="slide"
unmountOnExit
>
{/* showPaperManagement ? ( */}
{/* <animated.div style={animations}> */}
2024-02-08 10:28:52 +08:00
<>
<div className="paper-management-container flex flex-col items-center space-y-4">
<div className="max-w-md w-full bg-blue-gray-100 rounded overflow-hidden shadow-lg mx-auto p-5">
2024-02-12 20:55:14 +08:00
<h1 className="font-bold text-3xl text-center">
{" "}
{t("Paper Management")}
</h1>
2024-02-08 10:28:52 +08:00
</div>
2024-02-08 15:47:25 +08:00
{isVip ? (
<div>
<button
onClick={handleAddPaperClick}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
2024-02-12 20:55:14 +08:00
{t("+ Add Paper")}
2024-02-08 15:47:25 +08:00
</button>
<div className="flex flex-col items-center space-y-2">
2024-02-12 20:55:14 +08:00
<h2 className="text-xl font-semibold">
{" "}
{t("Your Cloud Papers")}
</h2>
2024-02-08 15:47:25 +08:00
{paperNumbers.length > 0 ? (
<ul className="list-disc">
{[...paperNumbers]
.sort((a, b) => parseInt(a, 10) - parseInt(b, 10))
.map((number, index) => (
<li
key={index}
className={`bg-white w-full max-w-md mx-auto rounded shadow p-4 cursor-pointer ${
number === paperNumberRedux ? "bg-yellow-200" : ""
}`}
onClick={() => handlePaperClick(number)}
>
<span>Paper {number}</span>
<ParagraphDeleteButton
index={index}
removeReferenceUpdateIndex={async () => {
await deletePaper(supabase, userId, number);
const numbers = await getUserPaperNumbers(
userId,
supabase
);
setPaperNumbers(numbers || []); // 直接在这里更新状态
}}
isRemovePaper={true}
title="Do you want to delete this paper?"
text="This action cannot be undone"
></ParagraphDeleteButton>
{/* <input
2024-02-08 10:28:52 +08:00
type="text"
value={paper.title}
onChange={(e) => handleTitleChange(index, e.target.value)}
placeholder="Enter paper title"
className="mt-2 p-2 border rounded"
/> */}
2024-02-08 15:47:25 +08:00
</li>
))}
</ul>
) : (
<p>No papers found.</p>
)}
</div>
</div>
) : (
2024-02-12 20:55:14 +08:00
<BuyVipButton lng={lng} />
2024-02-08 15:47:25 +08:00
)}
2024-02-08 10:28:52 +08:00
</div>
</>
{/* </animated.div>
) : null */}
2024-02-08 10:28:52 +08:00
</CSSTransition>
);
};
export default PaperManagement;