feat: 球局详情管理 未完
This commit is contained in:
@@ -807,7 +807,7 @@
|
||||
}
|
||||
|
||||
&-organizer-recommend-games {
|
||||
padding: 24px 15px 0;
|
||||
padding: 24px 15px 10px;
|
||||
|
||||
.organizer-title {
|
||||
overflow: hidden;
|
||||
@@ -1122,27 +1122,47 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-join-game {
|
||||
.detail-main-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 52px;
|
||||
width: auto;
|
||||
padding: 2px 6px;
|
||||
// padding: 2px 6px;
|
||||
box-sizing: border-box;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
flex: 1 0 0;
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
// border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
|
||||
&-price {
|
||||
font-family: "PoetsenOne";
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
line-height: 24px; /* 114.286% */
|
||||
letter-spacing: -0.56px;
|
||||
color: #000;
|
||||
.sticky-bottom-bar-join-game {
|
||||
margin-left: auto;
|
||||
width: 151px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&-price {
|
||||
font-family: "PoetsenOne";
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
line-height: 24px; /* 114.286% */
|
||||
letter-spacing: -0.56px;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.game_manage {
|
||||
width: 100px;
|
||||
margin-left: auto;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #000;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,12 @@ import Taro, {
|
||||
import dayjs from "dayjs";
|
||||
import "dayjs/locale/zh-cn";
|
||||
// 导入API服务
|
||||
import { CommonPopup, withAuth, NTRPEvaluatePopup } from "@/components";
|
||||
import {
|
||||
CommonPopup,
|
||||
withAuth,
|
||||
NTRPEvaluatePopup,
|
||||
GameManagePopup,
|
||||
} from "@/components";
|
||||
import {
|
||||
EvaluateType,
|
||||
SceneType,
|
||||
@@ -210,7 +215,7 @@ const SharePopup = forwardRef(
|
||||
</View>
|
||||
</CommonPopup>
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
function navto(url) {
|
||||
@@ -219,20 +224,18 @@ function navto(url) {
|
||||
});
|
||||
}
|
||||
|
||||
function toast(message) {
|
||||
Taro.showToast({ title: message, icon: "none" });
|
||||
}
|
||||
|
||||
// 底部操作栏
|
||||
function StickyButton(props) {
|
||||
const { handleShare, handleJoinGame, detail } = props;
|
||||
const { handleShare, handleJoinGame, detail, onStatusChange } = props;
|
||||
const ntrpRef = useRef(null);
|
||||
// const userInfo = useUserInfo();
|
||||
// const { id } = userInfo;
|
||||
const {
|
||||
id,
|
||||
publisher_id,
|
||||
match_status,
|
||||
price,
|
||||
user_action_status,
|
||||
end_time,
|
||||
} = detail || {};
|
||||
const { id, price, user_action_status, end_time, is_organizer } =
|
||||
detail || {};
|
||||
|
||||
const gameManageRef = useRef();
|
||||
|
||||
function handleSelfEvaluate() {
|
||||
// TODO: 打开自评弹窗
|
||||
@@ -240,13 +243,14 @@ function StickyButton(props) {
|
||||
}
|
||||
|
||||
function generateTextAndAction(
|
||||
user_action_status: null | { [key: string]: boolean },
|
||||
user_action_status: null | { [key: string]: boolean }
|
||||
): undefined | { text: string | React.FC; action: () => void } {
|
||||
if (!user_action_status) {
|
||||
return;
|
||||
}
|
||||
const displayPrice = is_organizer ? 0 : price;
|
||||
// user_action_status.can_assess = true;
|
||||
user_action_status.can_join = true;
|
||||
// user_action_status.can_join = true;
|
||||
const {
|
||||
can_assess,
|
||||
can_join,
|
||||
@@ -260,27 +264,27 @@ function StickyButton(props) {
|
||||
dayjs(end_time).isBefore(dayjs())
|
||||
) {
|
||||
return {
|
||||
text: "球局已结束,查看其他球局",
|
||||
action: navto.bind(null, "/game_pages/list/index"),
|
||||
text: "活动已结束",
|
||||
action: () => toast("活动已结束"),
|
||||
};
|
||||
}
|
||||
if (waiting_start) {
|
||||
return {
|
||||
text: "等待开始, 查看更多球局",
|
||||
action: navto.bind(null, "/game_pages/list/index"),
|
||||
text: () => <Text>¥{displayPrice} 已加入</Text>,
|
||||
action: () => toast("已加入"),
|
||||
};
|
||||
} else if (is_substituting) {
|
||||
return {
|
||||
text: "候补中,查看其他球局",
|
||||
action: navto.bind(null, "/game_pages/list/index"),
|
||||
text: () => <Text>¥{displayPrice} 已加入候补</Text>,
|
||||
action: () => toast("已加入候补"),
|
||||
};
|
||||
} else if (can_pay) {
|
||||
return {
|
||||
text: "继续支付",
|
||||
text: () => <Text>¥{price} 继续支付</Text>,
|
||||
action: async () => {
|
||||
const res = await OrderService.getUnpaidOrder(id);
|
||||
if (res.code === 0) {
|
||||
Taro.navigateTo({
|
||||
navto({
|
||||
url: `/order_pages/orderDetail/index?id=${res.data.order_info.order_id}`,
|
||||
});
|
||||
}
|
||||
@@ -288,21 +292,13 @@ function StickyButton(props) {
|
||||
};
|
||||
} else if (can_substitute) {
|
||||
return {
|
||||
text: "立即候补",
|
||||
text: () => <Text>¥{displayPrice} 我要候补</Text>,
|
||||
action: handleJoinGame,
|
||||
};
|
||||
} else if (can_join) {
|
||||
return {
|
||||
text: () => {
|
||||
return (
|
||||
<>
|
||||
<Text>🎾</Text>
|
||||
<Text>立即加入</Text>
|
||||
<View className="game-price">
|
||||
<Text>¥ {price}</Text>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
return <Text>¥{displayPrice} 立即加入</Text>;
|
||||
},
|
||||
action: handleJoinGame,
|
||||
};
|
||||
@@ -315,7 +311,7 @@ function StickyButton(props) {
|
||||
scene={SceneType.DETAIL}
|
||||
displayCondition={DisplayConditionType.AUTO}
|
||||
>
|
||||
<Text>NTRP自评</Text>
|
||||
<Text>¥{displayPrice} 立即加入</Text>
|
||||
</NTRPEvaluatePopup>
|
||||
),
|
||||
action: handleSelfEvaluate,
|
||||
@@ -341,36 +337,49 @@ function StickyButton(props) {
|
||||
};
|
||||
}
|
||||
|
||||
// const role = Number(publisher_id) === id ? "ownner" : "visitor";
|
||||
|
||||
return (
|
||||
<View className="sticky-bottom-bar">
|
||||
<View className="sticky-bottom-bar-share-and-comment">
|
||||
<View className="sticky-bottom-bar-share" onClick={handleShare}>
|
||||
<Image
|
||||
className="sticky-bottom-bar-share-icon"
|
||||
src={img.ICON_DETAIL_SHARE}
|
||||
/>
|
||||
<Text className="sticky-bottom-bar-share-text">分享</Text>
|
||||
<>
|
||||
<View className="sticky-bottom-bar">
|
||||
<View className="sticky-bottom-bar-share-and-comment">
|
||||
<View className="sticky-bottom-bar-share" onClick={handleShare}>
|
||||
<Image
|
||||
className="sticky-bottom-bar-share-icon"
|
||||
src={img.ICON_DETAIL_SHARE}
|
||||
/>
|
||||
<Text className="sticky-bottom-bar-share-text">分享</Text>
|
||||
</View>
|
||||
<View className="sticky-bottom-bar-share-and-comment-separator" />
|
||||
<View
|
||||
className="sticky-bottom-bar-comment"
|
||||
onClick={() => {
|
||||
Taro.showToast({ title: "To be continued", icon: "none" });
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
className="sticky-bottom-bar-comment-icon"
|
||||
src={img.ICON_DETAIL_COMMENT_DARK}
|
||||
/>
|
||||
<Text className="sticky-bottom-bar-comment-text">32</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View className="sticky-bottom-bar-share-and-comment-separator" />
|
||||
<View
|
||||
className="sticky-bottom-bar-comment"
|
||||
onClick={() => {
|
||||
Taro.showToast({ title: "To be continued", icon: "none" });
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
className="sticky-bottom-bar-comment-icon"
|
||||
src={img.ICON_DETAIL_COMMENT_DARK}
|
||||
/>
|
||||
<Text className="sticky-bottom-bar-comment-text">32</Text>
|
||||
<View className="detail-main-action">
|
||||
<View className="sticky-bottom-bar-join-game" onClick={action}>
|
||||
<ActionText />
|
||||
</View>
|
||||
{is_organizer && (
|
||||
<View
|
||||
className="game_manage"
|
||||
onClick={() => {
|
||||
gameManageRef.current.show(detail, onStatusChange);
|
||||
}}
|
||||
>
|
||||
管理
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
<View className="sticky-bottom-bar-join-game" onClick={action}>
|
||||
<ActionText />
|
||||
</View>
|
||||
</View>
|
||||
<GameManagePopup ref={gameManageRef} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -612,10 +621,11 @@ function VenueInfo(props) {
|
||||
}
|
||||
|
||||
function genNTRPRequirementText(min, max) {
|
||||
console.log(min, max, "ntrp");
|
||||
if (min && max && min !== max) {
|
||||
return `${min} - ${max} 之间`;
|
||||
} else if (max === 1) {
|
||||
return "没有要求";
|
||||
} else if (max === "1") {
|
||||
return "无要求";
|
||||
} else if (max) {
|
||||
return `${max} 以上`;
|
||||
}
|
||||
@@ -675,10 +685,9 @@ function Participants(props) {
|
||||
user_action_status;
|
||||
const showApplicationEntry =
|
||||
[can_pay, can_substitute, is_substituting, waiting_start].every(
|
||||
(item) => !item,
|
||||
(item) => !item
|
||||
) && can_join;
|
||||
const leftCount = max_participants - participant_count;
|
||||
const organizer_id = Number(detail.publisher_id);
|
||||
return (
|
||||
<View className="detail-page-content-participants">
|
||||
<View className="participants-title">
|
||||
@@ -694,7 +703,6 @@ function Participants(props) {
|
||||
className="participants-list-application"
|
||||
onClick={() => {
|
||||
handleJoinGame();
|
||||
// Taro.showToast({ title: "To be continued", icon: "none" });
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
@@ -711,11 +719,14 @@ function Participants(props) {
|
||||
<View
|
||||
className="participants-list-scroll-content"
|
||||
style={{
|
||||
width: `${participants.length * 103 + (participants.length - 1) * 8}px`,
|
||||
width: `${
|
||||
participants.length * 103 + (participants.length - 1) * 8
|
||||
}px`,
|
||||
}}
|
||||
>
|
||||
{participants.map((participant) => {
|
||||
const {
|
||||
is_organizer,
|
||||
user: {
|
||||
avatar_url,
|
||||
nickname,
|
||||
@@ -723,15 +734,17 @@ function Participants(props) {
|
||||
id: participant_user_id,
|
||||
},
|
||||
} = participant;
|
||||
const role =
|
||||
participant_user_id === organizer_id ? "组织者" : "参与者";
|
||||
const role = is_organizer ? "组织者" : "参与者";
|
||||
return (
|
||||
<View key={participant.id} className="participants-list-item">
|
||||
<Image
|
||||
className="participants-list-item-avatar"
|
||||
mode="aspectFill"
|
||||
src={avatar_url}
|
||||
onClick={handleViewUserInfo.bind(null, participant_user_id)}
|
||||
onClick={handleViewUserInfo.bind(
|
||||
null,
|
||||
participant_user_id
|
||||
)}
|
||||
/>
|
||||
<Text className="participants-list-item-name">
|
||||
{nickname || "未知"}
|
||||
@@ -813,7 +826,12 @@ function genRecommendGames(games, location, avatar) {
|
||||
avatar,
|
||||
applications: max_players,
|
||||
checkedApplications: current_players,
|
||||
levelRequirements: skill_level_max !== skill_level_min ? `${skill_level_min || '-'}至${skill_level_max || '-'}` : skill_level_min === 1 ? '无要求' : `${skill_level_min}以上`,
|
||||
levelRequirements:
|
||||
skill_level_max !== skill_level_min
|
||||
? `${skill_level_min || "-"}至${skill_level_max || "-"}`
|
||||
: skill_level_min === "1"
|
||||
? "无要求"
|
||||
: `${skill_level_min}以上`,
|
||||
playType: play_type,
|
||||
};
|
||||
});
|
||||
@@ -862,9 +880,9 @@ function OrganizerInfo(props) {
|
||||
};
|
||||
|
||||
function handleViewGame(gameId) {
|
||||
Taro.navigateTo({
|
||||
url: `/game_pages/detail/index?id=${gameId}&from=current`
|
||||
})
|
||||
navto({
|
||||
url: `/game_pages/detail/index?id=${gameId}&from=current`,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -875,7 +893,12 @@ function OrganizerInfo(props) {
|
||||
</View>
|
||||
{/* organizer avatar and name */}
|
||||
<View className="organizer-avatar-name">
|
||||
<Image className="organizer-avatar-name-avatar" src={avatar_url} mode="aspectFill" onClick={handleViewUserInfo.bind(null, id)} />
|
||||
<Image
|
||||
className="organizer-avatar-name-avatar"
|
||||
src={avatar_url}
|
||||
mode="aspectFill"
|
||||
onClick={handleViewUserInfo.bind(null, id)}
|
||||
/>
|
||||
<View className="organizer-avatar-name-message">
|
||||
<Text className="organizer-avatar-name-message-name">{nickname}</Text>
|
||||
<View className="organizer-avatar-name-message-stats">
|
||||
@@ -914,66 +937,79 @@ function OrganizerInfo(props) {
|
||||
</View>
|
||||
</View>
|
||||
{/* recommend games by organizer */}
|
||||
<View className="organizer-recommend-games">
|
||||
<View className="organizer-recommend-games-title" onClick={handleViewUserInfo.bind(null, id)}>
|
||||
<Text>TA的更多活动</Text>
|
||||
<Image
|
||||
className="organizer-recommend-games-title-arrow"
|
||||
src={img.ICON_DETAIL_ARROW_RIGHT}
|
||||
/>
|
||||
</View>
|
||||
<ScrollView className="recommend-games-list" scrollX>
|
||||
<View className="recommend-games-list-content">
|
||||
{recommendGames.map((game, index) => (
|
||||
<View key={index} className="recommend-games-list-item" onClick={handleViewGame.bind(null, game.id)}>
|
||||
{/* game title */}
|
||||
<View className="recommend-games-list-item-title">
|
||||
<Text>{game.title}</Text>
|
||||
<Image
|
||||
className="recommend-games-list-item-title-arrow"
|
||||
src={img.ICON_DETAIL_ARROW_RIGHT}
|
||||
/>
|
||||
</View>
|
||||
{/* game time and range */}
|
||||
<View className="recommend-games-list-item-time-range">
|
||||
<Text>{game.time}</Text>
|
||||
<Text>{game.timeLength}</Text>
|
||||
</View>
|
||||
{/* game location、vunue、distance */}
|
||||
<View className="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="recommend-games-list-item-addon">
|
||||
<Image
|
||||
className="recommend-games-list-item-addon-avatar"
|
||||
mode="aspectFill"
|
||||
src={game.avatar}
|
||||
onClick={(e) => { e.stopPropagation(); handleViewUserInfo(id) }}
|
||||
/>
|
||||
<View className="recommend-games-list-item-addon-message">
|
||||
<View className="recommend-games-list-item-addon-message-applications">
|
||||
<Text>
|
||||
报名人数 {game.checkedApplications}/{game.applications}
|
||||
</Text>
|
||||
</View>
|
||||
<View className="recommend-games-list-item-addon-message-level-requirements">
|
||||
<Text>{game.levelRequirements}</Text>
|
||||
</View>
|
||||
<View className="recommend-games-list-item-addon-message-play-type">
|
||||
<Text>{game.playType}</Text>
|
||||
{recommendGames.length > 0 && (
|
||||
<View className="organizer-recommend-games">
|
||||
<View
|
||||
className="organizer-recommend-games-title"
|
||||
onClick={handleViewUserInfo.bind(null, id)}
|
||||
>
|
||||
<Text>TA的更多活动</Text>
|
||||
<Image
|
||||
className="organizer-recommend-games-title-arrow"
|
||||
src={img.ICON_DETAIL_ARROW_RIGHT}
|
||||
/>
|
||||
</View>
|
||||
<ScrollView className="recommend-games-list" scrollX>
|
||||
<View className="recommend-games-list-content">
|
||||
{recommendGames.map((game, index) => (
|
||||
<View
|
||||
key={index}
|
||||
className="recommend-games-list-item"
|
||||
onClick={handleViewGame.bind(null, game.id)}
|
||||
>
|
||||
{/* game title */}
|
||||
<View className="recommend-games-list-item-title">
|
||||
<Text>{game.title}</Text>
|
||||
<Image
|
||||
className="recommend-games-list-item-title-arrow"
|
||||
src={img.ICON_DETAIL_ARROW_RIGHT}
|
||||
/>
|
||||
</View>
|
||||
{/* game time and range */}
|
||||
<View className="recommend-games-list-item-time-range">
|
||||
<Text>{game.time}</Text>
|
||||
<Text>{game.timeLength}</Text>
|
||||
</View>
|
||||
{/* game location、vunue、distance */}
|
||||
<View className="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="recommend-games-list-item-addon">
|
||||
<Image
|
||||
className="recommend-games-list-item-addon-avatar"
|
||||
mode="aspectFill"
|
||||
src={game.avatar}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleViewUserInfo(id);
|
||||
}}
|
||||
/>
|
||||
<View className="recommend-games-list-item-addon-message">
|
||||
<View className="recommend-games-list-item-addon-message-applications">
|
||||
<Text>
|
||||
报名人数 {game.checkedApplications}/
|
||||
{game.applications}
|
||||
</Text>
|
||||
</View>
|
||||
<View className="recommend-games-list-item-addon-message-level-requirements">
|
||||
<Text>{game.levelRequirements}</Text>
|
||||
</View>
|
||||
<View className="recommend-games-list-item-addon-message-play-type">
|
||||
<Text>{game.playType}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -987,6 +1023,9 @@ function Index() {
|
||||
const { id, from } = params;
|
||||
const [userInfo, setUserInfo] = useState({}); // 组织者的userInfo
|
||||
const { fetchUserInfo } = useUserActions(); // 获取登录用户的userInfo
|
||||
const myInfo = useUserInfo();
|
||||
|
||||
const isMyOwn = userInfo.id === myInfo.id;
|
||||
|
||||
const sharePopupRef = useRef<any>(null);
|
||||
|
||||
@@ -1031,7 +1070,6 @@ function Index() {
|
||||
async function fetchUserInfoById(user_id) {
|
||||
const userDetailInfo = await LoginService.getUserInfoById(user_id);
|
||||
if (userDetailInfo.code === 0) {
|
||||
// console.log(userDetailInfo.data);
|
||||
setUserInfo(userDetailInfo.data);
|
||||
}
|
||||
}
|
||||
@@ -1040,12 +1078,26 @@ function Index() {
|
||||
sharePopupRef.current.show();
|
||||
}
|
||||
|
||||
const handleJoinGame = () => {
|
||||
Taro.navigateTo({
|
||||
const handleJoinGame = async () => {
|
||||
if (isMyOwn) {
|
||||
const res = await DetailService.organizerJoin(Number(id));
|
||||
if (res.code === 0) {
|
||||
toast("加入成功");
|
||||
fetchDetail();
|
||||
}
|
||||
return;
|
||||
}
|
||||
navto({
|
||||
url: `/order_pages/orderDetail/index?gameId=${id}`,
|
||||
});
|
||||
};
|
||||
|
||||
function onStatusChange(result) {
|
||||
if (result) {
|
||||
fetchDetail();
|
||||
}
|
||||
}
|
||||
|
||||
function handleBack() {
|
||||
const pages = Taro.getCurrentPages();
|
||||
if (pages.length <= 1) {
|
||||
@@ -1058,9 +1110,9 @@ function Index() {
|
||||
}
|
||||
|
||||
function handleViewUserInfo(userId) {
|
||||
Taro.navigateTo({
|
||||
url: `/user_pages/other/index?userid=${userId}`
|
||||
})
|
||||
navto({
|
||||
url: `/user_pages/other/index?userid=${userId}`,
|
||||
});
|
||||
}
|
||||
|
||||
console.log("detail", detail);
|
||||
@@ -1093,7 +1145,11 @@ function Index() {
|
||||
{/* content */}
|
||||
<View className="detail-page-content">
|
||||
{/* avatar and tags */}
|
||||
<GameTags detail={detail} userInfo={userInfo} handleViewUserInfo={handleViewUserInfo} />
|
||||
<GameTags
|
||||
detail={detail}
|
||||
userInfo={userInfo}
|
||||
handleViewUserInfo={handleViewUserInfo}
|
||||
/>
|
||||
{/* title */}
|
||||
<View className="detail-page-content-title">
|
||||
<Text className="detail-page-content-title-text">{detail.title}</Text>
|
||||
@@ -1105,7 +1161,11 @@ function Index() {
|
||||
{/* gameplay requirements */}
|
||||
<GamePlayAndRequirement detail={detail} />
|
||||
{/* participants */}
|
||||
<Participants detail={detail} handleJoinGame={handleJoinGame} handleViewUserInfo={handleViewUserInfo} />
|
||||
<Participants
|
||||
detail={detail}
|
||||
handleJoinGame={handleJoinGame}
|
||||
handleViewUserInfo={handleViewUserInfo}
|
||||
/>
|
||||
{/* supplemental notes */}
|
||||
<SupplementalNotes detail={detail} />
|
||||
{/* organizer and recommend games by organizer */}
|
||||
@@ -1121,6 +1181,7 @@ function Index() {
|
||||
handleShare={handleShare}
|
||||
handleJoinGame={handleJoinGame}
|
||||
detail={detail}
|
||||
onStatusChange={onStatusChange}
|
||||
/>
|
||||
{/* share popup */}
|
||||
<SharePopup
|
||||
|
||||
Reference in New Issue
Block a user