forked from Roflin/gamenight
Adds a Apihelper to cleanup the react components.
This commit is contained in:
parent
cfaa6ebdb1
commit
f7f9f7456b
@ -5,6 +5,8 @@ import Login from './components/Login';
|
|||||||
import Gamenights from './components/Gamenights';
|
import Gamenights from './components/Gamenights';
|
||||||
import Gamenight from './components/Gamenight';
|
import Gamenight from './components/Gamenight';
|
||||||
|
|
||||||
|
import { get_gamenights, get_games, unpack_api_result, login } from './api/Api';
|
||||||
|
|
||||||
const localStorageUserKey = 'user';
|
const localStorageUserKey = 'user';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@ -15,24 +17,14 @@ function App() {
|
|||||||
const [games, setGames] = useState([]);
|
const [games, setGames] = useState([]);
|
||||||
const [activeGamenight, setActiveGamenight] = useState(null);
|
const [activeGamenight, setActiveGamenight] = useState(null);
|
||||||
|
|
||||||
|
const POST_HEADER = {'Content-Type': 'application/json'};
|
||||||
|
const AUTH_HEADER = {'Authorization': `Bearer ${user?.jwt}`};
|
||||||
|
|
||||||
const handleLogin = (input) => {
|
const handleLogin = (input) => {
|
||||||
const requestOptions = {
|
unpack_api_result(login(input), setFlashData)
|
||||||
method: 'POST',
|
.then(result => {
|
||||||
headers: { 'Content-Type': 'application/json' },
|
setUser(result.user);
|
||||||
body: JSON.stringify(input)
|
localStorage.setItem(localStorageUserKey, JSON.stringify(result.user));
|
||||||
};
|
|
||||||
fetch('api/login', requestOptions)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if(data.result === "Ok") {
|
|
||||||
setUser(data.user);
|
|
||||||
localStorage.setItem(localStorageUserKey, JSON.stringify(data.user));
|
|
||||||
} else {
|
|
||||||
setFlashData({
|
|
||||||
type: "Error",
|
|
||||||
message: data.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,43 +47,15 @@ function App() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user !== null) {
|
if (user !== null) {
|
||||||
const requestOptions = {
|
unpack_api_result(get_gamenights(user.jwt), setFlashData)
|
||||||
method: 'GET',
|
.then(result => setGamenights(result.gamenights));
|
||||||
headers: { 'Authorization': `Bearer ${user.jwt}` },
|
|
||||||
};
|
|
||||||
fetch('api/gamenights', requestOptions)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if(data.result === "Ok") {
|
|
||||||
setGamenights(data.gamenights)
|
|
||||||
} else {
|
|
||||||
setFlashData({
|
|
||||||
type: "Error",
|
|
||||||
message: data.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [user])
|
}, [user])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user !== null) {
|
if (user !== null) {
|
||||||
const requestOptions = {
|
unpack_api_result(get_games(user.jwt), setFlashData)
|
||||||
method: 'GET',
|
.then(result => setGames(result.games));
|
||||||
headers: { 'Authorization': `Bearer ${user.jwt}` },
|
|
||||||
};
|
|
||||||
fetch('api/games', requestOptions)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if(data.result === "Ok") {
|
|
||||||
setGames(data.games)
|
|
||||||
} else {
|
|
||||||
setFlashData({
|
|
||||||
type: "Error",
|
|
||||||
message: data.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [user])
|
}, [user])
|
||||||
|
|
||||||
|
70
frontend/src/api/Api.js
Normal file
70
frontend/src/api/Api.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
import fetchResource from './FetchResource'
|
||||||
|
|
||||||
|
export function unpack_api_result(promise, onError) {
|
||||||
|
promise.then(result => {
|
||||||
|
if(result.result !== 'Ok') {
|
||||||
|
onError({
|
||||||
|
type: 'Error',
|
||||||
|
message: result.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
onError({
|
||||||
|
type: 'Error',
|
||||||
|
message: `${error.status} ${error.message}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get_gamenights(token) {
|
||||||
|
return fetchResource('api/gamenights', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function post_gamenight(input, token) {
|
||||||
|
return fetchResource('api/gamenights', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify(input)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function delete_gamenight(input, token) {
|
||||||
|
return fetchResource('api/gamenights', {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify(input)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get_games(token) {
|
||||||
|
return fetchResource('api/games', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function login(body) {
|
||||||
|
return fetchResource('api/login', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body)
|
||||||
|
});
|
||||||
|
}
|
75
frontend/src/api/FetchResource.js
Normal file
75
frontend/src/api/FetchResource.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
const API_URL = '';
|
||||||
|
|
||||||
|
function ApiError(message, data, status) {
|
||||||
|
let response = null;
|
||||||
|
let isObject = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = JSON.parse(data);
|
||||||
|
isObject = true;
|
||||||
|
} catch (e) {
|
||||||
|
response = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.response = response;
|
||||||
|
this.message = message;
|
||||||
|
this.status = status;
|
||||||
|
this.toString = function () {
|
||||||
|
return `${ this.message }\nResponse:\n${ isObject ? JSON.stringify(this.response, null, 2) : this.response }`;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchResource = (path, userOptions = {}) => {
|
||||||
|
const defaultOptions = {};
|
||||||
|
const defaultHeaders = {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
};
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
...defaultOptions,
|
||||||
|
...userOptions,
|
||||||
|
headers: {
|
||||||
|
...defaultHeaders,
|
||||||
|
...userOptions.headers,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const url = `${ API_URL }/${ path }`;
|
||||||
|
const isFile = options.body instanceof File;
|
||||||
|
|
||||||
|
if (options.body && typeof options.body === 'object' && !isFile) {
|
||||||
|
options.body = JSON.stringify(options.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = null;
|
||||||
|
|
||||||
|
return fetch(url, options)
|
||||||
|
.then(responseObject => {
|
||||||
|
response = responseObject;
|
||||||
|
|
||||||
|
if (response.status === 401) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status < 200 || response.status >= 300) {
|
||||||
|
return response.text();
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(parsedResponse => {
|
||||||
|
if (response.status < 200 || response.status >= 300) {
|
||||||
|
throw parsedResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedResponse;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (response) {
|
||||||
|
throw new ApiError(`Request failed with status ${ response.status }.`, error, response.status);
|
||||||
|
} else {
|
||||||
|
throw new ApiError(error.toString(), null, 'REQUEST_FAILED');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default fetchResource;
|
@ -9,6 +9,7 @@ import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
|||||||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
||||||
|
|
||||||
import GameAdder from './GameAdder';
|
import GameAdder from './GameAdder';
|
||||||
|
import { post_gamenight, unpack_api_result} from '../api/Api';
|
||||||
|
|
||||||
function AddGameNight(props) {
|
function AddGameNight(props) {
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
@ -44,32 +45,14 @@ function AddGameNight(props) {
|
|||||||
game_list: gameList,
|
game_list: gameList,
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestOptions = {
|
unpack_api_result(post_gamenight(input, props.user.jwt), props.setFlash)
|
||||||
method: 'POST',
|
.then(result => {
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': `Bearer ${props.user.jwt}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify(input)
|
|
||||||
};
|
|
||||||
|
|
||||||
fetch('api/gamenights', requestOptions)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if(data.result !== "Ok") {
|
|
||||||
props.setFlash({
|
|
||||||
type: "Error",
|
|
||||||
message: data.message
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setExpanded(false);
|
setExpanded(false);
|
||||||
setGameName("");
|
setGameName("");
|
||||||
setDate(null);
|
setDate(null);
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.then(() => props.refetchGamenights())
|
.then(() => props.refetchGamenights())
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if(expanded) {
|
if(expanded) {
|
||||||
|
@ -9,35 +9,15 @@ import GamesIcon from '@mui/icons-material/Games';
|
|||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
|
|
||||||
import AddGameNight from './AddGameNight';
|
import AddGameNight from './AddGameNight';
|
||||||
|
import {delete_gamenight, unpack_api_result} from '../api/Api';
|
||||||
|
|
||||||
function Gamenights(props) {
|
function Gamenights(props) {
|
||||||
const [dense, setDense] = React.useState(false);
|
const [dense, setDense] = React.useState(false);
|
||||||
|
|
||||||
const DeleteGamenight = (gameId) => {
|
const DeleteGamenight = (game_id) => {
|
||||||
if (props.user !== null) {
|
if (props.user !== null) {
|
||||||
let input = {
|
const input = { game_id: game_id };
|
||||||
game_id: gameId,
|
unpack_api_result(delete_gamenight(input, props.user.jwt), props.setFlash)
|
||||||
}
|
|
||||||
|
|
||||||
const requestOptions = {
|
|
||||||
method: 'DELETE',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': `Bearer ${props.user.jwt}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify(input)
|
|
||||||
};
|
|
||||||
|
|
||||||
fetch('api/gamenights', requestOptions)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if(data.result !== "Ok") {
|
|
||||||
props.setFlash({
|
|
||||||
type: "Error",
|
|
||||||
message: data.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(() => props.refetchGamenights());
|
.then(() => props.refetchGamenights());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user