Files
mini-programs/src/main_pages/components/MyselfPageContent.tsx
2025-11-27 21:28:01 +08:00

267 lines
8.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect, useCallback } from "react";
import { View, Text, Image, ScrollView } from "@tarojs/components";
import Taro from "@tarojs/taro";
import styles from "./MyselfPageContent.module.scss";
import { UserInfoCard } from "@/components/UserInfo/index";
import { UserService } from "@/services/userService";
import ListContainer from "@/container/listContainer";
import { TennisMatch } from "@/../types/list/types";
import { NTRPTestEntryCard } from "@/components";
import { EvaluateScene } from "@/store/evaluateStore";
import { useUserInfo } from "@/store/userStore";
import { usePickerOption } from "@/store/pickerOptionsStore";
import { useGlobalState } from "@/store/global";
const MyselfPageContent: React.FC = () => {
const pickerOption = usePickerOption();
const { statusNavbarHeightInfo } = useGlobalState() || {};
const { totalHeight = 98 } = statusNavbarHeightInfo || {};
const instance = (Taro as any).getCurrentInstance();
const user_id = instance.router?.params?.userid || "";
// const is_current_user = !user_id;
const user_info = useUserInfo();
const [game_records, set_game_records] = useState<TennisMatch[]>([]);
const [ended_game_records, setEndedGameRecords] = useState<TennisMatch[]>([]);
const [loading] = useState(false);
const [is_following, setIsFollowing] = useState(false);
const [active_tab, setActiveTab] = useState<"hosted" | "participated">(
"hosted"
);
const [collapseProfile, setCollapseProfile] = useState(false);
useEffect(() => {
pickerOption.getCities();
pickerOption.getProfessions();
}, []);
const { useDidShow } = Taro as any;
useDidShow(() => {
// 确保从编辑页面返回时刷新数据
});
// 分类球局数据(使用 useCallback 包装,避免每次渲染都创建新函数)
const classifyGameRecords = useCallback(
(
game_records: TennisMatch[]
): { notEndGames: TennisMatch[]; finishedGames: TennisMatch[] } => {
const now = new Date().getTime();
return game_records.reduce(
(result, cur) => {
let { end_time } = cur;
end_time = end_time.replace(/\s/, "T");
new Date(end_time).getTime() > now
? result.notEndGames.push(cur)
: result.finishedGames.push(cur);
return result;
},
{
notEndGames: [] as TennisMatch[],
finishedGames: [] as TennisMatch[],
}
);
},
[]
);
// 使用 useCallback 包装 load_game_data避免每次渲染都创建新函数
const load_game_data = useCallback(async () => {
try {
if (!user_info || !("id" in user_info)) {
return;
}
let games_data;
if (active_tab === "hosted") {
games_data = await UserService.get_hosted_games(user_info.id);
} else {
games_data = await UserService.get_participated_games(user_info.id);
}
const sorted_games = games_data.sort((a, b) => {
return (
new Date(a.original_start_time.replace(/\s/, "T")).getTime() -
new Date(b.original_start_time.replace(/\s/, "T")).getTime()
);
});
const { notEndGames, finishedGames } = classifyGameRecords(sorted_games);
set_game_records(notEndGames);
setEndedGameRecords(finishedGames);
} catch (error) {
console.error("加载球局数据失败:", error);
}
}, [active_tab, user_info, classifyGameRecords]);
useEffect(() => {
if (!loading) {
load_game_data();
}
}, [loading, load_game_data]);
const handle_follow = async () => {
try {
const new_following_state = await UserService.toggle_follow(
user_id,
is_following
);
setIsFollowing(new_following_state);
(Taro as any).showToast({
title: new_following_state ? "关注成功" : "已取消关注",
icon: "success",
duration: 1500,
});
} catch (error) {
console.error("关注操作失败:", error);
(Taro as any).showToast({
title: "操作失败,请重试",
icon: "error",
duration: 2000,
});
}
};
const goPublish = () => {
(Taro as any).navigateTo({
url: "/publish_pages/publishBall/index",
});
};
const handle_game_orders = () => {
(Taro as any).navigateTo({
url: "/order_pages/orderList/index",
});
};
const handle_wallet = () => {
(Taro as any).navigateTo({
url: "/user_pages/wallet/index",
// url: "/user_pages/other/index?userid=18",
});
};
const handleOnTab = (tab) => {
setActiveTab(tab);
};
const handleScroll = (event: any) => {
const scrollData = event.detail;
setCollapseProfile(scrollData.scrollTop > 1);
};
return (
<ScrollView scrollY className={styles.myselfPage} onScroll={handleScroll}>
<View
className={styles.myselfPageContentMain}
style={{ paddingTop: `${totalHeight}px` }}
>
<View className={styles.userInfoSection}>
<UserInfoCard
editable={true}
user_info={user_info}
is_current_user={true}
is_following={is_following}
collapseProfile={collapseProfile}
on_follow={handle_follow}
onTab={handleOnTab}
/>
{!collapseProfile ? (
<View className={styles.quickActionsSection}>
<View className={styles.actionCard}>
<View
className={styles.actionContent}
onClick={handle_game_orders}
>
<Image
className={styles.actionIcon}
src={require("@/static/userInfo/order_btn.svg")}
/>
<Text className={styles.actionText}></Text>
</View>
<View className={styles.actionDivider}></View>
<View className={styles.actionContent} onClick={handle_wallet}>
<Image
className={styles.actionIcon}
src={require("@/static/userInfo/wallet.svg")}
/>
<Text className={styles.actionText}></Text>
</View>
</View>
</View>
) : null}
</View>
{!collapseProfile ? (
<View className={styles.testEntryCardBox}>
<NTRPTestEntryCard type={EvaluateScene.user} />
</View>
) : null}
<View className={styles.gameTabsSection}>
<View className={styles.tabContainer}>
<View
className={`${styles.tabItem} ${
active_tab === "hosted" ? styles.active : ""
}`}
onClick={() => setActiveTab("hosted")}
>
<Text className={styles.tabText}></Text>
</View>
<View
className={`${styles.tabItem} ${
active_tab === "participated" ? styles.active : ""
}`}
onClick={() => setActiveTab("participated")}
>
<Text className={styles.tabText}></Text>
</View>
</View>
</View>
<View className={styles.gameListSection}>
<ScrollView scrollY>
<ListContainer
data={game_records}
recommendList={[]}
loading={loading}
error={null}
errorImg="ICON_LIST_EMPTY"
emptyText="暂未发布球局"
btnText="去发布"
btnImg="ICON_ADD"
reload={goPublish}
isShowNoData={game_records.length === 0}
loadMoreMatches={() => {}}
collapse={true}
style={{ paddingBottom: 0, overflow: "hidden" }}
listLoadErrorHeight="320px"
defaultShowNum={3}
/>
</ScrollView>
</View>
<View className={styles.endedGameText}></View>
<View className={styles.gameListSection}>
<ScrollView scrollY>
<ListContainer
data={ended_game_records}
recommendList={[]}
loading={loading}
error={null}
errorImg="ICON_LIST_EMPTY"
isShowNoData={ended_game_records.length === 0}
loadMoreMatches={() => {}}
collapse={true}
style={{ paddingBottom: "90px", overflow: "hidden" }}
listLoadErrorHeight="320px"
defaultShowNum={3}
/>
</ScrollView>
</View>
</View>
</ScrollView>
);
};
export default MyselfPageContent;