Added Percent symbol in the Input which accepts Percent value.

Updated Doctor list
This commit is contained in:
Amey Bhagwat 2026-11-05 17:41:32 +05:30
parent 96ee4427f1
commit a49fa82703
4 changed files with 122 additions and 54 deletions

View File

@ -205,7 +205,7 @@ Sr NO,TASKFORCE,ZBM Name,RBM Name,ABM Name,HQ,TM ID,TM Name,HCP NAME,LEGACY_CODE
204,Respiratory 2,Shaikh Mohseen Ahmed,Prashant Gakkhar,SURAJ RAWAT,AJMER,162115,HIMANSHU GARG,Dr.PRAMOD DADHICH,CLX0013432,11743902,Chest Physician,A+,100028825,Dr.PRAMOD DADHICH,dadhichrashmi@gmail.com,9829083879 204,Respiratory 2,Shaikh Mohseen Ahmed,Prashant Gakkhar,SURAJ RAWAT,AJMER,162115,HIMANSHU GARG,Dr.PRAMOD DADHICH,CLX0013432,11743902,Chest Physician,A+,100028825,Dr.PRAMOD DADHICH,dadhichrashmi@gmail.com,9829083879
205,Respiratory 2,Shaikh Mohseen Ahmed,Prashant Gakkhar,SURAJ RAWAT,AJMER,162115,HIMANSHU GARG,DR NEERAJ GUPTA,CIR21066,10280704,Chest Physician,A+,100116917,DR NEERAJ GUPTA,drneerajajmer@yahoo.com,9829101942 205,Respiratory 2,Shaikh Mohseen Ahmed,Prashant Gakkhar,SURAJ RAWAT,AJMER,162115,HIMANSHU GARG,DR NEERAJ GUPTA,CIR21066,10280704,Chest Physician,A+,100116917,DR NEERAJ GUPTA,drneerajajmer@yahoo.com,9829101942
206,Respiratory 2,Shaikh Mohseen Ahmed,Prashant Gakkhar,SURAJ RAWAT,S MADHOPUR,168610,VIPUL SHARMA,Dr.Umesh Kumar Jatav,CLX0384426,10255366,Chest Physician,A+,100075453,Dr.Umesh Kumar Jatav,jahaji28@gmail.com,9602158647 206,Respiratory 2,Shaikh Mohseen Ahmed,Prashant Gakkhar,SURAJ RAWAT,S MADHOPUR,168610,VIPUL SHARMA,Dr.Umesh Kumar Jatav,CLX0384426,10255366,Chest Physician,A+,100075453,Dr.Umesh Kumar Jatav,jahaji28@gmail.com,9602158647
207,Respiratory 2,Shaikh Mohseen Ahmed,Prashant Gakkhar,SURAJ RAWAT,S MADHOPUR,168610,VIPUL SHARMA,Dr.Prem raj Singh,CIP610172,7659526,Chest Physician,A+,100037592,Dr.Prem raj Singh,drpremrajsingh@gmail.com,9929460655 &6350474968 207,Respiratory 2,Shaikh Mohseen Ahmed,Prashant Gakkhar,SURAJ RAWAT,S MADHOPUR,168610,VIPUL SHARMA,Dr.Prem raj Singh,CIP610172,7659526,Chest Physician,A+,100037592,Dr.Prem raj Singh,drpremrajsingh@gmail.com,9929460655
208,Respiratory 2,Amandeep sharma,Umesh garg,Abhinav Sharma,TM-Jalandhar 17089,150541,Ishant Setia,PUNEET SINGH PERHAR,CLX1239048,12632335,Chest Physician,A+,100041086,PUNEET SINGH PERHAR,puneetperhar@yahoo.com,9779149838 208,Respiratory 2,Amandeep sharma,Umesh garg,Abhinav Sharma,TM-Jalandhar 17089,150541,Ishant Setia,PUNEET SINGH PERHAR,CLX1239048,12632335,Chest Physician,A+,100041086,PUNEET SINGH PERHAR,puneetperhar@yahoo.com,9779149838
209,Respiratory 2,Amandeep sharma,Umesh garg,Abhinav Sharma,TM-AMRITSAR 7465,171383,Arun Kumar,Mandeep Singh,CLX1650772,11311299,Chest Physician,A+,100056055,Mandeep Singh,mandeepsingh27@gmail.com,9811660365 209,Respiratory 2,Amandeep sharma,Umesh garg,Abhinav Sharma,TM-AMRITSAR 7465,171383,Arun Kumar,Mandeep Singh,CLX1650772,11311299,Chest Physician,A+,100056055,Mandeep Singh,mandeepsingh27@gmail.com,9811660365
210,Respiratory 2,Amandeep sharma,Umesh garg,Abhinav Sharma,TM-AMRITSAR 23513,171358,Ankush Kapoor,naresh chawla,CIP1067150,15023224,Chest Physician,A,100087159,naresh chawla,dr.nareshchawla@gmail.com,9814104155 210,Respiratory 2,Amandeep sharma,Umesh garg,Abhinav Sharma,TM-AMRITSAR 23513,171358,Ankush Kapoor,naresh chawla,CIP1067150,15023224,Chest Physician,A,100087159,naresh chawla,dr.nareshchawla@gmail.com,9814104155

