From e7433d803f43d7bb3f258152378e7cfa1f10a213 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Thu, 6 Aug 2020 10:51:49 -0700 Subject: [PATCH 01/43] =?UTF-8?q?=F0=9F=93=A6=20Bump=20Version=20-=20Bump?= =?UTF-8?q?=20version=20to=20v1.4.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index dfae6f6..8934f9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gh-jobs", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d46ed2c..eea6c82 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gh-jobs", - "version": "1.3.0", + "version": "1.4.0", "description": "A MERN application bootstrapped with create-mern-application.", "main": "build/index.js", "scripts": { From 174738fc3cb1d7c6d561bc1020bb9612e1653bb3 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Thu, 6 Aug 2020 10:59:19 -0700 Subject: [PATCH 02/43] =?UTF-8?q?=F0=9F=93=9D=20CHANGELOG=20-=20Add=20v1.4?= =?UTF-8?q?.0=20to=20CHANGELOG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95efdb8..3ed6f1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.4.0] - _Unreleased_ + +### Added + +### Changed + +### Removed + +### Fixed + ## [1.3.0] - 2020-08-06 ### 🙈 Hide Job From ef9f37bb2eb675320299a4da0e43b092e75b5527 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Thu, 6 Aug 2020 11:47:09 -0700 Subject: [PATCH 03/43] =?UTF-8?q?=E2=8C=9B=20LoadingIndicator=20Stops=20Be?= =?UTF-8?q?fore=20Jobs=20Response=20Received=20#68=20-=20Adjust=20thunk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/redux/thunks.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 091ce49..1721cea 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -66,6 +66,8 @@ import { export const getJobs = (): AppThunk => async (dispatch) => { try { + dispatch(setIsLoading(true)); + const result = (await fetchServerData("/jobs", "GET")) as | GetJobsErrorResponse | GetJobsSuccessResponse; @@ -240,7 +242,6 @@ export const checkAuthentication = (): AppThunk => async (dispatch) => { // eslint-disable-next-line no-console console.error(error); } - dispatch(setIsLoading(false)); }; export const logOut = (): AppThunk => async (dispatch) => { From d1066ee66a48503ccb4ce2e73fa37000df8ceb1b Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Thu, 6 Aug 2020 13:12:02 -0700 Subject: [PATCH 04/43] =?UTF-8?q?=E2=8C=9B=20LoadingIndicator=20Stops=20Be?= =?UTF-8?q?fore=20Jobs=20Response=20Received=20#68=20-=20Add=20test=20case?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/search.spec.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/cypress/integration/search.spec.js b/cypress/integration/search.spec.js index 4b63222..40b89ad 100644 --- a/cypress/integration/search.spec.js +++ b/cypress/integration/search.spec.js @@ -82,3 +82,31 @@ context("Search - No Results", () => { ); }); }); + +context("Search - Loading Indicator", () => { + beforeEach(() => { + cy.fixture("jobs50").then((jobsJson) => { + cy.server(); + cy.route({ + method: "GET", + url: "/jobs", + status: 200, + response: jobsJson, + delay: 3000, + }); + }); + }); + + it("Should display note when there are no results", () => { + cy.visit("http://localhost:3000"); + cy.get("#no-results").should("be.visible"); + cy.get("[data-cy=orbit-container] > :nth-child(3)").should("be.visible"); + + cy.wait(3100); + + cy.get("#no-results").should("not.be.visible"); + cy.get("[data-cy=orbit-container] > :nth-child(3)").should( + "not.be.visible" + ); + }); +}); From 062717ad8361e193edb92fe6adc57f2bbb52a3d2 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Thu, 6 Aug 2020 13:23:55 -0700 Subject: [PATCH 05/43] =?UTF-8?q?=F0=9F=92=AC=20User=20Not=20Found=20Messa?= =?UTF-8?q?ge=20#67=20-=20Modify=20'UserController'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/controllers/user.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/server/controllers/user.ts b/src/server/controllers/user.ts index 2e7ad88..e4e006d 100644 --- a/src/server/controllers/user.ts +++ b/src/server/controllers/user.ts @@ -131,6 +131,15 @@ class UserController { return res.status(400).send({ error: "Invalid email" }); } + const usersWithEmail = await User.findOne({ email: req.body.email }); + + if (!usersWithEmail) { + return res.status(401).send({ + error: + "We couldn't find a user with that email address. Please create an account, or provide another email address.", + }); + } + const user: UserDocument = await User.findByCredentials( req.body.email, req.body.password From 37ce54f69da2a323584af0af9d86f0794cbac64d Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Thu, 6 Aug 2020 13:25:52 -0700 Subject: [PATCH 06/43] =?UTF-8?q?=F0=9F=92=AC=20User=20Not=20Found=20Messa?= =?UTF-8?q?ge=20#67=20-=20Add=20test=20case?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/login.spec.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/cypress/integration/login.spec.js b/cypress/integration/login.spec.js index 177d248..fae6a31 100644 --- a/cypress/integration/login.spec.js +++ b/cypress/integration/login.spec.js @@ -61,11 +61,22 @@ context("Login - Error", () => { cy.get("h1").should("have.text", "Login"); }); - it("Should not allow to login with invalid credentials", () => { + it("Should not allow to login with invalid credentials for an existing account", () => { + cy.get("#email").type("bobtest@email.com"); + cy.get("#password").type("Blue123456!!!"); + cy.get("#log-in").click(); + cy.wait(500); + cy.get("#notification").should("have.text", "Invalid credentials."); + }); + + it("Should not allow to login with an account that does not exist", () => { cy.get("#email").type("fake@email.com"); cy.get("#password").type("Red123456!!!"); cy.get("#log-in").click(); cy.wait(500); - cy.get("#notification").should("have.text", "Invalid credentials."); + cy.get("#notification").should( + "have.text", + "We couldn't find a user with that email address. Please create an account, or provide another email address." + ); }); }); From 404ce3ac5f0fdf7731dd354205e233e646f94f32 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Thu, 6 Aug 2020 13:31:53 -0700 Subject: [PATCH 07/43] =?UTF-8?q?=E2=8C=9B=20LoadingIndicator=20Stops=20Be?= =?UTF-8?q?fore=20Jobs=20Response=20Received=20#68=20-=20Change=20test=20c?= =?UTF-8?q?ase=20title?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/integration/search.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/integration/search.spec.js b/cypress/integration/search.spec.js index 40b89ad..b6dbe17 100644 --- a/cypress/integration/search.spec.js +++ b/cypress/integration/search.spec.js @@ -97,7 +97,7 @@ context("Search - Loading Indicator", () => { }); }); - it("Should display note when there are no results", () => { + it("Should display LoadingIndicator correctly on jobs loading", () => { cy.visit("http://localhost:3000"); cy.get("#no-results").should("be.visible"); cy.get("[data-cy=orbit-container] > :nth-child(3)").should("be.visible"); From 0c993df8ec8b99da29b0833f2701140469b32570 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Thu, 6 Aug 2020 13:34:27 -0700 Subject: [PATCH 08/43] =?UTF-8?q?=F0=9F=8C=90=20Forward=20Heroku=20to=20Gi?= =?UTF-8?q?tHubJobs.io=20#46=20-=20Attempt=20another=20redirect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/app.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/server/app.ts b/src/server/app.ts index f07488e..d32f659 100644 --- a/src/server/app.ts +++ b/src/server/app.ts @@ -74,9 +74,15 @@ class App { this.app.use(express.static(path.join(__dirname, "../dist"))); this.app.get("*", (req: Request, res: Response) => { - console.log({ hostname: req.hostname }); - console.log({ referrer: req.headers.referer }); - // return res.status(301).redirect("https://www.githubjobs.io/"); + if (req.headers.host === "gh-jobs.herokuapp.com") { + return res.status(301).redirect("https://www.githubjobs.io/"); + } + console.log( + chalk.blueBright.inverse({ + host: req.headers.host, + referrer: req.headers.referer, + }) + ); res.sendFile(path.join(__dirname, "../dist/index.html")); }); } From d794eeaf522df772e76c11ef4bcf2b6d08aafa4f Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Thu, 6 Aug 2020 14:05:26 -0700 Subject: [PATCH 09/43] =?UTF-8?q?=E2=9C=85=20OptionsPanel=20Search=20#43?= =?UTF-8?q?=20-=20Create=20Button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/components/OptionsPanel/OptionsPanel.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/client/components/OptionsPanel/OptionsPanel.tsx b/src/client/components/OptionsPanel/OptionsPanel.tsx index 94fb9a9..f858d0c 100644 --- a/src/client/components/OptionsPanel/OptionsPanel.tsx +++ b/src/client/components/OptionsPanel/OptionsPanel.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import { connect } from "react-redux"; +import Button from "../Button"; import Checkbox from "../Checkbox"; import Input from "../Input"; @@ -64,6 +65,8 @@ const OptionsPanel: React.SFC = ( value={location.name} /> ))} + + + + {modalContent} + + + + ); +}; + +const mapStateToProps = (state: RootState) => ({ + isModalOpen: state.application.isModalOpen, + modalContent: state.application.modalContent, + modalTitle: state.application.modalTitle, +}); + +const mapDispatchToProps = (dispatch) => ({ + handleCloseModal: () => dispatch(resetModal()), +}); + +export default connect(mapStateToProps, mapDispatchToProps)(Modal); diff --git a/src/client/components/Modal/index.ts b/src/client/components/Modal/index.ts new file mode 100644 index 0000000..09b91f7 --- /dev/null +++ b/src/client/components/Modal/index.ts @@ -0,0 +1 @@ +export { default } from "./Modal"; diff --git a/src/client/components/Profile/ProfileAccountDetails.tsx b/src/client/components/Profile/ProfileAccountDetails.tsx index b13d1c6..bb18e7b 100644 --- a/src/client/components/Profile/ProfileAccountDetails.tsx +++ b/src/client/components/Profile/ProfileAccountDetails.tsx @@ -13,10 +13,16 @@ import { import { editProfile } from "../../redux/thunks"; import { RootState } from "../../types"; +import { + setModalContent, + setModalTitle, + setIsModalOpen, +} from "../../redux/actions/application"; export interface ProfileAccountDetailsProps { email: string; handleEditProfile: (email: string, name: string) => void; + handleSettingsClick: () => void; isEditingProfile: boolean; name: string; } @@ -24,7 +30,13 @@ export interface ProfileAccountDetailsProps { const ProfileAccountDetails: React.SFC = ( props: ProfileAccountDetailsProps ) => { - const { email, handleEditProfile, isEditingProfile, name } = props; + const { + email, + handleEditProfile, + handleSettingsClick, + isEditingProfile, + name, + } = props; const [newName, setNewName] = React.useState(name); const [newEmail, setNewEmail] = React.useState(email); @@ -37,6 +49,7 @@ const ProfileAccountDetails: React.SFC = ( buttonStyle="secondary" id="settings" label="settings" + onClick={() => handleSettingsClick()} type="button" /> @@ -96,6 +109,11 @@ const mapStateToProps = (state: RootState) => ({ const mapDispatchToProps = (dispatch) => ({ handleEditProfile: (email: string, name: string) => dispatch(editProfile(email, name)), + handleSettingsClick: () => { + dispatch(setModalContent("SETTINGS CONTENT")); + dispatch(setModalTitle("Settings")); + dispatch(setIsModalOpen(true)); + }, }); export default connect( diff --git a/src/client/redux/actionTypes.ts b/src/client/redux/actionTypes.ts index b6f17cb..1288c6c 100644 --- a/src/client/redux/actionTypes.ts +++ b/src/client/redux/actionTypes.ts @@ -5,9 +5,12 @@ export const SET_CURRENT_PAGE = "SET_CURRENT_PAGE"; export const SET_ERROR = "SET_ERROR"; export const SET_FULL_TIME = "SET_FULL_TIME"; export const SET_IS_LOADING = "SET_IS_LOADING"; +export const SET_IS_MODAL_OPEN = "SET_IS_MODAL_OPEN"; export const SET_JOB_DETAILS = "SET_JOB_DETAILS"; export const SET_JOBS = "SET_JOBS"; export const SET_LOCATION_SEARCH = "SET_LOCATION_SEARCH"; +export const SET_MODAL_CONTENT = "SET_MODAL_CONTENT"; +export const SET_MODAL_TITLE = "SET_MODAL_TITLE"; export const SET_SEARCH_VALUE = "SET_SEARCH_VALUE"; export const SET_TOTAL_PAGES = "SET_TOTAL_PAGES"; diff --git a/src/client/redux/actions/application.ts b/src/client/redux/actions/application.ts index adff082..9bcf2fe 100644 --- a/src/client/redux/actions/application.ts +++ b/src/client/redux/actions/application.ts @@ -5,9 +5,12 @@ import { SET_ERROR, SET_FULL_TIME, SET_IS_LOADING, + SET_IS_MODAL_OPEN, SET_JOB_DETAILS, SET_JOBS, SET_LOCATION_SEARCH, + SET_MODAL_CONTENT, + SET_MODAL_TITLE, SET_SEARCH_VALUE, SET_TOTAL_PAGES, } from "../actionTypes"; @@ -50,6 +53,11 @@ export const setIsLoading = (isLoading: boolean): ApplicationAction => ({ payload: { isLoading }, }); +export const setIsModalOpen = (isModalOpen: boolean): ApplicationAction => ({ + type: SET_IS_MODAL_OPEN, + payload: { isModalOpen }, +}); + export const setJobDetails = (jobDetails: Job): ApplicationAction => ({ type: SET_JOB_DETAILS, payload: { jobDetails }, @@ -67,6 +75,16 @@ export const setLocationSearch = ( payload: { locationSearch }, }); +export const setModalContent = (modalContent: any): ApplicationAction => ({ + type: SET_MODAL_CONTENT, + payload: { modalContent }, +}); + +export const setModalTitle = (modalTitle: string): ApplicationAction => ({ + type: SET_MODAL_TITLE, + payload: { modalTitle }, +}); + export const setSearchValue = (searchValue: string): ApplicationAction => ({ type: SET_SEARCH_VALUE, payload: { searchValue }, diff --git a/src/client/redux/reducers/application.ts b/src/client/redux/reducers/application.ts index 7f29d94..b5ad282 100644 --- a/src/client/redux/reducers/application.ts +++ b/src/client/redux/reducers/application.ts @@ -7,9 +7,12 @@ import { SET_ERROR, SET_FULL_TIME, SET_IS_LOADING, + SET_IS_MODAL_OPEN, SET_JOB_DETAILS, SET_JOBS, SET_LOCATION_SEARCH, + SET_MODAL_CONTENT, + SET_MODAL_TITLE, SET_SEARCH_VALUE, SET_TOTAL_PAGES, } from "../actionTypes"; @@ -22,9 +25,12 @@ export const initialState: ApplicationState = { error: null, fullTime: false, isLoading: true, + isModalOpen: false, jobDetails: null, jobs: [], locationSearch: "", + modalContent: null, + modalTitle: "", notificationMessage: "", notificationType: "default", searchValue: "", @@ -89,9 +95,12 @@ const reducer = ( case SET_CURRENT_PAGE: case SET_FULL_TIME: case SET_IS_LOADING: + case SET_IS_MODAL_OPEN: case SET_JOB_DETAILS: case SET_JOBS: case SET_LOCATION_SEARCH: + case SET_MODAL_CONTENT: + case SET_MODAL_TITLE: case SET_SEARCH_VALUE: case SET_TOTAL_PAGES: { return { ...state, [key]: value }; diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index b5caac4..6bb3fb0 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -8,6 +8,9 @@ import { setTotalPages, setJobDetails, setError, + setModalContent, + setModalTitle, + setIsModalOpen, } from "./actions/application"; import { setConfirmPassword, @@ -662,3 +665,9 @@ export const getHiddenJobsDetails = (): AppThunk => async (dispatch) => { dispatch(setIsLoading(false)); } }; + +export const resetModal = (): AppThunk => (dispatch) => { + dispatch(setIsModalOpen(false)); + dispatch(setModalContent(null)); + dispatch(setModalTitle("")); +}; diff --git a/src/client/types.ts b/src/client/types.ts index f2e4224..4b46a0e 100644 --- a/src/client/types.ts +++ b/src/client/types.ts @@ -48,9 +48,12 @@ export interface ApplicationState { error: ApplicationError; fullTime: boolean; isLoading: boolean; + isModalOpen: boolean; jobDetails: Job; jobs: Job[]; locationSearch: string; + modalContent: any; + modalTitle: string; notificationMessage: string; notificationType: NotificationType; searchValue: string; From 120aa90cab3d5b162752a78b3c64ec03de213b5d Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Tue, 11 Aug 2020 07:56:01 -0700 Subject: [PATCH 21/43] =?UTF-8?q?=F0=9F=8E=A8=20Redesign=20Profile=20Displ?= =?UTF-8?q?ay=20#47=20-=20Add=20Modal=20Content?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/components/Modal/Modal.tsx | 9 +++++--- src/client/components/Modal/contents.ts | 7 ++++++ .../Profile/ProfileAccountDetails.tsx | 4 +++- .../modals/Settings/Settings-styled.tsx | 3 +++ src/client/modals/Settings/Settings.tsx | 23 +++++++++++++++++++ src/client/modals/Settings/index.ts | 1 + src/client/redux/actions/application.ts | 2 +- src/client/redux/reducers/application.ts | 2 +- src/client/redux/thunks.ts | 3 +++ src/client/types.ts | 2 +- 10 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 src/client/components/Modal/contents.ts create mode 100644 src/client/modals/Settings/Settings-styled.tsx create mode 100644 src/client/modals/Settings/Settings.tsx create mode 100644 src/client/modals/Settings/index.ts diff --git a/src/client/components/Modal/Modal.tsx b/src/client/components/Modal/Modal.tsx index fc1c189..43af45b 100644 --- a/src/client/components/Modal/Modal.tsx +++ b/src/client/components/Modal/Modal.tsx @@ -8,6 +8,8 @@ import { Shade, } from "./Modal-styled"; +import contents from "./contents"; + import { resetModal } from "../../redux/thunks"; import { RootState } from "../../types"; @@ -15,14 +17,15 @@ import { RootState } from "../../types"; export interface ModalProps { handleCloseModal: () => void; isModalOpen: boolean; - modalContent: any; + modalContent: string; modalTitle: string; } const Modal: React.SFC = (props: ModalProps) => { const { handleCloseModal, isModalOpen, modalContent, modalTitle } = props; - console.log(typeof modalContent); + const Content = contents[modalContent]; + return ( <> @@ -34,7 +37,7 @@ const Modal: React.SFC = (props: ModalProps) => { x - {modalContent} + {Content && } diff --git a/src/client/components/Modal/contents.ts b/src/client/components/Modal/contents.ts new file mode 100644 index 0000000..fc94f67 --- /dev/null +++ b/src/client/components/Modal/contents.ts @@ -0,0 +1,7 @@ +import Settings from "../../modals/Settings"; + +const contents = { + settings: Settings, +}; + +export default contents; diff --git a/src/client/components/Profile/ProfileAccountDetails.tsx b/src/client/components/Profile/ProfileAccountDetails.tsx index bb18e7b..f5a5b4c 100644 --- a/src/client/components/Profile/ProfileAccountDetails.tsx +++ b/src/client/components/Profile/ProfileAccountDetails.tsx @@ -10,6 +10,8 @@ import { ProfileAccountDetailsContainer, } from "./Profile-styled"; +import Settings from "../../modals/Settings/Settings"; + import { editProfile } from "../../redux/thunks"; import { RootState } from "../../types"; @@ -110,7 +112,7 @@ const mapDispatchToProps = (dispatch) => ({ handleEditProfile: (email: string, name: string) => dispatch(editProfile(email, name)), handleSettingsClick: () => { - dispatch(setModalContent("SETTINGS CONTENT")); + dispatch(setModalContent("settings")); dispatch(setModalTitle("Settings")); dispatch(setIsModalOpen(true)); }, diff --git a/src/client/modals/Settings/Settings-styled.tsx b/src/client/modals/Settings/Settings-styled.tsx new file mode 100644 index 0000000..09e6701 --- /dev/null +++ b/src/client/modals/Settings/Settings-styled.tsx @@ -0,0 +1,3 @@ +import styled from "styled-components"; + +export {}; diff --git a/src/client/modals/Settings/Settings.tsx b/src/client/modals/Settings/Settings.tsx new file mode 100644 index 0000000..9b1b134 --- /dev/null +++ b/src/client/modals/Settings/Settings.tsx @@ -0,0 +1,23 @@ +import * as React from "react"; +import { connect } from "react-redux"; +import { RootState } from "../../types"; + +export interface SettingsProps { + email: string; +} + +const Settings: React.SFC = (props: SettingsProps) => { + const { email } = props; + + return ( +
+ {email} +
+ ); +}; + +const mapStateToProps = (state: RootState) => ({ + email: state.user.email, +}); + +export default connect(mapStateToProps)(Settings); diff --git a/src/client/modals/Settings/index.ts b/src/client/modals/Settings/index.ts new file mode 100644 index 0000000..41d6622 --- /dev/null +++ b/src/client/modals/Settings/index.ts @@ -0,0 +1 @@ +export { default } from "./Settings"; diff --git a/src/client/redux/actions/application.ts b/src/client/redux/actions/application.ts index 9bcf2fe..54eb47f 100644 --- a/src/client/redux/actions/application.ts +++ b/src/client/redux/actions/application.ts @@ -75,7 +75,7 @@ export const setLocationSearch = ( payload: { locationSearch }, }); -export const setModalContent = (modalContent: any): ApplicationAction => ({ +export const setModalContent = (modalContent: string): ApplicationAction => ({ type: SET_MODAL_CONTENT, payload: { modalContent }, }); diff --git a/src/client/redux/reducers/application.ts b/src/client/redux/reducers/application.ts index b5ad282..fe966d7 100644 --- a/src/client/redux/reducers/application.ts +++ b/src/client/redux/reducers/application.ts @@ -29,7 +29,7 @@ export const initialState: ApplicationState = { jobDetails: null, jobs: [], locationSearch: "", - modalContent: null, + modalContent: "", modalTitle: "", notificationMessage: "", notificationType: "default", diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 6bb3fb0..0867b14 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -220,6 +220,9 @@ export const initializeApplication = (): AppThunk => async (dispatch) => { dispatch(setJobDetails(null)); dispatch(setJobs([])); dispatch(setTotalPages(1)); + dispatch(setIsModalOpen(false)); + dispatch(setModalContent("")); + dispatch(setModalTitle("")); // * Establish Job Data dispatch(getJobs()); diff --git a/src/client/types.ts b/src/client/types.ts index 4b46a0e..2c00493 100644 --- a/src/client/types.ts +++ b/src/client/types.ts @@ -52,7 +52,7 @@ export interface ApplicationState { jobDetails: Job; jobs: Job[]; locationSearch: string; - modalContent: any; + modalContent: string; modalTitle: string; notificationMessage: string; notificationType: NotificationType; From a9d64112d08f373d6d278fc6cae2b8a32bac6221 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Tue, 11 Aug 2020 09:52:06 -0700 Subject: [PATCH 22/43] =?UTF-8?q?=F0=9F=8E=A8=20Redesign=20Profile=20Displ?= =?UTF-8?q?ay=20#47=20-=20Ability=20to=20Log=20Out?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/modals/Settings/Settings.tsx | 23 ++++++++++++++++------- src/client/redux/thunks.ts | 3 +++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/client/modals/Settings/Settings.tsx b/src/client/modals/Settings/Settings.tsx index 9b1b134..2ad0896 100644 --- a/src/client/modals/Settings/Settings.tsx +++ b/src/client/modals/Settings/Settings.tsx @@ -1,23 +1,32 @@ import * as React from "react"; import { connect } from "react-redux"; -import { RootState } from "../../types"; + +import Button from "../../components/Button"; + +import { logOut } from "../../redux/thunks"; export interface SettingsProps { - email: string; + handleLogOut: () => void; } const Settings: React.SFC = (props: SettingsProps) => { - const { email } = props; + const { handleLogOut } = props; return (
- {email} +
); }; -const mapStateToProps = (state: RootState) => ({ - email: state.user.email, +const mapDispatchToProps = (dispatch) => ({ + handleLogOut: () => dispatch(logOut()), }); -export default connect(mapStateToProps)(Settings); +export default connect(null, mapDispatchToProps)(Settings); diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 0867b14..845f11d 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -272,6 +272,9 @@ export const logOut = (): AppThunk => async (dispatch) => { dispatch(setSavedJobs([])); dispatch(setHiddenJobs([])); dispatch(setIsLoggedIn(false)); + dispatch(setIsModalOpen(false)); + dispatch(setModalContent("")); + dispatch(setModalTitle("")); dispatch(setIsLoading(false)); }; From 18251fd36d4996e119a305033d273dd2da08c65b Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Tue, 11 Aug 2020 12:40:28 -0700 Subject: [PATCH 23/43] =?UTF-8?q?=F0=9F=8E=A8=20Redesign=20Profile=20Displ?= =?UTF-8?q?ay=20#47=20-=20Ability=20to=20Log=20Out=20All?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/modals/Settings/Settings.tsx | 13 +++++++++++-- src/client/redux/thunks.ts | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/client/modals/Settings/Settings.tsx b/src/client/modals/Settings/Settings.tsx index 2ad0896..35fb6d3 100644 --- a/src/client/modals/Settings/Settings.tsx +++ b/src/client/modals/Settings/Settings.tsx @@ -3,14 +3,15 @@ import { connect } from "react-redux"; import Button from "../../components/Button"; -import { logOut } from "../../redux/thunks"; +import { logOut, logOutAll } from "../../redux/thunks"; export interface SettingsProps { handleLogOut: () => void; + handleLogOutAll: () => void; } const Settings: React.SFC = (props: SettingsProps) => { - const { handleLogOut } = props; + const { handleLogOut, handleLogOutAll } = props; return (
@@ -21,12 +22,20 @@ const Settings: React.SFC = (props: SettingsProps) => { onClick={() => handleLogOut()} type="button" /> +
); }; const mapDispatchToProps = (dispatch) => ({ handleLogOut: () => dispatch(logOut()), + handleLogOutAll: () => dispatch(logOutAll()), }); export default connect(null, mapDispatchToProps)(Settings); diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 845f11d..47b2351 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -303,6 +303,9 @@ export const logOutAll = (): AppThunk => async (dispatch) => { dispatch(setSavedJobs([])); dispatch(setHiddenJobs([])); dispatch(setIsLoggedIn(false)); + dispatch(setIsModalOpen(false)); + dispatch(setModalContent("")); + dispatch(setModalTitle("")); dispatch(setIsLoading(false)); }; From 0197b3b006604b80fd1c235f7dc4945ec324f990 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Tue, 11 Aug 2020 13:11:23 -0700 Subject: [PATCH 24/43] =?UTF-8?q?=F0=9F=8E=A8=20Redesign=20Profile=20Displ?= =?UTF-8?q?ay=20#47=20-=20Ability=20to=20Delete=20Profile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/components/Modal/contents.ts | 2 + .../DeleteProfile/DeleteProfile-styled.tsx | 0 .../modals/DeleteProfile/DeleteProfile.tsx | 52 +++++++++++++++++++ src/client/modals/DeleteProfile/index.ts | 1 + src/client/modals/Settings/Settings.tsx | 25 ++++++++- src/client/redux/thunks.ts | 5 +- 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 src/client/modals/DeleteProfile/DeleteProfile-styled.tsx create mode 100644 src/client/modals/DeleteProfile/DeleteProfile.tsx create mode 100644 src/client/modals/DeleteProfile/index.ts diff --git a/src/client/components/Modal/contents.ts b/src/client/components/Modal/contents.ts index fc94f67..8c50a95 100644 --- a/src/client/components/Modal/contents.ts +++ b/src/client/components/Modal/contents.ts @@ -1,6 +1,8 @@ +import DeleteProfile from "../../modals/DeleteProfile/DeleteProfile"; import Settings from "../../modals/Settings"; const contents = { + deleteProfile: DeleteProfile, settings: Settings, }; diff --git a/src/client/modals/DeleteProfile/DeleteProfile-styled.tsx b/src/client/modals/DeleteProfile/DeleteProfile-styled.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/client/modals/DeleteProfile/DeleteProfile.tsx b/src/client/modals/DeleteProfile/DeleteProfile.tsx new file mode 100644 index 0000000..1341719 --- /dev/null +++ b/src/client/modals/DeleteProfile/DeleteProfile.tsx @@ -0,0 +1,52 @@ +import * as React from "react"; +import { connect } from "react-redux"; + +import Button from "../../components/Button"; + +import { + displayNotification, + setModalContent, + setModalTitle, +} from "../../redux/actions/application"; +import { deleteProfile } from "../../redux/thunks"; + +export interface DeleteProfileProps { + handleCancelDeleteProfile: () => void; + handleDeleteProfile: () => void; +} + +const DeleteProfile: React.SFC = ( + props: DeleteProfileProps +) => { + const { handleCancelDeleteProfile, handleDeleteProfile } = props; + + return ( +
+
+ ); +}; + +const mapDispatchToProps = (dispatch) => ({ + handleCancelDeleteProfile: () => { + dispatch(displayNotification("", "default")); + dispatch(setModalContent("settings")); + dispatch(setModalTitle("Settings")); + }, + handleDeleteProfile: () => dispatch(deleteProfile()), +}); + +export default connect(null, mapDispatchToProps)(DeleteProfile); diff --git a/src/client/modals/DeleteProfile/index.ts b/src/client/modals/DeleteProfile/index.ts new file mode 100644 index 0000000..6783475 --- /dev/null +++ b/src/client/modals/DeleteProfile/index.ts @@ -0,0 +1 @@ +export { default } from "./DeleteProfile"; diff --git a/src/client/modals/Settings/Settings.tsx b/src/client/modals/Settings/Settings.tsx index 35fb6d3..38152b8 100644 --- a/src/client/modals/Settings/Settings.tsx +++ b/src/client/modals/Settings/Settings.tsx @@ -3,15 +3,21 @@ import { connect } from "react-redux"; import Button from "../../components/Button"; +import { + displayNotification, + setModalContent, + setModalTitle, +} from "../../redux/actions/application"; import { logOut, logOutAll } from "../../redux/thunks"; export interface SettingsProps { + handleClickDeleteProfile: () => void; handleLogOut: () => void; handleLogOutAll: () => void; } const Settings: React.SFC = (props: SettingsProps) => { - const { handleLogOut, handleLogOutAll } = props; + const { handleClickDeleteProfile, handleLogOut, handleLogOutAll } = props; return (
@@ -29,11 +35,28 @@ const Settings: React.SFC = (props: SettingsProps) => { onClick={() => handleLogOutAll()} type="button" /> +
); }; const mapDispatchToProps = (dispatch) => ({ + handleClickDeleteProfile: () => { + dispatch( + displayNotification( + "Are you sure you would like to delete your profile? This can not be reversed.", + "warning" + ) + ); + dispatch(setModalContent("deleteProfile")); + dispatch(setModalTitle("Delete Profile")); + }, handleLogOut: () => dispatch(logOut()), handleLogOutAll: () => dispatch(logOutAll()), }); diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index 47b2351..f690d75 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -452,6 +452,9 @@ export const deleteProfile = (): AppThunk => async (dispatch) => { dispatch(setIsDeletingProfile(false)); dispatch(setIsLoggedIn(false)); dispatch(setIsLoading(false)); + dispatch(setIsModalOpen(false)); + dispatch(setModalContent("")); + dispatch(setModalTitle("")); } catch (error) { console.error(error); dispatch(displayNotification(error, "error")); @@ -677,6 +680,6 @@ export const getHiddenJobsDetails = (): AppThunk => async (dispatch) => { export const resetModal = (): AppThunk => (dispatch) => { dispatch(setIsModalOpen(false)); - dispatch(setModalContent(null)); + dispatch(setModalContent("")); dispatch(setModalTitle("")); }; From e19d54f30e77f5f7c90424f0a23a90d797efe6e6 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Tue, 11 Aug 2020 13:39:21 -0700 Subject: [PATCH 25/43] =?UTF-8?q?=F0=9F=8E=A8=20Redesign=20Profile=20Displ?= =?UTF-8?q?ay=20#47=20-=20Ability=20to=20Reset=20Password?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/components/Modal/contents.ts | 2 + .../components/Profile/ProfileReset.tsx | 2 +- .../ResetPassword/ResetPassword-styled.tsx | 0 .../modals/ResetPassword/ResetPassword.tsx | 117 ++++++++++++++++++ src/client/modals/ResetPassword/index.ts | 1 + src/client/modals/Settings/Settings.tsx | 19 ++- src/client/redux/thunks.ts | 28 ++--- 7 files changed, 151 insertions(+), 18 deletions(-) create mode 100644 src/client/modals/ResetPassword/ResetPassword-styled.tsx create mode 100644 src/client/modals/ResetPassword/ResetPassword.tsx create mode 100644 src/client/modals/ResetPassword/index.ts diff --git a/src/client/components/Modal/contents.ts b/src/client/components/Modal/contents.ts index 8c50a95..85b68a6 100644 --- a/src/client/components/Modal/contents.ts +++ b/src/client/components/Modal/contents.ts @@ -1,8 +1,10 @@ import DeleteProfile from "../../modals/DeleteProfile/DeleteProfile"; +import ResetPassword from "../../modals/ResetPassword"; import Settings from "../../modals/Settings"; const contents = { deleteProfile: DeleteProfile, + resetPassword: ResetPassword, settings: Settings, }; diff --git a/src/client/components/Profile/ProfileReset.tsx b/src/client/components/Profile/ProfileReset.tsx index 6ab447f..cbbc569 100644 --- a/src/client/components/Profile/ProfileReset.tsx +++ b/src/client/components/Profile/ProfileReset.tsx @@ -107,7 +107,7 @@ const mapStateToProps = (state: RootState) => ({ const mapDispatchToProps = (dispatch) => ({ handleCancelResetPassword: () => dispatch(cancelResetPassword()), - handleResetPassword: () => dispatch(resetPassword()), + handleResetPassword: () => dispatch(resetPassword("", "")), handleSetResetConfirmNewPassword: (resetConfirmNewPassword: string) => dispatch(setResetConfirmNewPassword(resetConfirmNewPassword)), handleSetResetCurrentPassword: (resetCurrentPassword: string) => diff --git a/src/client/modals/ResetPassword/ResetPassword-styled.tsx b/src/client/modals/ResetPassword/ResetPassword-styled.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/client/modals/ResetPassword/ResetPassword.tsx b/src/client/modals/ResetPassword/ResetPassword.tsx new file mode 100644 index 0000000..b794d24 --- /dev/null +++ b/src/client/modals/ResetPassword/ResetPassword.tsx @@ -0,0 +1,117 @@ +import * as React from "react"; +import { connect } from "react-redux"; + +import Button from "../../components/Button"; +import Input from "../../components/Input"; + +import { + displayNotification, + setModalContent, + setModalTitle, +} from "../../redux/actions/application"; +import { resetPassword } from "../../redux/thunks"; + +export interface ResetPasswordProps { + handleCancelResetPassword: () => void; + handleResetPassword: ( + currentPassword: string, + newPassword: string, + confirmNewPassword: string + ) => void; +} + +const ResetPassword: React.SFC = ( + props: ResetPasswordProps +) => { + const [resetCurrentPassword, setResetCurrentPassword] = React.useState(""); + const [resetNewPassword, setResetNewPassword] = React.useState(""); + const [resetConfirmNewPassword, setResetConfirmNewPassword] = React.useState( + "" + ); + + const { handleCancelResetPassword, handleResetPassword } = props; + + return ( +
+ setResetCurrentPassword(e.target.value)} + type="password" + value={resetCurrentPassword} + /> + + setResetNewPassword(e.target.value)} + type="password" + value={resetNewPassword} + /> + + setResetConfirmNewPassword(e.target.value)} + type="password" + value={resetConfirmNewPassword} + /> + +
+ ); +}; + +const mapDispatchToProps = (dispatch) => ({ + handleCancelResetPassword: () => { + dispatch(displayNotification("", "default")); + dispatch(setModalContent("settings")); + dispatch(setModalTitle("Settings")); + }, + handleResetPassword: ( + currentPassword: string, + newPassword: string, + confirmNewPassword: string + ) => { + if (newPassword !== confirmNewPassword) { + dispatch(displayNotification("Passwords do not match.", "error")); + return; + } + dispatch(resetPassword(currentPassword, newPassword)); + }, +}); + +export default connect(null, mapDispatchToProps)(ResetPassword); diff --git a/src/client/modals/ResetPassword/index.ts b/src/client/modals/ResetPassword/index.ts new file mode 100644 index 0000000..e600549 --- /dev/null +++ b/src/client/modals/ResetPassword/index.ts @@ -0,0 +1 @@ +export { default } from "./ResetPassword"; diff --git a/src/client/modals/Settings/Settings.tsx b/src/client/modals/Settings/Settings.tsx index 38152b8..49f034a 100644 --- a/src/client/modals/Settings/Settings.tsx +++ b/src/client/modals/Settings/Settings.tsx @@ -12,12 +12,18 @@ import { logOut, logOutAll } from "../../redux/thunks"; export interface SettingsProps { handleClickDeleteProfile: () => void; + handleClickResetPassword: () => void; handleLogOut: () => void; handleLogOutAll: () => void; } const Settings: React.SFC = (props: SettingsProps) => { - const { handleClickDeleteProfile, handleLogOut, handleLogOutAll } = props; + const { + handleClickDeleteProfile, + handleClickResetPassword, + handleLogOut, + handleLogOutAll, + } = props; return (
@@ -42,6 +48,13 @@ const Settings: React.SFC = (props: SettingsProps) => { onClick={() => handleClickDeleteProfile()} type="button" /> +
); }; @@ -57,6 +70,10 @@ const mapDispatchToProps = (dispatch) => ({ dispatch(setModalContent("deleteProfile")); dispatch(setModalTitle("Delete Profile")); }, + handleClickResetPassword: () => { + dispatch(setModalContent("resetPassword")); + dispatch(setModalTitle("Reset Password")); + }, handleLogOut: () => dispatch(logOut()), handleLogOutAll: () => dispatch(logOutAll()), }); diff --git a/src/client/redux/thunks.ts b/src/client/redux/thunks.ts index f690d75..a702c03 100644 --- a/src/client/redux/thunks.ts +++ b/src/client/redux/thunks.ts @@ -310,22 +310,12 @@ export const logOutAll = (): AppThunk => async (dispatch) => { dispatch(setIsLoading(false)); }; -export const resetPassword = (): AppThunk => async (dispatch, getState) => { +export const resetPassword = ( + currentPassword: string, + newPassword: string +): AppThunk => async (dispatch) => { dispatch(setIsLoading(true)); dispatch(displayNotification("", "default")); - const state: RootState = getState(); - - const { - resetConfirmNewPassword, - resetCurrentPassword, - resetNewPassword, - } = state.user; - - if (resetConfirmNewPassword !== resetNewPassword) { - dispatch(displayNotification("Passwords do not match.", "error")); - dispatch(setIsLoading(false)); - return; - } try { // TODO - Modify @@ -333,8 +323,8 @@ export const resetPassword = (): AppThunk => async (dispatch, getState) => { "/user/me", "PATCH", JSON.stringify({ - currentPassword: resetCurrentPassword, - newPassword: resetNewPassword, + currentPassword, + newPassword, }) ); @@ -349,6 +339,9 @@ export const resetPassword = (): AppThunk => async (dispatch, getState) => { dispatch(setResetCurrentPassword("")); dispatch(setResetNewPassword("")); dispatch(setIsResettingPassword(false)); + dispatch(setIsModalOpen(false)); + dispatch(setModalContent("")); + dispatch(setModalTitle("")); dispatch(setIsLoading(false)); } catch (error) { console.error(error); @@ -357,6 +350,7 @@ export const resetPassword = (): AppThunk => async (dispatch, getState) => { } }; +// TODO - Remove export const cancelResetPassword = (): AppThunk => (dispatch) => { dispatch(setResetConfirmNewPassword("")); dispatch(setResetCurrentPassword("")); @@ -365,11 +359,13 @@ export const cancelResetPassword = (): AppThunk => (dispatch) => { dispatch(setIsResettingPassword(false)); }; +// TODO - Remove export const clickEditProfile = (): AppThunk => (dispatch) => { dispatch(displayNotification("", "default")); dispatch(setIsEditingProfile(true)); }; +// TODO - Remove export const cancelEditProfile = (): AppThunk => (dispatch) => { dispatch(displayNotification("", "default")); dispatch(setIsEditingProfile(false)); From ff26e716bac41b4d8f7f08ab31c9ac3d1eb75319 Mon Sep 17 00:00:00 2001 From: alexlee-dev Date: Tue, 11 Aug 2020 13:59:31 -0700 Subject: [PATCH 26/43] =?UTF-8?q?=F0=9F=8E=A8=20Redesign=20Profile=20Displ?= =?UTF-8?q?ay=20#47=20-=20Style=20Modal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/components/Modal/Modal-styled.tsx | 2 +- .../modals/Settings/Settings-styled.tsx | 17 ++++- src/client/modals/Settings/Settings.tsx | 66 ++++++++++--------- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/client/components/Modal/Modal-styled.tsx b/src/client/components/Modal/Modal-styled.tsx index 1871480..df0c468 100644 --- a/src/client/components/Modal/Modal-styled.tsx +++ b/src/client/components/Modal/Modal-styled.tsx @@ -21,7 +21,7 @@ const ModalContainer = styled.div` const ModalInnerContainer = styled.div` background-color: #ffffff; border-radius: 1.25rem; - height: 50%; + height: fit-content; padding: 25px; width: 50%; `; diff --git a/src/client/modals/Settings/Settings-styled.tsx b/src/client/modals/Settings/Settings-styled.tsx index 09e6701..fb494a8 100644 --- a/src/client/modals/Settings/Settings-styled.tsx +++ b/src/client/modals/Settings/Settings-styled.tsx @@ -1,3 +1,18 @@ import styled from "styled-components"; -export {}; +const Container = styled.div` + display: flex; + flex-direction: column; +`; + +const Row = styled.div` + display: flex; + flex-direction: row; + justify-content: space-evenly; + + button { + width: 45%; + } +`; + +export { Container, Row }; diff --git a/src/client/modals/Settings/Settings.tsx b/src/client/modals/Settings/Settings.tsx index 49f034a..d18aa74 100644 --- a/src/client/modals/Settings/Settings.tsx +++ b/src/client/modals/Settings/Settings.tsx @@ -3,6 +3,8 @@ import { connect } from "react-redux"; import Button from "../../components/Button"; +import { Container, Row } from "./Settings-styled"; + import { displayNotification, setModalContent, @@ -26,36 +28,40 @@ const Settings: React.SFC = (props: SettingsProps) => { } = props; return ( -
-
+ + + diff --git a/src/client/components/Profile/Profile-styled.tsx b/src/client/components/Profile/Profile-styled.tsx index 1ea235d..e3dc1bf 100644 --- a/src/client/components/Profile/Profile-styled.tsx +++ b/src/client/components/Profile/Profile-styled.tsx @@ -183,7 +183,7 @@ const ProfileAccountStatsContainer = styled.div` padding: 25px; width: 40%; - h2 { + h3 { margin-top: 100px; } diff --git a/src/client/components/Profile/ProfileAccountDetails.tsx b/src/client/components/Profile/ProfileAccountDetails.tsx index d1c901b..8827833 100644 --- a/src/client/components/Profile/ProfileAccountDetails.tsx +++ b/src/client/components/Profile/ProfileAccountDetails.tsx @@ -10,17 +10,19 @@ import { ProfileAccountDetailsContainer, } from "./Profile-styled"; -import { editProfile } from "../../redux/thunks"; - -import { RootState } from "../../types"; import { setModalContent, setModalTitle, setIsModalOpen, } from "../../redux/actions/application"; +import { setIsEditingProfile } from "../../redux/actions/user"; +import { editProfile } from "../../redux/thunks"; + +import { RootState } from "../../types"; export interface ProfileAccountDetailsProps { email: string; + handleCancelEditProfile: () => void; handleEditProfile: (email: string, name: string) => void; handleSettingsClick: () => void; isEditingProfile: boolean; @@ -32,6 +34,7 @@ const ProfileAccountDetails: React.SFC = ( ) => { const { email, + handleCancelEditProfile, handleEditProfile, handleSettingsClick, isEditingProfile, @@ -82,17 +85,30 @@ const ProfileAccountDetails: React.SFC = ( value={newEmail} /> {isEditingProfile && ( -