diff --git a/package-lock.json b/package-lock.json index a57fb07..244daa8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4341,6 +4341,11 @@ "once": "^1.4.0" } }, + "enquire.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz", + "integrity": "sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ=" + }, "entities": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", @@ -8050,6 +8055,14 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, + "json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", + "requires": { + "string-convert": "^0.2.0" + } + }, "json5": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", @@ -8644,6 +8657,11 @@ "minimist": "^1.2.5" } }, + "moment": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", + "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -10633,6 +10651,14 @@ "resize-observer-polyfill": "^1.5.0" } }, + "react-reveal": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/react-reveal/-/react-reveal-1.2.2.tgz", + "integrity": "sha512-JCv3fAoU6Z+Lcd8U48bwzm4pMZ79qsedSXYwpwt6lJNtj/v5nKJYZZbw3yhaQPPgYePo3Y0NOCoYOq/jcsisuw==", + "requires": { + "prop-types": "^15.5.10" + } + }, "react-router": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", @@ -10664,6 +10690,18 @@ "tiny-warning": "^1.0.0" } }, + "react-slick": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.26.1.tgz", + "integrity": "sha512-IQVRSkikG2w5bkz+m9Ing5zZIuM9cI+qJyXG2o6PXHKj8GFcsMCJoTBADwyLSsVT8dHcZ8MZ0dsxq0i0CKIq+Q==", + "requires": { + "classnames": "^2.2.5", + "enquire.js": "^2.1.6", + "json2mq": "^0.2.0", + "lodash.debounce": "^4.0.8", + "resize-observer-polyfill": "^1.5.0" + } + }, "react-smooth": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-1.0.5.tgz", @@ -12092,6 +12130,11 @@ "xtend": "^4.0.0" } }, + "string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=" + }, "string-length": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", diff --git a/package.json b/package.json index dfada23..6079ab0 100644 --- a/package.json +++ b/package.json @@ -37,15 +37,17 @@ "axios": "^0.19.2", "bootstrap": "^4.5.0", "jquery": "^3.5.1", + "moment": "^2.26.0", "popper.js": "^1.16.1", "prop-types": "^15.7.2", - "moment": "^2.26.0", "react": "^16.13.1", "react-bootstrap": "^1.0.1", "react-dom": "^16.13.1", "react-redux": "^7.2.0", + "react-reveal": "^1.2.2", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", + "react-slick": "^0.26.1", "recharts": "^1.8.5", "redux": "^4.0.5", "redux-form": "^8.3.5", diff --git a/src/components/routes/afterAuth.js b/src/components/routes/afterAuth.js index 4c31713..e59a181 100644 --- a/src/components/routes/afterAuth.js +++ b/src/components/routes/afterAuth.js @@ -1,11 +1,13 @@ import React from 'react'; import { Switch, Route } from 'react-router-dom'; import Dashboard from '../views/dashboards/sme/sme'; +import InvestorsDashboard from '../views/dashboards/investors/index.jsx'; function smeRoutes() { return ( - + + ); } diff --git a/src/components/views/dashboards/investors/MainContents.jsx b/src/components/views/dashboards/investors/MainContents.jsx new file mode 100644 index 0000000..cc1b083 --- /dev/null +++ b/src/components/views/dashboards/investors/MainContents.jsx @@ -0,0 +1,184 @@ +import React, { Component } from 'react'; +import Slider from 'react-slick'; +import TopWidgets from './widgets/topWidgets.jsx'; +import Feeds from './widgets/investmentFeeds.jsx'; +import thumb from '../../../../static/wefinance-logo.png'; + +const details = [ + { title: 'Investments', boldText: '$2000', details: 'To Amount Invested' }, + { title: 'Returns', boldText: '$3000', details: 'Total returns' }, + { title: 'SMEs', boldText: 15, details: 'Total SMEs Invested' }, + { title: 'Widrawn', boldText: '$1000', details: 'Total Amount Withdrawn' }, + { title: 'Account', boldText: '$2000', details: 'Current Balance' }, + { title: 'Next Circle', boldText: '$1452', details: 'Amount Due Next Circle' } +]; + + +const feeds = [ + { + title: 'WeFinance Nigeria', + thumb, + feedStatus: 'Invest', + paragraph: 'Lorem ipsum dolor sit amet consectetur. Lorem ipsum dolor sit amet.', + round: 'First', + completed: '10', + pending: '5', + investors: '8', + raised: '$60,000', + needed: '$100,000', + return: 10, + Srates: 85 + }, + { + title: 'WeChat Global', + thumb, + feedStatus: 'Invested', + paragraph: 'Lorem ipsum dolor sit amet consectetur. Lorem ipsum dolor sit amet.', + round: 'Second', + completed: '20', + pending: '1', + investors: '8', + raised: '$60,000', + needed: '$100,000', + return: 10, + Srates: 85 + }, + { + title: 'FaceBook Inc', + thumb, + feedStatus: 'Invest', + paragraph: 'Lorem ipsum dolor sit amet consectetur. Lorem ipsum dolor sit amet.', + round: 'First', + completed: '10', + pending: '5', + investors: '8', + raised: '$60,000', + needed: '$100,000', + return: 10, + Srates: 85 + }, + { + title: 'Andela', + thumb, + feedStatus: 'Invest', + paragraph: 'Lorem ipsum dolor sit amet consectetur. Lorem ipsum dolor sit amet.', + round: 'First', + completed: '10', + pending: '5', + investors: '8', + raised: '$60,000', + needed: '$100,000', + return: 10, + Srates: 85 + }, + { + title: 'Glo Nigeria', + thumb, + feedStatus: 'Invested', + paragraph: 'Lorem ipsum dolor sit amet consectetur. Lorem ipsum dolor sit amet.', + round: 'First', + completed: '10', + pending: '5', + investors: '8', + raised: '$60,000', + needed: '$100,000', + return: 10, + Srates: 85 + } +]; + +// React Slick Settings +const settings = { + dots: false, + infinite: false, + speed: 500, + slidesToShow: 4, + slidesToScroll: 4, + initialSlide: 0, + responsive: [ + { + breakpoint: 1024, + settings: { + slidesToShow: 3, + slidesToScroll: 3, + infinite: true, + dots: false + } + }, + { + breakpoint: 600, + settings: { + slidesToShow: 2, + slidesToScroll: 2, + initialSlide: 2 + } + }, + { + breakpoint: 480, + settings: { + slidesToShow: 1, + slidesToScroll: 1 + } + } + ] +}; + +class MainContent extends Component { + render() { + this.name = 'Investors Dashboard'; + + return ( +
+
+ + {details.map((detail, i) => )} + +
+
+
+

