diff --git a/package-lock.json b/package-lock.json index e097712..8ba5f04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@testing-library/user-event": "^12.1.10", "antd": "^4.7.3", "axios": "^0.21.1", + "emailjs-com": "^3.1.0", "jsdoc": "^3.6.7", "react": "^17.0.1", "react-dom": "^17.0.1", @@ -6024,6 +6025,11 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" }, + "node_modules/emailjs-com": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/emailjs-com/-/emailjs-com-3.1.0.tgz", + "integrity": "sha512-e6rs1F2wTl4vrsTXNNCUPK5cFfuPXYcKJlZgPtsThOidIp5dbgNS5SUrpnP3qxt9p5Om0lkFCVkmBi1a6hQFnw==" + }, "node_modules/emittery": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", @@ -25447,6 +25453,11 @@ } } }, + "emailjs-com": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/emailjs-com/-/emailjs-com-3.1.0.tgz", + "integrity": "sha512-e6rs1F2wTl4vrsTXNNCUPK5cFfuPXYcKJlZgPtsThOidIp5dbgNS5SUrpnP3qxt9p5Om0lkFCVkmBi1a6hQFnw==" + }, "emittery": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", diff --git a/package.json b/package.json index b569e58..efd5aea 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@testing-library/user-event": "^12.1.10", "antd": "^4.7.3", "axios": "^0.21.1", + "emailjs-com": "^3.1.0", "jsdoc": "^3.6.7", "react": "^17.0.1", "react-dom": "^17.0.1", diff --git a/src/App.js b/src/App.js index 770e080..ee393ac 100644 --- a/src/App.js +++ b/src/App.js @@ -19,7 +19,6 @@ import UserContext from './contexts/user'; const { Header, Content, Footer } = Layout; - /** * @constructor App * Makes requests to the backend to see if the user is logged in and also processes the logout diff --git a/src/components/account.js b/src/components/account.js index 332510d..5d63e7f 100644 --- a/src/components/account.js +++ b/src/components/account.js @@ -2,6 +2,7 @@ import React from 'react'; import UserContext from '../contexts/user'; import { Image } from 'antd' import {useContext} from 'react'; +import ApplicationGrid from './applicationgrid'; /** * @function @@ -44,10 +45,11 @@ function Account(props) { return ( <>

Account

- avatarURL +

Username: {user.username}

Email: {user.email}

