Spaces:
Sleeping
Sleeping
File size: 5,635 Bytes
b0b150b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
import React, { useState, useEffect } from 'react';
import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
FormControlLabel,
Switch,
Typography,
Box,
Select,
MenuItem,
FormControl,
InputLabel,
Alert
} from '@mui/material';
import { useAuth } from '../contexts/AuthContext';
import client from '../api/client';
const SettingsModal = ({ open, onClose }) => {
const { user, refreshUser } = useAuth();
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);
// Default preferences
const [preferences, setPreferences] = useState({
tts_provider: 'elevenlabs',
auto_play_tts: false
});
useEffect(() => {
if (open && user?.preferences) {
setPreferences(prev => ({
...prev,
...user.preferences
}));
setError(null);
setSuccess(false);
}
}, [open, user]);
const handleChange = (prop) => (event) => {
const value = event.target.type === 'checkbox' ? event.target.checked : event.target.value;
setPreferences(prev => ({ ...prev, [prop]: value }));
setSuccess(false);
};
const handleSave = async () => {
setLoading(true);
setError(null);
try {
await client.put('/api/auth/preferences', preferences);
// Refresh user data to get updated preferences
await refreshUser();
setSuccess(true);
setTimeout(() => {
if (open) onClose();
}, 1000);
} catch (err) {
console.error('Failed to save settings:', err);
setError('Failed to save settings. Please try again.');
} finally {
setLoading(false);
}
};
return (
<Dialog
open={open}
onClose={loading ? null : onClose}
PaperProps={{
sx: {
bgcolor: '#1E1E2E',
color: 'white',
minWidth: '400px',
border: '1px solid rgba(255,255,255,0.1)'
}
}}
>
<DialogTitle>User Settings</DialogTitle>
<DialogContent>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, mt: 1 }}>
{error && <Alert severity="error">{error}</Alert>}
{success && <Alert severity="success">Settings saved successfully!</Alert>}
<Box>
<Typography variant="subtitle2" color="primary" gutterBottom>
Text-to-Speech (Voice)
</Typography>
<FormControl fullWidth margin="dense" variant="outlined">
<InputLabel sx={{ color: 'text.secondary' }}>TTS Provider</InputLabel>
<Select
value={preferences.tts_provider}
onChange={handleChange('tts_provider')}
label="TTS Provider"
sx={{
color: 'white',
'.MuiOutlinedInput-notchedOutline': { borderColor: 'rgba(255,255,255,0.2)' },
'&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'rgba(255,255,255,0.4)' },
'.MuiSvgIcon-root': { color: 'white' }
}}
>
<MenuItem value="elevenlabs">ElevenLabs (High Quality)</MenuItem>
<MenuItem value="web_speech">Web Browser (Free)</MenuItem>
</Select>
</FormControl>
<FormControlLabel
control={
<Switch
checked={preferences.auto_play_tts}
onChange={handleChange('auto_play_tts')}
color="primary"
/>
}
label={
<Box>
<Typography variant="body1">Auto-play Responses</Typography>
<Typography variant="caption" color="text.secondary">
Automatically read out assistant messages
</Typography>
</Box>
}
sx={{ mt: 2 }}
/>
</Box>
</Box>
</DialogContent>
<DialogActions sx={{ p: 2 }}>
<Button
onClick={onClose}
disabled={loading}
sx={{ color: 'text.secondary' }}
>
Cancel
</Button>
<Button
onClick={handleSave}
variant="contained"
disabled={loading}
sx={{ bgcolor: 'primary.main', '&:hover': { bgcolor: 'primary.dark' } }}
>
{loading ? 'Saving...' : 'Save Changes'}
</Button>
</DialogActions>
</Dialog>
);
};
export default SettingsModal;
|