feat(admin): add configurable sponsor ad pricing via admin settings #448
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a new "Monetization" section to the admin settings page, allowing administrators to configure sponsor ad pricing without code changes. The pricing displayed to users is now configurable while maintaining Stripe price IDs as the source of truth for actual charges.
Changes
1. New Settings Utility Functions
File:
lib/utils/settings.tsWhat was added:
getSponsorAdsEnabled()- Returns whether sponsor ads feature is enabled (default: true)getSponsorAdWeeklyPrice()- Returns weekly price in cents (default: 10000)getSponsorAdMonthlyPrice()- Returns monthly price in cents (default: 30000)getSponsorAdCurrency()- Returns currency code (default: USD)getSponsorAdPricingConfig()- Returns all pricing configuration as an objectReason: These utility functions follow the existing pattern in the codebase for reading settings from the YAML configuration via ConfigManager, providing a clean API for accessing sponsor ad pricing settings throughout the application.
2. Admin Settings UI - Monetization Section
File:
components/admin/settings/SettingsPage.tsxWhat was added:
SponsorAdsSettingsandMonetizationConfigSettingsSettingsinterface to includemonetizationpropertySettingInputcomponent import (existing component, newly used here)Reason: Provides administrators with a user-friendly interface to configure sponsor ad pricing without requiring code deployments or environment variable changes.
3. Sponsor Form Component Refactor
File:
components/sponsor-ads/sponsor-form.tsxProblem: The sponsor form had hardcoded pricing values using the
SponsorAdPricingenum from constants, and currency was hardcoded to USD. This made it impossible to change pricing without code changes.What was changed:
PricingConfiginterface withweeklyPrice,monthlyPrice, andcurrencypropertiespricingConfigas a required prop toSponsorFormPropsformatCurrency()function to accept currency parameter instead of hardcoding USDPRICING_OPTIONSconstant with dynamicgetPricingOptions()function that generates options from configpricingOptionsmemoized value generated frompricingConfigpropselectedPricinguseMemo to use dynamicpricingOptionsinstead of static constantformatCurrency()calls to pass the configured currencyWhat was deleted:
SponsorAdPricingimport from@/lib/constantsPRICING_OPTIONSconstant arrayReason for deletion: The static constant was replaced with a dynamic function that generates pricing options from the configuration passed via props, allowing runtime configuration of pricing.
Impact: The component now receives pricing configuration as props, making it flexible and configurable. Currency formatting now respects the configured currency instead of always using USD.
4. Sponsor Page Updates
File:
app/[locale]/sponsor/page.tsxWhat was added:
notFoundfromnext/navigationgetSponsorAdPricingConfigandgetSponsorAdsEnabledfrom settings utilitiespricingConfigprop toSponsorFormcomponentReason: The page now checks if the sponsor ads feature is enabled before rendering, and passes the configurable pricing to the form component.
5. Sponsor Ad Service Updates
File:
lib/services/sponsor-ad.service.tsWhat was added:
getSponsorAdWeeklyPrice,getSponsorAdMonthlyPrice, andgetSponsorAdCurrencyfrom settings utilitiesgetCurrency()method that returns the configured currencyWhat was changed:
getAmountForInterval()method to use configurable pricing from settings with fallback toSponsorAdPricingenum constantsReason: The service layer now uses configurable pricing while maintaining backward compatibility through fallback to the original constant values if settings are not configured.
6. Translation Files
Files: All 21 locale files in
messages/directory (ar, bg, de, en, es, fr, he, hi, id, it, ja, ko, nl, pl, pt, ru, th, tr, uk, vi, zh)What was added to each file under
admin.ADMIN_SETTINGS_PAGE:MONETIZATION_TITLE- Section titleMONETIZATION_DESC- Section descriptionMONETIZATION_SPONSOR_ADS_TITLE- Subsection titleMONETIZATION_SPONSOR_ADS_DESC- Subsection description with note about Stripe price IDsSPONSOR_ADS_ENABLED_LABEL- Toggle labelSPONSOR_ADS_ENABLED_DESC- Toggle descriptionSPONSOR_ADS_WEEKLY_PRICE_LABEL- Weekly price input labelSPONSOR_ADS_WEEKLY_PRICE_DESC- Weekly price input descriptionSPONSOR_ADS_MONTHLY_PRICE_LABEL- Monthly price input labelSPONSOR_ADS_MONTHLY_PRICE_DESC- Monthly price input descriptionSPONSOR_ADS_CURRENCY_LABEL- Currency selector labelSPONSOR_ADS_CURRENCY_DESC- Currency selector descriptionReason: All UI text for the new monetization settings section needs to be translatable to support the application's internationalization.
Backward Compatibility
SponsorAdPricingenum inlib/constants.tsis preserved and used as fallback defaultsImportant Notes
Summary by cubic
Adds admin controls to configure sponsor ad pricing and currency, and updates the sponsor flow to use these values at runtime. Pricing is display-only; Stripe price IDs still control actual charges.
Written for commit 3ed996e. Summary will update on new commits.