feat: publication IA (magazine/brief/essay) + fixes critique
Publication IA: - 4 templates (magazine, brief, essay, simple) avec CSS riche - Rewrite IA (article/exercises/tutorial/reference/mixed) - Modération avec timeout 12s + fallback safe - Quotas publish_enhance par tier (basic=2, pro=15, business=100) - Détection contenu stale (hash) - Migration DB publishedContent/publishedTemplate/publishedSourceHash Fixes: - cheerio v1.2: Element -> AnyNode (domhandler), decodeEntities cast - _isShared ajouté au type Note (champ virtuel serveur) - callout colors PDF export: extraction fonction pure testable - admin/published: guard note.userId null - Cmd+S fonctionne en mode dialog (pas seulement fullPage) i18n: - 23 clés publish* traduites dans les 15 locales - Extension Web Clipper: 13 locales mise à jour Tests: - callout-colors.test.ts (6 tests) - note-visible-in-view.test.ts (5 tests) - entitlements.test.ts + byok-entitlements.test.ts: mock usageLog + unstubAllEnvs - 199/199 tests passent Tracker: user-stories.md sync avec sprint-status.yaml
This commit is contained in:
@@ -327,7 +327,7 @@ export const AgentsView: React.FC<AgentsViewProps> = ({
|
||||
'Connexion SSH sans mot de passe à devSandbox',
|
||||
'Gateway token (blank to generate)',
|
||||
'Procédure d\'accès à openclaw',
|
||||
'Derniers commits du repo Momento'
|
||||
'Derniers commits du repo Memento'
|
||||
].map((note, i) => (
|
||||
<label key={i} className="flex items-center gap-4 px-6 py-4 cursor-pointer hover:bg-white/50 transition-colors group">
|
||||
<div className={`w-5 h-5 rounded border transition-all flex items-center justify-center
|
||||
|
||||
@@ -44,7 +44,7 @@ export const AuthPage: React.FC<AuthPageProps> = ({ onAuthComplete, onBack, init
|
||||
<div className="w-8 h-8 bg-ink text-white rounded-xl flex items-center justify-center shadow-lg">
|
||||
<span className="font-serif font-bold text-xl">M</span>
|
||||
</div>
|
||||
<span className="font-serif text-xl font-medium tracking-tight text-ink">Momento</span>
|
||||
<span className="font-serif text-xl font-medium tracking-tight text-ink">Memento</span>
|
||||
</div>
|
||||
|
||||
<div className="w-24" /> {/* Spacer */}
|
||||
@@ -191,7 +191,7 @@ export const AuthPage: React.FC<AuthPageProps> = ({ onAuthComplete, onBack, init
|
||||
</AnimatePresence>
|
||||
|
||||
<p className="text-center mt-8 text-[9px] text-concrete font-bold uppercase tracking-[0.3em] opacity-40">
|
||||
© 2024 Momento Labs — Privacy • Terms
|
||||
© 2024 Memento Labs — Privacy • Terms
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -124,7 +124,7 @@ export const ClipperSimulator: React.FC<ClipperSimulatorProps> = ({
|
||||
try {
|
||||
// Occasional simulated error for retry demonstration
|
||||
if (Math.random() < 0.15) {
|
||||
throw new Error("Connexion réseau interrompue. L'extension n'a pas pu joindre les serveurs Momento.");
|
||||
throw new Error("Connexion réseau interrompue. L'extension n'a pas pu joindre les serveurs Memento.");
|
||||
}
|
||||
|
||||
const dateStr = new Date().toLocaleDateString('fr-FR', {
|
||||
@@ -175,10 +175,10 @@ export const ClipperSimulator: React.FC<ClipperSimulatorProps> = ({
|
||||
setLastCreatedNoteId(newNoteId);
|
||||
setClipperState('success');
|
||||
|
||||
// Add note to Momento Database
|
||||
// Add note to Memento Database
|
||||
onAddNote(newNote);
|
||||
|
||||
// Fire real-time notification toast in Momento!
|
||||
// Fire real-time notification toast in Memento!
|
||||
onTriggerToast(clipTitle, newNoteId);
|
||||
|
||||
} catch (err: any) {
|
||||
@@ -260,7 +260,7 @@ export const ClipperSimulator: React.FC<ClipperSimulatorProps> = ({
|
||||
{/* Web Extension active badge */}
|
||||
<button
|
||||
className="p-1.5 bg-accent/10 border border-accent/20 rounded-lg text-accent animate-pulse relative group"
|
||||
title="Momento Web Clipper is active"
|
||||
title="Memento Web Clipper is active"
|
||||
>
|
||||
<Scissors size={14} className="-rotate-90" />
|
||||
<span className="absolute bottom-full right-0 mb-2 whitespace-nowrap hidden group-hover:block bg-ink text-paper text-[10px] py-1 px-2 rounded-md shadow-lg">
|
||||
@@ -356,12 +356,12 @@ export const ClipperSimulator: React.FC<ClipperSimulatorProps> = ({
|
||||
{/* Extension Hub Header */}
|
||||
<header className="px-5 py-4 border-b border-neutral-100 dark:border-neutral-800 bg-neutral-50 dark:bg-neutral-900/40 flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
{/* Momento Logo with Clipper Branding */}
|
||||
{/* Memento Logo with Clipper Branding */}
|
||||
<div className="w-7 h-7 bg-ink text-paper rounded-lg flex items-center justify-center font-serif font-black text-sm">
|
||||
M
|
||||
</div>
|
||||
<div className="leading-tight">
|
||||
<span className="text-xs font-bold font-serif text-ink dark:text-dark-ink tracking-tight">Momento</span>
|
||||
<span className="text-xs font-bold font-serif text-ink dark:text-dark-ink tracking-tight">Memento</span>
|
||||
<span className="text-[10px] text-accent block font-mono font-medium tracking-widest uppercase">Web Clipper</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -561,7 +561,7 @@ export const ClipperSimulator: React.FC<ClipperSimulatorProps> = ({
|
||||
}}
|
||||
className="w-full py-3.5 bg-ink text-paper rounded-xl text-xs font-bold uppercase tracking-widest flex items-center justify-center gap-2 hover:opacity-95 transition-opacity"
|
||||
>
|
||||
Voir dans Momento
|
||||
Voir dans Memento
|
||||
<ArrowUpRight size={14} />
|
||||
</button>
|
||||
|
||||
@@ -608,7 +608,7 @@ export const ClipperSimulator: React.FC<ClipperSimulatorProps> = ({
|
||||
|
||||
{/* Simulated context details */}
|
||||
<footer className="px-5 py-3 border-t border-neutral-100 dark:border-neutral-800 bg-neutral-50/50 dark:bg-neutral-900/40 text-[9px] text-concrete text-center">
|
||||
Momento Companion v2.1.2 • Sécurisé HTTPS TLS 1.3
|
||||
Memento Companion v2.1.2 • Sécurisé HTTPS TLS 1.3
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -37,7 +37,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
|
||||
<div className="w-10 h-10 bg-ink flex items-center justify-center rounded-xl shadow-lg rotate-3 group hover:rotate-0 transition-transform cursor-pointer">
|
||||
<span className="text-paper font-serif text-2xl font-bold">M</span>
|
||||
</div>
|
||||
<span className="font-serif text-2xl font-medium tracking-tight">Momento</span>
|
||||
<span className="font-serif text-2xl font-medium tracking-tight">Memento</span>
|
||||
</div>
|
||||
|
||||
<div className="hidden md:flex items-center gap-10">
|
||||
@@ -86,7 +86,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
|
||||
<span className="italic">enfin amplifié.</span>
|
||||
</h1>
|
||||
<p className="max-w-2xl mx-auto text-lg md:text-xl text-concrete font-light leading-relaxed mb-12">
|
||||
Momento n'est pas qu'une simple application de notes. C'est un écosystème intelligent qui connecte, analyse et développe vos idées en temps réel grâce à 6 types d'agents IA et une recherche sémantique de pointe.
|
||||
Memento n'est pas qu'une simple application de notes. C'est un écosystème intelligent qui connecte, analyse et développe vos idées en temps réel grâce à 6 types d'agents IA et une recherche sémantique de pointe.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
|
||||
@@ -155,7 +155,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
|
||||
<h2 className="text-4xl md:text-5xl font-serif tracking-tight text-ink">Une intelligence fluide, <br />intégrée à chaque mot.</h2>
|
||||
</div>
|
||||
<div className="text-concrete font-light">
|
||||
Momento orchestres vos idées grâce à une architecture multi-fournisseurs.
|
||||
Memento orchestres vos idées grâce à une architecture multi-fournisseurs.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -352,7 +352,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
|
||||
{
|
||||
name: "Basic",
|
||||
price: "Gratuit",
|
||||
desc: "Pour découvrir la magie de Momento.",
|
||||
desc: "Pour découvrir la magie de Memento.",
|
||||
features: ["100 Notes max", "3 Carnets", "50 crédits IA (Lifetime)", "Recherche sémantique", "Historique 7 jours"],
|
||||
cta: "Commencer",
|
||||
popular: false
|
||||
@@ -433,7 +433,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
|
||||
</div>
|
||||
<h3 className="text-3xl font-serif font-medium mb-4">La stratégie BYOK</h3>
|
||||
<p className="text-concrete font-light leading-relaxed mb-6">
|
||||
Vous possédez déjà des clés API OpenAI, Anthropic ou Google ? Connectez-les directement à Momento.
|
||||
Vous possédez déjà des clés API OpenAI, Anthropic ou Google ? Connectez-les directement à Memento.
|
||||
Utilisez l'IA sans limites de crédits imposées, en payant uniquement ce que vous consommez chez votre fournisseur favori.
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
@@ -472,12 +472,12 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
|
||||
<section className="py-40 px-8 text-center bg-paper relative overflow-hidden">
|
||||
<div className="max-w-3xl mx-auto relative z-10">
|
||||
<h2 className="text-5xl md:text-7xl font-serif tracking-tight mb-8 leading-tight">Prêt à libérer votre <br /><span className="italic">plein potentiel ?</span></h2>
|
||||
<p className="text-lg text-concrete font-light mb-12">Rejoignez des milliers de chercheurs, designers et penseurs qui utilisent déjà Momento pour construire leur futur.</p>
|
||||
<p className="text-lg text-concrete font-light mb-12">Rejoignez des milliers de chercheurs, designers et penseurs qui utilisent déjà Memento pour construire leur futur.</p>
|
||||
<button
|
||||
onClick={onEnter}
|
||||
className="px-16 py-6 bg-ink text-paper rounded-[32px] text-lg font-bold uppercase tracking-[0.2em] hover:scale-105 transition-all shadow-[0_30px_60px_-15px_rgba(0,0,0,0.3)]"
|
||||
>
|
||||
Lancer Momento
|
||||
Lancer Memento
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
@@ -489,7 +489,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
|
||||
<div className="flex-1 space-y-8">
|
||||
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-accent/10 text-accent text-[9px] font-bold uppercase tracking-widest">
|
||||
<Globe size={12} />
|
||||
Écosystème Momento
|
||||
Écosystème Memento
|
||||
</div>
|
||||
<h3 className="text-4xl font-serif font-medium leading-tight text-ink">
|
||||
Traduisez vos documents.<br />
|
||||
@@ -558,7 +558,7 @@ export const LandingPage: React.FC<LandingPageProps> = ({ onEnter, onLogin, onRe
|
||||
<div className="w-8 h-8 bg-ink flex items-center justify-center rounded-lg">
|
||||
<span className="text-paper font-serif text-lg font-bold">M</span>
|
||||
</div>
|
||||
<span className="font-serif text-xl medium tracking-tight">Momento</span>
|
||||
<span className="font-serif text-xl medium tracking-tight">Memento</span>
|
||||
</div>
|
||||
<p className="text-sm text-concrete font-light max-w-xs">Le second cerveau amplifié par l'IA. Pensé pour les esprits créatifs.</p>
|
||||
</div>
|
||||
|
||||
@@ -602,7 +602,7 @@ export const SearchModal: React.FC<SearchModalProps> = ({
|
||||
|
||||
<div className="flex items-center gap-1.5 text-[9px] font-bold uppercase tracking-wider text-concrete/60">
|
||||
<Command size={10} />
|
||||
<span>Momento Search OS v2.3</span>
|
||||
<span>Memento Search OS v2.3</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
@@ -9,7 +9,7 @@ export const BillingTab: React.FC = () => {
|
||||
name: 'Plan Basic',
|
||||
price: 'Gratuit',
|
||||
period: '',
|
||||
description: 'Pour découvrir la magie de Momento.',
|
||||
description: 'Pour découvrir la magie de Memento.',
|
||||
features: [
|
||||
'100 Notes max',
|
||||
'3 Carnets',
|
||||
@@ -119,7 +119,7 @@ export const BillingTab: React.FC = () => {
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<p className="text-xs text-concrete font-light">Votre plan gratuit n'expire jamais. Passez à la vitesse supérieure pour débloquer toute la puissance de Momento.</p>
|
||||
<p className="text-xs text-concrete font-light">Votre plan gratuit n'expire jamais. Passez à la vitesse supérieure pour débloquer toute la puissance de Memento.</p>
|
||||
<div className="pt-4 flex items-center justify-between border-t border-border/40 mt-4">
|
||||
<span className="text-[11px] font-bold text-ink uppercase tracking-widest">Plan Actuel</span>
|
||||
<span className="text-[11px] font-bold text-accent uppercase tracking-widest">GRATUIT</span>
|
||||
|
||||
Reference in New Issue
Block a user