1 Sr NO TASKFORCE ZBM Name RBM Name ABM Name HQ TM ID TM Name HCP NAME LEGACY_CODE PCODE SPECIALITY CLASS VENDORCODE VENDORNAME Email ID Contact No
205 204 Respiratory 2 Shaikh Mohseen Ahmed Prashant Gakkhar SURAJ RAWAT AJMER 162115 HIMANSHU GARG Dr.PRAMOD DADHICH CLX0013432 11743902 Chest Physician A+ 100028825 Dr.PRAMOD DADHICH dadhichrashmi@gmail.com 9829083879
206 205 Respiratory 2 Shaikh Mohseen Ahmed Prashant Gakkhar SURAJ RAWAT AJMER 162115 HIMANSHU GARG DR NEERAJ GUPTA CIR21066 10280704 Chest Physician A+ 100116917 DR NEERAJ GUPTA drneerajajmer@yahoo.com 9829101942
207 206 Respiratory 2 Shaikh Mohseen Ahmed Prashant Gakkhar SURAJ RAWAT S MADHOPUR 168610 VIPUL SHARMA Dr.Umesh Kumar Jatav CLX0384426 10255366 Chest Physician A+ 100075453 Dr.Umesh Kumar Jatav jahaji28@gmail.com 9602158647
208 207 Respiratory 2 Shaikh Mohseen Ahmed Prashant Gakkhar SURAJ RAWAT S MADHOPUR 168610 VIPUL SHARMA Dr.Prem raj Singh CIP610172 7659526 Chest Physician A+ 100037592 Dr.Prem raj Singh drpremrajsingh@gmail.com 9929460655 &6350474968 9929460655
209 208 Respiratory 2 Amandeep sharma Umesh garg Abhinav Sharma TM-Jalandhar 17089 150541 Ishant Setia PUNEET SINGH PERHAR CLX1239048 12632335 Chest Physician A+ 100041086 PUNEET SINGH PERHAR puneetperhar@yahoo.com 9779149838
210 209 Respiratory 2 Amandeep sharma Umesh garg Abhinav Sharma TM-AMRITSAR 7465 171383 Arun Kumar Mandeep Singh CLX1650772 11311299 Chest Physician A+ 100056055 Mandeep Singh mandeepsingh27@gmail.com 9811660365
211 210 Respiratory 2 Amandeep sharma Umesh garg Abhinav Sharma TM-AMRITSAR 23513 171358 Ankush Kapoor naresh chawla CIP1067150 15023224 Chest Physician A 100087159 naresh chawla dr.nareshchawla@gmail.com 9814104155

View File

