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 Gamenight from './components/Gamenight';
|
||||
|
||||
import { get_gamenights, get_games, unpack_api_result, login } from './api/Api';
|
||||
|
||||
const localStorageUserKey = 'user';
|
||||
|
||||
function App() {
|
||||
@ -15,24 +17,14 @@ function App() {
|
||||
const [games, setGames] = useState([]);
|
||||
const [activeGamenight, setActiveGamenight] = useState(null);
|
||||
|
||||
const POST_HEADER = {'Content-Type': 'application/json'};
|
||||
const AUTH_HEADER = {'Authorization': `Bearer ${user?.jwt}`};
|
||||
|
||||
const handleLogin = (input) => {
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(input)
|
||||
};
|
||||
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
|
||||
});
|
||||
}
|
||||
unpack_api_result(login(input), setFlashData)
|
||||
.then(result => {
|
||||
setUser(result.user);
|
||||
localStorage.setItem(localStorageUserKey, JSON.stringify(result.user));
|
||||
});
|
||||
};
|
||||
|
||||
@ -55,43 +47,15 @@ function App() {
|
||||
|
||||
useEffect(() => {
|
||||
if (user !== null) {
|
||||
const requestOptions = {
|
||||
method: 'GET',
|
||||
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
|
||||
});
|
||||
}
|
||||
});
|
||||
unpack_api_result(get_gamenights(user.jwt), setFlashData)
|
||||
.then(result => setGamenights(result.gamenights));
|
||||
}
|
||||
}, [user])
|
||||
|
||||
useEffect(() => {
|
||||
if (user !== null) {
|
||||
const requestOptions = {
|
||||
method: 'GET',
|
||||
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
|
||||
});
|
||||
}
|
||||
});
|
||||
unpack_api_result(get_games(user.jwt), setFlashData)
|
||||
.then(result => setGames(result.games));
|
||||
}
|
||||
}, [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 GameAdder from './GameAdder';
|
||||
import { post_gamenight, unpack_api_result} from '../api/Api';
|
||||
|
||||
function AddGameNight(props) {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
@ -44,32 +45,14 @@ function AddGameNight(props) {
|
||||
game_list: gameList,
|
||||
}
|
||||
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
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 {
|
||||
unpack_api_result(post_gamenight(input, props.user.jwt), props.setFlash)
|
||||
.then(result => {
|
||||
setExpanded(false);
|
||||
setGameName("");
|
||||
setDate(null);
|
||||
}
|
||||
})
|
||||
.then(() => props.refetchGamenights())
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if(expanded) {
|
||||
|
@ -9,35 +9,15 @@ import GamesIcon from '@mui/icons-material/Games';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
|
||||
import AddGameNight from './AddGameNight';
|
||||
import {delete_gamenight, unpack_api_result} from '../api/Api';
|
||||
|
||||
function Gamenights(props) {
|
||||
const [dense, setDense] = React.useState(false);
|
||||
|
||||
const DeleteGamenight = (gameId) => {
|
||||
const DeleteGamenight = (game_id) => {
|
||||
if (props.user !== null) {
|
||||
let input = {
|
||||
game_id: gameId,
|
||||
}
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
})
|
||||
const input = { game_id: game_id };
|
||||
unpack_api_result(delete_gamenight(input, props.user.jwt), props.setFlash)
|
||||
.then(() => props.refetchGamenights());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user