295 lines
14 KiB
JavaScript
295 lines
14 KiB
JavaScript
// // components/admin/tabs/AccountsTab.js
|
|
// import Link from "next/link";
|
|
|
|
// export default function AppealsWithStatusTab({ statusObj }) {
|
|
// return (
|
|
// <div>
|
|
// <h1>User Accounts</h1>
|
|
|
|
// <dl className="govuk-summary-list govuk-!-margin-bottom-9 results">
|
|
// <div className="govuk-summary-list__row results-headings">
|
|
// <dd className="govuk-summary-list__key govuk-!-font-size-16">
|
|
// Name
|
|
// </dd>
|
|
// <dd className="govuk-summary-list__key govuk-!-font-size-16">
|
|
// Last accessed
|
|
// </dd>
|
|
// </div>
|
|
|
|
// {statusObj.map((appeal) => (
|
|
// <div key={appeal.id} className="govuk-summary-list__row">
|
|
// <dd className="govuk-summary-list__value govuk-!-font-size-16 ">
|
|
// <Link
|
|
// target="_blank"
|
|
// href={`/auth/signin2?email=${appeal.value}`}
|
|
// >
|
|
// {appeal.value}
|
|
// </Link>
|
|
// <br />
|
|
|
|
// <dl className="govuk-summary-list govuk-!-margin-bottom-9 govuk-!-margin-left-9 results">
|
|
// <div className="govuk-summary-list__row results-headings">
|
|
// <dd className="govuk-summary-list__key govuk-!-font-size-16">
|
|
// Name
|
|
// </dd>
|
|
// <dd className="govuk-summary-list__key govuk-!-font-size-16">
|
|
// Last accessed
|
|
// </dd>
|
|
// </div>
|
|
|
|
// {appeal.statuses.map((statuses) => (
|
|
// <div
|
|
// key={appeal.id}
|
|
// className="govuk-summary-list__row"
|
|
// >
|
|
// <dd className="govuk-summary-list__value govuk-!-font-size-16 ">
|
|
// {statuses.value}
|
|
// </dd>
|
|
// <dd className="govuk-summary-list__value govuk-!-font-size-16 ">
|
|
// Total: {statuses.caseCount}
|
|
// </dd>
|
|
// </div>
|
|
// ))}
|
|
// </dl>
|
|
// </dd>
|
|
// <dd className="govuk-summary-list__value govuk-!-font-size-16 ">
|
|
// Total: {appeal.caseCount}
|
|
// </dd>
|
|
// </div>
|
|
// ))}
|
|
// </dl>
|
|
// </div>
|
|
// );
|
|
// }
|
|
|
|
import { useState } from "react";
|
|
import Link from "next/link";
|
|
|
|
export default function AppealsWithStatusTab({ statusObj = [] }) {
|
|
const [openSections, setOpenSections] = useState({});
|
|
|
|
const toggleSection = (index) => {
|
|
setOpenSections((current) => ({
|
|
...current,
|
|
[index]: !current[index]
|
|
}));
|
|
};
|
|
|
|
const showAll = () => {
|
|
const allOpen = {};
|
|
|
|
statusObj.forEach((_, index) => {
|
|
allOpen[index] = true;
|
|
});
|
|
|
|
setOpenSections(allOpen);
|
|
};
|
|
|
|
const hideAll = () => {
|
|
setOpenSections({});
|
|
};
|
|
|
|
const allExpanded =
|
|
statusObj.length > 0 &&
|
|
statusObj.every((_, index) => openSections[index]);
|
|
|
|
const sortedAppeals = [...statusObj].sort(
|
|
(a, b) => (b.caseCount || 0) - (a.caseCount || 0)
|
|
);
|
|
|
|
const maxCount = sortedAppeals[0]?.caseCount || 1;
|
|
|
|
return (
|
|
<div>
|
|
<h1 className="govuk-heading-l">Case status by appeal type</h1>
|
|
|
|
<div className="govuk-!-margin-bottom-6">
|
|
<h2 className="govuk-heading-m">Case counts by appeal type</h2>
|
|
|
|
<dl className="appeal-count-chart">
|
|
{sortedAppeals.map((appeal) => {
|
|
const maxCount = sortedAppeals[0]?.caseCount || 1;
|
|
const width =
|
|
((appeal.caseCount || 0) / maxCount) * 100;
|
|
|
|
return (
|
|
<div
|
|
className="appeal-count-chart__row"
|
|
key={appeal.appealType}
|
|
>
|
|
<dt className="appeal-count-chart__label">
|
|
{appeal.value}
|
|
</dt>
|
|
|
|
<dd className="appeal-count-chart__bar-wrapper">
|
|
<span
|
|
className="appeal-count-chart__bar"
|
|
style={{ width: `${width}%` }}
|
|
/>
|
|
<span className="appeal-count-chart__count">
|
|
{appeal.caseCount || 0}
|
|
</span>
|
|
</dd>
|
|
</div>
|
|
);
|
|
})}
|
|
</dl>
|
|
</div>
|
|
|
|
<div className="govuk-!-margin-bottom-6">
|
|
<h2 className="govuk-heading-m">Case stages by appeal type</h2>
|
|
|
|
<dl className="appeal-stage-chart">
|
|
{sortedAppeals.map((appeal) => (
|
|
<div
|
|
className="appeal-stage-chart__row"
|
|
key={appeal.appealType}
|
|
>
|
|
<dt className="appeal-stage-chart__label">
|
|
{appeal.value}
|
|
</dt>
|
|
|
|
<dd className="appeal-stage-chart__bar-wrapper">
|
|
<div
|
|
className="appeal-stage-chart__bar"
|
|
style={{
|
|
width: `${((appeal.caseCount || 0) / maxCount) * 100}%`
|
|
}}
|
|
aria-label={`${appeal.value}, ${appeal.caseCount || 0} cases`}
|
|
>
|
|
{(appeal.statuses || [])
|
|
.filter(
|
|
(status) => status.caseCount > 0
|
|
)
|
|
.sort(
|
|
(a, b) => b.caseCount - a.caseCount
|
|
)
|
|
.map((status, index) => (
|
|
<span
|
|
key={status.statuscode}
|
|
className={`appeal-stage-chart__segment appeal-stage-chart__segment--${index % 6}`}
|
|
style={{
|
|
width: `${((status.caseCount || 0) / (appeal.caseCount || 1)) * 100}%`
|
|
}}
|
|
title={`${status.value}: ${status.caseCount}`}
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
<span className="appeal-stage-chart__count">
|
|
{appeal.caseCount || 0}
|
|
</span>
|
|
</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
</div>
|
|
|
|
<div className="govuk-accordion__controls">
|
|
<button
|
|
type="button"
|
|
className="govuk-accordion__show-all"
|
|
onClick={allExpanded ? hideAll : showAll}
|
|
>
|
|
<span className="govuk-accordion__show-all-text">
|
|
{allExpanded
|
|
? "Hide all sections"
|
|
: "Show all sections"}
|
|
</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div className="govuk-accordion" id="appeals-with-status-accordion">
|
|
{[...statusObj]
|
|
.sort((a, b) => (b.caseCount || 0) - (a.caseCount || 0))
|
|
.map((appeal, index) => {
|
|
const isOpen = !!openSections[index];
|
|
|
|
return (
|
|
<div
|
|
className={
|
|
isOpen
|
|
? "govuk-accordion__section govuk-accordion__section--expanded"
|
|
: "govuk-accordion__section"
|
|
}
|
|
key={appeal.appealType || index}
|
|
>
|
|
<div className="govuk-accordion__section-header ">
|
|
<h2 className="govuk-accordion__section-heading">
|
|
<button
|
|
type="button"
|
|
className="govuk-accordion__section-button "
|
|
id={`appeal-status-heading-${index}`}
|
|
aria-expanded={isOpen}
|
|
aria-controls={`appeal-status-content-${index}`}
|
|
onClick={() => toggleSection(index)}
|
|
>
|
|
<span
|
|
style={{
|
|
display: "flex",
|
|
justifyContent:
|
|
"space-between",
|
|
alignItems: "center",
|
|
width: "100%",
|
|
paddingRight: "20px" // leaves room for accordion icon
|
|
}}
|
|
>
|
|
<span className="govuk-heading-s ">
|
|
{appeal.value}
|
|
</span>
|
|
|
|
<span
|
|
className="govuk-body-s"
|
|
style={{
|
|
fontWeight: "normal"
|
|
}}
|
|
>
|
|
{appeal.caseCount || 0}{" "}
|
|
cases
|
|
</span>
|
|
</span>
|
|
</button>
|
|
</h2>
|
|
</div>
|
|
|
|
<div
|
|
id={`appeal-status-content-${index}`}
|
|
className="govuk-accordion__section-content"
|
|
aria-labelledby={`appeal-status-heading-${index}`}
|
|
hidden={!isOpen}
|
|
>
|
|
<dl className="govuk-summary-list govuk-!-margin-left-9">
|
|
{(appeal.statuses || [])
|
|
.sort(
|
|
(a, b) =>
|
|
(b.caseCount || 0) -
|
|
(a.caseCount || 0)
|
|
)
|
|
.map((status) => (
|
|
<div
|
|
className="govuk-summary-list__row"
|
|
key={status.statuscode}
|
|
>
|
|
<dt className="govuk-summary-list__key">
|
|
<Link
|
|
target="_blank"
|
|
href={`/advancedsearchresults?apt=${appeal.appealType}&statuscode=${status.statuscode}`}
|
|
>
|
|
{status.value}
|
|
</Link>
|
|
</dt>
|
|
<dd className="govuk-summary-list__value">
|
|
{status.caseCount || 0}
|
|
</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|