Improved the responsiveness of the application for tablet as well
This commit is contained in:
@@ -37,7 +37,7 @@ export default function Layout({user, children, className, navDisabled = false,
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"w-full min-h-full h-fit md:mr-8 bg-white shadow-md rounded-2xl p-4 md:p-12 pb-8 flex flex-col gap-8 md:gap-12 relative overflow-hidden mt-2",
|
"w-full min-h-full h-fit md:mr-8 bg-white shadow-md rounded-2xl p-4 xl:p-12 pb-8 flex flex-col gap-8 md:gap-12 relative overflow-hidden mt-2",
|
||||||
className,
|
className,
|
||||||
)}>
|
)}>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -6,12 +7,13 @@ interface Props {
|
|||||||
label?: string;
|
label?: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
defaultValue?: string;
|
defaultValue?: string;
|
||||||
|
className?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
onChange: (value: string) => void;
|
onChange: (value: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Input({type, label, placeholder, name, required = false, defaultValue, disabled = false, onChange}: Props) {
|
export default function Input({type, label, placeholder, name, required = false, defaultValue, className, disabled = false, onChange}: Props) {
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
if (type === "password") {
|
if (type === "password") {
|
||||||
@@ -44,7 +46,7 @@ export default function Input({type, label, placeholder, name, required = false,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3 w-full">
|
<div className={clsx("flex flex-col gap-3 w-full", className)}>
|
||||||
{label && (
|
{label && (
|
||||||
<label className="font-normal text-base text-mti-gray-dim">
|
<label className="font-normal text-base text-mti-gray-dim">
|
||||||
{label}
|
{label}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const Nav = ({Icon, label, path, keyPath, disabled = false, isMinimized = false}
|
|||||||
"p-4 rounded-full flex gap-4 items-center cursor-pointer text-gray-500 hover:bg-mti-purple-light hover:text-white",
|
"p-4 rounded-full flex gap-4 items-center cursor-pointer text-gray-500 hover:bg-mti-purple-light hover:text-white",
|
||||||
"transition-all duration-300 ease-in-out",
|
"transition-all duration-300 ease-in-out",
|
||||||
path === keyPath && "bg-mti-purple-light text-white",
|
path === keyPath && "bg-mti-purple-light text-white",
|
||||||
isMinimized ? "w-fit" : "w-full min-w-[220px] px-8",
|
isMinimized ? "w-fit" : "w-full min-w-[200px] 2xl:min-w-[220px] px-8",
|
||||||
)}>
|
)}>
|
||||||
<Icon size={24} />
|
<Icon size={24} />
|
||||||
{!isMinimized && <span className="text-lg font-semibold">{label}</span>}
|
{!isMinimized && <span className="text-lg font-semibold">{label}</span>}
|
||||||
@@ -61,10 +61,10 @@ export default function Sidebar({path, navDisabled = false, focusMode = false, s
|
|||||||
<section
|
<section
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"h-full flex bg-transparent flex-col justify-between px-4 py-4 pb-8 relative",
|
"h-full flex bg-transparent flex-col justify-between px-4 py-4 pb-8 relative",
|
||||||
isMinimized ? "w-fit" : "w-1/6",
|
isMinimized ? "w-fit" : "w-1/6 -xl:w-fit",
|
||||||
className,
|
className,
|
||||||
)}>
|
)}>
|
||||||
<div className="flex flex-col gap-3">
|
<div className="xl:flex -xl:hidden flex-col gap-3">
|
||||||
<Nav disabled={disableNavigation} Icon={MdSpaceDashboard} label="Dashboard" path={path} keyPath="/" isMinimized={isMinimized} />
|
<Nav disabled={disableNavigation} Icon={MdSpaceDashboard} label="Dashboard" path={path} keyPath="/" isMinimized={isMinimized} />
|
||||||
<Nav disabled={disableNavigation} Icon={BsFileEarmarkText} label="Exams" path={path} keyPath="/exam" isMinimized={isMinimized} />
|
<Nav disabled={disableNavigation} Icon={BsFileEarmarkText} label="Exams" path={path} keyPath="/exam" isMinimized={isMinimized} />
|
||||||
<Nav disabled={disableNavigation} Icon={BsPencil} label="Exercises" path={path} keyPath="/exercises" isMinimized={isMinimized} />
|
<Nav disabled={disableNavigation} Icon={BsPencil} label="Exercises" path={path} keyPath="/exercises" isMinimized={isMinimized} />
|
||||||
@@ -74,6 +74,14 @@ export default function Sidebar({path, navDisabled = false, focusMode = false, s
|
|||||||
<Nav disabled={disableNavigation} Icon={BsShieldFill} label="Admin" path={path} keyPath="/admin" isMinimized={isMinimized} />
|
<Nav disabled={disableNavigation} Icon={BsShieldFill} label="Admin" path={path} keyPath="/admin" isMinimized={isMinimized} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="xl:hidden -xl:flex flex-col gap-3">
|
||||||
|
<Nav disabled={disableNavigation} Icon={MdSpaceDashboard} label="Dashboard" path={path} keyPath="/" isMinimized={true} />
|
||||||
|
<Nav disabled={disableNavigation} Icon={BsFileEarmarkText} label="Exams" path={path} keyPath="/exam" isMinimized={true} />
|
||||||
|
<Nav disabled={disableNavigation} Icon={BsPencil} label="Exercises" path={path} keyPath="/exercises" isMinimized={true} />
|
||||||
|
<Nav disabled={disableNavigation} Icon={BsGraphUp} label="Stats" path={path} keyPath="/stats" isMinimized={true} />
|
||||||
|
<Nav disabled={disableNavigation} Icon={BsClockHistory} label="Record" path={path} keyPath="/record" isMinimized={true} />
|
||||||
|
{showAdmin && <Nav disabled={disableNavigation} Icon={BsShieldFill} label="Admin" path={path} keyPath="/admin" isMinimized={true} />}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col gap-0 absolute bottom-12">
|
<div className="flex flex-col gap-0 absolute bottom-12">
|
||||||
<div
|
<div
|
||||||
@@ -81,7 +89,7 @@ export default function Sidebar({path, navDisabled = false, focusMode = false, s
|
|||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
onClick={toggleMinimize}
|
onClick={toggleMinimize}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"p-4 rounded-full flex gap-4 items-center cursor-pointer text-black hover:text-mti-rose transition duration-300 ease-in-out",
|
"p-4 rounded-full flex gap-4 items-center cursor-pointer text-black hover:text-mti-rose -xl:hidden transition duration-300 ease-in-out",
|
||||||
isMinimized ? "w-fit" : "w-full min-w-[250px] px-8",
|
isMinimized ? "w-fit" : "w-full min-w-[250px] px-8",
|
||||||
)}>
|
)}>
|
||||||
{isMinimized ? <BsChevronBarRight size={24} /> : <BsChevronBarLeft size={24} />}
|
{isMinimized ? <BsChevronBarRight size={24} /> : <BsChevronBarLeft size={24} />}
|
||||||
@@ -96,7 +104,7 @@ export default function Sidebar({path, navDisabled = false, focusMode = false, s
|
|||||||
isMinimized ? "w-fit" : "w-full min-w-[250px] px-8",
|
isMinimized ? "w-fit" : "w-full min-w-[250px] px-8",
|
||||||
)}>
|
)}>
|
||||||
<RiLogoutBoxFill size={24} />
|
<RiLogoutBoxFill size={24} />
|
||||||
{!isMinimized && <span className="text-lg font-medium">Log Out</span>}
|
{!isMinimized && <span className="text-lg font-medium -xl:hidden">Log Out</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{focusMode && <FocusLayer onFocusLayerMouseEnter={onFocusLayerMouseEnter} />}
|
{focusMode && <FocusLayer onFocusLayerMouseEnter={onFocusLayerMouseEnter} />}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export default function BatchCodeGenerator({user}: {user: User}) {
|
|||||||
</Button>
|
</Button>
|
||||||
{user && (user.type === "developer" || user.type === "owner") && (
|
{user && (user.type === "developer" || user.type === "owner") && (
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex -md:flex-row md:flex-col -md:items-center 2xl:flex-row 2xl:items-center justify-between gap-2">
|
||||||
<label className="font-normal text-base text-mti-gray-dim">Expiry Date</label>
|
<label className="font-normal text-base text-mti-gray-dim">Expiry Date</label>
|
||||||
<Checkbox isChecked={isExpiryDateEnabled} onChange={setIsExpiryDateEnabled}>
|
<Checkbox isChecked={isExpiryDateEnabled} onChange={setIsExpiryDateEnabled}>
|
||||||
Enabled
|
Enabled
|
||||||
@@ -108,30 +108,30 @@ export default function BatchCodeGenerator({user}: {user: User}) {
|
|||||||
)}
|
)}
|
||||||
<label className="font-normal text-base text-mti-gray-dim">Select the type of user they should be</label>
|
<label className="font-normal text-base text-mti-gray-dim">Select the type of user they should be</label>
|
||||||
{user && (
|
{user && (
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid -md:grid-cols-2 md:grid-cols-1 xl:grid-cols-2 gap-4 place-items-center">
|
||||||
<Button
|
<Button
|
||||||
className="w-44 md:w-48"
|
className="w-44 2xl:w-48"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => generateCode("student")}
|
onClick={() => generateCode("student")}
|
||||||
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.student.includes(user.type)}>
|
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.student.includes(user.type)}>
|
||||||
Student
|
Student
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className="w-44 md:w-48"
|
className="w-44 2xl:w-48"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => generateCode("teacher")}
|
onClick={() => generateCode("teacher")}
|
||||||
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.teacher.includes(user.type)}>
|
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.teacher.includes(user.type)}>
|
||||||
Teacher
|
Teacher
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className="w-44 md:w-48"
|
className="w-44 2xl:w-48"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => generateCode("admin")}
|
onClick={() => generateCode("admin")}
|
||||||
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.admin.includes(user.type)}>
|
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.admin.includes(user.type)}>
|
||||||
Admin
|
Admin
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className="w-44 md:w-48"
|
className="w-44 2xl:w-48"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => generateCode("owner")}
|
onClick={() => generateCode("owner")}
|
||||||
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.owner.includes(user.type)}>
|
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.owner.includes(user.type)}>
|
||||||
|
|||||||
@@ -57,30 +57,30 @@ export default function CodeGenerator({user}: {user: User}) {
|
|||||||
<div className="flex flex-col gap-4 border p-4 border-mti-gray-platinum rounded-xl">
|
<div className="flex flex-col gap-4 border p-4 border-mti-gray-platinum rounded-xl">
|
||||||
<label className="font-normal text-base text-mti-gray-dim">User Code Generator</label>
|
<label className="font-normal text-base text-mti-gray-dim">User Code Generator</label>
|
||||||
{user && (
|
{user && (
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid -md:grid-cols-2 md:grid-cols-1 place-items-center 2xl:grid-cols-2 gap-4">
|
||||||
<Button
|
<Button
|
||||||
className="w-44 md:w-48"
|
className="w-44 2xl:w-48"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => generateCode("student")}
|
onClick={() => generateCode("student")}
|
||||||
disabled={!PERMISSIONS.generateCode.student.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
disabled={!PERMISSIONS.generateCode.student.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
||||||
Student
|
Student
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className="w-44 md:w-48"
|
className="w-44 2xl:w-48"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => generateCode("teacher")}
|
onClick={() => generateCode("teacher")}
|
||||||
disabled={!PERMISSIONS.generateCode.teacher.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
disabled={!PERMISSIONS.generateCode.teacher.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
||||||
Teacher
|
Teacher
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className="w-44 md:w-48"
|
className="w-44 2xl:w-48"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => generateCode("admin")}
|
onClick={() => generateCode("admin")}
|
||||||
disabled={!PERMISSIONS.generateCode.admin.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
disabled={!PERMISSIONS.generateCode.admin.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
||||||
Admin
|
Admin
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className="w-44 md:w-48"
|
className="w-44 2xl:w-48"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => generateCode("owner")}
|
onClick={() => generateCode("owner")}
|
||||||
disabled={!PERMISSIONS.generateCode.owner.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
disabled={!PERMISSIONS.generateCode.owner.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
||||||
@@ -90,7 +90,7 @@ export default function CodeGenerator({user}: {user: User}) {
|
|||||||
)}
|
)}
|
||||||
{user && (user.type === "developer" || user.type === "owner") && (
|
{user && (user.type === "developer" || user.type === "owner") && (
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex -md:flex-row md:flex-col -md:items-center 2xl:flex-row 2xl:items-center justify-between gap-2">
|
||||||
<label className="font-normal text-base text-mti-gray-dim">Expiry Date</label>
|
<label className="font-normal text-base text-mti-gray-dim">Expiry Date</label>
|
||||||
<Checkbox isChecked={isExpiryDateEnabled} onChange={setIsExpiryDateEnabled}>
|
<Checkbox isChecked={isExpiryDateEnabled} onChange={setIsExpiryDateEnabled}>
|
||||||
Enabled
|
Enabled
|
||||||
|
|||||||
@@ -49,13 +49,16 @@ export default function ExamLoader() {
|
|||||||
<div className="flex flex-col gap-4 border p-4 border-mti-gray-platinum rounded-xl">
|
<div className="flex flex-col gap-4 border p-4 border-mti-gray-platinum rounded-xl">
|
||||||
<label className="font-normal text-base text-mti-gray-dim">Exam Loader</label>
|
<label className="font-normal text-base text-mti-gray-dim">Exam Loader</label>
|
||||||
<form className="flex flex-col gap-4 w-full" onSubmit={loadExam}>
|
<form className="flex flex-col gap-4 w-full" onSubmit={loadExam}>
|
||||||
<RadioGroup value={selectedModule} onChange={setSelectedModule} className="grid grid-cols-2 items-center gap-4 place-items-center">
|
<RadioGroup
|
||||||
|
value={selectedModule}
|
||||||
|
onChange={setSelectedModule}
|
||||||
|
className="grid -md:grid-cols-2 md:grid-cols-1 xl:grid-cols-2 items-center gap-4 place-items-center">
|
||||||
{MODULE_ARRAY.map((module) => (
|
{MODULE_ARRAY.map((module) => (
|
||||||
<RadioGroup.Option value={module} key={module}>
|
<RadioGroup.Option value={module} key={module}>
|
||||||
{({checked}) => (
|
{({checked}) => (
|
||||||
<span
|
<span
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"px-6 py-4 w-44 md:w-48 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
|
"px-6 py-4 w-44 2xl:w-48 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
|
||||||
"hover:bg-mti-purple-light hover:border-mti-purple-dark hover:text-white",
|
"hover:bg-mti-purple-light hover:border-mti-purple-dark hover:text-white",
|
||||||
"transition duration-300 ease-in-out",
|
"transition duration-300 ease-in-out",
|
||||||
!checked ? "bg-white border-mti-gray-platinum" : "bg-mti-purple-light border-mti-purple-dark text-white",
|
!checked ? "bg-white border-mti-gray-platinum" : "bg-mti-purple-light border-mti-purple-dark text-white",
|
||||||
@@ -66,8 +69,8 @@ export default function ExamLoader() {
|
|||||||
</RadioGroup.Option>
|
</RadioGroup.Option>
|
||||||
))}
|
))}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<Input type="text" name="examId" onChange={setExamId} placeholder="Exam ID" />
|
<Input type="text" name="examId" onChange={setExamId} placeholder="Exam ID" className="-md:!w-full md:!w-44 2xl:!w-full" />
|
||||||
<Button disabled={!selectedModule || !examId} isLoading={isLoading}>
|
<Button disabled={!selectedModule || !examId} isLoading={isLoading} className="-md:!w-full md:!w-44 2xl:!w-full">
|
||||||
Load Exam
|
Load Exam
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export default function Admin() {
|
|||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
{user && (
|
{user && (
|
||||||
<Layout user={user} className="gap-6">
|
<Layout user={user} className="gap-6">
|
||||||
<section className="w-full flex -md:flex-col gap-8 justify-between">
|
<section className="w-full flex -md:flex-col -xl:gap-2 gap-8 justify-between">
|
||||||
<ExamLoader />
|
<ExamLoader />
|
||||||
<CodeGenerator user={user} />
|
<CodeGenerator user={user} />
|
||||||
<BatchCodeGenerator user={user} />
|
<BatchCodeGenerator user={user} />
|
||||||
|
|||||||
@@ -176,12 +176,13 @@ export default function History({user}: {user: User}) {
|
|||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<>
|
<>
|
||||||
<div className="w-full flex justify-between items-center">
|
<div className="w-full flex justify-between -md:items-center 2xl:items-center">
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex md:flex-col 2xl:flex-row md:gap-1 -md:gap-2 2xl:gap-2 -md:items-center 2xl:items-center">
|
||||||
<span className="font-medium">{formatTimestamp(timestamp)}</span>
|
<span className="font-medium">{formatTimestamp(timestamp)}</span>
|
||||||
{timeSpent && (
|
{timeSpent && (
|
||||||
<>
|
<>
|
||||||
• <span className="text-sm">{Math.floor(timeSpent / 60)} minutes</span>
|
<span className="md:hidden 2xl:flex">• </span>
|
||||||
|
<span className="text-sm">{Math.floor(timeSpent / 60)} minutes</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -195,12 +196,12 @@ export default function History({user}: {user: User}) {
|
|||||||
{(aggregatedLevels.reduce((accumulator, current) => accumulator + current.level, 0) / aggregatedLevels.length).toFixed(1)}
|
{(aggregatedLevels.reduce((accumulator, current) => accumulator + current.level, 0) / aggregatedLevels.length).toFixed(1)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-4 gap-4 place-items-center w-full">
|
<div className="grid grid-cols-4 gap-2 place-items-start w-full -md:mt-2">
|
||||||
{aggregatedLevels.map(({module, level}) => (
|
{aggregatedLevels.map(({module, level}) => (
|
||||||
<div
|
<div
|
||||||
key={module}
|
key={module}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"flex gap-2 items-center w-fit text-white px-4 py-2 rounded-xl",
|
"flex gap-2 items-center w-fit text-white -md:px-4 xl:px-4 md:px-2 py-2 rounded-xl",
|
||||||
module === "reading" && "bg-ielts-reading",
|
module === "reading" && "bg-ielts-reading",
|
||||||
module === "listening" && "bg-ielts-listening",
|
module === "listening" && "bg-ielts-listening",
|
||||||
module === "writing" && "bg-ielts-writing",
|
module === "writing" && "bg-ielts-writing",
|
||||||
@@ -261,8 +262,8 @@ export default function History({user}: {user: User}) {
|
|||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
{user && (
|
{user && (
|
||||||
<Layout user={user}>
|
<Layout user={user}>
|
||||||
<div className="w-full flex -md:flex-col -md:gap-4 justify-between items-center">
|
<div className="w-full flex -xl:flex-col -xl:gap-4 justify-between items-center">
|
||||||
<div className="md:w-3/4">
|
<div className="xl:w-3/4">
|
||||||
{(user.type === "developer" || user.type === "owner") && (
|
{(user.type === "developer" || user.type === "owner") && (
|
||||||
<Select
|
<Select
|
||||||
options={users.map((x) => ({value: x.id, label: `${x.name} - ${x.email}`}))}
|
options={users.map((x) => ({value: x.id, label: `${x.name} - ${x.email}`}))}
|
||||||
@@ -294,7 +295,7 @@ export default function History({user}: {user: User}) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-4 w-full -md:justify-center md:justify-end">
|
<div className="flex gap-4 w-full justify-center xl:justify-end">
|
||||||
<button
|
<button
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"bg-mti-purple-ultralight text-mti-purple px-4 py-2 rounded-full hover:text-white hover:bg-mti-purple-light",
|
"bg-mti-purple-ultralight text-mti-purple px-4 py-2 rounded-full hover:text-white hover:bg-mti-purple-light",
|
||||||
@@ -325,7 +326,7 @@ export default function History({user}: {user: User}) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{groupedStats && Object.keys(groupedStats).length > 0 && !isStatsLoading && (
|
{groupedStats && Object.keys(groupedStats).length > 0 && !isStatsLoading && (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 w-full gap-4 md:gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 w-full gap-4 xl:gap-6">
|
||||||
{Object.keys(filterStatsByDate(groupedStats))
|
{Object.keys(filterStatsByDate(groupedStats))
|
||||||
.sort((a, b) => parseInt(b) - parseInt(a))
|
.sort((a, b) => parseInt(b) - parseInt(a))
|
||||||
.map(customContent)}
|
.map(customContent)}
|
||||||
|
|||||||
Reference in New Issue
Block a user