@open-mercato/core 0.6.1-develop.3278.1.a4d26475e4 → 0.6.1-develop.3287.1.450f4ffb56

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.
Files changed (58) hide show
  1. package/dist/helpers/integration/auth.js +1 -1
  2. package/dist/helpers/integration/auth.js.map +2 -2
  3. package/dist/helpers/integration/authUi.js +1 -1
  4. package/dist/helpers/integration/authUi.js.map +2 -2
  5. package/dist/modules/auth/frontend/login.js +4 -4
  6. package/dist/modules/auth/frontend/login.js.map +2 -2
  7. package/dist/modules/auth/frontend/reset/[token]/page.js +5 -5
  8. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  9. package/dist/modules/auth/frontend/reset.js +2 -2
  10. package/dist/modules/auth/frontend/reset.js.map +2 -2
  11. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +4 -3
  12. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  13. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +6 -5
  14. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  15. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +2 -2
  16. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
  17. package/dist/modules/customers/components/formConfig.js +2 -2
  18. package/dist/modules/customers/components/formConfig.js.map +2 -2
  19. package/dist/modules/integrations/backend/integrations/[id]/page.js +2 -3
  20. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  21. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +4 -3
  22. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
  23. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +3 -3
  24. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +2 -2
  25. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +4 -2
  26. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +2 -2
  27. package/dist/modules/sales/backend/sales/documents/[id]/page.js +3 -5
  28. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  29. package/dist/modules/sales/components/ProviderFieldInput.js +2 -2
  30. package/dist/modules/sales/components/ProviderFieldInput.js.map +2 -2
  31. package/dist/modules/sales/components/documents/SalesDocumentForm.js +3 -4
  32. package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
  33. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js +3 -4
  34. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js.map +2 -2
  35. package/dist/modules/workflows/backend/tasks/[id]/page.js +2 -2
  36. package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
  37. package/dist/modules/workflows/frontend/checkout-demo/page.js +2 -2
  38. package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
  39. package/package.json +5 -5
  40. package/src/helpers/integration/auth.ts +1 -1
  41. package/src/helpers/integration/authUi.ts +1 -1
  42. package/src/modules/auth/frontend/login.tsx +4 -3
  43. package/src/modules/auth/frontend/reset/[token]/page.tsx +4 -4
  44. package/src/modules/auth/frontend/reset.tsx +2 -2
  45. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +3 -2
  46. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +5 -4
  47. package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +2 -2
  48. package/src/modules/customers/components/formConfig.tsx +2 -2
  49. package/src/modules/integrations/backend/integrations/[id]/page.tsx +2 -2
  50. package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +4 -3
  51. package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +3 -3
  52. package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +4 -2
  53. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +3 -5
  54. package/src/modules/sales/components/ProviderFieldInput.tsx +2 -2
  55. package/src/modules/sales/components/documents/SalesDocumentForm.tsx +2 -3
  56. package/src/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.tsx +3 -4
  57. package/src/modules/workflows/backend/tasks/[id]/page.tsx +2 -2
  58. package/src/modules/workflows/frontend/checkout-demo/page.tsx +2 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/portal/frontend/%5BorgSlug%5D/portal/reset-password/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport { useCallback, useMemo, useState, useEffect } from 'react'\nimport { useSearchParams } from 'next/navigation'\nimport Link from 'next/link'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { usePortalContext } from '@open-mercato/ui/portal/PortalContext'\nimport { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'\n\ntype Props = { params: { orgSlug: string } }\n\nexport default function PortalResetPasswordPage({ params }: Props) {\n const t = useT()\n const orgSlug = params.orgSlug\n const { tenant } = usePortalContext()\n const searchParams = useSearchParams()\n\n const [password, setPassword] = useState('')\n const [confirmPassword, setConfirmPassword] = useState('')\n const [error, setError] = useState<string | null>(null)\n const [success, setSuccess] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n const [token, setToken] = useState<string | null>(null)\n\n useEffect(() => {\n const tokenParam = searchParams.get('token')\n if (!tokenParam) {\n setError(t('portal.resetPassword.error.noToken', 'Invalid or missing reset token.'))\n } else {\n setToken(tokenParam)\n }\n }, [searchParams, t])\n\n const handleSubmit = useCallback(\n async (event: React.FormEvent) => {\n event.preventDefault()\n setError(null)\n\n if (!token) {\n setError(t('portal.resetPassword.error.noToken', 'Invalid or missing reset token.'))\n return\n }\n\n if (password !== confirmPassword) {\n setError(t('portal.resetPassword.error.passwordMismatch', 'Passwords do not match.'))\n return\n }\n\n if (password.length < 8) {\n setError(t('portal.resetPassword.error.passwordTooShort', 'Password must be at least 8 characters long.'))\n return\n }\n\n setSubmitting(true)\n try {\n const result = await apiCall<{ ok: boolean; error?: string }>('/api/customer_accounts/password/reset-confirm', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token, password }),\n })\n\n if (result.ok && result.result?.ok) {\n setSuccess(true)\n return\n }\n\n if (result.status === 400) {\n setError(t('portal.resetPassword.error.invalidToken', 'Invalid or expired reset token.'))\n } else {\n setError(result.result?.error || t('portal.resetPassword.error.generic', 'Password reset failed. Please try again.'))\n }\n } catch {\n setError(t('portal.resetPassword.error.generic', 'Password reset failed. Please try again.'))\n } finally {\n setSubmitting(false)\n }\n },\n [token, password, confirmPassword, t],\n )\n\n const injectionContext = useMemo(\n () => ({ orgSlug }),\n [orgSlug],\n )\n\n if (tenant.loading) {\n return <div className=\"flex items-center justify-center py-20\"><Spinner /></div>\n }\n\n if (tenant.error) {\n return (\n <div className=\"mx-auto w-full max-w-md py-12\">\n <Alert variant=\"destructive\">\n <AlertDescription>{t('portal.org.invalid', 'Organization not found.')}</AlertDescription>\n </Alert>\n </div>\n )\n }\n\n if (success) {\n return (\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-8 text-center\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.resetPassword.success.title', 'Password Reset Complete')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t('portal.resetPassword.success.description', 'Your password has been successfully reset.')}</p>\n </div>\n\n <Alert>\n <AlertDescription>{t('portal.resetPassword.success.message', 'You can now sign in with your new password.')}</AlertDescription>\n </Alert>\n\n <div className=\"mt-6 text-center\">\n <Link href={`/${orgSlug}/portal/login`} className=\"font-medium text-foreground underline underline-offset-4 hover:opacity-80\">\n {t('portal.resetPassword.success.loginLink', 'Go to Sign In')}\n </Link>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-8 text-center\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.resetPassword.title', 'Reset Password')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t('portal.resetPassword.description', 'Enter your new password below.')}</p>\n </div>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageBefore('reset-password')} context={injectionContext} />\n\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-4\">\n {error ? (\n <Alert variant=\"destructive\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n ) : null}\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"reset-password\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.resetPassword.password', 'New Password')}</Label>\n <Input id=\"reset-password\" type=\"password\" autoComplete=\"new-password\" required placeholder={t('portal.resetPassword.password.placeholder', '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022')} value={password} onChange={(e) => setPassword(e.target.value)} disabled={submitting || !token} className=\"rounded-lg\" />\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"confirm-password\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.resetPassword.confirmPassword', 'Confirm New Password')}</Label>\n <Input id=\"confirm-password\" type=\"password\" autoComplete=\"new-password\" required placeholder={t('portal.resetPassword.confirmPassword.placeholder', '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022')} value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} disabled={submitting || !token} className=\"rounded-lg\" />\n </div>\n\n <Button type=\"submit\" disabled={submitting || !token} className=\"mt-1 w-full rounded-lg\">\n {submitting ? t('portal.resetPassword.submitting', 'Resetting password...') : t('portal.resetPassword.submit', 'Reset Password')}\n </Button>\n\n <p className=\"text-center text-sm text-muted-foreground\">\n {t('portal.resetPassword.backToLogin', 'Remember your password?')}{' '}\n <Link href={`/${orgSlug}/portal/login`} className=\"font-medium text-foreground underline underline-offset-4 hover:opacity-80\">\n {t('portal.resetPassword.loginLink', 'Sign in')}\n </Link>\n </p>\n </form>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageAfter('reset-password')} context={injectionContext} />\n </div>\n )\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport { useCallback, useMemo, useState, useEffect } from 'react'\nimport { useSearchParams } from 'next/navigation'\nimport Link from 'next/link'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { PasswordInput } from '@open-mercato/ui/primitives/password-input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { usePortalContext } from '@open-mercato/ui/portal/PortalContext'\nimport { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'\n\ntype Props = { params: { orgSlug: string } }\n\nexport default function PortalResetPasswordPage({ params }: Props) {\n const t = useT()\n const orgSlug = params.orgSlug\n const { tenant } = usePortalContext()\n const searchParams = useSearchParams()\n\n const [password, setPassword] = useState('')\n const [confirmPassword, setConfirmPassword] = useState('')\n const [error, setError] = useState<string | null>(null)\n const [success, setSuccess] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n const [token, setToken] = useState<string | null>(null)\n\n useEffect(() => {\n const tokenParam = searchParams.get('token')\n if (!tokenParam) {\n setError(t('portal.resetPassword.error.noToken', 'Invalid or missing reset token.'))\n } else {\n setToken(tokenParam)\n }\n }, [searchParams, t])\n\n const handleSubmit = useCallback(\n async (event: React.FormEvent) => {\n event.preventDefault()\n setError(null)\n\n if (!token) {\n setError(t('portal.resetPassword.error.noToken', 'Invalid or missing reset token.'))\n return\n }\n\n if (password !== confirmPassword) {\n setError(t('portal.resetPassword.error.passwordMismatch', 'Passwords do not match.'))\n return\n }\n\n if (password.length < 8) {\n setError(t('portal.resetPassword.error.passwordTooShort', 'Password must be at least 8 characters long.'))\n return\n }\n\n setSubmitting(true)\n try {\n const result = await apiCall<{ ok: boolean; error?: string }>('/api/customer_accounts/password/reset-confirm', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token, password }),\n })\n\n if (result.ok && result.result?.ok) {\n setSuccess(true)\n return\n }\n\n if (result.status === 400) {\n setError(t('portal.resetPassword.error.invalidToken', 'Invalid or expired reset token.'))\n } else {\n setError(result.result?.error || t('portal.resetPassword.error.generic', 'Password reset failed. Please try again.'))\n }\n } catch {\n setError(t('portal.resetPassword.error.generic', 'Password reset failed. Please try again.'))\n } finally {\n setSubmitting(false)\n }\n },\n [token, password, confirmPassword, t],\n )\n\n const injectionContext = useMemo(\n () => ({ orgSlug }),\n [orgSlug],\n )\n\n if (tenant.loading) {\n return <div className=\"flex items-center justify-center py-20\"><Spinner /></div>\n }\n\n if (tenant.error) {\n return (\n <div className=\"mx-auto w-full max-w-md py-12\">\n <Alert variant=\"destructive\">\n <AlertDescription>{t('portal.org.invalid', 'Organization not found.')}</AlertDescription>\n </Alert>\n </div>\n )\n }\n\n if (success) {\n return (\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-8 text-center\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.resetPassword.success.title', 'Password Reset Complete')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t('portal.resetPassword.success.description', 'Your password has been successfully reset.')}</p>\n </div>\n\n <Alert>\n <AlertDescription>{t('portal.resetPassword.success.message', 'You can now sign in with your new password.')}</AlertDescription>\n </Alert>\n\n <div className=\"mt-6 text-center\">\n <Link href={`/${orgSlug}/portal/login`} className=\"font-medium text-foreground underline underline-offset-4 hover:opacity-80\">\n {t('portal.resetPassword.success.loginLink', 'Go to Sign In')}\n </Link>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-8 text-center\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.resetPassword.title', 'Reset Password')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t('portal.resetPassword.description', 'Enter your new password below.')}</p>\n </div>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageBefore('reset-password')} context={injectionContext} />\n\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-4\">\n {error ? (\n <Alert variant=\"destructive\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n ) : null}\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"reset-password\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.resetPassword.password', 'New Password')}</Label>\n <PasswordInput id=\"reset-password\" autoComplete=\"new-password\" required placeholder={t('portal.resetPassword.password.placeholder', '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022')} value={password} onChange={(e) => setPassword(e.target.value)} disabled={submitting || !token} className=\"rounded-lg\" />\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"confirm-password\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.resetPassword.confirmPassword', 'Confirm New Password')}</Label>\n <PasswordInput id=\"confirm-password\" autoComplete=\"new-password\" required placeholder={t('portal.resetPassword.confirmPassword.placeholder', '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022')} value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} disabled={submitting || !token} className=\"rounded-lg\" />\n </div>\n\n <Button type=\"submit\" disabled={submitting || !token} className=\"mt-1 w-full rounded-lg\">\n {submitting ? t('portal.resetPassword.submitting', 'Resetting password...') : t('portal.resetPassword.submit', 'Reset Password')}\n </Button>\n\n <p className=\"text-center text-sm text-muted-foreground\">\n {t('portal.resetPassword.backToLogin', 'Remember your password?')}{' '}\n <Link href={`/${orgSlug}/portal/login`} className=\"font-medium text-foreground underline underline-offset-4 hover:opacity-80\">\n {t('portal.resetPassword.loginLink', 'Sign in')}\n </Link>\n </p>\n </form>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageAfter('reset-password')} context={injectionContext} />\n </div>\n )\n}"],
