diff --git a/package-lock.json b/package-lock.json index 511d160..2868ca2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,12 @@ "dependencies": { "cra-template": "1.2.0", "react": "^18.2.0", + "react-datepicker": "^4.8.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1" + }, + "devDependencies": { + "web-vitals": "^3.0.4" } }, "node_modules/@ampproject/remapping": { @@ -3058,6 +3062,15 @@ } } }, + "node_modules/@popperjs/core": { + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -5089,6 +5102,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "node_modules/clean-css": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", @@ -5784,6 +5802,18 @@ "node": ">=10" } }, + "node_modules/date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -13297,6 +13327,23 @@ "node": ">=14" } }, + "node_modules/react-datepicker": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.8.0.tgz", + "integrity": "sha512-u69zXGHMpxAa4LeYR83vucQoUCJQ6m/WBsSxmUMu/M8ahTSVMMyiyQzauHgZA2NUr9y0FUgOAix71hGYUb6tvg==", + "dependencies": { + "@popperjs/core": "^2.9.2", + "classnames": "^2.2.6", + "date-fns": "^2.24.0", + "prop-types": "^15.7.2", + "react-onclickoutside": "^6.12.0", + "react-popper": "^2.2.5" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17 || ^18", + "react-dom": "^16.9.0 || ^17 || ^18" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -13431,11 +13478,43 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-onclickoutside": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.12.2.tgz", + "integrity": "sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA==", + "funding": { + "type": "individual", + "url": "https://github.com/Pomax/react-onclickoutside/blob/master/FUNDING.md" + }, + "peerDependencies": { + "react": "^15.5.x || ^16.x || ^17.x || ^18.x", + "react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x" + } + }, + "node_modules/react-popper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", + "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", + "dependencies": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + }, + "peerDependencies": { + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17 || ^18", + "react-dom": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -15326,6 +15405,14 @@ "makeerror": "1.0.12" } }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -15346,6 +15433,12 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/web-vitals": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.0.4.tgz", + "integrity": "sha512-Yau8qf1AJ/dm6MY180Bi0qpCIuWmAfKAnOqmxLecGfIHn0+ND3H4JOhXeY73Pyi9zjSF5J4SNUewHLNUzU7mmA==", + "dev": true + }, "node_modules/webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -18250,6 +18343,11 @@ "source-map": "^0.7.3" } }, + "@popperjs/core": { + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -19761,6 +19859,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, + "classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "clean-css": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", @@ -20259,6 +20362,11 @@ "whatwg-url": "^8.0.0" } }, + "date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -25509,6 +25617,19 @@ "whatwg-fetch": "^3.6.2" } }, + "react-datepicker": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.8.0.tgz", + "integrity": "sha512-u69zXGHMpxAa4LeYR83vucQoUCJQ6m/WBsSxmUMu/M8ahTSVMMyiyQzauHgZA2NUr9y0FUgOAix71hGYUb6tvg==", + "requires": { + "@popperjs/core": "^2.9.2", + "classnames": "^2.2.6", + "date-fns": "^2.24.0", + "prop-types": "^15.7.2", + "react-onclickoutside": "^6.12.0", + "react-popper": "^2.2.5" + } + }, "react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -25609,11 +25730,31 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "react-onclickoutside": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.12.2.tgz", + "integrity": "sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA==", + "requires": {} + }, + "react-popper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", + "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", + "requires": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + } + }, "react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -27003,6 +27144,14 @@ "makeerror": "1.0.12" } }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -27020,6 +27169,12 @@ "minimalistic-assert": "^1.0.0" } }, + "web-vitals": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.0.4.tgz", + "integrity": "sha512-Yau8qf1AJ/dm6MY180Bi0qpCIuWmAfKAnOqmxLecGfIHn0+ND3H4JOhXeY73Pyi9zjSF5J4SNUewHLNUzU7mmA==", + "dev": true + }, "webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", diff --git a/package.json b/package.json index 7ad0538..7a1273c 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "cra-template": "1.2.0", "react": "^18.2.0", + "react-datepicker": "^4.8.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1" }, @@ -31,5 +32,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "web-vitals": "^3.0.4" } } diff --git a/src/App.js b/src/App.js index 4d333f8..0202e58 100644 --- a/src/App.js +++ b/src/App.js @@ -1,12 +1,18 @@ import './App.css'; +import Patients from './pages/patients'; +import Search from './pages/Search'; +import Login from './pages/login'; +import Signup from './pages/Signup'; + +function App() { + -const App = ()=>{ - // State here return (
- {/* Add new patient FORM */} - {/* Search input */} - {/* Table */} + + + +
); } diff --git a/src/Components/Button.jsx b/src/Components/Button.jsx new file mode 100644 index 0000000..43c2d3d --- /dev/null +++ b/src/Components/Button.jsx @@ -0,0 +1,3 @@ +export const Button = ({onClick, children})=>{ + return ; +} \ No newline at end of file diff --git a/src/Components/PatientCard.jsx b/src/Components/PatientCard.jsx new file mode 100644 index 0000000..ea442ac --- /dev/null +++ b/src/Components/PatientCard.jsx @@ -0,0 +1,22 @@ +import { Button } from "./Button"; + +const PCard = (props)=>{ + const helloFunc = ()=>alert('Hello') + console.log(props) + const patient = props.data + //let cls = patient.gender == 'm'?'bg-blue':'bg-pink'; + return
+
+
+

{patient.full_name}

+
+
+

{patient.gender}

+
+

{patient.phone}

+
+
+} + + +export default PCard; \ No newline at end of file diff --git a/src/pages/Patient.js b/src/pages/Patient.js new file mode 100644 index 0000000..765b766 --- /dev/null +++ b/src/pages/Patient.js @@ -0,0 +1,18 @@ +import { useEffect } from "react"; +import { useParams } from "react-router-dom"; + +export const Patient = (props)=>{ + + const par = useParams() + + useEffect(() => { + // call api + // paitents/id GET via, axios.get('URL/patients/id').then(res) + // response + // change state + return () => { + + }; + }, []); + return

Patient Profile: {par.id}

; +} \ No newline at end of file diff --git a/src/pages/Search.js b/src/pages/Search.js new file mode 100644 index 0000000..4068f28 --- /dev/null +++ b/src/pages/Search.js @@ -0,0 +1,37 @@ +import React, {useState} from 'react' +import PATIENTS from './patients' + +const SearchBar = () => { + const [searchInput, setSearchInput] = useState(""); + + const handleChange = (e) => { + e.preventDefault(); + setSearchInput(e.target.value); + }; + if (searchInput.length > 0) { + PATIENTS.filter((Patient) => { + return Patient.full_name.match(searchInput); + }); + } + +return
+ + + + { + PATIENTS && PATIENTS.map((item,index)=>{ + return + + + + + + }) + } + +
{item.full_name}{item.phone}{item.birth_date}{item.gender}
+
+}; + +export default SearchBar; + diff --git a/src/pages/Signup.js b/src/pages/Signup.js new file mode 100644 index 0000000..4a327af --- /dev/null +++ b/src/pages/Signup.js @@ -0,0 +1,82 @@ +import React from 'react'; + +export default function Signup() { + return ( +
+ +
+ + +
+

+ Sign Up +

+
+
+ + +
+ +
+ + +
+
+ + +
+ + Forget Password? + +
+ +
+
+ +

+ {" "} + You already have an account?{" "} + + Sign In + +

+
+
+
+ ); +} diff --git a/src/pages/history.js b/src/pages/history.js new file mode 100644 index 0000000..f6c0b14 --- /dev/null +++ b/src/pages/history.js @@ -0,0 +1,23 @@ +import { Button } from "../components/Button"; +const History = ()=>{ + const alertFunc = ()=> alert('We Will Back Soon. Thank You') + return
+ +
+} + +export default History; \ No newline at end of file diff --git a/src/pages/layout.js b/src/pages/layout.js new file mode 100644 index 0000000..88e5923 --- /dev/null +++ b/src/pages/layout.js @@ -0,0 +1,72 @@ +import { NavLink, Outlet } from "react-router-dom"; +import searchBar from './Search'; + +export default function Layout(){ + return <> +
+ +
+ +
+
+ +
+
+ + +} + diff --git a/src/pages/login.js b/src/pages/login.js new file mode 100644 index 0000000..8055a39 --- /dev/null +++ b/src/pages/login.js @@ -0,0 +1,70 @@ +import React from 'react'; + +export default function Login() { + return ( +
+

+ Digitalize Clinic +

+
+ + +
+

+ Sign in +

+
+
+ + +
+
+ + +
+ + Forget Password? + +
+ +
+
+ +

+ {" "} + Don't have an account?{" "} + + Sign up + +

+
+
+
+ ); +} diff --git a/src/pages/patients.js b/src/pages/patients.js new file mode 100644 index 0000000..2521830 --- /dev/null +++ b/src/pages/patients.js @@ -0,0 +1,132 @@ +import { useState } from "react" +import DatePicker from "react-datepicker"; +import 'react-datepicker/dist/react-datepicker.css' +import PCard from "../components/PatientCard"; + + +const PATIENTS = [ + { + id:1, + full_name:"Ali Ahmed", + birth_date:"10/10/1999", + gender:"m", + phone:"+96477889654" + }, + { + id:2, + full_name:"Ameer Saad", + birth_date:"10/10/2000", + gender:"m", + phone:"+96477809654" + }, + { + id:3, + full_name:"Muna Ali", + birth_date:"10/10/1998", + gender:"f", + phone:"+964777809654" + } +]; +const Patients = (props)=>{ + const [patients, setPatients] = useState(PATIENTS) + const [fullName , setFullName] = useState('') + const [PhoneNo, setPhoneNo] = useState('') + const [BirthDay, setBirthDay] = useState(new Date()) + const [gender, setGender] = useState('m') + const [selectedDate, setSelectedDate] = useState(null) + + + + const addNew = ()=>{ + if(!fullName) + { + alert('Please fill your name') + return + } + let pTemp = !patients?[]:patients + pTemp.push({ + id:4, + full_name:fullName, + birth_date:BirthDay, + gender:gender, + phone:PhoneNo + }) + + setPatients([...pTemp]) + } + + const changeFullName = (e)=>{ + let v = e.target.value + console.log(v) + setFullName(v) + } + + const changePhoneNo = (e)=>{ + let PN = e.target.value + setPhoneNo(PN) + } + + const genderOnChange = (e)=>{ + setGender(e.target.value) + } + + const submit = (e)=>{ + e.preventDefault() + addNew() + } + + return
+
+
+ +
+
+ +
+
+ setSelectedDate(date)} + placeholderText={'dd/mm/yyyy'} + filterDate={date => date.getDay() !== 6 && date.getDay() !== 0} + showYearDropdown + scrollableYearDropdown/> +
+
+ +
+ + + +
+
+ + + + + + + + + + + { + patients && patients.map((item,index)=>{ + return + + + + + + }) + } + +
Patient Full NamePhone NumberBirthdayGender
{item.full_name}{item.phone}{item.birth_date}{item.gender}
+
+
+} + +export default Patients; \ No newline at end of file