feat(settings): add textarea type, add systemInstructions

This commit is contained in:
ItzCrazyKns
2025-10-21 12:22:06 +05:30
parent 672fc3c3a8
commit c945bf1fc3
3 changed files with 105 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
import {
SelectUIConfigField,
StringUIConfigField,
TextareaUIConfigField,
UIConfigField,
} from '@/lib/config/types';
import { useState } from 'react';
@@ -156,6 +157,82 @@ const SettingsInput = ({
);
};
const SettingsTextarea = ({
field,
value,
setValue,
dataAdd,
}: {
field: TextareaUIConfigField;
value?: any;
setValue: (value: any) => void;
dataAdd: string;
}) => {
const [loading, setLoading] = useState(false);
const handleSave = async (newValue: any) => {
setLoading(true);
setValue(newValue);
try {
if (field.scope === 'client') {
localStorage.setItem(field.key, newValue);
} else {
const res = await fetch('/api/config', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
key: `${dataAdd}.${field.key}`,
value: newValue,
}),
});
if (!res.ok) {
console.error('Failed to save config:', await res.text());
throw new Error('Failed to save configuration');
}
}
} catch (error) {
console.error('Error saving config:', error);
toast.error('Failed to save configuration.');
} finally {
setTimeout(() => setLoading(false), 150);
}
};
return (
<section className="rounded-xl border border-light-200 bg-light-primary/80 p-4 lg:p-6 transition-colors dark:border-dark-200 dark:bg-dark-primary/80">
<div className="space-y-3 lg:space-y-5">
<div>
<h4 className="text-sm lg:text-base text-black dark:text-white">
{field.name}
</h4>
<p className="text-[11px] lg:text-xs text-black/50 dark:text-white/50">
{field.description}
</p>
</div>
<div className="relative">
<textarea
value={value ?? field.default ?? ''}
onChange={(event) => setValue(event.target.value)}
onBlur={(event) => handleSave(event.target.value)}
className="w-full rounded-lg border border-light-200 dark:border-dark-200 bg-light-primary dark:bg-dark-primary px-3 py-2 lg:px-4 lg:py-3 pr-10 !text-xs lg:!text-sm text-black/80 dark:text-white/80 placeholder:text-black/40 dark:placeholder:text-white/40 focus-visible:outline-none focus-visible:border-light-300 dark:focus-visible:border-dark-300 transition-colors disabled:cursor-not-allowed disabled:opacity-60"
placeholder={field.placeholder}
rows={4}
disabled={loading}
/>
{loading && (
<span className="pointer-events-none absolute right-3 translate-y-3 text-black/40 dark:text-white/40">
<Loader2 className="h-4 w-4 animate-spin" />
</span>
)}
</div>
</div>
</section>
);
};
const SettingsField = ({
field,
value,
@@ -186,6 +263,15 @@ const SettingsField = ({
dataAdd={dataAdd}
/>
);
case 'textarea':
return (
<SettingsTextarea
field={field}
value={val}
setValue={setVal}
dataAdd={dataAdd}
/>
);
default:
return <div>Unsupported field type: {field.type}</div>;
}

View File

@@ -40,6 +40,16 @@ class ConfigManager {
default: 'dark',
scope: 'client',
},
{
name: 'System Instructions',
key: 'systemInstructions',
type: 'textarea',
required: false,
description: 'Add custom behavior or tone for the model.',
placeholder:
'e.g., "Respond in a friendly and concise tone" or "Use British English and format answers as bullet points."',
scope: 'client',
},
],
modelProviders: [],
search: [

View File

@@ -32,10 +32,17 @@ type PasswordUIConfigField = BaseUIConfigField & {
default?: string;
};
type TextareaUIConfigField = BaseUIConfigField & {
type: 'textarea';
placeholder?: string;
default?: string;
};
type UIConfigField =
| StringUIConfigField
| SelectUIConfigField
| PasswordUIConfigField;
| PasswordUIConfigField
| TextareaUIConfigField;
type ConfigModelProvider = {
id: string;
@@ -87,4 +94,5 @@ export type {
StringUIConfigField,
ModelProviderUISection,
ConfigModelProvider,
TextareaUIConfigField,
};