Skip to content

Commit

Permalink
Merge pull request #214 from CS3219-AY2425S1/212-fe-visual-and-user-e…
Browse files Browse the repository at this point in the history
…xperience-enhancements

Enhance visual and user experience
  • Loading branch information
yunruu authored Nov 13, 2024
2 parents 8929f9b + 6d5eca7 commit 0dc80cd
Show file tree
Hide file tree
Showing 14 changed files with 59 additions and 40 deletions.
2 changes: 1 addition & 1 deletion frontend/components/account/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function Profile() {
dialogOpen={isDialogOpen}
onDialogOpenChange={manageDialog} // Allow toggling the dialog
text="Update Profile"
className="w-fit bg-btn text-white text-sm py-2 px-4 rounded-md hover:bg-purple-700"
className="w-fit bg-btn text-white text-sm py-2 px-4 rounded-md"
type="button"
variant="primary"
description="Are you sure you want to update your profile?"
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/account/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ function Setting() {
dialogOpen={isUpdateDialogOpen}
onDialogOpenChange={manageUpdateDialog}
text="Update Settings"
className="w-fit bg-btn text-white text-sm py-2 px-4 rounded-md hover:bg-theme-700"
className="w-fit bg-btn text-white text-sm py-2 px-4 rounded-md"
type="button"
variant="primary"
description="Are you sure you want to update your settings?"
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/customs/custom-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function CustomDialogWithButton(props: CustomDialogProps) {
<DialogTitle>
<div className="flex flex-row gap-5">
<ErrorIconDialog />
Warning
{props.text || 'Warning'}
</div>
<span className="h-0.5 w-full bg-slate-200 mt-5"></span>
</DialogTitle>
Expand Down
33 changes: 17 additions & 16 deletions frontend/components/customs/datatable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function Datatable({
<Table>
<TableHeader>
<TableRow>
<TableHead>{hideIdx ? null : 'No.'}</TableHead>
<TableHead style={{ width: '5%' }}>{hideIdx ? null : 'No.'}</TableHead>
{columns.map((elem) => {
if (elem.isHidden) {
return null
Expand Down Expand Up @@ -129,21 +129,22 @@ export default function Datatable({
<DeleteIcon />
</Button>
)}
{col.customAction && col.customAction.formatter ? (
col.customAction.formatter(elem, router)
) : (
<Button
variant="iconNoBorder"
size="icon"
onClick={() => {
if (col.customAction && col.customAction.onClick) {
col.customAction.onClick(elem)
}
}}
>
{col.customAction?.customActionIcon}
</Button>
)}
{col.customAction &&
(col.customAction.formatter ? (
col.customAction.formatter(elem, router)
) : (
<Button
variant="iconNoBorder"
size="icon"
onClick={() => {
if (col.customAction && col.customAction.onClick) {
col.customAction.onClick(elem)
}
}}
>
{col.customAction?.customActionIcon}
</Button>
))}
</TableCell>
)
}
Expand Down
8 changes: 5 additions & 3 deletions frontend/components/dashboard/new-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { addUserToMatchmaking } from '../../services/matching-service-api'
import CustomModal from '../customs/custom-modal'
import Loading from '../customs/loading'
import { capitalizeFirstLowerRest } from '@/util/string-modification'
import { encodeStr } from '@/util/encryption'

export const NewSession = () => {
const router = useRouter()
Expand Down Expand Up @@ -109,7 +110,8 @@ export const NewSession = () => {
switch (newMessage.type) {
case WebSocketMessageType.SUCCESS:
updateMatchmakingStatus(MatchingStatus.MATCH_FOUND, newMessage.matchId)
router.push(`/code/${newMessage.matchId}`)
const encodedId = encodeStr(newMessage.matchId)
router.push(`/code/${encodedId}`)
break
case WebSocketMessageType.FAILURE:
socketRef.current?.close()
Expand Down Expand Up @@ -204,7 +206,7 @@ export const NewSession = () => {
</SelectContent>
</Select>
</div>
<Button className="mt-4 bg-purple-600 hover:bg-[#A78BFA]" onClick={handleMatchmaking}>
<Button variant="primary" onClick={handleMatchmaking}>
Start matchmaking
</Button>

Expand Down Expand Up @@ -267,7 +269,7 @@ export const NewSession = () => {
<Button
variant={'ghostTabLabel'}
size={'lg'}
onClick={() => void router.push(`/code/${modalData.matchId}`)}
onClick={() => void router.push(`/code/${encodeStr(modalData.matchId)}`)}
>
Proceed to coding session
</Button>
Expand Down
9 changes: 7 additions & 2 deletions frontend/components/dashboard/resume-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Button } from '../ui/button'
import { IMatch } from '@repo/user-types'
import { convertSortedComplexityToComplexity } from '@repo/question-types'
import { capitalizeFirstLowerRest } from '@/util/string-modification'
import { encodeStr } from '@/util/encryption'
import { toast } from 'sonner'

interface IResumeSessionProps {
match: IMatch
Expand All @@ -18,8 +20,11 @@ export default function ResumeSession({ match, isOngoing }: IResumeSessionProps)
try {
const ongoing = await isOngoing()
if (!ongoing) return
router.push(`/code/${match.id}`)
} catch (error) {}
const encodedId = encodeStr(match.id)
router.push(`/code/${encodedId}`)
} catch (error) {
toast.error('Unable to resume session due to a server error')
}
}

return (
Expand Down
4 changes: 2 additions & 2 deletions frontend/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { cva, type 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 transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-gray-300 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
Expand All @@ -16,7 +16,7 @@ const buttonVariants = cva(
link: 'text-primary underline-offset-4 hover:underline',
icon: 'bg-transparent border-[1px] rounded-xl hover:bg-btn-secondaryHover',
iconNoBorder: 'hover:bg-btn-hover',
primary: 'bg-theme-600 hover:bg-theme-700 text-primary-foreground',
primary: 'bg-theme-600 hover:bg-theme-700 text-primary-foreground focus-visible:ring-gray-500',
activeTab:
'text-foreground bg-transparent hover:bg-btn-hover rounded-b-none border-b-2 border-theme-600',
ghostTab: 'text-foreground bg-transparent hover:bg-btn-hover rounded-b-none',
Expand Down
4 changes: 2 additions & 2 deletions frontend/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const DialogOverlay = React.forwardRef<
<DialogPrimitive.Overlay
ref={ref}
className={cn(
'fixed inset-0 z-50 bg-slate-200/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
'fixed inset-0 z-[995] bg-slate-200/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
className
)}
{...props}
Expand All @@ -38,7 +38,7 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-3xl translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-7 px-10 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
'fixed left-[50%] top-[50%] z-[995] grid w-full max-w-3xl translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-7 px-10 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
'flex flex-grow flex-col h-1/4 bg-white bg-opacity-100',
className
)}
Expand Down
10 changes: 7 additions & 3 deletions frontend/pages/code/[id]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { getChatHistory, getCollabHistory } from '@/services/collaboration-servi
import ReadOnlyCodeMirrorEditor from '../read-only-editor'
import { ResultModel } from '@repo/collaboration-types'
import { capitalizeFirstLowerRest } from '@/util/string-modification'
import { decodeStr } from '@/util/encryption'

const formatQuestionCategories = (cat: Category[]) => {
return cat.map((c) => capitalizeFirstLowerRest(c)).join(', ')
Expand All @@ -40,7 +41,7 @@ const formatQuestionCategories = (cat: Category[]) => {
export default function Code() {
const router = useRouter()
const [isChatOpen, setIsChatOpen] = useState(true)
const { id } = router.query
const [id, setId] = useState(router.query.id as string)
const editorRef = useRef<{ getText: () => string } | null>(null)
const [editorLanguage, setEditorLanguage] = useState<LanguageMode>(LanguageMode.Javascript)
const testTabs = ['Testcases', 'Test Results']
Expand Down Expand Up @@ -81,8 +82,10 @@ export default function Code() {
const { data: sessionData } = useSession()

useEffect(() => {
const matchId = router.query.id as string
const encodedId = router.query.id as string
const matchId = decodeStr(encodedId)
retrieveMatchDetails(matchId)
setId(matchId)
}, [router.query.id, retry])

useEffect(() => {
Expand Down Expand Up @@ -136,6 +139,7 @@ export default function Code() {
socketRef.current.on('disconnect', () => {
if (!isViewOnly) {
router.push('/')
toast.info('The session has ended')
}
})

Expand Down Expand Up @@ -201,7 +205,7 @@ export default function Code() {

function handleEndSessionConfirmation() {
if (socketRef.current) {
socketRef.current?.emit('end-session')
socketRef.current.emit('end-session')
router.push('/')
}
setIsDialogOpen(false)
Expand Down
6 changes: 2 additions & 4 deletions frontend/pages/questions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,8 @@ export default function Questions() {
} else if (modificationType === Modification.DELETE) {
if (!questionData.id) return
try {
const res = await deleteQuestionById(questionData.id)
if (res) {
toast.success('Question deleted successfully')
}
await deleteQuestionById(questionData.id)
toast.success('Question deleted successfully')
} catch (error) {
toast.error('Failed to delete question' + error)
return
Expand Down
3 changes: 0 additions & 3 deletions frontend/pages/questions/props.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ const getColumns = (isAdmin: boolean): IDatatableColumn[] => {
},
{
key: 'title',
width: '30%',
offAutoCapitalize: true,
},
{
key: 'categories',
width: '40%',
formatter: (values) => {
const c = values.map((v: string) => (
<CustomLabel
Expand Down Expand Up @@ -72,7 +70,6 @@ const getColumns = (isAdmin: boolean): IDatatableColumn[] => {
},
{
key: 'complexity',
width: '10%',
isSortable: true,
formatter: (value) => {
return <DifficultyLabel complexity={value} />
Expand Down
4 changes: 3 additions & 1 deletion frontend/pages/sessions/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DifficultyLabel } from '@/components/customs/difficulty-label'
import { Button } from '@/components/ui/button'
import CustomLabel from '@/components/ui/label'
import { IDatatableColumn, IRowData } from '@/types'
import { encodeStr } from '@/util/encryption'
import { capitalizeFirstLowerRest } from '@/util/string-modification'
import { EyeIcon } from 'lucide-react'
import { NextRouter } from 'next/router'
Expand Down Expand Up @@ -77,7 +78,8 @@ export const columns: IDatatableColumn[] = [
variant="iconNoBorder"
size="icon"
onClick={() => {
router.push(`/code/${elem._id}`)
const encoded = encodeStr(elem._id)
router.push(`/code/${encoded}`)
}}
>
{elem.isCompleted ? <EyeIcon /> : <PlayIcon />}
Expand Down
4 changes: 3 additions & 1 deletion frontend/pages/sessions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Button } from '@/components/ui/button'
import ConfirmDialog, { ConfirmDialogProps } from '@/components/customs/confirm-dialog'
import { getOngoingMatch } from '@/services/matching-service-api'
import { useRouter } from 'next/router'
import { encodeStr } from '@/util/encryption'

export default function Sessions() {
const router = useRouter()
Expand Down Expand Up @@ -111,7 +112,8 @@ export default function Sessions() {
if (!session?.user?.id) return
const matchData = await getOngoingMatch(session.user.id)
if (matchData) {
router.push(`/code/${matchData.id}`)
const encodedId = encodeStr(matchData.id)
router.push(`/code/${encodedId}`)
} else {
setDialog((prev) => ({ ...prev, dialogData: { ...prev.dialogData, isOpen: true } }))
}
Expand Down
8 changes: 8 additions & 0 deletions frontend/util/encryption.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const encodeStr = (str: string) => {
return btoa(str)
}

export const decodeStr = (encoded: string) => {
if (!encoded) return ''
return atob(encoded)
}

0 comments on commit 0dc80cd

Please sign in to comment.