dashboard view done

This commit is contained in:
wayanrivan
2025-04-24 11:12:00 +07:00
parent fd251919b3
commit 552d1de84c
5 changed files with 250 additions and 34 deletions

View File

@ -0,0 +1,114 @@
import React, { useEffect, useState } from 'react';
import { UsersIcon, UserCheckIcon } from "lucide-react";
import { apiConfig } from '@/config/api.config';
import { useCallApi } from '@/hooks';
const API_URL = apiConfig.api_dashboard;
interface Props {
startdate: string;
enddate: string;
}
const MemberActivity = ({ startdate, enddate }: Props) => {
const { GetData } = useCallApi();
const [responseTransactionValue, setResponseTransactionValue] = useState<any>(null);
useEffect(() => {
const fetchDataTransactionValue = async () => {
try {
const res = await GetData(`${API_URL}/active-user`, {
date_from: startdate,
date_to: enddate,
});
setResponseTransactionValue(res);
} catch (error) {
console.error('Error fetching transaction value:', error);
}
};
fetchDataTransactionValue();
}, [startdate, enddate, GetData]);
const percentage = responseTransactionValue?.data?.total_customer_active_percentage ?? 0;
const totalCustomer = responseTransactionValue?.data?.total_customer ?? 0;
const activeCustomer = responseTransactionValue?.data?.total_customer_active ?? 0;
// Hitung sudut pointer
const angle = 180 - (percentage / 100) * 180; // 180° (kiri bawah) ke 0° (kanan bawah)
const radians = (angle * Math.PI) / 180; // Mengubah derajat ke radian
const radius = 40; // Radius dari setengah lingkaran
const center = 50; // Titik pusat lingkaran
const pointerLength = 25; // Panjang pointer
const x = center + pointerLength * Math.cos(radians);
const y = center + pointerLength * Math.sin(radians);
// Hitung titik akhir untuk arc aktif
const arcAngle = (Math.PI * percentage) / 100;
const arcX = 50 + radius * Math.cos(Math.PI - arcAngle);
const arcY = 50 - radius * Math.sin(arcAngle);
return (
<div className="p-6 bg-white rounded-lg shadow-md w-full max-w-xl">
<div className="flex justify-between items-center pb-3 mb-4">
<h2 className="text-lg font-semibold text-gray-700">Member Activity</h2>
</div>
<div className="flex gap-6">
{/* Sidebar */}
<ul className="space-y-4 w-1/2 text-gray-700 text-sm">
<li className="flex items-center gap-2">
<UsersIcon className="w-4 h-4" />
<span>Total Customer: {totalCustomer}</span>
</li>
<li className="flex items-center gap-2">
<UserCheckIcon className="w-4 h-4" />
<span>Active Customer: {activeCustomer}</span>
</li>
</ul>
{/* Gauge Chart */}
<div className="w-1/2">
<div className="border border-gray-200 rounded-md p-4 text-center">
<h3 className="text-sm text-gray-600 font-medium mb-2">Active User</h3>
<div className="relative h-24 w-full">
<svg className="w-full h-full" viewBox="0 0 100 50">
{/* Background arc */}
<path
d="M 10 50 A 40 40 0 0 1 90 50"
fill="none"
stroke="#e5e7eb"
strokeWidth="10"
/>
{/* Active arc */}
<path
d={`M 10 50 A 40 40 0 ${percentage > 50 ? 1 : 0} 1 ${arcX} ${arcY}`}
fill="none"
stroke="#34d399"
strokeWidth="10"
/>
{/* Pointer */}
<line
x1="50"
y1="50"
x2={x}
y2={y}
stroke="#111827"
strokeWidth="4"
strokeLinecap="round"
/>
</svg>
<div className="flex justify-between text-xs text-gray-500 px-1">
<span>{percentage}%</span>
<span>100%</span>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default MemberActivity;