diff --git a/client/src/app/pages/dashboard/users/ARCIntegrationPage.tsx b/client/src/app/pages/dashboard/users/ARCIntegrationPage.tsx
new file mode 100644
index 000000000..40e17bc98
--- /dev/null
+++ b/client/src/app/pages/dashboard/users/ARCIntegrationPage.tsx
@@ -0,0 +1,123 @@
+import ApiError from "components/util/ApiError";
+import Divider from "components/util/Divider";
+import Loading from "components/util/Loading";
+import Muted from "components/util/Muted";
+import useApiQuery from "components/util/query/useApiQuery";
+import React, { useEffect, useState } from "react";
+import { Button, Col, Form } from "react-bootstrap";
+import { ARCSavedProfileDocument, PublicUserDocument } from "tachi-common";
+import { SetState } from "types/react";
+import { APIFetchV1 } from "util/api";
+
+export default function ARCIntegrationPage({ reqUser }: { reqUser: PublicUserDocument }) {
+ const [iidxID, setIIDXID] = useState("");
+ const [sdvxID, setSDVXID] = useState("");
+
+ const { data, isLoading, error } = useApiQuery<{
+ iidx: ARCSavedProfileDocument | null;
+ sdvx: ARCSavedProfileDocument | null;
+ }>(`/users/${reqUser.id}/integrations/arc`);
+
+ useEffect(() => {
+ if (data) {
+ setIIDXID(data.iidx?.accountID ?? "");
+ setSDVXID(data.sdvx?.accountID ?? "");
+ }
+ }, [data]);
+
+ if (error) {
+ return ;
+ }
+
+ if (!data || isLoading) {
+ return ;
+ }
+
+ return (
+ <>
+
+
ARC Integration
+ To import scores from ARC, just put your AccountIDs in the tabs below.
+
+
+ Note: Only the latest versions of IIDX and SDVX are supported for imports.
+
+
+
How to get your AccountID
+
+
Open the ARC website.
+
Go to the game you care about, and select My Bests.
+
+ In the URL, after /profiles, there'll be a string that looks
+ like H4JxPV3vQH_. Copy that into the text fields below!
+
+
To unset an integration, remove the account ID and hit save.
+
+
+
+
+ {iidxID && iidxID.length !== 11 && (
+
+ Invalid IIDX ID, it should be 11 characters long.
+
+ )}
+
+
+ {sdvxID && sdvxID.length !== 11 && (
+
+ Invalid SDVX ID, it should be 11 characters long.
+
+ )}
+
+
+
+
+
+ >
+ );
+}
+
+function IntegrationStatus({
+ name,
+ value,
+ setValue,
+}: {
+ name: string;
+ value: string;
+ setValue: SetState;
+}) {
+ return (
+
+ {`${name} Account ID`}
+ setValue(e.target.value)}
+ />
+
+ );
+}
diff --git a/client/src/app/pages/dashboard/users/UserIntegrationsPage.tsx b/client/src/app/pages/dashboard/users/UserIntegrationsPage.tsx
index e6f0fa930..d1323c8a4 100644
--- a/client/src/app/pages/dashboard/users/UserIntegrationsPage.tsx
+++ b/client/src/app/pages/dashboard/users/UserIntegrationsPage.tsx
@@ -1,7 +1,6 @@
import useSetSubheader from "components/layout/header/useSetSubheader";
import Card from "components/layout/page/Card";
import ApiError from "components/util/ApiError";
-import DebugContent from "components/util/DebugContent";
import Divider from "components/util/Divider";
import ExternalLink from "components/util/ExternalLink";
import FormInput from "components/util/FormInput";
@@ -16,12 +15,13 @@ import { Alert, Button, Col, Form, Modal, Row } from "react-bootstrap";
import {
APIPermissions,
APITokenDocument,
- TachiAPIClientDocument,
PublicUserDocument,
+ TachiAPIClientDocument,
} from "tachi-common";
import { SetState } from "types/react";
import { APIFetchV1 } from "util/api";
import { allPermissions, DelayedPageReload } from "util/misc";
+import ARCIntegrationPage from "./ARCIntegrationPage";
import FervidexIntegrationPage from "./FervidexIntegrationPage";
export default function UserIntegrationsPage({ reqUser }: { reqUser: PublicUserDocument }) {
@@ -41,7 +41,7 @@ export default function UserIntegrationsPage({ reqUser }: { reqUser: PublicUserD
{mode !== "btchi" && (
- Integrations
+ Service Configuration
)}
@@ -57,7 +57,7 @@ export default function UserIntegrationsPage({ reqUser }: { reqUser: PublicUserD