fix(ceo-web): correct imports in LegislationPage (session-provider + apiFetch pattern)
This commit is contained in:
parent
56ba4da17e
commit
5b734aa14b
1 changed files with 35 additions and 65 deletions
|
|
@ -1,26 +1,22 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useSession } from '../../../lib/session';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { apiFetch } from '../../../lib/api';
|
import { apiFetch } from '../../../lib/api';
|
||||||
|
import { useSession } from '../../../components/session-provider';
|
||||||
|
|
||||||
interface LegResult {
|
interface LegResult {
|
||||||
country?: string;
|
country?: string;
|
||||||
section?: string;
|
section?: string;
|
||||||
text?: string;
|
text?: string;
|
||||||
source_id?: string;
|
source_id?: string;
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ApiSearchResponse {
|
|
||||||
scenario?: string;
|
|
||||||
country_filter?: string;
|
|
||||||
results?: LegResult[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mode = 'search' | 'ask';
|
type Mode = 'search' | 'ask';
|
||||||
|
|
||||||
export default function LegislationPage() {
|
export default function LegislationPage() {
|
||||||
const { session } = useSession();
|
const { activeTenant } = useSession();
|
||||||
|
const tenantId = activeTenant?.tenantId ?? null;
|
||||||
|
|
||||||
const [mode, setMode] = useState<Mode>('ask');
|
const [mode, setMode] = useState<Mode>('ask');
|
||||||
const [input, setInput] = useState('');
|
const [input, setInput] = useState('');
|
||||||
const [country, setCountry] = useState('DE');
|
const [country, setCountry] = useState('DE');
|
||||||
|
|
@ -32,32 +28,29 @@ export default function LegislationPage() {
|
||||||
|
|
||||||
async function handleSubmit(e: React.FormEvent) {
|
async function handleSubmit(e: React.FormEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!input.trim() || !session) return;
|
if (!input.trim()) return;
|
||||||
setLoading(true); setError(null); setResults([]); setAiAnswer(null);
|
setLoading(true); setError(null); setResults([]); setAiAnswer(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const headers = {
|
|
||||||
Authorization: `Bearer ${session.access_token}`,
|
|
||||||
'x-tenant-id': session.tenant_id,
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (mode === 'search') {
|
if (mode === 'search') {
|
||||||
const data: ApiSearchResponse = await apiFetch('/v1/external/legislation/search', {
|
const data = await apiFetch<{ results?: LegResult[] }>('/v1/external/legislation/search', {
|
||||||
method: 'POST', headers,
|
method: 'POST',
|
||||||
body: JSON.stringify({ scenario: input.trim(), country, topK: 10 }),
|
body: { scenario: input.trim(), country, topK: 10 },
|
||||||
|
tenantId,
|
||||||
});
|
});
|
||||||
setResults(data.results ?? []);
|
setResults(data.results ?? []);
|
||||||
} else {
|
} else {
|
||||||
const data = await apiFetch('/v1/external/legislation/ask', {
|
const data = await apiFetch<{ textResponse?: string; response?: string }>('/v1/external/legislation/ask', {
|
||||||
method: 'POST', headers,
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: {
|
||||||
message: `${input.trim()} (context juridic: ${country})`,
|
message: `${input.trim()} (context juridic: ${country})`,
|
||||||
sessionId: 'ceo-legislation-' + Date.now(),
|
country,
|
||||||
}),
|
type: 'general',
|
||||||
}) as Record<string, unknown>;
|
sessionId: `ceo-legislation-${Date.now()}`,
|
||||||
const text = (data?.textResponse ?? data?.response ?? data?.message ?? '') as string;
|
},
|
||||||
setAiAnswer(text);
|
tenantId,
|
||||||
|
});
|
||||||
|
setAiAnswer(data?.textResponse ?? data?.response ?? '');
|
||||||
}
|
}
|
||||||
setSearched(true);
|
setSearched(true);
|
||||||
} catch {
|
} catch {
|
||||||
|
|
@ -79,7 +72,6 @@ export default function LegislationPage() {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mode toggle */}
|
|
||||||
<div className="flex gap-1 p-1 bg-muted rounded-lg w-fit">
|
<div className="flex gap-1 p-1 bg-muted rounded-lg w-fit">
|
||||||
{(['ask', 'search'] as Mode[]).map((m) => (
|
{(['ask', 'search'] as Mode[]).map((m) => (
|
||||||
<button key={m} onClick={() => setMode(m)}
|
<button key={m} onClick={() => setMode(m)}
|
||||||
|
|
@ -88,7 +80,7 @@ export default function LegislationPage() {
|
||||||
? 'bg-background shadow-sm text-foreground'
|
? 'bg-background shadow-sm text-foreground'
|
||||||
: 'text-muted-foreground hover:text-foreground'
|
: 'text-muted-foreground hover:text-foreground'
|
||||||
}`}>
|
}`}>
|
||||||
{m === 'ask' ? '🤖 Întreabă agentul AI' : '📄 Caută în corpus'}
|
{m === 'ask' ? 'Întreabă agentul AI' : 'Caută în corpus'}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -100,72 +92,52 @@ export default function LegislationPage() {
|
||||||
? 'ex: Am o firmă GmbH în Germania și vreau să angajez remote din România. Ce obligații legale am?'
|
? 'ex: Am o firmă GmbH în Germania și vreau să angajez remote din România. Ce obligații legale am?'
|
||||||
: 'Descrie situația ta complet pentru a obține secțiunile de lege relevante...'
|
: 'Descrie situația ta complet pentru a obține secțiunile de lege relevante...'
|
||||||
}
|
}
|
||||||
className="w-full rounded-lg border bg-background px-4 py-3 text-sm
|
className="w-full rounded-lg border bg-background px-4 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring resize-none"
|
||||||
focus:outline-none focus:ring-2 focus:ring-ring resize-none"
|
|
||||||
/>
|
/>
|
||||||
<div className="flex gap-3 flex-wrap">
|
<div className="flex gap-3 flex-wrap">
|
||||||
<select value={country} onChange={(e) => setCountry(e.target.value)}
|
<select value={country} onChange={(e) => setCountry(e.target.value)}
|
||||||
className="rounded-lg border bg-background px-3 py-2 text-sm
|
className="rounded-lg border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring">
|
||||||
focus:outline-none focus:ring-2 focus:ring-ring">
|
|
||||||
<option value="DE">Germania (DE)</option>
|
<option value="DE">Germania (DE)</option>
|
||||||
<option value="RO">România (RO)</option>
|
<option value="RO">România (RO)</option>
|
||||||
<option value="EU">UE (EU)</option>
|
<option value="EU">UE (EU)</option>
|
||||||
<option value="AT">Austria (AT)</option>
|
<option value="FR">Franța (FR)</option>
|
||||||
|
<option value="UK">UK (UK)</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="submit" disabled={loading || !input.trim()}
|
<button type="submit" disabled={loading || !input.trim()}
|
||||||
className="rounded-lg bg-primary px-6 py-2 text-sm font-medium
|
className="rounded-lg bg-primary px-6 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50">
|
||||||
text-primary-foreground hover:bg-primary/90 disabled:opacity-50">
|
|
||||||
{loading ? (mode === 'ask' ? 'Agent răspunde...' : 'Se caută...') : (mode === 'ask' ? 'Întreabă' : 'Caută')}
|
{loading ? (mode === 'ask' ? 'Agent răspunde...' : 'Se caută...') : (mode === 'ask' ? 'Întreabă' : 'Caută')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{error && (
|
{error && (
|
||||||
<div className="rounded-lg border border-destructive/40 bg-destructive/10 px-4 py-3
|
<div className="rounded-lg border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive">
|
||||||
text-sm text-destructive">
|
|
||||||
{error}
|
{error}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* AI Answer */}
|
|
||||||
{aiAnswer && (
|
{aiAnswer && (
|
||||||
<div className="rounded-xl border bg-card p-5 space-y-3">
|
<div className="rounded-xl border bg-card p-5 space-y-3">
|
||||||
<div className="flex items-center gap-2 text-sm font-medium">
|
<p className="text-sm font-medium">Răspuns agent legislație</p>
|
||||||
<span>🤖</span>
|
<div className="text-sm leading-relaxed whitespace-pre-wrap text-foreground">{aiAnswer}</div>
|
||||||
<span>Răspuns agent legislație</span>
|
|
||||||
</div>
|
|
||||||
<div className="text-sm leading-relaxed whitespace-pre-wrap text-foreground">
|
|
||||||
{aiAnswer}
|
|
||||||
</div>
|
|
||||||
<p className="text-xs text-muted-foreground border-t pt-2">
|
<p className="text-xs text-muted-foreground border-t pt-2">
|
||||||
Generat de agentul AnythingLLM · Nu constituie consultanță juridică
|
Generat de agentul AnythingLLM · Nu constituie consultanță juridică
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Vector search results */}
|
|
||||||
{results.length > 0 && (
|
{results.length > 0 && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">{results.length} secțiuni relevante găsite</p>
|
||||||
{results.length} secțiuni relevante găsite
|
|
||||||
</p>
|
|
||||||
{results.map((r, i) => (
|
{results.map((r, i) => (
|
||||||
<div key={i} className="rounded-xl border bg-card p-4 space-y-2">
|
<div key={i} className="rounded-xl border bg-card p-4 space-y-2">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{r.country && (
|
{r.country && (
|
||||||
<span className="text-xs bg-primary/10 text-primary px-2 py-0.5 rounded font-mono font-medium">
|
<span className="text-xs bg-primary/10 text-primary px-2 py-0.5 rounded font-mono font-medium">{r.country}</span>
|
||||||
{r.country}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{r.section && (
|
|
||||||
<span className="text-sm font-medium">{r.section}</span>
|
|
||||||
)}
|
)}
|
||||||
|
{r.section && <span className="text-sm font-medium">{r.section}</span>}
|
||||||
</div>
|
</div>
|
||||||
{r.text && (
|
{r.text && <p className="text-xs text-muted-foreground leading-relaxed line-clamp-4">{r.text}</p>}
|
||||||
<p className="text-xs text-muted-foreground leading-relaxed line-clamp-4">
|
|
||||||
{r.text}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<p className="text-xs text-muted-foreground/60">{r.source_id}</p>
|
<p className="text-xs text-muted-foreground/60">{r.source_id}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
@ -173,10 +145,8 @@ export default function LegislationPage() {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{searched && !loading && results.length === 0 && !aiAnswer && !error && (
|
{searched && !loading && results.length === 0 && !aiAnswer && !error && (
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">Niciun rezultat pentru scenariul introdus.</p>
|
||||||
Niciun rezultat pentru scenariul introdus.
|
|
||||||
</p>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue