Skip to content

Commit 33ef443

Browse files
Merge pull request #4533 from OneCommunityGlobal/shashank-madan-pr-grading-frontend
Shashank madan pr grading frontend
2 parents 1d8c257 + 0c8281f commit 33ef443

17 files changed

Lines changed: 2257 additions & 3 deletions

git_log.txt

2.32 KB
Binary file not shown.
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import React, { useState } from 'react';
2+
import { X, Check } from 'lucide-react';
3+
import styles from './AddPRModal.module.css';
4+
5+
const PR_NUMBER_REGEX = /^\d+(?:\s*\+\s*\d+)*$/;
6+
const GRADE_OPTIONS = ['Unsatisfactory', 'Okay', 'Exceptional', 'No Correct Image'];
7+
8+
function AddPRModal({ reviewer, onAdd, onCancel }) {
9+
const [prNumber, setPrNumber] = useState('');
10+
const [prNumberError, setPrNumberError] = useState('');
11+
const [selectedGrade, setSelectedGrade] = useState('');
12+
const [step, setStep] = useState(1); // 1: PR Number input, 2: Grade selection
13+
14+
const validatePRNumber = value => {
15+
const trimmedValue = value.trim();
16+
if (!trimmedValue) {
17+
setPrNumberError('');
18+
return false;
19+
}
20+
// Test the regex on the trimmed value
21+
// Allow formats like: "1234", "1234 + 5678", "1234+5678", "1234 + 5678 + 9012"
22+
const isValid = PR_NUMBER_REGEX.test(trimmedValue);
23+
if (!isValid) {
24+
setPrNumberError('Invalid format. Use format like "1234" or "1234 + 5678"');
25+
return false;
26+
}
27+
setPrNumberError('');
28+
return true;
29+
};
30+
31+
const handlePRNumberChange = e => {
32+
const value = e.target.value;
33+
setPrNumber(value);
34+
// Clear error when user starts typing, validate on blur/submit
35+
if (prNumberError) {
36+
// If there was an error, re-validate to show success when fixed
37+
if (value.trim()) {
38+
validatePRNumber(value);
39+
} else {
40+
setPrNumberError('');
41+
}
42+
}
43+
};
44+
45+
const handlePRNumberBlur = () => {
46+
if (prNumber.trim()) {
47+
validatePRNumber(prNumber);
48+
}
49+
};
50+
51+
const handlePRNumberSubmit = e => {
52+
e.preventDefault();
53+
if (validatePRNumber(prNumber)) {
54+
setStep(2);
55+
}
56+
};
57+
58+
const handleGradeSelect = grade => {
59+
setSelectedGrade(grade);
60+
// Automatically add on selection
61+
onAdd(reviewer, prNumber.trim(), grade);
62+
// Reset form
63+
setPrNumber('');
64+
setSelectedGrade('');
65+
setStep(1);
66+
setPrNumberError('');
67+
};
68+
69+
const handleCancel = () => {
70+
setPrNumber('');
71+
setSelectedGrade('');
72+
setStep(1);
73+
setPrNumberError('');
74+
onCancel();
75+
};
76+
77+
return (
78+
<div className={styles.modal}>
79+
<div className={styles.modalHeader}>
80+
<h3 className={styles.modalTitle}>Add PR for {reviewer}</h3>
81+
<button
82+
type="button"
83+
onClick={handleCancel}
84+
className={styles.closeButton}
85+
aria-label="Close"
86+
>
87+
<X className={styles.closeIcon} />
88+
</button>
89+
</div>
90+
91+
{step === 1 && (
92+
<form onSubmit={handlePRNumberSubmit}>
93+
<div className={styles.formGroup}>
94+
<label htmlFor="prNumber" className={styles.label}>
95+
PR Number
96+
</label>
97+
<input
98+
id="prNumber"
99+
type="text"
100+
value={prNumber}
101+
onChange={handlePRNumberChange}
102+
onBlur={handlePRNumberBlur}
103+
placeholder="e.g., 1234 or 1234 + 5678"
104+
className={`${styles.input} ${prNumberError ? styles.inputError : ''}`}
105+
/>
106+
{prNumberError && <p className={styles.errorMessage}>{prNumberError}</p>}
107+
{!prNumberError && prNumber.trim() && (
108+
<p className={styles.successMessage}>
109+
<Check className={styles.successIcon} />
110+
Valid format
111+
</p>
112+
)}
113+
</div>
114+
<div className={styles.buttonGroup}>
115+
<button
116+
type="button"
117+
onClick={handleCancel}
118+
className={`${styles.button} ${styles.buttonCancel}`}
119+
>
120+
Cancel
121+
</button>
122+
<button
123+
type="submit"
124+
disabled={!prNumber.trim() || !!prNumberError}
125+
className={`${styles.button} ${styles.buttonPrimary}`}
126+
>
127+
Next
128+
</button>
129+
</div>
130+
</form>
131+
)}
132+
133+
{step === 2 && (
134+
<div>
135+
<div className={styles.formGroup}>
136+
<p className={styles.prNumberDisplay}>
137+
PR Number: <span className={styles.prNumberValue}>{prNumber}</span>
138+
</p>
139+
<div className={styles.gradeLabel}>Select Grade</div>
140+
<div className={styles.gradeOptions}>
141+
{GRADE_OPTIONS.map(grade => (
142+
<button
143+
key={grade}
144+
type="button"
145+
onClick={() => handleGradeSelect(grade)}
146+
className={`${styles.gradeButton} ${
147+
selectedGrade === grade ? styles.gradeButtonSelected : ''
148+
}`}
149+
>
150+
{grade}
151+
</button>
152+
))}
153+
</div>
154+
</div>
155+
<div className={styles.buttonGroup}>
156+
<button
157+
type="button"
158+
onClick={() => {
159+
setStep(1);
160+
setSelectedGrade('');
161+
}}
162+
className={`${styles.button} ${styles.buttonCancel}`}
163+
>
164+
Back
165+
</button>
166+
</div>
167+
</div>
168+
)}
169+
</div>
170+
);
171+
}
172+
173+
export default AddPRModal;

0 commit comments

Comments
 (0)