Merge pull request 'join_gamenight' (#8) from join_gamenight into main
Reviewed-on: #8
This commit is contained in:
commit
5ace39d820
@ -31,6 +31,8 @@ struct ApiResponse {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
gamenights: Option<Vec<GamenightOutput>>,
|
gamenights: Option<Vec<GamenightOutput>>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
gamenight: Option<GamenightOutput>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
games: Option<Vec<Game>>,
|
games: Option<Vec<Game>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +45,7 @@ impl ApiResponse {
|
|||||||
message: None,
|
message: None,
|
||||||
user: None,
|
user: None,
|
||||||
gamenights: None,
|
gamenights: None,
|
||||||
|
gamenight: None,
|
||||||
games: None,
|
games: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,6 +55,7 @@ impl ApiResponse {
|
|||||||
message: Some(Cow::Owned(message)),
|
message: Some(Cow::Owned(message)),
|
||||||
user: None,
|
user: None,
|
||||||
gamenights: None,
|
gamenights: None,
|
||||||
|
gamenight: None,
|
||||||
games: None,
|
games: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,16 +69,29 @@ impl ApiResponse {
|
|||||||
jwt: jwt,
|
jwt: jwt,
|
||||||
}),
|
}),
|
||||||
gamenights: None,
|
gamenights: None,
|
||||||
|
gamenight: None,
|
||||||
games: None,
|
games: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gamenight_response(gamenights: Vec<GamenightOutput>) -> Self {
|
fn gamenights_response(gamenights: Vec<GamenightOutput>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
result: Self::SUCCES_RESULT,
|
result: Self::SUCCES_RESULT,
|
||||||
message: None,
|
message: None,
|
||||||
user: None,
|
user: None,
|
||||||
gamenights: Some(gamenights),
|
gamenights: Some(gamenights),
|
||||||
|
gamenight: None,
|
||||||
|
games: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gamenight_response(gamenight: GamenightOutput) -> Self {
|
||||||
|
Self {
|
||||||
|
result: Self::SUCCES_RESULT,
|
||||||
|
message: None,
|
||||||
|
user: None,
|
||||||
|
gamenights: None,
|
||||||
|
gamenight: Some(gamenight),
|
||||||
games: None,
|
games: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,6 +102,7 @@ impl ApiResponse {
|
|||||||
message: None,
|
message: None,
|
||||||
user: None,
|
user: None,
|
||||||
gamenights: None,
|
gamenights: None,
|
||||||
|
gamenight: None,
|
||||||
games: Some(games),
|
games: Some(games),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,6 +158,63 @@ pub struct GamenightOutput {
|
|||||||
participants: Vec<User>,
|
participants: Vec<User>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct GamenightUpdate {
|
||||||
|
action: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[patch("/gamenights/<gamenight_id>", format = "application/json", data = "<patch_json>")]
|
||||||
|
pub async fn patch_gamenight(conn: DbConn, user: User, gamenight_id: String, patch_json: Json<GamenightUpdate>) -> ApiResponseVariant {
|
||||||
|
let uuid = Uuid::parse_str(&gamenight_id).unwrap();
|
||||||
|
let patch = patch_json.into_inner();
|
||||||
|
match patch.action.as_str() {
|
||||||
|
"RemoveParticipant" => {
|
||||||
|
let entry = GamenightParticipantsEntry {
|
||||||
|
gamenight_id: uuid,
|
||||||
|
user_id: user.id
|
||||||
|
};
|
||||||
|
match remove_participant(&conn, entry).await {
|
||||||
|
Ok(_) => ApiResponseVariant::Value(json!(ApiResponse::SUCCES)),
|
||||||
|
Err(err) => ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"AddParticipant" => {
|
||||||
|
let entry = GamenightParticipantsEntry {
|
||||||
|
gamenight_id: uuid,
|
||||||
|
user_id: user.id
|
||||||
|
};
|
||||||
|
match add_participant(&conn, entry).await {
|
||||||
|
Ok(_) => ApiResponseVariant::Value(json!(ApiResponse::SUCCES)),
|
||||||
|
Err(err) => ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => ApiResponseVariant::Value(json!(ApiResponse::SUCCES))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/gamenights/<gamenight_id>")]
|
||||||
|
pub async fn gamenight(conn: DbConn, _user: User, gamenight_id: String) -> ApiResponseVariant {
|
||||||
|
let uuid = Uuid::parse_str(&gamenight_id).unwrap();
|
||||||
|
let gamenight = match get_gamenight(&conn, uuid).await {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(err) => return ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))),
|
||||||
|
};
|
||||||
|
let games = match get_games_of_gamenight(&conn, uuid).await {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(err) => return ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))),
|
||||||
|
};
|
||||||
|
let participants = match load_participants(&conn, uuid).await {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(err) => return ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))),
|
||||||
|
};
|
||||||
|
let gamenight_output = GamenightOutput {
|
||||||
|
gamenight: gamenight,
|
||||||
|
game_list: games,
|
||||||
|
participants: participants
|
||||||
|
};
|
||||||
|
return ApiResponseVariant::Value(json!(ApiResponse::gamenight_response(gamenight_output)))
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/gamenights")]
|
#[get("/gamenights")]
|
||||||
pub async fn gamenights(conn: DbConn, _user: User) -> ApiResponseVariant {
|
pub async fn gamenights(conn: DbConn, _user: User) -> ApiResponseVariant {
|
||||||
let gamenights = match get_all_gamenights(&conn).await {
|
let gamenights = match get_all_gamenights(&conn).await {
|
||||||
@ -164,7 +239,7 @@ pub async fn gamenights(conn: DbConn, _user: User) -> ApiResponseVariant {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match game_results {
|
match game_results {
|
||||||
Ok(result) => ApiResponseVariant::Value(json!(ApiResponse::gamenight_response(result))),
|
Ok(result) => ApiResponseVariant::Value(json!(ApiResponse::gamenights_response(result))),
|
||||||
Err(err) => ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))),
|
Err(err) => ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +295,7 @@ pub async fn gamenights_post_json(
|
|||||||
gamenight_id: gamenight_id,
|
gamenight_id: gamenight_id,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
};
|
};
|
||||||
match insert_participant(&conn, participant).await {
|
match add_participant(&conn, participant).await {
|
||||||
Ok(_) => ApiResponseVariant::Value(json!(ApiResponse::SUCCES)),
|
Ok(_) => ApiResponseVariant::Value(json!(ApiResponse::SUCCES)),
|
||||||
Err(err) => ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))),
|
Err(err) => ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))),
|
||||||
}
|
}
|
||||||
@ -375,7 +450,7 @@ pub async fn post_participants(
|
|||||||
_user: User,
|
_user: User,
|
||||||
entry_json: Json<GamenightParticipantsEntry>,
|
entry_json: Json<GamenightParticipantsEntry>,
|
||||||
) -> ApiResponseVariant {
|
) -> ApiResponseVariant {
|
||||||
match insert_participant(&conn, entry_json.into_inner()).await {
|
match add_participant(&conn, entry_json.into_inner()).await {
|
||||||
Ok(_) => ApiResponseVariant::Value(json!(ApiResponse::SUCCES)),
|
Ok(_) => ApiResponseVariant::Value(json!(ApiResponse::SUCCES)),
|
||||||
Err(error) => ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))),
|
Err(error) => ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))),
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,8 @@ async fn rocket() -> _ {
|
|||||||
.mount(
|
.mount(
|
||||||
"/api",
|
"/api",
|
||||||
routes![
|
routes![
|
||||||
|
api::gamenight,
|
||||||
|
api::patch_gamenight,
|
||||||
api::gamenights,
|
api::gamenights,
|
||||||
api::gamenights_unauthorized,
|
api::gamenights_unauthorized,
|
||||||
api::gamenights_post_json,
|
api::gamenights_post_json,
|
||||||
|
@ -110,9 +110,9 @@ pub async fn insert_gamenight(
|
|||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_gamenight(conn: &DbConn, game_id: Uuid) -> Result<Gamenight, DatabaseError> {
|
pub async fn get_gamenight(conn: &DbConn, gamenight_id: Uuid) -> Result<Gamenight, DatabaseError> {
|
||||||
Ok(conn
|
Ok(conn
|
||||||
.run(move |c| gamenight::table.find(game_id).first(c))
|
.run(move |c| gamenight::table.find(gamenight_id).first(c))
|
||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ pub async fn load_participants(
|
|||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn insert_participant(
|
pub async fn add_participant(
|
||||||
conn: &DbConn,
|
conn: &DbConn,
|
||||||
participant: GamenightParticipantsEntry,
|
participant: GamenightParticipantsEntry,
|
||||||
) -> Result<usize, DatabaseError> {
|
) -> Result<usize, DatabaseError> {
|
||||||
@ -198,6 +198,7 @@ pub async fn insert_participant(
|
|||||||
.run(move |c| {
|
.run(move |c| {
|
||||||
diesel::insert_into(gamenight_participants::table)
|
diesel::insert_into(gamenight_participants::table)
|
||||||
.values(&participant)
|
.values(&participant)
|
||||||
|
.on_conflict_do_nothing()
|
||||||
.execute(c)
|
.execute(c)
|
||||||
})
|
})
|
||||||
.await?)
|
.await?)
|
||||||
|
@ -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() {
|
||||||
@ -13,26 +15,16 @@ function App() {
|
|||||||
const [gamenights, setGamenights] = useState([]);
|
const [gamenights, setGamenights] = useState([]);
|
||||||
const [flashData, setFlashData] = useState({});
|
const [flashData, setFlashData] = useState({});
|
||||||
const [games, setGames] = useState([]);
|
const [games, setGames] = useState([]);
|
||||||
const [activeGamenight, setActiveGamenight] = useState(null);
|
const [activeGamenightId, setActiveGamenightId] = 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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,49 +42,21 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const dismissActiveGamenight = () => {
|
const dismissActiveGamenight = () => {
|
||||||
setActiveGamenight(null);
|
setActiveGamenightId(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
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])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -108,7 +72,7 @@ function App() {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let mainview;
|
let mainview;
|
||||||
if(activeGamenight === null) {
|
if(activeGamenightId === null) {
|
||||||
mainview = (
|
mainview = (
|
||||||
<Gamenights
|
<Gamenights
|
||||||
user={user}
|
user={user}
|
||||||
@ -116,13 +80,15 @@ function App() {
|
|||||||
setFlash={setFlash}
|
setFlash={setFlash}
|
||||||
refetchGamenights={refetchGamenights}
|
refetchGamenights={refetchGamenights}
|
||||||
gamenights={gamenights}
|
gamenights={gamenights}
|
||||||
onSelectGamenight={(g) => setActiveGamenight(g)}/>
|
onSelectGamenight={(g) => setActiveGamenightId(g.id)}/>
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
mainview = (
|
mainview = (
|
||||||
<Gamenight
|
<Gamenight
|
||||||
gamenight={activeGamenight}
|
gamenightId={activeGamenightId}
|
||||||
onDismis={dismissActiveGamenight}
|
onDismis={dismissActiveGamenight}
|
||||||
|
setFlash={setFlash}
|
||||||
|
user={user}
|
||||||
/>)
|
/>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
90
frontend/src/api/Api.js
Normal file
90
frontend/src/api/Api.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
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 get_gamenight(gamenight_id, token) {
|
||||||
|
return fetchResource(`api/gamenights/${gamenight_id}`, {
|
||||||
|
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 patch_gamenight(gamenight_id, input, token) {
|
||||||
|
return fetchResource(`api/gamenights/${gamenight_id}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
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)
|
||||||
|
});
|
||||||
|
}
|
73
frontend/src/api/FetchResource.js
Normal file
73
frontend/src/api/FetchResource.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
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 = {};
|
||||||
|
|
||||||
|
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: {
|
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) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import List from '@mui/material/List';
|
import List from '@mui/material/List';
|
||||||
import ListItem from '@mui/material/ListItem';
|
import ListItem from '@mui/material/ListItem';
|
||||||
import ListItemText from '@mui/material/ListItemText';
|
import ListItemText from '@mui/material/ListItemText';
|
||||||
@ -6,15 +6,26 @@ import ListSubheader from '@mui/material/ListSubheader';
|
|||||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import {unpack_api_result, get_gamenight, patch_gamenight} from '../api/Api';
|
||||||
|
|
||||||
function Gamenight(props) {
|
function Gamenight(props) {
|
||||||
|
|
||||||
const [dense, setDense] = useState(true);
|
const [dense, setDense] = useState(true);
|
||||||
|
const [gamenight, setGamenight] = useState(null);
|
||||||
|
|
||||||
let games = props.gamenight.game_list.map(g =>
|
const fetchGamenight = () => {
|
||||||
|
if (props.user !== null) {
|
||||||
|
unpack_api_result(get_gamenight(props.gamenightId, props.user.jwt), props.setFlash)
|
||||||
|
.then(result => setGamenight(result.gamenight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(fetchGamenight, []);
|
||||||
|
|
||||||
|
let games = gamenight?.game_list.map(g =>
|
||||||
(
|
(
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
@ -24,7 +35,7 @@ function Gamenight(props) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
let participants = props.gamenight.participants.map(p =>
|
const participants = gamenight?.participants.map(p =>
|
||||||
(
|
(
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
@ -32,7 +43,46 @@ function Gamenight(props) {
|
|||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
|
|
||||||
|
const Join = () => {
|
||||||
|
const input = {
|
||||||
|
action: 'AddParticipant'
|
||||||
|
};
|
||||||
|
|
||||||
|
unpack_api_result(patch_gamenight(gamenight.id, input, props.user.jwt), props.setFlash)
|
||||||
|
.then(() => fetchGamenight());
|
||||||
|
};
|
||||||
|
|
||||||
|
const Leave = () => {
|
||||||
|
const input = {
|
||||||
|
action: 'RemoveParticipant',
|
||||||
|
};
|
||||||
|
|
||||||
|
unpack_api_result(patch_gamenight(gamenight.id, input, props.user.jwt), props.setFlash)
|
||||||
|
.then(() => fetchGamenight());
|
||||||
|
};
|
||||||
|
|
||||||
|
let join_or_leave_button;
|
||||||
|
if(gamenight?.participants.find(p => p.id === props.user.id) === undefined) {
|
||||||
|
join_or_leave_button = (
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
color="success"
|
||||||
|
onClick={Join}>
|
||||||
|
Join
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
join_or_leave_button = (
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
color="error"
|
||||||
|
onClick={Leave}>
|
||||||
|
Leave
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -43,10 +93,10 @@ function Gamenight(props) {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
<Typography type="h3">
|
<Typography type="h3">
|
||||||
{props.gamenight.name}
|
{gamenight?.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography type="body1">
|
<Typography type="body1">
|
||||||
When: {moment(props.gamenight.datetime).format('LL HH:mm')}
|
When: {moment(gamenight?.datetime).format('LL HH:mm')}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<List
|
<List
|
||||||
@ -69,6 +119,7 @@ function Gamenight(props) {
|
|||||||
}>
|
}>
|
||||||
{participants}
|
{participants}
|
||||||
</List>
|
</List>
|
||||||
|
{join_or_leave_button}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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