GRV-Summit-Site/components/partners/ChampionStartupModal.tsx
“kirukib” 3693495dd0
Some checks are pending
Deploy to Cloudflare Workers (OpenNext) / deploy (push) Waiting to run
Add site-wide topography patterns and refine section styling.
Use mainwhite.svg on white sections with curvy green transitions into flat green bands, improve text and button contrast, and deploy via OpenNext on Cloudflare Workers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 20:34:36 +03:00

173 lines
5.8 KiB
TypeScript

"use client";
import { useState } from "react";
import { Rocket } from "lucide-react";
import { championStartupCopy } from "@/content/partners";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { DataConsentField } from "@/components/forms/DataConsentField";
import { dataConsent } from "@/content/consent";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
const sectors = ["Agriculture", "Healthcare", "Education", "Other"];
export function ChampionStartupModal() {
const [open, setOpen] = useState(false);
const [status, setStatus] = useState<"idle" | "loading" | "success" | "error">("idle");
const [error, setError] = useState("");
const [consent, setConsent] = useState(false);
const [sector, setSector] = useState<string>("");
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
if (!consent) {
setError(dataConsent.errorMessage);
return;
}
setStatus("loading");
setError("");
const form = e.currentTarget;
const data = new FormData(form);
try {
const res = await fetch("/api/inquiry", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
intent: "startup_referral",
name: data.get("name"),
email: data.get("email"),
startupName: data.get("startupName"),
startupWebsite: data.get("startupWebsite") || undefined,
startupSector: sector || undefined,
whyRecommend: data.get("whyRecommend"),
consent: true,
}),
});
const json = await res.json();
if (!res.ok || !json.ok) {
throw new Error(json.error || "Something went wrong");
}
setStatus("success");
form.reset();
setConsent(false);
setSector("");
setTimeout(() => {
setOpen(false);
setStatus("idle");
}, 2500);
} catch (err) {
setStatus("error");
setError(err instanceof Error ? err.message : "Failed to send");
}
}
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button
variant="outline"
className="rounded-full border-white/75 bg-transparent text-white hover:bg-white/12 hover:text-white"
>
<Rocket className="mr-2 size-4" />
{championStartupCopy.title}
</Button>
</DialogTrigger>
<DialogContent className="max-h-[90vh] max-w-lg overflow-y-auto">
<DialogHeader>
<DialogTitle>{championStartupCopy.title}</DialogTitle>
<DialogDescription>{championStartupCopy.intro}</DialogDescription>
</DialogHeader>
<p className="rounded-lg bg-muted/60 p-3 text-sm text-muted-foreground leading-relaxed">
{championStartupCopy.disclaimer}
</p>
<form onSubmit={onSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="champion-name">
Your name <span className="text-destructive">*</span>
</Label>
<Input id="champion-name" name="name" required />
</div>
<div className="space-y-2">
<Label htmlFor="champion-email">
Your email <span className="text-destructive">*</span>
</Label>
<Input id="champion-email" name="email" type="email" required />
</div>
<div className="space-y-2">
<Label htmlFor="startupName">
Startup name <span className="text-destructive">*</span>
</Label>
<Input id="startupName" name="startupName" required />
</div>
<div className="space-y-2">
<Label htmlFor="startupWebsite">Startup website (optional)</Label>
<Input id="startupWebsite" name="startupWebsite" type="url" placeholder="https://" />
</div>
<div className="space-y-2">
<Label>Sector</Label>
<Select value={sector} onValueChange={setSector}>
<SelectTrigger>
<SelectValue placeholder="Select sector" />
</SelectTrigger>
<SelectContent>
{sectors.map((s) => (
<SelectItem key={s} value={s}>
{s}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="whyRecommend">
Why do you recommend them? <span className="text-destructive">*</span>
</Label>
<Textarea
id="whyRecommend"
name="whyRecommend"
required
rows={4}
placeholder="Impact, traction, team, and fit with agriculture, health, or education…"
/>
</div>
<DataConsentField
id="champion-consent"
checked={consent}
onCheckedChange={setConsent}
/>
{error && <p className="text-sm text-destructive">{error}</p>}
{status === "success" && (
<p className="text-sm text-[#1a5c38]">Thank you for championing this startup!</p>
)}
<Button
type="submit"
className="w-full rounded-full bg-[#1f3d7e] hover:bg-[#1f3d7e]/90"
disabled={status === "loading"}
>
{status === "loading" ? "Submitting…" : "Submit recommendation"}
</Button>
</form>
</DialogContent>
</Dialog>
);
}