From 20b3a0d5112f6abadd98d9382ec3e0f42701034e Mon Sep 17 00:00:00 2001 From: KanonKC Date: Mon, 15 Jan 2024 02:52:09 +0700 Subject: [PATCH 1/5] DataTable --- @/components/ui/select.tsx | 158 +++++++++++++++++++ @/components/ui/table.tsx | 7 +- package-lock.json | 76 +++++++++ package.json | 2 + src/components/Cards/SubmissionCard.tsx | 5 +- src/components/DataTable.tsx | 136 ++++++++++++---- src/components/DataTablePagination.tsx | 108 +++++++++++++ src/components/Tables/MyProblemsTable.tsx | 52 ++++++ src/components/TestcasesGradingIndicator.tsx | 87 ++++++---- src/components/shadcn/Select.tsx | 158 +++++++++++++++++++ src/components/shadcn/Table.tsx | 5 +- src/views/My/Problems/MyProblems.tsx | 4 + 12 files changed, 732 insertions(+), 66 deletions(-) create mode 100644 @/components/ui/select.tsx create mode 100644 src/components/DataTablePagination.tsx create mode 100644 src/components/Tables/MyProblemsTable.tsx create mode 100644 src/components/shadcn/Select.tsx diff --git a/@/components/ui/select.tsx b/@/components/ui/select.tsx new file mode 100644 index 0000000..fe56d4d --- /dev/null +++ b/@/components/ui/select.tsx @@ -0,0 +1,158 @@ +import * as React from "react" +import * as SelectPrimitive from "@radix-ui/react-select" +import { Check, ChevronDown, ChevronUp } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Select = SelectPrimitive.Root + +const SelectGroup = SelectPrimitive.Group + +const SelectValue = SelectPrimitive.Value + +const SelectTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + span]:line-clamp-1", + className + )} + {...props} + > + {children} + + + + +)) +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName + +const SelectScrollUpButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName + +const SelectScrollDownButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollDownButton.displayName = + SelectPrimitive.ScrollDownButton.displayName + +const SelectContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, position = "popper", ...props }, ref) => ( + + + + + {children} + + + + +)) +SelectContent.displayName = SelectPrimitive.Content.displayName + +const SelectLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectLabel.displayName = SelectPrimitive.Label.displayName + +const SelectItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + + {children} + +)) +SelectItem.displayName = SelectPrimitive.Item.displayName + +const SelectSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectSeparator.displayName = SelectPrimitive.Separator.displayName + +export { + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +} diff --git a/@/components/ui/table.tsx b/@/components/ui/table.tsx index c7bed95..7f3502f 100644 --- a/@/components/ui/table.tsx +++ b/@/components/ui/table.tsx @@ -1,6 +1,6 @@ import * as React from "react" -import { cn } from "../../lib/utils" +import { cn } from "@/lib/utils" const Table = React.forwardRef< HTMLTableElement, @@ -42,7 +42,10 @@ const TableFooter = React.forwardRef< >(({ className, ...props }, ref) => ( tr]:last:border-b-0", + className + )} {...props} /> )) diff --git a/package-lock.json b/package-lock.json index 55de72e..6c7462d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.0.3", @@ -33,6 +34,7 @@ "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-toolbar": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-table": "^8.11.6", "@udecode/plate-alignment": "^24.5.2", "@udecode/plate-autoformat": "^24.5.2", "@udecode/plate-basic-marks": "^24.5.2", @@ -1613,6 +1615,49 @@ } } }, + "node_modules/@radix-ui/react-select": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.0.0.tgz", + "integrity": "sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.1", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-separator": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.0.3.tgz", @@ -2252,6 +2297,37 @@ "integrity": "sha512-z/G02d+59gyyUb7KYhKi9jOhicek6QD2oMaotUyG+lUkybpXoV49dY9bj7Ah5Q+y7knK2jU67UTX9FyfGzaxQg==", "dev": true }, + "node_modules/@tanstack/react-table": { + "version": "8.11.6", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.11.6.tgz", + "integrity": "sha512-i0heTVZtuHF9VPMwcYoZ21hbzGDmLjxHYemDMvbGpjk5fUZ8nLF3S8qjVRU79XfPW8KK9o7iTU2fGFVQQmxMSQ==", + "dependencies": { + "@tanstack/table-core": "8.11.6" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.11.6", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.11.6.tgz", + "integrity": "sha512-69WEY1PaZROaGYUrseng4/4sMYnRGhDe1vM6888CnWekGz/wuCnvqwOoOuKGYivnaiI4BVmZq4WKWhvahyj3/g==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@types/is-hotkey": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.8.tgz", diff --git a/package.json b/package.json index 6388ab9..36f45e2 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.0.3", @@ -35,6 +36,7 @@ "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-toolbar": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-table": "^8.11.6", "@udecode/plate-alignment": "^24.5.2", "@udecode/plate-autoformat": "^24.5.2", "@udecode/plate-basic-marks": "^24.5.2", diff --git a/src/components/Cards/SubmissionCard.tsx b/src/components/Cards/SubmissionCard.tsx index d63cacc..c107cbb 100644 --- a/src/components/Cards/SubmissionCard.tsx +++ b/src/components/Cards/SubmissionCard.tsx @@ -37,9 +37,10 @@ const SubmissionCard = ({
+ +
*/} + ); -}; - -export default DataTable; +} diff --git a/src/components/DataTablePagination.tsx b/src/components/DataTablePagination.tsx new file mode 100644 index 0000000..947ecfb --- /dev/null +++ b/src/components/DataTablePagination.tsx @@ -0,0 +1,108 @@ +import { + ArrowLeft, + ArrowRight, + ChevronLeftIcon, + ChevronRightIcon, + +} from "lucide-react" + +import { Table } from "@tanstack/react-table"; + +import { Button } from "./shadcn/Button"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "./shadcn/Select"; + +interface DataTablePaginationProps { + table: Table; +} + +export function DataTablePagination({ + table, +}: DataTablePaginationProps) { + return ( +
+
+ {table.getFilteredSelectedRowModel().rows.length} of{" "} + {table.getFilteredRowModel().rows.length} row(s) selected. +
+
+
+

Rows per page

+ +
+
+ Page {table.getState().pagination.pageIndex + 1} of{" "} + {table.getPageCount()} +
+
+ + + + +
+
+
+ ); +} diff --git a/src/components/Tables/MyProblemsTable.tsx b/src/components/Tables/MyProblemsTable.tsx new file mode 100644 index 0000000..68c7915 --- /dev/null +++ b/src/components/Tables/MyProblemsTable.tsx @@ -0,0 +1,52 @@ +import React from 'react' +import { ProblemPopulateTestcases } from '../../types/models/Problem.model' +import { ColumnDef } from "@tanstack/react-table" +import { Table } from '../shadcn/Table' +import { DataTable } from '../DataTable' +import { readableDateFormat } from '../../utilities/ReadableDateFormat' +import { FileSpreadsheet } from 'lucide-react' +import { Link } from 'react-router-dom' + +const columns: ColumnDef[] = [ + { + accessorKey: "title", + header: "Title", + cell: ({ row }) => { + + console.log(row.original.allowed_languages) + + return ( +
+ + + {row.original.title} + +
+ ) + } + }, + { + accessorKey: "updated_date", + header: "Updated Date", + cell: ({ row }) => ( +
{readableDateFormat(row.original.updated_date)}
+ ) + }, +] + +const MyProblemsTable = ({ + problems +}:{ + problems: ProblemPopulateTestcases[] +}) => { + return ( +
+ +
+ ) +} + +export default MyProblemsTable \ No newline at end of file diff --git a/src/components/TestcasesGradingIndicator.tsx b/src/components/TestcasesGradingIndicator.tsx index 8c7ea9c..6ff5b3f 100644 --- a/src/components/TestcasesGradingIndicator.tsx +++ b/src/components/TestcasesGradingIndicator.tsx @@ -5,45 +5,52 @@ import { HoverCardTrigger, } from "./shadcn/HoverCard"; -type TestcaseGradingResultStatus = "OK" | "TIMEOUT" | "ERROR" | "FAILED" +type TestcaseGradingResultStatus = "OK" | "TIMEOUT" | "ERROR" | "FAILED"; -const TestcaseGradingResult = ({ no,status,disableHover=false,sizeX=2,sizeY=4 }: { +const TestcaseGradingResult = ({ + no, + status, + disableHover = false, + sizeX = 2, + sizeY = 4, + className = "", +}: { no: number | string; status: "OK" | "TIMEOUT" | "ERROR" | "FAILED"; disableHover?: boolean; sizeX?: number; sizeY?: number; + className?: string; }) => { - const chartStyledFunction = () => { - let result = `px-${sizeX} py-${sizeY} cursor-pointer ` + let result = `px-${sizeX} py-${sizeY} cursor-pointer ${className} `; if (status === "OK") { - result += `bg-green-400` + result += `bg-green-400 `; } else if (status === "TIMEOUT") { - result += `bg-yellow-400` + result += `bg-yellow-400 `; } else if (status === "FAILED") { - result += `bg-red-400` + result += `bg-red-400 `; } else if (status === "ERROR") { - result += `bg-zinc-300` + result += `bg-zinc-300 `; } - return result - } + return result; + }; const textStyledFunction = () => { - let result = `font-bold ` + let result = `font-bold `; if (status === "OK") { - result += `text-green-400` + result += `text-green-400`; } else if (status === "TIMEOUT") { - result += `text-yellow-400` + result += `text-yellow-400`; } else if (status === "FAILED") { - result += `text-red-400` + result += `text-red-400`; } else if (status === "ERROR") { - result += `text-zinc-500` + result += `text-zinc-500`; } - return result - } + return result; + }; return ( @@ -54,32 +61,56 @@ const TestcaseGradingResult = ({ no,status,disableHover=false,sizeX=2,sizeY=4 }: {status === "ERROR" &&
} {status === "FAILED" &&
} */} - {!disableHover && -

Testcase #{no}

-

Status: {status}

-

Time Used: 1.234 seconds

-
} + {!disableHover && ( + +

Testcase #{no}

+

+ Status:{" "} + {status} +

+

+ Time Used:{" "} + 1.234 seconds +

+
+ )}
); }; -const TestcasesGradingIndicator = ({submissionTestcases,disableHover=false,className="",sizeX=2,sizeY=4}: { +const TestcasesGradingIndicator = ({ + submissionTestcases, + disableHover = false, + className = "", + sizeX = 2, + sizeY = 4, + testcaseGradingResultClassName = "", +}: { submissionTestcases?: SubmissionTestcaseSecureModel[]; disableHover?: boolean; className?: string; sizeX?: number; sizeY?: number; + testcaseGradingResultClassName?: string; }) => { // useEffect(()=>{ // console.log(submissionTestcases) // },[submissionTestcases]) return (
- { - submissionTestcases?.map((testcase,index) => ( - - )) - } + {submissionTestcases?.map((testcase, index) => ( + + ))}
); }; diff --git a/src/components/shadcn/Select.tsx b/src/components/shadcn/Select.tsx new file mode 100644 index 0000000..24ba608 --- /dev/null +++ b/src/components/shadcn/Select.tsx @@ -0,0 +1,158 @@ +import * as React from "react" +import * as SelectPrimitive from "@radix-ui/react-select" +import { Check, ChevronDown, ChevronUp } from "lucide-react" + +import { cn } from "../../lib/utils" + +const Select = SelectPrimitive.Root + +const SelectGroup = SelectPrimitive.Group + +const SelectValue = SelectPrimitive.Value + +const SelectTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + span]:line-clamp-1", + className + )} + {...props} + > + {children} + + + + +)) +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName + +const SelectScrollUpButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName + +const SelectScrollDownButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollDownButton.displayName = + SelectPrimitive.ScrollDownButton.displayName + +const SelectContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, position = "popper", ...props }, ref) => ( + + + + + {children} + + + + +)) +SelectContent.displayName = SelectPrimitive.Content.displayName + +const SelectLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectLabel.displayName = SelectPrimitive.Label.displayName + +const SelectItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + + {children} + +)) +SelectItem.displayName = SelectPrimitive.Item.displayName + +const SelectSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectSeparator.displayName = SelectPrimitive.Separator.displayName + +export { + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +} diff --git a/src/components/shadcn/Table.tsx b/src/components/shadcn/Table.tsx index c7bed95..6d7543b 100644 --- a/src/components/shadcn/Table.tsx +++ b/src/components/shadcn/Table.tsx @@ -42,7 +42,10 @@ const TableFooter = React.forwardRef< >(({ className, ...props }, ref) => ( tr]:last:border-b-0", + className + )} {...props} /> )) diff --git a/src/views/My/Problems/MyProblems.tsx b/src/views/My/Problems/MyProblems.tsx index 31ae15a..dcc8859 100644 --- a/src/views/My/Problems/MyProblems.tsx +++ b/src/views/My/Problems/MyProblems.tsx @@ -10,6 +10,7 @@ import { NavSidebarContext } from "../../../contexts/NavSidebarContext"; import NavbarSidebarLayout from "../../../layout/NavbarSidebarLayout"; import { ProblemService } from "../../../services/Problem.service"; import { ProblemPopulateTestcases } from "../../../types/models/Problem.model"; +import MyProblemsTable from "../../../components/Tables/MyProblemsTable"; const MyProblems = () => { const accountId = String(localStorage.getItem("account_id")); @@ -78,6 +79,9 @@ const MyProblems = () => { + {/* */} {tabValue === "personal" && filteredProblems.map((problem, index) => ( ))} From e8d6424416967c37834c5bf9b0e14d5b2b486ff2 Mon Sep 17 00:00:00 2001 From: KanonKC Date: Mon, 15 Jan 2024 14:11:21 +0700 Subject: [PATCH 2/5] ProblemTable --- src/components/DataTable.tsx | 2 + src/components/Tables/MyProblemsTable.tsx | 183 ++++++++++++++++------ src/constants/ProgrammingLanguage.ts | 27 ---- src/constants/ProgrammingLanguage.tsx | 33 ++++ src/services/Problem.service.ts | 8 +- src/types/apis/Problem.api.ts | 14 +- src/utilities/CheckRuntimeStatus.ts | 10 ++ src/views/My/Problems/MyProblems.tsx | 17 +- 8 files changed, 209 insertions(+), 85 deletions(-) delete mode 100644 src/constants/ProgrammingLanguage.ts create mode 100644 src/constants/ProgrammingLanguage.tsx create mode 100644 src/utilities/CheckRuntimeStatus.ts diff --git a/src/components/DataTable.tsx b/src/components/DataTable.tsx index 648e48c..ba4f4fa 100644 --- a/src/components/DataTable.tsx +++ b/src/components/DataTable.tsx @@ -90,7 +90,9 @@ export function DataTable({ +
+
{/*
- {/* */} - {tabValue === "personal" && filteredProblems.map((problem, index) => ( + /> + {/* {tabValue === "personal" && filteredProblems.map((problem, index) => ( ))} {tabValue === "manageable" && filteredManageableProblems.map((problem, index) => ( - ))} + ))} */} From 47449f010c3ca94fec8519f38b227243a88c30a3 Mon Sep 17 00:00:00 2001 From: KanonKC Date: Mon, 15 Jan 2024 21:37:57 +0700 Subject: [PATCH 3/5] Problem submission table --- @/components/ui/table.tsx | 2 +- .../TopicCollectionAccordionCard.tsx | 12 +- .../Cards/ProblemCards/MyProblemMiniCard2.tsx | 70 +++++++-- src/components/CheckBadge.tsx | 29 ++++ ...issionSourceCodeAndRuntimeResultDialog.tsx | 62 ++++++++ .../Dropdowns/MyProblemDropdown.tsx | 113 ++++++++++++++ .../CreateCollectionForm/ManageProblems.tsx | 11 +- .../CreateCourseForm/ManageCollections.tsx | 9 +- .../PreviousSubmissionsCombobox.tsx | 123 +++++++++------- src/components/Tables/MyCollectionsTable.tsx | 67 +++++++++ .../Tables/MyProblemSubmissionsTable.tsx | 95 ++++++++++++ .../{ => ProblemTables}/MyProblemsTable.tsx | 76 ++++++---- .../ProblemTables/PublicProblemsTable.tsx | 139 ++++++++++++++++++ src/components/shadcn/Table.tsx | 2 +- src/router.tsx | 2 + src/services/Submission.service.ts | 13 +- src/types/apis/Submission.api.ts | 7 +- src/types/models/Submission.model.ts | 6 + src/views/ExploreProblems.tsx | 10 +- src/views/My/Collections/MyCollections.tsx | 8 +- src/views/My/Problems/MyProblems.tsx | 4 +- src/views/My/Problems/ProblemStatistic.tsx | 46 ++++++ 22 files changed, 780 insertions(+), 126 deletions(-) create mode 100644 src/components/CheckBadge.tsx create mode 100644 src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx create mode 100644 src/components/Dropdowns/MyProblemDropdown.tsx create mode 100644 src/components/Tables/MyCollectionsTable.tsx create mode 100644 src/components/Tables/MyProblemSubmissionsTable.tsx rename src/components/Tables/{ => ProblemTables}/MyProblemsTable.tsx (60%) create mode 100644 src/components/Tables/ProblemTables/PublicProblemsTable.tsx create mode 100644 src/views/My/Problems/ProblemStatistic.tsx diff --git a/@/components/ui/table.tsx b/@/components/ui/table.tsx index 7f3502f..cb7720a 100644 --- a/@/components/ui/table.tsx +++ b/@/components/ui/table.tsx @@ -87,7 +87,7 @@ const TableCell = React.forwardRef< >(({ className, ...props }, ref) => ( )) diff --git a/src/components/Cards/CollectionCards/TopicCollectionAccordionCard.tsx b/src/components/Cards/CollectionCards/TopicCollectionAccordionCard.tsx index d3eb25d..afadfe7 100644 --- a/src/components/Cards/CollectionCards/TopicCollectionAccordionCard.tsx +++ b/src/components/Cards/CollectionCards/TopicCollectionAccordionCard.tsx @@ -12,6 +12,7 @@ import { Card } from "../../shadcn/Card"; import { ScrollArea } from "../../shadcn/ScrollArea"; import PublicProblemMiniCard from "../ProblemCards/PublicProblemMiniCard"; import { handleDeprecatedDescription } from "../../../utilities/HandleDeprecatedDescription"; +import PublicProblemsTable from "../../Tables/ProblemTables/PublicProblemsTable"; const isPassed = (collection: CollectionPopulateCollectionProblemPopulateProblemPopulateAccountAndSubmissionPopulateSubmissionTestcasesSecureModel):boolean => { return collection.problems.filter( @@ -67,7 +68,14 @@ const TopicCollectionAccordianCard = ({ value={JSON.parse(handleDeprecatedDescription(String(collection.description)))} /> - + + collectionProblem.problem + )} + /> + + {/*
{collection.problems.map((problem) => ( ))}
-
+
*/} diff --git a/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx b/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx index bf66148..a0fbca7 100644 --- a/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx +++ b/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx @@ -1,15 +1,17 @@ -import { - FileSpreadsheet -} from "lucide-react"; +import { FileSpreadsheet, Tally4 } from "lucide-react"; import { useState } from "react"; import { ProblemModel, ProblemPopulateTestcases, - ProblemSecureModel + ProblemSecureModel, } from "../../../types/models/Problem.model"; import { onMiddleClickOpenInNewTab } from "../../../utilities/OnMiddleClickOpenInNewTab"; import MyProblemContextMenu from "../../ContextMenus/MyProblemContextMenu"; import { Card } from "../../shadcn/Card"; +import CheckBadge from "../../CheckBadge"; +import { checkRuntimeStatus } from "../../../utilities/CheckRuntimeStatus"; +import { ProgrammingLanguageOptions } from "../../../constants/ProgrammingLanguage"; +import { Link } from "react-router-dom"; const MyProblemMiniCard2 = ({ problem, @@ -17,12 +19,11 @@ const MyProblemMiniCard2 = ({ disabledHighlight = false, onClick = () => {}, }: { - problem: ProblemPopulateTestcases | ProblemSecureModel | ProblemModel; + problem: ProblemPopulateTestcases | ProblemModel; disabled?: boolean; disabledHighlight?: boolean; onClick?: () => void; }) => { - const [highlightTitle, setHighlightTitle] = useState(false); const handleMouseOver = () => { @@ -49,7 +50,12 @@ const MyProblemMiniCard2 = ({ problem && ( onMiddleClickOpenInNewTab(e,`/my/problems/${problem.problem_id}/edit`)} + onMouseDown={(e) => + onMiddleClickOpenInNewTab( + e, + `/my/problems/${problem.problem_id}/edit` + ) + } onClick={() => onClick()} onMouseOver={handleMouseOver} onMouseOut={handleMouseOut} @@ -57,17 +63,55 @@ const MyProblemMiniCard2 = ({ // className={`pt-6 px-5 ${disabled ? "opacity-50" : }`}`} > -
-
+
+
-

{problem.title}

+ +

+ {problem.title} +

+
+
+ +
{problem.testcases.length}
+
+
+ + SC + + 0} + > + TC + + + NRE + +
+
+ {problem.allowed_languages + .split(",") + .map((lang, index) => { + if (index < 3) { + return ProgrammingLanguageOptions.find( + (option) => option.value === lang + )?.badge; + } else if (index === 3) { + return ...; + } + })}
- {/*
- {collection.problems.length} -
*/}
diff --git a/src/components/CheckBadge.tsx b/src/components/CheckBadge.tsx new file mode 100644 index 0000000..0ebaf61 --- /dev/null +++ b/src/components/CheckBadge.tsx @@ -0,0 +1,29 @@ +import React, { ReactNode } from 'react' +import { Badge } from './shadcn/Badge'; +import { Check, X } from 'lucide-react'; + +const CheckBadge = ({ + checked = false, + noIcon=false, + children, + className="" +}: { + checked?: boolean; + noIcon?: boolean; + children?: ReactNode; + className?: string; +}) => { + return checked ? ( + + {!noIcon && } + {children} + + ) : ( + + {!noIcon && } + {children} + + ); +}; + +export default CheckBadge \ No newline at end of file diff --git a/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx b/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx new file mode 100644 index 0000000..e6dcabf --- /dev/null +++ b/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx @@ -0,0 +1,62 @@ +import React from "react"; +import { Dialog, DialogContent, DialogTrigger } from "../shadcn/Dialog"; +import { Maximize2 } from "lucide-react"; +import { Button } from "../shadcn/Button"; +import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from "../../types/models/Submission.model"; +import { Editor as MonacoEditor } from "@monaco-editor/react"; +import TestcaseValidationAccordian from "../TestcaseValidationAccordion"; +import { Separator } from "../shadcn/Seperator"; +import { ScrollArea } from "../shadcn/ScrollArea"; +import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from "../../types/models/Problem.model"; + +const ProblemSubmissionSourceCodeAndRuntimeResultDialog = ({ + submission, + children, + problem +}: { + submission: SubmissionPopulateSubmissionTestcaseAndAccountModel; + children?: React.ReactNode; + problem: ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel +}) => { + const [sourceCode, setSourceCode] = React.useState( + submission.submission_code + ); + + return ( + + {children} + +
+
+ + setSourceCode(submission.submission_code) + } + language={submission.language} + /> +
+ +
+ +
+ +
+ + ({ + ...output, + input: problem.testcases[index].input + }))} + /> + +
+
+
+
+ ); +}; + +export default ProblemSubmissionSourceCodeAndRuntimeResultDialog; diff --git a/src/components/Dropdowns/MyProblemDropdown.tsx b/src/components/Dropdowns/MyProblemDropdown.tsx new file mode 100644 index 0000000..6a1bc46 --- /dev/null +++ b/src/components/Dropdowns/MyProblemDropdown.tsx @@ -0,0 +1,113 @@ +import { CopyPlus, PencilIcon, Trash } from "lucide-react"; +import React, { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { ProblemService } from "../../services/Problem.service"; +import { transformCreateProblemRequestForm2CreateProblemRequest } from "../../types/adapters/CreateProblemRequestForm.adapter"; +import { + ProblemModel, + ProblemPopulateTestcases, + ProblemSecureModel, +} from "../../types/models/Problem.model"; +import DeleteProblemConfirmationDialog from "../Dialogs/DeleteProblemConfirmationDialog"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "../shadcn/DropdownMenu"; +import { toast } from "../shadcn/UseToast"; +import { transformProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel2CreateProblemRequestForm } from "../../types/adapters/Problem.adapter"; + +const MyProblemDropdown = ({ + children, + problem, +}: { + children: React.ReactNode; + problem: ProblemModel | ProblemPopulateTestcases | ProblemSecureModel; +}) => { + const accountId = String(localStorage.getItem("account_id")); + const navigate = useNavigate(); + const [openDeleteDialog, setOpenDeleteDialog] = useState(false); + + const handleCloneProblem = async () => { + const response = await ProblemService.get( + accountId, + problem.problem_id + ); + + let createRequest = transformProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel2CreateProblemRequestForm( + response.data + ) + + createRequest.title += " (Copy)" + + const { request, groups } = + transformCreateProblemRequestForm2CreateProblemRequest( + createRequest + ); + + ProblemService.create(accountId, request) + .then((response) => { + return ProblemService.updateGroupPermissions( + response.data.problem_id, + accountId, + groups + ); + }) + .then((response) => { + // setLoading(false); + toast({ + title: `Cloned ${response.data.title}`, + }); + window.open(`/my/problems/${response.data.problem_id}`, "_blank"); + }); + }; + + return ( + + window.location.reload()} + /> + {children} + + +
{problem.title}
+
+ + + navigate(`/my/problems/${problem.problem_id}`) + } + > + + View Problem + + + navigate(`/my/problems/${problem.problem_id}/edit`) + } + > + + Edit Problem + + + + Clone Problem + + setOpenDeleteDialog(true)} + className="text-red-400" + > + + Delete Problem + +
+
+ ); +}; + +export default MyProblemDropdown; diff --git a/src/components/Forms/CreateCollectionForm/ManageProblems.tsx b/src/components/Forms/CreateCollectionForm/ManageProblems.tsx index 7b6c7e1..9c4d8a0 100644 --- a/src/components/Forms/CreateCollectionForm/ManageProblems.tsx +++ b/src/components/Forms/CreateCollectionForm/ManageProblems.tsx @@ -11,6 +11,7 @@ import MyProblemMiniCard2 from "../../Cards/ProblemCards/MyProblemMiniCard2"; import { Input } from "../../shadcn/Input"; import { ScrollArea } from "../../shadcn/ScrollArea"; import { Separator } from "../../shadcn/Seperator"; +import MyProblemsTable from "../../Tables/ProblemTables/MyProblemsTable"; const ManageProblems = ({ createRequest, @@ -102,15 +103,15 @@ const ManageProblems = ({ console.log("AAA",createRequest) // setSelectedProblemsSortable(createRequest.problemsInterface); setSelectedProblemsSortable( - createRequest.collection?.problems.map((cp) => ({ + createRequest.problemsInterface?.map((cp) => ({ id: cp.problem.problem_id, name: cp.problem.title, problem: cp.problem, - groupPermissions: cp.problem.group_permissions.map((gc) => ({ + groupPermissions: cp.groupPermissions.map((gc) => ({ groupId: gc.group.group_id, group: gc.group, - manageProblems: gc.permission_manage_problems, - viewProblems: gc.permission_view_problems, + manageProblems: gc.manageProblems, + viewProblems: gc.viewProblems, })), })) ?? ([] as ProblemItemInterface[]) ); @@ -170,7 +171,7 @@ const ManageProblems = ({ list={allProblemsSortable} setList={setAllProblemsSortable} filter=".selected" - className="grid grid-cols-3 gap-2 p-2 rounded-md" + className="grid grid-cols-1 gap-2 p-2 rounded-md" > {allProblemsSortable?.map((item) => (
{ @@ -116,16 +117,16 @@ const ManageCollections = ({ useEffect(() => { if (initial) { setSelectedCollectionsSortable( - createRequest.course?.collections.map((cc) => ({ + createRequest.collectionsInterface.map((cc) => ({ id: cc.collection.collection_id, name: cc.collection.name, collection: cc.collection, - groupPermissions: cc.collection.group_permissions.map( + groupPermissions: cc.groupPermissions.map( (gc) => ({ group_id: gc.group.group_id, group: gc.group, - manageCollections: gc.permission_manage_collections, - viewCollections: gc.permission_view_collections, + manageCollections: gc.manageCollections, + viewCollections: gc.viewCollections, }) ), })) ?? ([] as CollectionItemInterface[]) diff --git a/src/components/PreviousSubmissionsCombobox.tsx b/src/components/PreviousSubmissionsCombobox.tsx index 5d63163..2e78137 100644 --- a/src/components/PreviousSubmissionsCombobox.tsx +++ b/src/components/PreviousSubmissionsCombobox.tsx @@ -1,14 +1,14 @@ "use client"; -import { Check, ChevronsUpDown } from "lucide-react"; +import { Check, ChevronsUpDown, Languages } from "lucide-react"; import * as React from "react"; -import { ProgrammingLanguageLabel } from "../constants/ProgrammingLanguage"; +import { ProgrammingLanguageLabel, ProgrammingLanguageOptions } from "../constants/ProgrammingLanguage"; import { TestcaseStatusIndicatorColor } from "../constants/TestcaseStatusIndicatorColor"; import { cn } from "../lib/utils"; import { SubmissionPopulateSubmissionTestcasesSecureModel, - SubmissionTestcaseSecureModel + SubmissionTestcaseSecureModel, } from "../types/models/Submission.model"; import { readableDateFormat } from "../utilities/ReadableDateFormat"; import { Button } from "./shadcn/Button"; @@ -21,6 +21,7 @@ import { } from "./shadcn/Command"; import { Popover, PopoverContent, PopoverTrigger } from "./shadcn/Popover"; import { Separator } from "./shadcn/Seperator"; +import { ScrollArea } from "./shadcn/ScrollArea"; const TestcaseGradingMiniResult = ({ status, @@ -63,7 +64,7 @@ export function PreviousSubmissionsCombobox({ onSelect, }: { submissions: SubmissionPopulateSubmissionTestcasesSecureModel[]; - bestSubmission: SubmissionPopulateSubmissionTestcasesSecureModel ; + bestSubmission: SubmissionPopulateSubmissionTestcasesSecureModel; onSelect?: (value: string) => void; }) { const [open, setOpen] = React.useState(false); @@ -74,7 +75,8 @@ export function PreviousSubmissionsCombobox({
- {readableDateFormat(bestSubmission?.date)} {ProgrammingLanguageLabel[bestSubmission?.language]} + {readableDateFormat(bestSubmission?.date)}{" "} + {ProgrammingLanguageOptions.find((Languages ) => Languages.value === bestSubmission?.language)?.badge}
({ - label: ( -
-
-
- {readableDateFormat(submission?.date)} {ProgrammingLanguageLabel[submission?.language]} -
-
- -
+ const options = submissions.map((submission) => ({ + label: ( +
+
+
+ {readableDateFormat(submission?.date)}{" "} + {ProgrammingLanguageOptions.find((Languages ) => Languages.value === submission?.language)?.badge} +
+
+
- ), - value: String(submission?.submission_id), - }) - ); +
+ ), + value: String(submission?.submission_id), + })); return ( @@ -119,7 +120,9 @@ export function PreviousSubmissionsCombobox({ {value ? options.find((framework) => framework.value === value) ?.label - : (submissions.length === 0 ? "No Previous Submission" : "Previous Submissions")} + : submissions.length === 0 + ? "No Previous Submission" + : "Previous Submissions"} @@ -129,38 +132,14 @@ export function PreviousSubmissionsCombobox({ placeholder={"Select Previous Submissions ..."} /> {"Not found"} -
Best Submission
- - { - if (onSelect) { - onSelect(currentValue); - } - // setValue(currentValue === value ? "" : currentValue) - setValue(currentValue); - setOpen(false); - }} - > - - - {bestOptions.label} - - - - - {options.map((framework) => ( +
+ Best Submission +
+ +
{ if (onSelect) { onSelect(currentValue); @@ -173,15 +152,45 @@ export function PreviousSubmissionsCombobox({ - {framework.label} + {bestOptions.label} - ))} +
+
+ + + + {options.map((framework) => ( + { + if (onSelect) { + onSelect(currentValue); + } + // setValue(currentValue === value ? "" : currentValue) + setValue(currentValue); + setOpen(false); + }} + > + + + {framework.label} + + ))} + diff --git a/src/components/Tables/MyCollectionsTable.tsx b/src/components/Tables/MyCollectionsTable.tsx new file mode 100644 index 0000000..99a4be5 --- /dev/null +++ b/src/components/Tables/MyCollectionsTable.tsx @@ -0,0 +1,67 @@ +import React from 'react' +import { CollectionPopulateCollectionProblemPopulateProblemModel } from '../../types/models/Collection.model' +import { DataTable } from '../DataTable' +import { ColumnDef } from '@tanstack/react-table' +import { FileSpreadsheet, Folder } from 'lucide-react' +import { Link } from 'react-router-dom' +import { readableDateFormat } from '../../utilities/ReadableDateFormat' + +const columns: ColumnDef[] = [ + { + accessorKey: "name", + header: "Title", + cell: ({ row }) => ( +
+ + + {row.original.name} + +
+ ) + }, + { + accessorKey: "problems", + header: "Problems", + cell: ({ row }) => ( +
+ + {row.original.problems.length} +
+ ) + }, + { + accessorKey: "updated_date", + header: "Updated Date", + cell: ({ row }) => ( +
+ {readableDateFormat(row.original.updated_date)} +
+ ), + }, + { + accessorKey: "created_date", + header: "Created Date", + cell: ({ row }) => ( +
+ {readableDateFormat(row.original.created_date)} +
+ ), + }, +] + +const MyCollectionsTable = ({ + collections=[] +}:{ + collections?: CollectionPopulateCollectionProblemPopulateProblemModel[] +}) => { + return ( +
+ +
+ ) +} + +export default MyCollectionsTable \ No newline at end of file diff --git a/src/components/Tables/MyProblemSubmissionsTable.tsx b/src/components/Tables/MyProblemSubmissionsTable.tsx new file mode 100644 index 0000000..5d7a9b1 --- /dev/null +++ b/src/components/Tables/MyProblemSubmissionsTable.tsx @@ -0,0 +1,95 @@ +import React from "react"; +import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from "../../types/models/Submission.model"; +import { ColumnDef } from "@tanstack/react-table"; +import { DataTable } from "../DataTable"; +import TestcasesGradingIndicator from "../TestcasesGradingIndicator"; +import { readableDateFormat } from "../../utilities/ReadableDateFormat"; +import { ProgrammingLanguageOptions } from "../../constants/ProgrammingLanguage"; +import { Button } from "../shadcn/Button"; +import { Maximize, Maximize2 } from "lucide-react"; +import { Dialog, DialogContent, DialogTrigger } from "../shadcn/Dialog"; +import ProblemSubmissionSourceCodeAndRuntimeResultDialog from "../Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog"; +import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from "../../types/models/Problem.model"; + + + +const MyProblemSubmissionsTable = ({ + submissions = [], + problem +}: { + submissions?: SubmissionPopulateSubmissionTestcaseAndAccountModel[]; + problem: ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel +}) => { + + const columns: ColumnDef[] = + [ + { + accessorKey: "username", + header: "Username", + cell: ({ row }) => ( +
+ {row.original.account.username} +
+ ), + }, + { + accessorKey: "language", + header: "Language", + cell: ({ row }) => ( +
+ { + ProgrammingLanguageOptions.find( + (language) => + language.value === row.original.language + )?.badge + } +
+ ), + }, + { + accessorKey: "runtime_result", + header: "Runtime Result", + cell: ({ row }) => ( +
+ +
+ ), + }, + { + accessorKey: "date", + header: "Submitted Date", + cell: ({ row }) => ( +
{readableDateFormat(row.original.date)}
+ ), + }, + { + accessorKey: "action", + header: "", + cell: ({ row }) => ( +
+ + + +
+ ), + }, + ]; + + return ( +
+ +
+ ); +}; + +export default MyProblemSubmissionsTable; diff --git a/src/components/Tables/MyProblemsTable.tsx b/src/components/Tables/ProblemTables/MyProblemsTable.tsx similarity index 60% rename from src/components/Tables/MyProblemsTable.tsx rename to src/components/Tables/ProblemTables/MyProblemsTable.tsx index 50767d9..ab6c817 100644 --- a/src/components/Tables/MyProblemsTable.tsx +++ b/src/components/Tables/ProblemTables/MyProblemsTable.tsx @@ -1,14 +1,26 @@ import React, { ReactNode } from "react"; -import { ProblemPopulateTestcases } from "../../types/models/Problem.model"; +import { ProblemPopulateTestcases } from "../../../types/models/Problem.model"; import { ColumnDef } from "@tanstack/react-table"; -import { Table } from "../shadcn/Table"; -import { DataTable } from "../DataTable"; -import { readableDateFormat } from "../../utilities/ReadableDateFormat"; -import { Check, FileSpreadsheet, X } from "lucide-react"; +import { Table } from "../../shadcn/Table"; +import { DataTable } from "../../DataTable"; +import { readableDateFormat } from "../../../utilities/ReadableDateFormat"; +import { + Check, + FileSpreadsheet, + Layers3, + MoreHorizontal, + MoreVertical, + Tally4, + Timer, + X, +} from "lucide-react"; import { Link } from "react-router-dom"; -import { Badge } from "../shadcn/Badge"; -import { checkRuntimeStatus } from "../../utilities/CheckRuntimeStatus"; -import { ProgrammingLanguageOptions } from "../../constants/ProgrammingLanguage"; +import { Badge } from "../../shadcn/Badge"; +import { checkRuntimeStatus } from "../../../utilities/CheckRuntimeStatus"; +import { ProgrammingLanguageOptions } from "../../../constants/ProgrammingLanguage"; +import MyProblemContextMenu from "../../ContextMenus/MyProblemContextMenu"; +import MyProblemDropdown from "../../Dropdowns/MyProblemDropdown"; +import CheckBadge from "../../CheckBadge"; const columns: ColumnDef[] = [ { @@ -18,7 +30,7 @@ const columns: ColumnDef[] = [ console.log(row.original.allowed_languages); return ( -
+
{row.original.title} @@ -32,7 +44,13 @@ const columns: ColumnDef[] = [ accessorKey: "testcases", header: "Testcases", cell: ({ row }) => ( -
{row.original.testcases.length}
+
+ + {row.original.testcases.length} +
), }, @@ -40,7 +58,10 @@ const columns: ColumnDef[] = [ accessorKey: "time_limit", header: "Time Limit", cell: ({ row }) => ( -
{row.original.time_limit}
+
+ + {row.original.time_limit} +
), }, @@ -48,28 +69,8 @@ const columns: ColumnDef[] = [ accessorKey: "testcases", header: "Status", cell: ({ row }) => { - const CheckBadge = ({ - checked = false, - children, - }: { - checked?: boolean; - children?: ReactNode; - }) => { - return checked ? ( - - - {children} - - ) : ( - - - {children} - - ); - }; - return ( -
+
Source Code @@ -124,6 +125,17 @@ const columns: ColumnDef[] = [
), }, + { + accessorKey: "action", + header: "Action", + cell: ({ row }) => ( +
+ + + +
+ ), + }, ]; const MyProblemsTable = ({ diff --git a/src/components/Tables/ProblemTables/PublicProblemsTable.tsx b/src/components/Tables/ProblemTables/PublicProblemsTable.tsx new file mode 100644 index 0000000..5b57cad --- /dev/null +++ b/src/components/Tables/ProblemTables/PublicProblemsTable.tsx @@ -0,0 +1,139 @@ +import React, { ReactNode } from "react"; +import { + ProblemPopulateAccountAndSubmissionPopulateSubmissionTestcasesSecureModel, + ProblemPopulateTestcases, +} from "../../../types/models/Problem.model"; +import { ColumnDef } from "@tanstack/react-table"; +import { Table } from "../../shadcn/Table"; +import { DataTable } from "../../DataTable"; +import { readableDateFormat } from "../../../utilities/ReadableDateFormat"; +import { + Check, + FileSpreadsheet, + Layers3, + MoreHorizontal, + MoreVertical, + Puzzle, + Tally4, + Timer, + X, +} from "lucide-react"; +import { Link } from "react-router-dom"; +import { Badge } from "../../shadcn/Badge"; +import { checkRuntimeStatus } from "../../../utilities/CheckRuntimeStatus"; +import { ProgrammingLanguageOptions } from "../../../constants/ProgrammingLanguage"; +import MyProblemContextMenu from "../../ContextMenus/MyProblemContextMenu"; +import MyProblemDropdown from "../../Dropdowns/MyProblemDropdown"; +import CheckBadge from "../../CheckBadge"; +import TestcasesGradingIndicator from "../../TestcasesGradingIndicator"; +import { Button } from "../../shadcn/Button"; + +const columns: ColumnDef[] = + [ + { + accessorKey: "title", + header: "Title", + cell: ({ row }) => { + console.log(row.original.allowed_languages); + + return ( +
+ + + {row.original.title} + +
+ ); + }, + }, + + { + accessorKey: "author", + header: "Author", + cell: ({ row }) => ( +
+ {row.original.creator.username} +
+ ), + }, + { + accessorKey: "allowed_languages", + header: "Allowed Languages", + cell: ({ row }) => ( +
+ {row.original.allowed_languages.split(",").map((lang) => ( + + { + ProgrammingLanguageOptions.find( + (option) => option.value === lang + )?.badge + } + + ))} +
+ ), + }, + { + accessorKey: "best_submissions", + header: "Best Submissions", + cell: ({ row }) => ( +
+ +
+ ), + }, + + { + accessorKey: "updated_date", + header: "Updated Date", + cell: ({ row }) => ( +
+ {readableDateFormat(row.original.updated_date)} +
+ ), + }, + + { + accessorKey: "action", + header: "", + cell: ({ row }) => ( +
+ + + +
+ ), + }, + ]; + +const PublicProblemsTable = ({ + problems, +}: { + problems: ProblemPopulateAccountAndSubmissionPopulateSubmissionTestcasesSecureModel[]; +}) => { + return ( +
+ +
+ ); +}; + +export default PublicProblemsTable; diff --git a/src/components/shadcn/Table.tsx b/src/components/shadcn/Table.tsx index 6d7543b..9cc5cf1 100644 --- a/src/components/shadcn/Table.tsx +++ b/src/components/shadcn/Table.tsx @@ -87,7 +87,7 @@ const TableCell = React.forwardRef< >(({ className, ...props }, ref) => ( )) diff --git a/src/router.tsx b/src/router.tsx index 7b41ffd..71009c8 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -23,6 +23,7 @@ import ViewCourseProblem from "./views/ViewCourseProblem"; import ViewProblem from "./views/ViewProblem"; import { useContext, useEffect } from "react"; import { LoginContext } from "./contexts/LoginContext"; +import ProblemStatistic from "./views/My/Problems/ProblemStatistic"; const Router = () => { @@ -48,6 +49,7 @@ const Router = () => { } /> } /> + } /> } /> } /> diff --git a/src/services/Submission.service.ts b/src/services/Submission.service.ts index 3f5e6fe..a4bce4d 100644 --- a/src/services/Submission.service.ts +++ b/src/services/Submission.service.ts @@ -1,11 +1,13 @@ import axios from "axios"; import { BASE_URL } from "../constants/BackendBaseURL"; -import { GetAllSubmissionsResponse, SubmissionServiceAPI } from "../types/apis/Submission.api"; +import { GetAllSubmissionsResponse, GetSubmissionsByCretorProblemResponse, SubmissionServiceAPI } from "../types/apis/Submission.api"; import { GetSubmissionByAccountProblemResponse, SubmissionPopulateSubmissionTestcasesSecureModel } from "../types/models/Submission.model"; + + export const SubmissionService: SubmissionServiceAPI = { submit: async (accountId, problemId, request) => { - const response = await axios.post(`${BASE_URL}/api/accounts/${accountId}/problems/${problemId}/submissions`,request); + const response = await axios.post(`${BASE_URL}/api/problems/${problemId}/accounts/${accountId}/submissions`,request); return response; }, @@ -14,8 +16,13 @@ export const SubmissionService: SubmissionServiceAPI = { return response; }, + getByCreatorProblem: async (accountId, problemId) => { + const response = await axios.get(`${BASE_URL}/api/accounts/${accountId}/problems/${problemId}/submissions`); + return response; + }, + getByAccountProblem: async (accountId, problemId) => { - const response = await axios.get(`${BASE_URL}/api/accounts/${accountId}/problems/${problemId}/submissions`); + const response = await axios.get(`${BASE_URL}/api/problems/${problemId}/accounts/${accountId}/submissions`); return response; }, diff --git a/src/types/apis/Submission.api.ts b/src/types/apis/Submission.api.ts index f794db2..f589722 100644 --- a/src/types/apis/Submission.api.ts +++ b/src/types/apis/Submission.api.ts @@ -1,6 +1,6 @@ import { AxiosResponse } from "axios"; import { ProblemPopulateAccountSecureModel } from "../models/Problem.model"; -import { GetSubmissionByAccountProblemResponse, SubmissionPopulateSubmissionTestcaseAndProblemSecureModel, SubmissionPopulateSubmissionTestcasesSecureModel, SubmissionTestcaseSecureModel } from "../models/Submission.model"; +import { GetSubmissionByAccountProblemResponse, SubmissionPopulateSubmissionTestcaseAndAccountModel, SubmissionPopulateSubmissionTestcaseAndProblemSecureModel, SubmissionPopulateSubmissionTestcasesSecureModel, SubmissionTestcaseSecureModel } from "../models/Submission.model"; export type SubmitProblemRequest = { language: string @@ -35,9 +35,14 @@ export type GetAllSubmissionsResponse = { submissions: SubmissionPopulateSubmissionTestcaseAndProblemSecureModel[] } +export type GetSubmissionsByCretorProblemResponse = { + submissions: SubmissionPopulateSubmissionTestcaseAndAccountModel[] +} + export type SubmissionServiceAPI = { submit: (accountId:string,problemId:string,request: SubmitProblemRequest) => Promise>; topicSubmit: (accountId:string,topicId:string,problemId:string,request: SubmitProblemRequest) => Promise>; + getByCreatorProblem: (accountId:string,problemId:string) => Promise>; getByAccountProblem: (accountId:string,problemId:string) => Promise>; getByAccountProblemInTopic: (accountId:string,problemId:string,topicId:string) => Promise>; getAll: (query?:GetAllSubmissionsQuery) => Promise>; diff --git a/src/types/models/Submission.model.ts b/src/types/models/Submission.model.ts index 0693779..48f29bc 100644 --- a/src/types/models/Submission.model.ts +++ b/src/types/models/Submission.model.ts @@ -1,3 +1,4 @@ +import { AccountSecureModel } from "./Account.model"; import { ProblemModel, ProblemSecureModel } from "./Problem.model"; export type SubmissionTestcaseModel = { @@ -103,4 +104,9 @@ export type SubmissionPopulateSubmissionTestcasesSecureModel = { export type SubmissionPopulateSubmissionTestcaseAndProblemSecureModel = SubmissionModel & { problem: ProblemSecureModel; runtime_output: SubmissionTestcaseSecureModel[]; +} + +export type SubmissionPopulateSubmissionTestcaseAndAccountModel = SubmissionModel & { + account: AccountSecureModel; + runtime_output: SubmissionTestcaseModel[]; } \ No newline at end of file diff --git a/src/views/ExploreProblems.tsx b/src/views/ExploreProblems.tsx index cd06804..b6a39a0 100644 --- a/src/views/ExploreProblems.tsx +++ b/src/views/ExploreProblems.tsx @@ -5,6 +5,7 @@ import { Separator } from "../components/shadcn/Seperator"; import NavbarMenuLayout from "../layout/NavbarMenuLayout"; import { ProblemService } from "../services/Problem.service"; import { ProblemPopulateAccountAndSubmissionPopulateSubmissionTestcasesSecureModel } from "../types/models/Problem.model"; +import PublicProblemsTable from "../components/Tables/ProblemTables/PublicProblemsTable"; const ExploreProblems = () => { const [problems, setProblems] = useState< @@ -23,10 +24,13 @@ const ExploreProblems = () => {

Explore Public Problems

- - {problems.map((problem) => ( + + {/* {problems.map((problem) => ( - ))} + ))} */} +
diff --git a/src/views/My/Collections/MyCollections.tsx b/src/views/My/Collections/MyCollections.tsx index 04ec72c..98bd31b 100644 --- a/src/views/My/Collections/MyCollections.tsx +++ b/src/views/My/Collections/MyCollections.tsx @@ -12,6 +12,7 @@ import { CollectionService } from "../../../services/Collection.service"; import { CollectionPopulateCollectionProblemPopulateProblemModel } from "../../../types/models/Collection.model"; +import MyCollectionsTable from "../../../components/Tables/MyCollectionsTable"; const MyCollections = () => { const navigate = useNavigate(); @@ -92,14 +93,17 @@ const MyCollections = () => {
- {tabValue === "personal" && + + {/* {tabValue === "personal" && filteredCollections.map((collection) => ( ))} {tabValue === "manageable" && filteredManageableCollections.map((collection) => ( - ))} + ))} */}
diff --git a/src/views/My/Problems/MyProblems.tsx b/src/views/My/Problems/MyProblems.tsx index ea30123..f955ef9 100644 --- a/src/views/My/Problems/MyProblems.tsx +++ b/src/views/My/Problems/MyProblems.tsx @@ -10,7 +10,7 @@ import { NavSidebarContext } from "../../../contexts/NavSidebarContext"; import NavbarSidebarLayout from "../../../layout/NavbarSidebarLayout"; import { ProblemService } from "../../../services/Problem.service"; import { ProblemPopulateTestcases } from "../../../types/models/Problem.model"; -import MyProblemsTable from "../../../components/Tables/MyProblemsTable"; +import MyProblemsTable from "../../../components/Tables/ProblemTables/MyProblemsTable"; const MyProblems = () => { const accountId = String(localStorage.getItem("account_id")); @@ -44,7 +44,7 @@ const MyProblems = () => { }).then((response) => { setProblems(response.data.problems); setManageableProblems(response.data.manageable_problems) - return ProblemService.getAllAsCreator(accountId,{start: 10}) + return ProblemService.getAllAsCreator(accountId) }).then((response) => { setProblems(response.data.problems); setManageableProblems(response.data.manageable_problems) diff --git a/src/views/My/Problems/ProblemStatistic.tsx b/src/views/My/Problems/ProblemStatistic.tsx new file mode 100644 index 0000000..c179a2c --- /dev/null +++ b/src/views/My/Problems/ProblemStatistic.tsx @@ -0,0 +1,46 @@ +import React, { useEffect, useState } from 'react' +import NavbarSidebarLayout from '../../../layout/NavbarSidebarLayout' +import { useParams } from 'react-router-dom' +import { ProblemService } from './../../../services/Problem.service'; +import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from '../../../types/models/Problem.model'; +import { SubmissionService } from '../../../services/Submission.service'; +import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from '../../../types/models/Submission.model'; +import MyProblemSubmissionsTable from '../../../components/Tables/MyProblemSubmissionsTable'; + +const ProblemStatistic = () => { + + const {problemId} = useParams() + const accountId = String(localStorage.getItem("account_id")); + + const [problem,setProblem] = useState() + const [submissions,setSubmissions] = useState() + + useEffect(() => { + + if (!problemId) return + + ProblemService.get(accountId,problemId).then((response) => { + console.log('problem',response.data) + setProblem(response.data) + return SubmissionService.getByCreatorProblem(accountId,problemId) + }).then((response) => { + setSubmissions(response.data.submissions) + }) + },[accountId,problemId]) + + return ( + +
+
{problem?.title}
+
+ {problem && } +
+
+
+ ) +} + +export default ProblemStatistic \ No newline at end of file From 728dd1cb9ef8fcef57f76c76c526aaaf69006b69 Mon Sep 17 00:00:00 2001 From: KanonKC Date: Mon, 15 Jan 2024 21:51:27 +0700 Subject: [PATCH 4/5] Problem/Collection table are now work with manageable --- .../Cards/ProblemCards/MyProblemMiniCard2.tsx | 4 +- ...issionSourceCodeAndRuntimeResultDialog.tsx | 2 +- .../CreateCollectionForm/ManageProblems.tsx | 16 ++- src/components/Tables/MyCollectionsTable.tsx | 4 +- .../Tables/ProblemTables/MyProblemsTable.tsx | 4 +- src/views/My/Collections/MyCollections.tsx | 67 +++++++----- src/views/My/Problems/MyProblems.tsx | 14 +-- src/views/My/Problems/ProblemStatistic.tsx | 103 ++++++++++-------- 8 files changed, 129 insertions(+), 85 deletions(-) diff --git a/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx b/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx index a0fbca7..a3d6e34 100644 --- a/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx +++ b/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx @@ -74,7 +74,7 @@ const MyProblemMiniCard2 = ({ {problem.title}

-
+ {/*
{problem.testcases.length}
@@ -111,7 +111,7 @@ const MyProblemMiniCard2 = ({ return ...; } })} -
+
*/}
diff --git a/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx b/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx index e6dcabf..e3f0290 100644 --- a/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx +++ b/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx @@ -48,7 +48,7 @@ const ProblemSubmissionSourceCodeAndRuntimeResultDialog = ({ ({ ...output, - input: problem.testcases[index].input + input: problem.testcases[index]?.input }))} /> diff --git a/src/components/Forms/CreateCollectionForm/ManageProblems.tsx b/src/components/Forms/CreateCollectionForm/ManageProblems.tsx index 9c4d8a0..a9b03bb 100644 --- a/src/components/Forms/CreateCollectionForm/ManageProblems.tsx +++ b/src/components/Forms/CreateCollectionForm/ManageProblems.tsx @@ -72,7 +72,21 @@ const ManageProblems = ({ }, [selectedProblemsSortable]); useEffect(() => { - ProblemService.getAllAsCreator(accountId).then((response) => { + ProblemService.getAllAsCreator(accountId,{end:10}).then((response) => { + setAllProblems( + transformProblemModel2ProblemHashedTable(response.data.problems) + ); + setAllProblemsSortable( + response.data.problems.map((problem) => ({ + id: problem.problem_id, + name: problem.title, + problem: problem, + groupPermissions: [], + })) + ); + + return ProblemService.getAllAsCreator(accountId,{start:10}) + }).then((response) => { setAllProblems( transformProblemModel2ProblemHashedTable(response.data.problems) ); diff --git a/src/components/Tables/MyCollectionsTable.tsx b/src/components/Tables/MyCollectionsTable.tsx index 99a4be5..8179de8 100644 --- a/src/components/Tables/MyCollectionsTable.tsx +++ b/src/components/Tables/MyCollectionsTable.tsx @@ -33,7 +33,7 @@ const columns: ColumnDef ( -
+
{readableDateFormat(row.original.updated_date)}
), @@ -42,7 +42,7 @@ const columns: ColumnDef ( -
+
{readableDateFormat(row.original.created_date)}
), diff --git a/src/components/Tables/ProblemTables/MyProblemsTable.tsx b/src/components/Tables/ProblemTables/MyProblemsTable.tsx index ab6c817..b32d940 100644 --- a/src/components/Tables/ProblemTables/MyProblemsTable.tsx +++ b/src/components/Tables/ProblemTables/MyProblemsTable.tsx @@ -111,7 +111,7 @@ const columns: ColumnDef[] = [ accessorKey: "updated_date", header: "Updated Date", cell: ({ row }) => ( -
+
{readableDateFormat(row.original.updated_date)}
), @@ -120,7 +120,7 @@ const columns: ColumnDef[] = [ accessorKey: "created_date", header: "Created Date", cell: ({ row }) => ( -
+
{readableDateFormat(row.original.created_date)}
), diff --git a/src/views/My/Collections/MyCollections.tsx b/src/views/My/Collections/MyCollections.tsx index 98bd31b..62c2b3d 100644 --- a/src/views/My/Collections/MyCollections.tsx +++ b/src/views/My/Collections/MyCollections.tsx @@ -9,9 +9,7 @@ import { Tabs, TabsList, TabsTrigger } from "../../../components/shadcn/Tabs"; import { NavSidebarContext } from "../../../contexts/NavSidebarContext"; import NavbarSidebarLayout from "../../../layout/NavbarSidebarLayout"; import { CollectionService } from "../../../services/Collection.service"; -import { - CollectionPopulateCollectionProblemPopulateProblemModel -} from "../../../types/models/Collection.model"; +import { CollectionPopulateCollectionProblemPopulateProblemModel } from "../../../types/models/Collection.model"; import MyCollectionsTable from "../../../components/Tables/MyCollectionsTable"; const MyCollections = () => { @@ -27,25 +25,35 @@ const MyCollections = () => { const [filteredCollections, setFilteredCollections] = useState< CollectionPopulateCollectionProblemPopulateProblemModel[] >([]); - const [filteredManageableCollections, setFilteredManageableCollections] = useState< - CollectionPopulateCollectionProblemPopulateProblemModel[] - >([]); + const [filteredManageableCollections, setFilteredManageableCollections] = + useState([]); const { setSection } = useContext(NavSidebarContext); const [tabValue, setTabValue] = useState("personal"); - const [searchValue, setSearchValue] = useState("") + const [searchValue, setSearchValue] = useState(""); useEffect(() => { if (!searchValue || searchValue === "") { - setFilteredCollections(collections) - setFilteredManageableCollections(manageableCollections) - } - else { - setFilteredCollections(collections.filter((collection) => collection.name.toLowerCase().includes(searchValue.toLowerCase()))) - setFilteredManageableCollections(manageableCollections.filter((collection) => collection.name.toLowerCase().includes(searchValue.toLowerCase()))) + setFilteredCollections(collections); + setFilteredManageableCollections(manageableCollections); + } else { + setFilteredCollections( + collections.filter((collection) => + collection.name + .toLowerCase() + .includes(searchValue.toLowerCase()) + ) + ); + setFilteredManageableCollections( + manageableCollections.filter((collection) => + collection.name + .toLowerCase() + .includes(searchValue.toLowerCase()) + ) + ); } - },[searchValue,collections,manageableCollections]) + }, [searchValue, collections, manageableCollections]); useEffect(() => { setSection("COLLECTIONS"); @@ -65,7 +73,11 @@ const MyCollections = () => {
- setSearchValue(e.target.value)} placeholder="Search ..." /> + setSearchValue(e.target.value)} + placeholder="Search ..." + />
{
- - {/* {tabValue === "personal" && - filteredCollections.map((collection) => ( - - ))} + {/* */} + { + tabValue === "personal" && ( + + ) + // + } {tabValue === "manageable" && - filteredManageableCollections.map((collection) => ( - - ))} */} + // filteredManageableCollections.map((collection) => ( + + // + }
diff --git a/src/views/My/Problems/MyProblems.tsx b/src/views/My/Problems/MyProblems.tsx index f955ef9..2336d48 100644 --- a/src/views/My/Problems/MyProblems.tsx +++ b/src/views/My/Problems/MyProblems.tsx @@ -86,15 +86,13 @@ const MyProblems = () => {
- - {/* {tabValue === "personal" && filteredProblems.map((problem, index) => ( - - ))} - {tabValue === "manageable" && filteredManageableProblems.map((problem, index) => ( - - ))} */} + />} + {tabValue === "manageable" && }
diff --git a/src/views/My/Problems/ProblemStatistic.tsx b/src/views/My/Problems/ProblemStatistic.tsx index c179a2c..f6181c8 100644 --- a/src/views/My/Problems/ProblemStatistic.tsx +++ b/src/views/My/Problems/ProblemStatistic.tsx @@ -1,46 +1,61 @@ -import React, { useEffect, useState } from 'react' -import NavbarSidebarLayout from '../../../layout/NavbarSidebarLayout' -import { useParams } from 'react-router-dom' -import { ProblemService } from './../../../services/Problem.service'; -import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from '../../../types/models/Problem.model'; -import { SubmissionService } from '../../../services/Submission.service'; -import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from '../../../types/models/Submission.model'; -import MyProblemSubmissionsTable from '../../../components/Tables/MyProblemSubmissionsTable'; +import React, { useEffect, useState } from "react"; +import NavbarSidebarLayout from "../../../layout/NavbarSidebarLayout"; +import { Link, useParams } from "react-router-dom"; +import { ProblemService } from "./../../../services/Problem.service"; +import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from "../../../types/models/Problem.model"; +import { SubmissionService } from "../../../services/Submission.service"; +import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from "../../../types/models/Submission.model"; +import MyProblemSubmissionsTable from "../../../components/Tables/MyProblemSubmissionsTable"; +import { Button } from "../../../components/shadcn/Button"; const ProblemStatistic = () => { - - const {problemId} = useParams() - const accountId = String(localStorage.getItem("account_id")); - - const [problem,setProblem] = useState() - const [submissions,setSubmissions] = useState() - - useEffect(() => { - - if (!problemId) return - - ProblemService.get(accountId,problemId).then((response) => { - console.log('problem',response.data) - setProblem(response.data) - return SubmissionService.getByCreatorProblem(accountId,problemId) - }).then((response) => { - setSubmissions(response.data.submissions) - }) - },[accountId,problemId]) - - return ( - -
-
{problem?.title}
-
- {problem && } -
-
-
- ) -} - -export default ProblemStatistic \ No newline at end of file + const { problemId } = useParams(); + const accountId = String(localStorage.getItem("account_id")); + + const [problem, setProblem] = + useState(); + const [submissions, setSubmissions] = + useState(); + + useEffect(() => { + if (!problemId) return; + + ProblemService.get(accountId, problemId) + .then((response) => { + console.log("problem", response.data); + setProblem(response.data); + return SubmissionService.getByCreatorProblem( + accountId, + problemId + ); + }) + .then((response) => { + setSubmissions(response.data.submissions); + }); + }, [accountId, problemId]); + + return ( + +
+
{problem?.title}
+ +
+ + + +
+ +
+ {problem && ( + + )} +
+
+
+ ); +}; + +export default ProblemStatistic; From 8c46121f25dc04750c3396dd8c4eeb1d94f23fd9 Mon Sep 17 00:00:00 2001 From: KanonKC Date: Mon, 15 Jan 2024 22:00:37 +0700 Subject: [PATCH 5/5] Clear warning --- .../TopicCollectionAccordionCard.tsx | 6 ++--- .../Cards/ProblemCards/MyProblemMiniCard2.tsx | 9 ++----- src/components/CheckBadge.tsx | 4 +-- src/components/DataTable.tsx | 3 +-- ...issionSourceCodeAndRuntimeResultDialog.tsx | 10 +++---- .../CreateCollectionForm/ManageProblems.tsx | 1 - .../PreviousSubmissionsCombobox.tsx | 6 ++--- src/components/Tables/MyCollectionsTable.tsx | 5 ++-- .../Tables/MyProblemSubmissionsTable.tsx | 14 +++++----- .../Tables/ProblemTables/MyProblemsTable.tsx | 20 +++++--------- .../ProblemTables/PublicProblemsTable.tsx | 27 +++++-------------- src/views/ExploreProblems.tsx | 3 +-- src/views/My/Collections/MyCollections.tsx | 3 +-- src/views/My/Problems/MyProblems.tsx | 3 +-- src/views/My/Problems/ProblemStatistic.tsx | 12 ++++----- 15 files changed, 43 insertions(+), 83 deletions(-) diff --git a/src/components/Cards/CollectionCards/TopicCollectionAccordionCard.tsx b/src/components/Cards/CollectionCards/TopicCollectionAccordionCard.tsx index afadfe7..ac3157d 100644 --- a/src/components/Cards/CollectionCards/TopicCollectionAccordionCard.tsx +++ b/src/components/Cards/CollectionCards/TopicCollectionAccordionCard.tsx @@ -1,6 +1,8 @@ import { Check, FileCheck, Folder } from "lucide-react"; import { CollectionPopulateCollectionProblemPopulateProblemPopulateAccountAndSubmissionPopulateSubmissionTestcasesSecureModel } from "../../../types/models/Collection.model"; +import { handleDeprecatedDescription } from "../../../utilities/HandleDeprecatedDescription"; import ReadOnlyPlate from "../../ReadOnlyPlate"; +import PublicProblemsTable from "../../Tables/ProblemTables/PublicProblemsTable"; import { Accordion, AccordionContent, @@ -9,10 +11,6 @@ import { } from "../../shadcn/Accordion"; import { Badge } from "../../shadcn/Badge"; import { Card } from "../../shadcn/Card"; -import { ScrollArea } from "../../shadcn/ScrollArea"; -import PublicProblemMiniCard from "../ProblemCards/PublicProblemMiniCard"; -import { handleDeprecatedDescription } from "../../../utilities/HandleDeprecatedDescription"; -import PublicProblemsTable from "../../Tables/ProblemTables/PublicProblemsTable"; const isPassed = (collection: CollectionPopulateCollectionProblemPopulateProblemPopulateAccountAndSubmissionPopulateSubmissionTestcasesSecureModel):boolean => { return collection.problems.filter( diff --git a/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx b/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx index a3d6e34..e9e3bbf 100644 --- a/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx +++ b/src/components/Cards/ProblemCards/MyProblemMiniCard2.tsx @@ -1,17 +1,12 @@ -import { FileSpreadsheet, Tally4 } from "lucide-react"; +import { FileSpreadsheet } from "lucide-react"; import { useState } from "react"; import { ProblemModel, - ProblemPopulateTestcases, - ProblemSecureModel, + ProblemPopulateTestcases } from "../../../types/models/Problem.model"; import { onMiddleClickOpenInNewTab } from "../../../utilities/OnMiddleClickOpenInNewTab"; import MyProblemContextMenu from "../../ContextMenus/MyProblemContextMenu"; import { Card } from "../../shadcn/Card"; -import CheckBadge from "../../CheckBadge"; -import { checkRuntimeStatus } from "../../../utilities/CheckRuntimeStatus"; -import { ProgrammingLanguageOptions } from "../../../constants/ProgrammingLanguage"; -import { Link } from "react-router-dom"; const MyProblemMiniCard2 = ({ problem, diff --git a/src/components/CheckBadge.tsx b/src/components/CheckBadge.tsx index 0ebaf61..ec46e1f 100644 --- a/src/components/CheckBadge.tsx +++ b/src/components/CheckBadge.tsx @@ -1,6 +1,6 @@ -import React, { ReactNode } from 'react' -import { Badge } from './shadcn/Badge'; import { Check, X } from 'lucide-react'; +import { ReactNode } from 'react'; +import { Badge } from './shadcn/Badge'; const CheckBadge = ({ checked = false, diff --git a/src/components/DataTable.tsx b/src/components/DataTable.tsx index ba4f4fa..8562009 100644 --- a/src/components/DataTable.tsx +++ b/src/components/DataTable.tsx @@ -8,6 +8,7 @@ import { useReactTable, } from "@tanstack/react-table"; +import { DataTablePagination } from "./DataTablePagination"; import { Table, TableBody, @@ -16,8 +17,6 @@ import { TableHeader, TableRow, } from "./shadcn/Table"; -import { Button } from "./shadcn/Button"; -import { DataTablePagination } from "./DataTablePagination"; interface DataTableProps { columns: ColumnDef[]; diff --git a/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx b/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx index e3f0290..fd4d7d8 100644 --- a/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx +++ b/src/components/Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog.tsx @@ -1,13 +1,11 @@ +import { Editor as MonacoEditor } from "@monaco-editor/react"; import React from "react"; -import { Dialog, DialogContent, DialogTrigger } from "../shadcn/Dialog"; -import { Maximize2 } from "lucide-react"; -import { Button } from "../shadcn/Button"; +import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from "../../types/models/Problem.model"; import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from "../../types/models/Submission.model"; -import { Editor as MonacoEditor } from "@monaco-editor/react"; import TestcaseValidationAccordian from "../TestcaseValidationAccordion"; -import { Separator } from "../shadcn/Seperator"; +import { Dialog, DialogContent, DialogTrigger } from "../shadcn/Dialog"; import { ScrollArea } from "../shadcn/ScrollArea"; -import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from "../../types/models/Problem.model"; +import { Separator } from "../shadcn/Seperator"; const ProblemSubmissionSourceCodeAndRuntimeResultDialog = ({ submission, diff --git a/src/components/Forms/CreateCollectionForm/ManageProblems.tsx b/src/components/Forms/CreateCollectionForm/ManageProblems.tsx index a9b03bb..1d8056c 100644 --- a/src/components/Forms/CreateCollectionForm/ManageProblems.tsx +++ b/src/components/Forms/CreateCollectionForm/ManageProblems.tsx @@ -11,7 +11,6 @@ import MyProblemMiniCard2 from "../../Cards/ProblemCards/MyProblemMiniCard2"; import { Input } from "../../shadcn/Input"; import { ScrollArea } from "../../shadcn/ScrollArea"; import { Separator } from "../../shadcn/Seperator"; -import MyProblemsTable from "../../Tables/ProblemTables/MyProblemsTable"; const ManageProblems = ({ createRequest, diff --git a/src/components/PreviousSubmissionsCombobox.tsx b/src/components/PreviousSubmissionsCombobox.tsx index 2e78137..54357a5 100644 --- a/src/components/PreviousSubmissionsCombobox.tsx +++ b/src/components/PreviousSubmissionsCombobox.tsx @@ -1,9 +1,9 @@ "use client"; -import { Check, ChevronsUpDown, Languages } from "lucide-react"; +import { Check, ChevronsUpDown } from "lucide-react"; import * as React from "react"; -import { ProgrammingLanguageLabel, ProgrammingLanguageOptions } from "../constants/ProgrammingLanguage"; +import { ProgrammingLanguageOptions } from "../constants/ProgrammingLanguage"; import { TestcaseStatusIndicatorColor } from "../constants/TestcaseStatusIndicatorColor"; import { cn } from "../lib/utils"; import { @@ -20,8 +20,8 @@ import { CommandItem, } from "./shadcn/Command"; import { Popover, PopoverContent, PopoverTrigger } from "./shadcn/Popover"; -import { Separator } from "./shadcn/Seperator"; import { ScrollArea } from "./shadcn/ScrollArea"; +import { Separator } from "./shadcn/Seperator"; const TestcaseGradingMiniResult = ({ status, diff --git a/src/components/Tables/MyCollectionsTable.tsx b/src/components/Tables/MyCollectionsTable.tsx index 8179de8..57766ee 100644 --- a/src/components/Tables/MyCollectionsTable.tsx +++ b/src/components/Tables/MyCollectionsTable.tsx @@ -1,10 +1,9 @@ -import React from 'react' -import { CollectionPopulateCollectionProblemPopulateProblemModel } from '../../types/models/Collection.model' -import { DataTable } from '../DataTable' import { ColumnDef } from '@tanstack/react-table' import { FileSpreadsheet, Folder } from 'lucide-react' import { Link } from 'react-router-dom' +import { CollectionPopulateCollectionProblemPopulateProblemModel } from '../../types/models/Collection.model' import { readableDateFormat } from '../../utilities/ReadableDateFormat' +import { DataTable } from '../DataTable' const columns: ColumnDef[] = [ { diff --git a/src/components/Tables/MyProblemSubmissionsTable.tsx b/src/components/Tables/MyProblemSubmissionsTable.tsx index 5d7a9b1..8529c8e 100644 --- a/src/components/Tables/MyProblemSubmissionsTable.tsx +++ b/src/components/Tables/MyProblemSubmissionsTable.tsx @@ -1,15 +1,13 @@ -import React from "react"; -import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from "../../types/models/Submission.model"; import { ColumnDef } from "@tanstack/react-table"; +import { Maximize2 } from "lucide-react"; +import { ProgrammingLanguageOptions } from "../../constants/ProgrammingLanguage"; +import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from "../../types/models/Problem.model"; +import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from "../../types/models/Submission.model"; +import { readableDateFormat } from "../../utilities/ReadableDateFormat"; import { DataTable } from "../DataTable"; +import ProblemSubmissionSourceCodeAndRuntimeResultDialog from "../Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog"; import TestcasesGradingIndicator from "../TestcasesGradingIndicator"; -import { readableDateFormat } from "../../utilities/ReadableDateFormat"; -import { ProgrammingLanguageOptions } from "../../constants/ProgrammingLanguage"; import { Button } from "../shadcn/Button"; -import { Maximize, Maximize2 } from "lucide-react"; -import { Dialog, DialogContent, DialogTrigger } from "../shadcn/Dialog"; -import ProblemSubmissionSourceCodeAndRuntimeResultDialog from "../Dialogs/ProblemSubmissionSourceCodeAndRuntimeResultDialog"; -import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from "../../types/models/Problem.model"; diff --git a/src/components/Tables/ProblemTables/MyProblemsTable.tsx b/src/components/Tables/ProblemTables/MyProblemsTable.tsx index b32d940..f07b5c5 100644 --- a/src/components/Tables/ProblemTables/MyProblemsTable.tsx +++ b/src/components/Tables/ProblemTables/MyProblemsTable.tsx @@ -1,26 +1,18 @@ -import React, { ReactNode } from "react"; -import { ProblemPopulateTestcases } from "../../../types/models/Problem.model"; import { ColumnDef } from "@tanstack/react-table"; -import { Table } from "../../shadcn/Table"; -import { DataTable } from "../../DataTable"; -import { readableDateFormat } from "../../../utilities/ReadableDateFormat"; import { - Check, FileSpreadsheet, - Layers3, MoreHorizontal, - MoreVertical, Tally4, - Timer, - X, + Timer } from "lucide-react"; import { Link } from "react-router-dom"; -import { Badge } from "../../shadcn/Badge"; -import { checkRuntimeStatus } from "../../../utilities/CheckRuntimeStatus"; import { ProgrammingLanguageOptions } from "../../../constants/ProgrammingLanguage"; -import MyProblemContextMenu from "../../ContextMenus/MyProblemContextMenu"; -import MyProblemDropdown from "../../Dropdowns/MyProblemDropdown"; +import { ProblemPopulateTestcases } from "../../../types/models/Problem.model"; +import { checkRuntimeStatus } from "../../../utilities/CheckRuntimeStatus"; +import { readableDateFormat } from "../../../utilities/ReadableDateFormat"; import CheckBadge from "../../CheckBadge"; +import { DataTable } from "../../DataTable"; +import MyProblemDropdown from "../../Dropdowns/MyProblemDropdown"; const columns: ColumnDef[] = [ { diff --git a/src/components/Tables/ProblemTables/PublicProblemsTable.tsx b/src/components/Tables/ProblemTables/PublicProblemsTable.tsx index 5b57cad..afa27e5 100644 --- a/src/components/Tables/ProblemTables/PublicProblemsTable.tsx +++ b/src/components/Tables/ProblemTables/PublicProblemsTable.tsx @@ -1,30 +1,15 @@ -import React, { ReactNode } from "react"; -import { - ProblemPopulateAccountAndSubmissionPopulateSubmissionTestcasesSecureModel, - ProblemPopulateTestcases, -} from "../../../types/models/Problem.model"; import { ColumnDef } from "@tanstack/react-table"; -import { Table } from "../../shadcn/Table"; -import { DataTable } from "../../DataTable"; -import { readableDateFormat } from "../../../utilities/ReadableDateFormat"; import { - Check, FileSpreadsheet, - Layers3, - MoreHorizontal, - MoreVertical, - Puzzle, - Tally4, - Timer, - X, + Puzzle } from "lucide-react"; import { Link } from "react-router-dom"; -import { Badge } from "../../shadcn/Badge"; -import { checkRuntimeStatus } from "../../../utilities/CheckRuntimeStatus"; import { ProgrammingLanguageOptions } from "../../../constants/ProgrammingLanguage"; -import MyProblemContextMenu from "../../ContextMenus/MyProblemContextMenu"; -import MyProblemDropdown from "../../Dropdowns/MyProblemDropdown"; -import CheckBadge from "../../CheckBadge"; +import { + ProblemPopulateAccountAndSubmissionPopulateSubmissionTestcasesSecureModel +} from "../../../types/models/Problem.model"; +import { readableDateFormat } from "../../../utilities/ReadableDateFormat"; +import { DataTable } from "../../DataTable"; import TestcasesGradingIndicator from "../../TestcasesGradingIndicator"; import { Button } from "../../shadcn/Button"; diff --git a/src/views/ExploreProblems.tsx b/src/views/ExploreProblems.tsx index b6a39a0..114f4da 100644 --- a/src/views/ExploreProblems.tsx +++ b/src/views/ExploreProblems.tsx @@ -1,11 +1,10 @@ import { useEffect, useState } from "react"; import CardContainer from "../components/CardContainer"; -import PublicProblemCard from "../components/Cards/ProblemCards/PublicProblemCard"; +import PublicProblemsTable from "../components/Tables/ProblemTables/PublicProblemsTable"; import { Separator } from "../components/shadcn/Seperator"; import NavbarMenuLayout from "../layout/NavbarMenuLayout"; import { ProblemService } from "../services/Problem.service"; import { ProblemPopulateAccountAndSubmissionPopulateSubmissionTestcasesSecureModel } from "../types/models/Problem.model"; -import PublicProblemsTable from "../components/Tables/ProblemTables/PublicProblemsTable"; const ExploreProblems = () => { const [problems, setProblems] = useState< diff --git a/src/views/My/Collections/MyCollections.tsx b/src/views/My/Collections/MyCollections.tsx index 62c2b3d..b48dac8 100644 --- a/src/views/My/Collections/MyCollections.tsx +++ b/src/views/My/Collections/MyCollections.tsx @@ -2,7 +2,7 @@ import { FolderPlus } from "lucide-react"; import { useContext, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import CardContainer from "../../../components/CardContainer"; -import MyCollectionCard from "../../../components/Cards/CollectionCards/MyCollectionCard"; +import MyCollectionsTable from "../../../components/Tables/MyCollectionsTable"; import { Button } from "../../../components/shadcn/Button"; import { Input } from "../../../components/shadcn/Input"; import { Tabs, TabsList, TabsTrigger } from "../../../components/shadcn/Tabs"; @@ -10,7 +10,6 @@ import { NavSidebarContext } from "../../../contexts/NavSidebarContext"; import NavbarSidebarLayout from "../../../layout/NavbarSidebarLayout"; import { CollectionService } from "../../../services/Collection.service"; import { CollectionPopulateCollectionProblemPopulateProblemModel } from "../../../types/models/Collection.model"; -import MyCollectionsTable from "../../../components/Tables/MyCollectionsTable"; const MyCollections = () => { const navigate = useNavigate(); diff --git a/src/views/My/Problems/MyProblems.tsx b/src/views/My/Problems/MyProblems.tsx index 2336d48..03ad374 100644 --- a/src/views/My/Problems/MyProblems.tsx +++ b/src/views/My/Problems/MyProblems.tsx @@ -2,7 +2,7 @@ import { FilePlus } from "lucide-react"; import { useContext, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import CardContainer from "../../../components/CardContainer"; -import MyProblemCard from "../../../components/Cards/ProblemCards/MyProblemCard"; +import MyProblemsTable from "../../../components/Tables/ProblemTables/MyProblemsTable"; import { Button } from "../../../components/shadcn/Button"; import { Input } from "../../../components/shadcn/Input"; import { Tabs, TabsList, TabsTrigger } from "../../../components/shadcn/Tabs"; @@ -10,7 +10,6 @@ import { NavSidebarContext } from "../../../contexts/NavSidebarContext"; import NavbarSidebarLayout from "../../../layout/NavbarSidebarLayout"; import { ProblemService } from "../../../services/Problem.service"; import { ProblemPopulateTestcases } from "../../../types/models/Problem.model"; -import MyProblemsTable from "../../../components/Tables/ProblemTables/MyProblemsTable"; const MyProblems = () => { const accountId = String(localStorage.getItem("account_id")); diff --git a/src/views/My/Problems/ProblemStatistic.tsx b/src/views/My/Problems/ProblemStatistic.tsx index f6181c8..b1c9294 100644 --- a/src/views/My/Problems/ProblemStatistic.tsx +++ b/src/views/My/Problems/ProblemStatistic.tsx @@ -1,12 +1,12 @@ -import React, { useEffect, useState } from "react"; -import NavbarSidebarLayout from "../../../layout/NavbarSidebarLayout"; +import { useEffect, useState } from "react"; import { Link, useParams } from "react-router-dom"; -import { ProblemService } from "./../../../services/Problem.service"; -import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from "../../../types/models/Problem.model"; -import { SubmissionService } from "../../../services/Submission.service"; -import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from "../../../types/models/Submission.model"; import MyProblemSubmissionsTable from "../../../components/Tables/MyProblemSubmissionsTable"; import { Button } from "../../../components/shadcn/Button"; +import NavbarSidebarLayout from "../../../layout/NavbarSidebarLayout"; +import { SubmissionService } from "../../../services/Submission.service"; +import { ProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupModel } from "../../../types/models/Problem.model"; +import { SubmissionPopulateSubmissionTestcaseAndAccountModel } from "../../../types/models/Submission.model"; +import { ProblemService } from "./../../../services/Problem.service"; const ProblemStatistic = () => { const { problemId } = useParams();