113 lines
4.0 KiB
TypeScript
113 lines
4.0 KiB
TypeScript
import { View, Text, Image, ScrollView } from "@tarojs/components";
|
||
import dayjs from "dayjs";
|
||
import img from "@/config/images";
|
||
import { formatNtrpDisplay } from "@/utils/helper";
|
||
import styles from "./index.module.scss";
|
||
|
||
// 参与者
|
||
export default function Participants(props) {
|
||
const { detail = {}, handleJoinGame, handleViewUserInfo } = props;
|
||
const participants = detail.participants || [];
|
||
const {
|
||
participant_count,
|
||
max_participants,
|
||
user_action_status = {},
|
||
start_time,
|
||
} = detail;
|
||
const { can_join, can_pay, can_substitute, is_substituting, waiting_start } =
|
||
user_action_status;
|
||
const showApplicationEntry =
|
||
[can_pay, can_substitute, is_substituting, waiting_start].every(
|
||
(item) => !item
|
||
) &&
|
||
can_join &&
|
||
dayjs(start_time).isAfter(dayjs());
|
||
const leftCount = max_participants - participant_count;
|
||
return (
|
||
<View className={styles["detail-page-content-participants"]}>
|
||
<View className={styles["participants-title"]}>
|
||
<Text>参与者</Text>
|
||
<Text>·</Text>
|
||
<Text>{leftCount > 0 ? `剩余空位 ${leftCount}` : "已满员"}</Text>
|
||
</View>
|
||
{participant_count > 0 || showApplicationEntry ? (
|
||
<View className={styles["participants-list"]}>
|
||
{/* application */}
|
||
{showApplicationEntry && (
|
||
<View
|
||
className={styles["participants-list-application"]}
|
||
onClick={() => {
|
||
handleJoinGame();
|
||
}}
|
||
>
|
||
<Image
|
||
className={styles["participants-list-application-icon"]}
|
||
src={img.ICON_DETAIL_APPLICATION_ADD}
|
||
/>
|
||
<Text className={styles["participants-list-application-text"]}>
|
||
申请加入
|
||
</Text>
|
||
</View>
|
||
)}
|
||
{/* participants list */}
|
||
<ScrollView className={styles["participants-list-scroll"]} scrollX>
|
||
<View
|
||
className={styles["participants-list-scroll-content"]}
|
||
style={{
|
||
width: `${
|
||
participants.length * 103 + (participants.length - 1) * 8
|
||
}px`,
|
||
}}
|
||
>
|
||
{participants.map((participant) => {
|
||
const {
|
||
is_organizer,
|
||
user: {
|
||
avatar_url,
|
||
nickname,
|
||
level,
|
||
ntrp_level,
|
||
id: participant_user_id,
|
||
},
|
||
} = participant;
|
||
const role = is_organizer ? "组织者" : "参与者";
|
||
// 优先使用 ntrp_level,如果没有则使用 level
|
||
const ntrpValue = ntrp_level || level;
|
||
// 格式化显示 NTRP,如果没有值则显示"初学者"
|
||
const displayNtrp = ntrpValue ? formatNtrpDisplay(ntrpValue) : "初学者";
|
||
return (
|
||
<View
|
||
key={participant.id}
|
||
className={styles["participants-list-item"]}
|
||
>
|
||
<Image
|
||
className={styles["participants-list-item-avatar"]}
|
||
mode="aspectFill"
|
||
src={avatar_url}
|
||
onClick={handleViewUserInfo.bind(
|
||
null,
|
||
participant_user_id
|
||
)}
|
||
/>
|
||
<Text className={styles["participants-list-item-name"]}>
|
||
{nickname || "未知"}
|
||
</Text>
|
||
<Text className={styles["participants-list-item-level"]}>
|
||
{displayNtrp}
|
||
</Text>
|
||
<Text className={styles["participants-list-item-role"]}>
|
||
{role}
|
||
</Text>
|
||
</View>
|
||
);
|
||
})}
|
||
</View>
|
||
</ScrollView>
|
||
</View>
|
||
) : (
|
||
""
|
||
)}
|
||
</View>
|
||
);
|
||
}
|