97 lines
2.0 KiB
TypeScript
97 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { MediaPicker } from "./media-picker";
|
|
import { RichText } from "./rich-text";
|
|
|
|
export function ArticleForm({
|
|
action,
|
|
defaultValues,
|
|
}: {
|
|
action: (formData: FormData) => Promise<void>;
|
|
defaultValues?: {
|
|
title?: string;
|
|
image?: string;
|
|
shortStory?: string;
|
|
fullStory?: string;
|
|
};
|
|
}) {
|
|
const [image, setImage] = useState(defaultValues?.image ?? "");
|
|
const [imageError, setImageError] = useState(false);
|
|
|
|
return (
|
|
<form
|
|
action={action}
|
|
className="card"
|
|
style={{ display: "grid", gap: "0.6rem" }}
|
|
>
|
|
<input
|
|
name="title"
|
|
defaultValue={defaultValues?.title ?? ""}
|
|
placeholder="Title"
|
|
required
|
|
/>
|
|
<div>
|
|
<div
|
|
style={{ display: "flex", gap: "0.5rem", alignItems: "flex-start" }}
|
|
>
|
|
<input
|
|
name="image"
|
|
value={image}
|
|
onChange={(e) => {
|
|
setImage(e.target.value);
|
|
setImageError(false);
|
|
}}
|
|
placeholder="Image URL"
|
|
style={{ flex: 1 }}
|
|
/>
|
|
<MediaPicker
|
|
onSelect={(url) => {
|
|
setImage(url);
|
|
setImageError(false);
|
|
}}
|
|
current={image}
|
|
/>
|
|
</div>
|
|
{image && !imageError ? (
|
|
// eslint-disable-next-line @next/next/no-img-element
|
|
<img
|
|
src={image}
|
|
alt="preview"
|
|
onError={() => setImageError(true)}
|
|
style={{
|
|
marginTop: "0.4rem",
|
|
maxHeight: 120,
|
|
borderRadius: 6,
|
|
objectFit: "cover",
|
|
}}
|
|
/>
|
|
) : null}
|
|
{imageError ? (
|
|
<p
|
|
className="muted"
|
|
style={{ margin: "0.3rem 0 0", fontSize: "0.78rem" }}
|
|
>
|
|
Image not found — enter a valid URL or browse.
|
|
</p>
|
|
) : null}
|
|
</div>
|
|
<textarea
|
|
name="shortStory"
|
|
defaultValue={defaultValues?.shortStory ?? ""}
|
|
placeholder="Short story (summary)"
|
|
rows={2}
|
|
/>
|
|
<RichText
|
|
name="fullStory"
|
|
defaultValue={defaultValues?.fullStory ?? ""}
|
|
placeholder="Full story"
|
|
rows={10}
|
|
/>
|
|
<button type="submit" className="btn btn-primary">
|
|
{defaultValues ? "Save" : "Create"}
|
|
</button>
|
|
</form>
|
|
);
|
|
}
|