All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m12s
Replace JSON-string embeddings with native pgvector(1536) storage and add PostgreSQL full-text search (tsvector/GIN) with Reciprocal Rank Fusion for hybrid keyword + semantic ranking. Changes: - NoteEmbedding.embedding: String → vector(1536) via pgvector - NoteEmbedding: added updatedAt for reindex tracking - Note: added tsv (tsvector) with auto-update trigger for FTS - semantic-search.service: hybrid FTS + vector search with RRF fusion - embedding.service: toVectorString() for pgvector SQL literals - Removed JS-side cosine similarity loops (now DB-side via <=>) - Added HNSW index on NoteEmbedding.embedding (cosine distance) - Added GIN index on Note.tsv for FTS queries Schema migration in: prisma/migrations/20260512120000_pgvector_and_fts_search/ Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
153 lines
8.5 KiB
TypeScript
153 lines
8.5 KiB
TypeScript
import React from 'react';
|
|
import { Sparkles, Edit3, MessageCircle, Languages, Tag, History, FlaskConical } from 'lucide-react';
|
|
import { motion } from 'motion/react';
|
|
|
|
const AISettingCard = ({ icon, title, description, defaultChecked = false }: any) => (
|
|
<div className="bg-white/40 dark:bg-white/5 border border-border rounded-2xl p-6 flex items-center justify-between group hover:shadow-xl hover:shadow-blueprint/5 transition-all duration-300">
|
|
<div className="flex items-center gap-5">
|
|
<div className="p-3 bg-paper dark:bg-blueprint/10 rounded-2xl text-blueprint group-hover:bg-blueprint group-hover:text-white group-hover:scale-110 transition-all duration-300 border border-blueprint/20">
|
|
{icon}
|
|
</div>
|
|
<div className="space-y-1">
|
|
<h4 className="text-[13px] font-bold text-ink">{title}</h4>
|
|
<p className="text-[10px] text-muted-ink leading-relaxed pr-4 line-clamp-2">{description}</p>
|
|
</div>
|
|
</div>
|
|
<label className="relative inline-flex items-center cursor-pointer shrink-0 ml-4">
|
|
<input type="checkbox" className="sr-only peer" defaultChecked={defaultChecked} />
|
|
<div className="w-11 h-6 bg-gray-200 dark:bg-white/10 rounded-full peer peer-checked:after:translate-x-[20px] peer-checked:after:border-white after:content-[''] after:absolute after:top-[4px] after:left-[4px] after:bg-white after:rounded-full after:h-4 after:w-4 after:transition-all duration-300 ease-in-out peer-checked:bg-blueprint"></div>
|
|
</label>
|
|
</div>
|
|
);
|
|
|
|
export const AITab: React.FC = () => {
|
|
return (
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 10 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
className="space-y-16 pb-20"
|
|
>
|
|
<div className="space-y-10">
|
|
<h3 className="text-[10px] font-bold uppercase tracking-[0.4em] text-muted-ink opacity-60">Configurez vos fonctionnalités IA et préférences</h3>
|
|
|
|
<div className="space-y-6">
|
|
<h4 className="text-sm font-bold text-ink border-b border-border/40 pb-4">Fonctionnalités IA</h4>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-5">
|
|
<AISettingCard
|
|
icon={<Edit3 size={18} />}
|
|
title="Suggestions de titre"
|
|
description="Suggérer des titres pour les notes sans titre après 50+ mots"
|
|
defaultChecked
|
|
/>
|
|
<AISettingCard
|
|
icon={<Sparkles size={18} />}
|
|
title="IA Note"
|
|
description="Active le bouton de chat IA et les outils d'amélioration du texte"
|
|
defaultChecked
|
|
/>
|
|
<AISettingCard
|
|
icon={<MessageCircle size={18} />}
|
|
title="💡 J'ai remarqué quelque chose..."
|
|
description="Aperçu quotidien de vos notes"
|
|
defaultChecked
|
|
/>
|
|
<AISettingCard
|
|
icon={<Languages size={18} />}
|
|
title="Détection de langue"
|
|
description="Détecte automatiquement la langue de vos notes"
|
|
defaultChecked
|
|
/>
|
|
<AISettingCard
|
|
icon={<Tag size={18} />}
|
|
title="Suggestion des labels"
|
|
description="Suggère et applique des étiquettes automatiquement à vos notes"
|
|
defaultChecked
|
|
/>
|
|
<AISettingCard
|
|
icon={<History size={18} />}
|
|
title="Historique des notes"
|
|
description="Active les snapshots de versions et la restauration depuis History"
|
|
defaultChecked
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 pt-6">
|
|
{/* Fréquence */}
|
|
<div className="bg-white/40 dark:bg-white/5 border border-border rounded-2xl p-8 space-y-10">
|
|
<div className="space-y-1.5 text-left text-blueprint">
|
|
<h4 className="text-sm font-bold">Fréquence</h4>
|
|
<p className="text-[10px] opacity-60 uppercase tracking-wider font-semibold">Fréquence d'analyse des connexions</p>
|
|
</div>
|
|
<div className="space-y-6">
|
|
<label className="flex items-center gap-4 cursor-pointer group">
|
|
<input type="radio" name="freq" className="sr-only peer" defaultChecked />
|
|
<div className="w-5 h-5 rounded-full border-2 border-border peer-checked:border-blueprint flex items-center justify-center p-0.5 transition-all">
|
|
<div className="w-full h-full rounded-full bg-transparent peer-checked:bg-blueprint" />
|
|
</div>
|
|
<span className="text-sm font-medium text-ink group-hover:opacity-70 transition-opacity">Quotidienne</span>
|
|
</label>
|
|
<label className="flex items-center gap-4 cursor-pointer group">
|
|
<input type="radio" name="freq" className="sr-only peer" />
|
|
<div className="w-5 h-5 rounded-full border-2 border-border peer-checked:border-blueprint flex items-center justify-center p-0.5 transition-all">
|
|
<div className="w-full h-full rounded-full bg-transparent peer-checked:bg-blueprint" />
|
|
</div>
|
|
<span className="text-sm font-medium text-ink group-hover:opacity-70 transition-opacity">Hebdomadaire</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mode d'historique */}
|
|
<div className="bg-white/40 dark:bg-white/5 border border-border rounded-2xl p-8 space-y-10">
|
|
<div className="space-y-1.5 text-left text-blueprint">
|
|
<h4 className="text-sm font-bold">Mode d'historique</h4>
|
|
<p className="text-[10px] opacity-60 uppercase tracking-wider font-semibold">Gestion des snapshots</p>
|
|
</div>
|
|
<div className="space-y-6">
|
|
<label className="flex items-center gap-4 cursor-pointer group">
|
|
<input type="radio" name="hist" className="sr-only peer" defaultChecked />
|
|
<div className="w-5 h-5 rounded-full border-2 border-border peer-checked:border-blueprint flex items-center justify-center p-0.5 transition-all">
|
|
<div className="w-full h-full rounded-full bg-transparent peer-checked:bg-blueprint" />
|
|
</div>
|
|
<div className="space-y-0.5">
|
|
<p className="text-sm font-bold text-ink">Manuel (bouton commit)</p>
|
|
<p className="text-[10px] text-muted-ink">Créer des snapshots manuellement</p>
|
|
</div>
|
|
</label>
|
|
<label className="flex items-center gap-4 cursor-pointer group">
|
|
<input type="radio" name="hist" className="sr-only peer" />
|
|
<div className="w-5 h-5 rounded-full border-2 border-border peer-checked:border-blueprint flex items-center justify-center p-0.5 transition-all">
|
|
<div className="w-full h-full rounded-full bg-transparent peer-checked:bg-blueprint" />
|
|
</div>
|
|
<div className="space-y-0.5">
|
|
<p className="text-sm font-bold text-ink">Automatique (intelligent)</p>
|
|
<p className="text-[10px] text-muted-ink">Snapshots automatiques avec détection</p>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mode Démo */}
|
|
<div className="bg-ochre/5 dark:bg-ochre/10 border border-ochre/20 rounded-2xl p-8 flex items-center justify-between group transition-all duration-300 hover:bg-ochre/10">
|
|
<div className="flex items-center gap-6">
|
|
<div className="p-3 bg-paper dark:bg-ochre/20 rounded-2xl text-ochre border border-ochre/30">
|
|
<FlaskConical size={20} />
|
|
</div>
|
|
<div className="space-y-1.5 text-left">
|
|
<h4 className="text-sm font-bold text-ink flex items-center gap-3">
|
|
🧪 Mode Démo
|
|
</h4>
|
|
<p className="text-[11px] text-muted-ink leading-relaxed font-medium">Accélère Memory Echo pour les tests. Les connexions apparaissent instantanément.</p>
|
|
</div>
|
|
</div>
|
|
<label className="relative inline-flex items-center cursor-pointer shrink-0 ml-4">
|
|
<input type="checkbox" className="sr-only peer" />
|
|
<div className="w-11 h-6 bg-gray-200 dark:bg-white/10 rounded-full peer peer-checked:after:translate-x-[20px] peer-checked:after:border-white after:content-[''] after:absolute after:top-[4px] after:left-[4px] after:bg-white after:rounded-full after:h-4 after:w-4 after:transition-all duration-300 ease-in-out peer-checked:bg-ochre"></div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
};
|