Skip to content

Commit

Permalink
Merge pull request #233 from Sahil-Connect/SAH-118
Browse files Browse the repository at this point in the history
[SAH-118]: Add Reports Page
  • Loading branch information
Emmanuel-Melon authored Dec 16, 2024
2 parents adba75e + 1e3ee04 commit bf3f97e
Show file tree
Hide file tree
Showing 17 changed files with 1,347 additions and 278 deletions.
File renamed without changes.
2 changes: 2 additions & 0 deletions apps/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@
"next-auth-hasura-adapter": "^2.0.0",
"postcss": "8.4.28",
"react": "^18.3.1",
"react-day-picker": "8.10.0",
"react-dom": "^18.3.1",
"react-hook-form": "^7.45.4",
"react-hot-toast": "^2.4.1",
"react-icons": "^4.12.0",
"recharts": "^2.15.0",
"subscriptions-transport-ws": "^0.11.0",
"swr": "^2.2.1",
"tailwindcss": "3.3.3",
Expand Down
12 changes: 6 additions & 6 deletions apps/client/src/Layout/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
HiOutlineBuildingOffice,
HiOutlineCube,
HiOutlineCreditCard,
HiOutlineDocumentChartBar,
} from "react-icons/hi2";

const links = [
Expand All @@ -31,16 +32,15 @@ const links = [
href: "/account",
icon: HiOutlineUserCircle,
},
{

name: "Billing",
href: "/billing",
icon: HiOutlineCreditCard,
},
{
name: "Inventory",
href: "/inventory",
icon: HiOutlineCube
},
{
name: "Reports",
href: "/reports",
icon: HiOutlineDocumentChartBar
}
];

Expand Down
279 changes: 170 additions & 109 deletions apps/client/src/pages/account/index.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,87 @@
import {
BusinessProfileOverview,
BusinessOrderHistory,
} from "@sahil/features/businesses";
// import { useGetAccountBalance, useGetMomoAccountInfo } from "@/hooks/accounts";
import { useFetchBusinessByPK } from "@sahil/lib/hooks/businesses";
import { Card, JoinGrid } from "ui";
import { useState } from "react";
import {
"use client"

import { useState } from "react"
import { Card, JoinGrid } from "ui"
import {
HiOutlineCurrencyDollar,
HiOutlineCreditCard,
HiOutlineDocumentText,
HiPlus,
HiArrowSmallLeft,
HiArrowSmallRight,
HiOutlineMinusCircle,
HiOutlineXCircle,
HiOutlineCheckCircle,
} from "react-icons/hi2";
import { formatDateTime } from "@sahil/lib/dates";
import { formatCurrency } from "@sahil/lib";
HiOutlineCheckCircle
} from "react-icons/hi2"
import { formatDateTime } from "@sahil/lib/dates"
import { formatCurrency } from "@sahil/lib"
import { BusinessProfileOverview } from "@sahil/features/businesses"
import { useFetchBusinessByPK } from "@sahil/lib/hooks/businesses"

