From 132db4e6200ef7fc5946f371093ab000d142e6f1 Mon Sep 17 00:00:00 2001
From: Psychotoxical <171614930+Psychotoxical@users.noreply.github.com>
Date: Tue, 30 Jun 2026 18:16:44 +0200
Subject: [PATCH] refactor(auth): co-locate login page into features/auth
---
src/app/MainApp.tsx | 2 +-
src/features/auth/index.ts | 11 +++++++++++
src/{ => features/auth}/pages/Login.test.tsx | 6 +++---
src/{ => features/auth}/pages/Login.tsx | 12 ++++++------
src/{ => features/help}/pages/Help.tsx | 0
src/{ => features/whatsNew}/hooks/useReleaseNotes.ts | 0
src/{ => features/whatsNew}/pages/WhatsNew.tsx | 0
.../whatsNew/utils}/changelogMarkdown.test.tsx | 0
.../whatsNew/utils}/changelogMarkdown.tsx | 0
9 files changed, 21 insertions(+), 10 deletions(-)
create mode 100644 src/features/auth/index.ts
rename src/{ => features/auth}/pages/Login.test.tsx (95%)
rename src/{ => features/auth}/pages/Login.tsx (98%)
rename src/{ => features/help}/pages/Help.tsx (100%)
rename src/{ => features/whatsNew}/hooks/useReleaseNotes.ts (100%)
rename src/{ => features/whatsNew}/pages/WhatsNew.tsx (100%)
rename src/{utils/changelog => features/whatsNew/utils}/changelogMarkdown.test.tsx (100%)
rename src/{utils/changelog => features/whatsNew/utils}/changelogMarkdown.tsx (100%)
diff --git a/src/app/MainApp.tsx b/src/app/MainApp.tsx
index 66c23a31..037347b1 100644
--- a/src/app/MainApp.tsx
+++ b/src/app/MainApp.tsx
@@ -38,7 +38,7 @@ import BlockingMigrationGate from './BlockingMigrationGate';
import RequireAuth from './RequireAuth';
import { useMigrationStore } from '../store/migrationStore';
-const Login = lazy(() => import('../pages/Login'));
+const Login = lazy(() => import('@/features/auth/pages/Login'));
/**
* Main webview tree. Hosts the router, the application shell (sidebar /
diff --git a/src/features/auth/index.ts b/src/features/auth/index.ts
new file mode 100644
index 00000000..982c7828
--- /dev/null
+++ b/src/features/auth/index.ts
@@ -0,0 +1,11 @@
+/**
+ * Auth feature — the server login / connection page (add server, test
+ * credentials, custom HTTP headers, magic-string import). The page is
+ * lazy-loaded by the auth shell via its deep path, so it is not re-exported
+ * here.
+ *
+ * Stays OUT (global / shared, consumed by this feature, not owned): `authStore`
+ * (the cross-cutting localStorage-backed server-profile store) and the
+ * `utils/server/*` server-profile config helpers (also used by settings).
+ */
+export {};
diff --git a/src/pages/Login.test.tsx b/src/features/auth/pages/Login.test.tsx
similarity index 95%
rename from src/pages/Login.test.tsx
rename to src/features/auth/pages/Login.test.tsx
index e2db91f0..aae01cf6 100644
--- a/src/pages/Login.test.tsx
+++ b/src/features/auth/pages/Login.test.tsx
@@ -33,7 +33,7 @@ afterEach(() => {
describe('Login — v2 magic string paste persistence', () => {
it('persists alternateUrl + shareUsesLocalUrl from a pasted v2 invite', async () => {
- const Login = (await import('./Login')).default;
+ const Login = (await import('@/features/auth/pages/Login')).default;
renderWithProviders();
const user = userEvent.setup();
@@ -70,7 +70,7 @@ describe('Login — v2 magic string paste persistence', () => {
});
it('persists a v1 invite as a single-address profile (no alternateUrl)', async () => {
- const Login = (await import('./Login')).default;
+ const Login = (await import('@/features/auth/pages/Login')).default;
renderWithProviders();
const user = userEvent.setup();
@@ -100,7 +100,7 @@ describe('Login — v2 magic string paste persistence', () => {
});
it('persists custom HTTP headers and probes with gate profile on first connect', async () => {
- const Login = (await import('./Login')).default;
+ const Login = (await import('@/features/auth/pages/Login')).default;
renderWithProviders();
const user = userEvent.setup();
diff --git a/src/pages/Login.tsx b/src/features/auth/pages/Login.tsx
similarity index 98%
rename from src/pages/Login.tsx
rename to src/features/auth/pages/Login.tsx
index a6649d29..842475bc 100644
--- a/src/pages/Login.tsx
+++ b/src/features/auth/pages/Login.tsx
@@ -1,16 +1,16 @@
import React, { useState, useEffect } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { Wifi, WifiOff, Eye, EyeOff, Server, Globe } from 'lucide-react';
-import { useAuthStore } from '../store/authStore';
-import type { CustomHeaderEntry, CustomHeadersApplyTo, ServerProfile } from '../store/authStoreTypes';
+import { useAuthStore } from '@/store/authStore';
+import type { CustomHeaderEntry, CustomHeadersApplyTo, ServerProfile } from '@/store/authStoreTypes';
import { pingWithCredentialsForProfile, scheduleInstantMixProbeForServer } from '@/lib/api/subsonic';
import { CustomHttpHeadersEditor } from '@/features/settings';
import {
DEFAULT_CUSTOM_HEADERS_APPLY_TO,
serverCustomHeadersFromForm,
validateCustomHeaders,
-} from '../utils/server/serverHttpHeaders';
-import { syncServerHttpContextForProfile } from '../utils/server/syncServerHttpContext';
+} from '@/utils/server/serverHttpHeaders';
+import { syncServerHttpContextForProfile } from '@/utils/server/syncServerHttpContext';
import { useTranslation } from 'react-i18next';
import i18n from '@/lib/i18n';
import CustomSelect from '@/ui/CustomSelect';
@@ -19,8 +19,8 @@ import {
DECODED_PASSWORD_VISUAL_MASK,
encodeServerMagicString,
type ServerMagicPayload,
-} from '../utils/server/serverMagicString';
-import { shortHostFromServerUrl, serverListDisplayLabel } from '../utils/server/serverDisplayName';
+} from '@/utils/server/serverMagicString';
+import { shortHostFromServerUrl, serverListDisplayLabel } from '@/utils/server/serverDisplayName';
const PsysonicLogo = () => (
diff --git a/src/pages/Help.tsx b/src/features/help/pages/Help.tsx
similarity index 100%
rename from src/pages/Help.tsx
rename to src/features/help/pages/Help.tsx
diff --git a/src/hooks/useReleaseNotes.ts b/src/features/whatsNew/hooks/useReleaseNotes.ts
similarity index 100%
rename from src/hooks/useReleaseNotes.ts
rename to src/features/whatsNew/hooks/useReleaseNotes.ts
diff --git a/src/pages/WhatsNew.tsx b/src/features/whatsNew/pages/WhatsNew.tsx
similarity index 100%
rename from src/pages/WhatsNew.tsx
rename to src/features/whatsNew/pages/WhatsNew.tsx
diff --git a/src/utils/changelog/changelogMarkdown.test.tsx b/src/features/whatsNew/utils/changelogMarkdown.test.tsx
similarity index 100%
rename from src/utils/changelog/changelogMarkdown.test.tsx
rename to src/features/whatsNew/utils/changelogMarkdown.test.tsx
diff --git a/src/utils/changelog/changelogMarkdown.tsx b/src/features/whatsNew/utils/changelogMarkdown.tsx
similarity index 100%
rename from src/utils/changelog/changelogMarkdown.tsx
rename to src/features/whatsNew/utils/changelogMarkdown.tsx