import React, { useState, useMemo } from 'react'; import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; import { FaCheckCircle, FaTimesCircle, FaExclamationCircle, FaInfoCircle, FaUsers, FaExclamationTriangle } from 'react-icons/fa'; import { UserImport } from '@/interfaces/IUserImport'; import Modal from '../Modal'; import ParseExcelErrors from './ExcelError'; import { errorsByRows, ExcelError } from '@/utils/excel.errors'; import UserTable from '../Tables/UserTable'; interface Props { parsedExcel: { rows?: any[]; errors?: any[] }, newUsers: UserImport[], enlistedUsers: UserImport[], duplicateRows?: { duplicates: ExcelUserDuplicatesMap, count: number } } export interface ExcelUserDuplicatesMap { studentID: Map; email: Map; passport_id: Map; phone: Map; } interface ClassroomCounts { [key: string]: number; } const UserImportSummary: React.FC = ({ parsedExcel, newUsers, enlistedUsers, duplicateRows }) => { const [showErrorsModal, setShowErrorsModal] = useState(false); const [showDuplicatesModal, setShowDuplicatesModal] = useState(false); const [showEnlistedModal, setShowEnlistedModal] = useState(false); const [showClassroomModal, setShowClassromModal] = useState(false); const classroomCounts = useMemo(() => { return newUsers.reduce((acc: ClassroomCounts, user) => { const group = user.groupName; acc[group] = (acc[group] || 0) + 1; return acc; }, {}); }, [newUsers]); const errorCount = Object.entries(errorsByRows(parsedExcel.errors as ExcelError[])).length || 0; const fieldMapper = { "studentID": "Student ID", "passport_id": "Passport/National ID", "phone": "Phone Number", "email": "E-mail" } return ( <> Import Summary
{`${parsedExcel.rows?.length} total spreadsheet rows`} {parsedExcel.rows && parsedExcel.rows.filter(row => row === null).length > 0 && ( {` (${parsedExcel.rows.filter(row => row === null).length} empty)`} )}
{newUsers.length > 0 ? ( ) : ( )} {`${newUsers.length} new user${newUsers.length > 1 ? "s" : ''} to import`}
{newUsers.length > 0 && ( )}
{enlistedUsers.length > 0 && (
{`${enlistedUsers.length} already registered user${enlistedUsers.length > 1 ? "s" : ''}`}
)} {(duplicateRows && duplicateRows.count > 0) && (
{duplicateRows.count} duplicate entries in file
)} {errorCount > 0 && (
{errorCount} invalid rows
)}
{((duplicateRows && duplicateRows.count > 0) || errorCount > 0) && (

The following will be excluded from import:

    {duplicateRows && duplicateRows.count > 0 && (
  • {duplicateRows.count} rows with duplicate values
    {(Object.keys(duplicateRows.duplicates) as Array).map(field => { const duplicates = Array.from(duplicateRows.duplicates[field].entries()) .filter((entry) => entry[1].length > 1); if (duplicates.length === 0) return null; return (
    {field}: rows { duplicates.map(([_, rows]) => rows.join(', ')).join('; ') }
    ); })}
  • )} {errorCount > 0 && (
  • {errorCount} rows with invalid or missing information
    Rows: {Object.keys(errorsByRows(parsedExcel.errors || [])).join(', ')}
  • )}
)}
setShowErrorsModal(false)}> <>

Validation Errors

setShowEnlistedModal(false)} maxWidth='max-w-[85%]'> <>

Already Registered Users

setShowDuplicatesModal(false)}> <>

Duplicate Entries

{duplicateRows && < div className="space-y-6"> {(Object.keys(duplicateRows.duplicates) as Array).map(field => { const duplicates = Array.from(duplicateRows!.duplicates[field].entries()) .filter((entry): entry is [string, number[]] => entry[1].length > 1); if (duplicates.length === 0) return null; return (

{fieldMapper[field]} duplicates

{duplicates.length} {duplicates.length === 1 ? 'duplicate' : 'duplicates'}
{duplicates.map(([value, rows]) => (
{value}
Appears in rows: {rows.join(', ')}
{rows.length} occurrences
))}
); })} }
setShowClassromModal(false)}> <>

Students by Classroom

{Object.entries(classroomCounts).map(([classroom, count]) => (
{classroom}
{count} students
))}
); }; export default UserImportSummary;