Skip to content

Commit 44efbeb

Browse files
authored
Merge pull request #2 from JustAGhosT/tembo/docs-project-context-design-system
Document Design System
2 parents 6fbfcf1 + 35053b6 commit 44efbeb

51 files changed

Lines changed: 27233 additions & 5077 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# EditorConfig - https://editorconfig.org
2+
# Helps maintain consistent coding styles across editors
3+
4+
root = true
5+
6+
[*]
7+
charset = utf-8
8+
indent_style = space
9+
indent_size = 2
10+
end_of_line = lf
11+
insert_final_newline = true
12+
trim_trailing_whitespace = true
13+
14+
[*.{ts,tsx,js,jsx}]
15+
indent_size = 2
16+
17+
[*.{json,yml,yaml}]
18+
indent_size = 2
19+
20+
[*.md]
21+
trim_trailing_whitespace = false

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
run: npm ci
5050

5151
- name: Run tests
52-
run: npm test || true
52+
run: npm test
5353

5454
lint:
5555
name: Lint
@@ -67,7 +67,7 @@ jobs:
6767
run: npm ci
6868

6969
- name: Run ESLint
70-
run: npm run lint || true
70+
run: npm run lint
7171

7272
deploy:
7373
name: Deploy to Azure Static Web Apps

.storybook/main.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { StorybookConfig } from '@storybook/nextjs';
2+
3+
/**
4+
* Storybook Configuration
5+
* @audit DEBT-13 - Add Storybook for component documentation
6+
*
7+
* This configuration sets up Storybook for the Next.js App Router project.
8+
* Stories are located alongside components in the app/components directory.
9+
*/
10+
const config: StorybookConfig = {
11+
stories: [
12+
'../app/components/**/*.stories.@(js|jsx|mjs|ts|tsx)',
13+
'../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)',
14+
],
15+
addons: [
16+
'@storybook/addon-essentials',
17+
'@storybook/addon-interactions',
18+
],
19+
framework: {
20+
name: '@storybook/nextjs',
21+
options: {
22+
// Next.js App Router configuration
23+
builder: {
24+
useSWC: true,
25+
},
26+
},
27+
},
28+
staticDirs: ['../public'],
29+
docs: {
30+
autodocs: 'tag',
31+
},
32+
typescript: {
33+
reactDocgen: 'react-docgen-typescript',
34+
},
35+
};
36+
37+
export default config;

.storybook/preview.tsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import type { Preview } from '@storybook/react';
2+
import '../app/globals.css';
3+
4+
/**
5+
* Storybook Preview Configuration
6+
* @audit DEBT-13 - Add Storybook for component documentation
7+
*
8+
* This file configures the preview iframe where stories are rendered.
9+
* It imports global CSS and sets up decorators for theme support.
10+
*/
11+
const preview: Preview = {
12+
parameters: {
13+
controls: {
14+
matchers: {
15+
color: /(background|color)$/i,
16+
date: /Date$/i,
17+
},
18+
},
19+
backgrounds: {
20+
default: 'light',
21+
values: [
22+
{
23+
name: 'light',
24+
value: '#f8fafc',
25+
},
26+
{
27+
name: 'dark',
28+
value: '#0f172a',
29+
},
30+
],
31+
},
32+
layout: 'centered',
33+
},
34+
globalTypes: {
35+
theme: {
36+
description: 'Global theme for components',
37+
defaultValue: 'light',
38+
toolbar: {
39+
title: 'Theme',
40+
icon: 'circlehollow',
41+
items: ['light', 'dark'],
42+
dynamicTitle: true,
43+
},
44+
},
45+
},
46+
decorators: [
47+
(Story, context) => {
48+
const theme = context.globals.theme;
49+
// Apply theme class to story container
50+
return (
51+
<div className={theme === 'dark' ? 'dark' : ''}>
52+
<div className="p-4 bg-slate-50 dark:bg-slate-900">
53+
<Story />
54+
</div>
55+
</div>
56+
);
57+
},
58+
],
59+
};
60+
61+
export default preview;

