From dce5c8f6217222502174e858ac484084f94934ef Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Fri, 10 Mar 2023 23:20:08 -0800 Subject: [PATCH 1/2] add emailConfigured to status api --- backend/src/routes/status/status.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/src/routes/status/status.ts b/backend/src/routes/status/status.ts index 4ab82cca9..c7f7e9d04 100644 --- a/backend/src/routes/status/status.ts +++ b/backend/src/routes/status/status.ts @@ -1,4 +1,5 @@ import express, { Request, Response } from 'express'; +import { SMTP_CONFIGURED } from '../../config'; const router = express.Router(); @@ -8,6 +9,7 @@ router.get( res.status(200).json({ date: new Date(), message: 'Ok', + emailConfigured: SMTP_CONFIGURED }) } ); From 8e55d17a5501b0ad4ce076e80a1d72f5d4bb3f05 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Thu, 16 Mar 2023 09:56:42 -0700 Subject: [PATCH 2/2] show popup when email not configured --- .../src/components/signup/TeamInviteStep.tsx | 19 +++++++++++++- .../EmailServiceSetupModal.tsx | 21 ++++++++++++++++ .../v2/EmailServiceSetupModal/index.tsx | 1 + frontend/src/components/v2/index.tsx | 1 + frontend/src/hooks/api/serverDetails/index.ts | 1 + .../src/hooks/api/serverDetails/queries.tsx | 19 ++++++++++++++ frontend/src/hooks/api/serverDetails/types.ts | 5 ++++ frontend/src/pages/signup.tsx | 12 ++++++++- frontend/src/pages/verify-email.tsx | 20 ++++++++++++++- .../OrgIncidentContactsTable.tsx | 18 +++++++++++-- .../OrgMembersTable/OrgMembersTable.tsx | 25 +++++++++++++------ .../SecuritySection/SecuritySection.tsx | 21 ++++++++++++++-- 12 files changed, 149 insertions(+), 14 deletions(-) create mode 100644 frontend/src/components/v2/EmailServiceSetupModal/EmailServiceSetupModal.tsx create mode 100644 frontend/src/components/v2/EmailServiceSetupModal/index.tsx create mode 100644 frontend/src/hooks/api/serverDetails/index.ts create mode 100644 frontend/src/hooks/api/serverDetails/queries.tsx create mode 100644 frontend/src/hooks/api/serverDetails/types.ts diff --git a/frontend/src/components/signup/TeamInviteStep.tsx b/frontend/src/components/signup/TeamInviteStep.tsx index 29cb95076..12d558606 100644 --- a/frontend/src/components/signup/TeamInviteStep.tsx +++ b/frontend/src/components/signup/TeamInviteStep.tsx @@ -2,10 +2,13 @@ import React, { useState } from 'react'; import { useRouter } from 'next/router'; import { useTranslation } from 'next-i18next'; +import { useFetchServerStatus } from '@app/hooks/api/serverDetails'; +import { usePopUp } from '@app/hooks/usePopUp'; import addUserToOrg from '@app/pages/api/organization/addUserToOrg'; import getWorkspaces from '@app/pages/api/workspace/getWorkspaces'; import Button from '../basic/buttons/Button'; +import { EmailServiceSetupModal } from '../v2'; /** * This is the last step of the signup flow. People can optionally invite their teammates here. @@ -14,6 +17,10 @@ export default function TeamInviteStep(): JSX.Element { const [emails, setEmails] = useState(''); const { t } = useTranslation(); const router = useRouter(); + const {data: serverDetails } = useFetchServerStatus() + const { handlePopUpToggle, popUp, handlePopUpOpen } = usePopUp([ + 'setUpEmail' + ] as const); // Redirect user to the getting started page const redirectToHome = async () => { @@ -62,10 +69,20 @@ export default function TeamInviteStep(): JSX.Element { + + + +); diff --git a/frontend/src/components/v2/EmailServiceSetupModal/index.tsx b/frontend/src/components/v2/EmailServiceSetupModal/index.tsx new file mode 100644 index 000000000..33a7d1854 --- /dev/null +++ b/frontend/src/components/v2/EmailServiceSetupModal/index.tsx @@ -0,0 +1 @@ +export { EmailServiceSetupModal } from './EmailServiceSetupModal'; diff --git a/frontend/src/components/v2/index.tsx b/frontend/src/components/v2/index.tsx index 52c8fc4f4..130b797ae 100644 --- a/frontend/src/components/v2/index.tsx +++ b/frontend/src/components/v2/index.tsx @@ -3,6 +3,7 @@ export * from './Card'; export * from './Checkbox'; export * from './DeleteActionModal'; export * from './Dropdown'; +export * from './EmailServiceSetupModal' export * from './EmptyState'; export * from './FormControl'; export * from './IconButton'; diff --git a/frontend/src/hooks/api/serverDetails/index.ts b/frontend/src/hooks/api/serverDetails/index.ts new file mode 100644 index 000000000..812293a1d --- /dev/null +++ b/frontend/src/hooks/api/serverDetails/index.ts @@ -0,0 +1 @@ +export { useFetchServerStatus } from './queries' \ No newline at end of file diff --git a/frontend/src/hooks/api/serverDetails/queries.tsx b/frontend/src/hooks/api/serverDetails/queries.tsx new file mode 100644 index 000000000..29abea127 --- /dev/null +++ b/frontend/src/hooks/api/serverDetails/queries.tsx @@ -0,0 +1,19 @@ +import {useQuery } from '@tanstack/react-query'; + +import { apiRequest } from '@app/config/request'; + +import { ServerStatus } from './types'; + +// cache key +const serverStatusKeys = { + serverStatus: ['serverStatus'] as const +}; + +const fetchServerStatus = async () => { + const {data} = await apiRequest.get('/api/status'); + return data; +}; + +export const useFetchServerStatus= () => { + return useQuery({ queryKey: serverStatusKeys.serverStatus, queryFn: fetchServerStatus }); +} \ No newline at end of file diff --git a/frontend/src/hooks/api/serverDetails/types.ts b/frontend/src/hooks/api/serverDetails/types.ts new file mode 100644 index 000000000..0deb90a38 --- /dev/null +++ b/frontend/src/hooks/api/serverDetails/types.ts @@ -0,0 +1,5 @@ +export type ServerStatus = { + date: string; + message: string; + emailConfigured: boolean; +}; \ No newline at end of file diff --git a/frontend/src/pages/signup.tsx b/frontend/src/pages/signup.tsx index 62d0f4a47..298fc9536 100644 --- a/frontend/src/pages/signup.tsx +++ b/frontend/src/pages/signup.tsx @@ -13,6 +13,7 @@ import TeamInviteStep from '@app/components/signup/TeamInviteStep'; import UserInfoStep from '@app/components/signup/UserInfoStep'; import SecurityClient from '@app/components/utilities/SecurityClient'; import { getTranslatedStaticProps } from '@app/components/utilities/withTranslateProps'; +import { useFetchServerStatus } from '@app/hooks/api/serverDetails'; import checkEmailVerificationCode from './api/auth/CheckEmailVerificationCode'; import getWorkspaces from './api/workspace/getWorkspaces'; @@ -25,10 +26,12 @@ export default function SignUp() { const [password, setPassword] = useState(''); const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); - const [code, setCode] = useState(''); + const [code, setCode] = useState('123456'); const [codeError, setCodeError] = useState(false); const [step, setStep] = useState(1); const router = useRouter(); + const {data: serverDetails } = useFetchServerStatus() + const { t } = useTranslation(); @@ -68,6 +71,13 @@ export default function SignUp() { } }; + // when email service is not configured, skip step 2 + useEffect(() => { + if (!serverDetails?.emailConfigured && step === 2){ + incrementStep() + } + }, [step]); + return (
diff --git a/frontend/src/pages/verify-email.tsx b/frontend/src/pages/verify-email.tsx index 3b7e1c8d5..203b040bf 100644 --- a/frontend/src/pages/verify-email.tsx +++ b/frontend/src/pages/verify-email.tsx @@ -6,12 +6,19 @@ import Link from 'next/link'; import Button from '@app/components/basic/buttons/Button'; import InputField from '@app/components/basic/InputField'; import { getTranslatedStaticProps } from '@app/components/utilities/withTranslateProps'; +import { EmailServiceSetupModal } from '@app/components/v2'; +import { usePopUp } from '@app/hooks'; +import { useFetchServerStatus } from '@app/hooks/api/serverDetails'; import SendEmailOnPasswordReset from './api/auth/SendEmailOnPasswordReset'; export default function VerifyEmail() { const [email, setEmail] = useState(''); const [step, setStep] = useState(1); + const {data: serverDetails } = useFetchServerStatus() + const { handlePopUpToggle, popUp, handlePopUpOpen } = usePopUp([ + 'setUpEmail' + ] as const); /** * This function sends the verification email and forwards a user to the next step. @@ -63,7 +70,13 @@ export default function VerifyEmail() {
-
@@ -80,6 +93,11 @@ export default function VerifyEmail() { )} + + handlePopUpToggle('setUpEmail', isOpen)} + /> ); } diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsTable/OrgIncidentContactsTable.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsTable/OrgIncidentContactsTable.tsx index c3bd55f51..e118e455b 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsTable/OrgIncidentContactsTable.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsTable/OrgIncidentContactsTable.tsx @@ -13,6 +13,7 @@ import * as yup from 'yup'; import { Button, DeleteActionModal, + EmailServiceSetupModal, EmptyState, FormControl, IconButton, @@ -28,6 +29,7 @@ import { THead, Tr} from '@app/components/v2'; import { usePopUp } from '@app/hooks'; +import { useFetchServerStatus } from '@app/hooks/api/serverDetails'; import { IncidentContact } from '@app/hooks/api/types'; type Props = { @@ -50,9 +52,11 @@ export const OrgIncidentContactsTable = ({ isLoading }: Props) => { const [searchContact, setSearchContact] = useState(''); + const {data: serverDetails } = useFetchServerStatus() const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([ 'addContact', - 'removeContact' + 'removeContact', + 'setUpEmail' ] as const); const { @@ -92,7 +96,13 @@ export const OrgIncidentContactsTable = ({
@@ -180,6 +190,10 @@ export const OrgIncidentContactsTable = ({ onChange={(isOpen) => handlePopUpToggle('removeContact', isOpen)} onDeleteApproved={onRemoveIncidentContact} /> + handlePopUpToggle('setUpEmail', isOpen)} + />
); }; diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx index 9bed5954b..b127abeb9 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx @@ -9,7 +9,7 @@ import * as yup from 'yup'; import { Button, DeleteActionModal, - EmptyState, + EmailServiceSetupModal, EmptyState, FormControl, IconButton, Input, @@ -28,6 +28,7 @@ import { Tr, UpgradePlanModal} from '@app/components/v2'; import { usePopUp } from '@app/hooks'; +import { useFetchServerStatus } from '@app/hooks/api/serverDetails'; import { OrgUser, Workspace } from '@app/hooks/api/types'; type Props = { @@ -64,10 +65,12 @@ export const OrgMembersTable = ({ }: Props) => { const router = useRouter(); const [searchMemberFilter, setSearchMemberFilter] = useState(''); + const {data: serverDetails } = useFetchServerStatus() const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([ 'addMember', 'removeMember', - 'upgradePlan' + 'upgradePlan', + 'setUpEmail' ] as const); const { @@ -79,8 +82,8 @@ export const OrgMembersTable = ({ const onAddMember = async ({ email }: TAddMemberForm) => { await onInviteMember(email); - handlePopUpClose('addMember'); - reset(); + handlePopUpClose('addMember'); + reset(); }; const onRemoveOrgMemberApproved = async () => { @@ -121,10 +124,14 @@ export const OrgMembersTable = ({