subos-frontend 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,822 @@
1
+ # SubOS Frontend Package Reference
2
+
3
+ ## Overview
4
+
5
+ SubOS Frontend is a comprehensive React component library for managing subscriptions, pricing, billing, and account logic in SaaS applications. This package provides ready-to-use components, hooks, and API integrations for building subscription management interfaces.
6
+
7
+ **Built with:** React 19, TypeScript, Material-UI, Emotion, React Router DOM, Stripe
8
+
9
+ ---
10
+
11
+ ## 📦 Installation & Setup
12
+
13
+ ```bash
14
+ npm install subos-frontend
15
+ # or
16
+ yarn add subos-frontend
17
+ ```
18
+
19
+ ### Required Peer Dependencies
20
+ ```bash
21
+ npm install react react-dom react-router-dom @stripe/react-stripe-js @stripe/stripe-js
22
+ ```
23
+
24
+ ### Configuration (REQUIRED)
25
+ ```javascript
26
+ import { configureSubOS } from 'subos-frontend';
27
+ import 'subos-frontend/style.css';
28
+
29
+ // Configure at app startup
30
+ configureSubOS({
31
+ apiEndpoint: 'https://your-api.com/api/v1',
32
+ projectId: 'your-project-id',
33
+ stripePublishableKey: 'pk_test_your_stripe_key',
34
+ appName: 'Your App Name',
35
+ appEnvironment: 'production' // or 'development'
36
+ });
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 🎯 Components
42
+
43
+ ### Plan Components
44
+
45
+ #### `PlanCard`
46
+ Displays individual subscription plan details with selection functionality.
47
+
48
+ **Props:**
49
+ ```typescript
50
+ interface PlanCardProps {
51
+ plan: Plan; // Plan object with pricing and features
52
+ isSelected: boolean; // Whether this plan is currently selected
53
+ billingCycle: 'monthly' | 'yearly'; // Current billing cycle filter
54
+ onSelect: (plan: Plan) => void; // Callback when plan is selected
55
+ isActive?: boolean; // Whether this is user's current plan
56
+ }
57
+ ```
58
+
59
+ **Usage:**
60
+ ```jsx
61
+ <PlanCard
62
+ plan={planData}
63
+ isSelected={selectedPlan?.id === planData.id}
64
+ billingCycle="monthly"
65
+ onSelect={handlePlanSelect}
66
+ isActive={false}
67
+ />
68
+ ```
69
+
70
+ #### `PlansGrid`
71
+ Grid layout container for displaying multiple plan cards.
72
+
73
+ **Props:**
74
+ ```typescript
75
+ interface PlansGridProps {
76
+ plans: Plan[]; // Array of plans to display
77
+ selectedPlan: Plan | null; // Currently selected plan
78
+ billingCycle: 'monthly' | 'yearly'; // Billing cycle filter
79
+ onPlanSelect: (plan: Plan) => void; // Plan selection handler
80
+ activeSubscription?: Subscription; // User's current subscription
81
+ }
82
+ ```
83
+
84
+ #### `PlanSelector`
85
+ Complete plan selection interface with filtering and selection.
86
+
87
+ **Props:**
88
+ ```typescript
89
+ interface PlanSelectorProps {
90
+ onPlanSelect: (plan: Plan) => void; // Plan selection callback
91
+ initialBillingCycle?: 'monthly' | 'yearly'; // Default billing cycle
92
+ showBillingToggle?: boolean; // Show billing cycle toggle
93
+ showTierFilter?: boolean; // Show tier filtering dropdown
94
+ }
95
+ ```
96
+
97
+ #### `BillingCycleToggle`
98
+ Toggle component for switching between monthly and yearly billing.
99
+
100
+ **Props:**
101
+ ```typescript
102
+ interface BillingCycleToggleProps {
103
+ value: 'monthly' | 'yearly'; // Current billing cycle
104
+ onChange: (cycle: 'monthly' | 'yearly') => void; // Change handler
105
+ disabled?: boolean; // Disable the toggle
106
+ }
107
+ ```
108
+
109
+ #### `TierFilterDropdown`
110
+ Dropdown for filtering plans by tier/category.
111
+
112
+ **Props:**
113
+ ```typescript
114
+ interface TierFilterDropdownProps {
115
+ value: string; // Current filter value
116
+ onChange: (value: string) => void; // Filter change handler
117
+ options: DropdownOption[]; // Available filter options
118
+ disabled?: boolean; // Disable the dropdown
119
+ }
120
+ ```
121
+
122
+ ### Payment Components
123
+
124
+ #### `ChangeCardButton`
125
+ Button component for updating payment methods.
126
+
127
+ **Props:**
128
+ ```typescript
129
+ interface ChangeCardButtonProps {
130
+ onSuccess?: () => void; // Success callback
131
+ onError?: (error: string) => void; // Error callback
132
+ customerId: string; // Customer ID for payment method update
133
+ }
134
+ ```
135
+
136
+ #### `PaymentSuccessView`
137
+ Success page component after successful payment.
138
+
139
+ **Usage:**
140
+ ```jsx
141
+ <PaymentSuccessView />
142
+ ```
143
+
144
+ #### `PaymentCancelView`
145
+ Cancellation page component when payment is cancelled.
146
+
147
+ **Usage:**
148
+ ```jsx
149
+ <PaymentCancelView />
150
+ ```
151
+
152
+ ### Subscription Components
153
+
154
+ #### `SubscriptionDetails`
155
+ Displays detailed information about user's subscription.
156
+
157
+ **Props:**
158
+ ```typescript
159
+ interface SubscriptionDetailsProps {
160
+ subscription: Subscription; // Subscription data
161
+ onCancel?: () => void; // Cancel subscription callback
162
+ onUpgrade?: () => void; // Upgrade subscription callback
163
+ showActions?: boolean; // Show action buttons
164
+ }
165
+ ```
166
+
167
+ ### Transaction Components
168
+
169
+ #### `TransactionList`
170
+ List component for displaying transaction history.
171
+
172
+ **Props:**
173
+ ```typescript
174
+ interface TransactionListProps {
175
+ externalId: string; // Customer external ID
176
+ filters?: TransactionFilters; // Optional transaction filters
177
+ onTransactionClick?: (transaction: Transaction) => void; // Transaction click handler
178
+ }
179
+ ```
180
+
181
+ #### `TransactionModal`
182
+ Modal component for displaying transaction details.
183
+
184
+ **Props:**
185
+ ```typescript
186
+ interface TransactionModalProps {
187
+ transaction: Transaction | null; // Transaction to display
188
+ isOpen: boolean; // Modal open state
189
+ onClose: () => void; // Close modal callback
190
+ }
191
+ ```
192
+
193
+ ### Email Components
194
+
195
+ #### `EmailEntry`
196
+ Component for email input and management.
197
+
198
+ **Props:**
199
+ ```typescript
200
+ interface EmailEntryProps {
201
+ value: string; // Current email value
202
+ onChange: (email: string) => void; // Email change handler
203
+ onSubmit?: (email: string) => void; // Email submit handler
204
+ placeholder?: string; // Input placeholder
205
+ disabled?: boolean; // Disable input
206
+ }
207
+ ```
208
+
209
+ ### Upgrade Components
210
+
211
+ #### `UpgradeSummary`
212
+ Summary component showing upgrade details and pricing.
213
+
214
+ **Props:**
215
+ ```typescript
216
+ interface UpgradeSummaryProps {
217
+ currentPlan: Plan; // User's current plan
218
+ newPlan: Plan; // Plan to upgrade to
219
+ onConfirm: () => void; // Upgrade confirmation callback
220
+ onCancel: () => void; // Cancel upgrade callback
221
+ }
222
+ ```
223
+
224
+ ### Common Components
225
+
226
+ #### `Layout`
227
+ Main layout wrapper component.
228
+
229
+ **Usage:**
230
+ ```jsx
231
+ <Layout>
232
+ <YourContent />
233
+ </Layout>
234
+ ```
235
+
236
+ #### `LogoInline`
237
+ Inline logo component.
238
+
239
+ **Usage:**
240
+ ```jsx
241
+ <LogoInline />
242
+ ```
243
+
244
+ #### `Pagination`
245
+ Pagination component for paginated data.
246
+
247
+ **Props:**
248
+ ```typescript
249
+ interface PaginationProps {
250
+ currentPage: number; // Current page number
251
+ totalPages: number; // Total number of pages
252
+ onPageChange: (page: number) => void; // Page change handler
253
+ disabled?: boolean; // Disable pagination
254
+ }
255
+ ```
256
+
257
+ ### Icon Components
258
+
259
+ #### `CheckIcon`
260
+ Check mark icon component.
261
+
262
+ **Props:**
263
+ ```typescript
264
+ interface CheckIconProps {
265
+ className?: string; // CSS classes
266
+ size?: number; // Icon size
267
+ }
268
+ ```
269
+
270
+ ---
271
+
272
+ ## 🪝 Hooks
273
+
274
+ ### `usePlans()`
275
+ Hook for managing plan data and filtering.
276
+
277
+ **Returns:**
278
+ ```typescript
279
+ interface UsePlansReturn {
280
+ // Data
281
+ plans: Plan[]; // All available plans
282
+ filteredPlans: Plan[]; // Filtered plans based on current filters
283
+ selectedPlan: Plan | null; // Currently selected plan
284
+
285
+ // Filters
286
+ tierFilter: string; // Current tier filter
287
+ billingCycle: 'monthly' | 'yearly'; // Current billing cycle
288
+
289
+ // Loading states
290
+ loading: boolean; // Loading state
291
+ error: string | null; // Error message
292
+
293
+ // Actions
294
+ fetchPlans: () => Promise<void>; // Fetch plans from API
295
+ setSelectedPlan: (plan: Plan | null) => void; // Set selected plan
296
+ setTierFilter: (filter: string) => void; // Set tier filter
297
+ setBillingCycle: (cycle: 'monthly' | 'yearly') => void; // Set billing cycle
298
+ clearPlans: () => void; // Clear all plans
299
+
300
+ // Computed values
301
+ dropdownOptions: DropdownOption[]; // Options for tier dropdown
302
+ currentSelectionText: string; // Current filter description
303
+
304
+ // Plan operations
305
+ handlePlanSelect: (plan: Plan) => void; // Handle plan selection
306
+ handleUpgrade: (email: string) => Promise<void>; // Handle plan upgrade
307
+ }
308
+ ```
309
+
310
+ **Usage:**
311
+ ```jsx
312
+ const {
313
+ plans,
314
+ filteredPlans,
315
+ selectedPlan,
316
+ loading,
317
+ error,
318
+ fetchPlans,
319
+ setSelectedPlan,
320
+ setBillingCycle
321
+ } = usePlans();
322
+ ```
323
+
324
+ ### `useSubscription()`
325
+ Hook for managing subscription data.
326
+
327
+ **Returns:**
328
+ ```typescript
329
+ interface UseSubscriptionReturn {
330
+ subscription: Subscription | null; // Current subscription
331
+ loading: boolean; // Loading state
332
+ error: string | null; // Error message
333
+ fetchSubscription: (externalId: string) => Promise<void>; // Fetch subscription
334
+ cancelSubscription: (externalId: string, options?: CancelOptions) => Promise<void>; // Cancel subscription
335
+ }
336
+ ```
337
+
338
+ ### `useTransactions()`
339
+ Hook for managing transaction history.
340
+
341
+ **Props:**
342
+ ```typescript
343
+ interface UseTransactionsProps {
344
+ externalId: string; // Customer external ID
345
+ filters?: TransactionFilters; // Transaction filters
346
+ }
347
+ ```
348
+
349
+ **Returns:**
350
+ ```typescript
351
+ interface UseTransactionsReturn {
352
+ transactions: Transaction[]; // Transaction list
353
+ loading: boolean; // Loading state
354
+ error: string | null; // Error message
355
+ pagination: PaginationMeta; // Pagination information
356
+ fetchTransactions: () => Promise<void>; // Fetch transactions
357
+ downloadInvoice: (transactionId: string) => Promise<void>; // Download invoice
358
+ }
359
+ ```
360
+
361
+ ### `usePagination()`
362
+ Hook for managing pagination state.
363
+
364
+ **Props:**
365
+ ```typescript
366
+ interface UsePaginationProps {
367
+ totalItems: number; // Total number of items
368
+ itemsPerPage: number; // Items per page
369
+ initialPage?: number; // Initial page number
370
+ }
371
+ ```
372
+
373
+ **Returns:**
374
+ ```typescript
375
+ interface UsePaginationReturn {
376
+ currentPage: number; // Current page
377
+ totalPages: number; // Total pages
378
+ hasNextPage: boolean; // Has next page
379
+ hasPreviousPage: boolean; // Has previous page
380
+ goToPage: (page: number) => void; // Go to specific page
381
+ nextPage: () => void; // Go to next page
382
+ previousPage: () => void; // Go to previous page
383
+ }
384
+ ```
385
+
386
+ ### `useCancelSubscription()`
387
+ Hook for cancelling subscriptions.
388
+
389
+ **Props:**
390
+ ```typescript
391
+ interface UseCancelSubscriptionProps {
392
+ externalId: string; // Customer external ID
393
+ onSuccess?: () => void; // Success callback
394
+ onError?: (error: string) => void; // Error callback
395
+ }
396
+ ```
397
+
398
+ **Returns:**
399
+ ```typescript
400
+ interface UseCancelSubscriptionReturn {
401
+ cancelSubscription: (options?: CancelOptions) => Promise<void>; // Cancel function
402
+ loading: boolean; // Loading state
403
+ error: string | null; // Error message
404
+ }
405
+ ```
406
+
407
+ ### `useCustomerPortal()`
408
+ Hook for customer portal functionality.
409
+
410
+ **Props:**
411
+ ```typescript
412
+ interface UseCustomerPortalProps {
413
+ externalId: string; // Customer external ID
414
+ }
415
+ ```
416
+
417
+ **Returns:**
418
+ ```typescript
419
+ interface UseCustomerPortalReturn {
420
+ redirectToPortal: () => Promise<void>; // Redirect to customer portal
421
+ loading: boolean; // Loading state
422
+ error: string | null; // Error message
423
+ }
424
+ ```
425
+
426
+ ### `useEmailManagement()`
427
+ Hook for email management functionality.
428
+
429
+ **Returns:**
430
+ ```typescript
431
+ interface UseEmailManagementReturn {
432
+ email: string; // Current email
433
+ setEmail: (email: string) => void; // Set email
434
+ validateEmail: (email: string) => boolean; // Validate email
435
+ saveEmail: () => Promise<void>; // Save email
436
+ loading: boolean; // Loading state
437
+ error: string | null; // Error message
438
+ }
439
+ ```
440
+
441
+ ---
442
+
443
+ ## 🌐 API Functions
444
+
445
+ ### Plans API
446
+
447
+ #### `plansApi.getPlans()`
448
+ Fetch all available plans.
449
+
450
+ **Request:** No payload required
451
+
452
+ **Response:**
453
+ ```typescript
454
+ ApiResponse<Plan[]>
455
+ ```
456
+
457
+ **Usage:**
458
+ ```javascript
459
+ const response = await plansApi.getPlans();
460
+ if (response.success) {
461
+ console.log(response.data); // Plan[]
462
+ }
463
+ ```
464
+
465
+ #### `plansApi.getPlanByCode(code, externalId, queryParams?)`
466
+ Fetch specific plan by code.
467
+
468
+ **Parameters:**
469
+ - `code: string` - Plan code
470
+ - `externalId: string` - Customer external ID
471
+ - `queryParams?: { paymentMethodId?: string; couponCode?: string }` - Optional query parameters
472
+
473
+ **Response:**
474
+ ```typescript
475
+ ApiResponse<Plan>
476
+ ```
477
+
478
+ #### `plansApi.createPaymentSession(planCode, options?)`
479
+ Create payment session for checkout.
480
+
481
+ **Parameters:**
482
+ - `planCode: string` - Plan code to purchase
483
+ - `options?: { amount?: number; currency?: string; customerEmail?: string; couponCode?: string }` - Optional parameters
484
+
485
+ **Payload:**
486
+ ```typescript
487
+ {
488
+ planCode: string;
489
+ currency?: string; // Default: 'USD'
490
+ returnUrl: string; // Auto-generated: ${origin}/payment-success
491
+ cancelUrl: string; // Auto-generated: ${origin}/payment-cancel
492
+ customerEmail?: string; // Optional customer email
493
+ couponCode?: string; // Optional coupon code
494
+ amount?: number; // Optional custom amount
495
+ }
496
+ ```
497
+
498
+ **Response:**
499
+ ```typescript
500
+ ApiResponse<{
501
+ checkoutUrl: string; // Hosted checkout URL
502
+ gateway: string; // Payment gateway used
503
+ sessionId?: string; // Session ID
504
+ paymentId?: string; // Payment ID
505
+ }>
506
+ ```
507
+
508
+ ### Checkout API
509
+
510
+ #### `checkoutApi.getCheckoutDetails(planCode, queryParams?)`
511
+ Get checkout details including pricing and taxes.
512
+
513
+ **Parameters:**
514
+ - `planCode: string` - Plan code
515
+ - `queryParams?: { externalId?: string; paymentMethodId?: string; couponCode?: string }` - Optional parameters
516
+
517
+ **Response:**
518
+ ```typescript
519
+ ApiResponse<CheckoutDetails>
520
+ ```
521
+
522
+ ### Subscription API
523
+
524
+ #### `subscriptionApi.getActiveSubscription(externalId)`
525
+ Get user's active subscription.
526
+
527
+ **Parameters:**
528
+ - `externalId: string` - Customer external ID
529
+
530
+ **Response:**
531
+ ```typescript
532
+ ApiResponse<Subscription>
533
+ ```
534
+
535
+ #### `subscriptionApi.cancelSubscription(externalId, options?)`
536
+ Cancel user's subscription.
537
+
538
+ **Parameters:**
539
+ - `externalId: string` - Customer external ID
540
+ - `options?: { cancellationMode?: string; cancellationReason?: string }` - Cancellation options
541
+
542
+ **Response:**
543
+ ```typescript
544
+ ApiResponse<any>
545
+ ```
546
+
547
+ ### Customer API
548
+
549
+ #### `customerApi.getCustomer(externalId)`
550
+ Get customer information.
551
+
552
+ **Parameters:**
553
+ - `externalId: string` - Customer external ID
554
+
555
+ **Response:**
556
+ ```typescript
557
+ ApiResponse<Customer>
558
+ ```
559
+
560
+ ### Transaction API
561
+
562
+ #### `transactionApi.getTransactions(externalId, filters?)`
563
+ Get customer's transaction history.
564
+
565
+ **Parameters:**
566
+ - `externalId: string` - Customer external ID
567
+ - `filters?: TransactionFilters` - Optional filters
568
+
569
+ **Filters:**
570
+ ```typescript
571
+ interface TransactionFilters {
572
+ startDate?: string; // ISO date string
573
+ endDate?: string; // ISO date string
574
+ status?: string; // Transaction status
575
+ page?: number; // Page number (1-based)
576
+ limit?: number; // Items per page
577
+ }
578
+ ```
579
+
580
+ **Response:**
581
+ ```typescript
582
+ ApiResponse<PaginatedResponse<Transaction>>
583
+ ```
584
+
585
+ #### `transactionApi.getInvoice(transactionId)`
586
+ Get invoice URL for a transaction.
587
+
588
+ **Parameters:**
589
+ - `transactionId: string` - Transaction ID
590
+
591
+ **Response:**
592
+ ```typescript
593
+ ApiResponse<{ invoiceUrl: string }>
594
+ ```
595
+
596
+ ---
597
+
598
+ ## 🛠 Utility Functions
599
+
600
+ ### Plan Utilities
601
+
602
+ - `getPlanFeatures(plan: Plan): string[]` - Extract features from plan
603
+ - `getCandidateUnits(plans: Plan[]): string[]` - Get unique plan units
604
+ - `getUniqueCandidateUnits(plans: Plan[]): string[]` - Get unique candidate units
605
+ - `getDropdownOptions(plans: Plan[]): DropdownOption[]` - Generate dropdown options
606
+ - `getCurrentSelectionText(filter: string, options: DropdownOption[]): string` - Get current filter text
607
+ - `filterPlansByBillingCycle(plans: Plan[], cycle: 'monthly' | 'yearly'): Plan[]` - Filter by billing cycle
608
+ - `filterPlansByTier(plans: Plan[], tier: string): Plan[]` - Filter by tier
609
+ - `isPlanPopular(plan: Plan): boolean` - Check if plan is marked as popular
610
+ - `getPlanDescription(plan: Plan): string` - Get plan description
611
+ - `formatDate(date: string): string` - Format date string
612
+
613
+ ---
614
+
615
+ ## 📝 TypeScript Types
616
+
617
+ ### Core Types
618
+
619
+ ```typescript
620
+ interface Plan {
621
+ id: string;
622
+ name: string;
623
+ code: string;
624
+ fixedCost: number;
625
+ paymentMode: string;
626
+ interval: string;
627
+ successRedirectUrl: string;
628
+ order: number;
629
+ isDefault: boolean;
630
+ intervalCount: number;
631
+ projectId: string;
632
+ charges: any[];
633
+ description?: string;
634
+ price?: number;
635
+ billingFrequency?: 'monthly' | 'yearly' | 'one-time';
636
+ features?: string[];
637
+ isPopular?: boolean;
638
+ }
639
+
640
+ interface Subscription {
641
+ id: string;
642
+ isActive: boolean;
643
+ membershipDate: string;
644
+ expiryDate: string;
645
+ meta: Record<string, any>;
646
+ isPaymentFailed?: boolean;
647
+ transactionCode?: string;
648
+ usage: Record<string, any>;
649
+ plan: {
650
+ name: string;
651
+ code: string;
652
+ fixedCost: number;
653
+ paymentMode: string;
654
+ interval: string;
655
+ trialDays?: number;
656
+ charges: Array<{
657
+ billableMetric: {
658
+ code: string;
659
+ name: string;
660
+ };
661
+ chargeModel: string;
662
+ properties: Record<string, any>;
663
+ }>;
664
+ charge: number;
665
+ canceledOn: string | null;
666
+ features?: string[];
667
+ };
668
+ tax?: number;
669
+ amount?: number;
670
+ customer?: {
671
+ paymentMethodCurrency: string;
672
+ paymentMethodId?: string;
673
+ };
674
+ gracePeriodEndDate?: string;
675
+ remainingGracePeriodDays?: number;
676
+ }
677
+
678
+ interface Transaction {
679
+ id: string;
680
+ transactionCode?: string;
681
+ customerId?: string;
682
+ membershipId?: string;
683
+ purchaseId?: string;
684
+ amount: string | number;
685
+ tax?: number;
686
+ charge?: string | number;
687
+ membershipDate: string;
688
+ expiryDate: string;
689
+ transactionDate?: string;
690
+ transactionStatus: string;
691
+ paymentGateway?: string;
692
+ planName?: string;
693
+ planInterval?: string;
694
+ currency?: string;
695
+ coupon?: string | null;
696
+ discountAmt?: string | number;
697
+ isPlanActive?: boolean;
698
+ order?: number;
699
+ meta?: Record<string, any>;
700
+ invoiceUrl?: string;
701
+ }
702
+
703
+ interface ApiResponse<T> {
704
+ success: boolean;
705
+ data?: T;
706
+ error?: string;
707
+ }
708
+ ```
709
+
710
+ ---
711
+
712
+ ## 🚀 Complete Usage Example
713
+
714
+ ```jsx
715
+ import React from 'react';
716
+ import {
717
+ configureSubOS,
718
+ PlanSelector,
719
+ SubscriptionDetails,
720
+ TransactionList,
721
+ usePlans,
722
+ useSubscription,
723
+ useTransactions
724
+ } from 'subos-frontend';
725
+ import 'subos-frontend/style.css';
726
+
727
+ // Configure SubOS
728
+ configureSubOS({
729
+ apiEndpoint: 'https://api.example.com/v1',
730
+ projectId: 'your-project-id',
731
+ stripePublishableKey: 'pk_test_...',
732
+ appName: 'My SaaS App'
733
+ });
734
+
735
+ function SubscriptionApp() {
736
+ const { selectedPlan, handlePlanSelect } = usePlans();
737
+ const { subscription } = useSubscription();
738
+ const { transactions } = useTransactions({
739
+ externalId: 'customer-123'
740
+ });
741
+
742
+ return (
743
+ <div className="app">
744
+ <h1>Subscription Management</h1>
745
+
746
+ {/* Plan Selection */}
747
+ <section>
748
+ <h2>Choose Your Plan</h2>
749
+ <PlanSelector onPlanSelect={handlePlanSelect} />
750
+ </section>
751
+
752
+ {/* Current Subscription */}
753
+ {subscription && (
754
+ <section>
755
+ <h2>Current Subscription</h2>
756
+ <SubscriptionDetails
757
+ subscription={subscription}
758
+ showActions={true}
759
+ />
760
+ </section>
761
+ )}
762
+
763
+ {/* Transaction History */}
764
+ <section>
765
+ <h2>Transaction History</h2>
766
+ <TransactionList externalId="customer-123" />
767
+ </section>
768
+ </div>
769
+ );
770
+ }
771
+
772
+ export default SubscriptionApp;
773
+ ```
774
+
775
+ ---
776
+
777
+ ## 🔧 Configuration Options
778
+
779
+ ### Environment Variables
780
+ ```bash
781
+ VITE_API_ENDPOINT=https://your-api.com/api/v1
782
+ VITE_PROJECT_ID=your-project-id
783
+ VITE_STRIPE_PUBLISHABLE_KEY=pk_test_your_stripe_key
784
+ VITE_APP_NAME=Your App Name
785
+ VITE_APP_ENVIRONMENT=production
786
+ ```
787
+
788
+ ### Runtime Configuration
789
+ ```javascript
790
+ configureSubOS({
791
+ apiEndpoint: string; // Required: API base URL
792
+ projectId: string; // Required: Project identifier
793
+ stripePublishableKey: string; // Required: Stripe publishable key
794
+ appName?: string; // Optional: Application name
795
+ appEnvironment?: string; // Optional: Environment (development/production)
796
+ });
797
+ ```
798
+
799
+ ---
800
+
801
+ ## 📋 Requirements
802
+
803
+ - **React**: >=18
804
+ - **React DOM**: >=18
805
+ - **React Router DOM**: >=6
806
+ - **Stripe**: @stripe/react-stripe-js, @stripe/stripe-js
807
+
808
+ ---
809
+
810
+ ## 🎨 Styling
811
+
812
+ The package includes pre-built CSS that should be imported:
813
+
814
+ ```javascript
815
+ import 'subos-frontend/style.css';
816
+ ```
817
+
818
+ Components use Tailwind CSS classes and can be customized by overriding the CSS variables or classes.
819
+
820
+ ---
821
+
822
+ This documentation provides a complete reference for integrating and using the SubOS Frontend package in your React applications. Each component and hook is designed to work independently or together to create a complete subscription management experience.