mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-13 16:22:59 +10:00
- implement about section
This commit is contained in:
@ -13,6 +13,7 @@ import { StorageProvider } from './src/contexts/StorageContext';
|
||||
import { ThemeProvider } from './src/contexts/ThemeContext';
|
||||
import { UserProvider } from './src/contexts/UserContext';
|
||||
import './src/styles/global.css';
|
||||
import './src/styles/forms.css';
|
||||
import './src/styles/shadows.css';
|
||||
import './src/styles/tailwind.css';
|
||||
import './src/styles/toastify.css';
|
||||
|
||||
14
package-lock.json
generated
14
package-lock.json
generated
@ -18567,6 +18567,20 @@
|
||||
"is-typedarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"typeit": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/typeit/-/typeit-7.0.4.tgz",
|
||||
"integrity": "sha512-ETiVr3s4XOXUE9W+tVhF3gxGTf5z4tc35YjvWEQhqKsJhXWvpQlt/D/ZvIHkZzHegU3stxagjeG2pfm1/AWsYQ=="
|
||||
},
|
||||
"typeit-react": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/typeit-react/-/typeit-react-0.1.3.tgz",
|
||||
"integrity": "sha512-9HiAghnq8NjLj67dakc9C4eCHyunsCgl7ZSo04w/7YWAjs12bHb/+J3geFfTgBVpbWCL6GPDZ7eWBXNZ3ZweGw==",
|
||||
"requires": {
|
||||
"@types/react": "^16.9.19",
|
||||
"typeit": "^7.0.3"
|
||||
}
|
||||
},
|
||||
"unbzip2-stream": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
"react-scroll": "^1.8.0",
|
||||
"react-toastify": "^6.0.8",
|
||||
"short-unique-id": "^3.0.3",
|
||||
"typeit-react": "^0.1.3",
|
||||
"uuid": "^8.2.0",
|
||||
"yup": "^0.29.1"
|
||||
},
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import React, { memo } from 'react';
|
||||
import { FaCoffee } from 'react-icons/fa';
|
||||
import { FaCoffee, FaBug } from 'react-icons/fa';
|
||||
import { MdCode } from 'react-icons/md';
|
||||
import Button from '../../../shared/Button';
|
||||
import Heading from '../../../shared/Heading';
|
||||
import styles from './About.module.css';
|
||||
@ -37,6 +38,75 @@ const About = () => {
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.container}>
|
||||
<h5>Bug? Feature Request?</h5>
|
||||
|
||||
<p className="leading-loose">
|
||||
Something halting your progress from making a resume? Found a pesky
|
||||
bug that just won't quit? Talk about it on the GitHub Issues
|
||||
section, or send me and email using the actions below.
|
||||
</p>
|
||||
|
||||
<div className="mt-4 flex">
|
||||
<a
|
||||
href="https://github.com/AmruthPillai/Reactive-Resume/issues/new"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<Button icon={FaBug}>Raise an Issue</Button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.container}>
|
||||
<h5>Source Code</h5>
|
||||
|
||||
<p className="leading-loose">
|
||||
Want to run the project from its source? Are you a developer willing
|
||||
to contribute to the open-source development of this project? Click
|
||||
the button below.
|
||||
</p>
|
||||
|
||||
<div className="mt-4 flex">
|
||||
<a
|
||||
href="https://github.com/AmruthPillai/Reactive-Resume"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<Button icon={MdCode}>GitHub Repo</Button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.container}>
|
||||
<h5>License Information</h5>
|
||||
|
||||
<p className="leading-loose">
|
||||
The project is governed under the MIT License, which you can read more
|
||||
about below. Basically, you are allowed to use the project anywhere
|
||||
provided you give credits to the original author.
|
||||
</p>
|
||||
|
||||
<div className="mt-4 flex">
|
||||
<a
|
||||
href="https://github.com/AmruthPillai/Reactive-Resume/blob/master/LICENSE"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<Button icon={MdCode}>MIT License</Button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="my-4 text-center opacity-50 text-sm">
|
||||
<p>
|
||||
Made with Love by{' '}
|
||||
<a href="https://amruthpillai.com" rel="noreferrer" target="_blank">
|
||||
Amruth Pillai
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import React, { memo, useContext, useState } from 'react';
|
||||
import { FaAngleDown } from 'react-icons/fa';
|
||||
import UserContext from '../../../../contexts/UserContext';
|
||||
import Button from '../../../shared/Button';
|
||||
import Heading from '../../../shared/Heading';
|
||||
@ -6,6 +7,7 @@ import styles from './Settings.module.css';
|
||||
import Input from '../../../shared/Input';
|
||||
import ThemeContext from '../../../../contexts/ThemeContext';
|
||||
import themeConfig from '../../../../data/themeConfig';
|
||||
import languageConfig from '../../../../data/languageConfig';
|
||||
|
||||
const Settings = () => {
|
||||
const [deleteText, setDeleteText] = useState('Delete Account');
|
||||
@ -16,6 +18,10 @@ const Settings = () => {
|
||||
setTheme(e.target.value);
|
||||
};
|
||||
|
||||
const handleChangeLanguage = (e) => {
|
||||
console.log(e.target.value);
|
||||
};
|
||||
|
||||
const handleDeleteAccount = () => {
|
||||
if (deleteText === 'Delete Account') {
|
||||
setDeleteText('Are you sure?');
|
||||
@ -40,6 +46,37 @@ const Settings = () => {
|
||||
onChange={handleChangeTheme}
|
||||
/>
|
||||
|
||||
<label>
|
||||
<span>Language</span>
|
||||
<div className="relative grid items-center">
|
||||
<select onChange={handleChangeLanguage}>
|
||||
{languageConfig.map((x) => (
|
||||
<option key={x.key} value={x.key}>
|
||||
{x.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<FaAngleDown
|
||||
size="16px"
|
||||
className="absolute right-0 opacity-50 hover:opacity-75 mx-4"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<p className="text-sm leading-loose">
|
||||
If you would like to contribute by providing translations to Reactive
|
||||
Resume in your language,{' '}
|
||||
<a
|
||||
href="https://github.com/AmruthPillai/Reactive-Resume/blob/master/TRANSLATING.md"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
please visit this link
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
|
||||
<div className={styles.container}>
|
||||
<h5>Danger Zone</h5>
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { navigate } from 'gatsby';
|
||||
import TypeIt from 'typeit-react';
|
||||
import React, { memo, useContext } from 'react';
|
||||
import { FaGithub } from 'react-icons/fa';
|
||||
import ModalContext from '../../contexts/ModalContext';
|
||||
import UserContext from '../../contexts/UserContext';
|
||||
import Button from '../shared/Button';
|
||||
@ -18,7 +20,21 @@ const Hero = () => {
|
||||
<Logo className="shadow-lg" size="256px" />
|
||||
|
||||
<div className="ml-12">
|
||||
<h1 className="text-5xl font-bold">Reactive Resume</h1>
|
||||
<h1 className="sr-only">Reactive Resume</h1>
|
||||
<div className="text-5xl font-bold">
|
||||
<TypeIt
|
||||
getBeforeInit={(instance) => {
|
||||
return instance
|
||||
.type('Creative Resume')
|
||||
.pause(500)
|
||||
.move(-11)
|
||||
.delete(4)
|
||||
.pause(250)
|
||||
.type('Reac')
|
||||
.move('END');
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<h2 className="mt-1 text-3xl text-primary-500">
|
||||
A free and open-source resume builder.
|
||||
</h2>
|
||||
@ -33,6 +49,16 @@ const Hero = () => {
|
||||
Login
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<a
|
||||
href="https://github.com/AmruthPillai/Reactive-Resume"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<Button outline icon={FaGithub} className="ml-8">
|
||||
Source Code
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -18,7 +18,9 @@ const Avatar = ({ className }) => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
const photoURL = useMemo(() => toUrl(user.email, 'size=128'), [user.email]);
|
||||
const photoURL = useMemo(() => toUrl(user.email || '', 'size=128&d=retro'), [
|
||||
user.email,
|
||||
]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -31,7 +33,7 @@ const Avatar = ({ className }) => {
|
||||
>
|
||||
<img
|
||||
src={photoURL}
|
||||
alt={user.displayName}
|
||||
alt={user.displayName || 'Anonymous User'}
|
||||
className={cx(styles.container, className)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -46,7 +46,7 @@ const Input = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cx(styles.container, className)}>
|
||||
<div className={className}>
|
||||
<label htmlFor={uuid}>
|
||||
<span>
|
||||
{label}{' '}
|
||||
@ -115,7 +115,9 @@ const Input = ({
|
||||
onChange={onChange}
|
||||
>
|
||||
{options.map((x) => (
|
||||
<option key={x}>{x}</option>
|
||||
<option key={x} value={x}>
|
||||
{x}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
|
||||
@ -1,31 +1,3 @@
|
||||
.container label input,
|
||||
.container label textarea,
|
||||
.container label select {
|
||||
@apply w-full py-3 px-4 rounded text-primary-900 bg-primary-200 border border-transparent appearance-none;
|
||||
}
|
||||
|
||||
.container label input::placeholder,
|
||||
.container label textarea::placeholder,
|
||||
.container label select::placeholder {
|
||||
@apply opacity-50;
|
||||
}
|
||||
|
||||
.container label input:hover,
|
||||
.container label textarea:hover,
|
||||
.container label select:hover {
|
||||
@apply outline-none border-primary-400;
|
||||
}
|
||||
|
||||
.container label input:focus,
|
||||
.container label textarea:focus,
|
||||
.container label select:focus {
|
||||
@apply outline-none border-primary-600;
|
||||
}
|
||||
|
||||
.container label > p {
|
||||
@apply mt-1 text-red-600 text-xs;
|
||||
}
|
||||
|
||||
.circle {
|
||||
left: 14px;
|
||||
@apply absolute bg-primary-900 rounded-full w-6 h-6;
|
||||
|
||||
@ -17,6 +17,7 @@ const defaultState = {
|
||||
user: defaultUser,
|
||||
logout: async () => {},
|
||||
loginWithGoogle: async () => {},
|
||||
loginAnonymously: async () => {},
|
||||
deleteAccount: async () => {},
|
||||
};
|
||||
|
||||
@ -57,6 +58,14 @@ const UserProvider = ({ children }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const loginAnonymously = async () => {
|
||||
try {
|
||||
return await firebase.auth().signInAnonymously();
|
||||
} catch (error) {
|
||||
toast.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
firebase.auth().signOut();
|
||||
localStorage.removeItem('user');
|
||||
@ -87,6 +96,7 @@ const UserProvider = ({ children }) => {
|
||||
logout,
|
||||
loading,
|
||||
loginWithGoogle,
|
||||
loginAnonymously,
|
||||
deleteAccount,
|
||||
}}
|
||||
>
|
||||
|
||||
@ -17,11 +17,11 @@
|
||||
"title": "Venturesity Banyan Hack"
|
||||
},
|
||||
{
|
||||
"title": "Smart India Hackathon",
|
||||
"awarder": "Govt. of India",
|
||||
"date": "2017-04-01",
|
||||
"id": "89c0171a-eae9-403e-9f4c-a757fb535c2b",
|
||||
"summary": "",
|
||||
"id": "89c0171a-eae9-403e-9f4c-a757fb535c2b"
|
||||
"title": "Smart India Hackathon"
|
||||
}
|
||||
],
|
||||
"visible": true
|
||||
@ -44,11 +44,11 @@
|
||||
"title": "VCP6-DCV"
|
||||
},
|
||||
{
|
||||
"title": "DCUCI 642-999",
|
||||
"issuer": "Cisco Systems",
|
||||
"date": "2014-04-01",
|
||||
"id": "11107df6-5f3c-49ae-bcd4-62b8baa181a1",
|
||||
"issuer": "Cisco Systems",
|
||||
"summary": "",
|
||||
"id": "11107df6-5f3c-49ae-bcd4-62b8baa181a1"
|
||||
"title": "DCUCI 642-999"
|
||||
}
|
||||
],
|
||||
"visible": true
|
||||
@ -82,8 +82,8 @@
|
||||
"hobbies": {
|
||||
"heading": "Hobbies",
|
||||
"items": [
|
||||
{ "name": "Poetry", "id": "788dcf5a-78ca-4866-8397-c7a29073d9a1" },
|
||||
{ "name": "Travelling", "id": "e3523371-f50c-4348-8c5e-35fe84c0006d" },
|
||||
{ "id": "788dcf5a-78ca-4866-8397-c7a29073d9a1", "name": "Poetry" },
|
||||
{ "id": "e3523371-f50c-4348-8c5e-35fe84c0006d", "name": "Travelling" },
|
||||
{ "id": "92c35e3b-6cd7-4cea-b505-61347ec61b68", "name": "Photography" },
|
||||
{
|
||||
"id": "d36f2089-93a9-4f30-a425-3dd81c6b89df",
|
||||
@ -130,6 +130,31 @@
|
||||
},
|
||||
"font": "Open Sans",
|
||||
"layout": {
|
||||
"castform": [
|
||||
["awards", "certifications", "languages", "hobbies"],
|
||||
["objective", "work", "education", "skills", "projects", "references"]
|
||||
],
|
||||
"celebi": [
|
||||
["awards", "certifications", "languages", "hobbies"],
|
||||
["objective", "work", "education", "skills", "projects", "references"]
|
||||
],
|
||||
"gengar": [
|
||||
["objective", "skills"],
|
||||
["awards", "certifications", "languages", "references", "hobbies"],
|
||||
["work", "education", "projects"]
|
||||
],
|
||||
"glalie": [
|
||||
["awards", "certifications", "hobbies"],
|
||||
[
|
||||
"objective",
|
||||
"work",
|
||||
"education",
|
||||
"skills",
|
||||
"projects",
|
||||
"languages",
|
||||
"references"
|
||||
]
|
||||
],
|
||||
"onyx": [
|
||||
["objective", "work", "education", "projects"],
|
||||
["hobbies", "languages", "awards", "certifications"],
|
||||
@ -138,26 +163,9 @@
|
||||
"pikachu": [
|
||||
["skills", "languages", "hobbies", "awards", "certifications"],
|
||||
["work", "education", "projects", "references"]
|
||||
],
|
||||
"gengar": [
|
||||
["objective", "skills"],
|
||||
["awards", "certifications", "languages", "references", "hobbies"],
|
||||
["work", "education", "projects"]
|
||||
],
|
||||
"castform": [
|
||||
["awards", "certifications", "languages", "hobbies"],
|
||||
["objective", "work", "education", "skills", "projects", "references"]
|
||||
],
|
||||
"glalie": [
|
||||
["awards", "certifications", "hobbies"],
|
||||
["objective", "work", "education", "skills", "projects", "languages", "references"]
|
||||
],
|
||||
"celebi": [
|
||||
["awards", "certifications", "languages", "hobbies"],
|
||||
["objective", "work", "education", "skills", "projects", "references"]
|
||||
]
|
||||
},
|
||||
"template": "pikachu"
|
||||
"template": "castform"
|
||||
},
|
||||
"objective": {
|
||||
"body": "To obtain a job within my chosen field that will challenge me and allow me to use my education, skills and past experiences in a way that is mutually beneficial to both myself and my employer and allow for future growth and advancement.",
|
||||
@ -222,12 +230,12 @@
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"name": "Lorraine Beasley",
|
||||
"position": "Head of HR, Carson Logistics",
|
||||
"phone": "+1 661-808-4188",
|
||||
"email": "l.beasley@carsonlogistics.com",
|
||||
"summary": "",
|
||||
"id": "94e3447b-0a78-4fb7-b14d-591982d35320"
|
||||
"id": "94e3447b-0a78-4fb7-b14d-591982d35320",
|
||||
"name": "Lorraine Beasley",
|
||||
"phone": "+1 661-808-4188",
|
||||
"position": "Head of HR, Carson Logistics",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"visible": true
|
||||
@ -256,14 +264,14 @@
|
||||
"name": "Call Center Management"
|
||||
},
|
||||
{
|
||||
"name": "Teambuilding & Training",
|
||||
"id": "08d6c739-1465-41f7-8825-b8d94faa38d6",
|
||||
"level": "Novice",
|
||||
"id": "08d6c739-1465-41f7-8825-b8d94faa38d6"
|
||||
"name": "Teambuilding & Training"
|
||||
},
|
||||
{
|
||||
"name": "Continuous Improvement",
|
||||
"id": "261b8fc3-aeec-4347-88a8-bcacb1a17aa3",
|
||||
"level": "Fundamental Awareness",
|
||||
"id": "261b8fc3-aeec-4347-88a8-bcacb1a17aa3"
|
||||
"name": "Continuous Improvement"
|
||||
}
|
||||
],
|
||||
"visible": true
|
||||
@ -272,10 +280,10 @@
|
||||
"heading": "Social",
|
||||
"items": [
|
||||
{
|
||||
"url": "https://pillai.xyz/instagram",
|
||||
"id": "a832b37d-f11d-4a80-8b4d-24796e571b17",
|
||||
"network": "Instagram",
|
||||
"username": "AmruthPillai",
|
||||
"id": "a832b37d-f11d-4a80-8b4d-24796e571b17"
|
||||
"url": "https://pillai.xyz/instagram",
|
||||
"username": "AmruthPillai"
|
||||
},
|
||||
{
|
||||
"id": "a72107fa-a4a5-407d-9e85-39bdb9c0b11a",
|
||||
@ -315,12 +323,12 @@
|
||||
},
|
||||
{
|
||||
"company": "Pizza Hut, Newark, NJ",
|
||||
"position": "Waiter",
|
||||
"website": "https://pizzahut.com",
|
||||
"startDate": "2005-08-01",
|
||||
"endDate": "2009-09-01",
|
||||
"id": "dd935088-6fe7-4a4b-8ff5-7417c32d2add",
|
||||
"position": "Waiter",
|
||||
"startDate": "2005-08-01",
|
||||
"summary": "- Worked passionately in customer service in a high volume restaurant.\n- Completed the FAST customer service training class.\n- Maintained a high tip average thanks to consistent customer satisfaction.",
|
||||
"id": "dd935088-6fe7-4a4b-8ff5-7417c32d2add"
|
||||
"website": "https://pizzahut.com"
|
||||
}
|
||||
],
|
||||
"visible": true
|
||||
|
||||
8
src/data/languageConfig.js
Normal file
8
src/data/languageConfig.js
Normal file
@ -0,0 +1,8 @@
|
||||
const languageConfig = [
|
||||
{
|
||||
key: 'en',
|
||||
name: 'English',
|
||||
},
|
||||
];
|
||||
|
||||
export default languageConfig;
|
||||
@ -7,10 +7,13 @@ import BaseModal from './BaseModal';
|
||||
|
||||
const AuthModal = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
const [isLoadingGoogle, setLoadingGoogle] = useState(false);
|
||||
const [isLoadingAnonymous, setLoadingAnonymous] = useState(false);
|
||||
|
||||
const { emitter, events } = useContext(ModalContext);
|
||||
const { user, loginWithGoogle, logout } = useContext(UserContext);
|
||||
const { user, loginWithGoogle, loginAnonymously, logout } = useContext(
|
||||
UserContext,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const unbind = emitter.on(events.AUTH_MODAL, () => setOpen(true));
|
||||
@ -19,9 +22,15 @@ const AuthModal = () => {
|
||||
}, [emitter, events]);
|
||||
|
||||
const handleSignInWithGoogle = async () => {
|
||||
setLoading(true);
|
||||
setLoadingGoogle(true);
|
||||
await loginWithGoogle();
|
||||
setLoading(false);
|
||||
setLoadingGoogle(false);
|
||||
};
|
||||
|
||||
const handleSignInAnonymously = async () => {
|
||||
setLoadingAnonymous(true);
|
||||
await loginAnonymously();
|
||||
setLoadingAnonymous(false);
|
||||
};
|
||||
|
||||
const handleGotoApp = () => {
|
||||
@ -30,7 +39,7 @@ const AuthModal = () => {
|
||||
};
|
||||
|
||||
const getTitle = () =>
|
||||
user ? `Welcome, ${user.displayName}` : 'Who are you?';
|
||||
user ? `Welcome, ${user.displayName || 'Agent 47'}` : 'Who are you?';
|
||||
|
||||
const getMessage = () =>
|
||||
user
|
||||
@ -49,9 +58,18 @@ const AuthModal = () => {
|
||||
);
|
||||
|
||||
const loggedOutAction = (
|
||||
<Button isLoading={isLoading} onClick={handleSignInWithGoogle}>
|
||||
Sign in with Google
|
||||
</Button>
|
||||
<div className="flex">
|
||||
<Button isLoading={isLoadingGoogle} onClick={handleSignInWithGoogle}>
|
||||
Sign in with Google
|
||||
</Button>
|
||||
<Button
|
||||
className="ml-8"
|
||||
isLoading={isLoadingAnonymous}
|
||||
onClick={handleSignInAnonymously}
|
||||
>
|
||||
Sign in Anonymously
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@ -7,12 +7,17 @@ import RightSidebar from '../../components/builder/right/RightSidebar';
|
||||
import LoadingScreen from '../../components/router/LoadingScreen';
|
||||
import DatabaseContext from '../../contexts/DatabaseContext';
|
||||
import { useDispatch } from '../../contexts/ResumeContext';
|
||||
import Button from '../../components/shared/Button';
|
||||
|
||||
const Builder = ({ id }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { getResume } = useContext(DatabaseContext);
|
||||
|
||||
const handleLoadDemoData = () => {
|
||||
dispatch({ type: 'load_demo_data' });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const resume = await getResume(id);
|
||||
@ -25,6 +30,21 @@ const Builder = ({ id }) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (resume.createdAt === resume.updatedAt) {
|
||||
toast.dark(() => (
|
||||
<div className="py-2">
|
||||
<p className="leading-loose">
|
||||
Not sure where to begin? Try <strong>Loading Demo Data</strong> to
|
||||
see what Reactive Resume has to offer.
|
||||
</p>
|
||||
|
||||
<Button className="mt-4" onClick={handleLoadDemoData}>
|
||||
Load Demo Data
|
||||
</Button>
|
||||
</div>
|
||||
));
|
||||
}
|
||||
|
||||
dispatch({ type: 'set_data', payload: resume });
|
||||
return setLoading(false);
|
||||
})();
|
||||
|
||||
89
src/pages/faq.js
Normal file
89
src/pages/faq.js
Normal file
@ -0,0 +1,89 @@
|
||||
import React from 'react';
|
||||
import { MdKeyboardArrowLeft } from 'react-icons/md';
|
||||
import { Link } from '@reach/router';
|
||||
import Wrapper from '../components/shared/Wrapper';
|
||||
|
||||
const FrequentlyAskedQuestions = () => {
|
||||
return (
|
||||
<Wrapper>
|
||||
<div className="md:w-1/2 container px-8 md:px-0 py-16 grid gap-12">
|
||||
<div className="flex items-center">
|
||||
<Link to="/">
|
||||
<MdKeyboardArrowLeft size="32px" />
|
||||
</Link>
|
||||
<h1 className="ml-6 text-4xl font-semibold">
|
||||
Frequently Asked Questions
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="leading-loose">
|
||||
This is aimed to be the world's simplest privacy policy. This
|
||||
document should explain to you why the app collects some
|
||||
information, what happens when your account is deleted and some
|
||||
other frequently asked questions answered regarding your privacy.
|
||||
</p>
|
||||
|
||||
<p className="mt-6 leading-loose">
|
||||
If you have any more questions, please raise an issue regarding the
|
||||
same on GitHub and I'll answer as honest and quickly as
|
||||
possible :)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<h4 className="text-xl font-medium mb-4">
|
||||
What identifiable information is stored about me?
|
||||
</h4>
|
||||
<p className="leading-loose">
|
||||
Your name and your email address is stored along with your user
|
||||
information, if you signed in with Google, and of course, all the
|
||||
information you input in your resume is also stored in the database.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<h4 className="text-xl font-medium mb-4">
|
||||
Why are you using a database, why not keep everything local like in
|
||||
the first version of Reactive Resume?
|
||||
</h4>
|
||||
<p className="leading-loose">
|
||||
Not having a centralized database cause a lot more problems than I
|
||||
could solve, mainly having a large chunk of the users of the app
|
||||
having an outdated schema as the app evolved. This was a problem I
|
||||
could not solve without having at least some control.
|
||||
</p>
|
||||
|
||||
<p className="mt-6 leading-loose">
|
||||
Also, a lot of users were having trouble printing their resumes on
|
||||
their browsers, so with the help of Cloud Functions from Firebase,
|
||||
you can now print your resumes remotely. None of the resumes are
|
||||
stored, and they are sent to you immediately after generation, which
|
||||
can be verified by looking through the source code.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<h4 className="text-xl font-medium mb-4">
|
||||
How is this all free? There must be a catch!
|
||||
</h4>
|
||||
<p className="leading-loose">
|
||||
<strong>Absolutely no catch to this freebie.</strong> This project
|
||||
is just my way of giving back to the community that I've
|
||||
learned so much from. If you'd like to show your appreciation
|
||||
however, you can follow me on my social media and let me know, or
|
||||
donate to the app to help pay the cloud bills.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default FrequentlyAskedQuestions;
|
||||
@ -1,5 +1,6 @@
|
||||
import React, { memo } from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { Link } from '@reach/router';
|
||||
import Hero from '../components/landing/Hero';
|
||||
import Wrapper from '../components/shared/Wrapper';
|
||||
|
||||
@ -14,6 +15,10 @@ const Home = () => {
|
||||
<div className="container mt-24">
|
||||
<Hero />
|
||||
|
||||
<div className="my-24">
|
||||
<h4 className="text-xl uppercase font-bold mb-8">Screenshots</h4>
|
||||
</div>
|
||||
|
||||
<div className="pt-8">
|
||||
<Feature title="Create a resume that’s worthy of who you are.">
|
||||
Keep up with the latest trends in resume design without having to
|
||||
@ -51,12 +56,27 @@ const Home = () => {
|
||||
You must be thinking, if you're not paying for the product,
|
||||
then you are the product. Or, at least your data is?{' '}
|
||||
<strong>Well, this is the exception</strong>. Your data is your own,
|
||||
as stated in the ridiculously simple <a href="">Privacy Policy</a>,
|
||||
I don't do anything with the data, it just exists on a database
|
||||
for the convinient features provided by Reactive Resume.
|
||||
as stated in the ridiculously simple{' '}
|
||||
<Link to="/faq">Privacy Policy</Link>, I don't do anything with
|
||||
the data, it just exists on a database for the convinient features
|
||||
provided by Reactive Resume.
|
||||
</Feature>
|
||||
</div>
|
||||
|
||||
<div className="my-24">
|
||||
<h4 className="text-xl uppercase font-bold mb-8">
|
||||
Links of Interest
|
||||
</h4>
|
||||
<div className="grid grid-cols-4 gap-8">
|
||||
<Link to="/faq">Frequently Asked Questions</Link>
|
||||
<Link to="/faq">Checkout Source Code</Link>
|
||||
<Link to="/faq">Upvote on Product Hunt</Link>
|
||||
<Link to="/faq">Raise an Issue on GitHub</Link>
|
||||
<Link to="/faq">Donate to Reactive Resume</Link>
|
||||
<Link to="/faq">Building Great Looking Resumes</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer className="my-24">
|
||||
<p className="text-primary-500 opacity-75">
|
||||
Licensed under <a href="/">MIT</a>
|
||||
|
||||
35
src/styles/forms.css
Normal file
35
src/styles/forms.css
Normal file
@ -0,0 +1,35 @@
|
||||
label {
|
||||
@apply flex flex-col;
|
||||
}
|
||||
|
||||
label > span:first-child {
|
||||
@apply mb-1 text-primary-600 font-semibold tracking-wide text-xs uppercase;
|
||||
}
|
||||
|
||||
label > p {
|
||||
@apply mt-1 text-red-600 text-xs;
|
||||
}
|
||||
|
||||
label input,
|
||||
label textarea,
|
||||
label select {
|
||||
@apply w-full py-3 px-4 rounded text-primary-900 bg-primary-200 border border-transparent appearance-none;
|
||||
}
|
||||
|
||||
label input::placeholder,
|
||||
label textarea::placeholder,
|
||||
label select::placeholder {
|
||||
@apply opacity-50;
|
||||
}
|
||||
|
||||
label input:hover,
|
||||
label textarea:hover,
|
||||
label select:hover {
|
||||
@apply outline-none border-primary-400;
|
||||
}
|
||||
|
||||
label input:focus,
|
||||
label textarea:focus,
|
||||
label select:focus {
|
||||
@apply outline-none border-primary-600;
|
||||
}
|
||||
@ -26,14 +26,6 @@ section {
|
||||
@apply grid grid-cols-1 gap-8;
|
||||
}
|
||||
|
||||
label {
|
||||
@apply flex flex-col;
|
||||
}
|
||||
|
||||
label > span:first-child {
|
||||
@apply mb-1 text-primary-600 font-semibold tracking-wide text-xs uppercase;
|
||||
}
|
||||
|
||||
.MuiTooltip-tooltip {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
@ -22,16 +22,18 @@ const ContactC = () => {
|
||||
|
||||
return (
|
||||
<div className="text-xs grid gap-2">
|
||||
<div>
|
||||
<h6 className="capitalize font-semibold">Address</h6>
|
||||
<div className="flex flex-col text-xs">
|
||||
<span>{data.profile.address.line1}</span>
|
||||
<span>{data.profile.address.line2}</span>
|
||||
<span>
|
||||
{data.profile.address.city} {data.profile.address.pincode}
|
||||
</span>
|
||||
{data.profile.address.line1 && (
|
||||
<div>
|
||||
<h6 className="capitalize font-semibold">Address</h6>
|
||||
<div className="flex flex-col text-xs">
|
||||
<span>{data.profile.address.line1}</span>
|
||||
<span>{data.profile.address.line2}</span>
|
||||
<span>
|
||||
{data.profile.address.city} {data.profile.address.pincode}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ContactItem
|
||||
label="phone"
|
||||
|
||||
@ -40,16 +40,18 @@ const ContactD = () => {
|
||||
<MdFlare size="20px" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h6 className="capitalize font-semibold">Address</h6>
|
||||
<div className="flex flex-col text-xs">
|
||||
<span>{data.profile.address.line1}</span>
|
||||
<span>{data.profile.address.line2}</span>
|
||||
<span>
|
||||
{data.profile.address.city} {data.profile.address.pincode}
|
||||
</span>
|
||||
{data.profile.address.line1 && (
|
||||
<div>
|
||||
<h6 className="capitalize font-semibold">Address</h6>
|
||||
<div className="flex flex-col text-xs">
|
||||
<span>{data.profile.address.line1}</span>
|
||||
<span>{data.profile.address.line2}</span>
|
||||
<span>
|
||||
{data.profile.address.city} {data.profile.address.pincode}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ContactItem
|
||||
label="phone"
|
||||
|
||||
Reference in New Issue
Block a user