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 ( +
  • + + User avatar +

    {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 ( +
    +
    + User avatar +

    {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 ( + + + + + + + + + + + {items.map(({ id, type, amount, currency }) => ( + + + + + + ))} + +
    TypeAmountCurrency
    {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