@@ -12,6 +12,8 @@ import { Label } from "@/components/ui/label";
1212import { Input } from "@/components/ui/input" ;
1313import { RadioGroup , RadioGroupItem } from "@/app/components/ui/radio-group" ;
1414import { Button } from "@/components/ui/button" ;
15+ import { Checkbox } from "@/app/components/ui/checkbox" ;
16+ import { AlertCircle } from "lucide-react" ;
1517
1618interface SettingsDialogProps {
1719 isOpen : boolean ;
@@ -29,6 +31,8 @@ export const SettingsDialog = ({
2931 setOpenaiApiKey,
3032 geminiApiKey,
3133 setGeminiApiKey,
34+ saveToLocalStorage,
35+ setSaveToLocalStorage,
3236 refreshFromStorage,
3337 } = useAssistantSettings ( ) ;
3438
@@ -70,28 +74,106 @@ export const SettingsDialog = ({
7074 </ div >
7175
7276 { provider === "openai" && (
73- < div className = "space-y-2" >
74- < Label htmlFor = "openai-key" > OpenAI API Key</ Label >
75- < Input
76- id = "openai-key"
77- type = "password"
78- placeholder = "sk-..."
79- value = { openaiApiKey }
80- onChange = { ( e ) => setOpenaiApiKey ( e . target . value ) }
81- />
77+ < div className = "space-y-4" >
78+ < div className = "space-y-2" >
79+ < Label htmlFor = "openai-key" > OpenAI API Key</ Label >
80+ < Input
81+ id = "openai-key"
82+ type = "password"
83+ placeholder = "sk-..."
84+ value = { openaiApiKey }
85+ onChange = { ( e ) => setOpenaiApiKey ( e . target . value ) }
86+ />
87+ </ div >
88+
89+ < div className = "space-y-3" >
90+ < div className = "flex items-center space-x-2" >
91+ < Checkbox
92+ id = "save-to-storage"
93+ checked = { saveToLocalStorage }
94+ onCheckedChange = { ( checked ) =>
95+ setSaveToLocalStorage ( checked === true )
96+ }
97+ />
98+ < Label
99+ htmlFor = "save-to-storage"
100+ className = "text-sm font-normal cursor-pointer"
101+ >
102+ 保存 API Key 到本地存储
103+ </ Label >
104+ </ div >
105+
106+ { saveToLocalStorage && (
107+ < div className = "rounded-lg border border-amber-200 bg-amber-50 dark:border-amber-900/50 dark:bg-amber-950/20 p-3" >
108+ < div className = "flex gap-2" >
109+ < AlertCircle className = "size-4 text-amber-600 dark:text-amber-500 shrink-0 mt-0.5" />
110+ < div className = "space-y-1 text-xs text-amber-900 dark:text-amber-200" >
111+ < p className = "font-medium" > 安全提示</ p >
112+ < ul className = "space-y-0.5 list-disc list-inside" >
113+ < li >
114+ API Key 将以明文形式存储在浏览器的 localStorage 中
115+ </ li >
116+ < li > 任何能访问此浏览器的人都可能获取您的 API Key</ li >
117+ < li > 请勿在公用电脑或共享设备上勾选此选项</ li >
118+ < li > 建议定期更换 API Key 以提高安全性</ li >
119+ </ ul >
120+ </ div >
121+ </ div >
122+ </ div >
123+ ) }
124+ </ div >
82125 </ div >
83126 ) }
84127
85128 { provider === "gemini" && (
86- < div className = "space-y-2" >
87- < Label htmlFor = "gemini-key" > Gemini API Key</ Label >
88- < Input
89- id = "gemini-key"
90- type = "password"
91- placeholder = "AIzaSy..."
92- value = { geminiApiKey }
93- onChange = { ( e ) => setGeminiApiKey ( e . target . value ) }
94- />
129+ < div className = "space-y-4" >
130+ < div className = "space-y-2" >
131+ < Label htmlFor = "gemini-key" > Gemini API Key</ Label >
132+ < Input
133+ id = "gemini-key"
134+ type = "password"
135+ placeholder = "AIzaSy..."
136+ value = { geminiApiKey }
137+ onChange = { ( e ) => setGeminiApiKey ( e . target . value ) }
138+ />
139+ </ div >
140+
141+ < div className = "space-y-3" >
142+ < div className = "flex items-center space-x-2" >
143+ < Checkbox
144+ id = "save-to-storage"
145+ checked = { saveToLocalStorage }
146+ onCheckedChange = { ( checked ) =>
147+ setSaveToLocalStorage ( checked === true )
148+ }
149+ />
150+ < Label
151+ htmlFor = "save-to-storage"
152+ className = "text-sm font-normal cursor-pointer"
153+ >
154+ 保存 API Key 到本地存储
155+ </ Label >
156+ </ div >
157+
158+ { saveToLocalStorage && (
159+ < div className = "rounded-lg border border-amber-200 bg-amber-50 dark:border-amber-900/50 dark:bg-amber-950/20 p-3" >
160+ < div className = "flex gap-2" >
161+ < AlertCircle className = "size-4 text-amber-600 dark:text-amber-500 shrink-0 mt-0.5" />
162+ < div className = "space-y-1 text-xs text-amber-900 dark:text-amber-200" >
163+ < p className = "font-medium" > 安全提示</ p >
164+ < ul className = "space-y-0.5 list-disc list-inside" >
165+ < li >
166+ API Key 将以明文形式存储在浏览器的 localStorage 中
167+ </ li >
168+ < li > 任何能访问此浏览器的人都可能获取您的 API Key</ li >
169+ < li > 请勿在公用电脑或共享设备上勾选此选项</ li >
170+ < li > 建议定期更换 API Key 以提高安全性</ li >
171+ </ ul >
172+ </ div >
173+ </ div >
174+ </ div >
175+ ) }
176+ </ div >
95177 </ div >
96178 ) }
97179
0 commit comments