This commit is contained in:
alorig
2025-12-05 13:56:48 +05:00
parent 5b9d1dcfb0
commit 878ec612f8
3 changed files with 45 additions and 33 deletions

View File

@@ -3,6 +3,7 @@ import { useToast } from '../../components/ui/toast/ToastContainer';
import { getCreditTransactions, getCreditBalance, CreditTransaction as BillingTransaction, CreditBalance } from '../../services/billing.api'; import { getCreditTransactions, getCreditBalance, CreditTransaction as BillingTransaction, CreditBalance } from '../../services/billing.api';
import { Card } from '../../components/ui/card'; import { Card } from '../../components/ui/card';
import Badge from '../../components/ui/badge/Badge'; import Badge from '../../components/ui/badge/Badge';
import { CompactPagination } from '../ui/pagination';
// Credit costs per operation (copied from Billing usage page) // Credit costs per operation (copied from Billing usage page)
const CREDIT_COSTS: Record<string, { cost: number | string; description: string }> = { const CREDIT_COSTS: Record<string, { cost: number | string; description: string }> = {
@@ -22,6 +23,8 @@ export default function BillingUsagePanel() {
const [transactions, setTransactions] = useState<BillingTransaction[]>([]); const [transactions, setTransactions] = useState<BillingTransaction[]>([]);
const [balance, setBalance] = useState<CreditBalance | null>(null); const [balance, setBalance] = useState<CreditBalance | null>(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
useEffect(() => { useEffect(() => {
loadUsage(); loadUsage();
@@ -43,6 +46,9 @@ export default function BillingUsagePanel() {
} }
}; };
const totalPages = Math.max(1, Math.ceil(transactions.length / pageSize));
const paginated = transactions.slice((page - 1) * pageSize, page * pageSize);
if (loading) { if (loading) {
return ( return (
<div className="p-4"> <div className="p-4">
@@ -123,7 +129,7 @@ export default function BillingUsagePanel() {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{transactions.map((txn) => ( {paginated.map((txn) => (
<tr key={txn.id} className="border-b border-gray-100 dark:border-gray-800"> <tr key={txn.id} className="border-b border-gray-100 dark:border-gray-800">
<td className="py-3 px-4 text-sm text-gray-900 dark:text-white">{new Date(txn.created_at).toLocaleString()}</td> <td className="py-3 px-4 text-sm text-gray-900 dark:text-white">{new Date(txn.created_at).toLocaleString()}</td>
<td className="py-3 px-4"> <td className="py-3 px-4">
@@ -144,6 +150,23 @@ export default function BillingUsagePanel() {
</tbody> </tbody>
</table> </table>
</div> </div>
{transactions.length > 0 && (
<div className="mt-4 flex justify-between items-center">
<div className="text-sm text-gray-500 dark:text-gray-400">
Showing {(page - 1) * pageSize + 1}-{Math.min(page * pageSize, transactions.length)} of {transactions.length}
</div>
<CompactPagination
currentPage={page}
totalPages={totalPages}
pageSize={pageSize}
onPageChange={(p) => setPage(p)}
onPageSizeChange={(size) => {
setPageSize(size);
setPage(1);
}}
/>
</div>
)}
</Card> </Card>
</div> </div>
</div> </div>

View File

@@ -134,9 +134,11 @@ export default function TeamManagementPage() {
<div className="flex justify-end"> <div className="flex justify-end">
<Button <Button
variant="primary" variant="primary"
tone="brand"
size="md"
startIcon={<UserPlus className="w-4 h-4" />}
onClick={() => setShowInviteModal(true)} onClick={() => setShowInviteModal(true)}
> >
<UserPlus className="w-4 h-4 mr-2" />
Invite Team Member Invite Team Member
</Button> </Button>
</div> </div>
@@ -215,9 +217,11 @@ export default function TeamManagementPage() {
<div className="flex justify-end"> <div className="flex justify-end">
<Button <Button
variant="primary" variant="primary"
tone="brand"
size="md"
startIcon={<UserPlus className="w-4 h-4" />}
onClick={() => setShowInviteModal(true)} onClick={() => setShowInviteModal(true)}
> >
<UserPlus className="w-4 h-4 mr-2" />
Send Invitation Send Invitation
</Button> </Button>
</div> </div>

View File

@@ -12,6 +12,7 @@ import { Card } from '../../components/ui/card';
import Badge from '../../components/ui/badge/Badge'; import Badge from '../../components/ui/badge/Badge';
import BillingUsagePanel from '../../components/billing/BillingUsagePanel'; import BillingUsagePanel from '../../components/billing/BillingUsagePanel';
import BillingBalancePanel from '../../components/billing/BillingBalancePanel'; import BillingBalancePanel from '../../components/billing/BillingBalancePanel';
import Button from '../../components/ui/button/Button';
type TabType = 'credits' | 'api' | 'costs'; type TabType = 'credits' | 'api' | 'costs';
@@ -92,36 +93,20 @@ export default function UsageAnalyticsPage() {
{/* Period Selector */} {/* Period Selector */}
<div className="flex gap-2"> <div className="flex gap-2">
<button {[7, 30, 90].map((value) => {
onClick={() => setPeriod(7)} const isActive = period === value;
className={`px-4 py-2 rounded-md text-sm font-medium ${ return (
period === 7 <Button
? 'bg-primary-600 text-white' key={value}
: 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300' size="sm"
}`} variant={isActive ? 'primary' : 'secondary'}
tone={isActive ? 'brand' : 'neutral'}
onClick={() => setPeriod(value)}
> >
7 Days {value} Days
</button> </Button>
<button );
onClick={() => setPeriod(30)} })}
className={`px-4 py-2 rounded-md text-sm font-medium ${
period === 30
? 'bg-primary-600 text-white'
: 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300'
}`}
>
30 Days
</button>
<button
onClick={() => setPeriod(90)}
className={`px-4 py-2 rounded-md text-sm font-medium ${
period === 90
? 'bg-primary-600 text-white'
: 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300'
}`}
>
90 Days
</button>
</div> </div>
</div> </div>