|
| 1 | +--- |
| 2 | +title: "Subscription Settings" |
| 3 | +linkTitle: "Subscription Settings" |
| 4 | +weight: 4 |
| 5 | +description: > |
| 6 | + Understanding and configuring subscription settings |
| 7 | +--- |
| 8 | + |
| 9 | +## Overview |
| 10 | + |
| 11 | +Subscription settings in @fireact.dev/saas provide a way to store and manage subscription-specific configuration values. These settings are stored in the `settings` property of subscription documents in Firestore for security reasons, as this ensures that only backend operations can modify critical subscription properties while allowing frontend configuration of specific settings. |
| 12 | + |
| 13 | +## Demo Component |
| 14 | + |
| 15 | +The package includes a demo `SubscriptionSettings` component ([source code](https://github.com/fireact-dev/saas/blob/main/src/components/SubscriptionSettings.tsx)) that showcases how to implement settings management. However, since subscription settings are typically specific to your SaaS application's features and requirements, it's recommended to build your own settings component using the demo as a reference. |
| 16 | + |
| 17 | +The demo component demonstrates: |
| 18 | +- How to read and update settings |
| 19 | +- How to handle form submission |
| 20 | +- How to implement validation |
| 21 | +- How to manage the loading state |
| 22 | +- How to handle success/error messages |
| 23 | + |
| 24 | +You should create your own settings component that aligns with your specific: |
| 25 | +- Business requirements |
| 26 | +- UI/UX preferences |
| 27 | +- Custom settings fields |
| 28 | +- Validation rules |
| 29 | +- Error handling |
| 30 | + |
| 31 | +## Configuration |
| 32 | + |
| 33 | +Settings are defined in your `saasConfig.json` under the `settings` property. Each setting requires specific configuration properties: |
| 34 | + |
| 35 | +```json |
| 36 | +{ |
| 37 | + "settings": { |
| 38 | + "name": { |
| 39 | + "type": "string", |
| 40 | + "required": true, |
| 41 | + "label": "subscription.name", |
| 42 | + "placeholder": "subscription.namePlaceholder" |
| 43 | + } |
| 44 | + } |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +### Setting Properties |
| 49 | + |
| 50 | +- `type`: The input type (e.g., "string", "number", "email") |
| 51 | +- `required`: Boolean indicating if the field is mandatory |
| 52 | +- `label`: Translation key for the field label |
| 53 | +- `placeholder`: Translation key for the input placeholder |
| 54 | + |
| 55 | +## Adding New Settings |
| 56 | + |
| 57 | +To add a new setting to your subscription: |
| 58 | + |
| 59 | +1. Add the setting configuration to `saasConfig.json`: |
| 60 | +```json |
| 61 | +{ |
| 62 | + "settings": { |
| 63 | + "name": { |
| 64 | + "type": "string", |
| 65 | + "required": true, |
| 66 | + "label": "subscription.name", |
| 67 | + "placeholder": "subscription.namePlaceholder" |
| 68 | + }, |
| 69 | + "companySize": { |
| 70 | + "type": "number", |
| 71 | + "required": false, |
| 72 | + "label": "subscription.companySize", |
| 73 | + "placeholder": "subscription.companySizePlaceholder" |
| 74 | + } |
| 75 | + } |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +2. Add corresponding translations to your i18n files: |
| 80 | +```json |
| 81 | +{ |
| 82 | + "subscription": { |
| 83 | + "companySize": "Company Size", |
| 84 | + "companySizePlaceholder": "Enter number of employees" |
| 85 | + } |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +3. Update your TypeScript types (if using TypeScript): |
| 90 | +```typescript |
| 91 | +interface Settings { |
| 92 | + name: string; |
| 93 | + companySize?: number; |
| 94 | +} |
| 95 | +``` |
| 96 | + |
| 97 | +## Security |
| 98 | + |
| 99 | +Settings are protected by Firestore security rules that ensure only subscription administrators can modify the settings property. Other subscription properties remain protected and can only be modified through backend operations. |
| 100 | + |
| 101 | +The security rules enforce that: |
| 102 | +1. Only users with admin permission in the subscription can modify settings |
| 103 | +2. Only the `settings` property can be modified via frontend operations |
| 104 | +3. Other subscription properties (like billing, permissions, etc.) can only be modified through backend cloud functions |
| 105 | + |
| 106 | +Example security rule: |
| 107 | +```javascript |
| 108 | +match /subscriptions/{docId} { |
| 109 | + // Only subscription admins can update settings |
| 110 | + allow update: if request.auth != null |
| 111 | + && resource.data.permissions.admin.hasAny([request.auth.uid]) |
| 112 | + && request.resource.data.diff(resource.data).affectedKeys() |
| 113 | + .hasOnly(['settings']); |
| 114 | + |
| 115 | + // Other operations are restricted |
| 116 | + allow create, delete: if false; |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | +This ensures that: |
| 121 | +- Only subscription administrators can modify settings |
| 122 | +- Regular users cannot modify settings even if they have access to the subscription |
| 123 | +- No one can modify other critical subscription properties through frontend operations |
| 124 | + |
| 125 | +## Building Your Own Settings Component |
| 126 | + |
| 127 | +When building your own settings component, consider: |
| 128 | + |
| 129 | +1. **State Management**: Use the subscription context to access and update settings: |
| 130 | +```typescript |
| 131 | +const { subscription, updateSubscription } = useSubscription(); |
| 132 | +const [settings, setSettings] = useState(subscription?.settings || {}); |
| 133 | +``` |
| 134 | + |
| 135 | +2. **Form Handling**: Implement proper form validation and submission: |
| 136 | +```typescript |
| 137 | +const handleSubmit = async (e: React.FormEvent) => { |
| 138 | + e.preventDefault(); |
| 139 | + // Validate settings |
| 140 | + // Update Firestore |
| 141 | + // Handle success/error |
| 142 | +}; |
| 143 | +``` |
| 144 | + |
| 145 | +3. **Error Handling**: Implement proper error handling and user feedback: |
| 146 | +```typescript |
| 147 | +try { |
| 148 | + await updateDoc(subscriptionRef, { settings: newSettings }); |
| 149 | + // Show success message |
| 150 | +} catch (error) { |
| 151 | + // Show error message |
| 152 | +} |
| 153 | +``` |
| 154 | + |
| 155 | +4. **Loading States**: Handle loading states to improve user experience: |
| 156 | +```typescript |
| 157 | +const [isSubmitting, setIsSubmitting] = useState(false); |
| 158 | +``` |
| 159 | + |
| 160 | +5. **Type Safety**: If using TypeScript, define proper types for your settings: |
| 161 | +```typescript |
| 162 | +interface CustomSettings { |
| 163 | + name: string; |
| 164 | + // Add your custom settings |
| 165 | +} |
| 166 | +``` |
| 167 | + |
| 168 | +## Best Practices |
| 169 | + |
| 170 | +1. **Keep Settings Minimal**: Only store configuration that needs to be editable by subscription admins. |
| 171 | + |
| 172 | +2. **Use Appropriate Types**: Choose the correct input type for each setting to ensure proper validation. |
| 173 | + |
| 174 | +3. **Provide Clear Labels**: Use descriptive labels and placeholders to guide users. |
| 175 | + |
| 176 | +4. **Consider Validation**: Add any necessary frontend validation for setting values. |
| 177 | + |
| 178 | +5. **Security First**: Remember that settings are only editable by subscription admins - don't store sensitive information here. |
| 179 | + |
| 180 | +## Accessing Settings |
| 181 | + |
| 182 | +Settings can be accessed in your components using the subscription context: |
| 183 | + |
| 184 | +```typescript |
| 185 | +const { subscription } = useSubscription(); |
| 186 | +const settings = subscription?.settings; |
| 187 | +``` |
| 188 | + |
| 189 | +## Default Values |
| 190 | + |
| 191 | +When creating a new subscription, ensure you provide default values for required settings. These can be set in your cloud functions when creating new subscriptions: |
| 192 | + |
| 193 | +```typescript |
| 194 | +const defaultSettings = { |
| 195 | + name: "New Subscription" |
| 196 | +}; |
0 commit comments