Skip to content

Commit dfb39e2

Browse files
Merge pull request #163 from IPMS-Project/GroupC/APIendpoints
Group C PR Sprint 4
2 parents 3b11825 + abf38d5 commit dfb39e2

File tree

5 files changed

+105
-155
lines changed

5 files changed

+105
-155
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pids
1616
*.seed
1717
*.pid.lock
1818

19+
20+
1921
# Directory for instrumented libs generated by jscoverage/JSCover
2022
lib-cov
2123

client/src/pages/A1InternshipRequestForm.js

Lines changed: 46 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ const outcomeDescriptions = [
2020
"Apply computer science algorithms to create practical solutions",
2121
];
2222

23-
// Signature font options
2423
const signatureFonts = [
2524
{ name: "Dancing Script", class: "font-dancing-script" },
2625
{ name: "Great Vibes", class: "font-great-vibes" },
@@ -29,7 +28,7 @@ const signatureFonts = [
2928
{ name: "Caveat", class: "font-caveat" }
3029
];
3130

32-
// Signature Font Picker Component
31+
3332
const SignatureInput = ({ id, value, onChange, disabled, placeholder }) => {
3433
const [showFonts, setShowFonts] = useState(false);
3534
const [selectedFont, setSelectedFont] = useState(signatureFonts[0].class);
@@ -91,7 +90,7 @@ const SignatureInput = ({ id, value, onChange, disabled, placeholder }) => {
9190
const A1InternshipRequestForm = ({ userRole = "student" }) => {
9291
const initialState = {
9392
interneeName: "",
94-
soonerId: "",
93+
// soonerId: "",
9594
interneeEmail: "",
9695
workplaceName: "",
9796
website: "",
@@ -102,10 +101,8 @@ const A1InternshipRequestForm = ({ userRole = "student" }) => {
102101
advisorJobTitle: "",
103102
advisorEmail: "",
104103
interneeSignature: "",
105-
advisorSignature: "",
106-
coordinatorApproval: "",
107104
creditHours: "",
108-
tasks: Array(5).fill({ description: "", outcomes: [] }), // Updated for outcomes
105+
tasks: Array(5).fill({ description: "", outcomes: [] }),
109106
supervisorComments: "",
110107
coordinatorComments: "",
111108
};
@@ -223,15 +220,15 @@ const A1InternshipRequestForm = ({ userRole = "student" }) => {
223220

224221
const validateForm = () => {
225222
const namePattern = /^[A-Za-z\s]+$/;
226-
const numberPattern = /^[0-9]+$/;
223+
// const numberPattern = /^[0-9]+$/;
227224
const phonePattern = /^[0-9]{10}$/;
228225
const emailPattern = /^[\w.-]+@([\w-]+\.)+[\w-]{2,4}$/;
229226
const newErrors = {};
230227

231228
if (!formData.interneeName) newErrors.interneeName = "Internee name is required";
232229
else if (!namePattern.test(formData.interneeName)) newErrors.interneeName = "Name should contain only letters and spaces";
233-
if (!formData.soonerId) newErrors.soonerId = "Sooner ID is required";
234-
else if (!numberPattern.test(formData.soonerId)) newErrors.soonerId = "Sooner ID should be numeric";
230+
//if (!formData.soonerId) newErrors.soonerId = "Sooner ID is required";
231+
//else if (!numberPattern.test(formData.soonerId)) newErrors.soonerId = "Sooner ID should be numeric";
235232
if (!formData.interneeEmail) newErrors.interneeEmail = "Email is required";
236233
else if (!emailPattern.test(formData.interneeEmail)) newErrors.interneeEmail = "Invalid email format";
237234
if (!formData.workplaceName) newErrors.workplaceName = "Workplace name is required";
@@ -247,12 +244,6 @@ const A1InternshipRequestForm = ({ userRole = "student" }) => {
247244
else if (!emailPattern.test(formData.advisorEmail)) newErrors.advisorEmail = "Invalid supervisor email format";
248245
if (!formData.interneeSignature) newErrors.interneeSignature = "Internee signature is required";
249246
else if (!namePattern.test(formData.interneeSignature)) newErrors.interneeSignature = "Signature should contain only letters and spaces";
250-
if (formData.advisorSignature && !namePattern.test(formData.advisorSignature)) {
251-
newErrors.advisorSignature = "Signature should contain only letters and spaces";
252-
}
253-
if (formData.coordinatorApproval && !namePattern.test(formData.coordinatorApproval)) {
254-
newErrors.coordinatorApproval = "Approval should contain only letters and spaces";
255-
}
256247
if (!formData.creditHours) newErrors.creditHours = "Please select credit hours";
257248
const tasksFilled = formData.tasks.filter((task) => task.description.trim() !== "").length >= 3;
258249
if (!tasksFilled) newErrors.tasks = "At least 3 tasks are required";
@@ -354,7 +345,7 @@ const A1InternshipRequestForm = ({ userRole = "student" }) => {
354345
<tbody>
355346
<tr>
356347
<td colSpan="3">
357-
Name<span className="required-asterisk">*</span>:<br />
348+
First Name<span className="required-asterisk">*</span>:<br />
358349
<input
359350
type="text"
360351
id="interneeName"
@@ -389,39 +380,42 @@ const A1InternshipRequestForm = ({ userRole = "student" }) => {
389380
</td>
390381
</tr>
391382
<tr>
392-
<td colSpan="3">
393-
Sooner ID<span className="required-asterisk">*</span>:<br />
394-
<input
395-
type="text"
396-
id="soonerId"
397-
value={formData.soonerId}
398-
onChange={handleInputChange}
399-
disabled={!isFieldEditable("soonerId")}
400-
/>
401-
{errors.soonerId && <div style={{ color: "red", fontSize: "0.8rem" }}>{errors.soonerId}</div>}
402-
</td>
403-
<td colSpan="3">
404-
Website:<br />
405-
<input
406-
type="text"
407-
id="website"
408-
value={formData.website}
409-
onChange={handleInputChange}
410-
disabled={!isFieldEditable("website")}
411-
/>
412-
{errors.website && <div style={{ color: "red", fontSize: "0.8rem" }}>{errors.website}</div>}
413-
</td>
414-
<td colSpan="2">
415-
Job Title:<br />
416-
<input
417-
type="text"
418-
id="advisorJobTitle"
419-
value={formData.advisorJobTitle}
420-
onChange={handleInputChange}
421-
disabled={!isFieldEditable("advisorJobTitle")}
422-
/>
423-
</td>
424-
</tr>
383+
384+
<td colSpan="3">
385+
Last Name:<br />
386+
<input
387+
type="text"
388+
389+
/>
390+
{errors.website && <div style={{ color: "red", fontSize: "0.8rem" }}>{errors.website}</div>}
391+
</td>
392+
393+
394+
<td colSpan="3">
395+
Website:<br />
396+
<input
397+
type="text"
398+
id="website"
399+
value={formData.website}
400+
onChange={handleInputChange}
401+
disabled={!isFieldEditable("website")}
402+
/>
403+
{errors.website && <div style={{ color: "red", fontSize: "0.8rem" }}>{errors.website}</div>}
404+
</td>
405+
406+
407+
<td colSpan="2">
408+
Job Title:<br />
409+
<input
410+
type="text"
411+
id="advisorJobTitle"
412+
value={formData.advisorJobTitle}
413+
onChange={handleInputChange}
414+
disabled={!isFieldEditable("advisorJobTitle")}
415+
/>
416+
</td>
417+
</tr>
418+
425419
<tr>
426420
<td colSpan="3">
427421
Email<span className="required-asterisk">*</span>:<br />
@@ -431,7 +425,7 @@ const A1InternshipRequestForm = ({ userRole = "student" }) => {
431425
value={formData.interneeEmail}
432426
onChange={handleInputChange}
433427
disabled
434-
// disabled={!isFieldEditable("interneeEmail")}
428+
435429
/>
436430
{errors.interneeEmail && <div style={{ color: "red", fontSize: "0.8rem" }}>{errors.interneeEmail}</div>}
437431
</td>
@@ -559,7 +553,7 @@ const A1InternshipRequestForm = ({ userRole = "student" }) => {
559553
<table>
560554
<tbody>
561555
<tr>
562-
<td className="signature-cell" colSpan="3">
556+
<td className="signature-cell" colSpan="1">
563557
Internee Signature<span className="required-asterisk">*</span>:<br />
564558
<div className="signature-field">
565559
<SignatureInput
@@ -572,75 +566,7 @@ const A1InternshipRequestForm = ({ userRole = "student" }) => {
572566
</div>
573567
{errors.interneeSignature && <div style={{ color: "red", fontSize: "0.8rem" }}>{errors.interneeSignature}</div>}
574568
</td>
575-
<td className="signature-cell" colSpan="3">
576-
Internship Supervisor Signature:<br />
577-
<div className="signature-field">
578-
<SignatureInput
579-
id="advisorSignature"
580-
value={formData.advisorSignature}
581-
onChange={handleInputChange}
582-
disabled={!isFieldEditable("advisorSignature")}
583-
placeholder="Enter your full name"
584-
/>
585-
</div>
586-
{errors.advisorSignature && <div style={{ color: "red", fontSize: "0.8rem" }}>{errors.advisorSignature}</div>}
587-
</td>
588-
<td className="signature-cell" colSpan="2">
589-
Internship Coordinator Approval:<br />
590-
<div className="signature-field">
591-
<SignatureInput
592-
id="coordinatorApproval"
593-
value={formData.coordinatorApproval}
594-
onChange={handleInputChange}
595-
disabled={!isFieldEditable("coordinatorApproval")}
596-
placeholder="Enter your full name"
597-
/>
598-
</div>
599-
{errors.coordinatorApproval && <div style={{ color: "red", fontSize: "0.8rem" }}>{errors.coordinatorApproval}</div>}
600-
</td>
601-
</tr>
602-
{/* <tr>
603-
<td colSpan="3">
604-
<label htmlFor="supervisorComments" style={{ fontWeight: "bold" }}>Supervisor Comments:</label><br />
605-
<textarea
606-
id="supervisorComments"
607-
value={formData.supervisorComments}
608-
onChange={handleInputChange}
609-
placeholder="Enter any comments or feedback for this internship request"
610-
style={{
611-
width: "100%",
612-
padding: "8px",
613-
boxSizing: "border-box",
614-
minHeight: "80px",
615-
resize: "vertical",
616-
marginTop: "5px",
617-
border: "1px solid #ccc",
618-
borderRadius: "3px"
619-
}}
620-
disabled={!isFieldEditable("supervisorComments")}
621-
/>
622-
</td>
623-
<td colSpan="5">
624-
<label htmlFor="coordinatorComments" style={{ fontWeight: "bold" }}>Coordinator Comments:</label><br />
625-
<textarea
626-
id="coordinatorComments"
627-
value={formData.coordinatorComments}
628-
onChange={handleInputChange}
629-
placeholder="Enter any comments or feedback regarding this internship request"
630-
style={{
631-
width: "100%",
632-
padding: "8px",
633-
boxSizing: "border-box",
634-
minHeight: "80px",
635-
resize: "vertical",
636-
marginTop: "5px",
637-
border: "1px solid #ccc",
638-
borderRadius: "3px"
639-
}}
640-
disabled={!isFieldEditable("coordinatorComments")}
641-
/>
642-
</td>
643-
</tr> */}
569+
</tr>
644570
</tbody>
645571
</table>
646572

client/src/styles/A1InternshipRequestForm.css

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,55 @@
217217
max-width: 1200px;
218218
border-radius: 12px;
219219
}
220+
221+
.success-msg, .error-msg {
222+
animation: fadeIn 0.5s;
223+
}
224+
@keyframes fadeIn {
225+
from { opacity: 0; }
226+
to { opacity: 1; }
227+
}
228+
229+
.required-asterisk {
230+
color: #d93025;
231+
font-weight: bold;
232+
font-size: 1.2em;
233+
margin-left: 2px;
234+
vertical-align: middle;
235+
}
236+
237+
button[type="submit"] {
238+
box-shadow: 0 2px 8px rgba(44, 110, 203, 0.08);
239+
font-weight: 600;
240+
letter-spacing: 0.5px;
241+
}
242+
button[type="submit"]:active {
243+
background: #1e5dad;
244+
box-shadow: 0 1px 2px #777;
245+
}
246+
247+
input, select, textarea {
248+
margin-bottom: 10px;
249+
}
250+
textarea {
251+
min-height: 90px;
252+
resize: vertical;
253+
}
254+
255+
.section-card {
256+
background: #f7fafd;
257+
border-radius: 8px;
258+
box-shadow: 0 1px 8px rgba(44, 110, 203, 0.04);
259+
padding: 18px 20px 14px 20px;
260+
margin-bottom: 28px;
261+
border-left: 5px solid #007bff22;
262+
}
263+
264+
.section-title {
265+
color: #2451a0;
266+
border-left: 4px solid #007bffcc;
267+
padding-left: 10px;
268+
margin-bottom: 16px;
269+
font-size: 1.18rem;
270+
background: transparent;
271+
}

server/models/InternshipRequest.js

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@ const Task = new mongoose.Schema({
2222

2323
});
2424
const formA1 = new mongoose.Schema({
25-
// student: {
26-
// type: ObjectId,
27-
// required: true,
28-
// ref: 'UserTokenRequest'
29-
// },
25+
3026
student:{
3127
name:{
3228
type: String,
@@ -39,11 +35,7 @@ const formA1 = new mongoose.Schema({
3935
},
4036
},
4137
...formMetadata,
42-
// student: {
43-
// type: ObjectId,
44-
// required: true,
45-
// ref: 'UserTokenRequest'
46-
// },
38+
4739
workplace: {
4840
name: {
4941
type: String,
@@ -77,11 +69,7 @@ const formA1 = new mongoose.Schema({
7769
type: [Task],
7870
required: true
7971
},
80-
// status: {
81-
// type: String,
82-
// required: true,
83-
// enum: ['draft', 'submitted','pending manual review' ,'approved']
84-
// },
72+
8573
approvals: {
8674
type: [String],
8775
enum: ["advisor", "coordinator"],

0 commit comments

Comments
 (0)