{Object.keys(profile).map(key =>
  • {key}: {profile[key]}
  • )} + ); } diff --git a/src/components/admin.js b/src/components/admin.js index dcc2bc1..ae5089a 100644 --- a/src/components/admin.js +++ b/src/components/admin.js @@ -4,8 +4,6 @@ import HomeGrid from './homegrid'; import { Image } from 'antd' import Icon from './icon.png'; -const { Search } = Input; - /** * @function * @name Admin @@ -14,21 +12,6 @@ const { Search } = Input; * @returns {object} Page Structure */ function Admin(props) { - - const [search, setSearch] = useState(undefined); - - /** - * @function - * @name searchHandler - * Function to handle the search query - * @param {object} value - Query for the search - * @returns {object} Output from the search -*/ - function searchHandler(value) { - console.log("setting query") - setSearch(value) - } - return (
    @@ -36,13 +19,8 @@ function Admin(props) { -
    - +
    ); } diff --git a/src/components/applicationgrid.js b/src/components/applicationgrid.js new file mode 100644 index 0000000..176dbe1 --- /dev/null +++ b/src/components/applicationgrid.js @@ -0,0 +1,68 @@ +import React from 'react'; +import { withRouter } from "react-router"; +import { status, json } from '../utilities/requestHandlers'; +import { Typography, Space, Button, List, Col, Row } from 'antd'; +import UserContext from '../contexts/user'; +import ApplicationItem from './applicationitem'; + +const { Title } = Typography; + +class ApplicationGrid extends React.Component { + + static contextType = UserContext; + + constructor(props) { + super(props); + this.state = { + applications: [] + } + } + + componentDidMount() { + const id = this.context.user.ID; + const username = this.context.user.username + const password = this.context.user.password + fetch(`https://animal-hello-3000.codio-box.uk/api/v1/applications/account/${id}`, { + method: 'GET', + headers: { + "Authorization": "Basic " + btoa(username + ":" + password) + }, + }) + .then(status) + .then(json) + .then(application => { + this.setState({applications:application}) + }) + .catch(err => { + console.log(`Fetch error for application ${id}`) + }); + }; + + render() { + if (!this.state.applications.length) { + if(!this.state.found){ + return

    No applications found

    + } else { + return

    Loading applications...

    + } + } + const allApplications = this.state.applications.map(application => { + return ( +
    + + + +
    + ) + }); + + return( + <> + {allApplications} + + ); + } +} + +export default ApplicationGrid; \ No newline at end of file diff --git a/src/components/applicationitem.js b/src/components/applicationitem.js new file mode 100644 index 0000000..fbddc4d --- /dev/null +++ b/src/components/applicationitem.js @@ -0,0 +1,34 @@ +import React from 'react'; +import { List } from 'antd'; +import {Link} from "react-router-dom"; + +class ApplicationItem extends React.Component { + + render() { + + return( + View]}> + {this.props.companyName}} + description='Congratulations this application has been approved.' + /> +
    {this.props.ID}, {this.props.userID}
    +
    + ); + return( + View]}> + {this.props.companyName}} + description='This application is pending approval.' + /> +
    {this.props.dateCreated}
    +
    + ); + } + + +} + +export default ApplicationItem; \ No newline at end of file diff --git a/src/components/applicationsForUsers.js b/src/components/applicationsForUsers.js index d84760a..a51ecd1 100644 --- a/src/components/applicationsForUsers.js +++ b/src/components/applicationsForUsers.js @@ -5,9 +5,6 @@ import { status, json } from '../utilities/requestHandlers'; import UserContext from '../contexts/user'; -window.$name = "" - - const { Title, Paragraph } = Typography; class ApplicationForUsers extends React.Component { diff --git a/src/components/homegrid.js b/src/components/homegrid.js index 9c520c9..590f4db 100644 --- a/src/components/homegrid.js +++ b/src/components/homegrid.js @@ -1,5 +1,5 @@ import React from 'react'; -import { Col, Row } from 'antd'; +import { Col, Row, Input } from 'antd'; import ApplicationCard from './applicationcard'; import { status, json } from '../utilities/requestHandlers'; import { withRouter } from 'react-router-dom'; @@ -13,7 +13,8 @@ class HomeGrid extends React.Component { constructor(props) { super(props); this.state = { - applications: [] + applications: [], + search:{} } } @@ -44,8 +45,22 @@ class HomeGrid extends React.Component { }); } -/** Renders the page using Application Card */ +/** + * @function + * @name searchHandler + * Function to handle the search query + * @param {object} value - Query for the search + * @returns {object} Output from the search +*/ + searchHandler = value => { + console.log(value) + this.setState({search:value}) + } + +/** Renders the page using Application Card and filters the search query */ render() { + const { Search } = Input; + if (!this.context.user.loggedIn) { return (

    Login first in order to see applications!

    @@ -54,23 +69,54 @@ class HomeGrid extends React.Component { return (

    You have to be a user in order to see applications!

    ) - }else { - const applicationList = this.state.applications.map(application => { + }if(this.state.search.length){ + const searchedApplication = this.state.applications.filter(application=>application.companyName.toLowerCase() === this.state.search.toLowerCase() || application.crn.toLowerCase() === this.state.search || application.email.toLowerCase() === this.state.search.toLowerCase()).map(application => { + return ( +
    + + + +
    + ) + }); + return ( +
    + + + {searchedApplication} + +
    + ); + }else{ + const allApplications = this.state.applications.map(application => { + return ( +
    + + + +
    + ) + }); return ( -
    - - - +
    +
    + +
    + + {allApplications} +
    - ) - }); - return ( - - {applicationList} - - ); + ); + } } } -} export default withRouter(HomeGrid); diff --git a/src/components/nav.js b/src/components/nav.js index 921a10c..d6fbdf6 100644 --- a/src/components/nav.js +++ b/src/components/nav.js @@ -25,6 +25,7 @@ class Nav extends React.Component { }if (this.context.user.role!="admin") { return( + Home My Application Add Application Account diff --git a/src/components/newApplication.js b/src/components/newApplication.js index 3791a3a..f93b636 100644 --- a/src/components/newApplication.js +++ b/src/components/newApplication.js @@ -3,13 +3,14 @@ import { status, json } from '../utilities/requestHandlers'; import { Form, Input, Button, Typography, DatePicker } from 'antd'; import UserContext from '../contexts/user'; import { Link } from "react-router-dom"; +import emailjs from 'emailjs-com'; const { Title } = Typography; const { TextArea } = Input const nameRule=[ - {required:true,message:'Please type the name of the compnay.',whitespace:false, min:5,max:150} + {required:true,message:'Please type the name of the compnay.',whitespace:false, min:3,max:150} ] const crnRule=[ {required:true, message:'Please a valid company reference number.',whitespace:false, min:8,max:8} @@ -44,10 +45,29 @@ class NewApplication extends React.Component { constructor(props) { super(props); this.onFinish = this.onFinish.bind(this) + this.handleSubmit = this.handleSubmit.bind(this) } state = {redirect: null} + handleSubmit = (values) => { //Fix this to send the email!! + values.preventDefault(); // prevent reload + + var formData = new FormData(this); + formData.append('gmail'); + formData.append('template_tld'); + formData.append('user_4pQL25dW7YNzoZmVCML9j'); + + fetch('https://api.emailjs.com/api/v1.0/email/send', { + method: 'POST', + body: JSON.stringify(formData) + }).then(data => { + alert('Your mail is sent!'); + }).catch(err => { + alert('Oops... ' + JSON.stringify(err)); + }); + } + onFinish = (values) => { const {confirm, ...data} = values; fetch('https://animal-hello-3000.codio-box.uk/api/v1/applications', { @@ -66,6 +86,7 @@ class NewApplication extends React.Component { this.setState({redirect:`/myapplication/${this.context.user.id}`}); }) .catch(err => { + console.log(err) alert("Error occurred, try again!") }) } @@ -83,12 +104,12 @@ class NewApplication extends React.Component { }else { return ( -
    +

    Application Form

    -