Skip to content

Commit da2ee81

Browse files
committed
skeleton loader reconstruction
1 parent 542c5d4 commit da2ee81

File tree

10 files changed

+277
-72
lines changed

10 files changed

+277
-72
lines changed

src/Skeletons/Square.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React from 'react';
33
export default function Square() {
44
return (
55
<div className="w-full overflow-hidden h-full grow flex flex-col">
6-
<div className="flex flex-col grow bg-light-bg dark:bg-dark-frame-bg overflow-hidden px-4">
6+
{/* <div className="flex flex-col grow bg-light-bg dark:bg-dark-frame-bg overflow-hidden px-4">
77
<div className="flex flex-row pb-8 justify-center">
88
<div className="w-[100%] ">
99
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
@@ -17,7 +17,7 @@ export default function Square() {
1717
<div className="items-center ">
1818
<div className="w-[100%] h-[46vh] lg:h-[62vh] pb-14 mx-auto mt-8 bottom-0 bg-gray-300 dark:bg-gray-600 rounded-lg animate-pulse" />
1919
</div>
20-
</div>
20+
</div> */}
2121
</div>
2222
);
2323
}

src/Skeletons/calendar.skeleton.tsx

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React from 'react';
2+
3+
function CalendarSkeleton() {
4+
const days = Array.from({ length: 35 }, (_, i) => ({ id: `day-${i + 1}` }));
5+
const events = [{ id: 'event-1' }, { id: 'event-2' }];
6+
return (
7+
<div className="bg-light-bg dark:bg-dark-frame-bg pb-10">
8+
<div className="animate-pulse">
9+
<div className="flex justify-between items-center mb-4">
10+
<div className="h-6 bg-gray-200 rounded w-24" />
11+
<div className="h-6 bg-gray-200 rounded w-16" />
12+
</div>
13+
<div className="grid grid-cols-7 gap-1">
14+
{[
15+
'Sunday',
16+
'Monday',
17+
'Tuesday',
18+
'Wednesday',
19+
'Thursday',
20+
'Friday',
21+
'Saturday',
22+
].map((day) => (
23+
<div key={day} className="h-6 bg-gray-200 rounded text-center">
24+
<div className="h-4 bg-gray-200 rounded w-1/2 mx-auto" />
25+
</div>
26+
))}
27+
28+
{/* Calendar Days */}
29+
{days.map((day) => (
30+
<div
31+
key={day.id}
32+
className="h-20 bg-gray-200 rounded p-2 flex flex-col justify-between"
33+
>
34+
<div className="h-4 bg-gray-200 rounded w-1/4" />
35+
</div>
36+
))}
37+
</div>
38+
39+
<div className="mt-4 space-y-2">
40+
{events.map((event) => (
41+
<div
42+
key={event.id}
43+
className="flex items-center justify-between p-2 bg-gray-800 rounded"
44+
>
45+
<div className="h-4 bg-gray-200 rounded w-3/4" />
46+
<div className="h-4 bg-gray-200 rounded w-6" />
47+
</div>
48+
))}
49+
</div>
50+
</div>
51+
</div>
52+
);
53+
}
54+
55+
export default CalendarSkeleton;
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React from 'react';
2+
3+
function OrganizationTableSkeleton() {
4+
const rows = [{ id: 'row-1' }, { id: 'row-2' }, { id: 'row-3' }];
5+
const headers = [
6+
{ id: 'header-1' },
7+
{ id: 'header-2' },
8+
{ id: 'header-3' },
9+
{ id: 'header-4' },
10+
];
11+
12+
return (
13+
<div className="bg-light-bg dark:bg-dark-frame-bg pb-10">
14+
<div className="bg-white dark:bg-dark-bg shadow-lg px-5 py-8 rounded-md w-full">
15+
<div className="animate-pulse">
16+
<div className="flex ml-2 items-center justify-between mb-4">
17+
<div
18+
className="h-6 bg-gray-200 rounded w-1/3"
19+
aria-label="Loading table title"
20+
/>
21+
</div>
22+
23+
<div className="-mx-4 sm:-mx-8 px-4 sm:px-8 py-2 overflow-x-auto">
24+
<div className="inline-block w-full lg:min-w-full shadow rounded-lg overflow-hidden">
25+
<table className="min-w-full leading-normal">
26+
<thead>
27+
<tr>
28+
{headers.map((header) => (
29+
<th
30+
key={header.id} // Use header.id for unique keys
31+
className="p-6 border-b-2 border-gray-200 bg-gray-100 dark:bg-neutral-600 text-center text-xs font-semibold text-gray-600 dark:text-white uppercase tracking-wider"
32+
>
33+
<div
34+
className="h-4 bg-gray-200 rounded w-1/4 mx-auto"
35+
aria-label={`Loading content for ${header.id}`}
36+
/>
37+
</th>
38+
))}
39+
</tr>
40+
</thead>
41+
<tbody>
42+
{rows.map((row) => (
43+
<tr key={row.id}>
44+
{headers.map((header) => (
45+
<td
46+
key={`cell-${row.id}-${header.id}`} // Use a combination of row and header IDs for unique keys
47+
className="px-5 py-5 border-b border-gray-200 bg-white dark:bg-dark-bg text-sm"
48+
>
49+
<div
50+
className="h-4 bg-gray-200 rounded w-3/4 mx-auto"
51+
aria-label={`Loading content for row ${row.id}, column ${header.id}`}
52+
/>
53+
</td>
54+
))}
55+
</tr>
56+
))}
57+
</tbody>
58+
</table>
59+
</div>
60+
</div>
61+
</div>
62+
</div>
63+
</div>
64+
);
65+
}
66+
67+
export default OrganizationTableSkeleton;

