mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 11:23:10 +02:00
Add SaaS frontend code (#5879)
# Description of Changes Adds the code for the SaaS frontend as proprietary code to the OSS repo. This version of the code is adapted from 22/1/2026, which was the last SaaS version based on the 'V2' design. This will move us closer to being able to have the OSS products understand whether the user has a SaaS account, and provide the correct UI in those cases.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { useState } from 'react';
|
||||
import { supabase } from '@app/auth/supabase';
|
||||
import { Button } from '@mantine/core';
|
||||
import { usePlans } from '@app/hooks/usePlans';
|
||||
|
||||
interface TrialStatus {
|
||||
isTrialing: boolean;
|
||||
trialEnd: string;
|
||||
daysRemaining: number;
|
||||
hasPaymentMethod: boolean;
|
||||
hasScheduledSub: boolean;
|
||||
}
|
||||
|
||||
export function ManageBillingButton({
|
||||
returnUrl = typeof window !== 'undefined' ? window.location.href : '/',
|
||||
children = 'Manage billing',
|
||||
trialStatus,
|
||||
}: {
|
||||
returnUrl?: string;
|
||||
children?: React.ReactNode;
|
||||
trialStatus?: TrialStatus;
|
||||
}) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [err, setErr] = useState<string | null>(null);
|
||||
const { data } = usePlans();
|
||||
|
||||
// Hide for free plan users
|
||||
if (!data || data.currentPlan.id === 'free') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Hide for trial users who haven't scheduled a subscription yet
|
||||
if (trialStatus?.isTrialing && !trialStatus.hasScheduledSub) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const onClick = async () => {
|
||||
setLoading(true);
|
||||
setErr(null);
|
||||
try {
|
||||
const { data, error } = await supabase.functions.invoke('manage-billing', {
|
||||
body: {
|
||||
name: 'Functions',
|
||||
return_url: returnUrl},
|
||||
})
|
||||
if (error) throw error;
|
||||
if (!data || 'error' in data) throw new Error((data as any)?.error ?? 'No portal URL');
|
||||
window.location.href = (data as any).url;
|
||||
} catch (e: any) {
|
||||
setErr(e.message ?? 'Could not open billing portal');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={onClick} disabled={loading} className="px-4 py-2 rounded bg-black text-white">
|
||||
{loading ? 'Opening…' : children}
|
||||
</Button>
|
||||
{err && <div className="mt-2 text-red-600">{err}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user