Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
700279b
Theming css
KanonKC Oct 18, 2023
9228d1e
Login page (No logic)
KanonKC Oct 20, 2023
335cbbd
Centered container
KanonKC Oct 20, 2023
186446b
Add navbar
KanonKC Oct 23, 2023
71d2a8b
Shadcn folder, nevigation bar
KanonKC Oct 23, 2023
e36e012
Platejs, course management layout
KanonKC Oct 24, 2023
38667f4
Login button
KanonKC Oct 28, 2023
234ecbe
initial commit
KanonKC Nov 18, 2023
18d8cf1
It's finally work!
KanonKC Nov 19, 2023
0663346
Create problem page
KanonKC Nov 19, 2023
d640dc8
In progress: CreateProblem
KanonKC Nov 19, 2023
ba9f472
General detail completed
KanonKC Nov 20, 2023
46585f5
Fix: View path
KanonKC Nov 20, 2023
4e61ca9
Draft: CreateProblem page
KanonKC Nov 22, 2023
6a5eba7
Draft: ViewProblem and MyProblems
KanonKC Nov 23, 2023
670b622
Add type
KanonKC Nov 23, 2023
d9bcbe8
Draft: Navbar (for login) and MyCollections
KanonKC Nov 24, 2023
6d3de7d
Fix: Padding
KanonKC Nov 24, 2023
4093d10
Service for Account/Auth
KanonKC Nov 24, 2023
09add1d
init
KanonKC Nov 25, 2023
fbea2c2
Styled components
KanonKC Nov 26, 2023
c752be3
Responsive + API
KanonKC Nov 26, 2023
dcdd3a9
Login, logout system with Navbar
KanonKC Nov 27, 2023
547f133
New ProblemCard design
KanonKC Nov 27, 2023
db16664
Update ProblemCard
KanonKC Nov 29, 2023
1bf2ed1
Init
KanonKC Nov 29, 2023
0652d1a
ViewProblem is work, but many bugs need to be clear
KanonKC Nov 30, 2023
ccf2f49
Better submission
KanonKC Dec 1, 2023
e794fe2
Fix submission type + CreateProblem API
KanonKC Dec 1, 2023
59ac8ed
EditProblem API
KanonKC Dec 2, 2023
f8c8215
So-so Problem create/edit/view
KanonKC Dec 2, 2023
5cc0493
Implemented updated date on MyProblem
KanonKC Dec 2, 2023
c92b79c
Minor responsive
KanonKC Dec 3, 2023
e1e13e3
Add language to prev sub, fix combobox to change language
KanonKC Dec 4, 2023
1ea43db
Refactor CreateProblemForm
KanonKC Dec 4, 2023
7c57c35
Collection API service
KanonKC Dec 4, 2023
ba4fd27
Template for CreateCollection
KanonKC Dec 5, 2023
c7ac379
Initial commit + experiment
KanonKC Dec 5, 2023
bdfb752
Responsive + Card Container
KanonKC Dec 6, 2023
bc44f70
ExploreProblem view
KanonKC Dec 6, 2023
1b2acbb
More ExploreProblem page
KanonKC Dec 7, 2023
c836d9b
Explore view
KanonKC Dec 9, 2023
e8eea12
View problem
KanonKC Dec 9, 2023
fda8a27
Minor fixed
KanonKC Dec 10, 2023
a0f777a
Update many interfaces
KanonKC Dec 11, 2023
218bb49
Runtime outout can be NULL
KanonKC Dec 12, 2023
041edec
TestcaseValidation badge
KanonKC Dec 13, 2023
fe39561
Registration with API and error display
KanonKC Dec 13, 2023
ce07899
valid
KanonKC Dec 13, 2023
4e15465
Handle delete problem and MiniProblemCard for sortable
KanonKC Dec 14, 2023
ebb3b47
Negative circle Checkmark
KanonKC Dec 14, 2023
11e4d57
MOD-64: Create/Edit Collection
KanonKC Dec 15, 2023
7a8ce61
MyCourse + MyCourseCard (Draft)
KanonKC Dec 16, 2023
685dbef
CreateCourse (TODO: EditCourse)
KanonKC Dec 17, 2023
bd2af01
MOD-61,63: Create/Edit Course
KanonKC Dec 17, 2023
a83a292
Change site icon and title
KanonKC Dec 19, 2023
6e25812
Course view
KanonKC Dec 19, 2023
d4c633a
MiniCard for Problem in CollectionCard
KanonKC Dec 19, 2023
1742d23
ViewCourseProblem and ViewProblemLayout component
KanonKC Dec 20, 2023
60ae709
Better collection view on course
KanonKC Dec 20, 2023
9e7e7fa
CourseNavSidebar, CourseContext
KanonKC Dec 21, 2023
6c10683
Reponsive CourseNavSidebar
KanonKC Dec 22, 2023
e41ab2e
Full-state CourseNavbar context
KanonKC Dec 23, 2023
3bbecfd
template: dashboard
KanonKC Dec 23, 2023
5102127
MOD-66: Management Sidebar
KanonKC Dec 25, 2023
2ad3ca0
Clear warning
KanonKC Dec 25, 2023
cb0dd78
MyCard
KanonKC Dec 27, 2023
fa9e7ed
MOD-62,65: View: MyGroup and CreateGroup
KanonKC Dec 29, 2023
c45dec1
MiniCard V.2
KanonKC Dec 29, 2023
cca191a
Change ID from sequence number to random uuid4
KanonKC Dec 31, 2023
231ec01
Courses on dashboard (Access checked)
KanonKC Dec 31, 2023
9bb406a
Better card directories
KanonKC Dec 31, 2023
fc414d5
permission cards
KanonKC Jan 1, 2024
45636b0
GroupPermission on Course
KanonKC Jan 3, 2024
65a03f5
Improve MiniCard
KanonKC Jan 3, 2024
21c82c2
Resizable
KanonKC Jan 3, 2024
d77693a
Now can handle personal courses and manageable courses
KanonKC Jan 4, 2024
57e62fa
Resolved collection type conflict
KanonKC Jan 4, 2024
0360828
Disabled manage group (for non owner)
KanonKC Jan 4, 2024
11d35a1
Collection Permission
KanonKC Jan 6, 2024
8e8acb6
Course collections management
KanonKC Jan 7, 2024
95d0935
manage collection in course (Not done)
KanonKC Jan 8, 2024
7740bdd
CourseCollection permission manager
KanonKC Jan 9, 2024
daf6474
Mini bug fixed on course collection permission manager
KanonKC Jan 9, 2024
54164fd
Problem permission (Draft)
KanonKC Jan 10, 2024
ff0e27a
Manage problem permissions
KanonKC Jan 11, 2024
9c12557
Update collection to handle problem collection permissions
KanonKC Jan 11, 2024
90a76b5
Manage collection problems permissions
KanonKC Jan 11, 2024
0c5e350
Basic search engine
KanonKC Jan 11, 2024
bf43e40
Basic search
KanonKC Jan 11, 2024
fe0164d
Carousel + ContextMenu for Problem/Collection/Course
KanonKC Jan 12, 2024
ce0986f
Improve login qol
KanonKC Jan 13, 2024
581882c
New edit path and query section
KanonKC Jan 13, 2024
cb41a97
Merge pull request #1 from KanonKC/uuid-pk
KanonKC Jan 13, 2024
25abaa8
Clear warning pt.1
KanonKC Jan 13, 2024
78c7b53
Clear warnings pt.2
KanonKC Jan 13, 2024
fd7968a
Clear warnings pt.3 (Carousel + dialog)
KanonKC Jan 13, 2024
39c5f3f
Login improvement
KanonKC Jan 13, 2024
860bcdf
Setup environment
KanonKC Jan 13, 2024
5a42f1f
changed prefix
KanonKC Jan 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.env