src/Skeletons/ttls.skeleton.tsx

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
3+
export default function TtlSkeleton() {
4+
const skeletonRows = [{ id: 'row-1' }, { id: 'row-2' }, { id: 'row-3' }];
5+
6+
return (
7+
<div className="p-4">
8+
<div
9+
className="h-8 w-20 bg-gray-200 rounded animate-pulse"
10+
aria-label="Loading title"
11+
/>
12+
<div
13+
className="h-8 w-2/5 bg-gray-200 rounded mt-6 animate-pulse"
14+
aria-label="Loading subtitle"
15+
/>
16+
<div
17+
className="h-16 bg-gray-200 rounded mt-6 animate-pulse"
18+
aria-label="Loading header"
19+
/>
20+
21+
{skeletonRows.map((row) => (
22+
<div key={row.id} className="flex items-center mb-4">
23+
<div className="flex-1">
24+
<div
25+
className="h-5 bg-gray-200 rounded w-5/6 mt-2 animate-pulse"
26+
aria-label={`Loading row ${row.id}`}
27+
/>
28+
</div>
29+
30+
<div className="flex space-x-4 mr-8 mt-2">
31+
<div
32+
className="h-8 w-8 bg-gray-200 rounded animate-pulse"
33+
aria-label={`Loading button 1 for ${row.id}`}
34+
/>
35+
<div
36+
className="h-8 w-8 bg-gray-200 rounded animate-pulse"
37+
aria-label={`Loading button 2 for ${row.id}`}
38+
/>
39+
<div
40+
className="h-8 w-8 bg-gray-200 rounded animate-pulse"
41+
aria-label={`Loading button 3 for ${row.id}`}
42+
/>
43+
</div>
44+
</div>
45+
))}
46+
47+
<div className="flex space-x-4">
48+
<div
49+
className="h-8 w-12 bg-gray-200 rounded animate-pulse"
50+
aria-label="Loading footer button 1"
51+
/>
52+
<div
53+
className="h-8 w-12 bg-gray-200 rounded animate-pulse"
54+
aria-label="Loading footer button 2"
55+
/>
56+
</div>
57+
</div>
58+
);
59+
}

src/components/Calendar.tsx

