- run eslint --fix across project

This commit is contained in:
Amruth Pillai 2020-07-09 00:14:13 +05:30
parent a1931f5e36
commit 9045e2983d
72 changed files with 1392 additions and 868 deletions

24
.eslintrc Normal file
View File

@ -0,0 +1,24 @@
{
"globals": {
"document": true,
"localStorage": true
},
"extends": ["airbnb", "prettier"],
"plugins": ["prettier"],
"rules": {
"import/no-extraneous-dependencies": ["error", { "devDependencies": true }],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"jsx-a11y/label-has-associated-control": 0,
"react/jsx-one-expression-per-line": 0,
"react/jsx-props-no-spreading": 0,
"prettier/prettier": ["error"],
"react/no-array-index-key": 0,
"react/button-has-type": 0,
"no-unused-expressions": 0,
"no-restricted-syntax": 0,
"no-param-reassign": 0,
"consistent-return": 0,
"no-nested-ternary": 0,
"react/prop-types": 0
}
}

View File

@ -1 +1,5 @@
{}
{
"semi": true,
"trailingComma": "all",
"singleQuote": true
}

View File

@ -4,8 +4,8 @@
},
"[javascriptreact]": {
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": true,
"source.fixAll": true
}
},
"editor.formatOnSave": true
}
}

View File

