diff --git a/apps/website/app/[locale]/license/success/page.tsx b/apps/website/app/[locale]/license/success/page.tsx
index 596f73b..45987a5 100644
--- a/apps/website/app/[locale]/license/success/page.tsx
+++ b/apps/website/app/[locale]/license/success/page.tsx
@@ -41,12 +41,15 @@ export default function LicenseSuccess() {
useEffect(() => {
setLoading(true);
- fetch(`${SERVER_LICENSE_URL}/license/session?sessionId=${sessionId}`, {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
+ fetch(
+ `${SERVER_LICENSE_URL}/stripe/get-license-from-session?sessionId=${sessionId}`,
+ {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
},
- })
+ )
.then((res) => res.json())
.then((data) => {
if (data.error) {
diff --git a/apps/website/app/[locale]/license/view/page.tsx b/apps/website/app/[locale]/license/view/page.tsx
new file mode 100644
index 0000000..89d5c0b
--- /dev/null
+++ b/apps/website/app/[locale]/license/view/page.tsx
@@ -0,0 +1,162 @@
+import Link from "next/link";
+import { useParams } from "next/navigation";
+
+export const SERVER_LICENSE_URL =
+ process.env.NODE_ENV === "development"
+ ? "http://localhost:4002/api"
+ : "https://licenses.dokploy.com";
+
+const LicenseCard = ({ license, stripeSuscription }: any) => {
+ return (
+
+
+ {/* License Information Section */}
+
+
+ License Information
+
+
+
+
License ID
+
{license.id}
+
+
+
License Key
+
{license.licenseKey}
+
+
+
+ Activation Status
+
+
+ {license.activatedAt ? "Activated" : "Not Activated"}
+
+
+
+
+ Last Verification
+
+
+ {license.lastVerifiedAt || "Not Verified"}
+
+
+
+
Created At
+
+ {new Date(license.createdAt).toLocaleDateString()}
+
+
+
+
+ Last Updated
+
+
+ {new Date(license.updatedAt).toLocaleDateString()}
+
+
+
+
+
+ {/* Subscription Information Section */}
+
+
+
+ Subscription Information
+
+ {
+ // // Handle subscription management here
+ // }}
+ >
+ Manage Subscription
+
+
+
+
+
+ Subscription ID
+
+
{stripeSuscription.id}
+
+
+
Quantity
+
+ {stripeSuscription.quantity} licenses
+
+
+
+
+ Billing Type
+
+
+ {stripeSuscription.billingType}
+
+
+
+
+ Stripe Customer ID
+
+
{license.stripeCustomerId}
+
+
+
+
+
+ );
+};
+
+export const ViewLicensePage = async ({
+ searchParams,
+}: {
+ searchParams: Promise<{ temporalId: string }>;
+}) => {
+ const newParams = await searchParams;
+ const temporalId = newParams.temporalId;
+ const licences = await fetch(
+ `${SERVER_LICENSE_URL}/license/all?temporalId=${temporalId}`,
+ {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ },
+ );
+ const data = await licences.json();
+
+ if (!data.success) {
+ return (
+
+
+ License Details
+
+
+ {data.error}, Please try again in
+
+ Reset License
+
+
+
+ );
+ }
+
+ console.log(data);
+
+ return (
+
+
+ License Details
+
+ {data?.licenses?.map((item: any) => (
+
+ ))}
+
+ );
+};
+
+export default ViewLicensePage;
diff --git a/apps/website/app/[locale]/reset-license/page.tsx b/apps/website/app/[locale]/reset-license/page.tsx
index b6be0d5..9bb8e43 100644
--- a/apps/website/app/[locale]/reset-license/page.tsx
+++ b/apps/website/app/[locale]/reset-license/page.tsx
@@ -4,19 +4,38 @@ import { Container } from "@/components/Container";
import { SERVER_LICENSE_URL } from "@/components/pricing";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
+import {
+ InputOTP,
+ InputOTPGroup,
+ InputOTPSlot,
+} from "@/components/ui/input-otp";
+import { ArrowLeft, ExternalLink } from "lucide-react";
+import { useRouter } from "next/navigation";
import { useState } from "react";
import { toast } from "sonner";
+
+interface License {
+ email: string;
+ serverIp?: string[];
+ licenseKey: string;
+ productName: string;
+ createdAt: string;
+ lastVerifiedAt: string;
+ billingType: string;
+ activatedAt: string;
+ type: string;
+}
+
export default function ResetLicensePage() {
+ const router = useRouter();
const [email, setEmail] = useState("");
- const [showOtp, setShowOtp] = useState(false);
+ const [showRender, setShowRender] = useState<"otp" | "email">("email");
const [isLoading, setIsLoading] = useState(false);
+ const [otp, setOtp] = useState("");
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault();
- setIsLoading(true);
-
+ const sendEmail = async (email: string) => {
try {
- const result = await fetch(`${SERVER_LICENSE_URL}/license/verification`, {
+ const result = await fetch(`${SERVER_LICENSE_URL}/license/send-otp`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -25,7 +44,6 @@ export default function ResetLicensePage() {
});
const data = await result.json();
- console.log(data);
if (data.error) {
toast.error(
@@ -38,7 +56,52 @@ export default function ResetLicensePage() {
toast.success(
"We've sent you a code to verify your email. Please check your email for the code.",
);
- setShowOtp(true);
+ setShowRender("otp");
+ }
+ } catch (error) {
+ toast.error("Something went wrong. Please try again later.", {
+ duration: 15000,
+ description: error instanceof Error ? error.message : "Unknown error",
+ });
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setIsLoading(true);
+
+ await sendEmail(email);
+ };
+
+ const handleVerifyOtp = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setIsLoading(true);
+
+ try {
+ if (otp.length !== 6) {
+ toast.error("Please enter a valid 6-digit code.");
+ return;
+ }
+
+ const result = await fetch(`${SERVER_LICENSE_URL}/license/verify-otp`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ email, otpCode: otp }),
+ });
+
+ const data = await result.json();
+ if (data.error) {
+ toast.error("Error verifying code. Please try again.", {
+ description: data.error,
+ });
+ } else {
+ const temporalId = data.temporalId;
+ console.log(temporalId);
+ router.push(`/license/view?temporalId=${temporalId}`);
}
} catch (error) {
toast.error("Something went wrong. Please try again later.", {
@@ -57,33 +120,85 @@ export default function ResetLicensePage() {
Reset Your License
- Enter your email address and we'll send you instructions to reset your
- license.
+ {showRender === "otp"
+ ? "Enter the verification code sent to your email."
+ : "Enter your email address and we'll send you instructions to reset your license."}
-
+
+ setEmail(e.target.value)}
+ required
+ className="w-full"
+ disabled={isLoading}
+ />
+
+
+ {isLoading ? "Sending..." : "Reset License"}
+
+
+ ) : (
+
+ )}
);
diff --git a/apps/website/components/pricing.tsx b/apps/website/components/pricing.tsx
index 9cadbc4..2760462 100644
--- a/apps/website/components/pricing.tsx
+++ b/apps/website/components/pricing.tsx
@@ -147,7 +147,7 @@ export function Pricing() {
// Create checkout session
const response = await fetch(
- `${SERVER_LICENSE_URL!}/create-checkout-session`,
+ `${SERVER_LICENSE_URL!}/stripe/create-checkout-session`,
{
method: "POST",
headers: {