+23-14
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import useDocumentTitle from '../hook/useDocumentTitle';
1111
import { useLazyQuery, useMutation } from '@apollo/client';
1212
import { ADD_EVENT, GET_EVENTS } from '../Mutations/event';
1313
import moment from 'moment';
14+
import CalendarSkeleton from '../Skeletons/calendar.skeleton';
1415
/* istanbul ignore next */
1516

1617
const Calendar = () => {
@@ -25,6 +26,7 @@ const Calendar = () => {
2526
timeToFinish: '',
2627
});
2728
const [data, setData] = useState<EventInput[]>([]);
29+
const [loading, setLoading] = useState(true);
2830
const [getEvents] = useLazyQuery(GET_EVENTS);
2931
const [createEvent] = useMutation(ADD_EVENT);
3032
useEffect(() => {
@@ -48,6 +50,8 @@ const Calendar = () => {
4850
} catch (error) {
4951
console.log({ eventsError: data });
5052
// toast.error(error?.message || 'Something went wrong');
53+
} finally {
54+
setLoading(false);
5155
}
5256
};
5357
fetchData();
@@ -108,8 +112,9 @@ const Calendar = () => {
108112
<>
109113
{/* =========================== Start:: RegisterTraineeModel =========================== */}
110114
<div
111-
className={`font-serif h-screen w-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${addEventModel === true ? 'block' : 'hidden'
112-
}`}
115+
className={`font-serif h-screen w-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${
116+
addEventModel === true ? 'block' : 'hidden'
117+
}`}
113118
>
114119
<div className="bg-indigo-100 dark:bg-dark-bg w-full sm:w-3/4 md:w-1/2 xl:w-4/12 rounded-lg p-4 pb-8">
115120
<div className="card-title w-full flex flex-wrap justify-center items-center ">
@@ -155,9 +160,9 @@ const Calendar = () => {
155160
value={newEvent.hostName}
156161
onChange /* istanbul ignore next */={(e) =>
157162
/* istanbul ignore next */ setNewEvent({
158-
...newEvent,
159-
hostName: e.target.value,
160-
})
163+
...newEvent,
164+
hostName: e.target.value,
165+
})
161166
}
162167
/>
163168
</div>
@@ -172,9 +177,9 @@ const Calendar = () => {
172177
selected={newEvent.start}
173178
onChange /* istanbul ignore next */={(start: any) =>
174179
/* istanbul ignore next */ setNewEvent({
175-
...newEvent,
176-
start,
177-
})
180+
...newEvent,
181+
start,
182+
})
178183
}
179184
/>
180185
</div>
@@ -256,12 +261,16 @@ const Calendar = () => {
256261
>
257262
{t('Add event')}
258263
</button>
259-
<FullCalendar
260-
eventContent={renderEvent}
261-
events={data}
262-
plugins={[dayGridPlugin, interactionPlugin]}
263-
initialView="dayGridMonth"
264-
/>
264+
{loading ? (
265+
<CalendarSkeleton />
266+
) : (
267+
<FullCalendar
268+
eventContent={renderEvent}
269+
events={data}
270+
plugins={[dayGridPlugin, interactionPlugin]}
271+
initialView="dayGridMonth"
272+
/>
273+
)}
265274
</div>
266275
</>
267276
);

src/components/Organizations.tsx

+23-15
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { toast } from 'react-toastify';
1313
import { Icon } from '@iconify/react';
1414

1515
import DataTable from '../components/DataTable';
16+
import OrganizationTableSkeleton from '../Skeletons/organisation.skeleton';
1617

