Skip to content

Commit

Permalink
Refactor context in its own provider component
Browse files Browse the repository at this point in the history
  • Loading branch information
amadeuio committed Apr 5, 2024
1 parent 0075dce commit 5942dd7
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 78 deletions.
40 changes: 6 additions & 34 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,11 @@
import { useState, useEffect, createContext, Dispatch, SetStateAction } from "react";
import { HeaderObject, EducationObject, ExperienceObject } from "./data/types";
import {
initialHeaderObject,
initialEducationArray,
initialExperienceArray,
} from "./data/initialData";
import { useState, useEffect } from "react";

import FormSection from "./components/FormSection";
import CvSection from "./components/CvSection";
import ButtonToggleView from "./components/ButtonToggleView";

interface FormDataContext {
headerObject: HeaderObject;
setHeaderObject: Dispatch<SetStateAction<HeaderObject>>;
educationArray: EducationObject[];
setEducationArray: Dispatch<SetStateAction<EducationObject[]>>;
experienceArray: ExperienceObject[];
setExperienceArray: Dispatch<SetStateAction<ExperienceObject[]>>;
}

export const FormDataContext = createContext<FormDataContext | undefined>(undefined);
import { FormDataContextProvider } from "./Context";

function App() {
const [headerObject, setHeaderObject] = useState(initialHeaderObject);
const [educationArray, setEducationArray] = useState(initialEducationArray);
const [experienceArray, setExperienceArray] = useState(initialExperienceArray);

const [showForm, setShowForm] = useState(false);
const [isCollapsed, setIsCollapsed] = useState(window.innerWidth <= 1250);

Expand All @@ -52,20 +32,12 @@ function App() {
<h1>Make Your CV 📃</h1>
</div>

<div className="main-content-container">
<FormDataContext.Provider
value={{
headerObject,
setHeaderObject,
educationArray,
setEducationArray,
experienceArray,
setExperienceArray,
}}>
<FormDataContextProvider>
<div className="main-content-container">
{(!isCollapsed || showForm) && <FormSection />}
{(!isCollapsed || !showForm) && <CvSection />}
</FormDataContext.Provider>
</div>
</div>
</FormDataContextProvider>
</div>
);
}
Expand Down
43 changes: 43 additions & 0 deletions src/Context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useState, useContext, createContext, Dispatch, SetStateAction } from "react";
import { HeaderObject, EducationObject, ExperienceObject } from "./data/types";
import {
initialHeaderObject,
initialEducationArray,
initialExperienceArray,
} from "./data/initialData";

interface FormDataContext {
headerObject: HeaderObject;
setHeaderObject: Dispatch<SetStateAction<HeaderObject>>;
educationArray: EducationObject[];
setEducationArray: Dispatch<SetStateAction<EducationObject[]>>;
experienceArray: ExperienceObject[];
setExperienceArray: Dispatch<SetStateAction<ExperienceObject[]>>;
}

export const FormDataContext = createContext<FormDataContext | undefined>(undefined);

// eslint-disable-next-line react-refresh/only-export-components
export const useFormDataContext = () => {
return useContext(FormDataContext);
};

export const FormDataContextProvider = ({ children }) => {
const [headerObject, setHeaderObject] = useState(initialHeaderObject);
const [educationArray, setEducationArray] = useState(initialEducationArray);
const [experienceArray, setExperienceArray] = useState(initialExperienceArray);

return (
<FormDataContext.Provider
value={{
headerObject,
setHeaderObject,
educationArray,
setEducationArray,
experienceArray,
setExperienceArray,
}}>
{children}
</FormDataContext.Provider>
);
};
8 changes: 3 additions & 5 deletions src/components/CvSection.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { useContext, useRef } from "react";
import { FormDataContext } from "../App";

import { useRef } from "react";
import { useFormDataContext } from "../Context";
import html2canvas from "html2canvas";
import jsPDF from "jspdf";

import HeaderCv from "./HeaderCv";
import EducationCv from "./EducationCv";
import ExperienceCv from "./ExperienceCv";
Expand All @@ -26,7 +24,7 @@ function Cv({ divRef }: CvProps) {
}

