Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/locales/en/remnawave.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"response-rules": "Response Rules",
"remnawave-settings": "Remnawave Settings",
"node-plugins": "Plugins",
"certificates": "Certificates",
"tb-reports": "Torrent Blocker Reports",
"sessions-explorer": "Sessions Explorer",
"http-stats": "HTTP Stats"
Expand Down
1 change: 1 addition & 0 deletions public/locales/fa/remnawave.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"response-rules": "قوانین پاسخ",
"remnawave-settings": "تنظیمات Remnawave",
"node-plugins": "Plugins",
"certificates": "گواهی‌ها",
"tb-reports": "Torrent Blocker Reports",
"sessions-explorer": "Sessions Explorer",
"http-stats": "HTTP Stats"
Expand Down
1 change: 1 addition & 0 deletions public/locales/ru/remnawave.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"response-rules": "Правила ответов",
"remnawave-settings": "Настройки Remnawave",
"node-plugins": "Плагины",
"certificates": "Сертификаты",
"tb-reports": "Torrent Blocker Reports",
"sessions-explorer": "Обозреватель сессий",
"http-stats": "HTTP Статистика"
Expand Down
1 change: 1 addition & 0 deletions public/locales/zh/remnawave.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"response-rules": "请求订阅的应用",
"remnawave-settings": "Remnawave 设置",
"node-plugins": "插件",
"certificates": "证书",
"tb-reports": "Torrent 屏蔽报告",
"sessions-explorer": "会话管理器",
"http-stats": "HTTP 状态"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { HiChartPie, HiServer } from 'react-icons/hi'
import { PiArrowsInCardinalFill, PiChartLine, PiListChecks, PiUsers } from 'react-icons/pi'
import {
TbApi,
TbCertificate,
TbCirclesRelation,
TbCreditCard,
TbDeviceAnalytics,
Expand Down Expand Up @@ -84,6 +85,12 @@ export const useDesktopMenuSections = (): MenuItem[] => {
icon: TbPackage,
id: 'node-plugins'
},
{
name: t('constants.certificates'),
href: ROUTES.DASHBOARD.MANAGEMENT.ACME,
icon: TbCertificate,
id: 'acme-certificates'
},
{
name: t('constants.nodes-statistics'),
href: ROUTES.DASHBOARD.MANAGEMENT.NODES_STATS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from 'react-icons/pi'
import {
TbApi,
TbCertificate,
TbCirclesRelation,
TbCreditCard,
TbDeviceAnalytics,
Expand Down Expand Up @@ -98,6 +99,12 @@ export const useMobileMenuSections = (): MenuItem[] => {
icon: TbPackage,
id: 'node-plugins'
},
{
name: t('constants.certificates'),
href: ROUTES.DASHBOARD.MANAGEMENT.ACME,
icon: TbCertificate,
id: 'acme-certificates'
},

{
name: t('constants.nodes-statistics'),
Expand Down
6 changes: 6 additions & 0 deletions src/app/router/router.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { LoginPage } from '@pages/auth/login'
import { Oauth2CallbackPage } from '@pages/auth/oauth2-callback/oauth2-callback.page'
import { AcmePageConnector } from '@pages/dashboard/acme/ui/connectors/acme-page.connector'
import { ConfigProfilesPageConnector } from '@pages/dashboard/config-profiles/connectors'
import { ConfigProfileByUuidPageConnector } from '@pages/dashboard/config-profiles/connectors/config-profile-by-uuid.page.connector'
import { InfraBillingPageConnector } from '@pages/dashboard/crm/infra-billing/connectors/infra-billing.page.connector'
Expand Down Expand Up @@ -115,6 +116,11 @@ const router = createBrowserRouter(
path={ROUTES.DASHBOARD.MANAGEMENT.REMNAWAVE_SETTINGS}
/>

<Route
element={<AcmePageConnector />}
path={ROUTES.DASHBOARD.MANAGEMENT.ACME}
/>

<Route path={ROUTES.DASHBOARD.MANAGEMENT.NODE_PLUGINS.ROOT}>
<Route element={<NodePluginsBasePageConnector />} index />

Expand Down
61 changes: 61 additions & 0 deletions src/pages/dashboard/acme/ui/components/acme-page.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Tabs } from '@mantine/core'
import { GetNodesCommand } from '@remnawave/backend-contract'
import { AcmeCertificatesListWidget } from '@widgets/dashboard/acme/certificates-list/certificates-list.widget'
import { AcmeCredentialsGridWidget } from '@widgets/dashboard/acme/credentials-grid/credentials-grid.widget'
import { motion } from 'motion/react'
import { useTranslation } from 'react-i18next'
import { TbCertificate, TbKey } from 'react-icons/tb'
import { z } from 'zod'

import { AcmeCertificateSchema, AcmeCredentialSchema } from '@shared/api/contracts/acme.contract'
import { Page, PageHeaderShared } from '@shared/ui'

interface Props {
certificates: z.infer<typeof AcmeCertificateSchema>[]
credentials: z.infer<typeof AcmeCredentialSchema>[]
nodes: GetNodesCommand.Response['response']
}

export const AcmePageComponent = (props: Props) => {
const { certificates, credentials, nodes } = props

const { t } = useTranslation()

return (
<Page title={t('constants.certificates')}>
<PageHeaderShared
icon={<TbCertificate size={24} />}
title={t('constants.certificates')}
/>

<motion.div
animate={{ opacity: 1 }}
initial={{ opacity: 0 }}
transition={{ duration: 0.4 }}
>
<Tabs defaultValue="certificates" keepMounted={false}>
<Tabs.List mb="md">
<Tabs.Tab leftSection={<TbCertificate size={16} />} value="certificates">
Certificates
</Tabs.Tab>
<Tabs.Tab leftSection={<TbKey size={16} />} value="credentials">
Credentials
</Tabs.Tab>
</Tabs.List>

<Tabs.Panel value="certificates">
<AcmeCertificatesListWidget
certificates={certificates}
credentials={credentials}
nodes={nodes}
/>
</Tabs.Panel>

<Tabs.Panel value="credentials">
<AcmeCredentialsGridWidget credentials={credentials} />
</Tabs.Panel>
</Tabs>
</motion.div>
</Page>
)
}
29 changes: 29 additions & 0 deletions src/pages/dashboard/acme/ui/connectors/acme-page.connector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useGetAcmeCertificates, useGetAcmeCredentials, useGetNodes } from '@shared/api/hooks'
import { LoadingScreen } from '@shared/ui'

import { AcmePageComponent } from '../components/acme-page.component'

export function AcmePageConnector() {
const { data: credentials, isLoading: isCredentialsLoading } = useGetAcmeCredentials({})
const { data: certificates, isLoading: isCertificatesLoading } = useGetAcmeCertificates({})
const { data: nodes, isLoading: isNodesLoading } = useGetNodes()

if (
isCredentialsLoading ||
isCertificatesLoading ||
isNodesLoading ||
!credentials ||
!certificates ||
!nodes
) {
return <LoadingScreen text="Loading certificates..." />
}

return (
<AcmePageComponent
certificates={certificates.certificates}
credentials={credentials.credentials}
nodes={nodes}
/>
)
}
Loading