mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-03-31 21:14:48 -04:00
* Added Database checks to the onboarding flow * Added compatibility page setup Added more compatibility questions * Finished up the onboarding flow suite Added compatibility question tests and verifications Updated tests to cover Keywords and Headline changes recently made Updated tests to cover all of the big5 personality traits * Fix: Added 'tsconfig-paths/register' to playwright config so it applies tsconfig/ts-node to test files and imported modules....there was a syntax error: SyntaxError: tests/e2e/web/pages/homePage.ts: Unexpected token (2:0) * . * Updated ProfilePage: In some cases removed the use of "one shot grabs" using .textContent() to prevent flaky tests Added test for entering profile information post signup flow * Linting and Prettier * Fix: Merge conflict * Fix: Modified sortedAndFilteredAnswers to use "UseMemo" so that it doesnt run every time something changes * . * . * Merged "verifyInterestedInConnectingWith" and "verifyRelationShipTypeAndInterest" into "verifySeeking" to match ui changes * Added error message outlining the minimum character requirement for display names and usernames * Updated displayName error message to show when editing the user profile post signup * Fix: Added fix for None discriptive error issue #36 Updated signUp.spec.ts to use new fixture Updated Account information variable names Deleted "deleteUserFixture.ts" as it was incorporated into the "base.ts" file * Linting and Prettier * Minor cleaning * Organizing helper func * Linting and Prettier --------- Co-authored-by: MartinBraquet <martin.braquet@gmail.com>
357 lines
7.7 KiB
Markdown
357 lines
7.7 KiB
Markdown
# Web Application
|
|
|
|
The Compass web application built with Next.js, React and TypeScript.
|
|
|
|
## Overview
|
|
|
|
This is the frontend of the Compass platform, a transparent platform for forming deep, authentic 1-on-1 connections.
|
|
|
|
## Tech Stack
|
|
|
|
- **Framework**: Next.js 16
|
|
- **Language**: TypeScript
|
|
- **UI Library**: React 19.2.3
|
|
- **Styling**: Tailwind CSS 3.3.3
|
|
- **State Management**: React Context + Custom Hooks
|
|
- **Forms**: React Hook Form
|
|
- **Rich Text**: TipTap (ProseMirror)
|
|
- **Charts**: Recharts
|
|
- **i18n**: Custom solution with JSON message files
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
web/
|
|
├── components/ # React components
|
|
│ ├── auth-context.tsx # Authentication state
|
|
│ ├── buttons/ # Button components
|
|
│ ├── chat/ # Chat/messaging components
|
|
│ ├── comments/ # Comment components
|
|
│ ├── editor/ # Rich text editor
|
|
│ ├── events/ # Event components
|
|
│ ├── filters/ # Search filters
|
|
│ ├── matches/ # Match components
|
|
│ ├── nav/ # Navigation components
|
|
│ ├── profile/ # Profile components
|
|
│ └── widgets/ # Reusable widgets
|
|
├── hooks/ # Custom React hooks (50+)
|
|
├── lib/ # Utilities and services
|
|
│ ├── api.ts # API client
|
|
│ ├── firebase/ # Firebase configuration
|
|
│ ├── locale/ # Internationalization
|
|
│ ├── service/ # Analytics, push notifications
|
|
│ ├── supabase/ # Supabase client
|
|
│ └── logger.ts # Structured logging
|
|
├── pages/ # Next.js pages
|
|
│ ├── api/ # API routes
|
|
│ ├── _app.tsx # App wrapper
|
|
│ ├── _document.tsx # Document setup
|
|
│ └── [username].tsx # Dynamic routes
|
|
├── messages/ # Translation JSON files
|
|
├── public/ # Static assets
|
|
├── styles/ # Global CSS
|
|
├── tests/
|
|
│ ├── unit/ # Unit tests
|
|
│ └── integration/ # Integration tests
|
|
└── types/ # TypeScript type definitions
|
|
```
|
|
|
|
## Getting Started
|
|
|
|
### Prerequisites
|
|
|
|
- Node.js 20.x or later
|
|
- Yarn 1.x
|
|
|
|
### Installation
|
|
|
|
```bash
|
|
# From root directory
|
|
yarn install
|
|
```
|
|
|
|
### Development
|
|
|
|
```bash
|
|
# Run web app with hot reload
|
|
yarn dev
|
|
|
|
# Or from web directory
|
|
cd web
|
|
yarn serve
|
|
```
|
|
|
|
Visit http://localhost:3000
|
|
|
|
### Build
|
|
|
|
```bash
|
|
# Production build
|
|
yarn build
|
|
|
|
# Start production server
|
|
yarn start
|
|
```
|
|
|
|
### Testing
|
|
|
|
```bash
|
|
# Run tests
|
|
yarn test
|
|
|
|
# Run with coverage
|
|
yarn test --coverage
|
|
|
|
# Watch mode
|
|
yarn test --watch
|
|
```
|
|
|
|
### Linting
|
|
|
|
```bash
|
|
# Check lint
|
|
yarn lint
|
|
|
|
# Fix lint issues
|
|
yarn lint-fix
|
|
```
|
|
|
|
## Key Concepts
|
|
|
|
### Components
|
|
|
|
Components are organized by feature in `/components`. Reusable widgets are in `/components/widgets`.
|
|
|
|
Example component:
|
|
|
|
```tsx
|
|
// components/profile/profile-card.tsx
|
|
import {User} from 'common/src/user'
|
|
|
|
interface ProfileCardProps {
|
|
user: User
|
|
onLike?: (userId: string) => void
|
|
}
|
|
|
|
export function ProfileCard({user, onLike}: ProfileCardProps) {
|
|
return (
|
|
<div className="profile-card">
|
|
<img src={user.avatarUrl} alt={user.name} />
|
|
<h3>{user.name}</h3>
|
|
<button onClick={() => onLike?.(user.id)}>Like</button>
|
|
</div>
|
|
)
|
|
}
|
|
```
|
|
|
|
### Hooks
|
|
|
|
Use custom hooks for stateful logic. Common hooks:
|
|
|
|
- `useUser()` - Get current user
|
|
- `useAPIGetter()` - Fetch API data with caching
|
|
- `useMutation()` - Handle form submissions
|
|
- `usePersistentInMemoryState()` - Cache state across pages
|
|
|
|
```tsx
|
|
import {useAPIGetter} from 'web/hooks/use-api-getter'
|
|
|
|
function ProfileList() {
|
|
const {data, refresh} = useAPIGetter('get-profiles', {})
|
|
|
|
if (!data) return <Loading />
|
|
|
|
return (
|
|
<div>
|
|
{data.profiles.map((profile) => (
|
|
<ProfileCard key={profile.id} user={profile} />
|
|
))}
|
|
<button onClick={refresh}>Refresh</button>
|
|
</div>
|
|
)
|
|
}
|
|
```
|
|
|
|
### API Calls
|
|
|
|
Backend API is called through the `api` helper:
|
|
|
|
```tsx
|
|
import {api} from 'web/lib/api'
|
|
|
|
// Server-side (getStaticProps, getServerSideProps)
|
|
const profiles = await api('get-profiles', {})
|
|
|
|
// Client-side - use hooks
|
|
const {data} = useAPIGetter('get-profiles', {})
|
|
```
|
|
|
|
### Internationalization
|
|
|
|
Translation files are in `/common/messages` (e.g., `en.json`, `fr.json`).
|
|
|
|
```tsx
|
|
import {useT} from 'web/lib/locale'
|
|
|
|
function MyComponent() {
|
|
const t = useT()
|
|
|
|
return <h1>{t('welcome', 'Welcome to Compass')}</h1>
|
|
}
|
|
```
|
|
|
|
### Styling
|
|
|
|
Tailwind CSS is used for styling. Use utility classes:
|
|
|
|
```tsx
|
|
<div className="flex items-center justify-between p-4 bg-canvas-50 rounded-lg">
|
|
<span className="text-ink-900 font-medium">Content</span>
|
|
</div>
|
|
```
|
|
|
|
## Accessibility
|
|
|
|
The app includes several accessibility features:
|
|
|
|
### Error Boundary
|
|
|
|
Catches React errors and shows user-friendly message:
|
|
|
|
```tsx
|
|
import {ErrorBoundary} from 'web/components/error-boundary'
|
|
;<ErrorBoundary>
|
|
<MyComponent />
|
|
</ErrorBoundary>
|
|
```
|
|
|
|
### Live Region
|
|
|
|
Announces dynamic content changes to screen readers:
|
|
|
|
```tsx
|
|
import {useLiveRegion} from 'web/components/live-region'
|
|
|
|
const {announce} = useLiveRegion()
|
|
|
|
// Announce status changes
|
|
announce('Profile liked', 'polite')
|
|
```
|
|
|
|
Priority levels:
|
|
|
|
- `polite` - Waits for screen reader to finish (default)
|
|
- `assertive` - Interrupts immediately
|
|
|
|
### Skip Links
|
|
|
|
Keyboard users can skip to main content:
|
|
|
|
```tsx
|
|
import {SkipLink, MainContent} from 'web/components/skip-link'
|
|
;<>
|
|
<SkipLink />
|
|
<MainContent>...</MainContent>
|
|
</>
|
|
```
|
|
|
|
## Logging
|
|
|
|
Use the structured logger for debug logging that's filtered out in production:
|
|
|
|
```tsx
|
|
import {debug, logApiError} from 'common/logger'
|
|
|
|
// Simple logging
|
|
debug('User logged in', {userId: '123'})
|
|
|
|
// API errors with context
|
|
try {
|
|
await api('endpoint', {})
|
|
} catch (err) {
|
|
logApiError('get-profiles', err, {userId: '123'})
|
|
}
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
Key environment variables for the web app:
|
|
|
|
| Variable | Description |
|
|
| ------------------------------- | --------------------- |
|
|
| `NEXT_PUBLIC_SUPABASE_URL` | Supabase project URL |
|
|
| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Supabase anon key |
|
|
| `NEXT_PUBLIC_FIREBASE_API_KEY` | Firebase API key |
|
|
| `NEXT_PUBLIC_POSTHOG_KEY` | PostHog analytics key |
|
|
| `NEXT_PUBLIC_VERCEL_ENV` | Vercel environment |
|
|
|
|
## Common Tasks
|
|
|
|
### Adding a New Page
|
|
|
|
1. Create file in `/pages/`:
|
|
|
|
```tsx
|
|
// pages/new-page.tsx
|
|
import {Page} from 'web/components/page-base'
|
|
|
|
export default function NewPage() {
|
|
return (
|
|
<Page>
|
|
<h1>New Page</h1>
|
|
</Page>
|
|
)
|
|
}
|
|
```
|
|
|
|
### Adding a Component
|
|
|
|
1. Create file in appropriate `/components` subdirectory
|
|
2. Export the component
|
|
3. Add to parent component
|
|
|
|
### Adding a Hook
|
|
|
|
1. Create file in `/hooks/`
|
|
2. Follow naming convention:\*.ts`
|
|
|
|
### Adding Translations
|
|
|
|
1. Add key to `/messages/fr.json`
|
|
2. Add translations to other locale files
|
|
|
|
## Troubleshooting
|
|
|
|
### Slow local development
|
|
|
|
Running `yarn dev:isolated` uses local emulators and is faster.
|
|
|
|
### Type errors
|
|
|
|
Run `yarn typecheck` to see all type errors.
|
|
|
|
### Build failures
|
|
|
|
Check `yarn lint` first, as linting issues can cause build failures.
|
|
|
|
## See Also
|
|
|
|
- [Main README](../README.md)
|
|
- [Contributing Guide](../CONTRIBUTING.md)
|
|
- [Development Docs](../docs/development.md)
|
|
- [Testing Guide](../docs/TESTING.md)
|
|
- [Architecture Docs](../docs/knowledge.md)
|
|
|
|
## Setup
|
|
|
|
This is the setup for deployment on Vercel, which you only need to do if you create a new platform from scratch, not if
|
|
you are contributing to Compass.
|
|
|
|
Set up a Vercel account and link it to your GitHub repository.
|
|
|
|
Add the following environment variables and the ones in `.env` in the Vercel dashboard:
|
|
|
|
```bash
|
|
NEXT_PUBLIC_VERCEL=1
|
|
```
|