Files
chore/.github/specs/feat-landing-page.md
Ryan Kegel c922e1180d
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 3m23s
feat: add landing page components including hero, features, problem, and footer
- Introduced LandingHero component with logo, tagline, and action buttons.
- Created LandingFeatures component to showcase chore system benefits.
- Developed LandingProblem component explaining the importance of a structured chore system.
- Implemented LandingFooter for navigation and copyright information.
- Added LandingPage to assemble all components and manage navigation.
- Included unit tests for LandingHero component to ensure functionality.
2026-03-04 16:21:26 -05:00

6.1 KiB
Raw Blame History

Feature: Landing page with details

Overview

When an unauthenticated user visits the web site, they will be sent to this landing page. The page will contain a hero with various images. A sign up/sign in component. On scrolling, various components will show describing the application features and functionality.

Goal: New users are brought to the landing page to learn more about the app.

User Story: As a new user, I should be presented with the landing page that tells me about the app.

Rules: .github/copilot-instructions.md You know how my app works at a high level

Discussions:

  • I want each part of the landing page as different components (rows)
  • Should these components go into their own directory (components/landing)
  1. Row 1
    • My logo is resources\logo\full_logo.png
    • I plan to have my logo in the center near the top of the landing page
    • I'd like to have my hero as resources\logo\hero.png
    • I'd like to have my current sign in / sign up logic copied to a new component, but with this hero, it should be modern looking - semi-transparent glassmorphism box
    • Should I have sign in or sign up? or compact both together
  2. Row 2
    • This should describe the problem - getting kids to do chores consistently - Describe how a system benefits:
    1. Develops Executive Function: Managing a "to-do list" teaches kids how to prioritize tasks, manage their time, and follow multi-step directions—skills that translate directly to schoolwork and future careers.
    2. Fosters a "Can-Do" Attitude: Completing a task provides a tangible sense of mastery. This builds genuine self-esteem because its based on actual competence rather than just empty praise.
    3. Encourages Accountability: A system moves chores from "Mom/Dad is nagging me" to "This is my responsibility." It teaches that their actions (or lack thereof) have a direct impact on the people they live with.
    4. Normalizes Life Skills: By the time they head out on their own, "adulting" won't feel like a mountain to climb. Cooking, cleaning, and organizing will be second nature rather than a stressful learning curve.
    5. Promotes Family Belonging: Contributing to the home makes a child feel like a teammate rather than a guest. It reinforces the idea that a family is a unit where everyone supports one another.
  3. Row 3
    • This should describe how my app helps to solve the problem by creating the system
    1. Chores can be created with customizable points that children have fun collecting.
    2. Customized reward offer insentives for a child to set a goal. (saving points, etc)
    3. Easy interface for children to see which chores need to be done and what rewards they can afford.
    4. Parental controls (hidden) behind a pin that offer powerful tools for managing the system
    • In this component we'll show some screen shots of the interface.
  4. Row 4
    • I'm not sure what else I should add for now
  • How should I handle colors - should I follow my current theme in colors.css or should I adopt my logo / hero colors?

  • Should my landing page be more modern and sleek with animations? What kind?

  • Considerations for mobile should also be handled (whether in portrait or landscape mode)


Data Model Changes

Backend Model

Frontend Model


Backend Implementation

Backend Tests


Frontend Implementation

  • Copy resources/logo/full_logo.png and hero.png to frontend/vue-app/public/images/
  • Add landing CSS variables to colors.css
  • Create src/components/landing/LandingPage.vue — orchestrator with sticky nav
  • Create src/components/landing/LandingHero.vue — hero section with logo, tagline, glassmorphism CTA card
  • Create src/components/landing/LandingProblem.vue — 5-benefit problem section
  • Create src/components/landing/LandingFeatures.vue — 4-feature alternating layout with screenshot placeholders
  • Create src/components/landing/LandingFooter.vue — dark footer with links
  • Update router: add / → LandingPage route (meta: isPublic), update auth guard

Frontend Tests

  • Update authGuard.spec.ts: fix redirect assertions (/auth/) and add 3 landing-route guard tests
  • Create src/components/landing/__tests__/LandingHero.spec.ts: renders logo, tagline, buttons; CTA clicks push correct routes

Future Considerations

  • Eventually add a pricing section (component)

Acceptance Criteria (Definition of Done)

Backend

Frontend

  • Unauthenticated user visiting / sees the full landing page
  • Sign In CTA routes to /auth/login
  • Get Started CTA routes to /auth/signup
  • Logged-in user visiting / is redirected to /child or /parent
  • Unauthenticated user visiting any protected route is redirected to / (landing)
  • All 4 rows render: Hero, Problem, Features, Footer
  • Sticky nav appears on scroll
  • Mobile: hero buttons stack vertically, grid goes single-column
  • All colors use colors.css variables only

Bugs

BUG-001 — Landing page instantly redirects to /auth on first visit

Status: Fixed

Description: Visiting / as an unauthenticated user caused a visible flash of the landing page followed by an immediate hard redirect to /auth, making the landing page effectively unreachable.

Root Cause: App.vue calls checkAuth() on mount, which hits /api/auth/me. For an unauthenticated user this returns a 401. The fetch interceptor in api.ts (handleUnauthorizedResponse) then attempted a token refresh, which also failed, and finally called window.location.assign('/auth'). The interceptor only exempted paths already starting with /auth — not the landing page at /.

Solution:

  • frontend/vue-app/src/common/api.ts — Added if (window.location.pathname === '/') return inside handleUnauthorizedResponse() so the unauthorized interceptor does not forcibly redirect away from the public landing page.
  • frontend/vue-app/src/stores/auth.ts — Updated the cross-tab logout storage event handler to redirect to / instead of /auth/login, and skip the redirect entirely if already on /.