top of page

Leap Build Spec: Upgrade Custom Forms to Work Like SignUpGenius + Jotform

We need to upgrade community.givehub.com Custom Forms so they can handle:

  • SignUpGenius-style slot signups

  • Jotform-style conditional logic

  • multi-step forms

  • repeatable sections

  • capacity limits

  • waitlists

  • reminders

  • form-to-workflow automation

  • payment plans from Custom Forms

This should extend the existing Custom Forms system, not replace it.

1. New Form Field Types

Add these field/block types:

type CustomFormFieldType =
| existingFieldTypes
| "signup_slots"
| "repeatable_section"
| "payment_plan"
| "capacity_limit"
| "section_break"
| "page_break";

2. Signup Slots Field

Add a new Custom Form field type:

signup_slots

This allows orgs to create date/time-based signup options with capacity.

Admin builder settings

For each signup slot field, allow admin to configure:

{
title: string;
description?: string;
selectionMode: "single" | "multiple";
showRemainingSpots: boolean;
showRegistrantNames: boolean;
allowWaitlist: boolean;
cancellationAllowed: boolean;
reminderEnabled: boolean;
reminderHoursBefore: number;
slots: Array<{
id?: string;
label: string;
date: string;
startTime: string;
endTime: string;
location?: string;
notes?: string;
capacity: number;
priceCents?: number;
isActive: boolean;
}>;
}

Public form behavior

Show slot choices like:

Saturday, May 2
9:00 AM – 11:00 AM
3 spots left

Saturday, May 2
11:00 AM – 1:00 PM
FULL — Join Waitlist

Rules:

  • Prevent overbooking.

  • If slot is full and waitlist is enabled, allow waitlist signup.

  • If waitlist is disabled, disable the full slot.

  • If selectionMode = single, user can select one slot.

  • If selectionMode = multiple, user can select multiple slots.

  • If showRemainingSpots = true, show spots left.

  • If showRegistrantNames = true, show public-safe names like John S..

3. Database Tables for Slots

Create tables:

