Skip to content

Commit

Permalink
feat: added confirmation-modal to all leave-call-buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
malmen237 committed Dec 5, 2024
1 parent e3bd8af commit afbe705
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 43 deletions.
22 changes: 21 additions & 1 deletion src/components/calls-page/calls-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { JoinProduction } from "../landing-page/join-production";
import { ProductionLine } from "../production-line/production-line";
import { SecondaryButton } from "../landing-page/form-elements";
import { NavigateToRootButton } from "../navigate-to-root-button/navigate-to-root-button";
import { DisplayContainerHeader } from "../landing-page/display-container-header";
import { Modal } from "../modal/modal";
import { VerifyDecision } from "../verify-decision/verify-decision";
import { ModalConfirmationText } from "../modal/modal-confirmation-text";

const Container = styled.div`
display: flex;
Expand Down Expand Up @@ -47,6 +51,7 @@ const ButtonWrapper = styled.div`
export const CallsPage = () => {
const [productionId, setProductionId] = useState<string | null>(null);
const [addCallActive, setAddCallActive] = useState(false);
const [confirmExitModalOpen, setConfirmExitModalOpen] = useState(false);
const [{ calls, selectedProductionId }, dispatch] = useGlobalState();
const { productionId: paramProductionId, lineId: paramLineId } = useParams();
const navigate = useNavigate();
Expand All @@ -68,6 +73,7 @@ export const CallsPage = () => {

const runExitAllCalls = async () => {
setProductionId(null);
navigate("/");
Object.entries(calls).forEach(([callId]) => {
if (callId) {
dispatch({
Expand All @@ -81,7 +87,21 @@ export const CallsPage = () => {
return (
<Container>
<ButtonWrapper>
<NavigateToRootButton resetOnExit={runExitAllCalls} />
<NavigateToRootButton
resetOnExitRequest={() => setConfirmExitModalOpen(true)}
/>
{confirmExitModalOpen && (
<Modal onClose={() => setConfirmExitModalOpen(false)}>
<DisplayContainerHeader>Confirm</DisplayContainerHeader>
<ModalConfirmationText>
Are you sure you want to leave all calls?
</ModalConfirmationText>
<VerifyDecision
confirm={runExitAllCalls}
abort={() => setConfirmExitModalOpen(false)}
/>
</Modal>
)}
</ButtonWrapper>
<CallsContainer>
{Object.entries(calls).map(
Expand Down
29 changes: 25 additions & 4 deletions src/components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import styled from "@emotion/styled";
import { FC } from "react";
import { FC, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { backgroundColour } from "../css-helpers/defaults.ts";
import { useGlobalState } from "../global-state/context-provider.tsx";
import { useAudioCue } from "./production-line/use-audio-cue.ts";
import { DisplayContainerHeader } from "./landing-page/display-container-header.tsx";
import { Modal } from "./modal/modal.tsx";
import { VerifyDecision } from "./verify-decision/verify-decision.tsx";
import { ModalConfirmationText } from "./modal/modal-confirmation-text.ts";

const HeaderWrapper = styled.div`
width: 100%;
Expand All @@ -16,12 +20,14 @@ const HeaderWrapper = styled.div`
`;

export const Header: FC = () => {
const [confirmExitModalOpen, setConfirmExitModalOpen] = useState(false);
const [{ calls }, dispatch] = useGlobalState();
const navigate = useNavigate();
const location = useLocation();
const { playExitSound } = useAudioCue();

const runExitAllCalls = () => {
navigate("/");
playExitSound();
Object.entries(calls).forEach(([callId]) => {
if (callId) {
Expand All @@ -35,11 +41,26 @@ export const Header: FC = () => {

const returnToRoot = () => {
if (location.pathname.includes("/production")) {
runExitAllCalls();
navigate("/");
setConfirmExitModalOpen(true);
} else {
navigate("/");
}
};
return <HeaderWrapper onClick={returnToRoot}>Intercom</HeaderWrapper>;
return (
<>
<HeaderWrapper onClick={returnToRoot}>Intercom</HeaderWrapper>
{confirmExitModalOpen && (
<Modal onClose={() => setConfirmExitModalOpen(false)}>
<DisplayContainerHeader>Confirm</DisplayContainerHeader>
<ModalConfirmationText>
Are you sure you want to leave all calls?
</ModalConfirmationText>
<VerifyDecision
confirm={runExitAllCalls}
abort={() => setConfirmExitModalOpen(false)}
/>
</Modal>
)}
</>
);
};
38 changes: 6 additions & 32 deletions src/components/manage-productions/remove-production.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import styled from "@emotion/styled";
import { DisplayContainerHeader } from "../landing-page/display-container-header";
import { PrimaryButton } from "../landing-page/form-elements";
import { Spinner } from "../loader/loader";
import { VerifyDecision } from "../verify-decision/verify-decision";

const Container = styled.div`
max-width: 45rem;
Expand All @@ -16,15 +17,6 @@ const VerifyBtnWrapper = styled.div`
margin: 3rem 0 2rem 2rem;
`;

const VerifyButtons = styled.div`
display: flex;
padding: 1rem 0 0 0;
`;

const Button = styled(PrimaryButton)`
margin: 0 1rem 0 0;
`;

const ButtonWrapper = styled.div`
margin: 2rem 0 2rem 0;
`;
Expand Down Expand Up @@ -64,29 +56,11 @@ export const RemoveProduction = ({
{verifyRemove && (
<VerifyBtnWrapper>
<p>Are you sure?</p>
<VerifyButtons>
<Button
type="button"
className={deleteLoader ? "submit" : ""}
disabled={deleteLoader}
onClick={() => {
handleSubmit();
}}
>
Yes
{deleteLoader && <Spinner className="manage-production" />}
</Button>
<Button
type="button"
className={deleteLoader ? "submit" : ""}
onClick={() => {
reset();
}}
>
Go back
{deleteLoader && <Spinner className="manage-production" />}
</Button>
</VerifyButtons>
<VerifyDecision
loader={deleteLoader}
confirm={handleSubmit}
abort={reset}
/>
</VerifyBtnWrapper>
)}
</Container>
Expand Down
5 changes: 5 additions & 0 deletions src/components/modal/modal-confirmation-text.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styled from "@emotion/styled";

export const ModalConfirmationText = styled.p`
padding-bottom: 1rem;
`;
52 changes: 52 additions & 0 deletions src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import styled from "@emotion/styled";

const ModalWrapper = styled.div`
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
`;

const ModalContent = styled.div`
position: relative;
background-color: #121212;
padding: 2rem;
border-radius: 0.8rem;
box-shadow: 0 0.2rem 2rem rgba(123, 123, 123, 0.1);
width: 40rem;
max-width: 90%;
animation: slideIn 0.3s ease-out;
`;

const CloseButton = styled.button`
position: absolute;
top: 1rem;
right: 1rem;
background: none;
border: none;
font-size: 2rem;
cursor: pointer;
color: gray;
`;

interface ModalProps {
onClose: () => void;
children: React.ReactNode;
}

export const Modal = ({ onClose, children }: ModalProps) => {
return (
<ModalWrapper>
<ModalContent>
<CloseButton onClick={onClose}>&times;</CloseButton>
{children}
</ModalContent>
</ModalWrapper>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@ const StyledBackBtn = styled(PrimaryButton)`
`;

export const NavigateToRootButton = ({
resetOnExit,
resetOnExitRequest,
}: {
resetOnExit?: () => void;
resetOnExitRequest?: () => void;
}) => {
const navigate = useNavigate();

return (
<StyledBackBtn
type="button"
onClick={() => {
if (resetOnExit) {
resetOnExit();
if (resetOnExitRequest) {
resetOnExitRequest();
} else {
navigate("/");
}
navigate("/");
}}
>
<BackArrow />
Expand Down
18 changes: 17 additions & 1 deletion src/components/production-line/production-line.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import { DisplayWarning } from "../display-box.tsx";
import { SettingsModal, Hotkeys } from "./settings-modal.tsx";
import { CallState } from "../../global-state/types.ts";
import { ExitCallButton } from "./exit-call-button.tsx";
import { Modal } from "../modal/modal.tsx";
import { VerifyDecision } from "../verify-decision/verify-decision.tsx";
import { ModalConfirmationText } from "../modal/modal-confirmation-text.ts";

const TempDiv = styled.div`
padding: 0 0 2rem 0;
Expand Down Expand Up @@ -136,6 +139,7 @@ export const ProductionLine = ({
const [isInputMuted, setIsInputMuted] = useState(true);
const [isOutputMuted, setIsOutputMuted] = useState(false);
const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false);
const [confirmExitModalOpen, setConfirmExitModalOpen] = useState(false);
const [hotkeys, setHotkeys] = useState<Hotkeys>({
muteHotkey: "m",
speakerHotkey: "n",
Expand Down Expand Up @@ -269,7 +273,19 @@ export const ProductionLine = ({
<HeaderWrapper>
{!isMobile && !isSingleCall && (
<ButtonWrapper>
<ExitCallButton resetOnExit={exit} />
<ExitCallButton resetOnExit={() => setConfirmExitModalOpen(true)} />
{confirmExitModalOpen && (
<Modal onClose={() => setConfirmExitModalOpen(false)}>
<DisplayContainerHeader>Confirm</DisplayContainerHeader>
<ModalConfirmationText>
Are you sure you want to leave the call?
</ModalConfirmationText>
<VerifyDecision
confirm={exit}
abort={() => setConfirmExitModalOpen(false)}
/>
</Modal>
)}
</ButtonWrapper>
)}
{!loading && production && line && (
Expand Down
42 changes: 42 additions & 0 deletions src/components/verify-decision/verify-decision.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import styled from "@emotion/styled";
import { PrimaryButton } from "../landing-page/form-elements";
import { Spinner } from "../loader/loader";

type TVerifyDecision = {
loader?: boolean;
confirm: () => void;
abort: () => void;
};

const VerifyButtons = styled.div`
display: flex;
padding: 1rem 0 0 0;
`;

const Button = styled(PrimaryButton)`
margin: 0 1rem 0 0;
`;

export const VerifyDecision = ({ loader, confirm, abort }: TVerifyDecision) => {
return (
<VerifyButtons>
<Button
type="button"
className={loader ? "submit" : ""}
disabled={loader}
onClick={() => confirm()}
>
Yes
{loader && <Spinner className="manage-production" />}
</Button>
<Button
type="button"
className={loader ? "submit" : ""}
onClick={() => abort()}
>
Go back
{loader && <Spinner className="manage-production" />}
</Button>
</VerifyButtons>
);
};

0 comments on commit afbe705

Please sign in to comment.