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",
|
"name": "canvas-management",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"devNoSocket": "next dev",
|
"devNoSocket": "next dev",
|
||||||
"dev": "node src/websocket.js",
|
"dev": "node src/websocket.js",
|
||||||
@@ -23,8 +24,8 @@
|
|||||||
"form-data": "^4.0.1",
|
"form-data": "^4.0.1",
|
||||||
"jsdom": "^25.0.0",
|
"jsdom": "^25.0.0",
|
||||||
"next": "^15.0.2",
|
"next": "^15.0.2",
|
||||||
"react": "^18",
|
"react": "^19",
|
||||||
"react-dom": "^18",
|
"react-dom": "^19",
|
||||||
"socket.io": "^4.8.1",
|
"socket.io": "^4.8.1",
|
||||||
"superjson": "^2.2.1",
|
"superjson": "^2.2.1",
|
||||||
"ws": "^8.18.0",
|
"ws": "^8.18.0",
|
||||||
@@ -32,12 +33,12 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@monaco-editor/loader": "^1.4.0",
|
"@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/dom": "^10.4.0",
|
||||||
"@testing-library/react": "^16.0.0",
|
"@testing-library/react": "^16.0.0",
|
||||||
"@types/node": "^22",
|
"@types/node": "^22",
|
||||||
"@types/react": "^18",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^19",
|
||||||
"@vitejs/plugin-react": "^4.3.1",
|
"@vitejs/plugin-react": "^4.3.1",
|
||||||
"axios": "^1.7.5",
|
"axios": "^1.7.5",
|
||||||
"eslint-config-next": "^14.2.7",
|
"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 \
|
docker run -it --rm \
|
||||||
--name canvas-manager-2 \
|
--name canvas-manager-2 \
|
||||||
-e TZ=America/Denver \
|
-e TZ=America/Denver \
|
||||||
|
-e NODE_ENV=development \
|
||||||
-u 1000:1000 \
|
-u 1000:1000 \
|
||||||
-p 3000:3000 \
|
-p 3000:3000 \
|
||||||
-w /app \
|
-w /app \
|
||||||
@@ -15,8 +16,9 @@ docker run -it --rm \
|
|||||||
mkdir -p ~/.npm-global && \
|
mkdir -p ~/.npm-global && \
|
||||||
npm config set prefix '~/.npm-global' && \
|
npm config set prefix '~/.npm-global' && \
|
||||||
export PATH=~/.npm-global/bin:\$PATH && \
|
export PATH=~/.npm-global/bin:\$PATH && \
|
||||||
|
|
||||||
npm install -g pnpm && \
|
npm install -g pnpm && \
|
||||||
pnpm install && pnpm start
|
pnpm install && pnpm dev
|
||||||
"
|
"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,100 +4,19 @@ import {
|
|||||||
CalendarItemsInterface,
|
CalendarItemsInterface,
|
||||||
} from "./calendarItemsContext";
|
} from "./calendarItemsContext";
|
||||||
import {
|
import {
|
||||||
getDateFromStringOrThrow,
|
useCourseQuizzesByModuleByDateQuery,
|
||||||
getDateOnlyMarkdownString,
|
useCourseAssignmentsByModuleByDateQuery,
|
||||||
} from "@/models/local/utils/timeUtils";
|
useCoursePagesByModuleByDateQuery,
|
||||||
import { useAllCourseDataQuery } from "@/hooks/localCourse/localCourseModuleHooks";
|
} from "@/hooks/localCourse/localCourseModuleHooks";
|
||||||
import { trpc } from "@/services/serverFunctions/trpcClient";
|
|
||||||
|
|
||||||
export default function CalendarItemsContextProvider({
|
export default function CalendarItemsContextProvider({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}) {
|
}) {
|
||||||
const { assignmentsAndModules, quizzesAndModules, pagesAndModules } =
|
const quizzesByModuleByDate = useCourseQuizzesByModuleByDateQuery();
|
||||||
useAllCourseDataQuery();
|
const assignmentsByModuleByDate = useCourseAssignmentsByModuleByDateQuery();
|
||||||
|
const pagesByModuleByDate = useCoursePagesByModuleByDateQuery();
|
||||||
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 allDays = [
|
const allDays = [
|
||||||
...new Set([
|
...new Set([
|
||||||
|
|||||||
@@ -101,8 +101,19 @@ export const useUpdateAssignmentMutation = () => {
|
|||||||
return trpc.assignment.updateAssignment.useMutation({
|
return trpc.assignment.updateAssignment.useMutation({
|
||||||
onSuccess: (
|
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.getAllAssignments.invalidate({ courseName, moduleName });
|
||||||
utils.assignment.getAssignment.invalidate({
|
utils.assignment.getAssignment.invalidate({
|
||||||
courseName,
|
courseName,
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
|
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
|
||||||
import { trpc } from "@/services/serverFunctions/trpcClient";
|
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 = () => {
|
export const useModuleNamesQuery = () => {
|
||||||
const { courseName } = useCourseContext();
|
const { courseName } = useCourseContext();
|
||||||
@@ -18,14 +22,90 @@ export const useCreateModuleMutation = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useAllCourseDataQuery = (): {
|
export const useCourseQuizzesByModuleByDateQuery = () => {
|
||||||
assignmentsAndModules: {
|
const { courseName } = useCourseContext();
|
||||||
moduleName: string;
|
const [moduleNames] = useModuleNamesQuery();
|
||||||
assignment: LocalAssignment;
|
|
||||||
}[];
|
const [quizzes] = trpc.useSuspenseQueries((t) =>
|
||||||
quizzesAndModules: any[];
|
moduleNames.map((moduleName) =>
|
||||||
pagesAndModules: any[];
|
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 { courseName } = useCourseContext();
|
||||||
const [moduleNames] = useModuleNamesQuery();
|
const [moduleNames] = useModuleNamesQuery();
|
||||||
const [assignments] = trpc.useSuspenseQueries((t) =>
|
const [assignments] = trpc.useSuspenseQueries((t) =>
|
||||||
@@ -33,29 +113,36 @@ export const useAllCourseDataQuery = (): {
|
|||||||
t.assignment.getAllAssignments({ courseName, moduleName })
|
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) => {
|
const assignmentsAndModules = moduleNames.flatMap((moduleName, index) => {
|
||||||
return assignments[index].map((assignment) => ({ moduleName, assignment }));
|
return assignments[index].map((assignment) => ({ moduleName, assignment }));
|
||||||
});
|
});
|
||||||
const quizzesAndModules = moduleNames.flatMap((moduleName, index) => {
|
const assignmentsByModuleByDate = assignmentsAndModules.reduce(
|
||||||
return quizzes[index].map((quiz) => ({ moduleName, quiz }));
|
(previous, { assignment, moduleName }) => {
|
||||||
});
|
const dueDay = getDateOnlyMarkdownString(
|
||||||
const pagesAndModules = moduleNames.flatMap((moduleName, index) => {
|
getDateFromStringOrThrow(
|
||||||
return pages[index].map((page) => ({ moduleName, page }));
|
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 = () => {
|
export const useUpdatePageMutation = () => {
|
||||||
const utils = trpc.useUtils();
|
const utils = trpc.useUtils();
|
||||||
return trpc.page.updatePage.useMutation({
|
return trpc.page.updatePage.useMutation({
|
||||||
onSuccess: (_, { courseName, moduleName, pageName }) => {
|
onSuccess: (
|
||||||
|
_,
|
||||||
|
{ courseName, moduleName, pageName, previousModuleName }
|
||||||
|
) => {
|
||||||
utils.page.getAllPages.invalidate({ courseName, moduleName });
|
utils.page.getAllPages.invalidate({ courseName, moduleName });
|
||||||
utils.page.getPage.invalidate({ courseName, moduleName, pageName });
|
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 = () => {
|
export const useUpdateQuizMutation = () => {
|
||||||
const utils = trpc.useUtils();
|
const utils = trpc.useUtils();
|
||||||
return trpc.quiz.updateQuiz.useMutation({
|
return trpc.quiz.updateQuiz.useMutation({
|
||||||
onSuccess: (_, { courseName, moduleName, quizName, previousModuleName }) => {
|
onSuccess: (
|
||||||
utils.quiz.getAllQuizzes.invalidate({ courseName, moduleName: previousModuleName });
|
_,
|
||||||
|
{ courseName, moduleName, quizName, previousModuleName }
|
||||||
|
) => {
|
||||||
|
if (moduleName !== previousModuleName)
|
||||||
|
utils.quiz.getAllQuizzes.invalidate({
|
||||||
|
courseName,
|
||||||
|
moduleName: previousModuleName,
|
||||||
|
});
|
||||||
utils.quiz.getAllQuizzes.invalidate({ courseName, moduleName });
|
utils.quiz.getAllQuizzes.invalidate({ courseName, moduleName });
|
||||||
utils.quiz.getQuiz.invalidate({ courseName, moduleName, quizName });
|
utils.quiz.getQuiz.invalidate({ courseName, moduleName, quizName });
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user