@ -729,6 +729,14 @@ a:focus-visible {
.survey-grid-input input { .survey-grid-input input {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
-moz-appearance: textfield;
appearance: textfield;
}
.survey-grid-input input::-webkit-outer-spin-button,
.survey-grid-input input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
} }
.survey-grid-suffix { .survey-grid-suffix {
@ -737,6 +745,38 @@ a:focus-visible {
color: var(--text-muted); color: var(--text-muted);
} }
.percent-input {
position: relative;
display: block;
flex: 1;
min-width: 0;
}
.site .percent-input input {
padding-right: 2rem;
-moz-appearance: textfield;
appearance: textfield;
}
.percent-input input::-webkit-outer-spin-button,
.percent-input input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.percent-unit {
position: absolute;
top: 50%;
right: 0.75rem;
transform: translateY(-50%);
color: var(--text-muted);
pointer-events: none;
}
.survey-grid-percent .survey-grid-value {
width: 7.5rem;
}
.survey-grid td.survey-grid-choice { .survey-grid td.survey-grid-choice {
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
@ -880,6 +920,10 @@ a:focus-visible {
font-size: 1.25rem; font-size: 1.25rem;
} }
.survey-grid-percent .survey-grid-value {
width: auto;
}
.flow-steps li { .flow-steps li {
font-size: 0.68rem; font-size: 0.68rem;
} }

View File

@ -126,6 +126,18 @@ function blurOnWheel(event) {
event.currentTarget.blur(); event.currentTarget.blur();
} }
/** Show a "%" inside a percentage input; the saved value stays a plain number. */
function PercentInput({ children }) {
return (
<span className="percent-input">
{children}
<span className="percent-unit" aria-hidden="true">
%
</span>
</span>
);
}
/** /**
* @param {{ messages: string[] }} props * @param {{ messages: string[] }} props
*/ */
@ -213,27 +225,30 @@ function QuestionField({
} }
if (question.type === 'number' || question.type === 'percentage') { if (question.type === 'number' || question.type === 'percentage') {
const input = (
<input
type="number"
inputMode={question.integer ? 'numeric' : 'decimal'}
min={question.min}
max={question.max}
aria-invalid={invalid || undefined}
value={value === undefined || value === null ? '' : value}
onKeyDown={rangeKeyDown(question)}
onWheel={blurOnWheel}
onChange={(event) => {
const raw = event.target.value;
if (!inRange(question, raw)) {
return;
}
onChange(raw === '' ? '' : Number(raw));
}}
/>
);
return ( return (
<div className="survey-field"> <div className="survey-field">
<label> <label>
{question.label} {question.label}
<input {question.type === 'percentage' ? <PercentInput>{input}</PercentInput> : input}
type="number"
inputMode={question.integer ? 'numeric' : 'decimal'}
min={question.min}
max={question.max}
aria-invalid={invalid || undefined}
value={value === undefined || value === null ? '' : value}
onKeyDown={rangeKeyDown(question)}
onWheel={blurOnWheel}
onChange={(event) => {
const raw = event.target.value;
if (!inRange(question, raw)) {
return;
}
onChange(raw === '' ? '' : Number(raw));
}}
/>
</label> </label>
{errors} {errors}
</div> </div>
@ -318,16 +333,17 @@ function QuestionField({
if (question.type === 'grid_percentage' || question.type === 'grid_number') { if (question.type === 'grid_percentage' || question.type === 'grid_number') {
const grid = value && typeof value === 'object' ? value : {}; const grid = value && typeof value === 'object' ? value : {};
const percent = question.type === 'grid_percentage';
return ( return (
<div className="survey-field"> <div className="survey-field">
<fieldset aria-invalid={invalid || undefined}> <fieldset aria-invalid={invalid || undefined}>
<legend className={legendClass}>{question.label}</legend> <legend className={legendClass}>{question.label}</legend>
<table className="survey-grid"> <table className={percent ? 'survey-grid survey-grid-percent' : 'survey-grid'}>
<thead> <thead>
<tr> <tr>
<th scope="col">Pack type</th> <th scope="col">Pack type</th>
{question.columns.map((column) => ( {question.columns.map((column) => (
<th key={column.id} scope="col"> <th key={column.id} scope="col" className="survey-grid-value">
{column.label} {column.label}
</th> </th>
))} ))}
@ -337,40 +353,45 @@ function QuestionField({
{question.rows.map((row) => ( {question.rows.map((row) => (
<tr key={row.id}> <tr key={row.id}>
<th scope="row">{row.label}</th> <th scope="row">{row.label}</th>
{question.columns.map((column) => ( {question.columns.map((column) => {
<td key={column.id}> const cellInput = (
<span className="cell-label">{column.label}</span> <input
<div className="survey-grid-input"> type="number"
<input inputMode={question.integer ? 'numeric' : 'decimal'}
type="number" min={question.min}
inputMode={question.integer ? 'numeric' : 'decimal'} max={question.max}
min={question.min} aria-invalid={invalid || undefined}
max={question.max} aria-label={`${row.label}, ${column.label}`}
aria-invalid={invalid || undefined} value={grid[row.id]?.[column.id] ?? ''}
aria-label={`${row.label}, ${column.label}`} onKeyDown={rangeKeyDown(question)}
value={grid[row.id]?.[column.id] ?? ''} onWheel={blurOnWheel}
onKeyDown={rangeKeyDown(question)} onChange={(event) => {
onWheel={blurOnWheel} const raw = event.target.value;
onChange={(event) => { if (!inRange(question, raw)) {
const raw = event.target.value; return;
if (!inRange(question, raw)) { }
return; onChange({
} ...grid,
onChange({ [row.id]: {
...grid, ...(grid[row.id] ?? {}),
[row.id]: { [column.id]: raw === '' ? '' : Number(raw),
...(grid[row.id] ?? {}), },
[column.id]: raw === '' ? '' : Number(raw), });
}, }}
}); />
}} );
/> return (
{question.suffix ? ( <td key={column.id} className="survey-grid-value">
<span className="survey-grid-suffix">{question.suffix}</span> <span className="cell-label">{column.label}</span>
) : null} <div className="survey-grid-input">
</div> {percent ? <PercentInput>{cellInput}</PercentInput> : cellInput}
</td> {question.suffix ? (
))} <span className="survey-grid-suffix">{question.suffix}</span>
) : null}
</div>
</td>
);
})}
</tr> </tr>
))} ))}
</tbody> </tbody>

View File

@ -95,6 +95,7 @@ describe('survey steps', () => {
fireEvent.change(field, { target: { value: '100' } }); fireEvent.change(field, { target: { value: '100' } });
expect(field).toHaveValue(100); expect(field).toHaveValue(100);
expect(field.closest('.percent-input')?.querySelector('.percent-unit')).toHaveTextContent('%');
}); });
it('blocks the minus and exponent keys when the minimum is zero', async () => { it('blocks the minus and exponent keys when the minimum is zero', async () => {
@ -144,6 +145,8 @@ describe('survey steps', () => {
fireEvent.change(cell, { target: { value: '-1' } }); fireEvent.change(cell, { target: { value: '-1' } });
expect(cell).toHaveValue(60); expect(cell).toHaveValue(60);
expect(cell.closest('.percent-input')?.querySelector('.percent-unit')).toHaveTextContent('%');
expect(cell.closest('table')).toHaveClass('survey-grid-percent');
}); });
it('keeps a missing required answer on the current step', async () => { it('keeps a missing required answer on the current step', async () => {