v0.12.41 New settings options for messages
This commit is contained in:
@@ -10,6 +10,94 @@ const APP_TYPES = {
|
||||
'RosterChirp-Team': { label: 'RosterChirp-Team', desc: 'Chat, Branding, Group Manager and Schedule Manager.' },
|
||||
};
|
||||
|
||||
// ── Toggle switch ─────────────────────────────────────────────────────────────
|
||||
function Toggle({ checked, onChange }) {
|
||||
return (
|
||||
<div
|
||||
onClick={() => onChange(!checked)}
|
||||
role="switch"
|
||||
aria-checked={checked}
|
||||
style={{
|
||||
width: 44, height: 24, borderRadius: 12, cursor: 'pointer', flexShrink: 0,
|
||||
background: checked ? 'var(--primary)' : 'var(--border)',
|
||||
position: 'relative', transition: 'background 0.2s',
|
||||
}}
|
||||
>
|
||||
<div style={{
|
||||
position: 'absolute', top: 2, left: checked ? 22 : 2,
|
||||
width: 20, height: 20, borderRadius: '50%',
|
||||
background: 'white', transition: 'left 0.2s',
|
||||
boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
|
||||
}} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── Messages Tab ──────────────────────────────────────────────────────────────
|
||||
function MessagesTab() {
|
||||
const toast = useToast();
|
||||
const [settings, setSettings] = useState({
|
||||
msgPublic: true,
|
||||
msgGroup: true,
|
||||
msgPrivateGroup: true,
|
||||
msgU2U: true,
|
||||
});
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
api.getSettings().then(({ settings: s }) => {
|
||||
setSettings({
|
||||
msgPublic: s.feature_msg_public !== 'false',
|
||||
msgGroup: s.feature_msg_group !== 'false',
|
||||
msgPrivateGroup: s.feature_msg_private_group !== 'false',
|
||||
msgU2U: s.feature_msg_u2u !== 'false',
|
||||
});
|
||||
}).catch(() => {});
|
||||
}, []);
|
||||
|
||||
const toggle = (key) => setSettings(prev => ({ ...prev, [key]: !prev[key] }));
|
||||
|
||||
const handleSave = async () => {
|
||||
setSaving(true);
|
||||
try {
|
||||
await api.updateMessageSettings(settings);
|
||||
toast('Message settings saved', 'success');
|
||||
window.dispatchEvent(new Event('rosterchirp:settings-changed'));
|
||||
} catch (e) { toast(e.message, 'error'); }
|
||||
finally { setSaving(false); }
|
||||
};
|
||||
|
||||
const rows = [
|
||||
{ key: 'msgPublic', label: 'Public Messages', desc: 'Public group channels visible to all members.' },
|
||||
{ key: 'msgGroup', label: 'Group Messages', desc: 'Private group messages managed by User Groups.' },
|
||||
{ key: 'msgPrivateGroup', label: 'Private Group Messages', desc: 'Private multi-member group conversations.' },
|
||||
{ key: 'msgU2U', label: 'Private Messages (U2U)', desc: 'One-on-one direct messages between users.' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="settings-section-label">Message Features</div>
|
||||
<p style={{ fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 16 }}>
|
||||
Disable a feature to hide it from all menus, sidebars, and modals.
|
||||
</p>
|
||||
<div style={{ border: '1px solid var(--border)', borderRadius: 'var(--radius)', overflow: 'hidden', marginBottom: 16 }}>
|
||||
{rows.map((r, i) => (
|
||||
<div key={r.key} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px', borderBottom: i < rows.length - 1 ? '1px solid var(--border)' : 'none' }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ fontSize: 14, fontWeight: 500 }}>{r.label}</div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-tertiary)', marginTop: 2 }}>{r.desc}</div>
|
||||
</div>
|
||||
<Toggle checked={settings[r.key]} onChange={() => toggle(r.key)} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button className="btn btn-primary" onClick={handleSave} disabled={saving}>
|
||||
{saving ? 'Saving…' : 'Save'}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── Team Management Tab ───────────────────────────────────────────────────────
|
||||
function TeamManagementTab() {
|
||||
const toast = useToast();
|
||||
@@ -193,7 +281,7 @@ function RegistrationTab({ onFeaturesChanged }) {
|
||||
|
||||
// ── Main modal ────────────────────────────────────────────────────────────────
|
||||
export default function SettingsModal({ onClose, onFeaturesChanged }) {
|
||||
const [tab, setTab] = useState('registration');
|
||||
const [tab, setTab] = useState('messages');
|
||||
const [appType, setAppType] = useState('RosterChirp-Chat');
|
||||
|
||||
useEffect(() => {
|
||||
@@ -208,7 +296,8 @@ export default function SettingsModal({ onClose, onFeaturesChanged }) {
|
||||
const isTeam = appType === 'RosterChirp-Team';
|
||||
|
||||
const tabs = [
|
||||
isTeam && { id: 'team', label: 'Team Management' },
|
||||
{ id: 'messages', label: 'Messages' },
|
||||
isTeam && { id: 'team', label: 'Tools' },
|
||||
{ id: 'registration', label: 'Registration' },
|
||||
].filter(Boolean);
|
||||
|
||||
@@ -231,6 +320,7 @@ export default function SettingsModal({ onClose, onFeaturesChanged }) {
|
||||
))}
|
||||
</div>
|
||||
|
||||
{tab === 'messages' && <MessagesTab />}
|
||||
{tab === 'team' && <TeamManagementTab />}
|
||||
{tab === 'registration' && <RegistrationTab onFeaturesChanged={onFeaturesChanged} />}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user