-
-
-
- Prompt result
-
-
- {loading ? "Generating..." : "Ready"}
-
-
+ <>
+
+
+
+
+
+
+
+
+ {brief.mode === "simple" ? "Simple mode" : "Guided mode"}
+
+
+ {loading
+ ? "Forging your prompt..."
+ : error
+ ? "The forge cooled down"
+ : "Your prompt is ready"}
+
+
+ {brief.mode === "simple"
+ ? "A plain-language request went into the kiln. The result below is ready to copy."
+ : "Your structured brief went into the kiln. The result below is tuned to your details."}
+
+
-
- {copySuccess ? (
- <>
+
+ {copySuccess ? (
- Copied
- >
- ) : (
- <>
+ ) : (
- Copy
- >
- )}
-
-
-
-
- {briefCards.map((item) => (
-
-
- {item.label}
-
-
{item.value}
-
- ))}
-
+ )}
+ {copySuccess ? "Copied" : "Copy prompt"}
+
+
-
- {loading ? (
-
- Generating your prompt...
-
- ) : error ? (
-
{error}
- ) : (
-
- {generatedPrompt}
-
- )}
+
+ {loading ? (
+
+ ) : error ? (
+
+ {error}
+
+ ) : (
+
+ {generatedPrompt}
+
+ )}
+
-
-
-
+
+
+ >
);
}
export default function BuildPage() {
- return (
- <>
-
-
-
-
- >
- );
+ return
;
}
diff --git a/app/page.tsx b/app/page.tsx
index 47812dd..e7ee302 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -6,7 +6,9 @@ import { useRouter } from "next/navigation";
import { ArrowRight, Sparkles } from "lucide-react";
import { Navbar } from "@/components/layout/Navbar";
-type FormState = {
+type Mode = "guided" | "simple";
+
+type GuidedFormState = {
businessName: string;
businessType: string;
topic: string;
@@ -19,7 +21,7 @@ type FormState = {
notes: string;
};
-const INITIAL_STATE: FormState = {
+const INITIAL_GUIDED_STATE: GuidedFormState = {
businessName: "",
businessType: "",
topic: "",
@@ -82,10 +84,29 @@ const PLATFORM_OPTIONS = [
"Other",
];
-function buildQueryParams(form: FormState) {
+function buildQueryParams(
+ mode: Mode,
+ guidedForm: GuidedFormState,
+ description: string,
+) {
const params = new URLSearchParams();
+ params.set("mode", mode);
+ if (mode === "simple") {
+ const trimmed = description.trim();
+ if (trimmed) {
+ if (trimmed.length > 2000) {
+ if (typeof window !== "undefined") {
+ window.sessionStorage.setItem("forge_description", trimmed);
+ }
+ params.set("description_stored", "true");
+ } else {
+ params.set("description", trimmed);
+ }
+ }
+ return params;
+ }
- Object.entries(form).forEach(([key, value]) => {
+ Object.entries(guidedForm).forEach(([key, value]) => {
const trimmed = value.trim();
if (trimmed) {
params.set(key, trimmed);
@@ -105,55 +126,63 @@ function FieldLabel({
htmlFor?: string;
}) {
return (
-
-
- {title}
-
+
+ {title}
{description ? (
- {description}
+ {description}
) : null}
-
+
);
}
export default function HomePage() {
const router = useRouter();
- const [form, setForm] = useState
(INITIAL_STATE);
+ const [mode, setMode] = useState("guided");
+ const [guidedForm, setGuidedForm] = useState(INITIAL_GUIDED_STATE);
+ const [description, setDescription] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
const [formError, setFormError] = useState(null);
- const formSummary = useMemo(() => {
- const pieces = [form.businessName, form.topic, form.task].filter(Boolean);
+ const guidedSummary = useMemo(() => {
+ const pieces = [guidedForm.businessName, guidedForm.topic, guidedForm.task].filter(Boolean);
return pieces.length ? pieces.join(" · ") : "Build a more tailored prompt";
- }, [form.businessName, form.topic, form.task]);
+ }, [guidedForm.businessName, guidedForm.topic, guidedForm.task]);
+
+ const simpleSummary = useMemo(() => {
+ const trimmed = description.trim();
+ return trimmed ? trimmed.slice(0, 90) : "Describe the prompt in your own words";
+ }, [description]);
- const handleChange = (
- event: ChangeEvent<
- HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
- >,
+ const handleGuidedChange = (
+ event: ChangeEvent,
) => {
const { name, value } = event.target;
- setForm((current) => ({ ...current, [name]: value }));
+ setGuidedForm((current) => ({ ...current, [name]: value }));
setFormError(null);
};
- const handleSubmit = (event: FormEvent) => {
+ const handleSubmit = (event: FormEvent) => {
event.preventDefault();
- setIsSubmitting(true);
- setFormError(null);
- try {
- const params = buildQueryParams(form);
- const query = params.toString();
+ if (mode === "simple" && !description.trim()) {
+ setFormError("Please describe what you need first.");
+ return;
+ }
- if (!query) {
- setFormError(
- "Please provide at least one detail before generating a prompt.",
- );
+ if (mode === "guided") {
+ const hasAnyValue = Object.values(guidedForm).some((value) => value.trim().length > 0);
+ if (!hasAnyValue) {
+ setFormError("Please provide at least one detail before generating a prompt.");
return;
}
+ }
- router.push(`/build?${query}`);
+ setIsSubmitting(true);
+ setFormError(null);
+
+ try {
+ const params = buildQueryParams(mode, guidedForm, description);
+ router.push(`/build?${params.toString()}`);
} finally {
setIsSubmitting(false);
}
@@ -162,239 +191,256 @@ export default function HomePage() {
return (
<>
+
+
+
+
+
+
+
+ Prompt generation with a sharper brief
+
+
+ {
+ setMode("guided");
+ setFormError(null);
+ }}
+ className={`rounded-full px-4 py-2 text-sm font-semibold transition ${
+ mode === "guided"
+ ? "bg-ink text-surface"
+ : "text-muted hover:bg-black/5 hover:text-ink"
+ }`}
+ >
+ Guided
+
+ {
+ setMode("simple");
+ setFormError(null);
+ }}
+ className={`rounded-full px-4 py-2 text-sm font-semibold transition ${
+ mode === "simple"
+ ? "bg-ink text-surface"
+ : "text-muted hover:bg-black/5 hover:text-ink"
+ }`}
+ >
+ Simple
+
+
+
-
-
-
-
-
-
-
-
- Prompt generation with a sharper brief
-
-
-
- Tell us the shape of the task.
- Get a better prompt.
-
-
-
- PromptForge turns loose ideas into a structured brief and then
- into a ready-to-paste prompt. Add a few details and the AI can
- aim with a steadier hand.
-
-
-