diff --git a/package-lock.json b/package-lock.json
index cd16608..68921b2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,11 @@
"integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==",
"dev": true
},
+ "@types/node": {
+ "version": "10.5.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.4.tgz",
+ "integrity": "sha512-8TqvB0ReZWwtcd3LXq3YSrBoLyXFgBX/sBZfGye9+YS8zH7/g+i6QRIuiDmwBoTzcQ/pk89nZYTYU4c5akKkzw=="
+ },
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -4925,6 +4930,14 @@
"json-parse-better-errors": "1.0.2"
}
},
+ "parse5": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
+ "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
+ "requires": {
+ "@types/node": "10.5.4"
+ }
+ },
"parseurl": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
@@ -5853,6 +5866,11 @@
"prop-types": "15.6.2"
}
},
+ "react-attr-converter": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/react-attr-converter/-/react-attr-converter-0.3.1.tgz",
+ "integrity": "sha512-dSxo2Mn6Zx4HajeCeQNLefwEO4kNtV/0E682R1+ZTyFRPqxDa5zYb5qM/ocqw9Bxr/kFQO0IUiqdV7wdHw+Cdg=="
+ },
"react-dom": {
"version": "16.4.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.4.1.tgz",
@@ -5864,6 +5882,15 @@
"prop-types": "15.6.2"
}
},
+ "react-render-html": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/react-render-html/-/react-render-html-0.6.0.tgz",
+ "integrity": "sha512-F9Xn8Iy2oJvepMdDrN+XUPOwqv3ni856ikuvu/dyJ2guozN01vF0C55Ja+CQfnziQNlLevSVXzuQKYa/mhyjAQ==",
+ "requires": {
+ "parse5": "3.0.3",
+ "react-attr-converter": "0.3.1"
+ }
+ },
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
diff --git a/package.json b/package.json
index e975d47..3903f39 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"axios": "^0.18.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
+ "react-render-html": "^0.6.0",
"vex-js": "^4.1.0"
},
"devDependencies": {
diff --git a/src/app/PawnedListItem.css b/src/app/PawnedListItem.css
new file mode 100644
index 0000000..fdcaaf3
--- /dev/null
+++ b/src/app/PawnedListItem.css
@@ -0,0 +1,18 @@
+
+.breach-name {
+ font-size: 19px;
+ color: red;
+ font-weight: bold;
+}
+
+
+.breach-description a{
+ color: #565656;
+ font-weight: bold;
+}
+
+
+
+.breach {
+ padding-bottom: 10px;
+}
diff --git a/src/app/PawnedListItem.js b/src/app/PawnedListItem.js
index cf275e1..da537fd 100644
--- a/src/app/PawnedListItem.js
+++ b/src/app/PawnedListItem.js
@@ -1,16 +1,23 @@
-import React,{Component} from 'react';
+import React, { Component } from 'react';
+import renderHTML from 'react-render-html';
+import './PawnedListItem.css';
+export default class PawnedListItem extends Component {
-export default class PawnedListItem extends Component{
-
- constructor(props){
+ constructor(props) {
super(props);
}
- render(){
- return(
-
- {this.props.breach.Description}
-
+ render() {
+ return (
+
+
+ {this.props.breach.Domain}
+
+
+ {renderHTML(this.props.breach.Description)}
+
+
+
)
}
}
\ No newline at end of file
diff --git a/src/app/SearchField.css b/src/app/SearchField.css
new file mode 100644
index 0000000..72cf5aa
--- /dev/null
+++ b/src/app/SearchField.css
@@ -0,0 +1,75 @@
+.searchWrapper{
+ display: flex;
+ width: 500px;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column
+}
+
+.search{
+
+}
+
+.title{
+ font-size: 45px;
+}
+
+.check-button{
+ height: 52px;
+ padding-bottom: 7px;
+ margin-left: 11px;
+}
+
+.display-message{
+ padding-top: 13px;
+}
+
+.safe-message{
+ color: green;
+}
+
+.not-safe-message{
+ color: #ff4a4a;
+}
+
+.searchResults {
+ padding-top: 21px;
+ max-height: 400px;
+ overflow: auto;
+ margin: 0 .4rem;
+}
+
+.searchResults div{margin: 5px 0}
+
+.search .email-field{
+ border: 1px solid #000;
+ height: 46px;
+ width: 375px;
+ font-family: RMTyperighter;
+ font-size: 18px;
+ padding: 3px;
+}
+
+.hover-field {
+ text-decoration: none
+}
+.hover-field:hover {
+ position: relative
+}
+.hover-field span {
+ display: none;
+ font-size: 12px;
+ color: #000;
+}
+.hover-field:hover span {
+ border: #8f8e8e 1px solid;
+ padding: 5px 20px 5px 5px;
+ display: block;
+ z-index: 100;
+ left: -6px;
+ margin: 10px;
+ width: 250px;
+ position: absolute;
+ top: -46px;
+ text-decoration: none;
+}
\ No newline at end of file
diff --git a/src/app/SearchField.js b/src/app/SearchField.js
index 2a43cd3..9fb5a01 100644
--- a/src/app/SearchField.js
+++ b/src/app/SearchField.js
@@ -1,6 +1,7 @@
import React, { Component } from 'react';
import axios from 'axios';
import PawnedListItem from './PawnedListItem';
+import './SearchField.css';
export default class SearchField extends Component {
@@ -8,34 +9,48 @@ export default class SearchField extends Component {
super(props);
this.state = {
isPawnedEmail: '',
- pawnedList: []
+ pawnedList: [],
+ intiated: false,
+ displayMessage: '',
+ displayMessageStyle: ''
};
this.onFocus = this.onFocus.bind(this);
this.onBlur = this.onBlur.bind(this);
this.checkIsPawned = this.checkIsPawned.bind(this);
- this.videoItems = [];
+ this.breachItems = [];
+ this.displayMessage;
}
render() {
if (this.state.pawnedList.length > 0) {
- this.videoItems = this.state.pawnedList.map((breach) => {
+ this.breachItems = this.state.pawnedList.map((breach) => {
return
});
+ } else {
+ this.breachItems = [];
}
return (
-
+
-
this.setState({ isPawnedEmail: event.target.value })} required onFocus={this.onFocus} onBlur={this.onBlur} />
-
+
{ if (event.key == 'Enter') this.checkIsPawned.call() }} onChange={(event) => this.setState({ isPawnedEmail: event.target.value })} required onFocus={this.onFocus} onBlur={this.onBlur} />
+
+
+
+ {this.state.displayMessage}
- {this.videoItems}
+ {this.breachItems}
);
@@ -55,17 +70,29 @@ export default class SearchField extends Component {
checkIsPawned() {
// axios.get()
+ this.setState({
+ intiated: true
+ });
console.log(this.state.isPawnedEmail)
axios({
method: 'get',
url: `https://haveibeenpwned.com/api/v2/breachedaccount/${this.state.isPawnedEmail}`
}).then((response) => {
- console.log(response);
+ const breachList = response.data;
this.setState({
- pawnedList: response.data
- })
+ pawnedList: response.data,
+ displayMessage: `Your email address is Pawned on ${breachList.length} websites`,
+ displayMessageStyle: 'not-safe-message'
+ });
}).catch((error) => {
console.log('Error ', error);
+ if (error.response.status === 404) {
+ this.setState({
+ displayMessage: `You are safe now.`,
+ displayMessageStyle: 'safe-message',
+ pawnedList: []
+ });
+ }
})
}
}
\ No newline at end of file
diff --git a/src/css/style.css b/src/css/style.css
index 1c549f4..4edbd94 100644
--- a/src/css/style.css
+++ b/src/css/style.css
@@ -48,38 +48,3 @@ footer,header {
padding: .75em 2em;
cursor: pointer;
}
-.searchWrapper{
- display: flex;
- width: 500px;
- justify-content: center;
- align-items: center;
- flex-direction: column
-}
-.search{
-
-}
-.searchResults {
- padding-top: 21px;
- max-height: 400px;
- overflow: auto;
- margin: 0 .4rem;
-}
-.searchResults div{margin: 5px 0}
-.search .email-field{
- border: 1px solid #000;
- height: 46px;
- width: 375px;
- font-family: RMTyperighter;
- font-size: 18px;
- padding: 3px;
-}
-
-.check-button{
- height: 52px;
- padding-bottom: 7px;
- margin-left: 11px;
-}
-
-.title{
- font-size: 45px;
-}
\ No newline at end of file