Files
przekroj/ADDING_NEW_TOOLS_GUIDE.md

466 lines
13 KiB
Markdown

# Adding New Tools and Functionality Guide
This document provides a comprehensive guide for adding new tools and functionality to the Wastpol web application. It's designed to help developers (including AI agents) integrate new tools from separate projects into the main application.
## Project Overview
The Wastpol application is a Next.js-based web application with the following key characteristics:
- **Framework**: Next.js 12 with React 17
- **Styling**: Tailwind CSS with custom UI components
- **Authentication**: NextAuth.js
- **Architecture**: Pages-based routing with component-driven design
- **UI Library**: Custom components + Evergreen UI + Heroicons
## Project Structure
```
web-app/
├── pages/ # Next.js pages (routes)
│ ├── api/ # API endpoints
│ ├── index.js # Main dashboard with tabs
│ ├── cross.js # Grid tool
│ ├── uziomy.js # Ground connections tool
│ ├── tracking.js # Package tracking
│ └── [other-tools].js # Additional tools
├── components/
│ ├── ui/ # Reusable UI components
│ │ ├── Layout.js # Main layout with navigation
│ │ └── components.js # UI component library
│ └── templates/ # Tool-specific components
├── styles/ # Global styles
├── public/ # Static assets
└── externals/ # External data files
```
## Adding a New Tool - Step by Step
### 1. Planning Phase
Before adding a new tool, define:
- **Tool Purpose**: What does the tool do?
- **Tool Name**: Short, descriptive name
- **Route**: URL path (e.g., `/new-tool`)
- **Icon**: Choose from Heroicons
- **Dependencies**: Any new packages needed
- **API Requirements**: Backend processing needs
### 2. Tool Integration Checklist
#### A. Create the Main Page Component
Create a new file: `pages/[tool-name].js`
**Template Structure:**
```javascript
import { useState, useCallback } from "react";
import { useSession, signIn } from "next-auth/react";
import Layout from "../components/ui/Layout";
import { Card, CardHeader, CardContent, CardTitle, CardDescription, Button, Alert } from "../components/ui/components";
import { [ToolIcon] } from '@heroicons/react/24/outline';
export default function NewTool() {
const { data: session } = useSession();
const [isLoading, setIsLoading] = useState(false);
// Tool-specific state variables
const [toolData, setToolData] = useState(null);
// Authentication check
if (!session) {
return (
<Layout title="Wastpol - New Tool">
<div className="flex items-center justify-center min-h-screen">
<Card className="w-full max-w-md">
<CardContent className="text-center p-6">
<h2 className="text-xl font-semibold mb-4">Wymagane logowanie</h2>
<Button onClick={() => signIn()}>
Zaloguj się
</Button>
</CardContent>
</Card>
</div>
</Layout>
);
}
return (
<Layout title="Wastpol - New Tool">
<div className="p-6 max-w-7xl mx-auto">
{/* Page Header */}
<div className="mb-8">
<h1 className="text-3xl font-bold text-gray-900 mb-2">
New Tool Name
</h1>
<p className="text-gray-600">
Tool description here
</p>
</div>
{/* Main Content */}
<Card>
<CardHeader>
<CardTitle className="flex items-center">
<[ToolIcon] className="w-6 h-6 mr-2" />
Tool Interface
</CardTitle>
<CardDescription>
Brief description of what this tool does
</CardDescription>
</CardHeader>
<CardContent>
{/* Tool-specific UI goes here */}
</CardContent>
</Card>
</div>
</Layout>
);
}
```
#### B. Add Navigation Entry
Update `components/ui/Layout.js`:
1. **Import the icon:**
```javascript
import {
// ...existing imports
[NewToolIcon]
} from '@heroicons/react/24/outline';
```
2. **Add to navigationItems array:**
```javascript
const navigationItems = [
// ...existing items
{ name: 'New Tool Name', href: '/new-tool', icon: NewToolIcon },
];
```
#### C. Create API Endpoint (if needed)
Create `pages/api/[tool-name].js`:
```javascript
import formidable from 'formidable';
import { getSession } from 'next-auth/react';
export const config = {
api: {
bodyParser: false,
},
};
export default async function handler(req, res) {
// Authentication check
const session = await getSession({ req });
if (!session) {
return res.status(401).json({ error: 'Unauthorized' });
}
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
// Tool-specific processing logic
const form = new formidable.IncomingForm();
const [fields, files] = await form.parse(req);
// Process the request
const result = await processToolData(fields, files);
res.status(200).json({
success: true,
data: result
});
} catch (error) {
console.error('Tool processing error:', error);
res.status(500).json({
error: 'Internal server error',
details: error.message
});
}
}
async function processToolData(fields, files) {
// Implement tool-specific logic here
return {};
}
```
#### D. Add Tool-Specific Components (Optional)
Create reusable components in `components/templates/[tool-name]/`:
```javascript
// components/templates/new-tool/ToolComponent.js
import { useState } from 'react';
import { Button, Alert } from '../../ui/components';
export default function ToolComponent({ onSubmit, isLoading }) {
const [inputData, setInputData] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(inputData);
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
{/* Tool-specific form elements */}
<Button
type="submit"
disabled={isLoading}
className="w-full"
>
{isLoading ? 'Processing...' : 'Submit'}
</Button>
</form>
);
}
```
### 3. Integration from Separate Project
#### A. Identify Components to Port
When integrating from a separate project:
1. **Identify core functionality files**
2. **Extract reusable components**
3. **Map dependencies and APIs**
4. **Identify data processing logic**
#### B. Dependency Management
1. **Check existing dependencies** in `package.json`
2. **Add new dependencies** if needed:
```bash
npm install [new-package]
```
3. **Update package.json** if manual editing is needed
#### C. Asset Management
1. **Static files**: Place in `public/` directory
2. **External data**: Place in `externals/` directory
3. **Uploads**: Use `public/uploads/` for user uploads
### 4. Common Integration Patterns
#### File Upload Pattern
```javascript
import { FileUploader, FileCard } from "evergreen-ui";
const [files, setFiles] = useState([]);
const handleChange = useCallback((files) => setFiles([files[0]]), []);
```
#### API Call Pattern
```javascript
import axios from "axios";
const handleSubmit = async (data) => {
setIsLoading(true);
try {
const formData = new FormData();
formData.append("data", JSON.stringify(data));
const response = await axios.post("/api/new-tool", formData);
setResult(response.data);
} catch (error) {
setError(error.message);
} finally {
setIsLoading(false);
}
};
```
#### State Management Pattern
```javascript
const [isLoading, setIsLoading] = useState(false);
const [result, setResult] = useState(null);
const [error, setError] = useState(null);
```
### 5. Styling Guidelines
#### Use Existing UI Components
```javascript
import {
Card,
CardHeader,
CardContent,
CardTitle,
CardDescription,
Button,
Alert
} from "../components/ui/components";
```
#### Consistent Layout Classes
- **Container**: `p-6 max-w-7xl mx-auto`
- **Page Header**: `mb-8`
- **Title**: `text-3xl font-bold text-gray-900 mb-2`
- **Description**: `text-gray-600`
- **Cards**: Use existing Card components
- **Spacing**: `space-y-4` for form elements
### 6. Error Handling Best Practices
#### Client-Side Error Handling
```javascript
const [error, setError] = useState(null);
// Clear error on new action
const clearError = () => setError(null);
// Display errors
{error && (
<Alert variant="destructive" className="mb-4">
{error}
</Alert>
)}
```
#### Server-Side Error Handling
```javascript
try {
// Process request
} catch (error) {
console.error('Tool error:', error);
return res.status(500).json({
error: 'Processing failed',
details: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
```
### 7. Testing Integration
#### Manual Testing Checklist
- [ ] Tool loads without errors
- [ ] Authentication works correctly
- [ ] Navigation item appears and works
- [ ] File uploads work (if applicable)
- [ ] API endpoints respond correctly
- [ ] Results display properly
- [ ] Error handling works
- [ ] Mobile responsiveness
- [ ] Loading states display correctly
#### Console Testing
1. Check browser console for errors
2. Verify API responses in Network tab
3. Test with different user roles
### 8. AI Agent Instructions
When an AI agent is adding a new tool:
#### Information to Gather
1. **Tool description and purpose**
2. **Required input/output formats**
3. **Processing logic requirements**
4. **UI/UX preferences**
5. **Integration points with existing system**
#### Step-by-Step Process
1. **Analyze the existing project structure**
2. **Identify the closest existing tool for reference**
3. **Create the main page component**
4. **Add navigation entry**
5. **Create API endpoint if needed**
6. **Test the integration**
7. **Handle any errors or conflicts**
#### Code Quality Standards
- Follow existing naming conventions
- Use consistent styling patterns
- Implement proper error handling
- Add loading states for async operations
- Ensure responsive design
- Maintain authentication requirements
### 9. Example Tool Addition
Here's how to add a hypothetical "Document Generator" tool:
#### Step 1: Create `pages/document-generator.js`
```javascript
import { useState } from "react";
import { useSession, signIn } from "next-auth/react";
import Layout from "../components/ui/Layout";
import { Card, CardHeader, CardContent, CardTitle } from "../components/ui/components";
import { DocumentTextIcon } from '@heroicons/react/24/outline';
export default function DocumentGenerator() {
const { data: session } = useSession();
// Component implementation...
}
```
#### Step 2: Update `components/ui/Layout.js`
```javascript
import { DocumentTextIcon } from '@heroicons/react/24/outline';
const navigationItems = [
// ...existing items
{ name: 'Generator dokumentów', href: '/document-generator', icon: DocumentTextIcon },
];
```
#### Step 3: Create `pages/api/document-generator.js`
```javascript
export default async function handler(req, res) {
// API implementation...
}
```
### 10. Maintenance and Updates
#### Version Control
- Commit changes with descriptive messages
- Tag releases for major tool additions
- Document breaking changes
#### Documentation Updates
- Update this guide when patterns change
- Document new dependencies
- Keep API documentation current
#### Performance Considerations
- Monitor bundle size with new dependencies
- Optimize images and assets
- Consider lazy loading for heavy components
---
## Quick Reference Commands
```bash
# Install new dependency
npm install [package-name]
# Run development server
npm run dev
# Build for production
npm run build
# Deploy changes
npm run deploy
```
## Common File Locations
- **New page**: `pages/[tool-name].js`
- **API endpoint**: `pages/api/[tool-name].js`
- **Components**: `components/templates/[tool-name]/`
- **Navigation**: `components/ui/Layout.js`
- **Styles**: `styles/globals.css`
- **Assets**: `public/`
This guide should provide everything needed to successfully integrate new tools into the Wastpol application while maintaining consistency and code quality.