Archived
Merging completed Ch. 11 #2
@@ -21,3 +21,5 @@
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
projectnotes.md*
|
||||
|
||||
@@ -2,6 +2,10 @@ import React from "react"
|
||||
import { Route } from "react-router-dom"
|
||||
import { EventList } from "./game/EventList.js"
|
||||
import { GameList } from "./game/GameList.js"
|
||||
import { GameForm } from "./game/GameForm.js"
|
||||
import { EventForm } from "./game/EventForm.js"
|
||||
import { UpdateEvent } from "./game/UpdateEvent.js"
|
||||
import { UpdateGame} from "./game/UpdateGame.js"
|
||||
export const ApplicationViews = () => {
|
||||
return <>
|
||||
<main style={{
|
||||
@@ -13,6 +17,18 @@ export const ApplicationViews = () => {
|
||||
</Route>
|
||||
<Route exact path="/">
|
||||
<EventList />
|
||||
</Route>
|
||||
<Route exact path = "/games/new" >
|
||||
<GameForm />
|
||||
</Route>
|
||||
<Route exact path = "/events/new" >
|
||||
<EventForm />
|
||||
</Route>
|
||||
<Route exact path= "/events/update/:id(\d+)">
|
||||
<UpdateEvent />
|
||||
</Route>
|
||||
<Route exact path= "/games/update/:id(\d+)">
|
||||
<UpdateGame />
|
||||
</Route>
|
||||
</main>
|
||||
</>
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { useHistory } from 'react-router-dom'
|
||||
|
||||
|
||||
export const EventForm = () => {
|
||||
const history = useHistory()
|
||||
const [eventTypes, setEventTypes] = useState([])
|
||||
|
||||
/*
|
||||
Since the input fields are bound to the values of
|
||||
the properties of this state variable, you need to
|
||||
provide some default values.
|
||||
*/
|
||||
const [currentEvent, setCurrentEvent] = useState({
|
||||
skillLevel: 1,
|
||||
Description: "",
|
||||
date: "",
|
||||
time: "",
|
||||
game_id: 1,
|
||||
organizer_id: 1
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// TODO: Get the event types, then set the state
|
||||
}, [])
|
||||
|
||||
const changeEventState = (domEvent) => {
|
||||
// TODO: Complete the onChange function
|
||||
}
|
||||
|
||||
return (
|
||||
<form className="eventForm">
|
||||
<h2 className="eventForm__title">Register New Event</h2>
|
||||
<fieldset>
|
||||
<div className="form-group">
|
||||
<label htmlFor="title">Title: </label>
|
||||
<input type="text" name="title" required autoFocus className="form-control"
|
||||
value={currentEvent.title}
|
||||
onChange={changeEventState}
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{/* TODO: create the rest of the input fields */}
|
||||
|
||||
<button type="submit"
|
||||
onClick={evt => {
|
||||
// Prevent form from being submitted
|
||||
evt.preventDefault()
|
||||
|
||||
const event = {
|
||||
maker: currentEvent.maker,
|
||||
title: currentEvent.title,
|
||||
numberOfPlayers: parseInt(currentEvent.numberOfPlayers),
|
||||
skillLevel: parseInt(currentEvent.skillLevel),
|
||||
eventTypeId: parseInt(currentEvent.eventTypeId)
|
||||
}
|
||||
|
||||
// Send POST request to your API
|
||||
createEvent(event)
|
||||
.then(() => history.push("/events"))
|
||||
}}
|
||||
className="btn btn-primary">Create</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
@@ -1,23 +1,51 @@
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { getEvents } from "./EventManager.js"
|
||||
import React, { useEffect, useState, } from "react"
|
||||
import { getEvents, } from "./EventManager.js"
|
||||
import { UpdateEvent } from "./UpdateEvent.js"
|
||||
import { useHistory } from "react-router-dom/cjs/react-router-dom.min"
|
||||
|
||||
export const EventList = (props) => {
|
||||
const [ events, setEvents ] = useState([])
|
||||
const history = useHistory()
|
||||
|
||||
useEffect(() => {
|
||||
getEvents().then(data => setEvents(data))
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<article className="events">
|
||||
return (
|
||||
|
||||
<article className="events">
|
||||
|
||||
<button
|
||||
className="btn btn-2 btn-sep icon-create"
|
||||
onClick={
|
||||
() => {
|
||||
history.push(
|
||||
{ pathname: "/events/new" }
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
>Register New Event
|
||||
</button>
|
||||
{
|
||||
events.map(event => {
|
||||
return <section key={`event--${event.id}`} className="event">
|
||||
events.map(
|
||||
event => {
|
||||
return(
|
||||
<>
|
||||
<section key={`event--${event.id}`} className="event">
|
||||
<button onClick={()=> history.push(`./events/update/${event.id}`) }>Update Event</button>
|
||||
<div className="event__description">{event.description}</div>
|
||||
<div className="event__date">The event is happening on {event.date} at {event.time}.</div>
|
||||
</section>
|
||||
})
|
||||
}
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
)
|
||||
}
|
||||
@@ -5,4 +5,41 @@ export const getEvents = () => {
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
}
|
||||
|
||||
export const getEventById = (id) => {
|
||||
return fetch(`http://localhost:8000/events/${id}`, {
|
||||
headers:{
|
||||
"Authorization": `Token ${localStorage.getItem("lu_token")}`
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
}
|
||||
export const putEvents = (editedEvent) => {
|
||||
return fetch(`http://localhost:8000/events/${editedEvent.id}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(
|
||||
editedEvent
|
||||
),
|
||||
headers:{
|
||||
"Authorization": `Token ${localStorage.getItem("lu_token")}`,
|
||||
"Content-Type": "Application/json"
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(response => {response => {
|
||||
return response.json()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
export const createEvent = (event) => {
|
||||
return fetch("http://localhost:8000/events", {
|
||||
headers:{
|
||||
"Authorization": `Token ${localStorage.getItem("lu_token")}`
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import { createGame, getGameTypes } from './GameManager.js'
|
||||
|
||||
|
||||
export const GameForm = () => {
|
||||
const history = useHistory()
|
||||
const [gameTypes, setGameTypes] = useState([])
|
||||
|
||||
/*
|
||||
Since the input fields are bound to the values of
|
||||
the properties of this state variable, you need to
|
||||
provide some default values.
|
||||
*/
|
||||
const [currentGame, setCurrentGame] = useState({
|
||||
skillLevel: 1,
|
||||
numberOfPlayers: 0,
|
||||
title: "",
|
||||
maker: "",
|
||||
gameTypeId: 0
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// TODO: Get the game types, then set the state
|
||||
}, [])
|
||||
|
||||
const changeGameState = (domEvent) => {
|
||||
// TODO: Complete the onChange function
|
||||
}
|
||||
|
||||
return (
|
||||
<form className="gameForm">
|
||||
<h2 className="gameForm__title">Register New Game</h2>
|
||||
<fieldset>
|
||||
<div className="form-group">
|
||||
<label htmlFor="title">Title: </label>
|
||||
<input type="text" name="title" required autoFocus className="form-control"
|
||||
value={currentGame.title}
|
||||
onChange={changeGameState}
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{/* TODO: create the rest of the input fields */}
|
||||
|
||||
<button type="submit"
|
||||
onClick={evt => {
|
||||
// Prevent form from being submitted
|
||||
evt.preventDefault()
|
||||
|
||||
const game = {
|
||||
maker: currentGame.maker,
|
||||
title: currentGame.title,
|
||||
numberOfPlayers: parseInt(currentGame.numberOfPlayers),
|
||||
skillLevel: parseInt(currentGame.skillLevel),
|
||||
gameTypeId: parseInt(currentGame.gameTypeId)
|
||||
}
|
||||
|
||||
// Send POST request to your API
|
||||
createGame(game)
|
||||
.then(() => history.push("/games"))
|
||||
}}
|
||||
className="btn btn-primary">Create</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
@@ -1,18 +1,36 @@
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { getGames } from "./GameManager.js"
|
||||
import {useHistory } from "react-router-dom"
|
||||
import { UpdateEvent } from "./UpdateEvent.js"
|
||||
|
||||
export const GameList = (props) => {
|
||||
const [ games, setGames ] = useState([])
|
||||
const history = useHistory()
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getGames().then(data => setGames(data))
|
||||
}, [])
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
<article className="games">
|
||||
<button className="btn btn-2 btn-sep icon-create"
|
||||
onClick={
|
||||
() => {
|
||||
history.push(
|
||||
{ pathname: "/games/new" }
|
||||
)
|
||||
}
|
||||
}
|
||||
>Register New Game</button>
|
||||
{
|
||||
games.map(game => {
|
||||
return <section key={`game--${game.id}`} className="game">
|
||||
<button onClick={()=> history.push(`./games/update/${game.id}`) }>Update Game</button>
|
||||
<div className="game__title">{game.title} by {game.maker}</div>
|
||||
<div className="game__players">{game.number_of_players} players needed</div>
|
||||
<div className="game__skillLevel">Skill level is {game.skill_level}</div>
|
||||
@@ -20,5 +38,6 @@ export const GameList = (props) => {
|
||||
})
|
||||
}
|
||||
</article>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -5,4 +5,45 @@ export const getGames = () => {
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
}
|
||||
|
||||
export const getGameById = (id) => {
|
||||
return fetch(`http://localhost:8000/games/${id}`, {
|
||||
headers:{
|
||||
"Authorization": `Token ${localStorage.getItem("lu_token")}`
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
}
|
||||
|
||||
export const createGame = (game) => {
|
||||
return fetch("http://localhost:8000/games", {
|
||||
headers:{
|
||||
"Authorization": `Token ${localStorage.getItem("lu_token")}`
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
}
|
||||
|
||||
export const getGameTypes = () => {
|
||||
return fetch("http://localhost:8000/gametypes", {
|
||||
headers:{
|
||||
"Authorization": `Token ${localStorage.getItem("lu_token")}`
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
}
|
||||
|
||||
export const putGames = (editedGame) => {
|
||||
return fetch(`http://localhost:8000/games/${editedGame.id}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(
|
||||
editedGame
|
||||
),
|
||||
headers:{
|
||||
"Authorization": `Token ${localStorage.getItem("lu_token")}`,
|
||||
"Content-Type": "Application/json"
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
import react, { useState, useEffect, } from "react";
|
||||
import { useParams, useHistory } from "react-router-dom/cjs/react-router-dom.min";
|
||||
import { getGames } from "./GameManager";
|
||||
import { putEvents } from "./EventManager";
|
||||
import { getEvents, getEventById } from "./EventManager";
|
||||
|
||||
// getGames is imported to allow the select to display a list of games
|
||||
export const UpdateEvent = (props) => {
|
||||
const [ gameList, setGameList] = useState([])
|
||||
const [ eventList, setEventList] = useState([])
|
||||
const [ eventToEdit, setEventToEdit ] = useState({})
|
||||
|
||||
|
||||
let { id } = useParams()
|
||||
const history = useHistory()
|
||||
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getGames().then(data => setGameList(data))
|
||||
getEvents().then(data => setEventList(data))
|
||||
getEventById(id).then(data =>
|
||||
{
|
||||
setEventToEdit(data)
|
||||
|
||||
}
|
||||
)
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
|
||||
// Still need to write out this form and figure out controlled/uncontrolled input for it. Event pk value needs to be passed to the form as props if I'm understanding this correctly
|
||||
const eventupdateform = () => {
|
||||
return(
|
||||
<>
|
||||
<h2>Update Event</h2>
|
||||
<form id="editeventform">
|
||||
<label for="description">Event Description</label>
|
||||
<input type="text" id="description" value={eventToEdit.description} onChange=
|
||||
{
|
||||
(e)=>
|
||||
{
|
||||
const copy = {...eventToEdit}
|
||||
copy.description = e.target.value
|
||||
setEventToEdit(copy)
|
||||
}
|
||||
}
|
||||
>
|
||||
|
||||
</input>
|
||||
<label for="games">Select Game</label>
|
||||
<select name="games" form_id="editeventform"
|
||||
/* Set game via parsing the gameId as the indicator to select the correct game for the event*/
|
||||
onChange={(e)=>
|
||||
{
|
||||
const copy = {...eventToEdit}
|
||||
copy.game_id = e.target.value
|
||||
setEventToEdit(copy)}
|
||||
}>
|
||||
<option value={""} selected disabled>Change Game from {eventToEdit.game?.title}</option>
|
||||
|
||||
|
||||
|
||||
{ gameList.map(
|
||||
(gameList) => <option value={gameList.id}>{gameList.title}</option>
|
||||
)
|
||||
}
|
||||
</select>
|
||||
<label for="date">Updated Event Date</label>
|
||||
<input type="date" id="eventdate" value={eventToEdit.date}
|
||||
onChange={
|
||||
(e)=>
|
||||
{
|
||||
const copy = {...eventToEdit}
|
||||
copy.date = e.target.value
|
||||
setEventToEdit(copy)
|
||||
}
|
||||
}
|
||||
>
|
||||
|
||||
</input>
|
||||
<label for="time">Updated Event Time</label>
|
||||
<input type="time" id="time" value={eventToEdit.time} onChange={(e)=>
|
||||
{
|
||||
const copy = {...eventToEdit}
|
||||
copy.time = e.target.value
|
||||
setEventToEdit(copy)}
|
||||
}
|
||||
|
||||
>
|
||||
</input>
|
||||
<input type="submit"
|
||||
|
||||
onClick={
|
||||
(e)=>
|
||||
{
|
||||
e.preventDefault()
|
||||
putEvents(eventToEdit)
|
||||
history.push("/")
|
||||
}
|
||||
}
|
||||
>
|
||||
|
||||
</input>
|
||||
</form>
|
||||
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
return(
|
||||
eventupdateform()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
import react, { useState, useEffect, } from "react";
|
||||
import { useParams, useHistory } from "react-router-dom/cjs/react-router-dom.min";
|
||||
import { getGames, getGameById, getGameTypes, putGames } from "./GameManager";
|
||||
|
||||
// getGames is imported to allow the select to display a list of games
|
||||
export const UpdateGame = (props) => {
|
||||
const [ gameList, setGameList] = useState([])
|
||||
const [ gameToEdit, setGameToEdit ] = useState({})
|
||||
const [gametypes, setGameTypes ] = useState([])
|
||||
let { id } = useParams()
|
||||
const history = useHistory()
|
||||
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getGames().then(data => setGameList(data))
|
||||
getGameTypes().then(data=> setGameTypes(data))
|
||||
getGameById(id).then(data =>
|
||||
{
|
||||
data.game_type = data.game_type.id
|
||||
setGameToEdit(data)
|
||||
|
||||
}
|
||||
)
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
|
||||
|
||||
const gameupdateform = () => {
|
||||
return(
|
||||
<>
|
||||
<h2>Update Game</h2>
|
||||
<form id="editgameform">
|
||||
<label for="title">Game Title</label>
|
||||
<input type="textearea" id="title" value={gameToEdit.title} onChange=
|
||||
{
|
||||
(e)=>
|
||||
{
|
||||
const copy = {...gameToEdit}
|
||||
copy.title = e.target.value
|
||||
setGameToEdit(copy)
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
||||
|
||||
<label for="maker">Maker</label>
|
||||
<input type="text" id="maker" value={gameToEdit.maker} onChange= {
|
||||
(e)=>
|
||||
{
|
||||
const copy = {...gameToEdit}
|
||||
copy.maker = e.target.value
|
||||
setGameToEdit(copy)
|
||||
}
|
||||
} />
|
||||
<label for="numberofplayers">Update number of players allowed</label>
|
||||
<input type="number" id="numberofplayers" value={gameToEdit.number_of_players}
|
||||
onChange={(e)=>
|
||||
{
|
||||
const copy = {...gameToEdit}
|
||||
copy.number_of_players = e.target.value
|
||||
setGameToEdit(copy)}
|
||||
}
|
||||
|
||||
/>
|
||||
<label for="skillevel">Update required skill level</label>
|
||||
<input type="number" id="skilllevel" value={gameToEdit.skill_level}
|
||||
onChange={(e)=>
|
||||
{
|
||||
const copy = {...gameToEdit}
|
||||
copy.skill_level = e.target.value
|
||||
setGameToEdit(copy)}
|
||||
}
|
||||
|
||||
/>
|
||||
<label for="gametype">Select Game</label>
|
||||
<select name="gametype" form_id="editgameform"
|
||||
/* Why is the nested information on game_type_id not returning from the API? What server side problem is causing this to be inaccessible?*/
|
||||
onChange={(e)=>
|
||||
{
|
||||
const copy = {...gameToEdit}
|
||||
copy.game_type = e.target.value
|
||||
setGameToEdit(copy)}
|
||||
}>
|
||||
|
||||
{ gametypes.map(
|
||||
(gametypes) => <option value={gametypes.id} selected={gameToEdit.game_type === gametypes.id}>{gametypes.label}</option>
|
||||
)
|
||||
}
|
||||
</select>
|
||||
|
||||
<input type="submit"
|
||||
|
||||
onClick={
|
||||
(e)=>
|
||||
{
|
||||
e.preventDefault()
|
||||
putGames(gameToEdit)
|
||||
history.push("/")
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
return(
|
||||
gameupdateform()
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user