Skip to content

refactor: remove AuthControls component and update OrgSwitcher for im…#14

Merged
Guria merged 3 commits into
mainfrom
auth-fix
May 28, 2026
Merged

refactor: remove AuthControls component and update OrgSwitcher for im…#14
Guria merged 3 commits into
mainfrom
auth-fix

Conversation

@Guria
Copy link
Copy Markdown
Owner

@Guria Guria commented May 27, 2026

…proved organization handling

Summary by CodeRabbit

  • New Features

    • OrgSwitcher now displays a dropdown menu showing organizations, personal workspace, and create organization option
    • Responsive sidebar that adapts layout between desktop and mobile views
  • Refactor

    • Simplified authentication state management and removed automatic session restoration on app startup
    • Consolidated user controls into OrgSwitcher menu
  • Tests

    • Added test scenario for invalid credentials and refined authentication sign-out flow

Review Change Stack

Copilot AI review requested due to automatic review settings May 27, 2026 23:20
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Warning

Review limit reached

@Guria, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 4 minutes and 6 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9c2e2e84-8358-4bfe-a3fe-f2f1d21f2b3f

📥 Commits

Reviewing files that changed from the base of the PR and between ac010af and 9ecdf78.

📒 Files selected for processing (18)
  • docs/testing.md
  • src/app/App.tsx
  • src/app/AuthControls.tsx
  • src/app/OrgSwitcher.tsx
  • src/app/integration/Auth.stories.tsx
  • src/app/mocks/handlers.ts
  • src/entities/auth/api/authApi.ts
  • src/entities/auth/index.ts
  • src/entities/auth/mocks/handlers.ts
  • src/entities/auth/model/auth.ts
  • src/index.d.ts
  • src/main.tsx
  • src/pages/login/model/routes.tsx
  • src/pages/login/ui/LoginPage.tsx
  • src/shared/model/index.ts
  • src/shared/model/viewport.ts
  • src/widgets/app-shell/ui/AppShell.tsx
  • vite.config.ts

Walkthrough

The PR refactors authentication state management from token-based persistence to direct session storage with localStorage, updates the auth API surface to expose only login/logout functions, reorganizes UI components by replacing AuthControls with an enhanced OrgSwitcher dropdown menu, introduces responsive sidebar rendering based on a desktop media query, and removes the session restoration startup flow.

Changes

Auth State Simplification & Responsive UI Refactoring

Layer / File(s) Summary
Auth state model simplification and persistence
src/entities/auth/model/auth.ts
Auth atoms are rewritten to persist the session directly via withLocalStorage, remove token-based storage and error/pending atoms, and simplify authentication checks based solely on session presence. loginAction sets the session directly and uses extend(withAsync()), logoutAction becomes synchronous and clears the session immediately.
Auth API layer: login/logout functions
src/entities/auth/api/authApi.ts
API constants and functions are narrowed to expose login() and logout() backed by /auth/login and /auth/logout endpoints, removing the previous /auth/me session-fetching capability.
Auth module exports
src/entities/auth/index.ts
The auth barrel export is narrowed to remove authErrorAtom, authPendingAtom, and restoreSession, keeping only authSessionAtom, isAuthenticatedAtom, loginAction, and logoutAction.
Mock handlers: remove /auth/me endpoint
src/app/mocks/handlers.ts, src/entities/auth/mocks/handlers.ts
MSW handlers are updated at both the app-level and entity-level to remove the authMe handler and /auth/me endpoint, keeping only login, loginError, and logout mocks.
Login form refactoring: Reatom form integration
src/pages/login/model/routes.tsx, src/pages/login/ui/LoginPage.tsx, src/app/integration/Auth.stories.tsx
The login route builds a Reatom form instance wired to loginAction, with a loader/render pattern. LoginPage receives the form as a prop, derives error and pending states from form.submit, and uses bindField() for input binding instead of hardcoded attributes and callbacks. Storybook tests are updated to cover login errors and invalid credentials.
App shell and component refactoring
src/app/App.tsx, src/app/AuthControls.tsx, src/app/OrgSwitcher.tsx
AuthControls component is removed from the sidebar footer. OrgSwitcher is converted from a simple button to a Reatom-backed dropdown menu component that displays session details, organizations list, and a sign-out action wired to logoutAction() with localized text.
Responsive sidebar layout using media query
src/shared/model/viewport.ts, src/shared/model/index.ts, src/widgets/app-shell/ui/AppShell.tsx
isDesktopAtom is introduced via reatomMediaQuery('(min-width: 768px)') and re-exported from the shared model. AppShell uses this atom to conditionally render sidebar content: the drawer receives sidebarInner only when not in desktop mode, while the desktop sidebar always receives it.
Startup flow and config cleanup
src/main.tsx, vite.config.ts
The restoreSession() call is removed from the app initialization, and the vite config is cleaned up to remove PluginOption type imports and casts for plugins.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hops through auth anew,
Session stored, no token true.
OrgSwitcher dons a dropdown crown,
Responsive sidebars settle down.
🐰 Auth refactored, clean and bright!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the main changes: removing AuthControls and updating OrgSwitcher. It is concise, clear, and directly reflects the primary refactoring work in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch auth-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

