analytics layout

This commit is contained in:
knugget
2022-06-23 22:30:35 -05:00
parent a2b41e9259
commit 78e89c8b7c
6 changed files with 143 additions and 81 deletions

View File

@@ -7,9 +7,7 @@ interface Props {
KPI: string;
typeText?: boolean;
label: string;
hasToolTip?: boolean;
toolTipText: string;
hasTrend?: boolean;
trend: number;
}
@@ -18,30 +16,27 @@ const AnalyticsCard: React.FC<Props> = ({
KPI,
typeText = false,
label,
hasToolTip = false,
toolTipText,
hasTrend = false,
trend,
}) => {
return (
<div className="relative px-4 pt-5 overflow-hidden bg-white rounded-lg shadow sm:pt-6 sm:px-6s">
<div className="inline-flex items-center justify-center text-ui-gray-dark">
<div className="grid content-between px-4 py-2 bg-white rounded-md shadow-md">
<div className="inline-flex items-center text-sm text-ui-gray-dark">
{label}{" "}
{hasToolTip && (
{toolTipText && (
<QuestionMarkCircleIcon className="w-4 h-4 ml-1 text-red hover:text-ui-gray-dark" />
)}
</div>
<div
className={classNames(
`justify-between font-bold leading-none `,
typeText ? "text-2xl" : "",
"text-8xl"
`font-bold leading-none flex justify-between items-end`,
typeText ? "text-3xl tracking-tight leading-10" : "text-7xl"
)}
>
{KPI}
{hasTrend && (
<div className="text-green-600 bg-green-200 rounded-full">
{trend}
{trend && (
<div className="flex items-center h-6 px-6 py-2 mb-2.5 text-sm font-light text-green-600 bg-green-200 rounded-full">
{trend} %
</div>
)}
</div>

View File

@@ -5,6 +5,8 @@ import {
useSubmissionSessions,
} from "../../lib/submissionSessions";
import { timeSince } from "../../lib/utils";
import AnalyticsCard from "../layout/AnalyticsCard";
import Image from "next/image";
export default function ResultsAnalytics({ formId }) {
const { submissionSessions, isLoadingSubmissionSessions } =
@@ -22,56 +24,73 @@ export default function ResultsAnalytics({ formId }) {
{
id: "uniqueUsers",
name: "Unique Users",
stat: analytics.uniqueUsers,
icon: UsersIcon,
stat: analytics.uniqueUsers || "NaN",
toolTipText: "placeholder",
trend: "12",
},
{
id: "totalSubmissions",
name: "Total Submissions",
stat: analytics.totalSubmissions,
icon: InboxIcon,
stat: analytics.totalSubmissions || "NaN",
trend: "10",
},
{
id: "uniqueUsers",
id: "lastSubmission",
name: "Last Submission",
stat: timeSince(analytics.lastSubmissionAt) || "-",
icon: ClockIcon,
typeText: true,
},
];
}
}, [analytics]);
return (
<main>
<div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div className="max-w-5xl mx-auto sm:px-6 lg:px-8">
<h2 className="mt-8 text-xl font-bold text-ui-gray-dark">Analytics</h2>
<div>
{stats ? (
<dl className="grid grid-cols-1 gap-5 mt-8 sm:grid-cols-2 lg:grid-cols-3">
{stats.map((item) => (
<div
<AnalyticsCard
key={item.id}
className="relative px-4 bg-white rounded-lg shadow pt-5overflow-hidden sm:pt-6 sm:px-6"
>
<dt>
<div className="absolute p-3 rounded-md bg-red-500">
<item.icon
className="w-6 h-6 text-white"
aria-hidden="true"
/>
</div>
<p className="ml-16 text-sm font-medium text-gray-500 truncate">
{item.name}
</p>
</dt>
<dd className="flex items-baseline ml-16 sm:pb-7">
<p className="text-xl font-semibold text-gray-800">
{item.stat}
</p>
</dd>
</div>
KPI={item.stat}
label={item.name}
toolTipText={item.toolTipText}
typeText={item.typeText}
trend={item.trend}
/>
))}
</dl>
) : null}
</div>
<div className="flex items-end">
<h2 className="mt-16 text-xl font-bold text-ui-gray-dark">
Optimize Form
</h2>
<div className="px-3 py-2 ml-2 text-xs text-green-800 rounded-sm bg-green-50">
<p>coming soon</p>
</div>
</div>
<div className="grid grid-cols-2 gap-10 mt-8">
<div className="relative p-8 bg-white rounded-md shadow-md h-60">
<Image
src="/../../img/drop-offs-v1.svg"
alt="drop-off"
objectFit="cover"
layout="fill"
className="rounded-md"
/>
</div>
<div className="relative p-8 bg-white rounded-md shadow-md h-60">
<Image
src="/../../img/a-b-test-v1.svg"
alt="drop-off"
objectFit="cover"
layout="fill"
className="rounded-md"
/>
</div>
</div>
</div>
</main>
);

View File

@@ -8,6 +8,8 @@ import {
import { SubmissionSummary } from "../../lib/types";
import Loading from "../Loading";
import TextResults from "./summary/TextResults";
import { timeSince } from "../../lib/utils";
import AnalyticsCard from "../layout/AnalyticsCard";
export default function ResultsSummary({ formId }) {
const { submissionSessions, isLoadingSubmissionSessions } =
@@ -27,20 +29,22 @@ export default function ResultsSummary({ formId }) {
{
id: "uniqueUsers",
name: "Unique Users",
stat: 10,
icon: UsersIcon,
stat: summary.uniqueUsers || "NaN",
toolTipText: "placeholder",
trend: "12",
},
{
id: "totalSubmissions",
name: "Total Submissions",
stat: 10,
icon: InboxIcon,
stat: summary.totalSubmissions || "NaN",
trend: "10",
},
{
id: "uniqueUsers",
id: "lastSubmission",
name: "Last Submission",
stat: 10,
icon: ClockIcon,
// stat: timeSince(analytics.lastSubmissionAt) || "-",
stat: "NaN",
typeText: true,
},
];
}
@@ -52,49 +56,32 @@ export default function ResultsSummary({ formId }) {
return (
<main className="bg-gray-50">
<div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div>
<dl className="grid grid-cols-1 gap-5 mt-8 sm:grid-cols-2 lg:grid-cols-3">
{stats.map((item) => (
<div
key={item.id}
className="relative px-4 bg-white rounded-lg shadow pt-5overflow-hidden sm:pt-6 sm:px-6"
>
<dt>
<div className="absolute p-3 rounded-md bg-red-500">
<item.icon
className="w-6 h-6 text-white"
aria-hidden="true"
/>
</div>
<p className="ml-16 text-sm font-medium text-gray-500 truncate">
{item.name}
</p>
</dt>
<dd className="flex items-baseline ml-16 sm:pb-7">
<p className="text-xl font-semibold text-gray-800">
{item.stat}
</p>
</dd>
</div>
))}
</dl>
</div>
<hr className="my-8" />
<div className="max-w-5xl mx-auto sm:px-6 lg:px-8">
<h2 className="mt-8 text-xl font-bold text-ui-gray-dark">
Responses Overview
</h2>
<dl className="grid grid-cols-1 gap-5 mt-8 sm:grid-cols-2 lg:grid-cols-3">
{stats.map((item) => (
<AnalyticsCard
key={item.id}
KPI={item.stat}
label={item.name}
toolTipText={item.toolTipText}
typeText={item.typeText}
trend={item.trend}
/>
))}
</dl>
<div>
{summary.pages.map(
(page, pageIdx) =>
page.type === "form" && (
<div key={page.name}>
<h2 className="text-xl font-bold text-gray-700">
Page {pageIdx + 1}
</h2>
{page.elements.map((element) =>
element.type === "text" || element.type === "textarea" ? (
<TextResults element={element} />
) : null
)}
<hr className="my-8" />
</div>
)
)}

View File

@@ -6,7 +6,7 @@ export default function TextResults({ element }) {
<div className="flow-root px-8 my-4 mt-6 overflow-y-scroll text-center max-h-64">
<ul className="-my-5 divide-y divide-ui-gray-light">
{element.summary.map((answer) => (
<li key={answer} className="py-5">
<li key={answer} className="py-8">
<div className="relative focus-within:ring-2 focus-within:ring-indigo-500">
<h3 className="text-sm text-gray-700">
{/* Extend touch target to entire panel */}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 40 KiB