Add user purchase statistics tab
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
6 files changed
+74
-5
No files matched your search
@@ -12,6 +12,7 @@ const Register = React.lazy(() => import("./features/register/Register"));
|
||||
const OrderStats = React.lazy(() => import("./features/stats/OrderStats"));
|
||||
const ProductStats = React.lazy(() => import("./features/stats/ProductStats"));
|
||||
const Stats = React.lazy(() => import("./features/stats/Stats"));
|
||||
const UserStats = React.lazy(() => import("./features/stats/UserStats"));
|
||||
const UserDetail = React.lazy(() => import("./features/users/UserDetail"));
|
||||
const UserList = React.lazy(() => import("./features/users/UserList"));
|
||||
|
||||
@@ -26,6 +27,7 @@ export const Routes = (): JSX.Element => (
|
||||
<Route path="/stats" element={<Stats />} />
|
||||
<Route path="/stats/orders" element={<OrderStats />} />
|
||||
<Route path="/stats/products" element={<ProductStats />} />
|
||||
<Route path="/stats/users" element={<UserStats />} />
|
||||
<Route path="/users" element={<UserList />} />
|
||||
<Route path="/users/create" element={<UserCreate />} />
|
||||
<Route path="/user/:userId" element={<UserDetail />} />
|
||||
|
||||
@@ -25,7 +25,7 @@ export const StatsNav = () => (
|
||||
</NavLink>
|
||||
</li>
|
||||
<li>
|
||||
<NavLink className="disabled" to="/stats/users" title="TODO" hidden={true}>
|
||||
<NavLink className={navLinkStyles} to="/stats/users">
|
||||
Folk
|
||||
</NavLink>
|
||||
</li>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { ResponsiveBar } from "@nivo/bar";
|
||||
import React from "react";
|
||||
|
||||
import { GQLError } from "../../components/GQLError";
|
||||
import { UserStatsDocument } from "../../types";
|
||||
import styles from "./Stats.module.css";
|
||||
import { StatsView } from "./StatsView";
|
||||
import { chartTheme } from "./chartTheme";
|
||||
|
||||
const UserStats = () => {
|
||||
const { data, loading, error } = useQuery(UserStatsDocument);
|
||||
|
||||
if (error) return <GQLError error={error} />;
|
||||
|
||||
const users = (data?.allUsers || [])
|
||||
.filter((user) => Number(user.profile?.orderSumTotal || 0) > 0)
|
||||
.map((user) => ({
|
||||
name: `${user.firstName}${user.lastName ? ` ${user.lastName[0]}.` : ""}`,
|
||||
total: Number(user.profile?.orderSumTotal || 0),
|
||||
}))
|
||||
.sort((a, b) => b.total - a.total)
|
||||
.slice(0, 10);
|
||||
|
||||
return (
|
||||
<StatsView loading={loading}>
|
||||
<h3>Topp 10 etter total kjøpesum</h3>
|
||||
{users.length ? (
|
||||
<div className={styles.chart} style={{ height: Math.max(320, users.length * 44) }}>
|
||||
<ResponsiveBar
|
||||
data={users}
|
||||
keys={["total"]}
|
||||
indexBy="name"
|
||||
layout="horizontal"
|
||||
theme={chartTheme}
|
||||
margin={{ top: 10, right: 35, bottom: 40, left: 100 }}
|
||||
padding={0.3}
|
||||
enableLabel={false}
|
||||
axisBottom={{
|
||||
legend: "Kjøp totalt (kr)",
|
||||
legendPosition: "middle",
|
||||
legendOffset: 32,
|
||||
}}
|
||||
axisLeft={null}
|
||||
valueFormat={(value) => `${Number(value).toLocaleString("no")} kr`}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<p>Ingen kjøp å vise ennå.</p>
|
||||
)}
|
||||
</StatsView>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserStats;
|
||||
@@ -0,0 +1,10 @@
|
||||
query userStats {
|
||||
allUsers {
|
||||
id
|
||||
firstName
|
||||
lastName
|
||||
profile {
|
||||
orderSumTotal
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,6 +452,11 @@ export type ProductStatsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
export type ProductStatsQuery = { __typename: 'Query', productStats: Array<{ __typename: 'ProductOrderStat', productName: string, data: Array<{ __typename: 'Point', x: string, y: number }> }> };
|
||||
|
||||
export type UserStatsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type UserStatsQuery = { __typename: 'Query', allUsers: Array<{ __typename: 'User', id: string, firstName: string, lastName: string, profile: { __typename: 'UserProfile', orderSumTotal: string } | null }> };
|
||||
|
||||
export type UserDetailQueryVariables = Exact<{
|
||||
userId: string | number;
|
||||
}>;
|
||||
@@ -474,4 +479,5 @@ export const CreateOrderDocument = {"kind":"Document","definitions":[{"kind":"Op
|
||||
export const AllProductStatsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"allProductStats"},"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<AllProductStatsQuery, AllProductStatsQueryVariables>;
|
||||
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":"daily"},"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"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"productStats"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"x"}},{"kind":"Field","name":{"kind":"Name","value":"y"}}]}}]}}]}}]} as unknown as DocumentNode<ProductStatsQuery, ProductStatsQueryVariables>;
|
||||
export const UserStatsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"userStats"},"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":"orderSumTotal"}}]}}]}}]}}]} as unknown as DocumentNode<UserStatsQuery, UserStatsQueryVariables>;
|
||||
export const UserDetailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"userDetail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}}],"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"}},{"kind":"Field","name":{"kind":"Name","value":"topMonths"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"period"}},{"kind":"Field","name":{"kind":"Name","value":"sum"}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","name":{"kind":"Name","value":"productOrderStats"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"x"}},{"kind":"Field","name":{"kind":"Name","value":"y"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"orderSumTotal"}}]}}]}}]}}]} as unknown as DocumentNode<UserDetailQuery, UserDetailQueryVariables>;
|
||||
Reference in new issue
Block a user