From 71a52da85b53fef1032ffa18f27d4b2551e98cfe Mon Sep 17 00:00:00 2001 From: mudabbir-ahmad Date: Tue, 17 Mar 2026 19:07:03 +0000 Subject: [PATCH] Add initial API interaction functions and database schema --- DB/db.json | 45 +++++++++++++++++++++++++++ DB/schema.sql | 27 +++++++++++++++++ app/API/API-ReadMe.md | 18 +++++++++++ app/API/API.js | 48 +++++++++++++++++++++++++++++ app/Controller/LoginLogic.js | 59 ++++++++++++++++++++++++++++++++++++ app/Screens/LoginPage.jsx | 0 6 files changed, 197 insertions(+) create mode 100644 DB/db.json create mode 100644 DB/schema.sql create mode 100644 app/API/API-ReadMe.md create mode 100644 app/API/API.js create mode 100644 app/Controller/LoginLogic.js create mode 100644 app/Screens/LoginPage.jsx diff --git a/DB/db.json b/DB/db.json new file mode 100644 index 0000000..4f0ae0a --- /dev/null +++ b/DB/db.json @@ -0,0 +1,45 @@ +{ + "users": [ + { + "Uid": 1, + "username": "admin", + "password": "admin123", + "Gid": null, + "SGid": 0, + "TGid": null + }, + { + "Uid": 2, + "username": "user1", + "password": "user123", + "Gid": 1, + "SGid": 1, + "TGid": null + } + ], + "groups": [ + { + "Gid": 1, + "GroupName": "Public Group" + } + ], + "subgroups": [ + { + "SGid": 0, + "SubGroupName": "Admin Subgroup", + "Gid": null + }, + { + "SGid": 1, + "SubGroupName": "User Subgroup", + "Gid": 1 + } + ], + "user_groups": [ + { + "Uid": 2, + "Gid": 1, + "SGid": 1 + } + ] +} diff --git a/DB/schema.sql b/DB/schema.sql new file mode 100644 index 0000000..0c8ace9 --- /dev/null +++ b/DB/schema.sql @@ -0,0 +1,27 @@ +CREATE TABLE USER ( + Uid INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, + username TEXT NOT NULL, + password TEXT NOT NULL +); + +CREATE TABLE "GROUP" ( + Gid INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, + GroupName TEXT NOT NULL +); + +CREATE TABLE SUBGROUP ( + SGid INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, + SubGroupName TEXT NOT NULL, + Gid INTEGER NOT NULL, + FOREIGN KEY (Gid) REFERENCES "GROUP"(Gid) +); + +CREATE TABLE USER_GROUP ( + Uid INTEGER NOT NULL, + Gid INTEGER NOT NULL, + SGid INTEGER, + PRIMARY KEY (Uid, Gid), + FOREIGN KEY (Uid) REFERENCES USER(Uid), + FOREIGN KEY (Gid) REFERENCES "GROUP"(Gid), + FOREIGN KEY (SGid) REFERENCES SUBGROUP(SGid) +); \ No newline at end of file diff --git a/app/API/API-ReadMe.md b/app/API/API-ReadMe.md new file mode 100644 index 0000000..06e887d --- /dev/null +++ b/app/API/API-ReadMe.md @@ -0,0 +1,18 @@ +# ReadMe for the API endpoint + +### This page is for my project partner to understand the API endpoint, how to use it and also when to use it. + + +The database will first be made locally with regular SQL. + +Once the database is initialised and fully created locally, we can move the logic [refactor] it to use the API endpoint that will be created +api endpoint will be used here to fetch the data from the database and then display it on the frontend. +Same logic applies so minimal change in the code, for now we'll have the api endpoint point to the local database. +Therefore, still a need for the API.js file to be created and used in the frontend to fetch the data from the database and display it on the frontend. +To refactor its just going to be a simple replace. + +### API Endpoint +``` (Endpoint Link/URL once it's made.) ``` + +### How to use it +[Will be populated once there is data for me to provide here.] \ No newline at end of file diff --git a/app/API/API.js b/app/API/API.js new file mode 100644 index 0000000..006e309 --- /dev/null +++ b/app/API/API.js @@ -0,0 +1,48 @@ +// This file contains functions to interact with the API or local database. + +const API_BASE_URL = 'http://localhost:3000'; // Change this to the actual API endpoint when needed + +// Generic fetch function +const APIFetch = async (endpoint, options = {}) => { + try { + const response = await fetch(`${API_BASE_URL}/${endpoint}`, { + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers, + }, + }); + + if (!response.ok) { + throw new Error(`API error: ${response.statusText}`); + } + + return await response.json(); + } catch (error) { + console.error('Fetch error:', error); + throw error; + } +}; + +// Example function to fetch a user by username +const fetchUserByUsername = async (username) => { + return await APIFetch(`users?username=${username}`); +}; + +// Example function to fetch all groups +const fetchGroups = async () => { + return await APIFetch('groups'); +}; + +// Example function to fetch subgroups by group ID +const fetchSubgroupsByGroupId = async (groupId) => { + return await APIFetch(`groups/${groupId}/subgroups`); +}; + +// RESTful API functions +const fetchItems = async (endpoint) => await APIFetch(endpoint); +const createItem = async (endpoint, data) => await APIFetch(endpoint, { method: 'POST', body: JSON.stringify(data) }); +const updateItem = async (endpoint, data) => await APIFetch(endpoint, { method: 'PUT', body: JSON.stringify(data) }); +const deleteItem = async (endpoint) => await APIFetch(endpoint, { method: 'DELETE' }); + +export { APIFetch, fetchUserByUsername, fetchGroups, fetchSubgroupsByGroupId, fetchItems, createItem, updateItem, deleteItem }; diff --git a/app/Controller/LoginLogic.js b/app/Controller/LoginLogic.js new file mode 100644 index 0000000..8f45d45 --- /dev/null +++ b/app/Controller/LoginLogic.js @@ -0,0 +1,59 @@ +// If a user's subgroupID is 0, Treat them as ADMIN +// If a user's subgroupID is 1, Treat them as USER [For Public instances only subgroups avail are 0 and 1] +// If a user's subgroupID is 2, Treat them as USER [For Private instances, subgroups could range from 0-999 where 0 = admin, non 0 = member group] +// Use GroupID to link Subgroup to a group in the groups table, where subgroup --> defines permissions and whether the person is allowed to play or not. +// within subgroups have TeamGroups --> TeamGroups can come and go, they are not a fixed table [Team groups are enabled per admin request.] +// Team group ==> IF Teams are enabled a user can create a team group, if they're admin in team group they can kick people. +// All team groups have a unique JOIN CODE. +// User's table should have their [NULLABLE] unique Gid, SGid and TGid. +// Gid == GroupID || SGid == SubgroupID || TGid == TeamGroupID +// When a user logs in, we check their Gid, SGid and TGid to determine their permissions and what they can see on the front end. +// If a user is in a team group, they can only see other members of that team group and the games that team group is playing. +// If a user is in a subgroup, they can see all members of that subgroup and the games that subgroup is playing. +// If a user is in the admin subgroup, they can see all members and all games. + +import { useState } from 'react'; +import { useNavigation } from '@react-navigation/native'; + +const useLoginLogic = () => { + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const navigation = useNavigation(); + const dispatch = useDispatch(); + + const handleLogin = async () => { + try { + // Replace with your actual API endpoint + const response = await fetch('https://yourapi.com/login', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ username, password }), + }); + + if (!response.ok) { + alert("API error"); + } + + const data = await response.json(); + // Assuming the API returns user data including Gid, SGid, and TGid + const { Gid, SGid, TGid } = data; + + // Dispatch user data to Redux store + dispatch(setUser({ Gid, SGid, TGid })); + + // Navigate to the appropriate screen based on user role + if (SGid === 0) { + navigation.navigate('AdminDashboard'); + } else if (SGid === 1) { + navigation.navigate('UserDashboard'); + } else { + navigation.navigate('PrivateDashboard'); + } + } catch (error) { + Alert.alert('Login Error', error.message); + } + }; + +export default LoginLogic; diff --git a/app/Screens/LoginPage.jsx b/app/Screens/LoginPage.jsx new file mode 100644 index 0000000..e69de29