├── src
├── vite-env.d.ts
├── index.css
├── main.tsx
├── pages
│ ├── LoginPage.tsx
│ ├── ReportsPage.tsx
│ └── SearchPage.tsx
├── components
│ ├── SearchBar.tsx
│ ├── PulseGraph.tsx
│ ├── ReportsList.tsx
│ ├── Dashboard.tsx
│ ├── LoginForm.tsx
│ ├── Navigation.tsx
│ ├── MedicalHistory.tsx
│ └── ReportUpload.tsx
└── App.tsx
├── .bolt
├── config.json
└── prompt
├── .gitattributes
├── docs
└── report.pdf
├── Output
├── hardware.jpeg
├── Screenshot (315).png
├── Screenshot (316).png
├── Screenshot (317).png
├── Screenshot (318).png
└── Screenshot (319).png
├── postcss.config.js
├── tsconfig.json
├── tailwind.config.js
├── vite.config.ts
├── .gitignore
├── index.html
├── tsconfig.node.json
├── tsconfig.app.json
├── eslint.config.js
├── package.json
├── README.md
└── Arduinocode.ino
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/.bolt/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "bolt-vite-react-ts"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/docs/report.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VichuA2/SmartHealthMonitor/HEAD/docs/report.pdf
--------------------------------------------------------------------------------
/Output/hardware.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VichuA2/SmartHealthMonitor/HEAD/Output/hardware.jpeg
--------------------------------------------------------------------------------
/Output/Screenshot (315).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VichuA2/SmartHealthMonitor/HEAD/Output/Screenshot (315).png
--------------------------------------------------------------------------------
/Output/Screenshot (316).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VichuA2/SmartHealthMonitor/HEAD/Output/Screenshot (316).png
--------------------------------------------------------------------------------
/Output/Screenshot (317).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VichuA2/SmartHealthMonitor/HEAD/Output/Screenshot (317).png
--------------------------------------------------------------------------------
/Output/Screenshot (318).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VichuA2/SmartHealthMonitor/HEAD/Output/Screenshot (318).png
--------------------------------------------------------------------------------
/Output/Screenshot (319).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VichuA2/SmartHealthMonitor/HEAD/Output/Screenshot (319).png
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "./tsconfig.app.json" },
5 | { "path": "./tsconfig.node.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | };
9 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import react from '@vitejs/plugin-react';
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | optimizeDeps: {
8 | exclude: ['lucide-react'],
9 | },
10 | });
11 |
--------------------------------------------------------------------------------
/src/main.tsx:
--------------------------------------------------------------------------------
1 | import { StrictMode } from 'react';
2 | import { createRoot } from 'react-dom/client';
3 | import App from './App.tsx';
4 | import './index.css';
5 |
6 | createRoot(document.getElementById('root')!).render(
7 |
8 |
9 |
10 | );
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.bolt/prompt:
--------------------------------------------------------------------------------
1 | For all designs I ask you to make, have them be beautiful, not cookie cutter. Make webpages that are fully featured and worthy for production.
2 |
3 | By default, this template supports JSX syntax with Tailwind CSS classes, React hooks, and Lucide React for icons. Do not install other packages for UI themes, icons, etc unless absolutely necessary or I request them.
4 |
5 | Use icons from lucide-react for logos.
6 |
7 | Use stock photos from unsplash where appropriate, only valid URLs you know exist. Do not download the images, only link to them in image tags.
8 |
9 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "lib": ["ES2023"],
5 | "module": "ESNext",
6 | "skipLibCheck": true,
7 |
8 | /* Bundler mode */
9 | "moduleResolution": "bundler",
10 | "allowImportingTsExtensions": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | "noEmit": true,
14 |
15 | /* Linting */
16 | "strict": true,
17 | "noUnusedLocals": true,
18 | "noUnusedParameters": true,
19 | "noFallthroughCasesInSwitch": true
20 | },
21 | "include": ["vite.config.ts"]
22 | }
23 |
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "isolatedModules": true,
13 | "moduleDetection": "force",
14 | "noEmit": true,
15 | "jsx": "react-jsx",
16 |
17 | /* Linting */
18 | "strict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noFallthroughCasesInSwitch": true
22 | },
23 | "include": ["src"]
24 | }
25 |
--------------------------------------------------------------------------------
/src/pages/LoginPage.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useNavigate } from 'react-router-dom';
3 | import { LoginForm } from '../components/LoginForm';
4 |
5 | export function LoginPage() {
6 | const navigate = useNavigate();
7 |
8 | const handleLogin = (username: string, password: string) => {
9 | // Simulate login - In a real app, this would make an API call
10 | if (username && password) {
11 | navigate('/dashboard');
12 | }
13 | };
14 |
15 | return (
16 |
17 |
18 |
19 | );
20 | }
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js';
2 | import globals from 'globals';
3 | import reactHooks from 'eslint-plugin-react-hooks';
4 | import reactRefresh from 'eslint-plugin-react-refresh';
5 | import tseslint from 'typescript-eslint';
6 |
7 | export default tseslint.config(
8 | { ignores: ['dist'] },
9 | {
10 | extends: [js.configs.recommended, ...tseslint.configs.recommended],
11 | files: ['**/*.{ts,tsx}'],
12 | languageOptions: {
13 | ecmaVersion: 2020,
14 | globals: globals.browser,
15 | },
16 | plugins: {
17 | 'react-hooks': reactHooks,
18 | 'react-refresh': reactRefresh,
19 | },
20 | rules: {
21 | ...reactHooks.configs.recommended.rules,
22 | 'react-refresh/only-export-components': [
23 | 'warn',
24 | { allowConstantExport: true },
25 | ],
26 | },
27 | }
28 | );
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vite-react-typescript-starter",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "lucide-react": "^0.344.0",
14 | "react": "^18.3.1",
15 | "react-dom": "^18.3.1",
16 | "react-router-dom": "^6.22.3"
17 | },
18 | "devDependencies": {
19 | "@eslint/js": "^9.9.1",
20 | "@types/react": "^18.3.5",
21 | "@types/react-dom": "^18.3.0",
22 | "@vitejs/plugin-react": "^4.3.1",
23 | "autoprefixer": "^10.4.18",
24 | "eslint": "^9.9.1",
25 | "eslint-plugin-react-hooks": "^5.1.0-rc.0",
26 | "eslint-plugin-react-refresh": "^0.4.11",
27 | "globals": "^15.9.0",
28 | "postcss": "^8.4.35",
29 | "tailwindcss": "^3.4.1",
30 | "typescript": "^5.5.3",
31 | "typescript-eslint": "^8.3.0",
32 | "vite": "^5.4.2"
33 | }
34 | }
--------------------------------------------------------------------------------
/src/components/SearchBar.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Search } from 'lucide-react';
3 |
4 | interface SearchBarProps {
5 | onSearch: (id: string) => void;
6 | }
7 |
8 | export function SearchBar({ onSearch }: SearchBarProps) {
9 | const [searchId, setSearchId] = useState('');
10 |
11 | const handleSubmit = (e: React.FormEvent) => {
12 | e.preventDefault();
13 | if (searchId.trim()) {
14 | onSearch(searchId);
15 | }
16 | };
17 |
18 | return (
19 |
37 | );
38 | }
--------------------------------------------------------------------------------
/src/pages/ReportsPage.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { ReportUpload } from '../components/ReportUpload';
3 | import { ReportsList } from '../components/ReportsList';
4 |
5 | export function ReportsPage() {
6 | const [reports, setReports] = useState([
7 | {
8 | id: '1',
9 | type: 'scan',
10 | description: 'Chest X-Ray',
11 | date: '2024-03-15',
12 | fileUrl: '#',
13 | },
14 | {
15 | id: '2',
16 | type: 'prescription',
17 | description: 'Monthly Medication',
18 | date: '2024-03-10',
19 | fileUrl: '#',
20 | },
21 | ]);
22 |
23 | const handleUpload = (file: File, type: string, description: string) => {
24 | // Simulate file upload - In a real app, this would make an API call
25 | const newReport = {
26 | id: String(reports.length + 1),
27 | type,
28 | description,
29 | date: new Date().toISOString().split('T')[0],
30 | fileUrl: URL.createObjectURL(file),
31 | };
32 | setReports([newReport, ...reports]);
33 | };
34 |
35 | return (
36 |
42 | );
43 | }
--------------------------------------------------------------------------------
/src/components/PulseGraph.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Heart } from 'lucide-react';
3 |
4 | interface PulseGraphProps {
5 | currentPulse: number;
6 | }
7 |
8 | export function PulseGraph({ currentPulse }: PulseGraphProps) {
9 | const getPulseStatus = (pulse: number) => {
10 | if (pulse < 60) return 'Low';
11 | if (pulse > 100) return 'High';
12 | return 'Normal';
13 | };
14 |
15 | const getStatusColor = (status: string) => {
16 | switch (status) {
17 | case 'Low':
18 | return 'text-yellow-600';
19 | case 'High':
20 | return 'text-red-600';
21 | default:
22 | return 'text-green-600';
23 | }
24 | };
25 |
26 | const status = getPulseStatus(currentPulse);
27 |
28 | return (
29 |
30 |
31 |
Current Pulse Rate
32 |
33 |
34 |
35 |
{currentPulse}
36 |
BPM
37 |
38 | {status} Heart Rate
39 |
40 |
41 |
42 | );
43 | }
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
3 | import { Navigation } from './components/Navigation';
4 | import { LoginPage } from './pages/LoginPage';
5 | import { SearchPage } from './pages/SearchPage';
6 | import { Dashboard } from './components/Dashboard';
7 | import { ReportsPage } from './pages/ReportsPage';
8 |
9 | export default function App() {
10 | const handleLogout = () => {
11 | // Implement logout logic here
12 | window.location.href = '/';
13 | };
14 |
15 | return (
16 |
17 |
18 |
19 | } />
20 |
24 |
25 |
26 | } />
27 | } />
28 | } />
29 | } />
30 |
31 | >
32 | }
33 | />
34 |
35 |
36 |
37 | );
38 | }
--------------------------------------------------------------------------------
/src/components/ReportsList.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { FileText, Download } from 'lucide-react';
3 |
4 | interface Report {
5 | id: string;
6 | type: string;
7 | description: string;
8 | date: string;
9 | fileUrl: string;
10 | }
11 |
12 | interface ReportsListProps {
13 | reports: Report[];
14 | }
15 |
16 | export function ReportsList({ reports }: ReportsListProps) {
17 | return (
18 |
19 |
Medical Reports
20 |
21 | {reports.map((report) => (
22 |
26 |
27 |
28 |
29 |
{report.description}
30 |
31 | {report.type} • {report.date}
32 |
33 |
34 |
35 |
40 |
41 |
42 |
43 | ))}
44 |
45 |
46 | );
47 | }
--------------------------------------------------------------------------------
/src/components/Dashboard.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { PulseGraph } from './PulseGraph';
3 | import { MedicalHistory } from './MedicalHistory';
4 |
5 | interface DashboardProps {
6 | patientId: string;
7 | }
8 |
9 | export function Dashboard({ patientId }: DashboardProps) {
10 | // Simulated data for demonstration
11 | const currentPulse = 75;
12 | const medicalHistory = [
13 | {
14 | date: '2024-03-15',
15 | diagnosis: 'Regular Checkup',
16 | doctor: 'Dr. Smith',
17 | prescription: 'Vitamins',
18 | },
19 | {
20 | date: '2024-02-28',
21 | diagnosis: 'Mild Fever',
22 | doctor: 'Dr. Johnson',
23 | prescription: 'Paracetamol',
24 | },
25 | {
26 | date: '2024-01-15',
27 | diagnosis: 'Annual Physical',
28 | doctor: 'Dr. Williams',
29 | prescription: 'None',
30 | },
31 | ];
32 |
33 | return (
34 |
35 |
36 |
37 |
Patient ID: {patientId}
38 |
39 |
40 |
41 |
42 |
Quick Stats
43 |
44 |
45 |
Avg. Pulse Rate
46 |
72 BPM
47 |
48 |
49 |
Last Check
50 |
2h ago
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | );
59 | }
--------------------------------------------------------------------------------
/src/components/LoginForm.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { LogIn } from 'lucide-react';
3 |
4 | interface LoginFormProps {
5 | onLogin: (username: string, password: string) => void;
6 | }
7 |
8 | export function LoginForm({ onLogin }: LoginFormProps) {
9 | const [username, setUsername] = useState('');
10 | const [password, setPassword] = useState('');
11 |
12 | const handleSubmit = (e: React.FormEvent) => {
13 | e.preventDefault();
14 | onLogin(username, password);
15 | };
16 |
17 | return (
18 |
19 |
20 |
21 |
Login
22 |
23 |
57 |
58 | );
59 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Smart Health Monitoring System ❤️🩹
2 |
3 | ### A real-time health tracking system using ESP32 and Pulse Sensor. The system monitors pulse rates and displays the data on the Blynk app and a web platform that stores and displays medical history.
4 |
5 |
6 | ## Accessible link ⬇️:
7 | 🌐 https://smarthealthmonitor.netlify.app/
8 | ### ( Username: vishnu , Password : 22ai057 , Patient id : 22ai057 )
9 | ### ( Username: tharani , Password : 22ai055 , Patient id : 22ai055 )
10 | ### ( Username : rohan , Password : 22ai041 , Patient id : 22ai041 )
11 |
12 | ## Features :
13 | - Real-Time Pulse Monitoring: Tracks and displays pulse rate on the Blynk app.
14 | - Web Platform: View past pulse data, medical history, prescriptions, and reports (X-rays, blood tests).
15 | - User Profile: Secure login with Patient ID to access and manage health data.
16 |
17 | ## Technologies:
18 |
19 | Hardware:
20 | - ESP32 Microcontroller
21 | - Pulse Sensor
22 | - Wi-Fi Connectivity
23 |
24 | Software:
25 | - Blynk for real-time data visualization
26 | - Web Platform: Built with HTML, CSS, and JavaScript
27 | - Backend: Node.js/Flask
28 | - Database: MySQL/MongoDB
29 |
30 | ## Installation:
31 |
32 | Hardware Setup
33 | - Connect the Pulse Sensor to the ESP32 (GPIO34).
34 | - Upload the code to the ESP32 using Arduino IDE.
35 |
36 | Software Setup
37 | - Install the Blynk app on your mobile device.
38 | - Create a new project in the Blynk app and use the provided Auth Token to link the ESP32.
39 | - Set up the web platform by following the instructions in the Web Setup section.
40 |
41 | ## Usage:
42 |
43 | - Monitor Pulse: Open the Blynk app to view real-time pulse data.
44 | - Access Medical History: Log in to the web platform using Patient ID to view pulse history, prescriptions, and reports.
45 |
46 | ## Contributing:
47 |
48 | Feel free to fork, clone, and create pull requests. Contributions are welcome!
49 |
--------------------------------------------------------------------------------
/src/components/Navigation.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, useLocation } from 'react-router-dom';
3 | import { Activity, FileText, LogOut, Search } from 'lucide-react';
4 |
5 | interface NavigationProps {
6 | onLogout: () => void;
7 | }
8 |
9 | export function Navigation({ onLogout }: NavigationProps) {
10 | const location = useLocation();
11 |
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 | Smart Health Monitor
20 |
21 |
22 |
23 |
29 |
30 | Search
31 |
32 |
38 | Dashboard
39 |
40 |
46 |
47 | Reports
48 |
49 |
53 |
54 | Logout
55 |
56 |
57 |
58 |
59 |
60 | );
61 | }
--------------------------------------------------------------------------------
/Arduinocode.ino:
--------------------------------------------------------------------------------
1 | #define BLYNK_TEMPLATE_ID "TMPL3U7cpL6MD" // Replace with your Blynk Template ID
2 | #define BLYNK_TEMPLATE_NAME "Pulse BPM"
3 | #define BLYNK_AUTH_TOKEN "Ggl1cp59zomRm0moNL2gQ2BuILQL-Eue" // Replace with your Blynk Auth Token
4 |
5 | #include
6 | #include
7 |
8 | // Wi-Fi credentials
9 | const char* ssid = "vivot15g"; // Replace with your Wi-Fi SSID
10 | const char* password = ""; // Replace with your Wi-Fi password
11 |
12 | // Pulse Sensor Pin
13 | const int pulsePin = 34; // GPIO34 (analog input on ESP32)
14 | volatile int pulseCount = 0; // Counts the pulses
15 | unsigned long lastPulseTime = 0; // Tracks the last pulse time
16 | const int debounceInterval = 100; // Minimum interval between pulses (ms)
17 | unsigned long lastTime = 0;
18 | const int interval = 10000; // Update interval in milliseconds (10 seconds)
19 |
20 | // Interrupt to count pulses with debouncing
21 | void IRAM_ATTR countPulse() {
22 | unsigned long currentTime = millis();
23 | if (currentTime - lastPulseTime > debounceInterval) {
24 | pulseCount++;
25 | lastPulseTime = currentTime;
26 | }
27 | }
28 |
29 | void setup() {
30 | // Start Serial Monitor
31 | Serial.begin(115200);
32 |
33 | // Pulse Sensor Pin Setup
34 | pinMode(pulsePin, INPUT_PULLUP);
35 | attachInterrupt(digitalPinToInterrupt(pulsePin), countPulse, RISING);
36 |
37 | // Connect to Wi-Fi
38 | Serial.print("Connecting to Wi-Fi");
39 | WiFi.begin(ssid, password);
40 | while (WiFi.status() != WL_CONNECTED) {
41 | delay(1000);
42 | Serial.print(".");
43 | }
44 | Serial.println("\nConnected to Wi-Fi");
45 |
46 | // Connect to Blynk
47 | Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);
48 | Serial.println("Connected to Blynk!");
49 | }
50 |
51 | void loop() {
52 | Blynk.run(); // Run Blynk
53 |
54 | unsigned long currentTime = millis();
55 | if (currentTime - lastTime >= interval) {
56 | // Calculate BPM (pulses in 10 seconds * 6 to get BPM)
57 | int bpm = (pulseCount * 12000) / interval;
58 | pulseCount = 0; // Reset pulse count
59 | lastTime = currentTime;
60 |
61 | // Display BPM on Serial Monitor
62 | Serial.print("Pulse BPM: ");
63 | Serial.println(bpm);
64 |
65 | // Send BPM to Blynk (Virtual Pin V1)
66 | Blynk.virtualWrite(V1, bpm);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/components/MedicalHistory.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ClipboardList } from 'lucide-react';
3 |
4 | interface HistoryRecord {
5 | date: string;
6 | diagnosis: string;
7 | doctor: string;
8 | prescription: string;
9 | }
10 |
11 | interface MedicalHistoryProps {
12 | history: HistoryRecord[];
13 | }
14 |
15 | export function MedicalHistory({ history }: MedicalHistoryProps) {
16 | return (
17 |
18 |
19 |
Medical History
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Date
28 |
29 |
30 | Diagnosis
31 |
32 |
33 | Doctor
34 |
35 |
36 | Prescription
37 |
38 |
39 |
40 |
41 | {history.map((record, index) => (
42 |
43 |
44 | {record.date}
45 |
46 |
47 | {record.diagnosis}
48 |
49 |
50 | {record.doctor}
51 |
52 |
53 | {record.prescription}
54 |
55 |
56 | ))}
57 |
58 |
59 |
60 |
61 | );
62 | }
--------------------------------------------------------------------------------
/src/components/ReportUpload.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Upload } from 'lucide-react';
3 |
4 | interface ReportUploadProps {
5 | onUpload: (file: File, type: string, description: string) => void;
6 | }
7 |
8 | export function ReportUpload({ onUpload }: ReportUploadProps) {
9 | const [file, setFile] = useState(null);
10 | const [type, setType] = useState('scan');
11 | const [description, setDescription] = useState('');
12 |
13 | const handleSubmit = (e: React.FormEvent) => {
14 | e.preventDefault();
15 | if (file) {
16 | onUpload(file, type, description);
17 | setFile(null);
18 | setDescription('');
19 | }
20 | };
21 |
22 | return (
23 |
74 | );
75 | }
--------------------------------------------------------------------------------
/src/pages/SearchPage.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useNavigate } from 'react-router-dom';
3 | import { SearchBar } from '../components/SearchBar';
4 | import { Activity, Heart, ClipboardList, Brain } from 'lucide-react';
5 |
6 | export function SearchPage() {
7 | const navigate = useNavigate();
8 |
9 | const handleSearch = (patientId: string) => {
10 | navigate(`/dashboard?id=${patientId}`);
11 | };
12 |
13 | return (
14 |
15 |
16 |
36 |
37 |
38 |
43 |
48 |
53 |
54 |
55 |
56 | );
57 | }
58 |
59 | interface FeatureCardProps {
60 | icon: React.ElementType;
61 | title: string;
62 | description: string;
63 | }
64 |
65 | function FeatureCard({ icon: Icon, title, description }: FeatureCardProps) {
66 | return (
67 |
68 |
69 |
70 |
71 |
{title}
72 |
{description}
73 |
74 | );
75 | }
--------------------------------------------------------------------------------