1+ import { createServerClient } from '@/lib/supabase-server'
2+ import { NextRequest , NextResponse } from 'next/server'
3+ import { z } from 'zod'
4+
5+ export const runtime = 'nodejs'
6+ export const dynamic = 'force-dynamic'
7+
8+ const billingUpdateSchema = z . object ( {
9+ companyName : z . string ( ) . min ( 1 , 'Company name is required' ) ,
10+ companyEmail : z . string ( ) . email ( 'Valid email is required' ) ,
11+ taxId : z . string ( ) . optional ( ) ,
12+ address : z . string ( ) . min ( 1 , 'Address is required' ) ,
13+ city : z . string ( ) . min ( 1 , 'City is required' ) ,
14+ state : z . string ( ) . min ( 1 , 'State/Province is required' ) ,
15+ postalCode : z . string ( ) . min ( 1 , 'Postal code is required' ) ,
16+ country : z . string ( ) . min ( 1 , 'Country is required' ) ,
17+ paymentMethod : z . enum ( [ 'card' , 'bank_transfer' , 'invoice' ] ) ,
18+ billingCycle : z . enum ( [ 'monthly' , 'annual' ] ) ,
19+ } )
20+
21+ export async function POST ( request : NextRequest ) {
22+ try {
23+ const supabase = createServerClient ( )
24+
25+ const { data : { user } , error : authError } = await supabase . auth . getUser ( )
26+ if ( authError || ! user ) {
27+ return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
28+ }
29+
30+ const body = await request . json ( )
31+ const validatedData = billingUpdateSchema . parse ( body )
32+
33+ // Get user's team
34+ const { data : userTeam , error : teamError } = await supabase
35+ . from ( 'users_teams' )
36+ . select ( 'team_id, teams(*)' )
37+ . eq ( 'user_id' , user . id )
38+ . single ( )
39+
40+ if ( teamError || ! userTeam ) {
41+ return NextResponse . json ( { error : 'Team not found' } , { status : 404 } )
42+ }
43+
44+ // Update billing information in the database
45+ const { error : updateError } = await supabase
46+ . from ( 'billing_info' )
47+ . upsert ( {
48+ team_id : userTeam . team_id ,
49+ company_name : validatedData . companyName ,
50+ company_email : validatedData . companyEmail ,
51+ tax_id : validatedData . taxId ,
52+ address : validatedData . address ,
53+ city : validatedData . city ,
54+ state : validatedData . state ,
55+ postal_code : validatedData . postalCode ,
56+ country : validatedData . country ,
57+ payment_method : validatedData . paymentMethod ,
58+ billing_cycle : validatedData . billingCycle ,
59+ updated_at : new Date ( ) . toISOString ( ) ,
60+ } , {
61+ onConflict : 'team_id'
62+ } )
63+
64+ if ( updateError ) {
65+ console . error ( 'Error updating billing info:' , updateError )
66+ return NextResponse . json ( { error : 'Failed to update billing information' } , { status : 500 } )
67+ }
68+
69+ return NextResponse . json ( { success : true , message : 'Billing information updated successfully' } )
70+ } catch ( error ) {
71+ console . error ( 'Billing update error:' , error )
72+
73+ if ( error instanceof z . ZodError ) {
74+ return NextResponse . json ( {
75+ error : 'Validation error' ,
76+ details : error . errors
77+ } , { status : 400 } )
78+ }
79+
80+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
81+ }
82+ }
83+
84+ export async function GET ( request : NextRequest ) {
85+ try {
86+ const supabase = createServerClient ( )
87+
88+ const { data : { user } , error : authError } = await supabase . auth . getUser ( )
89+ if ( authError || ! user ) {
90+ return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
91+ }
92+
93+ // Get user's team
94+ const { data : userTeam , error : teamError } = await supabase
95+ . from ( 'users_teams' )
96+ . select ( 'team_id' )
97+ . eq ( 'user_id' , user . id )
98+ . single ( )
99+
100+ if ( teamError || ! userTeam ) {
101+ return NextResponse . json ( { error : 'Team not found' } , { status : 404 } )
102+ }
103+
104+ // Get billing information
105+ const { data : billingInfo , error : billingError } = await supabase
106+ . from ( 'billing_info' )
107+ . select ( '*' )
108+ . eq ( 'team_id' , userTeam . team_id )
109+ . single ( )
110+
111+ if ( billingError && billingError . code !== 'PGRST116' ) {
112+ console . error ( 'Error fetching billing info:' , billingError )
113+ return NextResponse . json ( { error : 'Failed to fetch billing information' } , { status : 500 } )
114+ }
115+
116+ return NextResponse . json ( {
117+ billingInfo : billingInfo || null
118+ } )
119+ } catch ( error ) {
120+ console . error ( 'Billing fetch error:' , error )
121+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
122+ }
123+ }
0 commit comments