Fallow audit report

No GitHub PR/MR findings.

Generated by fallow.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac010afc6d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/entities/auth/model/auth.ts
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors authentication/UI wiring by removing the AuthControls sidebar component, expanding OrgSwitcher into a menu that includes sign-out, and simplifying auth session persistence by storing the full session in localStorage. It also introduces a shared isDesktopAtom media-query atom and uses it to avoid rendering duplicate sidebar content for mobile vs desktop.

Changes:

  • Refactor login/auth flow to use reatomForm + loginAction(withAsync) and persist authSessionAtom via withLocalStorage, removing restoreSession and /auth/me.
  • Replace AuthControls with an expanded OrgSwitcher menu (org list + sign out) and update integration stories accordingly.
  • Add isDesktopAtom and use it in AppShell to conditionally render sidebar content based on viewport.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
vite.config.ts Removes PluginOption casts and relies on inferred Vite plugin types.
src/widgets/app-shell/ui/AppShell.tsx Uses new isDesktopAtom to render only the relevant sidebar variant.
src/shared/model/viewport.ts Adds isDesktopAtom via reatomMediaQuery.
src/shared/model/index.ts Re-exports isDesktopAtom from shared model index.
src/pages/login/ui/LoginPage.tsx Refactors login UI to consume a reatomForm model and bindField inputs.
src/pages/login/model/routes.tsx Creates/login form model via route loader and passes it into LoginPage.
src/main.tsx Removes restoreSession() bootstrap call (session now comes from localStorage).
src/entities/auth/model/auth.ts Simplifies auth model: persist session, remove error/pending atoms, add withAsync to login.
src/entities/auth/mocks/handlers.ts Removes /auth/me mock handler and updates auth mock exports.
src/entities/auth/index.ts Updates public exports to match new auth model (drops removed atoms/actions).
src/entities/auth/api/authApi.ts Removes /auth/me endpoint helpers.
src/app/OrgSwitcher.tsx Expands OrgSwitcher into a menu with org items and sign-out.
src/app/mocks/handlers.ts Removes registration of the deleted authMe mock handler.
src/app/integration/Auth.stories.tsx Updates auth integration tests for new login error behavior and sign-out UI path.
src/app/AuthControls.tsx Deletes the AuthControls component (sign-out is now in OrgSwitcher).
src/app/App.tsx Removes AuthControls from the sidebar footer layout.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/entities/auth/model/auth.ts Outdated
Comment on lines 17 to 20
export const logoutAction = action(() => {
authSessionAtom.set(null)
wrap(logout())
}, 'logoutAction')
Comment thread src/pages/login/model/routes.tsx Outdated
@@ -1,12 +1,21 @@
import { urlAtom } from '@reatom/core'
import { urlAtom, reatomForm } from '@reatom/core'
import { Fragment } from 'react/jsx-runtime'
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/shared/model/viewport.ts (1)

3-3: ⚡ Quick win

Keep the isDesktopAtom breakpoint aligned with the md responsive token

