mirror of
https://github.com/rjNemo/devbook_ts
synced 2026-06-06 02:36:39 +00:00
🐙 GitHub (#13)
* edit package.json * eslint * fetch git repos * create repo array on fetch * update repo array on profile edit * edit profile presentation
This commit is contained in:
parent
4880d2853d
commit
191130a7ad
12 changed files with 944 additions and 633 deletions
6
.eslintignore
Normal file
6
.eslintignore
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# don't ever lint node_modules
|
||||
node_modules
|
||||
# don't lint build output (make sure it's set to your correct build folder name)
|
||||
build
|
||||
# don't lint nyc coverage output
|
||||
coverage
|
||||
74
.eslintrc.js
74
.eslintrc.js
|
|
@ -1,19 +1,79 @@
|
|||
module.exports = {
|
||||
extends: ["react-app", "prettier"],
|
||||
plugins: ["prettier", "jest", "cypress"],
|
||||
parser: "babel-eslint",
|
||||
extends: [
|
||||
'react-app',
|
||||
'prettier',
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'airbnb-typescript',
|
||||
],
|
||||
plugins: ['prettier', 'jest', 'cypress', '@typescript-eslint'],
|
||||
// parser: 'babel-eslint',
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
"cypress/globals": true,
|
||||
'cypress/globals': true,
|
||||
es6: true,
|
||||
"jest/globals": true,
|
||||
'jest/globals': true,
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect",
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
"prettier/prettier": "warn",
|
||||
'prettier/prettier': 'warn',
|
||||
'adjacent-overload-signatures': true,
|
||||
'ban-comma-operator': true,
|
||||
'no-namespace': true,
|
||||
'no-parameter-reassignment': true,
|
||||
'no-reference': true,
|
||||
'no-unnecessary-type-assertion': true,
|
||||
'label-position': true,
|
||||
'no-conditional-assignment': true,
|
||||
'no-construct': true,
|
||||
'no-duplicate-super': true,
|
||||
'no-duplicate-switch-case': true,
|
||||
'no-duplicate-variable': [true, 'check-parameters'],
|
||||
'no-shadowed-variable': true,
|
||||
'no-empty': [true, 'allow-empty-catch'],
|
||||
'no-floating-promises': true,
|
||||
'no-implicit-dependencies': true,
|
||||
'no-invalid-this': true,
|
||||
'no-string-throw': true,
|
||||
'no-unsafe-finally': true,
|
||||
'no-void-expression': [true, 'ignore-arrow-function-shorthand'],
|
||||
'no-duplicate-imports': true,
|
||||
// Warn when an empty interface is defined. These are generally not useful.
|
||||
'no-empty-interface': {
|
||||
severity: 'warning',
|
||||
},
|
||||
'no-import-side-effect': {
|
||||
severity: 'warning',
|
||||
},
|
||||
'no-var-keyword': {
|
||||
severity: 'warning',
|
||||
},
|
||||
'triple-equals': {
|
||||
severity: 'warning',
|
||||
},
|
||||
deprecation: {
|
||||
severity: 'warning',
|
||||
},
|
||||
'prefer-for-of': {
|
||||
severity: 'warning',
|
||||
},
|
||||
'unified-signatures': {
|
||||
severity: 'warning',
|
||||
},
|
||||
'prefer-const': {
|
||||
severity: 'warning',
|
||||
},
|
||||
'trailing-comma': {
|
||||
severity: 'warning',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
11
package.json
11
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "client",
|
||||
"version": "0.1.0",
|
||||
"name": "devbook",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.13.0",
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
"@fortawesome/free-regular-svg-icons": "^5.13.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
||||
"@fortawesome/react-fontawesome": "^0.1.9",
|
||||
"@octokit/rest": "^17.9.2",
|
||||
"@reduxjs/toolkit": "^1.3.6",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
|
|
@ -19,7 +20,13 @@
|
|||
"@types/react-dom": "^16.9.0",
|
||||
"@types/react-redux": "^7.1.8",
|
||||
"@types/react-router-dom": "^5.1.5",
|
||||
"@typescript-eslint/eslint-plugin": "^2.34.0",
|
||||
"@typescript-eslint/parser": "^2.34.0",
|
||||
"cypress": "^4.5.0",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-jsx-a11y": "^6.2.3",
|
||||
"eslint-plugin-react": "^7.20.0",
|
||||
"eslint-plugin-react-hooks": "^4.0.2",
|
||||
"firebase": "^7.14.3",
|
||||
"moment": "^2.25.3",
|
||||
"react": "^16.13.1",
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ export const dummyDev: IDev = {
|
|||
name: 'Repo #1',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugit,deserunt.',
|
||||
link: '#',
|
||||
url: '#',
|
||||
stars: 42,
|
||||
watchers: 2,
|
||||
forks: 4,
|
||||
|
|
@ -137,7 +137,7 @@ export const dummyDev: IDev = {
|
|||
name: 'Repo #2',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugit,deserunt.',
|
||||
link: '#',
|
||||
url: '#',
|
||||
stars: 21,
|
||||
watchers: 1,
|
||||
forks: 2,
|
||||
|
|
@ -146,7 +146,7 @@ export const dummyDev: IDev = {
|
|||
name: 'Repo #3',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugit,deserunt.',
|
||||
link: '#',
|
||||
url: '#',
|
||||
stars: 50,
|
||||
watchers: 32,
|
||||
forks: 12,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import Alert from '../components/Alert';
|
|||
import Statuses from '../constants/statuses';
|
||||
// Form
|
||||
import useForm from '../hooks';
|
||||
import getGithubRepos from '../services/github';
|
||||
// Typing
|
||||
import Dev from '../models/Dev';
|
||||
import User from '../models/User';
|
||||
|
|
@ -75,7 +76,7 @@ const EditProfile: FC<IProps> = ({
|
|||
const {formData, handleChange} = useForm<FormData>(initFormData);
|
||||
|
||||
/** construct profile object from formData */
|
||||
const makeProfile = ({
|
||||
const makeProfile = async ({
|
||||
status,
|
||||
company,
|
||||
location,
|
||||
|
|
@ -99,6 +100,7 @@ const EditProfile: FC<IProps> = ({
|
|||
youtube: parseLink(youtube),
|
||||
};
|
||||
const newSkills: string[] = skills?.split(',');
|
||||
const newRepos = await getGithubRepos(github);
|
||||
return {
|
||||
status,
|
||||
company,
|
||||
|
|
@ -107,12 +109,13 @@ const EditProfile: FC<IProps> = ({
|
|||
github,
|
||||
links: newLinks,
|
||||
skills: newSkills,
|
||||
repos: newRepos,
|
||||
};
|
||||
};
|
||||
|
||||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => {
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
const updatedDev = makeProfile(formData);
|
||||
const updatedDev = await makeProfile(formData);
|
||||
try {
|
||||
firebase.updateProfile(updatedDev, {useSet: true, merge: true});
|
||||
setAlert({
|
||||
|
|
@ -122,6 +125,7 @@ const EditProfile: FC<IProps> = ({
|
|||
'Profile successfully updated. You may go back to your dashboard.',
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setAlert({...alert, show: true});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
|||
import {faThumbsUp} from '@fortawesome/free-solid-svg-icons';
|
||||
import Header from '../components/Header';
|
||||
// Typing
|
||||
import Post, {dummyPost as post} from '../models/Post';
|
||||
import Post from '../models/Post';
|
||||
import Collections from '../constants/collections';
|
||||
|
||||
interface IProps extends WithFirestoreProps {
|
||||
|
|
|
|||
|
|
@ -46,9 +46,6 @@ const Profile: FC<IProps> = ({dev}) => {
|
|||
return <NotFound />;
|
||||
}
|
||||
|
||||
const fn = dev?.description;
|
||||
console.log(fn);
|
||||
|
||||
/** return the icon corresponding to the social name */
|
||||
const renderSocialIcon = (name: string): IconDefinition => {
|
||||
switch (name) {
|
||||
|
|
@ -192,23 +189,23 @@ const Profile: FC<IProps> = ({dev}) => {
|
|||
</div>
|
||||
) : (
|
||||
dev.repos.map((r: Repo, i: number) => (
|
||||
<div className="repo bg-white my-1 p-1">
|
||||
<div className="repo bg-white my-1 p-1" key={i}>
|
||||
<div>
|
||||
<h4>
|
||||
<a href={r.link}>{r.name}</a>
|
||||
<a href={r.url}>{r.name}</a>
|
||||
</h4>
|
||||
<p>{r.description}</p>
|
||||
</div>
|
||||
<div>
|
||||
<ul>
|
||||
<li className="badge badge-primary">
|
||||
<FontAwesomeIcon icon={faStar} /> Stars: 42
|
||||
<FontAwesomeIcon icon={faStar} /> Stars: {r.stars}
|
||||
</li>
|
||||
<li className="badge badge-dark">
|
||||
<FontAwesomeIcon icon={faEye} /> Watchers: 2
|
||||
<FontAwesomeIcon icon={faEye} /> Watchers: {r.watchers}
|
||||
</li>
|
||||
<li className="badge badge-light">
|
||||
<FontAwesomeIcon icon={faCodeBranch} /> Forks: 4
|
||||
<FontAwesomeIcon icon={faCodeBranch} /> Forks: {r.forks}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
35
src/services/github/index.ts
Normal file
35
src/services/github/index.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Github
|
||||
import {Octokit} from '@octokit/rest';
|
||||
import Repo from '../../types/Repo';
|
||||
|
||||
/** official GitHub wrapper library */
|
||||
const octokit = new Octokit({
|
||||
auth: process.env.REACT_APP_GITHUB_TOKEN,
|
||||
userAgent: 'devBook v1',
|
||||
});
|
||||
|
||||
/**
|
||||
* fetch one user github repos and create a
|
||||
* @param owner githubusername
|
||||
* @returns a Repo array or undefined
|
||||
*/
|
||||
const getGithubRepos = async (owner: string) => {
|
||||
try {
|
||||
const {data: repos} = await octokit.repos.listForAuthenticatedUser({
|
||||
owner,
|
||||
});
|
||||
const newRepo: Repo[] = repos.map((r: any) => ({
|
||||
url: r.url,
|
||||
stars: r.stargazers_count,
|
||||
forks: r.forks_count,
|
||||
description: r.description,
|
||||
name: r.name,
|
||||
watchers: r.watchers_count,
|
||||
}));
|
||||
return newRepo;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
};
|
||||
|
||||
export default getGithubRepos;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
interface Repo {
|
||||
name: string;
|
||||
description: string;
|
||||
link: string;
|
||||
url: string;
|
||||
stars: number;
|
||||
watchers: number;
|
||||
forks: number;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"target": "es2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
|
|
@ -19,7 +15,5 @@
|
|||
"noEmit": true,
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
|
|||
63
tslint.json
63
tslint.json
|
|
@ -1,63 +0,0 @@
|
|||
{
|
||||
"rules": {
|
||||
"adjacent-overload-signatures": true,
|
||||
"ban-comma-operator": true,
|
||||
"no-namespace": true,
|
||||
"no-parameter-reassignment": true,
|
||||
"no-reference": true,
|
||||
"no-unnecessary-type-assertion": true,
|
||||
"label-position": true,
|
||||
"no-conditional-assignment": true,
|
||||
"no-construct": true,
|
||||
"no-duplicate-super": true,
|
||||
"no-duplicate-switch-case": true,
|
||||
"no-duplicate-variable": [
|
||||
true,
|
||||
"check-parameters"
|
||||
],
|
||||
"no-shadowed-variable": true,
|
||||
"no-empty": [
|
||||
true,
|
||||
"allow-empty-catch"
|
||||
],
|
||||
"no-floating-promises": true,
|
||||
"no-implicit-dependencies": true,
|
||||
"no-invalid-this": true,
|
||||
"no-string-throw": true,
|
||||
"no-unsafe-finally": true,
|
||||
"no-void-expression": [
|
||||
true,
|
||||
"ignore-arrow-function-shorthand"
|
||||
],
|
||||
"no-duplicate-imports": true,
|
||||
// Warn when an empty interface is defined. These are generally not useful.
|
||||
"no-empty-interface": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"no-import-side-effect": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"no-var-keyword": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"triple-equals": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"deprecation": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"prefer-for-of": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"unified-signatures": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"prefer-const": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"trailing-comma": {
|
||||
"severity": "warning"
|
||||
}
|
||||
},
|
||||
"defaultSeverity": "error"
|
||||
}
|
||||
Loading…
Reference in a new issue