mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 15:18:32 -06:00
better moving between modles
This commit is contained in:
11
package.json
11
package.json
@@ -2,6 +2,7 @@
|
||||
"name": "canvas-management",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"devNoSocket": "next dev",
|
||||
"dev": "node src/websocket.js",
|
||||
@@ -23,8 +24,8 @@
|
||||
"form-data": "^4.0.1",
|
||||
"jsdom": "^25.0.0",
|
||||
"next": "^15.0.2",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react": "^19",
|
||||
"react-dom": "^19",
|
||||
"socket.io": "^4.8.1",
|
||||
"superjson": "^2.2.1",
|
||||
"ws": "^8.18.0",
|
||||
@@ -32,12 +33,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@monaco-editor/loader": "^1.4.0",
|
||||
"@monaco-editor/react": "^4.6.0",
|
||||
"@monaco-editor/react": "^v4.7.0-rc.0",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@types/node": "^22",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"axios": "^1.7.5",
|
||||
"eslint-config-next": "^14.2.7",
|
||||
|
||||
2079
pnpm-lock.yaml
generated
2079
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
4
run.sh
4
run.sh
@@ -3,6 +3,7 @@
|
||||
docker run -it --rm \
|
||||
--name canvas-manager-2 \
|
||||
-e TZ=America/Denver \
|
||||
-e NODE_ENV=development \
|
||||
-u 1000:1000 \
|
||||
-p 3000:3000 \
|
||||
-w /app \
|
||||
@@ -15,8 +16,9 @@ docker run -it --rm \
|
||||
mkdir -p ~/.npm-global && \
|
||||
npm config set prefix '~/.npm-global' && \
|
||||
export PATH=~/.npm-global/bin:\$PATH && \
|
||||
|
||||
npm install -g pnpm && \
|
||||
pnpm install && pnpm start
|
||||
pnpm install && pnpm dev
|
||||
"
|
||||
|
||||
|
||||
|
||||
@@ -4,100 +4,19 @@ import {
|
||||
CalendarItemsInterface,
|
||||
} from "./calendarItemsContext";
|
||||
import {
|
||||
getDateFromStringOrThrow,
|
||||
getDateOnlyMarkdownString,
|
||||
} from "@/models/local/utils/timeUtils";
|
||||
import { useAllCourseDataQuery } from "@/hooks/localCourse/localCourseModuleHooks";
|
||||
import { trpc } from "@/services/serverFunctions/trpcClient";
|
||||
useCourseQuizzesByModuleByDateQuery,
|
||||
useCourseAssignmentsByModuleByDateQuery,
|
||||
useCoursePagesByModuleByDateQuery,
|
||||
} from "@/hooks/localCourse/localCourseModuleHooks";
|
||||
|
||||
export default function CalendarItemsContextProvider({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const { assignmentsAndModules, quizzesAndModules, pagesAndModules } =
|
||||
useAllCourseDataQuery();
|
||||
|
||||
const assignmentsByModuleByDate = assignmentsAndModules.reduce(
|
||||
(previous, { assignment, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
getDateFromStringOrThrow(
|
||||
assignment.dueAt,
|
||||
"due at for assignment in items context"
|
||||
)
|
||||
);
|
||||
const previousModules = previous[dueDay] ?? {};
|
||||
const previousModule = previousModules[moduleName] ?? {
|
||||
assignments: [],
|
||||
};
|
||||
|
||||
const updatedModule = {
|
||||
...previousModule,
|
||||
assignments: [...previousModule.assignments, assignment],
|
||||
};
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[dueDay]: {
|
||||
...previousModules,
|
||||
[moduleName]: updatedModule,
|
||||
},
|
||||
};
|
||||
},
|
||||
{} as CalendarItemsInterface
|
||||
);
|
||||
|
||||
const quizzesByModuleByDate = quizzesAndModules.reduce(
|
||||
(previous, { quiz, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
getDateFromStringOrThrow(quiz.dueAt, "due at for quiz in items context")
|
||||
);
|
||||
const previousModules = previous[dueDay] ?? {};
|
||||
const previousModule = previousModules[moduleName] ?? {
|
||||
quizzes: [],
|
||||
};
|
||||
|
||||
const updatedModule = {
|
||||
...previousModule,
|
||||
quizzes: [...previousModule.quizzes, quiz],
|
||||
};
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[dueDay]: {
|
||||
...previousModules,
|
||||
[moduleName]: updatedModule,
|
||||
},
|
||||
};
|
||||
},
|
||||
{} as CalendarItemsInterface
|
||||
);
|
||||
|
||||
const pagesByModuleByDate = pagesAndModules.reduce(
|
||||
(previous, { page, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
getDateFromStringOrThrow(page.dueAt, "due at for quiz in items context")
|
||||
);
|
||||
const previousModules = previous[dueDay] ?? {};
|
||||
const previousModule = previousModules[moduleName] ?? {
|
||||
pages: [],
|
||||
};
|
||||
|
||||
const updatedModule = {
|
||||
...previousModule,
|
||||
pages: [...previousModule.pages, page],
|
||||
};
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[dueDay]: {
|
||||
...previousModules,
|
||||
[moduleName]: updatedModule,
|
||||
},
|
||||
};
|
||||
},
|
||||
{} as CalendarItemsInterface
|
||||
);
|
||||
const quizzesByModuleByDate = useCourseQuizzesByModuleByDateQuery();
|
||||
const assignmentsByModuleByDate = useCourseAssignmentsByModuleByDateQuery();
|
||||
const pagesByModuleByDate = useCoursePagesByModuleByDateQuery();
|
||||
|
||||
const allDays = [
|
||||
...new Set([
|
||||
|
||||
@@ -101,8 +101,19 @@ export const useUpdateAssignmentMutation = () => {
|
||||
return trpc.assignment.updateAssignment.useMutation({
|
||||
onSuccess: (
|
||||
_,
|
||||
{ courseName, moduleName, assignmentName, previousAssignmentName }
|
||||
{
|
||||
courseName,
|
||||
moduleName,
|
||||
assignmentName,
|
||||
previousAssignmentName,
|
||||
previousModuleName,
|
||||
}
|
||||
) => {
|
||||
if (moduleName !== previousModuleName)
|
||||
utils.assignment.getAllAssignments.invalidate({
|
||||
courseName,
|
||||
moduleName: previousModuleName,
|
||||
});
|
||||
utils.assignment.getAllAssignments.invalidate({ courseName, moduleName });
|
||||
utils.assignment.getAssignment.invalidate({
|
||||
courseName,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
|
||||
import { trpc } from "@/services/serverFunctions/trpcClient";
|
||||
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||
import { CalendarItemsInterface } from "@/app/course/[courseName]/context/calendarItemsContext";
|
||||
import {
|
||||
getDateOnlyMarkdownString,
|
||||
getDateFromStringOrThrow,
|
||||
} from "@/models/local/utils/timeUtils";
|
||||
|
||||
export const useModuleNamesQuery = () => {
|
||||
const { courseName } = useCourseContext();
|
||||
@@ -18,14 +22,90 @@ export const useCreateModuleMutation = () => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useAllCourseDataQuery = (): {
|
||||
assignmentsAndModules: {
|
||||
moduleName: string;
|
||||
assignment: LocalAssignment;
|
||||
}[];
|
||||
quizzesAndModules: any[];
|
||||
pagesAndModules: any[];
|
||||
} => {
|
||||
export const useCourseQuizzesByModuleByDateQuery = () => {
|
||||
const { courseName } = useCourseContext();
|
||||
const [moduleNames] = useModuleNamesQuery();
|
||||
|
||||
const [quizzes] = trpc.useSuspenseQueries((t) =>
|
||||
moduleNames.map((moduleName) =>
|
||||
t.quiz.getAllQuizzes({ courseName, moduleName })
|
||||
)
|
||||
);
|
||||
|
||||
const quizzesAndModules = moduleNames.flatMap((moduleName, index) => {
|
||||
return quizzes[index].map((quiz) => ({ moduleName, quiz }));
|
||||
});
|
||||
|
||||
const quizzesByModuleByDate = quizzesAndModules.reduce(
|
||||
(previous, { quiz, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
getDateFromStringOrThrow(quiz.dueAt, "due at for quiz in items context")
|
||||
);
|
||||
const previousModules = previous[dueDay] ?? {};
|
||||
const previousModule = previousModules[moduleName] ?? {
|
||||
quizzes: [],
|
||||
};
|
||||
|
||||
const updatedModule = {
|
||||
...previousModule,
|
||||
quizzes: [...previousModule.quizzes, quiz],
|
||||
};
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[dueDay]: {
|
||||
...previousModules,
|
||||
[moduleName]: updatedModule,
|
||||
},
|
||||
};
|
||||
},
|
||||
{} as CalendarItemsInterface
|
||||
);
|
||||
return quizzesByModuleByDate;
|
||||
};
|
||||
|
||||
export const useCoursePagesByModuleByDateQuery = () => {
|
||||
const { courseName } = useCourseContext();
|
||||
const [moduleNames] = useModuleNamesQuery();
|
||||
const [pages] = trpc.useSuspenseQueries((t) =>
|
||||
moduleNames.map((moduleName) =>
|
||||
t.page.getAllPages({ courseName, moduleName })
|
||||
)
|
||||
);
|
||||
|
||||
const pagesAndModules = moduleNames.flatMap((moduleName, index) => {
|
||||
return pages[index].map((page) => ({ moduleName, page }));
|
||||
});
|
||||
|
||||
const pagesByModuleByDate = pagesAndModules.reduce(
|
||||
(previous, { page, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
getDateFromStringOrThrow(page.dueAt, "due at for page in items context")
|
||||
);
|
||||
const previousModules = previous[dueDay] ?? {};
|
||||
const previousModule = previousModules[moduleName] ?? {
|
||||
pages: [],
|
||||
};
|
||||
|
||||
const updatedModule = {
|
||||
...previousModule,
|
||||
pages: [...previousModule.pages, page],
|
||||
};
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[dueDay]: {
|
||||
...previousModules,
|
||||
[moduleName]: updatedModule,
|
||||
},
|
||||
};
|
||||
},
|
||||
{} as CalendarItemsInterface
|
||||
);
|
||||
return pagesByModuleByDate;
|
||||
};
|
||||
|
||||
export const useCourseAssignmentsByModuleByDateQuery = () => {
|
||||
const { courseName } = useCourseContext();
|
||||
const [moduleNames] = useModuleNamesQuery();
|
||||
const [assignments] = trpc.useSuspenseQueries((t) =>
|
||||
@@ -33,29 +113,36 @@ export const useAllCourseDataQuery = (): {
|
||||
t.assignment.getAllAssignments({ courseName, moduleName })
|
||||
)
|
||||
);
|
||||
|
||||
const [quizzes] = trpc.useSuspenseQueries((t) =>
|
||||
moduleNames.map((moduleName) =>
|
||||
t.quiz.getAllQuizzes({ courseName, moduleName })
|
||||
)
|
||||
);
|
||||
console.log(quizzes);
|
||||
|
||||
const [pages] = trpc.useSuspenseQueries((t) =>
|
||||
moduleNames.map((moduleName) =>
|
||||
t.page.getAllPages({ courseName, moduleName })
|
||||
)
|
||||
);
|
||||
|
||||
const assignmentsAndModules = moduleNames.flatMap((moduleName, index) => {
|
||||
return assignments[index].map((assignment) => ({ moduleName, assignment }));
|
||||
});
|
||||
const quizzesAndModules = moduleNames.flatMap((moduleName, index) => {
|
||||
return quizzes[index].map((quiz) => ({ moduleName, quiz }));
|
||||
});
|
||||
const pagesAndModules = moduleNames.flatMap((moduleName, index) => {
|
||||
return pages[index].map((page) => ({ moduleName, page }));
|
||||
});
|
||||
const assignmentsByModuleByDate = assignmentsAndModules.reduce(
|
||||
(previous, { assignment, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
getDateFromStringOrThrow(
|
||||
assignment.dueAt,
|
||||
"due at for assignment in items context"
|
||||
)
|
||||
);
|
||||
const previousModules = previous[dueDay] ?? {};
|
||||
const previousModule = previousModules[moduleName] ?? {
|
||||
assignments: [],
|
||||
};
|
||||
|
||||
return { assignmentsAndModules, quizzesAndModules, pagesAndModules };
|
||||
const updatedModule = {
|
||||
...previousModule,
|
||||
assignments: [...previousModule.assignments, assignment],
|
||||
};
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[dueDay]: {
|
||||
...previousModules,
|
||||
[moduleName]: updatedModule,
|
||||
},
|
||||
};
|
||||
},
|
||||
{} as CalendarItemsInterface
|
||||
);
|
||||
return assignmentsByModuleByDate;
|
||||
};
|
||||
|
||||
@@ -23,9 +23,18 @@ export const usePagesQueries = (moduleName: string) => {
|
||||
export const useUpdatePageMutation = () => {
|
||||
const utils = trpc.useUtils();
|
||||
return trpc.page.updatePage.useMutation({
|
||||
onSuccess: (_, { courseName, moduleName, pageName }) => {
|
||||
onSuccess: (
|
||||
_,
|
||||
{ courseName, moduleName, pageName, previousModuleName }
|
||||
) => {
|
||||
utils.page.getAllPages.invalidate({ courseName, moduleName });
|
||||
utils.page.getPage.invalidate({ courseName, moduleName, pageName });
|
||||
if (moduleName !== previousModuleName) {
|
||||
utils.page.getAllPages.invalidate({
|
||||
courseName,
|
||||
moduleName: previousModuleName,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -23,8 +23,15 @@ export const useQuizzesQueries = (moduleName: string) => {
|
||||
export const useUpdateQuizMutation = () => {
|
||||
const utils = trpc.useUtils();
|
||||
return trpc.quiz.updateQuiz.useMutation({
|
||||
onSuccess: (_, { courseName, moduleName, quizName, previousModuleName }) => {
|
||||
utils.quiz.getAllQuizzes.invalidate({ courseName, moduleName: previousModuleName });
|
||||
onSuccess: (
|
||||
_,
|
||||
{ courseName, moduleName, quizName, previousModuleName }
|
||||
) => {
|
||||
if (moduleName !== previousModuleName)
|
||||
utils.quiz.getAllQuizzes.invalidate({
|
||||
courseName,
|
||||
moduleName: previousModuleName,
|
||||
});
|
||||
utils.quiz.getAllQuizzes.invalidate({ courseName, moduleName });
|
||||
utils.quiz.getQuiz.invalidate({ courseName, moduleName, quizName });
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user