# Logs
logs
*.log
Expand Down
50 changes: 50 additions & 0 deletions @/components/plate-ui/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use client';

import * as React from 'react';
import * as AvatarPrimitive from '@radix-ui/react-avatar';

import { cn } from '../../lib/utils';

const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn(
'relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full',
className
)}
{...props}
/>
));
Avatar.displayName = AvatarPrimitive.Root.displayName;

const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Image
ref={ref}
className={cn('aspect-square h-full w-full', className)}
{...props}
/>
));
AvatarImage.displayName = AvatarPrimitive.Image.displayName;

const AvatarFallback = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Fallback>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
'flex h-full w-full items-center justify-center rounded-full bg-muted',
className
)}
{...props}
/>
));
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;

export { Avatar, AvatarImage, AvatarFallback };
25 changes: 25 additions & 0 deletions @/components/plate-ui/blockquote-element.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client';

import React from 'react';
import { PlateElement, PlateElementProps } from '@udecode/plate-common';

import { cn } from '../../lib/utils';

const BlockquoteElement = React.forwardRef<
React.ElementRef<typeof PlateElement>,
PlateElementProps
>(({ className, children, ...props }, ref) => {
return (
<PlateElement
asChild
ref={ref}
className={cn('my-1 border-l-2 pl-6 italic', className)}
{...props}
>
<blockquote>{children}</blockquote>
</PlateElement>
);
});
BlockquoteElement.displayName = 'BlockquoteElement';

export { BlockquoteElement };
63 changes: 63 additions & 0 deletions @/components/plate-ui/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import * as React from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva, VariantProps } from 'class-variance-authority';

import { cn } from '../../lib/utils';

