Skip to content

Account & Billing

RoutePurpose
/accountAccount settings
/billingBilling management (placeholder)
/upgradePlan selection and purchase

FieldTypeRequiredNotes
Display NametextYes
UsernametextYesRate-limited: 3 changes per 30 days
LanguagedropdownYes100+ languages
TimezonedropdownYes150+ timezones
CountrydropdownYes249+ countries

Username Rate Limiting:

  • Limit: 3 changes per 30-day rolling window
  • Tracking: lastUsernameChangeDate (Timestamp) + usernameChangeCount (number)
  • Reset: After 30 days pass since last change
  • Uniqueness checked against Firestore before update
  • Confirmation dialog shows remaining changes
FieldRequired
Current PasswordYes
New PasswordYes
Confirm PasswordYes (must match)

Strength Indicator (5 bars, 0-100 score):

CriteriaPoints
Length >= 8 chars+20
Lowercase letters+20
Uppercase letters+20
Numbers+20
Special chars (`!@#$%^&*(),.?”:{}<>`)
ScoreLevelBars
0-20Weak1 (red)
21-40Weak2 (red)
41-60Medium3 (yellow)
61-80Medium4 (yellow)
81-100Strong5 (green)

Auto-logout: 5 seconds after successful password change, redirect to /sign-in.

  • Requires valid email format (/^[^\s@]+@[^\s@]+\.[^\s@]+$/)
  • Cannot be same as current email
  • Not available for Google/OAuth accounts
  • Auto-logout: 4.5 seconds after change

Data tracked per session:

  • Status: online / away / offline
  • Browser name and OS
  • Timezone
  • Last seen timestamp

Source: Firebase Realtime Database at presence/{userId}/sessions

Actions:

  • View session details in dialog
  • Revoke All Sessions: Calls revokeAllUserSessionsCallable, signs out user, redirects to /sign-in

Default schedule: Monday-Friday, 9:00 AM - 4:00 PM

Custom schedule:

  • Set per day (Mon-Sun)
  • Multiple time slots per day
  • Format: { start: "HH:MM", end: "HH:MM" }
  • “Unavailable” = 0 slots for that day
  1. Click “Delete my account” (red button in Danger Zone)
  2. Confirmation dialog appears
  3. Non-OAuth: Enter password (required)
  4. OAuth: Session check, may need re-authentication
  5. Calls firekitAuth.deleteAccount(password?)
  6. Permanent and irreversible
  7. Redirect to /sign-in

Paid plan shows: Plan name, storage limit, monthly price, billing period start/end, status badge, Stripe Portal link.

Free plan shows: “Free Plan”, 100 MB storage, $0, “active” status, upgrade link.

Stripe Portal: Via ext-firestore-stripe-payments-createPortalLink Cloud Function.


FeatureFreeStandardElite
Monthly$0$32.99$97.99
Annual$0$359.99$1,019.99
Storage10GB100GB500GB
HubsUnlimitedUnlimitedUnlimited
TemplatesBasicAdvancedAll
ThemingNoYesYes
Custom DomainNoNoYes
Kickbacks5%10%20%
Commission12%6%3%
SupportBasicBasic + DiscordPremium + Elite Discord
Beta AccessNoNoYes
  • Annual shows savings badge: “Save $XX”
  • Annual price shown as monthly equivalent (annual / 12)
  1. Select plan and billing period
  2. Click “Purchase [Plan]”
  3. CheckoutService.createCheckoutSessionCustom() called with:
    • mode: 'subscription'
    • success_url: /checkout-success
    • cancel_url: /checkout-cancel
    • Metadata: priceId, price, planId, planName, planStorage, planKickback, planDiscount
  4. Watches for Stripe checkout URL
  5. Redirects to Stripe Checkout
  6. Returns to success/cancel URL

Organized by: Storage & Hubs, Templates & Customization, Revenue & Commissions, Support & Access.


Status: Placeholder only (“Billing management will go here”).

Billing Components (Built but not wired to page)

Section titled “Billing Components (Built but not wired to page)”
ComponentFeatures
Current PlanPlan name, status, renewal date, price, manage seats, cancel/upgrade
Payment MethodsTop 2 cards shown, manage all cards dialog, add new card form
Billing HistoryInvoice table (number, date, amount, tax, plan, status), download/view
Gift DialogSend plan to recipient via email, monthly/yearly, 20% extra on yearly

Cardholder name, card number (disabled for edit), expiry month/year, CVV, billing address (country, street, apt, city, state, ZIP).


Page: /notifications - Placeholder only.

  • Purple badge with unread count
  • Dropdown with notification list (max 350px height)
  • Per notification: avatar, title (truncated), description (2-line), timestamp, type badge

Type badges:

  • updates → purple
  • assignee → blue
  • status → green

Actions:

  • Click notification: marks as read + navigates to link
  • “Mark all as read”: batch update removing user from unreadBy arrays

Notification source: notificationManager.unreadNotifications (max 60, ordered by createdAt desc).