Phase 2: AI Chat, Calendar, Odoo connector, PWA

- AI Chat endpoint (/api/v1/chat) with Claude API context
- Calendar page with FullCalendar.js (day/week/month)
- Odoo API connector (import/export/webhook)
- PWA manifest + service worker for offline
- SW register component

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude CLI Agent
2026-03-29 10:12:53 +00:00
parent b5a6dd6d6f
commit 55993b70b2
16 changed files with 402 additions and 24 deletions

View File

@@ -1,4 +1,4 @@
const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000";
const API_BASE = typeof window !== "undefined" ? "" : (process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000");
interface ApiOptions {
method?: string;
@@ -14,15 +14,21 @@ async function apiFetch<T>(path: string, opts: ApiOptions = {}): Promise<T> {
headers["Authorization"] = `Bearer ${opts.token}`;
}
const res = await fetch(`${API_BASE}${path}`, {
const url = `${API_BASE}${path}`;
const res = await fetch(url, {
method: opts.method || "GET",
headers,
body: opts.body ? JSON.stringify(opts.body) : undefined,
cache: "no-store",
});
if (!res.ok) {
const err = await res.json().catch(() => ({ message: res.statusText }));
throw new Error(err.message || `HTTP ${res.status}`);
throw new Error(err.message || err.error || `HTTP ${res.status}`);
}
if (res.status === 204 || res.headers.get("content-length") === "0") {
return {} as T;
}
return res.json();