66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
// Displays a single secret with discovered checkbox and text.
|
|
import { AutoSaveTextarea } from "@/components/AutoSaveTextarea";
|
|
import { useDocumentCache } from "@/context/document/hooks";
|
|
import { pb } from "@/lib/pocketbase";
|
|
import type { Secret } from "@/lib/types";
|
|
import { useState } from "react";
|
|
|
|
/**
|
|
* Renders an editable secret form.
|
|
* Handles updating the discovered state and discoveredIn relationship.
|
|
*/
|
|
export const SecretEditForm = ({ secret }: { secret: Secret }) => {
|
|
const { dispatch } = useDocumentCache();
|
|
const [checked, setChecked] = useState(
|
|
!!(secret.data as any)?.secret?.discovered,
|
|
);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
async function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
|
|
const newChecked = e.target.checked;
|
|
setLoading(true);
|
|
setChecked(newChecked);
|
|
try {
|
|
const updated: Secret = await pb
|
|
.collection("documents")
|
|
.update(secret.id, {
|
|
data: {
|
|
...secret.data,
|
|
discovered: newChecked,
|
|
},
|
|
});
|
|
dispatch({ type: "setDocument", doc: updated });
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
async function saveText(text: string) {
|
|
const updated: Secret = await pb.collection("documents").update(secret.id, {
|
|
data: {
|
|
...secret.data,
|
|
text,
|
|
},
|
|
});
|
|
dispatch({ type: "setDocument", doc: updated });
|
|
}
|
|
|
|
return (
|
|
<div className="flex items-center gap-3">
|
|
<input
|
|
type="checkbox"
|
|
checked={checked}
|
|
onChange={handleChange}
|
|
className="accent-emerald-500 w-5 h-5"
|
|
aria-label="Discovered"
|
|
disabled={loading}
|
|
/>
|
|
<AutoSaveTextarea
|
|
multiline={false}
|
|
value={secret.data.text}
|
|
onSave={saveText}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|