@@ -2332,6 +2332,15 @@ | |||
"@types/react": "*" | |||
} | |||
}, | |||
"@types/react-modal": { | |||
"version": "3.12.0", | |||
"resolved": "https://registry.npmjs.org/@types/react-modal/-/react-modal-3.12.0.tgz", | |||
"integrity": "sha512-UnHu/YO73NZLwqFpju/c0tqiswR0UHIfeO16rkfLVJUIMfQsl7X0CBm99H5XXgBMe/PgtQ/Rkud72iuRBr1TeA==", | |||
"dev": true, | |||
"requires": { | |||
"@types/react": "*" | |||
} | |||
}, | |||
"@types/resolve": { | |||
"version": "0.0.8", | |||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", | |||
@@ -6148,6 +6157,11 @@ | |||
"strip-eof": "^1.0.0" | |||
} | |||
}, | |||
"exenv": { | |||
"version": "1.2.2", | |||
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", | |||
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" | |||
}, | |||
"exit": { | |||
"version": "0.1.2", | |||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", | |||
@@ -12436,6 +12450,22 @@ | |||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", | |||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" | |||
}, | |||
"react-lifecycles-compat": { | |||
"version": "3.0.4", | |||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", | |||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" | |||
}, | |||
"react-modal": { | |||
"version": "3.13.1", | |||
"resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.13.1.tgz", | |||
"integrity": "sha512-m6yXK7I4YKssQnsjHK7xITSXy2O81BSOHOsg0/uWAsdKtuT9HF2tdoYhRuxNNQg2V+LgepsoHUPJKS8m6no+eg==", | |||
"requires": { | |||
"exenv": "^1.2.0", | |||
"prop-types": "^15.5.10", | |||
"react-lifecycles-compat": "^3.0.0", | |||
"warning": "^4.0.3" | |||
} | |||
}, | |||
"react-refresh": { | |||
"version": "0.8.3", | |||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", | |||
@@ -15054,6 +15084,14 @@ | |||
"makeerror": "1.0.x" | |||
} | |||
}, | |||
"warning": { | |||
"version": "4.0.3", | |||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", | |||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", | |||
"requires": { | |||
"loose-envify": "^1.0.0" | |||
} | |||
}, | |||
"watchpack": { | |||
"version": "1.7.5", | |||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", | |||
@@ -12,6 +12,7 @@ | |||
"@types/react-dom": "^17.0.3", | |||
"react": "^17.0.2", | |||
"react-dom": "^17.0.2", | |||
"react-modal": "^3.13.1", | |||
"react-scripts": "4.0.3", | |||
"typescript": "^4.2.4", | |||
"web-vitals": "^1.1.1" | |||
@@ -39,5 +40,8 @@ | |||
"last 1 firefox version", | |||
"last 1 safari version" | |||
] | |||
}, | |||
"devDependencies": { | |||
"@types/react-modal": "^3.12.0" | |||
} | |||
} |
@@ -4,6 +4,12 @@ import "./App.css"; | |||
import Header from "./components/Header"; | |||
import Task from "./types/Task"; | |||
type TaskPassback = { | |||
title: string; | |||
description: string; | |||
priority: "normal" | "important" | "urgent"; | |||
} | |||
type Column = { | |||
id: number; | |||
name: string; | |||
@@ -61,16 +67,25 @@ class App extends React.Component<{}, State> { | |||
}); | |||
} | |||
addTask() { | |||
addTask(taskInstance? :TaskPassback) { | |||
if (this.state.columns.length > 0) { | |||
let taskId = this.state.taskIterator; | |||
this.setState({ taskIterator: taskId + 1 }); | |||
this.state.columns[0].tasks.push({ | |||
id: taskId, | |||
title: "Task " + taskId, | |||
description: "foo", | |||
priority: "normal", | |||
}); | |||
if (taskInstance !== undefined){ | |||
this.setState({ taskIterator: taskId + 1 }); | |||
this.state.columns[0].tasks.push({ | |||
id: taskId, | |||
title: taskInstance.title, | |||
description: taskInstance.description, | |||
priority: taskInstance.priority | |||
}); | |||
} | |||
} | |||
else{ | |||
alert("You might want to consider adding a column!") | |||
@@ -1,11 +1,76 @@ | |||
import * as react from "react"; | |||
import React from "react"; | |||
import Modal from "./Modal" | |||
import { Component } from 'react'; | |||
type TaskPassback = { | |||
title: string; | |||
description: string; | |||
priority: priority; | |||
} | |||
type priority = "normal" | "important" | "urgent"; | |||
type HeaderProps = { | |||
addColumn: () => void; | |||
addTask: () => void; | |||
addTask: (taskInstance?: TaskPassback) => void; | |||
}; | |||
type State = { | |||
show: boolean | |||
titleVar: string, | |||
descVar: string, | |||
prioVar: 'normal'|'important'|'urgent', | |||
}; | |||
class Header extends React.Component<HeaderProps, State>{ | |||
constructor(props: HeaderProps) { | |||
super(props); | |||
this.showModal = this.showModal.bind(this); | |||
this.hideModal = this.hideModal.bind(this); | |||
this.handleInputChange = this.handleInputChange.bind(this); | |||
this.state = { | |||
show: false, | |||
titleVar: "", | |||
descVar: "", | |||
prioVar: 'normal' | |||
}; | |||
} | |||
showModal = () => { | |||
this.setState({ show: true }); | |||
}; | |||
hideModal = () => { | |||
this.setState({ show: false }); | |||
}; | |||
const Header = (props: HeaderProps) => { | |||
handleInputChange(event: React.ChangeEvent<HTMLInputElement>) { | |||
const target = event.target.id | |||
if (target === "titleInput"){ | |||
let hold = this.state.titleVar | |||
this.setState({titleVar: event.target.value}) | |||
} | |||
if (target === "descInput"){ | |||
let hold = this.state.descVar | |||
this.setState({descVar: event.target.value}) | |||
} | |||
} | |||
handleSelectChange(event: React.ChangeEvent<HTMLSelectElement>){ | |||
event.target.value === 'normal' ? this.setState({prioVar: 'normal'}) | |||
: event.target.value === 'important' ? this.setState({prioVar: 'important'}) | |||
: this.setState({prioVar: 'urgent'}) | |||
} | |||
render(){ | |||
return ( | |||
<div className="header" style={{ height: 60 }}> | |||
<h1 | |||
style={{ | |||
@@ -16,10 +81,38 @@ const Header = (props: HeaderProps) => { | |||
}} | |||
> | |||
Kango Bango | |||
</h1> | |||
<button onClick={props.addTask}> Add task </button> | |||
<button onClick={props.addColumn}> Add column </button> | |||
</h1> | |||
<Modal show={this.state.show} handleClose={this.hideModal}> | |||
<label> Title: | |||
<input type="text" id="titleInput" value={this.state.titleVar} onChange={this.handleInputChange} /> | |||
</label> | |||
<br/> | |||
<label> Description: | |||
<input type="text" id='descInput' value={this.state.descVar} onChange={this.handleInputChange} /> | |||
</label> | |||
<br/> | |||
<label> Priority: | |||
<select value={this.state.prioVar} onChange={this.handleSelectChange}> | |||
<option value='normal'>Normal</option> | |||
<option value='important'>Important</option> | |||
<option value='urgent'>Urgent</option> | |||
</select> | |||
</label> | |||
<button onClick={() => this.props.addTask({title: this.state.titleVar, description: this.state.descVar, priority: this.state.prioVar})}> AHHHHH </button> | |||
</Modal> | |||
<button onClick={this.showModal}> Add task </button> | |||
<button onClick={this.props.addColumn}> Add column </button> | |||
</div> | |||
); | |||
}; | |||
} | |||
export default Header; |
@@ -0,0 +1,24 @@ | |||
import './modal.css'; | |||
type ModalProps = { | |||
handleClose: () => void, | |||
show: boolean, | |||
children: any | |||
} | |||
const Modal = ( props: ModalProps ) => { | |||
const showHideClassName = props.show ? "modal display-block" : "modal display-none"; | |||
return ( | |||
<div className={showHideClassName}> | |||
<section className="modal-main"> | |||
{props.children} | |||
<button type="button" onClick={props.handleClose}> | |||
Close | |||
</button> | |||
</section> | |||
</div> | |||
); | |||
}; | |||
export default Modal; |
@@ -0,0 +1,26 @@ | |||
.modal { | |||
position: fixed; | |||
top: 0; | |||
left: 0; | |||
width:100%; | |||
height: 100%; | |||
background: rgba(0, 0, 0, 0.6); | |||
} | |||
.modal-main { | |||
position:fixed; | |||
background: white; | |||
width: 80%; | |||
height: auto; | |||
top:50%; | |||
left:50%; | |||
transform: translate(-50%,-50%); | |||
} | |||
.display-block { | |||
display: block; | |||
} | |||
.display-none { | |||
display: none; | |||
} |