Skip to content

Commit

Permalink
feat: skeletons for most ui components
Browse files Browse the repository at this point in the history
  • Loading branch information
diced committed Dec 16, 2024
1 parent 2af85b4 commit d1cef2c
Show file tree
Hide file tree
Showing 13 changed files with 283 additions and 82 deletions.
8 changes: 6 additions & 2 deletions src/components/file/DashboardFileType.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import fileIcon from './fileIcon';
function PlaceholderContent({ text, Icon }: { text: string; Icon: Icon }) {
return (
<Stack align='center'>
<Icon size={48} />
<Icon size='4rem' stroke={2} style={{ filter: 'drop-shadow(0 0 10px rgba(0, 0, 0, 0.9))' }} />
<Text size='md' ta='center'>
{text}
</Text>
Expand Down Expand Up @@ -126,7 +126,11 @@ export default function DashboardFileType({
transform: 'translate(-50%, -50%)',
}}
>
<IconPlayerPlay size='4rem' stroke={3} />
<IconPlayerPlay
size='4rem'
stroke={3}
style={{ filter: 'drop-shadow(0 0 10px rgba(0, 0, 0, 0.9))' }}
/>
</Center>
</Box>
) : (
Expand Down
63 changes: 53 additions & 10 deletions src/components/pages/dashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Stat from '@/components/Stat';
import type { Response } from '@/lib/api/response';
import { bytes } from '@/lib/bytes';
import useLogin from '@/lib/hooks/useLogin';
import { LoadingOverlay, Paper, ScrollArea, SimpleGrid, Table, Text, Title } from '@mantine/core';
import { Paper, ScrollArea, SimpleGrid, Skeleton, Table, Text, Title } from '@mantine/core';
import { IconDeviceSdCard, IconEyeFilled, IconFiles, IconLink, IconStarFilled } from '@tabler/icons-react';
import useSWR from 'swr';

Expand All @@ -17,9 +17,13 @@ export default function DashboardHome() {
<Title order={1}>
Welcome back, <b>{user?.username}</b>
</Title>
<Text size='sm' c='dimmed'>
You have <b>{statsLoading ? '...' : stats?.filesUploaded}</b> files uploaded.
</Text>

<Skeleton visible={statsLoading} animate>
<Text size='sm' c='dimmed'>
You have <b>{statsLoading ? '...' : stats?.filesUploaded}</b> files uploaded.
</Text>
</Skeleton>

{user?.quota && (user.quota.maxBytes || user.quota.maxFiles) ? (
<Text size='sm' c='dimmed'>
{user.quota.filesQuota === 'BY_BYTES' ? (
Expand Down Expand Up @@ -47,9 +51,11 @@ export default function DashboardHome() {
</Title>

{recentLoading ? (
<Paper withBorder p='md' radius='md' pos='relative' h={300}>
<LoadingOverlay visible />
</Paper>
<SimpleGrid cols={{ base: 1, md: 2, lg: 3 }} spacing={{ base: 'sm', md: 'md' }}>
{[...Array(3)].map((i) => (
<Skeleton key={i} height={350} />
))}
</SimpleGrid>
) : recent?.length !== 0 ? (
<SimpleGrid cols={{ base: 1, md: 2, lg: 3 }} spacing={{ base: 'sm', md: 'md' }}>
{recent!.map((file) => (
Expand All @@ -70,9 +76,46 @@ export default function DashboardHome() {
</Text>

{statsLoading ? (
<Paper withBorder p='md' radius='md' pos='relative' h={300}>
<LoadingOverlay visible />
</Paper>
<>
<SimpleGrid cols={{ base: 1, md: 2, lg: 4 }} spacing={{ base: 'sm', md: 'md' }}>
{[...Array(8)].map((i) => (
<Skeleton key={i} height={105} />
))}
</SimpleGrid>

<Title order={3} mt='lg' mb='xs'>
File types
</Title>

<Paper radius='sm' withBorder>
<ScrollArea.Autosize mah={400} type='auto'>
<Table highlightOnHover>
<Table.Thead>
<Table.Tr>
<Table.Th>File Type</Table.Th>
<Table.Th>Count</Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{[1, 2, 3, 4, 5].map((i) => (
<Table.Tr key={i}>
<Table.Td>
<Skeleton animate>
<Text>...</Text>
</Skeleton>
</Table.Td>
<Table.Td>
<Skeleton animate>
<Text>...</Text>
</Skeleton>
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
</ScrollArea.Autosize>
</Paper>
</>
) : (
<>
<SimpleGrid cols={{ base: 1, md: 2, lg: 4 }} spacing={{ base: 'sm', md: 'md' }}>
Expand Down
16 changes: 2 additions & 14 deletions src/components/pages/files/views/Files.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import DashboardFile from '@/components/file/DashboardFile';
import {
Button,
Center,
Group,
LoadingOverlay,
Pagination,
Paper,
SimpleGrid,
Stack,
Title,
} from '@mantine/core';
import { Button, Center, Group, Pagination, Paper, SimpleGrid, Skeleton, Stack, Title } from '@mantine/core';
import { IconFileUpload, IconFilesOff } from '@tabler/icons-react';
import Link from 'next/link';
import { useRouter } from 'next/router';
Expand Down Expand Up @@ -51,9 +41,7 @@ export default function Files({ id }: { id?: string }) {
pos='relative'
>
{isLoading ? (
<Paper withBorder h={200}>
<LoadingOverlay visible />
</Paper>
[...Array(9)].map((_, i) => <Skeleton key={i} height={350} animate />)
) : (data?.page?.length ?? 0 > 0) ? (
data?.page.map((file) => <DashboardFile key={file.id} file={file} />)
) : (
Expand Down
19 changes: 15 additions & 4 deletions src/components/pages/folders/views/FolderGridView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Response } from '@/lib/api/response';
import { Folder } from '@/lib/db/models/folder';
import { Center, Group, LoadingOverlay, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
import { Center, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Title } from '@mantine/core';
import { IconLink } from '@tabler/icons-react';
import useSWR from 'swr';
import FolderCard from '../FolderCard';
Expand All @@ -12,9 +12,20 @@ export default function FolderGridView() {
return (
<>
{isLoading ? (
<Paper withBorder h={200}>
<LoadingOverlay visible />
</Paper>
<SimpleGrid
my='sm'
spacing='md'
cols={{
base: 1,
md: 2,
lg: 4,
}}
pos='relative'
>
{[...Array(4)].map((_, i) => (
<Skeleton key={i} height={120} animate />
))}
</SimpleGrid>
) : (folders?.length ?? 0 !== 0) ? (
<SimpleGrid
my='sm'
Expand Down
19 changes: 15 additions & 4 deletions src/components/pages/invites/views/InviteGridView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Response } from '@/lib/api/response';
import { Invite } from '@/lib/db/models/invite';
import { Center, Group, LoadingOverlay, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
import { Center, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Title } from '@mantine/core';
import { IconLink } from '@tabler/icons-react';
import useSWR from 'swr';
import InviteCard from '../InviteCard';
Expand All @@ -12,9 +12,20 @@ export default function InviteGridView() {
return (
<>
{isLoading ? (
<Paper withBorder h={200}>
<LoadingOverlay visible />
</Paper>
<SimpleGrid
my='sm'
spacing='md'
cols={{
base: 1,
md: 2,
lg: 4,
}}
pos='relative'
>
{[...Array(4)].map((_, i) => (
<Skeleton key={i} height={120} animate />
))}
</SimpleGrid>
) : (folders?.length ?? 0 !== 0) ? (
<SimpleGrid
my='sm'
Expand Down
12 changes: 9 additions & 3 deletions src/components/pages/metrics/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Box, Button, Group, Loader, Modal, Paper, SimpleGrid, Text, Title, Tooltip } from '@mantine/core';
import { Box, Button, Group, Modal, Paper, SimpleGrid, Text, Title, Tooltip } from '@mantine/core';
import { DatePicker } from '@mantine/dates';
import { IconCalendarSearch, IconCalendarTime } from '@tabler/icons-react';
import dynamic from 'next/dynamic';
import { useState } from 'react';
import FilesUrlsCountGraph from './parts/FilesUrlsCountGraph';
import { useApiStats } from './useStats';
import dynamic from 'next/dynamic';
import { StatsCardsSkeleton } from './parts/StatsCards';
import { StatsTablesSkeleton } from './parts/StatsTables';

const StatsCards = dynamic(() => import('./parts/StatsCards'));
const StatsTables = dynamic(() => import('./parts/StatsTables'));
Expand Down Expand Up @@ -92,7 +94,11 @@ export default function DashboardMetrics() {

<Box pos='relative' mih={300} my='sm'>
{isLoading ? (
<Loader />
<div>
<StatsCardsSkeleton />

<StatsTablesSkeleton />
</div>
) : data?.length ? (
<div>
<StatsCards data={data!} />
Expand Down
19 changes: 18 additions & 1 deletion src/components/pages/metrics/parts/StatsCards.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { bytes } from '@/lib/bytes';
import { Metric } from '@/lib/db/models/metric';
import { Group, Paper, SimpleGrid, Text, Title } from '@mantine/core';
import { Group, Paper, SimpleGrid, Skeleton, Text, Title } from '@mantine/core';
import {
IconDatabase,
IconEyeFilled,
Expand All @@ -26,6 +26,23 @@ function StatCard({ title, value, Icon }: { title: string; value: number | strin
);
}

export function StatsCardsSkeleton() {
return (
<SimpleGrid
cols={{
base: 1,
md: 2,
lg: 3,
}}
mb='sm'
>
{[...Array(6)].map((_, i) => (
<Skeleton key={i} height={100} animate />
))}
</SimpleGrid>
);
}

export default function StatsCards({ data }: { data: Metric[] }) {
if (!data.length) return null;
const recent = data[0];
Expand Down
111 changes: 110 additions & 1 deletion src/components/pages/metrics/parts/StatsTables.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,117 @@
import { bytes } from '@/lib/bytes';
import { Metric } from '@/lib/db/models/metric';
import { Paper, ScrollArea, SimpleGrid, Table } from '@mantine/core';
import { Paper, ScrollArea, SimpleGrid, Skeleton, Table, Text } from '@mantine/core';
import TypesPieChart from './TypesPieChart';

function SkeletonText() {
return (
<Table.Td>
<Skeleton animate>
<Text>...</Text>
</Skeleton>
</Table.Td>
);
}

export function StatsTablesSkeleton() {
return (
<>
<SimpleGrid cols={{ base: 1, md: 2 }}>
<Paper radius='sm' withBorder>
<ScrollArea.Autosize mah={500} type='auto'>
<Table highlightOnHover stickyHeader>
<Table.Thead>
<Table.Tr>
<Table.Th>User</Table.Th>
<Table.Th>Files</Table.Th>
<Table.Th>Storage Used</Table.Th>
<Table.Th>Views</Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{[...Array(5)].map((i) => (
<Table.Tr key={i}>
<Table.Td>
<SkeletonText />
</Table.Td>
<Table.Td>
<SkeletonText />
</Table.Td>
<Table.Td>
<SkeletonText />
</Table.Td>
<Table.Td>
<SkeletonText />
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
</ScrollArea.Autosize>
</Paper>

<Paper radius='sm' withBorder mah={500}>
<ScrollArea.Autosize mah={500} type='auto'>
<Table highlightOnHover stickyHeader>
<Table.Thead>
<Table.Tr>
<Table.Th>User</Table.Th>
<Table.Th>URLs</Table.Th>
<Table.Th>Views</Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{[...Array(5)].map((i) => (
<Table.Tr key={i}>
<Table.Td>
<SkeletonText />
</Table.Td>
<Table.Td>
<SkeletonText />
</Table.Td>
<Table.Td>
<SkeletonText />
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
</ScrollArea.Autosize>
</Paper>

<Paper radius='sm' withBorder>
<ScrollArea.Autosize mah={500} type='auto'>
<Table highlightOnHover stickyHeader>
<Table.Thead>
<Table.Tr>
<Table.Th>Type</Table.Th>
<Table.Th>Files</Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{[...Array(5)].map((i) => (
<Table.Tr key={i}>
<Table.Td>
<SkeletonText />
</Table.Td>
<Table.Td>
<SkeletonText />
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
</ScrollArea.Autosize>
</Paper>

<Paper radius='sm' withBorder p='sm'>
<Skeleton height={500} />
</Paper>
</SimpleGrid>
</>
);
}

export default function StatsTables({ data }: { data: Metric[] }) {
if (!data.length) return null;

Expand Down
Loading

0 comments on commit d1cef2c

Please sign in to comment.