├── .gitignore
├── LICENSE
├── README.md
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── package.json
├── src
├── components
│ ├── common
│ │ ├── ProgressBar.tsx
│ │ └── index.tsx
│ ├── layout.css
│ ├── layout.tsx
│ ├── sections
│ │ ├── about.tsx
│ │ ├── action.tsx
│ │ ├── careers.tsx
│ │ ├── index.tsx
│ │ ├── profile.tsx
│ │ └── skills.tsx
│ └── seo.tsx
├── images
│ └── gatsby-icon.png
├── models
│ └── index.ts
└── pages
│ ├── 404.tsx
│ └── index.tsx
├── static
├── profile-yaml.png
├── resumes
│ ├── chick.png
│ └── john-doe.yaml
└── simple-resume.png
├── tsconfig.json
├── tslint.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # dotenv environment variables file
55 | .env
56 |
57 | # gatsby files
58 | .cache/
59 | public
60 |
61 | # Mac files
62 | .DS_Store
63 |
64 | # Yarn
65 | yarn-error.log
66 | .pnp/
67 | .pnp.js
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 gatsbyjs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 |
5 | 🐤️ Simple-resume
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Overview
17 | Simple-resume은 React+Gatsby와 yaml을 통해 편리하고 빠르게 이력서를 작성 할 수 있습니다.
18 |
19 |

