diff --git a/src/components/App.jsx b/src/components/App.jsx
index ce3f3bf..2711529 100644
--- a/src/components/App.jsx
+++ b/src/components/App.jsx
@@ -1,16 +1,25 @@
+import { Profile } from './Profile/Profile';
+import user from '../data/user.json';
+import { Statistics } from './Statistics/Statistics';
+import data from '../data/data.json';
+import { FriendList } from './FriendList/FriendList';
+import friends from '../data/friends.json';
+import { TransactionHistory } from './TransactionHistory/TransactionHistory';
+import transactions from '../data/transactions.json';
+
export const App = () => {
return (
-
- React homework template
-
+ <>
+
+
+
+
+ >
);
};
diff --git a/src/components/FriendList/FriendList.jsx b/src/components/FriendList/FriendList.jsx
new file mode 100644
index 0000000..7d46f6a
--- /dev/null
+++ b/src/components/FriendList/FriendList.jsx
@@ -0,0 +1,26 @@
+import PropTypes from 'prop-types';
+import { FriendListItem } from 'components/FriendListItem/FriendListItem';
+import css from './FriendList.module.css';
+
+export const FriendList = ({ friends }) => {
+ return (
+
+ {friends.map(({ avatar, name, isOnline, id }) => (
+
+ ))}
+
+ );
+};
+
+FriendList.propTypes = {
+ friends: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.number.isRequired,
+ })
+ ).isRequired,
+};
diff --git a/src/components/FriendList/FriendList.module.css b/src/components/FriendList/FriendList.module.css
new file mode 100644
index 0000000..8a38e14
--- /dev/null
+++ b/src/components/FriendList/FriendList.module.css
@@ -0,0 +1,11 @@
+.friendList {
+ display: flex;
+ width: 350px;
+ flex-direction: column;
+ margin: 0 auto;
+ list-style-type: none;
+ padding: 0;
+ padding-top: 30px;
+ padding-bottom: 30px;
+ border-radius: 10px;
+}
diff --git a/src/components/FriendListItem/FriendListItem.jsx b/src/components/FriendListItem/FriendListItem.jsx
new file mode 100644
index 0000000..91cfe7c
--- /dev/null
+++ b/src/components/FriendListItem/FriendListItem.jsx
@@ -0,0 +1,18 @@
+import css from './FriendListItem.module.css';
+import PropTypes from 'prop-types';
+
+export const FriendListItem = ({ avatar, name, isOnline }) => {
+ return (
+
+
+
+ {name}
+
+ );
+};
+
+FriendListItem.propTypes = {
+ avatar: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ isOnline: PropTypes.bool.isRequired,
+};
diff --git a/src/components/FriendListItem/FriendListItem.module.css b/src/components/FriendListItem/FriendListItem.module.css
new file mode 100644
index 0000000..79a0fab
--- /dev/null
+++ b/src/components/FriendListItem/FriendListItem.module.css
@@ -0,0 +1,28 @@
+.friendListItem {
+ padding: 15px 30px;
+ margin-bottom: 15px;
+ display: flex;
+ align-items: center;
+ gap: 30px;
+ border-radius: 0px 0px 4px 4px;
+ background: white;
+ box-shadow: 0px 2px 1px 0px rgba(46, 47, 66, 0.08),
+ 0px 1px 1px 0px rgba(46, 47, 66, 0.16),
+ 0px 1px 6px 0px rgba(46, 47, 66, 0.08);
+}
+
+.status {
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+}
+
+.online {
+ composes: status;
+ background-color: green;
+}
+
+.offline {
+ composes: status;
+ background-color: red;
+}
diff --git a/src/components/Profile/Profile.jsx b/src/components/Profile/Profile.jsx
new file mode 100644
index 0000000..a2c3b25
--- /dev/null
+++ b/src/components/Profile/Profile.jsx
@@ -0,0 +1,42 @@
+import PropTypes from 'prop-types';
+import css from './Profile.module.css';
+
+export const Profile = ({ username, tag, location, avatar, stats }) => {
+ return (
+
+
+
+
{username}
+
@{tag}
+
{location}
+
+
+
+ -
+ Followers
+ {stats.followers}
+
+ -
+ Views
+ {stats.views}
+
+ -
+ Likes
+ {stats.likes}
+
+
+
+ );
+};
+
+Profile.propTypes = {
+ username: PropTypes.string.isRequired,
+ tag: PropTypes.string.isRequired,
+ location: PropTypes.string.isRequired,
+ avatar: PropTypes.string.isRequired,
+ stats: PropTypes.shape({
+ followers: PropTypes.number.isRequired,
+ views: PropTypes.number.isRequired,
+ likes: PropTypes.number.isRequired,
+ }).isRequired,
+};
diff --git a/src/components/Profile/Profile.module.css b/src/components/Profile/Profile.module.css
new file mode 100644
index 0000000..6fd7e7d
--- /dev/null
+++ b/src/components/Profile/Profile.module.css
@@ -0,0 +1,100 @@
+.profile {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding-top: 60px;
+ padding-bottom: 60px;
+
+}
+
+.description {
+
+ padding-top: 30px ;
+ padding-bottom: 30px;
+ background-color: white;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ border-top-left-radius: 10px;
+ border-top-right-radius: 10px;
+ width: 350px;
+ /* height: 370px; */
+ box-shadow: 0px 2px 1px 0px rgba(46, 47, 66, 0.08),
+ 0px 1px 1px 0px rgba(46, 47, 66, 0.16),
+ 0px 1px 6px 0px rgba(46, 47, 66, 0.08);
+
+
+}
+
+.avatar {
+ display: block;
+ width: 150px;
+ /* margin-top: 20px; */
+ border-radius: 50%;
+ background-color:#9CAF88;
+}
+
+.name {
+ font-size: 22px;
+ line-height: 1.62;
+ font-weight: bold;
+ color: #0f0f4f;
+ margin-top: 20px;
+}
+
+.userInfo {
+ margin-top: 10px;
+ font-size: 16px;
+ line-height: 1.62;
+ font-weight: 18px;
+ /* font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; */
+ color: slategrey;
+}
+
+.stats {
+ background-color: #f7fcff;
+ width: 350px;
+ display: flex;
+ margin: 0 auto;
+ padding: 0;
+ align-items: center;
+ justify-content: center;
+ border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ box-shadow: 0px 2px 1px 0px rgba(46, 47, 66, 0.08),
+ 0px 1px 1px 0px rgba(46, 47, 66, 0.16),
+ 0px 1px 6px 0px rgba(46, 47, 66, 0.08);
+}
+
+.item {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 5px;
+ border-top: 1px solid #cdcdcd;
+ border-right: 1px solid #cdcdcd;
+}
+
+.item:last-child {
+ border-right: none;
+}
+
+.label {
+ display: flex;
+ margin-top: 15px;
+ line-height: 1.62;
+ font-size: 16px;
+ font-weight: 18px;
+ text-align: center;
+ justify-content: center;
+ color: slategrey;
+}
+
+.quantity {
+ text-align: center;
+ line-height: 1.58;
+ font-weight: bold;
+ margin-bottom: 15px;
+ color: #0f0f4f;
+}
diff --git a/src/components/Statistics/Statistics.jsx b/src/components/Statistics/Statistics.jsx
new file mode 100644
index 0000000..d541fd3
--- /dev/null
+++ b/src/components/Statistics/Statistics.jsx
@@ -0,0 +1,41 @@
+import PropTypes from 'prop-types';
+import css from './Statistics.module.css';
+
+export const Statistics = ({ title, stats }) => {
+ // Generate Random Color
+ const generateRandomColor = () => {
+ return `rgb(${Math.floor(Math.random() * 256)}, ${Math.floor(
+ Math.random() * 256
+ )}, ${Math.floor(Math.random() * 256)})`;
+ };
+
+ return (
+
+ {title && {title}
}
+
+
+ {stats.map(stat => (
+ -
+ {stat.label}
+ {stat.percentage}%
+
+ ))}
+
+
+ );
+};
+
+Statistics.propTypes = {
+ title: PropTypes.string,
+ stats: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.string.isRequired,
+ label: PropTypes.string.isRequired,
+ percentage: PropTypes.number.isRequired,
+ })
+ ).isRequired,
+};
diff --git a/src/components/Statistics/Statistics.module.css b/src/components/Statistics/Statistics.module.css
new file mode 100644
index 0000000..d08cff9
--- /dev/null
+++ b/src/components/Statistics/Statistics.module.css
@@ -0,0 +1,62 @@
+.statistics {
+ width: 250px;
+ margin: 0 auto;
+ padding: 50px 20px;
+ width: 350px;
+
+}
+
+.title {
+ text-transform: uppercase;
+ text-align: center;
+ /* color: #192431; */
+ margin: 0 auto;
+ padding-top: 30px;
+ padding-bottom: 30px;
+ background-color: white;
+ color: #0f0f4f;
+ box-shadow: 0px 2px 1px 0px rgba(46, 47, 66, 0.08),
+ 0px 1px 1px 0px rgba(46, 47, 66, 0.16),
+ 0px 1px 6px 0px rgba(46, 47, 66, 0.08);
+
+}
+
+.statList {
+ display: flex;
+ justify-content: center;
+ margin: 0 auto;
+ padding: 0;
+ /* width: 350px; */
+ box-shadow: 0px 2px 1px 0px rgba(46, 47, 66, 0.08),
+ 0px 1px 1px 0px rgba(46, 47, 66, 0.16),
+ 0px 1px 6px 0px rgba(46, 47, 66, 0.08);
+}
+
+.item {
+ display: flex;
+ flex-direction: column;
+ margin: auto;
+ margin-top: 0;
+ text-align: center;
+
+ width: 100%;
+}
+
+.label {
+ padding-top: 5px;
+ color: white;
+ align-items: center;
+ /* width: 350px; */
+
+
+}
+
+.percentage {
+ font-size: 20px;
+ padding-bottom: 5px;
+ padding: 5px;
+ align-items: center;
+ color: white;
+ /* width: 350px; */
+
+}
diff --git a/src/components/TransactionHistory/TransactionHistory.jsx b/src/components/TransactionHistory/TransactionHistory.jsx
new file mode 100644
index 0000000..25dd7ef
--- /dev/null
+++ b/src/components/TransactionHistory/TransactionHistory.jsx
@@ -0,0 +1,37 @@
+import PropTypes from 'prop-types';
+import css from './TransactionHistory.module.css';
+
+export const TransactionHistory = ({ items }) => {
+ return (
+
+
+
+ Type |
+ Amount |
+ Currency |
+
+
+
+
+ {items.map(({ id, type, amount, currency }) => (
+
+ {type} |
+ {amount} |
+ {currency} |
+
+ ))}
+
+
+ );
+};
+
+TransactionHistory.propTypes = {
+ items: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.string.isRequired,
+ type: PropTypes.string.isRequired,
+ amount: PropTypes.string.isRequired,
+ currency: PropTypes.string.isRequired,
+ })
+ ).isRequired,
+};
diff --git a/src/components/TransactionHistory/TransactionHistory.module.css b/src/components/TransactionHistory/TransactionHistory.module.css
new file mode 100644
index 0000000..e7d761c
--- /dev/null
+++ b/src/components/TransactionHistory/TransactionHistory.module.css
@@ -0,0 +1,35 @@
+.transactionHistory {
+ border-collapse: collapse;
+ table-layout: auto;
+ width: 600px;
+ margin: 60px auto;
+ padding: 5px;
+ border-radius: 0px 0px 4px 4px;
+ background: white;
+ box-shadow: 0px 2px 1px 0px rgba(46, 47, 66, 0.08),
+ 0px 1px 1px 0px rgba(46, 47, 66, 0.16),
+ 0px 1px 6px 0px rgba(46, 47, 66, 0.08);
+}
+
+.tableHeader {
+ padding: 8px;
+ text-align: center;
+ text-transform: uppercase;
+ border-bottom: 1px solid #ddd;
+ background-color: #9CAF88;
+ color: white;
+}
+
+.tableData {
+ padding: 8px;
+ text-align: center;
+ border-bottom: 1px solid #ddd;
+}
+
+.tableData:first-of-type {
+ text-transform: capitalize;
+}
+
+.tableRow:nth-of-type(even) {
+ background-color: #f9f9f9;
+}
diff --git a/src/data/data.json b/src/data/data.json
new file mode 100644
index 0000000..0b37d4b
--- /dev/null
+++ b/src/data/data.json
@@ -0,0 +1,7 @@
+[
+ { "id": "id-1", "label": ".docx", "percentage": 22 },
+ { "id": "id-2", "label": ".pdf", "percentage": 4 },
+ { "id": "id-3", "label": ".mp3", "percentage": 17 },
+ { "id": "id-4", "label": ".psd", "percentage": 47 },
+ { "id": "id-5", "label": ".pdf", "percentage": 10 }
+]
diff --git a/src/data/friends.json b/src/data/friends.json
new file mode 100644
index 0000000..7082a76
--- /dev/null
+++ b/src/data/friends.json
@@ -0,0 +1,32 @@
+[
+ {
+ "avatar": "https://cdn-icons-png.flaticon.com/512/1998/1998592.png",
+ "name": "Mango",
+ "isOnline": true,
+ "id": 1812
+ },
+ {
+ "avatar": "https://cdn-icons-png.flaticon.com/512/616/616438.png",
+ "name": "Kiwi",
+ "isOnline": false,
+ "id": 1137
+ },
+ {
+ "avatar": "https://cdn-icons-png.flaticon.com/512/1623/1623681.png",
+ "name": "Ajax",
+ "isOnline": true,
+ "id": 1213
+ },
+ {
+ "avatar": "https://cdn-icons-png.flaticon.com/512/2977/2977285.png",
+ "name": "Jay",
+ "isOnline": true,
+ "id": 1714
+ },
+ {
+ "avatar": "https://cdn-icons-png.flaticon.com/512/1998/1998749.png",
+ "name": "Poly",
+ "isOnline": false,
+ "id": 1284
+ }
+]
diff --git a/src/data/transactions.json b/src/data/transactions.json
new file mode 100644
index 0000000..2d2a0df
--- /dev/null
+++ b/src/data/transactions.json
@@ -0,0 +1,122 @@
+[
+ {
+ "id": "1e0700a2-5183-4291-85cc-2065a036a683",
+ "type": "invoice",
+ "amount": "964.82",
+ "currency": "LRD"
+ },
+ {
+ "id": "a30f821b-4d25-4ff0-abdd-e340b3f0dd2b",
+ "type": "payment",
+ "amount": "686.50",
+ "currency": "WST"
+ },
+ {
+ "id": "44dca67a-8e5a-4798-bf8e-b15efd4e1abd",
+ "type": "invoice",
+ "amount": "828.62",
+ "currency": "UGX"
+ },
+ {
+ "id": "ea8ed3dc-2b68-4a53-905a-53ecb0adef33",
+ "type": "withdrawal",
+ "amount": "527.80",
+ "currency": "ALL"
+ },
+ {
+ "id": "ea76146a-0b00-4b80-bc02-a8c822176712",
+ "type": "withdrawal",
+ "amount": "371.43",
+ "currency": "MUR"
+ },
+ {
+ "id": "63ca02f9-d637-46b5-9237-f3b24425e029",
+ "type": "payment",
+ "amount": "862.44",
+ "currency": "AUD"
+ },
+ {
+ "id": "ed0263e8-59a5-4bf1-87e0-2bb88e53dc34",
+ "type": "withdrawal",
+ "amount": "907.00",
+ "currency": "GEL"
+ },
+ {
+ "id": "6013bad0-750c-4691-8bc2-d8f2b43969c4",
+ "type": "withdrawal",
+ "amount": "352.52",
+ "currency": "UGX"
+ },
+ {
+ "id": "252c7be4-8b06-4fa7-8d42-61fb835b70d5",
+ "type": "payment",
+ "amount": "388.98",
+ "currency": "TOP"
+ },
+ {
+ "id": "4eaab41b-b967-40ac-82ed-85fc66f646f1",
+ "type": "deposit",
+ "amount": "103.10",
+ "currency": "BWP"
+ },
+ {
+ "id": "9648a350-8469-42d5-8bf3-18090de5fe67",
+ "type": "withdrawal",
+ "amount": "322.32",
+ "currency": "MRO"
+ },
+ {
+ "id": "9c5c25fb-1a95-4b2f-8d1f-4c4426d677cc",
+ "type": "invoice",
+ "amount": "14.79",
+ "currency": "PYG"
+ },
+ {
+ "id": "43ef232c-80e9-4d6f-b48a-b22405620de3",
+ "type": "payment",
+ "amount": "904.86",
+ "currency": "CHF"
+ },
+ {
+ "id": "5161682e-e620-4019-ab0a-24ceb10fbd20",
+ "type": "withdrawal",
+ "amount": "307.08",
+ "currency": "NOK"
+ },
+ {
+ "id": "7b119d71-42e6-4c42-a141-6818b07bb9ff",
+ "type": "invoice",
+ "amount": "275.07",
+ "currency": "AWG"
+ },
+ {
+ "id": "a4f65722-65c4-4c28-b1f4-b8ed988bb205",
+ "type": "deposit",
+ "amount": "213.10",
+ "currency": "STD"
+ },
+ {
+ "id": "c6e5784b-0ca3-48d6-86e5-b5128af5a523",
+ "type": "invoice",
+ "amount": "116.11",
+ "currency": "CUP CUC"
+ },
+ {
+ "id": "c9ebed6a-3a02-4b49-ac0d-0534b51f2bfd",
+ "type": "invoice",
+ "amount": "878.67",
+ "currency": "HKD"
+ },
+ {
+ "id": "a4a98b0e-b22c-438b-9f83-de2df52110c8",
+ "type": "invoice",
+ "amount": "725.03",
+ "currency": "UYU UYI"
+ },
+ {
+ "id": "b39bfa7a-0166-4c47-94d6-87d20590f746",
+ "type": "payment",
+ "amount": "405.45",
+ "currency": "MDL"
+ }
+]
diff --git a/src/data/user.json b/src/data/user.json
new file mode 100644
index 0000000..a73669f
--- /dev/null
+++ b/src/data/user.json
@@ -0,0 +1,11 @@
+{
+ "username": "Jacques Gluke",
+ "tag": "jgluke",
+ "location": "Ocho Rios, Jamaica",
+ "avatar": "https://cdn-icons-png.flaticon.com/512/2922/2922506.png",
+ "stats": {
+ "followers": 5603,
+ "views": 4827,
+ "likes": 1308
+ }
+}
diff --git a/src/index.css b/src/index.css
index 1aac5f6..17f1f2d 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,15 +1,41 @@
-@import-normalize; /* bring in normalize.css styles */
+@import-normalize;
+/* bring in normalize.css styles */
body {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
+ /* font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
+ sans-serif; */
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ background-color: #f4f4fd;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p {
+ margin: 0;
+}
+
+ul,
+ol {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
\ No newline at end of file