5
+ "mappings": ";AA4FmE,cAgB3D,YAhB2D;AA3FnE,SAAS,aAAa,SAAS,UAAU,iBAAiB;AAC1D,SAAS,uBAAuB;AAChC,OAAO,UAAU;AACjB,SAAS,YAAY;AACrB,SAAS,qBAAqB;AAC9B,SAAS,aAAa;AACtB,SAAS,cAAc;AACvB,SAAS,OAAO,wBAAwB;AACxC,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,wBAAwB;AACjC,SAAS,qBAAqB;AAC9B,SAAS,4BAA4B;AAItB,SAAR,wBAAyC,EAAE,OAAO,GAAU;AACjE,QAAM,IAAI,KAAK;AACf,QAAM,UAAU,OAAO;AACvB,QAAM,EAAE,OAAO,IAAI,iBAAiB;AACpC,QAAM,eAAe,gBAAgB;AAErC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,EAAE;AACzD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AAEtD,YAAU,MAAM;AACd,UAAM,aAAa,aAAa,IAAI,OAAO;AAC3C,QAAI,CAAC,YAAY;AACf,eAAS,EAAE,sCAAsC,iCAAiC,CAAC;AAAA,IACrF,OAAO;AACL,eAAS,UAAU;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,cAAc,CAAC,CAAC;AAEpB,QAAM,eAAe;AAAA,IACnB,OAAO,UAA2B;AAChC,YAAM,eAAe;AACrB,eAAS,IAAI;AAEb,UAAI,CAAC,OAAO;AACV,iBAAS,EAAE,sCAAsC,iCAAiC,CAAC;AACnF;AAAA,MACF;AAEA,UAAI,aAAa,iBAAiB;AAChC,iBAAS,EAAE,+CAA+C,yBAAyB,CAAC;AACpF;AAAA,MACF;AAEA,UAAI,SAAS,SAAS,GAAG;AACvB,iBAAS,EAAE,+CAA+C,8CAA8C,CAAC;AACzG;AAAA,MACF;AAEA,oBAAc,IAAI;AAClB,UAAI;AACF,cAAM,SAAS,MAAM,QAAyC,iDAAiD;AAAA,UAC7G,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,QAC1C,CAAC;AAED,YAAI,OAAO,MAAM,OAAO,QAAQ,IAAI;AAClC,qBAAW,IAAI;AACf;AAAA,QACF;AAEA,YAAI,OAAO,WAAW,KAAK;AACzB,mBAAS,EAAE,2CAA2C,iCAAiC,CAAC;AAAA,QAC1F,OAAO;AACL,mBAAS,OAAO,QAAQ,SAAS,EAAE,sCAAsC,0CAA0C,CAAC;AAAA,QACtH;AAAA,MACF,QAAQ;AACN,iBAAS,EAAE,sCAAsC,0CAA0C,CAAC;AAAA,MAC9F,UAAE;AACA,sBAAc,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,IACA,CAAC,OAAO,UAAU,iBAAiB,CAAC;AAAA,EACtC;AAEA,QAAM,mBAAmB;AAAA,IACvB,OAAO,EAAE,QAAQ;AAAA,IACjB,CAAC,OAAO;AAAA,EACV;AAEA,MAAI,OAAO,SAAS;AAClB,WAAO,oBAAC,SAAI,WAAU,0CAAyC,8BAAC,WAAQ,GAAE;AAAA,EAC5E;AAEA,MAAI,OAAO,OAAO;AAChB,WACE,oBAAC,SAAI,WAAU,iCACb,8BAAC,SAAM,SAAQ,eACb,8BAAC,oBAAkB,YAAE,sBAAsB,yBAAyB,GAAE,GACxE,GACF;AAAA,EAEJ;AAEA,MAAI,SAAS;AACX,WACE,qBAAC,SAAI,WAAU,2BACb;AAAA,2BAAC,SAAI,WAAU,oBACb;AAAA,4BAAC,QAAG,WAAU,qCAAqC,YAAE,sCAAsC,yBAAyB,GAAE;AAAA,QACtH,oBAAC,OAAE,WAAU,wCAAwC,YAAE,4CAA4C,4CAA4C,GAAE;AAAA,SACnJ;AAAA,MAEA,oBAAC,SACC,8BAAC,oBAAkB,YAAE,wCAAwC,6CAA6C,GAAE,GAC9G;AAAA,MAEA,oBAAC,SAAI,WAAU,oBACb,8BAAC,QAAK,MAAM,IAAI,OAAO,iBAAiB,WAAU,6EAC/C,YAAE,0CAA0C,eAAe,GAC9D,GACF;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,2BACb;AAAA,yBAAC,SAAI,WAAU,oBACb;AAAA,0BAAC,QAAG,WAAU,qCAAqC,YAAE,8BAA8B,gBAAgB,GAAE;AAAA,MACrG,oBAAC,OAAE,WAAU,wCAAwC,YAAE,oCAAoC,gCAAgC,GAAE;AAAA,OAC/H;AAAA,IAEA,oBAAC,iBAAc,QAAQ,qBAAqB,WAAW,gBAAgB,GAAG,SAAS,kBAAkB;AAAA,IAErG,qBAAC,UAAK,UAAU,cAAc,WAAU,uBACrC;AAAA,cACC,oBAAC,SAAM,SAAQ,eACb,8BAAC,oBAAkB,iBAAM,GAC3B,IACE;AAAA,MAEJ,qBAAC,SAAI,WAAU,yBACb;AAAA,4BAAC,SAAM,SAAQ,kBAAiB,WAAU,iFAAiF,YAAE,iCAAiC,cAAc,GAAE;AAAA,QAC9K,oBAAC,iBAAc,IAAG,kBAAiB,cAAa,gBAAe,UAAQ,MAAC,aAAa,EAAE,6CAA6C,kDAAU,GAAG,OAAO,UAAU,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK,GAAG,UAAU,cAAc,CAAC,OAAO,WAAU,cAAa;AAAA,SACzQ;AAAA,MAEA,qBAAC,SAAI,WAAU,yBACb;AAAA,4BAAC,SAAM,SAAQ,oBAAmB,WAAU,iFAAiF,YAAE,wCAAwC,sBAAsB,GAAE;AAAA,QAC/L,oBAAC,iBAAc,IAAG,oBAAmB,cAAa,gBAAe,UAAQ,MAAC,aAAa,EAAE,oDAAoD,kDAAU,GAAG,OAAO,iBAAiB,UAAU,CAAC,MAAM,mBAAmB,EAAE,OAAO,KAAK,GAAG,UAAU,cAAc,CAAC,OAAO,WAAU,cAAa;AAAA,SAChS;AAAA,MAEA,oBAAC,UAAO,MAAK,UAAS,UAAU,cAAc,CAAC,OAAO,WAAU,0BAC7D,uBAAa,EAAE,mCAAmC,uBAAuB,IAAI,EAAE,+BAA+B,gBAAgB,GACjI;AAAA,MAEA,qBAAC,OAAE,WAAU,6CACV;AAAA,UAAE,oCAAoC,yBAAyB;AAAA,QAAG;AAAA,QACnE,oBAAC,QAAK,MAAM,IAAI,OAAO,iBAAiB,WAAU,6EAC/C,YAAE,kCAAkC,SAAS,GAChD;AAAA,SACF;AAAA,OACF;AAAA,IAEA,oBAAC,iBAAc,QAAQ,qBAAqB,UAAU,gBAAgB,GAAG,SAAS,kBAAkB;AAAA,KACtG;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -4,6 +4,8 @@ import { useCallback, useMemo, useState } from "react";
4
4
  import Link from "next/link";
