feat: Add extra weight, price tracking, print history, usage analytics
Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
- Extra Weight Field (#14): Track DryPods, custom holders in spool weight calculations. New extra_weight field on spool with DB migration. - Price/Cost Tracking: Compute remaining_value based on remaining weight and price. Added column to spool list, inventory value on dashboard. - Print History: Show print job history on spool detail page with collapsible table showing filename, filament used, status, dates. - Usage Analytics: New dashboard component with time-series chart showing daily consumption, period selector (7/30/90 days), and material breakdown. New API endpoints for analytics data. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { HighlightOutlined, InboxOutlined, DatabaseOutlined, UserOutlined } from "@ant-design/icons";
|
||||
import { DollarOutlined, HighlightOutlined, InboxOutlined, DatabaseOutlined, UserOutlined } from "@ant-design/icons";
|
||||
import { useList, useTranslate } from "@refinedev/core";
|
||||
import { Card, Col, Row, Statistic, theme } from "antd";
|
||||
import { useMemo } from "react";
|
||||
@@ -6,12 +6,14 @@ import { Link } from "react-router";
|
||||
import { IFilament } from "../../filaments/model";
|
||||
import { ISpool } from "../../spools/model";
|
||||
import { IVendor } from "../../vendors/model";
|
||||
import { useCurrencyFormatter } from "../../../utils/settings";
|
||||
|
||||
const { useToken } = theme;
|
||||
|
||||
export function QuickStats() {
|
||||
const t = useTranslate();
|
||||
const { token } = useToken();
|
||||
const currencyFormatter = useCurrencyFormatter();
|
||||
|
||||
const { result: filamentsResult, query: filamentsQuery } = useList<IFilament>({
|
||||
resource: "filament",
|
||||
@@ -40,6 +42,12 @@ export function QuickStats() {
|
||||
return data.reduce((sum, spool) => sum + (spool.remaining_weight ?? 0), 0);
|
||||
}, [spoolsResult?.data]);
|
||||
|
||||
// Calculate total inventory value
|
||||
const totalValue = useMemo(() => {
|
||||
const data = spoolsResult?.data || [];
|
||||
return data.reduce((sum, spool) => sum + (spool.remaining_value ?? 0), 0);
|
||||
}, [spoolsResult?.data]);
|
||||
|
||||
const formatWeight = (grams: number) => {
|
||||
if (grams >= 1000) {
|
||||
return `${(grams / 1000).toFixed(1)} kg`;
|
||||
@@ -49,7 +57,7 @@ export function QuickStats() {
|
||||
|
||||
return (
|
||||
<Row gutter={[12, 12]} style={{ marginTop: 16 }}>
|
||||
<Col xs={12} sm={6}>
|
||||
<Col xs={12} md={8} lg={4}>
|
||||
<Link to="/spool">
|
||||
<Card hoverable size="small">
|
||||
<Statistic
|
||||
@@ -61,7 +69,7 @@ export function QuickStats() {
|
||||
</Card>
|
||||
</Link>
|
||||
</Col>
|
||||
<Col xs={12} sm={6}>
|
||||
<Col xs={12} md={8} lg={4}>
|
||||
<Link to="/filament">
|
||||
<Card hoverable size="small">
|
||||
<Statistic
|
||||
@@ -73,7 +81,7 @@ export function QuickStats() {
|
||||
</Card>
|
||||
</Link>
|
||||
</Col>
|
||||
<Col xs={12} sm={6}>
|
||||
<Col xs={12} md={8} lg={4}>
|
||||
<Link to="/vendor">
|
||||
<Card hoverable size="small">
|
||||
<Statistic
|
||||
@@ -85,7 +93,7 @@ export function QuickStats() {
|
||||
</Card>
|
||||
</Link>
|
||||
</Col>
|
||||
<Col xs={12} sm={6}>
|
||||
<Col xs={12} md={12} lg={6}>
|
||||
<Card size="small">
|
||||
<Statistic
|
||||
title={t("home.quick_stats.total_weight")}
|
||||
@@ -95,6 +103,16 @@ export function QuickStats() {
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={12} md={12} lg={6}>
|
||||
<Card size="small">
|
||||
<Statistic
|
||||
title={t("home.quick_stats.total_value")}
|
||||
value={currencyFormatter.format(totalValue)}
|
||||
loading={spoolsQuery.isLoading}
|
||||
prefix={<DollarOutlined />}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user