diff --git a/.env.example b/.env.example deleted file mode 100644 index b6df08a..0000000 --- a/.env.example +++ /dev/null @@ -1 +0,0 @@ -REACT_APP_GITHUB_TOKEN = YOUR_GITHUB_TOKEN_HERE \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index baf5bd4..a21cbd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1832,6 +1832,17 @@ } } }, + "@reduxjs/toolkit": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.7.1.tgz", + "integrity": "sha512-wXwXYjBVz/ItxB7SMzEAMmEE/FBiY1ze18N+VVVX7NtVbRUrdOGKhpQMHivIJfkbJvSdLUU923a/yAagJQzY0Q==", + "requires": { + "immer": "^9.0.7", + "redux": "^4.1.2", + "redux-thunk": "^2.4.1", + "reselect": "^4.1.5" + } + }, "@rollup/plugin-babel": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz", @@ -2307,6 +2318,15 @@ "@types/node": "*" } }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", @@ -2380,6 +2400,11 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==" }, + "@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" + }, "@types/q": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", @@ -2395,6 +2420,27 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "@types/react": { + "version": "17.0.38", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.38.tgz", + "integrity": "sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-redux": { + "version": "7.1.22", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.22.tgz", + "integrity": "sha512-GxIA1kM7ClU73I6wg9IRTVwSO9GS+SAKZKe0Enj+82HMU6aoESFU2HNAdNi3+J53IaOHPiUfT3kSG4L828joDQ==", + "requires": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -2408,6 +2454,11 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==" }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + }, "@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -3018,6 +3069,14 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz", "integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==" }, + "axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "requires": { + "follow-redirects": "^1.14.4" + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -4051,6 +4110,11 @@ } } }, + "csstype": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz", + "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -4355,9 +4419,9 @@ } }, "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-15.0.0.tgz", + "integrity": "sha512-/l1sXXm79ry34KwwS0y4oVZjB468iw/6u9g1W26dtexKcIJAnVL2pMF+hxQwzZ7LutxOwEgtym9eIxvX33CMKg==" }, "dotenv-expand": { "version": "5.1.0", @@ -5602,6 +5666,14 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -9276,6 +9348,31 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-loader-spinner": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-5.1.0.tgz", + "integrity": "sha512-+t6Fo0HQH0/8pGRcyE18V9D2kPcnNIe2LBBfuE+9jsRqE+g66lt+BkEo8TY23tP5gmCcyUxIW3efn92YhoSLWQ==" + }, + "react-redux": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz", + "integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==", + "requires": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "dependencies": { + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + } + } + }, "react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -9334,6 +9431,13 @@ "webpack-dev-server": "^4.6.0", "webpack-manifest-plugin": "^4.0.2", "workbox-webpack-plugin": "^6.4.1" + }, + "dependencies": { + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + } } }, "readable-stream": { @@ -9371,6 +9475,19 @@ "strip-indent": "^3.0.0" } }, + "redux": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz", + "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, + "redux-thunk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", + "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==" + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -9533,6 +9650,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "reselect": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz", + "integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==" + }, "resolve": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", diff --git a/package.json b/package.json index 2c7b16a..93534c8 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,16 @@ "version": "0.1.0", "private": true, "dependencies": { + "@reduxjs/toolkit": "^1.7.1", "@testing-library/jest-dom": "^5.16.1", "@testing-library/react": "^12.1.2", "@testing-library/user-event": "^13.5.0", "axios": "^0.24.0", + "dotenv": "^15.0.0", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-loader-spinner": "^5.1.0", + "react-redux": "^7.2.6", "react-scripts": "5.0.0", "web-vitals": "^2.1.3" }, diff --git a/src/App.css b/src/App.css index 594fce5..0730f77 100644 --- a/src/App.css +++ b/src/App.css @@ -1,6 +1,8 @@ .app-container { + background-color: rgba(38, 1, 84, 0.933); display: flex; padding: 3em; + color: rgba(255, 255, 255, 0.775) } .profile-container { @@ -10,7 +12,7 @@ /* NAVBAR */ .navbar { - background-color: rgba(0, 0,0, .8); + background-color: rgb(82, 0, 140); padding: 10px; height: 60px; } @@ -40,7 +42,7 @@ .profile-avatar { width: 70%; height: auto; - border: 7px solid rgba(0, 0,0, .3); + border: 7px solid rgba(119, 0, 255, 0.72); border-radius: 50%; object-fit: cover; } @@ -76,6 +78,7 @@ display: flex; align-items: center; gap: 10px; + fill :rgb(169, 94, 255) } .profile-info-icon { @@ -103,12 +106,19 @@ } .single-repository-container { - border:solid 1px rgba(0, 0,0, .1); + border:solid 1px rgba(91, 21, 141, 0.953); + background-color: rgb(40, 9, 75); border-radius: 10px; height: 200px; width: 49%; } +div .single-repository-container#container:hover { + border-radius: 2.4rem; + border:solid 1px rgb(169, 94, 255); + transition: .35s; +} + .single-repository-content { padding: 10px 25px 20px 25px; } @@ -120,7 +130,7 @@ } .single-repository-name { - color:royalblue; + color:rgb(169, 94, 255); font-size: 20px; cursor: pointer; } @@ -130,9 +140,9 @@ } .single-repository-visibility-badge { - border: 1px solid rgba(0, 0,0, .3); - color: rgba(0, 0,0, .6); - background-color: transparent; + border: 1px solid rgb(169, 94, 255); + color: rgb(169, 94, 255); + background-color: rgba(52, 36, 94, 0.357); border-radius: 15px; padding: 4px 10px 7px 10px; align-items: center; @@ -158,6 +168,10 @@ gap: 5px; } +.single-repository-info-item svg { + fill: rgb(169, 94, 255); +} + /* Repositories list navigation buttons */ .repositoies-list-navigation-buttons-container { @@ -171,9 +185,9 @@ .repositoies-list-navigation-button { text-align: center; - color: rgba(0, 0,0, .3); - border: 1px solid rgba(0, 0,0, .3); - background-color: white; + color: rgb(169, 94, 255); + border: 1px solid rgb(169, 94, 255); + background-color: transparent; border-radius: 3px; width: 30px; height: 40px; @@ -184,6 +198,6 @@ } .repositoies-list-navigation-button:hover { - background-color: rgba(0, 0,0, .1); + background-color: rgba(0, 0, 0, 0.2); transition: .3s; } \ No newline at end of file diff --git a/src/App.js b/src/App.js index de71668..3658a67 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,6 @@ import "./App.css"; + // Components import RepositoriesList from "./components/repositories/RepositoriesList"; import Profile from "./components/profile/Profile"; diff --git a/src/components/profile/Profile.js b/src/components/profile/Profile.js index 089e18c..ecb74e6 100644 --- a/src/components/profile/Profile.js +++ b/src/components/profile/Profile.js @@ -3,37 +3,39 @@ import axios from "axios"; import email from "../../assets/img/email.png"; import anonymous_avatar from "../../assets/img/anonymous.png"; +import { useDispatch, useSelector } from "react-redux"; +import { fetchProfileData } from "../../store/actions/profile.action" function Profile() { - const [profile, setProfile] = useState({}); - useEffect(() => { - axios.get(`https://api.github.com/user`).then((response) => { - setProfile(response.data); - }); - }); + const dispatch = useDispatch() + const userData = useSelector((state) => state.profile.userData) + + useEffect(() => { + dispatch(fetchProfileData()) + }, []); const handleNavigateToProfile = () => { - window.location = profile.html_url; + window.location = Profile.html_url; }; return (
avatar

