@@ -2,6 +2,9 @@ import React, { useState, useCallback, useEffect } from "react";
22import { Dialog } from "@atyrode/excalidraw" ;
33import { Range } from "./Range" ;
44import { UserSettings , DEFAULT_SETTINGS } from "../types/settings" ;
5+ import { RefreshCw } from "lucide-react" ;
6+ import { normalizeCanvasData } from "../utils/canvasUtils" ;
7+ import { capture } from "../utils/posthog" ;
58import "./SettingsDialog.scss" ;
69
710interface SettingsDialogProps {
@@ -15,6 +18,8 @@ const SettingsDialog: React.FC<SettingsDialogProps> = ({
1518} ) => {
1619 const [ modalIsShown , setModalIsShown ] = useState ( true ) ;
1720 const [ settings , setSettings ] = useState < UserSettings > ( DEFAULT_SETTINGS ) ;
21+ const [ showRestoreConfirmation , setShowRestoreConfirmation ] = useState ( false ) ;
22+ const [ isRestoring , setIsRestoring ] = useState ( false ) ;
1823
1924 // Get current settings from excalidrawAPI when component mounts
2025 useEffect ( ( ) => {
@@ -35,6 +40,43 @@ const SettingsDialog: React.FC<SettingsDialogProps> = ({
3540 }
3641 } , [ onClose ] ) ;
3742
43+ const handleRestoreTutorialCanvas = async ( ) => {
44+ if ( ! excalidrawAPI ) return ;
45+
46+ try {
47+ setIsRestoring ( true ) ;
48+ capture ( 'restore_tutorial_canvas_clicked' ) ;
49+
50+ // Fetch the default canvas data from the backend
51+ const response = await fetch ( '/api/canvas/default' , {
52+ method : 'GET' ,
53+ credentials : 'include'
54+ } ) ;
55+
56+ if ( ! response . ok ) {
57+ throw new Error ( `Failed to fetch default canvas: ${ response . statusText } ` ) ;
58+ }
59+
60+ const defaultCanvasData = await response . json ( ) ;
61+
62+ // Normalize the canvas data before updating the scene
63+ const normalizedData = normalizeCanvasData ( defaultCanvasData ) ;
64+
65+ // Update the canvas with the normalized default data
66+ excalidrawAPI . updateScene ( normalizedData ) ;
67+
68+ console . log ( "Canvas reset to default successfully" ) ;
69+
70+ // Close the dialog after successful restore
71+ handleClose ( ) ;
72+ } catch ( error ) {
73+ console . error ( "Failed to reset canvas:" , error ) ;
74+ } finally {
75+ setIsRestoring ( false ) ;
76+ setShowRestoreConfirmation ( false ) ;
77+ }
78+ } ;
79+
3880 /**
3981 * Updates a specific setting and syncs it with the excalidraw app state
4082 * @param key The setting key to update
@@ -92,6 +134,42 @@ const SettingsDialog: React.FC<SettingsDialogProps> = ({
92134 </ div >
93135 </ div >
94136 </ div >
137+
138+ < div className = "settings-dialog__section" >
139+ < h3 className = "settings-dialog__section-title" > Canvas Management</ h3 >
140+ { showRestoreConfirmation ? (
141+ < div className = "settings-dialog__confirmation" >
142+ < p > Are you sure you want to restore the tutorial canvas?</ p >
143+ < p className = "settings-dialog__warning" > This will replace your current canvas and cannot be undone!</ p >
144+ < div className = "settings-dialog__actions" >
145+ < button
146+ className = "settings-dialog__button settings-dialog__button--restore"
147+ onClick = { handleRestoreTutorialCanvas }
148+ disabled = { isRestoring }
149+ >
150+ { isRestoring ? "Restoring..." : "Yes, Restore" }
151+ </ button >
152+ < button
153+ className = "settings-dialog__button settings-dialog__button--cancel"
154+ onClick = { ( ) => setShowRestoreConfirmation ( false ) }
155+ disabled = { isRestoring }
156+ >
157+ Cancel
158+ </ button >
159+ </ div >
160+ </ div >
161+ ) : (
162+ < div className = "settings-dialog__setting" >
163+ < button
164+ className = "settings-dialog__restore-button"
165+ onClick = { ( ) => setShowRestoreConfirmation ( true ) }
166+ >
167+ < RefreshCw size = { 16 } />
168+ < span > Restore Tutorial Canvas</ span >
169+ </ button >
170+ </ div >
171+ ) }
172+ </ div >
95173 </ div >
96174 ) ;
97175
0 commit comments