You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.5 KiB
172 lines
5.5 KiB
import { Dispatch, SetStateAction, useCallback } from "react"; |
|
import { Trans, useTranslation } from "react-i18next"; |
|
|
|
import { Button } from "@/components/buttons/Button"; |
|
import { Toggle } from "@/components/buttons/Toggle"; |
|
import { Icon, Icons } from "@/components/Icon"; |
|
import { SettingsCard } from "@/components/layout/SettingsCard"; |
|
import { MwLink } from "@/components/text/Link"; |
|
import { AuthInputBox } from "@/components/text-inputs/AuthInputBox"; |
|
import { Divider } from "@/components/utils/Divider"; |
|
import { Heading1 } from "@/components/utils/Text"; |
|
import { SetupPart } from "@/pages/parts/settings/SetupPart"; |
|
|
|
interface ProxyEditProps { |
|
proxyUrls: string[] | null; |
|
setProxyUrls: Dispatch<SetStateAction<string[] | null>>; |
|
} |
|
|
|
interface BackendEditProps { |
|
backendUrl: string | null; |
|
setBackendUrl: Dispatch<SetStateAction<string | null>>; |
|
} |
|
|
|
function ProxyEdit({ proxyUrls, setProxyUrls }: ProxyEditProps) { |
|
const { t } = useTranslation(); |
|
const add = useCallback(() => { |
|
setProxyUrls((s) => [...(s ?? []), ""]); |
|
}, [setProxyUrls]); |
|
|
|
const changeItem = useCallback( |
|
(index: number, val: string) => { |
|
setProxyUrls((s) => [ |
|
...(s ?? []).map((v, i) => { |
|
if (i !== index) return v; |
|
return val; |
|
}), |
|
]); |
|
}, |
|
[setProxyUrls], |
|
); |
|
|
|
const removeItem = useCallback( |
|
(index: number) => { |
|
setProxyUrls((s) => [...(s ?? []).filter((v, i) => i !== index)]); |
|
}, |
|
[setProxyUrls], |
|
); |
|
|
|
return ( |
|
<SettingsCard> |
|
<div className="flex justify-between items-center gap-4"> |
|
<div className="my-3"> |
|
<p className="text-white font-bold mb-3"> |
|
{t("settings.connections.workers.label")} |
|
</p> |
|
<p className="max-w-[20rem] font-medium"> |
|
<Trans i18nKey="settings.connections.workers.description"> |
|
<MwLink to="https://docs.movie-web.app/proxy/deploy"> |
|
Proxy documentation |
|
</MwLink> |
|
</Trans> |
|
</p> |
|
</div> |
|
<div> |
|
<Toggle |
|
onClick={() => setProxyUrls((s) => (s === null ? [] : null))} |
|
enabled={proxyUrls !== null} |
|
/> |
|
</div> |
|
</div> |
|
{proxyUrls !== null ? ( |
|
<> |
|
<Divider marginClass="my-6 px-8 box-content -mx-8" /> |
|
<p className="text-white font-bold mb-3"> |
|
{t("settings.connections.workers.urlLabel")} |
|
</p> |
|
|
|
<div className="my-6 space-y-2 max-w-md"> |
|
{(proxyUrls?.length ?? 0) === 0 ? ( |
|
<p>{t("settings.connections.workers.emptyState")}</p> |
|
) : null} |
|
{(proxyUrls ?? []).map((v, i) => ( |
|
<div |
|
// not the best but we can live with it |
|
// eslint-disable-next-line react/no-array-index-key |
|
key={i} |
|
className="grid grid-cols-[1fr,auto] items-center gap-2" |
|
> |
|
<AuthInputBox |
|
value={v} |
|
onChange={(val) => changeItem(i, val)} |
|
placeholder={ |
|
t("settings.connections.workers.urlPlaceholder") ?? |
|
undefined |
|
} |
|
/> |
|
<button |
|
type="button" |
|
onClick={() => removeItem(i)} |
|
className="h-full scale-90 hover:scale-100 rounded-full aspect-square bg-authentication-inputBg hover:bg-authentication-inputBgHover flex justify-center items-center transition-transform duration-200 hover:text-white cursor-pointer" |
|
> |
|
<Icon className="text-xl" icon={Icons.X} /> |
|
</button> |
|
</div> |
|
))} |
|
</div> |
|
|
|
<Button theme="purple" onClick={add}> |
|
{t("settings.connections.workers.addButton")} |
|
</Button> |
|
</> |
|
) : null} |
|
</SettingsCard> |
|
); |
|
} |
|
|
|
function BackendEdit({ backendUrl, setBackendUrl }: BackendEditProps) { |
|
const { t } = useTranslation(); |
|
return ( |
|
<SettingsCard> |
|
<div className="flex justify-between items-center gap-4"> |
|
<div className="my-3"> |
|
<p className="text-white font-bold mb-3"> |
|
{t("settings.connections.server.label")} |
|
</p> |
|
<p className="max-w-[20rem] font-medium"> |
|
<Trans i18nKey="settings.connections.server.description"> |
|
<MwLink to="https://docs.movie-web.app/backend/deploy"> |
|
Backend documentation |
|
</MwLink> |
|
</Trans> |
|
</p> |
|
</div> |
|
<div> |
|
<Toggle |
|
onClick={() => setBackendUrl((s) => (s === null ? "" : null))} |
|
enabled={backendUrl !== null} |
|
/> |
|
</div> |
|
</div> |
|
{backendUrl !== null ? ( |
|
<> |
|
<Divider marginClass="my-6 px-8 box-content -mx-8" /> |
|
<p className="text-white font-bold mb-3"> |
|
{t("settings.connections.server.urlLabel")} |
|
</p> |
|
<AuthInputBox onChange={setBackendUrl} value={backendUrl ?? ""} /> |
|
</> |
|
) : null} |
|
</SettingsCard> |
|
); |
|
} |
|
|
|
export function ConnectionsPart(props: BackendEditProps & ProxyEditProps) { |
|
const { t } = useTranslation(); |
|
return ( |
|
<div> |
|
<Heading1 border>{t("settings.connections.title")}</Heading1> |
|
<div className="space-y-6"> |
|
<SetupPart /> |
|
<ProxyEdit |
|
proxyUrls={props.proxyUrls} |
|
setProxyUrls={props.setProxyUrls} |
|
/> |
|
<BackendEdit |
|
backendUrl={props.backendUrl} |
|
setBackendUrl={props.setBackendUrl} |
|
/> |
|
</div> |
|
</div> |
|
); |
|
}
|
|
|