feat: add HeatmapCell component and Apple-inspired global design system with dark/light mode support.

This commit is contained in:
Michael committed 2026-02-26 15:54:47 +01:00
1 parent 174b7fa36c
commit 3438d1b35d
3 files changed
+104 -51

No files matched your search

+55 -15
View File
@@ -2,6 +2,42 @@ import { NextResponse } from "next/server";
import { db } from "@/db";
import { aiSupplierContext } from "@/db/schema";
import { eq } from "drizzle-orm";
import fs from "fs";
import path from "path";
// File system fallback for environments without PostgreSQL
const DATA_DIR = path.join(process.cwd(), "data");
const FALLBACK_FILE_PATH = path.join(DATA_DIR, "ai-context.json");
function ensureFallbackFileExists() {
if (!fs.existsSync(DATA_DIR)) {
fs.mkdirSync(DATA_DIR, { recursive: true });
}
if (!fs.existsSync(FALLBACK_FILE_PATH)) {
fs.writeFileSync(FALLBACK_FILE_PATH, JSON.stringify({}), "utf-8");
}
}
function getFallbackContext(codeFournisseur: string): string {
ensureFallbackFileExists();
try {
const data = JSON.parse(fs.readFileSync(FALLBACK_FILE_PATH, "utf-8"));
return data[codeFournisseur] || "";
} catch {
return "";
}
}
function saveFallbackContext(codeFournisseur: string, contextText: string) {
ensureFallbackFileExists();
try {
const data = JSON.parse(fs.readFileSync(FALLBACK_FILE_PATH, "utf-8"));
data[codeFournisseur] = contextText;
fs.writeFileSync(FALLBACK_FILE_PATH, JSON.stringify(data, null, 2), "utf-8");
} catch (err) {
console.error("Error saving fallback context:", err);
}
}
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
@@ -19,9 +55,8 @@ export async function GET(request: Request) {
return NextResponse.json({ context: result[0]?.context || "" });
} catch (error) {
console.error("Error fetching AI context:", error);
// Fallback en cas d'erreur de BDD ou si la table n'est pas encore créée
return NextResponse.json({ context: "" });
console.warn("DB fetch failed, using fallback JSON for AI context.");
return NextResponse.json({ context: getFallbackContext(codeFournisseur) });
}
}
@@ -34,23 +69,28 @@ export async function POST(request: Request) {
return NextResponse.json({ error: "Fournisseur manquant" }, { status: 400 });
}
await db.insert(aiSupplierContext)
.values({
codeFournisseur,
context: context || "",
updatedAt: new Date()
})
.onConflictDoUpdate({
target: aiSupplierContext.codeFournisseur,
set: {
try {
await db.insert(aiSupplierContext)
.values({
codeFournisseur,
context: context || "",
updatedAt: new Date()
}
});
})
.onConflictDoUpdate({
target: aiSupplierContext.codeFournisseur,
set: {
context: context || "",
updatedAt: new Date()
}
});
} catch (dbError) {
console.warn("DB insert failed, saving to fallback JSON.", dbError);
saveFallbackContext(codeFournisseur, context || "");
}
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error saving AI context:", error);
console.error("Error in AI context API:", error);
return NextResponse.json({ error: "Erreur lors de la sauvegarde" }, { status: 500 });
}
}