Skip to content

Conversation

@ariefgp
Copy link
Collaborator

@ariefgp ariefgp commented Dec 31, 2025

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.ts

What 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 object

Reason: 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.tsx

What was added:

  • New TypeScript interfaces: SponsorAdsSettings and MonetizationConfigSettings
  • Updated Settings interface to include monetization property
  • Added SettingInput component import (existing component, newly used here)
  • New "Monetization" accordion section with sponsor ads configuration containing:
    • Enable/disable toggle for sponsor ads
    • Weekly price input field (in cents)
    • Monthly price input field (in cents)
    • Currency dropdown selector (USD, EUR, GBP, CAD, AUD)

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.tsx

Problem: The sponsor form had hardcoded pricing values using the SponsorAdPricing enum from constants, and currency was hardcoded to USD. This made it impossible to change pricing without code changes.

What was changed:

  • Added new PricingConfig interface with weeklyPrice, monthlyPrice, and currency properties
  • Added pricingConfig as a required prop to SponsorFormProps
  • Updated formatCurrency() function to accept currency parameter instead of hardcoding USD
  • Replaced static PRICING_OPTIONS constant with dynamic getPricingOptions() function that generates options from config
  • Added pricingOptions memoized value generated from pricingConfig prop
  • Updated selectedPricing useMemo to use dynamic pricingOptions instead of static constant
  • Updated all formatCurrency() calls to pass the configured currency

What was deleted:

  • Removed SponsorAdPricing import from @/lib/constants
  • Removed static PRICING_OPTIONS constant array

Reason 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.tsx

What was added:

  • Import of notFound from next/navigation
  • Import of getSponsorAdPricingConfig and getSponsorAdsEnabled from settings utilities
  • Feature toggle check that returns 404 if sponsor ads are disabled
  • Retrieval of pricing configuration from settings
  • Passing pricingConfig prop to SponsorForm component

Reason: 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.ts

What was added:

  • Import of getSponsorAdWeeklyPrice, getSponsorAdMonthlyPrice, and getSponsorAdCurrency from settings utilities
  • New getCurrency() method that returns the configured currency

What was changed:

  • Updated getAmountForInterval() method to use configurable pricing from settings with fallback to SponsorAdPricing enum constants

Reason: 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 title
  • MONETIZATION_DESC - Section description
  • MONETIZATION_SPONSOR_ADS_TITLE - Subsection title
  • MONETIZATION_SPONSOR_ADS_DESC - Subsection description with note about Stripe price IDs
  • SPONSOR_ADS_ENABLED_LABEL - Toggle label
  • SPONSOR_ADS_ENABLED_DESC - Toggle description
  • SPONSOR_ADS_WEEKLY_PRICE_LABEL - Weekly price input label
  • SPONSOR_ADS_WEEKLY_PRICE_DESC - Weekly price input description
  • SPONSOR_ADS_MONTHLY_PRICE_LABEL - Monthly price input label
  • SPONSOR_ADS_MONTHLY_PRICE_DESC - Monthly price input description
  • SPONSOR_ADS_CURRENCY_LABEL - Currency selector label
  • SPONSOR_ADS_CURRENCY_DESC - Currency selector description

Reason: All UI text for the new monetization settings section needs to be translatable to support the application's internationalization.

Backward Compatibility

  • The SponsorAdPricing enum in lib/constants.ts is preserved and used as fallback defaults
  • All utility functions return sensible defaults if settings are not configured
  • No database migration is needed
  • Existing sponsor ads are not affected

Important Notes

  • This feature implements display-only pricing - the prices shown to users come from admin settings, but actual charges are determined by Stripe price IDs configured in environment variables
  • The pricing values are stored in cents (e.g., 10000 = $100.00) to maintain consistency with the existing codebase pattern

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.

  • New Features
    • Added a “Monetization” section in admin settings with toggle, weekly/monthly prices (standard currency amounts), and currency, using a new SettingCurrencyInput with symbols and thousand separators.
    • Introduced settings utilities to read sponsor ad config with defaults (weekly: 100, monthly: 300, currency: USD).
    • Refactored SponsorForm to accept a pricingConfig prop, generate dynamic options, and format prices in the selected currency.
    • Updated the sponsor page to respect the feature toggle (404 when disabled) and pass pricingConfig to the form.
    • Service layer now uses configurable prices with fallback to constants and exposes getCurrency; no database changes.
    • Text is localized across 21 locales.

Written for commit 3ed996e. Summary will update on new commits.

  - Add "Monetization" section to admin settings page with sponsor ads configuration
  - Add utility functions in lib/utils/settings.ts for sponsor ad pricing
  - Update SponsorForm to accept dynamic pricing config props
  - Update sponsor page to check feature toggle and pass pricing config
  - Update sponsor-ad.service.ts to use configurable pricing with fallback
  - Add translations for monetization settings to all 21 locale files
@ariefgp ariefgp self-assigned this Dec 31, 2025
@vercel
Copy link

vercel bot commented Dec 31, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
ever-works-website-template Ready Ready Preview, Comment Dec 31, 2025 11:19pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 31, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/admin-sponsor-ad-pricing-settings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

  - Create SettingCurrencyInput component with proper styling matching
    other form fields (rounded borders, focus ring, consistent height)
  - Add currency symbol prefix and thousand separators formatting
  - Change pricing from cents to regular currency values (e.g., 100 vs 10000)
  - Update formatCurrency/formatAmount helpers to remove /100 division
  - Update default values: weekly 100, monthly 300
  - Update translation strings to remove "(in cents)" references
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants