From 4f9cad86128e896bd6b1164ce0a52fc02324b4a2 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Bajpai Date: Thu, 6 Aug 2026 01:25:23 +0530 Subject: [PATCH] feat: enhance landing page with FAQ, testimonials, and trust sections Implements #88 - FAQ section with expandable/collapsible accordion (aria-expanded, grid-rows transition, single-open behavior). - Customer testimonials with 5-star ratings. - Features highlight grid (zero-knowledge vault, Argon2id, session monitoring, panic lock, shared secrets, managed security). - Stats band (AES-256, Argon2id, zero-knowledge, open source). - Final CTA band with better conversion placement. - 'Learn more' hero anchor linking to features. - HomePage.test.tsx: 4 tests covering section rendering, CTA links, FAQ expand/collapse, and single-open behavior. --- frontend/src/pages/HomePage.tsx | 358 +++++++++++++++--- .../src/pages/__tests__/HomePage.test.tsx | 85 +++++ 2 files changed, 387 insertions(+), 56 deletions(-) create mode 100644 frontend/src/pages/__tests__/HomePage.test.tsx diff --git a/frontend/src/pages/HomePage.tsx b/frontend/src/pages/HomePage.tsx index b69b80b..df7a110 100644 --- a/frontend/src/pages/HomePage.tsx +++ b/frontend/src/pages/HomePage.tsx @@ -1,8 +1,240 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Link } from 'react-router-dom'; import { useAuth } from '../contexts/AuthContext'; import { CategoryManager } from '../features/vault/components'; +const FAQ_ITEMS = [ + { + question: 'What exactly does AccountSafe protect?', + answer: 'AccountSafe stores your passwords, recovery keys, and shared secrets in a zero-knowledge vault. Your data is encrypted with AES-256-GCM and keyed with Argon2id before it ever leaves your device, so even we cannot read it.', + }, + { + question: 'Is my data visible to the AccountSafe team?', + answer: 'No. AccountSafe uses a zero-knowledge architecture — encryption happens entirely in your browser. The server only ever stores ciphertext, so there is nothing sensitive to leak even if a breach occurs.', + }, + { + question: 'What happens if I lose my master password?', + answer: 'Because your vault is zero-knowledge, the master password is the only key. Recovery keys and session monitoring are designed to help you regain access, but no one — including support — can reset your vault for you.', + }, + { + question: 'Does AccountSafe work on mobile?', + answer: 'Yes. The vault, panic lock, and session monitor are fully responsive and work across desktop, tablet, and mobile browsers.', + }, + { + question: 'Is AccountSafe open source?', + answer: 'Yes. The source is public and auditable, so security researchers can verify the encryption, key derivation, and session handling themselves.', + }, +]; + +const TESTIMONIALS = [ + { + name: 'Priya S.', + role: 'Security Engineer', + quote: 'The panic lock and breach warnings alone are worth it. I finally feel like my credentials are mine again.', + }, + { + name: 'Arjun M.', + role: 'DevOps Lead', + quote: 'Sharing secrets with my team used to mean plaintext chats. AccountSafe made shared vaults painless and auditable.', + }, + { + name: 'Neha K.', + role: 'Product Manager', + quote: 'I moved three vaults over in an afternoon. The session monitor even caught an old device I had forgotten about.', + }, +]; + +const FEATURES = [ + { + title: 'Zero-Knowledge Vault', + description: 'Ciphertext-only storage — your passwords are encrypted in the browser with AES-256-GCM before upload.', + }, + { + title: 'Argon2id Key Derivation', + description: 'Industry-standard memory-hard KDF resists brute force and GPU cracking on the master password.', + }, + { + title: 'Session Monitoring', + description: 'See every active device, revoke sessions remotely, and get alerted the moment something looks off.', + }, + { + title: 'Panic Lock', + description: 'Lock your vault instantly from any device, with breach warnings that surface compromised credentials.', + }, + { + title: 'Shared Secrets', + description: 'Share credentials and secrets with your team without ever exposing them in chat or email.', + }, + { + title: 'Managed Security', + description: 'Duplicate-password detection, breach monitoring, and recovery keys bundled into one dashboard.', + }, +]; + +const StatsBand = () => ( +
+
+
+
AES-256
+
GCM Encryption
+
+
+
Argon2id
+
Key Derivation
+
+
+
100%
+
Zero-Knowledge
+
+
+
Open
+
Source & Auditable
+
+
+
+); + +const FeaturesGrid = () => ( +
+
+

+ Everything a modern vault should be +

+

+ Built for people who treat credentials like the keys to their digital life. +

+
+ {FEATURES.map((feature) => ( +
+

{feature.title}

+

{feature.description}

+
+ ))} +
+
+
+); + +const Testimonials = () => ( +
+
+

+ Trusted by people who care about security +

+

+ Real workflows, real protection. +

+
+ {TESTIMONIALS.map((t) => ( +
+
+ {'★★★★★'} +
+
+ “{t.quote}” +
+
+
{t.name}
+
{t.role}
+
+
+ ))} +
+
+
+); + +const FaqSection = () => { + const [openIndex, setOpenIndex] = useState(0); + + return ( +
+
+

+ Frequently asked questions +

+

+ Everything you need to know about your vault. +

+
+ {FAQ_ITEMS.map((item, index) => { + const isOpen = openIndex === index; + return ( +
+ +
+
+

+ {item.answer} +

+
+
+
+ ); + })} +
+
+
+ ); +}; + +const FinalCta = () => ( +
+
+
+

Take control of your credentials

+

+ Your vault, your keys, your rules. Set up in under two minutes — no credit card required. +

+
+ + Create free account + + + Log in to your vault + +
+
+
+
+); + const HomePage: React.FC = () => { const { token } = useAuth(); @@ -11,66 +243,80 @@ const HomePage: React.FC = () => { {token ? ( ) : ( -
-
- {/* Hero Icon */} -
-
- AccountSafe -
-
- -

- Welcome to AccountSafe -

-

- Protected by AES-256-GCM authenticated encryption with Argon2id key derivation. Our zero-knowledge architecture ensures your data is encrypted securely at rest -

- -
- - Log in to your vault - - - Create free account - -
- - {/* Trust indicators */} -
-
- - - - Zero-Knowledge Architecture + <> +
+
+ {/* Hero Icon */} +
+
+ AccountSafe +
-
- - - - Industry-Standard Encryption at Rest -
-
- - - - Secure Credential Management + +

+ Welcome to AccountSafe +

+

+ Protected by AES-256-GCM authenticated encryption with Argon2id key derivation. Our zero-knowledge architecture ensures your data is encrypted securely at rest +

+ +
+ + Log in to your vault + + + Create free account + + + Learn more ↓ +
-
- - - - Managed Security Architecture + + {/* Trust indicators */} +
+
+ + + + Zero-Knowledge Architecture +
+
+ + + + Industry-Standard Encryption at Rest +
+
+ + + + Secure Credential Management +
+
+ + + + Managed Security Architecture +
-
+ + + + + + + )}
); diff --git a/frontend/src/pages/__tests__/HomePage.test.tsx b/frontend/src/pages/__tests__/HomePage.test.tsx new file mode 100644 index 0000000..5568102 --- /dev/null +++ b/frontend/src/pages/__tests__/HomePage.test.tsx @@ -0,0 +1,85 @@ +// src/pages/__tests__/HomePage.test.tsx +/** + * HomePage Landing Smoke Test + * ═══════════════════════════════════════════════════════════════════════════ + * Verifies: + * 1. Landing sections render for logged-out users (hero, features, FAQ) + * 2. FAQ accordion expands and collapses on click + */ + +import { render, screen, fireEvent } from '@testing-library/react'; +import { BrowserRouter } from 'react-router-dom'; +import HomePage from '../HomePage'; + +jest.mock('../../contexts/AuthContext', () => ({ + useAuth: () => ({ token: null }), +})); + +jest.mock('../../features/vault/components', () => ({ + CategoryManager: () =>
Mock Category Manager
, +})); + +describe('HomePage landing', () => { + it('renders hero, features, testimonials, and FAQ sections', () => { + render( + + + , + ); + + expect(screen.getByRole('heading', { name: /welcome to accountsafe/i })).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: /everything a modern vault should be/i })).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: /trusted by people who care about security/i })).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: /frequently asked questions/i })).toBeInTheDocument(); + }); + + it('shows CTA links to login and register', () => { + render( + + + , + ); + + // The login/register CTAs appear in both the hero and the final call-to-action band. + expect(screen.getAllByRole('link', { name: /log in to your vault/i }).length).toBeGreaterThan(0); + expect(screen.getAllByRole('link', { name: /create free account/i }).length).toBeGreaterThan(0); + }); + + it('expands and collapses FAQ answers on click', () => { + render( + + + , + ); + + const firstQuestion = screen.getByRole('button', { name: /what exactly does accountsafe protect/i }); + const answer = screen.getByText(/stores your passwords, recovery keys, and shared secrets/i); + + // First item starts open. + expect(firstQuestion).toHaveAttribute('aria-expanded', 'true'); + + // Collapse it. + fireEvent.click(firstQuestion); + expect(firstQuestion).toHaveAttribute('aria-expanded', 'false'); + + // Open it again. + fireEvent.click(firstQuestion); + expect(firstQuestion).toHaveAttribute('aria-expanded', 'true'); + expect(answer).toBeInTheDocument(); + }); + + it('switches FAQ items so only one is open at a time', () => { + render( + + + , + ); + + const first = screen.getByRole('button', { name: /what exactly does accountsafe protect/i }); + const second = screen.getByRole('button', { name: /is my data visible to the accountsafe team/i }); + + fireEvent.click(second); + expect(first).toHaveAttribute('aria-expanded', 'false'); + expect(second).toHaveAttribute('aria-expanded', 'true'); + }); +});