docs: add complete guide, env files, fix docker-compose

- Add GUIDE.md: complete user documentation covering installation,
  Docker deployment, AI providers, MCP server, N8N integration,
  email config, admin panel, env var reference, troubleshooting
- Add mcp-server/.env.example with all MCP-specific variables
- Update .env.docker.example with all 42 environment variables
- Fix docker-compose.yml: parameterize PostgreSQL credentials,
  add missing env vars (CUSTOM_OPENAI, AI_PROVIDER_CHAT,
  ALLOW_REGISTRATION, RESEND_API_KEY)
- Track memento-note/.env.example
This commit is contained in:
Sepehr Ramezani
2026-04-20 22:57:09 +02:00
parent e4d4e23dc7
commit 5b7cbcbc49
23 changed files with 1054 additions and 996 deletions

View File

@@ -113,25 +113,25 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
const [comparisonNotes, setComparisonNotes] = useState<Array<Partial<Note>>>([])
const [fusionNotes, setFusionNotes] = useState<Array<Partial<Note>>>([])
// Tags rejetés par l'utilisateur pour cette session
// Tags dismissed by the user for this session
const [dismissedTags, setDismissedTags] = useState<string[]>([])
const colorClasses = NOTE_COLORS[color as NoteColor] || NOTE_COLORS.default
const handleSelectGhostTag = async (tag: string) => {
// Vérification insensible à la casse
// Case-insensitive check
const tagExists = labels.some(l => l.toLowerCase() === tag.toLowerCase())
if (!tagExists) {
setLabels(prev => [...prev, tag])
// Créer le label globalement s'il n'existe pas
// Create the label globally if it doesn't exist
const globalExists = globalLabels.some(l => l.name.toLowerCase() === tag.toLowerCase())
if (!globalExists) {
try {
await addLabel(tag)
} catch (err) {
console.error('Erreur création label auto:', err)
console.error('Error creating auto-label:', err)
}
}
toast.success(t('ai.tagAdded', { tag }))
@@ -142,8 +142,8 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
setDismissedTags(prev => [...prev, tag])
}
// Filtrer les suggestions pour ne pas afficher celles rejetées par l'utilisateur
// ni celles déjà présentes sur la note
// Filter suggestions to exclude dismissed ones
// and those already present on the note
const existingLabelsLower = (note.labels || []).map((l) => l.toLowerCase())
const filteredSuggestions = suggestions.filter(s => {
if (!s || !s.tag) return false
@@ -241,7 +241,7 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
setTitleSuggestions(data.suggestions || [])
toast.success(t('ai.titlesGenerated', { count: data.suggestions.length }))
} catch (error: any) {
console.error('Erreur génération titres:', error)
console.error('Error generating titles:', error)
toast.error(error.message || t('ai.titleGenerationFailed'))
} finally {
setIsGeneratingTitles(false)
@@ -311,7 +311,7 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
option: data.option
})
} catch (error: any) {
console.error('Erreur reformulation:', error)
console.error('Error reformulating:', error)
toast.error(error.message || t('ai.reformulationFailed'))
} finally {
setIsReformulating(false)
@@ -494,10 +494,10 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
cleanupOrphanedImages(removedImageUrls, note.id).catch(() => {})
}
// Rafraîchir les labels globaux pour refléter les suppressions éventuelles (orphans)
// Refresh global labels to reflect any deletions (orphans)
await refreshLabels()
// Rafraîchir la liste des notes
// Refresh the notes list
triggerRefresh()
onClose()