add hide free domain option to domain picker

This commit is contained in:
miloschwartz
2025-09-10 15:36:05 -07:00
parent a4571a80ae
commit bedc5adb75
2 changed files with 44 additions and 29 deletions

View File

@@ -1504,5 +1504,18 @@
"internationaldomaindetected": "International Domain Detected", "internationaldomaindetected": "International Domain Detected",
"willbestoredas": "Will be stored as:", "willbestoredas": "Will be stored as:",
"idpGoogleDescription": "Google OAuth2/OIDC provider", "idpGoogleDescription": "Google OAuth2/OIDC provider",
"idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider",
"domainPickerProvidedDomain": "Provided Domain",
"domainPickerFreeProvidedDomain": "Free Provided Domain",
"domainPickerVerified": "Verified",
"domainPickerUnverified": "Unverified",
"domainPickerInvalidSubdomainStructure": "This subdomain contains invalid characters or structure. It will be sanitized automatically when you save.",
"domainPickerError": "Error",
"domainPickerErrorLoadDomains": "Failed to load organization domains",
"domainPickerErrorCheckAvailability": "Failed to check domain availability",
"domainPickerInvalidSubdomain": "Invalid subdomain",
"domainPickerInvalidSubdomainRemoved": "The input \"{sub}\" was removed because it's not valid.",
"domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" could not be made valid for {domain}.",
"domainPickerSubdomainSanitized": "Subdomain sanitized",
"domainPickerSubdomainCorrected": "\"{sub}\" was corrected to \"{sanitized}\""
} }

View File

