Skip to content

Commit cc7db9e

Browse files
authored
Merge pull request #334 from CivicDataLab/329-feature-add-shimmer-effect-using-framer-motion
Shimmer effect using framer motion
2 parents 1abb135 + 0930ff8 commit cc7db9e

File tree

17 files changed

+1026
-25
lines changed

17 files changed

+1026
-25
lines changed

app/[locale]/(user)/components/Datasets.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
import { cn } from '@/lib/utils';
1919
import { Icons } from '@/components/icons';
2020
import Styles from './datasets.module.scss';
21+
import { DatasetListingSkeleton } from '@/components/loading';
2122

2223
interface Bucket {
2324
key: string;
@@ -81,9 +82,10 @@ const Datasets = () => {
8182

8283
<CarouselContent className="p-4">
8384
{isLoading ? (
84-
<div className="p-8">
85-
<Spinner />
86-
</div>
85+
<DatasetListingSkeleton
86+
cardCount={3}
87+
cardsOnly={true}
88+
/>
8789
) : (
8890
facets &&
8991
facets.results.map((item: any) => (

app/[locale]/(user)/components/ListingComponent.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ const stripMarkdown = (markdown: string): string => {
6464
.trim()
6565
);
6666
};
67+
import {
68+
DatasetListingSkeleton,
69+
UseCaseListingSkeleton,
70+
} from '@/components/loading';
6771

6872
// Interfaces
6973
interface Bucket {
@@ -307,8 +311,12 @@ const ListingComponent: React.FC<ListingProps> = ({
307311
useEffect(() => {
308312
setHasMounted(true);
309313
}, []);
310-
311-
if (!hasMounted) return <Loading />;
314+
if (!hasMounted) {
315+
if (type === 'usecase') {
316+
return <UseCaseListingSkeleton cardCount={queryParams.pageSize} />;
317+
}
318+
return <DatasetListingSkeleton cardCount={queryParams.pageSize} />;
319+
}
312320

313321
const handlePageChange = (newPage: number) => {
314322
setQueryParams({ type: 'SET_CURRENT_PAGE', payload: newPage });

app/[locale]/(user)/components/Sectors.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useQuery } from '@tanstack/react-query'; // ✅ Ensure this is correct
1010
import { Button, Divider, Spinner, Text } from 'opub-ui';
1111

1212
import { GraphQL } from '@/lib/api';
13+
import { SectorListingSkeleton } from '@/components/loading';
1314

1415
const sectorDetails = graphql(`
1516
query SectorsList {
@@ -59,10 +60,10 @@ const Sectors = () => {
5960
</Button>
6061
</div>
6162
</div>
62-
{isLoading ? (
63-
<div className="m-4 flex justify-center">
64-
<Spinner />
65-
</div>
63+
{isLoading ? (
64+
<SectorListingSkeleton
65+
cardCount={9}
66+
/>
6667
) : (
6768
<div className="mt-6 lg:mt-12 grid w-full grid-cols-1 gap-6 px-4 md:grid-cols-2 md:px-12 lg:grid-cols-3 lg:px-12">
6869
{data?.activeSectors.map((sectors: any) => (

app/[locale]/(user)/components/UseCases.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { GraphQL } from '@/lib/api';
1919
import { cn, formatDate } from '@/lib/utils';
2020
import { Icons } from '@/components/icons';
2121
import Styles from './datasets.module.scss';
22+
import { UseCaseListingSkeleton } from '@/components/loading';
2223

2324
const useCasesListDoc: any = graphql(`
2425
query TopUseCases(
@@ -125,10 +126,11 @@ const UseCasesListingPage = () => {
125126
<Carousel className="flex w-full justify-between">
126127
<CarouselPrevious />
127128

128-
{getUseCasesList.isLoading ? (
129-
<div className="p-8">
130-
<Spinner />
131-
</div>
129+
{getUseCasesList.isLoading ? (
130+
<UseCaseListingSkeleton
131+
cardCount={3}
132+
cardsOnly={true}
133+
/>
132134
) : (
133135
<CarouselContent className="p-4 ">
134136
{getUseCasesList &&

app/[locale]/(user)/publishers/PublishersListingClient.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { cn, generateJsonLd } from '@/lib/utils';
1111
import BreadCrumbs from '@/components/BreadCrumbs';
1212
import JsonLd from '@/components/JsonLd';
1313
import PublisherCard from './PublisherCard';
14+
import { PublisherListingSkeleton } from '@/components/loading';
1415

1516
const getAllPublishers: any = graphql(`
1617
query PublishersList {
@@ -171,9 +172,7 @@ const PublishersListingPage = () => {
171172
</ButtonGroup>
172173
</div>
173174
{Details.isLoading ? (
174-
<div className="m-4 flex justify-center">
175-
<Spinner />
176-
</div>
175+
<PublisherListingSkeleton cardCount={9} />
177176
) : (
178177
Details.data &&
179178
Details.data.getPublishers.length > 0 && (

app/[locale]/(user)/sectors/SectorsListing.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import BreadCrumbs from '@/components/BreadCrumbs';
1818
import { ErrorPage } from '@/components/error';
1919
import JsonLd from '@/components/JsonLd';
2020
import Styles from '../datasets/dataset.module.scss';
21+
import { SectorListingSkeleton } from '@/components/loading';
2122

2223
const sectorsListQueryDoc: any = graphql(`
2324
query SectorsLists($order: SectorOrder, $filters: SectorFilter) {
@@ -191,9 +192,7 @@ const SectorsListing = () => {
191192
</div>
192193
</div>
193194
{isLoading ? (
194-
<div className="m-4 flex justify-center">
195-
<Spinner />
196-
</div>
195+
<SectorListingSkeleton cardCount={9} />
197196
) : data && data?.activeSectors?.length > 0 ? (
198197
<>
199198
<div className="grid w-full grid-cols-1 gap-10 md:grid-cols-2 lg:grid-cols-3">
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
/* ============================================
2+
FILE: components/loading/Skeleton/DatasetListingSkeleton/DatasetListingSkeleton.module.css
3+
============================================ */
4+
5+
.container {
6+
min-height: 100vh;
7+
background-color: var(--base-pure-white, #ffffff);
8+
}
9+
10+
/* Search Bar */
11+
.searchBar {
12+
height: 48px;
13+
width: 100%;
14+
background-color: #d1d5db;
15+
border-radius: 8px;
16+
}
17+
18+
/* Controls */
19+
.buttonGroup {
20+
height: 40px;
21+
width: 80px;
22+
background-color: #d1d5db;
23+
border-radius: 4px;
24+
}
25+
26+
.sortButton {
27+
height: 40px;
28+
width: 40px;
29+
background-color: #d1d5db;
30+
border-radius: 4px;
31+
}
32+
33+
.dropdown {
34+
height: 40px;
35+
width: 128px;
36+
background-color: #d1d5db;
37+
border-radius: 4px;
38+
}
39+
40+
.filterButton {
41+
height: 40px;
42+
width: 80px;
43+
background-color: #d1d5db;
44+
border-radius: 4px;
45+
}
46+
47+
/* Filter Sidebar */
48+
.filterSidebar {
49+
display: flex;
50+
width: 100%;
51+
flex-direction: column;
52+
padding: 1.5rem 1rem;
53+
background-color: var(--surface-default, #ffffff);
54+
border-radius: 16px;
55+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
56+
}
57+
58+
.filterHeader {
59+
display: flex;
60+
justify-content: space-between;
61+
margin-bottom: 1.25rem;
62+
}
63+
64+
.filterTitle {
65+
height: 20px;
66+
width: 64px;
67+
background-color: #d1d5db;
68+
border-radius: 4px;
69+
}
70+
71+
.resetButton {
72+
height: 20px;
73+
width: 48px;
74+
background-color: #d1d5db;
75+
border-radius: 4px;
76+
}
77+
78+
.filterList {
79+
display: flex;
80+
flex-direction: column;
81+
gap: 1.25rem;
82+
}
83+
84+
.filterItem {
85+
display: flex;
86+
width: 100%;
87+
align-items: center;
88+
gap: 0.5rem;
89+
padding: 0.75rem;
90+
background-color: #1f5f8d1a;
91+
border-radius: 4px;
92+
}
93+
94+
.filterLabel {
95+
height: 20px;
96+
width: 120px;
97+
background-color: #d1d5db;
98+
border-radius: 4px;
99+
}
100+
101+
/* Card - Default Vertical Layout */
102+
.card {
103+
display: flex;
104+
flex-direction: column;
105+
gap: 1rem;
106+
padding: 1.5rem;
107+
background-color: var(--surface-default, #ffffff);
108+
border-radius: 8px;
109+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
110+
}
111+
112+
/* Carousel Cards Container - NEW */
113+
.carouselContainer {
114+
display: flex;
115+
gap: 1rem;
116+
width: 100%;
117+
}
118+
119+
/* Carousel Card - Horizontal Layout for Homepage */
120+
.carouselCard {
121+
display: flex;
122+
flex-direction: column;
123+
gap: 1.25rem;
124+
padding: 2rem;
125+
background-color: var(--surface-default, #ffffff);
126+
border-radius: 8px;
127+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
128+
min-width: 480px;
129+
min-height: 320px;
130+
flex: 1;
131+
}
132+
133+
.cardTitle {
134+
height: 24px;
135+
width: 75%;
136+
background-color: #d1d5db;
137+
border-radius: 4px;
138+
}
139+
140+
/* Metadata */
141+
.metadataRow {
142+
display: flex;
143+
flex-wrap: wrap;
144+
align-items: center;
145+
gap: 0.75rem;
146+
}
147+
148+
.metadataItem {
149+
display: flex;
150+
align-items: center;
151+
gap: 0.5rem;
152+
}
153+
154+
.metadataIcon {
155+
height: 20px;
156+
width: 20px;
157+
background-color: #d1d5db;
158+
border-radius: 50%;
159+
}
160+
161+
.metadataText {
162+
height: 16px;
163+
width: 80px;
164+
background-color: #d1d5db;
165+
border-radius: 4px;
166+
}
167+
168+
.metadataTextSmall {
169+
height: 16px;
170+
width: 32px;
171+
background-color: #d1d5db;
172+
border-radius: 4px;
173+
}
174+
175+
.metadataTextMedium {
176+
height: 16px;
177+
width: 64px;
178+
background-color: #d1d5db;
179+
border-radius: 4px;
180+
}
181+
182+
/* Description */
183+
.descriptionLines {
184+
display: flex;
185+
flex-direction: column;
186+
gap: 0.5rem;
187+
}
188+
189+
.descriptionLine {
190+
height: 16px;
191+
width: 100%;
192+
background-color: #d1d5db;
193+
border-radius: 4px;
194+
}
195+
196+
.descriptionLineShort {
197+
height: 16px;
198+
width: 80%;
199+
background-color: #d1d5db;
200+
border-radius: 4px;
201+
}
202+
203+
/* Footer */
204+
.cardFooter {
205+
display: flex;
206+
align-items: center;
207+
gap: 0.75rem;
208+
padding-top: 1rem;
209+
margin-top: auto;
210+
border-top: 1px solid var(--border-default, #e5e7eb);
211+
}
212+
213+
.footerIcon {
214+
height: 32px;
215+
width: 32px;
216+
background-color: #d1d5db;
217+
border-radius: 50%;
218+
}

0 commit comments

Comments
 (0)