1718
export interface Admin {
1819
id: string;
@@ -303,7 +304,7 @@ const Organizations = () => {
303304
);
304305

305306
return (
306-
<div className='font-serif'>
307+
<div className="font-serif">
307308
{/* =========================== Start:: CreateOrganizationModel =============================== */}
308309
<CreateOrganizationModal
309310
createOrganizationModel={createOrganizationModel}
@@ -314,8 +315,9 @@ const Organizations = () => {
314315

315316
{/* =========================== Start:: delete Session Model =============================== */}
316317
<div
317-
className={`h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${deleteOrganizationModel === true ? 'block' : 'hidden'
318-
}`}
318+
className={`h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${
319+
deleteOrganizationModel === true ? 'block' : 'hidden'
320+
}`}
319321
>
320322
<div className="bg-white dark:bg-dark-bg w-full sm:w-3/4 md:w-1/2 xl:w-4/12 rounded-lg p-4 pb-8">
321323
<div className="card-title w-full flex flex-wrap justify-center items-center ">
@@ -370,8 +372,9 @@ const Organizations = () => {
370372
{/* =========================== Start:: SendInviteModel =============================== */}
371373

372374
<div
373-
className={`h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${sendInviteModel === true ? 'block' : 'hidden'
374-
}`}
375+
className={`h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${
376+
sendInviteModel === true ? 'block' : 'hidden'
377+
}`}
375378
>
376379
<div className="bg-white dark:bg-dark-bg w-full sm:w-3/4 xl:w-4/12 rounded-lg p-4 pb-8">
377380
<div className="card-title w-full flex flex-wrap justify-center items-center ">
@@ -429,8 +432,9 @@ const Organizations = () => {
429432
{/* =========================== Start:: ApproveMode =============================== */}
430433

431434
<div
432-
className={`h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${approveOpen === true ? 'block' : 'hidden'
433-
}`}
435+
className={`h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${
436+
approveOpen === true ? 'block' : 'hidden'
437+
}`}
434438
>
435439
<div className="bg-white dark:bg-dark-bg w-full sm:w-3/4 xl:w-4/12 rounded-lg p-4 pb-8">
436440
<div className="card-title w-full flex flex-wrap justify-center items-center ">
@@ -488,8 +492,9 @@ const Organizations = () => {
488492
{/* =========================== Start:: RejectModal =============================== */}
489493

490494
<div
491-
className={`h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${rejectOpen === true ? 'block' : 'hidden'
492-
}`}
495+
className={`h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${
496+
rejectOpen === true ? 'block' : 'hidden'
497+
}`}
493498
>
494499
<div className="bg-white dark:bg-dark-bg w-full sm:w-3/4 xl:w-4/12 rounded-lg p-4 pb-8">
495500
<div className="card-title w-full flex flex-wrap justify-center items-center ">
@@ -560,12 +565,15 @@ const Organizations = () => {
560565
</div>
561566
</div>
562567
<div className="">
563-
<DataTable
564-
columns={organizationColumns}
565-
data={organizationData ? (organizationData as [any]) : []}
566-
title={t('Organizations list')}
567-
loading={getLoading}
568-
/>
568+
{getLoading ? (
569+
<OrganizationTableSkeleton />
570+
) : (
571+
<DataTable
572+
columns={organizationColumns}
573+
data={organizationData ? (organizationData as [any]) : []}
574+
title={t('Organizations list')}
575+
/>
576+
)}
569577
</div>
570578
</div>
571579
</div>

src/containers/admin-dashBoard/TtlsModal.tsx

+2-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import ControlledSelect from '../../components/ControlledSelect';
2525
import { GET_GITHUB_STATISTICS } from '../../Mutations/manageStudentMutations';
2626
import GitHubActivityChart from '../../components/chartGitHub';
2727
import { toast } from 'react-toastify';
28+
import TtlSkeleton from '../../Skeletons/ttls.skeleton';
2829
/* istanbul ignore next */
2930
export default function TtlsPage() {
3031
const { t } = useTranslation();
@@ -645,10 +646,7 @@ export default function TtlsPage() {
645646
<div className="bg-light-bg dark:bg-dark-frame-bg min-h-screen overflow-y-auto overflow-x-hidden">
646647
<div className="">
647648
{loading ? (
648-
<div className="flex justify-center items-center h-48">
649-
<Spinner />
650-
<div className="spinner" />
651-
</div>
649+
<TtlSkeleton />
652650
) : (
653651
<DataTable
654652
columns={columns}

0 commit comments

Comments
 (0)