v0.6.2 added help window
This commit is contained in:
71
frontend/src/components/HelpModal.jsx
Normal file
71
frontend/src/components/HelpModal.jsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { marked } from 'marked';
|
||||
import { api } from '../utils/api.js';
|
||||
|
||||
// Configure marked for safe rendering
|
||||
marked.setOptions({ breaks: true, gfm: true });
|
||||
|
||||
export default function HelpModal({ onClose, dismissed: initialDismissed }) {
|
||||
const [content, setContent] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [dismissed, setDismissed] = useState(!!initialDismissed);
|
||||
|
||||
useEffect(() => {
|
||||
api.getHelp()
|
||||
.then(({ content }) => setContent(content))
|
||||
.catch(() => setContent('# Getting Started\n\nHelp content could not be loaded.'))
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
|
||||
const handleDismissToggle = async (e) => {
|
||||
const val = e.target.checked;
|
||||
setDismissed(val);
|
||||
try {
|
||||
await api.dismissHelp(val);
|
||||
if (val) onClose(); // immediately close when "do not show again" checked
|
||||
} catch (_) {}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
|
||||
<div className="modal help-modal">
|
||||
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between" style={{ marginBottom: 16 }}>
|
||||
<h2 className="modal-title" style={{ margin: 0 }}>Getting Started</h2>
|
||||
<button className="btn-icon" onClick={onClose}>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Scrollable markdown content */}
|
||||
<div className="help-content">
|
||||
{loading ? (
|
||||
<div style={{ textAlign: 'center', padding: 40, color: 'var(--text-tertiary)' }}>Loading…</div>
|
||||
) : (
|
||||
<div
|
||||
className="help-markdown"
|
||||
dangerouslySetInnerHTML={{ __html: marked.parse(content) }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="help-footer">
|
||||
<label className="flex items-center gap-2 text-sm" style={{ cursor: 'pointer', color: 'var(--text-secondary)' }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={dismissed}
|
||||
onChange={handleDismissToggle}
|
||||
/>
|
||||
Do not show again at login
|
||||
</label>
|
||||
<button className="btn btn-primary btn-sm" onClick={onClose}>Close</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -148,7 +148,7 @@ export default function SettingsModal({ onClose }) {
|
||||
{settings.pw_reset_active === 'true' && (
|
||||
<div className="warning-banner">
|
||||
<span>⚠️</span>
|
||||
<span><strong>PW_RESET is active.</strong> The default admin password is being reset on every restart. Set PW_RESET=false in your environment variables to stop this.</span>
|
||||
<span><strong>ADMPW_RESET is active.</strong> The default admin password is being reset on every restart. Set ADMPW_RESET=false in your environment variables to stop this.</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,7 @@ function useAppSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
export default function Sidebar({ groups, activeGroupId, onSelectGroup, notifications, unreadGroups = new Map(), onNewChat, onProfile, onUsers, onSettings: onOpenSettings, onGroupsUpdated, isMobile, onAbout }) {
|
||||
export default function Sidebar({ groups, activeGroupId, onSelectGroup, notifications, unreadGroups = new Map(), onNewChat, onProfile, onUsers, onSettings: onOpenSettings, onGroupsUpdated, isMobile, onAbout, onHelp }) {
|
||||
const { user, logout } = useAuth();
|
||||
const { connected } = useSocket();
|
||||
const toast = useToast();
|
||||
@@ -219,6 +219,10 @@ export default function Sidebar({ groups, activeGroupId, onSelectGroup, notifica
|
||||
</>
|
||||
)}
|
||||
<hr className="divider" style={{ margin: '4px 0' }} />
|
||||
<button className="footer-menu-item" onClick={() => { setShowMenu(false); onHelp && onHelp(); }}>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
|
||||
Help
|
||||
</button>
|
||||
<button className="footer-menu-item" onClick={() => { setShowMenu(false); onAbout && onAbout(); }}>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
||||
About
|
||||
|
||||
Reference in New Issue
Block a user