Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
17,760 changes: 17,760 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "gitstar-clone",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.19.0",
"prop-types": "^15.7.2",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"react-scripts": "^3.4.1",
"styled-components": "^4.4.0",
"styled-reset": "^4.1.2",
"uuid": "^3.3.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"prettier"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

package sorting 까지 디테일하게 챙기는편은 아니지만 devDependenciesDependencies는 붙여서 보여주는 것이 보기 더 좋을 것 같아요!

"eslint": "^6.6.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-prettier": "^6.4.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.16.0",
"eslint-plugin-react-hooks": "^1.7.0"
}
}
Binary file added public/favicon.ico
Binary file not shown.
43 changes: 43 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
25 changes: 25 additions & 0 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
2 changes: 2 additions & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
14 changes: 14 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import Search from './containers/Search';
import GlobalStyle from './styles/GlobalStyle';

const App = () => {
return (
<>
<Search />
<GlobalStyle />
</>
);
};

export default App;
23 changes: 23 additions & 0 deletions src/components/ErrorMessage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const S = {
Container: styled.div`
width: 100%;
padding: 1rem 2rem;
background-color: #e99002;
color: #fff;
`,
};
Comment on lines +5 to +12

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 이렇게 객체로 선언해서 쓰는건 처음보네요 🧐

Copy link
Author

@jus0k jus0k Apr 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Styled Component를 사용한 컴포넌트랑 일반 컴포넌트를 분리하려고 전에는 Styled 접두사를 붙였었는데요! 이렇게 하면 간단하게 구분할 수 있어서 좋은 것 같아요 ㅎㅎ 단점은 객체다 보니까 없는 속성 써도 린트에서 잡아내지 못한다는 점?이 있습니다!


const ErrorMessage = ({ errorName }) => {
const errorMessage = `User ${errorName} is not found.`;
return <S.Container>{errorMessage}</S.Container>;
};
Comment on lines +14 to +17

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요건 뭔가 요런식으로 써도 되지 않을까 하는 🙈
(개취에욬ㅋㅋ)

Suggested change
const ErrorMessage = ({ errorName }) => {
const errorMessage = `User ${errorName} is not found.`;
return <S.Container>{errorMessage}</S.Container>;
};
const ErrorMessage = ({ errorName }) => (<S.Container>User {errorName} is not found.</S.Container>);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 이거 아마 프리티어랑 린트가 제대로 동작을 안해서 이렇게 했던 것 같네요 ㅎ후ㅜ


ErrorMessage.propTypes = {
errorName: PropTypes.string.isRequired,
};
Comment on lines +19 to +21

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

propTypes 정의 해주는거 멋지십니다 👍


export default ErrorMessage;
20 changes: 20 additions & 0 deletions src/components/Frame.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Container = styled.div`
width: 100%;
max-width: 940px;
margin: auto;
padding: 5rem 0;
`;

const Frame = ({ children }) => {
return <Container>{children}</Container>;
};

Frame.propTypes = {
children: PropTypes.arrayOf(PropTypes.object).isRequired,
};

export default Frame;
44 changes: 44 additions & 0 deletions src/components/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import InputField from './InputField';

const S = {
Container: styled.div`
width: 100%;
padding: 3rem;
background-color: #fafafa;
box-sizing: border-box;
margin-bottom: 3rem;
`,
Title: styled.h1`
font-size: 4rem;
margin-bottom: 1rem;
`,
SubTitle: styled.h2`
font-size: 1.5rem;
font-weight: lighter;
margin-bottom: 1rem;
`,
};

const Header = ({ value, setValue, onSubmit }) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Header component의 props 이름으로 value, setValue, onSubmit보다 의미를 더 명확히 하는 네이밍은 어떤가요??

value -> username, setValue -> changeUsername, onSubmit -> searchUsername
이런 식으로 값의 주체를 명확히 해주는게 의미파악이 분명해질 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 넵 좋네요! 그럼 set보다 change라고 쓰는 이유가 있으신가요?! 지수님의 네이밍 규칙이 궁금하네요 ㅎㅎ

