fix: update billing period to match backend validation
continuous-integration/drone/push Build is passing Details

Backend only accepts: 'monthly', 'annual', or null
Frontend was offering: daily, weekly, monthly, quarterly, yearly, lifetime

Changes:
- Update BillingPeriod type to 'monthly' | 'annual' | null
- Update PlanFormModal dropdown to only show valid options
- Update PlanCard formatBillingPeriod to handle new values
- Display 'Annual (Yearly)' in UI but send 'annual' to API

Fixes validation error: 'Must be monthly, annual, or null'
master
Guillermo Pages 3 weeks ago
parent 7c1c3a7568
commit d29bf7884d

@ -13,14 +13,11 @@ export default function PlanCard({ plan, onEdit, onDelete }: PlanCardProps) {
return (cents / 100).toFixed(2); return (cents / 100).toFixed(2);
} }
function formatBillingPeriod(period: string): string { function formatBillingPeriod(period: string | null): string {
if (!period) return 'one-time payment';
const periodMap: Record<string, string> = { const periodMap: Record<string, string> = {
daily: 'per day',
weekly: 'per week',
monthly: 'per month', monthly: 'per month',
quarterly: 'per quarter', annual: 'per year'
yearly: 'per year',
lifetime: 'one-time'
}; };
return periodMap[period] || period; return periodMap[period] || period;
} }

@ -100,17 +100,14 @@ export default function PlanFormModal({
</label> </label>
<select <select
id="billing_period" id="billing_period"
value={formData.billing_period} value={formData.billing_period || ''}
onChange={e => setFormData({ ...formData, billing_period: e.target.value as BillingPeriod })} onChange={e => setFormData({ ...formData, billing_period: (e.target.value || null) as BillingPeriod })}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"
required required
> >
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option> <option value="monthly">Monthly</option>
<option value="quarterly">Quarterly</option> <option value="annual">Annual (Yearly)</option>
<option value="yearly">Yearly</option> <option value="">One-time (No recurring billing)</option>
<option value="lifetime">Lifetime</option>
</select> </select>
</div> </div>

@ -23,7 +23,8 @@ export interface MembershipPlan {
updated_at?: string; // ISO8601 updated_at?: string; // ISO8601
} }
export type BillingPeriod = 'daily' | 'weekly' | 'monthly' | 'quarterly' | 'yearly' | 'lifetime'; // Backend only accepts: 'monthly', 'annual', or null (one-time payment)
export type BillingPeriod = 'monthly' | 'annual' | null;
export interface CreatePlanRequest { export interface CreatePlanRequest {
name: string; name: string;

Loading…
Cancel
Save