5
5
  import { useT } from "@open-mercato/shared/lib/i18n/context";
6
6
  import { Input } from "@open-mercato/ui/primitives/input";
7
+ import { EmailInput } from "@open-mercato/ui/primitives/email-input";
8
+ import { PasswordInput } from "@open-mercato/ui/primitives/password-input";
7
9
  import { Label } from "@open-mercato/ui/primitives/label";
8
10
  import { Button } from "@open-mercato/ui/primitives/button";
9
11
  import { Alert, AlertDescription } from "@open-mercato/ui/primitives/alert";
@@ -85,11 +87,11 @@ function PortalSignupPage({ params }) {
85
87
  ] }),
86
88
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
87
89
  /* @__PURE__ */ jsx(Label, { htmlFor: "signup-email", className: "text-overline font-semibold uppercase tracking-wider text-muted-foreground/70", children: t("portal.signup.email", "Email") }),
88
- /* @__PURE__ */ jsx(Input, { id: "signup-email", type: "email", autoComplete: "email", required: true, placeholder: t("portal.signup.email.placeholder", "you@example.com"), value: email, onChange: (e) => setEmail(e.target.value), disabled: submitting, className: "rounded-lg" })
90
+ /* @__PURE__ */ jsx(EmailInput, { id: "signup-email", required: true, placeholder: t("portal.signup.email.placeholder", "you@example.com"), value: email, onChange: (e) => setEmail(e.target.value), disabled: submitting, className: "rounded-lg" })
89
91
  ] }),
