288 lines
9.5 KiB
TypeScript
288 lines
9.5 KiB
TypeScript
import Taro from "@tarojs/taro";
|
|
import dayjs from "dayjs";
|
|
import { View, Text, Image, ScrollView } from "@tarojs/components";
|
|
import classnames from "classnames";
|
|
import { calculateDistance } from "@/utils";
|
|
import { useUserInfo } from "@/store/userStore";
|
|
import * as LoginService from "@/services/loginService";
|
|
import img from "@/config/images";
|
|
import { navto, formatNtrpDisplay } from "@/utils/helper";
|
|
import styles from "./index.module.scss";
|
|
|
|
function genRecommendGames(games, location, avatar) {
|
|
return games.map((item) => {
|
|
const {
|
|
id,
|
|
title,
|
|
start_time,
|
|
end_time,
|
|
court_type,
|
|
location_name,
|
|
current_players,
|
|
max_players,
|
|
latitude,
|
|
longitude,
|
|
skill_level_max,
|
|
skill_level_min,
|
|
play_type,
|
|
} = item;
|
|
const [c_latitude, c_longitude] = location;
|
|
const distance =
|
|
calculateDistance(c_latitude, c_longitude, latitude, longitude) / 1000;
|
|
const startTime = dayjs(start_time);
|
|
const endTime = dayjs(end_time);
|
|
return {
|
|
id,
|
|
title,
|
|
time: startTime.format("YYYY-MM-DD HH:MM"),
|
|
timeLength: endTime.diff(startTime, "hour"),
|
|
venue: location_name,
|
|
venueType: court_type,
|
|
distance: `${distance.toFixed(2)}km`,
|
|
avatar,
|
|
applications: max_players,
|
|
checkedApplications: current_players,
|
|
levelRequirements:
|
|
skill_level_max !== skill_level_min
|
|
? `${formatNtrpDisplay(skill_level_min) || "-"}-${
|
|
formatNtrpDisplay(skill_level_max) || "-"
|
|
}`
|
|
: skill_level_min === "1"
|
|
? "无要求"
|
|
: `${formatNtrpDisplay(skill_level_min)}以上`,
|
|
playType: play_type,
|
|
};
|
|
});
|
|
}
|
|
|
|
export default function OrganizerInfo(props) {
|
|
const {
|
|
userInfo,
|
|
currentLocation: location,
|
|
onUpdateUserInfo = () => {},
|
|
handleViewUserInfo,
|
|
handleAddComment,
|
|
} = props;
|
|
const {
|
|
id,
|
|
nickname,
|
|
avatar_url,
|
|
is_following,
|
|
ntrp_level,
|
|
stats: { hosted_games_count } = {},
|
|
ongoing_games = [],
|
|
} = userInfo;
|
|
|
|
const myInfo = useUserInfo();
|
|
const { id: my_id } = myInfo as LoginService.UserInfoType;
|
|
|
|
const recommendGames = genRecommendGames(ongoing_games, location, avatar_url);
|
|
|
|
const toggleFollow = async (follow) => {
|
|
try {
|
|
if (follow) {
|
|
await LoginService.unFollowUser(id);
|
|
} else {
|
|
await LoginService.followUser(id);
|
|
}
|
|
onUpdateUserInfo();
|
|
Taro.showToast({
|
|
title: `${nickname} ${follow ? "已取消关注" : "已关注"}`,
|
|
icon: "success",
|
|
});
|
|
} catch (e) {
|
|
Taro.showToast({
|
|
title: `${nickname} ${follow ? "取消关注失败" : "关注失败"}`,
|
|
icon: "error",
|
|
});
|
|
}
|
|
};
|
|
|
|
function handleViewGame(gameId) {
|
|
navto(`/game_pages/detail/index?id=${gameId}&from=current`);
|
|
}
|
|
|
|
return (
|
|
<View className={styles["detail-page-content-organizer-recommend-games"]}>
|
|
{/* orgnizer title */}
|
|
<View className={styles["organizer-title"]}>
|
|
<Text>组织者</Text>
|
|
</View>
|
|
{/* organizer avatar and name */}
|
|
<View className={styles["organizer-avatar-name"]}>
|
|
<Image
|
|
className={styles["organizer-avatar-name-avatar"]}
|
|
src={avatar_url}
|
|
mode="aspectFill"
|
|
onClick={handleViewUserInfo.bind(null, id)}
|
|
/>
|
|
<View className={styles["organizer-avatar-name-message"]}>
|
|
<Text className={styles["organizer-avatar-name-message-name"]}>
|
|
{nickname}
|
|
</Text>
|
|
<View className={styles["organizer-avatar-name-message-stats"]}>
|
|
<Text>已组织 {hosted_games_count} 次</Text>
|
|
<View
|
|
className={
|
|
styles["organizer-avatar-name-message-stats-separator"]
|
|
}
|
|
/>
|
|
<Text>
|
|
NTRP {ntrp_level ? formatNtrpDisplay(ntrp_level) : "初学者"}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
<View className={styles["organizer-actions"]}>
|
|
{my_id === id ? (
|
|
""
|
|
) : (
|
|
<View
|
|
className={styles["organizer-actions-follow"]}
|
|
onClick={toggleFollow.bind(null, is_following)}
|
|
>
|
|
{is_following ? (
|
|
<Text className={styles["organizer-actions-follow-text"]}>
|
|
取消关注
|
|
</Text>
|
|
) : (
|
|
<>
|
|
<Image
|
|
className={styles["organizer-actions-follow-icon"]}
|
|
src={img.ICON_DETAIL_APPLICATION_ADD}
|
|
/>
|
|
<Text className={styles["organizer-actions-follow-text"]}>
|
|
关注
|
|
</Text>
|
|
</>
|
|
)}
|
|
</View>
|
|
)}
|
|
<View
|
|
className={styles["organizer-actions-comment"]}
|
|
onClick={() => handleAddComment()}
|
|
>
|
|
<Image
|
|
className={styles["organizer-actions-comment-icon"]}
|
|
src={img.ICON_DETAIL_COMMENT}
|
|
/>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
{/* recommend games by organizer */}
|
|
{recommendGames.length > 0 && (
|
|
<View className={styles["organizer-recommend-games"]}>
|
|
<View
|
|
className={styles["organizer-recommend-games-title"]}
|
|
onClick={handleViewUserInfo.bind(null, id)}
|
|
>
|
|
<Text>TA的更多活动</Text>
|
|
<Image
|
|
className={styles["organizer-recommend-games-title-arrow"]}
|
|
src={img.ICON_DETAIL_ARROW_RIGHT}
|
|
/>
|
|
</View>
|
|
<ScrollView refresherBackground="#FAFAFA" className={styles["recommend-games-list"]} scrollX>
|
|
<View className={styles["recommend-games-list-content"]}>
|
|
{recommendGames.map((game, index) => (
|
|
<View
|
|
key={index}
|
|
className={styles["recommend-games-list-item"]}
|
|
onClick={handleViewGame.bind(null, game.id)}
|
|
>
|
|
{/* game title */}
|
|
<View className={styles["recommend-games-list-item-title"]}>
|
|
<Text>{game.title}</Text>
|
|
<Image
|
|
className={
|
|
styles["recommend-games-list-item-title-arrow"]
|
|
}
|
|
src={img.ICON_DETAIL_ARROW_RIGHT}
|
|
/>
|
|
</View>
|
|
{/* game time and range */}
|
|
<View
|
|
className={styles["recommend-games-list-item-time-range"]}
|
|
>
|
|
<Text>{game.time}</Text>
|
|
<Text>{game.timeLength}</Text>
|
|
</View>
|
|
{/* game location、vunue、distance */}
|
|
<View
|
|
className={
|
|
styles[
|
|
"recommend-games-list-item-location-venue-distance"
|
|
]
|
|
}
|
|
>
|
|
<Text>{game.venue}</Text>
|
|
<Text>·</Text>
|
|
<Text>{game.venueType}</Text>
|
|
<Text>·</Text>
|
|
<Text>{game.distance}</Text>
|
|
</View>
|
|
{/* organizer avatar、applications、level requirements、play type */}
|
|
<View className={styles["recommend-games-list-item-addon"]}>
|
|
<Image
|
|
className={
|
|
styles["recommend-games-list-item-addon-avatar"]
|
|
}
|
|
mode="aspectFill"
|
|
src={game.avatar}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
handleViewUserInfo(id);
|
|
}}
|
|
/>
|
|
<View
|
|
className={
|
|
styles["recommend-games-list-item-addon-message"]
|
|
}
|
|
>
|
|
<View
|
|
className={classnames(
|
|
styles[
|
|
"recommend-games-list-item-addon-message-applications"
|
|
],
|
|
styles.joinMsg
|
|
)}
|
|
>
|
|
<Text>已加入</Text>
|
|
<View>
|
|
<Text>{game.checkedApplications}</Text>
|
|
<Text className={styles.weaktip}>
|
|
/{game.applications}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
<View
|
|
className={
|
|
styles[
|
|
"recommend-games-list-item-addon-message-level-requirements"
|
|
]
|
|
}
|
|
>
|
|
<Text>{game.levelRequirements}</Text>
|
|
<View className={styles.spearator} />
|
|
<Text>{game.playType}</Text>
|
|
</View>
|
|
{/* <View
|
|
className={
|
|
styles[
|
|
"recommend-games-list-item-addon-message-play-type"
|
|
]
|
|
}
|
|
>
|
|
<Text>{game.playType}</Text>
|
|
</View> */}
|
|
</View>
|
|
</View>
|
|
</View>
|
|
))}
|
|
</View>
|
|
</ScrollView>
|
|
</View>
|
|
)}
|
|
</View>
|
|
);
|
|
}
|