Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"clsx": "^2.1.1",
"csv-parser": "^3.0.0",
"debounce": "^2.1.1",
"isomorphic-dompurify": "^2.16.0",
"lodash": "^4.17.21",
"lodash.debounce": "^4.0.8",
"lru-cache": "^11.0.1",
Expand Down
69 changes: 34 additions & 35 deletions src/app/components/FAQDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,45 @@
import { useState } from "react";
import DOMPurify from "isomorphic-dompurify";

interface FAQDropdownProps {
question: string;
answer: string;
question: string;
answer: string;
}

const FAQDropdown: React.FC<FAQDropdownProps> = ({ question, answer }) => {
const [isOpen, setIsOpen] = useState(false);
const [isOpen, setIsOpen] = useState(false);

const toggleDropdown = () => {
setIsOpen((prev) => !prev);
};
const toggleDropdown = () => {
setIsOpen((prev) => !prev);
};

return (
<div className="border-gray-200">
<button
className={`flex justify-between items-center w-full py-4 text-left text-white focus:outline-none bg-gray-200 ${
isOpen ? "bg-opacity-40" : "bg-opacity-20"
} rounded-t-lg hover:bg-opacity-40 transition-all duration-200 ${
isOpen ? "" : "rounded-b-lg"
}`}
onClick={toggleDropdown}
>
<span className="ml-5 mr-5 text-lg font-medium">{question}</span>
<span
className={`mr-5 transition-transform ${
isOpen ? "rotate-180" : ""
}`}
>
</span>
</button>
{isOpen && (
<div className="py-2 text-white bg-gray-200 bg-opacity-20 rounded-b-lg">
<div
className="ml-5 mr-5"
dangerouslySetInnerHTML={{ __html: answer }}
/>
</div>
)}
</div>
);
// Sanitize the answer content
const sanitizedAnswer = DOMPurify.sanitize(answer);

return (
<div className="border border-gray-700 rounded-lg overflow-hidden">
<button
onClick={toggleDropdown}
className={`flex justify-between items-center w-full px-6 py-4 text-left text-gray-300 bg-gray-800 hover:bg-gray-700 transition-colors duration-200 ${
isOpen ? "rounded-t-lg" : "rounded-lg"
}`}
>
<span className="text-lg font-medium">{question}</span>
<span
className={`transform transition-transform duration-200 ${
isOpen ? "rotate-180" : ""
}`}
>
</span>
</button>
{isOpen && (
<div className="px-6 py-4 bg-gray-900 text-gray-400">
<div dangerouslySetInnerHTML={{ __html: sanitizedAnswer }} />
</div>
)}
</div>
);
};

export default FAQDropdown;
120 changes: 58 additions & 62 deletions src/app/components/GradesInfoCard.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,61 @@
import React from "react";

export const GradesInfoCard = () => {
return (
<>
<h3 className="text-lg font-bold mb-2 text-blue-400">
Grading Information
</h3>
<table className="w-full text-left text-sm text-white">
<thead>
<tr className="border-b">
<th className="pb-1">Grade</th>
<th className="pb-1">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td>Excellent</td>
</tr>
<tr>
<td>B</td>
<td>Good</td>
</tr>
<tr>
<td>C</td>
<td>Fair</td>
</tr>
<tr>
<td>D</td>
<td>Passing, Below Average</td>
</tr>
<tr>
<td>F</td>
<td>Failure</td>
</tr>
<tr>
<td>I</td>
<td>Incomplete</td>
</tr>
<tr>
<td>W</td>
<td>Withdrawn</td>
</tr>
<tr>
<td>Q</td>
<td>Withdrawn - No Penalty</td>
</tr>
<tr>
<td>P</td>
<td>Pass</td>
</tr>
<tr>
<td>R</td>
<td>Research</td>
</tr>
<tr>
<td>Z</td>
<td>No Credit</td>
</tr>
</tbody>
</table>
</>
);
interface GradeInfo {
grade: string;
description: string;
}

export const GradesInfoCard: React.FC = () => {
const grades: GradeInfo[] = [
{ grade: "A", description: "Excellent" },
{ grade: "B", description: "Good" },
{ grade: "C", description: "Fair" },
{ grade: "D", description: "Passing, Below Average" },
{ grade: "F", description: "Failure" },
{ grade: "I", description: "Incomplete" },
{ grade: "W", description: "Withdrawn" },
{ grade: "Q", description: "Withdrawn - No Penalty" },
{ grade: "P", description: "Pass" },
{ grade: "R", description: "Research" },
{ grade: "Z", description: "No Credit" },
];

return (
<section aria-labelledby="grading-info-heading">
<h3
id="grading-info-heading"
className="text-lg font-bold mb-2 text-blue-400"
>
Grading Information
</h3>
<div className="overflow-x-auto">
<table className="w-full text-left text-sm text-white">
<caption className="sr-only">Grading Information Table</caption>
<thead>
<tr className="border-b border-gray-700">
<th className="pb-2" scope="col">
Grade
</th>
<th className="pb-2" scope="col">
Description
</th>
</tr>
</thead>
<tbody>
{grades.map((item, index) => (
<tr
key={item.grade}
className={`border-b border-gray-700 last:border-none ${
index % 2 === 0 ? "bg-gray-800" : "bg-gray-900"
}`}
>
<td className="py-2 px-2">{item.grade}</td>
<td className="py-2 px-2">{item.description}</td>
</tr>
))}
</tbody>
</table>
</div>
</section>
);
};
Loading