Skip to content

Contract Summary Component (components/Editor/contract-summary.tsx)

Overview

A React component that displays contract information in a structured card layout with a table format. The component parses and presents contract details including issuer, scope of work, dates, and deliverables with associated icons.

Features

  • Tabular data display
  • Date parsing
  • Icon integration
  • Scrollable content
  • Error handling
  • Responsive layout
  • Default values
  • Whitespace handling
  • Array data support
  • Visual hierarchy

Implementation

interface ContractDate {
  title: string;
  value: string;
}

interface ParsedContractInfo {
  label: string;
  value: string | ContractDate[];
  icon: React.ReactNode;
}

function parseContractSummary(summary: Summary): ParsedContractInfo[] {
  const issuer = summary.ClientName || "Not specified";
  const scopeOfWork = summary.ScopeOfWork || "Not specified";
  const unitsDeliverables = summary.Deliverables || "Not specified";
  let dates: ContractDate[] = [];
  let datesSection: ParsedContractInfo[] = [];

  try {
    if (summary.Dates && summary.Dates.includes("Not Provided")) {
      dates = [{ title: "Dates", value: "Not Provided" }];
    } else {
      dates = JSON.parse(summary.Dates.replace(/\\n/g, '').replace(/\\"/g, '"').replace(/^\[ /, '[').replace(/ \]$/, ']')) || [];
      datesSection = dates.map((date) => ({
        label: date.title,
        value: date.value.includes("Not Provided") ? "Not Provided" : date.value || "Not specified",
        icon: <Calendar className="w-4 h-4" />,
      }));
    }
  } catch (error) {
    console.error("Error parsing dates:", error);
  }

  return [
    {
      label: "Issuer",
      value: issuer.includes("Not Provided") ? "Not Provided" : issuer || "Not specified",
      icon: <FileText className="w-4 h-4" />,
    },
    {
      label: "Scope of Work",
      value: scopeOfWork.includes("Not Provided") ? "Not Provided" : scopeOfWork || "Not specified",
      icon: <FileText className="w-4 h-4" />,
    },
    ...datesSection,
    {
      label: "Units/Deliverables",
      value: unitsDeliverables.includes("Not Provided") ? "Not Provided" : unitsDeliverables || "Not specified",
      icon: <Hash className="w-4 h-4" />,
    },
  ];
}

export function ContractSummary({ summary }: { summary: Summary }) {
  const contractInfo = parseContractSummary(summary);

  return (
    <Card className="max-w-4xl mx-auto">
      <CardHeader>
        <CardTitle className="text-2xl font-bold">Contract Summary</CardTitle>
      </CardHeader>
      <div className="mt-2 border-t border-pink-525"></div>
      <CardContent>
        <div style={{ maxHeight: "435px", overflowY: "auto" }}>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-1/3">Field</TableHead>
                <TableHead>Value</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {contractInfo.map((info, index) => (
                <TableRow key={index}>
                  <TableCell className="font-medium flex items-center gap-2">
                    {info.icon}
                    {info.label}
                  </TableCell>
                  <TableCell className="whitespace-pre-wrap">
                    {Array.isArray(info.value) ? (
                      info.value.map((date, dateIndex) => (
                        <div key={dateIndex}>
                          <strong>{date.title}:</strong> {date.value || "\u00A0"}
                        </div>
                      ))
                    ) : (
                      <span>{info.value || "\u00A0"}</span>
                    )}
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
      </CardContent>
    </Card>
  );
}

Dependencies

import { useState, useEffect } from "react"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { FileText, Calendar, Hash } from "lucide-react"
import { Summary } from "./summary"

Components Used

Notes

  • Parses contract summary data
  • Handles date formatting
  • Provides fallback values
  • Manages data display
  • Implements error handling
  • Supports scrollable content
  • Uses icon indicators
  • Maintains data structure
  • Ensures accessibility
  • Handles edge cases