function CvSection() {
const { headerObject } = useContext(FormDataContext)!;
const { headerObject } = useFormDataContext();
const [firstName, lastName] = headerObject.fullName.split(" ");

const divRef = useRef<HTMLDivElement>(null!);
Expand Down
6 changes: 2 additions & 4 deletions src/components/EducationCv.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { useContext } from "react";
import { FormDataContext } from "../App";
import { useFormDataContext } from "../Context";
import { EducationObject } from "../data/types";

import LocationIcon from "../icons/LocationIcon";

interface EducationItemProps {
Expand Down Expand Up @@ -31,7 +29,7 @@ function EducationItem({ educationObject }: EducationItemProps) {
}

function EducationCv() {
const { educationArray } = useContext(FormDataContext)!;
const { educationArray } = useFormDataContext();

if (educationArray.length === 0) {
return null;
Expand Down
17 changes: 6 additions & 11 deletions src/components/EducationForms.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { useContext, ChangeEvent, FormEvent } from "react";
import { FormDataContext } from "../App";
import { ChangeEvent, FormEvent } from "react";
import { useFormDataContext } from "../Context";
import { EducationObject } from "../data/types";

import { v4 as uuidv4 } from "uuid";
import { DragDropContext, Droppable, Draggable, DropResult } from "react-beautiful-dnd";

import Button from "./Button";
import ExpandLessIcon from "../icons/ExpandLessIcon";
import ExpandMoreIcon from "../icons/ExpandMoreIcon";

interface EducationFormProps {
educationObject: EducationObject;
setEducationArray: React.Dispatch<React.SetStateAction<EducationObject[]>>;
}

function EducationForm({ educationObject, setEducationArray }: EducationFormProps) {
function EducationForm({ educationObject }: EducationFormProps) {
const { id, school, qualification, startDate, endDate, location, isOpen } = educationObject;
const { setEducationArray } = useFormDataContext();

const toggleDropdown = () => {
setEducationArray((prevState) =>
Expand Down Expand Up @@ -126,7 +124,7 @@ function EducationForm({ educationObject, setEducationArray }: EducationFormProp
}

function EducationForms() {
const { educationArray, setEducationArray } = useContext(FormDataContext)!;
const { educationArray, setEducationArray } = useFormDataContext();

const handleAddNew = () => {
const newEducationEntry = {
Expand Down Expand Up @@ -173,10 +171,7 @@ function EducationForms() {
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}>
<EducationForm
educationObject={educationObject}
setEducationArray={setEducationArray}
/>
<EducationForm educationObject={educationObject} />
</div>
)}
</Draggable>
Expand Down
6 changes: 2 additions & 4 deletions src/components/ExperienceCv.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { useContext } from "react";
import { FormDataContext } from "../App";
import { useFormDataContext } from "../Context";
import { ExperienceObject } from "../data/types";

import LocationIcon from "../icons/LocationIcon";

interface ExperienceItemProps {
Expand Down Expand Up @@ -36,7 +34,7 @@ function ExperienceItem({ experienceObject }: ExperienceItemProps) {
}

function ExperienceCv() {
const { experienceArray } = useContext(FormDataContext)!;
const { experienceArray } = useFormDataContext();

if (experienceArray.length === 0) {
return null;
Expand Down
18 changes: 7 additions & 11 deletions src/components/ExperienceForms.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import { useContext, ChangeEvent, FormEvent } from "react";
import { FormDataContext } from "../App";
import { ChangeEvent, FormEvent } from "react";
import { useFormDataContext } from "../Context";
import { ExperienceObject } from "../data/types";

import { v4 as uuidv4 } from "uuid";
import { DragDropContext, Droppable, Draggable, DropResult } from "react-beautiful-dnd";

import Button from "./Button";
import ExpandLessIcon from "../icons/ExpandLessIcon";
import ExpandMoreIcon from "../icons/ExpandMoreIcon";

interface ExperienceFormProps {
experienceObject: ExperienceObject;
setExperienceArray: React.Dispatch<React.SetStateAction<ExperienceObject[]>>;
}

function ExperienceForm({ experienceObject, setExperienceArray }: ExperienceFormProps) {
function ExperienceForm({ experienceObject }: ExperienceFormProps) {
const { id, company, position, startDate, endDate, location, description, isOpen } =
experienceObject;

const { setExperienceArray } = useFormDataContext();

const toggleDropdown = () => {
setExperienceArray((prevState) =>
prevState.map((exp) => (exp.id === id ? { ...exp, isOpen: !exp.isOpen } : exp))
Expand Down Expand Up @@ -136,7 +135,7 @@ function ExperienceForm({ experienceObject, setExperienceArray }: ExperienceForm
}

function ExperienceForms() {
const { experienceArray, setExperienceArray } = useContext(FormDataContext)!;
const { experienceArray, setExperienceArray } = useFormDataContext();

const handleAddNew = () => {
const newEducationEntry = {
Expand Down Expand Up @@ -186,10 +185,7 @@ function ExperienceForms() {
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}>
<ExperienceForm
experienceObject={experienceObject}
setExperienceArray={setExperienceArray}
/>
<ExperienceForm experienceObject={experienceObject} />
</div>
)}
</Draggable>
Expand Down
6 changes: 2 additions & 4 deletions src/components/HeaderCv.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { useContext } from "react";
import { FormDataContext } from "../App";

import { useFormDataContext } from "../Context";
import MailIcon from "../icons/MailIcon";
import PhoneIcon from "../icons/PhoneIcon";
import LocationIcon from "../icons/LocationIcon";

function HeaderCv() {
const { headerObject } = useContext(FormDataContext)!;
const { headerObject } = useFormDataContext();
const { fullName, email, phone, address } = headerObject;

return (
Expand Down
7 changes: 3 additions & 4 deletions src/components/HeaderForm.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { useContext, ChangeEvent, FormEvent } from "react";
import { FormDataContext } from "../App";

import { ChangeEvent, FormEvent } from "react";
import { useFormDataContext } from "../Context";
import Button from "./Button";
import ExpandLessIcon from "../icons/ExpandLessIcon";
import ExpandMoreIcon from "../icons/ExpandMoreIcon";

function HeaderForm() {
const { headerObject, setHeaderObject } = useContext(FormDataContext)!;
const { headerObject, setHeaderObject } = useFormDataContext();
const { fullName, email, phone, address, isOpen } = headerObject;

const toggleDropdown = () => {
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"jsx": "react-jsx",

/* Linting */
"strict": true,
"strict": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
Expand Down

0 comments on commit 5942dd7

Please sign in to comment.