Diagramers Admin Template - React starter for admin dashboards.
A comprehensive React-based admin dashboard template with modern UI/UX, extensive customization options, and full integration with the Diagramers ecosystem. Built with React 18, TypeScript, and a modular architecture for rapid development of professional admin interfaces.
bash
Install CLI globally
npm install -g @diagramers/cliCreate new admin project
diagramers init admin my-admin-dashboardNavigate to project
cd my-admin-dashboardInstall dependencies
npm install --legacy-peer-depsStart development server
npm start
`$3
`bash
Install package
npm install @diagramers/adminInitialize project
npx diagramers-admin-init my-admin-dashboardNavigate to project
cd my-admin-dashboardInstall dependencies
npm install --legacy-peer-depsStart development server
npm start
`π οΈ Quick Start
$3
`bash
Create new admin project
diagramers init admin my-admin-dashboardNavigate to project
cd my-admin-dashboardConfigure environment variables
cp .env.example .env
Edit .env with your API URL and configuration
Install dependencies
npm install --legacy-peer-depsStart development server
npm start
`$3
`bash
Update API configuration in src/config.js
export const SERVICE_URL = 'http://localhost:3000';
export const REACT_HELMET_PROPS = {
defaultTitle: 'My Admin Dashboard',
titleTemplate: '%s | My Admin Dashboard',
};
`$3
`bash
Replace logo in public/img/logo/
Update favicon in public/img/favicon/
Customize theme in src/sass/themes/
Modify navigation in src/layout/nav/
`$3
`bash
Start development server
npm startBuild for production
npm run buildRun tests
npm testLint code
npm run lint
`π§ Configuration
$3
`bash
API Configuration
REACT_APP_API_URL=http://localhost:3000
REACT_APP_PROJECT_NAME=My Admin DashboardAuthentication
REACT_APP_JWT_SECRET=your-jwt-secret
REACT_APP_AUTH_PROVIDER=internalFeatures
REACT_APP_ENABLE_ANALYTICS=true
REACT_APP_ENABLE_NOTIFICATIONS=true
REACT_APP_ENABLE_REAL_TIME=trueExternal Services
REACT_APP_SOCKET_URL=ws://localhost:3000
REACT_APP_SENTRY_DSN=your-sentry-dsn
`$3
`javascript
// src/config.js
export const SERVICE_URL = process.env.REACT_APP_API_URL || 'http://localhost:3000';
export const REACT_HELMET_PROPS = {
defaultTitle: process.env.REACT_APP_PROJECT_NAME || 'Admin Dashboard',
titleTemplate: %s | ${process.env.REACT_APP_PROJECT_NAME || 'Admin Dashboard'},
};
`$3
`scss
// src/sass/themes/_custom.scss
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--success-color: #28a745;
--danger-color: #dc3545;
--warning-color: #ffc107;
--info-color: #17a2b8;
--light-color: #f8f9fa;
--dark-color: #343a40;
}
`π Component Library
$3
`jsx
import { Layout, Sidebar, Header, Footer } from '@diagramers/admin';// Main layout
{children}
`$3
`jsx
import { DataTable, DataGrid, DataChart } from '@diagramers/admin';// Data table with sorting and filtering
data={products}
columns={productColumns}
sortable
filterable
pagination
/>
// Interactive chart
type="line"
data={chartData}
options={chartOptions}
/>
`$3
`jsx
import { Form, Input, Select, Button } from '@diagramers/admin';// Dynamic form
`$3
`jsx
import { Navigation, Menu, Breadcrumb } from '@diagramers/admin';// Sidebar navigation
// Breadcrumb navigation
`π Authentication
$3
`jsx
import { LoginForm } from '@diagramers/admin'; onLogin={handleLogin}
providers={['internal', 'google', 'github']}
rememberMe
forgotPassword
/>
`$3
`jsx
import { ProtectedRoute, useAuth } from '@diagramers/admin';// Protected route component
path="/dashboard"
component={Dashboard}
roles={['admin', 'user']}
permissions={['read:dashboard']}
/>
// Use auth hook
const { user, isAuthenticated, login, logout } = useAuth();
`$3
`jsx
import { usePermissions } from '@diagramers/admin';const { hasPermission, hasRole } = usePermissions();
// Check permissions
{hasPermission('create:users') && (
)}
// Check roles
{hasRole('admin') && (
)}
`π Dashboard Features
$3
`jsx
import { AnalyticsDashboard } from '@diagramers/admin'; metrics={[
{ title: 'Total Users', value: 1250, change: '+12%' },
{ title: 'Revenue', value: '$45,230', change: '+8%' },
{ title: 'Orders', value: 89, change: '+5%' },
]}
charts={[
{ type: 'line', data: revenueData, title: 'Revenue Trend' },
{ type: 'bar', data: userData, title: 'User Growth' },
]}
/>
`$3
`jsx
import { DataManager } from '@diagramers/admin'; endpoint="/api/users"
columns={userColumns}
actions={['create', 'edit', 'delete', 'export']}
filters={['search', 'role', 'status']}
bulkActions={['activate', 'deactivate', 'delete']}
/>
`$3
`jsx
import { useWebSocket } from '@diagramers/admin';const { data, isConnected } = useWebSocket('/api/notifications');
// Real-time notifications
{data.map(notification => (
))}
`π¨ Customization
$3
`scss
// src/sass/themes/_custom.scss
:root {
// Primary colors
--primary-color: #007bff;
--primary-hover: #0056b3;
--primary-light: #e3f2fd;
// Secondary colors
--secondary-color: #6c757d;
--secondary-hover: #545b62;
// Success colors
--success-color: #28a745;
--success-hover: #1e7e34;
// Danger colors
--danger-color: #dc3545;
--danger-hover: #c82333;
// Typography
--font-family: 'Inter', sans-serif;
--font-size-base: 1rem;
--line-height-base: 1.5;
// Spacing
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 3rem;
}
`$3
`scss
// src/sass/components/_custom.scss
.custom-button {
background: var(--primary-color);
border: none;
border-radius: 8px;
padding: 12px 24px;
font-weight: 600;
transition: all 0.2s ease;
&:hover {
background: var(--primary-hover);
transform: translateY(-1px);
}
}.custom-card {
background: white;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
padding: 24px;
margin-bottom: 24px;
}
`$3
`jsx
// src/layout/Layout.js
import { Layout, Sidebar, Header } from '@diagramers/admin';const CustomLayout = ({ children }) => (
className="custom-sidebar"
logo="/img/logo/custom-logo.svg"
menuItems={customMenuItems}
/>
className="custom-header"
userMenu={customUserMenu}
notifications={customNotifications}
/>
{children}
);
`π API Integration
$3
`javascript
// src/services/api.js
import { ApiService } from '@diagramers/admin';const api = new ApiService({
baseURL: process.env.REACT_APP_API_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
// Add request interceptor for authentication
api.interceptors.request.use((config) => {
const token = localStorage.getItem('auth_token');
if (token) {
config.headers.Authorization =
Bearer ${token};
}
return config;
});// Add response interceptor for error handling
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Handle unauthorized access
window.location.href = '/login';
}
return Promise.reject(error);
}
);
export default api;
`$3
`jsx
import { useApi } from '@diagramers/admin';const { data, loading, error, refetch } = useApi('/api/users');
// With parameters
const { data: users } = useApi('/api/users', {
params: { page: 1, limit: 10, search: 'john' }
});
// With mutations
const { mutate, isLoading } = useApi('/api/users', {
method: 'POST',
onSuccess: () => {
// Handle success
},
onError: (error) => {
// Handle error
},
});
`$3
`jsx
import { useWebSocket } from '@diagramers/admin';const { data, isConnected, send } = useWebSocket('/api/notifications', {
onMessage: (message) => {
// Handle incoming messages
console.log('Received:', message);
},
onConnect: () => {
console.log('Connected to WebSocket');
},
onDisconnect: () => {
console.log('Disconnected from WebSocket');
},
});
// Send message
send({ type: 'notification', data: { message: 'Hello!' } });
`π± Responsive Design
$3
`scss
// src/sass/layout/_responsive.scss
.container {
width: 100%;
padding: 0 16px;
margin: 0 auto;
@media (min-width: 576px) {
max-width: 540px;
}
@media (min-width: 768px) {
max-width: 720px;
}
@media (min-width: 992px) {
max-width: 960px;
}
@media (min-width: 1200px) {
max-width: 1140px;
}
}.sidebar {
@media (max-width: 768px) {
transform: translateX(-100%);
position: fixed;
z-index: 1000;
&.open {
transform: translateX(0);
}
}
}
`$3
`jsx
import { TouchableButton, SwipeableCard } from '@diagramers/admin';// Touch-friendly button
size="large"
onPress={handlePress}
feedback="haptic"
>
Press Me
// Swipeable card
onSwipeLeft={() => handleDelete()}
onSwipeRight={() => handleEdit()}
>
`π§ͺ Testing
$3
`jsx
import { render, screen, fireEvent } from '@testing-library/react';
import { LoginForm } from '@diagramers/admin';test('login form submits with correct data', () => {
const mockOnLogin = jest.fn();
render( );
fireEvent.change(screen.getByLabelText('Email'), {
target: { value: 'test@example.com' },
});
fireEvent.change(screen.getByLabelText('Password'), {
target: { value: 'password123' },
});
fireEvent.click(screen.getByRole('button', { name: /login/i }));
expect(mockOnLogin).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123',
});
});
`$3
`jsx
import { render, screen, waitFor } from '@testing-library/react';
import { DataTable } from '@diagramers/admin';test('data table loads and displays data', async () => {
const mockData = [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' },
];
render( );
await waitFor(() => {
expect(screen.getByText('John Doe')).toBeInTheDocument();
expect(screen.getByText('Jane Smith')).toBeInTheDocument();
});
});
`π Deployment
$3
`javascript
// webpack.config.js
module.exports = {
mode: 'production',
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].chunk.js',
},
};
`$3
`bash
Development build
npm run build:devStaging build
npm run build:stagingProduction build
npm run build:prodAnalyze bundle
npm run build:analyze
`$3
`dockerfile
Dockerfile
FROM node:18-alpine as builderWORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build:prod
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
`π Performance Optimization
$3
`jsx
import { lazy, Suspense } from 'react';// Lazy load components
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Users = lazy(() => import('./pages/Users'));
const Settings = lazy(() => import('./pages/Settings'));
// Suspense wrapper
}>
`$3
`jsx
import { useMemo, useCallback } from 'react';// Memoize expensive calculations
const expensiveValue = useMemo(() => {
return data.reduce((sum, item) => sum + item.value, 0);
}, [data]);
// Memoize callbacks
const handleClick = useCallback((id) => {
// Handle click
}, []);
`$3
`jsx
import { OptimizedImage } from '@diagramers/admin'; src="/img/avatar.jpg"
alt="User Avatar"
width={100}
height={100}
lazy
placeholder="/img/avatar-placeholder.jpg"
/>
`π Security
$3
`javascript
// public/index.html
`$3
`jsx
import { useForm } from '@diagramers/admin';const { register, handleSubmit, errors } = useForm();
`$3
`jsx
import { sanitizeHtml } from '@diagramers/admin';// Sanitize user input
const sanitizedContent = sanitizeHtml(userInput);
// Safe rendering
`π Documentation
$3
`jsx
/**
* @component DataTable
* @description A responsive data table with sorting, filtering, and pagination
* @example
* `jsx
* * data={users}
* columns={userColumns}
* sortable
* filterable
* pagination
* />
* `
*/
`$3
`javascript
/**
* @api {get} /api/users Get users
* @apiName GetUsers
* @apiGroup Users
* @apiParam {Number} page Page number
* @apiParam {Number} limit Items per page
* @apiParam {String} search Search query
* @apiSuccess {Object[]} users List of users
* @apiSuccess {String} users.id User ID
* @apiSuccess {String} users.name User name
* @apiSuccess {String} users.email User email
*/
`π€ Contributing
$3
`bash
Clone repository
git clone https://github.com/diagramers/diagramers-admin.git
cd diagramers-adminInstall dependencies
npm installStart development server
npm startRun tests
npm testBuild project
npm run build
`$3
`bash
Run linting
npm run lintFix linting issues
npm run lint:fixFormat code
npm run formatType checking
npm run type-check
`$3
`bash
Run unit tests
npm run test:unitRun integration tests
npm run test:integrationRun e2e tests
npm run test:e2eGenerate coverage report
npm run test:coverage
``MIT License - see LICENSE file for details
- @diagramers/api - Node.js API template
- @diagramers/cli - Command-line interface for scaffolding
For support and questions:
- Create an issue on GitHub
- Check the documentation
- Review the examples in the codebase
- Join our community discussions