Ignore:
Timestamp:
09/04/26 19:08:08 (11 days ago)
Author:
MBK <marija.karapandzova@…>
Branches:
master
Children:
cdcff72
Parents:
e1f74f6
Message:

Fix frontend appearance

File:
1 edited

Legend:

Unmodified
Added
Removed
  • frontend/src/pages/lab-tests/LabTestList.js

    re1f74f6 r9af201e  
    55
    66function LabTestList() {
    7   const user = JSON.parse(localStorage.getItem('user') || '{}');
     7  const [user, setUser] = useState({});
    88  const isLabTechnician = user.role === 'LAB_TECHNICIAN';
    99
     
    4646    testDate: '',
    4747  });
     48
     49  // Load user from localStorage and listen for changes
     50  useEffect(() => {
     51    const loadUser = () => {
     52      const userStr = localStorage.getItem('user');
     53      console.log('[LabTestList] Loading user from localStorage:', userStr);
     54      if (userStr) {
     55        try {
     56          const parsedUser = JSON.parse(userStr);
     57          console.log('[LabTestList] Parsed user:', parsedUser);
     58          setUser(parsedUser);
     59        } catch (err) {
     60          console.error('Failed to parse user:', err);
     61          setUser({});
     62        }
     63      } else {
     64        console.log('[LabTestList] No user in localStorage');
     65        setUser({});
     66      }
     67    };
     68
     69    console.log('[LabTestList] useEffect running - loading user');
     70    loadUser();
     71
     72    // Listen for storage changes (other tabs/windows)
     73    window.addEventListener('storage', loadUser);
     74
     75    // Listen for custom event (same tab changes)
     76    window.addEventListener('userStorageChange', loadUser);
     77
     78    return () => {
     79      window.removeEventListener('storage', loadUser);
     80      window.removeEventListener('userStorageChange', loadUser);
     81    };
     82  }, []);
    4883
    4984  useEffect(() => {
     
    134169      setLoading(true);
    135170
    136       // Get doctor ID from localStorage (set during login)
    137       const doctorId = localStorage.getItem('doctorId') || 1;
     171      // Get doctor ID from logged-in user
     172      const doctorId = user.doctorId;
    138173
    139174      const request = {
     
    145180        notes: requestData.notes,
    146181      };
     182
     183      console.log('User object:', user);
     184      console.log('Sending lab test request with doctorId:', doctorId, 'Full request:', request);
    147185
    148186      await labService.requestLabTest(request);
     
    228266  if (isLabTechnician) {
    229267    return (
    230         <div>
    231           <h1 className="text-3xl font-bold mb-6" style={{ color: '#7c3aed' }}>Lab Tests - Submit Results</h1>
    232 
    233           {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
    234 
    235           {selectedTest ? (
    236               // Submit Result Form
    237               <div className="bg-white rounded-lg shadow p-6 mb-6">
    238                 <h2 className="text-xl font-bold mb-4">Submit Lab Result</h2>
    239                 <div className="mb-4 p-4 bg-gray-50 rounded-lg">
    240                   <p className="mb-2"><strong>Test:</strong> {selectedTest.testName}</p>
    241                   <p className="mb-2"><strong>Patient:</strong> {selectedTest.patientName}</p>
    242                   <p className="mb-2"><strong>Doctor:</strong> {selectedTest.doctorName}</p>
    243                   <p className="mb-2"><strong>Test Date:</strong> {selectedTest.testDate}</p>
    244                   {selectedTest.notes && <p><strong>Notes:</strong> {selectedTest.notes}</p>}
     268      <div>
     269        <h1 className="text-3xl font-bold mb-6" style={{ color: '#7c3aed' }}>Lab Tests - Submit Results</h1>
     270
     271        {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
     272
     273        {selectedTest ? (
     274          // Submit Result Form
     275          <div className="bg-white rounded-lg shadow p-6 mb-6">
     276            <h2 className="text-xl font-bold mb-4">Submit Lab Result</h2>
     277            <div className="mb-4 p-4 bg-gray-50 rounded-lg">
     278              <p className="mb-2"><strong>Test:</strong> {selectedTest.testName}</p>
     279              <p className="mb-2"><strong>Patient:</strong> {selectedTest.patientName}</p>
     280              <p className="mb-2"><strong>Doctor:</strong> {selectedTest.doctorName}</p>
     281              <p className="mb-2"><strong>Test Date:</strong> {selectedTest.testDate}</p>
     282              {selectedTest.notes && <p><strong>Notes:</strong> {selectedTest.notes}</p>}
     283            </div>
     284
     285            <form onSubmit={handleSubmitResult} className="space-y-4">
     286              <div>
     287                <label className="block text-sm font-semibold mb-2">Test Results *</label>
     288                <textarea
     289                  value={submitFormData.results}
     290                  onChange={(e) => setSubmitFormData({ ...submitFormData, results: e.target.value })}
     291                  placeholder="Enter detailed test results"
     292                  className="w-full px-4 py-2 border rounded-lg"
     293                  rows="4"
     294                  required
     295                />
     296              </div>
     297
     298              <div>
     299                <label className="block text-sm font-semibold mb-2">Result Date *</label>
     300                <input
     301                  type="date"
     302                  value={submitFormData.resultDate}
     303                  onChange={(e) => setSubmitFormData({ ...submitFormData, resultDate: e.target.value })}
     304                  className="w-full px-4 py-2 border rounded-lg"
     305                  required
     306                />
     307              </div>
     308
     309              <div className="flex gap-4">
     310                <button
     311                  type="submit"
     312                  disabled={loading}
     313                  style={{
     314                    background: loading ? '#d1d5db' : '#bfdbfe',
     315                    color: '#1e1035',
     316                    padding: '8px 24px',
     317                    borderRadius: '6px',
     318                    border: 'none',
     319                    cursor: loading ? 'not-allowed' : 'pointer',
     320                    fontSize: '14px',
     321                    fontWeight: '400'
     322                  }}
     323                  onMouseEnter={(e) => !loading && (e.currentTarget.style.background = '#93c5fd')}
     324                  onMouseLeave={(e) => !loading && (e.currentTarget.style.background = '#bfdbfe')}
     325                >
     326                  {loading ? 'Submitting...' : 'Submit Result'}
     327                </button>
     328                <button
     329                  type="button"
     330                  onClick={() => {
     331                    setSelectedTest(null);
     332                    setSubmitFormData({
     333                      results: '',
     334                      resultDate: new Date().toISOString().split('T')[0],
     335                    });
     336                  }}
     337                  className="bg-gray-400 text-white px-6 py-2 rounded hover:bg-gray-500"
     338                >
     339                  Cancel
     340                </button>
     341              </div>
     342            </form>
     343          </div>
     344        ) : (
     345          // Pending Tests List
     346          <div className="bg-white rounded-lg shadow overflow-hidden">
     347            <div className="p-6 border-b">
     348              <h2 className="text-xl font-bold">Pending Lab Tests ({pendingTests.length})</h2>
     349            </div>
     350
     351            {pendingTests.length === 0 ? (
     352              <div className="p-6 text-center text-gray-600">
     353                No pending lab tests
     354              </div>
     355            ) : (
     356              <>
     357                {/* Filters */}
     358                <div className="p-6 border-b bg-gray-50">
     359                  <h3 className="text-sm font-semibold mb-4">Filters</h3>
     360                  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
     361                    <div>
     362                      <label className="block text-sm font-semibold mb-2">Test</label>
     363                      <input
     364                        type="text"
     365                        placeholder="Filter by test name..."
     366                        value={pendingFilters.testName}
     367                        onChange={(e) => setPendingFilters({...pendingFilters, testName: e.target.value})}
     368                        className="w-full px-3 py-2 border rounded-lg text-sm"
     369                      />
     370                    </div>
     371                    <div>
     372                      <label className="block text-sm font-semibold mb-2">Patient</label>
     373                      <input
     374                        type="text"
     375                        placeholder="Filter by patient name..."
     376                        value={pendingFilters.patientName}
     377                        onChange={(e) => setPendingFilters({...pendingFilters, patientName: e.target.value})}
     378                        className="w-full px-3 py-2 border rounded-lg text-sm"
     379                      />
     380                    </div>
     381                    <div>
     382                      <label className="block text-sm font-semibold mb-2">Test Date</label>
     383                      <input
     384                        type="date"
     385                        value={pendingFilters.testDate}
     386                        onChange={(e) => setPendingFilters({...pendingFilters, testDate: e.target.value})}
     387                        className="w-full px-3 py-2 border rounded-lg text-sm"
     388                      />
     389                    </div>
     390                  </div>
     391                  <button
     392                    onClick={() => setPendingFilters({testName: '', patientName: '', testDate: ''})}
     393                    className="mt-4 bg-gray-300 text-gray-700 px-4 py-2 rounded text-sm hover:bg-gray-400"
     394                  >
     395                    Clear Filters
     396                  </button>
    245397                </div>
    246398
    247                 <form onSubmit={handleSubmitResult} className="space-y-4">
    248                   <div>
    249                     <label className="block text-sm font-semibold mb-2">Test Results *</label>
    250                     <textarea
    251                         value={submitFormData.results}
    252                         onChange={(e) => setSubmitFormData({ ...submitFormData, results: e.target.value })}
    253                         placeholder="Enter detailed test results"
    254                         className="w-full px-4 py-2 border rounded-lg"
    255                         rows="4"
    256                         required
    257                     />
     399                {/* Filtered Table */}
     400                <table className="w-full">
     401                  <thead className="bg-gray-100">
     402                    <tr>
     403                      <th className="px-6 py-3 text-left text-sm font-semibold">Test</th>
     404                      <th className="px-6 py-3 text-left text-sm font-semibold">Patient</th>
     405                      <th className="px-6 py-3 text-left text-sm font-semibold">Doctor</th>
     406                      <th className="px-6 py-3 text-left text-sm font-semibold">Requested</th>
     407                      <th className="px-6 py-3 text-left text-sm font-semibold">Test Date</th>
     408                      <th className="px-6 py-3 text-left text-sm font-semibold">Notes</th>
     409                      <th className="px-6 py-3 text-left text-sm font-semibold">Action</th>
     410                    </tr>
     411                  </thead>
     412                  <tbody>
     413                    {pendingTests
     414                      .filter((test) => {
     415                        const testName = (test.testName || '').toLowerCase();
     416                        const patientName = (test.patientName || '').toLowerCase();
     417                        const testDate = (test.testDate || '');
     418
     419                        return (
     420                          testName.includes(pendingFilters.testName.toLowerCase()) &&
     421                          patientName.includes(pendingFilters.patientName.toLowerCase()) &&
     422                          (pendingFilters.testDate === '' || testDate === pendingFilters.testDate)
     423                        );
     424                      })
     425                      .map((test, index) => (
     426                    <tr key={index} className="border-t hover:bg-gray-50">
     427                      <td className="px-6 py-3 font-medium">{test.testName}</td>
     428                      <td className="px-6 py-3">{test.patientName}</td>
     429                      <td className="px-6 py-3">{test.doctorName}</td>
     430                      <td className="px-6 py-3 text-green-600">{test.requestDate}</td>
     431                      <td className="px-6 py-3 text-purple-600">{test.testDate}</td>
     432                      <td className="px-6 py-3 text-gray-600 text-sm">{test.notes || '-'}</td>
     433                      <td className="px-6 py-3">
     434                        <button
     435                          onClick={() => setSelectedTest(test)}
     436                          style={{
     437                            background: '#bfdbfe',
     438                            color: '#1e1035',
     439                            padding: '6px 12px',
     440                            borderRadius: '4px',
     441                            border: 'none',
     442                            cursor: 'pointer',
     443                            fontSize: '12px',
     444                            fontWeight: '400'
     445                          }}
     446                          onMouseEnter={(e) => e.currentTarget.style.background = '#93c5fd'}
     447                          onMouseLeave={(e) => e.currentTarget.style.background = '#bfdbfe'}
     448                        >
     449                          Submit Result
     450                        </button>
     451                      </td>
     452                    </tr>
     453                  ))}
     454                  </tbody>
     455                </table>
     456              </>
     457            )}
     458          </div>
     459        )}
     460
     461        {/* Submitted Tests History */}
     462        {!selectedTest && (
     463          <div className="bg-white rounded-lg shadow overflow-hidden mt-6">
     464            <div className="p-6 border-b">
     465              <h2 className="text-xl font-bold">Submitted Lab Results History ({submittedTests.length})</h2>
     466            </div>
     467
     468            {submittedTests.length === 0 ? (
     469              <div className="p-6 text-center text-gray-600">
     470                No submitted lab results yet
     471              </div>
     472            ) : (
     473              <>
     474                {/* Filters */}
     475                <div className="p-6 border-b bg-gray-50">
     476                  <h3 className="text-sm font-semibold mb-4">Filters</h3>
     477                  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
     478                    <div>
     479                      <label className="block text-sm font-semibold mb-2">Test</label>
     480                      <input
     481                        type="text"
     482                        placeholder="Filter by test name..."
     483                        value={submittedFilters.testName}
     484                        onChange={(e) => setSubmittedFilters({...submittedFilters, testName: e.target.value})}
     485                        className="w-full px-3 py-2 border rounded-lg text-sm"
     486                      />
     487                    </div>
     488                    <div>
     489                      <label className="block text-sm font-semibold mb-2">Patient</label>
     490                      <input
     491                        type="text"
     492                        placeholder="Filter by patient name..."
     493                        value={submittedFilters.patientName}
     494                        onChange={(e) => setSubmittedFilters({...submittedFilters, patientName: e.target.value})}
     495                        className="w-full px-3 py-2 border rounded-lg text-sm"
     496                      />
     497                    </div>
     498                    <div>
     499                      <label className="block text-sm font-semibold mb-2">Test Date</label>
     500                      <input
     501                        type="date"
     502                        value={submittedFilters.testDate}
     503                        onChange={(e) => setSubmittedFilters({...submittedFilters, testDate: e.target.value})}
     504                        className="w-full px-3 py-2 border rounded-lg text-sm"
     505                      />
     506                    </div>
    258507                  </div>
    259 
    260                   <div>
    261                     <label className="block text-sm font-semibold mb-2">Result Date *</label>
    262                     <input
    263                         type="date"
    264                         value={submitFormData.resultDate}
    265                         onChange={(e) => setSubmitFormData({ ...submitFormData, resultDate: e.target.value })}
    266                         className="w-full px-4 py-2 border rounded-lg"
    267                         required
    268                     />
    269                   </div>
    270 
    271                   <div className="flex gap-4">
    272                     <button
    273                         type="submit"
    274                         disabled={loading}
    275                         style={{
    276                           background: loading ? '#d1d5db' : '#bfdbfe',
    277                           color: '#1e1035',
    278                           padding: '8px 24px',
    279                           borderRadius: '6px',
    280                           border: 'none',
    281                           cursor: loading ? 'not-allowed' : 'pointer',
    282                           fontSize: '14px',
    283                           fontWeight: '400'
    284                         }}
    285                         onMouseEnter={(e) => !loading && (e.currentTarget.style.background = '#93c5fd')}
    286                         onMouseLeave={(e) => !loading && (e.currentTarget.style.background = '#bfdbfe')}
    287                     >
    288                       {loading ? 'Submitting...' : 'Submit Result'}
    289                     </button>
    290                     <button
    291                         type="button"
    292                         onClick={() => {
    293                           setSelectedTest(null);
    294                           setSubmitFormData({
    295                             results: '',
    296                             resultDate: new Date().toISOString().split('T')[0],
    297                           });
    298                         }}
    299                         className="bg-gray-400 text-white px-6 py-2 rounded hover:bg-gray-500"
    300                     >
    301                       Cancel
    302                     </button>
    303                   </div>
    304                 </form>
    305               </div>
    306           ) : (
    307               // Pending Tests List
    308               <div className="bg-white rounded-lg shadow overflow-hidden">
    309                 <div className="p-6 border-b">
    310                   <h2 className="text-xl font-bold">Pending Lab Tests ({pendingTests.length})</h2>
     508                  <button
     509                    onClick={() => setSubmittedFilters({testName: '', patientName: '', testDate: ''})}
     510                    className="mt-4 bg-gray-300 text-gray-700 px-4 py-2 rounded text-sm hover:bg-gray-400"
     511                  >
     512                    Clear Filters
     513                  </button>
    311514                </div>
    312515
    313                 {pendingTests.length === 0 ? (
    314                     <div className="p-6 text-center text-gray-600">
    315                       No pending lab tests
    316                     </div>
    317                 ) : (
    318                     <>
    319                       {/* Filters */}
    320                       <div className="p-6 border-b bg-gray-50">
    321                         <h3 className="text-sm font-semibold mb-4">Filters</h3>
    322                         <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
    323                           <div>
    324                             <label className="block text-sm font-semibold mb-2">Test</label>
    325                             <input
    326                                 type="text"
    327                                 placeholder="Filter by test name..."
    328                                 value={pendingFilters.testName}
    329                                 onChange={(e) => setPendingFilters({...pendingFilters, testName: e.target.value})}
    330                                 className="w-full px-3 py-2 border rounded-lg text-sm"
    331                             />
    332                           </div>
    333                           <div>
    334                             <label className="block text-sm font-semibold mb-2">Patient</label>
    335                             <input
    336                                 type="text"
    337                                 placeholder="Filter by patient name..."
    338                                 value={pendingFilters.patientName}
    339                                 onChange={(e) => setPendingFilters({...pendingFilters, patientName: e.target.value})}
    340                                 className="w-full px-3 py-2 border rounded-lg text-sm"
    341                             />
    342                           </div>
    343                           <div>
    344                             <label className="block text-sm font-semibold mb-2">Test Date</label>
    345                             <input
    346                                 type="date"
    347                                 value={pendingFilters.testDate}
    348                                 onChange={(e) => setPendingFilters({...pendingFilters, testDate: e.target.value})}
    349                                 className="w-full px-3 py-2 border rounded-lg text-sm"
    350                             />
    351                           </div>
    352                         </div>
    353                         <button
    354                             onClick={() => setPendingFilters({testName: '', patientName: '', testDate: ''})}
    355                             className="mt-4 bg-gray-300 text-gray-700 px-4 py-2 rounded text-sm hover:bg-gray-400"
    356                         >
    357                           Clear Filters
    358                         </button>
    359                       </div>
    360 
    361                       {/* Filtered Table */}
    362                       <table className="w-full">
    363                         <thead className="bg-gray-100">
    364                         <tr>
    365                           <th className="px-6 py-3 text-left text-sm font-semibold">Test</th>
    366                           <th className="px-6 py-3 text-left text-sm font-semibold">Patient</th>
    367                           <th className="px-6 py-3 text-left text-sm font-semibold">Doctor</th>
    368                           <th className="px-6 py-3 text-left text-sm font-semibold">Requested</th>
    369                           <th className="px-6 py-3 text-left text-sm font-semibold">Test Date</th>
    370                           <th className="px-6 py-3 text-left text-sm font-semibold">Notes</th>
    371                           <th className="px-6 py-3 text-left text-sm font-semibold">Action</th>
    372                         </tr>
    373                         </thead>
    374                         <tbody>
    375                         {pendingTests
    376                             .filter((test) => {
    377                               const testName = (test.testName || '').toLowerCase();
    378                               const patientName = (test.patientName || '').toLowerCase();
    379                               const testDate = (test.testDate || '');
    380 
    381                               return (
    382                                   testName.includes(pendingFilters.testName.toLowerCase()) &&
    383                                   patientName.includes(pendingFilters.patientName.toLowerCase()) &&
    384                                   (pendingFilters.testDate === '' || testDate === pendingFilters.testDate)
    385                               );
    386                             })
    387                             .map((test, index) => (
    388                                 <tr key={index} className="border-t hover:bg-gray-50">
    389                                   <td className="px-6 py-3 font-medium">{test.testName}</td>
    390                                   <td className="px-6 py-3">{test.patientName}</td>
    391                                   <td className="px-6 py-3">{test.doctorName}</td>
    392                                   <td className="px-6 py-3 text-green-600">{test.requestDate}</td>
    393                                   <td className="px-6 py-3 text-purple-600">{test.testDate}</td>
    394                                   <td className="px-6 py-3 text-gray-600 text-sm">{test.notes || '-'}</td>
    395                                   <td className="px-6 py-3">
    396                                     <button
    397                                         onClick={() => setSelectedTest(test)}
    398                                         style={{
    399                                           background: '#bfdbfe',
    400                                           color: '#1e1035',
    401                                           padding: '6px 12px',
    402                                           borderRadius: '4px',
    403                                           border: 'none',
    404                                           cursor: 'pointer',
    405                                           fontSize: '12px',
    406                                           fontWeight: '400'
    407                                         }}
    408                                         onMouseEnter={(e) => e.currentTarget.style.background = '#93c5fd'}
    409                                         onMouseLeave={(e) => e.currentTarget.style.background = '#bfdbfe'}
    410                                     >
    411                                       Submit Result
    412                                     </button>
    413                                   </td>
    414                                 </tr>
    415                             ))}
    416                         </tbody>
    417                       </table>
    418                     </>
    419                 )}
    420               </div>
    421           )}
    422 
    423           {/* Submitted Tests History */}
    424           {!selectedTest && (
    425               <div className="bg-white rounded-lg shadow overflow-hidden mt-6">
    426                 <div className="p-6 border-b">
    427                   <h2 className="text-xl font-bold">Submitted Lab Results History ({submittedTests.length})</h2>
    428                 </div>
    429 
    430                 {submittedTests.length === 0 ? (
    431                     <div className="p-6 text-center text-gray-600">
    432                       No submitted lab results yet
    433                     </div>
    434                 ) : (
    435                     <>
    436                       {/* Filters */}
    437                       <div className="p-6 border-b bg-gray-50">
    438                         <h3 className="text-sm font-semibold mb-4">Filters</h3>
    439                         <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
    440                           <div>
    441                             <label className="block text-sm font-semibold mb-2">Test</label>
    442                             <input
    443                                 type="text"
    444                                 placeholder="Filter by test name..."
    445                                 value={submittedFilters.testName}
    446                                 onChange={(e) => setSubmittedFilters({...submittedFilters, testName: e.target.value})}
    447                                 className="w-full px-3 py-2 border rounded-lg text-sm"
    448                             />
    449                           </div>
    450                           <div>
    451                             <label className="block text-sm font-semibold mb-2">Patient</label>
    452                             <input
    453                                 type="text"
    454                                 placeholder="Filter by patient name..."
    455                                 value={submittedFilters.patientName}
    456                                 onChange={(e) => setSubmittedFilters({...submittedFilters, patientName: e.target.value})}
    457                                 className="w-full px-3 py-2 border rounded-lg text-sm"
    458                             />
    459                           </div>
    460                           <div>
    461                             <label className="block text-sm font-semibold mb-2">Test Date</label>
    462                             <input
    463                                 type="date"
    464                                 value={submittedFilters.testDate}
    465                                 onChange={(e) => setSubmittedFilters({...submittedFilters, testDate: e.target.value})}
    466                                 className="w-full px-3 py-2 border rounded-lg text-sm"
    467                             />
    468                           </div>
    469                         </div>
    470                         <button
    471                             onClick={() => setSubmittedFilters({testName: '', patientName: '', testDate: ''})}
    472                             className="mt-4 bg-gray-300 text-gray-700 px-4 py-2 rounded text-sm hover:bg-gray-400"
    473                         >
    474                           Clear Filters
    475                         </button>
    476                       </div>
    477 
    478                       {/* Filtered Results Table */}
    479                       <table className="w-full">
    480                         <thead className="bg-gray-100">
    481                         <tr>
    482                           <th className="px-6 py-3 text-left text-sm font-semibold">Test</th>
    483                           <th className="px-6 py-3 text-left text-sm font-semibold">Patient</th>
    484                           <th className="px-6 py-3 text-left text-sm font-semibold">Test Date</th>
    485                           <th className="px-6 py-3 text-left text-sm font-semibold">Result Date</th>
    486                           <th className="px-6 py-3 text-left text-sm font-semibold">Status</th>
    487                         </tr>
    488                         </thead>
    489                         <tbody>
    490                         {submittedTests
    491                             .filter((test) => {
    492                               const testName = (test.testName || '').toLowerCase();
    493                               const patientName = (test.patientName || '').toLowerCase();
    494                               const testDate = (test.testDate || '');
    495 
    496                               return (
    497                                   testName.includes(submittedFilters.testName.toLowerCase()) &&
    498                                   patientName.includes(submittedFilters.patientName.toLowerCase()) &&
    499                                   (submittedFilters.testDate === '' || testDate === submittedFilters.testDate)
    500                               );
    501                             })
    502                             .map((test, index) => (
    503                                 <tr key={index} className="border-t hover:bg-gray-50">
    504                                   <td className="px-6 py-3 font-medium">{test.testName || test.description || 'Lab Test'}</td>
    505                                   <td className="px-6 py-3">{test.patientName || 'N/A'}</td>
    506                                   <td className="px-6 py-3">{test.testDate || 'N/A'}</td>
    507                                   <td className="px-6 py-3 text-green-600">{test.resultDate || test.createdDate || 'N/A'}</td>
    508                                   <td className="px-6 py-3">
     516                {/* Filtered Results Table */}
     517                <table className="w-full">
     518                  <thead className="bg-gray-100">
     519                    <tr>
     520                      <th className="px-6 py-3 text-left text-sm font-semibold">Test</th>
     521                      <th className="px-6 py-3 text-left text-sm font-semibold">Patient</th>
     522                      <th className="px-6 py-3 text-left text-sm font-semibold">Test Date</th>
     523                      <th className="px-6 py-3 text-left text-sm font-semibold">Result Date</th>
     524                      <th className="px-6 py-3 text-left text-sm font-semibold">Status</th>
     525                    </tr>
     526                  </thead>
     527                  <tbody>
     528                    {submittedTests
     529                      .filter((test) => {
     530                        const testName = (test.testName || '').toLowerCase();
     531                        const patientName = (test.patientName || '').toLowerCase();
     532                        const testDate = (test.testDate || '');
     533
     534                        return (
     535                          testName.includes(submittedFilters.testName.toLowerCase()) &&
     536                          patientName.includes(submittedFilters.patientName.toLowerCase()) &&
     537                          (submittedFilters.testDate === '' || testDate === submittedFilters.testDate)
     538                        );
     539                      })
     540                      .map((test, index) => (
     541                        <tr key={index} className="border-t hover:bg-gray-50">
     542                          <td className="px-6 py-3 font-medium">{test.testName || test.description || 'Lab Test'}</td>
     543                          <td className="px-6 py-3">{test.patientName || 'N/A'}</td>
     544                          <td className="px-6 py-3">{test.testDate || 'N/A'}</td>
     545                          <td className="px-6 py-3 text-green-600">{test.resultDate || test.createdDate || 'N/A'}</td>
     546                          <td className="px-6 py-3">
    509547                            <span className="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm font-semibold">
    510548                              Submitted
    511549                            </span>
    512                                   </td>
    513                                 </tr>
    514                             ))}
    515                         </tbody>
    516                       </table>
    517                     </>
    518                 )}
    519               </div>
     550                          </td>
     551                        </tr>
     552                      ))}
     553                  </tbody>
     554                </table>
     555              </>
     556            )}
     557          </div>
     558        )}
     559      </div>
     560    );
     561  }
     562
     563  return (
     564    <div>
     565      <h1 className="text-3xl font-bold mb-6" style={{ color: '#7c3aed' }}>Lab Tests</h1>
     566
     567      {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
     568
     569      {/* Search Form */}
     570      <div className="bg-white rounded-lg shadow p-6 mb-6">
     571        <h2 className="text-xl font-bold mb-4">Search Patient</h2>
     572        <form onSubmit={handleSearch} className="space-y-4">
     573          <div className="flex gap-4">
     574            <div className="flex-1">
     575              <label className="block text-sm font-semibold mb-2">Patient EMBG</label>
     576              <input
     577                type="text"
     578                value={embg}
     579                onChange={(e) => setEmbg(e.target.value)}
     580                placeholder="e.g., 1402994123456"
     581                className="w-full px-4 py-2 border rounded-lg"
     582              />
     583            </div>
     584            <div className="flex items-end">
     585              <button
     586                type="submit"
     587                disabled={loading}
     588                className="bg-purple-600 text-white px-8 py-2 rounded-full hover:bg-purple-700 disabled:bg-gray-400"
     589              >
     590                {loading ? 'Searching...' : 'Search'}
     591              </button>
     592            </div>
     593          </div>
     594        </form>
     595      </div>
     596
     597      {/* Patient Lab Tests */}
     598      {searched && patient && (
     599        <div className="space-y-6">
     600          {/* Patient Info */}
     601          <div className="bg-white rounded-lg shadow p-6">
     602            <div className="flex justify-between items-start mb-4">
     603              <h2 className="text-2xl font-bold">{patient.firstName} {patient.lastName}</h2>
     604              {!showRequestForm && (
     605                <button
     606                  onClick={() => setShowRequestForm(true)}
     607                  className="bg-green-600 text-white px-4 py-2 rounded hover:bg-green-700"
     608                >
     609                  Request Lab Test
     610                </button>
     611              )}
     612            </div>
     613            <div className="grid grid-cols-4 gap-4">
     614              <div>
     615                <p className="text-sm text-gray-600">EMBG</p>
     616                <p className="font-semibold">{patient.embg}</p>
     617              </div>
     618              <div>
     619                <p className="text-sm text-gray-600">Blood Type</p>
     620                <p className="font-semibold">{patient.bloodType || 'N/A'}</p>
     621              </div>
     622              <div>
     623                <p className="text-sm text-gray-600">Date of Birth</p>
     624                <p className="font-semibold">{patient.dateOfBirth}</p>
     625              </div>
     626            </div>
     627          </div>
     628
     629          {/* Request Lab Test Form */}
     630          {showRequestForm && (
     631            <div className="bg-white rounded-lg shadow p-6">
     632              <h3 className="text-xl font-bold mb-4">Request Lab Test</h3>
     633              <form onSubmit={handleRequestTest} className="space-y-4">
     634                <div className="grid grid-cols-2 gap-4">
     635                  <div>
     636                    <label className="block text-sm font-semibold mb-2">Test</label>
     637                    <select
     638                      value={requestData.testId}
     639                      onChange={(e) => setRequestData({ ...requestData, testId: e.target.value })}
     640                      className="w-full px-4 py-2 border rounded-lg"
     641                      required
     642                    >
     643                      <option value="">Select a test</option>
     644                      {availableTests.map((test) => (
     645                        <option key={test.testId} value={test.testId}>
     646                          {test.testName} (${test.cost})
     647                        </option>
     648                      ))}
     649                    </select>
     650                  </div>
     651                  <div>
     652                    <label className="block text-sm font-semibold mb-2">Test Date</label>
     653                    <input
     654                      type="date"
     655                      value={requestData.testDate}
     656                      onChange={(e) => setRequestData({ ...requestData, testDate: e.target.value })}
     657                      className="w-full px-4 py-2 border rounded-lg"
     658                    />
     659                  </div>
     660                </div>
     661                <div>
     662                  <label className="block text-sm font-semibold mb-2">Notes</label>
     663                  <textarea
     664                    value={requestData.notes}
     665                    onChange={(e) => setRequestData({ ...requestData, notes: e.target.value })}
     666                    placeholder="Additional notes for the lab technician"
     667                    className="w-full px-4 py-2 border rounded-lg"
     668                    rows="3"
     669                  />
     670                </div>
     671                <div className="flex gap-4">
     672                  <button
     673                    type="submit"
     674                    disabled={loading}
     675                    className="bg-green-600 text-white px-6 py-2 rounded hover:bg-green-700 disabled:bg-gray-400"
     676                  >
     677                    {loading ? 'Requesting...' : 'Request Test'}
     678                  </button>
     679                  <button
     680                    type="button"
     681                    onClick={() => setShowRequestForm(false)}
     682                    className="bg-gray-400 text-white px-6 py-2 rounded hover:bg-gray-500"
     683                  >
     684                    Cancel
     685                  </button>
     686                </div>
     687              </form>
     688            </div>
     689          )}
     690
     691          {/* Test Requests */}
     692          {labTestRequests && labTestRequests.length > 0 && (
     693            <div className="bg-white rounded-lg shadow p-6">
     694              <h3 className="text-xl font-bold mb-4">Lab Test Requests</h3>
     695              <div className="space-y-3">
     696                {labTestRequests.map((request) => (
     697                  <div key={request.testId} className="border-l-4 border-purple-500 pl-4 py-2">
     698                    <p className="font-semibold text-lg">{request.testName}</p>
     699                    <p className="text-sm text-gray-600">Requested by: {request.doctorName}</p>
     700                    <p className="text-sm text-gray-600">Test Date: {request.requestDate}</p>
     701                    {request.notes && (
     702                      <p className="text-sm text-gray-600">Notes: {request.notes}</p>
     703                    )}
     704                  </div>
     705                ))}
     706              </div>
     707            </div>
     708          )}
     709
     710          {/* Lab Test Results */}
     711          {labResults && labResults.length > 0 && (
     712            <div className="bg-white rounded-lg shadow p-6">
     713              <h3 className="text-xl font-bold mb-4">Lab Test Results</h3>
     714              <div className="space-y-4">
     715                {labResults.map((result) => (
     716                  <div key={result.resultId} className="border-l-4 border-green-500 pl-4 py-3 bg-green-50 rounded">
     717                    <p className="font-semibold text-lg text-green-700">{result.testName}</p>
     718                    <p className="text-sm text-gray-700 mt-2"><strong>Results:</strong> {result.results}</p>
     719                    <p className="text-sm text-gray-600">Result Date: {result.resultDate}</p>
     720                  </div>
     721                ))}
     722              </div>
     723            </div>
     724          )}
     725
     726          {/* Link to submit results */}
     727          {labTestRequests && labTestRequests.length > 0 && (
     728            <div className="bg-yellow-50 rounded-lg p-6">
     729              <h3 className="text-lg font-semibold text-yellow-800 mb-3">Lab Technician: Submit Test Results</h3>
     730              <p className="text-sm text-gray-700 mb-4">
     731                {labTestRequests.length} test{labTestRequests.length !== 1 ? 's' : ''} awaiting results
     732              </p>
     733              <a
     734                href="/lab-tests/results"
     735                className="inline-block bg-yellow-600 text-white px-6 py-2 rounded hover:bg-yellow-700"
     736              >
     737                Submit Lab Results
     738              </a>
     739            </div>
     740          )}
     741
     742          {/* No requests message */}
     743          {(!labTestRequests || labTestRequests.length === 0) && !labResults?.length && (
     744            <div className="bg-blue-50 rounded-lg p-6 text-center">
     745              <p className="text-gray-600">No lab test requests for this patient</p>
     746            </div>
    520747          )}
    521748        </div>
    522     );
    523   }
    524 
    525   return (
    526       <div>
    527         <h1 className="text-3xl font-bold mb-6" style={{ color: '#7c3aed' }}>Lab Tests</h1>
    528 
    529         {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
    530 
    531         {/* Search Form */}
    532         <div className="bg-white rounded-lg shadow p-6 mb-6">
    533           <h2 className="text-xl font-bold mb-4">Search Patient</h2>
    534           <form onSubmit={handleSearch} className="space-y-4">
    535             <div className="flex gap-4">
    536               <div className="flex-1">
    537                 <label className="block text-sm font-semibold mb-2">Patient EMBG</label>
    538                 <input
    539                     type="text"
    540                     value={embg}
    541                     onChange={(e) => setEmbg(e.target.value)}
    542                     placeholder="e.g., 1402994123456"
    543                     className="w-full px-4 py-2 border rounded-lg"
    544                 />
    545               </div>
    546               <div className="flex items-end">
    547                 <button
    548                     type="submit"
    549                     disabled={loading}
    550                     className="bg-purple-600 text-white px-8 py-2 rounded-full hover:bg-purple-700 disabled:bg-gray-400"
    551                 >
    552                   {loading ? 'Searching...' : 'Search'}
    553                 </button>
    554               </div>
    555             </div>
    556           </form>
     749      )}
     750
     751      {/* No search performed */}
     752      {!searched && (
     753        <div className="bg-gray-50 rounded-lg p-12 text-center">
     754          <p className="text-gray-600 text-lg">Enter a patient EMBG to request lab tests</p>
    557755        </div>
    558 
    559         {/* Patient Lab Tests */}
    560         {searched && patient && (
    561             <div className="space-y-6">
    562               {/* Patient Info */}
    563               <div className="bg-white rounded-lg shadow p-6">
    564                 <div className="flex justify-between items-start mb-4">
    565                   <h2 className="text-2xl font-bold">{patient.firstName} {patient.lastName}</h2>
    566                   {!showRequestForm && (
    567                       <button
    568                           onClick={() => setShowRequestForm(true)}
    569                           className="bg-green-600 text-white px-4 py-2 rounded hover:bg-green-700"
    570                       >
    571                         Request Lab Test
    572                       </button>
    573                   )}
    574                 </div>
    575                 <div className="grid grid-cols-4 gap-4">
    576                   <div>
    577                     <p className="text-sm text-gray-600">EMBG</p>
    578                     <p className="font-semibold">{patient.embg}</p>
    579                   </div>
    580                   <div>
    581                     <p className="text-sm text-gray-600">Blood Type</p>
    582                     <p className="font-semibold">{patient.bloodType || 'N/A'}</p>
    583                   </div>
    584                   <div>
    585                     <p className="text-sm text-gray-600">Date of Birth</p>
    586                     <p className="font-semibold">{patient.dateOfBirth}</p>
    587                   </div>
    588                 </div>
    589               </div>
    590 
    591               {/* Request Lab Test Form */}
    592               {showRequestForm && (
    593                   <div className="bg-white rounded-lg shadow p-6">
    594                     <h3 className="text-xl font-bold mb-4">Request Lab Test</h3>
    595                     <form onSubmit={handleRequestTest} className="space-y-4">
    596                       <div className="grid grid-cols-2 gap-4">
    597                         <div>
    598                           <label className="block text-sm font-semibold mb-2">Test</label>
    599                           <select
    600                               value={requestData.testId}
    601                               onChange={(e) => setRequestData({ ...requestData, testId: e.target.value })}
    602                               className="w-full px-4 py-2 border rounded-lg"
    603                               required
    604                           >
    605                             <option value="">Select a test</option>
    606                             {availableTests.map((test) => (
    607                                 <option key={test.testId} value={test.testId}>
    608                                   {test.testName} (${test.cost})
    609                                 </option>
    610                             ))}
    611                           </select>
    612                         </div>
    613                         <div>
    614                           <label className="block text-sm font-semibold mb-2">Test Date</label>
    615                           <input
    616                               type="date"
    617                               value={requestData.testDate}
    618                               onChange={(e) => setRequestData({ ...requestData, testDate: e.target.value })}
    619                               className="w-full px-4 py-2 border rounded-lg"
    620                           />
    621                         </div>
    622                       </div>
    623                       <div>
    624                         <label className="block text-sm font-semibold mb-2">Notes</label>
    625                         <textarea
    626                             value={requestData.notes}
    627                             onChange={(e) => setRequestData({ ...requestData, notes: e.target.value })}
    628                             placeholder="Additional notes for the lab technician"
    629                             className="w-full px-4 py-2 border rounded-lg"
    630                             rows="3"
    631                         />
    632                       </div>
    633                       <div className="flex gap-4">
    634                         <button
    635                             type="submit"
    636                             disabled={loading}
    637                             className="bg-green-600 text-white px-6 py-2 rounded hover:bg-green-700 disabled:bg-gray-400"
    638                         >
    639                           {loading ? 'Requesting...' : 'Request Test'}
    640                         </button>
    641                         <button
    642                             type="button"
    643                             onClick={() => setShowRequestForm(false)}
    644                             className="bg-gray-400 text-white px-6 py-2 rounded hover:bg-gray-500"
    645                         >
    646                           Cancel
    647                         </button>
    648                       </div>
    649                     </form>
    650                   </div>
    651               )}
    652 
    653               {/* Test Requests */}
    654               {labTestRequests && labTestRequests.length > 0 && (
    655                   <div className="bg-white rounded-lg shadow p-6">
    656                     <h3 className="text-xl font-bold mb-4">Lab Test Requests</h3>
    657                     <div className="space-y-3">
    658                       {labTestRequests.map((request) => (
    659                           <div key={request.testId} className="border-l-4 border-purple-500 pl-4 py-2">
    660                             <p className="font-semibold text-lg">{request.testName}</p>
    661                             <p className="text-sm text-gray-600">Requested by: {request.doctorName}</p>
    662                             <p className="text-sm text-gray-600">Test Date: {request.requestDate}</p>
    663                             {request.notes && (
    664                                 <p className="text-sm text-gray-600">Notes: {request.notes}</p>
    665                             )}
    666                           </div>
    667                       ))}
    668                     </div>
    669                   </div>
    670               )}
    671 
    672               {/* Lab Test Results */}
    673               {labResults && labResults.length > 0 && (
    674                   <div className="bg-white rounded-lg shadow p-6">
    675                     <h3 className="text-xl font-bold mb-4">Lab Test Results</h3>
    676                     <div className="space-y-4">
    677                       {labResults.map((result) => (
    678                           <div key={result.resultId} className="border-l-4 border-green-500 pl-4 py-3 bg-green-50 rounded">
    679                             <p className="font-semibold text-lg text-green-700">{result.testName}</p>
    680                             <p className="text-sm text-gray-700 mt-2"><strong>Results:</strong> {result.results}</p>
    681                             <p className="text-sm text-gray-600">Result Date: {result.resultDate}</p>
    682                           </div>
    683                       ))}
    684                     </div>
    685                   </div>
    686               )}
    687 
    688               {/* Link to submit results */}
    689               {labTestRequests && labTestRequests.length > 0 && (
    690                   <div className="bg-yellow-50 rounded-lg p-6">
    691                     <h3 className="text-lg font-semibold text-yellow-800 mb-3">Lab Technician: Submit Test Results</h3>
    692                     <p className="text-sm text-gray-700 mb-4">
    693                       {labTestRequests.length} test{labTestRequests.length !== 1 ? 's' : ''} awaiting results
    694                     </p>
    695                     <a
    696                         href="/lab-tests/results"
    697                         className="inline-block bg-yellow-600 text-white px-6 py-2 rounded hover:bg-yellow-700"
    698                     >
    699                       Submit Lab Results
    700                     </a>
    701                   </div>
    702               )}
    703 
    704               {/* No requests message */}
    705               {!labTestRequests || labTestRequests.length === 0 && !labResults?.length && (
    706                   <div className="bg-blue-50 rounded-lg p-6 text-center">
    707                     <p className="text-gray-600">No lab test requests for this patient</p>
    708                   </div>
    709               )}
    710             </div>
    711         )}
    712 
    713         {/* No search performed */}
    714         {!searched && (
    715             <div className="bg-gray-50 rounded-lg p-12 text-center">
    716               <p className="text-gray-600 text-lg">Enter a patient EMBG to request lab tests</p>
    717             </div>
    718         )}
    719       </div>
     756      )}
     757    </div>
    720758  );
    721759}
Note: See TracChangeset for help on using the changeset viewer.