@@ -79,12 +79,14 @@ interface DomainPicker2Props {
baseDomain: string; baseDomain: string;
}) => void; }) => void;
cols?: number; cols?: number;
hideFreeDomain?: boolean;
} }
export default function DomainPicker2({ export default function DomainPicker2({
orgId, orgId,
onDomainChange, onDomainChange,
cols = 2 cols = 2,
hideFreeDomain = false
}: DomainPicker2Props) { }: DomainPicker2Props) {
const { env } = useEnvContext(); const { env } = useEnvContext();
const api = createApiClient({ env }); const api = createApiClient({ env });
@@ -153,12 +155,12 @@ export default function DomainPicker2({
fullDomain: firstOrgDomain.baseDomain, fullDomain: firstOrgDomain.baseDomain,
baseDomain: firstOrgDomain.baseDomain baseDomain: firstOrgDomain.baseDomain
}); });
} else if (build === "saas" || build === "enterprise") { } else if ((build === "saas" || build === "enterprise") && !hideFreeDomain) {
// If no organization domains, select the provided domain option // If no organization domains, select the provided domain option
const domainOptionText = const domainOptionText =
build === "enterprise" build === "enterprise"
? "Provided Domain" ? t("domainPickerProvidedDomain")
: "Free Provided Domain"; : t("domainPickerFreeProvidedDomain");
const freeDomainOption: DomainOption = { const freeDomainOption: DomainOption = {
id: "provided-search", id: "provided-search",
domain: domainOptionText, domain: domainOptionText,
@@ -171,8 +173,8 @@ export default function DomainPicker2({
console.error("Failed to load organization domains:", error); console.error("Failed to load organization domains:", error);
toast({ toast({
variant: "destructive", variant: "destructive",
title: "Error", title: t("domainPickerError"),
description: "Failed to load organization domains" description: t("domainPickerErrorLoadDomains")
}); });
} finally { } finally {
setLoadingDomains(false); setLoadingDomains(false);
@@ -180,7 +182,7 @@ export default function DomainPicker2({
}; };
loadOrganizationDomains(); loadOrganizationDomains();
}, [orgId, api]); }, [orgId, api, hideFreeDomain]);
const checkAvailability = useCallback( const checkAvailability = useCallback(
async (input: string) => { async (input: string) => {
@@ -202,8 +204,8 @@ export default function DomainPicker2({
setAvailableOptions([]); setAvailableOptions([]);
toast({ toast({
variant: "destructive", variant: "destructive",
title: "Error", title: t("domainPickerError"),
description: "Failed to check domain availability" description: t("domainPickerErrorCheckAvailability")
}); });
} finally { } finally {
setIsChecking(false); setIsChecking(false);
@@ -246,11 +248,11 @@ export default function DomainPicker2({
}); });
}); });
if (build === "saas" || build === "enterprise") { if ((build === "saas" || build === "enterprise") && !hideFreeDomain) {
const domainOptionText = const domainOptionText =
build === "enterprise" build === "enterprise"
? "Provided Domain" ? t("domainPickerProvidedDomain")
: "Free Provided Domain"; : t("domainPickerFreeProvidedDomain");
options.push({ options.push({
id: "provided-search", id: "provided-search",
domain: domainOptionText, domain: domainOptionText,
@@ -269,8 +271,8 @@ export default function DomainPicker2({
if (!sanitized) { if (!sanitized) {
toast({ toast({
variant: "destructive", variant: "destructive",
title: "Invalid subdomain", title: t("domainPickerInvalidSubdomain"),
description: `The input "${sub}" was removed because it's not valid.`, description: t("domainPickerInvalidSubdomainRemoved", { sub }),
}); });
return ""; return "";
} }
@@ -283,16 +285,16 @@ export default function DomainPicker2({
if (!ok) { if (!ok) {
toast({ toast({
variant: "destructive", variant: "destructive",
title: "Invalid subdomain", title: t("domainPickerInvalidSubdomain"),
description: `"${sub}" could not be made valid for ${base.domain}.`, description: t("domainPickerInvalidSubdomainCannotMakeValid", { sub, domain: base.domain }),
}); });
return ""; return "";
} }
if (sub !== sanitized) { if (sub !== sanitized) {
toast({ toast({
title: "Subdomain sanitized", title: t("domainPickerSubdomainSanitized"),
description: `"${sub}" was corrected to "${sanitized}"`, description: t("domainPickerSubdomainCorrected", { sub, sanitized }),
}); });
} }
@@ -453,7 +455,7 @@ export default function DomainPicker2({
/> />
{showSubdomainInput && subdomainInput && !isValidSubdomainStructure(subdomainInput) && ( {showSubdomainInput && subdomainInput && !isValidSubdomainStructure(subdomainInput) && (
<p className="text-sm text-red-500"> <p className="text-sm text-red-500">
This subdomain contains invalid characters or structure. It will be sanitized automatically when you save. {t("domainPickerInvalidSubdomainStructure")}
</p> </p>
)} )}
{showSubdomainInput && !subdomainInput && ( {showSubdomainInput && !subdomainInput && (
@@ -555,8 +557,8 @@ export default function DomainPicker2({
{orgDomain.type.toUpperCase()}{" "} {orgDomain.type.toUpperCase()}{" "}
{" "} {" "}
{orgDomain.verified {orgDomain.verified
? "Verified" ? t("domainPickerVerified")
: "Unverified"} : t("domainPickerUnverified")}
</span> </span>
</div> </div>
<Check <Check
@@ -574,14 +576,14 @@ export default function DomainPicker2({
</CommandList> </CommandList>
</CommandGroup> </CommandGroup>
{(build === "saas" || {(build === "saas" ||
build === "enterprise") && ( build === "enterprise") && !hideFreeDomain && (
<CommandSeparator className="my-2" /> <CommandSeparator className="my-2" />
)} )}
</> </>
)} )}
{(build === "saas" || {(build === "saas" ||
build === "enterprise") && ( build === "enterprise") && !hideFreeDomain && (
<CommandGroup <CommandGroup
heading={ heading={
build === "enterprise" build === "enterprise"
@@ -601,8 +603,8 @@ export default function DomainPicker2({
domain: domain:
build === build ===
"enterprise" "enterprise"
? "Provided Domain" ? t("domainPickerProvidedDomain")
: "Free Provided Domain", : t("domainPickerFreeProvidedDomain"),
type: "provided-search" type: "provided-search"
}) })
} }
@@ -614,8 +616,8 @@ export default function DomainPicker2({
<div className="flex flex-col flex-1 min-w-0"> <div className="flex flex-col flex-1 min-w-0">
<span className="font-medium truncate"> <span className="font-medium truncate">
{build === "enterprise" {build === "enterprise"
? "Provided Domain" ? t("domainPickerProvidedDomain")
: "Free Provided Domain"} : t("domainPickerFreeProvidedDomain")}
</span> </span>
<span className="text-xs text-muted-foreground"> <span className="text-xs text-muted-foreground">
{t( {t(
@@ -771,4 +773,4 @@ function debounce<T extends (...args: any[]) => any>(
func(...args); func(...args);
}, wait); }, wait);
}; };
} }