Documentation Index
Fetch the complete documentation index at: https://mintlify.com/toryshchyn/cat-web/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The ApiTesting component provides a developer-focused interface for testing protected API endpoints in Cat Web. It demonstrates API integration, displays available containers, and allows testing of authenticated API calls with visual feedback.
Source: src/components/ApiTesting.tsx
Key Features
- Test protected API endpoints with authentication
- Load and display containers from the API
- Interactive UI with buttons and dropdowns
- Toast notifications for success and error states
- Integration with custom
useApiService hook
- Auth0 authentication awareness
Props
This component does not accept any props.
const ApiTesting: React.FC = () => { ... }
State Management
The component manages container data with React state:
const [containers, setContainers] = React.useState<{ id: number; name: string }[]>([]);
Container Type
Containers are typed with the following structure:
{
id: number;
name: string;
}
API Integration
The component uses the useApiService custom hook for API operations:
const apiService = useApiService();
Loading Containers
Containers are loaded automatically when the user is authenticated:
useEffect(() => {
if (isAuthenticated) {
console.log('Load containers');
apiService.getContainers().then((containers) => {
setContainers(containers);
});
}
}, [isAuthenticated, apiService]);
Testing Protected API
The component provides a button to test protected API endpoints:
const handleCallProtectedApi = async () => {
try {
const phoneNumbers = await apiService.getPhoneNumbers();
console.log('Phone numbers:', phoneNumbers);
toast.success('Phone numbers loaded.');
} catch (err) {
console.error('API call failed', err);
toast.error('Failed to load phone numbers.');
}
};
User Interface
The component renders a simple testing interface with two main sections:
<Button onClick={handleCallProtectedApi}>
Call Protected API
</Button>
Clicking this button:
- Calls the
getPhoneNumbers() API method
- Logs the response to the console
- Shows a success toast notification
- Shows an error toast if the call fails
Container Dropdown
When containers are loaded, a dropdown appears:
{containers.length > 0 && (
<Box sx={{ marginTop: 2 }}>
<FormControl fullWidth>
<InputLabel id="container-select-label">Container</InputLabel>
<Select
labelId="container-select-label"
id="container-select"
value={containers.length > 0 ? containers[0].id : ''}
label="Container"
onChange={(e) => console.log(e.target.value)}
>
{containers.map((container) => (
<MenuItem key={container.id} value={container.id}>
{container.name}
</MenuItem>
))}
</Select>
</FormControl>
</Box>
)}
Material-UI Components
The component uses several Material-UI components:
Box: Container for layout and spacing
Button: Triggers API testing
FormControl: Wrapper for form inputs
InputLabel: Label for the select dropdown
Select: Dropdown menu for containers
MenuItem: Individual dropdown options
Toast Notifications
The component uses react-toastify for user feedback:
import { toast } from 'react-toastify';
// Success notification
toast.success('Phone numbers loaded.');
// Error notification
toast.error('Failed to load phone numbers.');
Required Setup
Ensure you have configured the ToastContainer in your app:
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
function App() {
return (
<>
<YourApp />
<ToastContainer />
</>
);
}
Usage Examples
Basic Usage in Routes
import { Routes, Route } from 'react-router-dom';
import ApiTesting from './components/ApiTesting';
function App() {
return (
<Routes>
<Route path="/api-tests" element={<ApiTesting />} />
</Routes>
);
}
Protected Route with AuthGuard
import AuthGuard from './components/AuthGuard';
import MasterLayout from './components/MasterLayout';
import ApiTesting from './components/ApiTesting';
function App() {
return (
<Routes>
<Route path="/" element={
<AuthGuard component={<MasterLayout />} />
}>
<Route path="api-tests" element={<ApiTesting />} />
</Route>
</Routes>
);
}
Development Access
Add a navigation link in your layout:
<Link to="/api-tests">
<ListItemButton>
<ListItemIcon>
<ApiIcon />
</ListItemIcon>
<ListItemText primary="API tests" />
</ListItemButton>
</Link>
Complete Source Code
import React, { useEffect } from 'react';
import { Box, Button, FormControl, InputLabel, MenuItem, Select } from '@mui/material';
import { toast } from 'react-toastify';
import useApiService from '../hooks/useApiService';
import { useAuth0 } from '@auth0/auth0-react';
const ApiTesting: React.FC = () => {
const { isAuthenticated } = useAuth0();
const [containers, setContainers] = React.useState<{ id: number; name: string }[]>([]);
const apiService = useApiService();
useEffect(() => {
if (isAuthenticated) {
console.log('Load containers');
apiService.getContainers().then((containers) => {
setContainers(containers);
});
}
}, [isAuthenticated, apiService]);
const handleCallProtectedApi = async () => {
try {
const phoneNumbers = await apiService.getPhoneNumbers();
console.log('Phone numbers:', phoneNumbers);
toast.success('Phone numbers loaded.');
} catch (err) {
console.error('API call failed', err);
toast.error('Failed to load phone numbers.');
}
};
return (
<Box sx={{ padding: 2 }}>
<Button onClick={handleCallProtectedApi}>
Call Protected API
</Button>
{containers.length > 0 && (
<Box sx={{ marginTop: 2 }}>
<FormControl fullWidth>
<InputLabel id="container-select-label">Container</InputLabel>
<Select
labelId="container-select-label"
id="container-select"
value={containers.length > 0 ? containers[0].id : ''}
label="Container"
onChange={(e) => console.log(e.target.value)}
>
{containers.map((container) => (
<MenuItem key={container.id} value={container.id}>
{container.name}
</MenuItem>
))}
</Select>
</FormControl>
</Box>
)}
</Box>
);
};
export default ApiTesting;
API Service Hook
The component depends on the useApiService hook which should provide:
interface ApiService {
getContainers: () => Promise<Array<{ id: number; name: string }>>;
getPhoneNumbers: () => Promise<any>;
}
The hook handles:
- Authentication token management
- API endpoint configuration
- Request/response handling
- Error handling
Best Practices
- Developer Tool: This component is intended for development and testing purposes
- Authentication Required: Always use behind authentication (AuthGuard)
- Error Handling: Use try-catch blocks for all API calls
- User Feedback: Provide toast notifications for all user actions
- Console Logging: Keep console logs for debugging API responses
- Loading States: Consider adding loading indicators for async operations
Extending the Component
Adding More API Tests
const handleTestAnotherEndpoint = async () => {
try {
const result = await apiService.someOtherMethod();
console.log('Result:', result);
toast.success('API call successful');
} catch (err) {
console.error('API call failed', err);
toast.error('API call failed');
}
};
// Add button in JSX
<Button onClick={handleTestAnotherEndpoint}>
Test Another Endpoint
</Button>
Adding Loading State
const [loading, setLoading] = useState(false);
const handleCallProtectedApi = async () => {
setLoading(true);
try {
const phoneNumbers = await apiService.getPhoneNumbers();
toast.success('Phone numbers loaded.');
} catch (err) {
toast.error('Failed to load phone numbers.');
} finally {
setLoading(false);
}
};
<Button onClick={handleCallProtectedApi} disabled={loading}>
{loading ? 'Loading...' : 'Call Protected API'}
</Button>
useApiService - Custom hook for API operations
useAuth0 - Auth0 authentication hook