File size: 5,087 Bytes
921d377
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React, { useEffect, useRef } from 'react';
import { EyeOff } from 'lucide-react';
export const DEFAULT_CHAT_SETTINGS = {
    advancedHelpEnabled: false,
    askBeforeActing: true,
    executionProfile: 'fast',
    incognito: false,
};
function Toggle({ value, onChange, }) {
    return (<button type="button" onClick={() => onChange(!value)} className={[
            'w-10 h-6 rounded-full border transition-all relative',
            value ? 'bg-white/20 border-white/25' : 'bg-white/5 border-white/10',
        ].join(' ')} aria-pressed={value}>
      <span className={[
            'absolute top-1/2 -translate-y-1/2 w-4 h-4 rounded-full transition-all',
            value ? 'left-[22px] bg-white/80' : 'left-[4px] bg-white/40',
        ].join(' ')}/>
    </button>);
}
export function ChatSettingsPopover({ open, onClose, settings, onChange, }) {
    const panelRef = useRef(null);
    useEffect(() => {
        if (!open)
            return;
        const onKeyDown = (e) => {
            if (e.key === 'Escape')
                onClose();
        };
        const onMouseDown = (e) => {
            const t = e.target;
            if (panelRef.current && !panelRef.current.contains(t))
                onClose();
        };
        window.addEventListener('keydown', onKeyDown);
        window.addEventListener('mousedown', onMouseDown);
        return () => {
            window.removeEventListener('keydown', onKeyDown);
            window.removeEventListener('mousedown', onMouseDown);
        };
    }, [open, onClose]);
    if (!open)
        return null;
    return (<div ref={panelRef} className="absolute right-0 mt-2 w-[320px] rounded-2xl border border-white/10 bg-black/80 backdrop-blur-xl shadow-2xl overflow-hidden">
      <div className="px-4 py-3 border-b border-white/10">
        <div className="text-sm font-semibold text-white/90">Chat settings</div>
        <div className="text-[11px] text-white/45 mt-0.5">
          These apply only to this chat.
        </div>
      </div>

      <div className="px-4 py-3 space-y-4">
        <div className="flex items-center justify-between gap-3">
          <div>
            <div className="text-sm text-white/90">Advanced help</div>
            <div className="text-[11px] text-white/45">
              Enables optional smart actions when available.
            </div>
          </div>
          <Toggle value={settings.advancedHelpEnabled} onChange={(v) => onChange({ ...settings, advancedHelpEnabled: v })}/>
        </div>

        <div className="flex items-center justify-between gap-3">
          <div>
            <div className="text-sm text-white/90">Ask before acting</div>
            <div className="text-[11px] text-white/45">
              Confirm before running advanced actions.
            </div>
          </div>
          <Toggle value={settings.askBeforeActing} onChange={(v) => onChange({ ...settings, askBeforeActing: v })}/>
        </div>

        {/* Divider */}
        <div className="border-t border-white/5"/>

        <div className="flex items-center justify-between gap-3">
          <div className="flex items-start gap-2">
            <EyeOff size={14} className="text-white/40 mt-0.5 shrink-0"/>
            <div>
              <div className="text-sm text-white/90">Incognito mode</div>
              <div className="text-[11px] text-white/45">
                No memories stored, no profile shared. Perfect for work tasks.
              </div>
            </div>
          </div>
          <Toggle value={settings.incognito} onChange={(v) => onChange({ ...settings, incognito: v })}/>
        </div>

        <div>
          <div className="flex items-center justify-between">
            <div>
              <div className="text-sm text-white/90">Execution style</div>
              <div className="text-[11px] text-white/45">
                Speed vs quality preference.
              </div>
            </div>
          </div>

          <div className="mt-2 grid grid-cols-3 gap-2">
            {['fast', 'balanced', 'quality'].map((p) => {
            const active = settings.executionProfile === p;
            return (<button key={p} type="button" onClick={() => onChange({ ...settings, executionProfile: p })} className={[
                    'px-3 py-2 rounded-xl text-xs font-semibold border transition-all',
                    active
                        ? 'bg-white/15 border-white/25 text-white'
                        : 'bg-white/5 border-white/10 text-white/70 hover:bg-white/10 hover:border-white/15',
                ].join(' ')}>
                  {p === 'fast' ? 'Fast' : p === 'balanced' ? 'Balanced' : 'Quality'}
                </button>);
        })}
          </div>
        </div>
      </div>

      <div className="px-4 py-3 border-t border-white/10 flex justify-end">
        <button type="button" onClick={onClose} className="text-xs px-3 py-1.5 rounded-xl bg-white/10 hover:bg-white/15 border border-white/10 hover:border-white/20 text-white/80 hover:text-white transition-all">
          Done
        </button>
      </div>
    </div>);
}