Files
wehub-resource-sync e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:40:13 +08:00

167 lines
5.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { type FormEvent, useCallback, useState } from "react";
interface ApplyFormProps {
roleTitle: string;
}
export const ApplyForm = ({ roleTitle }: ApplyFormProps) => {
const [fallbackVisible, setFallbackVisible] = useState(false);
const [mailtoHref, setMailtoHref] = useState("");
const [composedBody, setComposedBody] = useState("");
const [copyStatus, setCopyStatus] = useState<"idle" | "success" | "error">(
"idle",
);
const handleSubmit = useCallback(
(event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
const form = event.currentTarget;
const formData = new FormData(form);
const fullName = (formData.get("full_name") as string)?.trim() ?? "";
const urlsRaw = (formData.get("urls") as string)?.trim() ?? "";
const notes = (formData.get("notes") as string)?.trim() ?? "";
const urlLines = urlsRaw
.split(/\r?\n/)
.map((line) => line.trim())
.filter(Boolean)
.map((line) => `- ${line}`);
const bodyLines = [
"Hello,",
"",
`I am applying for the ${roleTitle} role.`,
"",
"Here are a few interesting links to showcase my profile:",
urlLines.length ? urlLines.join("\n") : "-",
];
if (notes) {
bodyLines.push("", notes);
}
bodyLines.push("", "Best,", fullName || "");
const body = bodyLines.join("\n");
const mailto = `mailto:careers@assistant-ui.com?subject=${encodeURIComponent(
`Application: ${roleTitle}`,
)}&body=${encodeURIComponent(body)}`;
// Attempt to open the user's default mail client.
// If it doesn't open (no handler configured), reveal fallbacks.
setComposedBody(body);
setMailtoHref(mailto);
setFallbackVisible(true);
try {
window.location.href = mailto;
} catch {
// No-op: rely on the fallback UI
}
},
[roleTitle],
);
return (
<form onSubmit={handleSubmit} className="grid gap-5">
<label className="grid gap-2 text-sm">
<span className="text-foreground font-medium">Full Name</span>
<input
type="text"
name="full_name"
required
autoComplete="name"
className="border-border bg-background focus:border-primary rounded-lg border px-3 py-2 text-base shadow-sm ring-0 transition outline-none"
placeholder="Ada Lovelace"
/>
</label>
<label className="grid gap-2 text-sm">
<span className="text-foreground font-medium">
URLs that best describe you
</span>
<textarea
name="urls"
required
rows={3}
className="border-border bg-background focus:border-primary rounded-lg border px-3 py-2 text-base shadow-sm ring-0 transition outline-none"
placeholder="Portfolio, GitHub, LinkedIn, blog one per line"
></textarea>
</label>
<label className="grid gap-2 text-sm">
<span className="text-foreground font-medium">
Anything else?{" "}
<span className="text-muted-foreground">(optional)</span>
</span>
<textarea
name="notes"
rows={4}
className="border-border bg-background focus:border-primary rounded-lg border px-3 py-2 text-base shadow-sm ring-0 transition outline-none"
placeholder="Tell us about goals, timelines, or anything you'd like us to know."
></textarea>
</label>
<button
type="submit"
className="border-border text-foreground hover:border-primary hover:bg-primary/5 hover:text-primary inline-flex w-fit items-center justify-center rounded-full border px-5 py-2 text-sm font-medium transition"
>
Apply now
</button>
{fallbackVisible ? (
<div className="border-border/70 bg-background/50 mt-2 grid gap-2 rounded-lg border border-dashed p-3">
<p className="text-muted-foreground text-xs">
If your email client didn&apos;t open, use the options below.
</p>
<div className="flex flex-wrap items-center gap-2">
<a
href={mailtoHref}
className="border-border text-foreground hover:border-primary hover:bg-primary/5 hover:text-primary inline-flex items-center justify-center rounded-full border px-4 py-1.5 text-xs font-medium transition"
>
Open email client
</a>
<button
type="button"
className="border-border text-foreground hover:border-primary hover:bg-primary/5 hover:text-primary inline-flex items-center justify-center rounded-full border px-4 py-1.5 text-xs font-medium transition"
onClick={async () => {
try {
const text = `To: careers@assistant-ui.com
Subject: Application: ${roleTitle}
${composedBody}`;
await navigator.clipboard.writeText(text);
setCopyStatus("success");
setTimeout(() => setCopyStatus("idle"), 2000);
} catch {
setCopyStatus("error");
setTimeout(() => setCopyStatus("idle"), 2000);
}
}}
>
Copy email text
</button>
<span className="text-muted-foreground text-xs">
{copyStatus === "success"
? "Copied!"
: copyStatus === "error"
? "Copy failed"
: ""}
</span>
</div>
<p className="text-muted-foreground text-[11px]">
Or email{" "}
<span className="text-foreground font-medium">
careers@assistant-ui.com
</span>{" "}
with the subject &quot;Application: {roleTitle}&quot;.
</p>
</div>
) : null}
</form>
);
};