join_gamenight #8

Merged
Roflin merged 2 commits from join_gamenight into main 2022-06-03 19:47:08 +02:00
5 changed files with 169 additions and 97 deletions
Showing only changes of commit f7f9f7456b - Show all commits

View File

@ -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
View 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)
});
}

View 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;

View File

@ -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: { setExpanded(false);
'Content-Type': 'application/json', setGameName("");
'Authorization': `Bearer ${props.user.jwt}` setDate(null);
},
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);
setGameName("");
setDate(null);
}
}) })
.then(() => props.refetchGamenights()) .then(() => props.refetchGamenights())
} }
}; };
if(expanded) { if(expanded) {

View File

@ -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());
} }
} }