CREATE TABLE custom_form_slots (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
form_id UUID NOT NULL,
field_id UUID NOT NULL,

label TEXT NOT NULL,
slot_date DATE NOT NULL,
start_time TIME NOT NULL,
end_time TIME NOT NULL,
location TEXT NULL,
notes TEXT NULL,

capacity INTEGER NOT NULL,
price_cents INTEGER NOT NULL DEFAULT 0,

is_active BOOLEAN NOT NULL DEFAULT true,

created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE custom_form_slot_registrations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
form_id UUID NOT NULL,
field_id UUID NOT NULL,
slot_id UUID NOT NULL REFERENCES custom_form_slots(id) ON DELETE CASCADE,
submission_id UUID NULL,

person_id UUID NULL,
registrant_name TEXT NOT NULL,
registrant_email TEXT NOT NULL,
registrant_phone TEXT NULL,

status TEXT NOT NULL DEFAULT 'confirmed',
/*
confirmed
waitlisted
canceled
attended
no_show
*/

waitlist_position INTEGER NULL,

created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_custom_form_slots_form_field
ON custom_form_slots(form_id, field_id);

CREATE INDEX idx_custom_form_slot_registrations_slot_status
ON custom_form_slot_registrations(slot_id, status);

Important: slot availability must be calculated from confirmed registrations only.

4. Slot Availability Logic

Add backend utility:

async function getSlotAvailability(slotId: string): Promise<{
capacity: number;
confirmedCount: number;
waitlistCount: number;
remainingSpots: number;
isFull: boolean;
}>

Availability rules:

remainingSpots = capacity - confirmedCount;
isFull = remainingSpots <= 0;

When submitting a form with selected slots:

  1. Start DB transaction.

  2. Lock selected slot rows or use transaction-safe count.

  3. Check current confirmed count.

  4. If spot available:

    • create registration with status = confirmed.

  5. If full and waitlist enabled:

    • create registration with status = waitlisted.

    • assign next waitlist_position.

  6. If full and waitlist disabled:

    • reject submission with user-friendly error.

  7. Commit transaction.

This must be race-condition safe.

5. Waitlist Promotion

When a confirmed registration is canceled:

  1. Find earliest waitlisted person for that slot.

  2. Promote to confirmed.

  3. Clear waitlist position.

  4. Send email/SMS notification.

Add admin action:

Promote next waitlisted person

6. Capacity Limits

Add form-level capacity settings.

Admin can configure:

{
maxSubmissionsEnabled: boolean;
maxSubmissions?: number;
closeWhenFull: boolean;
waitlistWhenFull: boolean;
}

Public behavior:

  • If form reaches max submissions and waitlist disabled:

    • show closed/full message.

  • If form reaches max submissions and waitlist enabled:

    • allow waitlist-only submission.

Add helper:

async function getFormCapacityStatus(formId: string): Promise<{
maxSubmissions?: number;
confirmedSubmissions: number;
remaining: number | null;
isFull: boolean;
}>

7. Repeatable Sections

Add field type:

repeatable_section

Used for:

  • registering multiple kids

  • adding multiple attendees

  • adding household members

  • adding multiple volunteer names

Admin settings:

{
title: string;
minItems: number;
maxItems: number;
buttonLabel: string;
fields: CustomFormField[];
}

Public behavior:

  • User can click “Add another participant.”

  • Each repeated item stores its own field values.

  • Validation runs per repeated item.

  • Payment calculation can optionally multiply by repeat count.

Example:

Participant 1
- First name
- Last name
- Grade
- T-shirt size

[Add another participant]

8. Conditional Logic Engine

Add form-level conditional logic similar to Jotform.

Admin can create rules:

{
id: string;
name: string;
conditions: Array<{
fieldId: string;
operator:
| "equals"
| "not_equals"
| "contains"
| "greater_than"
| "less_than"
| "is_empty"
| "is_not_empty";
value?: any;
}>;
conditionMode: "all" | "any";
actions: Array<{
type:
| "show_field"
| "hide_field"
| "require_field"
| "make_optional"
| "show_page"
| "skip_page"
| "set_value"
| "add_fee"
| "apply_tag";
targetFieldId?: string;
targetPageId?: string;
value?: any;
}>;
}

Public behavior:

  • Logic runs live as user fills out the form.

  • Hidden fields should not be required.

  • Hidden field values should either be cleared or excluded from submission.

  • Fees should update live when logic adds fees.

Examples:

IF “Do you need childcare?” = Yes
SHOW “Child Information”

IF “Ticket Type” = VIP
ADD FEE $50

IF “Volunteer Role” = Kitchen
SHOW “Food Allergy / Safety Questions”

9. Multi-Step Forms

Add page support using:

page_break

Admin builder should allow fields to be grouped into pages.

Public UI:

  • Step indicator

  • Next button

  • Back button

  • Save progress later, future enhancement

  • Validation per step before moving forward

Example:

Step 1: Contact Info
Step 2: Participant Details
Step 3: Slot / Registration
Step 4: Payment
Step 5: Confirmation

10. Payment Plan Integration

Connect this to the Payment Plan system from the previous spec.

Custom Forms should support:

  • Pay in full

  • Payment plan

  • Optional down payment

  • Installments

  • Saved payment method

  • Authorization checkbox

Payment fields should work with:

  • form fees

  • slot prices

  • repeatable participant count

  • add-on fees from conditional logic

Payment total should be calculated from:

baseFormAmount
+ selectedSlotPrices
+ repeatableSectionFees
+ conditionalLogicFees
+ addOns
- discounts

Then user can:

Pay full amount today
or
Enroll in payment plan

11. Form Submission → CRM

On submission:

  1. Create or update person by email.

  2. Attach form submission to person timeline.

  3. Apply selected tags.

  4. Save slot registrations.

  5. Save payment/payment plan records.

  6. Trigger workflows.

Activity timeline example:

Submitted form: Youth Camp Registration
Selected slot: Saturday 9 AM – 11 AM
Payment plan created: $100/month for 6 months

12. Form Submission → Workflow Automation

Add workflow trigger:

form_submitted

Trigger payload:

{
orgId: string;
formId: string;
submissionId: string;
personId?: string;
formName: string;
submittedAt: string;
fields: Record<string, any>;
selectedSlots?: Array<{
slotId: string;
label: string;
date: string;
startTime: string;
endTime: string;
}>;
payment?: {
totalAmountCents: number;
paymentStatus: string;
};
paymentPlan?: {
id: string;
status: string;
totalAmountCents: number;
};
}

Workflow actions should support:

  • Send email

  • Send SMS

  • Create task

  • Apply tag

  • Add to group/list

  • Notify admin

  • Start drip campaign

13. Confirmation Emails

After submission, send confirmation email.

Email should include:

  • Organization name

  • Form name

  • Submission summary

  • Selected slots

  • Payment summary

  • Payment plan schedule, if applicable

  • Cancellation/update link if enabled

Subject example:

Confirmation: {{formName}}

14. Reminder Emails/SMS for Slots

Create scheduled job:

sendSlotReminders

Runs hourly or daily.

Find confirmed slot registrations where:

slot start date/time is within reminder window
AND reminder has not already been sent

Send reminder email/SMS:

Reminder: {{slotLabel}}
Date: {{slotDate}}
Time: {{startTime}} - {{endTime}}
Location: {{location}}

Add reminder tracking table or fields so reminders are not sent twice.

15. Admin Submission Management

Add enhanced form submissions page.

Admin should be able to view:

  • Form submission

  • Person record

  • Selected slots

  • Payment status

  • Payment plan status

  • Tags applied

  • Workflow status

Admin actions:

  • Cancel slot registration

  • Promote waitlist

  • Resend confirmation

  • Export CSV

  • Mark attended/no-show

  • Refund payment, if existing refund flow exists

  • Open person profile

16. Public Update / Cancel Link

Generate secure tokenized link for each submission.

Allows user to:

  • View submission

  • Update basic details

  • Cancel slot if allowed

  • Update payment method for payment plan

Use expiring token or long-lived signed token.

Do not require account login.

17. Templates Library

Add starter templates.

Suggested templates:

  1. Volunteer Signup

  2. Meal Train / Serve Team Signup

  3. Youth Camp Registration

  4. Mission Trip Payment Plan

  5. School Fee Payment Plan

  6. Sponsorship Commitment Form

  7. Event RSVP

  8. Class Registration

  9. Childcare Signup

  10. Donation Pledge Form

Each template should preconfigure fields, slots, payment settings, and workflows where possible.

18. Permissions

Add permissions:

forms.view
forms.create
forms.edit
forms.delete
forms.manage_submissions
forms.manage_slots
forms.manage_waitlists
forms.export
forms.manage_templates
forms.manage_logic

Admins should get all permissions by default.

19. Reporting

Add reporting for:

  • Total form submissions

  • Capacity remaining

  • Slot registrations

  • Waitlist count

  • Attendance

  • Form revenue

  • Payment plan revenue

  • Outstanding payment plan balance

  • Failed payment plans

  • Conversion rate by form

  • Abandoned forms, future enhancement

CSV export should include:

  • Contact fields

  • Repeatable section values

  • Selected slots

  • Payment status

  • Payment plan status

  • Tags

  • Submission date

20. Build Order

Please build in this order:

Phase 1: Foundation

  1. Add DB tables for slots/registrations.

  2. Add signup_slots field type.

  3. Add public slot selection UI.

  4. Add safe backend submission handling with capacity protection.

Phase 2: Admin + Waitlist

  1. Add admin slot configuration UI.

  2. Add waitlist support.

  3. Add cancel/promote actions.

  4. Add enhanced submission view.

Phase 3: Jotform-style form power

  1. Add repeatable sections.

  2. Add conditional logic.

  3. Add multi-step/page-break forms.

Phase 4: GiveHub advantage

  1. Integrate payment plans.

  2. Add form-to-workflow trigger.

  3. Add reminder emails/SMS.

  4. Add templates library.

21. Important Requirements

  • Do not break existing Custom Forms.

  • Existing forms must continue working.

  • New field types should be backward-compatible.

  • Public form submission must be transaction-safe.

  • Slot capacity must not overbook.

  • Payment totals must be recalculated server-side.

  • Do not trust frontend fee totals.

  • All payment plan authorization must be stored.

  • Use existing GiveHub payment gateway logic.

  • Use existing People/CRM records when possible.

  • Use existing Messaging system when possible.

  • Use existing Workflow/task system when possible.

  • Use existing permissions pattern.

  • Use production-safe frontend/API URLs from environment config.

Final goal:

GiveHub Custom Forms should become a combination of:

SignUpGenius + Jotform + GiveHub Payments + GiveHub CRM + GiveHub Workflows

This should make Custom Forms useful for registrations, volunteers, events, camps, school fees, sponsorships, mission trips, pledges, tuition, and payment plans.

Givehub.com

GiveHub.com
Acworth, GA 30101

United States
Email: sales@givehub.com
Phone: 866-933-7048

 

MISSION STATEMENT

 

To offer a robust and a superior product suite to help non-profits and churches increase giving and operate more effectively and efficiently with cutting edge technology. 

 

Yours in Christ, 
GiveHub.com Team

  • Facebook Social Icon
  • LinkedIn Social Icon
  • Instagram Social Icon

© 2026 GiveHub.com - All rights reserved - Support - Book a Demo

bottom of page