diff --git a/data/repositories.json b/data/repositories.json new file mode 100644 index 0000000..3b2bbb4 --- /dev/null +++ b/data/repositories.json @@ -0,0 +1,41 @@ +{ + "org": "OpenDevUFCG", + "repositories": [ + { + "name": "calluswhatyouwant/spotify-web-sdk", + "difficulty": "avancado" + }, + { + "name": "calluswhatyouwant/musicritic", + "difficulty": "avancado" + }, + { + "name": "paulojbleitao/pokedex", + "difficulty": "intermediario" + }, + { + "name": "SubmiBot/SubmiBot", + "difficulty": "intermediario" + }, + { + "name": "marianabianca/pomodoro", + "difficulty": "iniciante" + }, + { + "name": "P-Sync/P-Sync", + "difficulty": "intermediario" + }, + { + "name": "FelipeMarinho97/iskra-webkit-greeter", + "difficulty": "intermediario" + }, + { + "name": "Rickecr/PyGraph", + "difficulty": "intermediario" + }, + { + "name": "Rickecr/CamaraDosDeputados", + "difficulty": "iniciante" + } + ] +} diff --git a/package.json b/package.json index 264084a..2505699 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,8 @@ "axios": "^0.18.0", "blueprint-css": "^3.0.0-beta.0", "prop-types": "^15.7.2", - "react": "^16.6.0", - "react-dom": "^16.6.0", + "react": "^16.10.2", + "react-dom": "^16.10.2", "react-markdown": "^4.2.2", "react-router-dom": "^4.3.1", "react-tooltip": "^3.11.1" diff --git a/src/components/mentors/MentorCard.css b/src/components/mentors/MentorCard.css new file mode 100644 index 0000000..2b665c3 --- /dev/null +++ b/src/components/mentors/MentorCard.css @@ -0,0 +1,56 @@ +.img-mentor { + border-radius: 100%; + width: 200px; + filter: grayscale(100%); + transition: all 0.7s ease; +} + +.card-mentor:hover .img-mentor { + filter: grayscale(0%); +} + +.name-mentor { + color: rgb(46, 46, 46); + margin-top: 20px; + font-size: 18px; + font-weight: bolder; +} + +.card-mentor { + padding: 30px 50px; + display: flex; + flex-direction: column; + align-items: center; + border-radius: 5px; +} + +.card-mentor:hover { + background-color: white; + box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.11); +} +.repository-mentor { + background-color: rgb(114, 161, 214); + border-radius: 30px; + padding: 3px 10px; + font-size: 11px; + margin: 3px 3px; + color: white; + font-weight: bolder; +} + +.repository-list-mentor { + visibility: hidden; + list-style-type: none; + display: flex; + flex-flow: row wrap; + text-align: center; + justify-content: center; + padding: 0; + opacity: 0; + transition: opacity 0.7s; +} + +.card-mentor:hover .repository-list-mentor { + visibility: visible; + opacity: 1; +} diff --git a/src/components/mentors/MentorCard.js b/src/components/mentors/MentorCard.js new file mode 100644 index 0000000..ab8eafd --- /dev/null +++ b/src/components/mentors/MentorCard.js @@ -0,0 +1,25 @@ +// @flow +import React from 'react'; +import type { Repository } from '../commons/repository/repository'; +import type { Mentor as MentorCardProps } from './mentor'; + +import './MentorCard.css'; + +const renderRepositories = (repositoriesList: Repository[]) => + repositoriesList.map(repository => ( +
  • + {repository.nameWithOwner} +
  • + )); + +const MentorCard = ({ name, imgUrl, repositoriesList }: MentorCardProps) => ( +
    + {name} +
    {name}
    + +
    +); + +export default MentorCard; diff --git a/src/components/mentors/MentorGrid.js b/src/components/mentors/MentorGrid.js new file mode 100644 index 0000000..2c7a5cb --- /dev/null +++ b/src/components/mentors/MentorGrid.js @@ -0,0 +1,24 @@ +// @flow +import React from 'react'; +import type { Mentor } from './mentor'; + +import MentorCard from './MentorCard'; + +type MentorGridProps = { + mentorsList: Mentor[], +}; + +const renderMentors = (mentorsList: Mentor[]) => + mentorsList.map(mentor => ( + + )); + +const MentorGrid = ({ mentorsList }: MentorGridProps) => ( + +); + +export default MentorGrid; diff --git a/src/components/mentors/mentor.js b/src/components/mentors/mentor.js new file mode 100644 index 0000000..77a6210 --- /dev/null +++ b/src/components/mentors/mentor.js @@ -0,0 +1,8 @@ +// @flow +import type { Repository } from '../commons/repository/repository'; + +export type Mentor = { + name: string, + imgUrl: string, + repositoriesList: Repository[], +}; diff --git a/src/graphql/queries.js b/src/graphql/queries.js new file mode 100644 index 0000000..54bd789 --- /dev/null +++ b/src/graphql/queries.js @@ -0,0 +1,55 @@ +// @flow + +const repoStatsQuery = ` +fragment SearchResultFields on SearchResultItemConnection { + nodes { + ... on Repository { + nameWithOwner + description + url + forkCount + object(expression: "master") { + ... on Commit { + history { + totalCount + } + } + } + issues(states: OPEN) { + totalCount + } + pullRequests(states: OPEN) { + totalCount + } + stargazers { + totalCount + } + } + } +}`; + +const searchRepoQuery = ( + query: string, + quantity: number, + after: string | any = null +) => { + let customAfter = after; + if (after) customAfter = `"${after}"`; + return `{ + search( + first: ${quantity}, + after: ${customAfter}, + query: "${query}", + type: REPOSITORY + ) { + ...SearchResultFields + repositoryCount + pageInfo { + endCursor + hasNextPage + } + } + } ${repoStatsQuery}`; +}; + +export default searchRepoQuery; diff --git a/src/lib/github.js b/src/lib/github.js index c17ab58..b99d7c3 100644 --- a/src/lib/github.js +++ b/src/lib/github.js @@ -1,34 +1,57 @@ // @flow import axios from 'axios'; +import projects from '../../data/repositories.json'; +import searchRepoQuery from '../graphql/queries'; const getAxiosInstance = () => { + const token = process.env.GITHUB_TOKEN || ''; const config = { - baseURL: 'https://laguinho.opendevufcg.org/v1', + baseURL: 'https://api.github.com', + headers: { Authorization: `Bearer ${token}` }, }; - return axios.create(config); }; -const requestGithub = async (after: string | any) => { - const response = await getAxiosInstance().get('/repositorios', { - params: { - apos: after, - quantidade: 6, - }, - }); - return response; +export const requestGithub = async (query: string, variables: any = {}) => { + const params = { query, variables }; + const response = await getAxiosInstance().post('/graphql', params); + return response.data; }; -const getRepositories = async (after: string | any) => { - const response = await requestGithub(after); - const { repos, endCursor } = response.data; +const transformRepository = (githubJson: any) => ({ + nameWithOwner: githubJson.nameWithOwner, + description: githubJson.description, + url: githubJson.url, + forkCount: githubJson.forkCount, + commitsCount: githubJson.object.history.totalCount, + issuesCount: githubJson.issues.totalCount, + pullRequestsCount: githubJson.pullRequests.totalCount, + stargazersCount: githubJson.stargazers.totalCount, +}); + +const getRepositories = async (after: string | any, quantity: number = 6) => { + const { repositories } = projects; + + let query = repositories.reduce( + (accum, current) => ` ${accum} repo:${current.name}`, + '' + ); + query = `org:${projects.org}${query}`; + + const response = await requestGithub( + searchRepoQuery(query, quantity, after) + ); + + const { + nodes: repos, + pageInfo: { endCursor }, + } = response.data.search; let lastCursor = endCursor; - if (lastCursor) lastCursor = lastCursor.replace('=', ''); if (!lastCursor) lastCursor = after; - return { repos, lastCursor }; + return { repos: repos.map(transformRepository), lastCursor }; }; export default getRepositories; diff --git a/yarn.lock b/yarn.lock index 66a6c8c..5ac78e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3455,6 +3455,7 @@ js-levenshtein@^1.1.3: "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-tokens@^3.0.2: version "3.0.2" @@ -3623,6 +3624,7 @@ loglevel@^1.6.3: loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" @@ -4062,6 +4064,7 @@ number-is-nan@^1.0.0: object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" @@ -4544,6 +4547,7 @@ promise-inflight@^1.0.1: prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== dependencies: loose-envify "^1.4.0" object-assign "^4.1.1" @@ -4694,22 +4698,24 @@ react-dev-utils@^6.1.1: strip-ansi "4.0.0" text-table "0.2.0" -react-dom@^16.6.0: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f" +react-dom@^16.10.2: + version "16.10.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.10.2.tgz#4840bce5409176bc3a1f2bd8cb10b92db452fda6" + integrity sha512-kWGDcH3ItJK4+6Pl9DZB16BXYAZyrYQItU4OMy0jAkv5aNqc+mAKb4TpFtAteI6TJZu+9ZlNhaeNQSVQDHJzkw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.6" + scheduler "^0.16.2" react-error-overlay@^5.1.0: version "5.1.6" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-5.1.6.tgz#0cd73407c5d141f9638ae1e0c63e7b2bf7e9929d" react-is@^16.8.1: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" + version "16.10.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab" + integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA== react-is@^16.8.6: version "16.10.2" @@ -4760,14 +4766,14 @@ react-tooltip@^3.11.1: classnames "^2.2.5" prop-types "^15.6.0" -react@^16.6.0: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" +react@^16.10.2: + version "16.10.2" + resolved "https://registry.yarnpkg.com/react/-/react-16.10.2.tgz#a5ede5cdd5c536f745173c8da47bda64797a4cf0" + integrity sha512-MFVIq0DpIhrHFyqLU0S3+4dIcBhhOvBE8bJ/5kHPVOVaGdo0KuiQzpcjCPsf585WvhypqtrMILyoE2th6dT+Lw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.6" read-pkg-up@^2.0.0: version "2.0.0" @@ -5075,9 +5081,10 @@ sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -scheduler@^0.13.6: - version "0.13.6" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" +scheduler@^0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.2.tgz#f74cd9d33eff6fc554edfb79864868e4819132c1" + integrity sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1"