✨ Add order stats

This commit is contained in:
Nikolai R Kristiansen committed 2022-02-06 21:05:40 +01:00
1 parent 6fa6bf1334
commit 771e0c2a3b
10 files changed
+336 -27

No files matched your search

@@ -1,5 +1,6 @@
.products {
display: grid;
max-width: 1200px;
gap: 1rem;
grid-template-columns: repeat(3, 1fr);
}
+101 -23
View File
@@ -1,8 +1,9 @@
import { useQuery } from "@apollo/client";
import { Bar } from "@nivo/bar";
import { Pie } from "@nivo/pie";
import React from "react";
import { ProductStatsDocument } from "../../types";
import { OrderStatsDocument, ProductStatsDocument, OrderStatsByTime } from "../../types";
import styles from "./Stats.module.css";
type UserCount = {
@@ -10,38 +11,115 @@ type UserCount = {
count: number;
};
const days = { 1: "Mandag", 2: "Tirsdag", 3: "Onsdag", 4: "Torsdag", 5: "Fredag", 6: "Lørdag", 7: "Søndag" };
const months = {
1: "Januar",
2: "Februar",
3: "Mars",
4: "April",
5: "Mai",
6: "Juni",
7: "Juli",
8: "August",
9: "September",
10: "Oktober",
11: "November",
12: "Desember",
};
export const Stats = () => {
const { data, loading } = useQuery(ProductStatsDocument);
const { data: productData, loading: productLoading } = useQuery(ProductStatsDocument);
const { data: orderData, loading: orderLoading } = useQuery(OrderStatsDocument);
const loading = orderLoading || productLoading;
if (loading) {
return <div>Loading...</div>;
}
return (
<div className={styles.stats}>
<h2>Stats</h2>
<h3>Produkter</h3>
<div className={styles.products}>
{(data?.allProducts || []).map((product) => {
return (
<div key={product.id}>
{product.name}
<Pie
margin={{ top: 40, right: 120, bottom: 40, left: 120 }}
data={product.userCounts.map((uc: UserCount) => ({
id: uc.name,
label: uc.name,
value: uc.count,
}))}
width={400}
height={300}
/>
</div>
);
})}
{(productData?.allProducts || []).map((product) => (
<div key={product.id}>
{product.name}
<Pie
margin={{ top: 40, right: 120, bottom: 40, left: 120 }}
data={product.userCounts.map((uc: UserCount) => ({
id: uc.name,
label: uc.name,
value: uc.count,
}))}
width={400}
height={300}
/>
</div>
))}
</div>
<h3>Hourly</h3>
<h3>Daily</h3>
<h3>Monthly</h3>
<h3>Yearly</h3>
<h3>Ordre per time</h3>
<Bar
data={(orderData?.orderStats?.hourly || []).map((stat: OrderStatsByTime) => ({
id: `${stat.period.toString().padStart(2, "0")}:00`,
label: stat.period,
value: stat.count,
}))}
margin={{ left: 60, bottom: 40 }}
width={1200}
height={400}
colorBy="indexValue"
enableLabel={false}
tooltipLabel={(d) => d.id.toString()}
axisLeft={{ legend: "Ordre", legendPosition: "middle", legendOffset: -50 }}
/>
<h3>Ordre per ukedag</h3>
<Bar
data={(orderData?.orderStats?.dayly || []).map((stat: OrderStatsByTime) => ({
/* @ts-expect-error Here, stat.period can only be a key in days range. */
id: days[stat.period],
label: stat.period,
value: stat.count,
}))}
margin={{ left: 60, bottom: 40 }}
width={1200}
height={400}
colorBy="indexValue"
enableLabel={false}
tooltipLabel={(d) => d.id.toString()}
axisLeft={{ legend: "Ordre", legendPosition: "middle", legendOffset: -50 }}
/>
<h3>Ordre per måned</h3>
<Bar
data={(orderData?.orderStats?.monthly || []).map((stat: OrderStatsByTime) => ({
/* @ts-expect-error Here, stat.period can only be a key in months range. */
id: months[stat.period],
label: stat.period,
value: stat.count,
}))}
margin={{ left: 60, bottom: 40 }}
width={1200}
height={400}
colorBy="indexValue"
enableLabel={false}
tooltipLabel={(d) => d.id.toString()}
axisLeft={{ legend: "Ordre", legendPosition: "middle", legendOffset: -50 }}
/>
<h3>Ordre per år</h3>
<Bar
data={(orderData?.orderStats?.yearly || []).map((stat: OrderStatsByTime) => ({
id: stat.period,
label: stat.period,
value: stat.count,
}))}
margin={{ left: 60, bottom: 40 }}
width={1200}
height={400}
colorBy="indexValue"
enableLabel={false}
tooltipLabel={(d) => d.id.toString()}
axisLeft={{ legend: "Ordre", legendPosition: "middle", legendOffset: -50 }}
/>
</div>
);
};
@@ -0,0 +1,20 @@
query orderStats {
orderStats {
yearly {
period
count
}
monthly {
period
count
}
dayly {
period
count
}
hourly {
period
count
}
}
}
+21
View File
@@ -117,6 +117,20 @@ export type OrderOrdering = {
created?: InputMaybe<Ordering>;
};
export type OrderStats = {
__typename?: 'OrderStats';
dayly: Array<OrderStatsByTime>;
hourly: Array<OrderStatsByTime>;
monthly: Array<OrderStatsByTime>;
yearly: Array<OrderStatsByTime>;
};
export type OrderStatsByTime = {
__typename?: 'OrderStatsByTime';
count: Scalars['String'];
period: Scalars['Int'];
};
export enum Ordering {
Asc = 'ASC',
Desc = 'DESC'
@@ -143,6 +157,7 @@ export type Query = {
allProducts: Array<Product>;
allUsers: Array<User>;
orderList: Array<Order>;
orderStats: OrderStats;
transactionList: Array<Transaction>;
};
@@ -236,6 +251,11 @@ export type CreateOrderMutationVariables = Exact<{
export type CreateOrderMutation = { __typename?: 'Mutation', createOrder: { __typename?: 'CreateOrderSuccess', order: { __typename?: 'Order', id: string, isExternal: boolean, orderSum: number, customer?: { __typename?: 'User', id: string, firstName: string, lastName: string, profile?: { __typename?: 'UserProfile', id: string, balance: number } | null } | null, orderlines?: Array<{ __typename?: 'OrderLine', id: string, amount: number, unitPrice: number, product: { __typename?: 'Product', id: string, name: string, salePriceExt: number, salePriceInt: number } }> | null } } | { __typename?: 'FormErrors', error: boolean, message: string, fields: Array<{ __typename?: 'FieldError', field: string, message: string }> } | { __typename?: 'InsufficientFunds', error: boolean, message: string, amountLacking: number } };
export type OrderStatsQueryVariables = Exact<{ [key: string]: never; }>;
export type OrderStatsQuery = { __typename?: 'Query', orderStats: { __typename?: 'OrderStats', yearly: Array<{ __typename?: 'OrderStatsByTime', period: number, count: string }>, monthly: Array<{ __typename?: 'OrderStatsByTime', period: number, count: string }>, dayly: Array<{ __typename?: 'OrderStatsByTime', period: number, count: string }>, hourly: Array<{ __typename?: 'OrderStatsByTime', period: number, count: string }> } };
export type ProductStatsQueryVariables = Exact<{
active?: InputMaybe<Scalars['Boolean']>;
}>;
@@ -250,4 +270,5 @@ export const TransactionListDocument = {"kind":"Document","definitions":[{"kind"
export const AllProductsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"allProducts"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"active"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"allProducts"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"active"},"value":{"kind":"Variable","name":{"kind":"Name","value":"active"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"imageUrl"}},{"kind":"Field","name":{"kind":"Name","value":"salePriceExt"}},{"kind":"Field","name":{"kind":"Name","value":"salePriceInt"}}]}}]}}]} as unknown as DocumentNode<AllProductsQuery, AllProductsQueryVariables>;
export const AllUsersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"allUsers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"allUsers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"balance"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"lastPurchaseDate"}}]}}]}}]}}]} as unknown as DocumentNode<AllUsersQuery, AllUsersQueryVariables>;
export const CreateOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"customerId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderLines"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OrderLineInput"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"isExternal"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"customerId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"customerId"}}},{"kind":"Argument","name":{"kind":"Name","value":"orderLines"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderLines"}}},{"kind":"Argument","name":{"kind":"Name","value":"isExternal"},"value":{"kind":"Variable","name":{"kind":"Name","value":"isExternal"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CreateOrderSuccess"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"isExternal"}},{"kind":"Field","name":{"kind":"Name","value":"customer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"balance"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"orderlines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"salePriceExt"}},{"kind":"Field","name":{"kind":"Name","value":"salePriceInt"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"orderSum"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"InsufficientFunds"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"amountLacking"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FormErrors"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"fields"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode<CreateOrderMutation, CreateOrderMutationVariables>;
export const OrderStatsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"orderStats"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"orderStats"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"yearly"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"period"}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","name":{"kind":"Name","value":"monthly"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"period"}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","name":{"kind":"Name","value":"dayly"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"period"}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","name":{"kind":"Name","value":"hourly"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"period"}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]}}]} as unknown as DocumentNode<OrderStatsQuery, OrderStatsQueryVariables>;
export const ProductStatsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"productStats"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"active"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"allProducts"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"active"},"value":{"kind":"Variable","name":{"kind":"Name","value":"active"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"userCounts"}}]}}]}}]} as unknown as DocumentNode<ProductStatsQuery, ProductStatsQueryVariables>;