I'm currently available for freelance projects or full-time work. If you're interested in working with me, please get in touch through {{ email }}.
17 |
31 |
--------------------------------------------------------------------------------
/editor/src/zip/index.js:
--------------------------------------------------------------------------------
1 | import JSZip from 'jszip'
2 | import FileSaver from 'file-saver'
3 | import { bundle } from '../util/paths'
4 |
5 | // TODO: proper zip singleton/management
6 | let zip
7 |
8 | export async function preloadZip () {
9 | try {
10 | const response = await fetch(bundle)
11 | zip = await JSZip.loadAsync(response.arrayBuffer())
12 | } catch (e) {
13 | // TODO: Better error messages
14 | alert('Sorry something went wrong! Please reload the page :(')
15 | console.error(e)
16 | }
17 | }
18 |
19 | export async function generateZip (html, data) {
20 | try {
21 | zip.file('index.html', html)
22 | zip.folder('src').file('data.js', `module.exports = ${JSON.stringify(data, null, 4)}`)
23 |
24 | if (JSZip.support.blob) {
25 | const blob = await zip.generateAsync({ type: 'blob' })
26 | FileSaver.saveAs(blob, 'riyu.zip')
27 | } else {
28 | throw new Error('Saving zip files through javascript not supported on this browser')
29 | }
30 | } catch (e) {
31 | // TODO: Better error messages
32 | alert('Sorry something went wrong! Please reload the page :(')
33 | console.error(e)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/fontello/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "css_prefix_text": "icon-",
4 | "css_use_suffix": false,
5 | "hinting": true,
6 | "units_per_em": 1000,
7 | "ascent": 850,
8 | "glyphs": [
9 | {
10 | "uid": "627abcdb627cb1789e009c08e2678ef9",
11 | "css": "twitter",
12 | "code": 61593,
13 | "src": "fontawesome"
14 | },
15 | {
16 | "uid": "58a16628dcbd6456c61218f3d27591be",
17 | "css": "skype",
18 | "code": 61822,
19 | "src": "fontawesome"
20 | },
21 | {
22 | "uid": "0f6a2573a7b6df911ed199bb63717e27",
23 | "css": "github-circled",
24 | "code": 61595,
25 | "src": "fontawesome"
26 | },
27 | {
28 | "uid": "ccc2329632396dc096bb638d4b46fb98",
29 | "css": "mail-alt",
30 | "code": 61664,
31 | "src": "fontawesome"
32 | },
33 | {
34 | "uid": "1145676a91138011729fa2909997af66",
35 | "css": "linkedin-squared",
36 | "code": 62220,
37 | "src": "fontawesome"
38 | },
39 | {
40 | "uid": "199c44bca402ec5a6351f75ba5228375",
41 | "css": "dribbble",
42 | "code": 61821,
43 | "src": "fontawesome"
44 | }
45 | ]
46 | }
--------------------------------------------------------------------------------
/src/scss/projects.scss:
--------------------------------------------------------------------------------
1 | .project {
2 | overflow: hidden;
3 | margin-bottom: 30px;
4 | text-align: center;
5 |
6 | @media #{$tablet} {
7 | text-align: left;
8 | }
9 |
10 | &__img-container {
11 | margin: 0 auto;
12 | text-align: center;
13 | height: 100px;
14 | width: 100px;
15 | line-height: 100px;
16 |
17 | @media #{$tablet} {
18 | float: left;
19 | line-height: 300px;
20 | height: 300px;
21 | width: 300px;
22 | }
23 | }
24 | &__img {
25 | display: inline-block;
26 | margin: 0 auto;
27 | max-height: 100%;
28 | max-width: 100%;
29 | text-align: center;
30 | vertical-align: middle;
31 | }
32 | &__name {
33 | margin-bottom: 5px;
34 | }
35 | &__details {
36 | padding: 15px;
37 |
38 | @media #{$tablet} {
39 | margin-left: 300px;
40 | margin-right: 0;
41 | }
42 | }
43 | }
44 |
45 |
46 | .project:nth-child(even) {
47 | .project__img-container {
48 | @media #{$tablet} {
49 | float: right;
50 | }
51 | }
52 | .project__details {
53 | @media #{$tablet} {
54 | margin-left: 0;
55 | margin-right: 300px;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/scss/base.scss:
--------------------------------------------------------------------------------
1 | // reset
2 | body {
3 | margin: 0;
4 | padding: 0;
5 | border: 0;
6 | vertical-align: baseline;
7 | }
8 |
9 | * {
10 | box-sizing: border-box;
11 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
12 | }
13 |
14 | .container {
15 | padding: 0 20px 20px 20px;
16 | margin: 0 auto;
17 |
18 | @media #{$tablet} {
19 | max-width: 900px;
20 | padding: 0 30px 50px 30px;
21 | }
22 | }
23 |
24 | .btn {
25 | border-radius: 3px;
26 | cursor: pointer;
27 | display: inline-block;
28 | font-size: 16px;
29 | font-weight: 700;
30 | padding: 9px 13px;
31 |
32 | text-decoration: none;
33 |
34 | background: $info-color;
35 | color: $info-text-color;
36 |
37 | &--primary {
38 | background: $main-color;
39 | color: $main-text-color;
40 | }
41 |
42 | &--lg {
43 | padding: 18px 26px;
44 | }
45 | }
46 |
47 | .skill-tags {
48 | @media #{$tablet} {
49 | margin-left: 10px;
50 | }
51 | }
52 |
53 | .skill-tag {
54 | background-color: $tag-color;
55 | display: inline-block;
56 | padding: 4px 8px;
57 | }
58 |
59 | .testimonial {
60 | border-left: 1px solid $main-color;
61 | padding: 15px 15px;
62 | p {
63 | margin-top: 0;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/editor/config/env.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
4 | // injected into the application via DefinePlugin in Webpack configuration.
5 |
6 | var REACT_APP = /^REACT_APP_/i;
7 |
8 | function getClientEnvironment(publicUrl) {
9 | var raw = Object
10 | .keys(process.env)
11 | .filter(key => REACT_APP.test(key))
12 | .reduce((env, key) => {
13 | env[key] = process.env[key];
14 | return env;
15 | }, {
16 | // Useful for determining whether we’re running in production mode.
17 | // Most importantly, it switches React into the correct mode.
18 | 'NODE_ENV': process.env.NODE_ENV || 'development',
19 | // Useful for resolving the correct path to static assets in `public`.
20 | // For example, .
21 | // This should only be used as an escape hatch. Normally you would put
22 | // images into the `src` and `import` them in code to get their paths.
23 | 'PUBLIC_URL': publicUrl
24 | });
25 | // Stringify all values so we can feed into Webpack DefinePlugin
26 | var stringified = {
27 | 'process.env': Object
28 | .keys(raw)
29 | .reduce((env, key) => {
30 | env[key] = JSON.stringify(raw[key]);
31 | return env;
32 | }, {})
33 | };
34 |
35 | return { raw, stringified };
36 | }
37 |
38 | module.exports = getClientEnvironment;
39 |
--------------------------------------------------------------------------------
/editor/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
16 |
17 | React App
18 |
19 |
20 |
21 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/editor/scripts/genZipBundle.js:
--------------------------------------------------------------------------------
1 | var archiver = require('archiver');
2 | var fs = require('fs-extra');
3 | var path = require('path');
4 |
5 | var paths = {
6 | // TODO: This should really not be hardcoded
7 | build: path.join(__dirname, '..', '/build'),
8 | bundle: path.join(__dirname, '..', '/public/riyu.zip'),
9 | riyu: path.join(__dirname, '..', '..'),
10 | }
11 |
12 | function prepareBundleStream () {
13 | if (fs.existsSync(paths.bundle)) {
14 | fs.unlink(paths.bundle);
15 | }
16 |
17 | return fs.createWriteStream(paths.bundle);
18 | }
19 |
20 | function onArchiverErr (err) {
21 | throw err;
22 | }
23 |
24 | function onArchiverFinish (archive) {
25 | console.log('riyu bundle finished: ' + archive.pointer() + ' total bytes');
26 | }
27 |
28 | function genZipBundle () {
29 | var output = prepareBundleStream();
30 | var archive = archiver('zip', { store: true });
31 |
32 | output.on('close', function () { onArchiverFinish(archive) });
33 | archive.on('error', onArchiverErr);
34 | archive.pipe(output);
35 |
36 | addFilesToArchiver(archive);
37 | archive.finalize();
38 | }
39 |
40 | function addFilesToArchiver(archive) {
41 | var directories = ['css', 'img', 'js', 'lib'];
42 | var files = ['index.html', 'README.md', 'package.json'];
43 |
44 | for (var i = 0; i < directories.length; i++) {
45 | var dir = directories[i];
46 | archive.directory(path.join(paths.riyu, dir), dir);
47 | }
48 |
49 | // TODO: there's gotta be a better way to do this
50 | for (var i = 0; i < files.length; i++) {
51 | var file = files[i];
52 | archive.glob(file, { cwd: paths.riyu });
53 | }
54 | }
55 |
56 | genZipBundle();
57 |
--------------------------------------------------------------------------------
/src/scss/experience.scss:
--------------------------------------------------------------------------------
1 | .experience-container {
2 | }
3 |
4 | .timeline {
5 | position: relative;
6 |
7 | &__line {
8 | width: 1px;
9 | background: $muted-color;
10 | position: absolute;
11 | top: 0;
12 | bottom: 0;
13 |
14 | left: 100%;
15 | @media #{$tablet} {
16 | left: 50%;
17 | }
18 | }
19 | &__item {
20 | animation: slideUp 750ms both;
21 |
22 | border: 1px solid #eaeaea;
23 | border-top: 2px solid $main-color;
24 | color: #222;
25 | display: inline-block;
26 | font-size: 13px;
27 | padding: 20px;
28 | position: relative;
29 | vertical-align: top;
30 | width: 97%;
31 | @media #{$tablet} {
32 | width: 46%;
33 | }
34 | &:after {
35 | height: 1px;
36 | top: 0;
37 | background-color: $muted-color;
38 | content: '';
39 | display: block;
40 | left: inherit;
41 | position: absolute;
42 |
43 | right: -4%;
44 | width: 4%;
45 |
46 | @media #{$tablet} {
47 | right: -9%;
48 | width: 9%;
49 | }
50 | }
51 | &:nth-child(odd) {
52 | margin-top: 20px;
53 | margin-bottom: -100px;
54 |
55 | @media #{$tablet} {
56 | margin-top: 160px;
57 | margin-left: 7%;
58 | &:after {
59 | left: -8%;
60 | width: 8%;
61 | }
62 | }
63 | }
64 | &:last-of-type {
65 | margin-bottom: 0;
66 | }
67 | }
68 | }
69 |
70 | .experience {
71 | &__header {
72 | margin-bottom: 10px;
73 | padding-bottom: 10px;
74 | border-bottom: 1px solid $muted-color;
75 | }
76 | &__name {
77 | margin: 0;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/editor/src/data.js:
--------------------------------------------------------------------------------
1 | import fixture from 'data';
2 | import Immutable, { fromJS, List } from 'immutable';
3 | import UUID from "node-uuid";
4 |
5 | export default fromJS({
6 | title: fixture.title,
7 | header: fixture.header,
8 | description: fixture.description,
9 | name: fixture.name,
10 | footerTitle: fixture.footerTitle,
11 | email: fixture.email,
12 | cta: fixture.cta,
13 | socials: {
14 | twitter: 'http://twitter/',
15 | 'github-circled': 'http://github',
16 | dribbble: 'http://dribbble',
17 | skype: 'htttp://skype',
18 | 'mail-alt': 'mailto: email',
19 | 'linkedin-squared': 'http://linkedin',
20 | },
21 | projects: [
22 | { __key: UUID.v4(), ...fixture.projects[0] },
23 | { __key: UUID.v4(), ...fixture.projects[1] }
24 | ],
25 | experiences: [
26 | { __key: UUID.v4(), ...fixture.experiences[0] },
27 | { __key: UUID.v4(), ...fixture.experiences[1] }
28 | ],
29 | testimonials: [
30 | { __key: UUID.v4(), ...fixture.testimonials[0] },
31 | { __key: UUID.v4(), ...fixture.testimonials[1] }
32 | ]
33 | })
34 |
35 | export const toLiquid = data => {
36 | const socials = data.get('socials')
37 |
38 | // convert 'socials' from Object to Array of Objects
39 | return data.setIn(
40 | ['socials'],
41 | List(socials.keySeq().toArray().map(key => (
42 | { icon: key, url: socials.get(key) }
43 | )))
44 | ).toJS()
45 | }
46 |
47 | export const isString = v => isVarTypeOf(v, String)
48 | export const isKeyed = Immutable.Iterable.isKeyed
49 | export const isIndexed = v => Immutable.Iterable.isIndexed(v) || isVarTypeOf(v, Array)
50 |
51 | function isVarTypeOf(_var, _type) {
52 | try {
53 | return _var.constructor === _type;
54 | } catch(ex) {
55 | return false; //fallback for null or undefined
56 | }
57 | }
58 |
59 | export const getScrollTop = (iwindow) => {
60 | if (typeof iwindow.pageYOffset !== 'undefined'){
61 | //most browsers except IE before #9
62 | return iwindow.pageYOffset;
63 | } else {
64 | var B = iwindow.document.body; //IE 'quirks'
65 | var D = iwindow.document.documentElement; //IE with doctype
66 | D = (D.clientHeight) ? D: B;
67 |
68 | return D.scrollTop;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/lib/fontello/css/animation.css:
--------------------------------------------------------------------------------
1 | /*
2 | Animation example, for spinners
3 | */
4 | .animate-spin {
5 | -moz-animation: spin 2s infinite linear;
6 | -o-animation: spin 2s infinite linear;
7 | -webkit-animation: spin 2s infinite linear;
8 | animation: spin 2s infinite linear;
9 | display: inline-block;
10 | }
11 | @-moz-keyframes spin {
12 | 0% {
13 | -moz-transform: rotate(0deg);
14 | -o-transform: rotate(0deg);
15 | -webkit-transform: rotate(0deg);
16 | transform: rotate(0deg);
17 | }
18 |
19 | 100% {
20 | -moz-transform: rotate(359deg);
21 | -o-transform: rotate(359deg);
22 | -webkit-transform: rotate(359deg);
23 | transform: rotate(359deg);
24 | }
25 | }
26 | @-webkit-keyframes spin {
27 | 0% {
28 | -moz-transform: rotate(0deg);
29 | -o-transform: rotate(0deg);
30 | -webkit-transform: rotate(0deg);
31 | transform: rotate(0deg);
32 | }
33 |
34 | 100% {
35 | -moz-transform: rotate(359deg);
36 | -o-transform: rotate(359deg);
37 | -webkit-transform: rotate(359deg);
38 | transform: rotate(359deg);
39 | }
40 | }
41 | @-o-keyframes spin {
42 | 0% {
43 | -moz-transform: rotate(0deg);
44 | -o-transform: rotate(0deg);
45 | -webkit-transform: rotate(0deg);
46 | transform: rotate(0deg);
47 | }
48 |
49 | 100% {
50 | -moz-transform: rotate(359deg);
51 | -o-transform: rotate(359deg);
52 | -webkit-transform: rotate(359deg);
53 | transform: rotate(359deg);
54 | }
55 | }
56 | @-ms-keyframes spin {
57 | 0% {
58 | -moz-transform: rotate(0deg);
59 | -o-transform: rotate(0deg);
60 | -webkit-transform: rotate(0deg);
61 | transform: rotate(0deg);
62 | }
63 |
64 | 100% {
65 | -moz-transform: rotate(359deg);
66 | -o-transform: rotate(359deg);
67 | -webkit-transform: rotate(359deg);
68 | transform: rotate(359deg);
69 | }
70 | }
71 | @keyframes spin {
72 | 0% {
73 | -moz-transform: rotate(0deg);
74 | -o-transform: rotate(0deg);
75 | -webkit-transform: rotate(0deg);
76 | transform: rotate(0deg);
77 | }
78 |
79 | 100% {
80 | -moz-transform: rotate(359deg);
81 | -o-transform: rotate(359deg);
82 | -webkit-transform: rotate(359deg);
83 | transform: rotate(359deg);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/lib/fontello/css/fontello.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'fontello';
3 | src: url('../font/fontello.eot?87006925');
4 | src: url('../font/fontello.eot?87006925#iefix') format('embedded-opentype'),
5 | url('../font/fontello.woff2?87006925') format('woff2'),
6 | url('../font/fontello.woff?87006925') format('woff'),
7 | url('../font/fontello.ttf?87006925') format('truetype'),
8 | url('../font/fontello.svg?87006925#fontello') format('svg');
9 | font-weight: normal;
10 | font-style: normal;
11 | }
12 | /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
13 | /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
14 | /*
15 | @media screen and (-webkit-min-device-pixel-ratio:0) {
16 | @font-face {
17 | font-family: 'fontello';
18 | src: url('../font/fontello.svg?87006925#fontello') format('svg');
19 | }
20 | }
21 | */
22 |
23 | [class^="icon-"]:before, [class*=" icon-"]:before {
24 | font-family: "fontello";
25 | font-style: normal;
26 | font-weight: normal;
27 | speak: none;
28 |
29 | display: inline-block;
30 | text-decoration: inherit;
31 | width: 1em;
32 | margin-right: .2em;
33 | text-align: center;
34 | /* opacity: .8; */
35 |
36 | /* For safety - reset parent styles, that can break glyph codes*/
37 | font-variant: normal;
38 | text-transform: none;
39 |
40 | /* fix buttons height, for twitter bootstrap */
41 | line-height: 1em;
42 |
43 | /* Animation center compensation - margins should be symmetric */
44 | /* remove if not needed */
45 | margin-left: .2em;
46 |
47 | /* you can be more comfortable with increased icons size */
48 | /* font-size: 120%; */
49 |
50 | /* Font smoothing. That was taken from TWBS */
51 | -webkit-font-smoothing: antialiased;
52 | -moz-osx-font-smoothing: grayscale;
53 |
54 | /* Uncomment for 3D effect */
55 | /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
56 | }
57 |
58 | .icon-twitter:before { content: '\f099'; } /* '' */
59 | .icon-github-circled:before { content: '\f09b'; } /* '' */
60 | .icon-mail-alt:before { content: '\f0e0'; } /* '' */
61 | .icon-dribbble:before { content: '\f17d'; } /* '' */
62 | .icon-skype:before { content: '\f17e'; } /* '' */
63 | .icon-linkedin-squared:before { content: '\f30c'; } /* '' */
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp')
2 | var browserSync = require('browser-sync').create();
3 | var plumber = require('gulp-plumber')
4 | var liquid = require('gulp-liquify')
5 | var prettify = require('gulp-jsbeautifier')
6 | var uglify = require('gulp-uglify')
7 | var sass = require('gulp-sass')
8 | var rename = require('gulp-rename')
9 | var autoprefixer = require('gulp-autoprefixer')
10 | var decache = require('decache')
11 |
12 | gulp.task('scripts', function () {
13 | return gulp.src('./src/js/scripts.js')
14 | .pipe(plumber(plumber({
15 | errorHandler: function (err) {
16 | console.log(err)
17 | this.emit('end')
18 | }
19 | })))
20 | .pipe(uglify({
21 | preserveComments: 'license'
22 | }))
23 | .pipe(rename({extname: '.min.js'}))
24 | .pipe(gulp.dest('js'))
25 | })
26 |
27 | gulp.task('styles', function () {
28 | return gulp.src('./src/scss/index.scss')
29 | .pipe(plumber(plumber({
30 | errorHandler: function (err) {
31 | console.log(err)
32 | this.emit('end')
33 | }
34 | })))
35 | .pipe(sass({outputStyle: 'compressed'}))
36 | .pipe(autoprefixer())
37 | .pipe(gulp.dest('css'))
38 | })
39 |
40 | gulp.task('templates', function () {
41 | var root = './src/templates/'
42 |
43 | decache('./src/data.js')
44 | var data = require('./src/data.js')
45 |
46 | return gulp.src(root + 'index.html')
47 | .pipe(liquid(data))
48 | .pipe(prettify())
49 | .pipe(rename('index.html'))
50 | .pipe(gulp.dest('./'))
51 | })
52 |
53 | gulp.task('watch', ['scripts', 'styles', 'templates'], function () {
54 | gulp.watch('src/js/*.js', ['scripts'])
55 | gulp.watch('src/scss/*.scss', ['styles'])
56 | gulp.watch(['src/templates/**/*.html', 'src/data.js'], ['templates'])
57 | })
58 |
59 | gulp.task('serve', ['scripts', 'styles', 'templates'], function() {
60 | browserSync.init({
61 | server: {
62 | baseDir: "./"
63 | },
64 | open: true
65 | })
66 |
67 | gulp.watch('src/js/*.js', ['scripts'])
68 | gulp.watch('src/scss/*.scss', ['styles'])
69 | gulp.watch(['src/templates/**/*.html', 'src/data.js'], ['templates']);
70 |
71 | gulp.watch('index.html', function () {
72 | gulp.src('index.html').pipe(browserSync.stream())
73 | })
74 | gulp.watch('css/index.css', function () {
75 | gulp.src('css/index.css').pipe(browserSync.stream())
76 | })
77 | })
78 |
79 | gulp.task('webserver', function() {
80 | gulp.src('app')
81 | .pipe(webserver({
82 | livereload: true,
83 | directoryListing: true,
84 | open: true
85 | }))
86 | })
87 |
88 | gulp.task('build', ['scripts', 'styles', 'templates'])
89 |
--------------------------------------------------------------------------------
/src/data.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | title: 'John Smith',
3 | header: "Hi, I'm John Smith",
4 | description: "I'm a college junior currently taking up Computer Science in University X. I'm a freelance developer with 4 years of experience, having worked with clients such as X, Y, Z. I enjoy building everything from small business sites to rich interactive web apps.",
5 | name: 'John Smith',
6 | footerTitle: 'Software Engineer',
7 | email: 'johnsmith@mail.com',
8 | cta: {
9 | label: 'Get my resume',
10 | url: 'resume.pdf',
11 | },
12 | socials: [
13 | { icon: 'twitter', url: '//' },
14 | { icon: 'github-circled', url: '//' },
15 | { icon: 'mail-alt' }, // mail alt automatically links to mailto:email
16 | { icon: 'dribbble', url: '//' },
17 | { icon: 'skype', url: '//' },
18 | { icon: 'linkedin-squared', url: '//' },
19 | ],
20 | projects: [
21 | {
22 | name: 'Combustion',
23 | description: 'Combustion is a sleek, modern web client for the transmission bittorrent client.',
24 | tags: ['React', 'Javascript', 'Webpack', 'Mobx', 'CSSModules'],
25 | alt: 'Combustion Screenshot', // alt description of image for accessibility. defaults to '{{name}} Screenshot'
26 | img: 'combustion.png',
27 | url: '//'
28 | },
29 | {
30 | name: 'Merc-01',
31 | description: 'Merc-01 is a fast paced twin-stick shooter built on top of pyglet.',
32 | tags: ['Python', 'WebGL', 'Pyglet'],
33 | img: 'merc-01.png',
34 | url: '//'
35 | }
36 | ],
37 | experiences: [
38 | {
39 | title: 'Senior Software Engineer at Company A',
40 | timeline: 'Jan 2016 - Present',
41 | description: 'Implemented Gamification for system',
42 | },
43 | {
44 | title: 'Fullstack Software Engineer at Company B',
45 | timeline: 'Feb 2015 - Dec 2015',
46 | responsibilities: [
47 | 'Worked with a global team of developers and artists for the implementation of new features in Existing Codebase of a Free-to-play MMO',
48 | 'Increased rate of tickets/tasks done by the team up to 300% within first few weeks!',
49 | 'Added Abstractions on Server API to Minimize Duplicate Code'
50 | ]
51 | }
52 | ],
53 | testimonials: [
54 | {
55 | quote: 'Incredibly talented and hardworking. A super friendly guy who is a frequent communicator',
56 | name: 'Person Name',
57 | title: 'CEO at Company'
58 | },
59 | {
60 | quote: 'Wow, thank you for this, you probably have the most intuitive explanation for this problem!',
61 | name: 'Person Name'
62 | }
63 | ]
64 | }
65 |
--------------------------------------------------------------------------------
/editor/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/lib/fontello/README.txt:
--------------------------------------------------------------------------------
1 | This webfont is generated by http://fontello.com open source project.
2 |
3 |
4 | ================================================================================
5 | Please, note, that you should obey original font licenses, used to make this
6 | webfont pack. Details available in LICENSE.txt file.
7 |
8 | - Usually, it's enough to publish content of LICENSE.txt file somewhere on your
9 | site in "About" section.
10 |
11 | - If your project is open-source, usually, it will be ok to make LICENSE.txt
12 | file publicly available in your repository.
13 |
14 | - Fonts, used in Fontello, don't require a clickable link on your site.
15 | But any kind of additional authors crediting is welcome.
16 | ================================================================================
17 |
18 |
19 | Comments on archive content
20 | ---------------------------
21 |
22 | - /font/* - fonts in different formats
23 |
24 | - /css/* - different kinds of css, for all situations. Should be ok with
25 | twitter bootstrap. Also, you can skip style and assign icon classes
26 | directly to text elements, if you don't mind about IE7.
27 |
28 | - demo.html - demo file, to show your webfont content
29 |
30 | - LICENSE.txt - license info about source fonts, used to build your one.
31 |
32 | - config.json - keeps your settings. You can import it back into fontello
33 | anytime, to continue your work
34 |
35 |
36 | Why so many CSS files ?
37 | -----------------------
38 |
39 | Because we like to fit all your needs :)
40 |
41 | - basic file, .css - is usually enough, it contains @font-face
42 | and character code definitions
43 |
44 | - *-ie7.css - if you need IE7 support, but still don't wish to put char codes
45 | directly into html
46 |
47 | - *-codes.css and *-ie7-codes.css - if you like to use your own @font-face
48 | rules, but still wish to benefit from css generation. That can be very
49 | convenient for automated asset build systems. When you need to update font -
50 | no need to manually edit files, just override old version with archive
51 | content. See fontello source code for examples.
52 |
53 | - *-embedded.css - basic css file, but with embedded WOFF font, to avoid
54 | CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain.
55 | We strongly recommend to resolve this issue by `Access-Control-Allow-Origin`
56 | server headers. But if you ok with dirty hack - this file is for you. Note,
57 | that data url moved to separate @font-face to avoid problems with (
53 |
58 | { show &&
59 |
60 |
61 | Riyu Editor
62 |
63 | Riyu
64 | is a cool, modern, and minimal portfolio/personal web page template that is super easy to customize.
65 | Riyu Editor is a companion web app that allows you to easily add your own content for Riyu. The editor creates both a ready built html file you can drop on your server and a data.json file for use on Riyu's build system.
66 |
67 |
FAQ:
68 |
69 |
How do I add my own images for my projects?
70 |
Simply add in the expected filename of your image (project.png) and generate the HTML. Then place your images on a directory named img - this is where all the images are resolved (/img/project.png). You can of course edit the html once generated.
71 |
Can I change the colour scheme?
72 |
You can change the colour scheme (and every style really) of Riyu. Changing colour schemes/styles through the Riyu Editor web app is currently not supported.
73 |
Is it free?
74 |
Riyu is free (as in beer) and open source (MIT). There is no need to add credits or linkbacks, but I'd appreciate if you star the repo :)
75 |
76 |
77 |
78 |
I'd love to hear what everyone is doing with Riyu. If so inclined, Open an issue here with a link to a site built on Riyu
79 |
You can open this page again by clicking the i button on the left inside the editor
80 |
81 |
82 |
83 | }
84 |
85 | )
86 |
--------------------------------------------------------------------------------
/editor/config/paths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var path = require('path');
4 | var fs = require('fs');
5 | var url = require('url');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebookincubator/create-react-app/issues/637
9 | var appDirectory = fs.realpathSync(process.cwd());
10 | function resolveApp(relativePath) {
11 | return path.resolve(appDirectory, relativePath);
12 | }
13 |
14 | // We support resolving modules according to `NODE_PATH`.
15 | // This lets you use absolute paths in imports inside large monorepos:
16 | // https://github.com/facebookincubator/create-react-app/issues/253.
17 |
18 | // It works similar to `NODE_PATH` in Node itself:
19 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
20 |
21 | // We will export `nodePaths` as an array of absolute paths.
22 | // It will then be used by Webpack configs.
23 | // Jest doesn’t need this because it already handles `NODE_PATH` out of the box.
24 |
25 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
26 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
27 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
28 |
29 | var nodePaths = (process.env.NODE_PATH || '')
30 | .split(process.platform === 'win32' ? ';' : ':')
31 | .filter(Boolean)
32 | .filter(folder => !path.isAbsolute(folder))
33 | .map(resolveApp);
34 |
35 | var envPublicUrl = process.env.PUBLIC_URL;
36 |
37 | function ensureSlash(path, needsSlash) {
38 | var hasSlash = path.endsWith('/');
39 | if (hasSlash && !needsSlash) {
40 | return path.substr(path, path.length - 1);
41 | } else if (!hasSlash && needsSlash) {
42 | return path + '/';
43 | } else {
44 | return path;
45 | }
46 | }
47 |
48 | function getPublicUrl(appPackageJson) {
49 | return envPublicUrl || require(appPackageJson).homepage;
50 | }
51 |
52 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
53 | // "public path" at which the app is served.
54 | // Webpack needs to know it to put the right
159 |