Skip to content
Merged
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
45 changes: 33 additions & 12 deletions entrypoints/degree-audit/components/degree-audit-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import Title from "@/entrypoints/components/common/text";
import "@/entrypoints/styles/content.css";
import { useAuditContext } from "../providers/audit-provider";
import { SimpleDegreeCompletionDonut } from "./degree-completion-donut";
import { CreditHourTotalsCard, GPATotalsCard } from "./gpa-credit-cards";
import RequirementBreakdown from "./requirement-breakdown";

const GpaSummaryCard = () => {
const SidePanel = () => {
const { sections } = useAuditContext();
const gpaSection = sections.find((section) =>
section.title.toLowerCase().includes("gpa"),
Expand Down Expand Up @@ -58,33 +59,53 @@ const SidePanel = () => {
x="center"
>
<SimpleDegreeCompletionDonut size={300} />
<div className="mt-10">
<GpaSummaryCard />
</div>
<VStack gap={4} className="w-sm mt-10">
<GPATotalsCard
required={gpaRule?.requiredHours ?? 2.0}
counted={gpaRule?.appliedHours ?? 0.0}
hoursUsed={80}
points={320}
/>
<CreditHourTotalsCard
requirements={[
{
met: true,
hours: 21,
description: "upper-division coursework in residence.",
},
{
met: false,
hours: 36,
description: "upper-division coursework required.",
},
]}
/>
</VStack>
</VStack>
);
};

const MainContent = () => {
const { progresses, sections } = useAuditContext();
const checklistSections = sections.filter(
const nonGPASections = sections.filter(
(section) => !section.title.toLowerCase().includes("gpa"),
);

return (
<VStack fill className="w-full">
<Title text="Degree Progress Overview" />
<Title text="Degree Checklist" />
{checklistSections.map((section) => {
const sectionIndex = sections.findIndex((item) => item === section);
{nonGPASections.map((section) => {
const originalIdx = sections.findIndex((s) => s.title === section.title);
const sectionProgress = progresses.sections[originalIdx];

return (
progresses.sections[sectionIndex]?.progress.total > 0 && (
sectionProgress?.progress.total > 0 && (
<RequirementBreakdown
key={section.title || `section-${sectionIndex}`}
key={section.title || `section-${originalIdx}`}
title={section.title}
hours={progresses.sections[sectionIndex].progress}
hours={sectionProgress.progress}
requirements={section.rule ?? []}
colorIndex={sectionIndex}
colorIndex={originalIdx}
/>
)
);
Expand Down
93 changes: 93 additions & 0 deletions entrypoints/degree-audit/components/gpa-credit-cards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { HStack, VStack } from "@/entrypoints/components/common/helperdivs";

type GPATotalsProps = {
required: number;
counted: number;
hoursUsed: number;
points: number;
};

export const GPATotalsCard = ({
required = 2.0,
counted = 4.0,
hoursUsed = 80,
points = 320,
}: GPATotalsProps) => {
return (
<div className="p-5 rounded-lg border border-gray-200 bg-white shadow-md">
<HStack x="between" y="top" fill>
<h3 className="text-xl font-bold text-gray-900">GPA Totals</h3>
<img src="/Info.svg" alt="Info" className="w-6 h-6 cursor-pointer" />
</HStack>

<HStack gap={6} className="mt-4">
<VStack gap={1}>
<span className="text-sm text-gray-500">Required</span>
<div className="px-4 py-2 bg-white border border-gray-300 rounded-lg">
<span className="text-lg font-semibold">{required.toFixed(4)}</span>
</div>
</VStack>
<VStack gap={1}>
<span className="text-sm text-gray-500">Counted</span>
<div className="px-4 py-2 bg-dap-green rounded-lg">
<span className="text-lg font-semibold text-white">
{counted.toFixed(4)}
</span>
</div>
</VStack>
</HStack>

<p className="mt-4 text-sm text-gray-600">
{hoursUsed} hours for a total of {points} points were used to calculate
the GPA.
</p>
</div>
);
};

type CreditRequirement = {
met: boolean;
hours: number;
description: string;
};

type CreditHourTotalsProps = {
requirements: CreditRequirement[];
};

export const CreditHourTotalsCard = ({
requirements = [
{
met: true,
hours: 21,
description: "hours of upper-division coursework in residence.",
},
{
met: false,
hours: 36,
description: "hours of upper-division coursework required.",
},
],
}: CreditHourTotalsProps) => {
return (
<div className="p-5 rounded-lg border border-gray-200 bg-white shadow-md">
<h3 className="text-xl font-bold text-gray-900">Credit Hour Totals</h3>

<VStack gap={3} className="mt-4">
{requirements.map((req, idx) => (
<HStack key={idx} gap={3} y="middle">
<img
src={req.met ? "/Frame.svg" : "/Frame (1).svg"}
alt={req.met ? "Met" : "Not met"}
className="w-7 h-7"
/>
<span className="text-sm text-gray-700">
<span className="font-semibold">{req.hours} hours</span> of{" "}
{req.description}
</span>
</HStack>
))}
</VStack>
</div>
);
};
10 changes: 10 additions & 0 deletions public/Frame (1).svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions public/Frame.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/Info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading