Skip to content

Commit d1cef2c

Browse files
committed
feat: skeletons for most ui components
1 parent 2af85b4 commit d1cef2c

File tree

13 files changed

+283
-82
lines changed

13 files changed

+283
-82
lines changed

src/components/file/DashboardFileType.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import fileIcon from './fileIcon';
1919
function PlaceholderContent({ text, Icon }: { text: string; Icon: Icon }) {
2020
return (
2121
<Stack align='center'>
22-
<Icon size={48} />
22+
<Icon size='4rem' stroke={2} style={{ filter: 'drop-shadow(0 0 10px rgba(0, 0, 0, 0.9))' }} />
2323
<Text size='md' ta='center'>
2424
{text}
2525
</Text>
@@ -126,7 +126,11 @@ export default function DashboardFileType({
126126
transform: 'translate(-50%, -50%)',
127127
}}
128128
>
129-
<IconPlayerPlay size='4rem' stroke={3} />
129+
<IconPlayerPlay
130+
size='4rem'
131+
stroke={3}
132+
style={{ filter: 'drop-shadow(0 0 10px rgba(0, 0, 0, 0.9))' }}
133+
/>
130134
</Center>
131135
</Box>
132136
) : (

src/components/pages/dashboard/index.tsx

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Stat from '@/components/Stat';
33
import type { Response } from '@/lib/api/response';
44
import { bytes } from '@/lib/bytes';
55
import useLogin from '@/lib/hooks/useLogin';
6-
import { LoadingOverlay, Paper, ScrollArea, SimpleGrid, Table, Text, Title } from '@mantine/core';
6+
import { Paper, ScrollArea, SimpleGrid, Skeleton, Table, Text, Title } from '@mantine/core';
77
import { IconDeviceSdCard, IconEyeFilled, IconFiles, IconLink, IconStarFilled } from '@tabler/icons-react';
88
import useSWR from 'swr';
99

@@ -17,9 +17,13 @@ export default function DashboardHome() {
1717
<Title order={1}>
1818
Welcome back, <b>{user?.username}</b>
1919
</Title>
20-
<Text size='sm' c='dimmed'>
21-
You have <b>{statsLoading ? '...' : stats?.filesUploaded}</b> files uploaded.
22-
</Text>
20+
21+
<Skeleton visible={statsLoading} animate>
22+
<Text size='sm' c='dimmed'>
23+
You have <b>{statsLoading ? '...' : stats?.filesUploaded}</b> files uploaded.
24+
</Text>
25+
</Skeleton>
26+
2327
{user?.quota && (user.quota.maxBytes || user.quota.maxFiles) ? (
2428
<Text size='sm' c='dimmed'>
2529
{user.quota.filesQuota === 'BY_BYTES' ? (
@@ -47,9 +51,11 @@ export default function DashboardHome() {
4751
</Title>
4852

4953
{recentLoading ? (
50-
<Paper withBorder p='md' radius='md' pos='relative' h={300}>
51-
<LoadingOverlay visible />
52-
</Paper>
54+
<SimpleGrid cols={{ base: 1, md: 2, lg: 3 }} spacing={{ base: 'sm', md: 'md' }}>
55+
{[...Array(3)].map((i) => (
56+
<Skeleton key={i} height={350} />
57+
))}
58+
</SimpleGrid>
5359
) : recent?.length !== 0 ? (
5460
<SimpleGrid cols={{ base: 1, md: 2, lg: 3 }} spacing={{ base: 'sm', md: 'md' }}>
5561
{recent!.map((file) => (
@@ -70,9 +76,46 @@ export default function DashboardHome() {
7076
</Text>
7177

7278
{statsLoading ? (
73-
<Paper withBorder p='md' radius='md' pos='relative' h={300}>
74-
<LoadingOverlay visible />
75-
</Paper>
79+
<>
80+
<SimpleGrid cols={{ base: 1, md: 2, lg: 4 }} spacing={{ base: 'sm', md: 'md' }}>
81+
{[...Array(8)].map((i) => (
82+
<Skeleton key={i} height={105} />
83+
))}
84+
</SimpleGrid>
85+
86+
<Title order={3} mt='lg' mb='xs'>
87+
File types
88+
</Title>
89+
90+
<Paper radius='sm' withBorder>
91+
<ScrollArea.Autosize mah={400} type='auto'>
92+
<Table highlightOnHover>
93+
<Table.Thead>
94+
<Table.Tr>
95+
<Table.Th>File Type</Table.Th>
96+
<Table.Th>Count</Table.Th>
97+
</Table.Tr>
98+
</Table.Thead>
99+
<Table.Tbody>
100+
{[1, 2, 3, 4, 5].map((i) => (
101+
<Table.Tr key={i}>
102+
<Table.Td>
103+
<Skeleton animate>
104+
<Text>...</Text>
105+
</Skeleton>
106+
</Table.Td>
107+
<Table.Td>
108+
<Skeleton animate>
109+
<Text>...</Text>
110+
</Skeleton>
111+
</Table.Td>
112+
</Table.Tr>
113+
))}
114+
</Table.Tbody>
115+
</Table>
116+
</ScrollArea.Autosize>
117+
</Paper>
118+
</>
76119
) : (
77120
<>
78121
<SimpleGrid cols={{ base: 1, md: 2, lg: 4 }} spacing={{ base: 'sm', md: 'md' }}>

src/components/pages/files/views/Files.tsx

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
import DashboardFile from '@/components/file/DashboardFile';
2-
import {
3-
Button,
4-
Center,
5-
Group,
6-
LoadingOverlay,
7-
Pagination,
8-
Paper,
9-
SimpleGrid,
10-
Stack,
11-
Title,
12-
} from '@mantine/core';
2+
import { Button, Center, Group, Pagination, Paper, SimpleGrid, Skeleton, Stack, Title } from '@mantine/core';
133
import { IconFileUpload, IconFilesOff } from '@tabler/icons-react';
144
import Link from 'next/link';
155
import { useRouter } from 'next/router';
@@ -51,9 +41,7 @@ export default function Files({ id }: { id?: string }) {
5141
pos='relative'
5242
>
5343
{isLoading ? (
54-
<Paper withBorder h={200}>
55-
<LoadingOverlay visible />
56-
</Paper>
44+
[...Array(9)].map((_, i) => <Skeleton key={i} height={350} animate />)
5745
) : (data?.page?.length ?? 0 > 0) ? (
5846
data?.page.map((file) => <DashboardFile key={file.id} file={file} />)
5947
) : (

src/components/pages/folders/views/FolderGridView.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Response } from '@/lib/api/response';
22
import { Folder } from '@/lib/db/models/folder';
3-
import { Center, Group, LoadingOverlay, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
3+
import { Center, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Title } from '@mantine/core';
44
import { IconLink } from '@tabler/icons-react';
55
import useSWR from 'swr';
66
import FolderCard from '../FolderCard';
@@ -12,9 +12,20 @@ export default function FolderGridView() {
1212
return (
1313
<>
1414
{isLoading ? (
15-
<Paper withBorder h={200}>
16-
<LoadingOverlay visible />
17-
</Paper>
15+
<SimpleGrid
16+
my='sm'
17+
spacing='md'
18+
cols={{
19+
base: 1,
20+
md: 2,
21+
lg: 4,
22+
}}
23+
pos='relative'
24+
>
25+
{[...Array(4)].map((_, i) => (
26+
<Skeleton key={i} height={120} animate />
27+
))}
28+
</SimpleGrid>
1829
) : (folders?.length ?? 0 !== 0) ? (
1930
<SimpleGrid
2031
my='sm'

src/components/pages/invites/views/InviteGridView.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Response } from '@/lib/api/response';
22
import { Invite } from '@/lib/db/models/invite';
3-
import { Center, Group, LoadingOverlay, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
3+
import { Center, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Title } from '@mantine/core';
44
import { IconLink } from '@tabler/icons-react';
55
import useSWR from 'swr';
66
import InviteCard from '../InviteCard';
@@ -12,9 +12,20 @@ export default function InviteGridView() {
1212
return (
1313
<>
1414
{isLoading ? (
15-
<Paper withBorder h={200}>
16-
<LoadingOverlay visible />
17-
</Paper>
15+
<SimpleGrid
16+
my='sm'
17+
spacing='md'
18+
cols={{
19+
base: 1,
20+
md: 2,
21+
lg: 4,
22+
}}
23+
pos='relative'
24+
>
25+
{[...Array(4)].map((_, i) => (
26+
<Skeleton key={i} height={120} animate />
27+
))}
28+
</SimpleGrid>
1829
) : (folders?.length ?? 0 !== 0) ? (
1930
<SimpleGrid
2031
my='sm'

src/components/pages/metrics/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import { Box, Button, Group, Loader, Modal, Paper, SimpleGrid, Text, Title, Tooltip } from '@mantine/core';
1+
import { Box, Button, Group, Modal, Paper, SimpleGrid, Text, Title, Tooltip } from '@mantine/core';
22
import { DatePicker } from '@mantine/dates';
33
import { IconCalendarSearch, IconCalendarTime } from '@tabler/icons-react';
4+
import dynamic from 'next/dynamic';
45
import { useState } from 'react';
56
import FilesUrlsCountGraph from './parts/FilesUrlsCountGraph';
67
import { useApiStats } from './useStats';
7-
import dynamic from 'next/dynamic';
8+
import { StatsCardsSkeleton } from './parts/StatsCards';
9+
import { StatsTablesSkeleton } from './parts/StatsTables';
810

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

9395
<Box pos='relative' mih={300} my='sm'>
9496
{isLoading ? (
95-
<Loader />
97+
<div>
98+
<StatsCardsSkeleton />
99+
100+
<StatsTablesSkeleton />
101+
</div>
96102
) : data?.length ? (
97103
<div>
98104
<StatsCards data={data!} />

src/components/pages/metrics/parts/StatsCards.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { bytes } from '@/lib/bytes';
22
import { Metric } from '@/lib/db/models/metric';
3-
import { Group, Paper, SimpleGrid, Text, Title } from '@mantine/core';
3+
import { Group, Paper, SimpleGrid, Skeleton, Text, Title } from '@mantine/core';
44
import {
55
IconDatabase,
66
IconEyeFilled,
@@ -26,6 +26,23 @@ function StatCard({ title, value, Icon }: { title: string; value: number | strin
2626
);
2727
}
2828

29+
export function StatsCardsSkeleton() {
30+
return (
31+
<SimpleGrid
32+
cols={{
33+
base: 1,
34+
md: 2,
35+
lg: 3,
36+
}}
37+
mb='sm'
38+
>
39+
{[...Array(6)].map((_, i) => (
40+
<Skeleton key={i} height={100} animate />
41+
))}
42+
</SimpleGrid>
43+
);
44+
}
45+
2946
export default function StatsCards({ data }: { data: Metric[] }) {
3047
if (!data.length) return null;
3148
const recent = data[0];

src/components/pages/metrics/parts/StatsTables.tsx

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,117 @@
11
import { bytes } from '@/lib/bytes';
22
import { Metric } from '@/lib/db/models/metric';
3-
import { Paper, ScrollArea, SimpleGrid, Table } from '@mantine/core';
3+
import { Paper, ScrollArea, SimpleGrid, Skeleton, Table, Text } from '@mantine/core';
44
import TypesPieChart from './TypesPieChart';
55

6+
function SkeletonText() {
7+
return (
8+
<Table.Td>
9+
<Skeleton animate>
10+
<Text>...</Text>
11+
</Skeleton>
12+
</Table.Td>
13+
);
14+
}
15+
16+
export function StatsTablesSkeleton() {
17+
return (
18+
<>
19+
<SimpleGrid cols={{ base: 1, md: 2 }}>
20+
<Paper radius='sm' withBorder>
21+
<ScrollArea.Autosize mah={500} type='auto'>
22+
<Table highlightOnHover stickyHeader>
23+
<Table.Thead>
24+
<Table.Tr>
25+
<Table.Th>User</Table.Th>
26+
<Table.Th>Files</Table.Th>
27+
<Table.Th>Storage Used</Table.Th>
28+
<Table.Th>Views</Table.Th>
29+
</Table.Tr>
30+
</Table.Thead>
31+
<Table.Tbody>
32+
{[...Array(5)].map((i) => (
33+
<Table.Tr key={i}>
34+
<Table.Td>
35+
<SkeletonText />
36+
</Table.Td>
37+
<Table.Td>
38+
<SkeletonText />
39+
</Table.Td>
40+
<Table.Td>
41+
<SkeletonText />
42+
</Table.Td>
43+
<Table.Td>
44+
<SkeletonText />
45+
</Table.Td>
46+
</Table.Tr>
47+
))}
48+
</Table.Tbody>
49+
</Table>
50+
</ScrollArea.Autosize>
51+
</Paper>
52+
53+
<Paper radius='sm' withBorder mah={500}>
54+
<ScrollArea.Autosize mah={500} type='auto'>
55+
<Table highlightOnHover stickyHeader>
56+
<Table.Thead>
57+
<Table.Tr>
58+
<Table.Th>User</Table.Th>
59+
<Table.Th>URLs</Table.Th>
60+
<Table.Th>Views</Table.Th>
61+
</Table.Tr>
62+
</Table.Thead>
63+
<Table.Tbody>
64+
{[...Array(5)].map((i) => (
65+
<Table.Tr key={i}>
66+
<Table.Td>
67+
<SkeletonText />
68+
</Table.Td>
69+
<Table.Td>
70+
<SkeletonText />
71+
</Table.Td>
72+
<Table.Td>
73+
<SkeletonText />
74+
</Table.Td>
75+
</Table.Tr>
76+
))}
77+
</Table.Tbody>
78+
</Table>
79+
</ScrollArea.Autosize>
80+
</Paper>
81+
82+
<Paper radius='sm' withBorder>
83+
<ScrollArea.Autosize mah={500} type='auto'>
84+
<Table highlightOnHover stickyHeader>
85+
<Table.Thead>
86+
<Table.Tr>
87+
<Table.Th>Type</Table.Th>
88+
<Table.Th>Files</Table.Th>
89+
</Table.Tr>
90+
</Table.Thead>
91+
<Table.Tbody>
92+
{[...Array(5)].map((i) => (
93+
<Table.Tr key={i}>
94+
<Table.Td>
95+
<SkeletonText />
96+
</Table.Td>
97+
<Table.Td>
98+
<SkeletonText />
99+
</Table.Td>
100+
</Table.Tr>
101+
))}
102+
</Table.Tbody>
103+
</Table>
104+
</ScrollArea.Autosize>
105+
</Paper>
106+
107+
<Paper radius='sm' withBorder p='sm'>
108+
<Skeleton height={500} />
109+
</Paper>
110+
</SimpleGrid>
111+
</>
112+
);
113+
}
114+
6115
export default function StatsTables({ data }: { data: Metric[] }) {
7116
if (!data.length) return null;
8117

0 commit comments

Comments
 (0)