You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
503 lines
20 KiB
503 lines
20 KiB
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
import Image from "next/image";
|
|
import UploadArea from "@/components/UploadArea";
|
|
import { useAuth } from "@/lib/auth-context";
|
|
import {
|
|
NavigationMenu,
|
|
NavigationMenuList,
|
|
NavigationMenuItem,
|
|
NavigationMenuLink,
|
|
} from "@/components/ui/navigation-menu";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
} from "@/components/ui/dropdown-menu";
|
|
import { ChevronDownIcon } from "lucide-react";
|
|
|
|
export default function Home() {
|
|
const { isAuthenticated, user, logout } = useAuth();
|
|
const [showSuccess, setShowSuccess] = useState(false);
|
|
const [userSubscription, setUserSubscription] = useState<any>(null);
|
|
|
|
// Check for success message in URL
|
|
useEffect(() => {
|
|
if (typeof window !== "undefined") {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
if (urlParams.get("success") === "true") {
|
|
setShowSuccess(true);
|
|
// Remove the query parameter from URL
|
|
window.history.replaceState({}, "", window.location.pathname);
|
|
// Hide after 5 seconds
|
|
setTimeout(() => setShowSuccess(false), 5000);
|
|
}
|
|
}
|
|
}, []);
|
|
|
|
// Fetch user subscription when authenticated
|
|
useEffect(() => {
|
|
const fetchUserSubscription = async () => {
|
|
if (!isAuthenticated || !user?.id) return;
|
|
|
|
try {
|
|
const response = await fetch("/api/subscriptions/me", {
|
|
headers: {
|
|
"user-id": user.id,
|
|
},
|
|
});
|
|
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setUserSubscription(data.subscription);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error fetching subscription:", error);
|
|
}
|
|
};
|
|
|
|
fetchUserSubscription();
|
|
}, [isAuthenticated, user]);
|
|
|
|
// Get user initials for the circle icon
|
|
const getUserInitials = () => {
|
|
if (!user) return "U";
|
|
const firstName = user.FirstName || "";
|
|
const lastName = user.LastName || "";
|
|
return (firstName.charAt(0) + lastName.charAt(0)).toUpperCase() || "U";
|
|
};
|
|
|
|
// Handle subscription button click
|
|
const handleSubscribe = async (tier: string) => {
|
|
if (!isAuthenticated) {
|
|
// Redirect to login
|
|
window.location.href = "/login?redirect=/";
|
|
return;
|
|
}
|
|
|
|
// Check if user already has an active subscription
|
|
if (userSubscription && userSubscription.status === "ACTIVE") {
|
|
alert(
|
|
"You already have an active subscription. Please manage it from the My Subscriptions page."
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Show loading state
|
|
setLoading(true);
|
|
|
|
try {
|
|
const response = await fetch("/api/create-checkout-session", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
tier,
|
|
userId: user?.id,
|
|
}),
|
|
});
|
|
|
|
// Check if response is JSON before parsing
|
|
const contentType = response.headers.get("content-type");
|
|
if (!contentType || !contentType.includes("application/json")) {
|
|
throw new Error(
|
|
"Invalid response from server. Please check your Stripe configuration."
|
|
);
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
const errorMessage = data.error || "Failed to create checkout session";
|
|
console.error("Payment API error:", errorMessage);
|
|
alert(errorMessage);
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
|
|
// Redirect to Stripe Checkout
|
|
if (data.url) {
|
|
window.location.href = data.url;
|
|
} else {
|
|
alert("No checkout URL received");
|
|
setLoading(false);
|
|
}
|
|
} catch (error) {
|
|
console.error("Payment error:", error);
|
|
alert("Failed to start payment process. Please try again.");
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
return (
|
|
<div className="min-h-screen" style={{ backgroundColor: "#FFFFFF" }}>
|
|
{/* Success Message Banner */}
|
|
{showSuccess && (
|
|
<div className="fixed top-16 left-1/2 transform -translate-x-1/2 z-50 bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg flex items-center space-x-2">
|
|
<span>✓</span>
|
|
<span>Subscription successful! Welcome to Reya Render.</span>
|
|
</div>
|
|
)}
|
|
|
|
{/* Sticky Navigation */}
|
|
<nav className="sticky top-0 z-50 bg-white/95 backdrop-blur-sm border-b border-gray-200">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="flex justify-between items-center h-16">
|
|
{/* Logo */}
|
|
<div className="flex-shrink-0">
|
|
<Image src="/reya2.svg" alt="Reya Logo" width={120} height={40} />
|
|
</div>
|
|
|
|
{/* Navigation Menu */}
|
|
<NavigationMenu className="hidden md:flex">
|
|
<NavigationMenuList>
|
|
<NavigationMenuItem>
|
|
<NavigationMenuLink
|
|
href="/contact"
|
|
className="px-4 py-2 text-gray-700 hover:text-gray-900"
|
|
>
|
|
Contact
|
|
</NavigationMenuLink>
|
|
</NavigationMenuItem>
|
|
<NavigationMenuItem>
|
|
<NavigationMenuLink
|
|
href="/pricing"
|
|
className="px-4 py-2 text-gray-700 hover:text-gray-900"
|
|
>
|
|
Pricing
|
|
</NavigationMenuLink>
|
|
</NavigationMenuItem>
|
|
{/* Show Upload File only when authenticated */}
|
|
{isAuthenticated && (
|
|
<NavigationMenuItem>
|
|
<NavigationMenuLink
|
|
href="/upload"
|
|
className="px-4 py-2 text-gray-700 hover:text-gray-900"
|
|
>
|
|
Upload File
|
|
</NavigationMenuLink>
|
|
</NavigationMenuItem>
|
|
)}
|
|
</NavigationMenuList>
|
|
</NavigationMenu>
|
|
|
|
{/* Auth Section */}
|
|
<div className="flex items-center space-x-4">
|
|
{isAuthenticated ? (
|
|
// Show user circle with dropdown when logged in
|
|
<div className="flex items-center space-x-4">
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<button className="flex items-center space-x-1 bg-white hover:bg-gray-50 text-gray-700 font-semibold text-sm rounded-full px-3 py-2 transition-colors cursor-pointer border border-gray-200 hover:border-gray-300">
|
|
<div className="w-8 h-8 bg-orange-500 rounded-full flex items-center justify-center text-white">
|
|
{getUserInitials()}
|
|
</div>
|
|
<ChevronDownIcon className="w-4 h-4 transition-transform duration-200 data-[state=open]:rotate-180" />
|
|
</button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end" className="w-56">
|
|
<DropdownMenuItem asChild>
|
|
<a href="/subscriptions" className="cursor-pointer">
|
|
My Subscriptions
|
|
</a>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem asChild>
|
|
<a href="/renders" className="cursor-pointer">
|
|
My Renders
|
|
</a>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem
|
|
onClick={logout}
|
|
className="cursor-pointer"
|
|
>
|
|
Logout
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</div>
|
|
) : (
|
|
// Show login/signup buttons when not authenticated
|
|
<>
|
|
<a
|
|
href="/login"
|
|
className="text-gray-700 hover:text-gray-900 px-4 py-2 border border-gray-300 hover:border-gray-400 rounded-md cursor-pointer transition-colors"
|
|
>
|
|
Log In
|
|
</a>
|
|
<a
|
|
href="/signup"
|
|
className="bg-orange-500 hover:bg-orange-600 text-white px-6 py-2 rounded-md font-medium cursor-pointer transition-colors"
|
|
>
|
|
Sign Up
|
|
</a>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
{/* Main Content */}
|
|
<div className="flex items-center justify-center min-h-screen">
|
|
<div
|
|
className="w-[90%] h-[600px] rounded-2xl flex justify-between items-start relative"
|
|
style={{
|
|
backgroundColor: "#FF580F",
|
|
margin: "20px",
|
|
marginTop: "5px",
|
|
}}
|
|
>
|
|
<div className="ml-8 mt-16">
|
|
<h1
|
|
className="text-white text-6xl font-bold mb-4"
|
|
style={{ fontFamily: "Inter, sans-serif" }}
|
|
>
|
|
Welcome to reYa Render
|
|
</h1>
|
|
<p
|
|
className="text-white text-2xl"
|
|
style={{ width: "600px", fontFamily: "Inter, sans-serif" }}
|
|
>
|
|
Whether you're working on animations, visualizations, or still
|
|
images, our render farm is optimized to deliver high-quality
|
|
results efficiently. Simply upload your files, and our system will
|
|
take care of the rendering process, saving you time and computing
|
|
power so you can focus on the creative side of your work.
|
|
</p>
|
|
<div className="flex gap-4 mt-6">
|
|
<button className="bg-white text-orange-500 px-6 py-3 rounded-md font-medium hover:bg-gray-100 cursor-pointer transition-colors">
|
|
Contact Us
|
|
</button>
|
|
<button className="bg-transparent border-2 border-white text-white px-6 py-3 rounded-md font-medium hover:bg-white hover:text-orange-500 cursor-pointer transition-colors">
|
|
Get Started
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div className="absolute bottom-4 right-4">
|
|
<img
|
|
src="/creativity.png"
|
|
alt="3D Model"
|
|
width={500}
|
|
height={500}
|
|
style={{ display: "block" }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Subscription Status Indicator */}
|
|
{isAuthenticated &&
|
|
userSubscription &&
|
|
userSubscription.status === "ACTIVE" && (
|
|
<div className="flex justify-center mt-8">
|
|
<div className="bg-green-50 border-2 border-green-500 rounded-lg p-6 max-w-2xl">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<p className="text-green-800 font-semibold text-lg mb-1">
|
|
✓ You have an active {userSubscription.tier} subscription
|
|
</p>
|
|
<p className="text-green-700 text-sm">
|
|
Member since{" "}
|
|
{new Date(userSubscription.created_at).toLocaleDateString()}
|
|
</p>
|
|
</div>
|
|
<a
|
|
href="/subscriptions"
|
|
className="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-md text-sm font-medium ml-4"
|
|
>
|
|
Manage Subscription
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Pricing Section */}
|
|
<div className="flex justify-center mt-16 mb-16">
|
|
<div className="w-[90%]">
|
|
<h2 className="text-4xl font-bold text-center mb-12 text-gray-800">
|
|
Available Plans
|
|
</h2>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
|
{/* Basic Plan */}
|
|
<div className="bg-white border-2 border-gray-200 rounded-xl p-8 text-center transition-all hover:transform hover:-translate-y-2 hover:shadow-xl hover:border-orange-500 cursor-pointer">
|
|
<div className="text-2xl font-bold text-orange-500 mb-2">
|
|
Basic
|
|
</div>
|
|
<div className="text-4xl font-bold text-orange-500 mb-8">
|
|
€9.99{" "}
|
|
<span className="text-lg font-normal text-gray-500">
|
|
/month
|
|
</span>
|
|
</div>
|
|
<button
|
|
onClick={() => handleSubscribe("basic")}
|
|
disabled={
|
|
loading ||
|
|
(userSubscription && userSubscription.status === "ACTIVE")
|
|
}
|
|
className="w-full bg-orange-500 text-white py-3 px-6 rounded-lg font-medium mb-6 hover:bg-orange-600 transition-colors hover:cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
{loading
|
|
? "Processing..."
|
|
: userSubscription && userSubscription.status === "ACTIVE"
|
|
? "Current Plan"
|
|
: "Choose Basic"}
|
|
</button>
|
|
<ul className="text-left space-y-3">
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
250 GB storage
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Custom subdomain
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Unlimited downloads
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Password protected links
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Basic analytics
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
{/* Standard Plan */}
|
|
<div className="bg-white border-2 border-gray-200 rounded-xl p-8 text-center transition-all hover:transform hover:-translate-y-2 hover:shadow-xl hover:border-orange-500 cursor-pointer">
|
|
<div className="text-2xl font-bold text-orange-500 mb-2">
|
|
Standard
|
|
</div>
|
|
<div className="text-4xl font-bold text-orange-500 mb-8">
|
|
€19.99{" "}
|
|
<span className="text-lg font-normal text-gray-500">
|
|
/month
|
|
</span>
|
|
</div>
|
|
<button
|
|
onClick={() => handleSubscribe("standard")}
|
|
disabled={
|
|
loading ||
|
|
(userSubscription && userSubscription.status === "ACTIVE")
|
|
}
|
|
className="w-full bg-orange-500 text-white py-3 px-6 rounded-lg font-medium mb-6 hover:bg-orange-600 transition-colors hover:cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
{loading
|
|
? "Processing..."
|
|
: userSubscription && userSubscription.status === "ACTIVE"
|
|
? "Current Plan"
|
|
: "Choose Standard"}
|
|
</button>
|
|
<ul className="text-left space-y-3">
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
500 GB storage
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Custom subdomain
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Unlimited downloads
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Password protected links
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Basic analytics
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Custom branding & logo
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Priority support
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
{/* Premium Plan */}
|
|
<div className="bg-white border-2 border-gray-200 rounded-xl p-8 text-center transition-all hover:transform hover:-translate-y-2 hover:shadow-xl hover:border-orange-500 cursor-pointer">
|
|
<div className="text-2xl font-bold text-orange-500 mb-2">
|
|
Premium
|
|
</div>
|
|
<div className="text-4xl font-bold text-orange-500 mb-8">
|
|
€39.99{" "}
|
|
<span className="text-lg font-normal text-gray-500">
|
|
/month
|
|
</span>
|
|
</div>
|
|
<button
|
|
onClick={() => handleSubscribe("premium")}
|
|
disabled={
|
|
loading ||
|
|
(userSubscription && userSubscription.status === "ACTIVE")
|
|
}
|
|
className="w-full bg-orange-500 text-white py-3 px-6 rounded-lg font-medium mb-6 hover:bg-orange-600 transition-colors hover:cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
{loading
|
|
? "Processing..."
|
|
: userSubscription && userSubscription.status === "ACTIVE"
|
|
? "Current Plan"
|
|
: "Choose Premium"}
|
|
</button>
|
|
<ul className="text-left space-y-3">
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>1 TB
|
|
storage
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Custom subdomain
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Unlimited downloads
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Password protected links
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Basic analytics
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Custom branding & logo
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Priority support
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Multiple user accounts
|
|
</li>
|
|
<li className="flex items-center">
|
|
<span className="text-green-500 font-bold mr-3">✓</span>
|
|
Team management
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|