Test


import React, { useState, useEffect } from 'react';
import { Trash2, Plus, Save, Upload, BookOpen } from 'lucide-react';

// GPA scale - standard US 4.0 scale
const gradePoints = {
  'A+': 4.0, 'A': 4.0, 'A-': 3.7,
  'B+': 3.3, 'B': 3.0, 'B-': 2.7,
  'C+': 2.3, 'C': 2.0, 'C-': 1.7,
  'D+': 1.3, 'D': 1.0, 'D-': 0.7,
  'F': 0.0
};

const GPACalculator = () => {
  const [semesters, setSemesters] = useState([{
    id: 1,
    name: 'Semester 1',
    courses: [{ id: 1, name: '', credits: 3, grade: 'A' }]
  }]);
  const [activeTab, setActiveTab] = useState('current');
  
  // Load data from localStorage on component mount
  useEffect(() => {
    const savedData = localStorage.getItem('gpaCalculatorData');
    if (savedData) {
      try {
        setSemesters(JSON.parse(savedData));
      } catch (e) {
        console.error('Failed to load saved data', e);
      }
    }
  }, []);

  const addCourse = (semesterId) => {
    setSemesters(semesters.map(semester => {
      if (semester.id === semesterId) {
        return {
          ...semester,
          courses: [
            ...semester.courses,
            {
              id: Math.max(0, ...semester.courses.map(c => c.id)) + 1,
              name: '',
              credits: 3,
              grade: 'A'
            }
          ]
        };
      }
      return semester;
    }));
  };

  const removeCourse = (semesterId, courseId) => {
    setSemesters(semesters.map(semester => {
      if (semester.id === semesterId) {
        return {
          ...semester,
          courses: semester.courses.filter(course => course.id !== courseId)
        };
      }
      return semester;
    }));
  };

  const updateCourse = (semesterId, courseId, field, value) => {
    setSemesters(semesters.map(semester => {
      if (semester.id === semesterId) {
        return {
          ...semester,
          courses: semester.courses.map(course => {
            if (course.id === courseId) {
              return { ...course, [field]: value };
            }
            return course;
          })
        };
      }
      return semester;
    }));
  };

  const addSemester = () => {
    const newId = Math.max(0, ...semesters.map(s => s.id)) + 1;
    setSemesters([
      ...semesters,
      {
        id: newId,
        name: `Semester ${newId}`,
        courses: [{ id: 1, name: '', credits: 3, grade: 'A' }]
      }
    ]);
  };

  const removeSemester = (semesterId) => {
    setSemesters(semesters.filter(semester => semester.id !== semesterId));
  };

  const updateSemesterName = (semesterId, name) => {
    setSemesters(semesters.map(semester => {
      if (semester.id === semesterId) {
        return { ...semester, name };
      }
      return semester;
    }));
  };

  const calculateSemesterGPA = (courses) => {
    if (courses.length === 0) return 0;
    
    let totalPoints = 0;
    let totalCredits = 0;
    
    courses.forEach(course => {
      const credits = parseFloat(course.credits) || 0;
      totalPoints += (gradePoints[course.grade] || 0) * credits;
      totalCredits += credits;
    });
    
    return totalCredits > 0 ? (totalPoints / totalCredits).toFixed(2) : 0;
  };

  const calculateCumulativeGPA = () => {
    let totalPoints = 0;
    let totalCredits = 0;
    
    semesters.forEach(semester => {
      semester.courses.forEach(course => {
        const credits = parseFloat(course.credits) || 0;
        totalPoints += (gradePoints[course.grade] || 0) * credits;
        totalCredits += credits;
      });
    });
    
    return totalCredits > 0 ? (totalPoints / totalCredits).toFixed(2) : 0;
  };

  const saveData = () => {
    localStorage.setItem('gpaCalculatorData', JSON.stringify(semesters));
    alert('Your GPA data has been saved!');
  };

  const exportData = () => {
    const dataStr = JSON.stringify(semesters, null, 2);
    const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);
    
    const exportFileDefaultName = 'gpa-data.json';
    
    const linkElement = document.createElement('a');
    linkElement.setAttribute('href', dataUri);
    linkElement.setAttribute('download', exportFileDefaultName);
    linkElement.click();
  };

  const importData = (event) => {
    const file = event.target.files[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        const data = JSON.parse(e.target.result);
        setSemesters(data);
        localStorage.setItem('gpaCalculatorData', JSON.stringify(data));
        alert('GPA data imported successfully!');
      } catch (error) {
        alert('Error importing data. Please check your file format.');
        console.error('Import error:', error);
      }
    };
    reader.readAsText(file);
  };

  return (
    <div className="p-4 max-w-4xl mx-auto bg-white rounded-lg shadow">
      <div className="flex items-center mb-6">
        <BookOpen className="text-blue-600 mr-2" size={24} />
        <h1 className="text-2xl font-bold text-gray-800">College GPA Calculator</h1>
      </div>

      <div className="mb-6">
        <div className="flex border-b">
          <button
            className={`py-2 px-4 ${activeTab === 'current' ? 'border-b-2 border-blue-500 text-blue-600' : 'text-gray-600'}`}
            onClick={() => setActiveTab('current')}
          >
            Current Semester
          </button>
          <button
            className={`py-2 px-4 ${activeTab === 'cumulative' ? 'border-b-2 border-blue-500 text-blue-600' : 'text-gray-600'}`}
            onClick={() => setActiveTab('cumulative')}
          >
            Cumulative GPA
          </button>
        </div>
      </div>

      {activeTab === 'current' && (
        <div>
          {semesters.map((semester) => (
            <div key={semester.id} className="mb-8 p-4 border rounded-lg bg-gray-50">
              <div className="flex justify-between items-center mb-4">
                <input
                  type="text"
                  value={semester.name}
                  onChange={(e) => updateSemesterName(semester.id, e.target.value)}
                  className="text-xl font-semibold bg-transparent border-b border-gray-300 focus:border-blue-500 outline-none"
                />
                <button
                  onClick={() => removeSemester(semester.id)}
                  className="text-red-500 hover:text-red-700"
                  disabled={semesters.length === 1}
                >
                  <Trash2 size={18} />
                </button>
              </div>

              <div className="overflow-x-auto">
                <table className="w-full mb-4">
                  <thead>
                    <tr className="bg-gray-100">
                      <th className="p-2 text-left">Course Name</th>
                      <th className="p-2 text-center">Credits</th>
                      <th className="p-2 text-center">Grade</th>
                      <th className="p-2 text-center">Action</th>
                    </tr>
                  </thead>
                  <tbody>
                    {semester.courses.map((course) => (
                      <tr key={course.id} className="border-b">
                        <td className="p-2">
                          <input
                            type="text"
                            value={course.name}
                            onChange={(e) => updateCourse(semester.id, course.id, 'name', e.target.value)}
                            placeholder="Course name"
                            className="w-full p-1 border rounded"
                          />
                        </td>
                        <td className="p-2">
                          <select
                            value={course.credits}
                            onChange={(e) => updateCourse(semester.id, course.id, 'credits', e.target.value)}
                            className="w-full p-1 border rounded text-center"
                          >
                            {[0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5].map(credit => (
                              <option key={credit} value={credit}>{credit}</option>
                            ))}
                          </select>
                        </td>
                        <td className="p-2">
                          <select
                            value={course.grade}
                            onChange={(e) => updateCourse(semester.id, course.id, 'grade', e.target.value)}
                            className="w-full p-1 border rounded text-center"
                          >
                            {Object.keys(gradePoints).map(grade => (
                              <option key={grade} value={grade}>{grade}</option>
                            ))}
                          </select>
                        </td>
                        <td className="p-2 text-center">
                          <button
                            onClick={() => removeCourse(semester.id, course.id)}
                            className="text-red-500 hover:text-red-700"
                            disabled={semester.courses.length === 1}
                          >
                            <Trash2 size={16} />
                          </button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>

              <div className="flex justify-between items-center">
                <button
                  onClick={() => addCourse(semester.id)}
                  className="flex items-center text-blue-600 hover:text-blue-800"
                >
                  <Plus size={16} className="mr-1" /> Add Course
                </button>
                <div className="text-right">
                  <div className="text-sm text-gray-600">Semester GPA</div>
                  <div className="text-2xl font-bold">{calculateSemesterGPA(semester.courses)}</div>
                </div>
              </div>
            </div>
          ))}

          <div className="mb-6">
            <button
              onClick={addSemester}
              className="flex items-center bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
            >
              <Plus size={16} className="mr-1" /> Add Semester
            </button>
          </div>
        </div>
      )}

      {activeTab === 'cumulative' && (
        <div className="mb-8">
          <div className="bg-gray-50 p-6 rounded-lg border">
            <h2 className="text-xl font-semibold mb-4">Cumulative GPA Summary</h2>
            
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
              <div className="bg-white p-4 rounded-lg border shadow-sm">
                <div className="text-sm text-gray-600 mb-1">Overall GPA</div>
                <div className="text-3xl font-bold text-blue-600">{calculateCumulativeGPA()}</div>
              </div>
              <div className="bg-white p-4 rounded-lg border shadow-sm">
                <div className="text-sm text-gray-600 mb-1">Total Credits</div>
                <div className="text-3xl font-bold text-green-600">
                  {semesters.reduce((total, semester) => 
                    total + semester.courses.reduce((sum, course) => 
                      sum + (parseFloat(course.credits) || 0), 0), 0)}
                </div>
              </div>
            </div>
            
            <h3 className="text-lg font-medium mb-3">Semester Breakdown</h3>
            <div className="overflow-x-auto">
              <table className="w-full">
                <thead>
                  <tr className="bg-gray-100">
                    <th className="p-2 text-left">Semester</th>
                    <th className="p-2 text-center">Credits</th>
                    <th className="p-2 text-center">GPA</th>
                  </tr>
                </thead>
                <tbody>
                  {semesters.map((semester) => {
                    const credits = semester.courses.reduce((sum, course) => 
                      sum + (parseFloat(course.credits) || 0), 0);
                    return (
                      <tr key={semester.id} className="border-b">
                        <td className="p-2">{semester.name}</td>
                        <td className="p-2 text-center">{credits}</td>
                        <td className="p-2 text-center">{calculateSemesterGPA(semester.courses)}</td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>
        </div>
      )}

      <div className="flex flex-wrap gap-2 justify-between mt-6">
        <div className="flex gap-2">
          <button
            onClick={saveData}
            className="flex items-center bg-green-600 text-white px-4 py-2 rounded hover:bg-green-700"
          >
            <Save size={16} className="mr-1" /> Save Data
          </button>
          <button
            onClick={exportData}
            className="flex items-center bg-purple-600 text-white px-4 py-2 rounded hover:bg-purple-700"
          >
            <Save size={16} className="mr-1" /> Export JSON
          </button>
          <div className="relative">
            <input
              type="file"
              id="import-file"
              accept=".json"
              onChange={importData}
              className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
            />
            <button className="flex items-center bg-yellow-600 text-white px-4 py-2 rounded hover:bg-yellow-700">
              <Upload size={16} className="mr-1" /> Import Data
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default GPACalculator;