diff --git a/backend/src/api/serializers.py b/backend/src/api/serializers.py index 906a7bf..aec894b 100644 --- a/backend/src/api/serializers.py +++ b/backend/src/api/serializers.py @@ -34,8 +34,7 @@ class Meta: class TicketSerializer(serializers.ModelSerializer): - professor = serializers.PrimaryKeyRelatedField( - queryset=Professor.prof.all()) + professor = serializers.PrimaryKeyRelatedField(queryset=Professor.prof.all()) course = serializers.PrimaryKeyRelatedField(queryset=Course.generic.all()) issue = serializers.PrimaryKeyRelatedField(queryset=Issues.generic.all()) # student = serializers.PrimaryKeyRelatedField( diff --git a/backend/src/api/views.py b/backend/src/api/views.py index 3c0e5c6..0a8eea4 100644 --- a/backend/src/api/views.py +++ b/backend/src/api/views.py @@ -21,8 +21,8 @@ MessageSerializer, ProfessorSerializer, SectionSerializer, - TicketSerializer, TicketGetSerializer, + TicketSerializer, UserSerializer, ) @@ -418,8 +418,7 @@ def get(self, request): sections = sections.filter(professor__in=query) if first_name := querystring.get("first-name"): - query = Professor.prof.filter( - first_name=first_name.capitalize()) + query = Professor.prof.filter(first_name=first_name.capitalize()) sections = sections.filter(professor__in=query) if modality := querystring.get("modality"): @@ -459,8 +458,7 @@ def get(self, request): if querystring: if department := querystring.get("department"): - courses = courses.filter( - course_department=self.sanitize(department)) + courses = courses.filter(course_department=self.sanitize(department)) if name := querystring.get("name"): courses = courses.filter(course_name=name) @@ -472,8 +470,7 @@ def get(self, request): courses = courses.filter(course_id=course_id) if course_id_contains := querystring.get("course-id-contains"): - courses = courses.filter( - course_id__contains=course_id_contains) + courses = courses.filter(course_id__contains=course_id_contains) if greater_than_code := querystring.get("higher-than"): courses = courses.filter(course_id__gt=greater_than_code) @@ -514,8 +511,7 @@ def get(self, request): if querystring: if department := querystring.get("department"): - users = users.filter( - course_department=self.sanitize(department)) + users = users.filter(course_department=self.sanitize(department)) if name := querystring.get("name"): users = users.filter(name=name) @@ -579,8 +575,7 @@ def get(self, request): if querystring: if department := querystring.get("department"): - users = users.filter( - course_department=self.sanitize(department)) + users = users.filter(course_department=self.sanitize(department)) if name := querystring.get("name"): users = users.filter(name=name) @@ -739,8 +734,7 @@ def get(self, request): query_string = self.get_querystring(request=request) if query_string: if professor_name := query_string.get("professor"): - professors = professors.filter( - full_name=self.sanitize(professor_name)) + professors = professors.filter(full_name=self.sanitize(professor_name)) if professor_id := query_string.get("id"): professors = professors.filter(professor_id=professor_id) if professor_first_name := query_string.get("first-name"): diff --git a/frontend-ts/.eslintignore b/frontend-ts/.eslintignore index c9c0913..198c793 100644 --- a/frontend-ts/.eslintignore +++ b/frontend-ts/.eslintignore @@ -1,3 +1,5 @@ # This is a typescript project. The only files that are JS files are # the test files from Jest **/*.js +*.js +js diff --git a/frontend-ts/.eslintrc.cjs b/frontend-ts/.eslintrc.cjs index 3b83286..63cd8d1 100644 --- a/frontend-ts/.eslintrc.cjs +++ b/frontend-ts/.eslintrc.cjs @@ -7,7 +7,7 @@ module.exports = { "plugin:@typescript-eslint/recommended", "plugin:react-hooks/recommended", ], - ignorePatterns: ["dist", ".eslintrc.cjs"], + ignorePatterns: ["dist", ".eslintrc.cjs", "*.js", "**/*.js", "data/"], parser: "@typescript-eslint/parser", plugins: ["react-refresh"], rules: { diff --git a/frontend-ts/.prettierignore b/frontend-ts/.prettierignore index 5963433..0cb528f 100644 --- a/frontend-ts/.prettierignore +++ b/frontend-ts/.prettierignore @@ -1,2 +1,5 @@ # Ignore useless json formatting **/*.json +# Ignore js files +**/*.js +*.js diff --git a/frontend-ts/index.html b/frontend-ts/index.html index 4bb23cd..4a61806 100644 --- a/frontend-ts/index.html +++ b/frontend-ts/index.html @@ -1,18 +1,16 @@ + + + + + + + CSLC Tutoring Portal + - - - - - - - CSLC Tutoring Portal - - - -
- - - - \ No newline at end of file + +
+ + + diff --git a/frontend-ts/src/Root.tsx b/frontend-ts/src/Root.tsx index 8cbba42..2760b94 100644 --- a/frontend-ts/src/Root.tsx +++ b/frontend-ts/src/Root.tsx @@ -20,7 +20,7 @@ export default function Root() {
-
+
diff --git a/frontend-ts/src/components/navigation/Navbar.tsx b/frontend-ts/src/components/navigation/Navbar.tsx index 0e9b357..fca045a 100644 --- a/frontend-ts/src/components/navigation/Navbar.tsx +++ b/frontend-ts/src/components/navigation/Navbar.tsx @@ -7,9 +7,9 @@ export default function Navbar() { } return ( <> -
- - {/*
*/} +
); } diff --git a/frontend-ts/src/components/tables/admin/Columns.tsx b/frontend-ts/src/components/tables/admin/Columns.tsx index 22c4d5d..5b63f51 100644 --- a/frontend-ts/src/components/tables/admin/Columns.tsx +++ b/frontend-ts/src/components/tables/admin/Columns.tsx @@ -1,187 +1,185 @@ -import { ColumnDef } from "@tanstack/react-table" +import { ColumnDef } from "@tanstack/react-table"; -import { Badge } from "@/components/ui/badge" -import { Checkbox } from "@/components/ui/checkbox" +import { Badge } from "@/components/ui/badge"; +import { Checkbox } from "@/components/ui/checkbox"; -import { labels, priorities, statuses } from "../data/data" -import { Task } from "../data/schema" -import { DataTableColumnHeader } from "@/components/tables/admin/DataTableColumnHeader" -import { DataTableRowActions } from "@/components/tables/admin/DataTableActions" +import { priorities, statuses } from "../data/data"; +import { Task } from "../data/schema"; +import { DataTableColumnHeader } from "@/components/tables/admin/DataTableColumnHeader"; +import { DataTableRowActions } from "@/components/tables/admin/DataTableActions"; export const columns: ColumnDef[] = [ - { - id: "select", - header: ({ table }) => ( - table.toggleAllPageRowsSelected(!!value)} - aria-label="Select all" - className="translate-y-[2px] ml-2" - /> - ), - cell: ({ row }) => ( - row.toggleSelected(!!value)} - aria-label="Select row" - className="translate-y-[2px] ml-2" - /> - ), - enableSorting: false, - enableHiding: false, + { + id: "select", + header: ({ table }) => ( + table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + className="translate-y-[2px] ml-2" + /> + ), + cell: ({ row }) => ( + row.toggleSelected(!!value)} + aria-label="Select row" + className="translate-y-[2px] ml-2" + /> + ), + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: "id", + header: ({ column }) => ( + + ), + cell: ({ row }) =>
{row.getValue("id")}
, + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: "title", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + return ( +
+ + {row.getValue("title")} + +
+ ); }, - { - accessorKey: "id", - header: ({ column }) => ( - - ), - cell: ({ row }) =>
{row.getValue("id")}
, - enableSorting: false, - enableHiding: false, - }, - { - accessorKey: "title", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const label = labels.find((label) => label.value === row.original.label) - - return ( -
- - {row.getValue("title")} - -
- ) - }, - }, - { - accessorKey: "status", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const status = statuses.find( - (status) => status.value === row.getValue("status") - ) + }, + { + accessorKey: "status", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const status = statuses.find( + (status) => status.value === row.getValue("status"), + ); - if (!status) { - return null - } + if (!status) { + return null; + } - return ( -
- {status.icon && ( - - )} - {status.label} -
- ) - }, - filterFn: (row, id, value) => { - return value.includes(row.getValue(id)) - }, + return ( +
+ {status.icon && ( + + )} + {status.label} +
+ ); + }, + filterFn: (row, id, value) => { + return value.includes(row.getValue(id)); }, - { - accessorKey: "priority", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const priority = priorities.find( - (priority) => priority.value === row.getValue("priority") - ) + }, + { + accessorKey: "priority", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const priority = priorities.find( + (priority) => priority.value === row.getValue("priority"), + ); - if (!priority) { - return null - } + if (!priority) { + return null; + } - return ( -
- {priority.icon && ( - - )} - {priority.label} -
- ) - }, - filterFn: (row, id, value) => { - return value.includes(row.getValue(id)) - }, + return ( +
+ {priority.icon && ( + + )} + {priority.label} +
+ ); }, - { - accessorKey: "issue", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - return ( -
- Homework -
- ) - }, - filterFn: (row, id, value) => { - return value.includes(row.getValue(id)) - }, + filterFn: (row, id, value) => { + return value.includes(row.getValue(id)); }, - { - accessorKey: "tutor", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const priority = priorities.find( - (priority) => priority.value === row.getValue("priority") - ) + }, + { + accessorKey: "issue", + header: ({ column }) => ( + + ), + cell: () => { + return ( +
+ Homework +
+ ); + }, + filterFn: (row, id, value) => { + return value.includes(row.getValue(id)); + }, + }, + { + accessorKey: "tutor", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const priority = priorities.find( + (priority) => priority.value === row.getValue("priority"), + ); - if (!priority) { - return null - } + if (!priority) { + return null; + } - return ( -
- {priority.icon && ( - - )} - {priority.label} -
- ) - }, - filterFn: (row, id, value) => { - return value.includes(row.getValue(id)) - }, + return ( +
+ {priority.icon && ( + + )} + {priority.label} +
+ ); + }, + filterFn: (row, id, value) => { + return value.includes(row.getValue(id)); }, - { - accessorKey: "student", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const priority = priorities.find( - (priority) => priority.value === row.getValue("priority") - ) + }, + { + accessorKey: "student", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const priority = priorities.find( + (priority) => priority.value === row.getValue("priority"), + ); - if (!priority) { - return null - } + if (!priority) { + return null; + } - return ( -
- {priority.icon && ( - - )} - {priority.label} -
- ) - }, - filterFn: (row, id, value) => { - return value.includes(row.getValue(id)) - }, + return ( +
+ {priority.icon && ( + + )} + {priority.label} +
+ ); }, - { - id: "actions", - cell: ({ row }) => , + filterFn: (row, id, value) => { + return value.includes(row.getValue(id)); }, -] \ No newline at end of file + }, + { + id: "actions", + cell: ({ row }) => , + }, +]; diff --git a/frontend-ts/src/components/tables/admin/DataTable.tsx b/frontend-ts/src/components/tables/admin/DataTable.tsx index 13e3930..8ff9bc0 100644 --- a/frontend-ts/src/components/tables/admin/DataTable.tsx +++ b/frontend-ts/src/components/tables/admin/DataTable.tsx @@ -1,124 +1,124 @@ -import * as React from "react" +import * as React from "react"; import { - ColumnDef, - ColumnFiltersState, - SortingState, - VisibilityState, - flexRender, - getCoreRowModel, - getFacetedRowModel, - getFacetedUniqueValues, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from "@tanstack/react-table" + ColumnDef, + ColumnFiltersState, + SortingState, + VisibilityState, + flexRender, + getCoreRowModel, + getFacetedRowModel, + getFacetedUniqueValues, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table"; import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table" + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; -import { DataTablePagination } from "@/components/tables/admin/DataTablePagination" -import { DataTableToolbar } from "@/components/tables/admin/DataTableToolbar" +import { DataTablePagination } from "@/components/tables/admin/DataTablePagination"; +import { DataTableToolbar } from "@/components/tables/admin/DataTableToolbar"; interface DataTableProps { - columns: ColumnDef[] - data: TData[] + columns: ColumnDef[]; + data: TData[]; } export function DataTable({ - columns, - data, + columns, + data, }: DataTableProps) { - const [rowSelection, setRowSelection] = React.useState({}) - const [columnVisibility, setColumnVisibility] = - React.useState({}) - const [columnFilters, setColumnFilters] = React.useState( - [] - ) - const [sorting, setSorting] = React.useState([]) + const [rowSelection, setRowSelection] = React.useState({}); + const [columnVisibility, setColumnVisibility] = + React.useState({}); + const [columnFilters, setColumnFilters] = React.useState( + [], + ); + const [sorting, setSorting] = React.useState([]); - const table = useReactTable({ - data, - columns, - state: { - sorting, - columnVisibility, - rowSelection, - columnFilters, - }, - enableRowSelection: true, - onRowSelectionChange: setRowSelection, - onSortingChange: setSorting, - onColumnFiltersChange: setColumnFilters, - onColumnVisibilityChange: setColumnVisibility, - getCoreRowModel: getCoreRowModel(), - getFilteredRowModel: getFilteredRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - getFacetedRowModel: getFacetedRowModel(), - getFacetedUniqueValues: getFacetedUniqueValues(), - }) + const table = useReactTable({ + data, + columns, + state: { + sorting, + columnVisibility, + rowSelection, + columnFilters, + }, + enableRowSelection: true, + onRowSelectionChange: setRowSelection, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + onColumnVisibilityChange: setColumnVisibility, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: getFacetedUniqueValues(), + }); - return ( -
- -
- - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext() - )} - - ) - })} - - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext() - )} - - ))} - - )) - ) : ( - - - No results. - - - )} - -
-
- -
- ) -} \ No newline at end of file + return ( +
+ +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + + )) + ) : ( + + + No results. + + + )} + +
+
+ +
+ ); +} diff --git a/frontend-ts/src/components/tables/admin/DataTableActions.tsx b/frontend-ts/src/components/tables/admin/DataTableActions.tsx index fb14ca4..8d030f3 100644 --- a/frontend-ts/src/components/tables/admin/DataTableActions.tsx +++ b/frontend-ts/src/components/tables/admin/DataTableActions.tsx @@ -1,67 +1,67 @@ -import { DotsHorizontalIcon } from "@radix-ui/react-icons" -import { Row } from "@tanstack/react-table" +import { DotsHorizontalIcon } from "@radix-ui/react-icons"; +import { Row } from "@tanstack/react-table"; -import { Button } from "@/components/ui/button" +import { Button } from "@/components/ui/button"; import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuRadioGroup, - DropdownMenuRadioItem, - DropdownMenuSeparator, - DropdownMenuShortcut, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu" + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; -import { labels } from "../data/data" -import { taskSchema } from "../data/schema" +import { labels } from "../data/data"; +import { taskSchema } from "../data/schema"; interface DataTableRowActionsProps { - row: Row + row: Row; } export function DataTableRowActions({ - row, + row, }: DataTableRowActionsProps) { - const task = taskSchema.parse(row.original) + const task = taskSchema.parse(row.original); - return ( - - - - - - Edit - Make a copy - Favorite - - - Labels - - - {labels.map((label) => ( - - {label.label} - - ))} - - - - - - Delete - ⌘⌫ - - - - ) -} \ No newline at end of file + return ( + + + + + + Edit + Make a copy + Favorite + + + Labels + + + {labels.map((label) => ( + + {label.label} + + ))} + + + + + + Delete + ⌘⌫ + + + + ); +} diff --git a/frontend-ts/src/components/tables/admin/DataTableColumnHeader.tsx b/frontend-ts/src/components/tables/admin/DataTableColumnHeader.tsx index 9d16d56..e2a9137 100644 --- a/frontend-ts/src/components/tables/admin/DataTableColumnHeader.tsx +++ b/frontend-ts/src/components/tables/admin/DataTableColumnHeader.tsx @@ -1,71 +1,71 @@ import { - ArrowDownIcon, - ArrowUpIcon, - CaretSortIcon, - EyeNoneIcon, -} from "@radix-ui/react-icons" -import { Column } from "@tanstack/react-table" + ArrowDownIcon, + ArrowUpIcon, + CaretSortIcon, + EyeNoneIcon, +} from "@radix-ui/react-icons"; +import { Column } from "@tanstack/react-table"; -import { cn } from "@/lib/utils" -import { Button } from "@/components/ui/button" +import { cn } from "@/lib/utils"; +import { Button } from "@/components/ui/button"; import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu" + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; interface DataTableColumnHeaderProps - extends React.HTMLAttributes { - column: Column - title: string + extends React.HTMLAttributes { + column: Column; + title: string; } export function DataTableColumnHeader({ - column, - title, - className, + column, + title, + className, }: DataTableColumnHeaderProps) { - if (!column.getCanSort()) { - return
{title}
- } + if (!column.getCanSort()) { + return
{title}
; + } - return ( -
- - - - - - column.toggleSorting(false)}> - - Asc - - column.toggleSorting(true)}> - - Desc - - - column.toggleVisibility(false)}> - - Hide - - - -
- ) -} \ No newline at end of file + return ( +
+ + + + + + column.toggleSorting(false)}> + + Asc + + column.toggleSorting(true)}> + + Desc + + + column.toggleVisibility(false)}> + + Hide + + + +
+ ); +} diff --git a/frontend-ts/src/components/tables/admin/DataTableFilter.tsx b/frontend-ts/src/components/tables/admin/DataTableFilter.tsx index 82812b5..917c005 100644 --- a/frontend-ts/src/components/tables/admin/DataTableFilter.tsx +++ b/frontend-ts/src/components/tables/admin/DataTableFilter.tsx @@ -1,147 +1,147 @@ -import * as React from "react" -import { CheckIcon, PlusCircledIcon } from "@radix-ui/react-icons" -import { Column } from "@tanstack/react-table" +import * as React from "react"; +import { CheckIcon, PlusCircledIcon } from "@radix-ui/react-icons"; +import { Column } from "@tanstack/react-table"; -import { cn } from "@/lib/utils" -import { Badge } from "@/components/ui/badge" -import { Button } from "@/components/ui/button" +import { cn } from "@/lib/utils"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, - CommandSeparator, -} from "@/components/ui/command" + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, +} from "@/components/ui/command"; import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover" -import { Separator } from "@/components/ui/separator" + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Separator } from "@/components/ui/separator"; interface DataTableFacetedFilterProps { - column?: Column - title?: string - options: { - label: string - value: string - icon?: React.ComponentType<{ className?: string }> - }[] + column?: Column; + title?: string; + options: { + label: string; + value: string; + icon?: React.ComponentType<{ className?: string }>; + }[]; } export function DataTableFacetedFilter({ - column, - title, - options, + column, + title, + options, }: DataTableFacetedFilterProps) { - const facets = column?.getFacetedUniqueValues() - const selectedValues = new Set(column?.getFilterValue() as string[]) + const facets = column?.getFacetedUniqueValues(); + const selectedValues = new Set(column?.getFilterValue() as string[]); - return ( - - - + + + + + + No results found. + + {options.map((option) => { + const isSelected = selectedValues.has(option.value); + return ( + { + if (isSelected) { + selectedValues.delete(option.value); + } else { + selectedValues.add(option.value); + } + const filterValues = Array.from(selectedValues); + column?.setFilterValue( + filterValues.length ? filterValues : undefined, + ); + }} + > +
+ +
+ {option.icon && ( + )} - - - - - - - No results found. - - {options.map((option) => { - const isSelected = selectedValues.has(option.value) - return ( - { - if (isSelected) { - selectedValues.delete(option.value) - } else { - selectedValues.add(option.value) - } - const filterValues = Array.from(selectedValues) - column?.setFilterValue( - filterValues.length ? filterValues : undefined - ) - }} - > -
- -
- {option.icon && ( - - )} - {option.label} - {facets?.get(option.value) && ( - - {facets.get(option.value)} - - )} -
- ) - })} -
- {selectedValues.size > 0 && ( - <> - - - column?.setFilterValue(undefined)} - className="justify-center text-center" - > - Clear filters - - - - )} -
-
-
-
- ) -} \ No newline at end of file + {option.label} + {facets?.get(option.value) && ( + + {facets.get(option.value)} + + )} + + ); + })} + + {selectedValues.size > 0 && ( + <> + + + column?.setFilterValue(undefined)} + className="justify-center text-center" + > + Clear filters + + + + )} + + + + + ); +} diff --git a/frontend-ts/src/components/tables/admin/DataTableOptions.tsx b/frontend-ts/src/components/tables/admin/DataTableOptions.tsx index 1f58e68..2125f7c 100644 --- a/frontend-ts/src/components/tables/admin/DataTableOptions.tsx +++ b/frontend-ts/src/components/tables/admin/DataTableOptions.tsx @@ -1,57 +1,57 @@ -import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu" -import { MixerHorizontalIcon } from "@radix-ui/react-icons" -import { Table } from "@tanstack/react-table" +import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"; +import { MixerHorizontalIcon } from "@radix-ui/react-icons"; +import { Table } from "@tanstack/react-table"; -import { Button } from "@/components/ui/button" +import { Button } from "@/components/ui/button"; import { - DropdownMenu, - DropdownMenuCheckboxItem, - DropdownMenuContent, - DropdownMenuLabel, - DropdownMenuSeparator, -} from "@/components/ui/dropdown-menu" + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuLabel, + DropdownMenuSeparator, +} from "@/components/ui/dropdown-menu"; interface DataTableViewOptionsProps { - table: Table + table: Table; } export function DataTableViewOptions({ - table, + table, }: DataTableViewOptionsProps) { - return ( - - - - - - Toggle columns - - {table - .getAllColumns() - .filter( - (column) => - typeof column.accessorFn !== "undefined" && column.getCanHide() - ) - .map((column) => { - return ( - column.toggleVisibility(!!value)} - > - {column.id} - - ) - })} - - - ) -} \ No newline at end of file + return ( + + + + + + Toggle columns + + {table + .getAllColumns() + .filter( + (column) => + typeof column.accessorFn !== "undefined" && column.getCanHide(), + ) + .map((column) => { + return ( + column.toggleVisibility(!!value)} + > + {column.id} + + ); + })} + + + ); +} diff --git a/frontend-ts/src/components/tables/admin/DataTablePagination.tsx b/frontend-ts/src/components/tables/admin/DataTablePagination.tsx index 4a69b6f..d79d0fe 100644 --- a/frontend-ts/src/components/tables/admin/DataTablePagination.tsx +++ b/frontend-ts/src/components/tables/admin/DataTablePagination.tsx @@ -1,97 +1,97 @@ import { - ChevronLeftIcon, - ChevronRightIcon, - DoubleArrowLeftIcon, - DoubleArrowRightIcon, -} from "@radix-ui/react-icons" -import { Table } from "@tanstack/react-table" + ChevronLeftIcon, + ChevronRightIcon, + DoubleArrowLeftIcon, + DoubleArrowRightIcon, +} from "@radix-ui/react-icons"; +import { Table } from "@tanstack/react-table"; -import { Button } from "@/components/ui/button" +import { Button } from "@/components/ui/button"; import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select" + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; interface DataTablePaginationProps { - table: Table + table: Table; } export function DataTablePagination({ - table, + 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()} -
-
- - - - -
-
+ return ( +
+
+ {table.getFilteredSelectedRowModel().rows.length} of{" "} + {table.getFilteredRowModel().rows.length} row(s) selected. +
+
+
+

Rows per page

+
- ) -} \ No newline at end of file +
+ Page {table.getState().pagination.pageIndex + 1} of{" "} + {table.getPageCount()} +
+
+ + + + +
+
+
+ ); +} diff --git a/frontend-ts/src/components/tables/admin/DataTableToolbar.tsx b/frontend-ts/src/components/tables/admin/DataTableToolbar.tsx index fe8de87..0710859 100644 --- a/frontend-ts/src/components/tables/admin/DataTableToolbar.tsx +++ b/frontend-ts/src/components/tables/admin/DataTableToolbar.tsx @@ -1,59 +1,59 @@ -import { Cross2Icon } from "@radix-ui/react-icons" -import { Table } from "@tanstack/react-table" +import { Cross2Icon } from "@radix-ui/react-icons"; +import { Table } from "@tanstack/react-table"; -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import { DataTableViewOptions } from "@/components/tables/admin/DataTableOptions" +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { DataTableViewOptions } from "@/components/tables/admin/DataTableOptions"; -import { priorities, statuses } from "../data/data" -import { DataTableFacetedFilter } from "@/components/tables/admin/DataTableFilter" +import { priorities, statuses } from "../data/data"; +import { DataTableFacetedFilter } from "@/components/tables/admin/DataTableFilter"; interface DataTableToolbarProps { - table: Table + table: Table; } export function DataTableToolbar({ - table, + table, }: DataTableToolbarProps) { - const isFiltered = table.getState().columnFilters.length > 0 + const isFiltered = table.getState().columnFilters.length > 0; - return ( -
-
- - table.getColumn("title")?.setFilterValue(event.target.value) - } - className="h-8 w-[150px] lg:w-[250px]" - /> - {table.getColumn("status") && ( - - )} - {table.getColumn("priority") && ( - - )} - {isFiltered && ( - - )} -
- -
- ) -} \ No newline at end of file + return ( +
+
+ + table.getColumn("title")?.setFilterValue(event.target.value) + } + className="h-8 w-[150px] lg:w-[250px]" + /> + {table.getColumn("status") && ( + + )} + {table.getColumn("priority") && ( + + )} + {isFiltered && ( + + )} +
+ +
+ ); +} diff --git a/frontend-ts/src/components/tables/data/data.tsx b/frontend-ts/src/components/tables/data/data.tsx index ee1046b..d46890a 100644 --- a/frontend-ts/src/components/tables/data/data.tsx +++ b/frontend-ts/src/components/tables/data/data.tsx @@ -1,71 +1,71 @@ import { - ArrowDownIcon, - ArrowRightIcon, - ArrowUpIcon, - CheckCircledIcon, - CircleIcon, - CrossCircledIcon, - QuestionMarkCircledIcon, - StopwatchIcon, -} from "@radix-ui/react-icons" + ArrowDownIcon, + ArrowRightIcon, + ArrowUpIcon, + CheckCircledIcon, + CircleIcon, + CrossCircledIcon, + QuestionMarkCircledIcon, + StopwatchIcon, +} from "@radix-ui/react-icons"; export const labels = [ - { - value: "bug", - label: "Bug", - }, - { - value: "feature", - label: "Feature", - }, - { - value: "documentation", - label: "Documentation", - }, -] + { + value: "bug", + label: "Bug", + }, + { + value: "feature", + label: "Feature", + }, + { + value: "documentation", + label: "Documentation", + }, +]; export const statuses = [ - { - value: "backlog", - label: "Backlog", - icon: QuestionMarkCircledIcon, - }, - { - value: "todo", - label: "Todo", - icon: CircleIcon, - }, - { - value: "in progress", - label: "In Progress", - icon: StopwatchIcon, - }, - { - value: "done", - label: "Done", - icon: CheckCircledIcon, - }, - { - value: "canceled", - label: "Canceled", - icon: CrossCircledIcon, - }, -] + { + value: "backlog", + label: "Backlog", + icon: QuestionMarkCircledIcon, + }, + { + value: "todo", + label: "Todo", + icon: CircleIcon, + }, + { + value: "in progress", + label: "In Progress", + icon: StopwatchIcon, + }, + { + value: "done", + label: "Done", + icon: CheckCircledIcon, + }, + { + value: "canceled", + label: "Canceled", + icon: CrossCircledIcon, + }, +]; export const priorities = [ - { - label: "Low", - value: "low", - icon: ArrowDownIcon, - }, - { - label: "Medium", - value: "medium", - icon: ArrowRightIcon, - }, - { - label: "High", - value: "high", - icon: ArrowUpIcon, - }, -] \ No newline at end of file + { + label: "Low", + value: "low", + icon: ArrowDownIcon, + }, + { + label: "Medium", + value: "medium", + icon: ArrowRightIcon, + }, + { + label: "High", + value: "high", + icon: ArrowUpIcon, + }, +]; diff --git a/frontend-ts/src/components/tables/data/schema.ts b/frontend-ts/src/components/tables/data/schema.ts index e5b8051..8cd11b0 100644 --- a/frontend-ts/src/components/tables/data/schema.ts +++ b/frontend-ts/src/components/tables/data/schema.ts @@ -1,13 +1,13 @@ -import { z } from "zod" +import { z } from "zod"; // We're keeping a simple non-relational schema here. // IRL, you will have a schema for your data models. export const taskSchema = z.object({ - id: z.string(), - title: z.string(), - status: z.string(), - label: z.string(), - priority: z.string(), -}) + id: z.string(), + title: z.string(), + status: z.string(), + label: z.string(), + priority: z.string(), +}); -export type Task = z.infer \ No newline at end of file +export type Task = z.infer; diff --git a/frontend-ts/src/components/tables/data/seed.ts b/frontend-ts/src/components/tables/data/seed.ts index 22e57e6..1e177aa 100644 --- a/frontend-ts/src/components/tables/data/seed.ts +++ b/frontend-ts/src/components/tables/data/seed.ts @@ -1,20 +1,20 @@ -import fs from "fs" -import path from "path" -import { faker } from "@faker-js/faker" +import fs from "fs"; +import path from "path"; +import { faker } from "@faker-js/faker"; -import { labels, priorities, statuses } from "./data" +import { labels, priorities, statuses } from "./data"; const tasks = Array.from({ length: 100 }, () => ({ - id: `TASK-${faker.datatype.number({ min: 1000, max: 9999 })}`, - title: faker.hacker.phrase().replace(/^./, (letter) => letter.toUpperCase()), - status: faker.helpers.arrayElement(statuses).value, - label: faker.helpers.arrayElement(labels).value, - priority: faker.helpers.arrayElement(priorities).value, -})) + id: `TASK-${faker.datatype.number({ min: 1000, max: 9999 })}`, + title: faker.hacker.phrase().replace(/^./, (letter) => letter.toUpperCase()), + status: faker.helpers.arrayElement(statuses).value, + label: faker.helpers.arrayElement(labels).value, + priority: faker.helpers.arrayElement(priorities).value, +})); fs.writeFileSync( - path.join(__dirname, "tasks.json"), - JSON.stringify(tasks, null, 2) -) + path.join(__dirname, "tasks.json"), + JSON.stringify(tasks, null, 2), +); -console.log("✅ Tasks data generated.") \ No newline at end of file +console.log("✅ Tasks data generated."); diff --git a/frontend-ts/src/components/tables/data/tasks.ts b/frontend-ts/src/components/tables/data/tasks.ts index 051ea48..21160eb 100644 --- a/frontend-ts/src/components/tables/data/tasks.ts +++ b/frontend-ts/src/components/tables/data/tasks.ts @@ -1,702 +1,782 @@ const TableData = [ - { - "id": "TASK-8782", - "title": "You can't compress the program without quantifying the open-source SSD pixel!", - "status": "in progress", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-7878", - "title": "Try to calculate the EXE feed, maybe it will index the multi-byte pixel!", - "status": "backlog", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-7839", - "title": "We need to bypass the neural TCP card!", - "status": "todo", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-5562", - "title": "The SAS interface is down, bypass the open-source pixel so we can back up the PNG bandwidth!", - "status": "backlog", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-8686", - "title": "I'll parse the wireless SSL protocol, that should driver the API panel!", - "status": "canceled", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-1280", - "title": "Use the digital TLS panel, then you can transmit the haptic system!", - "status": "done", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-7262", - "title": "The UTF8 application is down, parse the neural bandwidth so we can back up the PNG firewall!", - "status": "done", - "label": "feature", - "priority": "high" - }, - { - "id": "TASK-1138", - "title": "Generating the driver won't do anything, we need to quantify the 1080p SMTP bandwidth!", - "status": "in progress", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-7184", - "title": "We need to program the back-end THX pixel!", - "status": "todo", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-5160", - "title": "Calculating the bus won't do anything, we need to navigate the back-end JSON protocol!", - "status": "in progress", - "label": "documentation", - "priority": "high" - }, - { - "id": "TASK-5618", - "title": "Generating the driver won't do anything, we need to index the online SSL application!", - "status": "done", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-6699", - "title": "I'll transmit the wireless JBOD capacitor, that should hard drive the SSD feed!", - "status": "backlog", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-2858", - "title": "We need to override the online UDP bus!", - "status": "backlog", - "label": "bug", - "priority": "medium" - }, - { - "id": "TASK-9864", - "title": "I'll reboot the 1080p FTP panel, that should matrix the HEX hard drive!", - "status": "done", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-8404", - "title": "We need to generate the virtual HEX alarm!", - "status": "in progress", - "label": "bug", - "priority": "low" - }, - { - "id": "TASK-5365", - "title": "Backing up the pixel won't do anything, we need to transmit the primary IB array!", - "status": "in progress", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-1780", - "title": "The CSS feed is down, index the bluetooth transmitter so we can compress the CLI protocol!", - "status": "todo", - "label": "documentation", - "priority": "high" - }, - { - "id": "TASK-6938", - "title": "Use the redundant SCSI application, then you can hack the optical alarm!", - "status": "todo", - "label": "documentation", - "priority": "high" - }, - { - "id": "TASK-9885", - "title": "We need to compress the auxiliary VGA driver!", - "status": "backlog", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-3216", - "title": "Transmitting the transmitter won't do anything, we need to compress the virtual HDD sensor!", - "status": "backlog", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-9285", - "title": "The IP monitor is down, copy the haptic alarm so we can generate the HTTP transmitter!", - "status": "todo", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-1024", - "title": "Overriding the microchip won't do anything, we need to transmit the digital OCR transmitter!", - "status": "in progress", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-7068", - "title": "You can't generate the capacitor without indexing the wireless HEX pixel!", - "status": "canceled", - "label": "bug", - "priority": "low" - }, - { - "id": "TASK-6502", - "title": "Navigating the microchip won't do anything, we need to bypass the back-end SQL bus!", - "status": "todo", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-5326", - "title": "We need to hack the redundant UTF8 transmitter!", - "status": "todo", - "label": "bug", - "priority": "low" - }, - { - "id": "TASK-6274", - "title": "Use the virtual PCI circuit, then you can parse the bluetooth alarm!", - "status": "canceled", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-1571", - "title": "I'll input the neural DRAM circuit, that should protocol the SMTP interface!", - "status": "in progress", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-9518", - "title": "Compressing the interface won't do anything, we need to compress the online SDD matrix!", - "status": "canceled", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-5581", - "title": "I'll synthesize the digital COM pixel, that should transmitter the UTF8 protocol!", - "status": "backlog", - "label": "documentation", - "priority": "high" - }, - { - "id": "TASK-2197", - "title": "Parsing the feed won't do anything, we need to copy the bluetooth DRAM bus!", - "status": "todo", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-8484", - "title": "We need to parse the solid state UDP firewall!", - "status": "in progress", - "label": "bug", - "priority": "low" - }, - { - "id": "TASK-9892", - "title": "If we back up the application, we can get to the UDP application through the multi-byte THX capacitor!", - "status": "done", - "label": "documentation", - "priority": "high" - }, - { - "id": "TASK-9616", - "title": "We need to synthesize the cross-platform ASCII pixel!", - "status": "in progress", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-9744", - "title": "Use the back-end IP card, then you can input the solid state hard drive!", - "status": "done", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-1376", - "title": "Generating the alarm won't do anything, we need to generate the mobile IP capacitor!", - "status": "backlog", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-7382", - "title": "If we back up the firewall, we can get to the RAM alarm through the primary UTF8 pixel!", - "status": "todo", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-2290", - "title": "I'll compress the virtual JSON panel, that should application the UTF8 bus!", - "status": "canceled", - "label": "documentation", - "priority": "high" - }, - { - "id": "TASK-1533", - "title": "You can't input the firewall without overriding the wireless TCP firewall!", - "status": "done", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-4920", - "title": "Bypassing the hard drive won't do anything, we need to input the bluetooth JSON program!", - "status": "in progress", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-5168", - "title": "If we synthesize the bus, we can get to the IP panel through the virtual TLS array!", - "status": "in progress", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-7103", - "title": "We need to parse the multi-byte EXE bandwidth!", - "status": "canceled", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-4314", - "title": "If we compress the program, we can get to the XML alarm through the multi-byte COM matrix!", - "status": "in progress", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-3415", - "title": "Use the cross-platform XML application, then you can quantify the solid state feed!", - "status": "todo", - "label": "feature", - "priority": "high" - }, - { - "id": "TASK-8339", - "title": "Try to calculate the DNS interface, maybe it will input the bluetooth capacitor!", - "status": "in progress", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-6995", - "title": "Try to hack the XSS bandwidth, maybe it will override the bluetooth matrix!", - "status": "todo", - "label": "feature", - "priority": "high" - }, - { - "id": "TASK-8053", - "title": "If we connect the program, we can get to the UTF8 matrix through the digital UDP protocol!", - "status": "todo", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-4336", - "title": "If we synthesize the microchip, we can get to the SAS sensor through the optical UDP program!", - "status": "todo", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-8790", - "title": "I'll back up the optical COM alarm, that should alarm the RSS capacitor!", - "status": "done", - "label": "bug", - "priority": "medium" - }, - { - "id": "TASK-8980", - "title": "Try to navigate the SQL transmitter, maybe it will back up the virtual firewall!", - "status": "canceled", - "label": "bug", - "priority": "low" - }, - { - "id": "TASK-7342", - "title": "Use the neural CLI card, then you can parse the online port!", - "status": "backlog", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-5608", - "title": "I'll hack the haptic SSL program, that should bus the UDP transmitter!", - "status": "canceled", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-1606", - "title": "I'll generate the bluetooth PNG firewall, that should pixel the SSL driver!", - "status": "done", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-7872", - "title": "Transmitting the circuit won't do anything, we need to reboot the 1080p RSS monitor!", - "status": "canceled", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-4167", - "title": "Use the cross-platform SMS circuit, then you can synthesize the optical feed!", - "status": "canceled", - "label": "bug", - "priority": "medium" - }, - { - "id": "TASK-9581", - "title": "You can't index the port without hacking the cross-platform XSS monitor!", - "status": "backlog", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-8806", - "title": "We need to bypass the back-end SSL panel!", - "status": "done", - "label": "bug", - "priority": "medium" - }, - { - "id": "TASK-6542", - "title": "Try to quantify the RSS firewall, maybe it will quantify the open-source system!", - "status": "done", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-6806", - "title": "The VGA protocol is down, reboot the back-end matrix so we can parse the CSS panel!", - "status": "canceled", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-9549", - "title": "You can't bypass the bus without connecting the neural JBOD bus!", - "status": "todo", - "label": "feature", - "priority": "high" - }, - { - "id": "TASK-1075", - "title": "Backing up the driver won't do anything, we need to parse the redundant RAM pixel!", - "status": "done", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-1427", - "title": "Use the auxiliary PCI circuit, then you can calculate the cross-platform interface!", - "status": "done", - "label": "documentation", - "priority": "high" - }, - { - "id": "TASK-1907", - "title": "Hacking the circuit won't do anything, we need to back up the online DRAM system!", - "status": "todo", - "label": "documentation", - "priority": "high" - }, - { - "id": "TASK-4309", - "title": "If we generate the system, we can get to the TCP sensor through the optical GB pixel!", - "status": "backlog", - "label": "bug", - "priority": "medium" - }, - { - "id": "TASK-3973", - "title": "I'll parse the back-end ADP array, that should bandwidth the RSS bandwidth!", - "status": "todo", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-7962", - "title": "Use the wireless RAM program, then you can hack the cross-platform feed!", - "status": "canceled", - "label": "bug", - "priority": "low" - }, - { - "id": "TASK-3360", - "title": "You can't quantify the program without synthesizing the neural OCR interface!", - "status": "done", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-9887", - "title": "Use the auxiliary ASCII sensor, then you can connect the solid state port!", - "status": "backlog", - "label": "bug", - "priority": "medium" - }, - { - "id": "TASK-3649", - "title": "I'll input the virtual USB system, that should circuit the DNS monitor!", - "status": "in progress", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-3586", - "title": "If we quantify the circuit, we can get to the CLI feed through the mobile SMS hard drive!", - "status": "in progress", - "label": "bug", - "priority": "low" - }, - { - "id": "TASK-5150", - "title": "I'll hack the wireless XSS port, that should transmitter the IP interface!", - "status": "canceled", - "label": "feature", - "priority": "medium" - }, - { - "id": "TASK-3652", - "title": "The SQL interface is down, override the optical bus so we can program the ASCII interface!", - "status": "backlog", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-6884", - "title": "Use the digital PCI circuit, then you can synthesize the multi-byte microchip!", - "status": "canceled", - "label": "feature", - "priority": "high" - }, - { - "id": "TASK-1591", - "title": "We need to connect the mobile XSS driver!", - "status": "in progress", - "label": "feature", - "priority": "high" - }, - { - "id": "TASK-3802", - "title": "Try to override the ASCII protocol, maybe it will parse the virtual matrix!", - "status": "in progress", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-7253", - "title": "Programming the capacitor won't do anything, we need to bypass the neural IB hard drive!", - "status": "backlog", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-9739", - "title": "We need to hack the multi-byte HDD bus!", - "status": "done", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-4424", - "title": "Try to hack the HEX alarm, maybe it will connect the optical pixel!", - "status": "in progress", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-3922", - "title": "You can't back up the capacitor without generating the wireless PCI program!", - "status": "backlog", - "label": "bug", - "priority": "low" - }, - { - "id": "TASK-4921", - "title": "I'll index the open-source IP feed, that should system the GB application!", - "status": "canceled", - "label": "bug", - "priority": "low" - }, - { - "id": "TASK-5814", - "title": "We need to calculate the 1080p AGP feed!", - "status": "backlog", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-2645", - "title": "Synthesizing the system won't do anything, we need to navigate the multi-byte HDD firewall!", - "status": "todo", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-4535", - "title": "Try to copy the JSON circuit, maybe it will connect the wireless feed!", - "status": "in progress", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-4463", - "title": "We need to copy the solid state AGP monitor!", - "status": "done", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-9745", - "title": "If we connect the protocol, we can get to the GB system through the bluetooth PCI microchip!", - "status": "canceled", - "label": "feature", - "priority": "high" - }, - { - "id": "TASK-2080", - "title": "If we input the bus, we can get to the RAM matrix through the auxiliary RAM card!", - "status": "todo", - "label": "bug", - "priority": "medium" - }, - { - "id": "TASK-3838", - "title": "I'll bypass the online TCP application, that should panel the AGP system!", - "status": "backlog", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-1340", - "title": "We need to navigate the virtual PNG circuit!", - "status": "todo", - "label": "bug", - "priority": "medium" - }, - { - "id": "TASK-6665", - "title": "If we parse the monitor, we can get to the SSD hard drive through the cross-platform AGP alarm!", - "status": "canceled", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-7585", - "title": "If we calculate the hard drive, we can get to the SSL program through the multi-byte CSS microchip!", - "status": "backlog", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-6319", - "title": "We need to copy the multi-byte SCSI program!", - "status": "backlog", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-4369", - "title": "Try to input the SCSI bus, maybe it will generate the 1080p pixel!", - "status": "backlog", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-9035", - "title": "We need to override the solid state PNG array!", - "status": "canceled", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-3970", - "title": "You can't index the transmitter without quantifying the haptic ASCII card!", - "status": "todo", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-4473", - "title": "You can't bypass the protocol without overriding the neural RSS program!", - "status": "todo", - "label": "documentation", - "priority": "low" - }, - { - "id": "TASK-4136", - "title": "You can't hack the hard drive without hacking the primary JSON program!", - "status": "canceled", - "label": "bug", - "priority": "medium" - }, - { - "id": "TASK-3939", - "title": "Use the back-end SQL firewall, then you can connect the neural hard drive!", - "status": "done", - "label": "feature", - "priority": "low" - }, - { - "id": "TASK-2007", - "title": "I'll input the back-end USB protocol, that should bandwidth the PCI system!", - "status": "backlog", - "label": "bug", - "priority": "high" - }, - { - "id": "TASK-7516", - "title": "Use the primary SQL program, then you can generate the auxiliary transmitter!", - "status": "done", - "label": "documentation", - "priority": "medium" - }, - { - "id": "TASK-6906", - "title": "Try to back up the DRAM system, maybe it will reboot the online transmitter!", - "status": "done", - "label": "feature", - "priority": "high" - }, - { - "id": "TASK-5207", - "title": "The SMS interface is down, copy the bluetooth bus so we can quantify the VGA card!", - "status": "in progress", - "label": "bug", - "priority": "low" - } -] \ No newline at end of file + { + id: "TASK-8782", + title: + "You can't compress the program without quantifying the open-source SSD pixel!", + status: "in progress", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-7878", + title: + "Try to calculate the EXE feed, maybe it will index the multi-byte pixel!", + status: "backlog", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-7839", + title: "We need to bypass the neural TCP card!", + status: "todo", + label: "bug", + priority: "high", + }, + { + id: "TASK-5562", + title: + "The SAS interface is down, bypass the open-source pixel so we can back up the PNG bandwidth!", + status: "backlog", + label: "feature", + priority: "medium", + }, + { + id: "TASK-8686", + title: + "I'll parse the wireless SSL protocol, that should driver the API panel!", + status: "canceled", + label: "feature", + priority: "medium", + }, + { + id: "TASK-1280", + title: + "Use the digital TLS panel, then you can transmit the haptic system!", + status: "done", + label: "bug", + priority: "high", + }, + { + id: "TASK-7262", + title: + "The UTF8 application is down, parse the neural bandwidth so we can back up the PNG firewall!", + status: "done", + label: "feature", + priority: "high", + }, + { + id: "TASK-1138", + title: + "Generating the driver won't do anything, we need to quantify the 1080p SMTP bandwidth!", + status: "in progress", + label: "feature", + priority: "medium", + }, + { + id: "TASK-7184", + title: "We need to program the back-end THX pixel!", + status: "todo", + label: "feature", + priority: "low", + }, + { + id: "TASK-5160", + title: + "Calculating the bus won't do anything, we need to navigate the back-end JSON protocol!", + status: "in progress", + label: "documentation", + priority: "high", + }, + { + id: "TASK-5618", + title: + "Generating the driver won't do anything, we need to index the online SSL application!", + status: "done", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-6699", + title: + "I'll transmit the wireless JBOD capacitor, that should hard drive the SSD feed!", + status: "backlog", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-2858", + title: "We need to override the online UDP bus!", + status: "backlog", + label: "bug", + priority: "medium", + }, + { + id: "TASK-9864", + title: + "I'll reboot the 1080p FTP panel, that should matrix the HEX hard drive!", + status: "done", + label: "bug", + priority: "high", + }, + { + id: "TASK-8404", + title: "We need to generate the virtual HEX alarm!", + status: "in progress", + label: "bug", + priority: "low", + }, + { + id: "TASK-5365", + title: + "Backing up the pixel won't do anything, we need to transmit the primary IB array!", + status: "in progress", + label: "documentation", + priority: "low", + }, + { + id: "TASK-1780", + title: + "The CSS feed is down, index the bluetooth transmitter so we can compress the CLI protocol!", + status: "todo", + label: "documentation", + priority: "high", + }, + { + id: "TASK-6938", + title: + "Use the redundant SCSI application, then you can hack the optical alarm!", + status: "todo", + label: "documentation", + priority: "high", + }, + { + id: "TASK-9885", + title: "We need to compress the auxiliary VGA driver!", + status: "backlog", + label: "bug", + priority: "high", + }, + { + id: "TASK-3216", + title: + "Transmitting the transmitter won't do anything, we need to compress the virtual HDD sensor!", + status: "backlog", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-9285", + title: + "The IP monitor is down, copy the haptic alarm so we can generate the HTTP transmitter!", + status: "todo", + label: "bug", + priority: "high", + }, + { + id: "TASK-1024", + title: + "Overriding the microchip won't do anything, we need to transmit the digital OCR transmitter!", + status: "in progress", + label: "documentation", + priority: "low", + }, + { + id: "TASK-7068", + title: + "You can't generate the capacitor without indexing the wireless HEX pixel!", + status: "canceled", + label: "bug", + priority: "low", + }, + { + id: "TASK-6502", + title: + "Navigating the microchip won't do anything, we need to bypass the back-end SQL bus!", + status: "todo", + label: "bug", + priority: "high", + }, + { + id: "TASK-5326", + title: "We need to hack the redundant UTF8 transmitter!", + status: "todo", + label: "bug", + priority: "low", + }, + { + id: "TASK-6274", + title: + "Use the virtual PCI circuit, then you can parse the bluetooth alarm!", + status: "canceled", + label: "documentation", + priority: "low", + }, + { + id: "TASK-1571", + title: + "I'll input the neural DRAM circuit, that should protocol the SMTP interface!", + status: "in progress", + label: "feature", + priority: "medium", + }, + { + id: "TASK-9518", + title: + "Compressing the interface won't do anything, we need to compress the online SDD matrix!", + status: "canceled", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-5581", + title: + "I'll synthesize the digital COM pixel, that should transmitter the UTF8 protocol!", + status: "backlog", + label: "documentation", + priority: "high", + }, + { + id: "TASK-2197", + title: + "Parsing the feed won't do anything, we need to copy the bluetooth DRAM bus!", + status: "todo", + label: "documentation", + priority: "low", + }, + { + id: "TASK-8484", + title: "We need to parse the solid state UDP firewall!", + status: "in progress", + label: "bug", + priority: "low", + }, + { + id: "TASK-9892", + title: + "If we back up the application, we can get to the UDP application through the multi-byte THX capacitor!", + status: "done", + label: "documentation", + priority: "high", + }, + { + id: "TASK-9616", + title: "We need to synthesize the cross-platform ASCII pixel!", + status: "in progress", + label: "feature", + priority: "medium", + }, + { + id: "TASK-9744", + title: + "Use the back-end IP card, then you can input the solid state hard drive!", + status: "done", + label: "documentation", + priority: "low", + }, + { + id: "TASK-1376", + title: + "Generating the alarm won't do anything, we need to generate the mobile IP capacitor!", + status: "backlog", + label: "documentation", + priority: "low", + }, + { + id: "TASK-7382", + title: + "If we back up the firewall, we can get to the RAM alarm through the primary UTF8 pixel!", + status: "todo", + label: "feature", + priority: "low", + }, + { + id: "TASK-2290", + title: + "I'll compress the virtual JSON panel, that should application the UTF8 bus!", + status: "canceled", + label: "documentation", + priority: "high", + }, + { + id: "TASK-1533", + title: + "You can't input the firewall without overriding the wireless TCP firewall!", + status: "done", + label: "bug", + priority: "high", + }, + { + id: "TASK-4920", + title: + "Bypassing the hard drive won't do anything, we need to input the bluetooth JSON program!", + status: "in progress", + label: "bug", + priority: "high", + }, + { + id: "TASK-5168", + title: + "If we synthesize the bus, we can get to the IP panel through the virtual TLS array!", + status: "in progress", + label: "feature", + priority: "low", + }, + { + id: "TASK-7103", + title: "We need to parse the multi-byte EXE bandwidth!", + status: "canceled", + label: "feature", + priority: "low", + }, + { + id: "TASK-4314", + title: + "If we compress the program, we can get to the XML alarm through the multi-byte COM matrix!", + status: "in progress", + label: "bug", + priority: "high", + }, + { + id: "TASK-3415", + title: + "Use the cross-platform XML application, then you can quantify the solid state feed!", + status: "todo", + label: "feature", + priority: "high", + }, + { + id: "TASK-8339", + title: + "Try to calculate the DNS interface, maybe it will input the bluetooth capacitor!", + status: "in progress", + label: "feature", + priority: "low", + }, + { + id: "TASK-6995", + title: + "Try to hack the XSS bandwidth, maybe it will override the bluetooth matrix!", + status: "todo", + label: "feature", + priority: "high", + }, + { + id: "TASK-8053", + title: + "If we connect the program, we can get to the UTF8 matrix through the digital UDP protocol!", + status: "todo", + label: "feature", + priority: "medium", + }, + { + id: "TASK-4336", + title: + "If we synthesize the microchip, we can get to the SAS sensor through the optical UDP program!", + status: "todo", + label: "documentation", + priority: "low", + }, + { + id: "TASK-8790", + title: + "I'll back up the optical COM alarm, that should alarm the RSS capacitor!", + status: "done", + label: "bug", + priority: "medium", + }, + { + id: "TASK-8980", + title: + "Try to navigate the SQL transmitter, maybe it will back up the virtual firewall!", + status: "canceled", + label: "bug", + priority: "low", + }, + { + id: "TASK-7342", + title: "Use the neural CLI card, then you can parse the online port!", + status: "backlog", + label: "documentation", + priority: "low", + }, + { + id: "TASK-5608", + title: + "I'll hack the haptic SSL program, that should bus the UDP transmitter!", + status: "canceled", + label: "documentation", + priority: "low", + }, + { + id: "TASK-1606", + title: + "I'll generate the bluetooth PNG firewall, that should pixel the SSL driver!", + status: "done", + label: "feature", + priority: "medium", + }, + { + id: "TASK-7872", + title: + "Transmitting the circuit won't do anything, we need to reboot the 1080p RSS monitor!", + status: "canceled", + label: "feature", + priority: "medium", + }, + { + id: "TASK-4167", + title: + "Use the cross-platform SMS circuit, then you can synthesize the optical feed!", + status: "canceled", + label: "bug", + priority: "medium", + }, + { + id: "TASK-9581", + title: + "You can't index the port without hacking the cross-platform XSS monitor!", + status: "backlog", + label: "documentation", + priority: "low", + }, + { + id: "TASK-8806", + title: "We need to bypass the back-end SSL panel!", + status: "done", + label: "bug", + priority: "medium", + }, + { + id: "TASK-6542", + title: + "Try to quantify the RSS firewall, maybe it will quantify the open-source system!", + status: "done", + label: "feature", + priority: "low", + }, + { + id: "TASK-6806", + title: + "The VGA protocol is down, reboot the back-end matrix so we can parse the CSS panel!", + status: "canceled", + label: "documentation", + priority: "low", + }, + { + id: "TASK-9549", + title: "You can't bypass the bus without connecting the neural JBOD bus!", + status: "todo", + label: "feature", + priority: "high", + }, + { + id: "TASK-1075", + title: + "Backing up the driver won't do anything, we need to parse the redundant RAM pixel!", + status: "done", + label: "feature", + priority: "medium", + }, + { + id: "TASK-1427", + title: + "Use the auxiliary PCI circuit, then you can calculate the cross-platform interface!", + status: "done", + label: "documentation", + priority: "high", + }, + { + id: "TASK-1907", + title: + "Hacking the circuit won't do anything, we need to back up the online DRAM system!", + status: "todo", + label: "documentation", + priority: "high", + }, + { + id: "TASK-4309", + title: + "If we generate the system, we can get to the TCP sensor through the optical GB pixel!", + status: "backlog", + label: "bug", + priority: "medium", + }, + { + id: "TASK-3973", + title: + "I'll parse the back-end ADP array, that should bandwidth the RSS bandwidth!", + status: "todo", + label: "feature", + priority: "medium", + }, + { + id: "TASK-7962", + title: + "Use the wireless RAM program, then you can hack the cross-platform feed!", + status: "canceled", + label: "bug", + priority: "low", + }, + { + id: "TASK-3360", + title: + "You can't quantify the program without synthesizing the neural OCR interface!", + status: "done", + label: "feature", + priority: "medium", + }, + { + id: "TASK-9887", + title: + "Use the auxiliary ASCII sensor, then you can connect the solid state port!", + status: "backlog", + label: "bug", + priority: "medium", + }, + { + id: "TASK-3649", + title: + "I'll input the virtual USB system, that should circuit the DNS monitor!", + status: "in progress", + label: "feature", + priority: "medium", + }, + { + id: "TASK-3586", + title: + "If we quantify the circuit, we can get to the CLI feed through the mobile SMS hard drive!", + status: "in progress", + label: "bug", + priority: "low", + }, + { + id: "TASK-5150", + title: + "I'll hack the wireless XSS port, that should transmitter the IP interface!", + status: "canceled", + label: "feature", + priority: "medium", + }, + { + id: "TASK-3652", + title: + "The SQL interface is down, override the optical bus so we can program the ASCII interface!", + status: "backlog", + label: "feature", + priority: "low", + }, + { + id: "TASK-6884", + title: + "Use the digital PCI circuit, then you can synthesize the multi-byte microchip!", + status: "canceled", + label: "feature", + priority: "high", + }, + { + id: "TASK-1591", + title: "We need to connect the mobile XSS driver!", + status: "in progress", + label: "feature", + priority: "high", + }, + { + id: "TASK-3802", + title: + "Try to override the ASCII protocol, maybe it will parse the virtual matrix!", + status: "in progress", + label: "feature", + priority: "low", + }, + { + id: "TASK-7253", + title: + "Programming the capacitor won't do anything, we need to bypass the neural IB hard drive!", + status: "backlog", + label: "bug", + priority: "high", + }, + { + id: "TASK-9739", + title: "We need to hack the multi-byte HDD bus!", + status: "done", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-4424", + title: + "Try to hack the HEX alarm, maybe it will connect the optical pixel!", + status: "in progress", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-3922", + title: + "You can't back up the capacitor without generating the wireless PCI program!", + status: "backlog", + label: "bug", + priority: "low", + }, + { + id: "TASK-4921", + title: + "I'll index the open-source IP feed, that should system the GB application!", + status: "canceled", + label: "bug", + priority: "low", + }, + { + id: "TASK-5814", + title: "We need to calculate the 1080p AGP feed!", + status: "backlog", + label: "bug", + priority: "high", + }, + { + id: "TASK-2645", + title: + "Synthesizing the system won't do anything, we need to navigate the multi-byte HDD firewall!", + status: "todo", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-4535", + title: + "Try to copy the JSON circuit, maybe it will connect the wireless feed!", + status: "in progress", + label: "feature", + priority: "low", + }, + { + id: "TASK-4463", + title: "We need to copy the solid state AGP monitor!", + status: "done", + label: "documentation", + priority: "low", + }, + { + id: "TASK-9745", + title: + "If we connect the protocol, we can get to the GB system through the bluetooth PCI microchip!", + status: "canceled", + label: "feature", + priority: "high", + }, + { + id: "TASK-2080", + title: + "If we input the bus, we can get to the RAM matrix through the auxiliary RAM card!", + status: "todo", + label: "bug", + priority: "medium", + }, + { + id: "TASK-3838", + title: + "I'll bypass the online TCP application, that should panel the AGP system!", + status: "backlog", + label: "bug", + priority: "high", + }, + { + id: "TASK-1340", + title: "We need to navigate the virtual PNG circuit!", + status: "todo", + label: "bug", + priority: "medium", + }, + { + id: "TASK-6665", + title: + "If we parse the monitor, we can get to the SSD hard drive through the cross-platform AGP alarm!", + status: "canceled", + label: "feature", + priority: "low", + }, + { + id: "TASK-7585", + title: + "If we calculate the hard drive, we can get to the SSL program through the multi-byte CSS microchip!", + status: "backlog", + label: "feature", + priority: "low", + }, + { + id: "TASK-6319", + title: "We need to copy the multi-byte SCSI program!", + status: "backlog", + label: "bug", + priority: "high", + }, + { + id: "TASK-4369", + title: "Try to input the SCSI bus, maybe it will generate the 1080p pixel!", + status: "backlog", + label: "bug", + priority: "high", + }, + { + id: "TASK-9035", + title: "We need to override the solid state PNG array!", + status: "canceled", + label: "documentation", + priority: "low", + }, + { + id: "TASK-3970", + title: + "You can't index the transmitter without quantifying the haptic ASCII card!", + status: "todo", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-4473", + title: + "You can't bypass the protocol without overriding the neural RSS program!", + status: "todo", + label: "documentation", + priority: "low", + }, + { + id: "TASK-4136", + title: + "You can't hack the hard drive without hacking the primary JSON program!", + status: "canceled", + label: "bug", + priority: "medium", + }, + { + id: "TASK-3939", + title: + "Use the back-end SQL firewall, then you can connect the neural hard drive!", + status: "done", + label: "feature", + priority: "low", + }, + { + id: "TASK-2007", + title: + "I'll input the back-end USB protocol, that should bandwidth the PCI system!", + status: "backlog", + label: "bug", + priority: "high", + }, + { + id: "TASK-7516", + title: + "Use the primary SQL program, then you can generate the auxiliary transmitter!", + status: "done", + label: "documentation", + priority: "medium", + }, + { + id: "TASK-6906", + title: + "Try to back up the DRAM system, maybe it will reboot the online transmitter!", + status: "done", + label: "feature", + priority: "high", + }, + { + id: "TASK-5207", + title: + "The SMS interface is down, copy the bluetooth bus so we can quantify the VGA card!", + status: "in progress", + label: "bug", + priority: "low", + }, +]; diff --git a/frontend-ts/src/components/tickets/ClaimedTicket.tsx b/frontend-ts/src/components/tickets/ClaimedTicket.tsx deleted file mode 100644 index 8f2ac58..0000000 --- a/frontend-ts/src/components/tickets/ClaimedTicket.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Component } from "react"; -import { - Card, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { Badge } from "@radix-ui/themes"; - -export default class ClaimedTicket extends Component { - render() { - return ( - <> - - -
- - Open - -
- -
-

