Skip to content

Commit

Permalink
Merge pull request #452 from BinaryStudioAcademy/task/OV-444-add-warn…
Browse files Browse the repository at this point in the history
…ing-that-progress-not-saved-on-studio-page

OV-444: + add unsaved warning
  • Loading branch information
nikita-remeslov authored Sep 27, 2024
2 parents 264640c + 981a292 commit 370d6c2
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { UnsavedWarningContent } from './unsaved-warning-content.js';
export { WarningContent } from './warning-content.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
Button,
Flex,
Heading,
Text,
} from '~/bundles/common/components/components.js';

type Properties = {
onCancel: () => void;
onSubmit: () => void;
};

const UnsavedWarningContent: React.FC<Properties> = ({
onCancel,
onSubmit,
}) => {
return (
<>
<Heading variant="H3" color="typography.900" mb="20px">
Notice before you leave the page
</Heading>

<Text as="p" color="typography.600" mb="20px">
If you leave now all your unsaved changes will be lost. Please
save draft or submit to render before leaving.
</Text>

<Flex gap="10px" justify="end">
<Button label="Cancel" w="auto" onClick={onCancel} />
<Button
label="Leave Anyway"
w="auto"
variant="secondaryOutlined"
onClick={onSubmit}
/>
</Flex>
</>
);
};

export { UnsavedWarningContent };
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,22 @@ import {
ModalOverlay,
} from '~/bundles/common/components/components.js';

import { WarningContent } from './components/components.js';

type Properties = {
isOpen: boolean;
onClose: () => void;
onSubmit: () => void;
};

const WarningModal: React.FC<Properties> = ({ isOpen, onClose, onSubmit }) => {
const WarningModal: React.FC<React.PropsWithChildren<Properties>> = ({
isOpen,
onClose,
children,
}) => {
return (
<BaseModal isOpen={isOpen} onClose={onClose} size="xl">
<ModalOverlay />
<ModalContent>
<ModalCloseButton />
<ModalBody p="40px">
<WarningContent onCancel={onClose} onSubmit={onSubmit} />
</ModalBody>
<ModalBody p="40px">{children}</ModalBody>
</ModalContent>
</BaseModal>
);
Expand Down
48 changes: 42 additions & 6 deletions frontend/src/bundles/studio/pages/studio.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type PlayerRef } from '@remotion/player';
import { useBlocker } from 'react-router-dom';

import { AudioPlayer } from '~/bundles/common/components/audio-player/audio-player.js';
import {
Expand Down Expand Up @@ -30,6 +31,10 @@ import {
} from '~/bundles/common/hooks/hooks.js';
import { IconName } from '~/bundles/common/icons/icons.js';
import { notificationService } from '~/bundles/common/services/services.js';
import {
UnsavedWarningContent,
WarningContent,
} from '~/bundles/studio/components/warning-modal/components/components.js';

import {
PlayerControls,
Expand Down Expand Up @@ -81,6 +86,8 @@ const Studio: React.FC = () => {
scriptPlayer,
isVideoScriptsGenerationReady,
isVideoScriptsGenerationPending,
isDraftSaved,
isSubmitToRender,
} = useAppSelector(({ studio }) => studio);

const playerReference = useRef<PlayerRef>(null);
Expand Down Expand Up @@ -131,7 +138,6 @@ const Studio: React.FC = () => {
message: NotificationMessage.VIDEO_SUBMITTED,
title: NotificationTitle.VIDEO_SUBMITTED,
});
navigate(AppRoute.ROOT);
})
.catch(() => {
notificationService.error({
Expand All @@ -140,7 +146,7 @@ const Studio: React.FC = () => {
title: NotificationTitle.VIDEO_SUBMIT_FAILED,
});
});
}, [dispatch, navigate, scenes, scripts]);
}, [dispatch, scenes, scripts]);

const handleSubmit = useCallback(() => {
if (scenesExceedScripts(scenes, scripts)) {
Expand Down Expand Up @@ -242,6 +248,26 @@ const Studio: React.FC = () => {

const { isPlaying, url } = scriptPlayer;

const blocker = useBlocker(
({ currentLocation, nextLocation }) =>
!(isDraftSaved || isSubmitToRender) &&
currentLocation.pathname !== nextLocation.pathname,
);

const handleCloseUnsavedChangesModal = useCallback(() => {
blocker.reset?.();
}, [blocker]);

const handleSubmitUnsavedChangesModal = useCallback(() => {
blocker.proceed?.();
}, [blocker]);

useEffect(() => {
if (isSubmitToRender) {
navigate(AppRoute.ROOT);
}
}, [navigate, isSubmitToRender]);

return (
<>
<Overlay isOpen={isVideoScriptsGenerationPending}>
Expand All @@ -256,11 +282,21 @@ const Studio: React.FC = () => {
overflowY={'hidden'}
className={styles['scrollableContainer']}
>
<WarningModal isOpen={isModalOpen} onClose={handleCloseModal}>
<WarningContent
onCancel={handleCloseModal}
onSubmit={handleConfirmSubmit}
/>
</WarningModal>
<WarningModal
isOpen={isModalOpen}
onClose={handleCloseModal}
onSubmit={handleConfirmSubmit}
/>
isOpen={blocker.state === 'blocked'}
onClose={handleCloseUnsavedChangesModal}
>
<UnsavedWarningContent
onCancel={handleCloseUnsavedChangesModal}
onSubmit={handleSubmitUnsavedChangesModal}
/>
</WarningModal>
<Header
center={
<Button
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/bundles/studio/store/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ type State = {
videoSize: VideoPreviewT;
videoName: string;
isDraftSaved: boolean;
isSubmitToRender: boolean;
videoId: string | null;
voices: Voice[];
templates: {
Expand Down Expand Up @@ -126,6 +127,7 @@ const initialState: State = {
videoSize: VideoPreview.LANDSCAPE,
videoName: 'Untitled Video',
isDraftSaved: true,
isSubmitToRender: false,
videoId: null,
voices: [],
templates: {
Expand Down Expand Up @@ -623,6 +625,7 @@ const { reducer, actions, name } = createSlice({
state.dataStatus = DataStatus.PENDING;
});
builder.addCase(renderAvatar.fulfilled, (state) => {
state.isSubmitToRender = true;
state.dataStatus = DataStatus.FULFILLED;
});
builder.addCase(renderAvatar.rejected, (state) => {
Expand Down

0 comments on commit 370d6c2

Please sign in to comment.