20 |
21 |
22 | ## Installation
23 |
24 | ```shell
25 | $ git clone https://github.com/suites/simple-resume.git
26 | $ cd simple-resume
27 | $ yarn install
28 | ```
29 |
30 | 1. 프로젝트를 clone합니다.
31 | ```shell
32 | $ git clone https://github.com/suites/simple-resume.git
33 | ```
34 | 2. simple-resume 폴더로 이동합니다. `cd simple-resume`
35 | 3. yarn을 통해 package를 설치합니다. `yarn install`
36 |
37 | ## How to use
38 | ```shell
39 | $ npm run start
40 | ```
41 | - run your program, go to http://localhost:8000
42 |
43 | 1. static/resumes/john-doe.yaml 파일을 복사하여 새로운 profile.yaml을 작성합니다.
44 |
45 | 2. gatsby-config.js 에서 해당 코드의 path부분을 본인의 yaml 파일로 지정합니다.
46 |
47 | 3. ```json
48 | `gatsby-transformer-yaml`,
49 | {
50 | resolve: `gatsby-source-filesystem`,
51 | options: {
52 | path: `./static/resumes/resume.yaml`,
53 | },
54 | },
55 | ```
56 |
57 | 3. http://localhost:8000 에서 이력서를 확인할 수 있습니다.
58 |
59 | ## Demo
60 | * simple-resume
61 |
62 |
63 |
64 | ## Contributing
65 |
66 | This is an open source product, please feel free to fork and make pull requests!
67 |
68 | Any suggestions are welcomed!
69 |
70 | ## Authors
71 |
72 | [yoon.homme](https://github.com/suites)
73 |
74 | ## License
75 |
76 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
--------------------------------------------------------------------------------
/gatsby-browser.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Implement Gatsby's Browser APIs in this file.
3 | *
4 | * See: https://www.gatsbyjs.org/docs/browser-apis/
5 | */
6 |
7 | // You can delete this file if you're not using it
8 |
--------------------------------------------------------------------------------
/gatsby-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | siteMetadata: {
3 | title: `Resume - John Doe`,
4 | description: `This is a resume of software engineer John Doe.`,
5 | author: `John Doe`,
6 | },
7 | plugins: [
8 | `gatsby-plugin-react-helmet`,
9 | {
10 | resolve: `gatsby-source-filesystem`,
11 | options: {
12 | name: `images`,
13 | path: `${__dirname}/src/images`,
14 | },
15 | },
16 | `gatsby-transformer-sharp`,
17 | `gatsby-plugin-typescript`,
18 | `gatsby-plugin-sharp`,
19 | {
20 | resolve: `gatsby-plugin-manifest`,
21 | options: {
22 | name: `gatsby-starter-default`,
23 | short_name: `starter`,
24 | start_url: `/`,
25 | background_color: `#663399`,
26 | theme_color: `#663399`,
27 | display: `minimal-ui`,
28 | icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
29 | },
30 | },
31 | `gatsby-transformer-yaml`,
32 | {
33 | resolve: `gatsby-source-filesystem`,
34 | options: {
35 | path: `./static/resumes/john-doe.yaml`,
36 | },
37 | },
38 | // this (optional) plugin enables Progressive Web App + Offline functionality
39 | // To learn more, visit: https://gatsby.dev/offline
40 | // `gatsby-plugin-offline`,
41 | ],
42 | }
43 |
--------------------------------------------------------------------------------
/gatsby-node.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Implement Gatsby's Node APIs in this file.
3 | *
4 | * See: https://www.gatsbyjs.org/docs/node-apis/
5 | */
6 |
7 | // You can delete this file if you're not using it
8 |
--------------------------------------------------------------------------------
/gatsby-ssr.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
3 | *
4 | * See: https://www.gatsbyjs.org/docs/ssr-apis/
5 | */
6 |
7 | // You can delete this file if you're not using it
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simple-resume",
3 | "private": true,
4 | "description": "Simple resume",
5 | "version": "0.1.0",
6 | "author": "yoon.homme ",
7 | "dependencies": {
8 | "@types/react-helmet": "^5.0.9",
9 | "@types/react-linkify": "^0.2.0",
10 | "@types/styled-components": "^4.1.18",
11 | "babel-preset-gatsby": "^1.0.0",
12 | "gatsby": "^3.0.3",
13 | "gatsby-image": "^3.0.0",
14 | "gatsby-plugin-manifest": "^3.0.0",
15 | "gatsby-plugin-offline": "^3.0.0",
16 | "gatsby-plugin-react-helmet": "^4.0.0",
17 | "gatsby-plugin-sharp": "^3.0.0",
18 | "gatsby-plugin-typescript": "^3.0.0",
19 | "gatsby-source-filesystem": "^3.0.0",
20 | "gatsby-transformer-sharp": "^3.0.0",
21 | "gatsby-transformer-yaml": "^3.0.0",
22 | "prop-types": "^15.7.2",
23 | "react": "^17.0.0",
24 | "react-dom": "^16.9.0",
25 | "react-helmet": "^5.2.1",
26 | "react-icons": "^3.7.0",
27 | "react-linkify": "^1.0.0-alpha",
28 | "styled-components": "^4.3.2",
29 | "typescript": "^3.5.3"
30 | },
31 | "devDependencies": {
32 | "prettier": "^1.18.2"
33 | },
34 | "keywords": [
35 | "gatsby"
36 | ],
37 | "license": "MIT",
38 | "scripts": {
39 | "build": "gatsby build",
40 | "develop": "gatsby develop",
41 | "format": "prettier --write \"**/*.{js,jsx,json,md}\"",
42 | "start": "npm run develop",
43 | "serve": "gatsby serve",
44 | "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\""
45 | },
46 | "repository": {
47 | "type": "git",
48 | "url": "https://github.com/gatsbyjs/simple-resume"
49 | },
50 | "bugs": {
51 | "url": "https://github.com/gatsbyjs/gatsby/issues"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/components/common/ProgressBar.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styled from 'styled-components';
3 |
4 | const ProgressContainer = styled.div`
5 | width: 100%;
6 | height: 8px;
7 | background: #ccc;
8 | `;
9 |
10 | const Progress = styled.div`
11 | height: 8px;
12 | background: #3a7bd5;
13 | width: ${(props: { scrolled: string }) => props.scrolled};
14 | `;
15 |
16 | export class ProgressBar extends React.Component<{}, { scrolled: string }> {
17 | constructor(props: {}) {
18 | super(props);
19 | this.state = {
20 | scrolled: '0%',
21 | };
22 | }
23 |
24 | componentDidMount() {
25 | window.addEventListener('scroll', this.scrollProgress);
26 | }
27 |
28 | componentWillUnmount() {
29 | window.removeEventListener('scroll', this.scrollProgress);
30 | }
31 |
32 | scrollProgress = () => {
33 | const scrollPx = document.documentElement.scrollTop;
34 | const winHeightPx =
35 | document.documentElement.scrollHeight -
36 | document.documentElement.clientHeight;
37 | const scrolled = `${scrollPx / winHeightPx * 100}%`;
38 |
39 | this.setState({
40 | scrolled,
41 | });
42 | }
43 | render() {
44 | return (
45 |
46 |
47 |
48 | );
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/components/common/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import * as icons from 'react-icons/fa';
3 | import styled from 'styled-components';
4 |
5 | export * from './ProgressBar';
6 | export const Section = styled.section`
7 | padding: 0 2rem;
8 | `;
9 |
10 | export const SectionTitle = styled.h2`
11 | `;
12 |
13 | const StyledHeadline = styled.div`
14 | display: -webkit-box;
15 | display: -ms-flexbox;
16 | display: flex;
17 | border-bottom: 2px solid #3a7bd5;
18 | `;
19 |
20 | export const HeadLine = ({ icon, title }: { icon: string, title: string }) => {
21 | return (
22 |
23 |
24 |
30 | {title}
31 |
32 |
33 | );
34 | };
35 |
36 | export const Contents = styled.div`
37 | padding: 1rem 0rem 1rem;
38 | border-bottom: 1px solid #eeeeee;
39 | `;
40 |
41 | export const Row = styled(Contents)`
42 | display: flex;
43 | `;
44 |
45 | export const RowLeft = styled.div`
46 | flex-basis: 18rem;
47 | padding-right: 1rem;
48 | flex-shrink: 0;
49 | `;
50 |
51 | export const RowRight = styled.div`
52 | flex-grow: 1;
53 | `;
54 |
55 | export const StyledUl = styled.ul`
56 | list-style:none;
57 | padding:0;
58 | margin:0 0 1rem;
59 | font-size:1.1rem;
60 | `;
61 |
62 | export const ALink = styled.a`
63 | color: #3a7bd5;
64 | transition: color 0.3s ease;
65 | &:hover {
66 | color: #00d2ff;
67 | }
68 | `;
69 |
70 | export const StyledLi = styled.li`
71 | ${StyledUl} > & {
72 | position:relative;
73 | padding:.2rem 0 0rem 1rem;
74 | }
75 | &:before {
76 | position:absolute;
77 | left:0;
78 | display:inline-block;
79 | content:"•";
80 | color:#3a7bd5;
81 | }
82 | `;
83 |
84 | export const StyledH2 = styled.h2`
85 | font-size:2.5rem;
86 | margin:3rem 0 2rem;
87 | `;
88 |
89 | export const StyledH3 = styled.h3`
90 | font-size: 2rem;
91 | margin: 0 0 1rem 0;
92 | `;
93 |
94 | export const StyledH4 = styled.h4`
95 | font-size: 1.5rem;
96 | margin: 1rem 0 1rem 0;
97 | `;
98 |
99 | export const StyledH5 = styled.h5`
100 | font-size: 1.3rem;
101 | margin: 0.5rem 0 0.5rem 0;
102 | color: #333333;
103 | `;
104 |
105 | interface FaIconProps {
106 | icon: string;
107 | verticalAlign?: string;
108 | marginLeft?: string;
109 | marginRight?: string;
110 | size?: string;
111 | }
112 |
113 | export const FaIcon = ({ icon, verticalAlign, marginRight, marginLeft, size }: FaIconProps) => {
114 | try {
115 | const Result = (icons as any)[icon];
116 | return (
117 |
118 | );
119 | } catch {
120 | return <>>;
121 | }
122 |
123 | };
124 |
125 | interface DateProps {
126 | start: string;
127 | end?: string;
128 | }
129 |
130 | export const Date = ({ start, end }: DateProps) => {
131 | return (
132 |
133 |
136 | {
137 | end &&
138 | <>
139 | -
140 |
143 | >
144 | }
145 |
146 | );
147 | };
148 |
149 | export const StyledTime = styled.span`
150 | display: block;
151 | margin-bottom: 1.5rem;
152 | `;
153 |
154 | export const StyledP = styled.p`
155 | margin: 0 0 1rem 0;
156 | font-size: 1.1rem;
157 | line-height: 1.4;
158 | `;
159 |
--------------------------------------------------------------------------------
/src/components/layout.css:
--------------------------------------------------------------------------------
1 | @import url(//spoqa.github.io/spoqa-han-sans/css/SpoqaHanSans-kr.css);
2 | @import url(//spoqa.github.io/spoqa-han-sans/css/SpoqaHanSans-jp.css);
3 |
4 | ::selection {
5 | background: #00d2ff;
6 | }
7 |
8 | html, body, div, span, applet, object, iframe,
9 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
10 | a, abbr, acronym, address, big, cite, code,
11 | del, dfn, em, img, ins, kbd, q, s, samp,
12 | small, strike, strong, sub, sup, tt, var,
13 | b, u, i, center,
14 | dl, dt, dd, ol, ul, li,
15 | fieldset, form, label, legend,
16 | table, caption, tbody, tfoot, thead, tr, th, td,
17 | article, aside, canvas, details, embed,
18 | figure, figcaption, footer, header, hgroup,
19 | menu, nav, output, ruby, section, summary,
20 | time, mark, audio, video {
21 | margin: 0;
22 | padding: 0;
23 | border: 0;
24 | font-size: 100%;
25 | vertical-align: baseline;
26 | }
27 | /* HTML5 display-role reset for older browsers */
28 | article, aside, details, figcaption, figure,
29 | footer, header, hgroup, menu, nav, section {
30 | display: block;
31 | }
32 | body {
33 | font-size: 16px;
34 | word-break: keep-all;
35 | font-family: Spoqa Han Sans, sans-serif;
36 | letter-spacing: -0.3px;
37 | color: #222222;
38 | padding-bottom: 2rem;
39 | overflow-x: hidden;
40 | -webkit-font-smoothing: antialiased;
41 | -moz-osx-font-smoothing: grayscale;
42 | }
43 | ol, ul {
44 | list-style: none;
45 | }
46 | blockquote, q {
47 | quotes: none;
48 | }
49 | blockquote:before, blockquote:after,
50 | q:before, q:after {
51 | content: '';
52 | content: none;
53 | }
54 | table {
55 | border-collapse: collapse;
56 | border-spacing: 0;
57 | }
58 | a {
59 | color: #3a7bd5;
60 | transition: color 0.3s ease;
61 | }
62 | a:hover {
63 | color: #00d2ff;
64 | }
65 |
66 | * {
67 | box-sizing: border-box;
68 | }
--------------------------------------------------------------------------------
/src/components/layout.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { graphql, useStaticQuery } from 'gatsby';
4 | import styled from 'styled-components';
5 | import Resume from '../models';
6 | import { ProgressBar } from './common';
7 | import './layout.css';
8 | import { ActionComponent, Careers, Profile, Skills } from './sections';
9 | import { About } from './sections/about';
10 |
11 | const Header = styled.div`
12 | position: fixed;
13 | top: 0;
14 | z-index: 1;
15 | width: 100%;
16 | background-color: #f1f1f1;
17 | `;
18 |
19 | const Container = styled.div`
20 | width: 100%;
21 | max-width: 50rem;
22 | margin: auto;
23 | `;
24 |
25 | const Layout = () => {
26 | const data = useStaticQuery(graphql`
27 | query {
28 | allResumesYaml {
29 | edges {
30 | node {
31 | experiences {
32 | name
33 | information
34 | date {
35 | start
36 | end
37 | }
38 | description
39 | }
40 | educations {
41 | name
42 | date {
43 | start
44 | end
45 | }
46 | description
47 | }
48 | licenses {
49 | name
50 | information
51 | date {
52 | start
53 | end
54 | }
55 | description
56 | }
57 | }
58 | }
59 | }
60 | }
61 | `);
62 | const resume: Resume = data.allResumesYaml.edges[0].node;
63 |
64 | return (
65 | <>
66 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | >
79 | );
80 | };
81 |
82 | export default Layout;
83 |
--------------------------------------------------------------------------------
/src/components/sections/about.tsx:
--------------------------------------------------------------------------------
1 | import { graphql, useStaticQuery } from 'gatsby';
2 | import React from 'react';
3 | import Linkify from 'react-linkify';
4 | import Resume from '../../models';
5 | import { Contents, HeadLine, Section, StyledH4, StyledH5 } from '../common';
6 | export const About = () => {
7 | const data = useStaticQuery(graphql`
8 | query {
9 | allResumesYaml {
10 | edges {
11 | node {
12 | aboutme
13 | }
14 | }
15 | }
16 | }
17 | `);
18 | const resume: Resume = data.allResumesYaml.edges[0].node;
19 |
20 | return (
21 |
22 |
23 |
24 |
25 | {
26 | resume.aboutme.map((value, i) => {
27 | const Sentence =
28 | value.includes('##') && {value.replace('##', '')}
29 | || value.includes('#') && {value.replace('#', '')}
30 | || {value}
;
31 | return (
32 | Sentence
33 | );
34 | })
35 | }
36 |
37 |
38 |
39 | );
40 | };
41 |
--------------------------------------------------------------------------------
/src/components/sections/action.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Linkify from 'react-linkify';
3 | import styled from 'styled-components';
4 | import { Action } from '../../models';
5 | import { Contents, Date, HeadLine, Section, StyledH3 } from '../common';
6 |
7 | interface Props {
8 | title: string;
9 | icon: string;
10 | actions: Action[];
11 | }
12 |
13 | const Information = styled.span`
14 | `;
15 |
16 | const Text = styled.p`
17 | `;
18 |
19 | export const ActionComponent = ({ title, icon, actions }: Props) => {
20 | return (
21 |
22 |
23 | {actions && actions.map((action, i) => {
24 | return (
25 |
26 | {action.name}
27 | {action.information}
28 | {
29 | action.date &&
30 |
31 | }
32 |
33 | {
34 | action.description &&
35 | action.description.map((value, j) => {
36 | return (
37 | {value}
38 | );
39 | })
40 | }
41 |
42 |
43 | );
44 | })}
45 |
46 | );
47 | };
48 |
--------------------------------------------------------------------------------
/src/components/sections/careers.tsx:
--------------------------------------------------------------------------------
1 | import { graphql, useStaticQuery } from 'gatsby';
2 | import React from 'react';
3 | import Resume, { Career, Project } from '../../models';
4 | import { Date, FaIcon, HeadLine, Row, RowLeft, RowRight, Section, StyledH3, StyledH4, StyledH5, StyledLi, StyledP, StyledUl } from '../common';
5 |
6 | const TechStack = ({ career }: { career: Career }) => {
7 | return (
8 | <>
9 | {'Tech Stacks'}
10 |
11 | {career.techStacks.map((techStack, i) => {
12 | return (
13 |
14 | {`${techStack.name} : ${techStack.items.join(', ')}`}
15 |
16 | );
17 | })
18 | }
19 |
20 | >
21 | );
22 | };
23 |
24 | const ProjectComponent = ({ projects }: { projects: Project[] }) => {
25 | return (
26 | <>
27 | {
28 | projects.map((project, i) => {
29 | return (
30 |
31 |
32 |
39 | {project.name}
40 |
41 | {
42 | project.date &&
43 |
44 | }
45 | Descrition
46 | {project.description} StyledP>
47 | What did I do
48 |
49 | {project.parts.map((part, j) => {
50 | return (
51 |
52 | {part}
53 |
54 | );
55 | })}
56 |
57 |
58 | );
59 | })
60 | }
61 | >
62 | );
63 | };
64 |
65 | export const Careers = () => {
66 | const data = useStaticQuery(graphql`
67 | query {
68 | allResumesYaml {
69 | edges {
70 | node {
71 | careers {
72 | name
73 | information
74 | date {
75 | start
76 | end
77 | }
78 | techStacks {
79 | name
80 | items
81 | }
82 | projects {
83 | name
84 | date {
85 | start
86 | end
87 | }
88 | description
89 | parts
90 | }
91 | }
92 | }
93 | }
94 | }
95 | }
96 | `);
97 | const resume: Resume = data.allResumesYaml.edges[0].node;
98 |
99 | return (
100 |
101 |
102 | {
103 | resume.careers.map((career, i) => {
104 | return (
105 |
106 |
107 | {career.name}
108 | {career.information}
109 | {
110 | career.date &&
111 |
112 | }
113 |
114 |
115 |
116 |
117 |
118 |
119 | );
120 | })
121 | }
122 |
123 | );
124 | };
125 |
--------------------------------------------------------------------------------
/src/components/sections/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './profile';
2 | export * from './skills';
3 | export * from './careers';
4 | export * from './action';
5 | export * from './about';
6 |
--------------------------------------------------------------------------------
/src/components/sections/profile.tsx:
--------------------------------------------------------------------------------
1 | import { graphql, useStaticQuery } from 'gatsby';
2 | import React from 'react';
3 | import styled from 'styled-components';
4 | import Resume from '../../models';
5 | import { ALink, FaIcon, Row, RowLeft, RowRight, Section, StyledH2, StyledLi, StyledUl } from '../common';
6 |
7 | const Sentence = styled.div`
8 | `;
9 |
10 | const Introduction = styled.div`
11 | padding: 2rem 0 0rem;
12 | border-bottom: 0px;
13 | & > ${Sentence} {
14 | margin: 0 0 1rem 0;
15 | font-size: 2rem;
16 | line-height: 1.4;
17 | font-weight: 500;
18 | }
19 | `;
20 |
21 | const ProfileRow = styled(Row)`
22 | padding: 2rem 0 0rem;
23 | border-bottom: 0px;
24 | `;
25 |
26 | const Name = styled(StyledH2)`
27 | margin-top: 0px;
28 | `;
29 |
30 | const Address = styled(StyledUl)`
31 | list-style-type: none;
32 | `;
33 |
34 | const AddressItem = styled(StyledLi)`
35 | ${Address} > & {
36 | padding: .6rem 0 .2rem 0;
37 | }
38 | &::before{
39 | content:none;
40 | }
41 | `;
42 |
43 | export const Profile = () => {
44 | const data = useStaticQuery(graphql`
45 | query {
46 | allResumesYaml {
47 | edges {
48 | node {
49 | photo
50 | name
51 | links {
52 | type
53 | name
54 | symbol
55 | }
56 | introduction
57 | }
58 | }
59 | }
60 | }
61 | `);
62 | const resume: Resume = data.allResumesYaml.edges[0].node;
63 |
64 | return (
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | {resume.name}
73 |
74 |
75 | {
76 | resume.links.map((value, i) => {
77 | return (
78 |
79 |
84 | {value.name}
85 |
86 | );
87 | })
88 | }
89 |
90 |
91 |
92 |
93 | {
94 | resume.introduction.map((value, i) => {
95 | return {value};
96 | })
97 | }
98 |
99 |
100 | );
101 | };
102 |
--------------------------------------------------------------------------------
/src/components/sections/skills.tsx:
--------------------------------------------------------------------------------
1 | import { graphql, useStaticQuery } from 'gatsby';
2 | import React from 'react';
3 | import Resume from '../../models';
4 | import { HeadLine, Row, RowLeft, RowRight, Section, StyledH3, StyledLi, StyledUl } from '../common';
5 |
6 | export const Skills = () => {
7 | const data = useStaticQuery(graphql`
8 | query {
9 | allResumesYaml {
10 | edges {
11 | node {
12 | skills {
13 | name
14 | items
15 | }
16 | }
17 | }
18 | }
19 | }
20 | `);
21 | const resume: Resume = data.allResumesYaml.edges[0].node;
22 |
23 | return (
24 |
25 |
26 | {
27 | resume.skills.map((value, i) => {
28 | return (
29 |
30 |
31 | {value.name}
32 |
33 |
34 |
35 | {
36 | value.items.map((item, j) => {
37 | return {item};
38 | })
39 | }
40 |
41 |
42 |
43 | );
44 | })
45 | }
46 |
47 |
48 | );
49 | };
50 |
--------------------------------------------------------------------------------
/src/components/seo.tsx:
--------------------------------------------------------------------------------
1 | import { graphql, useStaticQuery } from 'gatsby';
2 | import PropTypes from 'prop-types';
3 | import React from 'react';
4 | import Helmet from 'react-helmet';
5 |
6 | function SEO({ description, lang, meta, title }: { description: string, lang: string, meta: any, title: string }) {
7 | const { site } = useStaticQuery(
8 | graphql`
9 | query {
10 | site {
11 | siteMetadata {
12 | title
13 | description
14 | author
15 | }
16 | }
17 | }
18 | `,
19 | );
20 |
21 | const metaDescription = description || site.siteMetadata.description;
22 |
23 | return (
24 |
65 | );
66 | }
67 |
68 | SEO.defaultProps = {
69 | lang: `en`,
70 | meta: [],
71 | description: ``,
72 | };
73 |
74 | SEO.propTypes = {
75 | description: PropTypes.string,
76 | lang: PropTypes.string,
77 | meta: PropTypes.arrayOf(PropTypes.object),
78 | title: PropTypes.string.isRequired,
79 | };
80 |
81 | export default SEO;
82 |
--------------------------------------------------------------------------------
/src/images/gatsby-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/suites/simple-resume/6415ed4e6fe644aee26feccc94e7cc27681e3c7d/src/images/gatsby-icon.png
--------------------------------------------------------------------------------
/src/models/index.ts:
--------------------------------------------------------------------------------
1 | export default interface Resume {
2 | blogUrl: string;
3 | description: string;
4 | cover: string;
5 | name: string;
6 | photo: string;
7 | introduction: string[];
8 | skills: Skill[];
9 | careers: Career[];
10 | links: Link[];
11 | experiences: Action[];
12 | educations: Action[];
13 | licenses: Action[];
14 | aboutme: string[];
15 | }
16 |
17 | export interface Skill {
18 | name: string;
19 | items: string[];
20 | }
21 |
22 | export interface Action {
23 | name: string;
24 | information?: string;
25 | date?: ActionDate;
26 | description?: string[];
27 | }
28 |
29 | export interface ActionDate {
30 | start: string;
31 | end?: string;
32 | }
33 |
34 | export interface Career extends Action {
35 | techStacks: Skill[];
36 | projects: Project[];
37 | }
38 |
39 | export interface Project extends Action {
40 | parts: string[];
41 | }
42 |
43 | export interface Link {
44 | name: string;
45 | symbol: string;
46 | type: string;
47 | }
48 |
--------------------------------------------------------------------------------
/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import SEO from '../components/seo';
4 |
5 | const NotFoundPage = () => (
6 | <>
7 |
8 | NOT FOUND
9 | You just hit a route that doesn't exist... the sadness.
10 | >
11 | );
12 |
13 | export default NotFoundPage;
14 |
--------------------------------------------------------------------------------
/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Layout from '../components/layout';
4 | import SEO from '../components/seo';
5 |
6 | const IndexPage = () => {
7 | return (
8 | <>
9 |
10 |
11 | >
12 | );
13 | };
14 |
15 | export default IndexPage;
16 |
--------------------------------------------------------------------------------
/static/profile-yaml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/suites/simple-resume/6415ed4e6fe644aee26feccc94e7cc27681e3c7d/static/profile-yaml.png
--------------------------------------------------------------------------------
/static/resumes/chick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/suites/simple-resume/6415ed4e6fe644aee26feccc94e7cc27681e3c7d/static/resumes/chick.png
--------------------------------------------------------------------------------
/static/resumes/john-doe.yaml:
--------------------------------------------------------------------------------
1 | # Head config [views/partials/head.ejs]
2 | # Meta tag 관련 설정입니다.
3 | # Meta tag-related settings.
4 | blogUrl: http://example.com/resume
5 | description: This is a resume of software engineer John Doe.
6 | cover: "/"
7 | # Resume config [views/partials/profile.ejs]
8 | # 이력서 상단에 들어갈 사진과 이름, 간단 소개입니다.
9 | # A picture, name and brief introduction to the top of your resume.
10 | name: John Doe
11 | photo: "resumes/chick.png"
12 | introduction:
13 | - Hello! I'm John Doe. I'm Software Engineer.
14 | - I enjoy playing games and eating. I'm happiest when I eat. I like pork.
15 |
16 | # Profile link config [views/sections/profile.ejs]
17 | # email, github, linkedin, blog의 주소와 아이콘 설정입니다.
18 | # The address and icon settings for email, github, linkedin, and blog.
19 |
20 | # name: 연결할 서비스의 주소입니다.
21 | # symbol: 링크 앞의 awesome font 심볼입니다. [https://fontawesome.com/icons/](ex : fab fa-apple)
22 | # type: 링크의 서비스명 입니다.
23 |
24 | # name: The address of the service to which you want to connect.
25 | # symbol: Awesome font symbol in front of the link. [https://fontawesome.com/icons/](ex : fab fa-apple)
26 | # type: This is the service name of the link.
27 |
28 | links:
29 | - name: "john.doe@example.com"
30 | symbol: FaEnvelope
31 | type: email
32 | - name: "https://github.com/johndoe"
33 | symbol: FaGithub
34 | type: github
35 | - name: https://www.linkedin.com/in/johndoe
36 | symbol: FaLinkedin
37 | type: linkedin
38 | - name: http://example.com
39 | symbol: FaHome
40 | type: blog
41 |
42 | # Skills config [views/sections/skills.ejs]
43 | # 보유기술 설정입니다. 항목을 자유롭게 추가할 수 있습니다.
44 |
45 | # This is a technology setting. You can add items freely.
46 | skills:
47 | - name: Languages
48 | items:
49 | - Node.js
50 | - python
51 | - mysql
52 | - name: Libraries
53 | items:
54 | - Express
55 | - name: Tools
56 | items:
57 | - vscode
58 | - name: VCS
59 | items:
60 | - Git
61 |
62 | # Careers config [views/sections/careers.ejs]
63 | # 경력사항 설정입니다. 회사와 프로젝트를 추가할 수 있습니다.
64 | # 회사 추가시 careers 밑의 -company 부터 복사하여 사용하고,
65 | # 프로젝트 추가시 projects 밑의 -name 부터 복사하여 사용합니다.
66 | # Date type : yyyy.mm
67 |
68 | # Experience settings. You can add companies and projects.
69 | # When adding a company, copy and use it from "-company" under careers.
70 | # When adding a project, copy and use "-name" under projects.
71 | careers:
72 | - name: John Company
73 | information: Junior Software Engineer
74 | date:
75 | start: '2018.03'
76 | end: 'now'
77 | techStacks:
78 | - name: Language
79 | items:
80 | - HTML
81 | - CSS3
82 | - JavaScript
83 | - Node.js
84 | - name: System
85 | items:
86 | - Ubuntu 16.04
87 | - name: Tool
88 | items:
89 | - Git
90 | projects:
91 | - name: Member management service operations
92 | date:
93 | start: '2018.03'
94 | end: '2018.06'
95 | description: The member management functions were developed and maintained for the smooth service use of users.
96 | parts:
97 | - Development of member management
98 | - Implement SNS login
99 |
100 | # Other Experiences config [views/sections/experiences.ejs]
101 | # 기타 경험 설정입니다. 이름, 역할, 기간, 요약등을 추가할 수 있습니다.
102 | # 항목 추가시 -experience 부터 description까지 복사하여 사용합니다.
103 |
104 | # Other experience settings. You can add names, informations, date, and summaries.
105 | # When adding an item, copy and use -experience to description under otherExperience.
106 | experiences:
107 | - name: Delicious Cookie Hackathon
108 | information: Development
109 | date:
110 | start: '2018.08'
111 | end: '2018.08'
112 | description:
113 | - Delicious Cookie Hackathon has developed Cookie Food Service and won it.
114 | - name: Nursing home volunteer activities
115 | information: Volunteer
116 | date:
117 | start: '2018.06'
118 | end: '2018.07'
119 | description:
120 | - https://example.com/example/
121 | - I went to the nursing home and did volunteer work. It was rewarding.
122 |
123 | # Educations config [views/sections/educations.ejs]
124 | # 학력, 교육 항목 설정입니다. 이름과 기간 요약을 추가할 수 있습니다.
125 | # 항목 추가시 -education 부터 description까지 복사하여 사용합니다.
126 |
127 | # Education, education item settings. Lets you add a name and a summary of the date summary.
128 | # When adding an item, copy and use the item from -education to description.
129 | educations:
130 | - name: Korea Cookie University
131 | date:
132 | start: '2011.03'
133 | end: '2015.03'
134 | description:
135 | - I graduated from school.
136 |
137 | # Licenses config [views/sections/licenses.ejs]
138 | # 자격증 항목 설정입니다. 이름과 기간 요약을 추가할 수 있습니다.
139 | # 항목 추가시 licenses 밑의 -license 부터 description까지 복사하여 사용합니다.
140 |
141 | # Certificate entry settings. Lets you add a name and a summary of the date summary.
142 | # When adding items, copy and use the -license to description under Licenses.
143 |
144 | licenses:
145 | - name: Confectionary function qualification
146 | information: Cookie Land
147 | date:
148 | start: '2008.03'
149 | end: ''
150 | description:
151 | - I got a license.
152 |
153 | # aboutme config [views/sections/about.ejs]
154 | # 자기소개서 설정입니다. 자유롭게 작성할 수 있습니다.
155 | # - 로 항목을 추가하면 문단이 추가되는 효과가 있습니다.
156 | aboutme:
157 | - Elit minim consectetur adipisicing nisi et laborum occaecat esse
158 | - dolor cupidatat exercitation consequat pariatur sunt. Esse est ipsum nostrud consectetur tempor ad. Anim laboris Lorem deserunt ad eu deserunt est aute.
159 | - '# Sit elit veniam'
160 | - Irure velit sit eiusmod cupidatat minim irure cupidatat velit magna mollit in cupidatat cillum. Amet aliqua dolor elit enim.
161 | - '## Sit elit veniam'
162 | - Minim esse consectetur velit sunt nostrud nulla id aliqua.
163 | - '## incididunt exercitation'
164 | - 'https://example.com'
165 | - veniam deserunt proident voluptate occaecat dolor incididunt exercitation irure sit ex. Veniam cupidatat excepteur nulla laboris non sunt Lorem irure Lorem eu non enim dolor. Culpa enim nulla quis ex cupidatat anim ad occaecat anim ea nostrud.
166 |
--------------------------------------------------------------------------------
/static/simple-resume.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/suites/simple-resume/6415ed4e6fe644aee26feccc94e7cc27681e3c7d/static/simple-resume.png
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "commonjs",
5 | "jsx": "react",
6 | "strict": true,
7 | "esModuleInterop": true,
8 | "typeRoots": [
9 | "./node_modules/@types",
10 | "./@types",
11 | ]
12 | }
13 | }
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultSeverity": "error",
3 | "extends": [
4 | "tslint:recommended"
5 | ],
6 | "jsRules": {},
7 | "rules": {
8 | "indent": {
9 | "options": [
10 | "spaces",
11 | 2
12 | ]
13 | },
14 | "interface-name": {
15 | "options": [
16 | "never-prefix"
17 | ]
18 | },
19 | "max-classes-per-file": {
20 | "options": [
21 | 10
22 | ]
23 | },
24 | "max-line-length": {
25 | "options": [
26 | 150
27 | ],
28 | "severity": "warning"
29 | },
30 | "member-access": false,
31 | "member-ordering": false,
32 | "no-console": false,
33 | "no-empty-interface": false,
34 | "no-reference": false,
35 | "no-var-requires": false,
36 | "object-literal-sort-keys": false,
37 | "quotemark": {
38 | "options": [
39 | "single",
40 | "jsx-single",
41 | "avoid-escape"
42 | ]
43 | },
44 | "trailing-comma": {
45 | "options": {
46 | "esSpecCompliant": true,
47 | "multiline": "always",
48 | "singleline": "never"
49 | }
50 | },
51 | "variable-name": {
52 | "options": [
53 | "ban-keywords",
54 | "check-format",
55 | "allow-pascal-case",
56 | "allow-snake-case"
57 | ]
58 | }
59 | },
60 | "rulesDirectory": []
61 | }
--------------------------------------------------------------------------------