@nextjscms/plugin-cpanel-dashboard 2.1.21 → 2.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/DashboardPage.d.ts.map +1 -1
- package/dist/client/DashboardPage.js +11 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +14 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -9
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardPage.d.ts","sourceRoot":"","sources":["../../src/client/DashboardPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DashboardPage.d.ts","sourceRoot":"","sources":["../../src/client/DashboardPage.tsx"],"names":[],"mappings":"AA+BA,KAAK,wBAAwB,GAAG;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,WAAW,wBAAwB,4CAgPtE,CAAA;AAiGD,eAAe,mBAAmB,CAAA"}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { humanReadableFileSize } from 'nextjs-cms/utils';
|
|
4
|
-
import {
|
|
4
|
+
import { usePluginTRPC } from 'nextjs-cms/plugins/client';
|
|
5
5
|
import { useI18n } from 'nextjs-cms/translations/client';
|
|
6
6
|
// import { LucideIcon } from 'lucide-react'
|
|
7
|
-
import { HardDriveIcon, NetworkIcon, MailIcon, DatabaseIcon, ServerIcon, FolderIcon, HexagonIcon, PackageIcon } from 'lucide-react';
|
|
7
|
+
import { HardDriveIcon, NetworkIcon, MailIcon, DatabaseIcon, ServerIcon, FolderIcon, HexagonIcon, PackageIcon, } from 'lucide-react';
|
|
8
8
|
export const CpanelDashboardPage = ({ title }) => {
|
|
9
9
|
const t = useI18n();
|
|
10
|
-
const trpc =
|
|
10
|
+
const trpc = usePluginTRPC();
|
|
11
11
|
const query = trpc?.cpanelDashboard?.getData.useQuery;
|
|
12
12
|
const { data, isLoading, isError, error } = query ? query() : { isLoading: true, isError: true, error: null };
|
|
13
13
|
if (!query) {
|
|
14
|
-
return (_jsx("div", { className: 'flex min-h-[200px] items-center justify-center p-6', children: _jsx("div", { className: '
|
|
14
|
+
return (_jsx("div", { className: 'flex min-h-[200px] items-center justify-center p-6', children: _jsx("div", { className: 'border-destructive/30 bg-destructive/5 text-destructive rounded-lg border px-6 py-4 text-sm', children: t('cpanelPluginMisconfigured') }) }));
|
|
15
15
|
}
|
|
16
|
-
return (_jsxs("div", { className: 'w-full', children: [_jsx("div", { className: '
|
|
16
|
+
return (_jsxs("div", { className: 'w-full', children: [_jsx("div", { className: 'text-foreground bg-orange-500 p-8 font-extrabold dark:bg-orange-800', children: _jsx("div", { className: 'relative', children: _jsx("h1", { className: 'text-3xl font-bold tracking-tight text-white', children: title || t('cPanelDashboard') }) }) }), _jsxs("div", { className: 'flex flex-col gap-6 p-6', children: [isLoading && (_jsx("div", { className: 'md-sidebar:grid-cols-2 2xl-sidebar:grid-cols-4 grid grid-cols-1 gap-4', children: [...Array(4)].map((_, i) => (_jsxs("div", { className: 'bg-card animate-pulse rounded-xl border p-5', children: [_jsxs("div", { className: 'mb-4 flex items-center gap-3', children: [_jsx("div", { className: 'bg-muted size-10 rounded-lg' }), _jsx("div", { className: 'bg-muted h-4 w-24 rounded' })] }), _jsx("div", { className: 'bg-muted mb-2 h-8 w-20 rounded' }), _jsx("div", { className: 'bg-muted h-2 rounded-full' })] }, i))) })), isError && !isLoading && (_jsxs("div", { className: 'border-destructive/30 bg-destructive/5 flex items-center gap-3 rounded-lg border p-4', children: [_jsx("div", { className: 'bg-destructive/10 flex size-10 shrink-0 items-center justify-center rounded-full', children: _jsx("svg", { className: 'text-destructive size-5', fill: 'none', stroke: 'currentColor', viewBox: '0 0 24 24', children: _jsx("path", { strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: 2, d: 'M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z' }) }) }), _jsxs("div", { children: [_jsx("p", { className: 'text-destructive font-medium', children: t('unableToLoadCpanelData') }), error instanceof Error && (_jsx("p", { className: 'text-destructive/80 mt-0.5 text-sm', children: error.message }))] })] })), data && (_jsxs(_Fragment, { children: [_jsxs("div", { className: 'md-sidebar:grid-cols-2 2xl-sidebar:grid-cols-4 grid grid-cols-1 gap-4', children: [_jsx(StatCard, { icon: _jsx(HardDriveIcon, { color: 'blue' }), title: t('diskSpace'), used: data.diskSpaceUsage, total: data.diskSpaceLimit, formatFn: humanReadableFileSize }), _jsx(StatCard, { icon: _jsx(NetworkIcon, { color: 'green' }), title: t('thisMothBandwidth'), used: data.bandwidthUsage, total: data.bandwidthLimit, formatFn: humanReadableFileSize }), _jsx(StatCard, { icon: _jsx(MailIcon, { color: 'red' }), title: t('emailAccounts'), used: data.emailsUsage, total: data.emailsLimit }), _jsx(StatCard, { icon: _jsx(DatabaseIcon, { color: 'purple' }), title: t('mysqlDatabases'), used: data.dbsCount, total: data.dbsLimit })] }), _jsxs("div", { className: 'lg-sidebar:grid-cols-2 grid grid-cols-1 gap-6', children: [_jsxs("div", { className: 'bg-card overflow-hidden rounded-xl border shadow-sm', children: [_jsxs("div", { className: 'flex items-center gap-3 border-b bg-gradient-to-r from-cyan-500/10 via-transparent to-transparent px-6 py-5', children: [_jsx("div", { className: 'flex size-10 items-center justify-center rounded-xl bg-cyan-500/15 text-cyan-600 dark:bg-cyan-500/20 dark:text-cyan-400', children: _jsx(ServerIcon, {}) }), _jsx("h2", { className: 'text-card-foreground text-lg font-semibold', children: t('accountInformation') })] }), _jsxs("div", { className: 'divide-y p-2', children: [_jsx(InfoRow, { icon: _jsx(HexagonIcon, {}), iconColor: 'text-green-800', label: t('nodeVersion'), value: data?.nodeVersion ?? 'N/A', valueColor: 'text-green-600 dark:text-green-400' }), _jsx(InfoRow, { icon: _jsx(PackageIcon, {}), iconColor: 'text-red-800', label: t('pnpmVersion'), value: data?.pnpmVersion ?? 'N/A', valueColor: 'text-green-600 dark:text-green-400' }), _jsx(InfoRow, { icon: _jsx(PackageIcon, {}), iconColor: 'text-red-800', label: t('npmVersion'), value: data?.npmVersion ?? 'N/A', valueColor: 'text-green-600 dark:text-green-400' }), _jsx(InfoRow, { icon: _jsx(PackageIcon, {}), iconColor: 'text-red-800', label: t('bunVersion'), value: data?.bunVersion ?? 'N/A', valueColor: 'text-green-600 dark:text-green-400' }), _jsx(InfoRow, { icon: _jsx("span", { className: 'font-mono text-xs font-bold text-indigo-600 dark:text-indigo-400', children: "PHP" }), label: t('phpVersion'), value: data?.phpVersion ?? 'N/A', valueColor: 'text-indigo-600 dark:text-indigo-400' }), _jsx(InfoRow, { icon: _jsx(FolderIcon, {}), iconColor: 'text-amber-500', label: t('documentRoot'), value: data?.documentRoot ?? 'N/A', mono: true })] })] }), _jsxs("div", { className: 'bg-card overflow-hidden rounded-xl border shadow-sm', children: [_jsxs("div", { className: 'flex items-center gap-3 border-b bg-gradient-to-r from-purple-500/10 via-transparent to-transparent px-6 py-5', children: [_jsx("div", { className: 'flex size-10 items-center justify-center rounded-xl bg-purple-500/15 text-purple-600 dark:bg-purple-500/20 dark:text-purple-400', children: _jsx(DatabaseIcon, {}) }), _jsx("h2", { className: 'text-card-foreground text-lg font-semibold', children: t('database') })] }), data?.dbInfo ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: 'divide-y border-b p-2', children: [_jsx(InfoRow, { label: t('version'), value: data.dbInfo.version, valueColor: 'text-purple-600 dark:text-purple-400 font-semibold' }), _jsx(InfoRow, { label: t('remote'), value: _jsx("span", { className: `inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold ${data.dbInfo.is_remote ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-400' : 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-400'}`, children: data.dbInfo.is_remote ? t('yes') : t('no') }) })] }), data?.dbsList?.length > 0 && (_jsxs("div", { className: 'p-4', children: [_jsxs("p", { className: 'mb-4 text-xs font-semibold tracking-wider text-purple-600 uppercase dark:text-purple-400', children: [t('databases'), " (", data.dbsList.length, ")"] }), _jsx("div", { className: 'space-y-3', children: data.dbsList.map((db, index) => (_jsxs("div", { className: 'flex items-center justify-between rounded-xl border border-purple-200/50 bg-gradient-to-r from-purple-50 to-transparent p-4 transition-all hover:border-purple-300 hover:shadow-sm dark:border-purple-800/30 dark:from-purple-900/20 dark:hover:border-purple-700', children: [_jsxs("div", { className: 'flex items-center gap-3', children: [_jsx("div", { className: 'flex size-10 items-center justify-center rounded-lg bg-purple-500/15 text-purple-600 dark:bg-purple-500/25 dark:text-purple-400', children: _jsx(DatabaseIcon, {}) }), _jsxs("div", { children: [_jsx("p", { className: 'text-card-foreground font-semibold', children: db.database }), _jsxs("p", { className: 'text-muted-foreground text-xs', children: [db.users?.length ?? 0, " ", t('users')] })] })] }), _jsxs("div", { className: 'text-right', children: [_jsx("p", { className: 'text-sm font-bold text-purple-600 dark:text-purple-400', children: humanReadableFileSize(db.disk_usage) }), _jsx("p", { className: 'text-muted-foreground text-xs', children: t('diskUsage') })] })] }, `${db.name}_${db.database}_${index}`))) })] }))] })) : (_jsx("div", { className: 'text-muted-foreground flex items-center justify-center py-12 text-sm', children: t('mysqlNotInstalled') }))] })] })] }))] })] }));
|
|
17
17
|
};
|
|
18
18
|
const StatCard = ({ icon, title, used, total, formatFn }) => {
|
|
19
19
|
const t = useI18n();
|
|
@@ -28,7 +28,11 @@ const StatCard = ({ icon, title, used, total, formatFn }) => {
|
|
|
28
28
|
return 'bg-yellow-500';
|
|
29
29
|
return 'bg-green-500';
|
|
30
30
|
};
|
|
31
|
-
return (_jsx("div", { className: `group relative overflow-hidden rounded-xl border border-l-4
|
|
31
|
+
return (_jsx("div", { className: `group bg-card relative overflow-hidden rounded-xl border border-l-4 p-6 shadow-sm transition-all hover:shadow-lg`, children: _jsxs("div", { className: 'relative flex flex-col', children: [_jsxs("div", { className: 'mb-4 flex items-center justify-between', children: [_jsx("span", { className: 'text-muted-foreground text-sm font-medium', children: title }), _jsx("div", { className: `flex size-11 items-center justify-center rounded-xl`, children: icon })] }), _jsxs("div", { className: 'mb-4 flex w-full content-end items-end justify-start gap-2 text-start', children: [_jsx("span", { dir: 'ltr', className: 'text-card-foreground text-3xl font-bold tracking-tight', children: displayUsed }), _jsx("span", { children: "/" }), _jsxs("span", { dir: 'ltr', className: 'text-muted-foreground text-sm', children: [' ', displayTotal] })] }), _jsx("div", { className: 'bg-muted/50 h-2.5 overflow-hidden rounded-full', children: _jsx("div", { className: `h-full rounded-full transition-all duration-500 ${getProgressColor()}`, style: { width: `${percentage}%` } }) }), _jsxs("div", { className: 'text-muted-foreground flex flex-row gap-2 pt-3 text-xs font-medium', children: [_jsxs("span", { className: percentage >= 75
|
|
32
|
+
? 'text-amber-600 dark:text-amber-400'
|
|
33
|
+
: percentage >= 90
|
|
34
|
+
? 'text-red-600 dark:text-red-400'
|
|
35
|
+
: '', children: [percentage.toFixed(1), "%"] }), _jsx("span", { children: t('usedLabel') })] })] }) }));
|
|
32
36
|
};
|
|
33
|
-
const InfoRow = ({ icon, iconColor, label, value, valueColor, mono }) => (_jsxs("div", { className: 'flex items-center justify-between rounded-lg px-4 py-4 transition-colors
|
|
37
|
+
const InfoRow = ({ icon, iconColor, label, value, valueColor, mono }) => (_jsxs("div", { className: 'hover:bg-muted/30 flex items-center justify-between rounded-lg px-4 py-4 transition-colors', children: [_jsxs("div", { className: 'text-muted-foreground flex items-center gap-3 text-sm', children: [icon && _jsx("span", { className: iconColor || 'text-muted-foreground/70', children: icon }), _jsx("span", { className: 'font-medium', children: label })] }), _jsx("span", { className: `text-sm ${valueColor || 'text-card-foreground'} ${mono ? 'font-mono text-xs' : 'font-medium'}`, children: value })] }));
|
|
34
38
|
export default CpanelDashboardPage;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,qBAAqB,CAAA;AAC9C,wBAAgB,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,qBAAqB,CAAA;AAC9C,wBAAgB,YAAY,6DAa3B"}
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import { definePlugin } from 'nextjs-cms/plugins/
|
|
1
|
+
import { definePlugin } from 'nextjs-cms/plugins/define';
|
|
2
2
|
import { cpanelDashboardRouter } from './router.js';
|
|
3
3
|
export const PLUGIN_TITLE = 'cPanel Dashboard';
|
|
4
4
|
export function createPlugin() {
|
|
5
5
|
return definePlugin({
|
|
6
6
|
title: PLUGIN_TITLE,
|
|
7
|
-
name: 'plugin_cpanel_dashboard',
|
|
8
|
-
registryName: 'cpanel-dashboard',
|
|
9
7
|
router: cpanelDashboardRouter,
|
|
10
8
|
routes: [
|
|
11
9
|
{
|
|
12
10
|
path: '/cpanel-dashboard',
|
|
13
11
|
title: PLUGIN_TITLE,
|
|
14
12
|
icon: 'home',
|
|
13
|
+
prefetch: 'cpanelDashboard.getData',
|
|
15
14
|
},
|
|
16
15
|
],
|
|
17
16
|
});
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAuDA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;gBAWU,CAAC;iBAEpC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8ER,CAAA"}
|
package/dist/router.js
CHANGED
|
@@ -2,7 +2,9 @@ import { TRPCError } from '@trpc/server';
|
|
|
2
2
|
import { execSync } from 'child_process';
|
|
3
3
|
import getString from 'nextjs-cms/translations';
|
|
4
4
|
import { CpanelAPI } from 'nextjs-cms/utils';
|
|
5
|
-
import { pluginProcedure, router } from 'nextjs-cms/api/
|
|
5
|
+
import { pluginProcedure, router } from 'nextjs-cms/api/plugin';
|
|
6
|
+
import { extractPluginName } from 'nextjs-cms/plugins/derive';
|
|
7
|
+
const PLUGIN_NAME = extractPluginName(import.meta.url);
|
|
6
8
|
const getNodeVersion = () => {
|
|
7
9
|
try {
|
|
8
10
|
const version = execSync('node -v', { encoding: 'utf-8' }).trim();
|
|
@@ -21,9 +23,18 @@ const getPnpmVersion = () => {
|
|
|
21
23
|
return null;
|
|
22
24
|
}
|
|
23
25
|
};
|
|
26
|
+
const cleanNpmEnv = () => {
|
|
27
|
+
const env = { ...process.env };
|
|
28
|
+
for (const key of Object.keys(env)) {
|
|
29
|
+
if (key.startsWith('npm_config_') || key === 'npm_package_json') {
|
|
30
|
+
delete env[key];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return env;
|
|
34
|
+
};
|
|
24
35
|
const getNpmVersion = () => {
|
|
25
36
|
try {
|
|
26
|
-
const version = execSync('npm -v', { encoding: 'utf-8' }).trim();
|
|
37
|
+
const version = execSync('npm -v', { encoding: 'utf-8', env: cleanNpmEnv() }).trim();
|
|
27
38
|
return version; // Returns something like "10.10.0"
|
|
28
39
|
}
|
|
29
40
|
catch {
|
|
@@ -40,7 +51,7 @@ const getBunVersion = () => {
|
|
|
40
51
|
}
|
|
41
52
|
};
|
|
42
53
|
export const cpanelDashboardRouter = router({
|
|
43
|
-
getData: pluginProcedure(
|
|
54
|
+
getData: pluginProcedure(PLUGIN_NAME).query(async ({ ctx }) => {
|
|
44
55
|
if (!process.env.CPANEL_USER || !process.env.CPANEL_PASSWORD || !process.env.CPANEL_DOMAIN) {
|
|
45
56
|
throw new TRPCError({
|
|
46
57
|
code: 'BAD_REQUEST',
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.tsx"],"names":[],"mappings":"AAMA,wBAA8B,qBAAqB,qDAWlD"}
|
package/dist/server.js
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { api, HydrateClient } from 'nextjs-cms/api/trpc/server';
|
|
3
2
|
import { CpanelDashboardPage } from './client/DashboardPage.js';
|
|
4
3
|
import { findPluginRouteByPath } from 'nextjs-cms/plugins/server';
|
|
5
4
|
import { resolveMultilingualString, resolveLanguage } from 'nextjs-cms/translations';
|
|
6
5
|
import { getCMSConfig } from 'nextjs-cms/core';
|
|
7
6
|
import auth from 'nextjs-cms/auth';
|
|
8
7
|
export default async function CpanelDashboardServer() {
|
|
9
|
-
const helpers = api;
|
|
10
|
-
const prefetch = helpers.cpanelDashboard?.getData?.prefetch;
|
|
11
|
-
if (!prefetch) {
|
|
12
|
-
throw new Error('[cpanel-dashboard] Missing cpanelDashboard.getData prefetch helper.');
|
|
13
|
-
}
|
|
14
|
-
await prefetch();
|
|
15
|
-
// Resolve the plugin route title
|
|
16
8
|
const [route, session, config] = await Promise.all([
|
|
17
9
|
findPluginRouteByPath('/cpanel-dashboard'),
|
|
18
10
|
auth(),
|
|
@@ -21,5 +13,5 @@ export default async function CpanelDashboardServer() {
|
|
|
21
13
|
const { supportedLanguages, fallbackLanguage } = config.i18n;
|
|
22
14
|
const language = resolveLanguage(session?.user?.language, supportedLanguages, fallbackLanguage);
|
|
23
15
|
const resolvedTitle = route ? resolveMultilingualString(route.title, language, fallbackLanguage) : '';
|
|
24
|
-
return
|
|
16
|
+
return _jsx(CpanelDashboardPage, { title: resolvedTitle });
|
|
25
17
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextjscms/plugin-cpanel-dashboard",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.23",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"lucide-react": "^0.563.0",
|
|
28
28
|
"react": "19.2.3",
|
|
29
29
|
"react-dom": "19.2.3",
|
|
30
|
-
"nextjs-cms": "0.9.
|
|
30
|
+
"nextjs-cms": "0.9.23"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/react": "^19.2.7",
|