feat(billing): integrate Stripe for subscription management and billing access

- Added billing-related fields to the User model in the database.
- Implemented functions for managing billing access, including trial periods and subscription statuses.
- Created new billing utility functions for Stripe integration.
- Updated onboarding page to include billing overview and workspace creation eligibility.
- Enhanced route access checks to require billing access for certain actions.
- Implemented cleanup scripts for expired billing workspaces and associated media.
- Updated header component to conditionally show app navigation based on billing access.
- Added new migrations for billing-related database changes.
This commit is contained in:
Yusuf İpek
2026-04-08 17:50:40 +03:00
parent 8db7a031e6
commit 6f22b0bf8b
45 changed files with 1859 additions and 218 deletions
@@ -35,9 +35,18 @@ interface WorkspacesClientProps {
workspaces: SerializedWorkspace[];
totalPages: number;
currentPage: number;
workspaceCreation: {
canCreateWorkspace: boolean;
reason: string | null;
};
}
export function WorkspacesClient({ workspaces, totalPages, currentPage }: WorkspacesClientProps) {
export function WorkspacesClient({
workspaces,
totalPages,
currentPage,
workspaceCreation,
}: WorkspacesClientProps) {
const router = useRouter();
return (
@@ -49,13 +58,26 @@ export function WorkspacesClient({ workspaces, totalPages, currentPage }: Worksp
<p className="text-muted-foreground mt-1">
Manage your workspaces and their projects
</p>
{!workspaceCreation.canCreateWorkspace && workspaceCreation.reason ? (
<p className="text-sm text-amber-700 dark:text-amber-400 mt-2">
{workspaceCreation.reason}
</p>
) : null}
</div>
<Button asChild className="w-full sm:w-auto">
<Link href="/workspaces/new">
<Plus className="h-4 w-4 mr-2" />
New Workspace
</Link>
</Button>
{workspaceCreation.canCreateWorkspace ? (
<Button asChild className="w-full sm:w-auto">
<Link href="/workspaces/new">
<Plus className="h-4 w-4 mr-2" />
New Workspace
</Link>
</Button>
) : (
<Button asChild className="w-full sm:w-auto">
<Link href="/settings">
Upgrade to Create Workspace
</Link>
</Button>
)}
</div>
{/* Workspaces Grid */}
@@ -101,12 +123,18 @@ export function WorkspacesClient({ workspaces, totalPages, currentPage }: Worksp
<p className="text-muted-foreground text-center mb-4">
Create a workspace to organize your projects and invite team members
</p>
<Button asChild>
<Link href="/workspaces/new">
<Plus className="h-4 w-4 mr-2" />
Create Workspace
</Link>
</Button>
{workspaceCreation.canCreateWorkspace ? (
<Button asChild>
<Link href="/workspaces/new">
<Plus className="h-4 w-4 mr-2" />
Create Workspace
</Link>
</Button>
) : (
<Button asChild>
<Link href="/settings">Upgrade to Create Workspace</Link>
</Button>
)}
</CardContent>
</Card>
)}