Optimize mobile load by lazy loading large modules
All checks were successful
Build & Push Docker Image / docker (push) Successful in 1m48s
All checks were successful
Build & Push Docker Image / docker (push) Successful in 1m48s
This commit is contained in:
parent
af68304404
commit
c00f58bced
@ -1,5 +1,6 @@
|
|||||||
import { AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
|
import { AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
|
||||||
import { SidebarMenuButton, useSidebar } from '@/components/ui/sidebar';
|
import { SidebarMenuButton, useSidebar } from '@/components/ui/sidebar';
|
||||||
|
import { useIsMobile } from '@/hooks/use-mobile';
|
||||||
import { routeLastSegment, routeSecondSegment } from '@/lib/route';
|
import { routeLastSegment, routeSecondSegment } from '@/lib/route';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { SharedData } from '@/types/global';
|
import { SharedData } from '@/types/global';
|
||||||
@ -14,6 +15,7 @@ const NavMainItem = (props: NavMainItemProps) => {
|
|||||||
const page = usePage<SharedData>();
|
const page = usePage<SharedData>();
|
||||||
const { auth, direction } = page.props;
|
const { auth, direction } = page.props;
|
||||||
const { state, toggleSidebar } = useSidebar();
|
const { state, toggleSidebar } = useSidebar();
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
const { pageRoute } = props;
|
const { pageRoute } = props;
|
||||||
const { Icon, name, path, children, slug } = pageRoute;
|
const { Icon, name, path, children, slug } = pageRoute;
|
||||||
@ -67,7 +69,7 @@ const NavMainItem = (props: NavMainItemProps) => {
|
|||||||
if (access.includes(auth.user.role)) {
|
if (access.includes(auth.user.role)) {
|
||||||
return (
|
return (
|
||||||
<SidebarMenuButton asChild key={index} isActive={activeChildRoute(pageRoute.slug, slug)} className="h-9 px-3">
|
<SidebarMenuButton asChild key={index} isActive={activeChildRoute(pageRoute.slug, slug)} className="h-9 px-3">
|
||||||
<Link href={path} prefetch>
|
<Link href={path} prefetch={!isMobile}>
|
||||||
<Dot className="w-12" />
|
<Dot className="w-12" />
|
||||||
<span className="text-sm font-normal capitalize">{name}</span>
|
<span className="text-sm font-normal capitalize">{name}</span>
|
||||||
</Link>
|
</Link>
|
||||||
@ -88,7 +90,7 @@ const NavMainItem = (props: NavMainItemProps) => {
|
|||||||
: '',
|
: '',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Link href={path} prefetch>
|
<Link href={path} prefetch={!isMobile}>
|
||||||
<Icon className="h-4 w-4" />
|
<Icon className="h-4 w-4" />
|
||||||
<span>{name}</span>
|
<span>{name}</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import AppLogo from '@/components/app-logo';
|
import AppLogo from '@/components/app-logo';
|
||||||
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarMenu, SidebarMenuItem, useSidebar } from '@/components/ui/sidebar';
|
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarMenu, SidebarMenuItem, useSidebar } from '@/components/ui/sidebar';
|
||||||
|
import { useIsMobile } from '@/hooks/use-mobile';
|
||||||
import { NavMain } from '@/layouts/dashboard/partials/nav-main';
|
import { NavMain } from '@/layouts/dashboard/partials/nav-main';
|
||||||
import { NavUser } from '@/layouts/dashboard/partials/nav-user';
|
import { NavUser } from '@/layouts/dashboard/partials/nav-user';
|
||||||
import { SharedData } from '@/types/global';
|
import { SharedData } from '@/types/global';
|
||||||
@ -9,6 +10,7 @@ const DashboardSidebar = () => {
|
|||||||
const { state } = useSidebar();
|
const { state } = useSidebar();
|
||||||
const { props } = usePage<SharedData>();
|
const { props } = usePage<SharedData>();
|
||||||
const compact = state === 'collapsed' ? true : false;
|
const compact = state === 'collapsed' ? true : false;
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sidebar collapsible="icon" variant="inset" side={props.direction === 'rtl' ? 'right' : 'left'} className="shadow-md">
|
<Sidebar collapsible="icon" variant="inset" side={props.direction === 'rtl' ? 'right' : 'left'} className="shadow-md">
|
||||||
@ -16,7 +18,7 @@ const DashboardSidebar = () => {
|
|||||||
<SidebarHeader>
|
<SidebarHeader>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem className="pt-1 pb-5">
|
<SidebarMenuItem className="pt-1 pb-5">
|
||||||
<Link href="/" prefetch>
|
<Link href="/" prefetch={!isMobile}>
|
||||||
<AppLogo className="h-[26px]" />
|
<AppLogo className="h-[26px]" />
|
||||||
</Link>
|
</Link>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
|
|||||||
@ -3,14 +3,16 @@ import RatingStars from '@/components/rating-stars';
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Card } from '@/components/ui/card';
|
import { Card } from '@/components/ui/card';
|
||||||
import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog';
|
import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog';
|
||||||
import VideoPlayer from '@/components/video-player';
|
|
||||||
import { getPageSection, getPropertyArray } from '@/lib/page';
|
import { getPageSection, getPropertyArray } from '@/lib/page';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { IntroPageProps } from '@/types/page';
|
import { IntroPageProps } from '@/types/page';
|
||||||
import { Link, usePage } from '@inertiajs/react';
|
import { Link, usePage } from '@inertiajs/react';
|
||||||
import { Play } from 'lucide-react';
|
import { Play } from 'lucide-react';
|
||||||
|
import { lazy, Suspense } from 'react';
|
||||||
import Section from '../section';
|
import Section from '../section';
|
||||||
|
|
||||||
|
const VideoPlayer = lazy(() => import('@/components/video-player'));
|
||||||
|
|
||||||
const Hero = () => {
|
const Hero = () => {
|
||||||
const { props } = usePage<IntroPageProps>();
|
const { props } = usePage<IntroPageProps>();
|
||||||
const { page } = props;
|
const { page } = props;
|
||||||
@ -65,17 +67,19 @@ const Hero = () => {
|
|||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
<DialogContent className="overflow-hidden p-0 md:min-w-3xl">
|
<DialogContent className="overflow-hidden p-0 md:min-w-3xl">
|
||||||
<VideoPlayer
|
<Suspense fallback={null}>
|
||||||
source={{
|
<VideoPlayer
|
||||||
type: 'video' as const,
|
source={{
|
||||||
sources: [
|
type: 'video' as const,
|
||||||
{
|
sources: [
|
||||||
src: heroSection?.video_url,
|
{
|
||||||
type: 'video/mp4' as const,
|
src: heroSection?.video_url,
|
||||||
},
|
type: 'video/mp4' as const,
|
||||||
],
|
},
|
||||||
}}
|
],
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
|
||||||
import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog';
|
import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog';
|
||||||
import VideoPlayer from '@/components/video-player';
|
|
||||||
import { getPageSection } from '@/lib/page';
|
import { getPageSection } from '@/lib/page';
|
||||||
import { IntroPageProps } from '@/types/page';
|
import { IntroPageProps } from '@/types/page';
|
||||||
import { usePage } from '@inertiajs/react';
|
import { usePage } from '@inertiajs/react';
|
||||||
import { File, FileQuestion, FileText, Image, Play, Video } from 'lucide-react';
|
import { File, FileQuestion, FileText, Image, Play, Video } from 'lucide-react';
|
||||||
|
import { lazy, Suspense } from 'react';
|
||||||
import Section from '../section';
|
import Section from '../section';
|
||||||
|
|
||||||
|
const VideoPlayer = lazy(() => import('@/components/video-player'));
|
||||||
|
|
||||||
const TopCourse = () => {
|
const TopCourse = () => {
|
||||||
const { props } = usePage<IntroPageProps>();
|
const { props } = usePage<IntroPageProps>();
|
||||||
const { page, topCourse, customize } = props;
|
const { page, topCourse, customize } = props;
|
||||||
@ -34,17 +36,19 @@ const TopCourse = () => {
|
|||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
<DialogContent className="overflow-hidden p-0 md:min-w-3xl">
|
<DialogContent className="overflow-hidden p-0 md:min-w-3xl">
|
||||||
<VideoPlayer
|
<Suspense fallback={null}>
|
||||||
source={{
|
<VideoPlayer
|
||||||
type: 'video' as const,
|
source={{
|
||||||
sources: [
|
type: 'video' as const,
|
||||||
{
|
sources: [
|
||||||
src: topCourse.preview,
|
{
|
||||||
type: 'video/mp4' as const,
|
src: topCourse.preview,
|
||||||
},
|
type: 'video/mp4' as const,
|
||||||
],
|
},
|
||||||
}}
|
],
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import SectionEditor from '@/components/section-editor';
|
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Pencil } from 'lucide-react';
|
import { Pencil } from 'lucide-react';
|
||||||
import { ReactNode } from 'react';
|
import { lazy, ReactNode, Suspense } from 'react';
|
||||||
|
|
||||||
|
const SectionEditor = lazy(() => import('@/components/section-editor'));
|
||||||
|
|
||||||
interface SectionProps extends React.HTMLAttributes<HTMLDivElement> {
|
interface SectionProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -19,14 +20,16 @@ const Section = ({ containerClass, contentClass, children, pageSection, customiz
|
|||||||
<section className={cn('container', containerClass)} {...props} style={containerStyle}>
|
<section className={cn('container', containerClass)} {...props} style={containerStyle}>
|
||||||
<div className={cn(contentClass, customize && 'section-edit')} style={contentStyle}>
|
<div className={cn(contentClass, customize && 'section-edit')} style={contentStyle}>
|
||||||
{customize && pageSection && (
|
{customize && pageSection && (
|
||||||
<SectionEditor
|
<Suspense fallback={null}>
|
||||||
section={pageSection}
|
<SectionEditor
|
||||||
actionComponent={
|
section={pageSection}
|
||||||
<Button size="icon" variant="secondary" className="absolute top-3 right-3 z-20">
|
actionComponent={
|
||||||
<Pencil className="h-7 w-7" />
|
<Button size="icon" variant="secondary" className="absolute top-3 right-3 z-20">
|
||||||
</Button>
|
<Pencil className="h-7 w-7" />
|
||||||
}
|
</Button>
|
||||||
/>
|
}
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user