From 5ac9dfcbf00b79e41dd3189d1c20698cc2f12a98 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sat, 18 Oct 2025 06:18:18 +0000 Subject: [PATCH] ea --- app.php | 64 ++++++++++ assets/css/glass-theme.css | 240 +++++++++++++++++++++++++++++++++++++ assets/js/main.js | 176 +++++++++++++++++++++++++++ settings.php | 143 ++++++++++++++++++++++ 4 files changed, 623 insertions(+) create mode 100644 app.php create mode 100644 assets/css/glass-theme.css create mode 100644 assets/js/main.js create mode 100644 settings.php diff --git a/app.php b/app.php new file mode 100644 index 0000000..1a48846 --- /dev/null +++ b/app.php @@ -0,0 +1,64 @@ + + + + + + + <?php echo htmlspecialchars($page_title); ?> - YourApp + + + + + +
+ + + + +
+

+ + +
+ +
+
+
+ + +
+
+ + +
+
+ + + + + diff --git a/assets/css/glass-theme.css b/assets/css/glass-theme.css new file mode 100644 index 0000000..b6cf290 --- /dev/null +++ b/assets/css/glass-theme.css @@ -0,0 +1,240 @@ +/* assets/css/glass-theme.css */ + +/* --- Core Theme & Animated Background --- */ +:root { + --primary-font: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + --title-font: 'Lexend Deca', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + --text-color: #f0f0f0; + --text-muted: #a0a0a0; + --accent-color: #8a2be2; /* Dark Orchid Purple */ + --accent-hover: #9932cc; /* Medium Orchid */ + --background-start: #000000; + --background-mid: #050510; + --background-end: #100510; + --glass-bg: rgba(10, 5, 20, 0.45); + --glass-border: rgba(255, 255, 255, 0.1); + --glass-shadow: rgba(0, 0, 0, 0.5); + --glass-blur: 10px; +} + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=Lexend+Deca&display=swap'); + +/* --- Animations --- */ +@keyframes blue-purple-glow { + 0% { + box-shadow: 0 0 20px 3px rgba(0, 100, 255, 0.4), 0 0 30px 8px rgba(75, 0, 130, 0.3); + } + 50% { + box-shadow: 0 0 25px 5px rgba(75, 0, 130, 0.4), 0 0 35px 10px rgba(0, 100, 255, 0.3); + } + 100% { + box-shadow: 0 0 20px 3px rgba(0, 100, 255, 0.4), 0 0 30px 8px rgba(75, 0, 130, 0.3); + } +} + +@keyframes float-effect { + 0% { transform: translateY(0px); } + 50% { transform: translateY(-6px); } + 100% { transform: translateY(0px); } +} + +body { + font-family: var(--primary-font); + background: linear-gradient(-45deg, var(--background-start), var(--background-mid), var(--background-end)); + background-size: 400% 400%; + animation: gradientBG 20s ease infinite; + color: var(--text-color); + margin: 0; + padding: 2rem; + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; +} + +@keyframes gradientBG { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} + +/* --- Main App Container --- */ +.app-container { + width: 100%; + max-width: 1200px; + height: 90vh; + display: flex; + background: rgba(0,0,0,0.2); + border-radius: 30px; /* More rounded */ + overflow: hidden; + border: 1px solid var(--glass-border); + box-shadow: 0 15px 35px var(--glass-shadow); +} + +/* --- Sidebar Navigation --- */ +.sidebar { + width: 240px; + background: rgba(0,0,0,0.15); + padding: 2rem 0; + flex-shrink: 0; + border-right: 1px solid var(--glass-border); +} + +.sidebar .logo { + text-align: center; + font-family: var(--title-font); + font-size: 1.8rem; + font-weight: 700; + color: #fff; + margin-bottom: 3rem; + padding: 0 1rem; + text-shadow: 0 0 12px var(--accent-hover); +} + +.sidebar .nav-menu { list-style: none; padding: 0; margin: 0; } +.sidebar .nav-menu .nav-item a { + display: block; padding: 1rem 2rem; color: var(--text-muted); + text-decoration: none; font-weight: 500; font-size: 1rem; + position: relative; transition: color 0.3s ease, background 0.3s ease; +} +.sidebar .nav-menu .nav-item a:hover { color: #fff; background: rgba(138, 43, 226, 0.15); } +.sidebar .nav-menu .nav-item.active a { color: #fff; font-weight: 700; } +.sidebar .nav-menu .nav-item.active a::before { + content: ''; position: absolute; left: 0; top: 0; height: 100%; + width: 4px; background: var(--accent-color); border-radius: 0 4px 4px 0; + box-shadow: 0 0 8px var(--accent-color); +} +.sidebar .logout-link { position: absolute; bottom: 2rem; width: 240px; text-align: center; } +.sidebar .logout-link a { color: var(--text-muted); text-decoration: none; font-weight: 500; transition: color 0.3s ease; } +.sidebar .logout-link a:hover { color: #fff; } + +/* --- Main Content Area --- */ +.main-content { flex-grow: 1; padding: 3rem; overflow-y: auto; } +.main-content h1 { + font-family: var(--title-font); font-size: 2.5rem; color: #fff; + margin-bottom: 2rem; text-shadow: 0 0 10px rgba(255,255,255,0.2); +} + +/* --- Glass Panel Style (with Blue/Purple Glow) --- */ +.glass-panel { + background: var(--glass-bg); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); + border: 1px solid var(--glass-border); + border-radius: 25px; /* More rounded */ + padding: 2.5rem; + animation: blue-purple-glow 10s linear infinite; +} + +/* --- Form Elements --- */ +.form-group { margin-bottom: 1.5rem; } +.form-group label { display: block; margin-bottom: 0.5rem; color: var(--text-muted); font-weight: 500; } +.form-control { + width: 100%; padding: 1rem 1.2rem; background: rgba(0, 0, 0, 0.4); + border: 1px solid var(--glass-border); border-radius: 15px; /* More rounded */ + color: var(--text-color); + font-size: 1rem; transition: border-color 0.3s ease, box-shadow 0.3s ease; +} +.form-control:focus { + outline: none; border-color: var(--accent-color); + box-shadow: 0 0 0 3px rgba(138, 43, 226, 0.3); +} +.form-control:disabled { background: rgba(0, 0, 0, 0.5); cursor: not-allowed; } + +/* --- Buttons (with Float and Glow) --- */ +.btn { + padding: 1rem 2rem; border: 1px solid transparent; border-radius: 50px; /* Pill shape */ + font-size: 1rem; font-weight: 700; cursor: pointer; + transition: all 0.4s ease; text-transform: uppercase; letter-spacing: 1px; + position: relative; overflow: hidden; + animation: float-effect 6s ease-in-out infinite; +} +.btn-primary { + background-color: var(--accent-color); color: #fff; + border-color: var(--accent-hover); + animation: blue-purple-glow 8s linear infinite alternate, float-effect 6s ease-in-out infinite; +} +.btn-primary:hover { + background-color: var(--accent-hover); + transform: translateY(-2px) scale(1.05); /* Keep hover effect, float is separate */ + box-shadow: 0 8px 25px rgba(153, 50, 204, 0.6); +} + +/* --- Notes Grid --- */ +.notes-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 2rem; margin-top: 2rem; +} + +.note-card { + background: var(--glass-bg); + backdrop-filter: blur(var(--glass-blur)); + border: 1px solid var(--glass-border); + border-radius: 25px; /* More rounded */ + padding: 1.5rem; + transition: transform 0.4s ease, box-shadow 0.4s ease, background 0.4s ease; + position: relative; overflow: hidden; + animation: blue-purple-glow 12s linear infinite; +} +.note-card:hover { + transform: translateY(-10px) scale(1.03); + background: rgba(20, 10, 30, 0.7); + animation-play-state: paused; /* Pause the glow to show a specific hover shadow */ + box-shadow: 0 10px 40px rgba(138, 43, 226, 0.5); +} + +.note-card-content { color: var(--text-color); margin-bottom: 1rem; max-height: 150px; overflow: hidden; text-overflow: ellipsis; } +.note-card-content a { color: var(--accent-hover); text-decoration: none; font-weight: 600; } +.note-card-content a:hover { text-decoration: underline; } +.note-card-footer { display: flex; justify-content: space-between; align-items: center; } +.note-card-date { font-size: 0.8rem; color: var(--text-muted); } +.delete-note-btn { + background: none; border: none; color: var(--text-muted); + font-size: 1.2rem; cursor: pointer; transition: color 0.3s ease; padding: 5px; +} +.delete-note-btn:hover { color: #ff4757; } + +/* Add Note Button */ +.add-note-card { + display: flex; align-items: center; justify-content: center; flex-direction: column; + min-height: 200px; cursor: pointer; border-style: dashed; border-width: 2px; + border-radius: 25px; /* More rounded */ + background: rgba(255, 255, 255, 0.02); + animation: blue-purple-glow 15s linear infinite reverse; +} +.add-note-card:hover { + background: rgba(138, 43, 226, 0.1); + border-color: var(--accent-hover); +} +.add-note-icon { font-size: 3rem; color: var(--text-muted); transition: color 0.3s ease; } +.add-note-card:hover .add-note-icon { color: var(--accent-hover); } +.add-note-text { margin-top: 1rem; font-weight: 500; color: var(--text-muted); transition: color 0.3s ease; } +.add-note-card:hover .add-note-text { color: var(--accent-hover); } + +/* Note Editor Modal */ +#note-editor-modal { + position: fixed; top: 0; left: 0; width: 100%; height: 100%; + background: rgba(0, 0, 0, 0.7); display: none; /* Hidden by default */ + align-items: center; justify-content: center; z-index: 1000; + backdrop-filter: blur(10px); +} +#note-editor-modal.show { display: flex; } +.note-editor-panel { + width: 90%; max-width: 700px; height: 70vh; + display: flex; flex-direction: column; + animation: blue-purple-glow 9s linear infinite; + border-radius: 25px; /* More rounded */ +} +#note-editor-textarea { + flex-grow: 1; background: rgba(0,0,0,0.5); + border: 1px solid var(--glass-border); color: var(--text-color); + padding: 1.5rem; font-size: 1.1rem; line-height: 1.6; + resize: none; border-radius: 25px 25px 0 0; +} +#note-editor-textarea:focus { outline: none; border-color: var(--accent-color); } +.note-editor-footer { + display: flex; justify-content: flex-end; padding: 1rem; + background: var(--glass-bg); border-top: 1px solid var(--glass-border); + border-radius: 0 0 25px 25px; +} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..c030af0 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,176 @@ +/* assets/js/main.js */ + +document.addEventListener('DOMContentLoaded', () => { + const notesGrid = document.getElementById('notes-grid'); + const modal = document.getElementById('note-editor-modal'); + const editorTextarea = document.getElementById('note-editor-textarea'); + const saveNoteBtn = document.getElementById('save-note-btn'); + const noteIdInput = document.getElementById('note-editor-id'); + + // --- Main Functions --- + + const fetchAndRenderNotes = async () => { + try { + const response = await fetch('api/notes.php'); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const notes = await response.json(); + renderNotes(notes); + } catch (error) { + console.error("Error fetching notes:", error); + notesGrid.innerHTML = '

Could not load notes. Please try again later.

'; + } + }; + + const renderNotes = (notes) => { + notesGrid.innerHTML = ''; // Clear existing notes + + // 1. Add "New Note" Card + const addCard = createAddNoteCard(); + notesGrid.appendChild(addCard); + + // 2. Add Note Cards + if (Array.isArray(notes)) { + notes.forEach(note => { + const noteCard = createNoteCard(note); + notesGrid.appendChild(noteCard); + }); + } + }; + + // --- UI Element Creation --- + + const createAddNoteCard = () => { + const card = document.createElement('div'); + card.className = 'note-card add-note-card'; + card.innerHTML = " +
+
Add New Note
+ "; + card.addEventListener('click', () => openEditor()); + return card; + }; + + const createNoteCard = (note) => { + const card = document.createElement('div'); + card.className = 'note-card'; + card.dataset.id = note.id; + + // Auto-link URLs + const linkedContent = (note.content || '').replace(/(https?:\[^\]+)/g, '$1'); + + card.innerHTML = " +
${linkedContent}
+
+ ${new Date(note.updated_at).toLocaleDateString()} + +
+ "; + + // Edit by clicking the card body + card.querySelector('.note-card-content').addEventListener('click', () => openEditor(note)); + + // Delete button + card.querySelector('.delete-note-btn').addEventListener('click', (e) => { + e.stopPropagation(); // Prevent opening editor + showDeleteConfirmation(note.id); + }); + + return card; + }; + + // --- Editor Modal Logic --- + + const openEditor = (note = {}) => { + noteIdInput.value = note.id || ''; + editorTextarea.value = note.content || ''; + modal.classList.add('show'); + editorTextarea.focus(); + }; + + const closeEditor = () => { + modal.classList.remove('show'); + noteIdInput.value = ''; + editorTextarea.value = ''; + }; + + const saveNote = async () => { + const id = noteIdInput.value; + const content = editorTextarea.value; + + const url = 'api/notes.php'; + const formData = new FormData(); + formData.append('content', content); + if (id) { + formData.append('id', id); + } + + try { + const response = await fetch(url, { + method: 'POST', // Using POST for both create and update + body: formData + }); + + if (!response.ok) { + throw new Error('Failed to save note'); + } + + closeEditor(); + await fetchAndRenderNotes(); // Refresh notes list + } catch (error) { + console.error("Error saving note:", error); + alert('Could not save note. Please try again.'); + } + }; + + const showDeleteConfirmation = (id) => { + if (confirm('Are you sure you want to delete this note?')) { + deleteNote(id); + } + }; + + const deleteNote = async (id) => { + try { + const formData = new FormData(); + formData.append('id', id); + + const response = await fetch('api/notes.php', { + method: 'DELETE', + body: formData + }); + + if (!response.ok) { + throw new Error('Failed to delete note'); + } + + await fetchAndRenderNotes(); // Refresh notes list + } catch (error) { + console.error("Error deleting note:", error); + alert('Could not delete note. Please try again.'); + } + }; + + // --- Event Listeners --- + + saveNoteBtn.addEventListener('click', saveNote); + + // Close modal if clicking on the background + modal.addEventListener('click', (e) => { + if (e.target === modal) { + closeEditor(); + } + }); + + // Close with Escape key + document.addEventListener('keydown', (e) => { + if (e.key === 'Escape' && modal.classList.contains('show')) { + closeEditor(); + } + }); + + // --- Initial Load --- + if (notesGrid) { // Only run on pages with the notes grid + fetchAndRenderNotes(); + } +}); diff --git a/settings.php b/settings.php new file mode 100644 index 0000000..b10071f --- /dev/null +++ b/settings.php @@ -0,0 +1,143 @@ +prepare("SELECT email FROM users WHERE id = ?"); + $stmt->execute([$user_id]); + $user = $stmt->fetch(); + if ($user && $user['email']) { + $email = htmlspecialchars($user['email']); + } +} catch (PDOException $e) { + // Log error or handle it gracefully + // For now, we just use the default +} + +$page_title = "Settings"; + +?> + + + + + + <?php echo htmlspecialchars($page_title); ?> - YourApp + + + + + +
+ + + + +
+

+ +
+
+ +

Profile Information

+

Your profile details are managed by the system.

+ +
+ + +
+ +
+ + +
+ +
+ +

Change Password

+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+
+
+
+
+ + + + +