settings: move dues config (Stripe + payment links) into its own Dues tab

The Stripe recurring-dues panel and the external payment-links panel were
rendered below the settings tab bar (outside SettingsClient), so they
floated under every tab. Add a Dues tab (Space / Integrations / Dues /
Webhooks) and render both panels there as standard tab cards. UI only.
This commit is contained in:
Moheeb Zara
2026-05-20 00:11:06 -07:00
parent be756035d5
commit 49d8805b4c
5 changed files with 26 additions and 16 deletions
+6 -12
View File
@@ -1,7 +1,5 @@
import { createClient } from '@/lib/supabase/server'
import SettingsClient from './settings-client'
import { StripeBillingPanel } from '@/components/settings/stripe-billing-panel'
import { DuesPaymentMethodsPanel } from '@/components/settings/dues-payment-methods-panel'
import { redirect } from 'next/navigation'
export default async function SettingsPage() {
@@ -27,15 +25,11 @@ export default async function SettingsPage() {
.from('integrations').select('*').eq('space_id', member.space_id)
return (
<>
<SettingsClient
space={space}
isAdmin={isAdmin}
integrations={integrations ?? []}
currentRole={member.role}
/>
<StripeBillingPanel spaceId={member.space_id} />
<DuesPaymentMethodsPanel />
</>
<SettingsClient
space={space}
isAdmin={isAdmin}
integrations={integrations ?? []}
currentRole={member.role}
/>
)
}
+12 -2
View File
@@ -9,6 +9,8 @@ import { financialVisibilities, directoryVisibilities } from '@/lib/validations'
import type { Tables } from '@/types/database'
import { PageTitle } from '@/components/ui/page-title'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { StripeBillingPanel } from '@/components/settings/stripe-billing-panel'
import { DuesPaymentMethodsPanel } from '@/components/settings/dues-payment-methods-panel'
type Space = Tables<'spaces'>
type Integration = Tables<'integrations'>
@@ -88,7 +90,7 @@ const INTEGRATIONS_CONFIG = [
]
export default function SettingsClient({ space, isAdmin, integrations, currentRole }: Props) {
const [activeTab, setActiveTab] = useState<'space' | 'integrations' | 'webhooks'>('space')
const [activeTab, setActiveTab] = useState<'space' | 'integrations' | 'dues' | 'webhooks'>('space')
const [saving, setSaving] = useState(false)
const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null)
@@ -223,7 +225,7 @@ export default function SettingsClient({ space, isAdmin, integrations, currentRo
<div className="flex-1 p-4 md:p-6">
{/* Tabs */}
<div className="bg-card border-b border-border flex gap-4 md:gap-6 px-2 mb-6 rounded-t overflow-x-auto">
{(['space', 'integrations', 'webhooks'] as const).map(tab => (
{(['space', 'integrations', 'dues', 'webhooks'] as const).map(tab => (
<button
key={tab}
onClick={() => setActiveTab(tab)}
@@ -476,6 +478,14 @@ export default function SettingsClient({ space, isAdmin, integrations, currentRo
</div>
)}
{/* Dues Tab: how members pay dues (Stripe recurring + external links) */}
{activeTab === 'dues' && (
<div className="space-y-6">
<StripeBillingPanel spaceId={space.id} />
<DuesPaymentMethodsPanel />
</div>
)}
{/* Webhooks Tab */}
{activeTab === 'webhooks' && (
<div className="bg-card rounded border border-border p-6 space-y-6">
@@ -78,7 +78,7 @@ export function DuesPaymentMethodsPanel() {
}
return (
<div className="p-4 md:p-6 border-t border-border">
<div className="bg-card rounded border border-border p-6">
<div className="max-w-2xl space-y-3">
<h2 className="font-mono text-[10px] uppercase tracking-widest text-muted-foreground">
Other ways to pay dues
+1 -1
View File
@@ -56,7 +56,7 @@ export function StripeBillingPanel({ spaceId }: { spaceId: string }) {
}
return (
<div className="p-4 md:p-6 border-t border-border">
<div className="bg-card rounded border border-border p-6">
<div className="max-w-2xl space-y-3">
<div className="flex items-center justify-between">
<h2 className="font-mono text-[10px] uppercase tracking-widest text-muted-foreground">
+6
View File
@@ -4,6 +4,12 @@ Append-only. Newest entries on top. Keep each entry to one screen.
---
## 2026-05-20 (pass 60): /settings "Dues" tab (LOCAL, NOT deployed)
Branch `main`. The Stripe-dues config + external-payment-links panels were floating below the settings tab bar (rendered by page.tsx outside SettingsClient, shown regardless of the active tab). Moved both into a new **Dues** tab inside SettingsClient (tabs are now Space / Integrations / Dues / Webhooks); the panels render as standard `bg-card rounded border` tab cards instead of `border-t` page sections. page.tsx now renders only SettingsClient. UI-only, no schema/actions change. Build + 594 unit green. NOT deployed.
---
## 2026-05-20 (pass 59): PROD OUTAGE fix + in-app inbox + /me consolidation + style
Branch `main`. Suite 594 unit, 40 integration, build clean.