Skip to content

Commit

Permalink
Kanban app first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jcastano-xk committed Mar 14, 2017
1 parent 298cb88 commit 1d5d950
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 108 deletions.
43 changes: 32 additions & 11 deletions app/CardForm.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import React, {Component, PropTypes} from 'react'

export default class CardForm from Component {
export default class CardForm extends Component {
handleChange(field, e){
this.props.handleChange(field, e.target.value)
}
Expand All @@ -15,15 +15,9 @@ export default class CardForm from Component {
<div>
<div className="Card big">
<form onsubmit={this.props.handleSubmit.bind(this)}>
<input
type="text"
value={this.props.draftCard.title}
onChange={this.handleChange.bnid(this, 'title')}
placeholder="Title"
requried={true} />
<textarea
value={this.props.draftCard.description}>
onChange={thi.handleChange.bind(this, 'description')}
<input type="text" value={this.props.draftCard.title} onChange={this.handleChange.bind(this, 'title')} placeholder="Title" requried={true} />
<textarea value={this.props.draftCard.description}
onChange={this.handleChange.bind(this, 'description')}
placeholder="Description"
required={true} />
<label htmlFor="status">Status</label>
Expand All @@ -34,9 +28,36 @@ export default class CardForm from Component {
<option value="in progress">In Progress</option>
<option value="done">Done</option>
</select>
<br />
<label htmlFor="color">Color</label>
<input id="color"
value={this.props.draftCard.color}
onChange={this.handleChange.bind(this, 'color')}
type="color"
defaultValue="#ff0000" />
<div className="Actions">
<button type="submit">{this.props.buttonLabel}</button>
</div>
</form>
</div>
<div className="overlay" onClick={this.handleClose.bind(this)}>
</div>
</div>
)
}
}


CardForm.propTypes = {
buttonLabel: PropTypes.string.isRequired,
draftCard: PropTypes.shape({
title: PropTypes.string,
description: PropTypes.string,
status: PropTypes.string,
color: PropTypes.string
}).isRequired,
handleChange: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
handleClose: PropTypes.func.isRequired

}
41 changes: 41 additions & 0 deletions app/EditCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, {Component, PropTypes} from 'react'
import CardForm from './CardForm'

export default class EditCard extends Component {
componentWillMount() {
let card = this.props.cards.find((card) => card.id === this.props.params.card_id)
this.setState(...card)
}


handleChange(field, value) {
this.setState({[field]: value})
}

handleSubmit(e) {
e.preventDeault();
this.props.cardCallbacks.updateCard(this.state)
this.props.history.pushState(null, '/')
}

handelClose() {
this.props.history.pushState(null, '/')
}


render() {
return (
<CardForm
draftCard={this.state}
buttonLabel="Edit Card"
handleChange={this.handleChange.bind(this)}
handleSubmit={this.handleSubmit.bind(this)}
handleClose={this.handleClose.bind(this)}
/>
)
}
}

EditCard.propTypes = {
cardCallbacks: PropTypes.object
}
6 changes: 5 additions & 1 deletion app/KanbanBoard.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import List from './List';
// and they way to get them is via refs or onSubmit
class KanbanBoard extends Component {
render() {

let cardModal = this.props.children && React.cloneElement(this.props.children, {
cards: this.props.cards,
cardCallbacks: this.props.cardCallbacks
})
return (
<div className="App">
<List
Expand All @@ -38,6 +41,7 @@ class KanbanBoard extends Component {
title="Done"
cards={ this.props.cards.filter((card) => card.status === "done")}>
</List>
{cardModal}
</div>
);
}
Expand Down
92 changes: 79 additions & 13 deletions app/KanbanBoardContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,20 +198,86 @@ export default class KanbanBoardContainer extends Component {
})
}

render() {
addCard(card) {
let prevState = this.state;
if(card.id === null) {
let card = Object.assign({}, card, {id: Date.now()})
}

let nextState = update(this.state.cards, {$push: [card]})

this.setState({cards: nextState})

fetch(`${API_URL}/cards`, {
method: 'post',
headers: API_HEADERS,
body: JSON.stringify(card)
})
.then((response) => {
if(response.ok) {
return response.json()
}
else {
throw new Error("Server reponse wasnt ok on adding card")
}
})
.then((responseData) =>{
card.id = responseData.id
this.setState({cards: nextState})
})
.catch((error) => {
this.setState(prevState)
})
}

updateCard(card) {
let prevState = this.state;

let cardIndex = this.state.cards.findIndex((c) => c.id === card.id)

let nextState = update(this.state.cards, {
[cardIndex]: {$set: card}
})

this.setState({cards:nextState})

return <KanbanBoard
cards={this.state.cards}
tasksCallbacks={{
toggle: this.toggleTask.bind(this),
delete: this.deleteTask.bind(this),
add: this.addTask.bind(this),
}}
cardCallbacks={{
updateStatus: this.updateCardStatus,
updatePosition: this.updateCardPosition,
persistCardDrag: this.persistCardDrag.bind(this)
}}/>
fetch(`${API_URL}/cards/${card.id}`, {
method: 'put',
headers: API_HEADERS,
body: JSON.stringify(card)
})
.then((response) => {
if(response.ok) {
return response.json()
}
else {
throw new Error("Server reponse wasnt ok on updating card")
}
})
.catch((error) => {
console.error("Fetch error: ", error);
this.setState(prevState)
})

}

render() {
let kanbanBoard = this.props.children && React.cloneElement(this.props.children, {
cards: this.state.cards,
tasksCallbacks: {
toggle: this.toggleTask.bind(this),
delete: this.deleteTask.bind(this),
add: this.addTask.bind(this),
},
cardCallbacks: {
addCard: this.addCard.bind(this),
updateCard: this.updateCard.bind(this),
updateStatus: this.updateCardStatus,
updatePosition: this.updateCardPosition,
persistCardDrag: this.persistCardDrag.bind(this)
}
})
return kanbanBoard
}

}
47 changes: 47 additions & 0 deletions app/NewCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, {Component, PropTypes} from 'react'
import CardForm from './CardForm'

export default class NewCard extends Component {
componentWillMount() {
this.setState({
id: Date.now(),
title: '',
description: '',
status: 'todo',
colors: '#c9c9c9',
tasks: []
})
}


handleChange(field, value) {
this.setState({[field]: value})
}

handleSubmit(e) {
e.preventDeault();
this.props.cardCallbacks.addCard(this.state)
this.props.history.pushState(null, '/')
}

handleClose() {
this.props.history.pushState(null, '/')
}


render() {
return (
<CardForm
draftCard={this.state}
buttonLabel="Create Card"
handleChange={this.handleChange.bind(this)}
handleSubmit={this.handleSubmit.bind(this)}
handleClose={this.handleClose.bind(this)}
/>
)
}
}

NewCard.propTypes = {
cardCallbacks: PropTypes.object
}
54 changes: 54 additions & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,60 @@
transition: max-height .25s ease-out;
}

.overlay {
position: absolute;
width: 100%;
height: 100%;
top: 0; left: 0; bottom: 0;right: 0;
z-index: 2;
background-color: rgba(0, 0, 0 , 0.6);
}

.Card.big {
position: absolute;
width: 450px;
height: 200px;
margin: auto;
padding: 15px;
top: 0; left:0; bottom: 100px; right: 0;
z-index: 3;
}

.Card.big input[type="text"], textarea {
width: 100%;
margin: 3px 0;
font-size: 13px;
border: none;
}

.Card.big input[type="text"] {
font-size: 12px;
font-weight: bold;
}

.Card.big input[type="text"]:focus,
.Card.big textarea:focus {
outline: dashed thin #999;
outline-offset: 2px;
}

.Card.big label {
margin: 3px 0 7px 3px;
color: #a7a7a7;
display: inline-block;
width: 60px;
}

.Actions {
margin-top: 10px;
text-align: right;
}

.Card.big button {
font-size: 14px;
padding: 8px;
}

/*input {
padding: 5px;
width: 120px;
Expand Down
Loading

0 comments on commit 1d5d950

Please sign in to comment.