{this.props.course}

-
-
-

{this.props.student}

-
-
- -
-
-

Professor: {this.props.professor}

-

Assignment: {this.props.assignment}

-

Description: {this.props.description}

-
-
-
- Submitted: {this.props.starttime} -
- {this.props.editedtime && ( -
- Edited: {this.props.editedtime} -
- )} -
-
-
-
-
- - ); - } -} diff --git a/frontend-ts/src/components/tickets/ClosedTicket.tsx b/frontend-ts/src/components/tickets/ClosedTicket.tsx deleted file mode 100644 index 931f0f6..0000000 --- a/frontend-ts/src/components/tickets/ClosedTicket.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Component } from "react"; -import { - Card, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { Badge } from "@radix-ui/themes"; - -export default class ClosedTicket extends Component { - render() { - return ( - <> - - -
- - Closed - -
- -
-

{this.props.course}

-
-
-

{this.props.student}

-
-
- -
-
-

Professor: {this.props.professor}

-

Assignment: {this.props.assignment}

-

Description: {this.props.description}

-
-
-
- Submitted: {this.props.starttime} -
- {this.props.editedtime && ( -
- Edited: {this.props.editedtime} -
- )} -
-
-
-
-
- - ); - } -} diff --git a/frontend-ts/src/components/tickets/Ticket.tsx b/frontend-ts/src/components/tickets/Ticket.tsx index e4733b4..60e978f 100644 --- a/frontend-ts/src/components/tickets/Ticket.tsx +++ b/frontend-ts/src/components/tickets/Ticket.tsx @@ -1,8 +1,4 @@ -import { ClipboardEditIcon, Trash2Icon } from "lucide-react"; -import { - CardDescription, - CardTitle, -} from "../ui/card"; +import { CardDescription, CardTitle } from "../ui/card"; import { Button } from "../ui/button"; import { Badge } from "../ui/badge"; import { Label } from "../ui/label"; @@ -10,32 +6,31 @@ import { Label } from "../ui/label"; export default function Ticket({ name, description, - start_time, professor, section, - tutor, type, }: any) { return (
{name} - {type === "new" && Unclaimed} - {type === "opened" && ( - Claimed - )} + {type === "new" && Unclaimed} + {type === "opened" && Claimed} + {type === "closed" && Closed}
{description}
-
-
); } diff --git a/frontend-ts/src/components/tickets/UnclaimedTicket.tsx b/frontend-ts/src/components/tickets/UnclaimedTicket.tsx deleted file mode 100644 index 2260d00..0000000 --- a/frontend-ts/src/components/tickets/UnclaimedTicket.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Component } from "react"; -import { - Card, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { Badge } from "@radix-ui/themes"; - -export default class UnclaimedTicket extends Component { - render() { - return ( - <> - - -
- - Unclaimed! - -
- -
-

{this.props.course}

-
-
-

{this.props.student}

-
-
- -
-
-

Professor: {this.props.professor}

-

Assignment: {this.props.assignment}

-

Description: {this.props.description}

-
-
-
- Submitted: {this.props.starttime} -
- {this.props.editedtime && ( -
- Edited: {this.props.editedtime} -
- )} -
-
-
-
-
- - ); - } -} diff --git a/frontend-ts/src/components/typography/Header.tsx b/frontend-ts/src/components/typography/Header.tsx index a448b95..026bb7a 100644 --- a/frontend-ts/src/components/typography/Header.tsx +++ b/frontend-ts/src/components/typography/Header.tsx @@ -1,4 +1,10 @@ -export default function Header({ text, subtext }: { text: string, subtext: string }) { +export default function Header({ + text, + subtext, +}: { + text: string; + subtext: string; +}) { return (
@@ -6,9 +12,7 @@ export default function Header({ text, subtext }: { text: string, subtext: strin {text}
-

- {subtext!} -

+

{subtext!}

diff --git a/frontend-ts/src/components/ui/badge.tsx b/frontend-ts/src/components/ui/badge.tsx index 87b43cb..ff34008 100644 --- a/frontend-ts/src/components/ui/badge.tsx +++ b/frontend-ts/src/components/ui/badge.tsx @@ -14,9 +14,9 @@ const badgeVariants = cva( "border-transparent bg-destructive text-destructive-foreground shadow", warning: "border-warning border-2", new_ticket: - "border-alert dark:bg-alert/25 bg-alert font-bold text-white", - opened_ticket: - "border-primary bg-primary/25 font-medium text-white", + "border-alert dark:bg-alert/25 bg-alert font-medium text-white subpixel-antialiased", + opened_ticket: "border-[#00B8D9] bg-[#00B8D9] font-bold text-white", + closed_ticket: "", outline: "text-foreground", }, }, @@ -28,7 +28,7 @@ const badgeVariants = cva( export interface BadgeProps extends React.HTMLAttributes, - VariantProps { } + VariantProps {} function Badge({ className, variant, ...props }: BadgeProps) { return ( diff --git a/frontend-ts/src/components/ui/command.tsx b/frontend-ts/src/components/ui/command.tsx index 6f4a5eb..6397547 100644 --- a/frontend-ts/src/components/ui/command.tsx +++ b/frontend-ts/src/components/ui/command.tsx @@ -1,12 +1,12 @@ -"use client" +"use client"; -import * as React from "react" -import { DialogProps } from "@radix-ui/react-dialog" -import { MagnifyingGlassIcon } from "@radix-ui/react-icons" -import { Command as CommandPrimitive } from "cmdk" +import * as React from "react"; +import { DialogProps } from "@radix-ui/react-dialog"; +import { MagnifyingGlassIcon } from "@radix-ui/react-icons"; +import { Command as CommandPrimitive } from "cmdk"; -import { cn } from "@/lib/utils" -import { Dialog, DialogContent } from "@/components/ui/dialog" +import { cn } from "@/lib/utils"; +import { Dialog, DialogContent } from "@/components/ui/dialog"; const Command = React.forwardRef< React.ElementRef, @@ -16,12 +16,12 @@ const Command = React.forwardRef< ref={ref} className={cn( "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground", - className + className, )} {...props} /> -)) -Command.displayName = CommandPrimitive.displayName +)); +Command.displayName = CommandPrimitive.displayName; interface CommandDialogProps extends DialogProps {} @@ -34,8 +34,8 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => { - ) -} + ); +}; const CommandInput = React.forwardRef< React.ElementRef, @@ -47,14 +47,14 @@ const CommandInput = React.forwardRef< ref={ref} className={cn( "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50", - className + className, )} {...props} />
-)) +)); -CommandInput.displayName = CommandPrimitive.Input.displayName +CommandInput.displayName = CommandPrimitive.Input.displayName; const CommandList = React.forwardRef< React.ElementRef, @@ -65,9 +65,9 @@ const CommandList = React.forwardRef< className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)} {...props} /> -)) +)); -CommandList.displayName = CommandPrimitive.List.displayName +CommandList.displayName = CommandPrimitive.List.displayName; const CommandEmpty = React.forwardRef< React.ElementRef, @@ -78,9 +78,9 @@ const CommandEmpty = React.forwardRef< className="py-6 text-center text-sm" {...props} /> -)) +)); -CommandEmpty.displayName = CommandPrimitive.Empty.displayName +CommandEmpty.displayName = CommandPrimitive.Empty.displayName; const CommandGroup = React.forwardRef< React.ElementRef, @@ -90,13 +90,13 @@ const CommandGroup = React.forwardRef< ref={ref} className={cn( "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground", - className + className, )} {...props} /> -)) +)); -CommandGroup.displayName = CommandPrimitive.Group.displayName +CommandGroup.displayName = CommandPrimitive.Group.displayName; const CommandSeparator = React.forwardRef< React.ElementRef, @@ -107,8 +107,8 @@ const CommandSeparator = React.forwardRef< className={cn("-mx-1 h-px bg-border", className)} {...props} /> -)) -CommandSeparator.displayName = CommandPrimitive.Separator.displayName +)); +CommandSeparator.displayName = CommandPrimitive.Separator.displayName; const CommandItem = React.forwardRef< React.ElementRef, @@ -118,13 +118,13 @@ const CommandItem = React.forwardRef< ref={ref} className={cn( "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", - className + className, )} {...props} /> -)) +)); -CommandItem.displayName = CommandPrimitive.Item.displayName +CommandItem.displayName = CommandPrimitive.Item.displayName; const CommandShortcut = ({ className, @@ -134,13 +134,13 @@ const CommandShortcut = ({ - ) -} -CommandShortcut.displayName = "CommandShortcut" + ); +}; +CommandShortcut.displayName = "CommandShortcut"; export { Command, @@ -152,4 +152,4 @@ export { CommandItem, CommandShortcut, CommandSeparator, -} +}; diff --git a/frontend-ts/src/components/ui/dropdown-menu.tsx b/frontend-ts/src/components/ui/dropdown-menu.tsx index 242b07a..9dc361e 100644 --- a/frontend-ts/src/components/ui/dropdown-menu.tsx +++ b/frontend-ts/src/components/ui/dropdown-menu.tsx @@ -1,31 +1,31 @@ -"use client" +"use client"; -import * as React from "react" -import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import * as React from "react"; +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"; import { CheckIcon, ChevronRightIcon, DotFilledIcon, -} from "@radix-ui/react-icons" +} from "@radix-ui/react-icons"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; -const DropdownMenu = DropdownMenuPrimitive.Root +const DropdownMenu = DropdownMenuPrimitive.Root; -const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; -const DropdownMenuGroup = DropdownMenuPrimitive.Group +const DropdownMenuGroup = DropdownMenuPrimitive.Group; -const DropdownMenuPortal = DropdownMenuPrimitive.Portal +const DropdownMenuPortal = DropdownMenuPrimitive.Portal; -const DropdownMenuSub = DropdownMenuPrimitive.Sub +const DropdownMenuSub = DropdownMenuPrimitive.Sub; -const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup; const DropdownMenuSubTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & { - inset?: boolean + inset?: boolean; } >(({ className, inset, children, ...props }, ref) => ( {children} -)) +)); DropdownMenuSubTrigger.displayName = - DropdownMenuPrimitive.SubTrigger.displayName + DropdownMenuPrimitive.SubTrigger.displayName; const DropdownMenuSubContent = React.forwardRef< React.ElementRef, @@ -52,13 +52,13 @@ const DropdownMenuSubContent = React.forwardRef< ref={ref} className={cn( "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", - className + className, )} {...props} /> -)) +)); DropdownMenuSubContent.displayName = - DropdownMenuPrimitive.SubContent.displayName + DropdownMenuPrimitive.SubContent.displayName; const DropdownMenuContent = React.forwardRef< React.ElementRef, @@ -71,18 +71,18 @@ const DropdownMenuContent = React.forwardRef< className={cn( "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md", "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", - className + className, )} {...props} /> -)) -DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName +)); +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; const DropdownMenuItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & { - inset?: boolean + inset?: boolean; } >(({ className, inset, ...props }, ref) => ( -)) -DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName +)); +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName; const DropdownMenuCheckboxItem = React.forwardRef< React.ElementRef, @@ -105,7 +105,7 @@ const DropdownMenuCheckboxItem = React.forwardRef< ref={ref} className={cn( "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", - className + className, )} checked={checked} {...props} @@ -117,9 +117,9 @@ const DropdownMenuCheckboxItem = React.forwardRef< {children} -)) +)); DropdownMenuCheckboxItem.displayName = - DropdownMenuPrimitive.CheckboxItem.displayName + DropdownMenuPrimitive.CheckboxItem.displayName; const DropdownMenuRadioItem = React.forwardRef< React.ElementRef, @@ -129,7 +129,7 @@ const DropdownMenuRadioItem = React.forwardRef< ref={ref} className={cn( "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", - className + className, )} {...props} > @@ -140,13 +140,13 @@ const DropdownMenuRadioItem = React.forwardRef< {children} -)) -DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName +)); +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName; const DropdownMenuLabel = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & { - inset?: boolean + inset?: boolean; } >(({ className, inset, ...props }, ref) => ( -)) -DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName +)); +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName; const DropdownMenuSeparator = React.forwardRef< React.ElementRef, @@ -170,8 +170,8 @@ const DropdownMenuSeparator = React.forwardRef< className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} /> -)) -DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName +)); +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; const DropdownMenuShortcut = ({ className, @@ -182,9 +182,9 @@ const DropdownMenuShortcut = ({ className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} /> - ) -} -DropdownMenuShortcut.displayName = "DropdownMenuShortcut" + ); +}; +DropdownMenuShortcut.displayName = "DropdownMenuShortcut"; export { DropdownMenu, @@ -202,4 +202,4 @@ export { DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, -} +}; diff --git a/frontend-ts/src/style/output.css b/frontend-ts/src/style/output.css index 5410ce2..e20f5fb 100644 --- a/frontend-ts/src/style/output.css +++ b/frontend-ts/src/style/output.css @@ -22,7 +22,7 @@ ::before, ::after { - --tw-content: ''; + --tw-content: ""; } /* @@ -42,9 +42,23 @@ html { -moz-tab-size: 4; /* 3 */ -o-tab-size: 4; - tab-size: 4; + tab-size: 4; /* 3 */ - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + "Helvetica Neue", + Arial, + "Noto Sans", + sans-serif, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; /* 4 */ font-feature-settings: normal; /* 5 */ @@ -85,7 +99,7 @@ Add the correct text decoration in Chrome, Edge, and Safari. abbr:where([title]) { -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; + text-decoration: underline dotted; } /* @@ -129,7 +143,8 @@ code, kbd, samp, pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace; /* 1 */ font-size: 1em; /* 2 */ @@ -224,9 +239,9 @@ select { */ button, -[type='button'], -[type='reset'], -[type='submit'] { +[type="button"], +[type="reset"], +[type="submit"] { -webkit-appearance: button; /* 1 */ background-color: transparent; @@ -273,7 +288,7 @@ Correct the cursor style of increment and decrement buttons in Safari. 2. Correct the outline style in Safari. */ -[type='search'] { +[type="search"] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; @@ -366,7 +381,8 @@ textarea { 2. Set the default placeholder color to the user's configured gray 400 color. */ -input::-moz-placeholder, textarea::-moz-placeholder { +input::-moz-placeholder, +textarea::-moz-placeholder { opacity: 1; /* 1 */ color: #9ca3af; @@ -434,10 +450,25 @@ video { display: none; } -[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select { +[type="text"], +input:where(:not([type])), +[type="email"], +[type="url"], +[type="password"], +[type="number"], +[type="date"], +[type="datetime-local"], +[type="month"], +[type="search"], +[type="tel"], +[type="time"], +[type="week"], +[multiple], +textarea, +select { -webkit-appearance: none; - -moz-appearance: none; - appearance: none; + -moz-appearance: none; + appearance: none; background-color: #fff; border-color: #6b7280; border-width: 1px; @@ -451,25 +482,45 @@ video { --tw-shadow: 0 0 #0000; } -[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus { +[type="text"]:focus, +input:where(:not([type])):focus, +[type="email"]:focus, +[type="url"]:focus, +[type="password"]:focus, +[type="number"]:focus, +[type="date"]:focus, +[type="datetime-local"]:focus, +[type="month"]:focus, +[type="search"]:focus, +[type="tel"]:focus, +[type="time"]:focus, +[type="week"]:focus, +[multiple]:focus, +textarea:focus, +select:focus { outline: 2px solid transparent; outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-inset: var(--tw-empty, /*!*/ /*!*/); --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow); border-color: #2563eb; } -input::-moz-placeholder, textarea::-moz-placeholder { +input::-moz-placeholder, +textarea::-moz-placeholder { color: #6b7280; opacity: 1; } -input::placeholder,textarea::placeholder { +input::placeholder, +textarea::placeholder { color: #6b7280; opacity: 1; } @@ -487,7 +538,15 @@ input::placeholder,textarea::placeholder { display: inline-flex; } -::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field { +::-webkit-datetime-edit, +::-webkit-datetime-edit-year-field, +::-webkit-datetime-edit-month-field, +::-webkit-datetime-edit-day-field, +::-webkit-datetime-edit-hour-field, +::-webkit-datetime-edit-minute-field, +::-webkit-datetime-edit-second-field, +::-webkit-datetime-edit-millisecond-field, +::-webkit-datetime-edit-meridiem-field { padding-top: 0; padding-bottom: 0; } @@ -499,32 +558,34 @@ select { background-size: 1.5em 1.5em; padding-right: 2.5rem; -webkit-print-color-adjust: exact; - print-color-adjust: exact; + print-color-adjust: exact; } -[multiple],[size]:where(select:not([size="1"])) { +[multiple], +[size]:where(select:not([size="1"])) { background-image: initial; background-position: initial; background-repeat: unset; background-size: initial; padding-right: 0.75rem; -webkit-print-color-adjust: unset; - print-color-adjust: unset; + print-color-adjust: unset; } -[type='checkbox'],[type='radio'] { +[type="checkbox"], +[type="radio"] { -webkit-appearance: none; - -moz-appearance: none; - appearance: none; + -moz-appearance: none; + appearance: none; padding: 0; -webkit-print-color-adjust: exact; - print-color-adjust: exact; + print-color-adjust: exact; display: inline-block; vertical-align: middle; background-origin: border-box; -webkit-user-select: none; - -moz-user-select: none; - user-select: none; + -moz-user-select: none; + user-select: none; flex-shrink: 0; height: 1rem; width: 1rem; @@ -535,27 +596,32 @@ select { --tw-shadow: 0 0 #0000; } -[type='checkbox'] { +[type="checkbox"] { border-radius: 0px; } -[type='radio'] { +[type="radio"] { border-radius: 100%; } -[type='checkbox']:focus,[type='radio']:focus { +[type="checkbox"]:focus, +[type="radio"]:focus { outline: 2px solid transparent; outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-inset: var(--tw-empty, /*!*/ /*!*/); --tw-ring-offset-width: 2px; --tw-ring-offset-color: #fff; --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow); } -[type='checkbox']:checked,[type='radio']:checked { +[type="checkbox"]:checked, +[type="radio"]:checked { border-color: transparent; background-color: currentColor; background-size: 100% 100%; @@ -563,20 +629,23 @@ select { background-repeat: no-repeat; } -[type='checkbox']:checked { +[type="checkbox"]:checked { background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); } -[type='radio']:checked { +[type="radio"]:checked { background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); } -[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus { +[type="checkbox"]:checked:hover, +[type="checkbox"]:checked:focus, +[type="radio"]:checked:hover, +[type="radio"]:checked:focus { border-color: transparent; background-color: currentColor; } -[type='checkbox']:indeterminate { +[type="checkbox"]:indeterminate { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); border-color: transparent; background-color: currentColor; @@ -585,12 +654,13 @@ select { background-repeat: no-repeat; } -[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus { +[type="checkbox"]:indeterminate:hover, +[type="checkbox"]:indeterminate:focus { border-color: transparent; background-color: currentColor; } -[type='file'] { +[type="file"] { background: unset; border-color: inherit; border-width: 0; @@ -600,7 +670,7 @@ select { line-height: inherit; } -[type='file']:focus { +[type="file"]:focus { outline: 1px solid ButtonText; outline: 1px auto -webkit-focus-ring-color; } @@ -670,11 +740,13 @@ body { background-color: hsl(var(--background)); color: hsl(var(--foreground)); font-feature-settings: - "rlig" 1, - "calt" 1; + "rlig" 1, + "calt" 1; } -*, ::before, ::after { +*, +::before, +::after { --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; @@ -845,22 +917,6 @@ body { bottom: 0px; } -.bottom-1 { - bottom: 0.25rem; -} - -.bottom-14 { - bottom: 3.5rem; -} - -.bottom-4 { - bottom: 1rem; -} - -.bottom-9 { - bottom: 2.25rem; -} - .left-0 { left: 0px; } @@ -873,10 +929,6 @@ body { left: 0.5rem; } -.left-6 { - left: 1.5rem; -} - .left-\[50\%\] { left: 50%; } @@ -893,18 +945,10 @@ body { right: 0.5rem; } -.right-20 { - right: 5rem; -} - .right-4 { right: 1rem; } -.right-5 { - right: 1.25rem; -} - .top-0 { top: 0px; } @@ -913,14 +957,6 @@ body { top: 0.25rem; } -.top-2 { - top: 0.5rem; -} - -.top-3 { - top: 0.75rem; -} - .top-4 { top: 1rem; } @@ -965,10 +1001,6 @@ body { grid-column: span 7 / span 7; } -.m-0 { - margin: 0px; -} - .-mx-1 { margin-left: -0.25rem; margin-right: -0.25rem; @@ -1004,12 +1036,13 @@ body { margin-bottom: 1rem; } -.-ml-3 { - margin-left: -0.75rem; +.mx-6 { + margin-left: 1.5rem; + margin-right: 1.5rem; } -.mb-0 { - margin-bottom: 0px; +.-ml-3 { + margin-left: -0.75rem; } .mb-1 { @@ -1060,10 +1093,6 @@ body { margin-right: 0.5rem; } -.mt-0 { - margin-top: 0px; -} - .mt-1 { margin-top: 0.25rem; } @@ -1221,6 +1250,10 @@ body { min-height: 15vh; } +.min-h-\[30vh\] { + min-height: 30vh; +} + .min-h-\[400px\] { min-height: 400px; } @@ -1354,10 +1387,6 @@ body { width: 100vw; } -.w-10 { - width: 2.5rem; -} - .min-w-\[8rem\] { min-width: 8rem; } @@ -1396,26 +1425,34 @@ body { .translate-x-\[-50\%\] { --tw-translate-x: -50%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .translate-y-\[-50\%\] { --tw-translate-y: -50%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .translate-y-\[2px\] { --tw-translate-y: 2px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .transform { - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } @keyframes pulse { 50% { - opacity: .5; + opacity: 0.5; } } @@ -1447,8 +1484,8 @@ body { .select-none { -webkit-user-select: none; - -moz-user-select: none; - user-select: none; + -moz-user-select: none; + user-select: none; } .resize-none { @@ -1519,6 +1556,10 @@ body { align-items: flex-start; } +.items-end { + align-items: flex-end; +} + .items-center { align-items: center; } @@ -1660,6 +1701,10 @@ body { border-color: rgb(229 231 235 / var(--tw-divide-opacity)); } +.place-self-center { + place-self: center; +} + .overflow-auto { overflow: auto; } @@ -1736,10 +1781,6 @@ body { border-width: 1px; } -.border-0 { - border-width: 0px; -} - .border-2 { border-width: 2px; } @@ -1772,6 +1813,11 @@ body { border-style: dashed; } +.border-\[\#00B8D9\] { + --tw-border-opacity: 1; + border-color: rgb(0 184 217 / var(--tw-border-opacity)); +} + .border-alert { border-color: hsl(var(--alert)); } @@ -1835,6 +1881,11 @@ body { border-top-color: transparent; } +.bg-\[\#00B8D9\] { + --tw-bg-opacity: 1; + background-color: rgb(0 184 217 / var(--tw-bg-opacity)); +} + .bg-\[\#ecedef\] { --tw-bg-opacity: 1; background-color: rgb(236 237 239 / var(--tw-bg-opacity)); @@ -1844,6 +1895,10 @@ body { background-color: hsl(var(--accent)); } +.bg-alert { + background-color: hsl(var(--alert)); +} + .bg-background { background-color: hsl(var(--background)); } @@ -1852,10 +1907,6 @@ body { background-color: hsl(var(--background) / 0.8); } -.bg-blue-200\/10 { - background-color: rgb(191 219 254 / 0.1); -} - .bg-border { background-color: hsl(var(--border)); } @@ -1872,11 +1923,6 @@ body { background-color: hsl(var(--destructive)); } -.bg-gray-400 { - --tw-bg-opacity: 1; - background-color: rgb(156 163 175 / var(--tw-bg-opacity)); -} - .bg-gray-900 { --tw-bg-opacity: 1; background-color: rgb(17 24 39 / var(--tw-bg-opacity)); @@ -1886,10 +1932,6 @@ body { background-color: hsl(var(--muted)); } -.bg-pink-200\/10 { - background-color: rgb(251 207 232 / 0.1); -} - .bg-popover { background-color: hsl(var(--popover)); } @@ -1964,10 +2006,6 @@ body { stroke: hsl(var(--info)); } -.stroke-online { - stroke: hsl(var(--online)); -} - .stroke-warning { stroke: hsl(var(--warning)); } @@ -2079,12 +2117,13 @@ body { padding-bottom: 1.5rem; } -.pb-2 { - padding-bottom: 0.5rem; +.px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; } -.pb-20 { - padding-bottom: 5rem; +.pb-2 { + padding-bottom: 0.5rem; } .pb-4 { @@ -2204,7 +2243,8 @@ body { } .font-mono { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace; } .text-2xl { @@ -2463,6 +2503,11 @@ body { text-underline-offset: 4px; } +.subpixel-antialiased { + -webkit-font-smoothing: auto; + -moz-osx-font-smoothing: auto; +} + .opacity-0 { opacity: 0; } @@ -2489,36 +2534,34 @@ body { .shadow { --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), + 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), + var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } .shadow-lg { - --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), + 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), + var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } .shadow-md { --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), + 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), + var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } .shadow-sm { --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-fortutor\/25 { - --tw-shadow-color: hsl(var(--fortutor) / 0.25); - --tw-shadow: var(--tw-shadow-colored); -} - -.shadow-info\/25 { - --tw-shadow-color: hsl(var(--info) / 0.25); - --tw-shadow: var(--tw-shadow-colored); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), + var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } .outline-none { @@ -2535,9 +2578,12 @@ body { } .ring-0 { - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow, 0 0 #0000); } .ring-offset-background { @@ -2546,23 +2592,60 @@ body { .blur { --tw-blur: blur(8px); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) + var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) + var(--tw-sepia) var(--tw-drop-shadow); } .filter { - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) + var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) + var(--tw-sepia) var(--tw-drop-shadow); } .backdrop-blur-sm { --tw-backdrop-blur: blur(4px); - -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) + var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) + var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) + var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) + var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) + var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) + var(--tw-backdrop-sepia); } .transition { - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + -webkit-backdrop-filter; + transition-property: color, background-color, border-color, + text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, + backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + backdrop-filter, + -webkit-backdrop-filter; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; } @@ -2574,7 +2657,8 @@ body { } .transition-colors { - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-property: color, background-color, border-color, + text-decoration-color, fill, stroke; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; } @@ -2606,14 +2690,34 @@ body { @keyframes enter { from { opacity: var(--tw-enter-opacity, 1); - transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0)); + transform: translate3d( + var(--tw-enter-translate-x, 0), + var(--tw-enter-translate-y, 0), + 0 + ) + scale3d( + var(--tw-enter-scale, 1), + var(--tw-enter-scale, 1), + var(--tw-enter-scale, 1) + ) + rotate(var(--tw-enter-rotate, 0)); } } @keyframes exit { to { opacity: var(--tw-exit-opacity, 1); - transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0)); + transform: translate3d( + var(--tw-exit-translate-x, 0), + var(--tw-exit-translate-y, 0), + 0 + ) + scale3d( + var(--tw-exit-scale, 1), + var(--tw-exit-scale, 1), + var(--tw-exit-scale, 1) + ) + rotate(var(--tw-exit-rotate, 0)); } } @@ -2786,21 +2890,30 @@ body { } .focus\:ring-0:focus { - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow, 0 0 #0000); } .focus\:ring-1:focus { - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow, 0 0 #0000); } .focus\:ring-2:focus { - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow, 0 0 #0000); } .focus\:ring-ring:focus { @@ -2817,15 +2930,21 @@ body { } .focus-visible\:ring-1:focus-visible { - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow, 0 0 #0000); } .focus-visible\:ring-2:focus-visible { - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow, 0 0 #0000); } .focus-visible\:ring-ring:focus-visible { @@ -2854,12 +2973,16 @@ body { .group:hover .group-hover\:translate-x-0 { --tw-translate-x: 0px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .group:hover .group-hover\:translate-x-0\.5 { --tw-translate-x: 0.125rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .group:hover .group-hover\:opacity-100 { @@ -2875,7 +2998,8 @@ body { color: rgb(252 165 165 / var(--tw-text-opacity)); } -.group.destructive .group-\[\.destructive\]\:hover\:border-destructive\/30:hover { +.group.destructive + .group-\[\.destructive\]\:hover\:border-destructive\/30:hover { border-color: hsl(var(--destructive) / 0.3); } @@ -2883,7 +3007,8 @@ body { background-color: hsl(var(--destructive)); } -.group.destructive .group-\[\.destructive\]\:hover\:text-destructive-foreground:hover { +.group.destructive + .group-\[\.destructive\]\:hover\:text-destructive-foreground:hover { color: hsl(var(--destructive-foreground)); } @@ -2929,49 +3054,67 @@ body { pointer-events: none; } -.data-\[side\=bottom\]\:translate-y-1[data-side=bottom] { +.data-\[side\=bottom\]\:translate-y-1[data-side="bottom"] { --tw-translate-y: 0.25rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.data-\[side\=left\]\:-translate-x-1[data-side=left] { +.data-\[side\=left\]\:-translate-x-1[data-side="left"] { --tw-translate-x: -0.25rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.data-\[side\=right\]\:translate-x-1[data-side=right] { +.data-\[side\=right\]\:translate-x-1[data-side="right"] { --tw-translate-x: 0.25rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.data-\[side\=top\]\:-translate-y-1[data-side=top] { +.data-\[side\=top\]\:-translate-y-1[data-side="top"] { --tw-translate-y: -0.25rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.data-\[state\=checked\]\:translate-x-4[data-state=checked] { +.data-\[state\=checked\]\:translate-x-4[data-state="checked"] { --tw-translate-x: 1rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked] { +.data-\[state\=unchecked\]\:translate-x-0[data-state="unchecked"] { --tw-translate-x: 0px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.data-\[swipe\=cancel\]\:translate-x-0[data-swipe=cancel] { +.data-\[swipe\=cancel\]\:translate-x-0[data-swipe="cancel"] { --tw-translate-x: 0px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.data-\[swipe\=end\]\:translate-x-\[var\(--radix-toast-swipe-end-x\)\][data-swipe=end] { +.data-\[swipe\=end\]\:translate-x-\[var\(--radix-toast-swipe-end-x\)\][data-swipe="end"] { --tw-translate-x: var(--radix-toast-swipe-end-x); - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.data-\[swipe\=move\]\:translate-x-\[var\(--radix-toast-swipe-move-x\)\][data-swipe=move] { +.data-\[swipe\=move\]\:translate-x-\[var\(--radix-toast-swipe-move-x\)\][data-swipe="move"] { --tw-translate-x: var(--radix-toast-swipe-move-x); - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } @keyframes accordion-up { @@ -2984,7 +3127,7 @@ body { } } -.data-\[state\=closed\]\:animate-accordion-up[data-state=closed] { +.data-\[state\=closed\]\:animate-accordion-up[data-state="closed"] { animation: accordion-up 0.2s ease-out; } @@ -2998,43 +3141,43 @@ body { } } -.data-\[state\=open\]\:animate-accordion-down[data-state=open] { +.data-\[state\=open\]\:animate-accordion-down[data-state="open"] { animation: accordion-down 0.2s ease-out; } -.data-\[state\=active\]\:bg-background[data-state=active] { +.data-\[state\=active\]\:bg-background[data-state="active"] { background-color: hsl(var(--background)); } -.data-\[state\=checked\]\:bg-primary[data-state=checked] { +.data-\[state\=checked\]\:bg-primary[data-state="checked"] { background-color: hsl(var(--primary)); } -.data-\[state\=open\]\:bg-accent[data-state=open] { +.data-\[state\=open\]\:bg-accent[data-state="open"] { background-color: hsl(var(--accent)); } -.data-\[state\=open\]\:bg-muted[data-state=open] { +.data-\[state\=open\]\:bg-muted[data-state="open"] { background-color: hsl(var(--muted)); } -.data-\[state\=selected\]\:bg-muted[data-state=selected] { +.data-\[state\=selected\]\:bg-muted[data-state="selected"] { background-color: hsl(var(--muted)); } -.data-\[state\=unchecked\]\:bg-input[data-state=unchecked] { +.data-\[state\=unchecked\]\:bg-input[data-state="unchecked"] { background-color: hsl(var(--input)); } -.data-\[state\=active\]\:text-foreground[data-state=active] { +.data-\[state\=active\]\:text-foreground[data-state="active"] { color: hsl(var(--foreground)); } -.data-\[state\=checked\]\:text-primary-foreground[data-state=checked] { +.data-\[state\=checked\]\:text-primary-foreground[data-state="checked"] { color: hsl(var(--primary-foreground)); } -.data-\[state\=open\]\:text-muted-foreground[data-state=open] { +.data-\[state\=open\]\:text-muted-foreground[data-state="open"] { color: hsl(var(--muted-foreground)); } @@ -3042,17 +3185,19 @@ body { opacity: 0.5; } -.data-\[state\=active\]\:shadow[data-state=active] { +.data-\[state\=active\]\:shadow[data-state="active"] { --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), + 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), + var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } -.data-\[swipe\=move\]\:transition-none[data-swipe=move] { +.data-\[swipe\=move\]\:transition-none[data-swipe="move"] { transition-property: none; } -.data-\[state\=open\]\:animate-in[data-state=open] { +.data-\[state\=open\]\:animate-in[data-state="open"] { animation-name: enter; animation-duration: 150ms; --tw-enter-opacity: initial; @@ -3062,7 +3207,7 @@ body { --tw-enter-translate-y: initial; } -.data-\[state\=closed\]\:animate-out[data-state=closed] { +.data-\[state\=closed\]\:animate-out[data-state="closed"] { animation-name: exit; animation-duration: 150ms; --tw-exit-opacity: initial; @@ -3072,7 +3217,7 @@ body { --tw-exit-translate-y: initial; } -.data-\[swipe\=end\]\:animate-out[data-swipe=end] { +.data-\[swipe\=end\]\:animate-out[data-swipe="end"] { animation-name: exit; animation-duration: 150ms; --tw-exit-opacity: initial; @@ -3082,63 +3227,63 @@ body { --tw-exit-translate-y: initial; } -.data-\[state\=closed\]\:fade-out-0[data-state=closed] { +.data-\[state\=closed\]\:fade-out-0[data-state="closed"] { --tw-exit-opacity: 0; } -.data-\[state\=closed\]\:fade-out-80[data-state=closed] { +.data-\[state\=closed\]\:fade-out-80[data-state="closed"] { --tw-exit-opacity: 0.8; } -.data-\[state\=open\]\:fade-in-0[data-state=open] { +.data-\[state\=open\]\:fade-in-0[data-state="open"] { --tw-enter-opacity: 0; } -.data-\[state\=closed\]\:zoom-out-95[data-state=closed] { - --tw-exit-scale: .95; +.data-\[state\=closed\]\:zoom-out-95[data-state="closed"] { + --tw-exit-scale: 0.95; } -.data-\[state\=open\]\:zoom-in-95[data-state=open] { - --tw-enter-scale: .95; +.data-\[state\=open\]\:zoom-in-95[data-state="open"] { + --tw-enter-scale: 0.95; } -.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom] { +.data-\[side\=bottom\]\:slide-in-from-top-2[data-side="bottom"] { --tw-enter-translate-y: -0.5rem; } -.data-\[side\=left\]\:slide-in-from-right-2[data-side=left] { +.data-\[side\=left\]\:slide-in-from-right-2[data-side="left"] { --tw-enter-translate-x: 0.5rem; } -.data-\[side\=right\]\:slide-in-from-left-2[data-side=right] { +.data-\[side\=right\]\:slide-in-from-left-2[data-side="right"] { --tw-enter-translate-x: -0.5rem; } -.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top] { +.data-\[side\=top\]\:slide-in-from-bottom-2[data-side="top"] { --tw-enter-translate-y: 0.5rem; } -.data-\[state\=closed\]\:slide-out-to-left-1\/2[data-state=closed] { +.data-\[state\=closed\]\:slide-out-to-left-1\/2[data-state="closed"] { --tw-exit-translate-x: -50%; } -.data-\[state\=closed\]\:slide-out-to-right-full[data-state=closed] { +.data-\[state\=closed\]\:slide-out-to-right-full[data-state="closed"] { --tw-exit-translate-x: 100%; } -.data-\[state\=closed\]\:slide-out-to-top-\[48\%\][data-state=closed] { +.data-\[state\=closed\]\:slide-out-to-top-\[48\%\][data-state="closed"] { --tw-exit-translate-y: -48%; } -.data-\[state\=open\]\:slide-in-from-left-1\/2[data-state=open] { +.data-\[state\=open\]\:slide-in-from-left-1\/2[data-state="open"] { --tw-enter-translate-x: -50%; } -.data-\[state\=open\]\:slide-in-from-top-\[48\%\][data-state=open] { +.data-\[state\=open\]\:slide-in-from-top-\[48\%\][data-state="open"] { --tw-enter-translate-y: -48%; } -.data-\[state\=open\]\:slide-in-from-top-full[data-state=open] { +.data-\[state\=open\]\:slide-in-from-top-full[data-state="open"] { --tw-enter-translate-y: -100%; } @@ -3150,12 +3295,8 @@ body { border-color: hsl(var(--destructive)); } -:is(.dark .dark\:bg-blue-500\/20) { - background-color: rgb(59 130 246 / 0.2); -} - -:is(.dark .dark\:bg-pink-500\/20) { - background-color: rgb(236 72 153 / 0.2); +:is(.dark .dark\:bg-alert\/25) { + background-color: hsl(var(--alert) / 0.25); } :is(.dark .dark\:bg-opacity-80) { @@ -3166,24 +3307,6 @@ body { color: hsl(var(--foreground)); } -:is(.dark .dark\:shadow-fortutor\/50) { - --tw-shadow-color: hsl(var(--fortutor) / 0.5); - --tw-shadow: var(--tw-shadow-colored); -} - -:is(.dark .dark\:shadow-info\/50) { - --tw-shadow-color: hsl(var(--info) / 0.5); - --tw-shadow: var(--tw-shadow-colored); -} - -:is(.dark .hover\:dark\:text-online):hover { - color: hsl(var(--online)); -} - -:is(.dark .hover\:dark\:text-warning):hover { - color: hsl(var(--warning)); -} - @media (min-width: 640px) { .sm\:bottom-0 { bottom: 0px; @@ -3205,6 +3328,11 @@ body { grid-column: span 4 / span 4; } + .sm\:mx-10 { + margin-left: 2.5rem; + margin-right: 2.5rem; + } + .sm\:mt-0 { margin-top: 0px; } @@ -3271,6 +3399,11 @@ body { border-radius: var(--radius); } + .sm\:px-4 { + padding-left: 1rem; + padding-right: 1rem; + } + .sm\:text-left { text-align: left; } @@ -3288,7 +3421,7 @@ body { line-height: 1.5rem; } - .data-\[state\=open\]\:sm\:slide-in-from-bottom-full[data-state=open] { + .data-\[state\=open\]\:sm\:slide-in-from-bottom-full[data-state="open"] { --tw-enter-translate-y: 100%; } } @@ -3302,6 +3435,10 @@ body { grid-column: span 6 / span 6; } + .md\:col-span-7 { + grid-column: span 7 / span 7; + } + .md\:block { display: block; } @@ -3515,17 +3652,17 @@ body { } } -.\[\&\+div\]\:text-xs+div { +.\[\&\+div\]\:text-xs + div { font-size: 0.75rem; line-height: 1rem; } -.\[\&\:has\(\>\.day-range-end\)\]\:rounded-r-md:has(>.day-range-end) { +.\[\&\:has\(\>\.day-range-end\)\]\:rounded-r-md:has(> .day-range-end) { border-top-right-radius: calc(var(--radius) - 2px); border-bottom-right-radius: calc(var(--radius) - 2px); } -.\[\&\:has\(\>\.day-range-start\)\]\:rounded-l-md:has(>.day-range-start) { +.\[\&\:has\(\>\.day-range-start\)\]\:rounded-l-md:has(> .day-range-start) { border-top-left-radius: calc(var(--radius) - 2px); border-bottom-left-radius: calc(var(--radius) - 2px); } @@ -3538,65 +3675,78 @@ body { background-color: hsl(var(--accent)); } -.first\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-l-md:has([aria-selected]):first-child { +.first\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-l-md:has( + [aria-selected] + ):first-child { border-top-left-radius: calc(var(--radius) - 2px); border-bottom-left-radius: calc(var(--radius) - 2px); } -.last\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-r-md:has([aria-selected]):last-child { +.last\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-r-md:has( + [aria-selected] + ):last-child { border-top-right-radius: calc(var(--radius) - 2px); border-bottom-right-radius: calc(var(--radius) - 2px); } -.\[\&\:has\(\[data-state\=checked\]\)\>div\]\:border-primary:has([data-state=checked])>div { +.\[\&\:has\(\[data-state\=checked\]\)\>div\]\:border-primary:has( + [data-state="checked"] + ) + > div { border-color: hsl(var(--primary)); } -.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]) { +.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role="checkbox"]) { padding-right: 0px; } -.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox] { +.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\] > [role="checkbox"] { --tw-translate-y: 2px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.\[\&\>p\]\:flex>p { +.\[\&\>p\]\:flex > p { display: flex; } -.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div { +.\[\&\>svg\+div\]\:translate-y-\[-3px\] > svg + div { --tw-translate-y: -3px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.\[\&\>svg\]\:absolute>svg { +.\[\&\>svg\]\:absolute > svg { position: absolute; } -.\[\&\>svg\]\:left-4>svg { +.\[\&\>svg\]\:left-4 > svg { left: 1rem; } -.\[\&\>svg\]\:top-4>svg { +.\[\&\>svg\]\:top-4 > svg { top: 1rem; } -.\[\&\>svg\]\:text-destructive>svg { +.\[\&\>svg\]\:text-destructive > svg { color: hsl(var(--destructive)); } -.\[\&\>svg\]\:text-foreground>svg { +.\[\&\>svg\]\:text-foreground > svg { color: hsl(var(--foreground)); } -.\[\&\>svg\~\*\]\:pl-7>svg~* { +.\[\&\>svg\~\*\]\:pl-7 > svg ~ * { padding-left: 1.75rem; } -.\[\&\[data-state\=open\]\>svg\]\:rotate-180[data-state=open]>svg { +.\[\&\[data-state\=open\]\>svg\]\:rotate-180[data-state="open"] > svg { --tw-rotate: 180deg; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading] { @@ -3622,7 +3772,9 @@ body { color: hsl(var(--muted-foreground)); } -.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden]) ~[cmdk-group] { +.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 + [cmdk-group]:not([hidden]) + ~ [cmdk-group] { padding-top: 0px; } diff --git a/frontend-ts/src/views/SettingsView.tsx b/frontend-ts/src/views/SettingsView.tsx index 2462c66..c416f4e 100644 --- a/frontend-ts/src/views/SettingsView.tsx +++ b/frontend-ts/src/views/SettingsView.tsx @@ -33,8 +33,7 @@ export function SettingsView() { if (data.theme === "dark") { document.getElementById("root")?.classList.remove("light"); document.getElementById("root")?.classList.add("dark"); - } - else { + } else { document.getElementById("root")?.classList.remove("dark"); document.getElementById("root")?.classList.add("light"); } diff --git a/frontend-ts/src/views/admin/AdminBlame.tsx b/frontend-ts/src/views/admin/AdminBlame.tsx index 697c846..cf200fa 100644 --- a/frontend-ts/src/views/admin/AdminBlame.tsx +++ b/frontend-ts/src/views/admin/AdminBlame.tsx @@ -1,336 +1,371 @@ import Header from "@/components/typography/Header"; import { Separator } from "@/components/ui/separator"; -import { z } from "zod" +import { z } from "zod"; -import { columns } from "@/components/tables/admin/Columns" -import { DataTable } from "@/components/tables/admin/DataTable" -import { taskSchema } from "@/components/tables/data/schema" +import { columns } from "@/components/tables/admin/Columns"; +import { DataTable } from "@/components/tables/admin/DataTable"; +import { taskSchema } from "@/components/tables/data/schema"; function getTasks() { const TableData = [ { - "id": "TASK-8782", - "title": "You can't compress the program without quantifying the open-source SSD pixel!", - "status": "in progress", - "label": "documentation", - "priority": "medium" + id: "TASK-8782", + title: + "You can't compress the program without quantifying the open-source SSD pixel!", + status: "in progress", + label: "documentation", + priority: "medium", }, { - "id": "TASK-7878", - "title": "Try to calculate the EXE feed, maybe it will index the multi-byte pixel!", - "status": "backlog", - "label": "documentation", - "priority": "medium" + id: "TASK-7878", + title: + "Try to calculate the EXE feed, maybe it will index the multi-byte pixel!", + status: "backlog", + label: "documentation", + priority: "medium", }, { - "id": "TASK-7839", - "title": "We need to bypass the neural TCP card!", - "status": "todo", - "label": "bug", - "priority": "high" + id: "TASK-7839", + title: "We need to bypass the neural TCP card!", + status: "todo", + label: "bug", + priority: "high", }, { - "id": "TASK-5562", - "title": "The SAS interface is down, bypass the open-source pixel so we can back up the PNG bandwidth!", - "status": "backlog", - "label": "feature", - "priority": "medium" + id: "TASK-5562", + title: + "The SAS interface is down, bypass the open-source pixel so we can back up the PNG bandwidth!", + status: "backlog", + label: "feature", + priority: "medium", }, { - "id": "TASK-8686", - "title": "I'll parse the wireless SSL protocol, that should driver the API panel!", - "status": "canceled", - "label": "feature", - "priority": "medium" + id: "TASK-8686", + title: + "I'll parse the wireless SSL protocol, that should driver the API panel!", + status: "canceled", + label: "feature", + priority: "medium", }, { - "id": "TASK-1280", - "title": "Use the digital TLS panel, then you can transmit the haptic system!", - "status": "done", - "label": "bug", - "priority": "high" + id: "TASK-1280", + title: + "Use the digital TLS panel, then you can transmit the haptic system!", + status: "done", + label: "bug", + priority: "high", }, { - "id": "TASK-7262", - "title": "The UTF8 application is down, parse the neural bandwidth so we can back up the PNG firewall!", - "status": "done", - "label": "feature", - "priority": "high" + id: "TASK-7262", + title: + "The UTF8 application is down, parse the neural bandwidth so we can back up the PNG firewall!", + status: "done", + label: "feature", + priority: "high", }, { - "id": "TASK-1138", - "title": "Generating the driver won't do anything, we need to quantify the 1080p SMTP bandwidth!", - "status": "in progress", - "label": "feature", - "priority": "medium" + id: "TASK-1138", + title: + "Generating the driver won't do anything, we need to quantify the 1080p SMTP bandwidth!", + status: "in progress", + label: "feature", + priority: "medium", }, { - "id": "TASK-7184", - "title": "We need to program the back-end THX pixel!", - "status": "todo", - "label": "feature", - "priority": "low" + id: "TASK-7184", + title: "We need to program the back-end THX pixel!", + status: "todo", + label: "feature", + priority: "low", }, { - "id": "TASK-5160", - "title": "Calculating the bus won't do anything, we need to navigate the back-end JSON protocol!", - "status": "in progress", - "label": "documentation", - "priority": "high" + id: "TASK-5160", + title: + "Calculating the bus won't do anything, we need to navigate the back-end JSON protocol!", + status: "in progress", + label: "documentation", + priority: "high", }, { - "id": "TASK-5618", - "title": "Generating the driver won't do anything, we need to index the online SSL application!", - "status": "done", - "label": "documentation", - "priority": "medium" + id: "TASK-5618", + title: + "Generating the driver won't do anything, we need to index the online SSL application!", + status: "done", + label: "documentation", + priority: "medium", }, { - "id": "TASK-6699", - "title": "I'll transmit the wireless JBOD capacitor, that should hard drive the SSD feed!", - "status": "backlog", - "label": "documentation", - "priority": "medium" + id: "TASK-6699", + title: + "I'll transmit the wireless JBOD capacitor, that should hard drive the SSD feed!", + status: "backlog", + label: "documentation", + priority: "medium", }, { - "id": "TASK-2858", - "title": "We need to override the online UDP bus!", - "status": "backlog", - "label": "bug", - "priority": "medium" + id: "TASK-2858", + title: "We need to override the online UDP bus!", + status: "backlog", + label: "bug", + priority: "medium", }, { - "id": "TASK-9864", - "title": "I'll reboot the 1080p FTP panel, that should matrix the HEX hard drive!", - "status": "done", - "label": "bug", - "priority": "high" + id: "TASK-9864", + title: + "I'll reboot the 1080p FTP panel, that should matrix the HEX hard drive!", + status: "done", + label: "bug", + priority: "high", }, { - "id": "TASK-8404", - "title": "We need to generate the virtual HEX alarm!", - "status": "in progress", - "label": "bug", - "priority": "low" + id: "TASK-8404", + title: "We need to generate the virtual HEX alarm!", + status: "in progress", + label: "bug", + priority: "low", }, { - "id": "TASK-5365", - "title": "Backing up the pixel won't do anything, we need to transmit the primary IB array!", - "status": "in progress", - "label": "documentation", - "priority": "low" + id: "TASK-5365", + title: + "Backing up the pixel won't do anything, we need to transmit the primary IB array!", + status: "in progress", + label: "documentation", + priority: "low", }, { - "id": "TASK-1780", - "title": "The CSS feed is down, index the bluetooth transmitter so we can compress the CLI protocol!", - "status": "todo", - "label": "documentation", - "priority": "high" + id: "TASK-1780", + title: + "The CSS feed is down, index the bluetooth transmitter so we can compress the CLI protocol!", + status: "todo", + label: "documentation", + priority: "high", }, { - "id": "TASK-6938", - "title": "Use the redundant SCSI application, then you can hack the optical alarm!", - "status": "todo", - "label": "documentation", - "priority": "high" + id: "TASK-6938", + title: + "Use the redundant SCSI application, then you can hack the optical alarm!", + status: "todo", + label: "documentation", + priority: "high", }, { - "id": "TASK-9885", - "title": "We need to compress the auxiliary VGA driver!", - "status": "backlog", - "label": "bug", - "priority": "high" + id: "TASK-9885", + title: "We need to compress the auxiliary VGA driver!", + status: "backlog", + label: "bug", + priority: "high", }, { - "id": "TASK-3216", - "title": "Transmitting the transmitter won't do anything, we need to compress the virtual HDD sensor!", - "status": "backlog", - "label": "documentation", - "priority": "medium" + id: "TASK-3216", + title: + "Transmitting the transmitter won't do anything, we need to compress the virtual HDD sensor!", + status: "backlog", + label: "documentation", + priority: "medium", }, { - "id": "TASK-9285", - "title": "The IP monitor is down, copy the haptic alarm so we can generate the HTTP transmitter!", - "status": "todo", - "label": "bug", - "priority": "high" + id: "TASK-9285", + title: + "The IP monitor is down, copy the haptic alarm so we can generate the HTTP transmitter!", + status: "todo", + label: "bug", + priority: "high", }, { - "id": "TASK-1024", - "title": "Overriding the microchip won't do anything, we need to transmit the digital OCR transmitter!", - "status": "in progress", - "label": "documentation", - "priority": "low" + id: "TASK-1024", + title: + "Overriding the microchip won't do anything, we need to transmit the digital OCR transmitter!", + status: "in progress", + label: "documentation", + priority: "low", }, { - "id": "TASK-7068", - "title": "You can't generate the capacitor without indexing the wireless HEX pixel!", - "status": "canceled", - "label": "bug", - "priority": "low" + id: "TASK-7068", + title: + "You can't generate the capacitor without indexing the wireless HEX pixel!", + status: "canceled", + label: "bug", + priority: "low", }, { - "id": "TASK-6502", - "title": "Navigating the microchip won't do anything, we need to bypass the back-end SQL bus!", - "status": "todo", - "label": "bug", - "priority": "high" + id: "TASK-6502", + title: + "Navigating the microchip won't do anything, we need to bypass the back-end SQL bus!", + status: "todo", + label: "bug", + priority: "high", }, { - "id": "TASK-5326", - "title": "We need to hack the redundant UTF8 transmitter!", - "status": "todo", - "label": "bug", - "priority": "low" + id: "TASK-5326", + title: "We need to hack the redundant UTF8 transmitter!", + status: "todo", + label: "bug", + priority: "low", }, { - "id": "TASK-6274", - "title": "Use the virtual PCI circuit, then you can parse the bluetooth alarm!", - "status": "canceled", - "label": "documentation", - "priority": "low" + id: "TASK-6274", + title: + "Use the virtual PCI circuit, then you can parse the bluetooth alarm!", + status: "canceled", + label: "documentation", + priority: "low", }, { - "id": "TASK-1571", - "title": "I'll input the neural DRAM circuit, that should protocol the SMTP interface!", - "status": "in progress", - "label": "feature", - "priority": "medium" + id: "TASK-1571", + title: + "I'll input the neural DRAM circuit, that should protocol the SMTP interface!", + status: "in progress", + label: "feature", + priority: "medium", }, { - "id": "TASK-9518", - "title": "Compressing the interface won't do anything, we need to compress the online SDD matrix!", - "status": "canceled", - "label": "documentation", - "priority": "medium" + id: "TASK-9518", + title: + "Compressing the interface won't do anything, we need to compress the online SDD matrix!", + status: "canceled", + label: "documentation", + priority: "medium", }, { - "id": "TASK-5581", - "title": "I'll synthesize the digital COM pixel, that should transmitter the UTF8 protocol!", - "status": "backlog", - "label": "documentation", - "priority": "high" + id: "TASK-5581", + title: + "I'll synthesize the digital COM pixel, that should transmitter the UTF8 protocol!", + status: "backlog", + label: "documentation", + priority: "high", }, { - "id": "TASK-2197", - "title": "Parsing the feed won't do anything, we need to copy the bluetooth DRAM bus!", - "status": "todo", - "label": "documentation", - "priority": "low" + id: "TASK-2197", + title: + "Parsing the feed won't do anything, we need to copy the bluetooth DRAM bus!", + status: "todo", + label: "documentation", + priority: "low", }, { - "id": "TASK-8484", - "title": "We need to parse the solid state UDP firewall!", - "status": "in progress", - "label": "bug", - "priority": "low" + id: "TASK-8484", + title: "We need to parse the solid state UDP firewall!", + status: "in progress", + label: "bug", + priority: "low", }, { - "id": "TASK-9892", - "title": "If we back up the application, we can get to the UDP application through the multi-byte THX capacitor!", - "status": "done", - "label": "documentation", - "priority": "high" + id: "TASK-9892", + title: + "If we back up the application, we can get to the UDP application through the multi-byte THX capacitor!", + status: "done", + label: "documentation", + priority: "high", }, { - "id": "TASK-9616", - "title": "We need to synthesize the cross-platform ASCII pixel!", - "status": "in progress", - "label": "feature", - "priority": "medium" + id: "TASK-9616", + title: "We need to synthesize the cross-platform ASCII pixel!", + status: "in progress", + label: "feature", + priority: "medium", }, { - "id": "TASK-9744", - "title": "Use the back-end IP card, then you can input the solid state hard drive!", - "status": "done", - "label": "documentation", - "priority": "low" + id: "TASK-9744", + title: + "Use the back-end IP card, then you can input the solid state hard drive!", + status: "done", + label: "documentation", + priority: "low", }, { - "id": "TASK-1376", - "title": "Generating the alarm won't do anything, we need to generate the mobile IP capacitor!", - "status": "backlog", - "label": "documentation", - "priority": "low" + id: "TASK-1376", + title: + "Generating the alarm won't do anything, we need to generate the mobile IP capacitor!", + status: "backlog", + label: "documentation", + priority: "low", }, { - "id": "TASK-7382", - "title": "If we back up the firewall, we can get to the RAM alarm through the primary UTF8 pixel!", - "status": "todo", - "label": "feature", - "priority": "low" + id: "TASK-7382", + title: + "If we back up the firewall, we can get to the RAM alarm through the primary UTF8 pixel!", + status: "todo", + label: "feature", + priority: "low", }, { - "id": "TASK-2290", - "title": "I'll compress the virtual JSON panel, that should application the UTF8 bus!", - "status": "canceled", - "label": "documentation", - "priority": "high" + id: "TASK-2290", + title: + "I'll compress the virtual JSON panel, that should application the UTF8 bus!", + status: "canceled", + label: "documentation", + priority: "high", }, { - "id": "TASK-1533", - "title": "You can't input the firewall without overriding the wireless TCP firewall!", - "status": "done", - "label": "bug", - "priority": "high" + id: "TASK-1533", + title: + "You can't input the firewall without overriding the wireless TCP firewall!", + status: "done", + label: "bug", + priority: "high", }, { - "id": "TASK-4920", - "title": "Bypassing the hard drive won't do anything, we need to input the bluetooth JSON program!", - "status": "in progress", - "label": "bug", - "priority": "high" + id: "TASK-4920", + title: + "Bypassing the hard drive won't do anything, we need to input the bluetooth JSON program!", + status: "in progress", + label: "bug", + priority: "high", }, { - "id": "TASK-5168", - "title": "If we synthesize the bus, we can get to the IP panel through the virtual TLS array!", - "status": "in progress", - "label": "feature", - "priority": "low" + id: "TASK-5168", + title: + "If we synthesize the bus, we can get to the IP panel through the virtual TLS array!", + status: "in progress", + label: "feature", + priority: "low", }, { - "id": "TASK-7103", - "title": "We need to parse the multi-byte EXE bandwidth!", - "status": "canceled", - "label": "feature", - "priority": "low" + id: "TASK-7103", + title: "We need to parse the multi-byte EXE bandwidth!", + status: "canceled", + label: "feature", + priority: "low", }, { - "id": "TASK-4314", - "title": "If we compress the program, we can get to the XML alarm through the multi-byte COM matrix!", - "status": "in progress", - "label": "bug", - "priority": "high" + id: "TASK-4314", + title: + "If we compress the program, we can get to the XML alarm through the multi-byte COM matrix!", + status: "in progress", + label: "bug", + priority: "high", }, { - "id": "TASK-3415", - "title": "Use the cross-platform XML application, then you can quantify the solid state feed!", - "status": "todo", - "label": "feature", - "priority": "high" + id: "TASK-3415", + title: + "Use the cross-platform XML application, then you can quantify the solid state feed!", + status: "todo", + label: "feature", + priority: "high", }, { - "id": "TASK-8339", - "title": "Try to calculate the DNS interface, maybe it will input the bluetooth capacitor!", - "status": "in progress", - "label": "feature", - "priority": "low" + id: "TASK-8339", + title: + "Try to calculate the DNS interface, maybe it will input the bluetooth capacitor!", + status: "in progress", + label: "feature", + priority: "low", }, { - "id": "TASK-6995", - "title": "Try to hack the XSS bandwidth, maybe it will override the bluetooth matrix!", - "status": "todo", - "label": "feature", - "priority": "high" + id: "TASK-6995", + title: + "Try to hack the XSS bandwidth, maybe it will override the bluetooth matrix!", + status: "todo", + label: "feature", + priority: "high", }, - ] + ]; - - return z.array(taskSchema).parse(TableData) + return z.array(taskSchema).parse(TableData); } export default function AdminBlame() { - const tasks = getTasks() + const tasks = getTasks(); return ( <>
-
-
+
-
-
+
diff --git a/frontend-ts/src/views/ethan.tsx b/frontend-ts/src/views/ethan.tsx index 3f15e01..66abc74 100644 --- a/frontend-ts/src/views/ethan.tsx +++ b/frontend-ts/src/views/ethan.tsx @@ -1,6 +1,13 @@ import { Button } from "@/components/ui/button"; -import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; import { Separator } from "@/components/ui/separator"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Textarea } from "@/components/ui/textarea"; @@ -9,75 +16,87 @@ import { useForm } from "react-hook-form"; import { z } from "zod"; const FormSchema = z.object({ - data: z.string({ - required_error: "This field is required" - }) -}) + data: z.string({ + required_error: "This field is required", + }), +}); function onSubmit(data: z.infer) { - console.log(data) + console.log(data); } - export default function ForEthan() { - const form = useForm>({ - resolver: zodResolver(FormSchema), - }); - return ( - <> -
-

Ethan Awesome API

-
- -
-
- - - Summarize - - Extract - - - Generate - - - -
- - ( - - - Summarize Data - - - -
-
- - - ) -} \ No newline at end of file + const form = useForm>({ + resolver: zodResolver(FormSchema), + }); + return ( + <> +
+

Ethan Awesome API

+
+ +
+
+ + + Summarize + + Extract + + + Generate + + + + + + ( + + Summarize Data + + +
+
+ + + ); +} diff --git a/frontend-ts/src/views/tutor/TutorDashboardView.tsx b/frontend-ts/src/views/tutor/TutorDashboardView.tsx index d25451a..30040fa 100644 --- a/frontend-ts/src/views/tutor/TutorDashboardView.tsx +++ b/frontend-ts/src/views/tutor/TutorDashboardView.tsx @@ -10,13 +10,20 @@ import { import { Label } from "@/components/ui/label"; import { Separator } from "@/components/ui/separator"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { FileCheck2Icon, FileIcon, FileX2Icon, LayersIcon } from "lucide-react"; +import { + FileCheck2Icon, + FileIcon, + FileX2Icon, + LayersIcon, + RatIcon, +} from "lucide-react"; import useFetchTicket from "@/API/tickets/useFetchTicket"; export default function TutorDashboard() { const unclaimedTickets = useFetchTicket("unclaimed", "?started=false"); - const openTickets = useFetchTicket("open", "?started=true"); + const openTickets = useFetchTicket("open", "?started=true&completed=false"); const closedTickets = useFetchTicket("closed", "?completed=true"); + const allTickets = useFetchTicket("all", "?"); return ( <>
@@ -35,88 +42,111 @@ export default function TutorDashboard() {
- - - - Total Tickets - - - - -
265
-

- +20.1% from last month -

-
-
- - - - Closed Tickets - - - - -
235
-

- -4% from last month -

-
-
- - - - Success Tickets - - - - -
230
-

- +19% from last month -

-
-
- - - - Open Now - - - - -
3
-

- +1 since last hour -

-
-
+
+ + + + Total Tickets + + + + +
+ {!allTickets?.isLoading && allTickets?.data.length} +
+

+ +20.1% from last month +

+
+
+
+
+ + + + Closed Tickets + + + + +
+ {!closedTickets?.isLoading && closedTickets?.data.length} +
+

+ -4% from last month +

+
+
+
+
+ + + + Success Tickets + + + + +
+ {!closedTickets?.isLoading && closedTickets?.data.length} +
+

+ +19% from last month +

+
+
+
+
+ + + + Open Now + + + + +
+ {!openTickets?.isLoading && openTickets?.data.length} +
+

+ +1 since last hour +

+
+
+
-
- - - Total Ticket Overview - - - - - - Recent Tickets - Insert Ticket Data Here - - placeholder text - +
+
+ + + Recent Tickets + + Overview of 24 hour ticket data + + + +
+
+ +
+
Wow, so empty!
+
+
+
+
@@ -128,8 +158,7 @@ export default function TutorDashboard() { that you are working on. - {console.log(unclaimedTickets?.data)} - + {!unclaimedTickets?.isLoading && unclaimedTickets?.data && unclaimedTickets.data.map((ticket: any) => ( @@ -153,7 +182,7 @@ export default function TutorDashboard() { ensure you close all opened tickets. - + {!openTickets?.isLoading && openTickets?.data && openTickets?.data.map((ticket: any) => ( @@ -178,20 +207,20 @@ export default function TutorDashboard() { ensure you close all opened tickets. - - {!openTickets?.isLoading && - openTickets?.data && - openTickets.data.map((openTickets: any) => ( + + {!closedTickets?.isLoading && + closedTickets?.data && + closedTickets.data.map((ticket: any) => ( ))} diff --git a/frontend-ts/tailwind.config.js b/frontend-ts/tailwind.config.js index a92f91c..19b3269 100644 --- a/frontend-ts/tailwind.config.js +++ b/frontend-ts/tailwind.config.js @@ -7,22 +7,22 @@ module.exports = { "./components/**/*.{ts,tsx}", "./app/**/*.{ts,tsx}", "./src/**/*.{ts,tsx}", - 'node_modules/preline/dist/*.js', + "node_modules/preline/dist/*.js", ], theme: { container: { center: true, padding: "2rem", screens: { - '2xl': '1400px' - } + "2xl": "1400px", + }, }, extend: { screens: { - '1xl': '1300px', - '3xl': '1800px', - "wide": "2200px", - "ultrawide": "2500px" + "1xl": "1300px", + "3xl": "1800px", + wide: "2200px", + ultrawide: "2500px", }, colors: { zoom: "hsl(var(--zoom))", @@ -86,5 +86,9 @@ module.exports = { }, }, }, - plugins: [require("tailwindcss-animate"), require("@tailwindcss/forms"), require('preline/plugin')], + plugins: [ + require("tailwindcss-animate"), + require("@tailwindcss/forms"), + require("preline/plugin"), + ], };