# TanStack Router + Tailwind 4 Setup Complete ✅

## What's Been Configured

### 1. TanStack Router with File-Based Routing
- **Routes directory**: `frontend/src/routes/`
- **Root route**: `root.tsx` - Layout with header, footer, and outlet
- **Home route**: `index.tsx` - Welcome page with getting started cards
- **Articles route**: `articles.tsx` - Article list with card grid
- **Router configuration**: Uses `createRouter` with route tree

### 2. Tailwind CSS 4 (CSS-First)
- **Configuration**: In `src/styles.css` using `@import` and `@theme` directives
- **Vite integration**: `tailwindcss()` plugin in `vite.config.ts`
- **No config file needed**: Tailwind 4 CSS-first doesn't use `tailwind.config.js`
- **Shadcn/ui compatible**: CSS variables for theming

### 3. Routing Structure
```
frontend/src/routes/
├── root.tsx       # Main layout (header, footer, <Outlet />)
├── index.tsx      # Home page (/)
└── articles.tsx    # Articles list (/articles)
```

### 4. Page Templates

#### Root Layout (`root.tsx`)
- Header with navigation (Home, Articles)
- Main content area with `<Outlet />`
- Footer with copyright
- Meta tags for SEO
- CSS import for Tailwind

#### Home Page (`index.tsx`)
- Welcome cards with:
  - "Welcome" - Introduction
  - "Get Started" - Feature list
- Centered layout with max-width container

#### Articles Page (`articles.tsx`)
- Grid of article cards (responsive: 1/2/3 columns)
- Loading state
- Error state
- Empty state (no articles)
- Each card shows:
  - Featured image (if available)
  - Title (truncated to 2 lines)
  - Excerpt (truncated to 3 lines)
  - Content preview (truncated to 4 lines)
  - Date and view count

## How It Works

### 1. Route Configuration
```tsx
// src/routes/root.tsx
import { createRootRoute, Link, Outlet } from '@tanstack/react-router'

export const rootRoute = createRootRoute({
  head: () => ({
    meta: [
      {
        title: 'Placebo.mk - Sarcastic News from Macedonia',
        description: 'Latest news and articles from Macedonia with a sarcastic twist',
      },
    ],
    links: [{ rel: 'stylesheet', href: '../../styles.css' }],
  }),
  component: () => (
    <div>
      <header>...</header>
      <main><Outlet /></main>
      <footer>...</footer>
    </div>
  ),
})
```

### 2. Route Tree
```tsx
// src/main.tsx
import { createRouter } from '@tanstack/react-router'
import { rootRoute } from './routes/root'
import { indexRoute } from './routes/index'
import { articlesRoute } from './routes/articles'

const routeTree = rootRoute.addChildren([indexRoute, articlesRoute])
const router = createRouter({ routeTree, context: { queryClient } })
```

### 3. File-Based Routes
```tsx
// src/routes/index.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/')({
  component: () => <div>Home</div>,
})
```

```tsx
// src/routes/articles.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/articles')({
  component: () => <div>Articles</div>,
})
```

### 4. Tailwind 4 CSS-First Setup

#### In `src/styles.css`:
```css
@import "tailwindcss";

@theme {
  --color-primary: oklch(0.647 0.22 0.23);
  --font-sans: "Inter", sans-serif;
}
```

#### In `vite.config.ts`:
```ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from 'tailwindcss'
import path from 'path'

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
})
```

## Running the App

```bash
cd frontend
npm run dev
```

Visit:
- Home: http://localhost:5173/
- Articles: http://localhost:5173/articles

## Adding New Routes

### Method 1: File-Based Routes (Recommended)
Create a new file in `src/routes/`:

```tsx
// src/routes/article-detail.tsx
import { createFileRoute } from '@tanstack/react-router'
import { useQuery } from '@tanstack/react-query'
import * as api from '../lib/api'

export const Route = createFileRoute('/articles/$id')({
  component: () => {
    const { id } = Route.useParams()
    const { data } = useQuery({
      queryKey: ['article', id],
      queryFn: () => api.fetchArticleById(id),
    })

    return (
      <div>
        <h1>{data?.title}</h1>
        <div dangerouslySetInnerHTML={{ __html: data?.content || '' }} />
      </div>
    )
  },
})
```

Then add to `src/main.tsx`:
```tsx
import { articleDetailRoute } from './routes/article-detail'

const routeTree = rootRoute.addChildren([indexRoute, articlesRoute, articleDetailRoute])
```

### Method 2: Using Link for Navigation
```tsx
import { Link } from '@tanstack/react-router'

// In your component
<Link to="/article/123">Read Article</Link>
```

## Adding Shadcn/ui Components

### Using the CLI (Recommended)
```bash
cd frontend
npx shadcn@latest add [component-name]
```

