saving might work idk
This commit is contained in:
@@ -8,11 +8,12 @@ import { Markdown } from "@tiptap/markdown";
|
||||
import { HomelabApp } from "@/types";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { useEffect, useState } from "react";
|
||||
import Menubar from "./menu-bar"; // Added menubar import back
|
||||
import Menubar from "./menu-bar";
|
||||
|
||||
interface TextEditorProps {
|
||||
content: string;
|
||||
onSave: (content: string, linkedAppIds: string[]) => void;
|
||||
initialTitle?: string;
|
||||
onSave: (content: string, linkedAppIds: string[], title: string) => void;
|
||||
initialLinkedAppIds?: string[];
|
||||
}
|
||||
|
||||
@@ -22,14 +23,21 @@ const getApps = async (): Promise<HomelabApp[]> => {
|
||||
|
||||
export default function TextEditor({
|
||||
content,
|
||||
initialTitle = "",
|
||||
onSave,
|
||||
initialLinkedAppIds = [],
|
||||
}: TextEditorProps) {
|
||||
const [availableApps, setAvailableApps] = useState<HomelabApp[]>([]);
|
||||
const [linkedAppIds, setLinkedAppIds] =
|
||||
useState<string[]>(initialLinkedAppIds);
|
||||
// Title control state
|
||||
const [title, setTitle] = useState<string>(initialTitle);
|
||||
// Save control
|
||||
// Will be saved on completed handleSave, error if func fails, and saving if the func is in progress
|
||||
const [isSaved, setIsSaved] = useState<"saved" | "error" | "saving">(
|
||||
"saving",
|
||||
);
|
||||
|
||||
// 🔄 FIX: Watch for updates to initialLinkedAppIds once fetched from the URL
|
||||
useEffect(() => {
|
||||
if (initialLinkedAppIds.length > 0) {
|
||||
setLinkedAppIds(initialLinkedAppIds);
|
||||
@@ -44,8 +52,6 @@ export default function TextEditor({
|
||||
fetchApps();
|
||||
}, []);
|
||||
|
||||
// ... rest of your TextEditor component stays the same
|
||||
|
||||
const editor = useEditor({
|
||||
extensions: [
|
||||
StarterKit.configure({
|
||||
@@ -57,7 +63,7 @@ export default function TextEditor({
|
||||
Markdown,
|
||||
],
|
||||
immediatelyRender: false,
|
||||
content: content || "<p>Start typing your documentation notes here...</p>",
|
||||
content,
|
||||
editorProps: {
|
||||
attributes: {
|
||||
class: "prose max-w-none focus:outline-none min-h-[300px]",
|
||||
@@ -66,32 +72,64 @@ export default function TextEditor({
|
||||
});
|
||||
|
||||
const toggleAppLink = (appId: string) => {
|
||||
setLinkedAppIds(
|
||||
(prev) =>
|
||||
prev.includes(appId)
|
||||
? prev.filter((id) => id !== appId) // Unlink if already added
|
||||
: [...prev, appId], // Link if not added
|
||||
setLinkedAppIds((prev) =>
|
||||
prev.includes(appId)
|
||||
? prev.filter((id) => id !== appId)
|
||||
: [...prev, appId],
|
||||
);
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
if (!editor) return;
|
||||
const htmlOutput = editor.getHTML();
|
||||
// Pass both the layout structure and the entire linked app set
|
||||
onSave(htmlOutput, linkedAppIds);
|
||||
setIsSaved("saving");
|
||||
try {
|
||||
if (!editor) return;
|
||||
const htmlOutput = editor.getHTML();
|
||||
// Dispatch text body layout, assets collection array, and document title string
|
||||
onSave(htmlOutput, linkedAppIds, title);
|
||||
setIsSaved("saved");
|
||||
} catch (error) {
|
||||
console.error("Error saving document:", error);
|
||||
setIsSaved("error");
|
||||
}
|
||||
};
|
||||
|
||||
// create debounced save, every 15 seconds
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
handleSave();
|
||||
}, 15000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [editor, linkedAppIds, title]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4 w-full">
|
||||
{/* Top action bar */}
|
||||
<div className="flex justify-between items-center pb-2 border-b border-zinc-100">
|
||||
<span className="text-sm text-zinc-400 font-medium">Draft Session</span>
|
||||
<button
|
||||
onClick={handleSave}
|
||||
className="px-4 py-1.5 bg-emerald-600 hover:bg-emerald-700 text-white font-medium text-sm rounded-md transition-colors"
|
||||
>
|
||||
Save Changes
|
||||
</button>
|
||||
{/* Top action bar updated with live Title Input */}
|
||||
<div className="flex justify-between items-center pb-2 border-b border-zinc-100 gap-4">
|
||||
<input
|
||||
type="text"
|
||||
value={title}
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
placeholder="Untitled Document..."
|
||||
className="bg-transparent text-zinc-800 font-semibold text-base placeholder-zinc-300 focus:outline-none flex-1 py-1"
|
||||
/>
|
||||
<div className="flex items-center gap-2">
|
||||
{isSaved === "saving" && (
|
||||
<span className="text-xs text-zinc-400">Saving...</span>
|
||||
)}
|
||||
{isSaved === "saved" && (
|
||||
<span className="text-xs text-emerald-600">Saved</span>
|
||||
)}
|
||||
{isSaved === "error" && (
|
||||
<span className="text-xs text-red-600">Error saving</span>
|
||||
)}
|
||||
<button
|
||||
onClick={handleSave}
|
||||
className="px-4 py-1.5 bg-emerald-600 hover:bg-emerald-700 text-white font-medium text-sm rounded-md transition-colors shrink-0"
|
||||
>
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Editor Controls */}
|
||||
@@ -129,9 +167,8 @@ export default function TextEditor({
|
||||
: "bg-white border-zinc-200 hover:border-zinc-300"
|
||||
}`}
|
||||
>
|
||||
{/* Subtle active border indicator */}
|
||||
{isLinked && (
|
||||
<div className="absolute top-0 right-0 h-0 w-0 border-t-[16px] border-t-emerald-500 border-l-[16px] border-l-transparent" />
|
||||
<div className="absolute top-0 right-0 h-0 w-0 border-t-16 border-t-emerald-500 border-l-16 border-l-transparent" />
|
||||
)}
|
||||
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user