mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-08 04:55:17 +00:00
Refactor License Key Settings UI: Simplify conditional rendering for license key management, update contact link to the official site, and enhance user feedback with improved loading states for activation and validation processes.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Key, Loader2 } from "lucide-react";
|
import { Key, Loader2, ShieldCheck } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
@@ -50,34 +50,36 @@ export function LicenseKeySettings() {
|
|||||||
<CardTitle className="text-xl">License Key</CardTitle>
|
<CardTitle className="text-xl">License Key</CardTitle>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
{enabled && (
|
||||||
<span className="text-xs text-muted-foreground">
|
<div className="flex items-center gap-2">
|
||||||
{enabled ? "Enabled" : "Disabled"}
|
<span className="text-xs text-muted-foreground">
|
||||||
</span>
|
{enabled ? "Enabled" : "Disabled"}
|
||||||
<Switch
|
</span>
|
||||||
checked={enabled}
|
<Switch
|
||||||
disabled={isLoading || isSaving || isDeactivating}
|
checked={enabled}
|
||||||
onCheckedChange={async (next) => {
|
disabled={isLoading || isSaving || isDeactivating}
|
||||||
try {
|
onCheckedChange={async (next) => {
|
||||||
await updateEnterpriseSettings({
|
try {
|
||||||
enableEnterpriseFeatures: next,
|
await updateEnterpriseSettings({
|
||||||
});
|
enableEnterpriseFeatures: next,
|
||||||
await utils.licenseKey.getEnterpriseSettings.invalidate();
|
});
|
||||||
toast.success("Enterprise features updated");
|
await utils.licenseKey.getEnterpriseSettings.invalidate();
|
||||||
} catch (error) {
|
toast.success("Enterprise features updated");
|
||||||
console.error(error);
|
} catch (error) {
|
||||||
toast.error("Failed to update enterprise features");
|
console.error(error);
|
||||||
}
|
toast.error("Failed to update enterprise features");
|
||||||
}}
|
}
|
||||||
/>
|
}}
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
To unlock extra features you need an enterprise license key.
|
To unlock extra features you need an enterprise license key.
|
||||||
Contact us{" "}
|
Contact us{" "}
|
||||||
<Link
|
<Link
|
||||||
href="http://localhost:3001/contact"
|
href="https://dokploy.com/contact"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="underline underline-offset-4"
|
className="underline underline-offset-4"
|
||||||
@@ -87,104 +89,142 @@ export function LicenseKeySettings() {
|
|||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{enabled && (
|
{enabled ? (
|
||||||
<div className="grid gap-3 md:grid-cols-[1fr_auto] md:items-end">
|
<>
|
||||||
<div className="space-y-2">
|
<div className="grid gap-3 md:grid-cols-[1fr_auto] md:items-end">
|
||||||
<label className="text-sm font-medium" htmlFor="licenseKey">
|
<div className="space-y-2">
|
||||||
License Key
|
<label className="text-sm font-medium" htmlFor="licenseKey">
|
||||||
</label>
|
License Key
|
||||||
<Input
|
</label>
|
||||||
id="licenseKey"
|
<Input
|
||||||
placeholder="Enter your enterprise license key"
|
id="licenseKey"
|
||||||
value={licenseKey}
|
placeholder="Enter your enterprise license key"
|
||||||
onChange={(e) => setLicenseKey(e.target.value)}
|
value={licenseKey}
|
||||||
/>
|
onChange={(e) => setLicenseKey(e.target.value)}
|
||||||
</div>
|
/>
|
||||||
<div className="md:justify-self-end flex gap-2">
|
</div>
|
||||||
{haveValidLicenseKey && (
|
<div className="md:justify-self-end flex gap-2">
|
||||||
<DialogAction
|
{haveValidLicenseKey && (
|
||||||
title="Deactivate License Key"
|
<DialogAction
|
||||||
description="Are you sure you want to deactivate this license key? This will disable enterprise features."
|
title="Deactivate License Key"
|
||||||
onClick={async () => {
|
description="Are you sure you want to deactivate this license key? This will disable enterprise features."
|
||||||
try {
|
onClick={async () => {
|
||||||
await deactivateLicenseKey();
|
try {
|
||||||
await utils.licenseKey.getEnterpriseSettings.invalidate();
|
await deactivateLicenseKey();
|
||||||
await utils.licenseKey.haveValidLicenseKey.invalidate();
|
await utils.licenseKey.getEnterpriseSettings.invalidate();
|
||||||
toast.success("License key deactivated");
|
await utils.licenseKey.haveValidLicenseKey.invalidate();
|
||||||
} catch (error) {
|
toast.success("License key deactivated");
|
||||||
console.error(error);
|
} catch (error) {
|
||||||
toast.error(
|
console.error(error);
|
||||||
error instanceof Error
|
toast.error(
|
||||||
? error.message
|
error instanceof Error
|
||||||
: "Failed to deactivate license key",
|
? error.message
|
||||||
);
|
: "Failed to deactivate license key",
|
||||||
}
|
);
|
||||||
}}
|
|
||||||
disabled={isDeactivating || !haveValidLicenseKey}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant="destructive"
|
|
||||||
disabled={isDeactivating || !haveValidLicenseKey}
|
|
||||||
isLoading={isDeactivating}
|
|
||||||
>
|
|
||||||
Deactivate
|
|
||||||
</Button>
|
|
||||||
</DialogAction>
|
|
||||||
)}
|
|
||||||
{haveValidLicenseKey && (
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
disabled={
|
|
||||||
isSaving || isCheckingLicenseKey || isDeactivating
|
|
||||||
}
|
|
||||||
isLoading={isValidating}
|
|
||||||
onClick={async () => {
|
|
||||||
try {
|
|
||||||
const valid = await validateLicenseKey({ licenseKey });
|
|
||||||
console.log("valid", valid);
|
|
||||||
if (valid) {
|
|
||||||
toast.success("License key is valid");
|
|
||||||
} else {
|
|
||||||
toast.error("License key is invalid");
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
}}
|
||||||
console.error(error);
|
disabled={isDeactivating || !haveValidLicenseKey}
|
||||||
toast.error(
|
>
|
||||||
error instanceof Error
|
<Button
|
||||||
? error.message
|
variant="destructive"
|
||||||
: "Failed to validate license key",
|
disabled={isDeactivating || !haveValidLicenseKey}
|
||||||
);
|
isLoading={isDeactivating}
|
||||||
|
>
|
||||||
|
Deactivate
|
||||||
|
</Button>
|
||||||
|
</DialogAction>
|
||||||
|
)}
|
||||||
|
{haveValidLicenseKey && (
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
disabled={
|
||||||
|
isSaving || isCheckingLicenseKey || isDeactivating
|
||||||
}
|
}
|
||||||
}}
|
isLoading={isValidating}
|
||||||
>
|
onClick={async () => {
|
||||||
Validate
|
try {
|
||||||
</Button>
|
const valid = await validateLicenseKey({
|
||||||
)}
|
licenseKey,
|
||||||
{!haveValidLicenseKey && (
|
});
|
||||||
<Button
|
console.log("valid", valid);
|
||||||
variant="secondary"
|
if (valid) {
|
||||||
disabled={isSaving || isValidating || isDeactivating}
|
toast.success("License key is valid");
|
||||||
isLoading={isActivating}
|
} else {
|
||||||
onClick={async () => {
|
toast.error("License key is invalid");
|
||||||
try {
|
}
|
||||||
await activateLicenseKey({ licenseKey });
|
} catch (error) {
|
||||||
await utils.licenseKey.getEnterpriseSettings.invalidate();
|
console.error(error);
|
||||||
await utils.licenseKey.haveValidLicenseKey.invalidate();
|
toast.error(
|
||||||
toast.success("License key activated");
|
error instanceof Error
|
||||||
} catch (error) {
|
? error.message
|
||||||
console.error(error);
|
: "Failed to validate license key",
|
||||||
toast.error(
|
);
|
||||||
error instanceof Error
|
}
|
||||||
? error.message
|
}}
|
||||||
: "Failed to activate license key",
|
>
|
||||||
);
|
Validate
|
||||||
}
|
</Button>
|
||||||
}}
|
)}
|
||||||
>
|
{!haveValidLicenseKey && (
|
||||||
Activate
|
<Button
|
||||||
</Button>
|
variant="secondary"
|
||||||
)}
|
disabled={isSaving || isValidating || isDeactivating}
|
||||||
|
isLoading={isActivating}
|
||||||
|
onClick={async () => {
|
||||||
|
try {
|
||||||
|
await activateLicenseKey({ licenseKey });
|
||||||
|
await utils.licenseKey.getEnterpriseSettings.invalidate();
|
||||||
|
await utils.licenseKey.haveValidLicenseKey.invalidate();
|
||||||
|
toast.success("License key activated");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
toast.error(
|
||||||
|
error instanceof Error
|
||||||
|
? error.message
|
||||||
|
: "Failed to activate license key",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Activate
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col items-center gap-4 justify-center min-h-[30vh] text-center">
|
||||||
|
<div className="flex flex-col items-center gap-2 max-w-[400px]">
|
||||||
|
<div className="rounded-full bg-muted p-4">
|
||||||
|
<ShieldCheck className="size-8 text-muted-foreground" />
|
||||||
|
</div>
|
||||||
|
<div className="space-y-1">
|
||||||
|
<h3 className="text-lg font-semibold">Enterprise Features</h3>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Unlock advanced capabilities like SSO, Audit logs,
|
||||||
|
whitelabeling and more.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
onClick={async () => {
|
||||||
|
try {
|
||||||
|
await updateEnterpriseSettings({
|
||||||
|
enableEnterpriseFeatures: true,
|
||||||
|
});
|
||||||
|
await utils.licenseKey.getEnterpriseSettings.invalidate();
|
||||||
|
toast.success("Enterprise features enabled");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
toast.error("Failed to enable enterprise features");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
isLoading={isSaving}
|
||||||
|
disabled={isLoading || isDeactivating}
|
||||||
|
>
|
||||||
|
Enable Enterprise Features
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user