GameCraftGameCraft

Admin Survey (System Admin)

System administrator tool for collecting and managing user feedback through surveys

Admin Survey (System Admin)

System Admin Feature: This is a system administrator tool. Only users with system admin privileges can view and manage survey submissions. Public users can submit surveys, but only system admins can access the admin panel to review them.

The Admin Survey system provides a flexible, config-based approach for system administrators to collect and manage user feedback through various form types without requiring database migrations for new form types.

Key Features for System Admins:

  • ✅ Config-based survey types (no DB migrations)
  • ✅ Type-safe validation with Zod
  • ✅ Public and authenticated forms
  • ✅ System admin management interface
  • ✅ Multiple submission control
  • ✅ Flexible JSONB storage

Quick Start

Accessing Survey Forms

Survey forms are available at /survey/[type] routes:

  • Contact Us: /survey/contact_us
  • Feedback: /survey/feedback
  • Waitlist: /survey/waitlist
  • Contact Sales: /survey/contact_sales
  • Newsletter: /survey/newsletter

Submitting a Survey

  1. Navigate to the survey URL
  2. Fill out the required fields
  3. Click "Submit"
  4. See confirmation message

Some surveys may require authentication. You'll be prompted to sign in if needed.


Survey Types

Contact Us

Route: /survey/contact_us

General contact and inquiry form for any questions or support needs.

Fields:

  • Name (required)
  • Email (required)
  • Company (optional)
  • Phone (optional)
  • Subject (required)
  • Message (required)

Settings:

  • Public access: Yes
  • Authentication required: No
  • Multiple submissions: Yes

Feedback

Route: /survey/feedback

Product feedback form with rating and categorization.

Fields:

  • Rating (1-5, required)
  • Category (feature_request, bug_report, improvement, general)
  • Title (required)
  • Feedback (required)
  • Email (optional)

Settings:

  • Public access: Yes
  • Authentication required: No
  • Multiple submissions: Yes

Waitlist

Route: /survey/waitlist

Early access signup form for collecting interested users.

Fields:

  • Name (required)
  • Email (required)
  • Company (optional)
  • Role (optional)
  • Use Case (required)
  • Team Size (optional)
  • Referral Source (optional)

Settings:

  • Public access: Yes
  • Authentication required: No
  • Multiple submissions: Yes

Contact Sales

Route: /survey/contact_sales

Sales inquiry form for pricing page "Contact Sales" CTA.

Fields:

  • Full Name (required)
  • Work Email (required)
  • Company (required)
  • Phone (optional)
  • Team Size (required: 1-10, 11-50, 51-200, 200+)
  • How can we help? (required)

Settings:

  • Public access: Yes
  • Authentication required: No
  • Multiple submissions: Yes

Newsletter

Route: /survey/newsletter

Newsletter subscription form.

Fields:

  • Email Address (required)
  • Name (optional)

Settings:

  • Public access: Yes
  • Authentication required: No
  • Multiple submissions: No (one subscription per user)

For System Administrators

System Admin Access Required: The following features are only available to users with system administrator privileges. Regular users cannot access the admin panel.

Viewing Submissions

System administrators can view all survey submissions at /systemadmin/surveys.

Features:

  • Filter by survey type, status, user, or space
  • View detailed submission information
  • Update submission status
  • Add admin notes for follow-up
  • View submission statistics

Managing Submissions

Status Workflow:

  1. Pending - New submission, awaiting review
  2. Reviewed - Admin has reviewed the submission
  3. Archived - Submission has been processed/closed

Actions:

  • View submission details
  • Update status and add notes
  • Delete submissions (with audit log)
  • Export submissions (coming soon)

Submission Details

Each submission includes:

  • Form data (all field values)
  • Submission metadata (IP, user agent, locale)
  • User information (if authenticated)
  • Space/organization (if associated)
  • Timestamps (created, updated)
  • Admin notes

For Developers

Architecture

Database:

  • Single surveys table with JSONB storage
  • Flexible field structure per survey type
  • Optional user and space associations
  • Status workflow tracking
  • Comprehensive indexing

Configuration: Survey types are defined in src/config/surveys.ts:

export const SURVEY_TYPES = {
  contact_us: {
    label: "Contact Us",
    schema: contactUsSchema, // Zod validation
    fields: [...],           // UI metadata
    public: true,
    allowMultipleSubmissions: true,
  },
} as const;

Adding New Survey Types

Create a new survey type without database migrations:

Define Zod Schema

// src/config/surveys.ts
const mySchema = z.object({
  field1: z.string().min(1, "Field 1 is required"),
  field2: z.string().email("Invalid email"),
  field3: z.enum(["option1", "option2", "option3"]),
});

Create Survey Definition

const myDefinition: SurveyTypeDefinition<typeof mySchema> = {
  label: "My Survey",
  description: "Description of what this survey is for",
  schema: mySchema,
  public: true,
  requireAuth: false,
  allowMultipleSubmissions: true,
  fields: [
    {
      name: "field1",
      label: "Field 1",
      type: "text",
      placeholder: "Enter value...",
      required: true,
    },
    {
      name: "field2",
      label: "Email",
      type: "email",
      required: true,
    },
    {
      name: "field3",
      label: "Select Option",
      type: "select",
      required: true,
      options: [
        { label: "Option 1", value: "option1" },
        { label: "Option 2", value: "option2" },
        { label: "Option 3", value: "option3" },
      ],
    },
  ],
};

Register Survey Type

export const SURVEY_TYPES = {
  // ... existing types
  my_survey: myDefinition,
} as const;

That's it! The new survey is immediately available at /survey/my_survey.

Field Types

Supported field types for survey forms:

