feat: add mobile dashboard menu, make dashboard pages responsive

This commit is contained in:
swve 2024-10-23 12:03:45 +02:00
parent 56d2007181
commit 3014817d95
13 changed files with 416 additions and 340 deletions

View file

@ -1,8 +1,10 @@
'use client';
import LeftMenu from '@components/Dashboard/UI/LeftMenu'
import DashLeftMenu from '@components/Dashboard/UI/DashLeftMenu'
import DashMobileMenu from '@components/Dashboard/UI/DashMobileMenu'
import AdminAuthorization from '@components/Security/AdminAuthorization'
import { SessionProvider } from 'next-auth/react'
import React from 'react'
import React, { useState, useEffect } from 'react'
import { useMediaQuery } from 'usehooks-ts';
function ClientAdminLayout({
children,
@ -11,11 +13,17 @@ function ClientAdminLayout({
children: React.ReactNode
params: any
}) {
const isMobile = useMediaQuery('(max-width: 768px)')
return (
<SessionProvider>
<AdminAuthorization authorizationMode="page">
<div className="flex">
<LeftMenu />
<div className="flex flex-col md:flex-row">
{isMobile ? (
<DashMobileMenu />
) : (
<DashLeftMenu />
)}
<div className="flex w-full">{children}</div>
</div>
</AdminAuthorization>
@ -23,4 +31,4 @@ function ClientAdminLayout({
)
}
export default ClientAdminLayout
export default ClientAdminLayout

View file

@ -1,6 +1,6 @@
'use client';
import BreadCrumbs from '@components/Dashboard/UI/BreadCrumbs'
import { BookOpen, BookX, EllipsisVertical, Eye, Layers2, UserRoundPen } from 'lucide-react'
import { BookOpen, BookX, EllipsisVertical, Eye, Layers2, Monitor, UserRoundPen } from 'lucide-react'
import React, { useEffect } from 'react'
import { AssignmentProvider, useAssignments } from '@components/Contexts/Assignments/AssignmentContext';
import ToolTip from '@components/StyledElements/Tooltip/Tooltip';
@ -15,12 +15,29 @@ import { updateActivity } from '@services/courses/activities';
// Lazy Loading
import dynamic from 'next/dynamic';
import AssignmentEditorSubPage from './subpages/AssignmentEditorSubPage';
import { useMediaQuery } from 'usehooks-ts';
const AssignmentSubmissionsSubPage = dynamic(() => import('./subpages/AssignmentSubmissionsSubPage'))
function AssignmentEdit() {
const params = useParams<{ assignmentuuid: string; }>()
const searchParams = useSearchParams()
const [selectedSubPage, setSelectedSubPage] = React.useState(searchParams.get('subpage') || 'editor')
const isMobile = useMediaQuery('(max-width: 767px)')
if (isMobile) {
// TODO: Work on a better mobile experience
return (
<div className="h-screen w-full bg-[#f8f8f8] flex items-center justify-center p-4">
<div className="bg-white p-6 rounded-lg shadow-md text-center">
<h2 className="text-xl font-bold mb-4">Desktop Only</h2>
<Monitor className='mx-auto my-5' size={60} />
<p>This page is only accessible from a desktop device.</p>
<p>Please switch to a desktop to view and manage the assignment.</p>
</div>
</div>
)
}
return (
<div className='flex w-full flex-col'>
<AssignmentProvider assignment_uuid={'assignment_' + params.assignmentuuid}>

View file

@ -46,19 +46,19 @@ function AssignmentsHome() {
return (
<div className='flex w-full'>
<div className='pl-10 mr-10 tracking-tighter flex flex-col space-y-5 w-full'>
<div className='pl-4 sm:pl-10 mr-4 sm:mr-10 tracking-tighter flex flex-col space-y-5 w-full'>
<div className='flex flex-col space-y-2'>
<BreadCrumbs type="assignments" />
<h1 className="pt-3 flex font-bold text-4xl">Assignments</h1>
</div>
<div className='flex flex-col space-y-3 w-full'>
{courseAssignments.map((assignments: any, index: number) => (
<div key={index} className='flex flex-col space-y-2 bg-white nice-shadow p-4 rounded-xl w-full'>
<div key={index} className='flex flex-col space-y-2 bg-white nice-shadow p-3 sm:p-4 rounded-xl w-full'>
<div>
<div className='flex space-x-2 items-center justify-between w-full'>
<div className='flex flex-col sm:flex-row space-y-2 sm:space-y-0 sm:space-x-2 items-start sm:items-center justify-between w-full'>
<div className='flex space-x-2 items-center'>
<MiniThumbnail course={courses[index]} />
<div className='flex flex-col font-bold text-lg '>
<div className='flex flex-col font-bold text-lg'>
<p className='bg-gray-200 text-gray-700 px-2 text-xs py-0.5 rounded-full w-fit'>Course</p>
<p>{courses[index].name}</p>
</div>
@ -75,10 +75,9 @@ function AssignmentsHome() {
</Link>
</div>
{assignments && assignments.map((assignment: any) => (
<div key={assignment.assignment_uuid} className='flex mt-3 p-3 rounded flex-row space-x-2 w-full light-shadow justify-between bg-gray-50 items-center'>
<div className='flex flex-row items-center space-x-2 '>
<div key={assignment.assignment_uuid} className='flex mt-3 p-2 sm:p-3 rounded flex-col sm:flex-row space-y-2 sm:space-y-0 sm:space-x-2 w-full light-shadow justify-between bg-gray-50 items-start sm:items-center'>
<div className='flex flex-col sm:flex-row items-start sm:items-center space-y-1 sm:space-y-0 sm:space-x-2'>
<div className='flex text-xs font-bold bg-gray-200 text-gray-700 px-2 py-0.5 rounded-full h-fit'>
<p>Assignment</p>
</div>
@ -86,7 +85,6 @@ function AssignmentsHome() {
<div className='flex font-semibold text-gray-600 px-2 py-0.5 rounded outline outline-gray-200/70'>{assignment.description}</div>
</div>
<div className='flex space-x-2 font-bold text-sm items-center'>
<EllipsisVertical className='text-gray-500' size={17} />
<Link
href={{
@ -103,7 +101,6 @@ function AssignmentsHome() {
pathname: getUriWithOrg(org.slug, `/dash/assignments/${removeAssignmentPrefix(assignment.assignment_uuid)}`),
query: { subpage: 'submissions' }
}}
prefetch
className='bg-white rounded-full flex space-x-2 nice-shadow items-center px-3 py-0.5'>
<UserRoundPen size={15} />
@ -124,10 +121,8 @@ function AssignmentsHome() {
</div>
</div>
))}
</div>
</div>
</div>
)
}
@ -172,4 +167,4 @@ const MiniThumbnail = (props: { course: any }) => {
}
export default AssignmentsHome
export default AssignmentsHome

View file

@ -7,84 +7,68 @@ import AdminAuthorization from '@components/Security/AdminAuthorization'
function DashboardHome() {
return (
<div className="flex items-center justify-center mx-auto min-h-screen flex-col space-x-3">
<div className="mx-auto pb-10">
<div className="flex items-center justify-center mx-auto min-h-screen flex-col p-4 sm:mb-0 mb-16">
<div className="mx-auto pb-6 sm:pb-10">
<Image
alt="learnhouse logo"
width={230}
src={learnhousetextlogo}
></Image>
className="w-48 sm:w-auto"
/>
</div>
<AdminAuthorization authorizationMode="component">
<div className="flex space-x-10">
<Link
href={`/dash/courses`}
className="flex bg-white shadow-lg p-[35px] w-[250px] rounded-lg items-center mx-auto hover:scale-105 transition-all ease-linear cursor-pointer"
>
<div className="flex flex-col mx-auto space-y-2">
<BookCopy className="mx-auto text-gray-500" size={50}></BookCopy>
<div className="text-center font-bold text-gray-500">Courses</div>
<p className="text-center text-sm text-gray-400">
Create and manage courses, chapters and ativities{' '}
</p>
</div>
</Link>
<Link
href={`/dash/org/settings/general`}
className="flex bg-white shadow-lg p-[35px] w-[250px] rounded-lg items-center mx-auto hover:scale-105 transition-all ease-linear cursor-pointer"
>
<div className="flex flex-col mx-auto space-y-2">
<School className="mx-auto text-gray-500" size={50}></School>
<div className="text-center font-bold text-gray-500">
Organization
</div>
<p className="text-center text-sm text-gray-400">
Configure your Organization general settings{' '}
</p>
</div>
</Link>
<Link
href={`/dash/users/settings/users`}
className="flex bg-white shadow-lg p-[35px] w-[250px] rounded-lg items-center mx-auto hover:scale-105 transition-all ease-linear cursor-pointer"
>
<div className="flex flex-col mx-auto space-y-2">
<Users className="mx-auto text-gray-500" size={50}></Users>
<div className="text-center font-bold text-gray-500">Users</div>
<p className="text-center text-sm text-gray-400">
Manage your Organization's users, roles{' '}
</p>
</div>
</Link>
<div className="flex flex-col sm:flex-row space-y-4 sm:space-y-0 sm:space-x-4 lg:space-x-10">
{/* Card components */}
<DashboardCard
href="/dash/courses"
icon={<BookCopy className="mx-auto text-gray-500" size={50} />}
title="Courses"
description="Create and manage courses, chapters and activities"
/>
<DashboardCard
href="/dash/org/settings/general"
icon={<School className="mx-auto text-gray-500" size={50} />}
title="Organization"
description="Configure your Organization general settings"
/>
<DashboardCard
href="/dash/users/settings/users"
icon={<Users className="mx-auto text-gray-500" size={50} />}
title="Users"
description="Manage your Organization's users, roles"
/>
</div>
</AdminAuthorization>
<div className="flex flex-col space-y-10 ">
<div className="flex flex-col space-y-6 sm:space-y-10 mt-6 sm:mt-10">
<AdminAuthorization authorizationMode="component">
<div className="h-1 w-[100px] bg-neutral-200 rounded-full mx-auto"></div>
<div className="flex justify-center items-center">
<Link
href={'https://university.learnhouse.io/'}
target='_blank'
className="flex mt-[40px] bg-black space-x-2 items-center py-3 px-7 rounded-lg shadow-lg hover:scale-105 transition-all ease-linear cursor-pointer"
className="flex mt-4 sm:mt-[40px] bg-black space-x-2 items-center py-3 px-7 rounded-lg shadow-lg hover:scale-105 transition-all ease-linear cursor-pointer"
>
<University className=" text-gray-100" size={20}></University>
<div className=" text-sm font-bold text-gray-100">
<University className="text-gray-100" size={20} />
<div className="text-sm font-bold text-gray-100">
LearnHouse University
</div>
</Link>
</div>
<div className="mx-auto mt-[40px] w-28 h-1 bg-neutral-200 rounded-full"></div>
<div className="mx-auto mt-4 sm:mt-[40px] w-28 h-1 bg-neutral-200 rounded-full"></div>
</AdminAuthorization>
<Link
href={'/dash/user-account/settings/general'}
className="flex bg-white shadow-lg p-[15px] items-center rounded-lg mx-auto hover:scale-105 transition-all ease-linear cursor-pointer"
className="flex bg-white shadow-lg p-4 items-center rounded-lg mx-auto hover:scale-105 transition-all ease-linear cursor-pointer max-w-md"
>
<div className="flex flex-row mx-auto space-x-3 items-center">
<Settings className=" text-gray-500" size={20}></Settings>
<div className=" font-bold text-gray-500">Account Settings</div>
<p className=" text-sm text-gray-400">
Configure your personal settings, passwords, email
</p>
<div className="flex flex-col sm:flex-row mx-auto space-y-2 sm:space-y-0 sm:space-x-3 items-center text-center sm:text-left">
<Settings className="text-gray-500" size={20} />
<div>
<div className="font-bold text-gray-500">Account Settings</div>
<p className="text-sm text-gray-400">
Configure your personal settings, passwords, email
</p>
</div>
</div>
</Link>
</div>
@ -92,4 +76,20 @@ function DashboardHome() {
)
}
// New component for dashboard cards
function DashboardCard({ href, icon, title, description }: { href: string, icon: React.ReactNode, title: string, description: string }) {
return (
<Link
href={href}
className="flex bg-white shadow-lg p-6 w-full sm:w-[250px] rounded-lg items-center mx-auto hover:scale-105 transition-all ease-linear cursor-pointer"
>
<div className="flex flex-col mx-auto space-y-2">
{icon}
<div className="text-center font-bold text-gray-500">{title}</div>
<p className="text-center text-sm text-gray-400">{description}</p>
</div>
</Link>
)
}
export default DashboardHome

View file

@ -2,8 +2,9 @@
import React, { useEffect } from 'react'
import { motion } from 'framer-motion'
import Link from 'next/link'
import { useMediaQuery } from 'usehooks-ts'
import { getUriWithOrg } from '@services/config/config'
import { ScanEye, SquareUserRound, UserPlus, Users } from 'lucide-react'
import { Monitor, ScanEye, SquareUserRound, UserPlus, Users } from 'lucide-react'
import BreadCrumbs from '@components/Dashboard/UI/BreadCrumbs'
import { useLHSession } from '@components/Contexts/LHSessionContext'
import { useOrg } from '@components/Contexts/OrgContext'
@ -22,6 +23,7 @@ function UsersSettingsPage({ params }: { params: SettingsParams }) {
const org = useOrg() as any
const [H1Label, setH1Label] = React.useState('')
const [H2Label, setH2Label] = React.useState('')
const isMobile = useMediaQuery('(max-width: 767px)')
function handleLabels() {
if (params.subpage == 'users') {
@ -46,6 +48,20 @@ function UsersSettingsPage({ params }: { params: SettingsParams }) {
handleLabels()
}, [session, org, params.subpage, params])
if (isMobile) {
// TODO: Work on a better mobile experience
return (
<div className="h-screen w-full bg-[#f8f8f8] flex items-center justify-center p-4">
<div className="bg-white p-6 rounded-lg shadow-md text-center">
<h2 className="text-xl font-bold mb-4">Desktop Only</h2>
<Monitor className='mx-auto my-5' size={60} />
<p>This page is only accessible from a desktop device.</p>
<p>Please switch to a desktop to view and manage user settings.</p>
</div>
</div>
)
}
return (
<div className="h-screen w-full bg-[#f8f8f8] grid grid-rows-[auto,1fr]">
<div className="pl-10 pr-10 tracking-tight bg-[#fcfbfc] z-10 shadow-[0px_4px_16px_rgba(0,0,0,0.06)]">