@flowtomic/logic 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/useAnimatedIndicator/index.d.ts +3 -0
- package/dist/hooks/useAnimatedIndicator/index.d.ts.map +1 -0
- package/dist/hooks/useAnimatedIndicator/index.js +1 -0
- package/dist/hooks/useAnimatedIndicator/useAnimatedIndicator.d.ts +94 -0
- package/dist/hooks/useAnimatedIndicator/useAnimatedIndicator.d.ts.map +1 -0
- package/dist/hooks/useAnimatedIndicator/useAnimatedIndicator.js +228 -0
- package/dist/hooks/useGenealogy/index.d.ts +3 -0
- package/dist/hooks/useGenealogy/index.d.ts.map +1 -0
- package/dist/hooks/useGenealogy/index.js +1 -0
- package/dist/hooks/useGenealogy/useGenealogy.d.ts +96 -0
- package/dist/hooks/useGenealogy/useGenealogy.d.ts.map +1 -0
- package/dist/hooks/useGenealogy/useGenealogy.js +335 -0
- package/dist/hooks/useMoblile/index.js +1 -868
- package/dist/hooks/useProjectProgress/index.d.ts +3 -0
- package/dist/hooks/useProjectProgress/index.d.ts.map +1 -0
- package/dist/hooks/useProjectProgress/index.js +1 -0
- package/dist/hooks/useProjectProgress/useProjectProgress.d.ts +103 -0
- package/dist/hooks/useProjectProgress/useProjectProgress.d.ts.map +1 -0
- package/dist/hooks/useProjectProgress/useProjectProgress.js +124 -0
- package/dist/hooks/useProjectStats/index.d.ts +3 -0
- package/dist/hooks/useProjectStats/index.d.ts.map +1 -0
- package/dist/hooks/useProjectStats/index.js +1 -0
- package/dist/hooks/useProjectStats/useProjectStats.d.ts +130 -0
- package/dist/hooks/useProjectStats/useProjectStats.d.ts.map +1 -0
- package/dist/hooks/useProjectStats/useProjectStats.js +87 -0
- package/dist/hooks/useResizable/index.d.ts +1 -1
- package/dist/hooks/useResizable/index.d.ts.map +1 -1
- package/dist/hooks/useStatCard/useStatCard.d.ts +44 -5
- package/dist/hooks/useStatCard/useStatCard.d.ts.map +1 -1
- package/dist/hooks/useStatCard/useStatCard.js +81 -20
- package/dist/hooks/useTimeTracker/index.d.ts +3 -0
- package/dist/hooks/useTimeTracker/index.d.ts.map +1 -0
- package/dist/hooks/useTimeTracker/index.js +1 -0
- package/dist/hooks/useTimeTracker/useTimeTracker.d.ts +106 -0
- package/dist/hooks/useTimeTracker/useTimeTracker.d.ts.map +1 -0
- package/dist/hooks/useTimeTracker/useTimeTracker.js +143 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProjectProgress/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useProjectProgress } from "./useProjectProgress";
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProjectProgress - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function MyProjectProgress() {
|
|
12
|
+
* const { percentage, status, distribution } = useProjectProgress({
|
|
13
|
+
* projects: [
|
|
14
|
+
* { id: '1', status: 'completed', ... },
|
|
15
|
+
* { id: '2', status: 'in-progress', ... },
|
|
16
|
+
* { id: '3', status: 'pending', ... },
|
|
17
|
+
* ],
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* return (
|
|
21
|
+
* <div>
|
|
22
|
+
* <div>Progress: {percentage}%</div>
|
|
23
|
+
* <div>Status: {status}</div>
|
|
24
|
+
* </div>
|
|
25
|
+
* )
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export type ProjectProgressStatus = "completed" | "in-progress" | "pending" | "on-hold";
|
|
30
|
+
export interface ProjectWithProgress {
|
|
31
|
+
id: string;
|
|
32
|
+
status: ProjectProgressStatus;
|
|
33
|
+
progress?: number;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
export interface UseProjectProgressOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Lista de projetos com progresso
|
|
39
|
+
*/
|
|
40
|
+
projects: ProjectWithProgress[];
|
|
41
|
+
/**
|
|
42
|
+
* Função customizada para calcular progresso de um projeto
|
|
43
|
+
* Se não fornecido, usa progress do projeto ou calcula baseado no status
|
|
44
|
+
*/
|
|
45
|
+
calculateProgress?: (project: ProjectWithProgress) => number;
|
|
46
|
+
}
|
|
47
|
+
export interface ProjectProgressDistribution {
|
|
48
|
+
/**
|
|
49
|
+
* Número de projetos completados
|
|
50
|
+
*/
|
|
51
|
+
completed: number;
|
|
52
|
+
/**
|
|
53
|
+
* Número de projetos em progresso
|
|
54
|
+
*/
|
|
55
|
+
inProgress: number;
|
|
56
|
+
/**
|
|
57
|
+
* Número de projetos pendentes
|
|
58
|
+
*/
|
|
59
|
+
pending: number;
|
|
60
|
+
/**
|
|
61
|
+
* Número de projetos em espera
|
|
62
|
+
*/
|
|
63
|
+
onHold: number;
|
|
64
|
+
}
|
|
65
|
+
export interface UseProjectProgressReturn {
|
|
66
|
+
/**
|
|
67
|
+
* Porcentagem total de progresso (0-100)
|
|
68
|
+
*/
|
|
69
|
+
percentage: number;
|
|
70
|
+
/**
|
|
71
|
+
* Status geral do progresso
|
|
72
|
+
*/
|
|
73
|
+
status: "completed" | "in-progress" | "pending" | "on-hold";
|
|
74
|
+
/**
|
|
75
|
+
* Distribuição de projetos por status
|
|
76
|
+
*/
|
|
77
|
+
distribution: ProjectProgressDistribution;
|
|
78
|
+
/**
|
|
79
|
+
* Total de projetos
|
|
80
|
+
*/
|
|
81
|
+
total: number;
|
|
82
|
+
/**
|
|
83
|
+
* Projetos completados
|
|
84
|
+
*/
|
|
85
|
+
completed: number;
|
|
86
|
+
/**
|
|
87
|
+
* Projetos em progresso
|
|
88
|
+
*/
|
|
89
|
+
inProgress: number;
|
|
90
|
+
/**
|
|
91
|
+
* Projetos pendentes
|
|
92
|
+
*/
|
|
93
|
+
pending: number;
|
|
94
|
+
/**
|
|
95
|
+
* Projetos em espera
|
|
96
|
+
*/
|
|
97
|
+
onHold: number;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Hook headless para calcular progresso de projetos
|
|
101
|
+
*/
|
|
102
|
+
export declare function useProjectProgress(options: UseProjectProgressOptions): UseProjectProgressReturn;
|
|
103
|
+
//# sourceMappingURL=useProjectProgress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProjectProgress.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProjectProgress/useProjectProgress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;AAExF,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAEhC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,MAAM,CAAC;CAC9D;AAED,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;IAE5D;;OAEG;IACH,YAAY,EAAE,2BAA2B,CAAC;IAE1C;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAwBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,wBAAwB,CA8E/F"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProjectProgress - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function MyProjectProgress() {
|
|
12
|
+
* const { percentage, status, distribution } = useProjectProgress({
|
|
13
|
+
* projects: [
|
|
14
|
+
* { id: '1', status: 'completed', ... },
|
|
15
|
+
* { id: '2', status: 'in-progress', ... },
|
|
16
|
+
* { id: '3', status: 'pending', ... },
|
|
17
|
+
* ],
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* return (
|
|
21
|
+
* <div>
|
|
22
|
+
* <div>Progress: {percentage}%</div>
|
|
23
|
+
* <div>Status: {status}</div>
|
|
24
|
+
* </div>
|
|
25
|
+
* )
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
import { useMemo } from "react";
|
|
30
|
+
/**
|
|
31
|
+
* Calcula progresso padrão baseado no status
|
|
32
|
+
*/
|
|
33
|
+
function getDefaultProgress(project) {
|
|
34
|
+
if (project.progress !== undefined) {
|
|
35
|
+
return project.progress;
|
|
36
|
+
}
|
|
37
|
+
switch (project.status) {
|
|
38
|
+
case "completed":
|
|
39
|
+
return 100;
|
|
40
|
+
case "in-progress":
|
|
41
|
+
return 50; // Valor padrão para projetos em progresso
|
|
42
|
+
case "pending":
|
|
43
|
+
return 0;
|
|
44
|
+
case "on-hold":
|
|
45
|
+
return 0;
|
|
46
|
+
default:
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Hook headless para calcular progresso de projetos
|
|
52
|
+
*/
|
|
53
|
+
export function useProjectProgress(options) {
|
|
54
|
+
const { projects, calculateProgress = getDefaultProgress } = options;
|
|
55
|
+
const result = useMemo(() => {
|
|
56
|
+
if (projects.length === 0) {
|
|
57
|
+
return {
|
|
58
|
+
percentage: 0,
|
|
59
|
+
status: "pending",
|
|
60
|
+
distribution: {
|
|
61
|
+
completed: 0,
|
|
62
|
+
inProgress: 0,
|
|
63
|
+
pending: 0,
|
|
64
|
+
onHold: 0,
|
|
65
|
+
},
|
|
66
|
+
total: 0,
|
|
67
|
+
completed: 0,
|
|
68
|
+
inProgress: 0,
|
|
69
|
+
pending: 0,
|
|
70
|
+
onHold: 0,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// Calcular distribuição
|
|
74
|
+
const distribution = {
|
|
75
|
+
completed: 0,
|
|
76
|
+
inProgress: 0,
|
|
77
|
+
pending: 0,
|
|
78
|
+
onHold: 0,
|
|
79
|
+
};
|
|
80
|
+
let totalProgress = 0;
|
|
81
|
+
projects.forEach((project) => {
|
|
82
|
+
const progress = calculateProgress(project);
|
|
83
|
+
totalProgress += progress;
|
|
84
|
+
switch (project.status) {
|
|
85
|
+
case "completed":
|
|
86
|
+
distribution.completed++;
|
|
87
|
+
break;
|
|
88
|
+
case "in-progress":
|
|
89
|
+
distribution.inProgress++;
|
|
90
|
+
break;
|
|
91
|
+
case "pending":
|
|
92
|
+
distribution.pending++;
|
|
93
|
+
break;
|
|
94
|
+
case "on-hold":
|
|
95
|
+
distribution.onHold++;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Calcular porcentagem média
|
|
100
|
+
const percentage = Math.round(totalProgress / projects.length);
|
|
101
|
+
// Determinar status geral
|
|
102
|
+
let status = "pending";
|
|
103
|
+
if (distribution.completed === projects.length) {
|
|
104
|
+
status = "completed";
|
|
105
|
+
}
|
|
106
|
+
else if (distribution.inProgress > 0 || distribution.completed > 0) {
|
|
107
|
+
status = "in-progress";
|
|
108
|
+
}
|
|
109
|
+
else if (distribution.onHold > 0) {
|
|
110
|
+
status = "on-hold";
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
percentage,
|
|
114
|
+
status,
|
|
115
|
+
distribution,
|
|
116
|
+
total: projects.length,
|
|
117
|
+
completed: distribution.completed,
|
|
118
|
+
inProgress: distribution.inProgress,
|
|
119
|
+
pending: distribution.pending,
|
|
120
|
+
onHold: distribution.onHold,
|
|
121
|
+
};
|
|
122
|
+
}, [projects, calculateProgress]);
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProjectStats/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useProjectStats } from "./useProjectStats";
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProjectStats - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function MyProjectStats() {
|
|
12
|
+
* const { total, ended, running, pending, stats } = useProjectStats({
|
|
13
|
+
* projects: [
|
|
14
|
+
* { id: '1', status: 'running', ... },
|
|
15
|
+
* { id: '2', status: 'ended', ... },
|
|
16
|
+
* ],
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* return (
|
|
20
|
+
* <div>
|
|
21
|
+
* <div>Total: {total}</div>
|
|
22
|
+
* <div>Running: {running}</div>
|
|
23
|
+
* <div>Ended: {ended}</div>
|
|
24
|
+
* <div>Pending: {pending}</div>
|
|
25
|
+
* </div>
|
|
26
|
+
* )
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export type ProjectStatus = "running" | "ended" | "pending" | "on-hold" | "cancelled";
|
|
31
|
+
export interface Project {
|
|
32
|
+
id: string;
|
|
33
|
+
status: ProjectStatus;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
export interface UseProjectStatsOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Lista de projetos
|
|
39
|
+
*/
|
|
40
|
+
projects: Project[];
|
|
41
|
+
/**
|
|
42
|
+
* Função customizada para filtrar projetos
|
|
43
|
+
*/
|
|
44
|
+
filter?: (project: Project) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Função customizada para agrupar projetos
|
|
47
|
+
*/
|
|
48
|
+
groupBy?: (project: Project) => string;
|
|
49
|
+
}
|
|
50
|
+
export interface ProjectStats {
|
|
51
|
+
/**
|
|
52
|
+
* Total de projetos
|
|
53
|
+
*/
|
|
54
|
+
total: number;
|
|
55
|
+
/**
|
|
56
|
+
* Projetos finalizados
|
|
57
|
+
*/
|
|
58
|
+
ended: number;
|
|
59
|
+
/**
|
|
60
|
+
* Projetos em execução
|
|
61
|
+
*/
|
|
62
|
+
running: number;
|
|
63
|
+
/**
|
|
64
|
+
* Projetos pendentes
|
|
65
|
+
*/
|
|
66
|
+
pending: number;
|
|
67
|
+
/**
|
|
68
|
+
* Projetos em espera
|
|
69
|
+
*/
|
|
70
|
+
onHold: number;
|
|
71
|
+
/**
|
|
72
|
+
* Projetos cancelados
|
|
73
|
+
*/
|
|
74
|
+
cancelled: number;
|
|
75
|
+
/**
|
|
76
|
+
* Distribuição por status
|
|
77
|
+
*/
|
|
78
|
+
byStatus: Record<ProjectStatus, number>;
|
|
79
|
+
/**
|
|
80
|
+
* Projetos filtrados (se filter foi fornecido)
|
|
81
|
+
*/
|
|
82
|
+
filtered: Project[];
|
|
83
|
+
/**
|
|
84
|
+
* Projetos agrupados (se groupBy foi fornecido)
|
|
85
|
+
*/
|
|
86
|
+
grouped?: Record<string, Project[]>;
|
|
87
|
+
}
|
|
88
|
+
export interface UseProjectStatsReturn {
|
|
89
|
+
/**
|
|
90
|
+
* Estatísticas calculadas
|
|
91
|
+
*/
|
|
92
|
+
stats: ProjectStats;
|
|
93
|
+
/**
|
|
94
|
+
* Total de projetos
|
|
95
|
+
*/
|
|
96
|
+
total: number;
|
|
97
|
+
/**
|
|
98
|
+
* Projetos finalizados
|
|
99
|
+
*/
|
|
100
|
+
ended: number;
|
|
101
|
+
/**
|
|
102
|
+
* Projetos em execução
|
|
103
|
+
*/
|
|
104
|
+
running: number;
|
|
105
|
+
/**
|
|
106
|
+
* Projetos pendentes
|
|
107
|
+
*/
|
|
108
|
+
pending: number;
|
|
109
|
+
/**
|
|
110
|
+
* Projetos em espera
|
|
111
|
+
*/
|
|
112
|
+
onHold: number;
|
|
113
|
+
/**
|
|
114
|
+
* Projetos cancelados
|
|
115
|
+
*/
|
|
116
|
+
cancelled: number;
|
|
117
|
+
/**
|
|
118
|
+
* Projetos filtrados
|
|
119
|
+
*/
|
|
120
|
+
filtered: Project[];
|
|
121
|
+
/**
|
|
122
|
+
* Projetos agrupados
|
|
123
|
+
*/
|
|
124
|
+
grouped?: Record<string, Project[]>;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Hook headless para calcular estatísticas de projetos
|
|
128
|
+
*/
|
|
129
|
+
export declare function useProjectStats(options: UseProjectStatsOptions): UseProjectStatsReturn;
|
|
130
|
+
//# sourceMappingURL=useProjectStats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProjectStats.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProjectStats/useProjectStats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAEtF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;IAEvC;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAExC;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,KAAK,EAAE,YAAY,CAAC;IAEpB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;CACrC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CA8DtF"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProjectStats - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function MyProjectStats() {
|
|
12
|
+
* const { total, ended, running, pending, stats } = useProjectStats({
|
|
13
|
+
* projects: [
|
|
14
|
+
* { id: '1', status: 'running', ... },
|
|
15
|
+
* { id: '2', status: 'ended', ... },
|
|
16
|
+
* ],
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* return (
|
|
20
|
+
* <div>
|
|
21
|
+
* <div>Total: {total}</div>
|
|
22
|
+
* <div>Running: {running}</div>
|
|
23
|
+
* <div>Ended: {ended}</div>
|
|
24
|
+
* <div>Pending: {pending}</div>
|
|
25
|
+
* </div>
|
|
26
|
+
* )
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { useMemo } from "react";
|
|
31
|
+
/**
|
|
32
|
+
* Hook headless para calcular estatísticas de projetos
|
|
33
|
+
*/
|
|
34
|
+
export function useProjectStats(options) {
|
|
35
|
+
const { projects, filter, groupBy } = options;
|
|
36
|
+
const stats = useMemo(() => {
|
|
37
|
+
// Aplicar filtro se fornecido
|
|
38
|
+
const filtered = filter ? projects.filter(filter) : projects;
|
|
39
|
+
// Calcular contagens por status
|
|
40
|
+
const byStatus = {
|
|
41
|
+
running: 0,
|
|
42
|
+
ended: 0,
|
|
43
|
+
pending: 0,
|
|
44
|
+
"on-hold": 0,
|
|
45
|
+
cancelled: 0,
|
|
46
|
+
};
|
|
47
|
+
filtered.forEach((project) => {
|
|
48
|
+
const status = project.status || "pending";
|
|
49
|
+
if (status in byStatus) {
|
|
50
|
+
byStatus[status]++;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// Agrupar se groupBy foi fornecido
|
|
54
|
+
const grouped = groupBy
|
|
55
|
+
? filtered.reduce((acc, project) => {
|
|
56
|
+
const key = groupBy(project);
|
|
57
|
+
if (!acc[key]) {
|
|
58
|
+
acc[key] = [];
|
|
59
|
+
}
|
|
60
|
+
acc[key].push(project);
|
|
61
|
+
return acc;
|
|
62
|
+
}, {})
|
|
63
|
+
: undefined;
|
|
64
|
+
return {
|
|
65
|
+
total: filtered.length,
|
|
66
|
+
ended: byStatus.ended,
|
|
67
|
+
running: byStatus.running,
|
|
68
|
+
pending: byStatus.pending,
|
|
69
|
+
onHold: byStatus["on-hold"],
|
|
70
|
+
cancelled: byStatus.cancelled,
|
|
71
|
+
byStatus,
|
|
72
|
+
filtered,
|
|
73
|
+
grouped,
|
|
74
|
+
};
|
|
75
|
+
}, [projects, filter, groupBy]);
|
|
76
|
+
return {
|
|
77
|
+
stats,
|
|
78
|
+
total: stats.total,
|
|
79
|
+
ended: stats.ended,
|
|
80
|
+
running: stats.running,
|
|
81
|
+
pending: stats.pending,
|
|
82
|
+
onHold: stats.onHold,
|
|
83
|
+
cancelled: stats.cancelled,
|
|
84
|
+
filtered: stats.filtered,
|
|
85
|
+
grouped: stats.grouped,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useResizable/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useResizable/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* ```tsx
|
|
11
|
+
* // Cálculo automático do delta a partir de lastMonth
|
|
11
12
|
* function MyCustomStatCard() {
|
|
12
13
|
* const { formattedValue, trend, getCardProps } = useStatCard({
|
|
13
14
|
* value: 122380,
|
|
14
|
-
* delta: 15.
|
|
15
|
-
* lastMonth: 105922,
|
|
15
|
+
* lastMonth: 105922, // delta será calculado automaticamente: +15.5%
|
|
16
16
|
* })
|
|
17
17
|
*
|
|
18
18
|
* return (
|
|
@@ -22,35 +22,65 @@
|
|
|
22
22
|
* </div>
|
|
23
23
|
* )
|
|
24
24
|
* }
|
|
25
|
+
*
|
|
26
|
+
* // Ou forneça delta explicitamente para casos especiais
|
|
27
|
+
* function CustomDeltaCard() {
|
|
28
|
+
* const { formattedValue, trend } = useStatCard({
|
|
29
|
+
* value: 122380,
|
|
30
|
+
* delta: 15.1, // delta explícito tem prioridade
|
|
31
|
+
* lastMonth: 105922,
|
|
32
|
+
* })
|
|
33
|
+
* }
|
|
25
34
|
* ```
|
|
26
35
|
*/
|
|
27
36
|
export interface StatCardData {
|
|
28
37
|
/**
|
|
29
38
|
* Valor principal do card
|
|
30
39
|
*/
|
|
31
|
-
value: number;
|
|
40
|
+
value: number | string;
|
|
32
41
|
/**
|
|
33
42
|
* Percentual de variação (positivo ou negativo)
|
|
43
|
+
* Se não fornecido, será calculado automaticamente quando `lastMonth` estiver disponível.
|
|
44
|
+
* Fórmula: ((value - lastMonth) / lastMonth) * 100
|
|
34
45
|
*/
|
|
35
46
|
delta?: number;
|
|
36
47
|
/**
|
|
37
48
|
* Valor do mês anterior para comparação
|
|
49
|
+
* Se fornecido e `delta` não estiver definido, o delta será calculado automaticamente.
|
|
38
50
|
*/
|
|
39
51
|
lastMonth?: number;
|
|
40
52
|
/**
|
|
41
53
|
* Prefixo para formatação do valor (ex: '$', 'R$')
|
|
54
|
+
* Se `locale` e `currency` forem fornecidos, será ignorado em favor da formatação de moeda
|
|
42
55
|
*/
|
|
43
56
|
prefix?: string;
|
|
44
57
|
/**
|
|
45
58
|
* Sufixo para formatação do valor (ex: 'M', 'K')
|
|
46
59
|
*/
|
|
47
60
|
suffix?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Locale para formatação numérica (ex: 'pt-BR', 'en-US', 'de-DE')
|
|
63
|
+
* Padrão: 'pt-BR' (formata com ponto como separador de milhares)
|
|
64
|
+
*/
|
|
65
|
+
locale?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Código da moeda para formatação (ex: 'BRL', 'USD', 'EUR')
|
|
68
|
+
* Se fornecido, usa formatação de moeda do locale
|
|
69
|
+
*/
|
|
70
|
+
currency?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Como exibir a moeda ('symbol' | 'narrowSymbol' | 'code' | 'name')
|
|
73
|
+
* Padrão: 'symbol' (ex: R$ para BRL, $ para USD)
|
|
74
|
+
*/
|
|
75
|
+
currencyDisplay?: "symbol" | "narrowSymbol" | "code" | "name";
|
|
48
76
|
/**
|
|
49
77
|
* Função customizada de formatação do valor principal
|
|
78
|
+
* Tem prioridade sobre locale e currency
|
|
50
79
|
*/
|
|
51
80
|
format?: (value: number) => string;
|
|
52
81
|
/**
|
|
53
82
|
* Função customizada de formatação do valor do mês anterior
|
|
83
|
+
* Tem prioridade sobre locale e currency
|
|
54
84
|
*/
|
|
55
85
|
lastFormat?: (value: number) => string;
|
|
56
86
|
/**
|
|
@@ -124,11 +154,11 @@ export interface UseStatCardReturn {
|
|
|
124
154
|
*
|
|
125
155
|
* @example
|
|
126
156
|
* ```tsx
|
|
157
|
+
* // Cálculo automático do delta a partir de lastMonth
|
|
127
158
|
* function MyCustomStatCard() {
|
|
128
159
|
* const { formattedValue, trend, getCardProps } = useStatCard({
|
|
129
160
|
* value: 122380,
|
|
130
|
-
* delta: 15.
|
|
131
|
-
* lastMonth: 105922,
|
|
161
|
+
* lastMonth: 105922, // delta será calculado automaticamente: +15.5%
|
|
132
162
|
* })
|
|
133
163
|
*
|
|
134
164
|
* return (
|
|
@@ -138,6 +168,15 @@ export interface UseStatCardReturn {
|
|
|
138
168
|
* </div>
|
|
139
169
|
* )
|
|
140
170
|
* }
|
|
171
|
+
*
|
|
172
|
+
* // Ou forneça delta explicitamente para casos especiais
|
|
173
|
+
* function CustomDeltaCard() {
|
|
174
|
+
* const { formattedValue, trend } = useStatCard({
|
|
175
|
+
* value: 122380,
|
|
176
|
+
* delta: 15.1, // delta explícito tem prioridade
|
|
177
|
+
* lastMonth: 105922,
|
|
178
|
+
* })
|
|
179
|
+
* }
|
|
141
180
|
* ```
|
|
142
181
|
*/
|
|
143
182
|
export declare function useStatCard(data: StatCardData): UseStatCardReturn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStatCard.d.ts","sourceRoot":"","sources":["../../../src/hooks/useStatCard/useStatCard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"useStatCard.d.ts","sourceRoot":"","sources":["../../../src/hooks/useStatCard/useStatCard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAEvB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,eAAe,CAAC,EAAE,QAAQ,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;IAE9D;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAEnC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,OAAO,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;IAEjD;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,YAAY,EAAE,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK;QAC7F,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IAEF;;OAEG;IACH,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAwCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,iBAAiB,CAwHjE"}
|