|
@@ -10,7 +10,6 @@ import {
|
|
|
Gift,
|
|
|
Users,
|
|
|
Video,
|
|
|
- DollarSign,
|
|
|
Zap,
|
|
|
} from "lucide-react";
|
|
|
|
|
@@ -30,6 +29,7 @@ const PersonalCenter = () => {
|
|
|
const [pointPage, setPointPage] = useState(1);
|
|
|
const [hasMorePredictions, setHasMorePredictions] = useState(true);
|
|
|
const [hasMorePoints, setHasMorePoints] = useState(true);
|
|
|
+ const [activities, setActivities] = useState([]);
|
|
|
|
|
|
const fetchInitialData = useCallback(async () => {
|
|
|
try {
|
|
@@ -40,27 +40,38 @@ const PersonalCenter = () => {
|
|
|
setUser(storedUser);
|
|
|
|
|
|
if (storedUser && storedUser.id) {
|
|
|
- const [predictionResponse, pointResponse, userResponse] =
|
|
|
+ const [
|
|
|
+ predictionResponse,
|
|
|
+ pointResponse,
|
|
|
+ userResponse,
|
|
|
+ activitiesResponse,
|
|
|
+ ] = await Promise.all([
|
|
|
+ fetch(
|
|
|
+ `/api/prediction?username=${encodeURIComponent(
|
|
|
+ storedUser.username
|
|
|
+ )}¤t=1&pageSize=${PAGE_SIZE}`
|
|
|
+ ),
|
|
|
+ fetch(
|
|
|
+ `/api/point-history?userId=${encodeURIComponent(
|
|
|
+ storedUser.id
|
|
|
+ )}¤t=1&pageSize=${PAGE_SIZE}`
|
|
|
+ ),
|
|
|
+ fetch(`/api/user?id=${encodeURIComponent(storedUser.id)}`),
|
|
|
+ fetch("/api/new-activities", {
|
|
|
+ headers: {
|
|
|
+ "x-from-frontend": "true",
|
|
|
+ },
|
|
|
+ }),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ const [predictionData, pointData, userData, activitiesData] =
|
|
|
await Promise.all([
|
|
|
- fetch(
|
|
|
- `/api/prediction?username=${encodeURIComponent(
|
|
|
- storedUser.username
|
|
|
- )}¤t=1&pageSize=${PAGE_SIZE}`
|
|
|
- ),
|
|
|
- fetch(
|
|
|
- `/api/point-history?userId=${encodeURIComponent(
|
|
|
- storedUser.id
|
|
|
- )}¤t=1&pageSize=${PAGE_SIZE}`
|
|
|
- ),
|
|
|
- fetch(`/api/user?id=${encodeURIComponent(storedUser.id)}`),
|
|
|
+ predictionResponse.json(),
|
|
|
+ pointResponse.json(),
|
|
|
+ userResponse.json(),
|
|
|
+ activitiesResponse.json(),
|
|
|
]);
|
|
|
|
|
|
- const [predictionData, pointData, userData] = await Promise.all([
|
|
|
- predictionResponse.json(),
|
|
|
- pointResponse.json(),
|
|
|
- userResponse.json(),
|
|
|
- ]);
|
|
|
-
|
|
|
if (predictionData.success) {
|
|
|
setPredictions(predictionData.data);
|
|
|
setHasMorePredictions(predictionData.data.length === PAGE_SIZE);
|
|
@@ -76,13 +87,28 @@ const PersonalCenter = () => {
|
|
|
}
|
|
|
|
|
|
if (userData.success && userData.data) {
|
|
|
- // 更新用户信息,特别是积分
|
|
|
const updatedUser = { ...storedUser, points: userData.data.points };
|
|
|
setUser(updatedUser);
|
|
|
localStorage.setItem("currentUser", JSON.stringify(updatedUser));
|
|
|
} else {
|
|
|
console.error("Failed to fetch user data:", userData.error);
|
|
|
}
|
|
|
+
|
|
|
+ // 处理活动数据
|
|
|
+ if (activitiesData.success) {
|
|
|
+ setActivities(activitiesData.data);
|
|
|
+ } else {
|
|
|
+ console.error("Failed to fetch activities:", activitiesData.error);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果用户未登录,仍然获取活动数据
|
|
|
+ const activitiesResponse = await activitiesPromise;
|
|
|
+ const activitiesData = await activitiesResponse.json();
|
|
|
+ if (activitiesData.success) {
|
|
|
+ setActivities(activitiesData.data);
|
|
|
+ } else {
|
|
|
+ console.error("Failed to fetch activities:", activitiesData.error);
|
|
|
+ }
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error("Error fetching data:", error);
|
|
@@ -167,22 +193,6 @@ const PersonalCenter = () => {
|
|
|
<h1 className="text-2xl font-bold ml-4">个人中心</h1>
|
|
|
</div>
|
|
|
|
|
|
- {/* <div className="bg-white text-black rounded-lg p-4 mb-4">
|
|
|
- <div className="flex items-center">
|
|
|
- <Image
|
|
|
- src="/images/cluo.webp"
|
|
|
- alt="User Avatar"
|
|
|
- width={50}
|
|
|
- height={50}
|
|
|
- className="rounded-full mr-2"
|
|
|
- />
|
|
|
- <div>
|
|
|
- <h2 className="text-xl font-bold">{user.username}</h2>
|
|
|
- <p className="text-gray-600">积分: {user.points}</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div> */}
|
|
|
-
|
|
|
<div className="bg-white text-black rounded-lg p-4 mb-4">
|
|
|
<div className="flex items-center justify-between">
|
|
|
<div className="flex items-center">
|
|
@@ -207,61 +217,34 @@ const PersonalCenter = () => {
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- {/* <div className="bg-white text-black rounded-lg p-4 mb-4">
|
|
|
- <h3 className="text-lg font-bold mb-2">最新活动</h3>
|
|
|
- <p className="mb-2">🔉最新福利活动</p>
|
|
|
- <p className="mb-2">🔜加入千人福利群</p>
|
|
|
- <div className="flex items-center">
|
|
|
- <MessageSquare className="w-5 h-5 mr-2" />
|
|
|
- <p>在线客服</p>
|
|
|
+ {activities && activities.length > 0 && (
|
|
|
+ <div className="bg-white text-black rounded-lg px-4 py-2 mb-4 shadow-md">
|
|
|
+ <h3 className="text-lg font-bold mb-1 text-blue-600">最新活动</h3>
|
|
|
+ {activities.map((activity) => (
|
|
|
+ <Link
|
|
|
+ key={activity._id}
|
|
|
+ href={activity.link}
|
|
|
+ className="flex items-center hover:bg-gray-100 p-2 rounded transition duration-300"
|
|
|
+ >
|
|
|
+ {activity.icon && (
|
|
|
+ <div className="w-5 h-5 mr-2 flex-shrink-0">
|
|
|
+ <Image
|
|
|
+ src={activity.icon}
|
|
|
+ alt={activity.title}
|
|
|
+ width={20}
|
|
|
+ height={20}
|
|
|
+ className="object-contain"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ <p>{activity.title}</p>
|
|
|
+ </Link>
|
|
|
+ ))}
|
|
|
</div>
|
|
|
- </div> */}
|
|
|
-
|
|
|
- <div className="bg-white text-black rounded-lg px-4 py-2 mb-4 shadow-md">
|
|
|
- <h3 className="text-xl font-bold mb-1 text-blue-600">最新活动</h3>
|
|
|
- <Link
|
|
|
- href="/betting"
|
|
|
- className="flex items-center hover:bg-gray-100 p-2 rounded transition duration-300"
|
|
|
- >
|
|
|
- {/* <DollarSign className="w-5 h-5 mr-1 text-red-500" /> */}
|
|
|
- <Zap className="w-5 h-5 mr-1 text-[#FFD700]" />
|
|
|
- <p className="text-lg">1919智博投注</p>
|
|
|
- </Link>
|
|
|
- <Link
|
|
|
- href="/activity"
|
|
|
- className="flex items-center hover:bg-gray-100 p-2 rounded transition duration-300"
|
|
|
- >
|
|
|
- <Gift className="w-5 h-5 mr-1 text-red-500" />
|
|
|
- <p className="text-lg">最新福利活动</p>
|
|
|
- </Link>
|
|
|
-
|
|
|
- <Link
|
|
|
- href="/live-stream"
|
|
|
- className="flex items-center hover:bg-gray-100 p-2 rounded transition duration-300"
|
|
|
- >
|
|
|
- <Video className="w-5 h-5 mr-1 text-green-500" />
|
|
|
- <p className="text-lg">高清直播美女解说</p>
|
|
|
- </Link>
|
|
|
-
|
|
|
- <Link
|
|
|
- href="/join-group"
|
|
|
- className="flex items-center hover:bg-gray-100 p-2 rounded transition duration-300"
|
|
|
- >
|
|
|
- <Users className="w-5 h-5 mr-1 text-purple-500" />
|
|
|
- <p className="text-lg">加入千人福利群</p>
|
|
|
- </Link>
|
|
|
-
|
|
|
- <Link
|
|
|
- href="/customer-service"
|
|
|
- className="flex items-center hover:bg-gray-100 p-2 rounded transition duration-300"
|
|
|
- >
|
|
|
- <MessageSquare className="w-5 h-5 mr-1 text-blue-500" />
|
|
|
- <p className="text-lg">在线客服</p>
|
|
|
- </Link>
|
|
|
- </div>
|
|
|
+ )}
|
|
|
|
|
|
<div className="bg-white text-black rounded-lg p-4 mb-4">
|
|
|
- <h3 className="text-xl font-bold mb-2 text-blue-600">预测记录</h3>
|
|
|
+ <h3 className="text-lg font-bold mb-2 text-blue-600">预测记录</h3>
|
|
|
<div id="predictionScroll" className="h-[300px] overflow-auto">
|
|
|
<InfiniteScroll
|
|
|
dataLength={predictions.length}
|
|
@@ -278,7 +261,7 @@ const PersonalCenter = () => {
|
|
|
key={prediction._id}
|
|
|
className="mb-4 border-b border-gray-200 pb-4 hover:bg-gray-50 transition duration-150 ease-in-out"
|
|
|
>
|
|
|
- <p className="font-bold text-lg text-blue-700 mb-2">
|
|
|
+ <p className="font-bold text-blue-700 mb-2">
|
|
|
{prediction.matchInfo}
|
|
|
</p>
|
|
|
<p className="text-gray-600 mb-2">
|
|
@@ -401,7 +384,7 @@ const PersonalCenter = () => {
|
|
|
|
|
|
<div className="bg-white text-black rounded-lg p-4 mb-4">
|
|
|
<h3 className="text-lg font-bold mb-2 text-blue-700">积分记录</h3>
|
|
|
- <div id="pointScroll" style={{ height: "300px", overflow: "auto" }}>
|
|
|
+ <div id="pointScroll" style={{ height: "250px", overflow: "auto" }}>
|
|
|
<InfiniteScroll
|
|
|
dataLength={points.length}
|
|
|
next={loadMorePoints}
|