mirror of
https://github.com/mudabbir-ahmad/MAD-Treasure-Hunt.git
synced 2026-10-08 03:00:20 +00:00
Add initial JSON data files and implement core page components for game functionality
This commit is contained in:
1 parent
81847a9188
commit
ca27f8d6ed
54 files changed
+2424
-250
No files matched your search
@@ -0,0 +1,29 @@
|
||||
import {
|
||||
approveAdminAccess,
|
||||
createPrivateGame,
|
||||
requestAdminAccess,
|
||||
updateGroupSettings,
|
||||
} from '../API/API';
|
||||
import { getSession, setSessionGroup } from '../Model/SessionStore';
|
||||
|
||||
const useAdminViewModel = () => {
|
||||
const createGame = async (payload) => {
|
||||
const { currentUid } = getSession();
|
||||
const group = await createPrivateGame({ ...payload, userId: currentUid });
|
||||
setSessionGroup(group.Gid, 0);
|
||||
return group;
|
||||
};
|
||||
const requestAdmin = async (payload) => requestAdminAccess(payload);
|
||||
const approveAdmin = async (payload) => approveAdminAccess(payload);
|
||||
const setTeamsEnabled = async (gid, teamsEnabled) => updateGroupSettings({ gid, teamsEnabled });
|
||||
|
||||
return {
|
||||
createGame,
|
||||
requestAdmin,
|
||||
approveAdmin,
|
||||
setTeamsEnabled,
|
||||
};
|
||||
};
|
||||
|
||||
export default useAdminViewModel;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { loginUser, registerUser } from '../API/API';
|
||||
import { setSessionUser } from '../Model/SessionStore';
|
||||
|
||||
const useAuthViewModel = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [username, setUsername] = useState('');
|
||||
const [confirmPassword, setConfirmPassword] = useState('');
|
||||
const [accountType, setAccountType] = useState('Individual');
|
||||
const [error, setError] = useState('');
|
||||
const [currentUser, setCurrentUser] = useState(null);
|
||||
|
||||
const canRegister = useMemo(
|
||||
() => Boolean(username && email && password && confirmPassword),
|
||||
[username, email, password, confirmPassword],
|
||||
);
|
||||
|
||||
const login = async () => {
|
||||
setError('');
|
||||
try {
|
||||
const user = await loginUser(email.trim(), password);
|
||||
setCurrentUser(user);
|
||||
setSessionUser(user);
|
||||
return user;
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const register = async () => {
|
||||
setError('');
|
||||
try {
|
||||
const user = await registerUser({
|
||||
username: username.trim(),
|
||||
email: email.trim().toLowerCase(),
|
||||
password,
|
||||
confirmPassword,
|
||||
accountType,
|
||||
});
|
||||
setCurrentUser(user);
|
||||
setSessionUser(user);
|
||||
return user;
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
email,
|
||||
password,
|
||||
username,
|
||||
confirmPassword,
|
||||
accountType,
|
||||
error,
|
||||
currentUser,
|
||||
canRegister,
|
||||
setEmail,
|
||||
setPassword,
|
||||
setUsername,
|
||||
setConfirmPassword,
|
||||
setAccountType,
|
||||
login,
|
||||
register,
|
||||
};
|
||||
};
|
||||
|
||||
export default useAuthViewModel;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { getGameTypes } from '../API/API';
|
||||
|
||||
const useGameTypeViewModel = () => {
|
||||
const [gameTypes, setGameTypes] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
let mounted = true;
|
||||
getGameTypes().then((types) => {
|
||||
if (mounted) {
|
||||
setGameTypes(types);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
mounted = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return { gameTypes };
|
||||
};
|
||||
|
||||
export default useGameTypeViewModel;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { useState } from 'react';
|
||||
import { createTeam, getLobby, joinTeam } from '../API/API';
|
||||
import { getSession, setSessionTeam } from '../Model/SessionStore';
|
||||
|
||||
const useLobbyViewModel = () => {
|
||||
const [teamCode, setTeamCode] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
|
||||
const loadLobby = async () => {
|
||||
const { currentGid } = getSession();
|
||||
return getLobby(currentGid);
|
||||
};
|
||||
|
||||
const createLobbyTeam = async ({ teamName }) => {
|
||||
setError('');
|
||||
try {
|
||||
const { currentUid, currentGid } = getSession();
|
||||
const team = await createTeam({ userId: currentUid, gid: currentGid, teamName });
|
||||
setSessionTeam(team.Tid);
|
||||
return team;
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const joinLobbyTeam = async () => {
|
||||
setError('');
|
||||
try {
|
||||
const { currentUid } = getSession();
|
||||
const team = await joinTeam({ userId: currentUid, teamCode: teamCode.trim().toUpperCase() });
|
||||
setSessionTeam(team.Tid);
|
||||
return team;
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
teamCode,
|
||||
error,
|
||||
setTeamCode,
|
||||
loadLobby,
|
||||
createLobbyTeam,
|
||||
joinLobbyTeam,
|
||||
};
|
||||
};
|
||||
|
||||
export default useLobbyViewModel;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { useState } from 'react';
|
||||
import { createPrivateGame, joinAsAdmin } from '../API/API';
|
||||
import { getSession, setSessionGroup } from '../Model/SessionStore';
|
||||
|
||||
const useManagePrivateSubtaskViewModel = () => {
|
||||
const [businessOrSchoolName, setBusinessOrSchoolName] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
|
||||
const createNewPrivateGame = async () => {
|
||||
setError('');
|
||||
const { currentUid } = getSession();
|
||||
try {
|
||||
const group = await createPrivateGame({
|
||||
userId: currentUid,
|
||||
groupName: businessOrSchoolName.trim() || 'New Private Game',
|
||||
businessOrSchoolName: businessOrSchoolName.trim() || 'Unnamed Business',
|
||||
isBusiness: true,
|
||||
});
|
||||
setSessionGroup(group.Gid, 0);
|
||||
return group;
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const joinAdminForPrivate = async () => {
|
||||
setError('');
|
||||
const { currentUid } = getSession();
|
||||
try {
|
||||
const response = await joinAsAdmin({
|
||||
userId: currentUid,
|
||||
businessOrSchoolName: businessOrSchoolName.trim(),
|
||||
});
|
||||
const gid = response?.Gid ?? null;
|
||||
if (gid !== null) {
|
||||
setSessionGroup(gid, 0);
|
||||
}
|
||||
return response;
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
businessOrSchoolName,
|
||||
error,
|
||||
setBusinessOrSchoolName,
|
||||
createNewPrivateGame,
|
||||
joinAdminForPrivate,
|
||||
};
|
||||
};
|
||||
|
||||
export default useManagePrivateSubtaskViewModel;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { getMapPoints } from '../API/API';
|
||||
import { getSession } from '../Model/SessionStore';
|
||||
|
||||
const useMapViewModel = (groupId = null) => {
|
||||
const [points, setPoints] = useState([]);
|
||||
const { currentGid, currentSGid } = getSession();
|
||||
const resolvedGid = groupId ?? currentGid;
|
||||
|
||||
useEffect(() => {
|
||||
if (!resolvedGid) {
|
||||
setPoints([]);
|
||||
return;
|
||||
}
|
||||
let active = true;
|
||||
getMapPoints(resolvedGid, currentSGid).then((payload) => {
|
||||
if (active) {
|
||||
setPoints(payload);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [resolvedGid, currentSGid]);
|
||||
|
||||
return { points };
|
||||
};
|
||||
|
||||
export default useMapViewModel;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { useState } from 'react';
|
||||
import { joinPrivateGame } from '../API/API';
|
||||
import { getSession, setSessionGroup } from '../Model/SessionStore';
|
||||
|
||||
const usePrivateGameViewModel = () => {
|
||||
const [joinCode, setJoinCode] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
|
||||
const joinWithCode = async () => {
|
||||
setError('');
|
||||
try {
|
||||
const { currentUid } = getSession();
|
||||
const group = await joinPrivateGame({ userId: currentUid, joinCode: joinCode.trim().toUpperCase() });
|
||||
setSessionGroup(group.Gid);
|
||||
return group;
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
joinCode,
|
||||
error,
|
||||
setJoinCode,
|
||||
joinWithCode,
|
||||
};
|
||||
};
|
||||
|
||||
export default usePrivateGameViewModel;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { createSubgroup, getSubgroups, updateSubgroupCache } from '../API/API';
|
||||
import { getSession } from '../Model/SessionStore';
|
||||
|
||||
const useSubgroupAdminViewModel = () => {
|
||||
const [subgroups, setSubgroups] = useState([]);
|
||||
const [subgroupName, setSubgroupName] = useState('');
|
||||
const [cacheTriggerMeters, setCacheTriggerMeters] = useState('20');
|
||||
const [error, setError] = useState('');
|
||||
const { currentGid } = getSession();
|
||||
|
||||
const loadSubgroups = useCallback(async () => {
|
||||
if (!currentGid) {
|
||||
return;
|
||||
}
|
||||
const rows = await getSubgroups(currentGid);
|
||||
setSubgroups(rows);
|
||||
}, [currentGid]);
|
||||
|
||||
useEffect(() => {
|
||||
loadSubgroups();
|
||||
}, [loadSubgroups]);
|
||||
|
||||
const addSubgroup = async () => {
|
||||
setError('');
|
||||
try {
|
||||
await createSubgroup({
|
||||
gid: currentGid,
|
||||
subgroupName: subgroupName.trim(),
|
||||
cacheTriggerMeters: Number(cacheTriggerMeters),
|
||||
});
|
||||
setSubgroupName('');
|
||||
await loadSubgroups();
|
||||
return true;
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const updateCacheForSubgroup = async (sgid, triggerMeters) => {
|
||||
setError('');
|
||||
try {
|
||||
await updateSubgroupCache({ gid: currentGid, sgid, triggerMeters });
|
||||
await loadSubgroups();
|
||||
return true;
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
subgroups,
|
||||
subgroupName,
|
||||
cacheTriggerMeters,
|
||||
error,
|
||||
setSubgroupName,
|
||||
setCacheTriggerMeters,
|
||||
addSubgroup,
|
||||
updateCacheForSubgroup,
|
||||
};
|
||||
};
|
||||
|
||||
export default useSubgroupAdminViewModel;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { getTeam } from '../API/API';
|
||||
import { getSession } from '../Model/SessionStore';
|
||||
|
||||
const useTeamViewModel = (teamId = null) => {
|
||||
const [team, setTeam] = useState(null);
|
||||
const resolvedTeamId = teamId ?? getSession().currentTGid;
|
||||
|
||||
useEffect(() => {
|
||||
if (!resolvedTeamId) {
|
||||
setTeam(null);
|
||||
return;
|
||||
}
|
||||
let active = true;
|
||||
getTeam(resolvedTeamId).then((payload) => {
|
||||
if (active) {
|
||||
setTeam(payload);
|
||||
}
|
||||
}).catch(() => {
|
||||
if (active) {
|
||||
setTeam(null);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [resolvedTeamId]);
|
||||
|
||||
return { team };
|
||||
};
|
||||
|
||||
export default useTeamViewModel;
|
||||
|
||||
Reference in new issue
Block a user