TypeDescriptionExample
textSingle-line text inputName, title
emailEmail input with validationuser@example.com
textareaMulti-line text inputMessages, descriptions
numberNumeric inputAge, quantity
selectDropdown selectionCategories, options
checkboxBoolean checkboxAgree to terms
radioRadio button groupSingle choice
dateDate pickerBirth date, event date

Configuration Options

SurveyTypeDefinition Options:

interface SurveyTypeDefinition<T extends z.ZodType> {
  label: string;                       // Display name
  description?: string;                // Description text
  schema: T;                           // Zod validation schema
  fields: SurveyFieldMeta[];          // UI field metadata
  public?: boolean;                    // Publicly accessible
  requireAuth?: boolean;               // Requires authentication
  allowMultipleSubmissions?: boolean;  // Allow repeat submissions
}

Field Metadata Options:

interface SurveyFieldMeta {
  name: string;                        // Field identifier
  label: string;                       // Display label
  type: FieldType;                     // Input type
  placeholder?: string;                // Placeholder text
  description?: string;                // Help text
  required?: boolean;                  // Required field
  options?: Array<{                    // For select/radio
    label: string;
    value: string | number;
  }>;
}

API Integration

Submit Survey (Public):

import { trpc } from '~/lib/trpc/client';

const submitMutation = trpc.surveys.submit.useMutation({
  onSuccess: () => {
    console.log('Survey submitted!');
  },
});

submitMutation.mutate({
  type: "contact_us",
  formData: {
    name: "John Doe",
    email: "john@example.com",
    // ... other fields
  },
  metadata: {
    userAgent: navigator.userAgent,
    locale: navigator.language,
  },
});

List User Submissions (Protected):

const { data } = trpc.surveys.mySubmissions.useQuery({
  type: "feedback", // optional filter
  limit: 20,
  offset: 0,
});

Admin: List All Submissions:

const { data } = trpc.siteAdmin.surveys.list.useQuery({
  type: "contact_sales",
  status: "pending",
  limit: 50,
});

Admin: Update Status:

const updateMutation = trpc.siteAdmin.surveys.updateStatus.useMutation();

updateMutation.mutate({
  id: "srv_abc123",
  status: "reviewed",
  notes: "Follow up scheduled for next week",
});

Security & Validation

Input Validation

All form submissions are validated using Zod schemas:

  1. Client-side: HTML5 validation for basic checks
  2. Server-side: Zod schema validation (primary)
  3. Type safety: TypeScript inference from schemas

Authorization

Public Surveys:

  • No authentication required
  • Accessible by anyone
  • IP and user agent tracked in metadata

Protected Surveys:

  • Authentication required (requireAuth: true)
  • User ID automatically associated
  • Ownership checks enforced

Admin Access:

  • System admin privileges required
  • All admin actions logged
  • Audit trail maintained

Multiple Submission Control

Control whether users can submit a survey multiple times:

// Allow multiple submissions (default)
allowMultipleSubmissions: true

// Restrict to one submission per user
allowMultipleSubmissions: false

When set to false:

  • Checks if user has already submitted (for authenticated users)
  • Returns error: "You have already submitted this survey"
  • Prevents duplicate subscriptions (e.g., newsletter)

Multiple submission control only works for authenticated users. Anonymous submissions cannot be restricted.


Best Practices

Survey Design

Do:

  • Keep forms short and focused
  • Use clear, descriptive labels
  • Provide helpful placeholder text
  • Make only essential fields required
  • Include field descriptions for clarity

Don't:

  • Ask for unnecessary information
  • Make every field required
  • Use confusing field names
  • Create overly long forms

Configuration

Do:

  • Use descriptive survey type keys
  • Write clear error messages
  • Set appropriate field types
  • Configure allowMultipleSubmissions based on use case
  • Add field descriptions for complex inputs

Don't:

  • Use generic survey names
  • Skip validation rules
  • Ignore field metadata
  • Allow multiple submissions for subscriptions

Data Management

Do:

  • Review submissions regularly
  • Update status to track progress
  • Add notes for follow-up
  • Archive processed submissions
  • Export data for analysis

Don't:

  • Leave submissions unreviewed
  • Forget to add notes
  • Delete submissions without backup
  • Ignore submission patterns

Troubleshooting

Form Not Loading

Problem: Survey page shows 404 error

Solutions:

  1. Verify survey type exists in SURVEY_TYPES
  2. Check URL spelling: /survey/[type]
  3. Restart development server after config changes

Submission Failed

Problem: Form submission returns error

Common causes:

  • Validation error (check field requirements)
  • Authentication required (sign in first)
  • Multiple submission not allowed (already submitted)
  • Server error (check logs)

Debug steps:

  1. Check browser console for error messages
  2. Verify all required fields are filled
  3. Check if authentication is needed
  4. Review Zod schema validation rules

Can't View Submissions

Problem: /systemadmin/surveys shows unauthorized

Solutions:

  1. Verify you have system admin privileges
  2. Check system_admins table for your user ID
  3. Use demo mode for testing: ?demo=1


Examples

Embedding in Landing Page

// In your landing page component
import Link from 'next/link';

export function CTASection() {
  return (
    <section>
      <h2>Get Started</h2>
      <p>Contact our sales team for a demo</p>
      <Link href="/survey/contact_sales">
        <button>Contact Sales</button>
      </Link>
    </section>
  );
}
// In your page footer
export function NewsletterSection() {
  return (
    <footer>
      <h3>Stay Updated</h3>
      <p>Subscribe to our newsletter</p>
      <Link href="/survey/newsletter">
        <button>Subscribe</button>
      </Link>
    </footer>
  );
}

Custom Survey Flow

// Multi-step survey (future enhancement)
export function MultiStepSurvey() {
  const [step, setStep] = useState(1);
  
  // Implement multi-step logic
  // Submit all data at once at the end
}

On this page