mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-19 11:12:00 +10:00
- complete onyx design template
- implement public sharable urls - implement more actions
This commit is contained in:
@ -1,19 +1,13 @@
|
||||
import firebase from 'gatsby-plugin-firebase';
|
||||
import { debounce } from 'lodash';
|
||||
import React, {
|
||||
createContext,
|
||||
memo,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import UserContext from './UserContext';
|
||||
import ShortUniqueId from 'short-unique-id';
|
||||
import React, { createContext, memo, useContext, useState } from 'react';
|
||||
import initialState from '../data/initialState';
|
||||
import UserContext from './UserContext';
|
||||
|
||||
const DEBOUNCE_WAIT_TIME = 4000;
|
||||
|
||||
const defaultState = {
|
||||
isOffline: false,
|
||||
isUpdating: false,
|
||||
createResume: () => {},
|
||||
deleteResume: () => {},
|
||||
@ -26,28 +20,26 @@ const defaultState = {
|
||||
const DatabaseContext = createContext(defaultState);
|
||||
|
||||
const DatabaseProvider = ({ children }) => {
|
||||
const [resumeId, setResumeId] = useState(false);
|
||||
const [isOffline, setOffline] = useState(false);
|
||||
const dictionary = 'abcdefghijklmnopqrstuvwxyz1234567890'.split('');
|
||||
const uuid = new ShortUniqueId({ dictionary });
|
||||
|
||||
const [isUpdating, setUpdating] = useState(false);
|
||||
const { user } = useContext(UserContext);
|
||||
|
||||
useEffect(() => {
|
||||
const connectedRef = firebase.database().ref('.info/connected');
|
||||
connectedRef.on('value', (snapshot) => {
|
||||
snapshot.val() === true ? setOffline(false) : setOffline(true);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const getResume = async (id) => {
|
||||
setResumeId(id);
|
||||
const snapshot = await firebase
|
||||
.database()
|
||||
.ref(`users/${user.uid}/resumes/${id}`)
|
||||
.once('value');
|
||||
return snapshot.val();
|
||||
try {
|
||||
const snapshot = await firebase
|
||||
.database()
|
||||
.ref(`resumes/${id}`)
|
||||
.once('value');
|
||||
return snapshot.val();
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const createResume = ({ id, name }) => {
|
||||
const createResume = ({ name }) => {
|
||||
const id = uuid();
|
||||
const createdAt = firebase.database.ServerValue.TIMESTAMP;
|
||||
|
||||
let firstName;
|
||||
@ -57,21 +49,21 @@ const DatabaseProvider = ({ children }) => {
|
||||
[firstName, lastName] = user.displayName.split(' ');
|
||||
}
|
||||
|
||||
firebase
|
||||
.database()
|
||||
.ref(`users/${user.uid}/resumes/${id}`)
|
||||
.set({
|
||||
...initialState,
|
||||
id,
|
||||
name,
|
||||
profile: {
|
||||
...initialState.profile,
|
||||
firstName: firstName || '',
|
||||
lastName: lastName || '',
|
||||
},
|
||||
createdAt,
|
||||
updatedAt: createdAt,
|
||||
});
|
||||
const resume = {
|
||||
...initialState,
|
||||
id,
|
||||
name,
|
||||
user: user.uid,
|
||||
profile: {
|
||||
...initialState.profile,
|
||||
firstName: firstName || '',
|
||||
lastName: lastName || '',
|
||||
},
|
||||
createdAt,
|
||||
updatedAt: createdAt,
|
||||
};
|
||||
|
||||
firebase.database().ref(`resumes/${id}`).set(resume);
|
||||
};
|
||||
|
||||
const updateResume = async (resume) => {
|
||||
@ -79,7 +71,7 @@ const DatabaseProvider = ({ children }) => {
|
||||
|
||||
await firebase
|
||||
.database()
|
||||
.ref(`users/${user.uid}/resumes/${resumeId}`)
|
||||
.ref(`resumes/${resume.id}`)
|
||||
.update({
|
||||
...resume,
|
||||
updatedAt: firebase.database.ServerValue.TIMESTAMP,
|
||||
@ -90,14 +82,18 @@ const DatabaseProvider = ({ children }) => {
|
||||
|
||||
const debouncedUpdateResume = debounce(updateResume, DEBOUNCE_WAIT_TIME);
|
||||
|
||||
const deleteResume = (id) => {
|
||||
firebase.database().ref(`users/${user.uid}/resumes/${id}`).remove();
|
||||
const deleteResume = async (id) => {
|
||||
await firebase
|
||||
.storage()
|
||||
.ref(`/users/${user.uid}/photographs/${id}`)
|
||||
.delete();
|
||||
|
||||
await firebase.database().ref(`/resumes/${id}`).remove();
|
||||
};
|
||||
|
||||
return (
|
||||
<DatabaseContext.Provider
|
||||
value={{
|
||||
isOffline,
|
||||
isUpdating,
|
||||
getResume,
|
||||
createResume,
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
flatten,
|
||||
concat,
|
||||
times,
|
||||
merge,
|
||||
} from 'lodash';
|
||||
import React, {
|
||||
createContext,
|
||||
@ -18,6 +19,7 @@ import React, {
|
||||
} from 'react';
|
||||
import DatabaseContext from './DatabaseContext';
|
||||
import initialState from '../data/initialState';
|
||||
import demoState from '../data/demoState.json';
|
||||
|
||||
const ResumeContext = createContext({});
|
||||
|
||||
@ -117,7 +119,20 @@ const ResumeProvider = ({ children }) => {
|
||||
return newState;
|
||||
|
||||
case 'set_data':
|
||||
return payload;
|
||||
newState = payload;
|
||||
debouncedUpdateResume(newState);
|
||||
return newState;
|
||||
|
||||
case 'reset_data':
|
||||
newState = merge(clone(state), initialState);
|
||||
debouncedUpdateResume(newState);
|
||||
return newState;
|
||||
|
||||
case 'load_demo_data':
|
||||
newState = merge(clone(state), demoState);
|
||||
newState.metadata.layout = demoState.metadata.layout;
|
||||
debouncedUpdateResume(newState);
|
||||
return newState;
|
||||
|
||||
default:
|
||||
throw new Error();
|
||||
|
||||
@ -20,6 +20,10 @@ const StorageProvider = ({ children }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const uploadPhotograph = async (file) => {
|
||||
if (!file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
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.",
|
||||
@ -27,6 +31,13 @@ const StorageProvider = ({ children }) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (file.size > 2097152) {
|
||||
toast.error(
|
||||
"Your image seems to be bigger than 2 MB. That's way too much. Maybe consider reducing it's size?",
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const uploadTask = firebase
|
||||
.storage()
|
||||
.ref(`/users/${user.uid}/photographs/${id}`)
|
||||
|
||||
@ -28,7 +28,7 @@ const COLOR_CONFIG = {
|
||||
};
|
||||
|
||||
const defaultState = {
|
||||
darkMode: false,
|
||||
darkMode: true,
|
||||
toggleDarkMode: () => {},
|
||||
};
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { navigate } from '@reach/router';
|
||||
import firebase from 'gatsby-plugin-firebase';
|
||||
import { pick } from 'lodash';
|
||||
import React, { createContext, memo, useEffect, useState } from 'react';
|
||||
@ -16,6 +17,7 @@ const defaultState = {
|
||||
user: defaultUser,
|
||||
logout: async () => {},
|
||||
loginWithGoogle: async () => {},
|
||||
deleteAccount: async () => {},
|
||||
};
|
||||
|
||||
const UserContext = createContext(defaultState);
|
||||
@ -49,16 +51,33 @@ const UserProvider = ({ children }) => {
|
||||
const provider = new firebase.auth.GoogleAuthProvider();
|
||||
|
||||
try {
|
||||
await firebase.auth().signInWithPopup(provider);
|
||||
return await firebase.auth().signInWithPopup(provider);
|
||||
} catch (error) {
|
||||
toast.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
const logout = async () => {
|
||||
await firebase.auth().signOut();
|
||||
const logout = () => {
|
||||
firebase.auth().signOut();
|
||||
localStorage.removeItem('user');
|
||||
setUser(null);
|
||||
navigate('/');
|
||||
};
|
||||
|
||||
const deleteAccount = async () => {
|
||||
const { currentUser } = firebase.auth();
|
||||
try {
|
||||
await currentUser.delete();
|
||||
} catch (e) {
|
||||
toast.error(e.message);
|
||||
await loginWithGoogle();
|
||||
await currentUser.delete();
|
||||
} finally {
|
||||
logout();
|
||||
toast(
|
||||
"It's sad to see you go, but we respect your privacy. All your data has been deleted successfully. Hope to see you again soon!",
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@ -68,6 +87,7 @@ const UserProvider = ({ children }) => {
|
||||
logout,
|
||||
loading,
|
||||
loginWithGoogle,
|
||||
deleteAccount,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user