@burdenoff/website-sdk 2026.813.3 → 2026.817.2

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/index.mjs CHANGED
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { createContext, useMemo, useContext, useState, useCallback, useLayoutEffect, useRef, useEffect } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { Instagram, Youtube, Facebook, Github, Linkedin, Twitter, Mail, Phone, MapPin, Clock, Send, CheckCircle, Upload, Globe, ChevronDown, Search, Rocket, ArrowRight, Download, History, ChevronLeft, ChevronRight, FileText } from 'lucide-react';
5
- import ReCAPTCHA3 from 'react-google-recaptcha';
5
+ import ReCAPTCHA4 from 'react-google-recaptcha';
6
6
  import { toast } from 'sonner';
7
7
  import { Helmet } from 'react-helmet-async';
8
8
  import { Slot } from '@radix-ui/react-slot';
@@ -981,7 +981,7 @@ function ContactPage({
981
981
  ] }),
982
982
  /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
983
983
  effectiveRecaptchaSiteKey && /* @__PURE__ */ jsx("div", { className: "flex justify-center sm:justify-start", children: /* @__PURE__ */ jsx(
984
- ReCAPTCHA3,
984
+ ReCAPTCHA4,
985
985
  {
986
986
  ref: recaptchaRef,
987
987
  sitekey: effectiveRecaptchaSiteKey
@@ -1614,6 +1614,7 @@ async function submitApplication(client, data, productId) {
1614
1614
  ...data.linkedinUrl ? { linkedinUrl: data.linkedinUrl } : {},
1615
1615
  ...data.portfolioUrl ? { portfolioUrl: data.portfolioUrl } : {},
1616
1616
  ...data.coverLetter ? { coverLetter: data.coverLetter } : {},
1617
+ ...data.jobPostingId ? { jobPostingId: data.jobPostingId } : {},
1617
1618
  ...data.recaptchaToken ? { recaptchaToken: data.recaptchaToken } : {}
1618
1619
  }
1619
1620
  });
@@ -1637,6 +1638,7 @@ function CareersApplyForm({
1637
1638
  productName,
1638
1639
  recaptchaSiteKey,
1639
1640
  positions = [],
1641
+ postings = [],
1640
1642
  heroTitle = "Become a part of the team",
1641
1643
  heroDescription = "Tell us about yourself and upload your resume \u2014 we'll be in touch.",
1642
1644
  headingLevel = 1,
@@ -1703,6 +1705,8 @@ function CareersApplyForm({
1703
1705
  try {
1704
1706
  const formData = new FormData(form);
1705
1707
  const resumeBase64 = await fileToBase64(resumeFile);
1708
+ const positionValue = formData.get("position") ?? "";
1709
+ const selectedPosting = postings.length > 0 ? postings.find((p) => p.id === positionValue) : void 0;
1706
1710
  const result = await submitApplication(
1707
1711
  client,
1708
1712
  {
@@ -1710,7 +1714,8 @@ function CareersApplyForm({
1710
1714
  lastName: formData.get("lastName") ?? "",
1711
1715
  email: formData.get("email") ?? "",
1712
1716
  phone: formData.get("phone") || void 0,
1713
- position: formData.get("position") ?? "",
1717
+ position: selectedPosting ? selectedPosting.title : positionValue,
1718
+ jobPostingId: selectedPosting?.id,
1714
1719
  linkedinUrl: formData.get("linkedinUrl") || void 0,
1715
1720
  portfolioUrl: formData.get("portfolioUrl") || void 0,
1716
1721
  coverLetter: formData.get("coverLetter") || void 0,
@@ -1821,7 +1826,20 @@ function CareersApplyForm({
1821
1826
  ] }),
1822
1827
  /* @__PURE__ */ jsxs("div", { children: [
1823
1828
  /* @__PURE__ */ jsx(Label, { htmlFor: "position", children: "Position *" }),
1824
- positions.length > 0 ? /* @__PURE__ */ jsxs(
1829
+ postings.length > 0 ? /* @__PURE__ */ jsxs(
1830
+ "select",
1831
+ {
1832
+ id: "position",
1833
+ name: "position",
1834
+ required: true,
1835
+ defaultValue: "",
1836
+ 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",
1837
+ children: [
1838
+ /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select a role" }),
1839
+ postings.map((p) => /* @__PURE__ */ jsx("option", { value: p.id, children: p.title }, p.id))
1840
+ ]
1841
+ }
1842
+ ) : positions.length > 0 ? /* @__PURE__ */ jsxs(
1825
1843
  "select",
1826
1844
  {
1827
1845
  id: "position",
@@ -1929,7 +1947,7 @@ function CareersApplyForm({
1929
1947
  )
1930
1948
  ] }),
1931
1949
  effectiveRecaptchaSiteKey && /* @__PURE__ */ jsx(
1932
- ReCAPTCHA3,
1950
+ ReCAPTCHA4,
1933
1951
  {
1934
1952
  ref: recaptchaRef,
1935
1953
  sitekey: effectiveRecaptchaSiteKey
@@ -1954,6 +1972,284 @@ function CareersApplyForm({
1954
1972
  )
1955
1973
  ] });
1956
1974
  }
1975
+ var SUBMIT_ASSIGNMENT_RESPONSE_MUTATION = (
1976
+ /* GraphQL */
1977
+ `
1978
+ mutation SubmitAssignmentResponse($input: SubmitAssignmentResponseInput!) {
1979
+ submitAssignmentResponse(input: $input) {
1980
+ success
1981
+ message
1982
+ applicationId
1983
+ roundId
1984
+ }
1985
+ }
1986
+ `
1987
+ );
1988
+ function isValidUrl(value) {
1989
+ try {
1990
+ const url = new URL(value);
1991
+ return url.protocol === "http:" || url.protocol === "https:";
1992
+ } catch {
1993
+ return false;
1994
+ }
1995
+ }
1996
+ async function submitAssignmentResponse(client, data) {
1997
+ try {
1998
+ const result = await client.mutate(SUBMIT_ASSIGNMENT_RESPONSE_MUTATION, {
1999
+ input: {
2000
+ email: data.email.trim().toLowerCase(),
2001
+ repoUrl: data.repoUrl.trim(),
2002
+ videoUrl: data.videoUrl.trim(),
2003
+ recaptchaToken: data.recaptchaToken ?? "",
2004
+ ...data.name ? { name: data.name } : {},
2005
+ ...data.position ? { position: data.position } : {},
2006
+ ...data.jobPostingId ? { jobPostingId: data.jobPostingId } : {},
2007
+ ...data.notes ? { notes: data.notes } : {}
2008
+ }
2009
+ });
2010
+ if (result.errors?.length) {
2011
+ return {
2012
+ success: false,
2013
+ message: result.errors[0]?.message ?? "Failed to submit assignment"
2014
+ };
2015
+ }
2016
+ const response = result.data?.submitAssignmentResponse;
2017
+ return response?.success ? { success: true, message: response.message || "Assignment submitted!" } : {
2018
+ success: false,
2019
+ message: response?.message || "Failed to submit assignment"
2020
+ };
2021
+ } catch (error) {
2022
+ console.error("Assignment submission error:", error);
2023
+ return { success: false, message: "Network error. Please try again." };
2024
+ }
2025
+ }
2026
+ var NO_APPLICATION_HINT = "Please use the same email address you applied with \u2014 or submit an application first.";
2027
+ function isNoApplicationError(message) {
2028
+ return /no application|not found/i.test(message);
2029
+ }
2030
+ function CareersSubmissionForm({
2031
+ productName,
2032
+ recaptchaSiteKey,
2033
+ postings = [],
2034
+ heroTitle = "Submit your assignment",
2035
+ heroDescription = "Share your GitHub repo and a short video walkthrough \u2014 make sure to use the same email you applied with.",
2036
+ headingLevel = 1,
2037
+ className,
2038
+ seo
2039
+ }) {
2040
+ const client = useWebSDK();
2041
+ const config = useWebSDKConfig();
2042
+ const { product } = useProduct();
2043
+ const displayName = productName ?? product?.name ?? config.productId;
2044
+ const effectiveRecaptchaSiteKey = recaptchaSiteKey ?? product?.recaptchaSiteKey ?? config.recaptchaSiteKey ?? "";
2045
+ const recaptchaRef = useRef(null);
2046
+ const [isSubmitting, setIsSubmitting] = useState(false);
2047
+ const [submittedMessage, setSubmittedMessage] = useState(null);
2048
+ const [formError, setFormError] = useState(null);
2049
+ const handleSubmit = async (e) => {
2050
+ e.preventDefault();
2051
+ setFormError(null);
2052
+ const recaptchaToken = recaptchaRef.current?.getValue() ?? "";
2053
+ if (effectiveRecaptchaSiteKey && !recaptchaToken) {
2054
+ toast.error("Please complete the reCAPTCHA verification");
2055
+ return;
2056
+ }
2057
+ const form = e.currentTarget;
2058
+ const formData = new FormData(form);
2059
+ const name = (formData.get("name") ?? "").trim();
2060
+ const email = (formData.get("email") ?? "").trim();
2061
+ const positionValue = (formData.get("position") ?? "").trim();
2062
+ const repoUrl = (formData.get("repoUrl") ?? "").trim();
2063
+ const videoUrl = (formData.get("videoUrl") ?? "").trim();
2064
+ const notes = (formData.get("notes") ?? "").trim();
2065
+ const selectedPosting = postings.length > 0 ? postings.find((p) => p.id === positionValue) : void 0;
2066
+ const position = selectedPosting ? selectedPosting.title : positionValue;
2067
+ if (!email) {
2068
+ setFormError("Please enter the email address you applied with.");
2069
+ return;
2070
+ }
2071
+ if (!position) {
2072
+ setFormError("Please select or enter the position you applied for.");
2073
+ return;
2074
+ }
2075
+ if (!repoUrl || !isValidUrl(repoUrl)) {
2076
+ setFormError(
2077
+ "Please enter a valid GitHub repository URL (e.g. https://github.com/you/project)."
2078
+ );
2079
+ return;
2080
+ }
2081
+ if (!videoUrl || !isValidUrl(videoUrl)) {
2082
+ setFormError(
2083
+ "Please enter a valid video URL (e.g. a Jam or Loom link starting with https://)."
2084
+ );
2085
+ return;
2086
+ }
2087
+ setIsSubmitting(true);
2088
+ try {
2089
+ const result = await submitAssignmentResponse(client, {
2090
+ name: name || void 0,
2091
+ email,
2092
+ position,
2093
+ jobPostingId: selectedPosting?.id,
2094
+ repoUrl,
2095
+ videoUrl,
2096
+ notes: notes || void 0,
2097
+ recaptchaToken
2098
+ });
2099
+ if (result.success) {
2100
+ setSubmittedMessage(result.message ?? "Assignment submitted!");
2101
+ toast.success(result.message ?? "Assignment submitted!");
2102
+ } else {
2103
+ const message = result.message ?? "Failed to submit assignment";
2104
+ setFormError(
2105
+ isNoApplicationError(message) ? `${message} ${NO_APPLICATION_HINT}` : message
2106
+ );
2107
+ toast.error(message);
2108
+ recaptchaRef.current?.reset();
2109
+ }
2110
+ } catch (err) {
2111
+ console.error("Careers submission form error:", err);
2112
+ setFormError("Something went wrong. Please try again.");
2113
+ toast.error("Something went wrong. Please try again.");
2114
+ recaptchaRef.current?.reset();
2115
+ } finally {
2116
+ setIsSubmitting(false);
2117
+ }
2118
+ };
2119
+ const Heading = headingLevel === 2 ? "h2" : "h1";
2120
+ 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";
2121
+ return /* @__PURE__ */ jsxs("div", { className, children: [
2122
+ seo && /* @__PURE__ */ jsx(
2123
+ PageHead,
2124
+ {
2125
+ title: seo.title ?? `Submit your assignment \u2014 ${displayName}`,
2126
+ description: seo.description ?? heroDescription,
2127
+ keywords: seo.keywords
2128
+ }
2129
+ ),
2130
+ /* @__PURE__ */ jsx(
2131
+ "section",
2132
+ {
2133
+ 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",
2134
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-3xl mx-auto px-4 sm:px-6 lg:px-8", children: [
2135
+ /* @__PURE__ */ jsxs("div", { className: "text-center mb-8 sm:mb-10", children: [
2136
+ /* @__PURE__ */ jsx(Heading, { className: headingClass, children: heroTitle }),
2137
+ /* @__PURE__ */ jsx("p", { className: "text-lg text-muted-foreground leading-relaxed", children: heroDescription })
2138
+ ] }),
2139
+ submittedMessage ? /* @__PURE__ */ jsxs("div", { className: "text-center rounded-xl border border-border bg-card p-10", children: [
2140
+ /* @__PURE__ */ jsx(CheckCircle, { className: "mx-auto mb-4 h-12 w-12 text-accent" }),
2141
+ /* @__PURE__ */ jsx("h3", { className: "text-xl font-semibold text-foreground mb-2", children: "Assignment received" }),
2142
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: submittedMessage })
2143
+ ] }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-5", children: [
2144
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-5", children: [
2145
+ /* @__PURE__ */ jsxs("div", { children: [
2146
+ /* @__PURE__ */ jsx(Label, { htmlFor: "name", children: "Name" }),
2147
+ /* @__PURE__ */ jsx(Input, { id: "name", name: "name", placeholder: "Ada Lovelace" })
2148
+ ] }),
2149
+ /* @__PURE__ */ jsxs("div", { children: [
2150
+ /* @__PURE__ */ jsx(Label, { htmlFor: "email", children: "Email *" }),
2151
+ /* @__PURE__ */ jsx(
2152
+ Input,
2153
+ {
2154
+ id: "email",
2155
+ name: "email",
2156
+ type: "email",
2157
+ required: true,
2158
+ placeholder: "ada@example.com"
2159
+ }
2160
+ )
2161
+ ] })
2162
+ ] }),
2163
+ /* @__PURE__ */ jsxs("div", { children: [
2164
+ /* @__PURE__ */ jsx(Label, { htmlFor: "position", children: "Position *" }),
2165
+ postings.length > 0 ? /* @__PURE__ */ jsxs(
2166
+ "select",
2167
+ {
2168
+ id: "position",
2169
+ name: "position",
2170
+ required: true,
2171
+ defaultValue: "",
2172
+ 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",
2173
+ children: [
2174
+ /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select a role" }),
2175
+ postings.map((p) => /* @__PURE__ */ jsx("option", { value: p.id, children: p.title }, p.id))
2176
+ ]
2177
+ }
2178
+ ) : /* @__PURE__ */ jsx(
2179
+ Input,
2180
+ {
2181
+ id: "position",
2182
+ name: "position",
2183
+ required: true,
2184
+ placeholder: "Role you applied for"
2185
+ }
2186
+ )
2187
+ ] }),
2188
+ /* @__PURE__ */ jsxs("div", { children: [
2189
+ /* @__PURE__ */ jsx(Label, { htmlFor: "repoUrl", children: "GitHub repository URL *" }),
2190
+ /* @__PURE__ */ jsx(
2191
+ Input,
2192
+ {
2193
+ id: "repoUrl",
2194
+ name: "repoUrl",
2195
+ type: "url",
2196
+ required: true,
2197
+ placeholder: "https://github.com/you/assignment"
2198
+ }
2199
+ )
2200
+ ] }),
2201
+ /* @__PURE__ */ jsxs("div", { children: [
2202
+ /* @__PURE__ */ jsx(Label, { htmlFor: "videoUrl", children: "Video walkthrough URL (Jam, Loom, \u2026) *" }),
2203
+ /* @__PURE__ */ jsx(
2204
+ Input,
2205
+ {
2206
+ id: "videoUrl",
2207
+ name: "videoUrl",
2208
+ type: "url",
2209
+ required: true,
2210
+ placeholder: "https://jam.dev/c/\u2026"
2211
+ }
2212
+ )
2213
+ ] }),
2214
+ /* @__PURE__ */ jsxs("div", { children: [
2215
+ /* @__PURE__ */ jsx(Label, { htmlFor: "notes", children: "Notes" }),
2216
+ /* @__PURE__ */ jsx(
2217
+ Textarea,
2218
+ {
2219
+ id: "notes",
2220
+ name: "notes",
2221
+ rows: 4,
2222
+ placeholder: "Anything we should know before reviewing\u2026"
2223
+ }
2224
+ )
2225
+ ] }),
2226
+ formError && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-sm text-destructive", children: formError }),
2227
+ effectiveRecaptchaSiteKey && /* @__PURE__ */ jsx(
2228
+ ReCAPTCHA4,
2229
+ {
2230
+ ref: recaptchaRef,
2231
+ sitekey: effectiveRecaptchaSiteKey
2232
+ }
2233
+ ),
2234
+ /* @__PURE__ */ jsx(
2235
+ Button,
2236
+ {
2237
+ type: "submit",
2238
+ size: "lg",
2239
+ disabled: isSubmitting,
2240
+ className: "w-full sm:w-auto",
2241
+ children: isSubmitting ? "Submitting\u2026" : /* @__PURE__ */ jsxs(Fragment, { children: [
2242
+ /* @__PURE__ */ jsx(Send, { className: "mr-2 h-4 w-4" }),
2243
+ " Submit assignment"
2244
+ ] })
2245
+ }
2246
+ )
2247
+ ] })
2248
+ ] })
2249
+ }
2250
+ )
2251
+ ] });
2252
+ }
1957
2253
  var newsletterSchema = z.object({
1958
2254
  email: z.string().email("Please enter a valid email address")
1959
2255
  });
@@ -2243,7 +2539,7 @@ function NewsletterPage({
2243
2539
  errors.email && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errors.email.message })
2244
2540
  ] }),