### Common Components to Add
```bash
npx shadcn@latest add button      # (already installed)
npx shadcn@latest add badge       # For article tags
npx shadcn@latest add input       # For search
npx shadcn@latest add dialog      # For article details
npx shadcn@latest add dropdown-menu
npx shadcn@latest add select
npx shadcn@latest add tabs        # For content organization
npx shadcn@latest add separator   # For visual separation
npx shadcn@latest add skeleton    # For loading states
npx shadcn@latest add pagination  # For article list navigation
```

### Using Components in Routes
```tsx
import { Button } from '@/components/ui/button'

export const Route = createFileRoute('/articles')({
  component: () => (
    <div>
      <Button variant="default">Click me</Button>
    </div>
  ),
})
```

## Customization

### Theme Colors

Edit `src/styles.css`:

```css
@theme {
  --color-primary: oklch(0.647 0.22 0.23);
  --color-secondary: oklch(0.8 0.15 0.1);
  --font-sans: "Your Font", sans-serif;
}
```

### Adding Fonts

Edit `src/styles.css`:

```css
@theme {
  --font-sans: "Inter", sans-serif;
}

@layer base {
  * {
    @apply font-sans;
  }
}
```

### Dark Mode

Add dark mode toggle to header:

```tsx
import { useEffect } from 'react'

export const rootRoute = createRootRoute({
  component: () => {
    const toggleDarkMode = () => {
      document.documentElement.classList.toggle('dark')
      localStorage.setItem('theme',
        document.documentElement.classList.contains('dark') ? 'dark' : 'light'
      )
    }

    return (
      <div>
        <header>
          <button onClick={toggleDarkMode}>
            Toggle Theme
          </button>
        </header>
        <main><Outlet /></main>
      </div>
    )
  },
})
```

## File Structure

```
frontend/
├── src/
│   ├── components/
│   │   └── ui/              # shadcn/ui components
│   ├── lib/
│   │   ├── api.ts            # Backend API functions
│   │   ├── query-client.ts    # TanStack Query configuration
│   │   └── utils.ts         # cn() utility (for shadcn/ui)
│   ├── routes/              # TanStack Router routes
│   │   ├── root.tsx         # Root layout
│   │   ├── index.tsx         # Home page
│   │   └── articles.tsx      # Articles list
│   ├── styles.css            # Tailwind CSS + theme
│   └── main.tsx             # App entry point
├── components.json            # shadcn/ui configuration
├── vite.config.ts            # Vite + Tailwind CSS plugin
├── tailwind.config.js         # (Not used - CSS-first approach)
└── package.json
```

## Troubleshooting

### Routes Not Working

1. Check that route files are in `src/routes/`
2. Check export: `export const Route = createFileRoute(...)`
3. Check imports in `src/main.tsx`
4. Restart dev server

### Styles Not Applying

1. Check `src/styles.css` has `@import "tailwindcss"`
2. Check `vite.config.ts` has `tailwindcss()` plugin
3. Restart dev server
4. Hard refresh browser (Ctrl+Shift+R)

### Component Imports Not Working

1. Check `tsconfig.json` has `@/` paths configured
2. Check `vite.config.ts` has resolve alias for `@/`
3. Restart TypeScript server (VSCode: Cmd+Shift+P → "TypeScript: Restart TS Server")

### TanStack Query Not Fetching

1. Check backend is running: `http://localhost:3000`
2. Check `.env` has correct API URL
3. Check browser network tab for failed requests
4. Check CORS configuration in backend

## Best Practices

### 1. Route Organization
- Keep routes in `src/routes/` directory
- Use file-based routing for simple pages
- Use nested routes for related content

### 2. Component Reusability
- Create reusable components in `src/components/`
- Use shadcn/ui for consistent styling
- Extract common patterns (loading states, error states)

### 3. Data Fetching
- Use TanStack Query for all server state
- Implement proper loading and error states
- Use query keys consistently

### 4. Performance
- Use `lazy()` for code splitting large components
- Implement image lazy loading
- Use `defer` for non-critical resources

### 5. SEO
- Add meta tags to root route
- Add Open Graph tags
- Implement structured data

## Next Steps

1. **Restart dev server** to load new configuration
2. **Visit home page**: http://localhost:5173/
3. **Visit articles page**: http://localhost:5173/articles
4. **Add article detail page** with `$id` parameter
5. **Add shadcn/ui components** as needed
6. **Add dark mode toggle**
7. **Add search functionality**
8. **Add category/tag filtering**

## Resources

- [TanStack Router Docs](https://tanstack.com/router/latest/docs/framework/react/start/file-based-routing)
- [Tailwind CSS 4 Docs](https://tailwindcss.com/docs/installation/using-postcss)
- [Shadcn/ui Documentation](https://ui.shadcn.com)
- [TanStack Query Docs](https://tanstack.com/query/latest)
