gestion-projet-ia/prompt.html

379 lines
19 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Générateur de prompt CR — IA-PRO Gestion de projet</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;700;800&family=Inter:wght@400;500;600;700;800&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root{
--paper:#F4F4FB; --paper-2:#F0F0F8; --paper-3:#E8E8F4; --card:#FFFFFF;
--ink:#1E1E2E; --ink-2:#4B5563; --ink-3:#9CA3AF;
--line:#E0E0EF; --line-2:#D1D5DB;
--amber:#5B4FE8; --amber-dark:#3730A3; --amber-bg:#EEF0FB; --amber-line:#C7C9F0;
--green:#65A30D; --green-bg:#F0F9E8;
--blue:#6366F1; --violet:#60A5FA;
--serif:'Plus Jakarta Sans','Inter',sans-serif; --sans:'Inter','Plus Jakarta Sans',sans-serif; --mono:'IBM Plex Mono',monospace;
--sh-sm:0 1px 2px rgba(30,30,46,.05); --sh-md:0 4px 14px rgba(30,30,46,.07); --sh-lg:0 16px 40px rgba(30,30,46,.10);
}
*{box-sizing:border-box;margin:0;padding:0}
body{
background:var(--paper);color:var(--ink);font-family:var(--sans);font-size:15px;line-height:1.5;
background-image:radial-gradient(at 5% -5%,rgba(91,79,232,.06) 0,transparent 40%),radial-gradient(at 100% 105%,rgba(55,48,163,.04) 0,transparent 40%);
background-attachment:fixed;min-height:100vh;
}
.wrap{max-width:1180px;margin:0 auto;padding:30px 24px 60px}
header.hero{margin-bottom:26px}
.kicker{display:inline-flex;align-items:center;gap:8px;font-size:11px;font-weight:900;letter-spacing:2px;text-transform:uppercase;color:var(--amber-dark);background:var(--amber-bg);border:1px solid var(--amber-line);border-radius:999px;padding:5px 14px;margin-bottom:12px}
h1{font-family:var(--serif);font-size:clamp(26px,4vw,38px);font-weight:700;letter-spacing:-.4px;line-height:1.15}
h1 em{font-style:italic;color:var(--amber-dark)}
.hero p{color:var(--ink-2);font-size:16px;margin-top:6px;max-width:640px}
.duo{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px;align-items:start}
@media(max-width:920px){.duo{grid-template-columns:1fr}}
.panel{background:var(--card);border:1px solid var(--line);border-radius:16px;box-shadow:var(--sh-sm)}
.panel-head{padding:14px 20px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px;font-family:var(--serif);font-weight:700;font-size:16px}
.panel-head .step{font-family:var(--mono);font-size:11px;font-weight:600;background:var(--ink);color:var(--paper);border-radius:7px;padding:2px 9px}
.panel-body{padding:20px}
label.lbl{display:block;font-size:11.5px;font-weight:900;letter-spacing:1.4px;text-transform:uppercase;color:var(--ink-3);margin:16px 0 7px}
label.lbl:first-child{margin-top:0}
input[type=text],select,textarea{
width:100%;background:var(--paper);border:1.5px solid var(--line-2);border-radius:10px;
padding:10px 13px;font-family:var(--sans);font-size:14.5px;color:var(--ink);
transition:border-color .15s, box-shadow .15s;
}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--amber);box-shadow:0 0 0 3px var(--amber-bg)}
textarea{font-family:var(--mono);font-size:13px;line-height:1.6;resize:vertical;min-height:120px}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:560px){.row2{grid-template-columns:1fr}}
.tpl-row{display:flex;gap:8px;flex-wrap:wrap}
.chip{
border:1.5px solid var(--line-2);background:var(--card);border-radius:99px;
padding:7px 15px;font-weight:700;font-size:13px;cursor:pointer;font-family:var(--sans);
color:var(--ink-2);transition:all .15s;
}
.chip:hover{border-color:var(--amber);transform:translateY(-1px)}
.chip.on{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.sec-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
@media(max-width:560px){.sec-grid{grid-template-columns:1fr}}
.sec-tick{
display:flex;align-items:center;gap:9px;border:1.5px solid var(--line-2);
background:var(--paper);border-radius:9px;padding:8px 12px;font-size:13.5px;font-weight:700;
cursor:pointer;user-select:none;transition:all .15s;color:var(--ink-2);
}
.sec-tick:hover{border-color:var(--amber)}
.sec-tick.on{background:var(--amber-bg);border-color:var(--amber);color:var(--amber-dark)}
.sec-tick .bx{
width:17px;height:17px;border-radius:5px;border:1.5px solid var(--line-2);
display:grid;place-items:center;font-size:11px;color:#fff;flex-shrink:0;transition:all .15s;background:var(--card);
}
.sec-tick.on .bx{background:var(--amber);border-color:var(--amber)}
.seg{display:flex;border:1.5px solid var(--line-2);border-radius:10px;overflow:hidden}
.seg button{
flex:1;border:none;background:var(--paper);padding:9px 6px;font-family:var(--sans);
font-weight:700;font-size:12.5px;cursor:pointer;color:var(--ink-3);transition:all .15s;
border-right:1.5px solid var(--line-2);
}
.seg button:last-child{border-right:none}
.seg button.on{background:var(--ink);color:var(--paper)}
/* output side */
.out-sticky{position:sticky;top:24px}
.prompt-paper{
background:#1A1A2E;color:#E8E6F0;border-radius:16px;box-shadow:var(--sh-lg);
font-family:var(--mono);font-size:12.8px;line-height:1.75;overflow:hidden;
}
.pp-head{display:flex;align-items:center;gap:8px;padding:13px 18px;border-bottom:1px solid #2A2A42}
.pp-dot{width:10px;height:10px;border-radius:50%}
.pp-title{font-family:var(--sans);font-weight:900;font-size:11px;letter-spacing:1.6px;text-transform:uppercase;color:#8B8BAA;margin-left:6px}
.pp-count{margin-left:auto;font-size:11px;color:#555575}
.pp-body{padding:18px 20px;max-height:430px;overflow:auto}
.pp-body::-webkit-scrollbar{width:8px}
.pp-body::-webkit-scrollbar-thumb{background:#2A2A42;border-radius:4px}
.seg-R{color:#A5B4FC}.seg-C{color:#C7D2FE}.seg-T{color:#CCEAAA}.seg-F{color:#BFDBFE}
.pl{font-weight:600;padding:1px 7px;border-radius:5px;font-size:10px;font-family:var(--sans);letter-spacing:1px;margin-right:6px}
.pl-R{background:rgba(91,79,232,.3);color:#A5B4FC}
.pl-C{background:rgba(99,102,241,.3);color:#C7D2FE}
.pl-T{background:rgba(101,163,13,.3);color:#CCEAAA}
.pl-F{background:rgba(96,165,250,.3);color:#BFDBFE}
.pp-notes{color:#8B8BAA;font-style:italic}
.pp-actions{display:flex;gap:10px;padding:14px 18px;border-top:1px solid #2A2A42;flex-wrap:wrap}
.btn{
font-family:var(--sans);font-weight:900;font-size:13.5px;border:none;cursor:pointer;
border-radius:10px;padding:10px 18px;display:inline-flex;align-items:center;gap:8px;
transition:transform .15s,background .2s;
}
.btn:active{transform:scale(.97)}
.btn-amber{background:var(--amber);color:#fff}
.btn-amber:hover{background:#c2670a}
.btn-dark-ghost{background:transparent;color:#BBBBD4;border:1px solid #2E2E50}
.btn-dark-ghost:hover{background:#22223A}
.legend{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}
.legend span{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:700;color:var(--ink-3)}
.legend i{width:11px;height:11px;border-radius:3px;display:inline-block}
.tip{
margin-top:16px;display:flex;gap:12px;align-items:flex-start;
background:var(--amber-bg);border:1px solid var(--amber-line);border-radius:12px;
padding:14px 16px;font-size:13.5px;color:var(--amber-dark);
}
.tip b{font-weight:900}
footer{margin-top:36px;text-align:center;font-size:12px;color:var(--ink-3)}
</style>
</head>
<body>
<div class="wrap">
<header class="hero">
<span class="kicker">IA-PRO · Gestion de projet · Méthode RCTF</span>
<h1>Générateur de prompt <em>compte-rendu</em></h1>
<p>Configurez à gauche, votre prompt s'assemble en direct à droite — coloré par brique RCTF. Copiez-le, collez vos notes, et obtenez votre CR en 30 secondes.</p>
</header>
<div class="duo">
<!-- ════ CONFIGURATION ════ -->
<div class="panel">
<div class="panel-head"><span class="step">1</span> Configuration de la réunion</div>
<div class="panel-body">
<label class="lbl">Template de départ</label>
<div class="tpl-row" id="tplRow">
<button class="chip on" data-tpl="standard">📄 CR standard</button>
<button class="chip" data-tpl="risques">🚨 Réunion à risques</button>
<button class="chip" data-tpl="client">🤝 Réunion client</button>
<button class="chip" data-tpl="sprint">🏃 Sprint / agile</button>
<button class="chip" data-tpl="copil">🏛️ COPIL</button>
</div>
<div class="row2">
<div>
<label class="lbl">Nom du projet</label>
<input type="text" id="fProjet" placeholder="ex. Projet Phoenix" value="">
</div>
<div>
<label class="lbl">Type de réunion</label>
<select id="fType">
<option>Suivi de projet</option><option>Kick-off</option><option>Réunion client</option>
<option>Sprint planning</option><option>Rétrospective</option><option>COPIL</option><option>Réunion de crise</option>
</select>
</div>
</div>
<div class="row2">
<div>
<label class="lbl">Participants (optionnel)</label>
<input type="text" id="fParts" placeholder="ex. Léa, Karim, Thomas, client ACME">
</div>
<div>
<label class="lbl">Langue de sortie</label>
<select id="fLang"><option>français</option><option>anglais</option><option>espagnol</option></select>
</div>
</div>
<label class="lbl">Sections à inclure dans le CR</label>
<div class="sec-grid" id="secGrid">
<div class="sec-tick on" data-sec="Résumé exécutif (3 lignes max)"><span class="bx"></span>Résumé exécutif</div>
<div class="sec-tick" data-sec="Liste des participants et absents"><span class="bx"></span>Participants</div>
<div class="sec-tick on" data-sec="Décisions prises (formulations fermes et datées)"><span class="bx"></span>Décisions</div>
<div class="sec-tick on" data-sec="Plan d'action : action / responsable / échéance"><span class="bx"></span>Plan d'action</div>
<div class="sec-tick on" data-sec="Risques et blocages identifiés, avec criticité"><span class="bx"></span>Risques / blocages</div>
<div class="sec-tick" data-sec="Points restés en suspens à traiter"><span class="bx"></span>Points en suspens</div>
<div class="sec-tick" data-sec="Date, ordre du jour pressenti de la prochaine réunion"><span class="bx"></span>Prochaine réunion</div>
<div class="sec-tick" data-sec="KPIs et indicateurs d'avancement mentionnés"><span class="bx"></span>KPIs / indicateurs</div>
<div class="sec-tick" data-sec="Points budget : consommé, reste à faire, alertes"><span class="bx"></span>Budget</div>
</div>
<label class="lbl">Tonalité</label>
<div class="seg" id="segTon">
<button class="on" data-v="professionnel et concis">Pro concise</button>
<button data-v="formel, adapté à une diffusion client ou COPIL">Formelle</button>
<button data-v="direct et décontracté, pour l'équipe interne">Équipe</button>
<button data-v="ultra-synthétique : uniquement les actions">Actions only</button>
</div>
<label class="lbl">Format de sortie</label>
<div class="seg" id="segFmt">
<button class="on" data-v="en Markdown structuré avec titres et listes à puces">Markdown</button>
<button data-v="en texte brut sans mise en forme">Texte brut</button>
<button data-v="sous forme de tableau : action / responsable / échéance / statut">Tableau</button>
<button data-v="sous forme d'e-mail prêt à envoyer (objet inclus)">E-mail</button>
</div>
<label class="lbl">Longueur cible</label>
<div class="seg" id="segLen">
<button data-v="moins de 200 mots">Court</button>
<button class="on" data-v="entre 200 et 400 mots">Moyen</button>
<button data-v="plus de 400 mots, exhaustif">Détaillé</button>
</div>
<label class="lbl">Vos notes brutes de réunion</label>
<textarea id="fNotes" placeholder="Collez ici vos notes prises à la volée… (si vide, le prompt demandera à l'IA de générer un exemple fictif pour tester le rendu)"></textarea>
</div>
</div>
<!-- ════ SORTIE ════ -->
<div class="out-sticky">
<div class="panel" style="margin-bottom:14px">
<div class="panel-head"><span class="step">2</span> Votre prompt — méthode RCTF en direct</div>
</div>
<div class="prompt-paper">
<div class="pp-head">
<span class="pp-dot" style="background:#e0443e"></span>
<span class="pp-dot" style="background:#dea123"></span>
<span class="pp-dot" style="background:#1aab29"></span>
<span class="pp-title">prompt-cr.txt</span>
<span class="pp-count" id="ppCount">0 mots</span>
</div>
<div class="pp-body" id="ppBody"></div>
<div class="pp-actions">
<button class="btn btn-amber" id="btnCopy">📋 Copier le prompt</button>
<a class="btn btn-dark-ghost" id="btnClaude" href="https://claude.ai/new" target="_blank" style="text-decoration:none">↗ Ouvrir une IA</a>
<button class="btn btn-dark-ghost" id="btnRaw">{ } Version brute</button>
</div>
</div>
<div class="legend">
<span><i style="background:#5B4FE8"></i> Rôle</span>
<span><i style="background:#6366F1"></i> Contexte</span>
<span><i style="background:#65A30D"></i> Tâche</span>
<span><i style="background:#60A5FA"></i> Format</span>
</div>
<div class="tip">💡<div><b>Astuce formation :</b> pas encore de notes ? Copiez le prompt tel quel — il demande à l'IA de créer un exemple fictif réaliste, idéal pour voir le rendu avant de l'utiliser en production.</div></div>
</div>
</div>
<footer>IA-PRO · Générateur de prompt CR · Méthode RCTF — Rôle · Contexte · Tâche · Format</footer>
</div>
<script>
/* ───── état ───── */
const st = {
tpl:'standard', ton:'professionnel et concis',
fmt:'en Markdown structuré avec titres et listes à puces',
len:'entre 200 et 400 mots', raw:false
};
/* ───── templates : pré-configurent les contrôles ───── */
const TPL = {
standard:{type:'Suivi de projet', ton:0, fmt:0, len:1, secs:['Résumé exécutif','Décisions','Plan d\'action','Risques / blocages']},
risques:{type:'Réunion de crise', ton:0, fmt:0, len:2, secs:['Résumé exécutif','Décisions','Plan d\'action','Risques / blocages','Points en suspens']},
client:{type:'Réunion client', ton:1, fmt:3, len:1, secs:['Résumé exécutif','Participants','Décisions','Plan d\'action','Prochaine réunion']},
sprint:{type:'Sprint planning', ton:2, fmt:2, len:0, secs:['Décisions','Plan d\'action','Points en suspens']},
copil:{type:'COPIL', ton:1, fmt:0, len:2, secs:['Résumé exécutif','Participants','Décisions','Plan d\'action','Risques / blocages','KPIs / indicateurs','Budget','Prochaine réunion']},
};
const $=id=>document.getElementById(id);
const esc=s=>s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
/* template chips */
$('tplRow').addEventListener('click',e=>{
const c=e.target.closest('.chip'); if(!c) return;
document.querySelectorAll('#tplRow .chip').forEach(x=>x.classList.toggle('on',x===c));
const T=TPL[c.dataset.tpl];
$('fType').value=T.type;
setSeg('segTon',T.ton); setSeg('segFmt',T.fmt); setSeg('segLen',T.len);
document.querySelectorAll('.sec-tick').forEach(t=>{
const label=t.textContent.replace('✓','').trim();
t.classList.toggle('on', T.secs.some(s=>label.startsWith(s)));
});
build();
});
/* segments */
function wireSeg(id,key){
$(id).addEventListener('click',e=>{
const b=e.target.closest('button'); if(!b) return;
[...$(id).children].forEach(x=>x.classList.toggle('on',x===b));
st[key]=b.dataset.v; build();
});
}
function setSeg(id,idx){
const btns=[...$(id).children];
btns.forEach((b,i)=>b.classList.toggle('on',i===idx));
const key={segTon:'ton',segFmt:'fmt',segLen:'len'}[id];
st[key]=btns[idx].dataset.v;
}
wireSeg('segTon','ton'); wireSeg('segFmt','fmt'); wireSeg('segLen','len');
/* sections */
$('secGrid').addEventListener('click',e=>{
const t=e.target.closest('.sec-tick'); if(!t) return;
t.classList.toggle('on'); build();
});
/* inputs */
['fProjet','fType','fParts','fLang','fNotes'].forEach(id=>$(id).addEventListener('input',build));
/* ───── construction du prompt ───── */
function segments(){
const projet=$('fProjet').value.trim();
const type=$('fType').value;
const parts=$('fParts').value.trim();
const lang=$('fLang').value;
const notes=$('fNotes').value.trim();
const secs=[...document.querySelectorAll('.sec-tick.on')].map(t=>t.dataset.sec);
const R = `Tu es un chef de projet senior, expert en animation de réunions et en communication écrite professionnelle. Tu rédiges des comptes-rendus fiables : tu n'inventes jamais d'information absente des notes, et tu signales explicitement les zones d'ombre par la mention [à confirmer].`;
let C = `Je sors d'une réunion de type « ${type} »`;
C += projet ? ` sur le projet « ${projet} ».` : `.`;
if(parts) C += ` Participants : ${parts}.`;
C += ` Mes notes sont brutes, prises à la volée : elles peuvent être désordonnées, abrégées et incomplètes.`;
let T = `À partir de mes notes ci-dessous, rédige un compte-rendu structuré`;
T += secs.length ? ` comprenant exactement ces sections, dans cet ordre :\n${secs.map((s,i)=>`${i+1}. ${s}`).join('\n')}` : `.`;
T += `\nReformule en phrases complètes, regroupe les éléments dispersés par thème, et transforme chaque tâche évoquée en action claire (verbe d'action + responsable + échéance quand ils sont identifiables).`;
const F = `Rédige en ${lang}, sur un ton ${st.ton}, ${st.fmt}. Longueur cible : ${st.len}. Termine par la mention « CR généré par IA — relu et validé par : ___ » pour rappeler la relecture humaine.`;
const NOTES = notes
? `--- MES NOTES BRUTES ---\n${notes}\n--- FIN DES NOTES ---`
: `--- MES NOTES BRUTES ---\n(Je n'ai pas encore de notes : génère un exemple fictif réaliste de réunion de ${type.toLowerCase()}${projet?` pour le projet « ${projet} »`:''} afin que je visualise le rendu final.)\n--- FIN DES NOTES ---`;
return {R,C,T,F,NOTES};
}
function plainPrompt(){
const s=segments();
return [s.R,s.C,s.T,s.F,s.NOTES].join('\n\n');
}
function build(){
const s=segments(), body=$('ppBody');
if(st.raw){
body.innerHTML=`<pre style="white-space:pre-wrap;font-family:inherit;color:#efe9dc">${esc(plainPrompt())}</pre>`;
} else {
body.innerHTML=
`<div class="seg-R" style="margin-bottom:14px"><span class="pl pl-R">RÔLE</span>${esc(s.R)}</div>`+
`<div class="seg-C" style="margin-bottom:14px"><span class="pl pl-C">CONTEXTE</span>${esc(s.C)}</div>`+
`<div class="seg-T" style="margin-bottom:14px;white-space:pre-wrap"><span class="pl pl-T">TÂCHE</span>${esc(s.T)}</div>`+
`<div class="seg-F" style="margin-bottom:14px"><span class="pl pl-F">FORMAT</span>${esc(s.F)}</div>`+
`<div class="pp-notes" style="white-space:pre-wrap">${esc(s.NOTES)}</div>`;
}
$('ppCount').textContent=plainPrompt().split(/\s+/).filter(Boolean).length+' mots';
}
/* actions */
$('btnCopy').onclick=function(){
navigator.clipboard.writeText(plainPrompt()).then(()=>{
this.textContent='✅ Copié !';
setTimeout(()=>this.textContent='📋 Copier le prompt',1800);
});
};
$('btnRaw').onclick=function(){
st.raw=!st.raw;
this.textContent=st.raw?'🎨 Version colorée':'{ } Version brute';
build();
};
build();
</script>
</body>
</html>