90
92
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
91
93
  /* @__PURE__ */ jsx(Label, { htmlFor: "signup-password", className: "text-overline font-semibold uppercase tracking-wider text-muted-foreground/70", children: t("portal.signup.password", "Password") }),
92
- /* @__PURE__ */ jsx(Input, { id: "signup-password", type: "password", autoComplete: "new-password", required: true, placeholder: t("portal.signup.password.placeholder", "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"), value: password, onChange: (e) => setPassword(e.target.value), disabled: submitting, className: "rounded-lg" })
94
+ /* @__PURE__ */ jsx(PasswordInput, { id: "signup-password", autoComplete: "new-password", required: true, placeholder: t("portal.signup.password.placeholder", "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"), value: password, onChange: (e) => setPassword(e.target.value), disabled: submitting, className: "rounded-lg" })
93
95
  ] }),
94
96
  /* @__PURE__ */ jsx(Button, { type: "submit", disabled: submitting, className: "mt-1 w-full rounded-lg", children: submitting ? t("portal.signup.submitting", "Creating account...") : t("portal.signup.submit", "Create Account") }),
95
97
  /* @__PURE__ */ jsxs("p", { className: "text-center text-sm text-muted-foreground", children: [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/portal/frontend/%5BorgSlug%5D/portal/signup/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport { useCallback, useMemo, useState } from 'react'\nimport Link from 'next/link'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { usePortalContext } from '@open-mercato/ui/portal/PortalContext'\nimport { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'\n\ntype Props = { params: { orgSlug: string } }\ntype SignupResponse = { ok: boolean; error?: string }\n\nexport default function PortalSignupPage({ params }: Props) {\n const t = useT()\n const orgSlug = params.orgSlug\n const { tenant } = usePortalContext()\n\n const [displayName, setDisplayName] = useState('')\n const [email, setEmail] = useState('')\n const [password, setPassword] = useState('')\n const [error, setError] = useState<string | null>(null)\n const [success, setSuccess] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n\n const handleSubmit = useCallback(\n async (event: React.FormEvent) => {\n event.preventDefault()\n setError(null)\n\n if (!tenant.tenantId || !tenant.organizationId) {\n setError(t('portal.org.invalid', 'Organization not found.'))\n return\n }\n\n setSubmitting(true)\n try {\n const result = await apiCall<SignupResponse>('/api/customer_accounts/signup', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, displayName, tenantId: tenant.tenantId, organizationId: tenant.organizationId }),\n })\n\n if (result.status === 202 && result.result?.ok) {\n setSuccess(true)\n return\n }\n\n setError(result.result?.error || t('portal.signup.error.generic', 'Signup failed. Please try again.'))\n } catch {\n setError(t('portal.signup.error.generic', 'Signup failed. Please try again.'))\n } finally {\n setSubmitting(false)\n }\n },\n [displayName, email, password, tenant.tenantId, tenant.organizationId, t],\n )\n\n const injectionContext = useMemo(\n () => ({ orgSlug }),\n [orgSlug],\n )\n\n if (tenant.loading) {\n return <div className=\"flex items-center justify-center py-20\"><Spinner /></div>\n }\n\n if (tenant.error) {\n return (\n <div className=\"mx-auto w-full max-w-md py-12\">\n <Alert variant=\"destructive\">\n <AlertDescription>{t('portal.org.invalid', 'Organization not found.')}</AlertDescription>\n </Alert>\n </div>\n )\n }\n\n if (success) {\n return (\n <div className=\"mx-auto w-full max-w-sm text-center\">\n <div className=\"mx-auto mb-4 flex size-12 items-center justify-center rounded-full bg-foreground text-background\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"size-6\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </div>\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.signup.success.title', 'Check your email')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t(\n 'portal.signup.success.description',\n 'If your registration was accepted, check your email for next steps before signing in. Some organizations require an administrator to activate new accounts.',\n )}</p>\n <Button asChild className=\"mt-6 w-full rounded-lg\">\n <Link href={`/${orgSlug}/portal/login`}>{t('portal.signup.success.loginLink', 'Sign In')}</Link>\n </Button>\n </div>\n )\n }\n\n return (\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-8 text-center\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.signup.title', 'Create Account')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t('portal.signup.description', 'Sign up for a portal account.')}</p>\n </div>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageBefore('signup')} context={injectionContext} />\n\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-4\">\n {error ? (\n <Alert variant=\"destructive\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n ) : null}\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"signup-name\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.signup.displayName', 'Full Name')}</Label>\n <Input id=\"signup-name\" type=\"text\" autoComplete=\"name\" required placeholder={t('portal.signup.displayName.placeholder', 'Jane Smith')} value={displayName} onChange={(e) => setDisplayName(e.target.value)} disabled={submitting} className=\"rounded-lg\" />\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"signup-email\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.signup.email', 'Email')}</Label>\n <Input id=\"signup-email\" type=\"email\" autoComplete=\"email\" required placeholder={t('portal.signup.email.placeholder', 'you@example.com')} value={email} onChange={(e) => setEmail(e.target.value)} disabled={submitting} className=\"rounded-lg\" />\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"signup-password\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.signup.password', 'Password')}</Label>\n <Input id=\"signup-password\" type=\"password\" autoComplete=\"new-password\" required placeholder={t('portal.signup.password.placeholder', '\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022')} value={password} onChange={(e) => setPassword(e.target.value)} disabled={submitting} className=\"rounded-lg\" />\n </div>\n\n <Button type=\"submit\" disabled={submitting} className=\"mt-1 w-full rounded-lg\">\n {submitting ? t('portal.signup.submitting', 'Creating account...') : t('portal.signup.submit', 'Create Account')}\n </Button>\n\n <p className=\"text-center text-sm text-muted-foreground\">\n {t('portal.signup.hasAccount', 'Already have an account?')}{' '}\n <Link href={`/${orgSlug}/portal/login`} className=\"font-medium text-foreground underline underline-offset-4 hover:opacity-80\">\n {t('portal.signup.loginLink', 'Sign in')}\n </Link>\n </p>\n </form>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageAfter('signup')} context={injectionContext} />\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport { useCallback, useMemo, useState } from 'react'\nimport Link from 'next/link'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { EmailInput } from '@open-mercato/ui/primitives/email-input'\nimport { PasswordInput } from '@open-mercato/ui/primitives/password-input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { usePortalContext } from '@open-mercato/ui/portal/PortalContext'\nimport { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'\n\ntype Props = { params: { orgSlug: string } }\ntype SignupResponse = { ok: boolean; error?: string }\n\nexport default function PortalSignupPage({ params }: Props) {\n const t = useT()\n const orgSlug = params.orgSlug\n const { tenant } = usePortalContext()\n\n const [displayName, setDisplayName] = useState('')\n const [email, setEmail] = useState('')\n const [password, setPassword] = useState('')\n const [error, setError] = useState<string | null>(null)\n const [success, setSuccess] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n\n const handleSubmit = useCallback(\n async (event: React.FormEvent) => {\n event.preventDefault()\n setError(null)\n\n if (!tenant.tenantId || !tenant.organizationId) {\n setError(t('portal.org.invalid', 'Organization not found.'))\n return\n }\n\n setSubmitting(true)\n try {\n const result = await apiCall<SignupResponse>('/api/customer_accounts/signup', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, displayName, tenantId: tenant.tenantId, organizationId: tenant.organizationId }),\n })\n\n if (result.status === 202 && result.result?.ok) {\n setSuccess(true)\n return\n }\n\n setError(result.result?.error || t('portal.signup.error.generic', 'Signup failed. Please try again.'))\n } catch {\n setError(t('portal.signup.error.generic', 'Signup failed. Please try again.'))\n } finally {\n setSubmitting(false)\n }\n },\n [displayName, email, password, tenant.tenantId, tenant.organizationId, t],\n )\n\n const injectionContext = useMemo(\n () => ({ orgSlug }),\n [orgSlug],\n )\n\n if (tenant.loading) {\n return <div className=\"flex items-center justify-center py-20\"><Spinner /></div>\n }\n\n if (tenant.error) {\n return (\n <div className=\"mx-auto w-full max-w-md py-12\">\n <Alert variant=\"destructive\">\n <AlertDescription>{t('portal.org.invalid', 'Organization not found.')}</AlertDescription>\n </Alert>\n </div>\n )\n }\n\n if (success) {\n return (\n <div className=\"mx-auto w-full max-w-sm text-center\">\n <div className=\"mx-auto mb-4 flex size-12 items-center justify-center rounded-full bg-foreground text-background\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"size-6\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </div>\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.signup.success.title', 'Check your email')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t(\n 'portal.signup.success.description',\n 'If your registration was accepted, check your email for next steps before signing in. Some organizations require an administrator to activate new accounts.',\n )}</p>\n <Button asChild className=\"mt-6 w-full rounded-lg\">\n <Link href={`/${orgSlug}/portal/login`}>{t('portal.signup.success.loginLink', 'Sign In')}</Link>\n </Button>\n </div>\n )\n }\n\n return (\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-8 text-center\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.signup.title', 'Create Account')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t('portal.signup.description', 'Sign up for a portal account.')}</p>\n </div>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageBefore('signup')} context={injectionContext} />\n\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-4\">\n {error ? (\n <Alert variant=\"destructive\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n ) : null}\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"signup-name\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.signup.displayName', 'Full Name')}</Label>\n <Input id=\"signup-name\" type=\"text\" autoComplete=\"name\" required placeholder={t('portal.signup.displayName.placeholder', 'Jane Smith')} value={displayName} onChange={(e) => setDisplayName(e.target.value)} disabled={submitting} className=\"rounded-lg\" />\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"signup-email\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.signup.email', 'Email')}</Label>\n <EmailInput id=\"signup-email\" required placeholder={t('portal.signup.email.placeholder', 'you@example.com')} value={email} onChange={(e) => setEmail(e.target.value)} disabled={submitting} className=\"rounded-lg\" />\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"signup-password\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.signup.password', 'Password')}</Label>\n <PasswordInput id=\"signup-password\" autoComplete=\"new-password\" required placeholder={t('portal.signup.password.placeholder', '\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022')} value={password} onChange={(e) => setPassword(e.target.value)} disabled={submitting} className=\"rounded-lg\" />\n </div>\n\n <Button type=\"submit\" disabled={submitting} className=\"mt-1 w-full rounded-lg\">\n {submitting ? t('portal.signup.submitting', 'Creating account...') : t('portal.signup.submit', 'Create Account')}\n </Button>\n\n <p className=\"text-center text-sm text-muted-foreground\">\n {t('portal.signup.hasAccount', 'Already have an account?')}{' '}\n <Link href={`/${orgSlug}/portal/login`} className=\"font-medium text-foreground underline underline-offset-4 hover:opacity-80\">\n {t('portal.signup.loginLink', 'Sign in')}\n </Link>\n </p>\n </form>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageAfter('signup')} context={injectionContext} />\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -17,6 +17,7 @@ import { Button } from "@open-mercato/ui/primitives/button";
