-
-
-
+
+
+
+
-
- {t(I18nKey.AUTH$LETS_GET_STARTED)}
-
+
+ {t(I18nKey.AUTH$LETS_GET_STARTED)}
+
+
+ {shouldShownHelperText && (
+
+ {emailVerified && (
+
+ {t(I18nKey.AUTH$EMAIL_VERIFIED_PLEASE_LOGIN)}
+
+ )}
+ {hasDuplicatedEmail && (
+
+ {t(I18nKey.AUTH$DUPLICATE_EMAIL_ERROR)}
+
+ )}
+ {recaptchaBlocked && (
+
+ {t(I18nKey.AUTH$RECAPTCHA_BLOCKED)}
+
+ )}
+ {hasInvitation && (
+
+ {t(I18nKey.AUTH$INVITATION_PENDING)}
+
+ )}
+ {showBitbucket && (
+
+ {t(I18nKey.AUTH$BITBUCKET_SIGNUP_DISABLED)}
+
+ )}
+
+ )}
- {shouldShownHelperText && (
- {emailVerified && (
-
- {t(I18nKey.AUTH$EMAIL_VERIFIED_PLEASE_LOGIN)}
-
- )}
- {hasDuplicatedEmail && (
-
- {t(I18nKey.AUTH$DUPLICATE_EMAIL_ERROR)}
-
- )}
- {recaptchaBlocked && (
-
- {t(I18nKey.AUTH$RECAPTCHA_BLOCKED)}
-
- )}
- {hasInvitation && (
-
- {t(I18nKey.AUTH$INVITATION_PENDING)}
-
- )}
- {showBitbucket && (
-
- {t(I18nKey.AUTH$BITBUCKET_SIGNUP_DISABLED)}
-
+ {noProvidersConfigured ? (
+
+ {t(I18nKey.AUTH$NO_PROVIDERS_CONFIGURED)}
+
+ ) : (
+ <>
+ {showGithub && (
+
+ )}
+
+ {showGitlab && (
+
+ )}
+
+ {showBitbucket && (
+
+ )}
+
+ {showBitbucketDataCenter && (
+
+ )}
+
+ {showEnterpriseSso && (
+
+ )}
+ >
)}
- )}
-
- {noProvidersConfigured ? (
-
- {t(I18nKey.AUTH$NO_PROVIDERS_CONFIGURED)}
-
- ) : (
- <>
- {showGithub && (
-
- )}
-
- {showGitlab && (
-
- )}
-
- {showBitbucket && (
-
- )}
-
- {showBitbucketDataCenter && (
-
- )}
-
- {showEnterpriseSso && (
-
- )}
- >
- )}
+
-
+ {appMode === "saas" && ENABLE_PROJ_USER_JOURNEY() &&
}
);
}
diff --git a/frontend/src/components/features/auth/login-cta.tsx b/frontend/src/components/features/auth/login-cta.tsx
new file mode 100644
index 0000000000..1d67b9cedb
--- /dev/null
+++ b/frontend/src/components/features/auth/login-cta.tsx
@@ -0,0 +1,66 @@
+import { useTranslation } from "react-i18next";
+import { Card } from "#/ui/card";
+import { CardTitle } from "#/ui/card-title";
+import { Typography } from "#/ui/typography";
+import { I18nKey } from "#/i18n/declaration";
+import { cn } from "#/utils/utils";
+import StackedIcon from "#/icons/stacked.svg?react";
+import { useTracking } from "#/hooks/use-tracking";
+
+export function LoginCTA() {
+ const { t } = useTranslation();
+ const { trackSaasSelfhostedInquiry } = useTracking();
+
+ const handleLearnMoreClick = () => {
+ trackSaasSelfhostedInquiry({ location: "login_page" });
+ };
+
+ return (
+
+
+
+
+
+
+
{t(I18nKey.CTA$ENTERPRISE)}
+
+
+ {t(I18nKey.CTA$ENTERPRISE_DEPLOY)}
+
+
+
+ - {t(I18nKey.CTA$FEATURE_ON_PREMISES)}
+ - {t(I18nKey.CTA$FEATURE_DATA_CONTROL)}
+ - {t(I18nKey.CTA$FEATURE_COMPLIANCE)}
+ - {t(I18nKey.CTA$FEATURE_SUPPORT)}
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/i18n/declaration.ts b/frontend/src/i18n/declaration.ts
index 81b1301ace..94f72e7c95 100644
--- a/frontend/src/i18n/declaration.ts
+++ b/frontend/src/i18n/declaration.ts
@@ -1141,6 +1141,12 @@ export enum I18nKey {
ONBOARDING$NEXT_BUTTON = "ONBOARDING$NEXT_BUTTON",
ONBOARDING$BACK_BUTTON = "ONBOARDING$BACK_BUTTON",
ONBOARDING$FINISH_BUTTON = "ONBOARDING$FINISH_BUTTON",
+ CTA$ENTERPRISE = "CTA$ENTERPRISE",
+ CTA$ENTERPRISE_DEPLOY = "CTA$ENTERPRISE_DEPLOY",
+ CTA$FEATURE_ON_PREMISES = "CTA$FEATURE_ON_PREMISES",
+ CTA$FEATURE_DATA_CONTROL = "CTA$FEATURE_DATA_CONTROL",
+ CTA$FEATURE_COMPLIANCE = "CTA$FEATURE_COMPLIANCE",
+ CTA$FEATURE_SUPPORT = "CTA$FEATURE_SUPPORT",
ENTERPRISE$SELF_HOSTED = "ENTERPRISE$SELF_HOSTED",
ENTERPRISE$TITLE = "ENTERPRISE$TITLE",
ENTERPRISE$DESCRIPTION = "ENTERPRISE$DESCRIPTION",
diff --git a/frontend/src/i18n/translation.json b/frontend/src/i18n/translation.json
index da7b4f391f..c712b2a2e1 100644
--- a/frontend/src/i18n/translation.json
+++ b/frontend/src/i18n/translation.json
@@ -18255,6 +18255,102 @@
"tr": "Bitir",
"uk": "Завершити"
},
+ "CTA$ENTERPRISE": {
+ "en": "Enterprise",
+ "ja": "エンタープライズ",
+ "zh-CN": "企业版",
+ "zh-TW": "企業版",
+ "ko-KR": "엔터프라이즈",
+ "no": "Bedrift",
+ "ar": "المؤسسات",
+ "de": "Unternehmen",
+ "fr": "Entreprise",
+ "it": "Azienda",
+ "pt": "Empresarial",
+ "es": "Empresa",
+ "tr": "Kurumsal",
+ "uk": "Підприємство"
+ },
+ "CTA$ENTERPRISE_DEPLOY": {
+ "en": "Deploy OpenHands on your own infrastructure. Full control over data, compliance, and security.",
+ "ja": "独自のインフラストラクチャにOpenHandsをデプロイ。データ、コンプライアンス、セキュリティを完全にコントロール。",
+ "zh-CN": "在您自己的基础设施上部署 OpenHands。完全控制数据、合规性和安全性。",
+ "zh-TW": "在您自己的基礎設施上部署 OpenHands。完全控制資料、合規性和安全性。",
+ "ko-KR": "자체 인프라에 OpenHands를 배포하세요. 데이터, 규정 준수 및 보안을 완벽하게 제어합니다.",
+ "no": "Distribuer OpenHands på din egen infrastruktur. Full kontroll over data, samsvar og sikkerhet.",
+ "ar": "انشر OpenHands على بنيتك التحتية الخاصة. تحكم كامل في البيانات والامتثال والأمان.",
+ "de": "Stellen Sie OpenHands auf Ihrer eigenen Infrastruktur bereit. Volle Kontrolle über Daten, Compliance und Sicherheit.",
+ "fr": "Déployez OpenHands sur votre propre infrastructure. Contrôle total sur les données, la conformité et la sécurité.",
+ "it": "Distribuisci OpenHands sulla tua infrastruttura. Controllo completo su dati, conformità e sicurezza.",
+ "pt": "Implante o OpenHands em sua própria infraestrutura. Controle total sobre dados, conformidade e segurança.",
+ "es": "Implemente OpenHands en su propia infraestructura. Control total sobre datos, cumplimiento y seguridad.",
+ "tr": "OpenHands'i kendi altyapınızda dağıtın. Veri, uyumluluk ve güvenlik üzerinde tam kontrol.",
+ "uk": "Розгорніть OpenHands на власній інфраструктурі. Повний контроль над даними, відповідністю та безпекою."
+ },
+ "CTA$FEATURE_ON_PREMISES": {
+ "en": "On-premises or private cloud",
+ "ja": "オンプレミスまたはプライベートクラウド",
+ "zh-CN": "本地部署或私有云",
+ "zh-TW": "本地部署或私有雲",
+ "ko-KR": "온프레미스 또는 프라이빗 클라우드",
+ "no": "Lokalt eller privat sky",
+ "ar": "محلي أو سحابة خاصة",
+ "de": "On-Premises oder Private Cloud",
+ "fr": "Sur site ou cloud privé",
+ "it": "On-premise o cloud privato",
+ "pt": "Local ou nuvem privada",
+ "es": "Local o nube privada",
+ "tr": "Şirket içi veya özel bulut",
+ "uk": "Локально або приватна хмара"
+ },
+ "CTA$FEATURE_DATA_CONTROL": {
+ "en": "Full data control",
+ "ja": "完全なデータ管理",
+ "zh-CN": "完全数据控制",
+ "zh-TW": "完全資料控制",
+ "ko-KR": "완전한 데이터 제어",
+ "no": "Full datakontroll",
+ "ar": "تحكم كامل في البيانات",
+ "de": "Volle Datenkontrolle",
+ "fr": "Contrôle total des données",
+ "it": "Controllo completo dei dati",
+ "pt": "Controle total de dados",
+ "es": "Control total de datos",
+ "tr": "Tam veri kontrolü",
+ "uk": "Повний контроль даних"
+ },
+ "CTA$FEATURE_COMPLIANCE": {
+ "en": "Custom compliance requirements",
+ "ja": "カスタムコンプライアンス要件",
+ "zh-CN": "自定义合规要求",
+ "zh-TW": "自訂合規要求",
+ "ko-KR": "사용자 정의 규정 준수 요구 사항",
+ "no": "Tilpassede samsvarkrav",
+ "ar": "متطلبات الامتثال المخصصة",
+ "de": "Individuelle Compliance-Anforderungen",
+ "fr": "Exigences de conformité personnalisées",
+ "it": "Requisiti di conformità personalizzati",
+ "pt": "Requisitos de conformidade personalizados",
+ "es": "Requisitos de cumplimiento personalizados",
+ "tr": "Özel uyumluluk gereksinimleri",
+ "uk": "Індивідуальні вимоги відповідності"
+ },
+ "CTA$FEATURE_SUPPORT": {
+ "en": "Dedicated support options",
+ "ja": "専用サポートオプション",
+ "zh-CN": "专属支持选项",
+ "zh-TW": "專屬支援選項",
+ "ko-KR": "전용 지원 옵션",
+ "no": "Dedikerte støttealternativer",
+ "ar": "خيارات دعم مخصصة",
+ "de": "Dedizierte Supportoptionen",
+ "fr": "Options de support dédiées",
+ "it": "Opzioni di supporto dedicate",
+ "pt": "Opções de suporte dedicado",
+ "es": "Opciones de soporte dedicado",
+ "tr": "Özel destek seçenekleri",
+ "uk": "Виділені варіанти підтримки"
+ },
"ENTERPRISE$SELF_HOSTED": {
"en": "Self-Hosted",
"ja": "セルフホスト",
diff --git a/frontend/src/tailwind.css b/frontend/src/tailwind.css
index 8cbacea7ef..afa6a9aef7 100644
--- a/frontend/src/tailwind.css
+++ b/frontend/src/tailwind.css
@@ -379,6 +379,6 @@
/* CTA card gradient and shadow */
.cta-card-gradient {
- background: radial-gradient(85.36% 123.38% at 50% 0%, rgba(255, 255, 255, 0.14) 0%, rgba(0, 0, 0, 0) 100%);
+ background: radial-gradient(85.36% 123.38% at 50% 0%, rgba(255, 255, 255, 0.14) 0%, rgba(0, 0, 0, 0) 100%), #000000;
box-shadow: 0px 4px 6px -4px rgba(0, 0, 0, 0.1), 0px 10px 15px -3px rgba(0, 0, 0, 0.1);
}