From 0dd5aced0030048f05857c75e3d148728d9529c0 Mon Sep 17 00:00:00 2001 From: kohler Date: Mon, 29 Jul 2024 11:38:11 +0200 Subject: [PATCH] DEAR-98 add print, download csv --- app/(main)/insights/page.tsx | 47 +++++---- app/(main)/insights/utils/downloadCSV.ts | 15 +++ styles/globals.css | 115 +++++++++++++++-------- 3 files changed, 122 insertions(+), 55 deletions(-) create mode 100644 app/(main)/insights/utils/downloadCSV.ts diff --git a/app/(main)/insights/page.tsx b/app/(main)/insights/page.tsx index 26fa5fb..4e592ec 100644 --- a/app/(main)/insights/page.tsx +++ b/app/(main)/insights/page.tsx @@ -21,6 +21,7 @@ import {} from '@radix-ui/react-select'; import Loading from '@components/Loading/Loading'; import { Button } from '@components/ui/Buttons/Button'; import { FileBarChart2, Printer } from 'lucide-react'; +import convertToCSV from '@/(main)/insights/utils/downloadCSV'; import WorkkindBarChart from './components/WorkkindBarChart'; import HappinessLineChart from './components/HappinessLineChart'; @@ -103,11 +104,25 @@ const InsightsPage: React.FC = () => { } }; + const downloadCSV = (): void => { + if (!happinessInsightData) return; + const csv = convertToCSV(happinessInsightData); + const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); + const link = document.createElement('a'); + const url = URL.createObjectURL(blob); + link.setAttribute('href', url); + link.setAttribute('download', 'happiness_insights.csv'); + link.style.visibility = 'hidden'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }; + return ( -
+
{user && selectedTeam && data && sprints ? ( -
-
+
+
- - -
-
- {/* */} - {/* */} - {/* */} +
+ + +
+ {/*
*/} + {/* */} + {/* */} + {/* */} + {/*
*/}
diff --git a/app/(main)/insights/utils/downloadCSV.ts b/app/(main)/insights/utils/downloadCSV.ts new file mode 100644 index 0000000..e2490be --- /dev/null +++ b/app/(main)/insights/utils/downloadCSV.ts @@ -0,0 +1,15 @@ +import { HappinessInsightsChartDTO } from '@/types/InsightsType'; + +const convertToCSV = (objArray: HappinessInsightsChartDTO[]): string => { + if (!Array.isArray(objArray) || objArray.length === 0) { + return ''; + } + + const keys = Object.keys(objArray[0]); + const header = keys.join(','); + const csvRows = objArray.map((obj) => keys.map((key) => obj[key as keyof HappinessInsightsChartDTO]).join(',')); + + return [header, ...csvRows].join('\r\n'); +}; + +export default convertToCSV; diff --git a/styles/globals.css b/styles/globals.css index 5f22fa7..26d1c38 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -3,64 +3,101 @@ @tailwind utilities; :root { - --font-outfit: 'Outfit', sans-serif; + --font-outfit: 'Outfit', sans-serif; } html, body { - height: 100%; - padding: 0; - margin: 0; - font-family: var(--font-outfit); + height: 100%; + padding: 0; + margin: 0; + font-family: var(--font-outfit); } @layer utilities { - .text-balance { - text-wrap: balance; - } + .text-balance { + text-wrap: balance; + } } @layer base { - h1 { - @apply text-2xl font-extrabold; - } + h1 { + @apply text-2xl font-extrabold; + } - h2 { - @apply text-xl font-medium; - } + h2 { + @apply text-xl font-medium; + } - h3 { - @apply text-sm font-medium; - } + h3 { + @apply text-sm font-medium; + } } @layer base { - :root { - --chart-1: 12 76% 61%; - --chart-2: 173 58% 39%; - --chart-3: 197 37% 24%; - --chart-4: 43 74% 66%; - --chart-5: 27 87% 67%; - } - - .dark { - --chart-1: 220 70% 50%; - --chart-2: 160 60% 45%; - --chart-3: 30 80% 55%; - --chart-4: 280 65% 60%; - --chart-5: 340 75% 55%; - } + :root { + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + } + + .dark { + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } } .rotate-360 { - animation: rotate 0.4s linear; + animation: rotate 0.4s linear; } @keyframes rotate { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } + +@media print { + + @page { + size: landscape; + margin: 1em; + } + + body { + transform: scale(0.9); + transform-origin: top left; + } + + /* Hide elements that should not be printed */ + .no-print { + display: none; + } + + .print-container { + width: 100%; + margin: 0; + padding: 0; + } + + .print-content { + page-break-inside: avoid; + margin: 0; + padding: 10px; + font-size: 1em; + } + + /* Prevent page breaks within the print content */ + .print-content, .print-content > div { + page-break-inside: avoid; + break-inside: avoid; + } +} \ No newline at end of file