17
17
  import { Badge } from "@open-mercato/ui/primitives/badge";
18
18
  import { Spinner } from "@open-mercato/ui/primitives/spinner";
19
19
  import { Input } from "@open-mercato/ui/primitives/input";
20
+ import { EmailInput } from "@open-mercato/ui/primitives/email-input";
20
21
  import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@open-mercato/ui/primitives/dialog";
21
22
  import { ArrowRightLeft, Building2, CreditCard, Mail, Pencil, Plus, Send, Store, Truck, UserRound, Wand2, X } from "lucide-react";
22
23
  import { FormHeader } from "@open-mercato/ui/backend/forms";
@@ -578,9 +579,8 @@ function CustomerInlineEditor({
578
579
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
579
580
  /* @__PURE__ */ jsx("label", { className: "text-sm font-medium text-foreground", children: t("customers.people.detail.highlights.primaryEmail", "Primary email") }),
580
581
  /* @__PURE__ */ jsx(
581
- Input,
582
+ EmailInput,
582
583
  {
583
- type: "email",
584
584
  value: snapshotDraft.primaryEmail,
585
585
  onChange: (event) => setSnapshotDraft((prev) => ({ ...prev, primaryEmail: event.target.value })),
586
586
  placeholder: t("customers.people.form.primaryEmailPlaceholder", "name@example.com")
@@ -829,16 +829,14 @@ function ContactEmailInlineEditor({
829
829
  },
830
830
  children: [
831
831
  /* @__PURE__ */ jsx(
832
- Input,
832
+ EmailInput,
833
833
  {
834
- leftIcon: /* @__PURE__ */ jsx(Mail, {}),
835
834
  value: draft,
836
835
  onChange: (event) => {
837
836
  if (error) setError(null);
838
837
  setDraft(event.target.value);
839
838
  },
840
839
  placeholder,
841
- type: "email",
842
840
  autoFocus: true,
843
841
  spellCheck: false
844
842
  }