11"use client" ;
22
33import type { Data } from "@puckeditor/core" ;
4- import { Puck } from "@puckeditor/core" ;
4+ import { Puck , blocksPlugin , outlinePlugin } from "@puckeditor/core" ;
55import config from "../../../../puck.config" ;
6- import { useState , createContext , useContext , useCallback } from "react" ;
6+ import { useState , useCallback } from "react" ;
77import { VersionPlugin } from "./VersionPlugin" ;
8- import { blocksPlugin , outlinePlugin } from "@puckeditor/core" ;
98import { ActionBarOverride } from "./ActionBarOverride" ;
109import { SaveButton } from "./SaveButton" ;
1110import { MediaProvider , type MediaWithUrl } from "@/components/puck/media-context" ;
1211import type { Version } from "../../../../lib/types" ;
13-
14- type DocumentContextType = {
15- documentId : number ;
16- documentName : string ;
17- versionId ?: number ;
18- publishedVersionId ?: number ;
19- versions : Version [ ] ;
20- isArchived : boolean ;
21- addVersion : ( version : Version ) => void ;
22- setPublishedVersionId : ( id : number ) => void ;
23- } ;
24-
25- const DocumentContext = createContext < DocumentContextType > ( {
26- documentId : 0 ,
27- documentName : "" ,
28- versions : [ ] ,
29- isArchived : false ,
30- addVersion : ( ) => { } ,
31- setPublishedVersionId : ( ) => { } ,
32- } ) ;
33-
34- export function useDocumentContext ( ) {
35- return useContext ( DocumentContext ) ;
36- }
12+ import { useUnsavedChangesGuard } from "./useUnsavedChangesGuard" ;
13+ import { DocumentContext } from "./document-context" ;
14+ import { UnsavedChangesContext } from "./unsaved-changes-context" ;
3715
3816export function Client ( {
3917 documentId,
@@ -57,32 +35,38 @@ export function Client({
5735 const [ versions , setVersions ] = useState ( initialVersions ) ;
5836 const [ versionId , setVersionId ] = useState ( initialVersionId ) ;
5937 const [ publishedVersionId , setPublishedVersionId ] = useState ( initialPublishedVersionId ) ;
38+ const [ isDirty , setIsDirty ] = useState ( false ) ;
39+ const { confirmDiscardChanges } = useUnsavedChangesGuard ( isDirty ) ;
6040
6141 const addVersion = useCallback ( ( version : Version ) => {
6242 setVersions ( prev => [ version , ...prev ] ) ;
6343 setVersionId ( version . id ) ;
44+ setIsDirty ( false ) ;
6445 } , [ ] ) ;
6546
6647 return (
6748 < MediaProvider media = { media } >
68- < DocumentContext . Provider
69- value = { { documentId, documentName, versionId, publishedVersionId, versions, isArchived, addVersion, setPublishedVersionId } }
70- >
71- < Puck
72- config = { config }
73- data = { data }
74- ui = { { plugin : { current : "version-plugin" } } }
75- plugins = { [ VersionPlugin , blocksPlugin ( ) , outlinePlugin ( ) ] }
76- permissions = { isArchived
77- ? { drag : false , duplicate : false , delete : false , edit : false , insert : false }
78- : { duplicate : false } // We replace this with our own, to avoid an icon collision
79- }
80- overrides = { {
81- actionBar : ActionBarOverride ,
82- headerActions : SaveButton
83- } }
84- />
85- </ DocumentContext . Provider >
49+ < DocumentContext . Provider
50+ value = { { documentId, documentName, versionId, publishedVersionId, versions, isArchived, isDirty, addVersion, setPublishedVersionId } }
51+ >
52+ < UnsavedChangesContext . Provider value = { { confirmDiscardChanges } } >
53+ < Puck
54+ config = { config }
55+ data = { data }
56+ onChange = { ( ) => setIsDirty ( true ) }
57+ ui = { { plugin : { current : "version-plugin" } } }
58+ plugins = { [ VersionPlugin , blocksPlugin ( ) , outlinePlugin ( ) ] }
59+ permissions = { isArchived
60+ ? { drag : false , duplicate : false , delete : false , edit : false , insert : false }
61+ : { duplicate : false } // We replace this with our own, to avoid an icon collision
62+ }
63+ overrides = { {
64+ actionBar : ActionBarOverride ,
65+ headerActions : SaveButton
66+ } }
67+ />
68+ </ UnsavedChangesContext . Provider >
69+ </ DocumentContext . Provider >
8670 </ MediaProvider >
8771 ) ;
8872}
0 commit comments