Skip to content

Commit

Permalink
Merge pull request #44 from roziqinkhoeru/main
Browse files Browse the repository at this point in the history
`feat(dashboard)` update dashboard features
  • Loading branch information
roziqinkhoeru authored Mar 11, 2024
2 parents c848433 + c1e1c92 commit 8e25e84
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 143 deletions.
142 changes: 0 additions & 142 deletions src/pages/Home.tsx

This file was deleted.

80 changes: 80 additions & 0 deletions src/pages/Home/components/PerformanceWidget.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
Gamepad2Icon,
GraduationCapIcon,
SchoolIcon,
UserIcon,
} from 'lucide-react';
import { getPercentage } from '../../../utilities/numberUtils';

import type { PerformanceWidgetProps, WidgetIconType } from '../../../types';

function PerformanceWidget({
type,
countItem,
activeItem,
name,
children,
}: PerformanceWidgetProps) {
const widgetIcon: WidgetIconType = {
permainan: (
<Gamepad2Icon
size={24}
className="dark:stroke-gray-200"
/>
),
sekolah: (
<SchoolIcon
size={24}
className="dark:stroke-gray-200"
/>
),
admin: (
<UserIcon
size={24}
className="dark:stroke-gray-200"
/>
),
siswa: (
<GraduationCapIcon
size={24}
className="dark:stroke-gray-200"
/>
),
};

return (
<div className="bg-white p-5 rounded-xl dark:bg-gray-800">
<div className={type === 'advanced' ? 'flex justify-between' : ''}>
<div className="flex size-10 rounded-lg dark:bg-gray-700/70 items-center justify-center mb-8">
{widgetIcon[name as keyof WidgetIconType]}
</div>
{type === 'advanced' && (
<div className="text-right">
<p className="font-medium dark:text-gray-200 text-right text-2xl">
{getPercentage(activeItem, countItem)}
</p>
<p className="text-xs dark:text-gray-400">
{activeItem} {name} aktif
</p>
</div>
)}
</div>
<div className={type === 'advanced' ? 'grid grid-cols-2 gap-x-3' : ''}>
<div className="">
<h5 className="dark:text-gray-400 mb-1 capitalize">
Performa {name}
</h5>
<p className="dark:text-gray-100 text-2xl">
{countItem}{' '}
<span className="text-lg dark:text-gray-400">
{name === 'admin' || name === 'siswa' ? 'orang' : 'item'}
</span>
</p>
</div>
{type === 'advanced' && <div className="">{children}</div>}
</div>
</div>
);
}

export default PerformanceWidget;
94 changes: 94 additions & 0 deletions src/pages/Home/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { useEffect } from 'react';
import { useAppDispatch } from '../../app/hooks';
import { useGetDashboardQuery } from '../../services/dashboardApi';
import { setBreadcrumb } from '../../features/breadcrumbSlice';
import { showErrorToast } from '../../components/Toast';
import Breadcrumb from '../../components/Breadcrumb';
import PerformanceWidget from './components/PerformanceWidget';

import type { Game, School } from '../../types';

function Home() {
const dispatch = useAppDispatch();
const {
data: dashboards,
isLoading,
isSuccess,
isError,
} = useGetDashboardQuery();

if (isError) {
showErrorToast('Gagal memuat data');
}

useEffect(() => {
dispatch(setBreadcrumb([]));
}, [dispatch]);

return (
<div className="">
<div className="mb-6">
<Breadcrumb />
<h5 className="font-semibold text-3xl mb-1.5">Home (Test)</h5>
<p className="text-gray-500">Selamat datang di Dashboard Gameon.</p>
</div>
<div className="grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 mb-6 gap-4">
<PerformanceWidget
countItem={dashboards?.data?.gameCount}
name="permainan"
type="simple"
/>
<PerformanceWidget
countItem={dashboards?.data?.schoolCount}
name="sekolah"
type="simple"
/>
<PerformanceWidget
activeItem={dashboards?.data?.activeAdmin}
countItem={dashboards?.data?.adminCount}
name="admin"
type="advanced"></PerformanceWidget>
<PerformanceWidget
activeItem={dashboards?.data?.activeStudents}
countItem={dashboards?.data?.studentsCount}
name="siswa"
type="advanced"></PerformanceWidget>
</div>
<div className="bg-white p-5 rounded-xl dark:bg-gray-800">
{isLoading && <p>Loading...</p>}
{isSuccess && (
<div className="mb-12">
<h3 className="mb-4 text-lg font-semibold">Permainan</h3>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
{dashboards?.data?.games?.map((game: Game) => (
<div
key={game._id}
className="bg-gray-100 p-4 rounded-lg dark:bg-gray-700">
<h5 className="mb-2 text-lg font-semibold">{game.name}</h5>
<p className="text-gray-400">{game.description}</p>
</div>
))}
</div>
</div>
)}
{isSuccess && (
<div className="mb-3">
<h3 className="mb-4 text-lg font-semibold">Sekolah</h3>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
{dashboards?.data?.schools?.map((school: School) => (
<div
key={school._id}
className="bg-gray-100 p-4 rounded-lg dark:bg-gray-700">
<h5 className="mb-2 text-lg font-semibold">{school.name}</h5>
<p className="text-gray-400">{school.address}</p>
</div>
))}
</div>
</div>
)}
</div>
</div>
);
}

export default Home;
9 changes: 9 additions & 0 deletions src/types/componentType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ interface ModalDisplayProps {
title: string;
}

interface PerformanceWidgetProps {
activeItem?: number;
countItem: number | undefined;
children?: ReactNode;
name: string;
type: 'simple' | 'advanced';
}

export type {
AlertDialogProps,
Breadcrumb,
Expand All @@ -110,6 +118,7 @@ export type {
HeaderContainerProps,
HeaderProfileProps,
ModalDisplayProps,
PerformanceWidgetProps,
ProfileUserProps,
ScoreTableProps,
StudentTableProps,
Expand Down
13 changes: 12 additions & 1 deletion src/types/utilitiesType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,16 @@ interface NormalizedScore {
interface NormalizeScoreChartDataEntry {
[key: string]: number | string;
}
interface WidgetIconType {
permainan: JSX.Element;
sekolah: JSX.Element;
admin: JSX.Element;
siswa: JSX.Element;
}

export type { NormalizedScore, NormalizeScoreChartDataEntry, ThemeState };
export type {
NormalizedScore,
NormalizeScoreChartDataEntry,
ThemeState,
WidgetIconType,
};

0 comments on commit 8e25e84

Please sign in to comment.