export default function Account() {
const {
data: business,
error,
loading,
} = useFetchBusinessByPK("e87924e8-69e4-4171-bd89-0c8963e03d08");
const PaymentMethodCard = ({ method, isPreferred, onEdit, onSetPreferred }) => (
<Card className="mb-4">
<div className="flex items-center justify-between p-2">
<div>
<span className="font-medium">{method.type} ending in {method.last4}</span>
{isPreferred && <span className="ml-2 text-sm text-green-600">Preferred</span>}
</div>
<div>
<button onClick={onEdit} className="text-blue-600 hover:underline mr-2">Edit</button>
{!isPreferred && (
<button onClick={onSetPreferred} className="text-green-600 hover:underline">Set as Preferred</button>
)}
</div>
</div>
</Card>
)

if (error) {
return <p>An error occurred while fetching you account details!</p>;
const TransactionCard = ({ transaction }) => {
const cardIcon = (status: string) => {
switch (status) {
case "Pending":
return <HiOutlineMinusCircle className="text-3xl" />
case "Canceled":
return <HiOutlineXCircle className="text-4xl text-error" />
case "Confirmed":
return <HiOutlineCheckCircle className="text-3xl text-success" />
default:
return null
}
}

return (
<div className="space-y-4">
<div className="flex flex-col gap-1 lg:gap-4 lg:flex-row">
<div className="grow mb-4 lg:mb-0 space-y-2">
{
// @ts-ignore
business && <BusinessProfileOverview business={business} />
}
<Card>
<div className="flex items-center gap-4 p-4">
<div className="grid place-items-center">
{cardIcon(transaction.status)}
</div>
<div className="basis-4/5 space-y-2">
<BusinessOrderHistory />
<TransactionsHistory />
<div className="w-full space-y-2">
<time className="text-sm">
{formatDateTime(transaction.date.toISOString())}
</time>
<div className="flex justify-between items-center">
<div>
<p className="text-gray-400 text-sm">Method</p>
<p>{transaction.method}</p>
</div>
<div>
<p className="text-gray-400 text-sm">Amount</p>
<p>{formatCurrency(transaction.amount)}</p>
</div>
</div>
</div>
</div>
</div>
);
</Card>
)
}

const TransactionsHistory = () => {
export default function BillingDashboard() {
const [paymentMethods, setPaymentMethods] = useState([
{ id: 1, type: 'Visa', last4: '1234' },
{ id: 2, type: 'Mastercard', last4: '5678' },
])
const [preferredMethodId, setPreferredMethodId] = useState(1)

const transactions = [
{
amount: 1000,
Expand All @@ -71,89 +107,114 @@ const TransactionsHistory = () => {
status: "Confirmed",
method: "Cash",
},
];
]

const handleAddPaymentMethod = () => {
// Implement add payment method logic
}

const handleEditPaymentMethod = (id) => {
// Implement edit payment method logic
}

const handleSetPreferred = (id) => {
setPreferredMethodId(id)
}

const {
data: business,
error,
loading,
} = useFetchBusinessByPK("e87924e8-69e4-4171-bd89-0c8963e03d08")

if (error) {
return <p>An error occurred while fetching your account details!</p>
}

if (loading) {
return <p>Loading...</p>
}

return (
<div className="bg-gray-100 space-y-2 grow p-4 rounded-xl">
<div className="flex justify-between items-center">
<h3 className="text-xl">Latest Transactions</h3>
</div>
<div className="flex items-center justify-between">
<div className="flex gap-2 items-center">
<div className="badge badge-accent">4 Transactions</div>
</div>
<div>
<JoinGrid>
<button
className="join-item btn btn-sm"
title="Left"
onClick={() => {}}
>
<HiArrowSmallLeft />
</button>
<div className="max-w-7xl mx-auto space-y-6">

<div className="flex flex-col lg:flex-row gap-6">
<div className="lg:w-1/3 space-y-6">
{business && <BusinessProfileOverview business={business} />}

<section>
<h2 className="text-xl font-semibold mb-4 flex items-center">
<HiOutlineCreditCard className="mr-2" /> Payment Methods
</h2>
{paymentMethods.map((method) => (
<PaymentMethodCard
key={method.id}
method={method}
isPreferred={method.id === preferredMethodId}
onEdit={() => handleEditPaymentMethod(method.id)}
onSetPreferred={() => handleSetPreferred(method.id)}
/>
))}
<button
className="join-item btn btn-sm"
title="Right"
onClick={() => {}}
onClick={handleAddPaymentMethod}
className="btn btn-primary w-full flex items-center justify-center"
>
<HiArrowSmallRight />
<HiPlus className="mr-2" /> Add Payment Method
</button>
</JoinGrid>
</div>
</div>
<div className={`grid grid-cols-auto-250 xl:grid-cols-4 gap-2`}>
{transactions.map((item, index) => (
<TransactionCard key={index} transaction={item} />
))}
</div>
</div>
);
};

type cardProps = {
transaction: {
amount: number;
date: Date;
status: string;
method: string;
};
};

const TransactionCard = ({ transaction }: cardProps) => {
const cardIcon = (status: string) => {
switch (status) {
case "Pending":
return <HiOutlineMinusCircle className="text-3xl " />;
break;
case "Canceled":
return <HiOutlineXCircle className="text-4xl text-error" />;
break;
case "Confirmed":
return <HiOutlineCheckCircle className="text-3xl text-success" />;
}
};
</section>

return (
<Card>
<div className="flex items-center gap-4">
<div className="grid place-items-center">
{cardIcon(transaction.status)}
<section className="space-y-4">
<h2 className="text-xl font-semibold flex items-center">
<HiOutlineCurrencyDollar className="mr-2" /> Summary
</h2>
<Card className="p-4">
<div className="grid gap-4">
<div>
<span className="block text-sm font-medium text-gray-500">Total Earned</span>
<span className="text-2xl font-bold">$1,234.56</span>
</div>
<div>
<span className="block text-sm font-medium text-gray-500">Total Spent</span>
<span className="text-2xl font-bold">$567.89</span>
</div>
</div>
</Card>
</section>
</div>
<div className="w-full space-y-2">
<time className="text-sm">
{formatDateTime(transaction.date.toISOString())}
</time>
<div className="flex justify-between items-center">
<div>
<p className="text-gray-400 text-sm">Method</p>
<p>{transaction.method}</p>

<div className="lg:w-2/3">
<div className="bg-gray-100 space-y-4 p-4 rounded-xl">
<div className="flex justify-between items-center">
<h2 className="text-xl font-semibold flex items-center">
<HiOutlineDocumentText className="mr-2" /> Latest Transactions
</h2>
</div>
<div>
<p className="text-gray-400 text-sm">Amount</p>
<p>{formatCurrency(transaction.amount)}</p>

<div className="flex items-center justify-between">
<div className="flex gap-2 items-center">
<div className="badge badge-accent">{transactions.length} Transactions</div>
</div>
<div>
<JoinGrid>
<button className="join-item btn btn-sm" title="Previous">
<HiArrowSmallLeft />
</button>
<button className="join-item btn btn-sm" title="Next">
<HiArrowSmallRight />
</button>
</JoinGrid>
</div>
</div>

<div className="grid gap-4 sm:grid-cols-2">
{transactions.map((transaction, index) => (
<TransactionCard key={index} transaction={transaction} />
))}
</div>
</div>
</div>
</div>
</Card>
);
};
</div>
)
}

9 changes: 2 additions & 7 deletions apps/client/src/pages/inventory/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useRouter } from 'next/router';
import { formatDateTime } from "@sahil/lib/dates";
import BusinessInventoryHeader from '@sahil/features/Inventory/BusinessInventoryHeader';
import FilterPanel from '@sahil/features/Inventory/FilterPanel';
import { CollectionControls } from "@sahil/features/Shared/CollectionControls";

interface ProductsTableProps {
products: any[];
Expand Down Expand Up @@ -172,13 +173,7 @@ export default function InventoryPage() {

return (
<div className="flex flex-col h-screen">
<BusinessInventoryHeader
suppliers={suppliers}
activeSupplier={activeSupplier}
onSupplierSelect={switchSupplier}
isLoading={suppliersLoading}
onAddProduct={handleAddProduct}
/>
<CollectionControls user={currentUser} />

<div className="flex flex-1 overflow-hidden">
<FilterPanel
Expand Down
Loading

0 comments on commit bf3f97e

Please sign in to comment.