- implement lists

- implement generic sections
- implement list actions
- implement error handlers
This commit is contained in:
Amruth Pillai
2020-07-08 05:01:50 +05:30
parent d7e86ddf29
commit bee6a40e9f
38 changed files with 762 additions and 177 deletions

View File

@ -1,7 +1,6 @@
import firebase from "gatsby-plugin-firebase";
import { debounce } from "lodash";
import React, { createContext, useContext, useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import UserContext from "./UserContext";
const defaultState = {
@ -38,27 +37,22 @@ const DatabaseProvider = ({ children }) => {
};
const createResume = (resume) => {
const id = uuidv4();
const { id } = resume;
const createdAt = firebase.database.ServerValue.TIMESTAMP;
let firstName = "",
lastName = "",
photograph = "";
let firstName, lastName;
if (!user.isAnonymous) {
[firstName, lastName] = user.displayName.split(" ");
photograph = user.photoURL;
}
firebase
.database()
.ref(`users/${user.uid}/resumes/${id}`)
.set({
id,
profile: {
firstName,
lastName,
photograph,
firstName: firstName || "",
lastName: lastName || "",
},
...resume,
createdAt,

View File

@ -4,6 +4,7 @@ import React, { createContext } from "react";
const events = {
AUTH_MODAL: "auth_modal",
CREATE_RESUME_MODAL: "create_resume_modal",
SOCIAL_MODAL: "social_modal",
};
const emitter = createNanoEvents();

View File

@ -1,26 +1,88 @@
import { set } from "lodash";
import React, { createContext, useContext, useReducer } from "react";
import arrayMove from "array-move";
import { clone, findIndex, get, setWith } from "lodash";
import React, {
createContext,
useCallback,
useContext,
useReducer,
} from "react";
import DatabaseContext from "./DatabaseContext";
const ResumeContext = createContext({});
const initialState = {};
const ResumeContext = createContext(initialState);
const ResumeProvider = ({ children }) => {
const { debouncedUpdate } = useContext(DatabaseContext);
const [state, dispatch] = useReducer((state, { type, payload }) => {
let newState;
const memoizedReducer = useCallback(
(state, { type, payload }) => {
let newState, index, items;
switch (type) {
case "on_input":
newState = set({ ...state }, payload.path, payload.value);
debouncedUpdate(newState);
return newState;
case "set_data":
return payload;
default:
throw new Error();
}
}, {});
switch (type) {
case "on_add_item":
items = get(state, payload.path, []);
newState = setWith(
clone(state),
payload.path,
[...items, payload.value],
clone
);
debouncedUpdate(newState);
return newState;
case "on_edit_item":
items = get(state, payload.path);
index = findIndex(items, ["id", payload.value.id]);
newState = setWith(
clone(state),
`${payload.path}[${index}]`,
payload.value,
clone
);
debouncedUpdate(newState);
return newState;
case "on_delete_item":
items = get(state, payload.path);
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":
items = get(state, payload.path);
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":
items = get(state, payload.path);
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":
newState = setWith(clone(state), payload.path, payload.value, clone);
debouncedUpdate(newState);
return newState;
case "set_data":
return payload;
default:
throw new Error();
}
},
[debouncedUpdate]
);
const [state, dispatch] = useReducer(memoizedReducer, initialState);
return (
<ResumeContext.Provider value={{ state, dispatch }}>

View File

@ -0,0 +1,85 @@
import firebase from "gatsby-plugin-firebase";
import React, { createContext, useContext, useRef } from "react";
import { toast } from "react-toastify";
import { isFileImage } from "../utils";
import ResumeContext from "./ResumeContext";
import UserContext from "./UserContext";
const defaultState = {
uploadPhotograph: async () => {},
};
const StorageContext = createContext(defaultState);
const StorageProvider = ({ children }) => {
const toastId = useRef(null);
const { user } = useContext(UserContext);
const { state, dispatch } = useContext(ResumeContext);
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."
);
return null;
}
const uploadTask = firebase
.storage()
.ref(`/users/${user.uid}/photographs/${state.id}`)
.put(file);
let progress = 0;
toastId.current = toast("Firing up engines...", {
progress,
});
uploadTask.on(
"state_changed",
(snapshot) => {
progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
toast.update(toastId.current, {
render: "Uploading...",
progress,
hideProgressBar: false,
});
},
(error) => toast.error(error),
async () => {
const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
dispatch({
type: "on_input",
payload: {
path: "profile.photograph",
value: downloadURL,
},
});
toast.update(toastId.current, {
render:
"Your photograph was uploaded successfully... and you look great!",
progress,
autoClose: 5000,
hideProgressBar: true,
});
toastId.current = null;
}
);
};
return (
<StorageContext.Provider
value={{
uploadPhotograph,
}}
>
{children}
</StorageContext.Provider>
);
};
export default StorageContext;
export { StorageProvider };

View File

@ -6,13 +6,13 @@ import useAuthState from "../hooks/useAuthState";
const defaultUser = {
uid: null,
displayName: null,
email: null,
photoURL: null,
displayName: null,
isAnonymous: false,
};
const defaultState = {
loading: false,
user: defaultUser,
logout: async () => {},
loginWithGoogle: async () => {},
@ -32,8 +32,8 @@ const UserProvider = ({ children }) => {
useEffect(() => {
if (firebaseUser) {
const user = pick(firebaseUser, Object.keys(defaultUser));
setUser(user);
localStorage.setItem("user", JSON.stringify(user));
setUser(user);
const addUserToDatabase = async () => {
const userRef = firebase.database().ref(`users/${user.uid}`);