├── 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 |
20 |
21 | setSearchId(e.target.value)} 25 | placeholder="Enter your Patient ID" 26 | className="w-full px-4 py-3 pl-12 text-gray-700 bg-white border rounded-lg focus:outline-none focus:border-blue-500" 27 | /> 28 | 29 | 35 |
36 |
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 |
37 |
38 | 39 | 40 |
41 |
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 |
24 |
25 | 28 | setUsername(e.target.value)} 33 | className="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" 34 | required 35 | /> 36 |
37 |
38 | 41 | setPassword(e.target.value)} 46 | className="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" 47 | required 48 | /> 49 |
50 | 56 |
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 | Smart Health Monitor Screenshot Smart Health Monitor Screenshot 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 | 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 | 29 | 32 | 35 | 38 | 39 | 40 | 41 | {history.map((record, index) => ( 42 | 43 | 46 | 49 | 52 | 55 | 56 | ))} 57 | 58 |
27 | Date 28 | 30 | Diagnosis 31 | 33 | Doctor 34 | 36 | Prescription 37 |
44 | {record.date} 45 | 47 | {record.diagnosis} 48 | 50 | {record.doctor} 51 | 53 | {record.prescription} 54 |
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 |
24 |

Upload New Report

25 |
26 |
27 | 30 | 40 |
41 |
42 | 45 | setDescription(e.target.value)} 49 | className="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" 50 | placeholder="Brief description of the report" 51 | required 52 | /> 53 |
54 |
55 | 58 | setFile(e.target.files?.[0] || null)} 61 | className="w-full" 62 | required 63 | /> 64 |
65 | 72 |
73 |
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 |
17 |

18 | Smart Health Monitoring System 19 |

20 |

21 | Enter your Patient ID to access your health records 22 |

23 |
24 | 25 |
26 | 32 | 33 | Live Pulse Rate Monitor 34 | 35 |
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 | } --------------------------------------------------------------------------------