Back to VideoVox Frontend

README

VideoVox POC

A proof-of-concept frontend application for video translation and subtitling, built with modern web technologies and best practices.

🚀 Tech Stack

  • Framework: Next.js 16 (App Router)
  • Language: TypeScript
  • Styling: Tailwind CSS + shadcn/ui
  • Component Development: Storybook 9
  • Testing:
- Unit/Integration: Jest + React Testing Library (70% coverage minimum) - E2E: Playwright
  • Design Pattern: Atomic Design
  • Code Quality: ESLint + Prettier
  • Git Hooks: Husky (pre-commit & pre-push checks)

📁 Project Structure

shell
videovox-poc/
├── src/
│   ├── app/                 # Next.js app router pages
│   ├── components/          # React components (atomic design)
│   │   ├── atoms/          # Basic building blocks (Button, Input, etc.)
│   │   ├── molecules/      # Simple combinations (SearchBar, Card, etc.)
│   │   ├── organisms/      # Complex components (Header, VideoPlayer, etc.)
│   │   └── templates/      # Page layouts
│   ├── lib/                # Utility functions
│   ├── styles/             # Global styles
│   └── types/              # TypeScript type definitions
├── e2e/                    # Playwright E2E tests
├── scripts/                # Build and quality check scripts
└── .storybook/             # Storybook configuration

🛠️ Getting Started

Prerequisites

  • Node.js 18+ and npm
  • Git

Installation

bash
# Clone the repository
git clone https://github.com/jonathanleahy/VideoVoxPoc.git
cd videovox-poc

# Install dependencies
npm install

# Set up git hooks
git config core.hooksPath .husky

Development

bash
# Start development server
npm run dev

# Open http://localhost:3000

Storybook

bash
# Start Storybook for component development
npm run storybook

# Open http://localhost:6006

🧪 Testing

Unit Tests (TDD)

bash
# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Generate coverage report (70% minimum required)
npm run test:coverage

Coverage thresholds:

  • Branches: 70%
  • Functions: 70%
  • Lines: 70%
  • Statements: 70%

E2E Tests (BDD)

bash
# Run Playwright tests
npm run test:e2e

# Run Playwright tests with UI
npm run test:e2e:ui

✅ Quality Checks

Manual Check

Run all quality checks manually before committing:

bash
npm run check
# or
./scripts/check.sh

This runs:

  • ✅ Prettier format check
  • ✅ TypeScript type check
  • ✅ ESLint check
  • ✅ Unit tests
  • ✅ Test coverage (70% minimum)
  • ✅ Next.js build
  • Automated Git Hooks

    Pre-commit (runs on git commit):

    • Format check
    • Type check
    • Lint check
    • Unit tests
    Pre-push (runs on git push):
    • Full quality check suite (all 6 checks)

    Override Git Hooks

    ⚠️ Not recommended, but if needed:

    bash
    # Skip pre-commit
    git commit --no-verify
    
    # Skip pre-push
    git push --no-verify

    🎨 Component Development (Atomic Design)

    Creating a New Component

  • Choose the atomic level:
  • - Atoms: Basic elements (Button, Input, Label) - Molecules: Simple groups (Form field with label and input) - Organisms: Complex sections (Navigation bar, Video uploader) - Templates: Page layouts

  • Create component files:
  • bash
    # Example: Creating a new atom
    mkdir -p src/components/atoms/Input
    touch src/components/atoms/Input/{Input.tsx,Input.test.tsx,Input.stories.tsx,index.ts}

  • Write tests FIRST (TDD):
  • typescript
    // Input.test.tsx
    import { render, screen } from "@testing-library/react";
    import { Input } from "./Input";
    
    describe("Input", () => {
      it("renders input element", () => {
        render(<Input placeholder="Enter text" />);
        expect(screen.getByPlaceholderText("Enter text")).toBeInTheDocument();
      });
    
      // Add more tests (aim for 70%+ coverage)
    });

  • Implement the component:
  • typescript
    // Input.tsx
    import React from "react";
    import { cn } from "@/lib/utils";
    
    export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
    
    const Input = React.forwardRef<HTMLInputElement, InputProps>(
      ({ className, ...props }, ref) => {
        return (
          <input
            className={cn("border rounded px-3 py-2", className)}
            ref={ref}
            {...props}
          />
        );
      }
    );
    
    Input.displayName = "Input";
    
    export { Input };

  • Create Storybook story:
  • typescript
    // Input.stories.tsx
    import type { Meta, StoryObj } from "@storybook/react";
    import { Input } from "./Input";
    
    const meta = {
      title: "Atoms/Input",
      component: Input,
      parameters: {
        layout: "centered",
      },
      tags: ["autodocs"],
    } satisfies Meta<typeof Input>;
    
    export default meta;
    type Story = StoryObj<typeof meta>;
    
    export const Default: Story = {
      args: {
        placeholder: "Enter text...",
      },
    };

  • Export from index.ts:
  • typescript
    // index.ts
    export { Input } from "./Input";
    export type { InputProps } from "./Input";

    🔧 Code Quality Standards

    TypeScript

    • Strict mode enabled
    • No any types (use unknown if needed)
    • Explicit return types for functions

    Testing

    • Write tests FIRST (TDD)
    • Aim for >70% coverage
    • Test user behavior, not implementation
    • Use BDD for E2E tests (Given-When-Then)

    Code Style

    • Use Prettier for formatting (auto-format on save recommended)
    • Follow ESLint rules
    • Use meaningful variable names
    • Keep functions small and focused

    🚀 Build & Deploy

    bash
    # Build for production
    npm run build
    
    # Start production server
    npm start

    🔗 Integration with VideoVox Backend

    This POC is designed to connect to the existing VideoVox GraphQL backend. GraphQL client setup will be added in future iterations.

    Backend Repository: VideoVox

    📚 Learn More

    📄 License

    MIT

    👥 Contributing

    See CONTRIBUTING.md for guidelines.

    © 2026 Jonathan Leahy · v1.0.9