Sidebar screen now primarily displays user-related information
and derives three render states from loginStatus + currentUser.isVip:
- guest (notLoggedIn): welcome panel + Sign in / Sign up entries
- member (logged in, no VIP): user info card + Get VIP CTA + Log out
- vip (logged in, VIP): user info card with VIP badge + Manage VIP CTA
+ Log out
Adds UserView.isVip (default false), patches user-machine.toView()
to populate it, and introduces three presentational components
(GuestPanel, UserInfoCard, VipCta) co-located under src/app/sidebar.
Preserves existing UserInit + logout-redirect behavior.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix chat components barrel to properly export all component modules
- Remove interceptor exports from API services barrel
- Regenerate store barrel files (auth, chat, sidebar, user) using barrelsby
Add a new /subscription route showing three VIP membership plans (Monthly,
Quarterly, Annual) with a pink→peach banner, per-plan gradient price bars,
a benefits card, a mock activate CTA, and an agreement checkbox.
- New reusable <Checkbox /> in src/app/_components/core for the legal
agreement toggle
- Hardcoded SUBSCRIPTION_PLANS constant in src/data/constants
- New SubscriptionScreen composed of 7 colocated components (back link,
user row, banner, plan card, benefits card, CTA button) with CSS
Modules matching the existing design-token system
- Route registered as protected and reached from /sidebar "Membership"
- Mock CTA: window.alert + router.push(/chat) — no payment calls
Co-Authored-By: Claude <noreply@anthropic.com>
Drop the QuotaDialog component invocation in chat-screen along with
its useState/useEffect wiring, and delete the component files. Update
JSDoc in chat-screen and routes to reflect the removed consumer.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Split `chatInitActor` into `loadQuotaActor` (guest quota fetch) and `loadHistoryActor` (local → network → save sync), and add `quotaLoaded` / `historyLoaded` state flags so the UI can display loading status during the new local-first history hydration flow. Also drop the now-unused `ChatInit` event and pipe Next.js stdout/stderr to a persistent log file in the post-receive hook for easier troubleshooting.
Move the NextAuth v4 configuration from the route handler
(src/app/api/auth/[...nextauth]/route.ts) into a dedicated module
(src/lib/auth/auth.ts) to establish a single source of truth. The
route file now simply re-exports the handler from the shared
module, keeping provider setup, JWT/session callbacks, and
environment variable references in one reusable location.
- Inline NextAuth v4 handler directly in `[...nextauth]/route.ts`, removing
the `@/lib/auth/nextauth` abstraction layer
- Add Google/Facebook providers with JWT/session callbacks that expose
`idToken` and `accessToken` on the session for backend exchange
- Refactor `AuthPlatform` from constructor-based to static methods
(`googleSignIn()` / `facebookSignIn()`)
- Update `auth-machine.ts` and layout comment reference to match new structure
- Align with original Dart `nextauth-helpers.{googleLogin, facebookLogin}()`
naming and keep persistence concerns (unstorage, backend, custom cookies)
out of scope for this iteration
- Move AiDisclosure and EmptyState logic into a new AiDisclosureBanner component
- Remove isGuest prop from ChatArea as it's no longer needed there
- Update styling with explicit color values for better visibility
- Remove redundant `loadingMoreHistory` and `ready` states from chat machine, consolidating history loading flow
- Add `align-self: flex-start` to chat row container for proper alignment
- Clean up commented-out margin rules in text bubble styles
- Update deploy script GIT_REMOTE from "server" to "test"
- Split chat state machine actors (chatInit, sendMessageHttp, loadMoreHistory, chatWebSocket) into a dedicated module
- Add comprehensive console logging across the chat state machine for full trace debugging
- Comment out margin on text bubble CSS for layout adjustment
- Add debug logging to chat input bar send handler
- Clean up redundant comments in auth-screen component
- Remove ChatScreenVisible and ChatScreenInvisible events from chat state machine
- Remove legacy ChatInit event handler
- Migrate state transitions to use absolute references (#chat.guestSession, #chat.userSession, #chat.idle)
- Adjust legal text wording for Cozsweet privacy agreement
Next.js Image scans only inline style for 'auto' to determine whether
sizing is fully delegated to CSS. The .logo class already sets
height: var(--auth-logo-height) and width: auto, but the inline auto
hint is required to suppress the width/height-modified warning.
Applies to both auth-facebook-panel and auth-email-panel where the same
login logo is rendered.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update auth-legal-text copy to "I agree to the Cozsweet Privacy
Agreement and Terms of User", keeping the two external links.
- Center the Facebook icon and "Login with Facebook" label as a group
inside the main Facebook button (change .facebookLabel flex).
- Apply the same centering to the shared AuthSocialButton .label rule
so the Email and Facebook entries in the "Other Sign-in Options"
bottom sheet also render icon+text centered.
Co-Authored-By: Claude <noreply@anthropic.com>
- chat-screen no longer manages WebSocket directly; it now dispatches three
auth lifecycle events (ChatGuestLogin, ChatNonGuestLogin, ChatLogout)
derived from auth.loginStatus
- chat-machine internally owns the WebSocket long-lived actor via
fromCallback, completing the previously deferred migration scope
- removed ChatWebSocket import, getWsToken helper, and direct WS
effect from chat-screen; renamed dispatchInitialLoad to
dispatchAuthLifecycle to reflect the new responsibility
- decouples auth from chat machine via event-driven boundary: machine
stays unaware of loginStatus, guest semantics live at the dispatch
layer (guest → skip WS, non-guest → connect with token)
The screen-lifecycle events were dead code: the transitions in chat-machine
(idle <-> ready) had no caller behavior tied to them, and the dispatches
in chat-screen.tsx were the only senders. Drop the union members, both
state transitions, and the mount-effect dispatches.
The idle state remains declared as initial but is no longer reachable
at runtime; can be refactored in a follow-up.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove ChatAuthStatusChanged dispatch from auth login flow; chat screen now subscribes directly to auth state machine (loginStatus) to derive isGuest and drive WS lifecycle
- Gate quota-exceeded and warning dialogs to guests only (non-guests have no message limit)
- Dispatch ChatLoadMoreHistory for non-guest initial load vs ChatInit for guests
- Fix AppConstants import path from @/core/constants/app_constants to @/core/app_constants
- Add defensive isGuest checks in quota effects to prevent non-guest quota triggers
TextBubble now fills the available half-row width instead of being
capped at 75%. Add 16px margin on the avatar-side edge (margin-left
for AI, margin-right for user) so short messages still feel airy
and long messages are no longer artificially clipped.
Co-Authored-By: Claude <noreply@anthropic.com>
- Splash Skip button now dispatches `AuthGuestLoginSubmitted` instead of
direct routing, keeping guest auth under the state machine
- Update PWA install dialog copy ("Add to Home Screen") and drop favicon
entry from manifest icons
- Add debug logging and routing sequence docs to splash-button
Add align-self: flex-end to .bubbleRowUser so the user message row
sizes to its content and pins to the right edge of the chat area.
Combined with the existing flex-end cross-axis alignment, this places
the user avatar at the right edge with the bubble to its left,
producing a proper left-to-right AI / right-to-left user mirror.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Match the Dart lib/ui/sidebar/sidebar_screen.dart + profile_view.dart
exactly:
- White inner shell with 24px padding
- Back button row (arrow icon + "Back" text, no "Profile" header)
- Single "Other" section with one "Log out" row
- Drop profile card, Account/Data/Session sections, and Sign-in CTA
Match Flutter row visuals in the shared SettingsSection:
- Gray (#f5f5f5) rounded row pill on a white card
- 20px chevron, 1px rgba(61,49,74,0.5) divider
- Destructive color #ff6b6b, 14px/600 black section title
Add tokens: --color-settings-card-background, --color-settings-row-background,
--color-settings-divider, --color-chevron-icon, --color-destructive.
Wire the BlocConsumer listener equivalent: on currentUser transitioning to
null, dispatch ChatAuthStatusChanged + AuthReset and router.replace("/chat").
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change flex-direction from column to row on .bubbleRowAi and
.bubbleRowUser so the avatar and message content render side-by-side
as the JSX and JSDoc already intend.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update the PWA install dialog styling and content to align with the
original Dart design, including a white background with large 40px
radius, 86x86 PNG icon, gradient primary button, and dynamic app title
sourced from AppConstants.
Move new AuthPlatform(provider).signIn() out of UI components and into
the auth state machine. UI now dispatches AuthGoogle/FacebookLoginSubmitted
events; a new oauthSignIn actor inside the machine calls next-auth/react's
signIn(provider). Errors and the OAuth redirect window are exposed via
the existing state.isLoading / state.errorMessage surface, removing the
local busy / error state in auth-facebook-panel.
Co-Authored-By: Claude <noreply@anthropic.com>
- Move state management from `src/contexts` to `src/stores` (zustand-based)
- Update barrelsby config to include new stores directory
- Add bottom-sheet and auth-background components
- Auto-open browser on dev server ready in VS Code launch config
- Refresh generated barrel index files
Replace the separate FacebookLogin and GoogleLogin classes with a single
AuthPlatform class that takes a provider name ("facebook" | "google") as a
constructor argument. This consolidates duplicate OAuth sign-in logic behind
one entry point while preserving the existing NextAuth flow.
- Add new src/lib/auth/auth_platform.ts exporting AuthPlatform and
AuthProvider type
- Update auth-facebook-panel.tsx and splash-button.tsx to use the new API
- Rename initialContext → initialState in the auth machine for consistency
- Update inline docs and comments to reference AuthPlatform
No behavioral change for end users; both providers still route through
NextAuth's signIn() with the same callbacks and cookies.
- Remove unused CharacterIntro export from chat components index
- Drop stale JSDoc block from splash-screen server component
- Set mobile shell background to explicit black so the desktop area outside the 500px viewport is black instead of inheriting from parent
Extract background image into a reusable AuthBackground component and restructure AuthScreen to use MobileShell as the top-level wrapper, mirroring the SplashScreen implementation.
Update chat-header and chat-input-text-field CSS to match the
Dart counterparts (chat_header.dart, chat_input_text_field.dart):
- Header: remove outer padding/background, use transparent base
- Guest banner: switch to --spacing-sm/md tokens
- Header row: add margin-left and symmetric padding
- Menu button: use 32px radius and #0d0b14 @ 0.7 background
- Input field: add white background, 32px radius, accent caret
color, and flex centering for vertical text alignment
- Drop AuthGate/AuthGateState re-exports from @/lib/auth/nextauth
- Simplify SplashButton by removing skipHref prop and hardcoding ROUTES.chat
- Update comments to reference useSession() (next-auth/react) directly instead of the AuthGate wrapper, since the auth UI gate no longer needs the extra abstraction layer.
Migrate from function-based social login helpers (`facebookLogin`, `googleLogin`)
to class-based services (`new FacebookLogin().signIn()`, `new GoogleLogin().signIn()`),
updating call sites in `AuthFacebookPanel` and `SplashButton` with try/catch error
handling. The NextAuth route handler is also refactored to the v4 pattern, importing
pre-built `GET` / `POST` exports from `@/lib/auth/nextauth` instead of constructing
the handler inline with `NextAuth(authOptions)`.
Configure Progressive Web App capabilities for production builds, enabling offline support and installability. PWA is disabled in dev to avoid HMR conflicts, and switches the build to webpack since PWA tooling requires it.