diff --git a/config/database.js b/config/database.js index e59f87b..b5463ca 100644 --- a/config/database.js +++ b/config/database.js @@ -149,6 +149,27 @@ function initDatabase() { logger.info('✓ Tables de base de données créées avec succès'); // Migrations automatiques + // Migration pour rss_summaries - ajouter feed_title + db.all("PRAGMA table_info(rss_summaries)", (err, columns) => { + if (err) { + logger.error('Erreur lors de la vérification de la structure de la table rss_summaries:', err); + return; + } + + const hasFeedTitle = columns.some(col => col.name === 'feed_title'); + + if (!hasFeedTitle) { + logger.info('Migration: Ajout de la colonne feed_title à rss_summaries...'); + db.run('ALTER TABLE rss_summaries ADD COLUMN feed_title TEXT', (err) => { + if (err) { + logger.error('Erreur lors de l\'ajout de la colonne feed_title:', err); + } else { + logger.info('✓ Colonne feed_title ajoutée avec succès'); + } + }); + } + }); + db.all("PRAGMA table_info(notes)", (err, columns) => { if (err) { logger.error('Erreur lors de la vérification de la structure de la table notes:', err); diff --git a/public/css/components.css b/public/css/components.css index 9931e4d..c9c26aa 100644 --- a/public/css/components.css +++ b/public/css/components.css @@ -84,6 +84,13 @@ object-fit: cover; border-radius: var(--radius-md); margin-bottom: var(--spacing-md); + cursor: pointer; + transition: all var(--transition-fast); +} + +.note-card-image:hover { + opacity: 0.9; + transform: scale(1.02); } .note-todos-preview { @@ -840,9 +847,16 @@ .note-image { width: 100%; - max-height: 300px; + max-height: 200px; object-fit: cover; border-radius: var(--radius-lg); + cursor: pointer; + transition: all var(--transition-fast); +} + +.note-image:hover { + opacity: 0.9; + transform: scale(1.02); } .btn-remove-image { diff --git a/public/css/skeleton.css b/public/css/skeleton.css index b861d41..048282d 100644 --- a/public/css/skeleton.css +++ b/public/css/skeleton.css @@ -174,3 +174,187 @@ font-size: var(--font-size-sm); opacity: 0.7; } + +/* Système de notifications */ +.notifications-container { + position: fixed; + top: calc(var(--header-height) + 20px); + right: 20px; + z-index: 300; + display: flex; + flex-direction: column; + gap: 12px; + max-width: 400px; + pointer-events: none; +} + +.notification { + background: var(--color-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + padding: 16px 20px; + box-shadow: var(--shadow-lg); + display: flex; + align-items: center; + gap: 12px; + opacity: 0; + transform: translateX(400px); + animation: slideInRight 0.3s ease-out forwards; + pointer-events: auto; + min-width: 300px; + position: relative; +} + +.notification.closing { + animation: slideOutRight 0.3s ease-in forwards; +} + +.notification-icon { + width: 24px; + height: 24px; + flex-shrink: 0; +} + +.notification-success { + border-left: 4px solid var(--color-success); +} + +.notification-success .notification-icon { + color: var(--color-success); +} + +.notification-error { + border-left: 4px solid var(--color-danger); +} + +.notification-error .notification-icon { + color: var(--color-danger); +} + +.notification-warning { + border-left: 4px solid var(--color-warning); +} + +.notification-warning .notification-icon { + color: var(--color-warning); +} + +.notification-info { + border-left: 4px solid var(--color-info); +} + +.notification-info .notification-icon { + color: var(--color-info); +} + +.notification-content { + flex: 1; + font-size: var(--font-size-sm); + color: var(--color-text-primary); + line-height: 1.4; +} + +.notification-close { + width: 24px; + height: 24px; + padding: 4px; + border: none; + background: transparent; + color: var(--color-text-secondary); + cursor: pointer; + border-radius: 50%; + transition: all var(--transition-fast); + flex-shrink: 0; +} + +.notification-close:hover { + background: var(--color-hover); + color: var(--color-text-primary); +} + +@keyframes slideInRight { + from { + opacity: 0; + transform: translateX(400px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes slideOutRight { + from { + opacity: 1; + transform: translateX(0); + } + to { + opacity: 0; + transform: translateX(400px); + } +} + +/* Modal pour agrandir les images */ +.image-modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.9); + z-index: 400; + display: none; + align-items: center; + justify-content: center; + padding: 40px; + cursor: pointer; + animation: fadeIn 0.2s ease-in; +} + +.image-modal.active { + display: flex; +} + +.image-modal-content { + position: relative; + max-width: 90vw; + max-height: 90vh; + cursor: default; +} + +.image-modal-img { + max-width: 100%; + max-height: 90vh; + object-fit: contain; + border-radius: var(--radius-md); + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); +} + +.image-modal-close { + position: fixed; + top: 20px; + right: 20px; + width: 48px; + height: 48px; + border: none; + background: rgba(255, 255, 255, 0.1); + color: white; + font-size: 32px; + cursor: pointer; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: all var(--transition-fast); + backdrop-filter: blur(10px); +} + +.image-modal-close:hover { + background: rgba(255, 255, 255, 0.2); + transform: scale(1.1); +} + +.image-modal-close svg { + width: 24px; + height: 24px; +} diff --git a/public/index.html b/public/index.html index e81e975..d4376aa 100644 --- a/public/index.html +++ b/public/index.html @@ -123,7 +123,7 @@