Textes projet éditables suivant Grav + écriture atomique du store

- Champ Présentation prérempli avec le texte Grav, suivi modifié/synchro
  (textOverride undefined = suit Grav, sinon figé ; bouton Réinitialiser)
- Fix génération PDF : savePortfolio écrit en atomique (temp+rename) pour
  éviter la corruption de lecture par l'autosave concurrent du rendu print
- Toast d'échec de génération explicite (message serveur)
- Refonte architecture visuelle, fond unifié white/tint/full, dispositions
  couverture bandeau/colonne, instantané public complet, index 3 lignes
This commit is contained in:
2026-07-06 13:26:06 +02:00
parent 59dfbe4155
commit ef1f14335d
22 changed files with 750 additions and 334 deletions
+30
View File
@@ -0,0 +1,30 @@
// Copie presse-papier robuste : l'API `navigator.clipboard` n'existe qu'en
// contexte sécurisé (HTTPS ou localhost) ; en HTTP sur IP LAN elle est absente,
// d'où un repli via un <textarea> temporaire + `document.execCommand('copy')`.
export async function copyToClipboard(text: string): Promise<boolean> {
if (import.meta.server) return false
if (navigator.clipboard && window.isSecureContext) {
try {
await navigator.clipboard.writeText(text)
return true
} catch {
// contexte sécurisé mais copie refusée → on tente le repli
}
}
try {
const ta = document.createElement('textarea')
ta.value = text
ta.setAttribute('readonly', '')
ta.style.position = 'fixed'
ta.style.top = '-9999px'
document.body.appendChild(ta)
ta.select()
const ok = document.execCommand('copy')
document.body.removeChild(ta)
return ok
} catch {
return false
}
}