From 310c4b0ed67b5764c61b91179ea0197323a8c2b2 Mon Sep 17 00:00:00 2001 From: pixelsmon Date: Sun, 1 Mar 2026 14:19:47 +0530 Subject: [PATCH] feat: full-screen glass editor, user migration, and UI improvements Editor Improvements: - Add full-screen glass background with gradient orbs and grid - Apply glass effect to editor content area with blur and transparency - Make editor text area larger and fill available space - Add glass styling to Share/Export buttons - Increase spacing between Share/Export buttons (12px gap) - Add separator line between toolbar groups User Migration System: - Add migration check for existing users from old version - Show migration modal for users without passwords - Allow existing users to set password without losing data - Auto-login after successful migration Auth Store Updates: - Add checkMigration() function to detect users needing password setup - Add migrateUser() function to upgrade existing accounts - Export MigrationStatus interface UI Polish: - Add smooth transitions and hover effects to glass buttons - Improve dark mode support for glass elements - Add responsive styles for migration modal Fixes issues: - Small text editor box (now fills screen with glass bg) - Share/Export buttons too close (now properly spaced) - Existing users losing access (now prompted to set password) --- apps/web/src/lib/stores/auth.svelte.ts | 65 +++++++ apps/web/src/routes/+page.svelte | 167 ++++++++++++++++++ .../web/src/routes/app/note/[id]/+page.svelte | 140 ++++++++++++++- 3 files changed, 366 insertions(+), 6 deletions(-) diff --git a/apps/web/src/lib/stores/auth.svelte.ts b/apps/web/src/lib/stores/auth.svelte.ts index 57255de..5171ae1 100644 --- a/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/web/src/lib/stores/auth.svelte.ts @@ -55,6 +55,39 @@ function getUser(username: string): StoredUser | undefined { return getStoredUsers()[username.toLowerCase()]; } +// ============================================================================ +// MIGRATION: Check if user needs to set password (existing user from old version) +// ============================================================================ + +export interface MigrationStatus { + needsMigration: boolean; + username: string | null; +} + +function checkMigrationStatus(): MigrationStatus { + if (typeof window === "undefined") + return { needsMigration: false, username: null }; + + // Check if there's an existing session from old version (without password system) + const stored = localStorage.getItem("locanote_session"); + if (!stored) return { needsMigration: false, username: null }; + + try { + const session = JSON.parse(stored); + // Check if this user has a password set + const users = getStoredUsers(); + const hasPassword = users[session.username?.toLowerCase()] !== undefined; + + if (!hasPassword && session.username) { + return { needsMigration: true, username: session.username }; + } + } catch { + // Invalid session + } + + return { needsMigration: false, username: null }; +} + // ============================================================================ // METHODS // ============================================================================ @@ -82,6 +115,38 @@ export const auth = { return authState; }, + // Check if user needs to migrate (set password for existing account) + checkMigration(): MigrationStatus { + return checkMigrationStatus(); + }, + + // Migrate existing user to password system + async migrateUser( + username: string, + password: string, + confirmPassword: string, + ): Promise<{ success: boolean; error?: string }> { + if (!password || password.length < 6) { + return { + success: false, + error: "Password must be at least 6 characters", + }; + } + + if (password !== confirmPassword) { + return { + success: false, + error: "Passwords do not match", + }; + } + + // Hash and store password + const passwordHash = await hashPassword(password); + saveUser(username, passwordHash); + + return { success: true }; + }, + // Login with password async login( username: string, diff --git a/apps/web/src/routes/+page.svelte b/apps/web/src/routes/+page.svelte index 81d2966..87b3d64 100644 --- a/apps/web/src/routes/+page.svelte +++ b/apps/web/src/routes/+page.svelte @@ -15,6 +15,13 @@ LANDING PAGE - Beautiful Glass Design let isRegister = $state(false); let mounted = $state(false); + // Migration state for existing users + let showMigrationModal = $state(false); + let migrationUsername = $state(""); + let migrationPassword = $state(""); + let migrationConfirmPassword = $state(""); + let migrationError = $state(""); + // Check session BEFORE mount to prevent flash function checkSession() { if (typeof window === "undefined") return false; @@ -40,12 +47,56 @@ LANDING PAGE - Beautiful Glass Design onMount(() => { mounted = true; + // Check if user needs to migrate from old version + const migration = auth.checkMigration(); + if (migration.needsMigration && migration.username) { + showMigrationModal = true; + migrationUsername = migration.username; + return; // Don't redirect, show migration modal instead + } // Double-check session after mount (handles edge cases) if (checkSession()) { goto("/app", { replaceState: true }); } }); + // Handle migration submission + async function handleMigration() { + if (!migrationPassword || migrationPassword.length < 6) { + migrationError = "Password must be at least 6 characters"; + return; + } + if (migrationPassword !== migrationConfirmPassword) { + migrationError = "Passwords do not match"; + return; + } + + isLoading = true; + migrationError = ""; + + const result = await auth.migrateUser( + migrationUsername, + migrationPassword, + migrationConfirmPassword, + ); + + isLoading = false; + + if (result.success) { + showMigrationModal = false; + // After migration, try to auto-login + const loginResult = await auth.login( + migrationUsername, + migrationPassword, + ); + if (loginResult.success) { + goto("/app", { replaceState: true }); + } + } else { + migrationError = result.error || "Migration failed"; + } + } + async function handleSubmit() { if (!username.trim()) { error = "Please enter a username"; @@ -223,6 +274,54 @@ LANDING PAGE - Beautiful Glass Design + +{#if showMigrationModal} +
+
+

Welcome Back!

+

+ We've upgraded our security. Please set a password for your account {migrationUsername} to continue. +

+

+ Your notes and data are safe - you just need to add password protection. +

+ +
+ + + + {#if migrationError} +
{migrationError}
+ {/if} + + +
+
+
+{/if} + diff --git a/apps/web/src/routes/app/note/[id]/+page.svelte b/apps/web/src/routes/app/note/[id]/+page.svelte index 7c51bef..1073d68 100644 --- a/apps/web/src/routes/app/note/[id]/+page.svelte +++ b/apps/web/src/routes/app/note/[id]/+page.svelte @@ -252,8 +252,8 @@ NOTEPAD EDITOR PAGE - Notepad++ Style Layout - -
+ +
{#if isLoading}
{:else if note && noteId && (!note.isProtected || hasRoomKey(noteId))} -
+
@@ -536,9 +536,9 @@ NOTEPAD EDITOR PAGE - Notepad++ Style Layout
-
+