mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-26 07:38:33 -06:00
moving to server actions
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||||
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
||||||
import { withErrorHandling } from "@/services/withErrorHandling";
|
import { withErrorHandling } from "@/services/withErrorHandling";
|
||||||
|
import { revalidatePath } from "next/cache";
|
||||||
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
_request: Request,
|
_request: Request,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
||||||
import { withErrorHandling } from "@/services/withErrorHandling";
|
import { withErrorHandling } from "@/services/withErrorHandling";
|
||||||
|
|
||||||
export const GET = async () =>
|
// export const GET = async () =>
|
||||||
await withErrorHandling(async () => {
|
// await withErrorHandling(async () => {
|
||||||
const directories = await fileStorageService.getEmptyDirectories();
|
// const directories = await fileStorageService.getEmptyDirectories();
|
||||||
return Response.json(directories);
|
// return Response.json(directories);
|
||||||
});
|
// });
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils";
|
|||||||
import { getCourseUrl } from "@/services/urlUtils";
|
import { getCourseUrl } from "@/services/urlUtils";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
export function AssignmentButtons({
|
export function AssignmentButtons({
|
||||||
moduleName,
|
moduleName,
|
||||||
@@ -43,6 +44,7 @@ export function AssignmentButtons({
|
|||||||
const deleteFromCanvas = useDeleteAssignmentFromCanvasMutation();
|
const deleteFromCanvas = useDeleteAssignmentFromCanvasMutation();
|
||||||
const updateAssignment = useUpdateAssignmentInCanvasMutation();
|
const updateAssignment = useUpdateAssignmentInCanvasMutation();
|
||||||
const deleteLocal = useDeleteAssignmentMutation();
|
const deleteLocal = useDeleteAssignmentMutation();
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const assignmentInCanvas = canvasAssignments.find(
|
const assignmentInCanvas = canvasAssignments.find(
|
||||||
(a) => a.name === assignmentName
|
(a) => a.name === assignmentName
|
||||||
@@ -126,12 +128,16 @@ export function AssignmentButtons({
|
|||||||
<br />
|
<br />
|
||||||
<div className="flex justify-around gap-3">
|
<div className="flex justify-around gap-3">
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
|
setIsLoading(true);
|
||||||
router.push(getCourseUrl(courseName));
|
router.push(getCourseUrl(courseName));
|
||||||
deleteLocal.mutate({
|
await deleteLocal.mutateAsync({
|
||||||
moduleName,
|
moduleName,
|
||||||
itemName: assignmentName,
|
itemName: assignmentName,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.refresh();
|
||||||
|
setIsLoading(false);
|
||||||
}}
|
}}
|
||||||
className="btn-danger"
|
className="btn-danger"
|
||||||
>
|
>
|
||||||
@@ -139,6 +145,7 @@ export function AssignmentButtons({
|
|||||||
</button>
|
</button>
|
||||||
<button onClick={closeModal}>No</button>
|
<button onClick={closeModal}>No</button>
|
||||||
</div>
|
</div>
|
||||||
|
{(deleteLocal.isPending || isLoading) && <Spinner />}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ function OtherSettings({
|
|||||||
value={selectedDirectory}
|
value={selectedDirectory}
|
||||||
setValue={setSelectedDirectory}
|
setValue={setSelectedDirectory}
|
||||||
label={"Storage Folder"}
|
label={"Storage Folder"}
|
||||||
options={emptyDirectories}
|
options={emptyDirectories ?? []}
|
||||||
getOptionName={(d) => d}
|
getOptionName={(d) => d}
|
||||||
emptyOptionText="--- add a new folder to your docker compose to add more folders ---"
|
emptyOptionText="--- add a new folder to your docker compose to add more folders ---"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import AddNewCourse from "./newCourse/AddNewCourse";
|
|||||||
|
|
||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
return (
|
return (
|
||||||
<main className="min-h-0 flex justify-center">
|
<main className="h-full flex justify-center overflow-auto">
|
||||||
<div>
|
<div>
|
||||||
<CourseList />
|
<CourseList />
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ import {
|
|||||||
useSuspenseQueries,
|
useSuspenseQueries,
|
||||||
useSuspenseQuery,
|
useSuspenseQuery,
|
||||||
} from "@tanstack/react-query";
|
} from "@tanstack/react-query";
|
||||||
|
import {
|
||||||
|
getAllItemsFromServer,
|
||||||
|
getItemFromServer,
|
||||||
|
} from "./courseItemServerActions";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
export const getAllItemsQueryConfig = <T extends CourseItemType>(
|
export const getAllItemsQueryConfig = <T extends CourseItemType>(
|
||||||
courseName: string,
|
courseName: string,
|
||||||
@@ -29,6 +34,11 @@ export const getAllItemsQueryConfig = <T extends CourseItemType>(
|
|||||||
typeToFolder[type];
|
typeToFolder[type];
|
||||||
const response = await axiosClient.get(url);
|
const response = await axiosClient.get(url);
|
||||||
return response.data;
|
return response.data;
|
||||||
|
// return await getAllItemsFromServer({
|
||||||
|
// courseName,
|
||||||
|
// moduleName,
|
||||||
|
// type,
|
||||||
|
// });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -52,6 +62,12 @@ export const getItemQueryConfig = <T extends CourseItemType>(
|
|||||||
encodeURIComponent(name);
|
encodeURIComponent(name);
|
||||||
const response = await axiosClient.get<CourseItemReturnType<T>>(url);
|
const response = await axiosClient.get<CourseItemReturnType<T>>(url);
|
||||||
return response.data;
|
return response.data;
|
||||||
|
// return await getItemFromServer({
|
||||||
|
// moduleName,
|
||||||
|
// courseName,
|
||||||
|
// itemName: name,
|
||||||
|
// type,
|
||||||
|
// });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -223,6 +239,7 @@ export const useCreateItemMutation = <T extends CourseItemType>(type: T) => {
|
|||||||
|
|
||||||
export const useDeleteItemMutation = <T extends CourseItemType>(type: T) => {
|
export const useDeleteItemMutation = <T extends CourseItemType>(type: T) => {
|
||||||
const { courseName } = useCourseContext();
|
const { courseName } = useCourseContext();
|
||||||
|
const router = useRouter();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async ({
|
mutationFn: async ({
|
||||||
@@ -246,7 +263,7 @@ export const useDeleteItemMutation = <T extends CourseItemType>(type: T) => {
|
|||||||
onSuccess: async (_, { moduleName, itemName }) => {
|
onSuccess: async (_, { moduleName, itemName }) => {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, type),
|
queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, type),
|
||||||
refetchType: "all",
|
// refetchType: "all",
|
||||||
});
|
});
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: localCourseKeys.itemOfType(
|
queryKey: localCourseKeys.itemOfType(
|
||||||
|
|||||||
70
nextjs/src/hooks/localCourse/courseItemServerActions.ts
Normal file
70
nextjs/src/hooks/localCourse/courseItemServerActions.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
"use server";
|
||||||
|
|
||||||
|
import { ItemInDay } from "@/app/course/[courseName]/calendar/day/ItemInDay";
|
||||||
|
import {
|
||||||
|
CourseItemReturnType,
|
||||||
|
CourseItemType,
|
||||||
|
} from "@/models/local/courseItemTypes";
|
||||||
|
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
||||||
|
|
||||||
|
export async function getAllItemsFromServer<T extends CourseItemType>({
|
||||||
|
courseName,
|
||||||
|
moduleName,
|
||||||
|
type,
|
||||||
|
}: {
|
||||||
|
courseName: string;
|
||||||
|
moduleName: string;
|
||||||
|
type: T;
|
||||||
|
}): Promise<CourseItemReturnType<T>[]> {
|
||||||
|
if (type === "Assignment") {
|
||||||
|
const assignments = await fileStorageService.assignments.getAssignments(
|
||||||
|
courseName,
|
||||||
|
moduleName
|
||||||
|
);
|
||||||
|
return assignments as CourseItemReturnType<T>[];
|
||||||
|
}
|
||||||
|
if (type === "Quiz") {
|
||||||
|
const quizzes = await fileStorageService.quizzes.getQuizzes(
|
||||||
|
courseName,
|
||||||
|
moduleName
|
||||||
|
);
|
||||||
|
return quizzes as CourseItemReturnType<T>[];
|
||||||
|
}
|
||||||
|
const pages = await fileStorageService.pages.getPages(courseName, moduleName);
|
||||||
|
return pages as CourseItemReturnType<T>[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getItemFromServer<T extends CourseItemType>({
|
||||||
|
courseName,
|
||||||
|
moduleName,
|
||||||
|
type,
|
||||||
|
itemName,
|
||||||
|
}: {
|
||||||
|
courseName: string;
|
||||||
|
moduleName: string;
|
||||||
|
type: T;
|
||||||
|
itemName: string;
|
||||||
|
}): Promise<CourseItemReturnType<T>> {
|
||||||
|
if (type === "Assignment") {
|
||||||
|
const assignment = await fileStorageService.assignments.getAssignment(
|
||||||
|
courseName,
|
||||||
|
moduleName,
|
||||||
|
itemName
|
||||||
|
);
|
||||||
|
return assignment as CourseItemReturnType<T>;
|
||||||
|
}
|
||||||
|
if (type === "Assignment") {
|
||||||
|
const quiz = await fileStorageService.quizzes.getQuiz(
|
||||||
|
courseName,
|
||||||
|
moduleName,
|
||||||
|
itemName
|
||||||
|
);
|
||||||
|
return quiz as CourseItemReturnType<T>;
|
||||||
|
}
|
||||||
|
const page = await fileStorageService.pages.getPage(
|
||||||
|
courseName,
|
||||||
|
moduleName,
|
||||||
|
itemName
|
||||||
|
);
|
||||||
|
return page as CourseItemReturnType<T>;
|
||||||
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
import { axiosClient } from "@/services/axiosUtils";
|
import { axiosClient } from "@/services/axiosUtils";
|
||||||
import { useSuspenseQuery } from "@tanstack/react-query";
|
import { useQuery, useSuspenseQuery } from "@tanstack/react-query";
|
||||||
|
import { getEmptyDirectories } from "./storageDirectoryServerActions";
|
||||||
|
|
||||||
export const directoryKeys = {
|
export const directoryKeys = {
|
||||||
emptyFolders: ["empty folders"] as const,
|
emptyFolders: ["empty folders"] as const,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useEmptyDirectoriesQuery = () =>
|
export const useEmptyDirectoriesQuery = () =>
|
||||||
useSuspenseQuery({
|
useQuery({
|
||||||
queryKey: directoryKeys.emptyFolders,
|
queryKey: directoryKeys.emptyFolders,
|
||||||
queryFn: getEmptyDirectories
|
queryFn: async () => await getEmptyDirectories(),
|
||||||
|
// queryFn: getEmptyDirectories,
|
||||||
// async () => {
|
// async () => {
|
||||||
// const url = "/api/directories/empty";
|
// const url = "/api/directories/empty";
|
||||||
// const { data } = await axiosClient.get<string[]>(url);
|
// const { data } = await axiosClient.get<string[]>(url);
|
||||||
|
|||||||
Reference in New Issue
Block a user