README.md

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ This is the marketing website for CodeFlow AI, providing information about the p
88

99
## Technology Stack
1010

11-
- **Next.js**: React framework
12-
- **TypeScript**: Type-safe JavaScript
13-
- **Tailwind CSS**: Utility-first CSS framework
11+
- **Framework**: [Next.js 16.x](https://nextjs.org/) with App Router
12+
- **Language**: [TypeScript](https://www.typescriptlang.org/)
13+
- **Styling**: [Tailwind CSS 4.x](https://tailwindcss.com/)
14+
- **Testing**: [Vitest](https://vitest.dev/) + [React Testing Library](https://testing-library.com/react)
15+
- **Deployment**: [Azure Static Web Apps](https://azure.microsoft.com/services/app-service/static/)
1416

1517
## Development
1618

1719
### Prerequisites
1820

19-
- Node.js 18+
21+
- Node.js 18+
2022
- npm or yarn
2123

2224
### Getting Started
@@ -35,15 +37,81 @@ npm run build
3537
npm start
3638
```
3739

40+
### Testing
41+
42+
```bash
43+
# Run tests
44+
npm test
45+
46+
# Run tests in watch mode
47+
npm run test:watch
48+
49+
# Run tests with coverage report
50+
npm run test:coverage
51+
```
52+
53+
**Coverage Thresholds**: 60% for statements, branches, functions, and lines.
54+
55+
### Linting
56+
57+
```bash
58+
# Run ESLint
59+
npm run lint
60+
```
61+
62+
## Documentation
63+
64+
Comprehensive documentation is available in the `docs/` directory:
65+
66+
| Document | Description |
67+
|----------|-------------|
68+
| [Project Context](docs/project-context.md) | Business goals, target users, and user journeys |
69+
| [Design System](docs/design-system.md) | Design tokens, typography, colors, and component inventory |
70+
| [Architecture Overview](docs/architecture-overview.md) | System architecture, data flow, and deployment pipeline |
71+
| [Tech Stack](docs/tech-stack.md) | Detailed technology breakdown by layer |
72+
| [Best Practices Benchmark](docs/best-practices-benchmark.md) | Industry standards and evaluation criteria |
73+
| [Audit Findings](docs/audit-findings.md) | Code audit results and recommendations |
74+
| [Technical Debt Registry](docs/technical-debt-registry.md) | Tracked issues, priorities, and resolution status |
75+
3876
## Deployment
3977

4078
The website is deployed to Azure Static Web Apps. See [`codeflow-infrastructure`](https://github.com/JustAGhosT/codeflow-infrastructure) for deployment infrastructure.
4179

80+
### CI/CD Pipeline
81+
82+
The project uses GitHub Actions for continuous integration:
83+
84+
- **Build**: Compiles the Next.js application
85+
- **Test**: Runs Vitest test suite (blocking)
86+
- **Lint**: Runs ESLint checks (blocking)
87+
- **Deploy**: Deploys to Azure Static Web Apps on push to main
88+
89+
## Contributing
90+
91+
### Code Quality Standards
92+
93+
1. **TypeScript**: All code must be properly typed
94+
2. **Testing**: New features should include unit tests
95+
3. **Linting**: Code must pass ESLint without errors
96+
4. **Accessibility**: Follow WCAG 2.1 AA guidelines
97+
98+
### Commit Message Format
99+
100+
Use semantic commit messages:
101+
102+
```text
103+
feat: add new feature
104+
fix: resolve bug
105+
docs: update documentation
106+
test: add or update tests
107+
refactor: code improvements without behavior change
108+
```
109+
42110
## Related Repositories
43111

44112
- [`codeflow-engine`](https://github.com/JustAGhosT/codeflow-engine) - Core engine
45113
- [`codeflow-infrastructure`](https://github.com/JustAGhosT/codeflow-infrastructure) - Production infrastructure
46-
- [`codeflow-desktop`](https://github.com/JustAGhosT/codeflow-desktop) - Desktop application
114+
- [`codeflow-desktop`](https://github.com/JustAGhosT/codeflow-desktop) - Desktop application (contains shared design system)
47115
- [`codeflow-vscode-extension`](https://github.com/JustAGhosT/codeflow-vscode-extension) - VS Code extension
48116
- [`codeflow-azure-setup`](https://github.com/JustAGhosT/codeflow-azure-setup) - Azure bootstrap scripts
49117

app/components/AnimatedBackground.tsx

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
'use client';
22

3-
import { useEffect, useRef, useState, useCallback } from 'react';
3+
import { useEffect, useRef, useCallback, useSyncExternalStore } from 'react';
4+
import { debounce } from '../utils/debounce';
5+
import { useTheme } from './ThemeProvider';
6+
7+
// Hook for subscribing to reduced motion preference
8+
function useReducedMotion(): boolean {
9+
const subscribe = useCallback((callback: () => void) => {
10+
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
11+
mediaQuery.addEventListener('change', callback);
12+
return () => mediaQuery.removeEventListener('change', callback);
13+
}, []);
14+
15+
const getSnapshot = useCallback(() => {
16+
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
17+
}, []);
18+
19+
// Server-side default: true (safe, no animation)
20+
const getServerSnapshot = useCallback(() => true, []);
21+
22+
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
23+
}
424

525
/**
626
* AnimatedBackground - Particle animation background using design tokens
@@ -68,20 +88,15 @@ export default function AnimatedBackground() {
6888
const canvasRef = useRef<HTMLCanvasElement>(null);
6989
const animationFrameRef = useRef<number | null>(null);
7090
const particlesRef = useRef<Particle[]>([]);
71-
const [prefersReducedMotion, setPrefersReducedMotion] = useState(true); // Default to true (safe)
91+
const prefersReducedMotion = useReducedMotion();
92+
const { resolvedTheme } = useTheme();
93+
// Use ref to track theme in animation loop without causing re-renders
94+
const isDarkRef = useRef(resolvedTheme === 'dark');
7295

73-
// Check initial reduced motion preference on mount
96+
// Keep ref in sync with theme context
7497
useEffect(() => {
75-
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
76-
setPrefersReducedMotion(mediaQuery.matches);
77-
78-
const handleChange = (e: MediaQueryListEvent) => {
79-
setPrefersReducedMotion(e.matches);
80-
};
81-
82-
mediaQuery.addEventListener('change', handleChange);
83-
return () => mediaQuery.removeEventListener('change', handleChange);
84-
}, []);
98+
isDarkRef.current = resolvedTheme === 'dark';
99+
}, [resolvedTheme]);
85100

86101
const initParticles = useCallback((width: number, height: number) => {
87102
particlesRef.current = [];
@@ -140,8 +155,12 @@ export default function AnimatedBackground() {
140155
initParticles(canvas.width, canvas.height);
141156
};
142157

158+
// Debounce resize handler to prevent particle re-initialization thrashing
159+
const debouncedResize = debounce(resizeCanvas, 250);
160+
143161
const animate = () => {
144-
const isDark = document.documentElement.classList.contains('dark');
162+
// Use theme from context (via ref) instead of DOM class inspection
163+
const isDark = isDarkRef.current;
145164

146165
ctx.clearRect(0, 0, canvas.width, canvas.height);
147166

@@ -155,16 +174,18 @@ export default function AnimatedBackground() {
155174
animationFrameRef.current = requestAnimationFrame(animate);
156175
};
157176

177+
// Initial setup (not debounced)
158178
resizeCanvas();
159179
animate();
160180

161-
window.addEventListener('resize', resizeCanvas);
181+
window.addEventListener('resize', debouncedResize);
162182

163183
return () => {
164184
if (animationFrameRef.current) {
165185
cancelAnimationFrame(animationFrameRef.current);
166186
}
167-
window.removeEventListener('resize', resizeCanvas);
187+
debouncedResize.cancel();
188+
window.removeEventListener('resize', debouncedResize);
168189
};
169190
}, [prefersReducedMotion, initParticles, drawConnections]);
170191

0 commit comments

Comments
 (0)