@burdenoff/microfe-devportal 2026.1107.3 → 2026.1108.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PublisherPayoutsPage.js","names":[],"sources":["../../../src/devportal/pages/PublisherPayoutsPage.tsx"],"sourcesContent":["import type { FC, FormEvent } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useSearchParams } from \"react-router\";\nimport {\n AlertCircle,\n BadgeCheck,\n CheckCircle2,\n ExternalLink,\n Info,\n Landmark,\n Loader2,\n Plus,\n RefreshCw,\n ShieldCheck,\n Trash2,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport {\n CheckboxField,\n InputField,\n SelectField,\n} from \"../components/FormField\";\nimport { ConfirmDialog } from \"../components/ConfirmDialog\";\nimport { PermissionGuard } from \"../components\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n useAcceptMyPublisherDeveloperAgreementMutation,\n useAddMyPublisherPayoutMethodMutation,\n useGetMyPublisherPayoutsQuery,\n useRefreshMyPublisherPayoutOnboardingMutation,\n useRemoveMyPublisherPayoutMethodMutation,\n useStartMyPublisherPayoutOnboardingMutation,\n type GetMyPublisherPayoutsQuery,\n} from \"../hooks/useGraphQL\";\nimport { PayoutMethodType } from \"../../generated/global-types\";\nimport { cn } from \"../utils/cn\";\nimport { useTr } from \"../utils/i18n\";\nimport {\n accountLast4Of,\n canStartOnboarding,\n methodTypesForCountry,\n methodsToPoll,\n needsBankDetails,\n normalizeCountry,\n payoutErrorMessage,\n payoutMethodPhase,\n readOnboardingRedirect,\n redirectToOnboarding,\n safeOnboardingUrl,\n stripeMethodsInOnboarding,\n supportsAutomaticOnboarding,\n toAddPayoutMethodInput,\n toOnboardingInput,\n validateAddPayoutMethod,\n validateOnboarding,\n type AddPayoutMethodField,\n type AddPayoutMethodForm,\n type OnboardingField,\n type OnboardingForm,\n type PayoutMethodPhase,\n} from \"../utils/publisherPayouts\";\n\ntype PayoutMethod =\n GetMyPublisherPayoutsQuery[\"myPublisherPayoutMethods\"][number];\n\n/** How often an in-progress verification is re-read while the page is open. */\nexport const PAYOUT_POLL_INTERVAL_MS = 15_000;\n/** Polls per page visit (about five minutes); the store keeps syncing after. */\nexport const PAYOUT_POLL_MAX_ROUNDS = 20;\n\nconst PHASE_STYLES: Record<PayoutMethodPhase, string> = {\n VERIFIED: \"bg-status-success-bg-subtle text-status-success-text\",\n NOT_STARTED: \"bg-bg-sunken text-text-primary\",\n IN_PROGRESS: \"bg-status-info-bg-subtle text-status-info-text\",\n AWAITING_KYC: \"bg-status-warning-bg-subtle text-status-warning-text\",\n FAILED: \"bg-status-error-bg-subtle text-status-error-text\",\n MANUAL_REVIEW: \"bg-status-warning-bg-subtle text-status-warning-text\",\n REJECTED: \"bg-status-error-bg-subtle text-status-error-text\",\n SUSPENDED: \"bg-status-error-bg-subtle text-status-error-text\",\n CLOSED: \"bg-bg-sunken text-text-secondary\",\n};\n\nconst EMPTY_ADD_FORM: AddPayoutMethodForm = {\n type: \"\",\n country: \"\",\n accountHolderName: \"\",\n accountNumberLast4: \"\",\n bankCode: \"\",\n bankName: \"\",\n isDefault: false,\n};\n\nconst EMPTY_ONBOARDING_FORM: OnboardingForm = {\n contactEmail: \"\",\n contactPhone: \"\",\n accountNumber: \"\",\n};\n\ntype Notice = { tone: \"success\" | \"info\" | \"error\"; text: string } | null;\n\nconst primaryButton =\n \"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:cursor-not-allowed disabled:opacity-50\";\nconst secondaryButton =\n \"inline-flex items-center gap-2 rounded-md border border-border-default bg-bg-surface px-3 py-1.5 text-sm font-medium text-text-primary hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-50\";\n\n/**\n * Publisher Payouts page (BOFF-10953).\n *\n * Lists the publisher's payout methods with their verification state, adds\n * new ones, and runs automatic processor onboarding: RazorpayX fund-account\n * validation for India (the full account number is entered once and never\n * stored) and Stripe Connect Express hosted onboarding everywhere else. Stripe\n * sends the publisher back here with `?onboarding=return` (re-read the state)\n * or `?onboarding=refresh` (the link expired; start again).\n *\n * Mounted at `/devportal/publisher/payouts`; global-store-svc's\n * STORE_PAYOUT_ONBOARDING_URL points at this page.\n */\nexport const PublisherPayoutsPage: FC = () => {\n const tr = useTr();\n const { currentUser, navigate, basePath } = useDevportal();\n const [searchParams, setSearchParams] = useSearchParams();\n\n const payoutsQuery = useGetMyPublisherPayoutsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n const { loading, error, refetch } = payoutsQuery;\n // Typed explicitly: the generated hook's data resolves loosely here.\n const data: GetMyPublisherPayoutsQuery | undefined = payoutsQuery.data;\n const [acceptAgreement, { loading: accepting }] =\n useAcceptMyPublisherDeveloperAgreementMutation();\n const [addMethod, { loading: adding }] =\n useAddMyPublisherPayoutMethodMutation();\n const [removeMethod, { loading: removing }] =\n useRemoveMyPublisherPayoutMethodMutation();\n const [startOnboarding, { loading: starting }] =\n useStartMyPublisherPayoutOnboardingMutation();\n const [refreshOnboarding] = useRefreshMyPublisherPayoutOnboardingMutation();\n\n const onboarding = data?.myPublisherOnboarding;\n const publisher = onboarding?.publisher ?? null;\n const route = onboarding?.payoutRoute ?? null;\n const methods = useMemo(\n () => data?.myPublisherPayoutMethods ?? [],\n [data?.myPublisherPayoutMethods],\n );\n const agreementStep = onboarding?.steps.find(\n (s) => s.key === \"DEVELOPER_AGREEMENT\",\n );\n const payoutStep = onboarding?.steps.find((s) => s.key === \"PAYOUT_METHOD\");\n const agreementAccepted = agreementStep?.status === \"COMPLETE\";\n\n const [notice, setNotice] = useState<Notice>(null);\n const [showAddForm, setShowAddForm] = useState(false);\n const [addForm, setAddForm] = useState<AddPayoutMethodForm>(EMPTY_ADD_FORM);\n const [addErrors, setAddErrors] = useState<\n Partial<Record<AddPayoutMethodField, string>>\n >({});\n const [verifyingId, setVerifyingId] = useState<string | null>(null);\n const [onboardingForm, setOnboardingForm] = useState<OnboardingForm>(\n EMPTY_ONBOARDING_FORM,\n );\n const [onboardingErrors, setOnboardingErrors] = useState<\n Partial<Record<OnboardingField, string>>\n >({});\n const [removeTarget, setRemoveTarget] = useState<PayoutMethod | null>(null);\n const [checkingId, setCheckingId] = useState<string | null>(null);\n\n const defaultEmail = publisher?.contactEmail || currentUser?.email || \"\";\n const defaultPhone = publisher?.contactPhone || \"\";\n\n const openVerifyForm = useCallback(\n (methodId: string) => {\n setVerifyingId(methodId);\n setOnboardingErrors({});\n setOnboardingForm({\n contactEmail: defaultEmail,\n contactPhone: defaultPhone,\n accountNumber: \"\",\n });\n },\n [defaultEmail, defaultPhone],\n );\n\n // ── Stripe hands the publisher back with ?onboarding=return|refresh ────────\n const redirect = readOnboardingRedirect(`?${searchParams.toString()}`);\n const redirectHandled = useRef(false);\n useEffect(() => {\n if (!redirect || redirectHandled.current || !data) return;\n redirectHandled.current = true;\n const stripeMethods = stripeMethodsInOnboarding(methods);\n const clearParam = () => {\n const next = new URLSearchParams(searchParams);\n next.delete(\"onboarding\");\n setSearchParams(next, { replace: true });\n };\n if (redirect === \"refresh\") {\n const first = stripeMethods[0];\n if (first) openVerifyForm(first.id);\n setNotice({\n tone: \"info\",\n text: tr(\n \"devportal.payouts.linkExpired\",\n \"Your Stripe onboarding link expired. Confirm your contact email to get a fresh link.\",\n ),\n });\n clearParam();\n return;\n }\n void (async () => {\n try {\n await Promise.all(\n stripeMethods.map((m) =>\n refreshOnboarding({ variables: { id: m.id } }),\n ),\n );\n await refetch();\n setNotice({\n tone: \"success\",\n text: tr(\n \"devportal.payouts.returnedFromStripe\",\n \"Welcome back. We checked your Stripe account; its status is shown below.\",\n ),\n });\n } catch (err) {\n setNotice({ tone: \"error\", text: payoutErrorMessage(err, \"refresh\") });\n } finally {\n clearParam();\n }\n })();\n }, [\n redirect,\n data,\n methods,\n searchParams,\n setSearchParams,\n refreshOnboarding,\n refetch,\n openVerifyForm,\n tr,\n ]);\n\n // ── Re-read in-progress verifications while the page is open ───────────────\n const pollIds = methodsToPoll(methods)\n .map((m) => m.id)\n .join(\",\");\n useEffect(() => {\n if (!pollIds) return;\n const ids = pollIds.split(\",\");\n let rounds = 0;\n const timer = setInterval(() => {\n rounds += 1;\n if (rounds > PAYOUT_POLL_MAX_ROUNDS) {\n clearInterval(timer);\n return;\n }\n void Promise.all(\n ids.map((id) => refreshOnboarding({ variables: { id } })),\n )\n .then(() => refetch())\n .catch(() => {\n // A failed background poll is not the publisher's problem; the\n // store's own five-minute sync keeps the state current.\n });\n }, PAYOUT_POLL_INTERVAL_MS);\n return () => clearInterval(timer);\n }, [pollIds, refreshOnboarding, refetch]);\n\n const offeredTypes = methodTypesForCountry(\n addForm.country || route?.country,\n route,\n );\n\n const openAddForm = () => {\n setShowAddForm(true);\n setAddErrors({});\n const country = normalizeCountry(publisher?.country ?? route?.country);\n const types = methodTypesForCountry(country, route);\n setAddForm({\n ...EMPTY_ADD_FORM,\n country,\n type: types[0] ?? \"\",\n accountHolderName: publisher?.name ?? \"\",\n });\n };\n\n const handleAccept = async () => {\n if (!onboarding) return;\n setNotice(null);\n try {\n await acceptAgreement({\n variables: { version: onboarding.currentAgreementVersion },\n });\n await refetch();\n setNotice({\n tone: \"success\",\n text: tr(\n \"devportal.payouts.agreementAccepted\",\n \"Agreement accepted. You can now add a payout method.\",\n ),\n });\n } catch (err) {\n setNotice({ tone: \"error\", text: payoutErrorMessage(err, \"agreement\") });\n }\n };\n\n const handleAdd = async (event: FormEvent) => {\n event.preventDefault();\n const errors = validateAddPayoutMethod(addForm, route);\n setAddErrors(errors);\n if (Object.keys(errors).length > 0) return;\n setNotice(null);\n try {\n const result = await addMethod({\n variables: { input: toAddPayoutMethodInput(addForm) },\n });\n const created = result.data?.addMyPublisherPayoutMethod;\n await refetch();\n setShowAddForm(false);\n setAddForm(EMPTY_ADD_FORM);\n if (created && supportsAutomaticOnboarding(created.type)) {\n openVerifyForm(created.id);\n setNotice({\n tone: \"success\",\n text: tr(\n \"devportal.payouts.addedVerifyNext\",\n \"Payout method added. Verify it automatically below so payouts can be sent to it.\",\n ),\n });\n } else {\n setNotice({\n tone: \"success\",\n text: tr(\n \"devportal.payouts.addedManualReview\",\n \"Payout method added. The marketplace team verifies bank transfers, usually within two business days.\",\n ),\n });\n }\n } catch (err) {\n setNotice({ tone: \"error\", text: payoutErrorMessage(err, \"add\") });\n }\n };\n\n const handleStart = async (method: PayoutMethod, event: FormEvent) => {\n event.preventDefault();\n const errors = validateOnboarding(\n method.type,\n onboardingForm,\n accountLast4Of(method.maskedDetails),\n );\n setOnboardingErrors(errors);\n if (Object.keys(errors).length > 0) return;\n setNotice(null);\n try {\n const result = await startOnboarding({\n variables: {\n id: method.id,\n input: toOnboardingInput(method.type, onboardingForm),\n },\n });\n // The account number is never kept in the page once it has been sent.\n setOnboardingForm(EMPTY_ONBOARDING_FORM);\n const outcome = result.data?.startMyPublisherPayoutOnboarding;\n const url = safeOnboardingUrl(outcome?.onboardingUrl);\n if (method.type === \"STRIPE_CONNECT\" && url) {\n setNotice({\n tone: \"info\",\n text: tr(\n \"devportal.payouts.redirectingToStripe\",\n \"Taking you to Stripe to finish setting up your account...\",\n ),\n });\n redirectToOnboarding(url);\n return;\n }\n setVerifyingId(null);\n await refetch();\n setNotice(\n outcome?.method.status === \"VERIFIED\"\n ? {\n tone: \"success\",\n text: tr(\n \"devportal.payouts.verified\",\n \"Your payout method is verified. Payouts will be sent to it.\",\n ),\n }\n : {\n tone: \"info\",\n text: tr(\n \"devportal.payouts.verificationStarted\",\n \"Verification started. This page updates on its own when the processor confirms your account.\",\n ),\n },\n );\n } catch (err) {\n setOnboardingForm((f) => ({ ...f, accountNumber: \"\" }));\n setNotice({ tone: \"error\", text: payoutErrorMessage(err, \"start\") });\n }\n };\n\n const handleCheckStatus = async (method: PayoutMethod) => {\n setCheckingId(method.id);\n setNotice(null);\n try {\n await refreshOnboarding({ variables: { id: method.id } });\n await refetch();\n } catch (err) {\n setNotice({ tone: \"error\", text: payoutErrorMessage(err, \"refresh\") });\n } finally {\n setCheckingId(null);\n }\n };\n\n const handleRemove = async () => {\n if (!removeTarget) return;\n try {\n await removeMethod({ variables: { id: removeTarget.id } });\n setRemoveTarget(null);\n if (verifyingId === removeTarget.id) setVerifyingId(null);\n await refetch();\n setNotice({\n tone: \"success\",\n text: tr(\"devportal.payouts.removed\", \"Payout method removed.\"),\n });\n } catch (err) {\n setRemoveTarget(null);\n setNotice({ tone: \"error\", text: payoutErrorMessage(err, \"remove\") });\n }\n };\n\n const goTo = (path: string) => {\n const base = (basePath ?? \"\").replace(/\\/$/, \"\");\n navigate?.(`${base}/${path}`);\n };\n\n const title = tr(\"devportal.payouts.title\", \"Payouts\");\n const description = tr(\n \"devportal.payouts.description\",\n \"Choose where the marketplace sends your earnings\",\n );\n\n if (loading && !data) {\n return (\n <PageLayout title={title} description={description}>\n <div\n className=\"flex items-center justify-center py-20\"\n role=\"status\"\n aria-label={tr(\"devportal.payouts.loading\", \"Loading payout methods\")}\n >\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error && !data) {\n return (\n <PageLayout title={title} description={description}>\n <div className=\"flex flex-col items-center justify-center gap-4 py-20\">\n <AlertCircle className=\"h-12 w-12 text-status-error-text\" />\n <p className=\"text-text-secondary\">\n {tr(\n \"devportal.payouts.loadFailed\",\n \"Your payout methods could not be loaded.\",\n )}\n </p>\n <button onClick={() => void refetch()} className={primaryButton}>\n {tr(\"devportal.retryButton\", \"Retry\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n const phaseLabel = (phase: PayoutMethodPhase): string => {\n switch (phase) {\n case \"VERIFIED\":\n return tr(\"devportal.payouts.phase.verified\", \"Verified\");\n case \"NOT_STARTED\":\n return tr(\"devportal.payouts.phase.notStarted\", \"Not verified yet\");\n case \"IN_PROGRESS\":\n return tr(\n \"devportal.payouts.phase.inProgress\",\n \"Verification in progress\",\n );\n case \"AWAITING_KYC\":\n return tr(\n \"devportal.payouts.phase.awaitingKyc\",\n \"Waiting for publisher verification\",\n );\n case \"FAILED\":\n return tr(\"devportal.payouts.phase.failed\", \"Verification failed\");\n case \"MANUAL_REVIEW\":\n return tr(\"devportal.payouts.phase.manualReview\", \"In manual review\");\n case \"REJECTED\":\n return tr(\"devportal.payouts.phase.rejected\", \"Rejected\");\n case \"SUSPENDED\":\n return tr(\"devportal.payouts.phase.suspended\", \"Suspended\");\n case \"CLOSED\":\n return tr(\"devportal.payouts.phase.closed\", \"Closed\");\n }\n };\n\n const phaseHint = (\n method: PayoutMethod,\n phase: PayoutMethodPhase,\n ): string | null => {\n switch (phase) {\n case \"NOT_STARTED\":\n return tr(\n \"devportal.payouts.hint.notStarted\",\n \"Verify this method automatically so payouts can be sent to it.\",\n );\n case \"IN_PROGRESS\":\n return method.type === \"STRIPE_CONNECT\"\n ? tr(\n \"devportal.payouts.hint.inProgressStripe\",\n \"Finish the Stripe onboarding form. If you closed it, continue to get a fresh link.\",\n )\n : tr(\n \"devportal.payouts.hint.inProgressRazorpay\",\n \"RazorpayX is validating your bank account. This usually takes a few minutes.\",\n );\n case \"AWAITING_KYC\":\n return tr(\n \"devportal.payouts.hint.awaitingKyc\",\n \"The processor confirmed your account. It is verified as soon as your publisher verification (KYC) is approved.\",\n );\n case \"FAILED\":\n return tr(\n \"devportal.payouts.hint.failed\",\n \"The processor could not verify this account. Check the details and verify again, or remove it and add a new one.\",\n );\n case \"MANUAL_REVIEW\":\n return tr(\n \"devportal.payouts.hint.manualReview\",\n \"The marketplace team verifies bank transfers by hand, usually within two business days.\",\n );\n default:\n return null;\n }\n };\n\n const typeLabel = (type: string): string => {\n switch (type) {\n case PayoutMethodType.RazorpayX:\n return tr(\"devportal.payouts.type.razorpayX\", \"RazorpayX (India, INR)\");\n case PayoutMethodType.StripeConnect:\n return tr(\"devportal.payouts.type.stripeConnect\", \"Stripe Connect\");\n case PayoutMethodType.BankTransfer:\n return tr(\"devportal.payouts.type.bankTransfer\", \"Bank transfer\");\n default:\n return type;\n }\n };\n\n const noticeStyles: Record<\"success\" | \"info\" | \"error\", string> = {\n success: \"bg-status-success-bg-subtle text-status-success-text\",\n info: \"bg-status-info-bg-subtle text-status-info-text\",\n error: \"bg-status-error-bg-subtle text-status-error-text\",\n };\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={title}\n description={description}\n backLink=\"publisher/profile\"\n backLabel={tr(\"devportal.payouts.backToProfile\", \"Publisher profile\")}\n purpose={tr(\n \"devportal.payouts.purpose\",\n \"Paid listings pay out monthly to a verified payout method. In India payouts go through RazorpayX in INR; everywhere else through Stripe Connect in USD, with an international bank transfer as the alternative.\",\n )}\n actions={\n publisher && agreementAccepted && !showAddForm ? (\n <button onClick={openAddForm} className={primaryButton}>\n <Plus size={16} />\n {tr(\"devportal.payouts.addMethod\", \"Add payout method\")}\n </button>\n ) : undefined\n }\n >\n {notice && (\n <div\n role={notice.tone === \"error\" ? \"alert\" : \"status\"}\n className={cn(\n \"flex gap-3 rounded-lg border border-border-subtle p-4 text-sm\",\n noticeStyles[notice.tone],\n )}\n >\n {notice.tone === \"error\" ? (\n <AlertCircle size={16} className=\"mt-0.5 flex-shrink-0\" />\n ) : notice.tone === \"success\" ? (\n <CheckCircle2 size={16} className=\"mt-0.5 flex-shrink-0\" />\n ) : (\n <Info size={16} className=\"mt-0.5 flex-shrink-0\" />\n )}\n <p>{notice.text}</p>\n </div>\n )}\n\n {!publisher ? (\n <PageSection\n title={tr(\n \"devportal.payouts.noPublisherTitle\",\n \"No publisher profile yet\",\n )}\n >\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.payouts.noPublisherBody\",\n \"Your publisher profile is created when you submit your first app to the store. Once it exists you can accept the developer agreement and add a payout method here.\",\n )}\n </p>\n <button\n onClick={() => goTo(\"apps\")}\n className={cn(primaryButton, \"mt-4\")}\n >\n {tr(\"devportal.payouts.goToApps\", \"Go to my apps\")}\n </button>\n </PageSection>\n ) : (\n <>\n {!agreementAccepted && onboarding && (\n <PageSection\n title={tr(\n \"devportal.payouts.agreementTitle\",\n \"Accept the Marketplace & Developer Agreement\",\n )}\n description={tr(\n \"devportal.payouts.agreementDescription\",\n \"Payout methods can be added once you accept the current agreement.\",\n )}\n >\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {agreementStep?.reason === \"AGREEMENT_OUTDATED\"\n ? tr(\n \"devportal.payouts.agreementOutdated\",\n \"The agreement has changed since you accepted it. Review version {{version}} to continue.\",\n { version: onboarding.currentAgreementVersion },\n )\n : tr(\n \"devportal.payouts.agreementBody\",\n \"Version {{version}}. Your share of net sales is {{share}}%.\",\n {\n version: onboarding.currentAgreementVersion,\n share: onboarding.revenueSharePercent,\n },\n )}{\" \"}\n <a\n href={onboarding.agreementUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 font-medium text-primary hover:underline\"\n >\n {tr(\n \"devportal.payouts.readAgreement\",\n \"Read the agreement\",\n )}\n <ExternalLink size={12} />\n </a>\n </p>\n <button\n onClick={() => void handleAccept()}\n disabled={accepting}\n className={primaryButton}\n >\n {accepting ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : (\n <ShieldCheck size={16} />\n )}\n {tr(\"devportal.payouts.acceptAgreement\", \"I accept\")}\n </button>\n </div>\n </PageSection>\n )}\n\n {route && (\n <div className=\"flex gap-3 rounded-lg border border-border-subtle bg-status-info-bg-subtle p-4 text-sm text-status-info-text\">\n <Info size={16} className=\"mt-0.5 flex-shrink-0\" />\n <p>\n {route.processor === \"RAZORPAYX\"\n ? tr(\n \"devportal.payouts.routeIndia\",\n \"Your payouts are sent through RazorpayX in {{currency}}.\",\n { currency: route.currency },\n )\n : tr(\n \"devportal.payouts.routeInternational\",\n \"Your payouts are sent through Stripe Connect in {{currency}}, or by international bank transfer.\",\n { currency: route.currency },\n )}\n {payoutStep?.status === \"COMPLETE\"\n ? ` ${tr(\"devportal.payouts.stepComplete\", \"You have a verified payout method.\")}`\n : ` ${tr(\"devportal.payouts.stepIncomplete\", \"You need a verified payout method before paid listings can be paid out.\")}`}\n </p>\n </div>\n )}\n\n {showAddForm && (\n <PageSection\n title={tr(\"devportal.payouts.addTitle\", \"Add a payout method\")}\n description={tr(\n \"devportal.payouts.addDescription\",\n \"Only the last four digits and the bank code are stored. The processor holds the full account.\",\n )}\n >\n <form\n onSubmit={(e) => void handleAdd(e)}\n className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\"\n noValidate\n >\n <InputField\n id=\"payout-country\"\n label={tr(\"devportal.payouts.country\", \"Account country\")}\n value={addForm.country}\n maxLength={2}\n required\n hint={tr(\n \"devportal.payouts.countryHint\",\n \"Two-letter code, for example IN or US\",\n )}\n error={addErrors.country}\n onChange={(e) => {\n const country = e.target.value.toUpperCase();\n const types = methodTypesForCountry(country, route);\n setAddForm((f) => ({\n ...f,\n country,\n type: types.some((t) => t === f.type)\n ? f.type\n : (types[0] ?? \"\"),\n }));\n }}\n />\n <SelectField\n id=\"payout-type\"\n label={tr(\"devportal.payouts.methodType\", \"Payout method\")}\n value={addForm.type}\n required\n error={addErrors.type}\n options={offeredTypes.map((t) => ({\n value: t,\n label: typeLabel(t),\n }))}\n onChange={(e) =>\n setAddForm((f) => ({ ...f, type: e.target.value }))\n }\n />\n <InputField\n id=\"payout-holder\"\n label={tr(\n \"devportal.payouts.holderName\",\n \"Account holder name\",\n )}\n value={addForm.accountHolderName}\n required\n error={addErrors.accountHolderName}\n onChange={(e) =>\n setAddForm((f) => ({\n ...f,\n accountHolderName: e.target.value,\n }))\n }\n />\n {needsBankDetails(addForm.type) && (\n <>\n <InputField\n id=\"payout-last4\"\n label={tr(\n \"devportal.payouts.last4\",\n \"Last four digits of the account number\",\n )}\n value={addForm.accountNumberLast4}\n inputMode=\"numeric\"\n maxLength={4}\n required\n error={addErrors.accountNumberLast4}\n onChange={(e) =>\n setAddForm((f) => ({\n ...f,\n accountNumberLast4: e.target.value.replace(\n /\\D/g,\n \"\",\n ),\n }))\n }\n />\n <InputField\n id=\"payout-bank-code\"\n label={\n normalizeCountry(addForm.country) === \"IN\"\n ? tr(\"devportal.payouts.ifsc\", \"IFSC\")\n : tr(\"devportal.payouts.swift\", \"SWIFT / BIC\")\n }\n value={addForm.bankCode}\n maxLength={11}\n required\n error={addErrors.bankCode}\n onChange={(e) =>\n setAddForm((f) => ({\n ...f,\n bankCode: e.target.value.toUpperCase(),\n }))\n }\n />\n <InputField\n id=\"payout-bank-name\"\n label={tr(\n \"devportal.payouts.bankName\",\n \"Bank name (optional)\",\n )}\n value={addForm.bankName}\n onChange={(e) =>\n setAddForm((f) => ({\n ...f,\n bankName: e.target.value,\n }))\n }\n />\n </>\n )}\n {addForm.type === PayoutMethodType.StripeConnect && (\n <p className=\"text-sm text-text-secondary sm:col-span-2\">\n {tr(\n \"devportal.payouts.stripeNote\",\n \"Stripe collects your bank details and identity on its own secure page when you verify the method.\",\n )}\n </p>\n )}\n <CheckboxField\n id=\"payout-default\"\n className=\"sm:col-span-2\"\n label={tr(\n \"devportal.payouts.makeDefault\",\n \"Use as my default payout method\",\n )}\n checked={addForm.isDefault}\n onChange={(e) =>\n setAddForm((f) => ({ ...f, isDefault: e.target.checked }))\n }\n />\n <div className=\"flex gap-2 sm:col-span-2\">\n <button\n type=\"submit\"\n disabled={adding}\n className={primaryButton}\n >\n {adding ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : (\n <Plus size={16} />\n )}\n {tr(\"devportal.payouts.saveMethod\", \"Add method\")}\n </button>\n <button\n type=\"button\"\n onClick={() => setShowAddForm(false)}\n className={secondaryButton}\n >\n {tr(\"devportal.payouts.cancel\", \"Cancel\")}\n </button>\n </div>\n </form>\n </PageSection>\n )}\n\n <PageSection\n title={tr(\n \"devportal.payouts.methodsTitle\",\n \"Your payout methods\",\n )}\n >\n {methods.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 py-8 text-center\">\n <Landmark className=\"h-10 w-10 text-text-secondary\" />\n <p className=\"text-sm text-text-secondary\">\n {agreementAccepted\n ? tr(\n \"devportal.payouts.emptyReady\",\n \"You have not added a payout method yet.\",\n )\n : tr(\n \"devportal.payouts.emptyNeedsAgreement\",\n \"Accept the agreement above, then add a payout method.\",\n )}\n </p>\n </div>\n ) : (\n <ul\n className=\"flex flex-col gap-3\"\n aria-label={tr(\n \"devportal.payouts.methodsTitle\",\n \"Your payout methods\",\n )}\n >\n {methods.map((method) => {\n const phase = payoutMethodPhase(method);\n const hint = phaseHint(method, phase);\n const isVerifying = verifyingId === method.id;\n const last4 = accountLast4Of(method.maskedDetails);\n return (\n <li\n key={method.id}\n data-testid={`payout-method-${method.id}`}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text-primary\">\n {method.displayLabel ?? typeLabel(method.type)}\n </span>\n <span\n className={cn(\n \"inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium\",\n PHASE_STYLES[phase],\n )}\n >\n {phase === \"VERIFIED\" && (\n <BadgeCheck size={12} className=\"mr-1\" />\n )}\n {phaseLabel(phase)}\n </span>\n {method.isDefault && (\n <span className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {tr(\"devportal.payouts.default\", \"Default\")}\n </span>\n )}\n </div>\n <p className=\"text-xs text-text-secondary\">\n {typeLabel(method.type)}\n {method.country ? ` · ${method.country}` : \"\"}\n {method.currency ? ` · ${method.currency}` : \"\"}\n </p>\n {hint && (\n <p className=\"text-sm text-text-secondary\">\n {hint}\n </p>\n )}\n {method.processorFailureReason &&\n phase === \"FAILED\" && (\n <p className=\"text-sm text-status-error-text\">\n {tr(\n \"devportal.payouts.failureReason\",\n \"Reason: {{reason}}\",\n {\n reason: method.processorFailureReason,\n },\n )}\n </p>\n )}\n {method.rejectionReason && phase === \"REJECTED\" && (\n <p className=\"text-sm text-status-error-text\">\n {tr(\n \"devportal.payouts.rejectionReason\",\n \"Reason: {{reason}}\",\n {\n reason: method.rejectionReason,\n },\n )}\n </p>\n )}\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {canStartOnboarding(method) && !isVerifying && (\n <button\n onClick={() => openVerifyForm(method.id)}\n className={primaryButton}\n >\n <ShieldCheck size={16} />\n {phase === \"IN_PROGRESS\"\n ? tr(\n \"devportal.payouts.continueStripe\",\n \"Continue on Stripe\",\n )\n : tr(\n \"devportal.payouts.verifyAutomatically\",\n \"Verify automatically\",\n )}\n </button>\n )}\n {(phase === \"IN_PROGRESS\" ||\n phase === \"AWAITING_KYC\") && (\n <button\n onClick={() => void handleCheckStatus(method)}\n disabled={checkingId === method.id}\n className={secondaryButton}\n >\n <RefreshCw\n size={14}\n className={cn(\n checkingId === method.id && \"animate-spin\",\n )}\n />\n {tr(\n \"devportal.payouts.checkStatus\",\n \"Check status\",\n )}\n </button>\n )}\n {phase !== \"CLOSED\" && phase !== \"REJECTED\" && (\n <button\n onClick={() => setRemoveTarget(method)}\n className={secondaryButton}\n aria-label={tr(\n \"devportal.payouts.removeLabel\",\n \"Remove {{label}}\",\n {\n label:\n method.displayLabel ??\n typeLabel(method.type),\n },\n )}\n >\n <Trash2 size={14} />\n {tr(\"devportal.payouts.remove\", \"Remove\")}\n </button>\n )}\n </div>\n </div>\n\n {isVerifying && (\n <form\n onSubmit={(e) => void handleStart(method, e)}\n className=\"mt-4 grid grid-cols-1 gap-4 border-t border-border-subtle pt-4 sm:grid-cols-2\"\n aria-label={tr(\n \"devportal.payouts.verifyFormLabel\",\n \"Verify payout method\",\n )}\n noValidate\n >\n <InputField\n id={`contact-email-${method.id}`}\n type=\"email\"\n label={tr(\n \"devportal.payouts.contactEmail\",\n \"Contact email\",\n )}\n value={onboardingForm.contactEmail}\n required\n autoComplete=\"email\"\n error={onboardingErrors.contactEmail}\n onChange={(e) =>\n setOnboardingForm((f) => ({\n ...f,\n contactEmail: e.target.value,\n }))\n }\n />\n {method.type === PayoutMethodType.RazorpayX && (\n <>\n <InputField\n id={`contact-phone-${method.id}`}\n type=\"tel\"\n label={tr(\n \"devportal.payouts.contactPhone\",\n \"Contact phone (optional)\",\n )}\n value={onboardingForm.contactPhone}\n autoComplete=\"tel\"\n error={onboardingErrors.contactPhone}\n onChange={(e) =>\n setOnboardingForm((f) => ({\n ...f,\n contactPhone: e.target.value,\n }))\n }\n />\n <InputField\n id={`account-number-${method.id}`}\n type=\"password\"\n label={tr(\n \"devportal.payouts.accountNumber\",\n \"Full account number\",\n )}\n value={onboardingForm.accountNumber}\n required\n autoComplete=\"off\"\n inputMode=\"numeric\"\n hint={\n last4\n ? tr(\n \"devportal.payouts.accountNumberHint\",\n \"Ends in {{last4}}. Sent to RazorpayX once for validation and never stored.\",\n { last4 },\n )\n : tr(\n \"devportal.payouts.accountNumberHintNoLast4\",\n \"Sent to RazorpayX once for validation and never stored.\",\n )\n }\n error={onboardingErrors.accountNumber}\n onChange={(e) =>\n setOnboardingForm((f) => ({\n ...f,\n accountNumber: e.target.value,\n }))\n }\n />\n </>\n )}\n {method.type === PayoutMethodType.StripeConnect && (\n <p className=\"text-sm text-text-secondary sm:col-span-2\">\n {tr(\n \"devportal.payouts.stripeRedirectNote\",\n \"You will continue on Stripe's secure page to add your bank account and confirm your identity, then come back here.\",\n )}\n </p>\n )}\n <div className=\"flex gap-2 sm:col-span-2\">\n <button\n type=\"submit\"\n disabled={starting}\n className={primaryButton}\n >\n {starting ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : (\n <ShieldCheck size={16} />\n )}\n {method.type === PayoutMethodType.StripeConnect\n ? tr(\n \"devportal.payouts.continueToStripe\",\n \"Continue to Stripe\",\n )\n : tr(\n \"devportal.payouts.startVerification\",\n \"Start verification\",\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setVerifyingId(null);\n setOnboardingForm(EMPTY_ONBOARDING_FORM);\n }}\n className={secondaryButton}\n >\n {tr(\"devportal.payouts.cancel\", \"Cancel\")}\n </button>\n </div>\n </form>\n )}\n </li>\n );\n })}\n </ul>\n )}\n </PageSection>\n </>\n )}\n\n <ConfirmDialog\n open={removeTarget !== null}\n onOpenChange={(open) => {\n if (!open) setRemoveTarget(null);\n }}\n onConfirm={handleRemove}\n title={tr(\n \"devportal.payouts.removeTitle\",\n \"Remove this payout method?\",\n )}\n description={tr(\n \"devportal.payouts.removeDescription\",\n \"Payouts will no longer be sent to it. You can add it again later.\",\n )}\n confirmLabel={tr(\"devportal.payouts.remove\", \"Remove\")}\n cancelLabel={tr(\"devportal.payouts.cancel\", \"Cancel\")}\n variant=\"destructive\"\n loading={removing}\n />\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PublisherProfilePage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/PublisherProfilePage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAwBhC;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,EAAE,EA8blC,CAAC"}
1
+ {"version":3,"file":"PublisherProfilePage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/PublisherProfilePage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAyBhC;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,EAAE,EAodlC,CAAC"}
@@ -9,261 +9,274 @@ import "../components/index.js";
9
9
  import { useDevportalPermission as l } from "../hooks/usePermission.js";
