Skip to content

Commit f6a21ad

Browse files
authored
feat: add new pad creation functionality in PadsDialog (#84)
- Implemented a button for creating new pads, enhancing user interaction within the PadsDialog. - Added state management for the creation process, including loading and error handling. - Integrated analytics tracking for pad creation events to improve user insights. - Updated styling for the new pad button to ensure a consistent UI experience.
1 parent 5e97bc8 commit f6a21ad

File tree

2 files changed

+71
-2
lines changed

2 files changed

+71
-2
lines changed

src/frontend/src/ui/PadsDialog.scss

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,34 @@
2121
font-size: 1.2rem;
2222
font-weight: 600;
2323
}
24+
25+
&__new-pad-button {
26+
display: flex;
27+
align-items: center;
28+
gap: 0.5rem;
29+
padding: 0.4rem 0.8rem;
30+
border-radius: 4px;
31+
border: none;
32+
background-color: #cc6d24;
33+
color: white;
34+
font-size: 0.9rem;
35+
cursor: pointer;
36+
transition: background-color 0.2s ease;
37+
38+
&:hover {
39+
background-color: #b05e1f;
40+
}
41+
42+
&:disabled {
43+
opacity: 0.6;
44+
cursor: not-allowed;
45+
}
46+
47+
&--creating {
48+
opacity: 0.7;
49+
cursor: wait;
50+
}
51+
}
2452

2553
&__content {
2654
padding: 1rem;

src/frontend/src/ui/PadsDialog.tsx

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React, { useState, useCallback } from "react";
22
import { Dialog } from "@atyrode/excalidraw";
3-
import { Pencil, Trash2 } from "lucide-react";
3+
import { Pencil, Trash2, FilePlus2 } from "lucide-react";
44
import { useAllPads, useRenamePad, useDeletePad, PadData } from "../api/hooks";
5-
import { loadPadData, getActivePad, setActivePad, saveCurrentPadBeforeSwitching } from "../utils/canvasUtils";
5+
import { loadPadData, getActivePad, setActivePad, saveCurrentPadBeforeSwitching, createNewPad } from "../utils/canvasUtils";
66
import { queryClient } from "../api/queryClient";
77
import { capture } from "../utils/posthog";
88
import "./PadsDialog.scss";
@@ -21,6 +21,7 @@ const PadsDialog: React.FC<PadsDialogProps> = ({
2121
const activePadId = getActivePad();
2222
const [editingPadId, setEditingPadId] = useState<string | null>(null);
2323
const [newPadName, setNewPadName] = useState("");
24+
const [isCreatingPad, setIsCreatingPad] = useState(false);
2425

2526
// Get the renamePad mutation
2627
const { mutate: renamePad } = useRenamePad({
@@ -76,6 +77,37 @@ const PadsDialog: React.FC<PadsDialogProps> = ({
7677
}
7778
});
7879

80+
const handleCreateNewPad = async () => {
81+
if (isCreatingPad || !excalidrawAPI) return; // Prevent multiple clicks or if API not available
82+
83+
try {
84+
setIsCreatingPad(true);
85+
86+
// Create a new pad using the imported function
87+
// Note: createNewPad already updates the query cache internally
88+
const newPad = await createNewPad(excalidrawAPI, activePadId, (data) => {
89+
console.debug("[pad.ws] Canvas saved before creating new pad");
90+
});
91+
92+
// Track pad creation event
93+
capture("pad_created", {
94+
padId: newPad.id,
95+
padName: newPad.display_name
96+
});
97+
98+
// Set the new pad as active and load it
99+
setActivePad(newPad.id);
100+
loadPadData(excalidrawAPI, newPad.id, newPad.data);
101+
102+
// Close the dialog
103+
handleClose();
104+
} catch (error) {
105+
console.error('[pad.ws] Error creating new pad:', error);
106+
} finally {
107+
setIsCreatingPad(false);
108+
}
109+
};
110+
79111
const handleClose = useCallback(() => {
80112
setModalIsShown(false);
81113
if (onClose) {
@@ -265,6 +297,15 @@ const PadsDialog: React.FC<PadsDialogProps> = ({
265297
<h2 className="pads-dialog__title">
266298
Manage Pads
267299
</h2>
300+
<button
301+
className={`pads-dialog__new-pad-button ${isCreatingPad ? 'pads-dialog__new-pad-button--creating' : ''}`}
302+
onClick={handleCreateNewPad}
303+
disabled={isCreatingPad || !excalidrawAPI}
304+
title="Create new pad"
305+
>
306+
<FilePlus2 size={18} />
307+
<span>New Pad</span>
308+
</button>
268309
</div>
269310
}
270311
closeOnClickOutside={true}

0 commit comments

Comments
 (0)