<div class="container"></div>
body {
	padding: 2rem 2rem 4rem;
}
ul {
    display: block;
    list-style-type: disc;
    margin-block-start: 1em;
    margin-block-end: 1em;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
    padding-inline-start: 40px;
}
h2 {
	display: block;
    font-size: 1.17em;
    margin-block-start: 1em;
    margin-block-end: 1em;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
    font-weight: bold;
}
h3 {
	display: block;
    font-size: 1em;
    margin-block-start: 1em;
    margin-block-end: 1em;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
    font-weight: bold;
}
table {
    margin-top: 1rem;
    margin-bottom: 1rem;
}
table thead {
    background-color: #f2f2f2;
    text-align: left;
}

label {
    display: block;
    margin-right: 0.5rem;
}
select {
    border-radius: 2px;
    padding: 0.75rem 1rem;
    -moz-appearance: none;
    -webkit-appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    -ms-appearance: none;
    appearance: none;
	background: transparent;
	background-image: url("data:image/svg+xml;utf8,<svg fill='black' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>");
	background-repeat: no-repeat;
	background-position-x: 98%;
	background-position-y: 12px;
	border: 1px solid #ccc;	
	width: 320px;
}
option {
	width: 100%;
    border-radius: 10px;
    padding: 1rem;
}
.box {
	margin: 0rem auto 3rem auto
}
//ES6 const, let
//ES6 Destructuring 
const { Component, useEffect, useState } = React;

// TypeScript interfaces
interface Doctor {
  id: number
  name: string
  specialty: string
  hospitals: {
    id: number
    name: string
    location: string
  }[]
  experience: string
  contact: string
  email: string
}

interface Hospital {
  id: number
  name: string
  location: string
}

const App = () => {  	
	const [selectedHospitalId, setSelectedHospitalId] = useState<number | null>(null)	
    const [uniqueHospitals, setUniqueHospitals] = useState<Hospital[]>([])	
	const [data, setData] = useState<{ doctors: Doctor[] }>({ doctors: [] })
	// 	Get JSON data
	useEffect(() => {
		const getDoctors = async () =>
		  await fetch(
			'https://raw.githubusercontent.com/dyarfi/doctors.json/master/doctorHospital.json'
		  ).then(async (items) => {
			const itemsJson = await items.json()
			setData({ doctors: itemsJson.data })
		  })
		getDoctors()
	}, [])
	// 	Set JSON data	
 	useEffect(() => {
		// Ensure unique hospitals
		const allHospitals = data.doctors.flatMap((doctor) => doctor.hospitals)
		// Populate the dropdown with unique hospital names
		const uniqueHospitals = Array.from(
			new Set(allHospitals.map((hospital) => hospital.id))
		)
		.map(
			(hospitalId) =>
			allHospitals.find(
				(hospital) => hospital.id === hospitalId
			) as Hospital
		)
		.sort((a, b) => {
			const nameA = a.name.toUpperCase() // ignore upper and lowercase
			const nameB = b.name.toUpperCase() // ignore upper and lowercase
			if (nameA < nameB) {
				return -1
			}
			if (nameA > nameB) {
				return 1
			}
			// names must be equal
			return 0
		})
		// Initially set all hospitals
		setUniqueHospitals(uniqueHospitals)

		// Handle case when there are hospitals
		if (uniqueHospitals.length > 0) {
			setSelectedHospitalId(uniqueHospitals[0].id) // Set the default hospital ID
		}
	}, [data])
	
	const handleDropdownChange = (event: ChangeEvent<HTMLSelectElement>) => {
		const id = parseInt(event.target.value)
		setSelectedHospitalId(id)
	}

	const getDoctorsByHospital = (hospitalId: number | null): Doctor[] => {
		if (hospitalId === null) {
			return data.doctors
		}
		return data.doctors.filter((doctor) =>doctor.hospitals.some((hospital) => hospital.id === hospitalId))
	}

  	const filteredDoctors = getDoctorsByHospital(selectedHospitalId)
	
	// =============================================================================== //
	
	const [selectedDoctorId, setSelectedDoctorId] = useState<number | null>(null)	
	
	useEffect(() => {
		// Handle case when there are doctors
		if (data.doctors.length > 0) {
			setSelectedDoctorId(data.doctors[0].id) // Set the default doctor ID
		}
	}, [data])

	const handleDropdownChange2 = (event: ChangeEvent<HTMLSelectElement>) => {
		const id = parseInt(event.target.value)
		setSelectedDoctorId(id)
	}

	const getHospitalsByDoctor = (doctorId: number | null): Hospital[] => {
		if (doctorId === null) {
			return []
		}
		const selectedDoctor = data.doctors.find((doctor) => doctor.id === doctorId)
		return selectedDoctor ? selectedDoctor.hospitals : []
	}

	const hospitalsForSelectedDoctor = getHospitalsByDoctor(selectedDoctorId)
  
	// Render the component with the fetched data
	return (
		<div>	
			<div className="box">
				<h2>Find Doctor from Hospital ID</h2>
				<form>
				  <label htmlFor="hospitalDropdown">Select Hospital:</label>
				  <select
					id="hospitalDropdown"
					onChange={handleDropdownChange}
					value={selectedHospitalId || ''}
				  >
					{uniqueHospitals.map((hospital) => (
					  <option key={hospital.id} value={hospital.id}>
						{hospital.name}
					  </option>
					))}
				  </select>
				</form>
		        <h3>Doctors for Selected Hospitals:</h3>
				<table className="mantine-Table-table">
				  <thead className="mantine-Table-thead">
					<tr className="mantine-Table-tr">
					  <th>ID</th>
					  <th>Name</th>
					  <th>Specialty</th>
					  <th>Experience</th>
					  <th>Contact</th>
					  <th>Email</th>
					</tr>
				  </thead>
				  <tbody className="mantine-Table-tbody">
					{filteredDoctors.map((doctor) => (
					  <tr key={doctor.id}>
						<td style={{ width: '10%' }}>{doctor.id}</td>
						<td style={{ width: '20%' }}>{doctor.name}</td>
						<td style={{ width: '20%' }}>{doctor.specialty}</td>
						<td style={{ width: '20%' }}>{doctor.experience}</td>
						<td style={{ width: '20%' }}>{doctor.contact}</td>
						<td style={{ width: '10%' }}>{doctor.email}</td>
					  </tr>
					))}
				  </tbody>
				</table>
			</div>
			<div className="box">
				<h2>Find Hospital from Doctors ID</h2>
				<form>
				  <label htmlFor="doctorDropdown">Select Doctor:</label>
				  <select
					id="doctorDropdown"
					onChange={handleDropdownChange2}
					value={selectedDoctorId || ''}
				  >
					{data.doctors.map((doctor) => (
					  <option key={doctor.id} value={doctor.id}>
						{doctor.name}
					  </option>
					))}
				  </select>
				</form>

				<h3>Hospitals for Selected Doctor:</h3>
				<ul>
				  {hospitalsForSelectedDoctor.map((hospital) => (
					<li key={hospital.id}>
					  {hospital.name} - {hospital.location}
					</li>
				  ))}
				</ul>
			</div>
		</div>
	)
}

ReactDOM.render(<App />, document.querySelector(".container"));
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js
  3. https://unpkg.com/@types/react@16.8.6/index.d.ts
  4. https://unpkg.com/@types/react-dom@16.8.6/index.d.ts
  5. https://unpkg.com/@types/react-dom@16.8.4/index.d.ts