diff --git a/frontend/web-app/package-lock.json b/frontend/web-app/package-lock.json index 2f8a1a9..f957c4f 100644 --- a/frontend/web-app/package-lock.json +++ b/frontend/web-app/package-lock.json @@ -17,6 +17,7 @@ "@types/react-dom": "^18.3.5", "ajv": "^8.17.1", "ajv-keywords": "^5.1.0", + "axios": "^1.7.9", "react": "^18.0.0", "react-dom": "^18.0.0", "react-router-dom": "^7.1.5", @@ -4691,6 +4692,29 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -13204,6 +13228,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", @@ -20053,6 +20082,28 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==" }, + "axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "requires": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -25961,6 +26012,11 @@ } } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "psl": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", diff --git a/frontend/web-app/package.json b/frontend/web-app/package.json index 6c8021d..db8c1ee 100644 --- a/frontend/web-app/package.json +++ b/frontend/web-app/package.json @@ -12,6 +12,7 @@ "@types/react-dom": "^18.3.5", "ajv": "^8.17.1", "ajv-keywords": "^5.1.0", + "axios": "^1.7.9", "react": "^18.0.0", "react-dom": "^18.0.0", "react-router-dom": "^7.1.5", diff --git a/frontend/web-app/src/Constants/global.ts b/frontend/web-app/src/Constants/global.ts new file mode 100644 index 0000000..8b990a0 --- /dev/null +++ b/frontend/web-app/src/Constants/global.ts @@ -0,0 +1 @@ +export const Dummy = 5000 //Dummy constant \ No newline at end of file diff --git a/frontend/web-app/src/Context/AuthContext.tsx b/frontend/web-app/src/Context/AuthContext.tsx new file mode 100644 index 0000000..70863d5 --- /dev/null +++ b/frontend/web-app/src/Context/AuthContext.tsx @@ -0,0 +1,37 @@ +import { createContext, useReducer } from "react"; +import { AuthContextAction, AuthContextState } from "../Interfaces/AuthInterfaces"; + +// Dummy AuthContext + +const AuthContext = createContext({}); + +const initialState : AuthContextState={ + authUser: '', + authToken: '', + isLoading: false, +} + +const reducer = (state: AuthContextState, action: AuthContextAction): AuthContextState =>{ + switch(action.type){ + case 'LOGIN': { + return {...state, authUser: action.data.authUser , authToken: action.data.authToken} + } + default: { + return state; + } + } +} + +export const AuthProvider = ({children}: {children: any}) => { + const [{authUser, authToken, isLoading}, dispatch] = useReducer(reducer, initialState); + const values = { + authUser, + authToken, + isLoading, + dispatch, + } + return {children} + +} + +export default AuthContext; \ No newline at end of file diff --git a/frontend/web-app/src/Controller/AuthController.ts b/frontend/web-app/src/Controller/AuthController.ts new file mode 100644 index 0000000..3610227 --- /dev/null +++ b/frontend/web-app/src/Controller/AuthController.ts @@ -0,0 +1,19 @@ +import authService from "../Services/AuthServices"; +import axiosInstance from "../Utils/axiosInstance"; + +// Dummy AuthController +class AuthController{ + public getUsers= async (): Promise =>{ + try{ + const response = await axiosInstance.get('/users'); + const usersData = authService.getUsers(response.data); + return usersData; + }catch(error){ + throw new Error('Error getUsers'); + } + } +} + +const authController = new AuthController(); + +export default authController; \ No newline at end of file diff --git a/frontend/web-app/src/Images/dummy-image.png b/frontend/web-app/src/Images/dummy-image.png new file mode 100644 index 0000000..109f4af Binary files /dev/null and b/frontend/web-app/src/Images/dummy-image.png differ diff --git a/frontend/web-app/src/Interfaces/AuthInterfaces.ts b/frontend/web-app/src/Interfaces/AuthInterfaces.ts new file mode 100644 index 0000000..909f031 --- /dev/null +++ b/frontend/web-app/src/Interfaces/AuthInterfaces.ts @@ -0,0 +1,15 @@ +// Dummy AuthInterfaces + +export interface AuthContextState{ + authUser: string, + authToken: string, + isLoading: boolean, +} + +export interface AuthContextAction{ + type: string, + data: { + authUser: string, + authToken: string, + } +} \ No newline at end of file diff --git a/frontend/web-app/src/Pages/HomePage.tsx b/frontend/web-app/src/Pages/HomePage.tsx index b7876b9..a580b38 100644 --- a/frontend/web-app/src/Pages/HomePage.tsx +++ b/frontend/web-app/src/Pages/HomePage.tsx @@ -1,6 +1,21 @@ -import React from 'react' +import React, { useEffect } from 'react' +import authController from '../Controller/AuthController' function HomePage() { +// example of using APIs +// you need not necessarily call APIs in useEffect +// you may also call them through other ways +// but make sure to keep them in async functions +// and use await while calling them to resolve Promise. + + useEffect(() => { + const fetchUserData = async () => { + const data = await authController.getUsers(); + console.log(data); + } + fetchUserData(); + }, []) + return (
HomePage
) diff --git a/frontend/web-app/src/Services/AuthServices.ts b/frontend/web-app/src/Services/AuthServices.ts new file mode 100644 index 0000000..31535b6 --- /dev/null +++ b/frontend/web-app/src/Services/AuthServices.ts @@ -0,0 +1,18 @@ +// This is an example of how to create service +// please remember that I have used any as an interface for some variable +// but that is not good please make specific interface for specific variable used in controller and service. + + +class AuthService{ + public getUsers=(data:any)=>{ + return data.map((userData: any)=>{ + return { + name: userData.username + } + }) + } +} + +const authService = new AuthService(); + +export default authService; \ No newline at end of file diff --git a/frontend/web-app/src/Styles/global.css b/frontend/web-app/src/Styles/global.css new file mode 100644 index 0000000..538abe8 --- /dev/null +++ b/frontend/web-app/src/Styles/global.css @@ -0,0 +1 @@ +/* Global CSS */ diff --git a/frontend/web-app/src/Utils/axiosInstance.ts b/frontend/web-app/src/Utils/axiosInstance.ts new file mode 100644 index 0000000..e2c3c1b --- /dev/null +++ b/frontend/web-app/src/Utils/axiosInstance.ts @@ -0,0 +1,13 @@ +import axios from "axios"; + +// Dummy URL is used here we need to change it later. + +const axiosInstance = axios.create({ + baseURL: 'https://jsonplaceholder.typicode.com', + timeout: 5000, + headers: { + "Content-Type": 'application/json', + } +}) + +export default axiosInstance; \ No newline at end of file diff --git a/frontend/web-app/src/Utils/global.ts b/frontend/web-app/src/Utils/global.ts new file mode 100644 index 0000000..3be8936 --- /dev/null +++ b/frontend/web-app/src/Utils/global.ts @@ -0,0 +1,5 @@ +// Dummy Utils function +export const isNull=(item: any)=>{ + if(item) return true; + else return false; +} \ No newline at end of file