1+ import React , { useState , useCallback , useEffect } from "react" ;
2+ import {
3+ Button ,
4+ Dialog ,
5+ DialogTitle ,
6+ DialogContent ,
7+ DialogActions ,
8+ FormControl ,
9+ InputLabel ,
10+ Select ,
11+ MenuItem ,
12+ Stack ,
13+ } from "@mui/material" ;
14+ import { ApiHelper } from "@churchapps/apphelper" ;
15+
16+ interface Props {
17+ open : boolean ;
18+ onClose : ( ) => void ;
19+ onSelect : ( venueId : string ) => void ;
20+ }
21+
22+ export const LessonSelector : React . FC < Props > = ( { open, onClose, onSelect } ) => {
23+ const [ lessonTree , setLessonTree ] = useState < any > ( { } ) ;
24+ const [ selectedProgram , setSelectedProgram ] = useState < string > ( "" ) ;
25+ const [ selectedStudy , setSelectedStudy ] = useState < string > ( "" ) ;
26+ const [ selectedLesson , setSelectedLesson ] = useState < string > ( "" ) ;
27+ const [ selectedVenue , setSelectedVenue ] = useState < string > ( "" ) ;
28+
29+ const loadLessonTree = useCallback ( async ( ) => {
30+ try {
31+ const data = await ApiHelper . getAnonymous ( "/lessons/public/tree" , "LessonsApi" ) ;
32+ setLessonTree ( data || { } ) ;
33+
34+ // Auto-select defaults
35+ if ( data ?. programs ?. length > 0 ) {
36+ const firstProgram = data . programs [ 0 ] ;
37+ setSelectedProgram ( firstProgram . id ) ;
38+
39+ if ( firstProgram . studies ?. length > 0 ) {
40+ const firstStudy = firstProgram . studies [ 0 ] ;
41+ setSelectedStudy ( firstStudy . id ) ;
42+
43+ if ( firstStudy . lessons ?. length > 0 ) {
44+ const firstLesson = firstStudy . lessons [ 0 ] ;
45+ setSelectedLesson ( firstLesson . id ) ;
46+
47+ if ( firstLesson . venues ?. length > 0 ) {
48+ setSelectedVenue ( firstLesson . venues [ 0 ] . id ) ;
49+ }
50+ }
51+ }
52+ }
53+ } catch ( error ) {
54+ console . error ( "Error loading lesson tree:" , error ) ;
55+ setLessonTree ( { } ) ;
56+ }
57+ } , [ ] ) ;
58+
59+ const getCurrentProgram = useCallback ( ( ) => {
60+ return lessonTree ?. programs ?. find ( ( p : any ) => p . id === selectedProgram ) ;
61+ } , [ lessonTree , selectedProgram ] ) ;
62+
63+ const getCurrentStudy = useCallback ( ( ) => {
64+ const program = getCurrentProgram ( ) ;
65+ return program ?. studies ?. find ( ( s : any ) => s . id === selectedStudy ) ;
66+ } , [ getCurrentProgram , selectedStudy ] ) ;
67+
68+ const getCurrentLesson = useCallback ( ( ) => {
69+ const study = getCurrentStudy ( ) ;
70+ return study ?. lessons ?. find ( ( l : any ) => l . id === selectedLesson ) ;
71+ } , [ getCurrentStudy , selectedLesson ] ) ;
72+
73+ const handleProgramChange = useCallback ( ( programId : string ) => {
74+ setSelectedProgram ( programId ) ;
75+ setSelectedStudy ( "" ) ;
76+ setSelectedLesson ( "" ) ;
77+ setSelectedVenue ( "" ) ;
78+ } , [ ] ) ;
79+
80+ const handleStudyChange = useCallback ( ( studyId : string ) => {
81+ setSelectedStudy ( studyId ) ;
82+ setSelectedLesson ( "" ) ;
83+ setSelectedVenue ( "" ) ;
84+ } , [ ] ) ;
85+
86+ const handleLessonChange = useCallback ( ( lessonId : string ) => {
87+ setSelectedLesson ( lessonId ) ;
88+ setSelectedVenue ( "" ) ;
89+ } , [ ] ) ;
90+
91+ const handleVenueChange = useCallback ( ( venueId : string ) => {
92+ setSelectedVenue ( venueId ) ;
93+ } , [ ] ) ;
94+
95+ const handleSelect = useCallback ( ( ) => {
96+ if ( selectedVenue ) {
97+ onSelect ( selectedVenue ) ;
98+ onClose ( ) ;
99+ }
100+ } , [ selectedVenue , onSelect , onClose ] ) ;
101+
102+ const handleClose = useCallback ( ( ) => {
103+ setSelectedProgram ( "" ) ;
104+ setSelectedStudy ( "" ) ;
105+ setSelectedLesson ( "" ) ;
106+ setSelectedVenue ( "" ) ;
107+ onClose ( ) ;
108+ } , [ onClose ] ) ;
109+
110+ useEffect ( ( ) => {
111+ if ( open ) loadLessonTree ( ) ;
112+ } , [ open , loadLessonTree ] ) ;
113+
114+ const currentProgram = getCurrentProgram ( ) ;
115+ const currentStudy = getCurrentStudy ( ) ;
116+ const currentLesson = getCurrentLesson ( ) ;
117+
118+ return (
119+ < Dialog open = { open } onClose = { handleClose } maxWidth = "sm" fullWidth >
120+ < DialogTitle > Associate Lesson</ DialogTitle >
121+ < DialogContent >
122+ < Stack spacing = { 3 } sx = { { mt : 1 } } >
123+ < FormControl fullWidth >
124+ < InputLabel > Program</ InputLabel >
125+ < Select
126+ value = { selectedProgram }
127+ onChange = { ( e ) => handleProgramChange ( e . target . value ) }
128+ label = "Program"
129+ >
130+ { lessonTree ?. programs ?. map ( ( program : any ) => (
131+ < MenuItem key = { program . id } value = { program . id } >
132+ { program . name }
133+ </ MenuItem >
134+ ) ) }
135+ </ Select >
136+ </ FormControl >
137+
138+ < FormControl fullWidth disabled = { ! selectedProgram } >
139+ < InputLabel > Study</ InputLabel >
140+ < Select
141+ value = { selectedStudy }
142+ onChange = { ( e ) => handleStudyChange ( e . target . value ) }
143+ label = "Study"
144+ >
145+ { currentProgram ?. studies ?. map ( ( study : any ) => (
146+ < MenuItem key = { study . id } value = { study . id } >
147+ { study . name }
148+ </ MenuItem >
149+ ) ) }
150+ </ Select >
151+ </ FormControl >
152+
153+ < FormControl fullWidth disabled = { ! selectedStudy } >
154+ < InputLabel > Lesson</ InputLabel >
155+ < Select
156+ value = { selectedLesson }
157+ onChange = { ( e ) => handleLessonChange ( e . target . value ) }
158+ label = "Lesson"
159+ >
160+ { currentStudy ?. lessons ?. map ( ( lesson : any ) => (
161+ < MenuItem key = { lesson . id } value = { lesson . id } >
162+ { lesson . name }
163+ </ MenuItem >
164+ ) ) }
165+ </ Select >
166+ </ FormControl >
167+
168+ < FormControl fullWidth disabled = { ! selectedLesson } >
169+ < InputLabel > Venue</ InputLabel >
170+ < Select
171+ value = { selectedVenue }
172+ onChange = { ( e ) => handleVenueChange ( e . target . value ) }
173+ label = "Venue"
174+ >
175+ { currentLesson ?. venues ?. map ( ( venue : any ) => (
176+ < MenuItem key = { venue . id } value = { venue . id } >
177+ { venue . name }
178+ </ MenuItem >
179+ ) ) }
180+ </ Select >
181+ </ FormControl >
182+
183+
184+ </ Stack >
185+ </ DialogContent >
186+ < DialogActions >
187+ < Button onClick = { handleClose } > Cancel</ Button >
188+ < Button onClick = { handleSelect } disabled = { ! selectedVenue } variant = "contained" >
189+ Associate Lesson
190+ </ Button >
191+ </ DialogActions >
192+ </ Dialog >
193+ ) ;
194+ } ;
0 commit comments