Skip to content

Commit

Permalink
Maakaf#246 - Initial commit - Adding skeleton loading spinner in memb…
Browse files Browse the repository at this point in the history
…ers page as described in Figma
  • Loading branch information
develad committed Apr 1, 2024
1 parent 56b870c commit 0270c7e
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 7 deletions.
6 changes: 3 additions & 3 deletions actions/fetchFilteredMemebers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ export const fetchFilteredMembers = async (term: string) => {
longDescription: dummyMember.longDescription,
joinDate: dummyMember.joinDate,
isAdmin: dummyMember.isAdmin,
linkedInUrl: linkedIn || '',
githubUrl: github || '',
twitterUrl: '',
linkedInUrl: linkedIn || '#/',
githubUrl: github || '#/',
twitterUrl: '#/',
_id: _id || '',
meta: meta || {},
timestamp: timestamp || '',
Expand Down
13 changes: 11 additions & 2 deletions app/[locale]/members/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useTranslations } from 'next-intl';
import useTextDirection from '@/hooks/useTextDirection';
import Magnifier from '@/components/SvgCmps/Magnifier';
import classNames from 'classnames';
import SkeletonCards from '@/components/Members/Skeleton/SkeletonCards';

const WelcomeMessage = () => {
const t = useTranslations('Members');
Expand Down Expand Up @@ -48,6 +49,12 @@ const MembersPage: React.FC<{}> = ({}) => {
return () => clearTimeout(timeoutId);
}, [searchTerm]);

const notFoundJSX = (
<p className="mt-8 text-2xl md:text-4xl font-bold text-center text-red-400">
{t('noMemberFound')}
</p>
);

return (
<div className="py-6" dir={direction}>
<h1 className="text-center leading-[1.2]">{t('title')}</h1>
Expand All @@ -66,7 +73,7 @@ const MembersPage: React.FC<{}> = ({}) => {
<div className="w-full relative h-[45px]">
<input
type="text"
name={searchTerm}
name="searchTerm"
className="px-4 top-0 right-0 w-full h-full bg-purple-100 dark:bg-gray-800 rounded-r-3xl rounded-l-3xl"
placeholder={t('searchPlaceholder')}
onChange={e => setSearchTerm(e.target.value)}
Expand All @@ -79,7 +86,9 @@ const MembersPage: React.FC<{}> = ({}) => {
/>
</div>
</div>
<MembersList members={members} />
{members.length === 0 && searchTerm === '' && <SkeletonCards cards={6} />}
{members.length === 0 && searchTerm !== '' && notFoundJSX}
{members.length !== 0 && <MembersList members={members} />}
</div>
);
};
Expand Down
28 changes: 28 additions & 0 deletions components/Members/Skeleton/SkeletonCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Skeleton } from '@/components/ui/skeleton';

const SkeletonCard = () => {
return (
<Skeleton className="flex bg-purple-100 dark:bg-gray-600 rounded-2xl shadow-md w-full xl:w-[400px] xl:h-[173px]">
<div className="flex flex-col rounded-md p-[10px] pr-6 w-full">
<div className="flex gap-4">
<Skeleton className="w-[50px] h-[50px] rounded-full bg-purple-200 dark:bg-slate-100/50" />
<div className="titles-container">
<div className="flex items-center">
<Skeleton className="ml-4 h-4 w-20 bg-purple-200 dark:bg-slate-100/50" />
</div>
<Skeleton className="mt-2 w-[150px] h-4 bg-purple-200 dark:bg-slate-100/50" />
</div>
</div>
<Skeleton className="w-10/12 md:w-[291px] h-[51px] mt-2 mb-1 bg-purple-200 dark:bg-slate-100/50" />
<Skeleton className="w-[100px] h-[15px] mt-2 bg-purple-200 dark:bg-slate-100/50" />
</div>
<div className="flex flex-col items-center w-[67px] bg-purple-200 justify-evenly dark:bg-gray-800 rounded-tl-2xl rounded-bl-2xl shadow-2xl">
<Skeleton className="w-[30px] h-[30px] rounded-full bg-purple-100 dark:bg-slate-100/50" />
<Skeleton className="w-[30px] h-[30px] rounded-full bg-purple-100 dark:bg-slate-100/50" />
<Skeleton className="w-[30px] h-[30px] rounded-full bg-purple-100 dark:bg-slate-100/50" />
</div>
</Skeleton>
);
};

export default SkeletonCard;
17 changes: 17 additions & 0 deletions components/Members/Skeleton/SkeletonCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import SkeletonCard from './SkeletonCard';

const SkeletonCards = ({ cards = 6 }: { cards?: number }) => {
const cardsToRender = Array(cards)
.fill(null)
.map((_, i) => i);
return (
<div className="flex mx-auto w-[90%] flex-wrap gap-4 mt-6 justify-between">
{cardsToRender.map(card => (
<SkeletonCard key={card} />
))}
</div>
);
};

export default SkeletonCards;
18 changes: 18 additions & 0 deletions components/ui/skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { cn } from '@/lib/utils/tailwind/cn';

function Skeleton({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn(
'animate-pulse rounded-md bg-purple-100 dark:bg-gray-600',
className
)}
{...props}
/>
);
}

export { Skeleton };
3 changes: 3 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const createNextIntlPlugin = require('next-intl/plugin');
const withNextIntl = createNextIntlPlugin('./app/i18n.ts');

const nextConfig = {
experimental: {
serverActions: true,
},
eslint: {
dirs: ['app', 'components'],
},
Expand Down
3 changes: 2 additions & 1 deletion public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@
"startOfActivity": "Start of activity",
"searchPlaceholder": "Search by name, role",
"secondOption": "Second option",
"thirdOption": "Third option"
"thirdOption": "Third option",
"noMemberFound": "No Member found"
},
"Components": {
"home": {
Expand Down
3 changes: 2 additions & 1 deletion public/locales/he.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@
"startOfActivity": "תחילת פעילות",
"searchPlaceholder": "חפש לפי שם תפקיד...",
"secondOption": "אופציה שניה",
"thirdOption": "אופציה שלישית"
"thirdOption": "אופציה שלישית",
"noMemberFound": "המשתמש לא נמצא"
},
"Components": {
"home": {
Expand Down

0 comments on commit 0270c7e

Please sign in to comment.