Fix: Form submission refresh bug and resolve TypeScript type errors

- Add explicit type=button to frame and step buttons to prevent unwanted form submission
- Move e.preventDefault() form submission logic into useNewGuide hook
- Fix TypeScript assignment error by adding 'title' to initial frame objects
- Export CompiledGuideType and update schema type references
This commit is contained in:
johannes-hernehult 2026-06-14 20:14:08 +02:00
parent 1bb6ddf403
commit 0f70457d29
5 changed files with 48 additions and 14 deletions

View file

@ -16,9 +16,18 @@ export default function Frame({
}) {
return (
<div>
<button onClick={() => onRemove(frame.id)}>Remove Frame</button>
<button type="button" onClick={() => onRemove(frame.id)}>
Remove Frame
</button>
<label>Title</label>
<input
type="text"
onChange={(e) => updateStep(frame.id, e.target.value)}
/>
<img src={URL.createObjectURL(frame.file)} alt={frame.title} />
<button onClick={() => addStep(frame.id)}>Add Step</button>
<button type="button" onClick={() => addStep(frame.id)}>
Add Step
</button>
{frame.steps.map((step: StepType, index: number) => (
<Step
key={step.id}

View file

@ -21,7 +21,9 @@ export default function Step({
onChange={(e) => updateStep(step.id, e.target.value)}
/>
</label>
<button onClick={() => removeStep(step.id)}>Remove Step</button>
<button type="button" onClick={() => removeStep(step.id)}>
Remove Step
</button>
</div>
);
}

View file

@ -1,8 +1,12 @@
import { useState } from "react";
import { type Frame, type Guide, type Steps } from "../../../lib/schemas";
import {
type CompiledGuideType,
type FrameType,
type GuideType,
} from "../../../lib/schemas";
export default function useNewGuide() {
const [guide, setGuide] = useState<Guide>({
const [guide, setGuide] = useState<GuideType>({
id: crypto.randomUUID(),
title: "",
description: "",
@ -10,7 +14,7 @@ export default function useNewGuide() {
updatedAt: new Date(),
deletedAt: undefined,
});
const [frames, setFrames] = useState<Frame[]>([]);
const [frames, setFrames] = useState<FrameType[]>([]);
const handleUpdateTitle = (title: string) => {
setGuide((prev) => ({ ...prev, title }));
@ -31,6 +35,7 @@ export default function useNewGuide() {
return {
id: frameId,
file: file,
title: "",
guideId: guide.id,
steps: [{ id: crypto.randomUUID(), text: "", frameId: frameId }],
};
@ -87,9 +92,16 @@ export default function useNewGuide() {
);
};
const handleSaveGuide = () => {
const compiledGuide = {
...guide,
const handleSaveGuide = (e: React.SubmitEvent<HTMLFormElement>) => {
e.preventDefault();
const compiledGuide: CompiledGuideType = {
id: guide.id,
title: guide.title,
description: guide.description,
createdAt: guide.createdAt,
updatedAt: guide.updatedAt,
deletedAt: guide.deletedAt,
frames,
};

View file

@ -15,14 +15,10 @@ export default function NewGuide() {
handleUpdateStep,
handleSaveGuide,
} = useNewGuide();
const handleSubmitForm = (e: React.SubmitEvent<HTMLFormElement>) => {
e.preventDefault();
console.log(e.currentTarget);
};
return (
<div className="new-guide">
<form className="new-guide__form" onSubmit={handleSubmitForm}>
<form className="new-guide__form" onSubmit={(e) => handleSaveGuide(e)}>
<label>
<span>Title</span>
<input type="text" name="title" />
@ -45,6 +41,12 @@ export default function NewGuide() {
updateStep={handleUpdateStep}
/>
))}
{frames.length === 0 && <p>No frames added yet.</p>}
{frames.length > 0 && <FileUpload onChange={handleAddFrames} />}
<button type="submit">Save</button>
</form>
</div>
);

View file

@ -26,3 +26,12 @@ export const GuideSchema = z.object({
export type StepType = z.infer<typeof StepsSchema>;
export type FrameType = z.infer<typeof FrameSchema>;
export type GuideType = z.infer<typeof GuideSchema>;
export type CompiledGuideType = {
id: string;
title: string;
description: string | undefined;
createdAt: Date;
updatedAt: Date;
deletedAt: Date | undefined;
frames: FrameType[];
};