@burdenoff/website-sdk 2026.817.1 → 2026.824.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/partners.js.map +1 -1
- package/dist/components/partners.mjs.map +1 -1
- package/dist/content/index.js +25 -3
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +25 -3
- package/dist/content/index.mjs.map +1 -1
- package/dist/index.d.mts +31 -1
- package/dist/index.d.ts +31 -1
- package/dist/index.js +341 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +339 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -69,6 +69,36 @@ interface CareersApplyFormProps {
|
|
|
69
69
|
}
|
|
70
70
|
declare function CareersApplyForm({ productName, recaptchaSiteKey, positions, postings, heroTitle, heroDescription, headingLevel, maxResumeBytes, className, seo, }: CareersApplyFormProps): react_jsx_runtime.JSX.Element;
|
|
71
71
|
|
|
72
|
+
interface CareersSubmissionFormProps {
|
|
73
|
+
/** Product name (falls back to product context / SDK config). */
|
|
74
|
+
productName?: string;
|
|
75
|
+
/** reCAPTCHA site key (falls back to SDK config). */
|
|
76
|
+
recaptchaSiteKey?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Job postings for the dropdown (e.g. from `usePublicJobPostings`). When
|
|
79
|
+
* non-empty the selected posting's ID is sent as `jobPostingId` and its
|
|
80
|
+
* title as `position`. When empty, a free-text "position" input is shown
|
|
81
|
+
* instead so the form works before a postings list exists.
|
|
82
|
+
*/
|
|
83
|
+
postings?: readonly CareersPostingOption[];
|
|
84
|
+
heroTitle?: string;
|
|
85
|
+
heroDescription?: string;
|
|
86
|
+
/**
|
|
87
|
+
* `1` (default) renders a full page hero `<h1>`; `2` renders a compact
|
|
88
|
+
* `<h2>` section header for embedding under a page that owns the `<h1>`.
|
|
89
|
+
*/
|
|
90
|
+
headingLevel?: 1 | 2;
|
|
91
|
+
className?: string;
|
|
92
|
+
seo?: {
|
|
93
|
+
title?: string;
|
|
94
|
+
description?: string;
|
|
95
|
+
keywords?: string;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/** True when `value` parses as an absolute http(s) URL. */
|
|
99
|
+
declare function isValidUrl(value: string): boolean;
|
|
100
|
+
declare function CareersSubmissionForm({ productName, recaptchaSiteKey, postings, heroTitle, heroDescription, headingLevel, className, seo, }: CareersSubmissionFormProps): react_jsx_runtime.JSX.Element;
|
|
101
|
+
|
|
72
102
|
declare const buttonVariants: (props?: ({
|
|
73
103
|
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
74
104
|
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
@@ -95,4 +125,4 @@ declare const Textarea: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLP
|
|
|
95
125
|
*/
|
|
96
126
|
declare const ECOSYSTEM_PRODUCTS: WebsiteSwitcherProduct[];
|
|
97
127
|
|
|
98
|
-
export { Button, type ButtonProps, CareersApplyForm, type CareersApplyFormProps, type CareersPostingOption, ECOSYSTEM_PRODUCTS, Input, Label, Select, Textarea, WebsiteSwitcherProduct, buttonVariants };
|
|
128
|
+
export { Button, type ButtonProps, CareersApplyForm, type CareersApplyFormProps, type CareersPostingOption, CareersSubmissionForm, type CareersSubmissionFormProps, ECOSYSTEM_PRODUCTS, Input, Label, Select, Textarea, WebsiteSwitcherProduct, buttonVariants, isValidUrl };
|
package/dist/index.d.ts
CHANGED
|
@@ -69,6 +69,36 @@ interface CareersApplyFormProps {
|
|
|
69
69
|
}
|
|
70
70
|
declare function CareersApplyForm({ productName, recaptchaSiteKey, positions, postings, heroTitle, heroDescription, headingLevel, maxResumeBytes, className, seo, }: CareersApplyFormProps): react_jsx_runtime.JSX.Element;
|
|
71
71
|
|
|
72
|
+
interface CareersSubmissionFormProps {
|
|
73
|
+
/** Product name (falls back to product context / SDK config). */
|
|
74
|
+
productName?: string;
|
|
75
|
+
/** reCAPTCHA site key (falls back to SDK config). */
|
|
76
|
+
recaptchaSiteKey?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Job postings for the dropdown (e.g. from `usePublicJobPostings`). When
|
|
79
|
+
* non-empty the selected posting's ID is sent as `jobPostingId` and its
|
|
80
|
+
* title as `position`. When empty, a free-text "position" input is shown
|
|
81
|
+
* instead so the form works before a postings list exists.
|
|
82
|
+
*/
|
|
83
|
+
postings?: readonly CareersPostingOption[];
|
|
84
|
+
heroTitle?: string;
|
|
85
|
+
heroDescription?: string;
|
|
86
|
+
/**
|
|
87
|
+
* `1` (default) renders a full page hero `<h1>`; `2` renders a compact
|
|
88
|
+
* `<h2>` section header for embedding under a page that owns the `<h1>`.
|
|
89
|
+
*/
|
|
90
|
+
headingLevel?: 1 | 2;
|
|
91
|
+
className?: string;
|
|
92
|
+
seo?: {
|
|
93
|
+
title?: string;
|
|
94
|
+
description?: string;
|
|
95
|
+
keywords?: string;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/** True when `value` parses as an absolute http(s) URL. */
|
|
99
|
+
declare function isValidUrl(value: string): boolean;
|
|
100
|
+
declare function CareersSubmissionForm({ productName, recaptchaSiteKey, postings, heroTitle, heroDescription, headingLevel, className, seo, }: CareersSubmissionFormProps): react_jsx_runtime.JSX.Element;
|
|
101
|
+
|
|
72
102
|
declare const buttonVariants: (props?: ({
|
|
73
103
|
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
74
104
|
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
@@ -95,4 +125,4 @@ declare const Textarea: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLP
|
|
|
95
125
|
*/
|
|
96
126
|
declare const ECOSYSTEM_PRODUCTS: WebsiteSwitcherProduct[];
|
|
97
127
|
|
|
98
|
-
export { Button, type ButtonProps, CareersApplyForm, type CareersApplyFormProps, type CareersPostingOption, ECOSYSTEM_PRODUCTS, Input, Label, Select, Textarea, WebsiteSwitcherProduct, buttonVariants };
|
|
128
|
+
export { Button, type ButtonProps, CareersApplyForm, type CareersApplyFormProps, type CareersPostingOption, CareersSubmissionForm, type CareersSubmissionFormProps, ECOSYSTEM_PRODUCTS, Input, Label, Select, Textarea, WebsiteSwitcherProduct, buttonVariants, isValidUrl };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var React = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var lucideReact = require('lucide-react');
|
|
6
|
-
var
|
|
6
|
+
var ReCAPTCHA4 = require('react-google-recaptcha');
|
|
7
7
|
var sonner = require('sonner');
|
|
8
8
|
var reactHelmetAsync = require('react-helmet-async');
|
|
9
9
|
var reactSlot = require('@radix-ui/react-slot');
|
|
@@ -41,7 +41,7 @@ function _interopNamespace(e) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
44
|
-
var
|
|
44
|
+
var ReCAPTCHA4__default = /*#__PURE__*/_interopDefault(ReCAPTCHA4);
|
|
45
45
|
var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
|
|
46
46
|
var DOMPurify__default = /*#__PURE__*/_interopDefault(DOMPurify);
|
|
47
47
|
var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
|
|
@@ -1011,7 +1011,7 @@ function ContactPage({
|
|
|
1011
1011
|
] }),
|
|
1012
1012
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
1013
1013
|
effectiveRecaptchaSiteKey && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center sm:justify-start", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1014
|
-
|
|
1014
|
+
ReCAPTCHA4__default.default,
|
|
1015
1015
|
{
|
|
1016
1016
|
ref: recaptchaRef,
|
|
1017
1017
|
sitekey: effectiveRecaptchaSiteKey
|
|
@@ -1185,16 +1185,38 @@ var PUBLIC_CONTENT_PAGES_QUERY = `
|
|
|
1185
1185
|
}
|
|
1186
1186
|
}
|
|
1187
1187
|
`;
|
|
1188
|
+
function resolveContentPageGate(resolvedProductId, hasProvider, productLoading) {
|
|
1189
|
+
if (resolvedProductId) return "fetch";
|
|
1190
|
+
return hasProvider && productLoading ? "wait" : "unavailable";
|
|
1191
|
+
}
|
|
1188
1192
|
function useContentPage(slug, options) {
|
|
1189
1193
|
const client = useWebSDK();
|
|
1190
1194
|
const config = useWebSDKConfig();
|
|
1191
|
-
const {
|
|
1195
|
+
const {
|
|
1196
|
+
product,
|
|
1197
|
+
loading: productLoading,
|
|
1198
|
+
error: productError,
|
|
1199
|
+
hasProvider
|
|
1200
|
+
} = useProduct();
|
|
1192
1201
|
const resolvedProductId = product?.id || config.productId;
|
|
1202
|
+
const gate = resolveContentPageGate(
|
|
1203
|
+
resolvedProductId,
|
|
1204
|
+
hasProvider,
|
|
1205
|
+
productLoading
|
|
1206
|
+
);
|
|
1193
1207
|
const [data, setData] = React.useState(null);
|
|
1194
1208
|
const [loading, setLoading] = React.useState(true);
|
|
1195
1209
|
const [error, setError] = React.useState(null);
|
|
1196
1210
|
const fetchPage = React.useCallback(async () => {
|
|
1197
|
-
if (
|
|
1211
|
+
if (gate === "wait") return;
|
|
1212
|
+
if (gate === "unavailable") {
|
|
1213
|
+
setData(null);
|
|
1214
|
+
setError(
|
|
1215
|
+
productError ?? "Product unavailable \u2014 cannot load content page"
|
|
1216
|
+
);
|
|
1217
|
+
setLoading(false);
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1198
1220
|
setLoading(true);
|
|
1199
1221
|
setError(null);
|
|
1200
1222
|
try {
|
|
@@ -1219,7 +1241,7 @@ function useContentPage(slug, options) {
|
|
|
1219
1241
|
} finally {
|
|
1220
1242
|
setLoading(false);
|
|
1221
1243
|
}
|
|
1222
|
-
}, [client, resolvedProductId, slug, options?.resolve]);
|
|
1244
|
+
}, [client, gate, productError, resolvedProductId, slug, options?.resolve]);
|
|
1223
1245
|
React.useEffect(() => {
|
|
1224
1246
|
fetchPage();
|
|
1225
1247
|
}, [fetchPage]);
|
|
@@ -1977,7 +1999,7 @@ function CareersApplyForm({
|
|
|
1977
1999
|
)
|
|
1978
2000
|
] }),
|
|
1979
2001
|
effectiveRecaptchaSiteKey && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1980
|
-
|
|
2002
|
+
ReCAPTCHA4__default.default,
|
|
1981
2003
|
{
|
|
1982
2004
|
ref: recaptchaRef,
|
|
1983
2005
|
sitekey: effectiveRecaptchaSiteKey
|
|
@@ -2002,6 +2024,313 @@ function CareersApplyForm({
|
|
|
2002
2024
|
)
|
|
2003
2025
|
] });
|
|
2004
2026
|
}
|
|
2027
|
+
var SUBMIT_ASSIGNMENT_RESPONSE_MUTATION = (
|
|
2028
|
+
/* GraphQL */
|
|
2029
|
+
`
|
|
2030
|
+
mutation SubmitAssignmentResponse($input: SubmitAssignmentResponseInput!) {
|
|
2031
|
+
submitAssignmentResponse(input: $input) {
|
|
2032
|
+
success
|
|
2033
|
+
message
|
|
2034
|
+
applicationId
|
|
2035
|
+
roundId
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
`
|
|
2039
|
+
);
|
|
2040
|
+
function isValidUrl(value) {
|
|
2041
|
+
try {
|
|
2042
|
+
const url = new URL(value);
|
|
2043
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
2044
|
+
} catch {
|
|
2045
|
+
return false;
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
async function submitAssignmentResponse(client, data) {
|
|
2049
|
+
try {
|
|
2050
|
+
const result = await client.mutate(SUBMIT_ASSIGNMENT_RESPONSE_MUTATION, {
|
|
2051
|
+
input: {
|
|
2052
|
+
email: data.email.trim().toLowerCase(),
|
|
2053
|
+
repoUrl: data.repoUrl.trim(),
|
|
2054
|
+
videoUrl: data.videoUrl.trim(),
|
|
2055
|
+
recaptchaToken: data.recaptchaToken ?? "",
|
|
2056
|
+
...data.name ? { name: data.name } : {},
|
|
2057
|
+
...data.position ? { position: data.position } : {},
|
|
2058
|
+
...data.jobPostingId ? { jobPostingId: data.jobPostingId } : {},
|
|
2059
|
+
...data.notes ? { notes: data.notes } : {}
|
|
2060
|
+
}
|
|
2061
|
+
});
|
|
2062
|
+
if (result.errors?.length) {
|
|
2063
|
+
return {
|
|
2064
|
+
success: false,
|
|
2065
|
+
message: result.errors[0]?.message ?? "Failed to submit assignment"
|
|
2066
|
+
};
|
|
2067
|
+
}
|
|
2068
|
+
const response = result.data?.submitAssignmentResponse;
|
|
2069
|
+
return response?.success ? { success: true, message: response.message || "Assignment submitted!" } : {
|
|
2070
|
+
success: false,
|
|
2071
|
+
message: response?.message || "Failed to submit assignment"
|
|
2072
|
+
};
|
|
2073
|
+
} catch (error) {
|
|
2074
|
+
console.error("Assignment submission error:", error);
|
|
2075
|
+
return { success: false, message: "Network error. Please try again." };
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
var NO_APPLICATION_HINT = "Please use the same email address you applied with \u2014 or submit an application first.";
|
|
2079
|
+
function isNoApplicationError(message) {
|
|
2080
|
+
return /no application|not found/i.test(message);
|
|
2081
|
+
}
|
|
2082
|
+
var OTHER_POSITION = "__other__";
|
|
2083
|
+
function CareersSubmissionForm({
|
|
2084
|
+
productName,
|
|
2085
|
+
recaptchaSiteKey,
|
|
2086
|
+
postings = [],
|
|
2087
|
+
heroTitle = "Submit your assignment",
|
|
2088
|
+
heroDescription = "Share your GitHub repo and a short video walkthrough \u2014 make sure to use the same email you applied with.",
|
|
2089
|
+
headingLevel = 1,
|
|
2090
|
+
className,
|
|
2091
|
+
seo
|
|
2092
|
+
}) {
|
|
2093
|
+
const client = useWebSDK();
|
|
2094
|
+
const config = useWebSDKConfig();
|
|
2095
|
+
const { product } = useProduct();
|
|
2096
|
+
const displayName = productName ?? product?.name ?? config.productId;
|
|
2097
|
+
const effectiveRecaptchaSiteKey = recaptchaSiteKey ?? product?.recaptchaSiteKey ?? config.recaptchaSiteKey ?? "";
|
|
2098
|
+
const recaptchaRef = React.useRef(null);
|
|
2099
|
+
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
2100
|
+
const [submittedMessage, setSubmittedMessage] = React.useState(null);
|
|
2101
|
+
const [formError, setFormError] = React.useState(null);
|
|
2102
|
+
const [useFreeTextPosition, setUseFreeTextPosition] = React.useState(
|
|
2103
|
+
postings.length === 0
|
|
2104
|
+
);
|
|
2105
|
+
const handleSubmit = async (e) => {
|
|
2106
|
+
e.preventDefault();
|
|
2107
|
+
setFormError(null);
|
|
2108
|
+
const recaptchaToken = recaptchaRef.current?.getValue() ?? "";
|
|
2109
|
+
if (effectiveRecaptchaSiteKey && !recaptchaToken) {
|
|
2110
|
+
sonner.toast.error("Please complete the reCAPTCHA verification");
|
|
2111
|
+
return;
|
|
2112
|
+
}
|
|
2113
|
+
const form = e.currentTarget;
|
|
2114
|
+
const formData = new FormData(form);
|
|
2115
|
+
const name = (formData.get("name") ?? "").trim();
|
|
2116
|
+
const email = (formData.get("email") ?? "").trim();
|
|
2117
|
+
const positionValue = (formData.get("position") ?? "").trim();
|
|
2118
|
+
const repoUrl = (formData.get("repoUrl") ?? "").trim();
|
|
2119
|
+
const videoUrl = (formData.get("videoUrl") ?? "").trim();
|
|
2120
|
+
const notes = (formData.get("notes") ?? "").trim();
|
|
2121
|
+
const selectedPosting = postings.length > 0 && !useFreeTextPosition ? postings.find((p) => p.id === positionValue) : void 0;
|
|
2122
|
+
const position = selectedPosting ? selectedPosting.title : positionValue;
|
|
2123
|
+
if (!email) {
|
|
2124
|
+
setFormError("Please enter the email address you applied with.");
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2127
|
+
if (!position) {
|
|
2128
|
+
setFormError("Please select or enter the position you applied for.");
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
if (!repoUrl || !isValidUrl(repoUrl)) {
|
|
2132
|
+
setFormError(
|
|
2133
|
+
"Please enter a valid GitHub repository URL (e.g. https://github.com/you/project)."
|
|
2134
|
+
);
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
if (!videoUrl || !isValidUrl(videoUrl)) {
|
|
2138
|
+
setFormError(
|
|
2139
|
+
"Please enter a valid video URL (e.g. a Jam or Loom link starting with https://)."
|
|
2140
|
+
);
|
|
2141
|
+
return;
|
|
2142
|
+
}
|
|
2143
|
+
setIsSubmitting(true);
|
|
2144
|
+
try {
|
|
2145
|
+
const result = await submitAssignmentResponse(client, {
|
|
2146
|
+
name: name || void 0,
|
|
2147
|
+
email,
|
|
2148
|
+
position,
|
|
2149
|
+
jobPostingId: selectedPosting?.id,
|
|
2150
|
+
repoUrl,
|
|
2151
|
+
videoUrl,
|
|
2152
|
+
notes: notes || void 0,
|
|
2153
|
+
recaptchaToken
|
|
2154
|
+
});
|
|
2155
|
+
if (result.success) {
|
|
2156
|
+
setSubmittedMessage(result.message ?? "Assignment submitted!");
|
|
2157
|
+
sonner.toast.success(result.message ?? "Assignment submitted!");
|
|
2158
|
+
} else {
|
|
2159
|
+
const message = result.message ?? "Failed to submit assignment";
|
|
2160
|
+
setFormError(
|
|
2161
|
+
isNoApplicationError(message) ? `${message} ${NO_APPLICATION_HINT}` : message
|
|
2162
|
+
);
|
|
2163
|
+
sonner.toast.error(message);
|
|
2164
|
+
recaptchaRef.current?.reset();
|
|
2165
|
+
}
|
|
2166
|
+
} catch (err) {
|
|
2167
|
+
console.error("Careers submission form error:", err);
|
|
2168
|
+
setFormError("Something went wrong. Please try again.");
|
|
2169
|
+
sonner.toast.error("Something went wrong. Please try again.");
|
|
2170
|
+
recaptchaRef.current?.reset();
|
|
2171
|
+
} finally {
|
|
2172
|
+
setIsSubmitting(false);
|
|
2173
|
+
}
|
|
2174
|
+
};
|
|
2175
|
+
const Heading = headingLevel === 2 ? "h2" : "h1";
|
|
2176
|
+
const headingClass = headingLevel === 2 ? "text-2xl md:text-3xl font-bold mb-3" : "text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6";
|
|
2177
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
2178
|
+
seo && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2179
|
+
PageHead,
|
|
2180
|
+
{
|
|
2181
|
+
title: seo.title ?? `Submit your assignment \u2014 ${displayName}`,
|
|
2182
|
+
description: seo.description ?? heroDescription,
|
|
2183
|
+
keywords: seo.keywords
|
|
2184
|
+
}
|
|
2185
|
+
),
|
|
2186
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2187
|
+
"section",
|
|
2188
|
+
{
|
|
2189
|
+
className: headingLevel === 2 ? "py-12 md:py-16" : "bg-gradient-to-b from-background to-muted/20 py-12 sm:py-16 md:py-20 lg:py-24",
|
|
2190
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl mx-auto px-4 sm:px-6 lg:px-8", children: [
|
|
2191
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center mb-8 sm:mb-10", children: [
|
|
2192
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { className: headingClass, children: heroTitle }),
|
|
2193
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg text-muted-foreground leading-relaxed", children: heroDescription })
|
|
2194
|
+
] }),
|
|
2195
|
+
submittedMessage ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center rounded-xl border border-border bg-card p-10", children: [
|
|
2196
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle, { className: "mx-auto mb-4 h-12 w-12 text-accent" }),
|
|
2197
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-xl font-semibold text-foreground mb-2", children: "Assignment received" }),
|
|
2198
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: submittedMessage })
|
|
2199
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "space-y-5", children: [
|
|
2200
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-5", children: [
|
|
2201
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2202
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "name", children: "Name" }),
|
|
2203
|
+
/* @__PURE__ */ jsxRuntime.jsx(Input, { id: "name", name: "name", placeholder: "Ada Lovelace" })
|
|
2204
|
+
] }),
|
|
2205
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2206
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "email", children: "Email *" }),
|
|
2207
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2208
|
+
Input,
|
|
2209
|
+
{
|
|
2210
|
+
id: "email",
|
|
2211
|
+
name: "email",
|
|
2212
|
+
type: "email",
|
|
2213
|
+
required: true,
|
|
2214
|
+
placeholder: "ada@example.com"
|
|
2215
|
+
}
|
|
2216
|
+
)
|
|
2217
|
+
] })
|
|
2218
|
+
] }),
|
|
2219
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2220
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "position", children: "Position *" }),
|
|
2221
|
+
postings.length > 0 && !useFreeTextPosition ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2222
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2223
|
+
"select",
|
|
2224
|
+
{
|
|
2225
|
+
id: "position",
|
|
2226
|
+
name: "position",
|
|
2227
|
+
required: true,
|
|
2228
|
+
defaultValue: "",
|
|
2229
|
+
onChange: (e) => {
|
|
2230
|
+
if (e.target.value === OTHER_POSITION) {
|
|
2231
|
+
setUseFreeTextPosition(true);
|
|
2232
|
+
}
|
|
2233
|
+
},
|
|
2234
|
+
className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
|
|
2235
|
+
children: [
|
|
2236
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: "Select a role" }),
|
|
2237
|
+
postings.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p.id, children: p.title }, p.id)),
|
|
2238
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: OTHER_POSITION, children: "My role isn't listed" })
|
|
2239
|
+
]
|
|
2240
|
+
}
|
|
2241
|
+
),
|
|
2242
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: [
|
|
2243
|
+
"Applied to a role that's since closed? Choose",
|
|
2244
|
+
" ",
|
|
2245
|
+
/* @__PURE__ */ jsxRuntime.jsx("em", { children: "My role isn't listed" }),
|
|
2246
|
+
" and type it in \u2014 you can still submit."
|
|
2247
|
+
] })
|
|
2248
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2249
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2250
|
+
Input,
|
|
2251
|
+
{
|
|
2252
|
+
id: "position",
|
|
2253
|
+
name: "position",
|
|
2254
|
+
required: true,
|
|
2255
|
+
placeholder: "Role you applied for"
|
|
2256
|
+
}
|
|
2257
|
+
),
|
|
2258
|
+
postings.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2259
|
+
"button",
|
|
2260
|
+
{
|
|
2261
|
+
type: "button",
|
|
2262
|
+
onClick: () => setUseFreeTextPosition(false),
|
|
2263
|
+
className: "mt-1 text-xs text-accent hover:underline",
|
|
2264
|
+
children: "Choose from open roles instead"
|
|
2265
|
+
}
|
|
2266
|
+
)
|
|
2267
|
+
] })
|
|
2268
|
+
] }),
|
|
2269
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2270
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "repoUrl", children: "GitHub repository URL *" }),
|
|
2271
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2272
|
+
Input,
|
|
2273
|
+
{
|
|
2274
|
+
id: "repoUrl",
|
|
2275
|
+
name: "repoUrl",
|
|
2276
|
+
type: "url",
|
|
2277
|
+
required: true,
|
|
2278
|
+
placeholder: "https://github.com/you/assignment"
|
|
2279
|
+
}
|
|
2280
|
+
)
|
|
2281
|
+
] }),
|
|
2282
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2283
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "videoUrl", children: "Video walkthrough URL (Jam, Loom, \u2026) *" }),
|
|
2284
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2285
|
+
Input,
|
|
2286
|
+
{
|
|
2287
|
+
id: "videoUrl",
|
|
2288
|
+
name: "videoUrl",
|
|
2289
|
+
type: "url",
|
|
2290
|
+
required: true,
|
|
2291
|
+
placeholder: "https://jam.dev/c/\u2026"
|
|
2292
|
+
}
|
|
2293
|
+
)
|
|
2294
|
+
] }),
|
|
2295
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2296
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "notes", children: "Notes" }),
|
|
2297
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2298
|
+
Textarea,
|
|
2299
|
+
{
|
|
2300
|
+
id: "notes",
|
|
2301
|
+
name: "notes",
|
|
2302
|
+
rows: 4,
|
|
2303
|
+
placeholder: "Anything we should know before reviewing\u2026"
|
|
2304
|
+
}
|
|
2305
|
+
)
|
|
2306
|
+
] }),
|
|
2307
|
+
formError && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive", children: formError }),
|
|
2308
|
+
effectiveRecaptchaSiteKey && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2309
|
+
ReCAPTCHA4__default.default,
|
|
2310
|
+
{
|
|
2311
|
+
ref: recaptchaRef,
|
|
2312
|
+
sitekey: effectiveRecaptchaSiteKey
|
|
2313
|
+
}
|
|
2314
|
+
),
|
|
2315
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2316
|
+
Button,
|
|
2317
|
+
{
|
|
2318
|
+
type: "submit",
|
|
2319
|
+
size: "lg",
|
|
2320
|
+
disabled: isSubmitting,
|
|
2321
|
+
className: "w-full sm:w-auto",
|
|
2322
|
+
children: isSubmitting ? "Submitting\u2026" : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2323
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "mr-2 h-4 w-4" }),
|
|
2324
|
+
" Submit assignment"
|
|
2325
|
+
] })
|
|
2326
|
+
}
|
|
2327
|
+
)
|
|
2328
|
+
] })
|
|
2329
|
+
] })
|
|
2330
|
+
}
|
|
2331
|
+
)
|
|
2332
|
+
] });
|
|
2333
|
+
}
|
|
2005
2334
|
var newsletterSchema = zod.z.object({
|
|
2006
2335
|
email: zod.z.string().email("Please enter a valid email address")
|
|
2007
2336
|
});
|
|
@@ -2291,7 +2620,7 @@ function NewsletterPage({
|
|
|
2291
2620
|
errors.email && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", children: errors.email.message })
|
|
2292
2621
|
] }),
|
|
2293
2622
|
effectiveRecaptchaSiteKey && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2294
|
-
|
|
2623
|
+
ReCAPTCHA4__default.default,
|
|
2295
2624
|
{
|
|
2296
2625
|
ref: recaptchaRef,
|
|
2297
2626
|
sitekey: effectiveRecaptchaSiteKey
|
|
@@ -2343,7 +2672,7 @@ function NewsletterPage({
|
|
|
2343
2672
|
errors.email && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", children: errors.email.message })
|
|
2344
2673
|
] }),
|
|
2345
2674
|
effectiveRecaptchaSiteKey && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center sm:justify-start", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2346
|
-
|
|
2675
|
+
ReCAPTCHA4__default.default,
|
|
2347
2676
|
{
|
|
2348
2677
|
ref: recaptchaRef,
|
|
2349
2678
|
sitekey: effectiveRecaptchaSiteKey
|
|
@@ -2521,7 +2850,7 @@ function NewsletterForm({
|
|
|
2521
2850
|
justifyContent: "flex-start"
|
|
2522
2851
|
},
|
|
2523
2852
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2524
|
-
|
|
2853
|
+
ReCAPTCHA4__default.default,
|
|
2525
2854
|
{
|
|
2526
2855
|
ref: recaptchaRef,
|
|
2527
2856
|
sitekey: effectiveRecaptchaSiteKey,
|
|
@@ -9267,6 +9596,7 @@ exports.BlogListPage = BlogListPage;
|
|
|
9267
9596
|
exports.BlogPostPage = BlogPostPage;
|
|
9268
9597
|
exports.Button = Button;
|
|
9269
9598
|
exports.CareersApplyForm = CareersApplyForm;
|
|
9599
|
+
exports.CareersSubmissionForm = CareersSubmissionForm;
|
|
9270
9600
|
exports.CaseStudiesListPage = CaseStudiesListPage;
|
|
9271
9601
|
exports.CaseStudyPage = CaseStudyPage;
|
|
9272
9602
|
exports.ChangelogPage = ChangelogPage;
|
|
@@ -9313,6 +9643,7 @@ exports.fetchPublicJobPosting = fetchPublicJobPosting;
|
|
|
9313
9643
|
exports.fetchPublicJobPostings = fetchPublicJobPostings;
|
|
9314
9644
|
exports.formatDownloads = formatDownloads;
|
|
9315
9645
|
exports.formatPrice = formatPrice2;
|
|
9646
|
+
exports.isValidUrl = isValidUrl;
|
|
9316
9647
|
exports.useContentPage = useContentPage;
|
|
9317
9648
|
exports.useContentPages = useContentPages;
|
|
9318
9649
|
exports.useProduct = useProduct;
|