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
10 changes: 8 additions & 2 deletions backend/degree/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,15 @@ def retrieve(self, request, *args, **kwargs):
return Response(serializer.data, status=status.HTTP_200_OK)

def create(self, request, *args, **kwargs):
if request.data.get("name") is None:
name = request.data.get("name")
if name is None:
raise ValidationError({"name": "This field is required."})
new_degree_plan = DegreePlan(name=request.data.get("name"), person=self.request.user)
if DegreePlan.objects.filter(name=name, person=self.request.user).exists():
return Response(
{"warning": f"A degree plan with name {name} already exists."},
status=status.HTTP_409_CONFLICT
)
new_degree_plan = DegreePlan(name=name, person=self.request.user)
new_degree_plan.save()
serializer = self.get_serializer(new_degree_plan)
return Response(serializer.data, status=status.HTTP_201_CREATED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Column,
ColumnsContainer,
CourseContainer,
ErrorText,
customSelectStylesCourses,
customSelectStylesLeft,
customSelectStylesRight,
Expand Down Expand Up @@ -38,7 +39,7 @@ import {
interpolateSemesters,
} from "@/components/FourYearPlan/Semesters";
import { TRANSFER_CREDIT_SEMESTER_KEY } from "@/constants";
import { postFetcher, useSWRCrud } from "@/hooks/swrcrud";
import { postFetcher, getCsrf } from "@/hooks/swrcrud";
import { getMajorOptions } from "@/utils/parseUtils";

type WelcomeLayoutProps = {
Expand Down Expand Up @@ -77,13 +78,12 @@ export default function CreateWithTranscriptPanel({
const [loading, setLoading] = useState(false);
const [name, setName] = useState("");

const [nameAlreadyExists, setNameAlreadyExists] = useState(false);

const { data: options } = useSWR<Options>("/api/options");
const { data: degrees, isLoading: isLoadingDegrees } = useSWR<
DegreeListing[]
>(`/api/degree/degrees`);
const { create: createDegreeplan } = useSWRCrud<DegreePlan>(
"/api/degree/degreeplans"
);

// Workaround solution to only input courses once degree has been created and degreeID exists.
// Will likely change in the future!
Expand Down Expand Up @@ -124,26 +124,53 @@ export default function CreateWithTranscriptPanel({

const handleAddDegrees = () => {
setLoading(true);
createDegreeplan({ name: name }).then((res) => {
if (res) {

const createDegreeplan = async () => {
// Need to handle the case where degree plan of same name already exists.
const res = await fetch("/api/degree/degreeplans", {
credentials: "include",
mode: "same-origin",
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": getCsrf(),
"Accept": "application/json",
} as HeadersInit,
body: JSON.stringify({ name: name }),
});

if (res.ok) {
const _new = await res.json();
if (startingYear && graduationYear) {
const semesters = interpolateSemesters(
startingYear.value,
graduationYear.value
);
semesters[TRANSFER_CREDIT_SEMESTER_KEY] = [];
window.localStorage.setItem(
getLocalSemestersKey(res.id),
getLocalSemestersKey(_new.id),
JSON.stringify(semesters)
);
}
postFetcher(`/api/degree/degreeplans/${res.id}/degrees`, {
postFetcher(`/api/degree/degreeplans/${_new.id}/degrees`, {
degree_ids: majors.map((m) => m.value.id),
}); // add degree
setActiveDegreeplan(res);
setDegreeID(res.id);
setActiveDegreeplan(_new);
setDegreeID(_new.id);
} else if (res.status === 409) {
// Case where degree plan of same name already exists.
setNameAlreadyExists(true);
setLoading(false);

setTimeout(() => {
setNameAlreadyExists(false);
}, 5000);
} else {
console.error(await res.text());
}
});
}

createDegreeplan().then(() => {});
};

const complete =
Expand Down Expand Up @@ -203,6 +230,14 @@ export default function CreateWithTranscriptPanel({
onChange={(e) => setName(e.target.value)}
placeholder=""
/>
<ErrorText
style={{
color: "red",
visibility: nameAlreadyExists ? "visible" : "hidden",
}}
>
A degree plan with this name already exists. Please choose a different name.
</ErrorText>
</FieldWrapper>

<FieldWrapper>
Expand Down
2 changes: 1 addition & 1 deletion frontend/degree-plan/hooks/swrcrud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface SWRCrudError extends Error {
/**
* @returns {string | boolean} The CSRF token used by the Django REST Framework
*/
const getCsrf = (): string | boolean => {
export const getCsrf = (): string | boolean => {
const result =
document.cookie &&
document.cookie
Expand Down
Loading