Skip to content

Commit

Permalink
show popup when email not configured
Browse files Browse the repository at this point in the history
  • Loading branch information
maidul98 committed Mar 16, 2023
1 parent dce5c8f commit 8e55d17
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 14 deletions.
19 changes: 18 additions & 1 deletion frontend/src/components/signup/TeamInviteStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 () => {
Expand Down Expand Up @@ -62,10 +69,20 @@ export default function TeamInviteStep(): JSX.Element {
</div>
<Button
text={t('signup:step5-send-invites') ?? ''}
onButtonPressed={() => inviteUsers({ emails })}
onButtonPressed={() => {
if(serverDetails?.emailConfigured){
inviteUsers({ emails })
}else{
handlePopUpOpen('setUpEmail');
}
}}
size="lg"
/>
</div>
<EmailServiceSetupModal
isOpen={popUp.setUpEmail?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle('setUpEmail', isOpen)}
/>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Button } from '../Button';
import { Modal, ModalContent } from '../Modal';

type Props = {
isOpen?: boolean;
onOpenChange?: (isOpen: boolean) => void;
};

export const EmailServiceSetupModal = ({ isOpen, onOpenChange }: Props): JSX.Element => (
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
<ModalContent title="Email service not configured">
<p className="mb-4 text-bunker-300">
The administrators of this Infisical instance have not yet set up an email service provider required to perform this action
</p>

<a href="https://infisical.com/docs/self-hosting/configuration/email">
<Button className="mr-4">Learn more</Button>
</a>
</ModalContent>
</Modal>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EmailServiceSetupModal } from './EmailServiceSetupModal';
1 change: 1 addition & 0 deletions frontend/src/components/v2/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
1 change: 1 addition & 0 deletions frontend/src/hooks/api/serverDetails/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useFetchServerStatus } from './queries'
19 changes: 19 additions & 0 deletions frontend/src/hooks/api/serverDetails/queries.tsx
Original file line number Diff line number Diff line change
@@ -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<ServerStatus>('/api/status');
return data;
};

export const useFetchServerStatus= () => {
return useQuery({ queryKey: serverStatusKeys.serverStatus, queryFn: fetchServerStatus });
}
5 changes: 5 additions & 0 deletions frontend/src/hooks/api/serverDetails/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type ServerStatus = {
date: string;
message: string;
emailConfigured: boolean;
};
12 changes: 11 additions & 1 deletion frontend/src/pages/signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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();

Expand Down Expand Up @@ -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 (
<div className="bg-bunker-800 h-screen flex flex-col items-center justify-center">
<Head>
Expand Down
20 changes: 19 additions & 1 deletion frontend/src/pages/verify-email.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -63,7 +70,13 @@ export default function VerifyEmail() {
</div>
<div className="flex flex-col items-center justify-center w-full md:p-2 max-h-20 max-w-md mt-4 mx-auto text-sm">
<div className="text-l mt-6 m-8 px-8 py-3 text-lg">
<Button text="Continue" onButtonPressed={sendVerificationEmail} size="lg" />
<Button text="Continue" onButtonPressed={()=>{
if (serverDetails?.emailConfigured){
sendVerificationEmail()
} else {
handlePopUpOpen('setUpEmail');
}
}} size="lg" />
</div>
</div>
</div>
Expand All @@ -80,6 +93,11 @@ export default function VerifyEmail() {
</div>
</div>
)}

<EmailServiceSetupModal
isOpen={popUp.setUpEmail?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle('setUpEmail', isOpen)}
/>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as yup from 'yup';
import {
Button,
DeleteActionModal,
EmailServiceSetupModal,
EmptyState,
FormControl,
IconButton,
Expand All @@ -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 = {
Expand All @@ -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 {
Expand Down Expand Up @@ -92,7 +96,13 @@ export const OrgIncidentContactsTable = ({
<div>
<Button
leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => handlePopUpOpen('addContact')}
onClick={() => {
if (serverDetails?.emailConfigured){
handlePopUpOpen('addContact');
} else {
handlePopUpOpen('setUpEmail');
}
}}
>
Add Contact
</Button>
Expand Down Expand Up @@ -180,6 +190,10 @@ export const OrgIncidentContactsTable = ({
onChange={(isOpen) => handlePopUpToggle('removeContact', isOpen)}
onDeleteApproved={onRemoveIncidentContact}
/>
<EmailServiceSetupModal
isOpen={popUp.setUpEmail?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle('setUpEmail', isOpen)}
/>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as yup from 'yup';
import {
Button,
DeleteActionModal,
EmptyState,
EmailServiceSetupModal, EmptyState,
FormControl,
IconButton,
Input,
Expand All @@ -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 = {
Expand Down Expand Up @@ -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 {
Expand All @@ -79,8 +82,8 @@ export const OrgMembersTable = ({

const onAddMember = async ({ email }: TAddMemberForm) => {
await onInviteMember(email);
handlePopUpClose('addMember');
reset();
handlePopUpClose('addMember');
reset();
};

const onRemoveOrgMemberApproved = async () => {
Expand Down Expand Up @@ -121,10 +124,14 @@ export const OrgMembersTable = ({
<Button
leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => {
if (isMoreUserNotAllowed) {
handlePopUpOpen('upgradePlan');
if (serverDetails?.emailConfigured){
if (isMoreUserNotAllowed) {
handlePopUpOpen('upgradePlan');
} else {
handlePopUpOpen('addMember');
}
} else {
handlePopUpOpen('addMember');
handlePopUpOpen('setUpEmail');
}
}}
>
Expand Down Expand Up @@ -291,6 +298,10 @@ export const OrgMembersTable = ({
onOpenChange={(isOpen) => handlePopUpToggle('upgradePlan', isOpen)}
text="You can add custom environments if you switch to Infisical's Team plan."
/>
<EmailServiceSetupModal
isOpen={popUp.setUpEmail?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle('setUpEmail', isOpen)}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useEffect, useState } from 'react';

import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider';
import { Checkbox } from '@app/components/v2';
import { Checkbox, EmailServiceSetupModal } from '@app/components/v2';
import { useFetchServerStatus } from '@app/hooks/api/serverDetails';
import { usePopUp } from '@app/hooks/usePopUp';

import { useGetUser } from '../../../../hooks/api';
import { User } from '../../../../hooks/api/types';
Expand All @@ -11,6 +13,11 @@ export const SecuritySection = () => {
const [isMfaEnabled, setIsMfaEnabled] = useState(false);
const { data: user } = useGetUser();
const { createNotification } = useNotificationContext();
const { handlePopUpToggle, popUp, handlePopUpOpen } = usePopUp([
'setUpEmail'
] as const);

const {data: serverDetails } = useFetchServerStatus()

useEffect(() => {
if (user && typeof user.isMfaEnabled !== 'undefined') {
Expand Down Expand Up @@ -42,6 +49,7 @@ export const SecuritySection = () => {
}

return (
<>
<form>
<div className="mb-6 mt-2 flex w-full flex-col items-start rounded-md bg-white/5 px-6 pb-6 pt-2">
<p className="mb-4 mt-2 text-xl font-semibold">
Expand All @@ -52,12 +60,21 @@ export const SecuritySection = () => {
id="isTwoFAEnabled"
isChecked={isMfaEnabled}
onCheckedChange={(state) => {
toggleMfa(state as boolean);
if (serverDetails?.emailConfigured){
toggleMfa(state as boolean);
} else {
handlePopUpOpen('setUpEmail');
}
}}
>
Enable 2-factor authentication via your personal email.
</Checkbox>
</div>
</form>
<EmailServiceSetupModal
isOpen={popUp.setUpEmail?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle('setUpEmail', isOpen)}
/>
</>
);
};

0 comments on commit 8e55d17

Please sign in to comment.