import { Box, Toast } from "@prismicio/editor-ui"; import { PushChangesLimit } from "@slicemachine/manager"; import Head from "next/head"; import { useRouter } from "next/router"; import React, { useEffect, useMemo, useState } from "react"; import { toast } from "react-toastify"; import { BaseStyles } from "theme-ui"; import { getState, telemetry } from "@/apiClient"; import { BreadcrumbItem } from "@/components/Breadcrumb"; import { NoChangesBlankSlate } from "@/features/changes/BlankSlates"; import { PushChangesButton } from "@/features/changes/PushChangesButton"; import { useOnboarding } from "@/features/onboarding/useOnboarding"; import { pushChanges } from "@/features/sync/actions/pushChanges"; import { useAutoSync } from "@/features/sync/AutoSyncProvider"; import { useUnSyncChanges } from "@/features/sync/useUnSyncChanges"; import { useAuthStatus } from "@/hooks/useAuthStatus"; import { useNetwork } from "@/hooks/useNetwork"; import { useRepositoryInformation } from "@/hooks/useRepositoryInformation"; import { AppLayout, AppLayoutActions, AppLayoutBreadcrumb, AppLayoutContent, AppLayoutHeader, } from "@/legacy/components/AppLayout"; import { OfflinePage, UnauthenticatedView, } from "@/legacy/components/ChangesEmptyState"; import { ChangesItems } from "@/legacy/components/ChangesItems"; import { HardDeleteDocumentsDrawer, SoftDeleteDocumentsDrawer, } from "@/legacy/components/DeleteDocumentsDrawer"; import { AuthStatus } from "@/modules/userContext/types"; import useSliceMachineActions from "@/modules/useSliceMachineActions"; const Changes: React.FunctionComponent = () => { const { unSyncedSlices, unSyncedCustomTypes, changedCustomTypes, changedSlices, modelsStatuses, } = useUnSyncChanges(); const isOnline = useNetwork(); const authStatus = useAuthStatus(); const { pushChangesSuccess, refreshState } = useSliceMachineActions(); const [isSyncing, setIsSyncing] = useState(false); const [openModalData, setOpenModalData] = useState< PushChangesLimit | undefined >(undefined); const { autoSyncStatus } = useAutoSync(); const router = useRouter(); const [isPushed, setIsPushed] = useState(false); const [isToastOpen, setIsToastOpen] = useState(false); const { repositoryUrl } = useRepositoryInformation(); const { completeStep } = useOnboarding(); const numberOfChanges = unSyncedSlices.length + unSyncedCustomTypes.length; // Changes page should not be accessible when the autoSyncStatus is syncing, synced or failed useEffect(() => { if ( autoSyncStatus === "synced" || autoSyncStatus === "failed" || autoSyncStatus === "syncing" ) { void router.push("/"); } }, [autoSyncStatus, router]); const onPush = async (confirmDeleteDocuments: boolean) => { try { setIsSyncing(true); setOpenModalData(undefined); const limit = await pushChanges({ confirmDeleteDocuments, changedCustomTypes, changedSlices, }); if (limit !== undefined) { setOpenModalData(limit); } else { const serverState = await getState(); refreshState(serverState); // Update last sync value in local storage pushChangesSuccess(); setIsPushed(true); setIsToastOpen(true); void completeStep("reviewAndPush"); } } catch (error) { console.error( "Something went wrong when manually pushing your changes", error, ); toast.error( "Something went wrong when pushing your changes. Check your terminal logs.", ); } setIsSyncing(false); }; const PageContent = useMemo(() => { if (!isOnline) { return ; } if (authStatus === AuthStatus.UNAUTHENTICATED) { return ; } if (numberOfChanges === 0) { return ( ); } return ( ); }, [ isOnline, authStatus, numberOfChanges, unSyncedSlices, unSyncedCustomTypes, modelsStatuses, isPushed, repositoryUrl, ]); return ( <> Changes - Slice Machine Changes { void onPush(false); // not deleting documents by default }} /> } // 322 is a toast width, needed for the toast to be displayed with proper paddings open={isToastOpen} variant="card" seconds={20} title="Success! 🎉" subtitle="Your changes have been pushed." action={{ title: "Create content in the Page Builder", onClick: () => { void telemetry.track({ event: "post-push:toast-cta-clicked", }); void window.open(repositoryUrl, "_blank"); }, }} cancel={{ onClick: () => setIsToastOpen(false), }} onOpenChange={setIsToastOpen} /> {PageContent} void onPush(confirmDeleteDocuments) } modalData={openModalData} onClose={() => setOpenModalData(undefined)} /> void onPush(confirmDeleteDocuments) } modalData={openModalData} onClose={() => setOpenModalData(undefined)} /> ); }; export default Changes;