src/shared/model/viewport.ts hardcodes reatomMediaQuery('(min-width: 768px)') for isDesktopAtom, while sidebar/layout visibility is controlled via md responsive props elsewhere (e.g., src/widgets/app-shell/ui/sidebar.tsx, src/widgets/app-shell/ui/AppShell.tsx, src/widgets/master-details/ui/MasterDetails.tsx). If the md breakpoint value changes, these can diverge—derive the query from the same shared breakpoint source/constant as md.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/model/viewport.ts` at line 3, Replace the hardcoded '(min-width:
768px)' in export const isDesktopAtom = reatomMediaQuery(...) with the shared
`md` breakpoint constant used across the app: import the project’s responsive
token (the shared `md` breakpoint) and construct the media query dynamically
(e.g., reatomMediaQuery(`(min-width: ${md})`)) so `isDesktopAtom` always follows
the same `md` token as components like Sidebar/AppShell/MasterDetails.
src/pages/login/model/routes.tsx (1)

13-13: ⚡ Quick win

Avoid hardcoded default credentials in initial form state.

Line 13 pre-fills real-looking credentials by default. Prefer empty defaults and let stories/tests fill values explicitly.

♻️ Suggested change
-		{ email: 'alex@example.com', password: 'password' },
+		{ email: '', password: '' },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/login/model/routes.tsx` at line 13, The initial form state in
src/pages/login/model/routes.tsx currently hardcodes realistic credentials ({
email: 'alex@example.com', password: 'password' }); replace those defaults with
empty values (e.g., email: '' and password: '') so no real-looking credentials
are stored in source, and ensure tests/stories explicitly set any needed example
values instead of relying on this file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/entities/auth/model/auth.ts`:
- Around line 17-20: logoutAction currently clears authSessionAtom too early and
fire-forgets logout() via wrap(logout()), causing unhandled rejections and
possible client/server divergence; change logoutAction to perform the logout
call as an async/await flow (use wrap(logout()).extend(withAsync()) or await the
wrapped promise inside the action), move authSessionAtom.set(null) to after a
successful logout, and add try/catch around the await to handle/log failures and
avoid unhandled rejections (reference logoutAction, logout(),
authSessionAtom.set, wrap).

---

Nitpick comments:
In `@src/pages/login/model/routes.tsx`:
- Line 13: The initial form state in src/pages/login/model/routes.tsx currently
hardcodes realistic credentials ({ email: 'alex@example.com', password:
'password' }); replace those defaults with empty values (e.g., email: '' and
password: '') so no real-looking credentials are stored in source, and ensure
tests/stories explicitly set any needed example values instead of relying on
this file.

In `@src/shared/model/viewport.ts`:
- Line 3: Replace the hardcoded '(min-width: 768px)' in export const
isDesktopAtom = reatomMediaQuery(...) with the shared `md` breakpoint constant
used across the app: import the project’s responsive token (the shared `md`
breakpoint) and construct the media query dynamically (e.g.,
reatomMediaQuery(`(min-width: ${md})`)) so `isDesktopAtom` always follows the
same `md` token as components like Sidebar/AppShell/MasterDetails.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 070f45a2-6463-428c-8ef4-4efef85ec19b

📥 Commits

Reviewing files that changed from the base of the PR and between d4cd1e8 and ac010af.

📒 Files selected for processing (16)
  • src/app/App.tsx
  • src/app/AuthControls.tsx
  • src/app/OrgSwitcher.tsx
  • src/app/integration/Auth.stories.tsx
  • src/app/mocks/handlers.ts
  • src/entities/auth/api/authApi.ts
  • src/entities/auth/index.ts
  • src/entities/auth/mocks/handlers.ts
  • src/entities/auth/model/auth.ts
  • src/main.tsx
  • src/pages/login/model/routes.tsx
  • src/pages/login/ui/LoginPage.tsx
  • src/shared/model/index.ts
  • src/shared/model/viewport.ts
  • src/widgets/app-shell/ui/AppShell.tsx
  • vite.config.ts
💤 Files with no reviewable changes (6)
  • src/entities/auth/index.ts
  • src/app/mocks/handlers.ts
  • src/main.tsx
  • src/app/AuthControls.tsx
  • src/app/App.tsx
  • src/entities/auth/api/authApi.ts

Comment thread src/entities/auth/model/auth.ts Outdated
@Guria Guria merged commit 3f3be0c into main May 28, 2026
2 checks passed
@Guria Guria deleted the auth-fix branch May 28, 2026 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants