Skip to content

Commit

Permalink
Merge pull request #43 from atlp-rwanda/187354242-seller-statistics
Browse files Browse the repository at this point in the history
Feature that allows seller to update and delete a product
  • Loading branch information
niyontwali authored Jul 25, 2024
2 parents 7113f8c + aabeedb commit 0cfb527
Show file tree
Hide file tree
Showing 23 changed files with 960 additions and 148 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
"@types/react-redux": "^7.1.33",
"apexcharts": "^3.49.1",
"axios": "^1.7.2",
"chart.js": "^4.4.3",
"clsx": "^2.1.1",
"jwt-decode": "^4.0.0",
"react": "^18.2.0",
"react-apexcharts": "^1.4.1",
"react-chartjs-2": "^5.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.5",
"react-icons": "^5.2.1",
Expand Down
24 changes: 13 additions & 11 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ import Category from './pages/admin/Category';
import Sellers from './pages/admin/Sellers';
import Buyers from './pages/admin/Buyers';
import UserManagement from './pages/admin/UserManagement';
import NotFoundPage from './pages/NotFoundPage';
import SellerSettings from './pages/seller/Settings';
import SellersPage from './pages/seller';
import Orders from './pages/seller/Orders';
import Products from './pages/seller/Products';
import Customers from './pages/seller/Customers';
Expand All @@ -37,22 +35,26 @@ import PaymentSuccessCard from './components/checkout/PaymentSuccessCard';
import PaymentPage from './pages/PaymentPage';
import { useSelector } from 'react-redux';
import { RootState } from './redux/store';
import { SellerDashboard } from './pages/seller';
import { ErrorPage } from './pages/ErrorPage';
import EditProduct from './pages/seller/EditProduct';

import BuyerRestrictedRoutes from './containers/buyer/BuyerRestrictedRoutes';
const App = () => {
const isAuthenticated = useSelector((state: RootState) => state.user.token);
const dispatch = useDispatch();
useEffect(() => {
dispatch<any>(productsApi.endpoints.getProducts.initiate())
dispatch<any>(productsApi.endpoints.getProducts.initiate());
if (isAuthenticated) {
dispatch<any>(cartApi.endpoints.getCarts.initiate());
console.log("Cart")
console.log('Cart');
}
}, [dispatch]);

const router = createBrowserRouter([
{
path: '/',
errorElement: <ErrorPage />,
children: [
{
index: true,
Expand Down Expand Up @@ -109,7 +111,7 @@ const App = () => {
{
path: 'buyer-profile',
element: <BuyerRestrictedRoutes role='buyer' />,
}
},
],
},
{
Expand Down Expand Up @@ -159,7 +161,7 @@ const App = () => {
children: [
{
index: true,
element: <SellersPage />,
element: <SellerDashboard />,
},
{
path: 'orders',
Expand All @@ -170,9 +172,13 @@ const App = () => {
element: <Products />,
},
{
path: 'add-new-product',
path: 'products/add-new-product',
element: <AddNewProduct />,
},
{
path: 'products/edit-product/:id',
element: <EditProduct />,
},
{
path: 'customers',
element: <Customers />,
Expand All @@ -187,10 +193,6 @@ const App = () => {
path: 'search',
element: <Searchpage />,
},
{
path: '*',
element: <NotFoundPage />,
},
]);
return (
<>
Expand Down
10 changes: 10 additions & 0 deletions src/assets/face-id-error.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions src/components/dashboard/AreaChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { useEffect } from 'react';
import { Line } from 'react-chartjs-2';
import { Chart, ChartData, ChartOptions } from 'chart.js/auto';

const AreaChart: React.FC = () => {
const data: ChartData<'line'> = {
labels: ['Jan', 'Feb', 'Mar', 'April', 'May', 'June', 'July', 'August', 'Sept', 'Oct', 'Nov', 'Dec'],
datasets: [
{
label: 'Yearly sales',
data: [200, 300, 1700, 400, 300, 200, 100, 100, 100, 50, 50],
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: '#0E9CFF',
fill: true,
borderWidth: 2,
},
],
};

const options: ChartOptions<'line'> = {
responsive: true,
maintainAspectRatio: false,
};

useEffect(() => {
return () => {
Object.values(Chart.instances).forEach(instance => instance.destroy());
};
}, []);

return <Line data={data} options={options} />;
};

export default AreaChart;
55 changes: 55 additions & 0 deletions src/components/dashboard/BarChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// BarChart.tsx
import React from 'react';
import { Bar } from 'react-chartjs-2';
import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, ChartOptions } from 'chart.js';
import { ChartData } from 'chart.js/auto';

ChartJS.register(CategoryScale, LinearScale, BarElement);

const BarChart: React.FC = () => {
const data: ChartData<'bar'> = {
labels: ['', '', '', '', '', ''],
datasets: [
{
data: [65, 59, 80, 81, 56, 55],
backgroundColor: '#1877F2',
borderRadius: 5, // No border radius
},
],
};

const options: ChartOptions<'bar'> = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
},
tooltip: {
enabled: false,
},
},
scales: {
x: {
display: false,
grid: {
display: false,
},
},
y: {
display: false,
grid: {
display: false,
},
},
},
};

return (
<div style={{ height: '100%', width: '100%' }}>
<Bar data={data} options={options} />
</div>
);
};

export default BarChart;
2 changes: 1 addition & 1 deletion src/components/dashboard/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function Navbar({ location, page }: { location: string; page: str

return (
<div
className={`md:ml-64 flex justify-between items-center sticky top-0 ${page === 'admin' ? 'bg-[#D3E4DE]' : 'bg-[#EFF4FE]'} px-6`}
className={`md:ml-64 flex justify-between items-center sticky top-0 ${page === 'admin' ? 'bg-[#D3E4DE]' : 'bg-[#EFF4FE]'} px-6 z-10`}
>
<h1 className='text-2xl font-normal'>{location}</h1>
<div className='flex items-center'>
Expand Down
18 changes: 18 additions & 0 deletions src/components/dashboard/StatisticsCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import BarChart from './BarChart';

export const StatisticsCard = () => {
return (
<div className='flex md:flex-1 items-center justify-between bg-[#F9F9F9] px-3 py-5 rounded-lg border border-grayColor mb-2'>
<div className='w-1/2 space-y-1'>
<p>New Products</p>
<p className='font-medium'>2,300</p>
<p className='text-sm'>
<span className='text-greenColor'>12.5%</span> since last month
</p>
</div>
<div className='h-20 w-1/2'>
<BarChart />
</div>
</div>
);
};
121 changes: 121 additions & 0 deletions src/components/dashboard/Table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import React from 'react';
import { Transaction } from '../../types/Types';

const transactions: Transaction[] = [
{
reference: '18342342342343',
customer: 'John doe',
product: 'T-shirts',
date: '10 Mar, 4:32 am',
status: 'Delivered',
price: '$100',
},
{
reference: '18342342342343',
customer: 'John doe',
product: 'T-shirts',
date: '10 Mar, 4:32 am',
status: 'Canceled',
price: '$100',
},
{
reference: '18342342342343',
customer: 'John doe',
product: 'T-shirts',
date: '10 Mar, 4:32 am',
status: 'Pending',
price: '$100',
},
{
reference: '18342342342343',
customer: 'John doe',
product: 'T-shirts',
date: '10 Mar, 4:32 am',
status: 'In review',
price: '$100',
},
{
reference: '18342342342343',
customer: 'John doe',
product: 'T-shirts',
date: '10 Mar, 4:32 am',
status: 'Pending',
price: '$100',
},
{
reference: '18342342342343',
customer: 'John doe',
product: 'T-shirts',
date: '10 Mar, 4:32 am',
status: 'In review',
price: '$100',
},
{
reference: '18342342342343',
customer: 'John doe',
product: 'T-shirts',
date: '10 Mar, 4:32 am',
status: 'In review',
price: '$100',
},
];

const statusColors: { [key: string]: string } = {
'Delivered': 'bg-[#d1fae5] text-[#065f46]',
'Canceled': 'bg-[#fee2e2] text-[#991b1b]',
'Pending': 'bg-[#e9d5ff] text-[#6b21a8]',
'In review': 'bg-[#fef3c7] text-[#854d0e]',
};

const TransactionTable: React.FC = () => {
return (
<div className='mt-3'>
<div className='bg-[#ffffff] shadow-md rounded-lg p-6 border border-grayColor'>
<div className='mb-4'>
<h2 className='text-lg font-semibold'>Transactions</h2>
<p className='text-sm text-[#6b7280]'>List of latest transactions</p>
</div>
<div className='overflow-x-auto'>
<table className='min-w-full bg-[#ffffff]'>
<thead>
<tr>
<th className='px-4 py-2 border-b border-[#e5e7eb] text-start'>REFERENCE NUMBER</th>
<th className='px-4 py-2 border-b border-[#e5e7eb] text-start'>CUSTOMER</th>
<th className='px-4 py-2 border-b border-[#e5e7eb] text-start'>PRODUCT</th>
<th className='px-4 py-2 border-b border-[#e5e7eb] text-start'>DATE</th>
<th className='px-4 py-2 border-b border-[#e5e7eb] text-start'>STATUS</th>
<th className='px-4 py-2 border-b border-[#e5e7eb] text-start'>PRICE</th>
</tr>
</thead>
<tbody>
{transactions.map((transaction, index) => (
<tr key={index}>
<td className='px-4 py-2 border-b border-[#e5e7eb] font-light'>{transaction.reference}</td>
<td className='px-4 py-2 border-b border-[#e5e7eb] font-light'>{transaction.customer}</td>
<td className='px-4 py-2 border-b border-[#e5e7eb] font-light'>{transaction.product}</td>
<td className='px-4 py-2 border-b border-[#e5e7eb] font-light'>{transaction.date}</td>
<td className='px-4 py-2 border-b border-[#e5e7eb] font-light'>
<span className={`px-2 py-1 rounded-full text-xs font-medium ${statusColors[transaction.status]}`}>
{transaction.status}
</span>
</td>
<td className='px-4 py-2 border-b border-[#e5e7eb] font-light'>{transaction.price}</td>
</tr>
))}
</tbody>
</table>
</div>
<div className='mt-4 flex justify-between'>
<div>
<button className='text-sm text-[#6b7280]'>Last 7 days</button>
</div>
<div>
<button className='text-[#3b82f6] text-sm font-medium'>Full Report</button>
</div>
</div>
</div>
</div>
);
};

export default TransactionTable;
21 changes: 21 additions & 0 deletions src/components/dashboard/TopSellingProductCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const TopSellingProductCard = () => {
return (
<div className='flex justify-between items-center bg-[#F9F9F9] shadow-sm p-1'>
<div className='flex gap-2 items-center mt-3'>
<img
className='w-12 h-10 rounded-sm'
src='https://images.unsplash.com/photo-1703434123142-1b41a1b1055b?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
></img>
<div>
<div>
<p className='font-semibold text-sm'>iPhone 14 Pro</p>
<p className='text-xs'>
<span className='text-[#0E9F6E]'>12.5%</span> <span className='text-[#8F8183]'>vs last month</span>
</p>
</div>
</div>
</div>
<p className='font-bold'>$445,557</p>
</div>
);
};
Loading

0 comments on commit 0cfb527

Please sign in to comment.