feat: implement Mistral BYOK feature for OCR processing with user profile integration

This commit is contained in:
2025-12-21 15:16:41 +05:30
parent 0f277d6b3d
commit 8919942322
6 changed files with 80 additions and 9 deletions

View File

@@ -18,6 +18,7 @@ interface UserProfile {
alcohol: boolean | null
diet: string | null
avatar_url: string | null
has_mistral_key: boolean
}
export function ProfilePage() {
@@ -37,6 +38,8 @@ export function ProfilePage() {
const [alcohol, setAlcohol] = useState<boolean | null>(null)
const [dietId, setDietId] = useState<number | null>(null)
const [avatarUrl, setAvatarUrl] = useState<string | null>(null)
const [mistralApiKey, setMistralApiKey] = useState('')
const [hasMistralKey, setHasMistralKey] = useState(false)
const avatarOptions = [
...[1, 2, 3, 4, 5, 6, 7].map(i => `/icons/user/icons8-male-user-50${i === 1 ? '' : `-${i}`}.png`),
@@ -69,6 +72,7 @@ export function ProfilePage() {
const diet = dietsData.find((d: Diet) => d.name === profile.diet)
setDietId(diet?.id || null)
setAvatarUrl(profile.avatar_url)
setHasMistralKey(profile.has_mistral_key)
})
})
.finally(() => {
@@ -102,6 +106,7 @@ export function ProfilePage() {
alcohol,
diet_id: dietId,
avatar_url: avatarUrl,
mistral_api_key: mistralApiKey || null,
}),
})
@@ -277,6 +282,27 @@ export function ProfilePage() {
</div>
</div>
{/* API Keys */}
<div className="card mb-lg">
<h3 className="mb-md">API Keys</h3>
<p className="text-secondary text-sm mb-md">Use your own Mistral API key for document parsing (optional)</p>
<div className="form-group">
<label htmlFor="mistralKey">Mistral API Key</label>
<input
id="mistralKey"
type="password"
className="input"
value={mistralApiKey}
onChange={(e) => setMistralApiKey(e.target.value)}
placeholder={hasMistralKey ? '••••••••••••••••' : 'Enter your API key'}
/>
{hasMistralKey && (
<span className="text-xs text-secondary mt-xs">You have an API key configured. Enter a new one to update.</span>
)}
</div>
</div>
{message && (
<div className={message.type === 'success' ? 'success-message' : 'error-message'}>
{message.text}