diff --git a/packages/console/src/App.tsx b/packages/console/src/App.tsx
index b3071fc2b..9125e35c6 100644
--- a/packages/console/src/App.tsx
+++ b/packages/console/src/App.tsx
@@ -12,8 +12,8 @@ import initI18n from './i18n/init';
import ApiResources from './pages/ApiResources';
import ApplicationDetails from './pages/ApplicationDetails';
import Applications from './pages/Applications';
+import ConnectorDetails from './pages/ConnectorDetails';
import Connectors from './pages/Connectors';
-import Connector from './pages/Connectors/Connector';
import { fetcher } from './swr';
const isBasenameNeeded = process.env.NODE_ENV !== 'development' || process.env.PORT === '5002';
@@ -46,7 +46,7 @@ const Main = () => {
} />
} />
- } />
+ } />
diff --git a/packages/console/src/pages/ApplicationDetails/icons/Back.tsx b/packages/console/src/components/BackLink/Back.tsx
similarity index 100%
rename from packages/console/src/pages/ApplicationDetails/icons/Back.tsx
rename to packages/console/src/components/BackLink/Back.tsx
diff --git a/packages/console/src/components/BackLink/index.module.scss b/packages/console/src/components/BackLink/index.module.scss
new file mode 100644
index 000000000..01d855fc6
--- /dev/null
+++ b/packages/console/src/components/BackLink/index.module.scss
@@ -0,0 +1,14 @@
+@use '@/scss/underscore' as _;
+
+.button {
+ padding-left: 0;
+
+ .body {
+ display: flex;
+ align-items: center;
+
+ > *:not(:first-child) {
+ margin-left: _.unit(1);
+ }
+ }
+}
diff --git a/packages/console/src/components/BackLink/index.tsx b/packages/console/src/components/BackLink/index.tsx
new file mode 100644
index 000000000..e85d320e9
--- /dev/null
+++ b/packages/console/src/components/BackLink/index.tsx
@@ -0,0 +1,24 @@
+import classNames from 'classnames';
+import React, { ReactNode } from 'react';
+import { Link } from 'react-router-dom';
+
+import * as buttonStyles from '@/components/TextButton/index.module.scss';
+
+import Back from './Back';
+import * as styles from './index.module.scss';
+
+type Props = {
+ to: string;
+ children: ReactNode;
+};
+
+const BackLink = ({ to, children }: Props) => (
+
+
+
+);
+
+export default BackLink;
diff --git a/packages/console/src/pages/ApplicationDetails/index.module.scss b/packages/console/src/pages/ApplicationDetails/index.module.scss
index 3d4ddc312..38dd451f6 100644
--- a/packages/console/src/pages/ApplicationDetails/index.module.scss
+++ b/packages/console/src/pages/ApplicationDetails/index.module.scss
@@ -6,19 +6,6 @@
}
}
-.button {
- padding-left: 0;
-
- .body {
- display: flex;
- align-items: center;
-
- > *:not(:first-child) {
- margin-left: _.unit(1);
- }
- }
-}
-
.container .header {
padding: _.unit(8);
display: flex;
diff --git a/packages/console/src/pages/ApplicationDetails/index.tsx b/packages/console/src/pages/ApplicationDetails/index.tsx
index 9994bd483..e4fc76f73 100644
--- a/packages/console/src/pages/ApplicationDetails/index.tsx
+++ b/packages/console/src/pages/ApplicationDetails/index.tsx
@@ -1,18 +1,16 @@
import { Application } from '@logto/schemas';
-import classNames from 'classnames';
import React from 'react';
import { useTranslation } from 'react-i18next';
-import { Link, useParams } from 'react-router-dom';
+import { useParams } from 'react-router-dom';
import useSWR from 'swr';
+import BackLink from '@/components/BackLink';
import Card from '@/components/Card';
import CopyToClipboard from '@/components/CopyToClipboard';
import ImagePlaceholder from '@/components/ImagePlaceholder';
-import * as buttonStyles from '@/components/TextButton/index.module.scss';
import { RequestError } from '@/swr';
import { applicationTypeI18nKey } from '@/types/applications';
-import Back from './icons/Back';
import * as styles from './index.module.scss';
const ApplicationDetails = () => {
@@ -23,12 +21,7 @@ const ApplicationDetails = () => {
return (
-
-
-
-
{t('application_details.back_to_applications')}
-
-
+
{t('application_details.back_to_applications')}
{isLoading &&
loading
}
{error &&
{`error occurred: ${error.metadata.code}`}
}
{data && (
diff --git a/packages/console/src/pages/ConnectorDetails/index.module.scss b/packages/console/src/pages/ConnectorDetails/index.module.scss
new file mode 100644
index 000000000..29be84eb2
--- /dev/null
+++ b/packages/console/src/pages/ConnectorDetails/index.module.scss
@@ -0,0 +1,51 @@
+@use '@/scss/underscore' as _;
+
+.container {
+ > *:not(:first-child) {
+ margin-top: _.unit(4);
+ }
+}
+
+.container .header {
+ padding: _.unit(8);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+
+ > *:not(:first-child) {
+ margin-left: _.unit(6);
+ }
+
+ .logo {
+ width: _.unit(19);
+ height: _.unit(19);
+ border-radius: _.unit(4);
+ }
+
+ .metadata {
+ flex: 1;
+
+ > div {
+ display: flex;
+ align-items: center;
+
+ &:not(:first-child) {
+ margin-top: _.unit(2);
+ }
+
+ > *:not(:first-child) {
+ margin-left: _.unit(2);
+ }
+ }
+
+ .name {
+ font: var(--font-title-large);
+ color: var(--color-component-text);
+ }
+
+ .id {
+ font: var(--font-subhead-2);
+ color: var(--color-component-caption);
+ }
+ }
+}
diff --git a/packages/console/src/pages/ConnectorDetails/index.tsx b/packages/console/src/pages/ConnectorDetails/index.tsx
new file mode 100644
index 000000000..ffcfc9f34
--- /dev/null
+++ b/packages/console/src/pages/ConnectorDetails/index.tsx
@@ -0,0 +1,58 @@
+import { ConnectorDTO } from '@logto/schemas';
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+import { useParams } from 'react-router-dom';
+import useSWR from 'swr';
+
+import BackLink from '@/components/BackLink';
+import Card from '@/components/Card';
+import ImagePlaceholder from '@/components/ImagePlaceholder';
+import Status from '@/components/Status';
+import { RequestError } from '@/swr';
+
+import * as styles from './index.module.scss';
+
+const ConnectorDetails = () => {
+ const { connectorId } = useParams();
+ const {
+ t,
+ i18n: { language },
+ } = useTranslation(undefined, { keyPrefix: 'admin_console' });
+ const { data, error } = useSWR
(
+ connectorId && `/api/connectors/${connectorId}`
+ );
+ const isLoading = !data && !error;
+
+ return (
+
+
{t('connector_details.back_to_connectors')}
+ {isLoading &&
loading
}
+ {error &&
{`error occurred: ${error.metadata.code}`}
}
+ {data && (
+
+ {data.metadata.logo.startsWith('http') ? (
+
+ ) : (
+
+ )}
+
+
+
{data.metadata.name[language]}
+
{data.id}
+
+
+
+ {t('connectors.connector_status', {
+ context: data.enabled ? 'enabled' : 'disabled',
+ })}
+
+
+
+ action
+
+ )}
+
+ );
+};
+
+export default ConnectorDetails;
diff --git a/packages/console/src/pages/Connectors/Connector.tsx b/packages/console/src/pages/Connectors/Connector.tsx
deleted file mode 100644
index d6f727215..000000000
--- a/packages/console/src/pages/Connectors/Connector.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { ConnectorDTO } from '@logto/schemas';
-import React from 'react';
-import { useParams } from 'react-router-dom';
-import useSWR from 'swr';
-
-import Card from '@/components/Card';
-import { RequestError } from '@/swr';
-
-const Connector = () => {
- const { connectorId } = useParams();
- const { data, error } = useSWR(
- connectorId && `/api/connectors/${connectorId}`
- );
- const isLoading = !data && !error;
-
- return (
-
- {isLoading && 'loading'}
- {error && error}
-
- );
-};
-
-export default Connector;
diff --git a/packages/phrases/src/locales/en.ts b/packages/phrases/src/locales/en.ts
index 49ade6af3..f23290f90 100644
--- a/packages/phrases/src/locales/en.ts
+++ b/packages/phrases/src/locales/en.ts
@@ -101,6 +101,9 @@ const translation = {
application_details: {
back_to_applications: 'Back to Applications',
},
+ connector_details: {
+ back_to_connectors: 'Back to Connectors',
+ },
},
};
diff --git a/packages/phrases/src/locales/zh-cn.ts b/packages/phrases/src/locales/zh-cn.ts
index cd341d20f..94cdd3b57 100644
--- a/packages/phrases/src/locales/zh-cn.ts
+++ b/packages/phrases/src/locales/zh-cn.ts
@@ -103,6 +103,9 @@ const translation = {
application_details: {
back_to_applications: '返回应用集',
},
+ connector_details: {
+ back_to_connectors: '返回连接器',
+ },
},
};