10
10
  import { DEVPORTAL_PERMISSIONS as u } from "../constants/permissions.js";
11
11
  import { useEffect as d, useState as f } from "react";
12
- import { AlertCircle as p, CheckCircle2 as m, Info as h, Loader2 as g, Save as _, Store as v } from "lucide-react";
13
- import { jsx as y, jsxs as b } from "react/jsx-runtime";
14
- import { useI18n as x } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
+ import { AlertCircle as p, CheckCircle2 as m, Info as h, Landmark as g, Loader2 as _, Save as v, Store as y } from "lucide-react";
13
+ import { jsx as b, jsxs as x } from "react/jsx-runtime";
14
+ import { useI18n as S } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
15
  //#region src/devportal/pages/PublisherProfilePage.tsx
16
- var S = () => {
17
- let { t: S } = x(), C = (e, t) => {
18
- let n = S(e);
16
+ var C = () => {
17
+ let { t: C } = S(), w = (e, t) => {
18
+ let n = C(e);
19
19
  return n === e ? t : n;
20
- }, { currentUser: w } = e(), { allowed: T } = l(u.PROFILE_UPDATE), { data: E, loading: D, error: O, refetch: k } = r({ fetchPolicy: "cache-and-network" }), [A, { loading: j }] = i(), [M, { loading: N }] = n(), P = j || N, F = E?.myDeveloperProfile, [I, L] = f(""), [R, z] = f(""), [B, V] = f(""), [H, U] = f(""), [W, G] = f(""), [K, q] = f(""), [J, Y] = f("idle");
20
+ }, { currentUser: T, navigate: E, basePath: D } = e(), O = () => {
21
+ let e = (D ?? "").replace(/\/$/, "");
22
+ E?.(`${e}/publisher/payouts`);
23
+ }, { allowed: k } = l(u.PROFILE_UPDATE), { data: A, loading: j, error: M, refetch: N } = r({ fetchPolicy: "cache-and-network" }), [P, { loading: F }] = i(), [I, { loading: L }] = n(), R = F || L, z = A?.myDeveloperProfile, [B, V] = f(""), [H, U] = f(""), [W, G] = f(""), [K, q] = f(""), [J, Y] = f(""), [X, Z] = f(""), [Q, $] = f("idle");
21
24
  return d(() => {
22
- if (F) L(F.companyName ?? ""), z(F.website ?? ""), V(F.bio ?? ""), U(F.githubUsername ?? ""), G(F.twitterUsername ?? ""), q(F.linkedinUrl ?? "");
23
- else if (!D && w) {
24
- let e = [w.firstName, w.lastName].filter(Boolean).join(" ");
25
- e && L(e);
25
+ if (z) V(z.companyName ?? ""), U(z.website ?? ""), G(z.bio ?? ""), q(z.githubUsername ?? ""), Y(z.twitterUsername ?? ""), Z(z.linkedinUrl ?? "");
26
+ else if (!j && T) {
27
+ let e = [T.firstName, T.lastName].filter(Boolean).join(" ");
28
+ e && V(e);
26
29
  }
27
30
  }, [
28
- F,
29
- D,
30
- w
31
- ]), D && !F ? /* @__PURE__ */ y(a, {
32
- title: C("devportal.publisherProfileTitle", "Publisher Profile"),
33
- description: C("devportal.loadingPublisherProfile", "Loading your publisher profile..."),
34
- children: /* @__PURE__ */ y("div", {
31
+ z,
32
+ j,
33
+ T
34
+ ]), j && !z ? /* @__PURE__ */ b(a, {
35
+ title: w("devportal.publisherProfileTitle", "Publisher Profile"),
36
+ description: w("devportal.loadingPublisherProfile", "Loading your publisher profile..."),
37
+ children: /* @__PURE__ */ b("div", {
35
38
  className: "flex items-center justify-center py-20",
36
- children: /* @__PURE__ */ y(g, { className: "h-8 w-8 animate-spin text-text-secondary" })
39
+ children: /* @__PURE__ */ b(_, { className: "h-8 w-8 animate-spin text-text-secondary" })
37
40
  })
38
- }) : O && !F ? /* @__PURE__ */ y(a, {
39
- title: C("devportal.publisherProfileTitle", "Publisher Profile"),
40
- description: C("devportal.manageStorePublisherPresence", "Manage your store publisher presence"),
41
- children: /* @__PURE__ */ b("div", {
41
+ }) : M && !z ? /* @__PURE__ */ b(a, {
42
+ title: w("devportal.publisherProfileTitle", "Publisher Profile"),
43
+ description: w("devportal.manageStorePublisherPresence", "Manage your store publisher presence"),
44
+ children: /* @__PURE__ */ x("div", {
42
45
  className: "flex flex-col items-center justify-center gap-4 py-20",
43
46
  children: [
44
- /* @__PURE__ */ y(p, { className: "h-12 w-12 text-status-error-text" }),
45
- /* @__PURE__ */ y("p", {
47
+ /* @__PURE__ */ b(p, { className: "h-12 w-12 text-status-error-text" }),
48
+ /* @__PURE__ */ b("p", {
46
49
  className: "text-text-secondary",
47
- children: C("devportal.failedToLoadProfile", "Failed to load profile")
50
+ children: w("devportal.failedToLoadProfile", "Failed to load profile")
48
51
  }),
49
- /* @__PURE__ */ y("button", {
50
- onClick: () => k(),
52
+ /* @__PURE__ */ b("button", {
53
+ onClick: () => N(),
51
54
  className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
52
- children: C("devportal.retryButton", "Retry")
55
+ children: w("devportal.retryButton", "Retry")
53
56
  })
54
57
  ]
55
58
  })
56
- }) : /* @__PURE__ */ y(c, {
59
+ }) : /* @__PURE__ */ b(c, {
57
60
  authOnly: !0,
58
- children: /* @__PURE__ */ y(a, {
59
- title: C("devportal.publisherProfileTitle", "Publisher Profile"),
60
- description: C("devportal.manageMarketplaceAppearance", "Manage how you appear to users in the marketplace"),
61
- purpose: C("devportal.publisherProfilePurpose", "This is your public face in the marketplace — the name, logo, bio, and links users see before installing your apps. A complete, trustworthy profile makes shoppers more likely to install and is required before some apps can be published."),
62
- actions: /* @__PURE__ */ b("button", {
61
+ children: /* @__PURE__ */ b(a, {
62
+ title: w("devportal.publisherProfileTitle", "Publisher Profile"),
63
+ description: w("devportal.manageMarketplaceAppearance", "Manage how you appear to users in the marketplace"),
64
+ purpose: w("devportal.publisherProfilePurpose", "This is your public face in the marketplace — the name, logo, bio, and links users see before installing your apps. A complete, trustworthy profile makes shoppers more likely to install and is required before some apps can be published."),
65
+ actions: /* @__PURE__ */ x("button", {
63
66
  onClick: async () => {
64
- Y("saving");
67
+ $("saving");
65
68
  try {
66
- if (!F) {
67
- let e = await M({ variables: { input: {
68
- companyName: I || void 0,
69
- website: R || void 0,
70
- bio: B || void 0,
71
- githubUsername: H || void 0,
72
- twitterUsername: W || void 0,
73
- linkedinUrl: K || void 0
69
+ if (!z) {
70
+ let e = await I({ variables: { input: {
71
+ companyName: B || void 0,
72
+ website: H || void 0,
73
+ bio: W || void 0,
74
+ githubUsername: K || void 0,
75
+ twitterUsername: J || void 0,
76
+ linkedinUrl: X || void 0
74
77
  } } });
75
78
  if (e.error) throw e.error;
76
- Y("saved"), await k(), setTimeout(() => Y("idle"), 3e3);
79
+ $("saved"), await N(), setTimeout(() => $("idle"), 3e3);
77
80
  return;
78
81
  }
79
- let e = await A({ variables: {
80
- userId: F.userId,
82
+ let e = await P({ variables: {
83
+ userId: z.userId,
81
84
  input: {
82
- companyName: I || null,
83
- website: R || null,
84
- bio: B || null,
85
- githubUsername: H || null,
86
- twitterUsername: W || null,
87
- linkedinUrl: K || null,
88
- emailNotifications: F.emailNotifications,
89
- marketingEmails: F.marketingEmails
85
+ companyName: B || null,
86
+ website: H || null,
87
+ bio: W || null,
88
+ githubUsername: K || null,
89
+ twitterUsername: J || null,
90
+ linkedinUrl: X || null,
91
+ emailNotifications: z.emailNotifications,
92
+ marketingEmails: z.marketingEmails
90
93
  }
91
94
  } });
92
95
  if (e.error) throw e.error;
93
- Y("saved"), await k(), setTimeout(() => Y("idle"), 3e3);
96
+ $("saved"), await N(), setTimeout(() => $("idle"), 3e3);
94
97
  } catch {
95
- Y("error"), setTimeout(() => Y("idle"), 5e3);
98
+ $("error"), setTimeout(() => $("idle"), 5e3);
96
99
  }
97
100
  },
98
- disabled: P || !T,
99
- "aria-disabled": !T,
100
- className: t("inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors", J === "saved" ? "bg-status-success-bg text-white" : J === "error" ? "bg-status-error-bg text-status-error-text" : "bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90", P && "opacity-50 cursor-not-allowed"),
101
- children: [P ? /* @__PURE__ */ y(g, {
101
+ disabled: R || !k,
102
+ "aria-disabled": !k,
103
+ className: t("inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors", Q === "saved" ? "bg-status-success-bg text-white" : Q === "error" ? "bg-status-error-bg text-status-error-text" : "bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90", R && "opacity-50 cursor-not-allowed"),
104
+ children: [R ? /* @__PURE__ */ b(_, {
102
105
  size: 16,
103
106
  className: "animate-spin"
104
- }) : y(J === "saved" ? m : J === "error" ? p : _, { size: 16 }), P ? C("devportal.savingButton", "Saving...") : J === "saved" ? C("devportal.savedButton", "Saved!") : J === "error" ? C("devportal.errorButton", "Error") : C("devportal.saveChangesButton", "Save Changes")]
107
+ }) : b(Q === "saved" ? m : Q === "error" ? p : v, { size: 16 }), R ? w("devportal.savingButton", "Saving...") : Q === "saved" ? w("devportal.savedButton", "Saved!") : Q === "error" ? w("devportal.errorButton", "Error") : w("devportal.saveChangesButton", "Save Changes")]
105
108
  }),
106
- children: /* @__PURE__ */ b("div", {
109
+ children: /* @__PURE__ */ x("div", {
107
110
  className: "flex flex-col gap-6",
108
- children: [/* @__PURE__ */ b("div", {
111
+ children: [/* @__PURE__ */ x("div", {
109
112
  className: "flex gap-3 rounded-lg border border-border-subtle bg-status-info-bg-subtle p-4 text-sm text-status-info-text",
110
- children: [/* @__PURE__ */ y(h, {
113
+ children: [/* @__PURE__ */ b(h, {
111
114
  size: 16,
112
115
  className: "flex-shrink-0 mt-0.5"
113
- }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
116
+ }), /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
114
117
  className: "font-medium",
115
- children: C("devportal.publisherProfilesWorkTitle", "How publisher profiles work")
116
- }), /* @__PURE__ */ y("p", {
118
+ children: w("devportal.publisherProfilesWorkTitle", "How publisher profiles work")
119
+ }), /* @__PURE__ */ b("p", {
117
120
  className: "mt-1 text-status-info-text",
118
- children: C("devportal.publisherProfilesWorkDesc", "When you publish your first app, a publisher profile is automatically created in the marketplace using your developer details. Keep this information up to date so users can trust and find your apps. Changes here are reflected when your next app is published.")
121
+ children: w("devportal.publisherProfilesWorkDesc", "When you publish your first app, a publisher profile is automatically created in the marketplace using your developer details. Keep this information up to date so users can trust and find your apps. Changes here are reflected when your next app is published.")
119
122
  })] })]
120
- }), /* @__PURE__ */ b("div", {
123
+ }), /* @__PURE__ */ x("div", {
121
124
  className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
122
- children: [/* @__PURE__ */ b("div", {
125
+ children: [/* @__PURE__ */ x("div", {
123
126
  className: "lg:col-span-2 space-y-6",
124
- children: [/* @__PURE__ */ y(o, {
125
- title: C("devportal.publisherIdentityTitle", "Publisher Identity"),
126
- description: C("devportal.publisherIdentityDesc", "Displayed on your marketplace listings"),
127
- children: /* @__PURE__ */ b("div", {
127
+ children: [/* @__PURE__ */ b(o, {
128
+ title: w("devportal.publisherIdentityTitle", "Publisher Identity"),
129
+ description: w("devportal.publisherIdentityDesc", "Displayed on your marketplace listings"),
130
+ children: /* @__PURE__ */ x("div", {
128
131
  className: "space-y-4",
129
132
  children: [
130
- /* @__PURE__ */ y(s, {
131
- label: C("devportal.displayNameLabel", "Display Name / Company"),
132
- value: I,
133
- onChange: (e) => L(e.target.value),
134
- placeholder: C("devportal.displayNamePlaceholder", "Your name or company (shown on all your apps)")
135
- }),
136
- /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
137
- className: "text-sm font-medium text-text-primary",
138
- children: C("devportal.bioLabel", "Bio")
139
- }), /* @__PURE__ */ y("textarea", {
133
+ /* @__PURE__ */ b(s, {
134
+ label: w("devportal.displayNameLabel", "Display Name / Company"),
140
135
  value: B,
141
136
  onChange: (e) => V(e.target.value),
142
- placeholder: C("devportal.bioPlaceholder", "A short description of you or your company shown on the marketplace..."),
137
+ placeholder: w("devportal.displayNamePlaceholder", "Your name or company (shown on all your apps)")
138
+ }),
139
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
140
+ className: "text-sm font-medium text-text-primary",
141
+ children: w("devportal.bioLabel", "Bio")
142
+ }), /* @__PURE__ */ b("textarea", {
143
+ value: W,
144
+ onChange: (e) => G(e.target.value),
145
+ placeholder: w("devportal.bioPlaceholder", "A short description of you or your company shown on the marketplace..."),
143
146
  rows: 3,
144
147
  className: "mt-1 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm ring-offset-background placeholder:text-text-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none"
145
148
  })] }),
146
- /* @__PURE__ */ y(s, {
147
- label: C("devportal.websiteLabel", "Website"),
148
- value: R,
149
- onChange: (e) => z(e.target.value),
150
- placeholder: C("devportal.websitePlaceholder", "https://your-website.com")
149
+ /* @__PURE__ */ b(s, {
150
+ label: w("devportal.websiteLabel", "Website"),
151
+ value: H,
152
+ onChange: (e) => U(e.target.value),
153
+ placeholder: w("devportal.websitePlaceholder", "https://your-website.com")
151
154
  })
152
155
  ]
153
156
  })
154
- }), /* @__PURE__ */ y(o, {
155
- title: C("devportal.socialLinksTitle", "Social Links"),
156
- description: C("devportal.socialLinksDesc", "Build trust with your developer community"),
157
- children: /* @__PURE__ */ b("div", {
157
+ }), /* @__PURE__ */ b(o, {
158
+ title: w("devportal.socialLinksTitle", "Social Links"),
159
+ description: w("devportal.socialLinksDesc", "Build trust with your developer community"),
160
+ children: /* @__PURE__ */ x("div", {
158
161
  className: "space-y-4",
159
162
  children: [
160
- /* @__PURE__ */ y(s, {
161
- label: C("devportal.githubUsernameLabel", "GitHub Username"),
162
- value: H,
163
- onChange: (e) => U(e.target.value),
164
- placeholder: C("devportal.githubUsernamePlaceholder", "your-github-username")
165
- }),
166
- /* @__PURE__ */ y(s, {
167
- label: C("devportal.twitterUsernameLabel", "Twitter / X Username"),
168
- value: W,
169
- onChange: (e) => G(e.target.value),
170
- placeholder: C("devportal.twitterUsernamePlaceholder", "your_twitter")
171
- }),
172
- /* @__PURE__ */ y(s, {
173
- label: C("devportal.linkedinUrlLabel", "LinkedIn URL"),
163
+ /* @__PURE__ */ b(s, {
164
+ label: w("devportal.githubUsernameLabel", "GitHub Username"),
174
165
  value: K,
175
166
  onChange: (e) => q(e.target.value),
176
- placeholder: C("devportal.linkedinUrlPlaceholder", "https://linkedin.com/in/you")
167
+ placeholder: w("devportal.githubUsernamePlaceholder", "your-github-username")
168
+ }),
169
+ /* @__PURE__ */ b(s, {
170
+ label: w("devportal.twitterUsernameLabel", "Twitter / X Username"),
171
+ value: J,
172
+ onChange: (e) => Y(e.target.value),
173
+ placeholder: w("devportal.twitterUsernamePlaceholder", "your_twitter")
174
+ }),
175
+ /* @__PURE__ */ b(s, {
176
+ label: w("devportal.linkedinUrlLabel", "LinkedIn URL"),
177
+ value: X,
178
+ onChange: (e) => Z(e.target.value),
179
+ placeholder: w("devportal.linkedinUrlPlaceholder", "https://linkedin.com/in/you")
177
180
  })
178
181
  ]
179
182
  })
180
183
  })]
181
- }), /* @__PURE__ */ b("div", {
184
+ }), /* @__PURE__ */ x("div", {
182
185
  className: "space-y-6",
183
186
  children: [
184
- /* @__PURE__ */ y(o, {
185
- title: C("devportal.publisherStatusTitle", "Publisher Status"),
186
- children: /* @__PURE__ */ b("div", {
187
+ /* @__PURE__ */ b(o, {
188
+ title: w("devportal.publisherStatusTitle", "Publisher Status"),
189
+ children: /* @__PURE__ */ x("div", {
187
190
  className: "flex items-center gap-3",
188
- children: [/* @__PURE__ */ y(v, { className: "h-8 w-8 text-primary" }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
191
+ children: [/* @__PURE__ */ b(y, { className: "h-8 w-8 text-primary" }), /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
189
192
  className: "font-medium",
190
- children: F?.isVerified ? C("devportal.verifiedPublisher", "Verified Publisher") : C("devportal.publisher", "Publisher")
191
- }), /* @__PURE__ */ y("p", {
193
+ children: z?.isVerified ? w("devportal.verifiedPublisher", "Verified Publisher") : w("devportal.publisher", "Publisher")
194
+ }), /* @__PURE__ */ b("p", {
192
195
  className: "text-xs text-text-secondary",
193
- children: F?.isVerified ? C("devportal.publisherIdentityVerified", "Your publisher identity is verified") : C("devportal.publishFirstAppMessage", "Publish your first app to appear in the marketplace")
196
+ children: z?.isVerified ? w("devportal.publisherIdentityVerified", "Your publisher identity is verified") : w("devportal.publishFirstAppMessage", "Publish your first app to appear in the marketplace")
194
197
  })] })]
195
198
  })
196
199
  }),
197
- /* @__PURE__ */ y(o, {
198
- title: C("devportal.profileCompletenessTitle", "Profile Completeness"),
199
- children: /* @__PURE__ */ y("div", {
200
+ /* @__PURE__ */ b(o, {
201
+ title: w("devportal.payouts.title", "Payouts"),
202
+ description: w("devportal.payouts.profileCardDescription", "Add and verify where the marketplace sends your earnings"),
203
+ children: /* @__PURE__ */ x("button", {
204
+ type: "button",
205
+ onClick: () => O(),
206
+ className: "flex items-center gap-2 text-sm font-medium text-primary hover:underline",
207
+ children: [/* @__PURE__ */ b(g, { size: 16 }), w("devportal.payouts.manage", "Manage payout methods")]
208
+ })
209
+ }),
210
+ /* @__PURE__ */ b(o, {
211
+ title: w("devportal.profileCompletenessTitle", "Profile Completeness"),
212
+ children: /* @__PURE__ */ b("div", {
200
213
  className: "space-y-2",
201
214
  children: [
202
215
  {
203
- label: C("devportal.completenessDisplayName", "Display name"),
204
- ok: !!I
205
- },
206
- {
207
- label: C("devportal.completenessBio", "Bio"),
216
+ label: w("devportal.completenessDisplayName", "Display name"),
208
217
  ok: !!B
209
218
  },
210
219
  {
211
- label: C("devportal.completenessWebsite", "Website"),
212
- ok: !!R
220
+ label: w("devportal.completenessBio", "Bio"),
221
+ ok: !!W
213
222
  },
214
223
  {
215
- label: C("devportal.completenessGithub", "GitHub"),
224
+ label: w("devportal.completenessWebsite", "Website"),
216
225
  ok: !!H
217
226
  },
218
227
  {
219
- label: C("devportal.completenessSocialLinks", "Social links"),
220
- ok: !!W || !!K
228
+ label: w("devportal.completenessGithub", "GitHub"),
229
+ ok: !!K
230
+ },
231
+ {
232
+ label: w("devportal.completenessSocialLinks", "Social links"),
233
+ ok: !!J || !!X
221
234
  }
222
- ].map(({ label: e, ok: t }) => /* @__PURE__ */ b("div", {
235
+ ].map(({ label: e, ok: t }) => /* @__PURE__ */ x("div", {
223
236
  className: "flex items-center gap-2 text-sm",
224
- children: [t ? /* @__PURE__ */ y(m, {
237
+ children: [t ? /* @__PURE__ */ b(m, {
225
238
  size: 14,
226
239
  className: "text-status-success-text"
227
- }) : /* @__PURE__ */ y("div", { className: "h-3.5 w-3.5 rounded-full border-2 border-muted-foreground" }), /* @__PURE__ */ y("span", {
240
+ }) : /* @__PURE__ */ b("div", { className: "h-3.5 w-3.5 rounded-full border-2 border-muted-foreground" }), /* @__PURE__ */ b("span", {
228
241
  className: t ? "text-text-primary" : "text-text-secondary",
229
242
  children: e
230
243
  })]
231
244
  }, e))
232
245
  })
233
246
  }),
234
- /* @__PURE__ */ y(o, {
235
- title: C("devportal.marketplaceStatsTitle", "Marketplace Stats"),
236
- children: /* @__PURE__ */ b("div", {
247
+ /* @__PURE__ */ b(o, {
248
+ title: w("devportal.marketplaceStatsTitle", "Marketplace Stats"),
249
+ children: /* @__PURE__ */ x("div", {
237
250
  className: "space-y-3 text-sm",
238
251
  children: [
239
- /* @__PURE__ */ b("div", {
252
+ /* @__PURE__ */ x("div", {
240
253
  className: "flex justify-between",
241
- children: [/* @__PURE__ */ y("span", {
254
+ children: [/* @__PURE__ */ b("span", {
242
255
  className: "text-text-secondary",
243
- children: C("devportal.publishedAppsLabel", "Published apps")
244
- }), /* @__PURE__ */ y("span", {
256
+ children: w("devportal.publishedAppsLabel", "Published apps")
257
+ }), /* @__PURE__ */ b("span", {
245
258
  className: "font-semibold",
246
- children: F?.applicationCount ?? 0
259
+ children: z?.applicationCount ?? 0
247
260
  })]
248
261
  }),
249
- /* @__PURE__ */ b("div", {
262
+ /* @__PURE__ */ x("div", {
250
263
  className: "flex justify-between",
251
- children: [/* @__PURE__ */ y("span", {
264
+ children: [/* @__PURE__ */ b("span", {
252
265
  className: "text-text-secondary",
253
- children: C("devportal.totalInstallsLabel", "Total installs")
254
- }), /* @__PURE__ */ y("span", {
266
+ children: w("devportal.totalInstallsLabel", "Total installs")
267
+ }), /* @__PURE__ */ b("span", {
255
268
  className: "font-semibold",
256
- children: F?.totalInstalls ?? 0
269
+ children: z?.totalInstalls ?? 0
257
270
  })]
258
271
  }),
259
- /* @__PURE__ */ b("div", {
272
+ /* @__PURE__ */ x("div", {
260
273
  className: "flex justify-between",
261
- children: [/* @__PURE__ */ y("span", {
274
+ children: [/* @__PURE__ */ b("span", {
262
275
  className: "text-text-secondary",
263
- children: C("devportal.avgRatingLabel", "Avg rating")
264
- }), /* @__PURE__ */ y("span", {
276
+ children: w("devportal.avgRatingLabel", "Avg rating")
277
+ }), /* @__PURE__ */ b("span", {
265
278
  className: "font-semibold",
266
- children: F?.averageRating ? F.averageRating.toFixed(1) : "—"
279
+ children: z?.averageRating ? z.averageRating.toFixed(1) : "—"
267
280
  })]
268
281
  })
269
282
  ]
@@ -277,6 +290,6 @@ var S = () => {
277
290
  });
278
291
  };
279
292
  //#endregion
280
- export { S as PublisherProfilePage };
293
+ export { C as PublisherProfilePage };
281
294
 
282
295
  //# sourceMappingURL=PublisherProfilePage.js.map