mirror of
https://github.com/Dokploy/website
synced 2025-06-26 18:16:01 +00:00
feat: enhance LicenseCard and ViewLicensePage
This commit is contained in:
@@ -8,49 +8,73 @@ export const SERVER_LICENSE_URL =
|
|||||||
|
|
||||||
const LicenseCard = ({ license, stripeSuscription }: any) => {
|
const LicenseCard = ({ license, stripeSuscription }: any) => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-800 rounded-lg shadow-xl p-6 max-w-2xl mx-auto border border-gray-700">
|
<div className="bg-card backdrop-blur supports-[backdrop-filter]:bg-card/60 rounded-lg shadow-xl p-6 border border-border h-full">
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* License Information Section */}
|
{/* License Information Section */}
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-2xl font-bold text-white mb-4">
|
<h2 className="text-xl font-bold text-foreground mb-4">
|
||||||
License Information
|
License Information
|
||||||
</h2>
|
</h2>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">License ID</p>
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
<p className="text-gray-200">{license.id}</p>
|
License ID
|
||||||
|
</p>
|
||||||
|
<p className="text-foreground">{license.id}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">License Key</p>
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
<p className="text-gray-200 break-all">{license.licenseKey}</p>
|
License Key
|
||||||
|
</p>
|
||||||
|
<p className="text-foreground break-all">{license.licenseKey}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
Activation Status
|
Activation Status
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-200">
|
<p className="text-foreground">
|
||||||
{license.activatedAt ? "Activated" : "Not Activated"}
|
{license.activatedAt ? "Activated" : "Not Activated"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
|
Server IPs
|
||||||
|
</p>
|
||||||
|
{license.serverIps && license.serverIps.length > 0 ? (
|
||||||
|
<div className="space-y-1">
|
||||||
|
{license.serverIps.map((ip: string, index: number) => (
|
||||||
|
<p key={ip} className="text-foreground">
|
||||||
|
{ip}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<p className="text-muted-foreground italic">
|
||||||
|
Not activated on any machine
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
Last Verification
|
Last Verification
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-200">
|
<p className="text-foreground">
|
||||||
{license.lastVerifiedAt || "Not Verified"}
|
{license.lastVerifiedAt || "Not Verified"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">Created At</p>
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
<p className="text-gray-200">
|
Created At
|
||||||
|
</p>
|
||||||
|
<p className="text-foreground">
|
||||||
{new Date(license.createdAt).toLocaleDateString()}
|
{new Date(license.createdAt).toLocaleDateString()}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
Last Updated
|
Last Updated
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-200">
|
<p className="text-foreground">
|
||||||
{new Date(license.updatedAt).toLocaleDateString()}
|
{new Date(license.updatedAt).toLocaleDateString()}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,48 +84,50 @@ const LicenseCard = ({ license, stripeSuscription }: any) => {
|
|||||||
{/* Subscription Information Section */}
|
{/* Subscription Information Section */}
|
||||||
<div>
|
<div>
|
||||||
<div className="flex justify-between items-center mb-4">
|
<div className="flex justify-between items-center mb-4">
|
||||||
<h2 className="text-2xl font-bold text-white">
|
<h2 className="text-xl font-bold text-foreground">
|
||||||
Subscription Information
|
Subscription Information
|
||||||
</h2>
|
</h2>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors duration-200 flex items-center space-x-2"
|
|
||||||
// onClick={() => {
|
|
||||||
// // Handle subscription management here
|
|
||||||
// }}
|
|
||||||
>
|
|
||||||
<span>Manage Subscription</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
Subscription ID
|
Subscription ID
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-200">{stripeSuscription.id}</p>
|
<p className="text-foreground">{stripeSuscription.id}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">Quantity</p>
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
<p className="text-gray-200">
|
Quantity
|
||||||
|
</p>
|
||||||
|
<p className="text-foreground">
|
||||||
{stripeSuscription.quantity} licenses
|
{stripeSuscription.quantity} licenses
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
Billing Type
|
Billing Type
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-200 capitalize">
|
<p className="text-foreground capitalize">
|
||||||
{stripeSuscription.billingType}
|
{stripeSuscription.billingType}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-semibold text-gray-400">
|
<p className="text-sm font-semibold text-muted-foreground">
|
||||||
Stripe Customer ID
|
Stripe Customer ID
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-200">{license.stripeCustomerId}</p>
|
<p className="text-foreground">{license.stripeCustomerId}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="pt-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="w-full inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2"
|
||||||
|
>
|
||||||
|
<span>Manage Subscription</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -127,13 +153,16 @@ export const ViewLicensePage = async ({
|
|||||||
|
|
||||||
if (!data.success) {
|
if (!data.success) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4 items-center justify-center mx-auto py-8 px-4">
|
<div className="container mx-auto py-8 px-4">
|
||||||
<h1 className="text-3xl font-bold text-white mb-8 text-center">
|
<h1 className="text-3xl font-bold text-foreground mb-8 text-center">
|
||||||
License Details
|
License Details
|
||||||
</h1>
|
</h1>
|
||||||
<span className="text-red-500 text-center flex flex-col gap-2">
|
<span className="text-destructive text-center flex flex-col gap-2">
|
||||||
{data.error}, Please try again in
|
{data.error}, Please try again in
|
||||||
<Link href="/reset-license" className="text-white">
|
<Link
|
||||||
|
href="/reset-license"
|
||||||
|
className="text-primary hover:text-primary/90"
|
||||||
|
>
|
||||||
Reset License
|
Reset License
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
@@ -141,20 +170,22 @@ export const ViewLicensePage = async ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4 items-center justify-center mx-auto py-8 px-4">
|
<div className="container mx-auto py-8 px-4">
|
||||||
<h1 className="text-3xl font-bold text-white mb-8 text-center">
|
<div className="flex flex-col gap-6">
|
||||||
License Details
|
<h1 className="text-3xl font-bold text-foreground text-center">
|
||||||
</h1>
|
License Details
|
||||||
{data?.licenses?.map((item: any) => (
|
</h1>
|
||||||
<LicenseCard
|
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
|
||||||
key={item.license.id}
|
{data?.licenses?.map((item: any) => (
|
||||||
license={item.license}
|
<LicenseCard
|
||||||
stripeSuscription={item.stripeSuscription}
|
key={item.license.id}
|
||||||
/>
|
license={item.license}
|
||||||
))}
|
stripeSuscription={item.stripeSuscription}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user