mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-13 00:03:27 +10:00
- designing the dashboard
- resume preview - create resume modal
This commit is contained in:
@ -1,19 +1,29 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { MuiThemeProvider, createMuiTheme } from "@material-ui/core";
|
||||||
import "firebase/auth";
|
import "firebase/auth";
|
||||||
import "firebase/analytics";
|
import "firebase/analytics";
|
||||||
import "firebase/firestore";
|
import "firebase/firestore";
|
||||||
|
import { ModalProvider } from "./src/contexts/ModalContext";
|
||||||
import { ThemeProvider } from "./src/contexts/ThemeContext";
|
import { ThemeProvider } from "./src/contexts/ThemeContext";
|
||||||
|
import { UserProvider } from "./src/contexts/UserContext";
|
||||||
|
|
||||||
import "./src/styles/colors.css";
|
import "./src/styles/colors.css";
|
||||||
import "./src/styles/tailwind.css";
|
import "./src/styles/tailwind.css";
|
||||||
import "./src/styles/global.css";
|
import "./src/styles/global.css";
|
||||||
import { ModalProvider } from "./src/contexts/ModalContext";
|
|
||||||
import { UserProvider } from "./src/contexts/UserContext";
|
const theme = createMuiTheme({
|
||||||
|
typography: {
|
||||||
|
fontWeightRegular: 500,
|
||||||
|
fontFamily: ["Montserrat", "sans-serif"].join(","),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const wrapRootElement = ({ element }) => (
|
export const wrapRootElement = ({ element }) => (
|
||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
|
<MuiThemeProvider theme={theme}>
|
||||||
<ModalProvider>
|
<ModalProvider>
|
||||||
<UserProvider>{element}</UserProvider>
|
<UserProvider>{element}</UserProvider>
|
||||||
</ModalProvider>
|
</ModalProvider>
|
||||||
|
</MuiThemeProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -13,6 +13,10 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
resolve: `gatsby-plugin-create-client-paths`,
|
||||||
|
options: { prefixes: [`/app/*`] },
|
||||||
|
},
|
||||||
`gatsby-plugin-lodash`,
|
`gatsby-plugin-lodash`,
|
||||||
`gatsby-plugin-react-helmet`,
|
`gatsby-plugin-react-helmet`,
|
||||||
{
|
{
|
||||||
|
|||||||
92
package-lock.json
generated
92
package-lock.json
generated
@ -3611,6 +3611,13 @@
|
|||||||
"better-queue-memory": "^1.0.1",
|
"better-queue-memory": "^1.0.1",
|
||||||
"node-eta": "^0.9.0",
|
"node-eta": "^0.9.0",
|
||||||
"uuid": "^3.0.0"
|
"uuid": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"better-queue-memory": {
|
"better-queue-memory": {
|
||||||
@ -7989,6 +7996,33 @@
|
|||||||
"mime-types": "^2.1.12"
|
"mime-types": "^2.1.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"formik": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/formik/-/formik-2.1.4.tgz",
|
||||||
|
"integrity": "sha512-oKz8S+yQBzuQVSEoxkqqJrKQS5XJASWGVn6mrs+oTWrBoHgByVwwI1qHiVc9GKDpZBU9vAxXYAKz2BvujlwunA==",
|
||||||
|
"requires": {
|
||||||
|
"deepmerge": "^2.1.1",
|
||||||
|
"hoist-non-react-statics": "^3.3.0",
|
||||||
|
"lodash": "^4.17.14",
|
||||||
|
"lodash-es": "^4.17.14",
|
||||||
|
"react-fast-compare": "^2.0.1",
|
||||||
|
"scheduler": "^0.18.0",
|
||||||
|
"tiny-warning": "^1.0.2",
|
||||||
|
"tslib": "^1.10.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"deepmerge": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA=="
|
||||||
|
},
|
||||||
|
"react-fast-compare": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"forwarded": {
|
"forwarded": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||||
@ -8325,6 +8359,11 @@
|
|||||||
"ansi-regex": "^4.1.0"
|
"ansi-regex": "^4.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||||
@ -8388,6 +8427,14 @@
|
|||||||
"micromatch": "^3.1.10"
|
"micromatch": "^3.1.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gatsby-plugin-create-client-paths": {
|
||||||
|
"version": "2.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/gatsby-plugin-create-client-paths/-/gatsby-plugin-create-client-paths-2.3.9.tgz",
|
||||||
|
"integrity": "sha512-e5kT2LhLWHSVWGdcyG6x5YT2zECAl7KImV7Q4M/TR+MOqa0Z9FCg664aljmaDZeR6tFAnZXzvmy29PPd9eOGbw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.10.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"gatsby-plugin-firebase": {
|
"gatsby-plugin-firebase": {
|
||||||
"version": "0.2.0-beta.4",
|
"version": "0.2.0-beta.4",
|
||||||
"resolved": "https://registry.npmjs.org/gatsby-plugin-firebase/-/gatsby-plugin-firebase-0.2.0-beta.4.tgz",
|
"resolved": "https://registry.npmjs.org/gatsby-plugin-firebase/-/gatsby-plugin-firebase-0.2.0-beta.4.tgz",
|
||||||
@ -8655,6 +8702,11 @@
|
|||||||
"proper-lockfile": "^4.1.1",
|
"proper-lockfile": "^4.1.1",
|
||||||
"xdg-basedir": "^4.0.0"
|
"xdg-basedir": "^4.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -9013,6 +9065,11 @@
|
|||||||
"version": "0.7.3",
|
"version": "0.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
||||||
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
|
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -11799,6 +11856,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||||
},
|
},
|
||||||
|
"lodash-es": {
|
||||||
|
"version": "4.17.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
|
||||||
|
"integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
|
||||||
|
},
|
||||||
"lodash-webpack-plugin": {
|
"lodash-webpack-plugin": {
|
||||||
"version": "0.11.5",
|
"version": "0.11.5",
|
||||||
"resolved": "https://registry.npmjs.org/lodash-webpack-plugin/-/lodash-webpack-plugin-0.11.5.tgz",
|
"resolved": "https://registry.npmjs.org/lodash-webpack-plugin/-/lodash-webpack-plugin-0.11.5.tgz",
|
||||||
@ -15824,6 +15886,11 @@
|
|||||||
"version": "6.5.2",
|
"version": "6.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -16648,6 +16715,11 @@
|
|||||||
"websocket-driver": ">=0.5.1"
|
"websocket-driver": ">=0.5.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
},
|
||||||
"websocket-driver": {
|
"websocket-driver": {
|
||||||
"version": "0.6.5",
|
"version": "0.6.5",
|
||||||
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz",
|
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz",
|
||||||
@ -17620,6 +17692,13 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"temp-dir": "^1.0.0",
|
"temp-dir": "^1.0.0",
|
||||||
"uuid": "^3.0.1"
|
"uuid": "^3.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"term-size": {
|
"term-size": {
|
||||||
@ -18599,9 +18678,9 @@
|
|||||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||||
},
|
},
|
||||||
"uuid": {
|
"uuid": {
|
||||||
"version": "3.4.0",
|
"version": "8.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz",
|
||||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
"integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q=="
|
||||||
},
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
@ -19134,6 +19213,13 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"ansi-colors": "^3.0.0",
|
"ansi-colors": "^3.0.0",
|
||||||
"uuid": "^3.3.2"
|
"uuid": "^3.3.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webpack-merge": {
|
"webpack-merge": {
|
||||||
|
|||||||
@ -17,8 +17,10 @@
|
|||||||
"@material-ui/core": "^4.11.0",
|
"@material-ui/core": "^4.11.0",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"firebase": "^7.15.5",
|
"firebase": "^7.15.5",
|
||||||
|
"formik": "^2.1.4",
|
||||||
"gatsby": "^2.23.12",
|
"gatsby": "^2.23.12",
|
||||||
"gatsby-image": "^2.4.12",
|
"gatsby-image": "^2.4.12",
|
||||||
|
"gatsby-plugin-create-client-paths": "^2.3.9",
|
||||||
"gatsby-plugin-firebase": "^0.2.0-beta.4",
|
"gatsby-plugin-firebase": "^0.2.0-beta.4",
|
||||||
"gatsby-plugin-lodash": "^3.3.9",
|
"gatsby-plugin-lodash": "^3.3.9",
|
||||||
"gatsby-plugin-manifest": "^2.4.17",
|
"gatsby-plugin-manifest": "^2.4.17",
|
||||||
@ -35,7 +37,8 @@
|
|||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-icons": "^3.10.0",
|
"react-icons": "^3.10.0",
|
||||||
"react-loader-spinner": "^3.1.14",
|
"react-loader-spinner": "^3.1.14",
|
||||||
"react-toastify": "^6.0.8"
|
"react-toastify": "^6.0.8",
|
||||||
|
"uuid": "^8.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "2.0.5",
|
"prettier": "2.0.5",
|
||||||
|
|||||||
34
src/components/dashboard/CreateResume.js
Normal file
34
src/components/dashboard/CreateResume.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React, { useContext } from "react";
|
||||||
|
import { MdAdd } from "react-icons/md";
|
||||||
|
import styles from "./CreateResume.module.css";
|
||||||
|
import ModalContext from "../../contexts/ModalContext";
|
||||||
|
|
||||||
|
const CreateResume = () => {
|
||||||
|
const { createResumeModal } = useContext(ModalContext);
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
createResumeModal.setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.resume}>
|
||||||
|
<div className={styles.backdrop}>
|
||||||
|
<MdAdd color="#FFF" size="48" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
tabIndex="0"
|
||||||
|
role="button"
|
||||||
|
className={styles.page}
|
||||||
|
onClick={handleClick}
|
||||||
|
onKeyDown={() => {}}
|
||||||
|
>
|
||||||
|
<MdAdd color="#444" size="48" />
|
||||||
|
</div>
|
||||||
|
<div className={styles.meta}>
|
||||||
|
<p>Create New Resume</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreateResume;
|
||||||
31
src/components/dashboard/CreateResume.module.css
Normal file
31
src/components/dashboard/CreateResume.module.css
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
.resume {
|
||||||
|
@apply relative flex flex-col items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .backdrop {
|
||||||
|
max-width: 184px;
|
||||||
|
height: 260px;
|
||||||
|
@apply rounded absolute w-full bg-black shadow;
|
||||||
|
@apply absolute text-gray-500 flex justify-center items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .page {
|
||||||
|
max-width: 184px;
|
||||||
|
height: 260px;
|
||||||
|
@apply rounded absolute w-full bg-white;
|
||||||
|
@apply transition-opacity duration-200 ease-in-out;
|
||||||
|
@apply cursor-pointer absolute text-gray-500 flex justify-center items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .page:hover {
|
||||||
|
@apply transition-opacity duration-200 ease-in-out opacity-25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .meta {
|
||||||
|
margin-top: 260px;
|
||||||
|
@apply text-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .meta p {
|
||||||
|
@apply mt-3 font-medium leading-normal;
|
||||||
|
}
|
||||||
64
src/components/dashboard/ResumePreview.js
Normal file
64
src/components/dashboard/ResumePreview.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { MdMoreHoriz, MdOpenInNew } from "react-icons/md";
|
||||||
|
import { Menu, MenuItem } from "@material-ui/core";
|
||||||
|
import styles from "./ResumePreview.module.css";
|
||||||
|
|
||||||
|
const ResumePreview = ({ title, subtitle }) => {
|
||||||
|
const [anchorEl, setAnchorEl] = useState(null);
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
console.log("Hello, World!");
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMenuClick = (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMenuClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.resume}>
|
||||||
|
<div className={styles.backdrop}>
|
||||||
|
<img
|
||||||
|
src="https://source.unsplash.com/random/210x297"
|
||||||
|
alt="Resume Preview"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={styles.page}>
|
||||||
|
<MdOpenInNew
|
||||||
|
color="#fff"
|
||||||
|
size="48"
|
||||||
|
className="cursor-pointer"
|
||||||
|
onClick={handleClick}
|
||||||
|
/>
|
||||||
|
<MdMoreHoriz
|
||||||
|
color="#fff"
|
||||||
|
size="48"
|
||||||
|
className="cursor-pointer"
|
||||||
|
aria-haspopup="true"
|
||||||
|
onClick={handleMenuClick}
|
||||||
|
/>
|
||||||
|
<Menu
|
||||||
|
keepMounted
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
open={Boolean(anchorEl)}
|
||||||
|
onClose={handleMenuClose}
|
||||||
|
>
|
||||||
|
<MenuItem onClick={handleMenuClose}>Duplicate</MenuItem>
|
||||||
|
<MenuItem onClick={handleMenuClose}>
|
||||||
|
<span className="text-red-600">Delete</span>
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
<div className={styles.meta}>
|
||||||
|
<p>{title}</p>
|
||||||
|
<span>{subtitle}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ResumePreview;
|
||||||
40
src/components/dashboard/ResumePreview.module.css
Normal file
40
src/components/dashboard/ResumePreview.module.css
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
.resume {
|
||||||
|
@apply relative flex flex-col items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .backdrop {
|
||||||
|
max-width: 184px;
|
||||||
|
height: 260px;
|
||||||
|
@apply rounded absolute w-full bg-black shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .backdrop img {
|
||||||
|
max-width: 184px;
|
||||||
|
height: 260px;
|
||||||
|
@apply w-full object-cover rounded;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .page {
|
||||||
|
max-width: 184px;
|
||||||
|
height: 260px;
|
||||||
|
@apply rounded absolute w-full bg-black;
|
||||||
|
@apply opacity-0 transition-opacity duration-200 ease-in-out;
|
||||||
|
@apply absolute text-gray-500 flex flex-col justify-evenly items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .page:hover {
|
||||||
|
@apply opacity-75 transition-opacity duration-200 ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .meta {
|
||||||
|
margin-top: 260px;
|
||||||
|
@apply flex flex-col items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .meta p {
|
||||||
|
@apply mt-3 font-medium leading-normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resume > .meta span {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
41
src/components/dashboard/TopNavbar.js
Normal file
41
src/components/dashboard/TopNavbar.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import React, { useContext } from "react";
|
||||||
|
import Logo from "../shared/Logo";
|
||||||
|
import UserContext from "../../contexts/UserContext";
|
||||||
|
import styles from "./TopNavbar.module.css";
|
||||||
|
import { navigate, Link } from "gatsby";
|
||||||
|
|
||||||
|
const TopNavbar = () => {
|
||||||
|
const { user, logout } = useContext(UserContext);
|
||||||
|
|
||||||
|
const handleLogout = async () => {
|
||||||
|
await logout();
|
||||||
|
navigate("/");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.navbar}>
|
||||||
|
<div className="container">
|
||||||
|
<Link to="/">
|
||||||
|
<Logo size="40px" />
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="flex items-center">
|
||||||
|
<button
|
||||||
|
className="text-primary font-semibold focus:outline-none hover:underline"
|
||||||
|
onClick={handleLogout}
|
||||||
|
>
|
||||||
|
Logout
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<img
|
||||||
|
className="ml-8 h-12 rounded-full"
|
||||||
|
src={user.photoURL}
|
||||||
|
alt={user.displayName}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TopNavbar;
|
||||||
8
src/components/dashboard/TopNavbar.module.css
Normal file
8
src/components/dashboard/TopNavbar.module.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.navbar {
|
||||||
|
height: 65px;
|
||||||
|
@apply w-full shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar > div {
|
||||||
|
@apply h-full flex items-center justify-between;
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import ModalContext from "../../contexts/ModalContext";
|
|||||||
import UserContext from "../../contexts/UserContext";
|
import UserContext from "../../contexts/UserContext";
|
||||||
import Button from "../shared/Button";
|
import Button from "../shared/Button";
|
||||||
import Logo from "../shared/Logo";
|
import Logo from "../shared/Logo";
|
||||||
|
import { navigate } from "gatsby";
|
||||||
|
|
||||||
const Hero = () => {
|
const Hero = () => {
|
||||||
const { user, loading } = useContext(UserContext);
|
const { user, loading } = useContext(UserContext);
|
||||||
@ -13,9 +14,11 @@ const Hero = () => {
|
|||||||
|
|
||||||
const handleLogin = () => authModal.setOpen(true);
|
const handleLogin = () => authModal.setOpen(true);
|
||||||
|
|
||||||
|
const handleGotoApp = () => navigate("/app/dashboard");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Logo size="256px" />
|
<Logo className="shadow-lg" size="256px" />
|
||||||
|
|
||||||
<div className="ml-12">
|
<div className="ml-12">
|
||||||
<h1 className="text-5xl font-bold">Reactive Resume</h1>
|
<h1 className="text-5xl font-bold">Reactive Resume</h1>
|
||||||
@ -27,7 +30,7 @@ const Hero = () => {
|
|||||||
{user ? (
|
{user ? (
|
||||||
<Button
|
<Button
|
||||||
title="Go to App"
|
title="Go to App"
|
||||||
onClick={handleLogin}
|
onClick={handleGotoApp}
|
||||||
isLoading={loading || authModal.isOpen}
|
isLoading={loading || authModal.isOpen}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
19
src/components/router/LoadingScreen.js
Normal file
19
src/components/router/LoadingScreen.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import React from "react";
|
||||||
|
import Modal from "@material-ui/core/Modal";
|
||||||
|
import Loader from "react-loader-spinner";
|
||||||
|
import Logo from "../shared/Logo";
|
||||||
|
|
||||||
|
const LoadingScreen = () => {
|
||||||
|
return (
|
||||||
|
<Modal open hideBackdrop>
|
||||||
|
<div className="w-screen h-screen flex justify-center items-center outline-none">
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
<Logo size="48px" className="mb-4" />
|
||||||
|
<Loader type="ThreeDots" color="#AAA" height={32} width={48} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoadingScreen;
|
||||||
21
src/components/router/PrivateRoute.js
Normal file
21
src/components/router/PrivateRoute.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import React, { useContext } from "react";
|
||||||
|
import { navigate } from "gatsby";
|
||||||
|
import UserContext from "../../contexts/UserContext";
|
||||||
|
import LoadingScreen from "./LoadingScreen";
|
||||||
|
|
||||||
|
const PrivateRoute = ({ component: Component, location, ...props }) => {
|
||||||
|
const { user, loading } = useContext(UserContext);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <LoadingScreen />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
navigate("/");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Component {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PrivateRoute;
|
||||||
32
src/components/shared/Input.js
Normal file
32
src/components/shared/Input.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import styles from "./Input.module.css";
|
||||||
|
|
||||||
|
const Input = ({
|
||||||
|
label,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
placeholder,
|
||||||
|
type = "text",
|
||||||
|
}) => {
|
||||||
|
const uuid = uuidv4();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<label htmlFor={uuid}>
|
||||||
|
<span>{label}</span>
|
||||||
|
<input
|
||||||
|
id={uuid}
|
||||||
|
name={name}
|
||||||
|
type={type}
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
placeholder={placeholder}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Input;
|
||||||
15
src/components/shared/Input.module.css
Normal file
15
src/components/shared/Input.module.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.container > label {
|
||||||
|
@apply flex flex-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container > label > span {
|
||||||
|
@apply mb-1 text-gray-600 font-medium text-sm uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container > label > input {
|
||||||
|
@apply py-4 px-4 rounded bg-gray-200 border border-gray-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container > label > input:focus {
|
||||||
|
@apply outline-none border-gray-500;
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ import React from "react";
|
|||||||
import { useStaticQuery, graphql } from "gatsby";
|
import { useStaticQuery, graphql } from "gatsby";
|
||||||
import GatsbyImage from "gatsby-image";
|
import GatsbyImage from "gatsby-image";
|
||||||
|
|
||||||
const Logo = ({ size = "256px" }) => {
|
const Logo = ({ size = "256px", className }) => {
|
||||||
const { file } = useStaticQuery(graphql`
|
const { file } = useStaticQuery(graphql`
|
||||||
query {
|
query {
|
||||||
file(relativePath: { eq: "logo.png" }) {
|
file(relativePath: { eq: "logo.png" }) {
|
||||||
@ -18,7 +18,7 @@ const Logo = ({ size = "256px" }) => {
|
|||||||
return (
|
return (
|
||||||
<GatsbyImage
|
<GatsbyImage
|
||||||
loading="eager"
|
loading="eager"
|
||||||
className="shadow-md rounded"
|
className={`rounded ${className}`}
|
||||||
style={{ width: size, height: size }}
|
style={{ width: size, height: size }}
|
||||||
fluid={file.childImageSharp.fluid}
|
fluid={file.childImageSharp.fluid}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -2,17 +2,23 @@ import React, { createContext, useState } from "react";
|
|||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
authModal: {},
|
authModal: {},
|
||||||
|
createResumeModal: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const ModalContext = createContext(defaultState);
|
const ModalContext = createContext(defaultState);
|
||||||
|
|
||||||
const ModalProvider = ({ children }) => {
|
const ModalProvider = ({ children }) => {
|
||||||
const [authOpen, setAuthOpen] = useState(false);
|
const [authOpen, setAuthOpen] = useState(false);
|
||||||
|
const [createResumeOpen, setCreateResumeOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalContext.Provider
|
<ModalContext.Provider
|
||||||
value={{
|
value={{
|
||||||
authModal: { isOpen: authOpen, setOpen: setAuthOpen },
|
authModal: { isOpen: authOpen, setOpen: setAuthOpen },
|
||||||
|
createResumeModal: {
|
||||||
|
isOpen: createResumeOpen,
|
||||||
|
setOpen: setCreateResumeOpen,
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ const defaultUser = {
|
|||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
user: defaultUser,
|
user: defaultUser,
|
||||||
logout: () => {},
|
logout: async () => {},
|
||||||
loginWithGoogle: async () => {},
|
loginWithGoogle: async () => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -23,10 +23,16 @@ const UserProvider = ({ children }) => {
|
|||||||
const [firebaseUser, loading] = useAuthState(firebase.auth());
|
const [firebaseUser, loading] = useAuthState(firebase.auth());
|
||||||
const [user, setUser] = useState(null);
|
const [user, setUser] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const user = JSON.parse(localStorage.getItem("user"));
|
||||||
|
setUser(user);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (firebaseUser) {
|
if (firebaseUser) {
|
||||||
const user = pick(firebaseUser, Object.keys(defaultUser));
|
const user = pick(firebaseUser, Object.keys(defaultUser));
|
||||||
setUser(user);
|
setUser(user);
|
||||||
|
localStorage.setItem("user", JSON.stringify(user));
|
||||||
|
|
||||||
const addUserToDatabase = async () => {
|
const addUserToDatabase = async () => {
|
||||||
const docRef = firebase.firestore().collection("users").doc(user.uid);
|
const docRef = firebase.firestore().collection("users").doc(user.uid);
|
||||||
@ -48,8 +54,9 @@ const UserProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const logout = () => {
|
const logout = async () => {
|
||||||
firebase.auth().signOut();
|
await firebase.auth().signOut();
|
||||||
|
localStorage.removeItem("user");
|
||||||
setUser(null);
|
setUser(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,8 +64,8 @@ const UserProvider = ({ children }) => {
|
|||||||
<UserContext.Provider
|
<UserContext.Provider
|
||||||
value={{
|
value={{
|
||||||
user,
|
user,
|
||||||
loading,
|
|
||||||
logout,
|
logout,
|
||||||
|
loading,
|
||||||
loginWithGoogle,
|
loginWithGoogle,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import BaseModal from "./BaseModal";
|
|||||||
import Button from "../components/shared/Button";
|
import Button from "../components/shared/Button";
|
||||||
import ModalContext from "../contexts/ModalContext";
|
import ModalContext from "../contexts/ModalContext";
|
||||||
import UserContext from "../contexts/UserContext";
|
import UserContext from "../contexts/UserContext";
|
||||||
|
import { navigate } from "gatsby";
|
||||||
|
|
||||||
const AuthModal = () => {
|
const AuthModal = () => {
|
||||||
const [isLoading, setLoading] = useState(false);
|
const [isLoading, setLoading] = useState(false);
|
||||||
@ -15,8 +16,9 @@ const AuthModal = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGoToApp = () => {
|
const handleGotoApp = () => {
|
||||||
console.log("Go to App");
|
navigate("/app/dashboard");
|
||||||
|
authModal.setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTitle = () =>
|
const getTitle = () =>
|
||||||
@ -30,7 +32,7 @@ const AuthModal = () => {
|
|||||||
const loggedInAction = (
|
const loggedInAction = (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Button outline className="mr-8" title="Logout" onClick={logout} />
|
<Button outline className="mr-8" title="Logout" onClick={logout} />
|
||||||
<Button title="Go to App" onClick={handleGoToApp} />
|
<Button title="Go to App" onClick={handleGotoApp} />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { isFunction } from "lodash";
|
||||||
import Modal from "@material-ui/core/Modal";
|
import Modal from "@material-ui/core/Modal";
|
||||||
import Backdrop from "@material-ui/core/Backdrop";
|
import Backdrop from "@material-ui/core/Backdrop";
|
||||||
import Fade from "@material-ui/core/Fade";
|
import Fade from "@material-ui/core/Fade";
|
||||||
@ -6,10 +7,13 @@ import { MdClose } from "react-icons/md";
|
|||||||
import styles from "./BaseModal.module.css";
|
import styles from "./BaseModal.module.css";
|
||||||
import Button from "../components/shared/Button";
|
import Button from "../components/shared/Button";
|
||||||
|
|
||||||
const BaseModal = ({ title, state, children, action }) => {
|
const BaseModal = ({ title, state, children, action, onDestroy }) => {
|
||||||
const { isOpen, setOpen } = state;
|
const { isOpen, setOpen } = state;
|
||||||
|
|
||||||
const handleClose = () => setOpen(false);
|
const handleClose = () => {
|
||||||
|
setOpen(false);
|
||||||
|
isFunction(onDestroy) && onDestroy();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
55
src/modals/CreateResumeModal.js
Normal file
55
src/modals/CreateResumeModal.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import React, { useContext } from "react";
|
||||||
|
import { useFormik } from "formik";
|
||||||
|
import BaseModal from "./BaseModal";
|
||||||
|
import ModalContext from "../contexts/ModalContext";
|
||||||
|
import Button from "../components/shared/Button";
|
||||||
|
import Input from "../components/shared/Input";
|
||||||
|
|
||||||
|
const CreateResumeModal = () => {
|
||||||
|
const { createResumeModal } = useContext(ModalContext);
|
||||||
|
const formik = useFormik({
|
||||||
|
initialValues: {
|
||||||
|
name: "",
|
||||||
|
},
|
||||||
|
onSubmit: (values) => {
|
||||||
|
alert(JSON.stringify(values, null, 2));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const submitAction = (
|
||||||
|
<Button title="Create Resume" onClick={() => formik.handleSubmit()} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const onDestroy = () => {
|
||||||
|
formik.resetForm();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseModal
|
||||||
|
state={createResumeModal}
|
||||||
|
title="Create New Resume"
|
||||||
|
action={submitAction}
|
||||||
|
onDestroy={onDestroy}
|
||||||
|
>
|
||||||
|
<form className="mb-8">
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
label="Name"
|
||||||
|
name="name"
|
||||||
|
placeholder="Full Stack Web Developer"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.name}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<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.
|
||||||
|
</p>
|
||||||
|
</BaseModal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreateResumeModal;
|
||||||
@ -1,10 +1,12 @@
|
|||||||
import React, { Fragment } from "react";
|
import React, { Fragment } from "react";
|
||||||
import AuthModal from "./AuthModal";
|
import AuthModal from "./AuthModal";
|
||||||
|
import CreateResumeModal from "./CreateResumeModal";
|
||||||
|
|
||||||
const ModalRegistrar = () => {
|
const ModalRegistrar = () => {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<AuthModal />
|
<AuthModal />
|
||||||
|
<CreateResumeModal />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { navigate } from "gatsby";
|
import { navigate } from "gatsby";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
const NotFoundPage = () => {
|
const NotFound = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
navigate("/");
|
navigate("/");
|
||||||
}, []);
|
}, []);
|
||||||
@ -9,4 +9,4 @@ const NotFoundPage = () => {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NotFoundPage;
|
export default NotFound;
|
||||||
|
|||||||
17
src/pages/app.js
Normal file
17
src/pages/app.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Router, Redirect } from "@reach/router";
|
||||||
|
import Wrapper from "../components/shared/Wrapper";
|
||||||
|
import Dashboard from "./app/dashboard";
|
||||||
|
import PrivateRoute from "../components/router/PrivateRoute";
|
||||||
|
import NotFound from "./404";
|
||||||
|
|
||||||
|
const App = () => (
|
||||||
|
<Wrapper>
|
||||||
|
<Router>
|
||||||
|
<Redirect noThrow from="/app" to="/app/dashboard" exact />
|
||||||
|
<PrivateRoute path="/app/dashboard" component={Dashboard} />
|
||||||
|
<NotFound default />
|
||||||
|
</Router>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
export default App;
|
||||||
25
src/pages/app/dashboard.js
Normal file
25
src/pages/app/dashboard.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import React from "react";
|
||||||
|
import Wrapper from "../../components/shared/Wrapper";
|
||||||
|
import CreateResume from "../../components/dashboard/CreateResume";
|
||||||
|
import ResumePreview from "../../components/dashboard/ResumePreview";
|
||||||
|
import TopNavbar from "../../components/dashboard/TopNavbar";
|
||||||
|
|
||||||
|
const Dashboard = () => {
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<TopNavbar />
|
||||||
|
|
||||||
|
<div className="container mt-12">
|
||||||
|
<div className="grid grid-cols-6 gap-8">
|
||||||
|
<CreateResume />
|
||||||
|
<ResumePreview
|
||||||
|
title="Full Stack Developer"
|
||||||
|
subtitle="Last updated 6 days ago"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dashboard;
|
||||||
@ -1,5 +1,4 @@
|
|||||||
@import "~react-loader-spinner/dist/loader/css/react-spinner-loader.css";
|
@import "~react-loader-spinner/dist/loader/css/react-spinner-loader.css";
|
||||||
@import "~react-toastify/dist/ReactToastify.css";
|
|
||||||
@import "./toastify.css";
|
@import "./toastify.css";
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
@import "~react-toastify/dist/ReactToastify.css";
|
||||||
|
|
||||||
.Toastify__toast {
|
.Toastify__toast {
|
||||||
@apply px-8 py-6 shadow-lg rounded;
|
@apply px-8 py-6 shadow rounded;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Toastify__toast--default {
|
.Toastify__toast--default {
|
||||||
|
|||||||
Reference in New Issue
Block a user