mirror of
https://github.com/priyanshujain/margin.git
synced 2026-10-02 19:17:03 +00:00
feat(settings): draft Book setup, commit changes only on Save
This commit is contained in:
1 parent
008e22c36c
commit
041619821f
1 file changed
+36
-14
+36
-14
@@ -1,3 +1,4 @@
|
|||||||
|
import { useState } from "react";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useBook } from "../store/useBook";
|
import { useBook } from "../store/useBook";
|
||||||
import { Icon } from "./Icon";
|
import { Icon } from "./Icon";
|
||||||
@@ -11,6 +12,15 @@ const LANGUAGES = [
|
|||||||
{ value: "pt", label: "Portuguese" },
|
{ value: "pt", label: "Portuguese" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
interface Draft {
|
||||||
|
title: string;
|
||||||
|
subtitle: string;
|
||||||
|
author: string;
|
||||||
|
isbn: string;
|
||||||
|
language: string;
|
||||||
|
bleed: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
function Field({ label, children }: { label: string; children: ReactNode }) {
|
function Field({ label, children }: { label: string; children: ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<label className="field">
|
<label className="field">
|
||||||
@@ -25,8 +35,26 @@ export function Settings({ onClose, onSave }: { onClose: () => void; onSave: ()
|
|||||||
const setMetadata = useBook((s) => s.setMetadata);
|
const setMetadata = useBook((s) => s.setMetadata);
|
||||||
const setSettings = useBook((s) => s.setSettings);
|
const setSettings = useBook((s) => s.setSettings);
|
||||||
|
|
||||||
|
const [draft, setDraft] = useState<Draft>(() => ({
|
||||||
|
title: book?.metadata.title ?? "",
|
||||||
|
subtitle: book?.metadata.subtitle ?? "",
|
||||||
|
author: book?.metadata.author ?? "",
|
||||||
|
isbn: book?.metadata.isbn ?? "",
|
||||||
|
language: book?.metadata.language ?? "en",
|
||||||
|
bleed: book?.settings.bleed ?? true,
|
||||||
|
}));
|
||||||
|
|
||||||
if (!book) return null;
|
if (!book) return null;
|
||||||
const { metadata, settings } = book;
|
|
||||||
|
const set = (patch: Partial<Draft>) => setDraft((d) => ({ ...d, ...patch }));
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
const { bleed, ...metadata } = draft;
|
||||||
|
setMetadata(metadata);
|
||||||
|
setSettings({ bleed });
|
||||||
|
onSave();
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overlay" onClick={onClose}>
|
<div className="overlay" onClick={onClose}>
|
||||||
@@ -39,19 +67,19 @@ export function Settings({ onClose, onSave }: { onClose: () => void; onSave: ()
|
|||||||
</div>
|
</div>
|
||||||
<div className="panel-body">
|
<div className="panel-body">
|
||||||
<Field label="Title">
|
<Field label="Title">
|
||||||
<input value={metadata.title} placeholder="Untitled" onChange={(e) => setMetadata({ title: e.target.value })} />
|
<input value={draft.title} placeholder="Untitled" onChange={(e) => set({ title: e.target.value })} />
|
||||||
</Field>
|
</Field>
|
||||||
<Field label="Subtitle">
|
<Field label="Subtitle">
|
||||||
<input value={metadata.subtitle} onChange={(e) => setMetadata({ subtitle: e.target.value })} />
|
<input value={draft.subtitle} onChange={(e) => set({ subtitle: e.target.value })} />
|
||||||
</Field>
|
</Field>
|
||||||
<Field label="Author">
|
<Field label="Author">
|
||||||
<input value={metadata.author} onChange={(e) => setMetadata({ author: e.target.value })} />
|
<input value={draft.author} onChange={(e) => set({ author: e.target.value })} />
|
||||||
</Field>
|
</Field>
|
||||||
<Field label="ISBN">
|
<Field label="ISBN">
|
||||||
<input value={metadata.isbn} placeholder="optional" onChange={(e) => setMetadata({ isbn: e.target.value })} />
|
<input value={draft.isbn} placeholder="optional" onChange={(e) => set({ isbn: e.target.value })} />
|
||||||
</Field>
|
</Field>
|
||||||
<Field label="Language">
|
<Field label="Language">
|
||||||
<select value={metadata.language} onChange={(e) => setMetadata({ language: e.target.value })}>
|
<select value={draft.language} onChange={(e) => set({ language: e.target.value })}>
|
||||||
{LANGUAGES.map((l) => (
|
{LANGUAGES.map((l) => (
|
||||||
<option key={l.value} value={l.value}>
|
<option key={l.value} value={l.value}>
|
||||||
{l.label}
|
{l.label}
|
||||||
@@ -60,18 +88,12 @@ export function Settings({ onClose, onSave }: { onClose: () => void; onSave: ()
|
|||||||
</select>
|
</select>
|
||||||
</Field>
|
</Field>
|
||||||
<label className="check">
|
<label className="check">
|
||||||
<input type="checkbox" checked={settings.bleed} onChange={(e) => setSettings({ bleed: e.target.checked })} />
|
<input type="checkbox" checked={draft.bleed} onChange={(e) => set({ bleed: e.target.checked })} />
|
||||||
Add bleed for full-page images (print)
|
Add bleed for full-page images (print)
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="panel-foot">
|
<div className="panel-foot">
|
||||||
<button
|
<button className="btn-primary" onClick={save}>
|
||||||
className="btn-primary"
|
|
||||||
onClick={() => {
|
|
||||||
onSave();
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in new issue
Block a user