- {profile.name}
- {profile.login && ( - @{profile.login} + {userData.name}
+ {userData.login && ( + @{userData.login} )}

- {profile.bio} + {userData.bio}
- {profile.followers && ( + {userData.followers && ( - {profile.followers} followers + {userData.followers} followers )} - {profile.following && ( + {userData.following && ( . - {profile.following} following + {userData.following} following )}
- {profile.email && ( + {userData.email && ( email - {profile.email} + {userData.email} )} - {profile.location && ( + {userData.location && ( - {profile.location} + {userData.location} )} - {profile.company && ( + {userData.company && ( - {profile.company} + {userData.company} )}
diff --git a/src/components/repositories/RepositoriesList.js b/src/components/repositories/RepositoriesList.js index 2893d0f..27e660f 100644 --- a/src/components/repositories/RepositoriesList.js +++ b/src/components/repositories/RepositoriesList.js @@ -1,6 +1,8 @@ import React, { useEffect, useState } from "react"; import axios from "axios"; import SingleRepository from "./SingleRepository"; +import { useDispatch, useSelector } from "react-redux"; +import { fetchRepos } from "../../store/actions/repos.actions"; function RepositoriesList() { const initialFilters = { @@ -10,27 +12,15 @@ function RepositoriesList() { }; const [filters, setFilters] = useState(initialFilters); - const [repos, setRepos] = useState([]); + const dispatch = useDispatch() + const reposData = useSelector((state) => state.repos.reposData) ; useEffect(() => { - fetchRepos(); + dispatch(fetchRepos()); // eslint-disable-next-line }, []); - const fetchRepos = () => { - setRepos("loading"); - axios - .get("https://api.github.com/user/repos", { - params: filters, - }) - .then((response) => { - setRepos(response.data); - }) - .catch((error) => { - console.log(error); - setRepos([]); - }); - }; + const handleNextPage = () => { setFilters( @@ -38,7 +28,7 @@ function RepositoriesList() { filters: { ...filters, page: filters.page + 1 }, }, () => { - fetchRepos(); + dispatch(fetchRepos()); } ); }; @@ -49,7 +39,7 @@ function RepositoriesList() { filters: { ...filters, page: filters.page - 1 }, }, () => { - fetchRepos(); + dispatch(fetchRepos()); } ); }; @@ -58,21 +48,21 @@ function RepositoriesList() {

Popular Repositories:

- {repos === "loading" ? ( + {reposData === "loading" ? (
Loading ...
- ) : repos.length === 0 ? ( + ) : reposData.length === 0 ? (
No repositories ...
) : (
- {repos.map((repo, index) => ( -
+ { reposData.map((repo,index) => +
- ))} + )}