From 81f0244c840743d8b10e2651ef6028dbbdb4d23d Mon Sep 17 00:00:00 2001 From: Gabriel Dinkel Date: Wed, 19 Jul 2023 10:03:29 -0300 Subject: [PATCH 1/2] Initial commit --- public/index.html | 3 +- src/App.css | 46 +++++++-------------------- src/App.test.tsx | 6 ++-- src/App.tsx | 28 ++++++----------- src/assets/stethoscope.svg | 25 +++++++++++++++ src/components/Appointment.css | 13 ++++++++ src/components/Appointment.tsx | 20 ++++++++++++ src/components/Clinic.css | 10 ++++++ src/components/Clinic.tsx | 50 ++++++++++++++++++++++++++++++ src/components/Login.css | 0 src/components/Login.tsx | 33 ++++++++++++++++++++ src/components/Provider.css | 16 ++++++++++ src/components/Provider.tsx | 21 +++++++++++++ src/components/Schedule.css | 15 +++++++++ src/components/Schedule.tsx | 22 +++++++++++++ src/components/StethoscopeIcon.css | 7 +++++ src/components/StethoscopeIcon.tsx | 13 ++++++++ src/index.tsx | 38 ++++++++++++----------- src/pages/Appointments.css | 3 ++ src/pages/Appointments.tsx | 46 +++++++++++++++++++++++++++ src/store/auth-context.tsx | 49 +++++++++++++++++++++++++++++ 21 files changed, 389 insertions(+), 75 deletions(-) create mode 100644 src/assets/stethoscope.svg create mode 100644 src/components/Appointment.css create mode 100644 src/components/Appointment.tsx create mode 100644 src/components/Clinic.css create mode 100644 src/components/Clinic.tsx create mode 100644 src/components/Login.css create mode 100644 src/components/Login.tsx create mode 100644 src/components/Provider.css create mode 100644 src/components/Provider.tsx create mode 100644 src/components/Schedule.css create mode 100644 src/components/Schedule.tsx create mode 100644 src/components/StethoscopeIcon.css create mode 100644 src/components/StethoscopeIcon.tsx create mode 100644 src/pages/Appointments.css create mode 100644 src/pages/Appointments.tsx create mode 100644 src/store/auth-context.tsx diff --git a/public/index.html b/public/index.html index aa069f2..1f8c861 100644 --- a/public/index.html +++ b/public/index.html @@ -24,7 +24,8 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + + ZoomCare diff --git a/src/App.css b/src/App.css index 74b5e05..b487773 100644 --- a/src/App.css +++ b/src/App.css @@ -1,38 +1,16 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} +@import url(https://db.onlinewebfonts.com/c/924ee4158324c02e3e0d62e54cafd14f?family=Gotham+Book); -.App-link { - color: #61dafb; +@font-face { + font-family: "Gotham Book"; + src: url("https://db.onlinewebfonts.com/t/924ee4158324c02e3e0d62e54cafd14f.eot"); + src: url("https://db.onlinewebfonts.com/t/924ee4158324c02e3e0d62e54cafd14f.eot?#iefix")format("embedded-opentype"), + url("https://db.onlinewebfonts.com/t/924ee4158324c02e3e0d62e54cafd14f.woff2")format("woff2"), + url("https://db.onlinewebfonts.com/t/924ee4158324c02e3e0d62e54cafd14f.woff")format("woff"), + url("https://db.onlinewebfonts.com/t/924ee4158324c02e3e0d62e54cafd14f.ttf")format("truetype"), + url("https://db.onlinewebfonts.com/t/924ee4158324c02e3e0d62e54cafd14f.svg#Gotham Book")format("svg"); } -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } +#root { + color: #191E31; + font-family: "Gotham Book"; } diff --git a/src/App.test.tsx b/src/App.test.tsx index 2a68616..5f98815 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -2,8 +2,8 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import App from './App'; -test('renders learn react link', () => { +test('renders Appointments App', () => { render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); + const headerElement = screen.getByText(/Appointments App/i); + expect(headerElement).toBeInTheDocument(); }); diff --git a/src/App.tsx b/src/App.tsx index a53698a..34095ac 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,25 +1,15 @@ -import React from 'react'; -import logo from './logo.svg'; +import React, { FC } from 'react'; +import Appointments from './pages/Appointments'; import './App.css'; +import Login from './components/Login'; -function App() { +const App: FC = () => { return ( -
-
- logo -

- Edit src/App.tsx and save to reload. -

- - Learn React - -
-
+ <> +

Appointments App

+ + + ); } diff --git a/src/assets/stethoscope.svg b/src/assets/stethoscope.svg new file mode 100644 index 0000000..e75026f --- /dev/null +++ b/src/assets/stethoscope.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/Appointment.css b/src/components/Appointment.css new file mode 100644 index 0000000..25ca008 --- /dev/null +++ b/src/components/Appointment.css @@ -0,0 +1,13 @@ +.appointment-container { + border: 1px solid #A1A1A1; + border-bottom: none; + padding: 20px 24px; + cursor: pointer; +} +.appointment-container:nth-last-child(-n+1) { + border-bottom: 1px solid #A1A1A1 !important; +} +.appointment-container:hover .container { + transform: translate(-20px, -40px) rotate(-15deg) scale(1.1); + box-shadow: 0 3px 10px rgb(0 0 0 / 0.2); +} \ No newline at end of file diff --git a/src/components/Appointment.tsx b/src/components/Appointment.tsx new file mode 100644 index 0000000..18f5290 --- /dev/null +++ b/src/components/Appointment.tsx @@ -0,0 +1,20 @@ +import React, { FC } from 'react'; +import { AppointmentSlot } from '../zoomcare-api'; +import ClinicComponent from './Clinic'; +import ProviderComponent from './Provider'; +import Schedule from './Schedule'; +import './Appointment.css'; + +const AppointmentComponent:FC<{appointment:AppointmentSlot}> = ({appointment}) => { + + return ( +
+ + + + +
+ ) +} + +export default AppointmentComponent; \ No newline at end of file diff --git a/src/components/Clinic.css b/src/components/Clinic.css new file mode 100644 index 0000000..a5a371b --- /dev/null +++ b/src/components/Clinic.css @@ -0,0 +1,10 @@ +H1 { + color: #293A41; + font-size: 15px; +} +.address { + font-size: 12px; +} +.clinic-container { + padding-bottom: 16px; +} \ No newline at end of file diff --git a/src/components/Clinic.tsx b/src/components/Clinic.tsx new file mode 100644 index 0000000..d744032 --- /dev/null +++ b/src/components/Clinic.tsx @@ -0,0 +1,50 @@ +import React, { FC, useEffect, useState, useContext } from "react"; +import useFetch from "use-http"; +import AuthContext from "../store/auth-context"; +import { Clinic } from "../zoomcare-api"; +import "./Clinic.css"; + +const ClinicComponent: FC<{ clinicId: number }> = ({ clinicId }) => { + const ctx = useContext(AuthContext); + + const [clinic, setClinic] = useState({ + id: 0, + name: "", + address: "", + city: "", + state: "", + zipcode: "", + }); + const { get, response, loading, error } = useFetch("api", { + headers: { Authorization: ctx.token }, + }); + + useEffect(() => { + async function loadClinic() { + const clinic = await get(`/clinics/${clinicId}`); + if (response.ok) setClinic(clinic); + } + loadClinic(); + }, [clinicId, get, response.ok]); + + if (error) { + return null; + } + + return ( + <> + {loading && "Loading..."} + {clinic.id && ( +
+

{clinic.name}

+
{clinic.address}
+
+ {clinic.city}, {clinic.state} {clinic.zipcode} +
+
+ )} + + ); +}; + +export default ClinicComponent; diff --git a/src/components/Login.css b/src/components/Login.css new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Login.tsx b/src/components/Login.tsx new file mode 100644 index 0000000..ee7b7ad --- /dev/null +++ b/src/components/Login.tsx @@ -0,0 +1,33 @@ +import React, { FC, useEffect, useContext } from "react"; +import useFetch from "use-http"; +import AuthContext from "../store/auth-context"; + +const Login: FC = () => { + const ctx = useContext(AuthContext); + + const username = "username"; + const password = "password"; + + const { post, response, loading, error } = useFetch("/api"); + async function logUser() { + const user = await post("/login", { + username, + password, + }); + if (response.ok) { + ctx.onLogin(user.authToken, user.username); + } + } + useEffect(() => { + logUser(); + }, []); + + return ( + <> + {error && "Error!"} + {loading && "Loading..."} + + ); +}; + +export default Login; diff --git a/src/components/Provider.css b/src/components/Provider.css new file mode 100644 index 0000000..595d4c6 --- /dev/null +++ b/src/components/Provider.css @@ -0,0 +1,16 @@ +.provider-container { + display: flex; +} +.provider-info { + display: flex; + flex-direction: column; + justify-content: center; + padding-left: 16px; +} +.provider-info h1 { + color: #1CB6E3; +} +.provider-info p { + font-size: 12px; + margin-top: 0; +} \ No newline at end of file diff --git a/src/components/Provider.tsx b/src/components/Provider.tsx new file mode 100644 index 0000000..c24b9c2 --- /dev/null +++ b/src/components/Provider.tsx @@ -0,0 +1,21 @@ +import React, { FC } from 'react'; +import { Provider } from '../zoomcare-api'; +import StethoscopeIcon from './StethoscopeIcon'; +import './Provider.css'; + +const ProviderComponent:FC<{provider: Provider}> = ({ provider, children }) => { + return ( +
+
+ +
+
+

{provider.name}, {provider.credentials}

+

{provider.phoneNumber}

+
{children}
+
+
+ ) +} + +export default ProviderComponent; \ No newline at end of file diff --git a/src/components/Schedule.css b/src/components/Schedule.css new file mode 100644 index 0000000..14dacc5 --- /dev/null +++ b/src/components/Schedule.css @@ -0,0 +1,15 @@ +.schedule-container { + display: flex; + gap: 10px; +} +.box { + width: 110px; + height: 37px; + background-color: #293A41; + color: #ffffff; + font-weight: bolder; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; +} diff --git a/src/components/Schedule.tsx b/src/components/Schedule.tsx new file mode 100644 index 0000000..daf6746 --- /dev/null +++ b/src/components/Schedule.tsx @@ -0,0 +1,22 @@ +import React, { FC } from 'react'; +import './Schedule.css'; + +type ScheduleData = { + startTime: string; + durationInMinutes: number; +} + +const Schedule: FC = ({startTime, durationInMinutes}) => { + const startDate = new Date(startTime.substring(0,16)); + const endDate = new Date(startDate.getTime() + durationInMinutes*60000); + const formattedStartTime = startDate.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) + const formattedEndTime = endDate.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) + + return ( +
+
{formattedStartTime}
{formattedEndTime}
+
+ ) +} + +export default Schedule; \ No newline at end of file diff --git a/src/components/StethoscopeIcon.css b/src/components/StethoscopeIcon.css new file mode 100644 index 0000000..d72233e --- /dev/null +++ b/src/components/StethoscopeIcon.css @@ -0,0 +1,7 @@ +.container { + width: 110px; + height: 110px; + padding: 20px 10px 20px 30px; + background-color: #EEEEEE; + border-radius: 50%; +} \ No newline at end of file diff --git a/src/components/StethoscopeIcon.tsx b/src/components/StethoscopeIcon.tsx new file mode 100644 index 0000000..b4705b8 --- /dev/null +++ b/src/components/StethoscopeIcon.tsx @@ -0,0 +1,13 @@ +import React, { FC } from 'react'; +import { ReactComponent as StethoscopeSVG } from '../assets/stethoscope.svg' +import './StethoscopeIcon.css'; + +const StethoscopeIcon:FC = () => { + return ( +
+ +
+ ) +} + +export default StethoscopeIcon; \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index a0b33b5..7a31a22 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,26 +1,28 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import './index.css'; -import App from './App'; -import reportWebVitals from './reportWebVitals'; -import {worker} from "./mocks/browser"; - -worker.start({ - onUnhandledRequest: "bypass" -}) -.then(() => { +import React from "react"; +import ReactDOM from "react-dom"; +import "./index.css"; +import App from "./App"; +import reportWebVitals from "./reportWebVitals"; +import { worker } from "./mocks/browser"; +import { AuthContextProvider } from "./store/auth-context"; +worker + .start({ + onUnhandledRequest: "bypass", + }) + .then(() => { ReactDOM.render( - - - , - document.getElementById('root') + + + + + , + document.getElementById("root") ); - // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals(); -}).catch(console.error) - + }) + .catch(console.error); diff --git a/src/pages/Appointments.css b/src/pages/Appointments.css new file mode 100644 index 0000000..b1d8b73 --- /dev/null +++ b/src/pages/Appointments.css @@ -0,0 +1,3 @@ +.appointments-container { + padding: 24px; +} \ No newline at end of file diff --git a/src/pages/Appointments.tsx b/src/pages/Appointments.tsx new file mode 100644 index 0000000..ff8a343 --- /dev/null +++ b/src/pages/Appointments.tsx @@ -0,0 +1,46 @@ +import React, { FC, useEffect, useState, useContext } from "react"; +import useFetch from "use-http"; +import AuthContext from "../store/auth-context"; +import { AppointmentSlot } from "../zoomcare-api"; +import AppointmentComponent from "../components/Appointment"; +import "./Appointments.css"; + +const Appointments: FC = () => { + const ctx = useContext(AuthContext); + + const [appointments, setAppointments] = useState([]); + + // const options = { method: "GET", headers: { "Authorization": ctx.token } }; + // console.log(options); + // const { + // loading, + // error, + // data = [], + // } = useFetch("/api/appointments", options, []); + + // console.log(data); + const { get, response, loading, error } = useFetch("api", { + headers: { Authorization: ctx.token }, + }); + + useEffect(() => { + loadAppointments(); + }, []); + + async function loadAppointments() { + const { appointmentSlots } = await get(`/appointments`); + console.log('appointments: ', appointmentSlots); + if (response.ok) setAppointments(appointmentSlots); + } + return ( +
+ {error && "Error!"} + {loading && "Loading..."} + {appointments.map((appointment) => ( + + ))} +
+ ); +}; + +export default Appointments; diff --git a/src/store/auth-context.tsx b/src/store/auth-context.tsx new file mode 100644 index 0000000..b2f2bf0 --- /dev/null +++ b/src/store/auth-context.tsx @@ -0,0 +1,49 @@ +import React, { useState, useEffect, FC } from 'react'; + +const AuthContext = React.createContext({ + token: '', + username: '', + onLogout: () => {}, + onLogin: (token: string, username: string) => {} +}); + +export const AuthContextProvider: FC = (props) => { + const [token, setToken] = useState(''); + const [username, setUsername] = useState(''); + + useEffect(() => { + const storedTokenInformation = localStorage.getItem('token'); + const storedUserInformation = localStorage.getItem('username'); + setToken(storedTokenInformation ? storedTokenInformation : ''); + setUsername(storedUserInformation ? storedUserInformation : ''); + }, []); + + const logoutHandler = () => { + localStorage.removeItem('token'); + localStorage.removeItem('username'); + setToken(''); + setUsername(''); + }; + + const loginHandler = (token: string, username: string) => { + localStorage.setItem('token', token); + localStorage.setItem('username', username); + setToken(token); + setUsername(username); + }; + + return ( + + {props.children} + + ); +}; + +export default AuthContext; \ No newline at end of file From e4e2498a775faf3ad7753dad7cc6430c14a3d5dc Mon Sep 17 00:00:00 2001 From: Gabriel Dinkel Date: Wed, 19 Jul 2023 10:18:28 -0300 Subject: [PATCH 2/2] Format documents for better reading --- src/App.tsx | 16 +++++------ src/components/Appointment.css | 18 ++++++------ src/components/Appointment.tsx | 40 ++++++++++++++------------ src/components/Clinic.css | 12 ++++---- src/components/Clinic.tsx | 6 ++-- src/components/Provider.css | 18 ++++++------ src/components/Provider.tsx | 45 ++++++++++++++++++------------ src/components/Schedule.css | 22 +++++++-------- src/components/Schedule.tsx | 45 +++++++++++++++++++----------- src/components/StethoscopeIcon.css | 12 ++++---- src/components/StethoscopeIcon.tsx | 22 +++++++-------- src/pages/Appointments.css | 4 +-- src/pages/Appointments.tsx | 11 +------- 13 files changed, 144 insertions(+), 127 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 34095ac..8267e3f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,16 +1,16 @@ -import React, { FC } from 'react'; -import Appointments from './pages/Appointments'; -import './App.css'; -import Login from './components/Login'; +import React, { FC } from "react"; +import Appointments from "./pages/Appointments"; +import "./App.css"; +import Login from "./components/Login"; const App: FC = () => { return ( <> -

Appointments App

- - +

Appointments App

+ + ); -} +}; export default App; diff --git a/src/components/Appointment.css b/src/components/Appointment.css index 25ca008..9de603f 100644 --- a/src/components/Appointment.css +++ b/src/components/Appointment.css @@ -1,13 +1,13 @@ .appointment-container { - border: 1px solid #A1A1A1; - border-bottom: none; - padding: 20px 24px; - cursor: pointer; + border: 1px solid #a1a1a1; + border-bottom: none; + padding: 20px 24px; + cursor: pointer; } -.appointment-container:nth-last-child(-n+1) { - border-bottom: 1px solid #A1A1A1 !important; +.appointment-container:nth-last-child(-n + 1) { + border-bottom: 1px solid #a1a1a1 !important; } .appointment-container:hover .container { - transform: translate(-20px, -40px) rotate(-15deg) scale(1.1); - box-shadow: 0 3px 10px rgb(0 0 0 / 0.2); -} \ No newline at end of file + transform: translate(-20px, -40px) rotate(-15deg) scale(1.1); + box-shadow: 0 3px 10px rgb(0 0 0 / 0.2); +} diff --git a/src/components/Appointment.tsx b/src/components/Appointment.tsx index 18f5290..e5e49d2 100644 --- a/src/components/Appointment.tsx +++ b/src/components/Appointment.tsx @@ -1,20 +1,24 @@ -import React, { FC } from 'react'; -import { AppointmentSlot } from '../zoomcare-api'; -import ClinicComponent from './Clinic'; -import ProviderComponent from './Provider'; -import Schedule from './Schedule'; -import './Appointment.css'; +import React, { FC } from "react"; +import { AppointmentSlot } from "../zoomcare-api"; +import ClinicComponent from "./Clinic"; +import ProviderComponent from "./Provider"; +import Schedule from "./Schedule"; +import "./Appointment.css"; -const AppointmentComponent:FC<{appointment:AppointmentSlot}> = ({appointment}) => { - - return ( -
- - - - -
- ) -} +const AppointmentComponent: FC<{ appointment: AppointmentSlot }> = ({ + appointment, +}) => { + return ( +
+ + + + +
+ ); +}; -export default AppointmentComponent; \ No newline at end of file +export default AppointmentComponent; diff --git a/src/components/Clinic.css b/src/components/Clinic.css index a5a371b..c1074a7 100644 --- a/src/components/Clinic.css +++ b/src/components/Clinic.css @@ -1,10 +1,10 @@ -H1 { - color: #293A41; - font-size: 15px; +h1 { + color: #293a41; + font-size: 15px; } .address { - font-size: 12px; + font-size: 12px; } .clinic-container { - padding-bottom: 16px; -} \ No newline at end of file + padding-bottom: 16px; +} diff --git a/src/components/Clinic.tsx b/src/components/Clinic.tsx index d744032..f7c5f13 100644 --- a/src/components/Clinic.tsx +++ b/src/components/Clinic.tsx @@ -36,9 +36,11 @@ const ClinicComponent: FC<{ clinicId: number }> = ({ clinicId }) => { {loading && "Loading..."} {clinic.id && (
-

{clinic.name}

+
+

{clinic.name}

+
{clinic.address}
-
+
{clinic.city}, {clinic.state} {clinic.zipcode}
diff --git a/src/components/Provider.css b/src/components/Provider.css index 595d4c6..39ad920 100644 --- a/src/components/Provider.css +++ b/src/components/Provider.css @@ -1,16 +1,16 @@ .provider-container { - display: flex; + display: flex; } .provider-info { - display: flex; - flex-direction: column; - justify-content: center; - padding-left: 16px; + display: flex; + flex-direction: column; + justify-content: center; + padding-left: 16px; } .provider-info h1 { - color: #1CB6E3; + color: #1cb6e3; } .provider-info p { - font-size: 12px; - margin-top: 0; -} \ No newline at end of file + font-size: 12px; + margin-top: 0; +} diff --git a/src/components/Provider.tsx b/src/components/Provider.tsx index c24b9c2..26a1c60 100644 --- a/src/components/Provider.tsx +++ b/src/components/Provider.tsx @@ -1,21 +1,30 @@ -import React, { FC } from 'react'; -import { Provider } from '../zoomcare-api'; -import StethoscopeIcon from './StethoscopeIcon'; -import './Provider.css'; +import React, { FC } from "react"; +import { Provider } from "../zoomcare-api"; +import StethoscopeIcon from "./StethoscopeIcon"; +import "./Provider.css"; -const ProviderComponent:FC<{provider: Provider}> = ({ provider, children }) => { - return ( -
-
- -
-
-

{provider.name}, {provider.credentials}

-

{provider.phoneNumber}

-
{children}
-
+const ProviderComponent: FC<{ provider: Provider }> = ({ + provider, + children, +}) => { + return ( +
+
+ +
+
+
+

+ {provider.name}, {provider.credentials} +

- ) -} +
+

{provider.phoneNumber}

+
+
{children}
+
+
+ ); +}; -export default ProviderComponent; \ No newline at end of file +export default ProviderComponent; diff --git a/src/components/Schedule.css b/src/components/Schedule.css index 14dacc5..7bdd064 100644 --- a/src/components/Schedule.css +++ b/src/components/Schedule.css @@ -1,15 +1,15 @@ .schedule-container { - display: flex; - gap: 10px; + display: flex; + gap: 10px; } .box { - width: 110px; - height: 37px; - background-color: #293A41; - color: #ffffff; - font-weight: bolder; - display: flex; - align-items: center; - justify-content: center; - border-radius: 4px; + width: 110px; + height: 37px; + background-color: #293a41; + color: #ffffff; + font-weight: bolder; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; } diff --git a/src/components/Schedule.tsx b/src/components/Schedule.tsx index daf6746..de63391 100644 --- a/src/components/Schedule.tsx +++ b/src/components/Schedule.tsx @@ -1,22 +1,33 @@ -import React, { FC } from 'react'; -import './Schedule.css'; +import React, { FC } from "react"; +import "./Schedule.css"; type ScheduleData = { - startTime: string; - durationInMinutes: number; -} + startTime: string; + durationInMinutes: number; +}; -const Schedule: FC = ({startTime, durationInMinutes}) => { - const startDate = new Date(startTime.substring(0,16)); - const endDate = new Date(startDate.getTime() + durationInMinutes*60000); - const formattedStartTime = startDate.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) - const formattedEndTime = endDate.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) +const Schedule: FC = ({ startTime, durationInMinutes }) => { + const startDate = new Date(startTime.substring(0, 16)); + const endDate = new Date(startDate.getTime() + durationInMinutes * 60000); + const formattedStartTime = startDate.toLocaleTimeString("en-US", { + hour: "numeric", + minute: "2-digit", + }); + const formattedEndTime = endDate.toLocaleTimeString("en-US", { + hour: "numeric", + minute: "2-digit", + }); - return ( -
-
{formattedStartTime}
{formattedEndTime}
-
- ) -} + return ( +
+
+ {formattedStartTime} +
+
+ {formattedEndTime} +
+
+ ); +}; -export default Schedule; \ No newline at end of file +export default Schedule; diff --git a/src/components/StethoscopeIcon.css b/src/components/StethoscopeIcon.css index d72233e..dfd8866 100644 --- a/src/components/StethoscopeIcon.css +++ b/src/components/StethoscopeIcon.css @@ -1,7 +1,7 @@ .container { - width: 110px; - height: 110px; - padding: 20px 10px 20px 30px; - background-color: #EEEEEE; - border-radius: 50%; -} \ No newline at end of file + width: 110px; + height: 110px; + padding: 20px 10px 20px 30px; + background-color: #eeeeee; + border-radius: 50%; +} diff --git a/src/components/StethoscopeIcon.tsx b/src/components/StethoscopeIcon.tsx index b4705b8..9178e4c 100644 --- a/src/components/StethoscopeIcon.tsx +++ b/src/components/StethoscopeIcon.tsx @@ -1,13 +1,13 @@ -import React, { FC } from 'react'; -import { ReactComponent as StethoscopeSVG } from '../assets/stethoscope.svg' -import './StethoscopeIcon.css'; +import React, { FC } from "react"; +import { ReactComponent as StethoscopeSVG } from "../assets/stethoscope.svg"; +import "./StethoscopeIcon.css"; -const StethoscopeIcon:FC = () => { - return ( -
- -
- ) -} +const StethoscopeIcon: FC = () => { + return ( +
+ +
+ ); +}; -export default StethoscopeIcon; \ No newline at end of file +export default StethoscopeIcon; diff --git a/src/pages/Appointments.css b/src/pages/Appointments.css index b1d8b73..80d0eb5 100644 --- a/src/pages/Appointments.css +++ b/src/pages/Appointments.css @@ -1,3 +1,3 @@ .appointments-container { - padding: 24px; -} \ No newline at end of file + padding: 24px; +} diff --git a/src/pages/Appointments.tsx b/src/pages/Appointments.tsx index ff8a343..25810af 100644 --- a/src/pages/Appointments.tsx +++ b/src/pages/Appointments.tsx @@ -10,15 +10,6 @@ const Appointments: FC = () => { const [appointments, setAppointments] = useState([]); - // const options = { method: "GET", headers: { "Authorization": ctx.token } }; - // console.log(options); - // const { - // loading, - // error, - // data = [], - // } = useFetch("/api/appointments", options, []); - - // console.log(data); const { get, response, loading, error } = useFetch("api", { headers: { Authorization: ctx.token }, }); @@ -29,7 +20,7 @@ const Appointments: FC = () => { async function loadAppointments() { const { appointmentSlots } = await get(`/appointments`); - console.log('appointments: ', appointmentSlots); + console.log("appointments: ", appointmentSlots); if (response.ok) setAppointments(appointmentSlots); } return (