import React, { useState, useEffect } from "react"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // icons import { XCircleIcon, RocketLaunchIcon } from "@heroicons/react/24/outline"; import { CheckCircleIcon } from "@heroicons/react/24/solid"; // ui import { CircularProgress } from "components/ui"; // types import type { ICurrentUserResponse, IWorkspace } from "types"; declare global { interface Window { supabase: any; } } type Props = { isOpen: boolean; onClose: () => void; user: ICurrentUserResponse | undefined; issueNumber: number; }; const UpgradeToProModal: React.FC = ({ isOpen, onClose, user, issueNumber }) => { const [supabaseClient, setSupabaseClient] = useState(null); useEffect(() => { // Create a Supabase client if (process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) { const { createClient } = window.supabase; const supabase = createClient( process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, { auth: { autoRefreshToken: false, persistSession: false, }, } ); if (supabase) { setSupabaseClient(supabase); } } }, []); const [isLoading, setIsLoading] = useState(false); const handleClose = () => { onClose(); setIsLoading(false); }; const proFeatures = [ "Everything in free", "Unlimited users", "Unlimited file uploads", "Priority Support", "Custom Theming", "Access to Roadmap", "Plane AI (GPT unlimited)", ]; const [errorMessage, setErrorMessage] = useState( null ); const [loader, setLoader] = useState(false); const submitEmail = async () => { setLoader(true); const payload = { email: user?.email || "" }; if (supabaseClient) { if (payload?.email) { const emailExists = await supabaseClient .from("web-waitlist") .select("id,email,count") .eq("email", payload?.email); if (emailExists.data.length === 0) { const emailCreation = await supabaseClient .from("web-waitlist") .insert([{ email: payload?.email, count: 1, last_visited: new Date() }]) .select("id,email,count"); if (emailCreation.status === 201) setErrorMessage({ status: "success", message: "Successfully registered." }); else setErrorMessage({ status: "insert_error", message: "Insertion Error." }); } else { const emailCountUpdate = await supabaseClient .from("web-waitlist") .upsert({ id: emailExists.data[0]?.id, count: emailExists.data[0]?.count + 1, last_visited: new Date(), }) .select("id,email,count"); if (emailCountUpdate.status === 201) setErrorMessage({ status: "email_already_exists", message: "Email already exists.", }); else setErrorMessage({ status: "update_error", message: "Update Error." }); } } else setErrorMessage({ status: "email_required", message: "Please provide email." }); } else setErrorMessage({ status: "supabase_error", message: "Network error. Please try again later.", }); setLoader(false); }; return (
= 750 ? "text-red-600" : issueNumber >= 500 ? "text-yellow-600" : "text-green-600" }`} title="Shortcuts" > 100 ? 100 : (issueNumber / 1024) * 100 } />
Upgrade to pro
This workspace has used {issueNumber} of its 1024 issues creation limit ( {((issueNumber / 1024) * 100).toFixed(2)}%).
Order summary
Priority support, file uploads, and access to premium features.
{proFeatures.map((feature, index) => (
{feature}
))}
Summary
Plane application is currently in dev-mode. We will soon introduce Pro plans once general availability has been established. Stay tuned for more updates. In the meantime, Plane remains free and unrestricted.

We{"'"}ll ensure a smooth transition from the community version to the Pro plan for you.
{errorMessage && (
{errorMessage?.message}
)}
); }; export default UpgradeToProModal;