Skip to content

Tender Requirements (components/Editor/tender-requirements.tsx)

Overview

A comprehensive component for managing tender requirements, including questions and themes, with functionality for adding, editing, and removing questions, managing themes, and processing tender requirements. The component provides an interactive interface with batch operations and real-time updates.

Features

  • Question management
  • Theme handling
  • Batch operations
  • Animated transitions
  • Responsive layout
  • Real-time updates
  • State persistence
  • Error handling
  • Search functionality
  • Progress tracking

Dependencies

import { useState, useEffect } from 'react'
import { motion } from 'framer-motion'
import { Button } from '@/components/ui/button'
import { QuestionCard } from './question-card'
import { ThemesSection } from './themes-section'
import { ContractSummary } from './contract-summary'

Props

interface TenderRequirementsProps {
  initialQuestions: Question[];
  setReadyToProcess: (ready: boolean) => void;
  onQuestionsUpdate: (questions: Question[]) => void;
  onThemesUpdate: (themes: Theme[]) => void;
}

interface Question {
  id: string;
  text: string;
  themes: Theme[];
}

interface Theme {
  id: string;
  name: string;
  description: string;
}

Implementation

State Management

const [questions, setQuestions] = useState<Question[]>(initialQuestions);
const [selectedQuestions, setSelectedQuestions] = useState<string[]>([]);
const [isRemoveMode, setIsRemoveMode] = useState(false);
const [themes, setThemes] = useState<Theme[]>([]);

Methods

const handleQuestionEdit = (id: string, text: string) => {
  setQuestions(questions.map(q =>
    q.id === id ? { ...q, text } : q
  ));
  onQuestionsUpdate(questions);
};

const handleThemeChange = (questionId: string, newThemes: Theme[]) => {
  setQuestions(questions.map(q =>
    q.id === questionId ? { ...q, themes: newThemes } : q
  ));
  onQuestionsUpdate(questions);
};

const handleRemoveQuestions = () => {
  setQuestions(questions.filter(q => !selectedQuestions.includes(q.id)));
  setSelectedQuestions([]);
  setIsRemoveMode(false);
  onQuestionsUpdate(questions);
};

Unique Functionality

// Manages tender requirements with theme assignment and batch operations

HTML Structure

<div className="space-y-6">
  <div className="flex justify-between items-center">
    <h2 className="text-2xl font-bold">Tender Requirements</h2>
    <div className="flex space-x-2">
      <Button onClick={() => setIsRemoveMode(!isRemoveMode)}>
        {isRemoveMode ? 'Cancel' : 'Remove Questions'}
      </Button>
      {isRemoveMode && selectedQuestions.length > 0 && (
        <Button onClick={handleRemoveQuestions}>
          Remove Selected ({selectedQuestions.length})
        </Button>
      )}
    </div>
  </div>

  <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
    <div className="space-y-4">
      {questions.map(question => (
        <QuestionCard
          key={question.id}
          {...question}
          isRemoveMode={isRemoveMode}
          isSelected={selectedQuestions.includes(question.id)}
          onSelect={(id) => {
            setSelectedQuestions(prev =>
              prev.includes(id)
                ? prev.filter(qId => qId !== id)
                : [...prev, id]
            );
          }}
          onEdit={handleQuestionEdit}
          onThemeChange={handleThemeChange}
        />
      ))}
    </div>

    <ThemesSection
      themes={themes}
      onThemesUpdate={setThemes}
      onThemeSelect={(theme) => {
        const updatedQuestions = questions.map(q => ({
          ...q,
          themes: [...q.themes, theme]
        }));
        setQuestions(updatedQuestions);
        onQuestionsUpdate(updatedQuestions);
      }}
    />
  </div>
</div>

API Integration

  • Question state persistence
  • Theme synchronization
  • Progress tracking
  • Batch operations

Components Used

Notes

  • Supports batch operations
  • Maintains theme consistency
  • Features responsive design
  • Handles state updates
  • Provides user feedback