@@ -31,6 +31,7 @@ interface CheckoutFormProps {
3131 features ?: string | null ;
3232 userName ?: string ;
3333 userEmail ?: string ;
34+ paymentProvider ?: string | null ;
3435}
3536
3637export function CheckoutForm ( {
@@ -45,6 +46,7 @@ export function CheckoutForm({
4546 features,
4647 userName,
4748 userEmail,
49+ paymentProvider,
4850} : CheckoutFormProps ) {
4951 const [ loading , setLoading ] = useState ( false ) ;
5052 const [ paymentMethod , setPaymentMethod ] = useState < 'card' | 'offline' > ( 'card' ) ;
@@ -57,7 +59,8 @@ export function CheckoutForm({
5759 const router = useRouter ( ) ;
5860 const t = useTranslations ( 'checkout' ) ;
5961
60- const isFree = typeof price === 'number' ? price === 0 : price === t ( 'free' ) ;
62+ const isFree = typeof price === 'number' ? price === 0 : price === t ( 'free' )
63+ const showOfflineTab = ! paymentProvider || paymentProvider === 'manual' ;
6164 const displayPrice = formattedPrice || ( typeof price === 'number' ? `$${ price } ` : price ) ;
6265
6366 // Parse features string into list (features are stored as newline or comma-separated text)
@@ -180,19 +183,89 @@ export function CheckoutForm({
180183
181184 { /* Payment methods */ }
182185 < div className = "px-6 py-6 sm:px-8" >
183- < Tabs defaultValue = "card" onValueChange = { ( v ) => v && setPaymentMethod ( v as 'card' | 'offline' ) } >
184- < TabsList className = "w-full" >
185- < TabsTrigger value = "card" className = "flex-1 gap-1.5" >
186- < IconCreditCard className = "h-3.5 w-3.5" />
187- { t ( 'payment.card' ) }
188- </ TabsTrigger >
189- < TabsTrigger value = "offline" className = "flex-1 gap-1.5" >
190- < IconBuildingBank className = "h-3.5 w-3.5" />
191- { t ( 'payment.offline' ) }
192- </ TabsTrigger >
193- </ TabsList >
186+ { showOfflineTab ? (
187+ < Tabs defaultValue = "card" onValueChange = { ( v ) => v && setPaymentMethod ( v as 'card' | 'offline' ) } >
188+ < TabsList className = "w-full" >
189+ < TabsTrigger value = "card" className = "flex-1 gap-1.5" >
190+ < IconCreditCard className = "h-3.5 w-3.5" />
191+ { t ( 'payment.card' ) }
192+ </ TabsTrigger >
193+ < TabsTrigger value = "offline" className = "flex-1 gap-1.5" >
194+ < IconBuildingBank className = "h-3.5 w-3.5" />
195+ { t ( 'payment.offline' ) }
196+ </ TabsTrigger >
197+ </ TabsList >
194198
195- < TabsContent value = "card" className = "mt-5 space-y-4" >
199+ < TabsContent value = "card" className = "mt-5 space-y-4" >
200+ < div className = "space-y-1.5" >
201+ < Label htmlFor = "cardholder" className = "text-xs font-medium" > { t ( 'payment.cardholder' ) } </ Label >
202+ < Input id = "cardholder" placeholder = "John Doe" disabled = { loading } />
203+ </ div >
204+ < div className = "space-y-1.5" >
205+ < Label htmlFor = "cardNumber" className = "text-xs font-medium" > { t ( 'payment.cardNumber' ) } </ Label >
206+ < div className = "relative" >
207+ < Input
208+ id = "cardNumber"
209+ placeholder = "4242 4242 4242 4242"
210+ className = "pl-10"
211+ disabled = { loading }
212+ />
213+ < IconCreditCard className = "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
214+ </ div >
215+ </ div >
216+ < div className = "grid grid-cols-2 gap-3" >
217+ < div className = "space-y-1.5" >
218+ < Label htmlFor = "expiry" className = "text-xs font-medium" > { t ( 'payment.expiry' ) } </ Label >
219+ < Input id = "expiry" placeholder = "MM/YY" disabled = { loading } />
220+ </ div >
221+ < div className = "space-y-1.5" >
222+ < Label htmlFor = "cvc" className = "text-xs font-medium" > { t ( 'payment.cvc' ) } </ Label >
223+ < Input id = "cvc" placeholder = "123" disabled = { loading } />
224+ </ div >
225+ </ div >
226+ </ TabsContent >
227+
228+ < TabsContent value = "offline" className = "mt-5 space-y-4" >
229+ < p className = "rounded-lg bg-muted/50 px-4 py-3 text-xs leading-relaxed text-muted-foreground" >
230+ { t ( 'payment.offlineInstructions' ) }
231+ </ p >
232+ < div className = "space-y-1.5" >
233+ < Label htmlFor = "offlineName" className = "text-xs font-medium" > { t ( 'payment.contactName' ) } </ Label >
234+ < Input
235+ id = "offlineName"
236+ placeholder = "Your Name"
237+ value = { offlineData . name }
238+ onChange = { e => setOfflineData ( { ...offlineData , name : e . target . value } ) }
239+ disabled = { loading }
240+ />
241+ </ div >
242+ < div className = "space-y-1.5" >
243+ < Label htmlFor = "offlineEmail" className = "text-xs font-medium" > { t ( 'payment.contactEmail' ) } </ Label >
244+ < Input
245+ id = "offlineEmail"
246+ type = "email"
247+ placeholder = "email@example.com"
248+ value = { offlineData . email }
249+ onChange = { e => setOfflineData ( { ...offlineData , email : e . target . value } ) }
250+ disabled = { loading }
251+ readOnly = { ! ! userEmail }
252+ className = { userEmail ? 'bg-muted' : '' }
253+ />
254+ </ div >
255+ < div className = "space-y-1.5" >
256+ < Label htmlFor = "offlinePhone" className = "text-xs font-medium" > { t ( 'payment.contactPhone' ) } </ Label >
257+ < Input
258+ id = "offlinePhone"
259+ placeholder = "+1 234 567 8900"
260+ value = { offlineData . phone }
261+ onChange = { e => setOfflineData ( { ...offlineData , phone : e . target . value } ) }
262+ disabled = { loading }
263+ />
264+ </ div >
265+ </ TabsContent >
266+ </ Tabs >
267+ ) : (
268+ < div className = "space-y-4" >
196269 < div className = "space-y-1.5" >
197270 < Label htmlFor = "cardholder" className = "text-xs font-medium" > { t ( 'payment.cardholder' ) } </ Label >
198271 < Input id = "cardholder" placeholder = "John Doe" disabled = { loading } />
@@ -219,47 +292,8 @@ export function CheckoutForm({
219292 < Input id = "cvc" placeholder = "123" disabled = { loading } />
220293 </ div >
221294 </ div >
222- </ TabsContent >
223-
224- < TabsContent value = "offline" className = "mt-5 space-y-4" >
225- < p className = "rounded-lg bg-muted/50 px-4 py-3 text-xs leading-relaxed text-muted-foreground" >
226- { t ( 'payment.offlineInstructions' ) }
227- </ p >
228- < div className = "space-y-1.5" >
229- < Label htmlFor = "offlineName" className = "text-xs font-medium" > { t ( 'payment.contactName' ) } </ Label >
230- < Input
231- id = "offlineName"
232- placeholder = "Your Name"
233- value = { offlineData . name }
234- onChange = { e => setOfflineData ( { ...offlineData , name : e . target . value } ) }
235- disabled = { loading }
236- />
237- </ div >
238- < div className = "space-y-1.5" >
239- < Label htmlFor = "offlineEmail" className = "text-xs font-medium" > { t ( 'payment.contactEmail' ) } </ Label >
240- < Input
241- id = "offlineEmail"
242- type = "email"
243- placeholder = "email@example.com"
244- value = { offlineData . email }
245- onChange = { e => setOfflineData ( { ...offlineData , email : e . target . value } ) }
246- disabled = { loading }
247- readOnly = { ! ! userEmail }
248- className = { userEmail ? 'bg-muted' : '' }
249- />
250- </ div >
251- < div className = "space-y-1.5" >
252- < Label htmlFor = "offlinePhone" className = "text-xs font-medium" > { t ( 'payment.contactPhone' ) } </ Label >
253- < Input
254- id = "offlinePhone"
255- placeholder = "+1 234 567 8900"
256- value = { offlineData . phone }
257- onChange = { e => setOfflineData ( { ...offlineData , phone : e . target . value } ) }
258- disabled = { loading }
259- />
260- </ div >
261- </ TabsContent >
262- </ Tabs >
295+ </ div >
296+ ) }
263297 </ div >
264298
265299 { /* Submit */ }
0 commit comments