diff --git a/README.md b/README.md index 3886e14..bb06c51 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,11 @@ expo start --android - `src/components/layout`: shared screen wrapper. - `src/components/UI`: shared UI components. - `src/components/screens`: app screens. -- `src/hooks`: app state, local DB link, and feature hooks. +- `src/hooks`: app state, API link, and feature hooks. - `DB`: local JSON data files. ## Notes -- The app uses local JSON data from `DB` through `src/hooks/DbController.js`. +- The app accesses game/auth data through the centralized API endpoint via `src/hooks/dbLink.js`. - Navigation is handled with React Navigation native stack. diff --git a/src/components/screens/GameTypeScreen.js b/src/components/screens/GameTypeScreen.js index e0c7dc4..8a3ef5d 100644 --- a/src/components/screens/GameTypeScreen.js +++ b/src/components/screens/GameTypeScreen.js @@ -1,50 +1,68 @@ -import React from 'react'; +import React, {useEffect, useState} from 'react'; import {Pressable, StyleSheet, Text, View} from 'react-native'; import useGameHook from '../../hooks/useGameHook'; import Screen from '../layout/Screen'; const GameTypeScreen = ({ navigation }) => { const { getGameTypes } = useGameHook(); - const gameTypes = getGameTypes(); + const [gameTypes, setGameTypes] = useState([]); + + useEffect(() => { + let isMounted = true; + + const load = async () => { + const types = await getGameTypes(); + if (isMounted) { + setGameTypes(types || []); + } + }; + + load(); + + return () => { + isMounted = false; + }; + }, [getGameTypes]); return ( - - Select Game Type - - {gameTypes && gameTypes.map((type) => ( - navigation.navigate('GameLobbyScreen')}> - {type} - - ))} - - + + Select Game Type + + {gameTypes && gameTypes.map((type) => ( + navigation.navigate('GameLobbyScreen')}> + {type} + + ))} + + ); }; const styles = StyleSheet.create({ container: { - justifyContent: 'center', + justifyContent: 'center', }, content: { - gap: 12, - flex: 1, + gap: 12, + flex: 1, }, title: { - fontSize: 24, - fontWeight: 'bold', - textAlign: 'center', - marginBottom: 20, + fontSize: 24, + fontWeight: 'bold', + textAlign: 'center', + marginBottom: 20, }, button: { - backgroundColor: '#2563eb', - borderRadius: 8, - paddingVertical: 12, - alignItems: 'center', + backgroundColor: '#2563eb', + borderRadius: 8, + paddingVertical: 12, + alignItems: 'center', }, buttonText: { - color: '#ffffff', - fontWeight: '600', + color: '#ffffff', + fontWeight: '600', }, }); export default GameTypeScreen; + diff --git a/src/components/screens/ManageGameScreen.js b/src/components/screens/ManageGameScreen.js index 038c7da..3bb235b 100644 --- a/src/components/screens/ManageGameScreen.js +++ b/src/components/screens/ManageGameScreen.js @@ -14,12 +14,13 @@ const ManageGameScreen = () => { const [error, setError] = useState(''); const [cacheRecords, setCacheRecords] = useState([]); - const loadCaches = useCallback(() => { + const loadCaches = useCallback(async () => { if (!session.currentGid) { setCacheRecords([]); return; } - setCacheRecords(getCaches(session.currentGid, null)); + const rows = await getCaches(session.currentGid, null); + setCacheRecords(rows || []); }, [getCaches, session.currentGid]); useEffect(() => { @@ -63,11 +64,11 @@ const ManageGameScreen = () => { }; }, []); - const handleAddCache = (coordinate) => { + const handleAddCache = async (coordinate) => { if (!session.currentGid) { return; } - upsertCache({ + await upsertCache({ gid: session.currentGid, latitude: coordinate.latitude, longitude: coordinate.longitude, @@ -75,10 +76,10 @@ const ManageGameScreen = () => { clue: `Cache ${cacheRecords.length + 1}`, subgroupId: 1, }); - loadCaches(); + await loadCaches(); }; - const handleMoveCache = (cacheId, coordinate) => { + const handleMoveCache = async (cacheId, coordinate) => { if (!session.currentGid) { return; } @@ -86,7 +87,7 @@ const ManageGameScreen = () => { if (!current) { return; } - upsertCache({ + await upsertCache({ gid: session.currentGid, cacheId, latitude: coordinate.latitude, @@ -95,7 +96,7 @@ const ManageGameScreen = () => { clue: current.clue, subgroupId: current.subgroupId, }); - loadCaches(); + await loadCaches(); }; if (!session.currentGid) { diff --git a/src/components/screens/MapScreen.js b/src/components/screens/MapScreen.js index 8587033..8e1704b 100644 --- a/src/components/screens/MapScreen.js +++ b/src/components/screens/MapScreen.js @@ -40,13 +40,13 @@ const MapScreen = () => { const subgroupFilter = session.currentSGid; const { visibleCache, isClaiming, setIsClaiming } = usePlayerGame(userLocation, heading, activeCaches); - const loadCaches = useCallback(() => { + const loadCaches = useCallback(async () => { if (!session.currentGid) { setCacheRecords([]); return; } - const rows = getCaches(session.currentGid, subgroupFilter); - setCacheRecords(rows); + const rows = await getCaches(session.currentGid, subgroupFilter); + setCacheRecords(rows || []); }, [getCaches, session.currentGid, subgroupFilter]); useEffect(() => { @@ -99,18 +99,18 @@ const MapScreen = () => { }; }, []); - const handleClaim = (cacheId) => { + const handleClaim = async (cacheId) => { if (!session.currentGid) { return; } - claimCache({ + await claimCache({ gid: session.currentGid, cacheId, uid: session.currentUid, tid: session.currentTid, }); setIsClaiming(false); - loadCaches(); + await loadCaches(); }; if (!session.currentGid) { diff --git a/src/hooks/DbController.js b/src/hooks/DbController.js deleted file mode 100644 index 3d48f3b..0000000 --- a/src/hooks/DbController.js +++ /dev/null @@ -1,495 +0,0 @@ -import buildDbLink from './dbLink'; - -class DbController { - constructor(db = buildDbLink()) { - this.db = db; - } - - hashPassword(value) { - let hash = 0; - for (let i = 0; i < value.length; i += 1) { - hash = (hash << 5) - hash + value.charCodeAt(i); - hash |= 0; - } - return `H_${Math.abs(hash)}`; - } - - toMinuteIso(date = new Date()) { - return `${date.toISOString().slice(0, 16)}Z`; - } - - generateJoinCode(length = 5) { - const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - let code = ''; - for (let i = 0; i < length; i += 1) { - code += charset[Math.floor(Math.random() * charset.length)]; - } - return code; - } - - generateUniqueJoinCode(collection, key) { - let code = this.generateJoinCode(Math.random() > 0.5 ? 5 : 6); - while (collection.some((item) => item[key] === code)) { - code = this.generateJoinCode(Math.random() > 0.5 ? 5 : 6); - } - return code; - } - - nextId(counterKey) { - const keyToCollection = { - user: { collection: 'users', field: 'Uid' }, - group: { collection: 'groups', field: 'Gid' }, - team: { collection: 'teams', field: 'Tid' }, - }; - - const config = keyToCollection[counterKey]; - if (!config) { - throw new Error(`Unsupported counter key: ${counterKey}`); - } - - const rows = this.db[config.collection] || []; - const maxId = rows.reduce((max, row) => { - const value = Number(row[config.field] || 0); - return value > max ? value : max; - }, 0); - - return maxId + 1; - } - - getUserByEmail(email) { - return this.db.users.find((u) => u.email.toLowerCase() === email.toLowerCase()) || null; - } - - getUserById(uid) { - return this.db.users.find((u) => u.Uid === Number(uid)) || null; - } - - getGroupById(gid) { - return this.db.groups.find((group) => group.Gid === Number(gid)) || null; - } - - register(payload) { - const { username, email, password, confirmPassword, accountType } = payload; - - if (!username || !email || !password || !confirmPassword) { - throw new Error('Missing required registration fields'); - } - if (password !== confirmPassword) { - throw new Error('Passwords do not match'); - } - if (this.getUserByEmail(email)) { - throw new Error('Email already in use'); - } - - const uid = this.nextId('user'); - const user = { - Uid: uid, - username, - email, - passwordHash: this.hashPassword(password), - isBusiness: accountType === 'Business/School', - IsAcceptedAdmin: false, - Gid: null, - SGid: null, - TGid: null, - }; - - this.db.users.push(user); - return user; - } - - login(payload) { - const { email, password } = payload; - const user = this.getUserByEmail(email); - if (!user) { - throw new Error('Email not found'); - } - const incomingHash = this.hashPassword(password); - if (incomingHash !== user.passwordHash) { - throw new Error('Invalid password'); - } - return user; - } - - getGameTypes() { - return this.db.game_types; - } - - getSubgroupByJoinCode(joinCode) { - return this.db.subgroups.find( - (subgroup) => subgroup.JoinCode && subgroup.JoinCode === joinCode.toUpperCase(), - ) || null; - } - - ensureMembership(uid, gid, sgid, isAcceptedAdmin) { - const existing = this.db.subgroup_memberships.find( - (membership) => membership.Uid === uid && membership.Gid === gid, - ); - - if (existing) { - existing.SGid = sgid; - existing.IsAcceptedAdmin = isAcceptedAdmin; - return existing; - } - - const membership = { - Uid: uid, - Gid: gid, - SGid: sgid, - IsAcceptedAdmin: isAcceptedAdmin, - }; - this.db.subgroup_memberships.push(membership); - return membership; - } - - ensureGroupGameData(gid) { - const existing = this.db.game_data.find((entry) => entry.Gid === gid); - if (existing) { - return existing; - } - const payload = { Gid: gid, GeoCaches: [] }; - this.db.game_data.push(payload); - return payload; - } - - hasActiveAdmin(gid) { - return this.db.subgroup_memberships.some( - (membership) => membership.Gid === gid && membership.SGid === 0 && membership.IsAcceptedAdmin, - ); - } - - canJoinTeamForSubgroup(group, sgid) { - return group.TeamsEnabled && sgid > 0; - } - - createPrivateGame(payload) { - const { userId, groupName, businessOrSchoolName, gameType = 'private', isBusiness = false } = payload; - - const user = this.getUserById(Number(userId)); - if (!user) { - throw new Error('User not found'); - } - - const existing = this.db.groups.find( - (group) => group.CreatedByUid === Number(userId) && group.GameType === 'private', - ); - if (existing) { - return existing; - } - - const gid = this.nextId('group'); - const isBusinessGroup = Boolean(isBusiness); - const group = { - Gid: gid, - GroupName: groupName, - BusinessOrSchoolName: businessOrSchoolName || groupName, - GameType: gameType, - AdminJoinCode: this.generateUniqueJoinCode(this.db.groups, 'AdminJoinCode'), - CreatedByUid: user.Uid, - MaxMemberSubgroups: isBusinessGroup ? 999 : 1, - TeamsEnabled: true, - IsBusinessGroup: isBusinessGroup, - ApprovedAdmins: isBusinessGroup ? [user.Uid] : [], - CreatedAt: this.toMinuteIso(), - }; - - this.db.groups.push(group); - this.ensureGroupGameData(gid); - - this.db.subgroups.push({ - SGid: 0, - SubGroupName: 'Admins', - Gid: group.Gid, - JoinCode: null, - IsAdminGroup: true, - IsGameStarted: false, - CacheTriggerMeters: 20, - }); - - if (!isBusinessGroup) { - const memberSGid = this.db.subgroups.filter((sg) => sg.Gid === gid).length; - this.db.subgroups.push({ - SGid: memberSGid, - SubGroupName: 'Members', - Gid: gid, - JoinCode: this.generateUniqueJoinCode(this.db.subgroups, 'JoinCode'), - IsAdminGroup: false, - IsGameStarted: false, - CacheTriggerMeters: 20, - }); - } - - const ownerSgid = isBusinessGroup ? 0 : 1; - this.ensureMembership(user.Uid, gid, ownerSgid, isBusinessGroup); - user.Gid = gid; - user.SGid = ownerSgid; - user.IsAcceptedAdmin = isBusinessGroup; - - return group; - } - - joinPrivateGame(payload) { - const { userId, joinCode } = payload; - const user = this.getUserById(Number(userId)); - const subgroup = this.getSubgroupByJoinCode(joinCode); - - if (!user || !subgroup || subgroup.IsAdminGroup) { - throw new Error('Invalid subgroup join code'); - } - - const group = this.getGroupById(subgroup.Gid); - if (!group) { - throw new Error('Group not found'); - } - - this.ensureMembership(user.Uid, subgroup.Gid, subgroup.SGid, false); - user.Gid = group.Gid; - user.SGid = subgroup.SGid; - user.IsAcceptedAdmin = false; - return group; - } - - joinAsAdmin(payload) { - const { userId, adminJoinCode } = payload; - const user = this.getUserById(Number(userId)); - const group = this.db.groups.find((g) => g.AdminJoinCode === adminJoinCode); - - if (!user || !group) { - throw new Error('Invalid admin join code or user not found'); - } - - if (this.hasActiveAdmin(group.Gid)) { - this.db.admin_waitlist.push({ - Uid: user.Uid, - Gid: group.Gid, - RequestedAt: this.toMinuteIso(), - }); - return { status: 'pending', message: 'Admin approval pending' }; - } - - group.ApprovedAdmins.push(user.Uid); - this.ensureMembership(user.Uid, group.Gid, 0, true); - user.Gid = group.Gid; - user.SGid = 0; - user.IsAcceptedAdmin = true; - - return { status: 'approved', group }; - } - - getCreatedPrivateGameByUser(uid) { - return this.db.groups.find( - (group) => group.CreatedByUid === Number(uid) && group.GameType === 'private', - ) || null; - } - - createSubgroup(payload) { - const { gid, subgroupName, cacheTriggerMeters = 20 } = payload; - const group = this.getGroupById(gid); - if (!group) { - throw new Error('Group not found'); - } - - const existingCount = this.db.subgroups.filter((sg) => sg.Gid === gid).length; - if (existingCount >= group.MaxMemberSubgroups + 1) { - throw new Error('Max subgroups reached'); - } - - const sgid = existingCount; - const newSubgroup = { - SGid: sgid, - SubGroupName: subgroupName, - Gid: gid, - JoinCode: this.generateUniqueJoinCode(this.db.subgroups, 'JoinCode'), - IsAdminGroup: false, - IsGameStarted: false, - CacheTriggerMeters: cacheTriggerMeters, - }; - - this.db.subgroups.push(newSubgroup); - return newSubgroup; - } - - getSubgroups(gid) { - return this.db.subgroups.filter((sg) => sg.Gid === gid); - } - - getVisibleSubgroups(gid) { - return this.db.subgroups.filter((sg) => sg.Gid === gid && sg.SGid > 0); - } - - updateSubgroupCacheSettings(payload) { - const { gid, sgid, cacheTriggerMeters } = payload; - const subgroup = this.db.subgroups.find((sg) => sg.Gid === gid && sg.SGid === sgid); - if (!subgroup) { - throw new Error('Subgroup not found'); - } - subgroup.CacheTriggerMeters = cacheTriggerMeters; - return subgroup; - } - - createTeam(payload) { - const { gid, sgid, teamName, leaderId } = payload; - const tid = this.nextId('team'); - const team = { - Tid: tid, - Gid: gid, - SGid: sgid, - TeamName: teamName, - LeaderId: leaderId, - JoinCode: this.generateUniqueJoinCode(this.db.teams, 'JoinCode'), - CreatedAt: this.toMinuteIso(), - }; - - this.db.teams.push(team); - this.db.team_members.push({ Uid: leaderId, Tid: tid }); - - return team; - } - - joinTeamByCode(payload) { - const { userId, joinCode } = payload; - const team = this.db.teams.find((t) => t.JoinCode === joinCode.toUpperCase()); - - if (!team) { - throw new Error('Team join code not found'); - } - - const existing = this.db.team_members.find((tm) => tm.Uid === userId && tm.Tid === team.Tid); - if (existing) { - throw new Error('User already in team'); - } - - this.db.team_members.push({ Uid: userId, Tid: team.Tid }); - return team; - } - - getLobby(gid) { - const group = this.getGroupById(gid); - const subgroups = this.getSubgroups(gid); - const teams = this.db.teams.filter((t) => t.Gid === gid); - const teamMembers = this.db.team_members; - - return { group, subgroups, teams, teamMembers }; - } - - getTeam(tid) { - return this.db.teams.find((t) => t.Tid === tid); - } - - getMapPoints(gid, sgid = null) { - const gameData = this.db.game_data.find((entry) => entry.Gid === Number(gid)); - if (!gameData) { - return []; - } - if (sgid === null || sgid === undefined) { - return gameData.GeoCaches; - } - return gameData.GeoCaches.filter((cache) => cache.SGid === Number(sgid)); - } - - normalizeCache(cache, gid) { - return { - id: cache.CacheId ?? cache.id, - coordinates: { - latitude: Number(cache.Latitude ?? cache.coordinates?.latitude ?? 0), - longitude: Number(cache.Longitude ?? cache.coordinates?.longitude ?? 0), - }, - radius: Number(cache.TriggerMeters ?? cache.radius ?? 20), - clue: cache.Title ?? cache.clue ?? 'Cache', - groupId: Number(gid), - subgroupId: Number(cache.SGid ?? cache.subgroupId ?? 1), - claimedBy: cache.ClaimedBy ?? null, - claimedAt: cache.ClaimedAt ?? null, - }; - } - - getCaches(gid, sgid = null) { - const gameData = this.db.game_data.find((entry) => entry.Gid === Number(gid)); - if (!gameData) { - return []; - } - const caches = gameData.GeoCaches || []; - const filtered = sgid === null || sgid === undefined - ? caches - : caches.filter((cache) => Number(cache.SGid) === Number(sgid)); - return filtered.map((cache) => this.normalizeCache(cache, gid)); - } - - upsertCache(payload) { - const { - gid, - cacheId, - latitude, - longitude, - radius = 20, - clue = 'Cache', - subgroupId = 1, - } = payload; - - const groupId = Number(gid); - const gameData = this.ensureGroupGameData(groupId); - const id = cacheId || `C${Date.now()}`; - const existingIndex = (gameData.GeoCaches || []).findIndex( - (cache) => (cache.CacheId ?? cache.id) === id, - ); - - const nextCache = { - CacheId: id, - Title: clue, - Latitude: Number(latitude), - Longitude: Number(longitude), - TriggerMeters: Number(radius), - SGid: Number(subgroupId), - ClaimedBy: existingIndex >= 0 ? gameData.GeoCaches[existingIndex].ClaimedBy ?? null : null, - ClaimedAt: existingIndex >= 0 ? gameData.GeoCaches[existingIndex].ClaimedAt ?? null : null, - }; - - if (!gameData.GeoCaches) { - gameData.GeoCaches = []; - } - - if (existingIndex >= 0) { - gameData.GeoCaches[existingIndex] = nextCache; - } else { - gameData.GeoCaches.push(nextCache); - } - - return this.normalizeCache(nextCache, groupId); - } - - claimCache(payload) { - const { gid, cacheId, uid = null, tid = null } = payload; - const gameData = this.db.game_data.find((entry) => entry.Gid === Number(gid)); - if (!gameData || !gameData.GeoCaches) { - throw new Error('Game data not found'); - } - const target = gameData.GeoCaches.find((cache) => (cache.CacheId ?? cache.id) === cacheId); - if (!target) { - throw new Error('Cache not found'); - } - - target.ClaimedBy = tid || uid; - target.ClaimedAt = this.toMinuteIso(); - - return this.normalizeCache(target, gid); - } - - updateGroupSettings(payload) { - const { gid, ...settings } = payload; - const group = this.getGroupById(gid); - if (!group) { - throw new Error('Group not found'); - } - Object.assign(group, settings); - return group; - } - - getState() { - return this.db; - } -} - -const dbController = new DbController(); - -export { DbController }; -export default dbController; diff --git a/src/hooks/dbLink.js b/src/hooks/dbLink.js index 4d84170..755ea82 100644 --- a/src/hooks/dbLink.js +++ b/src/hooks/dbLink.js @@ -1,24 +1,22 @@ -import usersSeed from '../../DB/users.json'; -import groupsSeed from '../../DB/groups.json'; -import subgroupsSeed from '../../DB/subgroups.json'; -import subgroupMembershipsSeed from '../../DB/subgroup-memberships.json'; -import adminWaitlistSeed from '../../DB/admin-waitlist.json'; -import teamsSeed from '../../DB/teams.json'; -import teamMembersSeed from '../../DB/team-members.json'; -import gameDataSeed from '../../DB/game-data.json'; -import gameTypesSeed from '../../DB/game-types.json'; +import Constants from 'expo-constants'; -const buildDbLink = () => ({ - users: usersSeed, - groups: groupsSeed, - subgroups: subgroupsSeed, - subgroup_memberships: subgroupMembershipsSeed, - admin_waitlist: adminWaitlistSeed, - teams: teamsSeed, - team_members: teamMembersSeed, - game_data: gameDataSeed, - game_types: gameTypesSeed, -}); +const hostFromExpo = Constants.expoConfig?.hostUri?.split(':')[0] || null; +const apiBaseUrl = 'http://localhost:3000'; // Shirish, i need to deploy the database first so... wait until that... sorry buddy... +// if you want you can run your own db locally i can send you the files for it just ask :((( -export default buildDbLink; +const postJson = async (path, payload) => { + const response = await fetch(`${apiBaseUrl}${path}`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), + }); + const result = await response.json(); + if (!response.ok) { + throw new Error(result.message || 'Request failed'); + } + return result; +}; +export const postDb = async (action, payload = {}) => { + return postJson('/db', { action, payload }); +}; diff --git a/src/hooks/useAuthHook.js b/src/hooks/useAuthHook.js index ef03984..3e2e010 100644 --- a/src/hooks/useAuthHook.js +++ b/src/hooks/useAuthHook.js @@ -1,24 +1,7 @@ import {useState} from 'react'; -import Constants from 'expo-constants'; -import dbController from './DbController'; +import {postDb} from './dbLink'; import {clearSession, setSessionUser} from './SessionStore'; -const hostFromExpo = Constants.expoConfig?.hostUri?.split(':')[0] || null; -const apiBaseUrl = process.env.EXPO_PUBLIC_API_BASE_URL || (hostFromExpo ? `http://${hostFromExpo}:3000` : 'http://localhost:3000'); - -const postJson = async (path, payload) => { - const response = await fetch(`${apiBaseUrl}${path}`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload), - }); - const result = await response.json(); - if (!response.ok) { - throw new Error(result.message || 'Request failed'); - } - return result; -}; - const useAuthHook = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); @@ -32,21 +15,14 @@ const useAuthHook = () => { setError(''); setIsLoading(true); try { - const user = await postJson('/auth/login', { email: email.trim(), password }); + const user = await postDb('login', { email: email.trim(), password }); setSessionUser(user); setIsLoading(false); return user; } catch (e) { - try { - const fallbackUser = dbController.login({ email: email.trim(), password }); - setSessionUser(fallbackUser); - setIsLoading(false); - return fallbackUser; - } catch { - setError(e.message); - setIsLoading(false); - return null; - } + setError(e.message); + setIsLoading(false); + return null; } }; @@ -54,7 +30,7 @@ const useAuthHook = () => { setError(''); setIsLoading(true); try { - const user = await postJson('/auth/register', { + const user = await postDb('register', { username: username.trim(), email: email.trim().toLowerCase(), password, @@ -65,22 +41,9 @@ const useAuthHook = () => { setIsLoading(false); return user; } catch (e) { - try { - const fallbackUser = dbController.register({ - username: username.trim(), - email: email.trim().toLowerCase(), - password, - confirmPassword, - accountType, - }); - setSessionUser(fallbackUser); - setIsLoading(false); - return fallbackUser; - } catch { - setError(e.message); - setIsLoading(false); - return null; - } + setError(e.message); + setIsLoading(false); + return null; } }; diff --git a/src/hooks/useGameHook.js b/src/hooks/useGameHook.js index 4d4b640..082f874 100644 --- a/src/hooks/useGameHook.js +++ b/src/hooks/useGameHook.js @@ -1,55 +1,33 @@ -import dbController from './DbController'; +import {postDb} from './dbLink'; const useGameHook = () => { - const getGameTypes = () => dbController.getGameTypes(); + const request = async (action, payload = {}) => postDb(action, payload); - const getCreatedPrivateGame = (userId) => { - return dbController.getCreatedPrivateGameByUser(userId); - }; + const getGameTypes = async () => request('getGameTypes'); - const createPrivateGame = (payload) => { - return dbController.createPrivateGame(payload); - }; + const getCreatedPrivateGame = async (userId) => request('getCreatedPrivateGameByUser', { userId }); - const joinPrivateGame = (payload) => { - return dbController.joinPrivateGame(payload); - }; + const createPrivateGame = async (payload) => request('createPrivateGame', payload); - const joinAsAdmin = (payload) => { - return dbController.joinAsAdmin(payload); - }; + const joinPrivateGame = async (payload) => request('joinPrivateGame', payload); - const getLobby = (gid) => { - return dbController.getLobby(gid); - }; + const joinAsAdmin = async (payload) => request('joinAsAdmin', payload); - const getTeam = (tid) => { - return dbController.getTeam(tid); - }; + const getLobby = async (gid) => request('getLobby', { gid }); - const createTeam = (payload) => { - return dbController.createTeam(payload); - }; + const getTeam = async (tid) => request('getTeam', { tid }); - const joinTeamByCode = (payload) => { - return dbController.joinTeamByCode(payload); - }; + const createTeam = async (payload) => request('createTeam', payload); - const getMapPoints = (gid, sgid = null) => { - return dbController.getMapPoints(gid, sgid); - }; + const joinTeamByCode = async (payload) => request('joinTeamByCode', payload); - const getCaches = (gid, sgid = null) => { - return dbController.getCaches(gid, sgid); - }; + const getMapPoints = async (gid, sgid = null) => request('getMapPoints', { gid, sgid }); - const upsertCache = (payload) => { - return dbController.upsertCache(payload); - }; + const getCaches = async (gid, sgid = null) => request('getCaches', { gid, sgid }); - const claimCache = (payload) => { - return dbController.claimCache(payload); - }; + const upsertCache = async (payload) => request('upsertCache', payload); + + const claimCache = async (payload) => request('claimCache', payload); return { getGameTypes,