return (
<S.Container>
<S.Title>Gitstar Ranking</S.Title>
<S.SubTitle>
Unofficial GitHub star ranking for users, organizations and
repositories.
</S.SubTitle>
<InputField value={value} setValue={setValue} onSubmit={onSubmit} />
</S.Container>
Comment on lines +6 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 이렇게 styled-component를 이렇게 namespace로 사용하는거 좋은 거 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네! 요래 하면 깔끔하게 적을 수 있는데 단점은 객체의 프로퍼티로 읽다보니 없는 프로퍼티를 린트에서 잡아내지 못한다는 점입니다 ㅜ

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jus0k

확실하진 않은데, 요거 TS에서는 잡을 수 있는 것으로 알아요!
Welcome to TS world 🎉

);
};

Header.propTypes = {
value: PropTypes.string.isRequired,
setValue: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
};

export default Header;
48 changes: 48 additions & 0 deletions src/components/InputField.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const S = {
Container: styled.form``,
Input: styled.input`
padding: 1rem 1rem;
border: 1px solid #eaeaea;
font-size: 0.875rem;
width: 100%;
max-width: 380px;
`,
Button: styled.input`
padding: 1rem 2rem;
font-size: 0.875rem;
background-color: #eaeaea;
outline: none;
border: none;
`,
};

const InputField = ({ onSubmit, value, setValue }) => {
const handleChange = event => {
setValue(event.target.value);
};

return (
<S.Container onSubmit={onSubmit}>
<S.Input
name="username"
type="text"
value={value}
onChange={handleChange}
placeholder="Github username"
/>
<S.Button type="submit" value="Search" />
</S.Container>
);
};

InputField.propTypes = {
value: PropTypes.string.isRequired,
setValue: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
};

export default InputField;
50 changes: 50 additions & 0 deletions src/components/Loading.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';
import styled from 'styled-components';

const S = {
Container: styled.div`
width: 100%;
`,
Loader: styled.svg`
enable-background: new 0 0 50 50;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우와 처음보는 속성인데 신기하네요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

svg는 가져다가 쓴거라 저도 잘 모르겠습니닷 ㅎㅎ후

position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
`,
};

const Loading = () => (
<S.Container>
<S.Loader
version="1.1"
id="loader-1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
width="40px"
height="40px"
viewBox="0 0 50 50"
xmlSpace="preserve"
>
<path
fill="#000"
d="M43.935,25.145c0-10.318-8.364-18.683-18.683-18.683c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615c8.072,0,14.615,6.543,14.615,14.615H43.935z"
style={{ fill: '#D8D8D8' }}
>
<animateTransform
attributeType="xml"
attributeName="transform"
type="rotate"
from="0 25 25"
to="360 25 25"
dur="0.6s"
repeatCount="indefinite"
/>
</path>
</S.Loader>
Comment on lines +19 to +46

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

svg 커스텀하시는거 짱 멋있어요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거는 로딩 인디케이터 가져다가 썼습니다! 제가 한 것은 아니에요 ㅎㅎ

</S.Container>
);

export default Loading;
45 changes: 45 additions & 0 deletions src/components/RepositoryItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import starImg from '../image/star.svg';

const S = {
Container: styled.div`
width: 100%;
padding: 1rem;
border: 1px solid #ededed;
display: flex;
flex-direction: row;
box-sizing: border-box;
margin-bottom: -1px;
`,
Star: styled.div`
margin-left: auto;
`,
Icon: styled.img`
width: 0.875rem;
`,
Name: styled.div`
font-size: 0.875rem;
`,
StarNumber: styled.span`
margin-left: 0.5rem;
`,
};

const RepositoryItem = ({ name, star }) => (
<S.Container>
<S.Name>{name}</S.Name>
<S.Star>
<S.Icon src={starImg} alt="star icon" />
<S.StarNumber>{star}</S.StarNumber>
</S.Star>
</S.Container>
);

RepositoryItem.propTypes = {
name: PropTypes.string.isRequired,
star: PropTypes.number.isRequired,
};

export default RepositoryItem;
Loading