const buttonVariants = cva(
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline:
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
inlineLink: 'text-base text-primary underline underline-offset-4',
},
size: {
default: 'h-10 px-4 py-2',
xs: 'h-8 rounded-md px-3',
sm: 'h-9 rounded-md px-3',
sms: 'h-9 w-9 rounded-md px-0',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
none: '',
},
isMenu: {
true: 'h-auto w-full cursor-pointer justify-start',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
);

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, isMenu, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : 'button';
return (
<Comp
className={cn(buttonVariants({ isMenu, variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = 'Button';

export { Button, buttonVariants };
52 changes: 52 additions & 0 deletions @/components/plate-ui/caption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { ComponentProps } from 'react';
import {
Caption as CaptionPrimitive,
CaptionTextarea as CaptionTextareaPrimitive,
} from '@udecode/plate-caption';
import { cva, VariantProps } from 'class-variance-authority';

import { cn } from '../../lib/utils';

const captionVariants = cva('max-w-full', {
variants: {
align: {
left: 'mr-auto',
center: 'mx-auto',
right: 'ml-auto',
},
},
defaultVariants: {
align: 'center',
},
});

const Caption = React.forwardRef<
React.ElementRef<typeof CaptionPrimitive>,
ComponentProps<typeof CaptionPrimitive> & VariantProps<typeof captionVariants>
>(({ className, align, ...props }, ref) => (
<CaptionPrimitive
ref={ref}
className={cn(captionVariants({ align }), className)}
{...props}
/>
));
Caption.displayName = 'Caption';

const CaptionTextarea = React.forwardRef<
React.ElementRef<typeof CaptionTextareaPrimitive>,
ComponentProps<typeof CaptionTextareaPrimitive>
>(({ className, ...props }, ref) => (
<CaptionTextareaPrimitive
ref={ref}
className={cn(
'mt-2 w-full resize-none border-none bg-inherit p-0 font-[inherit] text-inherit',
'focus:outline-none focus:[&::placeholder]:opacity-0',
'text-center print:placeholder:text-transparent',
className
)}
{...props}
/>
));
CaptionTextarea.displayName = 'CaptionTextarea';

export { Caption, CaptionTextarea };
30 changes: 30 additions & 0 deletions @/components/plate-ui/checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use client';

import * as React from 'react';
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';

import { cn } from '../../lib/utils';
import { Icons } from './icons';

const Checkbox = React.forwardRef<
React.ElementRef<typeof CheckboxPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
>(({ className, ...props }, ref) => (
<CheckboxPrimitive.Root
ref={ref}
className={cn(
'peer h-4 w-4 shrink-0 rounded-sm border border-primary bg-background ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
className
)}
{...props}
>
<CheckboxPrimitive.Indicator
className={cn('flex items-center justify-center text-current')}
>
<Icons.check className="h-4 w-4" />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
));
Checkbox.displayName = CheckboxPrimitive.Root.displayName;

export { Checkbox };
90 changes: 90 additions & 0 deletions @/components/plate-ui/code-block-combobox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
'use client';

import React, { useState } from 'react';
import {
CODE_BLOCK_LANGUAGES,
CODE_BLOCK_LANGUAGES_POPULAR,
useCodeBlockCombobox,
useCodeBlockComboboxState,
} from '@udecode/plate-code-block';

import { cn } from '../../lib/utils';
import { Icons } from './icons';

import { Button } from './button';
import {
Command,
CommandEmpty,
CommandInput,
CommandItem,
CommandList,
} from './command';
import { Popover, PopoverContent, PopoverTrigger } from './popover';

const languages: { value: string; label: string }[] = [
{ value: 'text', label: 'Plain Text' },
...Object.entries({
...CODE_BLOCK_LANGUAGES_POPULAR,
...CODE_BLOCK_LANGUAGES,
}).map(([key, val]) => ({
value: key,
label: val as string,
})),
];

export function CodeBlockCombobox() {
const state = useCodeBlockComboboxState();
const { commandItemProps } = useCodeBlockCombobox(state);

const [open, setOpen] = useState(false);

if (state.readOnly) return null;

return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant="ghost"
role="combobox"
aria-expanded={open}
className="h-5 justify-between px-1 text-xs"
size="xs"
>
{state.value
? languages.find((language) => language.value === state.value)
?.label
: 'Plain Text'}
<Icons.chevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
<CommandInput placeholder="Search language..." />
<CommandEmpty>No language found.</CommandEmpty>

<CommandList>
{languages.map((language) => (
<CommandItem
key={language.value}
value={language.value}
className="cursor-pointer"
onSelect={(_value) => {
commandItemProps.onSelect(_value);
setOpen(false);
}}
>
<Icons.check
className={cn(
'mr-2 h-4 w-4',
state.value === language.value ? 'opacity-100' : 'opacity-0'
)}
/>
{language.label}
</CommandItem>
))}
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
}
Loading