# Nomadics Web App - Developer Guide

## Project Overview

Nomadics is a creative studio platform that connects creators with premium studio spaces across multiple global locations. The application showcases various studio types (music, video, photo) and allows users to browse locations, view studio details, and book sessions.

## Technology Stack

- **Framework**: [Remix](https://remix.run/) - Full-stack web framework
- **Styling**: Tailwind CSS with custom Clash Grotesk font
- **UI Components**: Custom components with shadcn/ui base
- **Language**: TypeScript
- **Package Manager**: Bun
- **Deployment**: Vite for development, production-ready build system

## Getting Started

### Prerequisites
- Node.js (v18 or higher)
- Bun (latest version)

### Installation
```bash
# Install dependencies
bun install

# Start development server
bun run dev

# Build for production
bun run build

# Run production build
bun start
```

## Project Structure

```
nomadics-web-app/
├── app/
│   ├── routes/               # Page routes
│   ├── components/           # Reusable components
│   │   ├── pages/           # Page-specific components
│   │   ├── shared/          # Shared components
│   │   └── ui/              # Base UI components
│   ├── config/              # Configuration and mock data
│   ├── lib/                 # Utilities
│   └── tailwind.css         # Global styles
├── public/                   # Static assets
│   └── images/              # Images organized by section
└── package.json
```

## Architecture Pattern

The application follows a consistent, data-driven architecture pattern across all routes:

### 1. Route Structure
Each dynamic route follows this pattern:

```typescript
// app/routes/[resource].$param.tsx

import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { resourceConfig } from "~/config/[resource]";
import { SectionA, SectionB, SectionC } from "~/components/pages/[resource]";

// Loader fetches data from config (will be replaced with API calls)
export async function loader({ params }: LoaderFunctionArgs) {
  const param = params.param;
  const data = resourceConfig[param];
  
  if (!data) {
    throw new Response("Not Found", { status: 404 });
  }
  
  return Response.json({ data });
}

// Meta function for SEO
export const meta: MetaFunction<typeof loader> = ({ data }) => {
  if (!data) {
    return [
      { title: "Not Found | Nomadics" },
      { name: "description", content: "Resource not found" },
    ];
  }
  
  return [
    { title: data.data.meta.title },
    { name: "description", content: data.data.meta.description },
  ];
};

// Component passes data to sections
export default function Page() {
  const { data } = useLoaderData<typeof loader>();
  
  return (
    <div>
      <SectionA data={data.sectionA} />
      <SectionB data={data.sectionB} />
      <SectionC data={data.sectionC} />
    </div>
  );
}
```

### 2. Component Structure
All components are data-driven and receive props:

```typescript
// app/components/pages/[resource]/SectionName/SectionName.tsx

interface SectionData {
  title: string;
  content: string;
  // ... other fields
}

interface SectionProps {
  data: SectionData;
}

export function Section({ data }: SectionProps) {
  return (
    <div>
      <h2>{data.title}</h2>
      <p>{data.content}</p>
    </div>
  );
}
```

### 3. Configuration Structure
All data currently lives in TypeScript configuration files:

```typescript
// app/config/[resource].ts

export interface ResourceData {
  meta: {
    title: string;
    description: string;
  };
  sectionA: { /* ... */ };
  sectionB: { /* ... */ };
  sectionC: { /* ... */ };
}

export const resourceConfig: Record<string, ResourceData> = {
  key1: { /* data */ },
  key2: { /* data */ },
};
```

## Main Routes

### Static Routes
- `/` - Homepage (app/routes/_index.tsx)
- `/people` - People listing
- `/events` - Events page
- `/equipment` - Equipment catalog

### Dynamic Routes
These routes follow the standardized pattern:

#### 1. Locations Route (`/locations/[location]`)
- **File**: `app/routes/locations.$location.tsx`
- **Config**: `app/config/locations.ts`
- **Available locations**: bali, bangkok, mexico, costa-rica, new-york, mumbai
- **Components**: WelcomeSection, LocationInfo, StudiosSection, EventsSection, PlanYourVisitSection

#### 2. Studios Route (`/studios/[type]`)
- **File**: `app/routes/studios.$type.tsx`
- **Config**: `app/config/studios.ts`
- **Available types**: music, photo, video
- **Components**: WelcomeSection, StudiosSection, PhotoSection, BookSection

#### 3. Book Studio Route (`/book-studio/[studioId]`)
- **File**: `app/routes/book-studio.$studioId.tsx`
- **Config**: `app/config/book-studio.ts`
- **Studio ID format**: `[location]-[type]` (e.g., "bali-music-studio")
- **Components**: StudioHeroSection, StudioInfoSection, CrewSection, EquipmentSection

## Component Library

### Shared Components
Located in `app/components/shared/`:
- `MembershipSection` - Membership CTAs
- `PeopleSection` - Team member grid with filtering
- `PhotoGallery` - Image gallery with modal view
- `BookingForm` - Studio booking form
- `EventsGrid` - Event cards display
- `StudiosGrid` - Studio cards grid
- `Tag` - Tag component for labels

### UI Components
Base components in `app/components/ui/`:
- Button, Card, Input, Badge, Sheet, NavigationMenu, etc.
- These follow shadcn/ui patterns

## Adding New Features

### Creating a New Page

1. **Static Page Example**:
```typescript
// app/routes/new-page.tsx
import type { MetaFunction } from "@remix-run/node";

export const meta: MetaFunction = () => {
  return [
    { title: "New Page | Nomadics" },
    { name: "description", content: "Page description" },
  ];
};

export default function NewPage() {
  return (
    <div>
      <h1>New Page</h1>
      {/* Add your content */}
    </div>
  );
}
```

2. **Dynamic Page Example**:
Follow the pattern in `app/routes/locations.$location.tsx`:
- Create route file with `$param` syntax
- Add configuration in `app/config/`
- Create section components in `app/components/pages/[page-name]/`

### Creating a New Component

1. Create component file in appropriate directory
2. Export from index.ts for clean imports
3. Follow existing naming conventions

Example:
```typescript
// app/components/pages/studios/NewSection/NewSection.tsx
interface NewSectionData {
  title: string;
  items: Array<{ id: string; name: string }>;
}

interface NewSectionProps {
  data: NewSectionData;
}

export function NewSection({ data }: NewSectionProps) {
  return (
    <section>
      <h2>{data.title}</h2>
      {data.items.map(item => (
        <div key={item.id}>{item.name}</div>
      ))}
    </section>
  );
}
```

## Styling Guidelines

### Tailwind Classes
- Use Tailwind utility classes for styling
- Custom font classes: `font-clash-grotesk`
- Responsive design: mobile-first approach
- Breakpoints: `sm:`, `md:`, `lg:`, `xl:`

### Common Patterns
```css
/* Container */
className="mx-auto max-w-7xl px-4 lg:px-14"

/* Grid layouts */
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"

/* Typography */
className="text-heading-3 font-medium uppercase"
```

## Data Management

### Current State (Mock Data)
All data is currently in TypeScript configuration files:
- `/app/config/locations.ts` - Location data
- `/app/config/studios.ts` - Studio types data
- `/app/config/book-studio.ts` - Booking page data

### Future API Integration
To replace mock data with API calls:

1. Update loader functions to fetch from API:
```typescript
export async function loader({ params }: LoaderFunctionArgs) {
  const response = await fetch(`${API_URL}/locations/${params.location}`);
  const data = await response.json();
  
  if (!response.ok) {
    throw new Response("Not Found", { status: 404 });
  }
  
  return Response.json({ data });
}
```

2. Keep the same data structure for seamless transition
3. Components won't need changes if API returns same structure

## Testing

Run tests with:
```bash
bun test
```

## Build and Deployment

### Development
```bash
bun run dev
# Opens at http://localhost:5173
```

### Production Build
```bash
bun run build
bun start
```

### Type Checking
```bash
bun run typecheck
```

## Common Tasks

### Adding a New Location
1. Add location data to `app/config/locations.ts`
2. Add location type to `LocationType` type
3. Location will automatically be available at `/locations/[location-name]`

### Adding a New Studio Type
1. Add studio data to `app/config/studios.ts`
2. Add type to `StudioType` type
3. Studio will be available at `/studios/[type]`

### Updating Navigation
Edit `app/components/AppHeader.tsx` to modify main navigation

### Changing Footer
Edit `app/components/AppFooter.tsx`

## Troubleshooting

### Common Issues

1. **Import errors**: Ensure using `~` alias for app directory imports
2. **Type errors**: Run `bun run typecheck` to identify issues
3. **Style not applying**: Check Tailwind classes are valid
4. **Route not found**: Verify file naming follows Remix conventions

## Best Practices

1. **Keep components pure**: Components should only render based on props
2. **Data in configs**: All mock data in `/app/config/` files
3. **Type safety**: Define interfaces for all data structures
4. **Consistent patterns**: Follow existing route and component patterns
5. **Responsive design**: Test on mobile and desktop viewports

## Resources

- [Remix Documentation](https://remix.run/docs)
- [Tailwind CSS](https://tailwindcss.com/docs)
- [TypeScript](https://www.typescriptlang.org/docs)
- [shadcn/ui](https://ui.shadcn.com)

## Contact

For questions about the codebase structure, refer to this documentation or examine the existing implemented patterns in the codebase. The architecture is designed to be self-documenting through consistent patterns.