2245
2541
  effectiveRecaptchaSiteKey && /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
2246
- ReCAPTCHA3,
2542
+ ReCAPTCHA4,
2247
2543
  {
2248
2544
  ref: recaptchaRef,
2249
2545
  sitekey: effectiveRecaptchaSiteKey
@@ -2295,7 +2591,7 @@ function NewsletterPage({
2295
2591
  errors.email && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errors.email.message })
2296
2592
  ] }),
2297
2593
  effectiveRecaptchaSiteKey && /* @__PURE__ */ jsx("div", { className: "flex justify-center sm:justify-start", children: /* @__PURE__ */ jsx(
2298
- ReCAPTCHA3,
2594
+ ReCAPTCHA4,
2299
2595
  {
2300
2596
  ref: recaptchaRef,
2301
2597
  sitekey: effectiveRecaptchaSiteKey
@@ -2473,7 +2769,7 @@ function NewsletterForm({
2473
2769
  justifyContent: "flex-start"
2474
2770
  },
2475
2771
  children: /* @__PURE__ */ jsx(
2476
- ReCAPTCHA3,
2772
+ ReCAPTCHA4,
2477
2773
  {
2478
2774
  ref: recaptchaRef,
2479
2775
  sitekey: effectiveRecaptchaSiteKey,
@@ -4389,6 +4685,138 @@ function RybbitAnalytics({
4389
4685
  }, [siteId, scriptUrl, enabled]);
4390
4686
  return null;
4391
4687
  }
4688
+ var PUBLIC_JOB_POSTING_FIELDS = (
4689
+ /* GraphQL */
4690
+ `
4691
+ id
4692
+ slug
4693
+ title
4694
+ department
4695
+ location
4696
+ employmentType
4697
+ openings
4698
+ description
4699
+ overview
4700
+ responsibilities
4701
+ learnings
4702
+ qualifications
4703
+ rounds {
4704
+ roundNumber
4705
+ name
4706
+ roundType
4707
+ isRequired
4708
+ description
4709
+ }
4710
+ `
4711
+ );
4712
+ var PUBLIC_JOB_POSTINGS_QUERY = (
4713
+ /* GraphQL */
4714
+ `
4715
+ query PublicJobPostings($productId: ID, $limit: Int, $offset: Int) {
4716
+ publicJobPostings(productId: $productId, limit: $limit, offset: $offset) {
4717
+ ${PUBLIC_JOB_POSTING_FIELDS}
4718
+ }
4719
+ }
4720
+ `
4721
+ );
4722
+ var PUBLIC_JOB_POSTING_QUERY = (
4723
+ /* GraphQL */
4724
+ `
4725
+ query PublicJobPosting($slug: String!, $productId: ID) {
4726
+ publicJobPosting(slug: $slug, productId: $productId) {
4727
+ ${PUBLIC_JOB_POSTING_FIELDS}
4728
+ }
4729
+ }
4730
+ `
4731
+ );
4732
+ async function fetchPublicJobPostings(client, options) {
4733
+ const result = await client.query(PUBLIC_JOB_POSTINGS_QUERY, {
4734
+ productId: options?.productId,
4735
+ limit: options?.limit ?? 50,
4736
+ offset: options?.offset ?? 0
4737
+ });
4738
+ if (result.errors?.length) {
4739
+ throw new Error(result.errors[0]?.message ?? "Unknown error");
4740
+ }
4741
+ return result.data?.publicJobPostings ?? [];
4742
+ }
4743
+ async function fetchPublicJobPosting(client, slug, options) {
4744
+ const result = await client.query(PUBLIC_JOB_POSTING_QUERY, {
4745
+ slug,
4746
+ productId: options?.productId
4747
+ });
4748
+ if (result.errors?.length) {
4749
+ throw new Error(result.errors[0]?.message ?? "Unknown error");
4750
+ }
4751
+ return result.data?.publicJobPosting ?? null;
4752
+ }
4753
+ function usePublicJobPostings(options) {
4754
+ const client = useWebSDK();
4755
+ const config = useWebSDKConfig();
4756
+ const { product } = useProduct();
4757
+ const resolvedProductId = options?.productId ?? product?.id ?? config.productId;
4758
+ const [postings, setPostings] = useState([]);
4759
+ const [loading, setLoading] = useState(true);
4760
+ const [error, setError] = useState(null);
4761
+ const fetchPostings = useCallback(async () => {
4762
+ setLoading(true);
4763
+ setError(null);
4764
+ try {
4765
+ const items = await fetchPublicJobPostings(client, {
4766
+ productId: resolvedProductId,
4767
+ limit: options?.limit,
4768
+ offset: options?.offset
4769
+ });
4770
+ setPostings(items);
4771
+ } catch (err) {
4772
+ setError(
4773
+ err instanceof Error ? err.message : "Failed to fetch job postings"
4774
+ );
4775
+ setPostings([]);
4776
+ } finally {
4777
+ setLoading(false);
4778
+ }
4779
+ }, [client, resolvedProductId, options?.limit, options?.offset]);
4780
+ useEffect(() => {
4781
+ fetchPostings();
4782
+ }, [fetchPostings]);
4783
+ return { postings, loading, error, refetch: fetchPostings };
4784
+ }
4785
+ function usePublicJobPosting(slug, options) {
4786
+ const client = useWebSDK();
4787
+ const config = useWebSDKConfig();
4788
+ const { product } = useProduct();
4789
+ const resolvedProductId = options?.productId ?? product?.id ?? config.productId;
4790
+ const [posting, setPosting] = useState(null);
4791
+ const [loading, setLoading] = useState(true);
4792
+ const [error, setError] = useState(null);
4793
+ const fetchPosting = useCallback(async () => {
4794
+ if (!slug) {
4795
+ setPosting(null);
4796
+ setLoading(false);
4797
+ return;
4798
+ }
4799
+ setLoading(true);
4800
+ setError(null);
4801
+ try {
4802
+ const item = await fetchPublicJobPosting(client, slug, {
4803
+ productId: resolvedProductId
4804
+ });
4805
+ setPosting(item);
4806
+ } catch (err) {
4807
+ setError(
4808
+ err instanceof Error ? err.message : "Failed to fetch job posting"
4809
+ );
4810
+ setPosting(null);
4811
+ } finally {
4812
+ setLoading(false);
4813
+ }
4814
+ }, [client, resolvedProductId, slug]);
4815
+ useEffect(() => {
4816
+ fetchPosting();
4817
+ }, [fetchPosting]);
4818
+ return { posting, loading, error, refetch: fetchPosting };
4819
+ }
4392
4820
  var PROSE_CSS = `
4393
4821
  .boff-prose {
4394
4822
  max-width: none;
@@ -9083,6 +9511,6 @@ var ECOSYSTEM_PRODUCTS = [
9083
9511
  }
9084
9512
  ];
9085
9513
 
9086
- export { BlogListPage, BlogPostPage, Button, CareersApplyForm, CaseStudiesListPage, CaseStudyPage, ChangelogPage, ContactPage, ContentRenderer, ContractsPage, DEFAULT_CONTACT_CATEGORIES, ECOSYSTEM_PRODUCTS, ElectronDownloadLink, Input, Label, LaunchCountdown, Markdown, NewsletterForm, NewsletterPage, PageHead, PartnersPage, PressKitPage, PricingPage, PricingSection, ProblemsSolvedSection, ProductCard, ProductProvider, ResourceLinks, RybbitAnalytics, Select, SocialLinks, StarRating, StoreBrowsePage, StoreHomePage, StoreProductDetailPage, Textarea, TypeBadge, UnsubscribePage, WaitlistForm, WaitlistPage, WebSDKClient, WebSDKProvider, WebsiteSwitcher, buttonVariants, cn, detectElectronPlatform, formatDownloads, formatPrice2 as formatPrice, useContentPage, useContentPages, useProduct, useProductConfig, useWebSDK, useWebSDKConfig };
9514
+ export { BlogListPage, BlogPostPage, Button, CareersApplyForm, CareersSubmissionForm, CaseStudiesListPage, CaseStudyPage, ChangelogPage, ContactPage, ContentRenderer, ContractsPage, DEFAULT_CONTACT_CATEGORIES, ECOSYSTEM_PRODUCTS, ElectronDownloadLink, Input, Label, LaunchCountdown, Markdown, NewsletterForm, NewsletterPage, PageHead, PartnersPage, PressKitPage, PricingPage, PricingSection, ProblemsSolvedSection, ProductCard, ProductProvider, ResourceLinks, RybbitAnalytics, Select, SocialLinks, StarRating, StoreBrowsePage, StoreHomePage, StoreProductDetailPage, Textarea, TypeBadge, UnsubscribePage, WaitlistForm, WaitlistPage, WebSDKClient, WebSDKProvider, WebsiteSwitcher, buttonVariants, cn, detectElectronPlatform, fetchPublicJobPosting, fetchPublicJobPostings, formatDownloads, formatPrice2 as formatPrice, isValidUrl, useContentPage, useContentPages, useProduct, useProductConfig, usePublicJobPosting, usePublicJobPostings, useWebSDK, useWebSDKConfig };
9087
9515
  //# sourceMappingURL=index.mjs.map
9088
9516
  //# sourceMappingURL=index.mjs.map