From 01554466e44f223a74790e3591a5ec624352343d Mon Sep 17 00:00:00 2001 From: guilherme Date: Thu, 11 Dec 2025 12:00:11 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20adicionar=20suporte=20a=20m=C3=A9tricas?= =?UTF-8?q?=20din=C3=A2micas=20no=20componente=20ProfileCard=20e=20integra?= =?UTF-8?q?r=20ao=20slide=20de=20retrospectiva?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 50 +++++++ package.json | 1 + src/views/components/ProfileCard.jsx | 125 +++++++++++++++++- src/views/components/retrospective-slides.tsx | 71 +++------- 4 files changed, 189 insertions(+), 58 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4b4d799..53ab696 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "date-fns": "^4.1.0", "embla-carousel-react": "^8.6.0", "framer-motion": "^12.23.26", + "html2canvas": "^1.4.1", "lucide-react": "^0.554.0", "react": "^19.2.0", "react-day-picker": "^9.11.1", @@ -3487,6 +3488,15 @@ "dev": true, "license": "MIT" }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/baseline-browser-mapping": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.29.tgz", @@ -3728,6 +3738,15 @@ "node": ">= 8" } }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -4692,6 +4711,19 @@ "hermes-estree": "0.25.1" } }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "license": "MIT", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -5944,6 +5976,15 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", @@ -6181,6 +6222,15 @@ } } }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, "node_modules/vaul": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", diff --git a/package.json b/package.json index e4c523d..7b2f208 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "date-fns": "^4.1.0", "embla-carousel-react": "^8.6.0", "framer-motion": "^12.23.26", + "html2canvas": "^1.4.1", "lucide-react": "^0.554.0", "react": "^19.2.0", "react-day-picker": "^9.11.1", diff --git a/src/views/components/ProfileCard.jsx b/src/views/components/ProfileCard.jsx index 8497a18..e7447fc 100644 --- a/src/views/components/ProfileCard.jsx +++ b/src/views/components/ProfileCard.jsx @@ -1,4 +1,10 @@ -import React, { useCallback, useEffect, useMemo, useRef } from 'react'; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; import './ProfileCard.css'; import logoImg from '@/assets/images/agape-logo.png'; @@ -39,7 +45,15 @@ const ProfileCardComponent = ({ contactText = 'Contact', showUserInfo = true, onContactClick, + // métricas para popular o cartão + totalAcessos = null, + aplicacoesCount = null, + topAppName = null, + topAppAcessos = null, + // permite mostrar/ocultar botões de compartilhamento + showShareButtons = true, }) => { + const [sharing, setSharing] = useState(false); const wrapRef = useRef(null); const shellRef = useRef(null); @@ -346,17 +360,23 @@ const ProfileCardComponent = ({ gap: '16px', padding: '24px', }}> - {/* Card de Acessos */} + {/* Card de Acessos (dinâmico) */}
-

23.343

+

+ {totalAcessos != null + ? totalAcessos.toLocaleString('pt-BR') + : '—'} +

Acessos

-

8

+

+ {aplicacoesCount != null ? aplicacoesCount : '—'} +

Aplicações

@@ -365,13 +385,106 @@ const ProfileCardComponent = ({
TOP 1 -

agGestor

+

{topAppName || '—'}

- Aplicação mais utilizada + {topAppAcessos != null + ? `${topAppAcessos.toLocaleString('pt-BR')} acessos` + : 'Aplicação mais utilizada'}

+ + {/* Botões de compartilhamento */} + {showShareButtons && ( +
+ + + + + +
+ )} diff --git a/src/views/components/retrospective-slides.tsx b/src/views/components/retrospective-slides.tsx index b78342e..5a7ba30 100644 --- a/src/views/components/retrospective-slides.tsx +++ b/src/views/components/retrospective-slides.tsx @@ -4,7 +4,11 @@ import { } from '@/app/hooks/useMetrics'; import logoAImg from '@/assets/images/a-agape.png'; import logoImg from '@/assets/images/agape-logo.png'; -import { BuildingIcon, ChartLineUpIcon, ClockIcon, SpinnerIcon } from '@phosphor-icons/react'; +import { + BuildingIcon, + ChartLineUpIcon, + SpinnerIcon, +} from '@phosphor-icons/react'; import { motion } from 'framer-motion'; import * as React from 'react'; import { useSearchParams } from 'react-router-dom'; @@ -62,6 +66,13 @@ export function RetrospectiveSlides() { .sort((a, b) => b.totalAcessos - a.totalAcessos) .slice(0, 5); + const allItems = [...(metricsPortal || []), ...(metricsSystems || [])]; + const aplicacoesCount = new Set( + allItems.map((i) => (i.nomeSistema || '').trim()).filter((n) => !!n), + ).size; + const topAppName = topItems[0]?.nomeSistema ?? null; + const topAppAcessos = topItems[0]?.totalAcessos ?? null; + return (
{isLoading ? ( @@ -178,7 +189,7 @@ export function RetrospectiveSlides() { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.6, delay: 0.1 }}> - Portal Corporativo + Acessos no AgPortal
- -
-
- {Math.round( - metricsPortal.reduce( - (acc, p) => acc + p.totalAcessos, - 0, - ) / 2920, - )} -
-
- Por hora* -
-
@@ -270,14 +267,11 @@ export function RetrospectiveSlides() { viewport={{ once: true }} transition={{ duration: 0.6 }}>
- + Aplicativos Mais Acessados
-

- Os sistemas que mais acessaram o portal -

{/* Lista de sistemas */} @@ -368,44 +362,12 @@ export function RetrospectiveSlides() { ); })} - - {/* Indicador de progresso */} - -
-
- Próxima análise -
-
- {[...Array(3)].map((_, i) => ( - - ))} -
-
-
)} -
@@ -450,6 +412,11 @@ export function RetrospectiveSlides() { status="Online" contactText="Contato" avatarUrl="https://github.com/GuilhermeSantosUI.png" + // métricas para preencher o cartão final + totalAcessos={totalAcessos} + aplicacoesCount={aplicacoesCount} + topAppName={topAppName} + topAppAcessos={topAppAcessos} showUserInfo={true} enableTilt={true} enableMobileTilt={false}