Files
bbs/frontend/src/features/users/UserDetail.tsx
T

109 lines
3.5 KiB
TypeScript

import { useQuery } from "@apollo/client/react";
import { ResponsiveLine } from "@nivo/line";
import { useParams } from "react-router-dom";
import styles from "./UserDetail.module.css";
import { GQLError } from "../../components/GQLError";
import { SchemaUser as User, UserDetailDocument, SchemaUserProfile as UserProfile } from "../../types";
import { formatMonth, formatTime } from "../../utils/time";
import { chartTheme, chartTooltipStyle } from "../stats/chartTheme";
const UserDetail = () => {
const { userId } = useParams();
const { data, loading, error } = useQuery(UserDetailDocument, { variables: { userId: userId || "" }, skip: !userId });
if (loading) return <div>Loading...</div>;
if (error) return <GQLError error={error} />;
const user = data?.user as User;
const profile = user?.profile as UserProfile;
const series = (profile?.productOrderStats || []).map(({ productName: id, data }) => ({
id,
data: data.map((point, index, points) => ({
x: point.x,
y: point.y + (points[index - 1]?.y || 0),
})),
}));
return (
<div className={styles.userDetail}>
<div>
<h1>
{profile.image && <img src={profile.image} alt={`${user.firstName}s profile picture`} />} {user.firstName}
</h1>
<div>
<div>Stats</div>
<ul>
<li>
Saldo: <strong>{Number(profile.balance).toLocaleString("no")} kr</strong>
</li>
<li>
Siste kjøp: <strong>{formatTime(profile.lastPurchaseDate)}</strong>
</li>
<li>
Kjøp totalt: <strong>{Number(profile.orderSumTotal).toLocaleString("no")} kr</strong>
</li>
</ul>
</div>
<br />
<div>
<div>Top 5 måneder</div>
<ul>
{profile.topMonths.map((topMonth) => (
<li key={topMonth.period}>
{formatMonth(topMonth.period)}: <strong>{topMonth.count}</strong> kjøp på totalt{" "}
<strong>{topMonth.sum} kr</strong>
</li>
))}
</ul>
</div>
</div>
<div>
<h2>Kjøp over tid</h2>
<div className={styles.chart}>
<ResponsiveLine
data={series}
theme={chartTheme}
margin={{ top: 50, right: 110, bottom: 50, left: 60 }}
xScale={{
type: "time",
format: "%Y-%m-%d",
useUTC: false,
precision: "day",
}}
xFormat="time:%Y-%m-%d"
yScale={{
type: "linear",
stacked: false,
}}
axisLeft={{
legend: "Purchases",
legendOffset: 12,
}}
axisBottom={{
format: "%b %Y",
legend: "Date",
legendPosition: "middle",
legendOffset: -20,
}}
useMesh
pointLabelYOffset={0}
tooltip={({ point }) => (
<div style={chartTooltipStyle}>
<div>
<strong>{point.data.xFormatted}</strong>
</div>
<div>
<span style={{ background: point.seriesColor, width: 13, height: 13, display: "inline-block" }} />{" "}
<strong>{String(point.data.yFormatted)}</strong> {point.seriesId}
</div>
</div>
)}
/>
</div>
</div>
</div>
);
};
export default UserDetail;