1+ import React , { useRef , useEffect } from 'react' ;
2+ import { RecordingConfig } from '../services/recorder' ;
3+
4+ type ConfigModalProps = {
5+ isOpen : boolean ;
6+ onClose : ( ) => void ;
7+ recordingConfig : RecordingConfig ;
8+ draftInactivityTimeLimit : number ;
9+ onDraftInactivityTimeLimitChange : ( newLimit : number ) => void ;
10+ submitInactivityTimeLimitChange : ( ) => void ;
11+ draftUploaderUrl : string ;
12+ onDraftUploaderUrlChange : ( newUrl : string ) => void ;
13+ submitUploaderUrlChange : ( ) => void ;
14+ } ;
15+
16+ export function asModal < P extends { isOpen : boolean ; onClose : ( ) => void } > (
17+ Component : React . ComponentType < P >
18+ ) {
19+ return ( props : P ) => {
20+ const dialogRef = useRef < HTMLDialogElement > ( null ) ;
21+
22+ useEffect ( ( ) => {
23+ const dialog = dialogRef . current ;
24+ if ( ! dialog ) return ;
25+
26+ if ( props . isOpen ) {
27+ dialog . showModal ( ) ;
28+ } else {
29+ dialog . close ( ) ;
30+ }
31+ } , [ props . isOpen ] ) ;
32+
33+ const handleClose = ( ) => {
34+ props . onClose ( ) ;
35+ } ;
36+
37+ return (
38+ < dialog ref = { dialogRef } onClose = { handleClose } >
39+ < Component { ...props } />
40+ </ dialog >
41+ ) ;
42+ } ;
43+ }
44+
45+ function ConfigModalBase ( {
46+ onClose,
47+ recordingConfig,
48+ draftInactivityTimeLimit,
49+ onDraftInactivityTimeLimitChange,
50+ submitInactivityTimeLimitChange,
51+ draftUploaderUrl,
52+ onDraftUploaderUrlChange,
53+ submitUploaderUrlChange
54+ } : ConfigModalProps ) {
55+ return (
56+ < div >
57+ < div className = "modal-header" >
58+ < h2 className = "modal-title" > ⚙️ Recording Settings</ h2 >
59+ </ div >
60+ < div className = "modal-body" >
61+ < div className = "form-group" >
62+ < label className = "form-label" htmlFor = "inactivity-limit" >
63+ Inactivity Time Limit (seconds)
64+ </ label >
65+ < input
66+ id = "inactivity-limit"
67+ type = 'number'
68+ className = 'form-input'
69+ value = { draftInactivityTimeLimit }
70+ onChange = { ( e ) => onDraftInactivityTimeLimitChange ( parseInt ( e . target . value ) ) }
71+ min = { 1 }
72+ max = { 300 }
73+ />
74+ < p className = "text-muted" style = { { fontSize : '0.875rem' , marginTop : '0.5rem' } } >
75+ Recording will automatically stop after this many seconds of inactivity
76+ </ p >
77+ </ div >
78+
79+ < div className = "form-group" >
80+ < label className = "form-label" htmlFor = "uploader-url" >
81+ Uploader URL
82+ </ label >
83+ < input
84+ id = "uploader-url"
85+ type = 'text'
86+ className = 'form-input'
87+ value = { draftUploaderUrl }
88+ onChange = { ( e ) => onDraftUploaderUrlChange ( e . target . value ) }
89+ placeholder = "https://example.com/upload"
90+ />
91+ < p className = "text-muted" style = { { fontSize : '0.875rem' , marginTop : '0.5rem' } } >
92+ URL endpoint for uploading recorded files (leave empty to disable uploads)
93+ </ p >
94+ </ div >
95+ </ div >
96+ < div className = "modal-footer" >
97+ < button
98+ type = 'button'
99+ className = 'btn-secondary'
100+ onClick = { onClose }
101+ >
102+ Cancel
103+ </ button >
104+ < button
105+ type = 'button'
106+ className = 'btn-primary'
107+ onClick = { ( ) => {
108+ submitInactivityTimeLimitChange ( ) ;
109+ submitUploaderUrlChange ( ) ;
110+ onClose ( ) ;
111+ } }
112+ >
113+ Save Changes
114+ </ button >
115+ </ div >
116+ </ div >
117+ ) ;
118+ }
119+
120+ export const ConfigModal = asModal ( ConfigModalBase ) ;
0 commit comments