@ -1,29 +1,30 @@
import { createMuiTheme, MuiThemeProvider } from "@material-ui/core";
import "firebase/analytics";
import "firebase/auth";
import "firebase/database";
import "firebase/storage";
import React from "react";
import { DatabaseProvider } from "./src/contexts/DatabaseContext";
import { ModalProvider } from "./src/contexts/ModalContext";
import { ResumeProvider } from "./src/contexts/ResumeContext";
import { StorageProvider } from "./src/contexts/StorageContext";
import { TemplateProvider } from "./src/contexts/TemplateContext";
import { ThemeProvider } from "./src/contexts/ThemeContext";
import { UserProvider } from "./src/contexts/UserContext";
import "./src/styles/colors.css";
import "./src/styles/global.css";
import "./src/styles/shadows.css";
import "./src/styles/tailwind.css";
import "./src/styles/toastify.css";
import { createMuiTheme, MuiThemeProvider } from '@material-ui/core';
import 'firebase/analytics';
import 'firebase/auth';
import 'firebase/database';
import 'firebase/storage';
import React from 'react';
import { DatabaseProvider } from './src/contexts/DatabaseContext';
import { ModalProvider } from './src/contexts/ModalContext';
import { ResumeProvider } from './src/contexts/ResumeContext';
import { StorageProvider } from './src/contexts/StorageContext';
import { TemplateProvider } from './src/contexts/TemplateContext';
import { ThemeProvider } from './src/contexts/ThemeContext';
import { UserProvider } from './src/contexts/UserContext';
import './src/styles/colors.css';
import './src/styles/global.css';
import './src/styles/shadows.css';
import './src/styles/tailwind.css';
import './src/styles/toastify.css';
const theme = createMuiTheme({
typography: {
fontWeightRegular: 500,
fontFamily: ["Montserrat", "sans-serif"].join(","),
fontFamily: ['Montserrat', 'sans-serif'].join(','),
},
});
// eslint-disable-next-line import/prefer-default-export
export const wrapRootElement = ({ element }) => (
<ThemeProvider>
<MuiThemeProvider theme={theme}>

View File

@ -1,53 +1,65 @@
require("dotenv").config();
require('dotenv').config();
module.exports = {
plugins: [
`gatsby-plugin-react-helmet`,
'gatsby-plugin-react-helmet',
{
resolve: `gatsby-plugin-prefetch-google-fonts`,
resolve: 'gatsby-plugin-eslint',
options: {
test: /\.js$|\.jsx$/,
exclude: /(node_modules|.cache|public)/,
stages: ['develop'],
options: {
emitWarning: true,
failOnError: false,
},
},
},
{
resolve: 'gatsby-plugin-prefetch-google-fonts',
options: {
fonts: [
{
family: `Montserrat`,
variants: [`400`, `500`, `600`, `700`],
family: 'Montserrat',
variants: ['400', '500', '600', '700'],
},
],
},
},
{
resolve: `gatsby-plugin-create-client-paths`,
options: { prefixes: [`/app/*`] },
resolve: 'gatsby-plugin-create-client-paths',
options: { prefixes: ['/app/*'] },
},
{
resolve: `gatsby-plugin-offline`,
resolve: 'gatsby-plugin-offline',
options: {
precachePages: [`/`, `/app/*`],
precachePages: ['/', '/app/*'],
},
},
`gatsby-plugin-lodash`,
'gatsby-plugin-lodash',
{
resolve: `gatsby-plugin-manifest`,
resolve: 'gatsby-plugin-manifest',
options: {
name: `Reactive Resume`,
short_name: `RxResume`,
start_url: `/`,
background_color: `#FFFFFF`,
theme_color: `#444444`,
display: `standalone`,
name: 'Reactive Resume',
short_name: 'RxResume',
start_url: '/',
background_color: '#FFFFFF',
theme_color: '#444444',
display: 'standalone',
},
},
`gatsby-plugin-postcss`,
'gatsby-plugin-postcss',
{
resolve: `gatsby-source-filesystem`,
resolve: 'gatsby-source-filesystem',
options: {
name: `images`,
name: 'images',
path: `${__dirname}/assets/images/`,
},
},
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`,
'gatsby-plugin-sharp',
'gatsby-transformer-sharp',
{
resolve: "gatsby-plugin-firebase",
resolve: 'gatsby-plugin-firebase',
options: {
credentials: {
apiKey: process.env.FIREBASE_APIKEY,

View File

@ -1,12 +1,14 @@
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
exports.onCreateWebpackConfig = ({ actions, stage, getConfig }) => {
if (stage === "build-javascript") {
if (stage === 'build-javascript') {
const config = getConfig();
const index = config.plugins.findIndex((plugin) => {
return plugin.constructor.name === "MiniCssExtractPlugin";
return plugin.constructor.name === 'MiniCssExtractPlugin';
});
config.plugins[index] = new MiniCssExtractPlugin({
ignoreOrder: true,
});
config.plugins[index] = new MiniCssExtractPlugin({ ignoreOrder: true });
actions.replaceWebpackConfig(config);
}
};

View File

@ -1,4 +1,4 @@
import "firebase/analytics";
import "firebase/auth";
import "firebase/database";
import "firebase/storage";
import 'firebase/analytics';
import 'firebase/auth';
import 'firebase/database';
import 'firebase/storage';

665
package-lock.json generated
View File

@ -7144,6 +7144,23 @@
}
}
},
"enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
"integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
"dev": true,
"requires": {
"ansi-colors": "^4.1.1"
},
"dependencies": {
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true
}
}
},
"entities": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
@ -7227,21 +7244,23 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"eslint": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
"integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.4.0.tgz",
"integrity": "sha512-gU+lxhlPHu45H3JkEGgYhWhkR9wLHHEXC9FbWFnTlEkbKyZKWgWRLgf61E8zWmBuI6g5xKBph9ltg3NtZMVF8g==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"ajv": "^6.10.0",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.5",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"eslint-scope": "^5.0.0",
"eslint-utils": "^1.4.3",
"eslint-visitor-keys": "^1.1.0",
"espree": "^6.1.2",
"esquery": "^1.0.1",
"enquirer": "^2.3.5",
"eslint-scope": "^5.1.0",
"eslint-utils": "^2.0.0",
"eslint-visitor-keys": "^1.2.0",
"espree": "^7.1.0",
"esquery": "^1.2.0",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
@ -7250,51 +7269,90 @@
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^7.0.0",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"levn": "^0.4.1",
"lodash": "^4.17.14",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.3",
"optionator": "^0.9.1",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^6.1.2",
"strip-ansi": "^5.2.0",
"strip-json-comments": "^3.0.1",
"regexpp": "^3.1.0",
"semver": "^7.2.1",
"strip-ansi": "^6.0.0",
"strip-json-comments": "^3.1.0",
"table": "^5.2.3",
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"eslint-utils": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
"integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
"requires": {
"eslint-visitor-keys": "^1.1.0"
}
},
"glob-parent": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
@ -7303,37 +7361,121 @@
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
"regexpp": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
"integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw=="
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
"dev": true
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
"ansi-regex": "^5.0.0"
}
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"v8-compile-cache": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
"integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ=="
"integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
"dev": true
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
}
}
},
"eslint-config-airbnb": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.0.tgz",
"integrity": "sha512-Fz4JIUKkrhO0du2cg5opdyPKQXOI2MvF8KUvN2710nJMT6jaRUpRE2swrJftAjVGL7T1otLM5ieo5RqS1v9Udg==",
"dev": true,
"requires": {
"eslint-config-airbnb-base": "^14.2.0",
"object.assign": "^4.1.0",
"object.entries": "^1.1.2"
}
},
"eslint-config-airbnb-base": {
"version": "14.2.0",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz",
"integrity": "sha512-Snswd5oC6nJaevs3nZoLSTvGJBvzTfnBqOIArkf3cbyTyq9UD79wOk8s+RiL6bhca0p/eRO6veczhf6A/7Jy8Q==",
"dev": true,
"requires": {
"confusing-browser-globals": "^1.0.9",
"object.assign": "^4.1.0",
"object.entries": "^1.1.2"
}
},
"eslint-config-prettier": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz",
"integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==",
"dev": true,
"requires": {
"get-stdin": "^6.0.0"
},
"dependencies": {
"get-stdin": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
"integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
"dev": true
}
}
},
@ -7370,24 +7512,103 @@
}
},
"eslint-loader": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.2.1.tgz",
"integrity": "sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-4.0.2.tgz",
"integrity": "sha512-EDpXor6lsjtTzZpLUn7KmXs02+nIjGcgees9BYjNkWra3jVq5vVa8IoCKgzT2M7dNNeoMBtaSG83Bd40N3poLw==",
"dev": true,
"requires": {
"loader-fs-cache": "^1.0.0",
"loader-utils": "^1.0.2",
"object-assign": "^4.0.1",
"object-hash": "^1.1.4",
"rimraf": "^2.6.1"
"find-cache-dir": "^3.3.1",
"fs-extra": "^8.1.0",
"loader-utils": "^2.0.0",
"object-hash": "^2.0.3",
"schema-utils": "^2.6.5"
},
"dependencies": {
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"find-cache-dir": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
"integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
"dev": true,
"requires": {
"glob": "^7.1.3"
"commondir": "^1.0.1",
"make-dir": "^3.0.2",
"pkg-dir": "^4.1.0"
}
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"requires": {
"p-locate": "^4.1.0"
}
},
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"requires": {
"semver": "^6.0.0"
}
},
"object-hash": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz",
"integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==",
"dev": true
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"requires": {
"p-limit": "^2.2.0"
}
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
"requires": {
"find-up": "^4.0.0"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
@ -7547,6 +7768,15 @@
}
}
},
"eslint-plugin-prettier": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz",
"integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==",
"dev": true,
"requires": {
"prettier-linter-helpers": "^1.0.0"
}
},
"eslint-plugin-react": {
"version": "7.20.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz",
@ -7603,13 +7833,14 @@
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
},
"espree": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
"integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz",
"integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==",
"dev": true,
"requires": {
"acorn": "^7.1.1",
"acorn": "^7.2.0",
"acorn-jsx": "^5.2.0",
"eslint-visitor-keys": "^1.1.0"
"eslint-visitor-keys": "^1.2.0"
}
},
"esprima": {
@ -8093,6 +8324,12 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"fast-diff": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
"dev": true
},
"fast-glob": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
@ -8720,6 +8957,100 @@
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
},
"eslint": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
"integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
"requires": {
"@babel/code-frame": "^7.0.0",
"ajv": "^6.10.0",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.5",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"eslint-scope": "^5.0.0",
"eslint-utils": "^1.4.3",
"eslint-visitor-keys": "^1.1.0",
"espree": "^6.1.2",
"esquery": "^1.0.1",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^5.0.0",
"globals": "^12.1.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^7.0.0",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"lodash": "^4.17.14",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.3",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^6.1.2",
"strip-ansi": "^5.2.0",
"strip-json-comments": "^3.0.1",
"table": "^5.2.3",
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "^2.1.1"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
},
"v8-compile-cache": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
"integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ=="
}
}
},
"eslint-loader": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.2.1.tgz",
"integrity": "sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg==",
"requires": {
"loader-fs-cache": "^1.0.0",
"loader-utils": "^1.0.2",
"object-assign": "^4.0.1",
"object-hash": "^1.1.4",
"rimraf": "^2.6.1"
}
},
"eslint-utils": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
"integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
"requires": {
"eslint-visitor-keys": "^1.1.0"
}
},
"espree": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
"integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
"requires": {
"acorn": "^7.1.1",
"acorn-jsx": "^5.2.0",
"eslint-visitor-keys": "^1.1.0"
}
},
"gatsby-cli": {
"version": "2.12.59",
"resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-2.12.59.tgz",
@ -8774,6 +9105,22 @@
}
}
},
"glob-parent": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
"requires": {
"is-glob": "^4.0.1"
}
},
"globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"requires": {
"type-fest": "^0.8.1"
}
},
"hosted-git-info": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz",
@ -8782,6 +9129,25 @@
"lru-cache": "^5.1.1"
}
},
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
},
"is-plain-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
}
},
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@ -8790,11 +9156,98 @@
"yallist": "^3.0.2"
}
},
"mini-css-extract-plugin": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.2.tgz",
"integrity": "sha512-a3Y4of27Wz+mqK3qrcd3VhYz6cU0iW5x3Sgvqzbj+XmlrSizmvu8QQMl5oMYJjgHOC4iyt+w7l4umP+dQeW3bw==",
"requires": {
"loader-utils": "^1.1.0",
"normalize-url": "1.9.1",
"schema-utils": "^1.0.0",
"webpack-sources": "^1.1.0"
}
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"normalize-url": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
"integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
"requires": {
"object-assign": "^4.0.1",
"prepend-http": "^1.0.0",
"query-string": "^4.1.0",
"sort-keys": "^1.0.0"
},
"dependencies": {
"query-string": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
"requires": {
"object-assign": "^4.1.0",
"strict-uri-encode": "^1.0.0"
}
}
}
},
"optionator": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
"integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
"requires": {
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.6",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"word-wrap": "~1.2.3"
}
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"prepend-http": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
},
"regexpp": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
"integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw=="
},
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"requires": {
"glob": "^7.1.3"
}
},
"schema-utils": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
"requires": {
"ajv": "^6.1.0",
"ajv-errors": "^1.0.0",
"ajv-keywords": "^3.1.0"
}
},
"sort-keys": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
"integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
"requires": {
"is-plain-obj": "^1.0.0"
}
},
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
@ -8808,6 +9261,14 @@
"ansi-regex": "^4.1.0"
}
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
"prelude-ls": "~1.1.2"
}
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
@ -8884,6 +9345,12 @@
"@babel/runtime": "^7.10.3"
}
},
"gatsby-plugin-eslint": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/gatsby-plugin-eslint/-/gatsby-plugin-eslint-2.0.8.tgz",
"integrity": "sha512-vAMy37povmQJNg6ZxY78fkWR3pKwG8MNMhO3u+4vXj2MYT5avhFvHPJTAb126ZCuygf30gAWlpwbV50zP894Jw==",
"dev": true
},
"gatsby-plugin-firebase": {
"version": "0.2.0-beta.4",
"resolved": "https://registry.npmjs.org/gatsby-plugin-firebase/-/gatsby-plugin-firebase-0.2.0-beta.4.tgz",
@ -12102,12 +12569,13 @@
}
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
"requires": {
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
}
},
"lines-and-columns": {
@ -12883,9 +13351,10 @@
}
},
"mini-css-extract-plugin": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.2.tgz",
"integrity": "sha512-a3Y4of27Wz+mqK3qrcd3VhYz6cU0iW5x3Sgvqzbj+XmlrSizmvu8QQMl5oMYJjgHOC4iyt+w7l4umP+dQeW3bw==",
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz",
"integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==",
"dev": true,
"requires": {
"loader-utils": "^1.1.0",
"normalize-url": "1.9.1",
@ -12896,12 +13365,14 @@
"is-plain-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
"dev": true
},
"normalize-url": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
"integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
"dev": true,
"requires": {
"object-assign": "^4.0.1",
"prepend-http": "^1.0.0",
@ -12912,12 +13383,14 @@
"prepend-http": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
"dev": true
},
"query-string": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
"dev": true,
"requires": {
"object-assign": "^4.1.0",
"strict-uri-encode": "^1.0.0"
@ -12927,6 +13400,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
"dev": true,
"requires": {
"ajv": "^6.1.0",
"ajv-errors": "^1.0.0",
@ -12937,6 +13411,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
"integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
"dev": true,
"requires": {
"is-plain-obj": "^1.0.0"
}
@ -13672,16 +14147,17 @@
}
},
"optionator": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
"integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
"dev": true,
"requires": {
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.6",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"word-wrap": "~1.2.3"
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
"type-check": "^0.4.0",
"word-wrap": "^1.2.3"
}
},
"original": {
@ -14669,12 +15145,12 @@
}
},
"postcss-nested": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.2.1.tgz",
"integrity": "sha512-AMayXX8tS0HCp4O4lolp4ygj9wBn32DJWXvG6gCv+ZvJrEa00GUxJcJEEzMh87BIe6FrWdYkpR2cuyqHKrxmXw==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.2.2.tgz",
"integrity": "sha512-KivGs+ikQlX8VvR9pbaNA/eVmnCN9WcvD8sO9gPqgy6Q6teOH9NqbHHv+czcVJwbBtIdcq/lCzsVgK9daNrhDQ==",
"dev": true,
"requires": {
"postcss": "^7.0.21",
"postcss": "^7.0.32",
"postcss-selector-parser": "^6.0.2"
}
},
@ -14974,9 +15450,10 @@
}
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"prepend-http": {
"version": "2.0.0",
@ -14988,6 +15465,15 @@
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz",
"integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg=="
},
"prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"requires": {
"fast-diff": "^1.1.2"
}
},
"pretty-bytes": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz",
@ -18512,11 +18998,12 @@
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
"requires": {
"prelude-ls": "~1.1.2"
"prelude-ls": "^1.2.1"
}
},
"type-fest": {

View File

@ -5,6 +5,8 @@
"version": "2.0.0",
"license": "MIT",
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
@ -15,8 +17,10 @@
},
"dependencies": {
"@material-ui/core": "^4.11.0",
"@reach/router": "^1.3.4",
"array-move": "^2.2.2",
"classnames": "^2.2.6",
"dotenv": "^8.2.0",
"firebase": "^7.15.5",
"formik": "^2.1.4",
"gatsby": "^2.23.22",
@ -33,7 +37,7 @@
"gatsby-source-filesystem": "^2.3.18",
"gatsby-source-gravatar": "^1.0.0",
"gatsby-transformer-sharp": "^2.5.10",
"lodash": "^4.17.17",
"lodash": "^4.17.19",
"moment": "^2.27.0",
"nanoevents": "^5.1.8",
"react": "^16.13.1",
@ -46,6 +50,16 @@
"yup": "^0.29.1"
},
"devDependencies": {
"eslint": "^7.4.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.20.3",
"gatsby-plugin-eslint": "^2.0.8",
"mini-css-extract-plugin": "^0.9.0",
"prettier": "2.0.5",
"tailwindcss": "^1.4.6"
},

View File

@ -1,3 +1,5 @@
const tailwindcss = require('tailwindcss');
module.exports = () => ({
plugins: [require("tailwindcss")],
plugins: [tailwindcss],
});

View File

@ -1,14 +1,14 @@
import React, { useContext } from "react";
import { Helmet } from "react-helmet";
import { useSelector } from "../../../contexts/ResumeContext";
import TemplateContext from "../../../contexts/TemplateContext";
import Onyx from "../../../templates/Onyx";
import styles from "./Artboard.module.css";
import React, { useContext } from 'react';
import { Helmet } from 'react-helmet';
import { useSelector } from '../../../contexts/ResumeContext';
import TemplateContext from '../../../contexts/TemplateContext';
import Onyx from '../../../templates/Onyx';
import styles from './Artboard.module.css';
const Artboard = () => {
const { blocks, colors } = useContext(TemplateContext);
const state = useSelector((state) => state),
{ id, name } = state;
const state = useSelector((s) => s);
const { id, name } = state;
return (
<div>

View File

@ -1,31 +1,29 @@
import { Link } from "gatsby";
import React from "react";
import sections from "../../../data/leftSections";
import Avatar from "../../shared/Avatar";
import Logo from "../../shared/Logo";
import SectionIcon from "../../shared/SectionIcon";
import styles from "./LeftNavbar.module.css";
import { Link } from 'gatsby';
import React from 'react';
import sections from '../../../data/leftSections';
import Avatar from '../../shared/Avatar';
import Logo from '../../shared/Logo';
import SectionIcon from '../../shared/SectionIcon';
import styles from './LeftNavbar.module.css';
const LeftNavbar = () => {
return (
<div className={styles.container}>
<Link to="/app/dashboard">
<Logo size="40px" />
</Link>
const LeftNavbar = () => (
<div className={styles.container}>
<Link to="/app/dashboard">
<Logo size="40px" />
</Link>
<hr className="my-6" />
<hr className="my-6" />
<div className="grid grid-cols-1 gap-8">
{sections.map((x) => (
<SectionIcon key={x.id} section={x} />
))}
</div>
<hr className="mt-auto my-6" />
<Avatar />
<div className="grid grid-cols-1 gap-8">
{sections.map((x) => (
<SectionIcon key={x.id} section={x} />
))}
</div>
);
};
<hr className="mt-auto my-6" />
<Avatar />
</div>
);
export default LeftNavbar;

View File

@ -1,23 +1,21 @@
import React, { Fragment } from "react";
import sections from "../../../data/leftSections";
import LeftNavbar from "./LeftNavbar";
import styles from "./LeftSidebar.module.css";
import React, { Fragment } from 'react';
import sections from '../../../data/leftSections';
import LeftNavbar from './LeftNavbar';
import styles from './LeftSidebar.module.css';
const LeftSidebar = () => {
return (
<div className="flex">
<LeftNavbar />
const LeftSidebar = () => (
<div className="flex">
<LeftNavbar />
<div className={styles.container}>
{sections.map(({ id, name, event, component: Component }) => (
<Fragment key={id}>
<Component id={id} name={name} event={event} />
<hr />
</Fragment>
))}
</div>
<div className={styles.container}>
{sections.map(({ id, name, event, component: Component }) => (
<Fragment key={id}>
<Component id={id} name={name} event={event} />
<hr />
</Fragment>
))}
</div>
);
};
</div>
);
export default LeftSidebar;

View File

@ -1,4 +1,4 @@
import React from "react";
import React from 'react';
const EmptyList = () => (
<div className="py-6 opacity-75 text-center">This list is empty.</div>

View File

@ -1,13 +1,13 @@
import { get, isEmpty } from "lodash";
import moment from "moment";
import React, { useContext } from "react";
import { MdAdd } from "react-icons/md";
import ModalContext from "../../../contexts/ModalContext";
import { useSelector } from "../../../contexts/ResumeContext";
import Button from "../../shared/Button";
import EmptyList from "./EmptyList";
import styles from "./List.module.css";
import ListItem from "./ListItem";
import { get, isEmpty } from 'lodash';
import moment from 'moment';
import React, { useContext } from 'react';
import { MdAdd } from 'react-icons/md';
import ModalContext from '../../../contexts/ModalContext';
import { useSelector } from '../../../contexts/ResumeContext';
import Button from '../../shared/Button';
import EmptyList from './EmptyList';
import styles from './List.module.css';
import ListItem from './ListItem';
const List = ({
path,
@ -27,10 +27,10 @@ const List = ({
const handleEdit = (data) => emitter.emit(event, data);
const formatDateRange = (x) =>
`${moment(x.startDate).format("MMMM Y")}${
`${moment(x.startDate).format('MMMM Y')}${
moment(x.endDate).isValid()
? moment(x.endDate).format("MMMM Y")
: "Present"
? moment(x.endDate).format('MMMM Y')
: 'Present'
}`;
return (
@ -44,11 +44,11 @@ const List = ({
key={x.id}
data={x}
path={path}
title={title || get(x, titlePath, "")}
title={title || get(x, titlePath, '')}
subtitle={
subtitle || get(x, subtitlePath, "") || formatDateRange(x)
subtitle || get(x, subtitlePath, '') || formatDateRange(x)
}
text={text || get(x, textPath, "")}
text={text || get(x, textPath, '')}
className={styles.listItem}
onEdit={() => handleEdit(x)}
isFirst={i === 0}

View File

@ -1,9 +1,9 @@
import { Menu, MenuItem } from "@material-ui/core";
import React, { useState } from "react";
import { IoIosArrowDown, IoIosArrowUp } from "react-icons/io";
import { MdMoreVert } from "react-icons/md";
import { useDispatch } from "../../../contexts/ResumeContext";
import styles from "./ListItem.module.css";
import { Menu, MenuItem } from '@material-ui/core';
import React, { useState } from 'react';
import { IoIosArrowDown, IoIosArrowUp } from 'react-icons/io';
import { MdMoreVert } from 'react-icons/md';
import { useDispatch } from '../../../contexts/ResumeContext';
import styles from './ListItem.module.css';
const ListItem = ({
title,
@ -29,7 +29,7 @@ const ListItem = ({
const handleMoveUp = () => {
dispatch({
type: "on_move_item_up",
type: 'on_move_item_up',
payload: {
path,
value: data,
@ -41,7 +41,7 @@ const ListItem = ({
const handleMoveDown = () => {
dispatch({
type: "on_move_item_down",
type: 'on_move_item_down',
payload: {
path,
value: data,
@ -53,7 +53,7 @@ const ListItem = ({
const handleDelete = () => {
dispatch({
type: "on_delete_item",
type: 'on_delete_item',
payload: {
path,
value: data,

View File

@ -1,12 +1,9 @@
import cx from "classnames";
import React, { useContext } from "react";
import { MdPerson, MdSync, MdSyncDisabled } from "react-icons/md";
import DatabaseContext from "../../../contexts/DatabaseContext";
import styles from "./RightNavbar.module.css";
import React from 'react';
import { MdPerson } from 'react-icons/md';
import styles from './RightNavbar.module.css';
import SyncIndicator from './SyncIndicator';
const RightNavbar = () => {
const { isOffline, isUpdating } = useContext(DatabaseContext);
return (
<div className={styles.container}>
<div className="grid grid-cols-1 gap-6">
@ -16,13 +13,9 @@ const RightNavbar = () => {
/>
</div>
<div className="text-4xl mt-auto">
{isOffline ? (
<MdSyncDisabled className="text-red-600" />
) : (
<MdSync className={cx({ spin: isUpdating })} />
)}
</div>
<hr className="mt-auto my-6" />
<SyncIndicator />
</div>
);
};

View File

@ -1,7 +1,7 @@
import React from "react";
import Layout from "../sections/Layout";
import RightNavbar from "./RightNavbar";
import styles from "./RightSidebar.module.css";
import React from 'react';
import Layout from '../sections/Layout';
import RightNavbar from './RightNavbar';
import styles from './RightSidebar.module.css';
const RightSidebar = () => {
return (

View File

@ -0,0 +1,20 @@
import cx from 'classnames';
import React, { useContext } from 'react';
import { MdSync, MdSyncDisabled } from 'react-icons/md';
import DatabaseContext from '../../../contexts/DatabaseContext';
const SyncIndicator = () => {
const { isOffline, isUpdating } = useContext(DatabaseContext);
return (
<div className="text-4xl">
{isOffline ? (
<MdSyncDisabled className="text-red-600" />
) : (
<MdSync className={cx({ spin: isUpdating })} />
)}
</div>
);
};
export default SyncIndicator;

View File

@ -1,8 +1,8 @@
import React from "react";
import Heading from "../../shared/Heading";
import List from "../lists/List";
import React from 'react';
import Heading from '../../shared/Heading';
import List from '../lists/List';
const Awards = ({ id, name, event, state }) => {
const Awards = ({ id, name, event }) => {
const path = `${id}.items`;
return (

View File

@ -1,8 +1,8 @@
import React from "react";
import Heading from "../../shared/Heading";
import List from "../lists/List";
import React from 'react';
import Heading from '../../shared/Heading';
import List from '../lists/List';
const Certifications = ({ id, name, event, state }) => {
const Certifications = ({ id, name, event }) => {
const path = `${id}.items`;
return (

View File

@ -1,8 +1,8 @@
import React from "react";
import Heading from "../../shared/Heading";
import List from "../lists/List";
import React from 'react';
import Heading from '../../shared/Heading';
import List from '../lists/List';
const Education = ({ id, name, event, state }) => {
const Education = ({ id, name, event }) => {
const path = `${id}.items`;
return (

View File

@ -1,8 +1,8 @@
import React, { useContext } from "react";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import TemplateContext from "../../../contexts/TemplateContext";
import Heading from "../../shared/Heading";
import styles from "./Layout.module.css";
import React, { useContext } from 'react';
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
import TemplateContext from '../../../contexts/TemplateContext';
import Heading from '../../shared/Heading';
import styles from './Layout.module.css';
const Layout = () => {
const { blocks, onDragEnd } = useContext(TemplateContext);
@ -20,11 +20,11 @@ const Layout = () => {
<DragDropContext onDragEnd={onDragEnd}>
{blocks.map((el, ind) => (
<Droppable key={ind} droppableId={`${ind}`}>
{(provided) => (
{(dropProvided) => (
<div
ref={provided.innerRef}
ref={dropProvided.innerRef}
className={styles.droppable}
{...provided.droppableProps}
{...dropProvided.droppableProps}
>
<div className="grid gap-3">
<span className="uppercase font-semibold text-xs">
@ -36,12 +36,12 @@ const Layout = () => {
draggableId={item.id}
index={index}
>
{(provided) => (
{(dragProvided) => (
<div
ref={provided.innerRef}
ref={dragProvided.innerRef}
className={styles.draggable}
{...provided.draggableProps}
{...provided.dragHandleProps}
{...dragProvided.draggableProps}
{...dragProvided.dragHandleProps}
>
{item.name}
</div>
@ -49,7 +49,7 @@ const Layout = () => {
</Draggable>
))}
</div>
{provided.placeholder}
{dropProvided.placeholder}
</div>
)}
</Droppable>

View File

@ -1,6 +1,6 @@
import React from "react";
import Heading from "../../shared/Heading";
import Input from "../../shared/Input";
import React from 'react';
import Heading from '../../shared/Heading';
import Input from '../../shared/Input';
const Objective = () => {
return (

View File

@ -1,7 +1,7 @@
import React from "react";
import Heading from "../../shared/Heading";
import Input from "../../shared/Input";
import PhotoUpload from "../../shared/PhotoUpload";
import React from 'react';
import Heading from '../../shared/Heading';
import Input from '../../shared/Input';
import PhotoUpload from '../../shared/PhotoUpload';
const Profile = () => {
return (

View File

@ -1,6 +1,6 @@
import React from "react";
import Heading from "../../shared/Heading";
import List from "../lists/List";
import React from 'react';
import Heading from '../../shared/Heading';
import List from '../lists/List';
const Skills = ({ id, name, event }) => {
const path = `${id}.items`;

View File

@ -1,6 +1,6 @@
import React from "react";
import Heading from "../../shared/Heading";
import List from "../lists/List";
import React from 'react';
import Heading from '../../shared/Heading';
import List from '../lists/List';
const Social = ({ id, name, event }) => {
const path = `${id}.items`;

View File

@ -1,8 +1,8 @@
import React from "react";
import Heading from "../../shared/Heading";
import List from "../lists/List";
import React from 'react';
import Heading from '../../shared/Heading';
import List from '../lists/List';
const Work = ({ id, name, event, state }) => {
const Work = ({ id, name, event }) => {
const path = `${id}.items`;
return (

View File

@ -1,8 +1,8 @@
import React, { useContext } from "react";
import { MdAdd } from "react-icons/md";
import ModalContext from "../../contexts/ModalContext";
import { handleKeyDown } from "../../utils";
import styles from "./CreateResume.module.css";
import React, { useContext } from 'react';
import { MdAdd } from 'react-icons/md';
import ModalContext from '../../contexts/ModalContext';
import { handleKeyDown } from '../../utils';
import styles from './CreateResume.module.css';
const CreateResume = () => {
const { emitter, events } = useContext(ModalContext);

View File

@ -1,12 +1,12 @@
import { Menu, MenuItem } from "@material-ui/core";
import { navigate } from "gatsby";
import moment from "moment";
import React, { useContext, useState } from "react";
import { MdMoreHoriz, MdOpenInNew } from "react-icons/md";
import { toast } from "react-toastify";
import DatabaseContext from "../../contexts/DatabaseContext";
import ModalContext from "../../contexts/ModalContext";
import styles from "./ResumePreview.module.css";
import { Menu, MenuItem } from '@material-ui/core';
import { navigate } from 'gatsby';
import moment from 'moment';
import React, { useContext, useState } from 'react';
import { MdMoreHoriz, MdOpenInNew } from 'react-icons/md';
import { toast } from 'react-toastify';
import DatabaseContext from '../../contexts/DatabaseContext';
import ModalContext from '../../contexts/ModalContext';
import styles from './ResumePreview.module.css';
const ResumePreview = ({ resume }) => {
const [anchorEl, setAnchorEl] = useState(null);

View File

@ -1,16 +1,16 @@
import { Link, navigate } from "gatsby";
import React, { useContext } from "react";
import UserContext from "../../contexts/UserContext";
import Avatar from "../shared/Avatar";
import Logo from "../shared/Logo";
import styles from "./TopNavbar.module.css";
import { Link, navigate } from 'gatsby';
import React, { useContext } from 'react';
import UserContext from '../../contexts/UserContext';
import Avatar from '../shared/Avatar';
import Logo from '../shared/Logo';
import styles from './TopNavbar.module.css';
const TopNavbar = () => {
const { logout } = useContext(UserContext);
const handleLogout = async () => {
await logout();
navigate("/");
navigate('/');
};
return (

View File

@ -1,11 +1,11 @@
import { navigate } from "gatsby";
import React, { useContext } from "react";
import { FaGithub } from "react-icons/fa";
import ModalContext from "../../contexts/ModalContext";
import ThemeContext from "../../contexts/ThemeContext";
import UserContext from "../../contexts/UserContext";
import Button from "../shared/Button";
import Logo from "../shared/Logo";
import { navigate } from 'gatsby';
import React, { useContext } from 'react';
import { FaGithub } from 'react-icons/fa';
import ModalContext from '../../contexts/ModalContext';
import ThemeContext from '../../contexts/ThemeContext';
import UserContext from '../../contexts/UserContext';
import Button from '../shared/Button';
import Logo from '../shared/Logo';
const Hero = () => {
const { emitter, events } = useContext(ModalContext);
@ -14,7 +14,7 @@ const Hero = () => {
const handleLogin = () => emitter.emit(events.AUTH_MODAL);
const handleGotoApp = () => navigate("/app/dashboard");
const handleGotoApp = () => navigate('/app/dashboard');
return (
<div className="flex items-center">

View File

@ -1,7 +1,7 @@
import { Fade, Modal } from "@material-ui/core";
import React from "react";
import { getRandomTip } from "../../data/tips";
import Logo from "../shared/Logo";
import { Fade, Modal } from '@material-ui/core';
import React from 'react';
import { getRandomTip } from '../../data/tips';
import Logo from '../shared/Logo';
const LoadingScreen = () => {
return (

View File

@ -1,7 +1,7 @@
import { navigate } from "gatsby";
import React, { useContext } from "react";
import UserContext from "../../contexts/UserContext";
import LoadingScreen from "./LoadingScreen";
import { navigate } from 'gatsby';
import React, { useContext } from 'react';
import UserContext from '../../contexts/UserContext';
import LoadingScreen from './LoadingScreen';
const PrivateRoute = ({ component: Component, location, ...props }) => {
const { user, loading } = useContext(UserContext);
@ -11,7 +11,7 @@ const PrivateRoute = ({ component: Component, location, ...props }) => {
}
if (!user) {
navigate("/");
navigate('/');
return null;
}

View File

@ -1,13 +1,13 @@
import cx from "classnames";
import { toUrl } from "gatsby-source-gravatar";
import React, { useContext, useMemo } from "react";
import UserContext from "../../contexts/UserContext";
import styles from "./Avatar.module.css";
import cx from 'classnames';
import { toUrl } from 'gatsby-source-gravatar';
import React, { useContext, useMemo } from 'react';
import UserContext from '../../contexts/UserContext';
import styles from './Avatar.module.css';
const Avatar = ({ className }) => {
const { user } = useContext(UserContext);
const photoURL = useMemo(() => toUrl(user.email, "size=128"), [user.email]);
const photoURL = useMemo(() => toUrl(user.email, 'size=128'), [user.email]);
return (
<img

View File

@ -1,17 +1,9 @@
import classNames from "classnames";
import React from "react";
import { handleKeyDown } from "../../utils";
import styles from "./Button.module.css";
import classNames from 'classnames';
import React from 'react';
import { handleKeyDown } from '../../utils';
import styles from './Button.module.css';
const Button = ({
icon,
title,
onClick,
outline,
className,
isLoading,
type = "button",
}) => {
const Button = ({ icon, title, onClick, outline, className, isLoading }) => {
const Icon = icon;
const classes = classNames(styles.container, className, {
[styles.outline]: outline,
@ -19,13 +11,12 @@ const Button = ({
return (
<button
type={type}
className={classes}
onKeyDown={(e) => handleKeyDown(e, onClick)}
onClick={isLoading ? undefined : onClick}
>
{icon && <Icon size="14" className="mr-2" />}
{isLoading ? "Loading..." : title}
{isLoading ? 'Loading...' : title}
</button>
);
};

View File

@ -1,4 +1,4 @@
import React from "react";
import React from 'react';
const Heading = ({ children }) => {
return <h2 className="text-4xl">{children}</h2>;

View File

@ -1,11 +1,11 @@
import cx from "classnames";
import { get, isFunction } from "lodash";
import React, { useMemo } from "react";
import { MdClose } from "react-icons/md";
import { v4 as uuidv4 } from "uuid";
import { useDispatch, useSelector } from "../../contexts/ResumeContext";
import { handleKeyDown } from "../../utils";
import styles from "./Input.module.css";
import cx from 'classnames';
import { get, isFunction } from 'lodash';
import React from 'react';
import { MdClose } from 'react-icons/md';
import { v4 as uuidv4 } from 'uuid';
import { useDispatch, useSelector } from '../../contexts/ResumeContext';
import { handleKeyDown } from '../../utils';
import styles from './Input.module.css';
const Input = ({
name,
@ -22,7 +22,7 @@ const Input = ({
placeholder,
onDeleteItem,
showDeleteItemButton,
type = "text",
type = 'text',
}) => {
const uuid = uuidv4();
const stateValue = useSelector((state) => get(state, path));
@ -33,7 +33,7 @@ const Input = ({
? onChange
: (e) => {
dispatch({
type: "on_input",
type: 'on_input',
payload: {
path,
value: e.target.value,
@ -41,93 +41,72 @@ const Input = ({
});
};
return useMemo(
() => (
<div className={cx(styles.container, className)}>
<label htmlFor={uuid}>
<span>
{label}{" "}
{isRequired && (
<span className="opacity-75 font-normal lowercase">
(Required)
</span>
return (
<div className={cx(styles.container, className)}>
<label htmlFor={uuid}>
<span>
{label}{' '}
{isRequired && (
<span className="opacity-75 font-normal lowercase">(Required)</span>
)}
</span>
{type === 'text' && (
<div className="relative grid items-center">
<input
id={uuid}
name={name}
type={type}
value={value}
onBlur={onBlur}
checked={checked}
onChange={onChange}
placeholder={placeholder}
/>
{showDeleteItemButton && isFunction(onDeleteItem) && (
<MdClose
size="16px"
tabIndex="0"
onClick={onDeleteItem}
onKeyDown={(e) => handleKeyDown(e, onDeleteItem)}
className="absolute right-0 cursor-pointer opacity-50 hover:opacity-75 mx-4"
/>
)}
</span>
</div>
)}
{type === "text" && (
<div className="relative grid items-center">
<input
id={uuid}
name={name}
type={type}
value={value}
onBlur={onBlur}
checked={checked}
onChange={onChange}
placeholder={placeholder}
/>
{type === 'textarea' && (
<div className="flex flex-col">
<textarea
id={uuid}
rows="4"
name={name}
type={type}
value={value}
onBlur={onBlur}
checked={checked}
onChange={onChange}
placeholder={placeholder}
/>
{showDeleteItemButton && isFunction(onDeleteItem) && (
<MdClose
size="16px"
tabIndex="0"
onClick={onDeleteItem}
onKeyDown={(e) => handleKeyDown(e, onDeleteItem)}
className="absolute right-0 cursor-pointer opacity-50 hover:opacity-75 mx-4"
/>
)}
</div>
)}
<p className="mt-2 text-sm opacity-75">
This text block supports{' '}
<a
href="https://www.markdownguide.org/basic-syntax/"
className="text-blue-600"
target="blank"
>
markdown
</a>
.
</p>
</div>
)}
{type === "textarea" && (
<div className="flex flex-col">
<textarea
id={uuid}
rows="4"
name={name}
type={type}
value={value}
onBlur={onBlur}
checked={checked}
onChange={onChange}
placeholder={placeholder}
/>
<p className="mt-2 text-sm opacity-75">
This text block supports{" "}
<a
href="https://www.markdownguide.org/basic-syntax/"
className="text-blue-600"
target="blank"
>
markdown
</a>
.
</p>
</div>
)}
{error && touched && <p>{error}</p>}
</label>
</div>
),
[
checked,
className,
error,
isRequired,
label,
name,
onBlur,
onChange,
onDeleteItem,
placeholder,
showDeleteItemButton,
touched,
type,
uuid,
value,
]
{error && touched && <p>{error}</p>}
</label>
</div>
);
};

View File

@ -1,10 +1,10 @@
import cx from "classnames";
import { graphql, useStaticQuery } from "gatsby";
import GatsbyImage from "gatsby-image";
import React from "react";
import styles from "./Logo.module.css";
import cx from 'classnames';
import { graphql, useStaticQuery } from 'gatsby';
import GatsbyImage from 'gatsby-image';
import React from 'react';
import styles from './Logo.module.css';
const Logo = ({ size = "256px", className }) => {
const Logo = ({ size = '256px', className }) => {
const { file } = useStaticQuery(graphql`
query {
file(relativePath: { eq: "logo.png" }) {

View File

@ -1,9 +1,9 @@
import React, { useContext, useRef } from "react";
import { MdFileUpload } from "react-icons/md";
import StorageContext from "../../contexts/StorageContext";
import { handleKeyDown } from "../../utils";
import Input from "./Input";
import styles from "./PhotoUpload.module.css";
import React, { useContext, useRef } from 'react';
import { MdFileUpload } from 'react-icons/md';
import StorageContext from '../../contexts/StorageContext';
import { handleKeyDown } from '../../utils';
import Input from './Input';
import styles from './PhotoUpload.module.css';
const PhotoUpload = () => {
const fileInputRef = useRef(null);

View File

@ -1,7 +1,7 @@
import { Tooltip } from "@material-ui/core";
import React from "react";
import { Tooltip } from '@material-ui/core';
import React from 'react';
const SectionIcon = ({ section, placement = "right" }) => {
const SectionIcon = ({ section, placement = 'right' }) => {
const { icon: Icon, name } = section;
return (

View File

@ -1,25 +1,25 @@
import React, { Fragment, useEffect } from "react";
import { Slide, toast } from "react-toastify";
import ModalRegistrar from "../../modals/ModalRegistrar";
import React, { useEffect } from 'react';
import { Slide, toast } from 'react-toastify';
import ModalRegistrar from '../../modals/ModalRegistrar';
const Wrapper = ({ children }) => {
useEffect(() => {
toast.configure({
role: "alert",
role: 'alert',
hideProgressBar: true,
transition: Slide,
closeButton: false,
position: "bottom-right",
position: 'bottom-right',
pauseOnFocusLoss: false,
});
}, []);
return (
<Fragment>
<>
{children}
<ModalRegistrar />
</Fragment>
</>
);
};

View File

@ -1,12 +1,12 @@
const ModalEvents = {
AUTH_MODAL: "auth_modal",
CREATE_RESUME_MODAL: "create_resume_modal",
SOCIAL_MODAL: "social_modal",
WORK_MODAL: "work_modal",
EDUCATION_MODAL: "education_modal",
AWARD_MODAL: "award_modal",
CERTIFICATION_MODAL: "certification_modal",
SKILL_MODAL: "skill_modal",
AUTH_MODAL: 'auth_modal',
CREATE_RESUME_MODAL: 'create_resume_modal',
SOCIAL_MODAL: 'social_modal',
WORK_MODAL: 'work_modal',
EDUCATION_MODAL: 'education_modal',
AWARD_MODAL: 'award_modal',
CERTIFICATION_MODAL: 'certification_modal',
SKILL_MODAL: 'skill_modal',
};
export default ModalEvents;

View File

@ -1,7 +1,7 @@
import firebase from "gatsby-plugin-firebase";
import { debounce } from "lodash";
import React, { createContext, useContext, useEffect, useState } from "react";
import UserContext from "./UserContext";
import firebase from 'gatsby-plugin-firebase';
import { debounce } from 'lodash';
import React, { createContext, useContext, useEffect, useState } from 'react';
import UserContext from './UserContext';
const defaultState = {
isOffline: false,
@ -22,8 +22,8 @@ const DatabaseProvider = ({ children }) => {
const { user } = useContext(UserContext);
useEffect(() => {
const connectedRef = firebase.database().ref(".info/connected");
connectedRef.on("value", (snapshot) => {
const connectedRef = firebase.database().ref('.info/connected');
connectedRef.on('value', (snapshot) => {
snapshot.val() === true ? setOffline(false) : setOffline(true);
});
}, []);
@ -32,7 +32,7 @@ const DatabaseProvider = ({ children }) => {
const snapshot = await firebase
.database()
.ref(`users/${user.uid}/resumes/${id}`)
.once("value");
.once('value');
return snapshot.val();
};
@ -40,10 +40,11 @@ const DatabaseProvider = ({ children }) => {
const { id } = resume;
const createdAt = firebase.database.ServerValue.TIMESTAMP;
let firstName, lastName;
let firstName;
let lastName;
if (!user.isAnonymous) {
[firstName, lastName] = user.displayName.split(" ");
[firstName, lastName] = user.displayName.split(' ');
}
firebase
@ -51,8 +52,8 @@ const DatabaseProvider = ({ children }) => {
.ref(`users/${user.uid}/resumes/${id}`)
.set({
profile: {
firstName: firstName || "",
lastName: lastName || "",
firstName: firstName || '',
lastName: lastName || '',
},
...resume,
createdAt,

View File

@ -1,6 +1,6 @@
import { createNanoEvents } from "nanoevents";
import React, { createContext } from "react";
import ModalEvents from "../constants/ModalEvents";
import { createNanoEvents } from 'nanoevents';
import React, { createContext } from 'react';
import ModalEvents from '../constants/ModalEvents';
const emitter = createNanoEvents();

View File

@ -1,12 +1,12 @@
import arrayMove from "array-move";
import { clone, findIndex, get, setWith } from "lodash";
import arrayMove from 'array-move';
import { clone, findIndex, get, setWith } from 'lodash';
import React, {
createContext,
useCallback,
useContext,
useReducer,
} from "react";
import DatabaseContext from "./DatabaseContext";
} from 'react';
import DatabaseContext from './DatabaseContext';
const initialState = {};
@ -17,71 +17,73 @@ const ResumeProvider = ({ children }) => {
const memoizedReducer = useCallback(
(state, { type, payload }) => {
let newState, index, items;
let newState;
let index;
let items;
switch (type) {
case "on_add_item":
delete payload.value.__temp;
case 'on_add_item':
delete payload.value.temp;
items = get(state, payload.path, []);
newState = setWith(
clone(state),
payload.path,
[...items, payload.value],
clone
clone,
);
debouncedUpdate(newState);
return newState;
case "on_edit_item":
delete payload.value.__temp;
case 'on_edit_item':
delete payload.value.temp;
items = get(state, payload.path);
index = findIndex(items, ["id", payload.value.id]);
index = findIndex(items, ['id', payload.value.id]);
newState = setWith(
clone(state),
`${payload.path}[${index}]`,
payload.value,
clone
clone,
);
debouncedUpdate(newState);
return newState;
case "on_delete_item":
case 'on_delete_item':
items = get(state, payload.path);
index = findIndex(items, ["id", payload.value.id]);
index = findIndex(items, ['id', payload.value.id]);
items.splice(index, 1);
newState = setWith(clone(state), payload.path, items, clone);
debouncedUpdate(newState);
return newState;
case "on_move_item_up":
case 'on_move_item_up':
items = get(state, payload.path);
index = findIndex(items, ["id", payload.value.id]);
index = findIndex(items, ['id', payload.value.id]);
items = arrayMove(items, index, index - 1);
newState = setWith(clone(state), payload.path, items, clone);
debouncedUpdate(newState);
return newState;
case "on_move_item_down":
case 'on_move_item_down':
items = get(state, payload.path);
index = findIndex(items, ["id", payload.value.id]);
index = findIndex(items, ['id', payload.value.id]);
items = arrayMove(items, index, index + 1);
newState = setWith(clone(state), payload.path, items, clone);
debouncedUpdate(newState);
return newState;
case "on_input":
case 'on_input':
newState = setWith(clone(state), payload.path, payload.value, clone);
debouncedUpdate(newState);
return newState;
case "set_data":
case 'set_data':
return payload;
default:
throw new Error();
}
},
[debouncedUpdate]
[debouncedUpdate],
);
const [state, dispatch] = useReducer(memoizedReducer, initialState);

View File

@ -1,9 +1,9 @@
import firebase from "gatsby-plugin-firebase";
import React, { createContext, useContext, useRef } from "react";
import { toast } from "react-toastify";
import { isFileImage } from "../utils";
import { useDispatch, useSelector } from "./ResumeContext";
import UserContext from "./UserContext";
import firebase from 'gatsby-plugin-firebase';
import React, { createContext, useContext, useRef } from 'react';
import { toast } from 'react-toastify';
import { isFileImage } from '../utils';
import { useDispatch, useSelector } from './ResumeContext';
import UserContext from './UserContext';
const defaultState = {
uploadPhotograph: async () => {},
@ -22,7 +22,7 @@ const StorageProvider = ({ children }) => {
const uploadPhotograph = async (file) => {
if (!isFileImage(file)) {
toast.error(
"You tried to upload a file that was not an image. That won't look good on your resume. Please try again."
"You tried to upload a file that was not an image. That won't look good on your resume. Please try again.",
);
return null;
}
@ -33,16 +33,16 @@ const StorageProvider = ({ children }) => {
.put(file);
let progress = 0;
toastId.current = toast("Firing up engines...", {
toastId.current = toast('Firing up engines...', {
progress,
});
uploadTask.on(
"state_changed",
'state_changed',
(snapshot) => {
progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
toast.update(toastId.current, {
render: "Uploading...",
render: 'Uploading...',
progress,
hideProgressBar: false,
});
@ -51,23 +51,23 @@ const StorageProvider = ({ children }) => {
async () => {
const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
dispatch({
type: "on_input",
type: 'on_input',
payload: {
path: "profile.photograph",
path: 'profile.photograph',
value: downloadURL,
},
});
toast.update(toastId.current, {
render:
"Your photograph was uploaded successfully... and you look great!",
'Your photograph was uploaded successfully... and you look great!',
progress,
autoClose: 5000,
hideProgressBar: true,
});
toastId.current = null;
}
},
);
};

View File

@ -1,14 +1,14 @@
import { flatten } from "lodash";
import React, { createContext, useState } from "react";
import leftSections from "../data/leftSections";
import { flatten } from 'lodash';
import React, { createContext, useState } from 'react';
import leftSections from '../data/leftSections';
const defaultState = {
selected: "Pikachu",
selected: 'Pikachu',
setSelected: () => {},
colors: {
textColor: "#212121",
primaryColor: "#f44336",
backgroundColor: "#FFFFFF",
textColor: '#212121',
primaryColor: '#f44336',
backgroundColor: '#FFFFFF',
},
blocks: [leftSections],
setBlocks: () => {},
@ -60,17 +60,17 @@ const TemplateProvider = ({ children }) => {
newState[sInd] = items;
setBlocks(newState);
} else {
const result = move(blocks[sInd], blocks[dInd], source, destination);
const newResult = move(blocks[sInd], blocks[dInd], source, destination);
const newState = [...blocks];
newState[sInd] = result[sInd];
newState[dInd] = result[dInd];
newState[sInd] = newResult[sInd];
newState[dInd] = newResult[dInd];
setBlocks(newState);
}
};
const setFixedBlocks = (fixedBlocks) => {
const newBlocks = blocks.map((x) =>
x.filter((y) => !fixedBlocks.includes(y))
x.filter((y) => !fixedBlocks.includes(y)),
);
setBlocks(newBlocks);
};

View File

@ -1,23 +1,23 @@
import React, { createContext, useEffect, useState } from "react";
import React, { createContext, useEffect, useState } from 'react';
const COLOR_CONFIG = {
light: {
"--color-primary": "#444",
"--color-primary-dark": "#333",
"--color-inverse": "#fff",
"--color-inverse-dark": "#f5f5f5",
"--color-secondary-light": "#f7fafc",
"--color-secondary": "#edf2f7",
"--color-secondary-dark": "#718096",
'--color-primary': '#444',
'--color-primary-dark': '#333',
'--color-inverse': '#fff',
'--color-inverse-dark': '#f5f5f5',
'--color-secondary-light': '#f7fafc',
'--color-secondary': '#edf2f7',
'--color-secondary-dark': '#718096',
},
dark: {
"--color-primary": "#f5f5f5",
"--color-primary-dark": "#eeeeee",
"--color-inverse": "#212121",
"--color-inverse-dark": "#181818",
"--color-secondary-light": "#2c2c2c",
"--color-secondary": "#444",
"--color-secondary-dark": "#888",
'--color-primary': '#f5f5f5',
'--color-primary-dark': '#eeeeee',
'--color-inverse': '#212121',
'--color-inverse-dark': '#181818',
'--color-secondary-light': '#2c2c2c',
'--color-secondary': '#444',
'--color-secondary-dark': '#888',
},
};
@ -32,7 +32,7 @@ const ThemeProvider = ({ children }) => {
const [darkMode, setDarkMode] = useState(defaultState.darkMode);
useEffect(() => {
const isDarkMode = JSON.parse(localStorage.getItem("darkMode"));
const isDarkMode = JSON.parse(localStorage.getItem('darkMode'));
isDarkMode ? setDarkMode(true) : setDarkMode(false);
}, []);
@ -45,7 +45,7 @@ const ThemeProvider = ({ children }) => {
const toggleDarkMode = () => {
setDarkMode(!darkMode);
localStorage.setItem("darkMode", JSON.stringify(!darkMode));
localStorage.setItem('darkMode', JSON.stringify(!darkMode));
};
return (

View File

@ -1,8 +1,8 @@
import firebase from "gatsby-plugin-firebase";
import { pick } from "lodash";
import React, { createContext, useEffect, useState } from "react";
import { toast } from "react-toastify";
import useAuthState from "../hooks/useAuthState";
import firebase from 'gatsby-plugin-firebase';
import { pick } from 'lodash';
import React, { createContext, useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import useAuthState from '../hooks/useAuthState';
const defaultUser = {
uid: null,
@ -25,20 +25,20 @@ const UserProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() => {
const user = JSON.parse(localStorage.getItem("user"));
setUser(user);
const localUser = JSON.parse(localStorage.getItem('user'));
setUser(localUser);
}, []);
useEffect(() => {
if (firebaseUser) {
const user = pick(firebaseUser, Object.keys(defaultUser));
localStorage.setItem("user", JSON.stringify(user));
setUser(user);
const remoteUser = pick(firebaseUser, Object.keys(defaultUser));
localStorage.setItem('user', JSON.stringify(remoteUser));
setUser(remoteUser);
const addUserToDatabase = async () => {
const userRef = firebase.database().ref(`users/${user.uid}`);
const snapshot = await userRef.once("value");
!snapshot.val() && userRef.set(user);
const userRef = firebase.database().ref(`users/${remoteUser.uid}`);
const snapshot = await userRef.once('value');
!snapshot.val() && userRef.set(remoteUser);
};
addUserToDatabase();
@ -57,7 +57,7 @@ const UserProvider = ({ children }) => {
const logout = async () => {
await firebase.auth().signOut();
localStorage.removeItem("user");
localStorage.removeItem('user');
setUser(null);
};

View File

@ -1,68 +1,68 @@
import { AiFillSafetyCertificate, AiOutlineTwitter } from "react-icons/ai";
import { FaAward, FaTools } from "react-icons/fa";
import { IoMdBriefcase, IoMdDocument } from "react-icons/io";
import { MdPerson, MdSchool } from "react-icons/md";
import Awards from "../components/builder/sections/Awards";
import Certifications from "../components/builder/sections/Certifications";
import Education from "../components/builder/sections/Education";
import Objective from "../components/builder/sections/Objective";
import Profile from "../components/builder/sections/Profile";
import Skills from "../components/builder/sections/Skills";
import Social from "../components/builder/sections/Social";
import Work from "../components/builder/sections/Work";
import ModalEvents from "../constants/ModalEvents";
import { AiFillSafetyCertificate, AiOutlineTwitter } from 'react-icons/ai';
import { FaAward, FaTools } from 'react-icons/fa';
import { IoMdBriefcase, IoMdDocument } from 'react-icons/io';
import { MdPerson, MdSchool } from 'react-icons/md';
import Awards from '../components/builder/sections/Awards';
import Certifications from '../components/builder/sections/Certifications';
import Education from '../components/builder/sections/Education';
import Objective from '../components/builder/sections/Objective';
import Profile from '../components/builder/sections/Profile';
import Skills from '../components/builder/sections/Skills';
import Social from '../components/builder/sections/Social';
import Work from '../components/builder/sections/Work';
import ModalEvents from '../constants/ModalEvents';
export default [
{
id: "profile",
name: "Profile",
id: 'profile',
name: 'Profile',
icon: MdPerson,
component: Profile,
},
{
id: "social",
name: "Social Network",
id: 'social',
name: 'Social Network',
icon: AiOutlineTwitter,
component: Social,
event: ModalEvents.SOCIAL_MODAL,
},
{
id: "objective",
name: "Objective",
id: 'objective',
name: 'Objective',
icon: IoMdDocument,
component: Objective,
},
{
id: "work",
name: "Work Experience",
id: 'work',
name: 'Work Experience',
icon: IoMdBriefcase,
component: Work,
event: ModalEvents.WORK_MODAL,
},
{
id: "education",
name: "Education",
id: 'education',
name: 'Education',
icon: MdSchool,
component: Education,
event: ModalEvents.EDUCATION_MODAL,
},
{
id: "awards",
name: "Awards",
id: 'awards',
name: 'Awards',
icon: FaAward,
component: Awards,
event: ModalEvents.AWARD_MODAL,
},
{
id: "certifications",
name: "Certifications",
id: 'certifications',
name: 'Certifications',
icon: AiFillSafetyCertificate,
component: Certifications,
event: ModalEvents.CERTIFICATION_MODAL,
},
{
id: "skills",
name: "Skills",
id: 'skills',
name: 'Skills',
icon: FaTools,
component: Skills,
event: ModalEvents.SKILL_MODAL,

View File

@ -1,14 +1,14 @@
export const tips = [
"Create a professional email address.",
"Update your contact information.",
"Set your font size to 10-12 points.",
"Use reverse-chronological order.",
"Align your content to the left to make it skimmable.",
"Make strategic use of bold, caps, and italics.",
"Choose an attractive and readable font.",
"Only add jobs youve had in the past 10-15 years.",
"Give your sections simple subheadings.",
"Include URLs to social media profiles, personal websites, and your blog.",
'Create a professional email address.',
'Update your contact information.',
'Set your font size to 10-12 points.',
'Use reverse-chronological order.',
'Align your content to the left to make it skimmable.',
'Make strategic use of bold, caps, and italics.',
'Choose an attractive and readable font.',
'Only add jobs youve had in the past 10-15 years.',
'Give your sections simple subheadings.',
'Include URLs to social media profiles, personal websites, and your blog.',
];
export const getRandomTip = () => {

View File

@ -1,32 +1,32 @@
import { useEffect, useReducer, useState } from "react";
import { useEffect, useReducer, useState } from 'react';
export default function useAuthState(firebase) {
const [auth, setAuth] = useState(undefined);
const [state, dispatch] = useReducer(
(state, action) => {
(innerState, action) => {
switch (action.type) {
case "auth_state_changed":
case 'auth_state_changed':
return {
...state,
...innerState,
user: action.user,
loading: false,
};
case "error":
case 'error':
return {
...state,
...innerState,
error: action.error,
loading: false,
};
default:
return state;
return innerState;
}
},
{
user: undefined,
loading: true,
error: undefined,
}
},
);
useEffect(() => {
@ -38,11 +38,11 @@ export default function useAuthState(firebase) {
const unsubscribe = auth.onAuthStateChanged(
(user) => {
dispatch({ type: "auth_state_changed", user });
dispatch({ type: 'auth_state_changed', user });
},
(error) => {
dispatch({ type: "error", error });
}
dispatch({ type: 'error', error });
},
);
return () => {

View File

@ -1,9 +1,9 @@
import { navigate } from "gatsby";
import React, { Fragment, useContext, useEffect, useState } from "react";
import Button from "../components/shared/Button";
import ModalContext from "../contexts/ModalContext";
import UserContext from "../contexts/UserContext";
import BaseModal from "./BaseModal";
import { navigate } from 'gatsby';
import React, { useContext, useEffect, useState } from 'react';
import Button from '../components/shared/Button';
import ModalContext from '../contexts/ModalContext';
import UserContext from '../contexts/UserContext';
import BaseModal from './BaseModal';
const AuthModal = () => {
const [open, setOpen] = useState(false);
@ -25,12 +25,12 @@ const AuthModal = () => {
};
const handleGotoApp = () => {
navigate("/app/dashboard");
navigate('/app/dashboard');
setOpen(false);
};
const getTitle = () =>
user ? `Welcome, ${user.displayName}` : "Who are you?";
user ? `Welcome, ${user.displayName}` : 'Who are you?';
const getMessage = () =>
user
@ -38,10 +38,10 @@ const AuthModal = () => {
: `Reactive Resume needs to know who you are so it can securely authenticate you into the app and show you only your information. Once you are in, you can start building your resume, editing it to add new skills or sharing it with the world!`;
const loggedInAction = (
<Fragment>
<>
<Button outline className="mr-8" title="Logout" onClick={logout} />
<Button title="Go to App" onClick={handleGotoApp} />
</Fragment>
</>
);
const loggedOutAction = (

View File

@ -1,12 +1,12 @@
import Backdrop from "@material-ui/core/Backdrop";
import Fade from "@material-ui/core/Fade";
import Modal from "@material-ui/core/Modal";
import { isFunction } from "lodash";
import React, { forwardRef, useImperativeHandle } from "react";
import { MdClose } from "react-icons/md";
import Button from "../components/shared/Button";
import { handleKeyDown } from "../utils";
import styles from "./BaseModal.module.css";
import Backdrop from '@material-ui/core/Backdrop';
import Fade from '@material-ui/core/Fade';
import Modal from '@material-ui/core/Modal';
import { isFunction } from 'lodash';
import React, { forwardRef, useImperativeHandle } from 'react';
import { MdClose } from 'react-icons/md';
import Button from '../components/shared/Button';
import { handleKeyDown } from '../utils';
import styles from './BaseModal.module.css';
const BaseModal = forwardRef(
({ title, state, children, action, onDestroy }, ref) => {
@ -58,7 +58,7 @@ const BaseModal = forwardRef(
</Fade>
</Modal>
);
}
},
);
export default BaseModal;

View File

@ -1,12 +1,12 @@
import { useFormikContext } from "formik";
import { isEmpty, isFunction } from "lodash";
import React, { useContext, useEffect, useRef, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import Button from "../components/shared/Button";
import ModalContext from "../contexts/ModalContext";
import { useDispatch } from "../contexts/ResumeContext";
import { getModalText } from "../utils";
import BaseModal from "./BaseModal";
import { useFormikContext } from 'formik';
import { isEmpty, isFunction } from 'lodash';
import React, { useContext, useEffect, useRef, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import Button from '../components/shared/Button';
import ModalContext from '../contexts/ModalContext';
import { useDispatch } from '../contexts/ResumeContext';
import { getModalText } from '../utils';
import BaseModal from './BaseModal';
const DataModal = ({
name,
@ -28,9 +28,9 @@ const DataModal = ({
const { values, setValues, resetForm, validateForm } = useFormikContext();
useEffect(() => {
const unbind = emitter.on(event, (data) => {
const unbind = emitter.on(event, (payload) => {
setOpen(true);
setData(data);
setData(payload);
});
return () => unbind();
@ -38,7 +38,6 @@ const DataModal = ({
useEffect(() => {
data && setValues(data) && setEditMode(true);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data]);
const onSubmit = async (newData) => {
@ -48,7 +47,7 @@ const DataModal = ({
isFunction(onEdit)
? onEdit(newData)
: dispatch({
type: "on_edit_item",
type: 'on_edit_item',
payload: {
path,
value: newData,
@ -61,7 +60,7 @@ const DataModal = ({
isFunction(onCreate)
? onCreate(newData)
: dispatch({
type: "on_add_item",
type: 'on_add_item',
payload: {
path,
value: newData,

View File

@ -1,16 +1,16 @@
import React, { Fragment } from "react";
import AuthModal from "./AuthModal";
import ResumeModal from "./ResumeModal";
import AwardModal from "./sections/AwardModal";
import CertificateModal from "./sections/CertificateModal";
import EducationModal from "./sections/EducationModal";
import SkillModal from "./sections/SkillModal";
import SocialModal from "./sections/SocialModal";
import WorkModal from "./sections/WorkModal";
import React from 'react';
import AuthModal from './AuthModal';
import ResumeModal from './ResumeModal';
import AwardModal from './sections/AwardModal';
import CertificateModal from './sections/CertificateModal';
import EducationModal from './sections/EducationModal';
import SkillModal from './sections/SkillModal';
import SocialModal from './sections/SocialModal';
import WorkModal from './sections/WorkModal';
const ModalRegistrar = () => {
return (
<Fragment>
<>
<AuthModal />
<ResumeModal />
<SocialModal />
@ -19,7 +19,7 @@ const ModalRegistrar = () => {
<AwardModal />
<CertificateModal />
<SkillModal />
</Fragment>
</>
);
};

View File

@ -1,20 +1,20 @@
import { Formik } from "formik";
import { get } from "lodash";
import React, { useContext } from "react";
import * as Yup from "yup";
import Input from "../components/shared/Input";
import ModalEvents from "../constants/ModalEvents";
import DatabaseContext from "../contexts/DatabaseContext";
import DataModal from "./DataModal";
import { Formik } from 'formik';
import { get } from 'lodash';
import React, { useContext } from 'react';
import * as Yup from 'yup';
import Input from '../components/shared/Input';
import ModalEvents from '../constants/ModalEvents';
import DatabaseContext from '../contexts/DatabaseContext';
import DataModal from './DataModal';
const initialValues = {
name: "",
name: '',
};
const validationSchema = Yup.object().shape({
name: Yup.string()
.min(5, "Please enter at least 5 characters.")
.required("This is a required field."),
.min(5, 'Please enter at least 5 characters.')
.required('This is a required field.'),
});
const ResumeModal = () => {
@ -22,7 +22,7 @@ const ResumeModal = () => {
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
error: get(formik, `errors.${name}`, ''),
isRequired: get(validationSchema, `fields.${name}._exclusive.required`),
...formik.getFieldProps(name),
});
@ -37,8 +37,8 @@ const ResumeModal = () => {
<DataModal
name="Resume"
title={{
create: "Create Resume",
edit: "Edit Resume",
create: 'Create Resume',
edit: 'Edit Resume',
}}
onEdit={updateResume}
onCreate={createResume}
@ -48,14 +48,14 @@ const ResumeModal = () => {
label="Name"
className="mb-8"
placeholder="Full Stack Web Developer"
{...getFieldProps(formik, "name")}
{...getFieldProps(formik, 'name')}
/>
<p>
You are going to be creating a new resume from scratch, but first,
let's give it a name. This can be the name of the role you want to
apply for, or if you're making a resume for a friend, you could call
it Alex's Resume.
let&apos;s give it a name. This can be the name of the role you want
to apply for, or if you&apos;re making a resume for a friend, you
could call it Alex&apos;s Resume.
</p>
</DataModal>
)}

View File

@ -1,21 +1,21 @@
import { Formik } from "formik";
import { get } from "lodash";
import React from "react";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
import ModalEvents from "../../constants/ModalEvents";
import DataModal from "../DataModal";
import { Formik } from 'formik';
import { get } from 'lodash';
import React from 'react';
import * as Yup from 'yup';
import Input from '../../components/shared/Input';
import ModalEvents from '../../constants/ModalEvents';
import DataModal from '../DataModal';
const initialValues = {
title: "",
awarder: "",
date: "",
summary: "",
title: '',
awarder: '',
date: '',
summary: '',
};
const validationSchema = Yup.object().shape({
title: Yup.string().required("This is a required field."),
awarder: Yup.string().required("This is a required field."),
title: Yup.string().required('This is a required field.'),
awarder: Yup.string().required('This is a required field.'),
date: Yup.date().max(new Date()),
summary: Yup.string(),
});
@ -23,7 +23,7 @@ const validationSchema = Yup.object().shape({
const AwardModal = () => {
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
error: get(formik, `errors.${name}`, ''),
isRequired: get(validationSchema, `fields.${name}._exclusive.required`),
...formik.getFieldProps(name),
});
@ -45,26 +45,26 @@ const AwardModal = () => {
label="Title"
className="col-span-2"
placeholder="Intl. Flutter Hackathon '19"
{...getFieldProps(formik, "title")}
{...getFieldProps(formik, 'title')}
/>
<Input
label="Awarder"
placeholder="Google"
{...getFieldProps(formik, "awarder")}
{...getFieldProps(formik, 'awarder')}
/>
<Input
type="date"
label="Date"
{...getFieldProps(formik, "date")}
{...getFieldProps(formik, 'date')}
/>
<Input
type="textarea"
label="Summary"
className="col-span-2"
{...getFieldProps(formik, "summary")}
{...getFieldProps(formik, 'summary')}
/>
</div>
</DataModal>

View File

@ -1,21 +1,21 @@
import { Formik } from "formik";
import { get } from "lodash";
import React from "react";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
import ModalEvents from "../../constants/ModalEvents";
import DataModal from "../DataModal";
import { Formik } from 'formik';
import { get } from 'lodash';
import React from 'react';
import * as Yup from 'yup';
import Input from '../../components/shared/Input';
import ModalEvents from '../../constants/ModalEvents';
import DataModal from '../DataModal';
const initialValues = {
title: "",
issuer: "",
date: "",
summary: "",
title: '',
issuer: '',
date: '',
summary: '',
};
const validationSchema = Yup.object().shape({
title: Yup.string().required("This is a required field."),
issuer: Yup.string().required("This is a required field."),
title: Yup.string().required('This is a required field.'),
issuer: Yup.string().required('This is a required field.'),
date: Yup.date().max(new Date()),
summary: Yup.string(),
});
@ -23,7 +23,7 @@ const validationSchema = Yup.object().shape({
const CertificateModal = () => {
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
error: get(formik, `errors.${name}`, ''),
isRequired: get(validationSchema, `fields.${name}._exclusive.required`),
...formik.getFieldProps(name),
});
@ -45,26 +45,26 @@ const CertificateModal = () => {
label="Title"
className="col-span-2"
placeholder="CCNP"
{...getFieldProps(formik, "title")}
{...getFieldProps(formik, 'title')}
/>
<Input
label="Issuer"
placeholder="Cisco Systems"
{...getFieldProps(formik, "issuer")}
{...getFieldProps(formik, 'issuer')}
/>
<Input
type="date"
label="Date"
{...getFieldProps(formik, "date")}
{...getFieldProps(formik, 'date')}
/>
<Input
type="textarea"
label="Summary"
className="col-span-2"
{...getFieldProps(formik, "summary")}
{...getFieldProps(formik, 'summary')}
/>
</div>
</DataModal>

View File

@ -1,44 +1,44 @@
import { Field, FieldArray, Formik } from "formik";
import { get } from "lodash";
import React from "react";
import { MdAdd } from "react-icons/md";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
import ModalEvents from "../../constants/ModalEvents";
import { handleKeyDown } from "../../utils";
import DataModal from "../DataModal";
import { Field, FieldArray, Formik } from 'formik';
import { get } from 'lodash';
import React from 'react';
import { MdAdd } from 'react-icons/md';
import * as Yup from 'yup';
import Input from '../../components/shared/Input';
import ModalEvents from '../../constants/ModalEvents';
import { handleKeyDown } from '../../utils';
import DataModal from '../DataModal';
const initialValues = {
institution: "",
field: "",
degree: "",
gpa: "",
startDate: "",
endDate: "",
institution: '',
field: '',
degree: '',
gpa: '',
startDate: '',
endDate: '',
courses: [],
__temp: "",
temp: '',
};
const validationSchema = Yup.object().shape({
institution: Yup.string().required("This is a required field."),
field: Yup.string().required("This is a required field."),
institution: Yup.string().required('This is a required field.'),
field: Yup.string().required('This is a required field.'),
degree: Yup.string(),
gpa: Yup.string(),
startDate: Yup.date().required("This is a required field."),
startDate: Yup.date().required('This is a required field.'),
endDate: Yup.date().when(
"startDate",
'startDate',
(startDate, schema) =>
startDate &&
schema.min(startDate, "End Date must be later than Start Date")
schema.min(startDate, 'End Date must be later than Start Date'),
),
courses: Yup.array().of(Yup.string().required("This is a required field.")),
__temp: Yup.string().ensure(),
courses: Yup.array().of(Yup.string().required('This is a required field.')),
temp: Yup.string().ensure(),
});
const EducationModal = () => {
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
error: get(formik, `errors.${name}`, ''),
isRequired: get(validationSchema, `fields.${name}._exclusive.required`),
...formik.getFieldProps(name),
});
@ -60,49 +60,48 @@ const EducationModal = () => {
label="Institution"
className="col-span-2"
placeholder="Dayananda Sagar College of Engineering"
{...getFieldProps(formik, "institution")}
{...getFieldProps(formik, 'institution')}
/>
<Input
label="Field of Study"
className="col-span-2"
placeholder="Computer Science &amp; Engineering"
{...getFieldProps(formik, "field")}
{...getFieldProps(formik, 'field')}
/>
<Input
label="Degree Type"
placeholder="Bachelor's Degree"
{...getFieldProps(formik, "degree")}
{...getFieldProps(formik, 'degree')}
/>
<Input
label="GPA"
placeholder="8.8"
{...getFieldProps(formik, "gpa")}
{...getFieldProps(formik, 'gpa')}
/>
<Input
type="date"
label="Start Date"
placeholder="6th August 208"
{...getFieldProps(formik, "startDate")}
{...getFieldProps(formik, 'startDate')}
/>
<Input
type="date"
label="End Date"
placeholder="6th August 208"
{...getFieldProps(formik, "endDate")}
{...getFieldProps(formik, 'endDate')}
/>
<FieldArray
name="courses"
render={(arrayHelpers) => {
const handleClickAdd = () => {
formik.values.__temp &&
arrayHelpers.push(formik.values.__temp);
formik.setFieldValue("__temp", "");
formik.values.temp && arrayHelpers.push(formik.values.temp);
formik.setFieldValue('temp', '');
};
return (
@ -112,7 +111,7 @@ const EducationModal = () => {
{formik.values.courses &&
formik.values.courses.map((x, i) => (
<Field key={i} name={`courses.${i}`}>
<Field key={x} name={`courses.${i}`}>
{({ field, meta }) => (
<Input
className="my-1"
@ -128,7 +127,7 @@ const EducationModal = () => {
<div className="flex items-center">
<Input
placeholder="Algorithms &amp; Data Structures"
{...getFieldProps(formik, "__temp")}
{...getFieldProps(formik, 'temp')}
/>
<MdAdd
size="18px"

View File

@ -1,25 +1,25 @@
import { Formik } from "formik";
import { get } from "lodash";
import React from "react";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
import ModalEvents from "../../constants/ModalEvents";
import DataModal from "../DataModal";
import { Formik } from 'formik';
import { get } from 'lodash';
import React from 'react';
import * as Yup from 'yup';
import Input from '../../components/shared/Input';
import ModalEvents from '../../constants/ModalEvents';
import DataModal from '../DataModal';
const initialValues = {
name: "",
level: "",
name: '',
level: '',
};
const validationSchema = Yup.object().shape({
name: Yup.string().required("This is a required field."),
level: Yup.string().required("This is a required field."),
name: Yup.string().required('This is a required field.'),
level: Yup.string().required('This is a required field.'),
});
const SkillModal = () => {
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
error: get(formik, `errors.${name}`, ''),
isRequired: get(validationSchema, `fields.${name}._exclusive.required`),
...formik.getFieldProps(name),
});
@ -40,13 +40,13 @@ const SkillModal = () => {
<Input
label="Name"
placeholder="ReactJS"
{...getFieldProps(formik, "name")}
{...getFieldProps(formik, 'name')}
/>
<Input
type="select"
label="Level"
{...getFieldProps(formik, "level")}
{...getFieldProps(formik, 'level')}
/>
</div>
</DataModal>

View File

@ -1,32 +1,32 @@
import { Formik } from "formik";
import { get } from "lodash";
import React from "react";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
import ModalEvents from "../../constants/ModalEvents";
import DataModal from "../DataModal";
import { Formik } from 'formik';
import { get } from 'lodash';
import React from 'react';
import * as Yup from 'yup';
import Input from '../../components/shared/Input';
import ModalEvents from '../../constants/ModalEvents';
import DataModal from '../DataModal';
const initialValues = {
url: "https://",
network: "",
username: "",
url: 'https://',
network: '',
username: '',
};
const validationSchema = Yup.object().shape({
network: Yup.string()
.min(5, "Please enter at least 5 characters.")
.required("This is a required field."),
username: Yup.string().required("This is a required field."),
.min(5, 'Please enter at least 5 characters.')
.required('This is a required field.'),
username: Yup.string().required('This is a required field.'),
url: Yup.string()
.min(5, "Please enter at least 5 characters.")
.required("This is a required field.")
.url("Must be a valid URL"),
.min(5, 'Please enter at least 5 characters.')
.required('This is a required field.')
.url('Must be a valid URL'),
});
const SocialModal = () => {
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
error: get(formik, `errors.${name}`, ''),
isRequired: get(validationSchema, `fields.${name}._exclusive.required`),
...formik.getFieldProps(name),
});
@ -47,20 +47,20 @@ const SocialModal = () => {
<Input
label="Network"
placeholder="Twitter"
{...getFieldProps(formik, "network")}
{...getFieldProps(formik, 'network')}
/>
<Input
label="Username"
placeholder="KingOKings"
{...getFieldProps(formik, "username")}
{...getFieldProps(formik, 'username')}
/>
<Input
label="URL"
className="col-span-2"
placeholder="https://twitter.com/KingOKings"
{...getFieldProps(formik, "url")}
{...getFieldProps(formik, 'url')}
/>
</div>
</DataModal>

View File

@ -1,46 +1,46 @@
import { Field, FieldArray, Formik } from "formik";
import { get } from "lodash";
import React from "react";
import { MdAdd } from "react-icons/md";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
import ModalEvents from "../../constants/ModalEvents";
import { handleKeyDown } from "../../utils";
import DataModal from "../DataModal";
import { Field, FieldArray, Formik } from 'formik';
import { get } from 'lodash';
import React from 'react';
import { MdAdd } from 'react-icons/md';
import * as Yup from 'yup';
import Input from '../../components/shared/Input';
import ModalEvents from '../../constants/ModalEvents';
import { handleKeyDown } from '../../utils';
import DataModal from '../DataModal';
const initialValues = {
company: "",
position: "",
website: "https://",
startDate: "",
endDate: "",
summary: "",
company: '',
position: '',
website: 'https://',
startDate: '',
endDate: '',
summary: '',
highlights: [],
__temp: "",
temp: '',
};
const validationSchema = Yup.object().shape({
company: Yup.string().required("This is a required field."),
position: Yup.string().required("This is a required field."),
website: Yup.string().url("Must be a valid URL"),
startDate: Yup.date().required("This is a required field."),
company: Yup.string().required('This is a required field.'),
position: Yup.string().required('This is a required field.'),
website: Yup.string().url('Must be a valid URL'),
startDate: Yup.date().required('This is a required field.'),
endDate: Yup.date().when(
"startDate",
'startDate',
(startDate, schema) =>
startDate &&
schema.min(startDate, "End Date must be later than Start Date")
schema.min(startDate, 'End Date must be later than Start Date'),
),
summary: Yup.string().min(10, "Please enter at least 10 characters."),
summary: Yup.string().min(10, 'Please enter at least 10 characters.'),
highlights: Yup.array().of(
Yup.string().required("This is a required field.")
Yup.string().required('This is a required field.'),
),
__temp: Yup.string().ensure(),
temp: Yup.string().ensure(),
});
const WorkModal = () => {
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
error: get(formik, `errors.${name}`, ''),
isRequired: get(validationSchema, `fields.${name}._exclusive.required`),
...formik.getFieldProps(name),
});
@ -62,49 +62,48 @@ const WorkModal = () => {
label="Company"
className="col-span-2"
placeholder="Postdot Technologies Pvt. Ltd."
{...getFieldProps(formik, "company")}
{...getFieldProps(formik, 'company')}
/>
<Input
label="Position"
placeholder="Full Stack Web Developer"
{...getFieldProps(formik, "position")}
{...getFieldProps(formik, 'position')}
/>
<Input
label="Website"
placeholder="https://example.com/"
{...getFieldProps(formik, "website")}
{...getFieldProps(formik, 'website')}
/>
<Input
type="date"
label="Start Date"
placeholder="6th August 208"
{...getFieldProps(formik, "startDate")}
{...getFieldProps(formik, 'startDate')}
/>
<Input
type="date"
label="End Date"
placeholder="6th August 208"
{...getFieldProps(formik, "endDate")}
{...getFieldProps(formik, 'endDate')}
/>
<Input
type="textarea"
label="Summary"
className="col-span-2"
{...getFieldProps(formik, "summary")}
{...getFieldProps(formik, 'summary')}
/>
<FieldArray
name="highlights"
render={(arrayHelpers) => {
const handleClickAdd = () => {
formik.values.__temp &&
arrayHelpers.push(formik.values.__temp);
formik.setFieldValue("__temp", "");
formik.values.temp && arrayHelpers.push(formik.values.temp);
formik.setFieldValue('temp', '');
};
return (
@ -114,7 +113,7 @@ const WorkModal = () => {
{formik.values.highlights &&
formik.values.highlights.map((x, i) => (
<Field key={i} name={`highlights.${i}`}>
<Field key={x} name={`highlights.${i}`}>
{({ field, meta }) => (
<Input
className="my-1"
@ -130,7 +129,7 @@ const WorkModal = () => {
<div className="flex items-center">
<Input
placeholder="Worked passionately in customer service in a high volume restaurant."
{...getFieldProps(formik, "__temp")}
{...getFieldProps(formik, 'temp')}
/>
<MdAdd
size="18px"

View File

@ -1,9 +1,9 @@
import { navigate } from "gatsby";
import { useEffect } from "react";
import { navigate } from 'gatsby';
import { useEffect } from 'react';
const NotFound = () => {
useEffect(() => {
navigate("/");
navigate('/');
}, []);
return null;

View File

@ -1,10 +1,10 @@
import { Redirect, Router } from "@reach/router";
import React from "react";
import PrivateRoute from "../components/router/PrivateRoute";
import Wrapper from "../components/shared/Wrapper";
import NotFound from "./404";
import Builder from "./app/builder";
import Dashboard from "./app/dashboard";
import { Redirect, Router } from '@reach/router';
import React from 'react';
import PrivateRoute from '../components/router/PrivateRoute';
import Wrapper from '../components/shared/Wrapper';
import NotFound from './404';
import Builder from './app/builder';
import Dashboard from './app/dashboard';
const App = () => (
<Wrapper>

View File

@ -1,12 +1,12 @@
import { navigate } from "gatsby";
import React, { useContext, useEffect, useMemo, useState } from "react";
import { toast } from "react-toastify";
import Artboard from "../../components/builder/center/Artboard";
import LeftSidebar from "../../components/builder/left/LeftSidebar";
import RightSidebar from "../../components/builder/right/RightSidebar";
import LoadingScreen from "../../components/router/LoadingScreen";
import DatabaseContext from "../../contexts/DatabaseContext";
import { useDispatch } from "../../contexts/ResumeContext";
import { navigate } from 'gatsby';
import React, { useContext, useEffect, useMemo, useState } from 'react';
import { toast } from 'react-toastify';
import Artboard from '../../components/builder/center/Artboard';
import LeftSidebar from '../../components/builder/left/LeftSidebar';
import RightSidebar from '../../components/builder/right/RightSidebar';
import LoadingScreen from '../../components/router/LoadingScreen';
import DatabaseContext from '../../contexts/DatabaseContext';
import { useDispatch } from '../../contexts/ResumeContext';
const Builder = ({ id }) => {
const dispatch = useDispatch();
@ -18,17 +18,16 @@ const Builder = ({ id }) => {
const resume = await getResume(id);
if (!resume) {
navigate("/app/dashboard");
navigate('/app/dashboard');
toast.error(
`The resume you were looking for does not exist anymore... or maybe it never did?`
`The resume you were looking for does not exist anymore... or maybe it never did?`,
);
return null;
}
dispatch({ type: "set_data", payload: resume });
setLoading(false);
dispatch({ type: 'set_data', payload: resume });
return setLoading(false);
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id]);
return useMemo(() => {

View File

@ -1,10 +1,10 @@
import firebase from "gatsby-plugin-firebase";
import React, { useEffect, useState } from "react";
import { Helmet } from "react-helmet";
import CreateResume from "../../components/dashboard/CreateResume";
import ResumePreview from "../../components/dashboard/ResumePreview";
import TopNavbar from "../../components/dashboard/TopNavbar";
import LoadingScreen from "../../components/router/LoadingScreen";
import firebase from 'gatsby-plugin-firebase';
import React, { useEffect, useState } from 'react';
import { Helmet } from 'react-helmet';
import CreateResume from '../../components/dashboard/CreateResume';
import ResumePreview from '../../components/dashboard/ResumePreview';
import TopNavbar from '../../components/dashboard/TopNavbar';
import LoadingScreen from '../../components/router/LoadingScreen';
const Dashboard = ({ user }) => {
const [resumes, setResumes] = useState([]);
@ -16,12 +16,12 @@ const Dashboard = ({ user }) => {
firebase
.database()
.ref(ref)
.on("value", (snapshot) => {
.on('value', (snapshot) => {
if (snapshot.val()) {
const resumes = [];
const resumesArr = [];
const data = snapshot.val();
Object.keys(data).forEach((key) => resumes.push(data[key]));
setResumes(resumes);
Object.keys(data).forEach((key) => resumesArr.push(data[key]));
setResumes(resumesArr);
}
setLoading(false);

View File

@ -1,7 +1,7 @@
import React from "react";
import { Helmet } from "react-helmet";
import Hero from "../components/landing/Hero";
import Wrapper from "../components/shared/Wrapper";
import React from 'react';
import { Helmet } from 'react-helmet';
import Hero from '../components/landing/Hero';
import Wrapper from '../components/shared/Wrapper';
const Home = () => {
return (
@ -32,11 +32,11 @@ const Home = () => {
</Feature>
<Feature title="Kickstarting your career shouldnt come at a cost.">
There are brilliant alternatives to this app like{" "}
There are brilliant alternatives to this app like{' '}
<a href="/" target="blank">
Novoresume
</a>{" "}
and{" "}
</a>{' '}
and{' '}
<a href="/" target="blank">
Zety
</a>
@ -50,7 +50,7 @@ const Home = () => {
<footer className="my-24">
<p className="font-medium text-gray-500">
Licensed under <a href="/">MIT</a> | Made with love by{" "}
Licensed under <a href="/">MIT</a> | Made with love by{' '}
<a href="https://www.amruthpillai.com/">Amruth Pillai</a>
</p>
</footer>

View File

@ -1,6 +1,6 @@
import React from "react";
import { FaGlobeAmericas, FaPhone } from "react-icons/fa";
import { MdEmail } from "react-icons/md";
import React from 'react';
import { FaGlobeAmericas, FaPhone } from 'react-icons/fa';
import { MdEmail } from 'react-icons/md';
const Onyx = ({ data, layout, colors }) => {
return (

View File

@ -13,6 +13,6 @@ export const handleKeyDown = (event, action) => {
};
export const isFileImage = (file) => {
const acceptedImageTypes = ["image/jpeg", "image/png"];
return file && acceptedImageTypes.includes(file["type"]);
const acceptedImageTypes = ['image/jpeg', 'image/png'];
return file && acceptedImageTypes.includes(file.type);
};

View File

@ -1,18 +1,18 @@
module.exports = {
purge: ["./src/**/*.js", "./src/**/*.jsx", "./src/**/*.ts", "./src/**/*.tsx"],
purge: ['./src/**/*.js', './src/**/*.jsx', './src/**/*.ts', './src/**/*.tsx'],
theme: {
container: {
center: true,
},
extend: {
colors: {
primary: "var(--color-primary)",
"primary-dark": "var(--color-primary-dark)",
inverse: "var(--color-inverse)",
"inverse-dark": "var(--color-inverse-dark)",
"secondary-light": "var(--color-secondary-light)",
secondary: "var(--color-secondary)",
"secondary-dark": "var(--color-secondary-dark)",
primary: 'var(--color-primary)',
'primary-dark': 'var(--color-primary-dark)',
inverse: 'var(--color-inverse)',
'inverse-dark': 'var(--color-inverse-dark)',
'secondary-light': 'var(--color-secondary-light)',
secondary: 'var(--color-secondary)',
'secondary-dark': 'var(--color-secondary-dark)',
},
},
},