349 lines
8.3 KiB
Markdown
349 lines
8.3 KiB
Markdown
# Frontend Setup Complete - TanStack Router + Tailwind 4 ✅
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
cd frontend
|
|
npm run dev
|
|
```
|
|
|
|
Visit:
|
|
- Home: http://localhost:5173/
|
|
- Articles: http://localhost:5173/articles
|
|
|
|
## Architecture
|
|
|
|
### Tech Stack
|
|
- **React 19** - UI framework
|
|
- **TanStack Router** - File-based routing
|
|
- **TanStack Query** - Server state management
|
|
- **Tailwind CSS 4** - CSS-first (v4 no config file)
|
|
- **Shadcn/ui** - Pre-built components
|
|
- **TypeScript** - Type safety
|
|
|
|
### Project Structure
|
|
|
|
```
|
|
frontend/
|
|
├── src/
|
|
│ ├── components/
|
|
│ │ └── ui/ # shadcn/ui components
|
|
│ │ ├── button.tsx
|
|
│ │ └── card.tsx
|
|
│ ├── lib/
|
|
│ │ ├── api.ts # Backend API functions
|
|
│ │ ├── query-client.ts # TanStack Query config
|
|
│ │ └── utils.ts # cn() utility
|
|
│ ├── 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
|
|
├── components.json # shadcn/ui config
|
|
├── vite.config.ts # Vite + Tailwind CSS plugin
|
|
└── package.json
|
|
```
|
|
|
|
## Pages & Routes
|
|
|
|
### Home Page (`/`)
|
|
- Welcome message about Placebo.mk
|
|
- "Welcome" card with intro
|
|
- "Get Started" card with feature list
|
|
- Centered layout with max-width container
|
|
|
|
### Articles Page (`/articles`)
|
|
- Grid of article cards (responsive: 1/2/3 columns)
|
|
- Each card shows:
|
|
- Title (truncated to 2 lines)
|
|
- Excerpt (truncated to 3 lines)
|
|
- Content preview (truncated to 4 lines)
|
|
- Creation date
|
|
- View count
|
|
- Loading state
|
|
- Error state
|
|
- Empty state when no articles
|
|
|
|
### Root Layout
|
|
- Header with navigation (Home, Articles links)
|
|
- Main content area with `<Outlet />`
|
|
- Footer with copyright
|
|
- SEO meta tags
|
|
- Tailwind CSS import
|
|
|
|
## Components
|
|
|
|
### Card (`src/components/ui/card.tsx`)
|
|
- Card - Main container
|
|
- CardHeader - Header section
|
|
- CardTitle - Title (h3 element)
|
|
- CardDescription - Description (p element)
|
|
- CardContent - Content area
|
|
- CardFooter - Footer area
|
|
|
|
### Button (`src/components/ui/button.tsx`)
|
|
- Variants: default, destructive, outline, secondary, ghost, link
|
|
- Sizes: default, sm, lg, icon
|
|
- Uses shadcn/ui theming system
|
|
- Ready to use (not used yet)
|
|
|
|
## Utilities
|
|
|
|
### cn() Function (`src/lib/utils.ts`)
|
|
```tsx
|
|
import { cn } from '@/lib/utils'
|
|
|
|
// Merge Tailwind classes with conditional logic
|
|
<div className={cn(
|
|
'base-class',
|
|
isActive && 'active-class',
|
|
className
|
|
)}>
|
|
```
|
|
|
|
## Styling
|
|
|
|
### Tailwind CSS 4 (CSS-First)
|
|
Configuration in `src/styles.css`:
|
|
```css
|
|
@import "tailwindcss";
|
|
|
|
@theme {
|
|
--color-primary: oklch(0.647 0.22 0.23);
|
|
--font-sans: "Inter", sans-serif;
|
|
}
|
|
```
|
|
|
|
### Shadcn/ui Theme
|
|
CSS variables in `src/styles.css`:
|
|
- `--background` - Background color
|
|
- `--foreground` - Text color
|
|
- `--card` - Card background
|
|
- `--primary` - Primary brand color
|
|
- `--muted` - Muted text color
|
|
- Dark mode support with `.dark` class
|
|
|
|
## Data Flow
|
|
|
|
### API Layer (`src/lib/api.ts`)
|
|
- `fetchArticles()` - Get all articles with filters
|
|
- `fetchArticleById()` - Get single article by ID
|
|
- `fetchArticleBySlug()` - Get article by slug
|
|
|
|
### TanStack Query
|
|
- Automatic caching
|
|
- Refetch on window focus (disabled)
|
|
- Stale time: 5 minutes
|
|
- Retry: 1 attempt
|
|
- Query client shared across app
|
|
|
|
## Backend Integration
|
|
|
|
### API Configuration
|
|
```typescript
|
|
const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000/api/v1'
|
|
```
|
|
|
|
### Environment Variables
|
|
Create `frontend/.env`:
|
|
```bash
|
|
VITE_API_URL=http://localhost:3000/api/v1
|
|
```
|
|
|
|
## Adding New Pages
|
|
|
|
### Method 1: File-Based Routes (Current)
|
|
Create new route file in `src/routes/`:
|
|
|
|
```tsx
|
|
// src/routes/about.tsx
|
|
import { createFileRoute } from '@tanstack/react-router'
|
|
|
|
export const Route = createFileRoute('/about')({
|
|
component: () => <div>About Page</div>,
|
|
})
|
|
```
|
|
|
|
Add to `src/main.tsx`:
|
|
```tsx
|
|
import { aboutRoute } from './routes/about'
|
|
|
|
const routeTree = rootRoute.addChildren([indexRoute, articlesRoute, aboutRoute])
|
|
```
|
|
|
|
### Method 2: Using TanStack Router
|
|
Create routes dynamically in existing route files.
|
|
|
|
## Adding Shadcn/ui Components
|
|
|
|
### Using CLI (Recommended)
|
|
```bash
|
|
cd frontend
|
|
npx shadcn@latest add [component-name]
|
|
```
|
|
|
|
### Recommended Components
|
|
```bash
|
|
npx shadcn@latest add badge # Article tags
|
|
npx shadcn@latest add input # Search box
|
|
npx shadcn@latest add dialog # Article detail modal
|
|
npx shadcn@latest add tabs # Content organization
|
|
npx shadcn@latest add separator # Visual separation
|
|
npx shadcn@latest add skeleton # Loading placeholder
|
|
npx shadcn@latest add pagination # Article list navigation
|
|
npx shadcn@latest add dropdown-menu # Menus and filters
|
|
npx shadcn@latest add select # Dropdown selectors
|
|
```
|
|
|
|
## Customization
|
|
|
|
### Changing Brand Colors
|
|
Edit `src/styles.css`:
|
|
|
|
```css
|
|
@theme {
|
|
--color-primary: oklch(0.7 0.5 0.2); /* Your brand color */
|
|
--font-sans: "Your Font", sans-serif;
|
|
}
|
|
```
|
|
|
|
### Dark Mode
|
|
Add toggle button to header:
|
|
|
|
```tsx
|
|
// src/routes/root.tsx
|
|
const toggleDarkMode = () => {
|
|
document.documentElement.classList.toggle('dark')
|
|
localStorage.setItem('theme',
|
|
document.documentElement.classList.contains('dark') ? 'dark' : 'light'
|
|
)
|
|
}
|
|
|
|
// In component
|
|
<button onClick={toggleDarkMode}>Toggle Theme</button>
|
|
```
|
|
|
|
### Typography
|
|
Edit `src/styles.css`:
|
|
|
|
```css
|
|
@theme {
|
|
--font-sans: "Your Custom Font", sans-serif;
|
|
}
|
|
|
|
@layer base {
|
|
* {
|
|
@apply font-sans;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Routes Not Loading
|
|
1. Check route files exist in `src/routes/`
|
|
2. Check exports: `export const Route = createFileRoute(...)`
|
|
3. Check route tree in `src/main.tsx`
|
|
4. Restart dev server
|
|
|
|
### Styles Not Applying
|
|
1. Check `src/styles.css` has Tailwind directives
|
|
2. Check `vite.config.ts` has `tailwindcss()` plugin
|
|
3. Restart dev server
|
|
4. Hard refresh browser (Ctrl+Shift+R)
|
|
|
|
### Component Imports Failing
|
|
1. Check `tsconfig.json` has `@/` paths
|
|
2. Check import paths are correct: `@/components/ui/component`
|
|
3. Restart TypeScript server (VSCode: Cmd+Shift+P)
|
|
|
|
### Data Not Fetching
|
|
1. Check backend is running: `http://localhost:3000`
|
|
2. Check `.env` file exists and has correct API URL
|
|
3. Check browser network tab for failed requests
|
|
4. Check CORS in backend (`backend/src/main.ts`)
|
|
|
|
### TypeScript Errors
|
|
1. Run: `npm run type-check`
|
|
2. Restart TypeScript server (VSCode)
|
|
3. Clear Vite cache: `rm -rf node_modules/.vite`
|
|
|
|
## Performance Tips
|
|
|
|
1. **Code Splitting**: Use lazy() for large components
|
|
2. **Image Optimization**: Add loading="lazy" to article images
|
|
3. **Query Caching**: TanStack Query caches automatically
|
|
4. **Bundle Size**: Run `npm run build` and check size
|
|
|
|
## Development Workflow
|
|
|
|
### Adding New Article
|
|
1. Create article in Strapi CMS: http://localhost:1337/admin
|
|
2. Publish article
|
|
3. Sync to backend: `curl -X POST http://localhost:3000/api/v1/webhooks/strapi/sync/all`
|
|
4. Refresh frontend to see new article
|
|
|
|
### Running All Services
|
|
```bash
|
|
# Terminal 1 - Backend
|
|
cd backend
|
|
npm run start:dev
|
|
|
|
# Terminal 2 - Frontend
|
|
cd frontend
|
|
npm run dev
|
|
|
|
# Terminal 3 - Strapi CMS (optional)
|
|
cd cms/cms
|
|
npm run develop
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Manual Testing
|
|
```bash
|
|
# Test API
|
|
curl http://localhost:3000/api/v1/articles
|
|
|
|
# Test frontend
|
|
npm run dev
|
|
# Open http://localhost:5173
|
|
```
|
|
|
|
### Type Checking
|
|
```bash
|
|
cd frontend
|
|
npm run type-check
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
1. Add article detail page with `$id` parameter
|
|
2. Add search input for filtering articles
|
|
3. Add category/tag filtering
|
|
4. Add pagination for article lists
|
|
5. Add dark mode toggle
|
|
6. Add "about" page with site information
|
|
7. Add "contact" page or form
|
|
8. Add article comments system
|
|
9. Add social sharing buttons
|
|
10. Add analytics for article views
|
|
|
|
## Files to Edit
|
|
|
|
| File | Purpose |
|
|
|-------|---------|
|
|
| `src/styles.css` | Theme colors, fonts, CSS variables |
|
|
| `vite.config.ts` | Vite plugins, path aliases |
|
|
| `components.json` | shadcn/ui configuration |
|
|
| `tsconfig.json` | TypeScript paths |
|
|
| `.env` | Environment variables |
|
|
|
|
## Resources
|
|
|
|
- [TanStack Router Docs](https://tanstack.com/router/latest)
|
|
- [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)
|