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.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| isOpen | boolean | Required | — | Controls modal visibility |
| onOpenChange | (open: boolean) => void | Required | — | Called when modal open state changes (aligns with shadcn Dialog) |
| schools | LinkedSchool[] | Required | — | Pre-filtered schools array |
| onSchoolSelect | (school: LinkedSchool) => void | Required | — | Called when a school is selected |
| selectedSchoolName | string | Optional | — | Current school name to highlight in the list |
| title | string | Optional | "Select Site" | Modal title |
| isLoading | boolean | Optional | false | Disables all interactions during selection/navigation |
| districts | District[] | Optional | — | List of districts for filtering (selector shown when >1) |
| selectedDistrictId | string | number | Optional | — | Currently selected district ID |
| onDistrictChange | (districtId: string | number) => void | Optional | — | Called 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
}}
/>