SchoolSelectorModal

Modal dialog for selecting schools from a searchable, scrollable list with optional district filtering. Uses Shadcn Popover + Command pattern for district selection. Props-based with no data dependencies.

Interactive Preview

Live component with different configuration options. Switch between variants and toggle code view.

Component Examples

Select different variants to see how props affect the component behavior

Preview

Current Selection:

District: Alisal Union School District

Props

Component accepts the following props for configuration and behavior.

PropTypeRequiredDefaultDescription
isOpenbooleanRequiredControls modal visibility
onOpenChange(open: boolean) => voidRequiredCalled when modal open state changes (aligns with shadcn Dialog)
schoolsLinkedSchool[]RequiredPre-filtered schools array
onSchoolSelect(school: LinkedSchool) => voidRequiredCalled when a school is selected
selectedSchoolNamestringOptionalCurrent school name to highlight in the list
titlestringOptional"Select Site"Modal title
isLoadingbooleanOptionalfalseDisables all interactions during selection/navigation
districtsDistrict[]OptionalList of districts for filtering (selector shown when >1)
selectedDistrictIdstring | numberOptionalCurrently selected district ID
onDistrictChange(districtId: string | number) => voidOptionalCalled when district selection changes

Type Definitions

LinkedSchool

Represents a linked school for site navigation

interface LinkedSchool {
  groupId: number   // School group identifier
  userId: number    // User identifier for jump URL
  name: string      // School display name
}
District

Represents a district for site navigation

interface District {
  id: string | number  // District identifier
  name: string         // District display name
}
SchoolSelectorModalProps

Full props interface for the SchoolSelectorModal component

interface SchoolSelectorModalProps {
  isOpen: boolean
  onOpenChange: (open: boolean) => void
  schools: LinkedSchool[]
  onSchoolSelect: (school: LinkedSchool) => void
  selectedSchoolName?: string
  title?: string
  isLoading?: boolean
  districts?: District[]
  selectedDistrictId?: string | number
  onDistrictChange?: (districtId: string | number) => void
}

Usage Examples

Common patterns and implementation examples.

With District Filtering

import { SchoolSelectorModal } from '@/components/shared/school-selector-modal'
import { type LinkedSchool } from '@/types/cms'

const [isOpen, setIsOpen] = useState(false)
const [isNavigating, setIsNavigating] = useState(false)
const [selectedDistrictId, setSelectedDistrictId] = useState(districts[0].id)

// Filter schools by selected district (parent responsibility)
const schools = allSchools.filter(s => s.districtId === selectedDistrictId)

<SchoolSelectorModal
  isOpen={isOpen}
  onOpenChange={setIsOpen}
  schools={schools}
  districts={districts}
  selectedDistrictId={selectedDistrictId}
  onDistrictChange={setSelectedDistrictId}
  selectedSchoolName="Spike School District"
  title="Select Site"
  isLoading={isNavigating}
  onSchoolSelect={(school) => {
    setIsNavigating(true)
    const currentPath = window.location.pathname
    const redirectParam = `?redirect=${encodeURIComponent(currentPath)}`
    const jumpUrl = `/apps/dws/link/jump/${school.groupId}/${school.userId}${redirectParam}`

    window.location.href = jumpUrl
  }}
/>

Without District (Backward Compatible)

import { SchoolSelectorModal } from '@/components/shared/school-selector-modal'

const [isOpen, setIsOpen] = useState(false)

<SchoolSelectorModal
  isOpen={isOpen}
  onOpenChange={setIsOpen}
  schools={linkedSchools}
  selectedSchoolName="Spike School District"
  onSchoolSelect={(school) => {
    const currentPath = window.location.pathname
    const redirectParam = `?redirect=${encodeURIComponent(currentPath)}`
    const jumpUrl = `/apps/dws/link/jump/${school.groupId}/${school.userId}${redirectParam}`

    window.location.href = jumpUrl
  }}
/>