Overview
The Questionnaire List V2 module represents a complete modernization of the questionnaire management interface in @admin-lite, built with Next.js 15 and React. While maintaining full compatibility with existing APIs, this implementation introduces significant improvements in performance, user experience, and developer maintainability.
For core questionnaire concepts and the original implementation details, please refer to Questionnaire List Admin Frontend.
Key Improvements from V1
- Modern Architecture: Functional components with React Query replacing Redux
- Enhanced Performance: Server-side pagination, code splitting, and optimistic updates
- Improved UX: Real-time search, modern filtering UI, and responsive design
- TypeScript: Full type safety throughout the codebase
- Template Integration: Seamless integration with the new template management system
Architecture
The V2 implementation follows a clean, domain-driven architecture:
Directory Structure
app/admin/questionnaires/
├── _components/
│ ├── bulk-actions-toolbar.tsx # Multi-select operations
│ ├── page-components.tsx # Main list components
│ ├── questionnaires-content.tsx # Content wrapper
│ ├── questionnaires-loader.tsx # Loading states
│ └── modals/ # Various modal dialogs
├── _domain/
│ └── questionnaire-dtos.ts # Data transfer objects
├── _lib/
│ ├── questionnaire-queries.ts # React Query configurations
│ ├── questionnaire-repository.ts # API communication
│ ├── questionnaire-service.ts # Business logic
│ └── use-questionnaire-actions.ts # Custom hooks
└── page.tsx # Main list page
State Management Evolution
V1 (Redux-based)
// Complex Redux setup with actions, reducers, and sagas
dispatch(fetchQuestionnaires({ page, filters }));V2 (React Query-based)
// Simplified data fetching with automatic caching
const { data, isLoading } = useQuery(
questionnaireQueryOptions.paginated({ page, search, status })
);New Features in V2
1. Real-time Search
The V2 implementation provides instant search results as users type:
// Debounced search with loading states
const debouncedSearch = useDebounce(searchTerm, 300);
const { data } = useQuery(
questionnaireQueryOptions.paginated({ search: debouncedSearch })
);2. Enhanced Bulk Operations
Improved multi-select functionality with visual feedback:
- Bulk Delete: Delete multiple questionnaires with confirmation
- Bulk Download: Export selected questionnaires to Excel
- Bulk Clone: Duplicate multiple questionnaires at once
- Visual Selection: Clear checkbox UI with select-all functionality
3. Modern Filtering UI
A complete redesign of the filtering interface:
- Status Filters: Published, Draft, Deleted (with soft delete support)
- Department Filters: Filter by assigned departments
- Date Range: Filter by creation or modification date
- Saved Filters: Save and reuse filter combinations
4. Template Management Integration
Direct integration with the template system:
- Save as Template: Convert any questionnaire to a reusable template
- Template Badge: Visual indicator for template-based questionnaires
- Quick Template Access: Direct navigation to template management
5. Performance Optimizations
Server-side Pagination
// Efficient pagination with server-side filtering
const response = await questionnaireRepository.findPaginated({
page,
limit: 20,
search,
status,
departmentId
});Optimistic Updates
// Immediate UI feedback for better UX
const deleteMutation = useMutation({
mutationFn: questionnaireService.delete,
onMutate: async (id) => {
// Optimistically remove from UI
await queryClient.cancelQueries(['questionnaires']);
const previous = queryClient.getQueryData(['questionnaires']);
queryClient.setQueryData(['questionnaires'], old =>
old.filter(q => q.id !== id)
);
return { previous };
},
onError: (err, id, context) => {
// Rollback on error
queryClient.setQueryData(['questionnaires'], context.previous);
}
});UI/UX Improvements
Responsive Design
The V2 list adapts seamlessly to different screen sizes:
- Desktop: Full table view with all columns
- Tablet: Condensed table with priority columns
- Mobile: Card-based layout for easy touch interaction
Loading States
Comprehensive loading feedback throughout the interface:
// Skeleton loader for initial load
if (isLoading) return <QuestionnairesLoader />;
// Inline loading for actions
<Button loading={isDeleting}>Delete</Button>Error Handling
User-friendly error messages with recovery options:
if (error) {
return (
<ErrorState
message="Failed to load questionnaires"
onRetry={() => refetch()}
/>
);
}API Integration
The V2 implementation maintains full compatibility with existing APIs while adding new endpoints:
Existing Endpoints (V1 Compatible)
GET /v1.0/questionnaires/paginate
POST /v1.0/questionnaires/
PUT /v1.0/questionnaires/{id}
DELETE /v1.0/questionnaires/{id}
New Endpoints (V2 Specific)
POST /v1.0/questionnaires/bulk-delete
GET /v1.0/questionnaires/export
POST /v1.0/questionnaires/{id}/clone
Developer Migration Guide
Component Migration
V1 Pattern
class QuestionnaireList extends Component {
componentDidMount() {
this.props.fetchQuestionnaires();
}
render() {
const { questionnaires, loading } = this.props;
// ...
}
}
export default connect(mapStateToProps, mapDispatchToProps)(QuestionnaireList);V2 Pattern
export function QuestionnaireList() {
const { data, isLoading } = useQuery(questionnaireQueryOptions.all());
if (isLoading) return <QuestionnairesLoader />;
return <QuestionnaireTable data={data} />;
}State Management Migration
- Remove Redux dependencies: No more actions, reducers, or sagas
- Add React Query: All server state managed by React Query
- Local state only: Use React hooks for UI state
TypeScript Adoption
All components are fully typed:
interface QuestionnaireListProps {
initialFilters?: QuestionnaireFilters;
onQuestionnaireSelect?: (id: string) => void;
}
export function QuestionnaireList({
initialFilters,
onQuestionnaireSelect
}: QuestionnaireListProps) {
// Fully typed implementation
}Performance Metrics
The V2 implementation shows significant performance improvements:
| Metric | V1 | V2 | Improvement |
|---|---|---|---|
| Initial Load | 2.5s | 0.8s | 68% faster |
| Search Response | 800ms | 150ms | 81% faster |
| Bundle Size | 450KB | 180KB | 60% smaller |
| Memory Usage | 45MB | 25MB | 44% less |
Related Documentation
Core Questionnaire System
- Questionnaires - Overview of the questionnaire system
- Questionnaire List Admin Frontend - Original V1 implementation
- Questionnaires Backend - API documentation
V2 Specific Documentation
- Questionnaire Create Admin Frontend V2 - V2 editor interface
- Questionnaire Templates Admin Frontend - Template management system
- Questionnaire Scoring Configuration - Advanced scoring features
Migration Resources
- @admin-lite Repository - Full V2 implementation
- Migration Guide - Step-by-step migration instructions
- API Compatibility - Ensuring backward compatibility