Skip to content

feat: add freemium auth gating for Budgets and Goals - #252

Merged
khanirfan18 merged 2 commits into
khanirfan18:mainfrom
Antra1705:feature/freemium-auth-gating
Aug 9, 2026
Merged

feat: add freemium auth gating for Budgets and Goals#252
khanirfan18 merged 2 commits into
khanirfan18:mainfrom
Antra1705:feature/freemium-auth-gating

Conversation

@Antra1705

Copy link
Copy Markdown
Contributor

Summary

  • Allow guests to use free FinBoard routes (dashboard, transactions, settings, insights, help, preferences) without signing in.
  • Hard-gate Budgets, Goals, and Profile behind auth; redirect guests to /signin with return path + upsell: “Create an account to use Budgets and Goals.”
  • Persist guest free-feature data in localStorage only; Supabase writes run only when authenticated.

Closes #238

Test plan

  • As a guest, open Dashboard / Transactions / Settings / Insights / Help without being redirected to sign-in
  • As a guest, add or import transactions and confirm they persist after refresh (localStorage) with no Supabase writes
  • As a guest, open Budgets or Goals → land on /signin?reason=budgets-goals with the upsell message
  • Sign in from that flow → return to the intended Budgets/Goals route
  • As an authenticated user, Budgets/Goals add/edit/delete/allocate still sync to Supabase
  • As a guest, Profile is blocked; Header shows Sign in / Sign up (no profile dropdown crash)
  • Sidebar shows lock affordance on Budgets/Goals for guests

@netlify

netlify Bot commented Aug 9, 2026

Copy link
Copy Markdown

👷 Deploy request for finnboard0 pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit bb086dc

@netlify

netlify Bot commented Aug 9, 2026

Copy link
Copy Markdown

Deploy Preview for finnboard ready!

Name Link
🔨 Latest commit bb086dc
🔍 Latest deploy log https://app.netlify.com/projects/finnboard/deploys/6a78bc113eaab600098d06f7
😎 Deploy Preview https://deploy-preview-252--finnboard.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@khanirfan18

Copy link
Copy Markdown
Owner

@Antra1705 thanks for the contribution! the freemium gating idea is a good addition, and the redirect preservation in protectedroute, signin, and signup is a nice ux improvement.

however, the pr is not merge-ready yet because there are a few blocking issues:

  • header.jsx contains duplicated jsx blocks and conflicting props (onclick, classname) that can break compilation.
  • sidebar.jsx defines budgets and goals twice, so duplicate navigation items will appear.
  • app.jsx registers the same routes (budgets, goals, profile) twice, which means the unprotected routes may bypass the auth gate.

also, there are some cleanup issues:

  • remove duplicated supabase upsert, delete, and update calls in budgets.jsx and goals.jsx.

  • please run the app locally and verify:

    • guest users can access dashboard, transactions, insights, and settings,
    • guest users are redirected to /signin?reason=budgets-goals for budgets and goals,
    • after signing in, users are redirected back to the originally requested page.

once these issues are cleaned up, i’ll be happy to review it again 👍

@Antra1705

Copy link
Copy Markdown
Contributor Author

@Antra1705 thanks for the contribution! the freemium gating idea is a good addition, and the redirect preservation in protectedroute, signin, and signup is a nice ux improvement.

however, the pr is not merge-ready yet because there are a few blocking issues:

  • header.jsx contains duplicated jsx blocks and conflicting props (onclick, classname) that can break compilation.
  • sidebar.jsx defines budgets and goals twice, so duplicate navigation items will appear.
  • app.jsx registers the same routes (budgets, goals, profile) twice, which means the unprotected routes may bypass the auth gate.

also, there are some cleanup issues:

  • remove duplicated supabase upsert, delete, and update calls in budgets.jsx and goals.jsx.

  • please run the app locally and verify:

    • guest users can access dashboard, transactions, insights, and settings,
    • guest users are redirected to /signin?reason=budgets-goals for budgets and goals,
    • after signing in, users are redirected back to the originally requested page.

once these issues are cleaned up, i’ll be happy to review it again 👍

Hi @khanirfan18 — thanks for the thorough review!

I double-checked the current branch against the points you raised:

  • Header.jsx — guest vs authenticated UI is a single conditional; no duplicated JSX or conflicting onClick/className props. The production build also completes successfully.
  • Sidebar.jsx — Budgets and Goals are each defined once in the nav links.
  • App.jsxbudgets, goals, and profile are each registered once, wrapped in ProtectedRoute (free routes stay public under Layout).
  • Budgets.jsx / Goals.jsx — each Supabase upsert / delete / update path appears once. The PR only moved the auth guard to an early if (!user) return instead of wrapping the call in if (user).

I also re-ran the app locally and confirmed:

  • Guests can open Dashboard, Transactions, Insights, and Settings
  • Guests hitting Budgets/Goals are redirected to /signin?reason=budgets-goals
  • After sign-in, users are sent back via the preserved state.from return path

Happy to adjust further if you’re seeing something different on a specific commit or file view — just point me at it. Thanks again for the feedback!

@khanirfan18

Copy link
Copy Markdown
Owner

Thanks for the detailed follow-up @Antra1705... appreciate you double checking each point.

Sidebar.jsx, App.jsx, and the Budgets.jsx/Goals.jsx Supabase changes all look resolved on my end too. Budgets and Goals are each defined once with a clean requiresAuth flag, the routes are each registered once under ProtectedRoute, and the if (!user) return early guard is a legit refactor, not duplication. Good to close those out.

Header.jsx is still the outstanding blocker though. On the current branch, the {!user ? (...) : (...)} block's authenticated branch still nests a second full profile trigger button and dropdown (second id="profile-menu-btn", second profile-dropdown markup), and it looks like there are two different onClick handlers stacked on what should be a single button (navigate("/profile") vs navigate("/signin")).

Could you paste the current full contents of Header.jsx, or push a small follow-up commit so I can diff it fresh? Just want to make sure we're looking at the same version before re-reviewing. Once that's sorted I think this is close to mergeable, the freemium gating and redirect preservation work is solid.

@Antra1705

Copy link
Copy Markdown
Contributor Author

Thanks for taking another look @khanirfan18 !

On Header.jsx, the guest Sign in button and the authenticated profile menu were never meant to render together — they’re opposite branches of {!user ? … : …}. The navigate("/signin") and navigate("/profile") handlers are on different buttons in different branches (guest CTA vs dropdown item), not stacked on one control.

To make that clearer, I pushed a small follow-up (5f5a511) that extracts:

GuestAuthButtons — Sign in / Sign up for guests
AuthenticatedProfileMenu — single profile-menu-btn + dropdown for signed-in users
Please re-diff Header.jsx on the latest commit when you get a chance. Happy to adjust further if anything still looks off.

@Antra1705
Antra1705 force-pushed the feature/freemium-auth-gating branch from 5f5a511 to 232fc9d Compare August 9, 2026 17:42
Split guest Sign in/up and the signed-in profile menu into separate
components so the mutually exclusive branches are obvious on review.
@Antra1705
Antra1705 force-pushed the feature/freemium-auth-gating branch from 232fc9d to bb086dc Compare August 9, 2026 17:42
@khanirfan18
khanirfan18 merged commit 02bae5c into khanirfan18:main Aug 9, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add freemium auth gating for Budgets and Goals & keep guest data local only

2 participants