Investment Opportuinities

+ { + feeds.map((feed, i) => ) + } + +
+
+ 1 +
+
+ 2 +
+
+ 3 +
+
+ 4 +
+
+ Next +
+
+
+
+ + + +
+
+
+ ); + } +} +export default MainContent; diff --git a/src/components/views/dashboards/investors/SideNav.jsx b/src/components/views/dashboards/investors/SideNav.jsx new file mode 100644 index 0000000..d1376e0 --- /dev/null +++ b/src/components/views/dashboards/investors/SideNav.jsx @@ -0,0 +1,52 @@ +import React, { Component } from 'react'; +import { Link } from 'react-router-dom'; +import avatar from '../../../../static/jd.jpg'; + +const user = { name: 'Funny Doe', avatar }; + +class SideNav extends Component { + render() { + this.name = 'sidenav'; + return ( +
+
+
+ avatar +
+
+ Welcome {user.name} +
+
+ +
+ ); + } +} + +export default SideNav; diff --git a/src/components/views/dashboards/investors/index.jsx b/src/components/views/dashboards/investors/index.jsx new file mode 100644 index 0000000..940fde5 --- /dev/null +++ b/src/components/views/dashboards/investors/index.jsx @@ -0,0 +1,18 @@ +import React, { Component } from 'react'; +import Main from './MainContents.jsx'; +import SideNav from './SideNav.jsx'; +import '../../../../styles/dashboard/investors.css'; + +class Investors extends Component { + render() { + this.name = 'investors'; + + return ( +
+ +
+
+ ); + } +} +export default Investors; diff --git a/src/components/views/dashboards/investors/widgets/investmentFeeds.jsx b/src/components/views/dashboards/investors/widgets/investmentFeeds.jsx new file mode 100644 index 0000000..5db5c34 --- /dev/null +++ b/src/components/views/dashboards/investors/widgets/investmentFeeds.jsx @@ -0,0 +1,82 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +class InvestmentFeeds extends Component { + render() { + this.name = 'feeds'; + + return ( +
+
+
+ {this.props.thumb} +
+
+

{this.props.title}

+

{this.props.paragraph}

+
+ + +
+
+
+
+
+
+

{this.props.completed} Comp. M

+
+
+
+

{this.props.pending} Pending M

+
+
+
+

{this.props.investors} Investors

+
+
+
+

{this.props.raised} Raised

+
+ +
+
+
+
+

{this.props.needed} Needed

+
+
+
+

{this.props.round} Round

+
+
+
+

{this.props.return}% Returns

+
+
+
+

{this.props.Srates}% SR

+
+
+
+
+
+ ); + } +} +InvestmentFeeds.propTypes = { + title: PropTypes.String, + thumb: PropTypes.String, + feedStatus: PropTypes.String, + paragraph: PropTypes.String, + round: PropTypes.String, + completed: PropTypes.String, + pending: PropTypes.String, + investors: PropTypes.String, + raised: PropTypes.String, + needed: PropTypes.String, + return: PropTypes.String, + Srates: PropTypes.Number + +}; + +export default InvestmentFeeds; diff --git a/src/components/views/dashboards/investors/widgets/topWidgets.jsx b/src/components/views/dashboards/investors/widgets/topWidgets.jsx new file mode 100644 index 0000000..9f82d62 --- /dev/null +++ b/src/components/views/dashboards/investors/widgets/topWidgets.jsx @@ -0,0 +1,29 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Fade from 'react-reveal/Fade'; + +class TopWidget extends Component { + render() { + this.name = 'top'; + + return ( +
+ +

{this.props.title}

+
+
+

{this.props.boldText}

+
+

{this.props.details}

+
+ ); + } +} +TopWidget.propTypes = { + title: PropTypes.String, + boldText: PropTypes.String, + details: PropTypes.String + +}; + +export default TopWidget; diff --git a/src/components/views/dashboards/sme/sme.js b/src/components/views/dashboards/sme/sme.js index ee68f2c..66bc6ed 100644 --- a/src/components/views/dashboards/sme/sme.js +++ b/src/components/views/dashboards/sme/sme.js @@ -7,11 +7,17 @@ import Transaction from './transactions'; import Investors from './investors'; import Tasks from './currentTasks'; import equity from '../../../../static/equity.svg'; +import Sidebar from '../../../navbar/sidenav'; class Sme extends Component { render() { this.name = 'sme'; return ( + <> +
+ +
+
@@ -30,6 +36,8 @@ class Sme extends Component {
+ + ); } } diff --git a/src/index.html b/src/index.html index 9ca1657..3a7b6b2 100644 --- a/src/index.html +++ b/src/index.html @@ -3,6 +3,8 @@ + + Document diff --git a/src/static/jd.jpg b/src/static/jd.jpg new file mode 100644 index 0000000..25cee9b Binary files /dev/null and b/src/static/jd.jpg differ diff --git a/src/styles/dashboard/investors.css b/src/styles/dashboard/investors.css new file mode 100644 index 0000000..7f3aafd --- /dev/null +++ b/src/styles/dashboard/investors.css @@ -0,0 +1,312 @@ +@import url('https://fonts.googleapis.com/css2?family=Gothic+A1&family=Montserrat&family=Roboto&display=swap'); + +* { + font-family: 'Roboto', sans-serif; +} + +.investor-dashboard { + display: flex; + justify-content: space-around; + width: 100%; + position: relative; +} + +.investor-dashboard > .side-nav { + width: 20%; + display: flex; + flex-direction: column; + align-items: center; + position: fixed; + left: 0; +} + +.user-section { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 2rem; +} + +.user-section > .avatar { + width: 8rem; + height: 8rem; + border-radius: 50%; + display: flex; + justify-content: center; + margin-bottom: 1rem; +} + +.feed-image > img { + width: 100%; + height: 100%; + border-radius: 5px; +} + +.user-section > .avatar img { + width: 100%; + border-radius: 50%; + box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(0, 0, 0, 0.3); +} + +.side-nav > .nav { + display: flex; + flex-direction: column; + text-align: left; + margin-top: 3rem; + width: 90%; + padding: 1rem 2rem; +} + +.side-nav > .nav > li { + padding: 1rem 0; +} + +.side-nav > .nav > li > a { + font-size: 1.6rem; + font-family: 'Roboto', sans-serif; + font-weight: 300; +} + +.investor-dashboard > .main { + display: flex; + flex-direction: column; + width: 80%; + margin: 0 auto; + position: absolute; + right: 5rem; +} + +/* .investor-dashboard > .main > .top-widget-container { + display: flex; + flex-direction: row; + justify-content: space-between; +} */ + +.top-widget { + width: 15rem; + margin: 1rem; + height: 15rem; + text-align: center; + box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(0, 0, 0, 0.3); + cursor: pointer; + border-bottom-left-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; +} + +.top-widget:hover { + box-shadow: 0 4px 4px rgba(0, 0, 0, 0.1), 0 4px 4px rgba(0, 0, 0, 0.3); +} + +.top-widget > h2 { + color: white; + background: blue; + padding: 1rem; + font-weight: 400; +} + +.top-widget > .bold > h3 { + font-weight: 600; + padding: 1rem 0; + font-size: 3rem; +} + +.top-widget > p { + font-size: 1.2rem; + margin-top: 1rem; +} + +.overview-container { + margin: 3rem auto; + width: 100%; + display: flex; + flex-direction: row; +} + +.investment-feed { + width: 85%; + display: flex; + flex-direction: column; + align-items: center; + box-shadow: 0 4px 4px rgba(0, 0, 0, 0.1), 0 4px 4px rgba(0, 0, 0, 0.3); + border-top: 1px solid rgb(209, 209, 209); + margin-top: 0.9rem; +} + +.investment-feed h2 { + padding: 2rem 0; + border-bottom: 1px solid rgb(209, 209, 209); + width: 100%; + text-align: center; + color: rgb(136, 136, 136); +} + +.feed-widget { + width: 100%; +} + +.feed-containers { + display: flex; + padding: 1rem; + height: 12rem; + margin: 1rem auto; + width: 98%; +} + +.feed-containers:hover { + box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(0, 0, 0, 0.3); +} + +.feed-image { + width: 8rem; + height: 8rem; + border-radius: 5px; + margin-right: 2rem; +} + +.dots { + width: 1rem; + height: 1rem; + border-radius: 50%; +} + +.feed-details { + width: 60%; +} + +.feed-details > p { + font-size: 1.3rem; +} + +.feed-footer { + display: flex; + flex-direction: row; + border-top: 1px solid #d8d8d8; + padding-top: 1rem; +} + +.feed-preview { + border: 1px solid #d8d8d8; + background: none; + padding: 0.6rem 1.5rem; + font-size: 1.4rem; + border-radius: 0.5rem; + color: blue; + margin-right: 2rem; +} + +.Invested { + background-color: #d8d8d8; + cursor: not-allowed; + border: none; + padding: 0.6rem 1.5rem; + font-size: 1.4rem; + border-radius: 0.5rem; +} + +.Invest { + background: blue; + color: white; + border: none; + padding: 0.6rem 1.5rem; + font-size: 1.4rem; + border-radius: 0.5rem; +} + +.Invest:hover { + color: blue; + background-color: white; + border: 1px solid blue; +} + +.feed-milestones { + width: 35%; + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.milestone-item-container { + display: flex; + flex-direction: column; + padding: 0.5rem; +} + +.milestone-item-container > div { + display: flex; + flex-direction: row; + margin: 0; + padding: 0.2rem; +} + +.milestone-item-container > div > p { + padding: 0; + margin: 0; + padding-left: 0.5rem; + font-size: 1rem; + margin-top: -0.2rem; + color: rgb(136, 136, 136); +} + +.green { + background: green; +} + +.black { + background: black; +} + +.gray { + background: gray; +} + +.orange { + background: orange; +} + +.blue { + background: blue; +} + +/* NAVIGATION FOR FEEDS */ +.footer-nav { + width: 100%; + padding: 1rem; + margin: 2rem auto; + display: flex; + flex-direction: row; + justify-content: center; +} + +.active { + background: blue; + color: white; + padding: 0.5rem 1rem; + font-size: 1.6rem; + border-radius: 5px; + font-weight: 300; + margin-right: 1rem; +} + +.inactive { + border: 1px solid blue; + color: blue; + padding: 0.5rem 1rem; + font-size: 1.6rem; + border-radius: 5px; + font-weight: 300; + margin-right: 1rem; + cursor: pointer; +} + +.inactive:hover { + background: blue; + color: white; +} + +.slick-next::before, +.slick-prev::before { + font-size: 3rem; + line-height: 1; + opacity: 0.75; + color: #858383; +}