Knowledge > Products > Pro Website > Admin Features
Pro Website Admin Features
Dashboard Overview
Pro Website administration happens in the PewSearch admin dashboard at pewsearch.com/admin/[token]. The admin dashboard serves both Premium Page and Pro Website customers, but the WebsiteTab is only visible when premium_churches.plan === 'pro_website'.
The admin token is a unique, per-church secret string stored in premium_churches.admin_token. Churches receive this token via magic link during onboarding. There is no username/password login -- the token IS the authentication.
WebsiteTab Structure
The WebsiteTab contains 3 sub-tabs that organize all Pro Website editing capabilities:
Sub-Tab 1: Design
Controls the visual presentation of the Pro Website.
| Feature | UI Element | Data Field | Notes |
|---|---|---|---|
| Hero Video | Picker grid (12 thumbnails) | hero_video_key | Click to select, shows preview |
| Slideshow Builder | Multi-select video picker | hero_slideshow_keys | Drag to reorder, add/remove videos |
| Transition Video | Picker grid (3 thumbnails) | transition_video_key | Click to select |
| Logo Upload | Drag-drop zone + file picker | logo_url | Max 2MB, PNG/JPG/SVG accepted |
Logo Upload Details:
Upload flow:
1. User drags file onto drop zone OR clicks to open file picker
2. Client-side validation:
- File size <= 2MB
- File type: image/png, image/jpeg, image/svg+xml
- If validation fails: show inline error, do not upload
3. POST /api/upload/logo with FormData
4. Server uploads to Supabase Storage (church-logos bucket)
5. Returns public URL
6. UPDATE premium_churches SET logo_url = returned_url
7. Preview updates in real-time
The logo appears in the StickyNav (Section 1) of the Pro Website page. If no logo is uploaded, the church name is displayed as text.
Sub-Tab 2: Content
Controls the informational content displayed on the Pro Website. This is where churches spend most of their admin time.
Hours Editor
Structured day/time grid for service and office hours.
Data structure (custom_hours JSONB):
{
"sunday": [
{"label": "Morning Worship", "time": "9:00 AM"},
{"label": "Sunday School", "time": "10:30 AM"},
{"label": "Evening Service", "time": "6:00 PM"}
],
"monday": [],
"tuesday": [
{"label": "Bible Study", "time": "7:00 PM"}
],
...
}
UI: A grid with rows for each day of the week (Sunday through Saturday). Each day has an "Add Time" button to add label/time pairs. Entries can be edited or deleted. The day ordering in the display is always Sunday-first, matching visitor expectations.
Staff Editor
Manages the staff directory (Section 9).
Data structure (custom_staff JSONB array):
[
{
"name": "Pastor John Smith",
"title": "Senior Pastor",
"bio": "Pastor John has served our church for 15 years...",
"photo_url": "https://...",
"order": 1
}
]
UI features:
- Add/remove staff members
- Edit name, title, bio for each
- Photo upload (drag-drop or file picker, max 2MB, PNG/JPG)
- Drag-to-reorder (updates
orderfield) - Photo upload endpoint: POST
/api/upload/staff-photo
Staff photo upload flow:
1. User clicks "Upload Photo" or drags onto staff card
2. Client-side validation: size <= 2MB, image type
3. POST /api/upload/staff-photo with FormData (includes church_id)
4. Server uploads to Supabase Storage (staff-photos bucket)
5. Returns public URL
6. Updates staff entry's photo_url in the JSONB array
7. Preview updates in card
Known gap: Staff photo upload UI needs polish. The drag-drop zone is functional but not as visually polished as the logo upload.
Ministries Editor
Manages ministry cards (Section 11).
Data structure (custom_ministries JSONB array):
[
{
"name": "Youth Group",
"description": "For students in grades 6-12. Meets Wednesday evenings.",
"order": 1
}
]
UI features:
- Add/remove ministries
- Edit name and description for each
- Drag-to-reorder
- No image/icon upload (text-only ministry cards)
Sermons Editor
Manages sermon video embeds (Section 12).
Data structure (sermons JSONB array):
[
{
"title": "Walking by Faith",
"speaker": "Pastor John Smith",
"date": "2026-03-16",
"video_url": "https://youtube.com/watch?v=...",
"description": "A message about trusting God in uncertain times."
}
]
UI features:
- Add/remove sermons
- Edit title, speaker, date, video URL, description
- Video URL validation (YouTube or Vimeo)
- Most recent sermon appears as the featured/primary embed
Also supports a standalone featured_video_url field that overrides the first sermon as the primary video embed.
Beliefs Editor
Manages belief statement cards (Section 5).
Data structure (beliefs JSONB array):
[
{
"title": "The Bible",
"description": "We believe the Bible is the inspired, authoritative Word of God."
}
]
UI features:
- Add/remove belief statements
- Edit title and description
- Reorder
Events Editor
Manages upcoming events (Section 13).
Data structure (events JSONB array):
[
{
"title": "Easter Sunday Service",
"date": "2026-04-05",
"time": "9:00 AM",
"description": "Special Easter celebration.",
"location": "Main Sanctuary"
}
]
UI features:
- Add/remove events
- Edit title, date, time, description, location
- Date picker for date field
Known gap: No recurring event support. A weekly Bible study must be entered as separate events for each date. This is the most requested improvement from a UX perspective.
What to Expect Editor
Manages the 10-field first-visit guide (Section 8).
Data structure (what_to_expect JSONB object):
{
"dress_code": "Come as you are! Most people wear casual.",
"parking": "Free parking in our main lot.",
"children": "Nursery and kids programs available.",
"first_visit": "Arrive 10 minutes early.",
"music_style": "Contemporary worship with a full band.",
"service_length": "About 75 minutes.",
"accessibility": "Wheelchair accessible.",
"communion": "First Sunday of each month.",
"coffee": "Free coffee in the lobby!",
"guest_checkin": "Fill out a connection card."
}
UI: 10 text fields, each with a descriptive label and placeholder text suggesting what to write. Fields can be left empty -- only non-empty fields render on the Pro Website page.
| Field | Label in Admin | Placeholder Hint |
|---|---|---|
dress_code | Dress Code | What should visitors wear? |
parking | Parking | Where should visitors park? |
children | Children's Programs | What's available for kids? |
first_visit | First Visit Experience | What happens when someone walks in? |
music_style | Music Style | What kind of worship music? |
service_length | Service Length | How long is a typical service? |
accessibility | Accessibility | Wheelchair access, hearing assistance? |
communion | Communion / Lord's Supper | When and who can participate? |
coffee | Coffee & Refreshments | Is there coffee? Snacks? |
guest_checkin | Guest Check-In | Connection cards, welcome desk? |
Giving URL
Single text field for the church's online giving link (e.g., Tithe.ly, Planning Center Giving, PayPal).
Data field: premium_churches.giving_url
Contact Email
Email address that receives contact form submissions from the Pro Website.
Data field: premium_churches.contact_email
Sub-Tab 3: Settings
Controls routing, identity, and integration settings.
Vanity Slug
Text field for the church's custom subdomain.
Validation rules:
Regex: /^[a-z0-9][a-z0-9-]{1,28}[a-z0-9]$/
- 3-30 characters total
- Must start and end with a letter or number
- May contain hyphens in the middle
- Lowercase only
- No spaces, underscores, or special characters
UI behavior:
- Real-time validation as user types
- Shows preview URL:
grace-community.pewsearch.com - Uniqueness check against existing vanity_slugs (server-side on save)
- Error message if slug is taken or invalid
See Vanity URLs for the full routing system.
Contact Email
Same field as in Content sub-tab (duplicated for convenience in Settings context).
Social Media Links
Manages social media profile URLs for the church.
Data structure (custom_social_media JSONB object):
{
"facebook": "https://facebook.com/gracechurch",
"instagram": "https://instagram.com/gracechurch",
"twitter": "https://twitter.com/gracechurch",
"youtube": "https://youtube.com/@gracechurch",
"tiktok": "https://tiktok.com/@gracechurch"
}
UI: 5 text fields with platform-specific icons and URL validation. Empty fields are acceptable -- only populated platforms show social icons on the Pro Website page.
Known gap: Social media editor is minimal. Future improvements could include preview of the linked page, follower count display, or automatic content sync.
Care Settings
Configuration for pastoral care features (prayer request routing, callback preferences, notification settings). This overlaps with ChurchWiseAI settings for churches that also have a CWA subscription.
Role-Based Access Control
The admin dashboard uses a 9-role system defined in premium-shared.ts. This controls which tabs are visible and which edit actions are permitted.
Role Definitions
| Role | Display Name | Dashboard Tabs | Edit Permissions |
|---|---|---|---|
admin | Administrator | All tabs | All edit permissions, team management |
office_admin | Office Admin | Overview, Calls, Requests, Care, Training, Website, Settings | Basic info, contact info, website content |
prayer_team | Prayer Team | Overview, Requests | View only (prayer requests) |
care_team | Care Team | Overview, Requests, Care | View only (care cases) |
treasurer | Treasurer | Overview | View only (financial metrics) |
volunteer_coordinator | Volunteer Coordinator | Overview, Requests | View only |
worship_leader | Worship Leader | Overview, Training | Edit pastor_pulse only |
spiritual_leader | Spiritual Leader | Overview, Training | View only |
care_leader | Care Leader | Overview, Training | View only |
Tab Visibility by Role
Tab visibility matrix:
admin office_admin prayer care treasurer volunteer worship
Overview Y Y Y Y Y Y Y
Calls Y Y N N N N N
Requests Y Y Y Y N Y N
Care Y Y N Y N N N
Training Y Y N N N N Y
Website Y Y N N N N N
Settings Y Y N N N N N
Upgrade Y N N N N N N
Confidential Content Access
Sensitive pastoral information is access-controlled by role:
PASTORAL_ROLES = ['admin', 'office_admin']
IF user.role IN PASTORAL_ROLES:
Show full prayer request text
Show full callback request reasons
Show visitor contact details
ELSE:
Show redacted prayer text (first 20 chars + "...")
Show "Callback requested" without reason
Show visitor name only (no phone/email)
This ensures that prayer team members can see that prayer requests exist and pray generally, but cannot access detailed personal information unless they have pastoral-level access.
Team Management
How It Works
The admin (token holder) can invite team members by generating an invite link. Each team member gets their own access_token with an assigned role.
Database tables:
| Table | Purpose |
|---|---|
premium_churches | Stores the primary admin_token for the church admin |
church_team_members | Stores team member tokens: access_token, role, church_id, name, email, is_active, last_accessed_at, created_at |
Invite flow:
1. Admin clicks "Invite Team Member" in Settings
2. Admin enters: name, email, role (dropdown)
3. System generates unique access_token
4. INSERT into church_team_members (church_id, name, email, role, access_token, is_active=true)
5. Invite link generated: pewsearch.com/admin/{access_token}
6. Admin shares link with team member (email, text, etc.)
7. Team member clicks link → resolveToken validates → dashboard loads with role permissions
Token resolution (resolveToken):
1. Check premium_churches.admin_token first
IF match: role = 'admin', return church data
2. Check church_team_members.access_token
IF match AND is_active = true:
Update last_accessed_at = now()
Return church data with team member's role
3. IF no match: return 401 unauthorized
Team Management UI
The admin can:
- View all team members (name, role, last accessed)
- Edit a team member's role
- Deactivate a team member (
is_active = false) - Re-activate a deactivated member
- Generate a new invite link
Team members CANNOT:
- Invite other team members
- Change their own role
- Access tabs outside their role's permissions
- See the admin token
Save Behavior
All editors in WebsiteTab use an auto-save with debounce pattern:
1. User makes an edit (types, selects, reorders)
2. Debounce timer starts (500ms)
3. If user edits again within 500ms, timer resets
4. After 500ms of inactivity:
- PATCH /api/admin/premium-churches (or direct Supabase update)
- UPDATE premium_churches SET [changed_field] = [new_value] WHERE church_id = ...
- Show "Saved" indicator (green checkmark, fades after 2 seconds)
5. If save fails: show error toast, retry button
This means there is no "Save" button. Changes are persisted as the admin types, with a brief debounce to avoid excessive database writes.
API Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/api/upload/logo | POST | Upload church logo to Supabase Storage |
/api/upload/staff-photo | POST | Upload staff member photo to Supabase Storage |
/api/admin/premium-churches | PATCH | Update premium_churches fields |
/api/contact | POST | Process contact form submissions (public) |
File References
| File | Purpose |
|---|---|
pewsearch/web/src/app/admin/[token]/components/WebsiteTab.tsx | Main WebsiteTab component with all 3 sub-tabs |
pewsearch/web/src/lib/premium-shared.ts | Role definitions, tab visibility, tier constants (client-safe) |
pewsearch/web/src/lib/premium-queries.ts | Server-side Supabase queries for premium data |
pewsearch/web/src/app/admin/[token]/page.tsx | Admin page entry point, token resolution |
pewsearch/web/src/app/api/upload/logo/route.ts | Logo upload API |
pewsearch/web/src/app/api/upload/staff-photo/route.ts | Staff photo upload API |
See Also
- Overview -- product summary, data model, pricing
- Sections -- how admin-edited content renders on the Pro Website page
- Vanity URLs -- vanity slug validation and routing
- Chatbot Integration -- chatbot enable/disable and agent ID settings
- Chatbot Tier Restrictions -- how admin features differ by subscription tier