// PDS host selector shown during signup. // // The flow: user clicks "Sign Up" in the login modal → login modal // closes and this one opens → user picks a PDS (or enters a custom // URL) and confirms → onSubmit(pdsHost) is called and the modal // closes. The caller is responsible for setting the PDS and starting // the login round-trip. import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { useStore } from "@/lib/store"; import { SHUFFLED_PDS_HOSTS, type PdsHost } from "@streamplace/core"; import { Check, ExternalLink } from "lucide-react"; import { useState } from "react"; import { Trans, useTranslation } from "react-i18next"; interface PdsHostSelectorModalProps { open: boolean; onOpenChange: (open: boolean) => void; onSubmit: (pdsHost: string) => void; } export function PdsHostSelectorModal({ open, onOpenChange, onSubmit, }: PdsHostSelectorModalProps) { const { t } = useTranslation("common"); const [selectedHost, setSelectedHost] = useState( SHUFFLED_PDS_HOSTS[0].value, ); const [customHost, setCustomHost] = useState(""); const [useCustom, setUseCustom] = useState(false); const [handlePolicyChecked, setHandlePolicyChecked] = useState(false); const [showOtherHosts, setShowOtherHosts] = useState(false); const [defaultHost, ...otherHosts] = SHUFFLED_PDS_HOSTS; const loginError = useStore((s) => s.loginState.error); const setLoginError = useStore((s) => s.setLoginError); const selectedHostObj: PdsHost = SHUFFLED_PDS_HOSTS.find((host) => host.value === selectedHost) ?? SHUFFLED_PDS_HOSTS[0]; const handleCancel = () => { setSelectedHost(SHUFFLED_PDS_HOSTS[0].value); setCustomHost(""); setUseCustom(false); setHandlePolicyChecked(false); setShowOtherHosts(false); setLoginError(null); onOpenChange(false); }; const handleSubmit = () => { const hostToUse = useCustom ? customHost : selectedHost; if (!hostToUse) return; onSubmit(hostToUse); handleCancel(); }; const handleLearnMore = () => { window.open( "https://atproto.com/guides/self-hosting", "_blank", "noopener", ); }; const handleTOS = () => { window.open(selectedHostObj.terms, "_blank", "noopener"); }; const handlePrivacy = () => { window.open(selectedHostObj.privacy, "_blank", "noopener"); }; const handleHandlePolicy = () => { if (selectedHostObj.handlePolicyDocs) { window.open(selectedHostObj.handlePolicyDocs, "_blank", "noopener"); } }; const canSubmit = (useCustom ? customHost.trim().length > 0 : true) && (handlePolicyChecked || !selectedHostObj.handlePolicyDocs); return ( { if (next) return; handleCancel(); }} >
{t("pds-selector-title")} {t("pds-selector-description")}
{ setSelectedHost(defaultHost.value); setUseCustom(false); }} /> {!showOtherHosts && ( )} {showOtherHosts && ( <> {otherHosts.map((host) => ( { setSelectedHost(host.value); setUseCustom(false); }} /> ))} {useCustom && (
)} {!useCustom && selectedHostObj.handlePolicyDocs && ( )} )}

{t("pds-selector-info")}

{!useCustom && (

), privacyLink: (

{loginError && (

{loginError}

)}
); } function HostOption({ host, selected, onSelect, }: { host: PdsHost; selected: boolean; onSelect: () => void; }) { return ( ); }