mirror of
https://github.com/mudabbir-ahmad/MAD-Treasure-Hunt.git
synced 2026-10-08 03:00:20 +00:00
Enhance navigation and data handling: update BottomNavbar to pass selected department, refactor GameSettingsScreen and PlayersScreen for improved subgroup management, and adjust API calls to support department-specific data.
This commit is contained in:
1 parent
43c8bb2bff
commit
4a0468d155
7 files changed
+148
-60
No files matched your search
@@ -3,17 +3,29 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|||||||
import {clearGameSession, getSession} from '../../hooks/SessionStore';
|
import {clearGameSession, getSession} from '../../hooks/SessionStore';
|
||||||
import API, {API_BASE_URL} from '../API/API';
|
import API, {API_BASE_URL} from '../API/API';
|
||||||
|
|
||||||
const BottomNavbar = ({navigation, routeName}) => {
|
const BottomNavbar = ({navigation, routeName, routeParams}) => {
|
||||||
// Initialisation ------------
|
// Initialisation ------------
|
||||||
|
|
||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
const session = getSession();
|
const session = getSession();
|
||||||
|
|
||||||
|
const selectedDepartment = routeName === 'DepartmentSettingsScreen' && routeParams?.SGid
|
||||||
|
? {SGid: routeParams.SGid, SubGroupName: routeParams.SubGroupName || routeParams.selectedDepartmentName || 'Department'}
|
||||||
|
: null;
|
||||||
|
|
||||||
const adminTabs = [
|
const adminTabs = [
|
||||||
{label: 'Settings', route: 'GameSettingsScreen', onPress: () => navigation.navigate('GameSettingsScreen')},
|
{label: 'Settings', route: 'GameSettingsScreen', onPress: () => navigation.navigate('GameSettingsScreen')},
|
||||||
{label: 'Map', route: 'MapScreen', onPress: () => navigation.navigate('MapScreen')},
|
{label: 'Map', route: 'MapScreen', onPress: () => navigation.navigate('MapScreen')},
|
||||||
{label: 'Players', route: 'PlayersScreen', onPress: () => navigation.navigate('PlayersScreen')},
|
{
|
||||||
{label: 'Leaderboard', route: 'LeaderboardScreen', onPress: () => navigation.navigate('LeaderboardScreen')},
|
label: 'Players',
|
||||||
|
route: 'PlayersScreen',
|
||||||
|
onPress: () => navigation.navigate('PlayersScreen', selectedDepartment ? {department: selectedDepartment} : undefined),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Leaderboard',
|
||||||
|
route: 'LeaderboardScreen',
|
||||||
|
onPress: () => navigation.navigate('LeaderboardScreen', selectedDepartment ? {department: selectedDepartment} : undefined),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Only show the Leave tab when the player is actually in a game
|
// Only show the Leave tab when the player is actually in a game
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const Screen = ({ children, style, showBack = false }) => {
|
|||||||
<View style={[styles.screen, isAuthScreen && {paddingTop: insets.top, paddingBottom: insets.bottom}]}>
|
<View style={[styles.screen, isAuthScreen && {paddingTop: insets.top, paddingBottom: insets.bottom}]}>
|
||||||
{!isAuthScreen && <TopNavbar title={pageTitle} showBack={showBack} navigation={navigation} />}
|
{!isAuthScreen && <TopNavbar title={pageTitle} showBack={showBack} navigation={navigation} />}
|
||||||
<View style={[styles.content, style]}>{children}</View>
|
<View style={[styles.content, style]}>{children}</View>
|
||||||
{!isAuthScreen && <BottomNavbar navigation={navigation} routeName={routeName} />}
|
{!isAuthScreen && <BottomNavbar navigation={navigation} routeName={routeName} routeParams={route.params} />}
|
||||||
<StatusBar style="light" />
|
<StatusBar style="light" />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, {useEffect, useState} from 'react';
|
import React, {useCallback, useState} from 'react';
|
||||||
import {ActivityIndicator, Alert, ScrollView, StyleSheet, Switch, Text, TextInput, View} from 'react-native';
|
import {ActivityIndicator, Alert, ScrollView, StyleSheet, Switch, Text, TextInput, View} from 'react-native';
|
||||||
|
import {useFocusEffect} from '@react-navigation/native';
|
||||||
import Screen from '../layout/Screen';
|
import Screen from '../layout/Screen';
|
||||||
import Card from '../UI/Card';
|
import Card from '../UI/Card';
|
||||||
import {Button, ButtonTray} from '../UI/Button';
|
import {Button, ButtonTray} from '../UI/Button';
|
||||||
@@ -11,7 +12,6 @@ const GameSettingsScreen = ({navigation}) => {
|
|||||||
|
|
||||||
const session = getSession();
|
const session = getSession();
|
||||||
const {getLobby, updateGroup, getSubgroups, createSubgroup, deleteSubgroup, resetGame, getAdminWaitlist, approveAdmin, rejectAdmin, getUser, disbandTeams} = useGameHook();
|
const {getLobby, updateGroup, getSubgroups, createSubgroup, deleteSubgroup, resetGame, getAdminWaitlist, approveAdmin, rejectAdmin, getUser, disbandTeams} = useGameHook();
|
||||||
const isBusiness = Boolean(session.isBusiness);
|
|
||||||
|
|
||||||
// State ----------------------
|
// State ----------------------
|
||||||
|
|
||||||
@@ -27,15 +27,16 @@ const GameSettingsScreen = ({navigation}) => {
|
|||||||
const [memberJoinCode, setMemberJoinCode] = useState('');
|
const [memberJoinCode, setMemberJoinCode] = useState('');
|
||||||
const [waitlist, setWaitlist] = useState([]);
|
const [waitlist, setWaitlist] = useState([]);
|
||||||
const [waitlistNames, setWaitlistNames] = useState({});
|
const [waitlistNames, setWaitlistNames] = useState({});
|
||||||
|
const [isBusinessGroup, setIsBusinessGroup] = useState(Boolean(session.isBusiness));
|
||||||
// Business subgroup management
|
// Business subgroup management
|
||||||
const [subgroupList, setSubgroupList] = useState([]);
|
const [subgroupList, setSubgroupList] = useState([]);
|
||||||
const [newDeptName, setNewDeptName] = useState('');
|
const [newDeptName, setNewDeptName] = useState('');
|
||||||
|
|
||||||
// Handlers -------------------
|
// Handlers -------------------
|
||||||
|
|
||||||
const loadWaitlist = async () => {
|
const loadWaitlist = useCallback(async (gid) => {
|
||||||
if (!session.currentGid) return;
|
if (!gid) return;
|
||||||
const rows = await getAdminWaitlist(session.currentGid);
|
const rows = await getAdminWaitlist(gid);
|
||||||
setWaitlist(rows || []);
|
setWaitlist(rows || []);
|
||||||
const names = {};
|
const names = {};
|
||||||
for (const entry of (rows || [])) {
|
for (const entry of (rows || [])) {
|
||||||
@@ -43,27 +44,28 @@ const GameSettingsScreen = ({navigation}) => {
|
|||||||
if (u) names[entry.Uid] = u.username;
|
if (u) names[entry.Uid] = u.username;
|
||||||
}
|
}
|
||||||
setWaitlistNames(names);
|
setWaitlistNames(names);
|
||||||
};
|
}, [getAdminWaitlist, getUser]);
|
||||||
|
|
||||||
const loadSubgroups = async () => {
|
const loadSubgroups = useCallback(async (gid) => {
|
||||||
if (!session.currentGid) return;
|
if (!gid) return;
|
||||||
const sgs = await getSubgroups(session.currentGid);
|
const sgs = await getSubgroups(gid);
|
||||||
setSubgroupList(sgs || []);
|
setSubgroupList(sgs || []);
|
||||||
// Set the default member join code from first non-admin subgroup
|
// Set the default member join code from first non-admin subgroup
|
||||||
const memberSg = (sgs || []).find((sg) => !sg.IsAdminGroup);
|
const memberSg = (sgs || []).find((sg) => !sg.IsAdminGroup);
|
||||||
if (memberSg) setMemberJoinCode(memberSg.JoinCode || '');
|
if (memberSg) setMemberJoinCode(memberSg.JoinCode || '');
|
||||||
};
|
}, [getSubgroups]);
|
||||||
|
|
||||||
useEffect(() => {
|
const loadSettings = useCallback(async () => {
|
||||||
const load = async () => {
|
const activeSession = getSession();
|
||||||
if (!session.currentGid) {
|
if (!activeSession.currentGid) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const group = await getLobby(session.currentGid);
|
const group = await getLobby(activeSession.currentGid);
|
||||||
if (group) {
|
if (group) {
|
||||||
setGroupName(group.GroupName || '');
|
setGroupName(group.GroupName || '');
|
||||||
setBusinessName(group.BusinessOrSchoolName || '');
|
setBusinessName(group.BusinessOrSchoolName || '');
|
||||||
|
setIsBusinessGroup(Boolean(group.BusinessOrSchoolName || group.OrgJoinCode));
|
||||||
const serverTeams = Boolean(group.TeamsEnabled);
|
const serverTeams = Boolean(group.TeamsEnabled);
|
||||||
setTeamsEnabled(serverTeams);
|
setTeamsEnabled(serverTeams);
|
||||||
setServerTeamsEnabled(serverTeams);
|
setServerTeamsEnabled(serverTeams);
|
||||||
@@ -72,12 +74,17 @@ const GameSettingsScreen = ({navigation}) => {
|
|||||||
setAdminJoinCode(group.AdminJoinCode || '');
|
setAdminJoinCode(group.AdminJoinCode || '');
|
||||||
setOrgJoinCode(group.OrgJoinCode || '');
|
setOrgJoinCode(group.OrgJoinCode || '');
|
||||||
}
|
}
|
||||||
await loadSubgroups();
|
await loadSubgroups(activeSession.currentGid);
|
||||||
await loadWaitlist();
|
await loadWaitlist(activeSession.currentGid);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
}, [getLobby, loadSubgroups, loadWaitlist]);
|
||||||
load();
|
|
||||||
}, []);
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
setLoading(true);
|
||||||
|
loadSettings();
|
||||||
|
}, [loadSettings]),
|
||||||
|
);
|
||||||
|
|
||||||
// --- Individual save ---
|
// --- Individual save ---
|
||||||
const saveSettings = async () => {
|
const saveSettings = async () => {
|
||||||
@@ -100,7 +107,7 @@ const GameSettingsScreen = ({navigation}) => {
|
|||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
if (!session.currentGid) return;
|
if (!session.currentGid) return;
|
||||||
// Business save — only save business name
|
// Business save — only save business name
|
||||||
if (isBusiness) {
|
if (isBusinessGroup) {
|
||||||
setSaving(true);
|
setSaving(true);
|
||||||
await updateGroup(session.currentGid, {
|
await updateGroup(session.currentGid, {
|
||||||
BusinessOrSchoolName: businessName.trim(),
|
BusinessOrSchoolName: businessName.trim(),
|
||||||
@@ -180,7 +187,11 @@ const GameSettingsScreen = ({navigation}) => {
|
|||||||
|
|
||||||
// Business — navigate to department settings
|
// Business — navigate to department settings
|
||||||
const handleEnterDepartment = (sg) => {
|
const handleEnterDepartment = (sg) => {
|
||||||
navigation.navigate('DepartmentSettingsScreen', {SGid: sg.SGid, Gid: session.currentGid});
|
navigation.navigate('DepartmentSettingsScreen', {
|
||||||
|
SGid: sg.SGid,
|
||||||
|
Gid: session.currentGid,
|
||||||
|
SubGroupName: sg.SubGroupName,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// View -----------------------
|
// View -----------------------
|
||||||
@@ -205,7 +216,7 @@ const GameSettingsScreen = ({navigation}) => {
|
|||||||
const departments = subgroupList.filter((sg) => !sg.IsAdminGroup);
|
const departments = subgroupList.filter((sg) => !sg.IsAdminGroup);
|
||||||
|
|
||||||
// ===== Business Admin View =====
|
// ===== Business Admin View =====
|
||||||
if (isBusiness) {
|
if (isBusinessGroup) {
|
||||||
return (
|
return (
|
||||||
<Screen>
|
<Screen>
|
||||||
<ScrollView contentContainerStyle={styles.formContainer} showsVerticalScrollIndicator={false}>
|
<ScrollView contentContainerStyle={styles.formContainer} showsVerticalScrollIndicator={false}>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const LeaderboardScreen = ({navigation, route}) => {
|
|||||||
const isAdmin = session.isAcceptedAdmin;
|
const isAdmin = session.isAcceptedAdmin;
|
||||||
const isBusiness = Boolean(session.isBusiness);
|
const isBusiness = Boolean(session.isBusiness);
|
||||||
const selectedDepartment = route?.params?.department || null;
|
const selectedDepartment = route?.params?.department || null;
|
||||||
const {getLobby, getTeams, getTeamMembers, getGroupMembers, getCaches, getUser, deleteTeam, resetPlayerProgress, resetTeamProgress, getSubgroups} = useGameHook();
|
const {getLobby, getSubgroup, getTeams, getTeamMembers, getGroupMembers, getCaches, getUser, deleteTeam, resetPlayerProgress, resetTeamProgress, getSubgroups} = useGameHook();
|
||||||
|
|
||||||
// State ----------------------
|
// State ----------------------
|
||||||
|
|
||||||
@@ -33,7 +33,16 @@ const LeaderboardScreen = ({navigation, route}) => {
|
|||||||
if (!session.currentGid) { setLoading(false); return; }
|
if (!session.currentGid) { setLoading(false); return; }
|
||||||
|
|
||||||
const group = await getLobby(session.currentGid);
|
const group = await getLobby(session.currentGid);
|
||||||
const isTeams = Boolean(group?.TeamsEnabled);
|
|
||||||
|
const effectiveSGid = isBusiness
|
||||||
|
? ((isAdmin && selectedDepartment?.SGid) ? selectedDepartment.SGid : (isAdmin ? null : session.currentSGid))
|
||||||
|
: null;
|
||||||
|
|
||||||
|
let isTeams = Boolean(group?.TeamsEnabled);
|
||||||
|
if (effectiveSGid !== null && effectiveSGid !== undefined) {
|
||||||
|
const subgroup = await getSubgroup(effectiveSGid);
|
||||||
|
if (subgroup) isTeams = Boolean(subgroup.TeamsEnabled);
|
||||||
|
}
|
||||||
setTeamsEnabled(isTeams);
|
setTeamsEnabled(isTeams);
|
||||||
|
|
||||||
if (isBusiness && isAdmin && !selectedDepartment) {
|
if (isBusiness && isAdmin && !selectedDepartment) {
|
||||||
@@ -43,24 +52,16 @@ const LeaderboardScreen = ({navigation, route}) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const leaderboardSGid = (isBusiness && isAdmin && selectedDepartment?.SGid)
|
const caches = await getCaches(session.currentGid, effectiveSGid ?? null);
|
||||||
? selectedDepartment.SGid
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const caches = await getCaches(session.currentGid, leaderboardSGid);
|
|
||||||
const total = (caches || []).length;
|
const total = (caches || []).length;
|
||||||
setTotalCacheCount(total);
|
setTotalCacheCount(total);
|
||||||
|
|
||||||
if (isTeams) {
|
if (isTeams) {
|
||||||
// Build team rankings
|
// Build team rankings
|
||||||
const teams = await getTeams(session.currentGid);
|
const teams = await getTeams(session.currentGid, effectiveSGid ?? null);
|
||||||
const teamData = [];
|
const teamData = [];
|
||||||
|
|
||||||
const scopedTeams = leaderboardSGid
|
for (const team of (teams || [])) {
|
||||||
? (teams || []).filter((team) => !team.SGid || team.SGid === leaderboardSGid)
|
|
||||||
: (teams || []);
|
|
||||||
|
|
||||||
for (const team of scopedTeams) {
|
|
||||||
const members = await getTeamMembers(team.Tid);
|
const members = await getTeamMembers(team.Tid);
|
||||||
const memberData = [];
|
const memberData = [];
|
||||||
for (const m of (members || [])) {
|
for (const m of (members || [])) {
|
||||||
@@ -98,12 +99,9 @@ const LeaderboardScreen = ({navigation, route}) => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Build player rankings (no teams)
|
// Build player rankings (no teams)
|
||||||
const allMembers = await getGroupMembers(session.currentGid);
|
const scopedMembers = await getGroupMembers(session.currentGid, effectiveSGid ?? null);
|
||||||
const scopedMembers = leaderboardSGid
|
|
||||||
? (allMembers || []).filter((mem) => mem.SGid === leaderboardSGid)
|
|
||||||
: (allMembers || []);
|
|
||||||
const playerData = [];
|
const playerData = [];
|
||||||
for (const m of scopedMembers.filter((mem) => !mem.IsAcceptedAdmin)) {
|
for (const m of (scopedMembers || []).filter((mem) => !mem.IsAcceptedAdmin)) {
|
||||||
const user = await getUser(m.Uid);
|
const user = await getUser(m.Uid);
|
||||||
const count = (caches || []).filter((c) =>
|
const count = (caches || []).filter((c) =>
|
||||||
(c.Claims || []).some((cl) => cl.Uid === m.Uid)
|
(c.Claims || []).some((cl) => cl.Uid === m.Uid)
|
||||||
@@ -119,7 +117,7 @@ const LeaderboardScreen = ({navigation, route}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}, [session.currentGid, session.currentTid, isBusiness, isAdmin, selectedDepartment, selectedDepartment?.SGid]);
|
}, [session.currentGid, session.currentTid, session.currentSGid, isBusiness, isAdmin, selectedDepartment, selectedDepartment?.SGid]);
|
||||||
|
|
||||||
useEffect(() => { loadData(); }, [loadData]);
|
useEffect(() => { loadData(); }, [loadData]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,43 @@
|
|||||||
import React, {useCallback, useEffect, useState} from 'react';
|
import React, {useCallback, useEffect, useState} from 'react';
|
||||||
import {ActivityIndicator, Alert, ScrollView, StyleSheet, Text, View} from 'react-native';
|
import {ActivityIndicator, Alert, Pressable, ScrollView, StyleSheet, Text, View} from 'react-native';
|
||||||
import Screen from '../layout/Screen';
|
import Screen from '../layout/Screen';
|
||||||
import Card from '../UI/Card';
|
import Card from '../UI/Card';
|
||||||
import {Button} from '../UI/Button';
|
import {Button} from '../UI/Button';
|
||||||
import useGameHook from '../../hooks/useGameHook';
|
import useGameHook from '../../hooks/useGameHook';
|
||||||
import {getSession} from '../../hooks/SessionStore';
|
import {getSession} from '../../hooks/SessionStore';
|
||||||
|
|
||||||
const PlayersScreen = () => {
|
const PlayersScreen = ({navigation, route}) => {
|
||||||
// Initialisation ------------
|
// Initialisation ------------
|
||||||
|
|
||||||
const session = getSession();
|
const session = getSession();
|
||||||
const {getTeams, getTeamMembers, getGroupMembers, removeMember, resetPlayerProgress, getUser, getAdminWaitlist, approveAdmin, rejectAdmin, getSubgroups} = useGameHook();
|
const {getTeams, getTeamMembers, getGroupMembers, removeMember, resetPlayerProgress, getUser, getAdminWaitlist, approveAdmin, rejectAdmin, getSubgroups} = useGameHook();
|
||||||
const isBusiness = Boolean(session.isBusiness);
|
const isBusiness = Boolean(session.isBusiness);
|
||||||
|
const isAdmin = Boolean(session.isAcceptedAdmin);
|
||||||
|
const selectedDepartment = route?.params?.department || null;
|
||||||
|
|
||||||
// State ----------------------
|
// State ----------------------
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [players, setPlayers] = useState([]);
|
const [players, setPlayers] = useState([]);
|
||||||
|
const [departmentList, setDepartmentList] = useState([]);
|
||||||
|
|
||||||
// Handlers -------------------
|
// Handlers -------------------
|
||||||
|
|
||||||
const loadData = useCallback(async () => {
|
const loadData = useCallback(async () => {
|
||||||
if (!session.currentGid) { setLoading(false); return; }
|
if (!session.currentGid) { setLoading(false); return; }
|
||||||
|
|
||||||
|
const effectiveSGid = isBusiness
|
||||||
|
? ((isAdmin && selectedDepartment?.SGid) ? selectedDepartment.SGid : (isAdmin ? null : session.currentSGid))
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (isBusiness && isAdmin && !selectedDepartment) {
|
||||||
|
const sgs = await getSubgroups(session.currentGid);
|
||||||
|
setDepartmentList((sgs || []).filter((sg) => !sg.IsAdminGroup));
|
||||||
|
setPlayers([]);
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Load subgroup names for department display (business accounts)
|
// Load subgroup names for department display (business accounts)
|
||||||
let subgroupNameMap = {};
|
let subgroupNameMap = {};
|
||||||
if (isBusiness) {
|
if (isBusiness) {
|
||||||
@@ -33,10 +48,10 @@ const PlayersScreen = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get ALL members (including admins)
|
// Get ALL members (including admins)
|
||||||
const allMembers = await getGroupMembers(session.currentGid);
|
const allMembers = await getGroupMembers(session.currentGid, effectiveSGid ?? null);
|
||||||
|
|
||||||
// Get admin waitlist entries
|
// Get admin waitlist entries
|
||||||
const waitlist = await getAdminWaitlist(session.currentGid);
|
const waitlist = effectiveSGid ? [] : await getAdminWaitlist(session.currentGid);
|
||||||
|
|
||||||
// Deduplicate allMembers by Uid — a user may have two rows if they were a
|
// Deduplicate allMembers by Uid — a user may have two rows if they were a
|
||||||
// regular member before being approved as an admin. Prefer the admin row.
|
// regular member before being approved as an admin. Prefer the admin row.
|
||||||
@@ -46,7 +61,7 @@ const PlayersScreen = () => {
|
|||||||
.filter((m) => { if (seenUids.has(m.Uid)) return false; seenUids.add(m.Uid); return true; });
|
.filter((m) => { if (seenUids.has(m.Uid)) return false; seenUids.add(m.Uid); return true; });
|
||||||
|
|
||||||
// Build team lookup: { Uid -> { teamCode, teamName, isLeader } }
|
// Build team lookup: { Uid -> { teamCode, teamName, isLeader } }
|
||||||
const allTeams = await getTeams(session.currentGid);
|
const allTeams = await getTeams(session.currentGid, effectiveSGid ?? null);
|
||||||
const teamInfoByUid = {};
|
const teamInfoByUid = {};
|
||||||
for (const team of (allTeams || [])) {
|
for (const team of (allTeams || [])) {
|
||||||
const tms = await getTeamMembers(team.Tid);
|
const tms = await getTeamMembers(team.Tid);
|
||||||
@@ -107,7 +122,7 @@ const PlayersScreen = () => {
|
|||||||
|
|
||||||
setPlayers(playerList);
|
setPlayers(playerList);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}, [session.currentGid]);
|
}, [session.currentGid, session.currentUid, session.currentSGid, isBusiness, isAdmin, selectedDepartment, selectedDepartment?.SGid]);
|
||||||
|
|
||||||
useEffect(() => { loadData(); }, [loadData]);
|
useEffect(() => { loadData(); }, [loadData]);
|
||||||
|
|
||||||
@@ -164,8 +179,34 @@ const PlayersScreen = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isBusiness && isAdmin && !selectedDepartment) {
|
||||||
|
return (
|
||||||
|
<Screen style={styles.container}>
|
||||||
|
<Text style={styles.sectionTitle}>Departments</Text>
|
||||||
|
<ScrollView style={styles.listSection}>
|
||||||
|
{departmentList.map((department) => (
|
||||||
|
<Pressable
|
||||||
|
key={department.SGid}
|
||||||
|
onPress={() => navigation.navigate('PlayersScreen', {department})}
|
||||||
|
>
|
||||||
|
<Card>
|
||||||
|
<View style={styles.playerRow}>
|
||||||
|
<Text style={styles.playerName}>{department.SubGroupName}</Text>
|
||||||
|
<Text style={styles.openLabel}>Open</Text>
|
||||||
|
</View>
|
||||||
|
</Card>
|
||||||
|
</Pressable>
|
||||||
|
))}
|
||||||
|
{departmentList.length === 0 && (
|
||||||
|
<Text style={styles.emptyText}>No departments yet.</Text>
|
||||||
|
)}
|
||||||
|
</ScrollView>
|
||||||
|
</Screen>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Screen style={styles.container}>
|
<Screen style={styles.container} showBack={Boolean(selectedDepartment)}>
|
||||||
<Text style={styles.sectionTitle}>Players</Text>
|
<Text style={styles.sectionTitle}>Players</Text>
|
||||||
<ScrollView style={styles.listSection}>
|
<ScrollView style={styles.listSection}>
|
||||||
{players.map((player) => (
|
{players.map((player) => (
|
||||||
@@ -255,6 +296,7 @@ const styles = StyleSheet.create({
|
|||||||
paddingHorizontal: 15,
|
paddingHorizontal: 15,
|
||||||
paddingTop: 15,
|
paddingTop: 15,
|
||||||
},
|
},
|
||||||
|
openLabel: {fontSize: 13, fontWeight: '700', color: '#2563eb'},
|
||||||
listSection: {flex: 1, paddingHorizontal: 15},
|
listSection: {flex: 1, paddingHorizontal: 15},
|
||||||
emptyText: {color: '#9ca3af', textAlign: 'center', marginTop: 30, fontSize: 14},
|
emptyText: {color: '#9ca3af', textAlign: 'center', marginTop: 30, fontSize: 14},
|
||||||
playerRow: {
|
playerRow: {
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ const TeamScreen = () => {
|
|||||||
|
|
||||||
const session = getSession();
|
const session = getSession();
|
||||||
const isAdmin = session.isAcceptedAdmin;
|
const isAdmin = session.isAcceptedAdmin;
|
||||||
const {getLobby, getTeam, createTeam, joinTeamByCode, getTeamMembers, leaveTeam, getUser, updateUser, updateTeam, getAdminWaitlist} = useGameHook();
|
const isBusiness = Boolean(session.isBusiness);
|
||||||
|
const {getLobby, getSubgroup, getTeam, createTeam, joinTeamByCode, getTeamMembers, leaveTeam, getUser, updateUser, updateTeam, getAdminWaitlist} = useGameHook();
|
||||||
|
|
||||||
// State ----------------------
|
// State ----------------------
|
||||||
|
|
||||||
@@ -46,11 +47,19 @@ const TeamScreen = () => {
|
|||||||
if (!session.currentGid) { setLoading(false); return; }
|
if (!session.currentGid) { setLoading(false); return; }
|
||||||
|
|
||||||
const group = await getLobby(session.currentGid);
|
const group = await getLobby(session.currentGid);
|
||||||
if (group && !group.TeamsEnabled) {
|
let teamsAreEnabled = Boolean(group?.TeamsEnabled);
|
||||||
|
|
||||||
|
if (isBusiness && session.currentSGid) {
|
||||||
|
const subgroup = await getSubgroup(session.currentSGid);
|
||||||
|
if (subgroup) teamsAreEnabled = Boolean(subgroup.TeamsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!teamsAreEnabled) {
|
||||||
setTeamsDisabled(true);
|
setTeamsDisabled(true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
setTeamsDisabled(false);
|
||||||
|
|
||||||
if (!activeTid) {
|
if (!activeTid) {
|
||||||
const waitlist = await getAdminWaitlist(session.currentGid, session.currentUid);
|
const waitlist = await getAdminWaitlist(session.currentGid, session.currentUid);
|
||||||
@@ -70,7 +79,11 @@ const TeamScreen = () => {
|
|||||||
if (!teamCode.trim()) return;
|
if (!teamCode.trim()) return;
|
||||||
// Force uppercase just in case a lowercase code is pasted
|
// Force uppercase just in case a lowercase code is pasted
|
||||||
const code = teamCode.trim().toUpperCase();
|
const code = teamCode.trim().toUpperCase();
|
||||||
const result = await joinTeamByCode({JoinCode: code, Uid: session.currentUid});
|
const result = await joinTeamByCode({
|
||||||
|
JoinCode: code,
|
||||||
|
Uid: session.currentUid,
|
||||||
|
ExpectedSGid: session.currentSGid,
|
||||||
|
});
|
||||||
if (!result) return;
|
if (!result) return;
|
||||||
|
|
||||||
// If the server indicates this code matched the admin join code
|
// If the server indicates this code matched the admin join code
|
||||||
|
|||||||
@@ -89,8 +89,10 @@ const useGameHook = () => {
|
|||||||
return response.isSuccess ? response.result : null;
|
return response.isSuccess ? response.result : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGroupMembers = async (gid) => {
|
const getGroupMembers = async (gid, sgid = null) => {
|
||||||
const response = await API.get(`${subgroupMembersEndpoint}?Gid=${gid}`);
|
let url = `${subgroupMembersEndpoint}?Gid=${gid}`;
|
||||||
|
if (sgid !== null && sgid !== undefined) url += `&SGid=${sgid}`;
|
||||||
|
const response = await API.get(url);
|
||||||
return response.isSuccess ? response.result : [];
|
return response.isSuccess ? response.result : [];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,8 +102,10 @@ const useGameHook = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Teams
|
// Teams
|
||||||
const getTeams = async (gid) => {
|
const getTeams = async (gid, sgid = null) => {
|
||||||
const response = await API.get(`${teamsEndpoint}?Gid=${gid}`);
|
let url = `${teamsEndpoint}?Gid=${gid}`;
|
||||||
|
if (sgid !== null && sgid !== undefined) url += `&SGid=${sgid}`;
|
||||||
|
const response = await API.get(url);
|
||||||
return response.isSuccess ? response.result : [];
|
return response.isSuccess ? response.result : [];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -131,7 +135,15 @@ const useGameHook = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const joinTeamByCode = async (payload) => {
|
const joinTeamByCode = async (payload) => {
|
||||||
const response = await API.post(teamMembersEndpoint, payload);
|
const data = {
|
||||||
|
Uid: payload.Uid,
|
||||||
|
};
|
||||||
|
if (payload.JoinCode !== undefined) data.JoinCode = payload.JoinCode;
|
||||||
|
if (payload.Tid !== undefined) data.Tid = payload.Tid;
|
||||||
|
if (payload.ExpectedSGid !== undefined && payload.ExpectedSGid !== null) {
|
||||||
|
data.ExpectedSGid = payload.ExpectedSGid;
|
||||||
|
}
|
||||||
|
const response = await API.post(teamMembersEndpoint, data);
|
||||||
return response.isSuccess ? response.result : null;
|
return response.isSuccess ? response.result : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user