prjct-cli 0.18.2 → 0.19.0

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.
Files changed (243) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/CLAUDE.md +74 -211
  3. package/core/agentic/prompt-builder.ts +3 -7
  4. package/core/command-registry/optional-commands.ts +0 -20
  5. package/core/infrastructure/command-installer/command-installer.ts +8 -1
  6. package/core/infrastructure/command-installer/global-config.ts +31 -1
  7. package/core/infrastructure/command-installer/index.ts +1 -1
  8. package/core/infrastructure/setup.ts +3 -0
  9. package/package.json +3 -17
  10. package/templates/commands/done.md +57 -258
  11. package/templates/commands/now.md +72 -277
  12. package/templates/commands/ship.md +55 -261
  13. package/templates/commands/test.md +328 -21
  14. package/templates/global/CLAUDE.md +40 -205
  15. package/templates/global/docs/agents.md +88 -0
  16. package/templates/global/docs/architecture.md +103 -0
  17. package/templates/global/docs/commands.md +98 -0
  18. package/templates/global/docs/validation.md +95 -0
  19. package/templates/mcp-config.json +36 -0
  20. package/bin/dev.js +0 -216
  21. package/bin/serve.js +0 -361
  22. package/packages/web/README.md +0 -36
  23. package/packages/web/app/api/claude/sessions/route.ts +0 -44
  24. package/packages/web/app/api/claude/status/route.ts +0 -34
  25. package/packages/web/app/api/projects/[id]/icon/route.ts +0 -33
  26. package/packages/web/app/api/projects/[id]/momentum/route.ts +0 -257
  27. package/packages/web/app/api/projects/[id]/route.ts +0 -29
  28. package/packages/web/app/api/projects/[id]/stats/route.ts +0 -41
  29. package/packages/web/app/api/projects/[id]/status/route.ts +0 -21
  30. package/packages/web/app/api/projects/route.ts +0 -16
  31. package/packages/web/app/api/sessions/current/route.ts +0 -132
  32. package/packages/web/app/api/sessions/history/route.ts +0 -204
  33. package/packages/web/app/error.tsx +0 -34
  34. package/packages/web/app/favicon.ico +0 -0
  35. package/packages/web/app/globals.css +0 -198
  36. package/packages/web/app/layout.tsx +0 -53
  37. package/packages/web/app/loading.tsx +0 -7
  38. package/packages/web/app/not-found.tsx +0 -25
  39. package/packages/web/app/page.tsx +0 -12
  40. package/packages/web/app/project/[id]/code/layout.tsx +0 -18
  41. package/packages/web/app/project/[id]/code/page.tsx +0 -408
  42. package/packages/web/app/project/[id]/error.tsx +0 -41
  43. package/packages/web/app/project/[id]/loading.tsx +0 -9
  44. package/packages/web/app/project/[id]/not-found.tsx +0 -27
  45. package/packages/web/app/project/[id]/page.tsx +0 -384
  46. package/packages/web/app/project/[id]/reports/page.tsx +0 -59
  47. package/packages/web/app/project/[id]/reports/print/page.tsx +0 -58
  48. package/packages/web/app/sessions/page.tsx +0 -165
  49. package/packages/web/app/settings/page.tsx +0 -151
  50. package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +0 -2
  51. package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +0 -49
  52. package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +0 -8
  53. package/packages/web/components/ActivityTimeline/hooks/index.ts +0 -2
  54. package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +0 -9
  55. package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +0 -23
  56. package/packages/web/components/ActivityTimeline/index.ts +0 -2
  57. package/packages/web/components/AgentsCard/AgentsCard.tsx +0 -93
  58. package/packages/web/components/AgentsCard/AgentsCard.types.ts +0 -14
  59. package/packages/web/components/AgentsCard/index.ts +0 -2
  60. package/packages/web/components/AppSidebar/AppSidebar.tsx +0 -316
  61. package/packages/web/components/AppSidebar/index.ts +0 -1
  62. package/packages/web/components/BackLink/BackLink.tsx +0 -18
  63. package/packages/web/components/BackLink/BackLink.types.ts +0 -5
  64. package/packages/web/components/BackLink/index.ts +0 -2
  65. package/packages/web/components/BentoCard/BentoCard.constants.ts +0 -16
  66. package/packages/web/components/BentoCard/BentoCard.tsx +0 -48
  67. package/packages/web/components/BentoCard/BentoCard.types.ts +0 -15
  68. package/packages/web/components/BentoCard/index.ts +0 -2
  69. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +0 -9
  70. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +0 -18
  71. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +0 -5
  72. package/packages/web/components/BentoCardSkeleton/index.ts +0 -2
  73. package/packages/web/components/BentoGrid/BentoGrid.tsx +0 -18
  74. package/packages/web/components/BentoGrid/BentoGrid.types.ts +0 -4
  75. package/packages/web/components/BentoGrid/index.ts +0 -2
  76. package/packages/web/components/BlockersCard/BlockersCard.tsx +0 -75
  77. package/packages/web/components/BlockersCard/BlockersCard.types.ts +0 -12
  78. package/packages/web/components/BlockersCard/index.ts +0 -2
  79. package/packages/web/components/CommandBar/CommandBar.tsx +0 -67
  80. package/packages/web/components/CommandBar/index.ts +0 -1
  81. package/packages/web/components/CommandButton/CommandButton.tsx +0 -46
  82. package/packages/web/components/CommandButton/index.ts +0 -1
  83. package/packages/web/components/ConnectionStatus/ConnectionStatus.tsx +0 -29
  84. package/packages/web/components/ConnectionStatus/index.ts +0 -1
  85. package/packages/web/components/DashboardContent/DashboardContent.tsx +0 -284
  86. package/packages/web/components/DashboardContent/index.ts +0 -1
  87. package/packages/web/components/DateGroup/DateGroup.tsx +0 -18
  88. package/packages/web/components/DateGroup/DateGroup.types.ts +0 -6
  89. package/packages/web/components/DateGroup/DateGroup.utils.ts +0 -11
  90. package/packages/web/components/DateGroup/index.ts +0 -2
  91. package/packages/web/components/EmptyState/EmptyState.tsx +0 -76
  92. package/packages/web/components/EmptyState/EmptyState.types.ts +0 -11
  93. package/packages/web/components/EmptyState/index.ts +0 -2
  94. package/packages/web/components/EventRow/EventRow.constants.ts +0 -10
  95. package/packages/web/components/EventRow/EventRow.tsx +0 -49
  96. package/packages/web/components/EventRow/EventRow.types.ts +0 -7
  97. package/packages/web/components/EventRow/EventRow.utils.ts +0 -49
  98. package/packages/web/components/EventRow/index.ts +0 -2
  99. package/packages/web/components/ExpandButton/ExpandButton.tsx +0 -18
  100. package/packages/web/components/ExpandButton/ExpandButton.types.ts +0 -6
  101. package/packages/web/components/ExpandButton/index.ts +0 -2
  102. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +0 -14
  103. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +0 -5
  104. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +0 -13
  105. package/packages/web/components/HealthGradientBackground/index.ts +0 -2
  106. package/packages/web/components/HeroSection/HeroSection.tsx +0 -92
  107. package/packages/web/components/HeroSection/HeroSection.types.ts +0 -14
  108. package/packages/web/components/HeroSection/HeroSection.utils.ts +0 -11
  109. package/packages/web/components/HeroSection/hooks/index.ts +0 -2
  110. package/packages/web/components/HeroSection/hooks/useCountUp.ts +0 -45
  111. package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +0 -18
  112. package/packages/web/components/HeroSection/index.ts +0 -2
  113. package/packages/web/components/IdeasCard/IdeasCard.tsx +0 -115
  114. package/packages/web/components/IdeasCard/IdeasCard.types.ts +0 -10
  115. package/packages/web/components/IdeasCard/index.ts +0 -2
  116. package/packages/web/components/InsightMessage/InsightMessage.tsx +0 -9
  117. package/packages/web/components/InsightMessage/InsightMessage.types.ts +0 -3
  118. package/packages/web/components/InsightMessage/index.ts +0 -2
  119. package/packages/web/components/Logo/Logo.tsx +0 -65
  120. package/packages/web/components/Logo/index.ts +0 -1
  121. package/packages/web/components/MarkdownContent/MarkdownContent.tsx +0 -123
  122. package/packages/web/components/MarkdownContent/index.ts +0 -1
  123. package/packages/web/components/MasonryGrid/MasonryGrid.tsx +0 -18
  124. package/packages/web/components/MasonryGrid/index.ts +0 -1
  125. package/packages/web/components/MomentumWidget/MomentumWidget.tsx +0 -119
  126. package/packages/web/components/MomentumWidget/MomentumWidget.types.ts +0 -16
  127. package/packages/web/components/MomentumWidget/index.ts +0 -2
  128. package/packages/web/components/NowCard/NowCard.tsx +0 -118
  129. package/packages/web/components/NowCard/NowCard.types.ts +0 -16
  130. package/packages/web/components/NowCard/index.ts +0 -2
  131. package/packages/web/components/PageHeader/PageHeader.tsx +0 -24
  132. package/packages/web/components/PageHeader/index.ts +0 -1
  133. package/packages/web/components/ProgressRing/ProgressRing.constants.ts +0 -20
  134. package/packages/web/components/ProgressRing/ProgressRing.tsx +0 -51
  135. package/packages/web/components/ProgressRing/ProgressRing.types.ts +0 -11
  136. package/packages/web/components/ProgressRing/index.ts +0 -2
  137. package/packages/web/components/ProjectAvatar/ProjectAvatar.tsx +0 -54
  138. package/packages/web/components/ProjectAvatar/index.ts +0 -1
  139. package/packages/web/components/ProjectColorDot/ProjectColorDot.tsx +0 -37
  140. package/packages/web/components/ProjectColorDot/index.ts +0 -1
  141. package/packages/web/components/ProjectSelectorModal/ProjectSelectorModal.tsx +0 -104
  142. package/packages/web/components/ProjectSelectorModal/index.ts +0 -1
  143. package/packages/web/components/Providers/Providers.tsx +0 -48
  144. package/packages/web/components/Providers/index.ts +0 -1
  145. package/packages/web/components/QueueCard/QueueCard.tsx +0 -125
  146. package/packages/web/components/QueueCard/QueueCard.types.ts +0 -12
  147. package/packages/web/components/QueueCard/QueueCard.utils.ts +0 -12
  148. package/packages/web/components/QueueCard/index.ts +0 -2
  149. package/packages/web/components/RecoverCard/RecoverCard.tsx +0 -72
  150. package/packages/web/components/RecoverCard/RecoverCard.types.ts +0 -16
  151. package/packages/web/components/RecoverCard/index.ts +0 -2
  152. package/packages/web/components/RoadmapCard/RoadmapCard.tsx +0 -145
  153. package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +0 -16
  154. package/packages/web/components/RoadmapCard/index.ts +0 -2
  155. package/packages/web/components/ShipsCard/ShipsCard.tsx +0 -95
  156. package/packages/web/components/ShipsCard/ShipsCard.types.ts +0 -14
  157. package/packages/web/components/ShipsCard/ShipsCard.utils.ts +0 -4
  158. package/packages/web/components/ShipsCard/index.ts +0 -2
  159. package/packages/web/components/SparklineChart/SparklineChart.tsx +0 -40
  160. package/packages/web/components/SparklineChart/SparklineChart.types.ts +0 -6
  161. package/packages/web/components/SparklineChart/index.ts +0 -2
  162. package/packages/web/components/StatsMasonry/StatsMasonry.tsx +0 -95
  163. package/packages/web/components/StatsMasonry/index.ts +0 -1
  164. package/packages/web/components/StreakCard/StreakCard.constants.ts +0 -2
  165. package/packages/web/components/StreakCard/StreakCard.tsx +0 -55
  166. package/packages/web/components/StreakCard/StreakCard.types.ts +0 -4
  167. package/packages/web/components/StreakCard/index.ts +0 -2
  168. package/packages/web/components/TasksCounter/TasksCounter.tsx +0 -14
  169. package/packages/web/components/TasksCounter/TasksCounter.types.ts +0 -3
  170. package/packages/web/components/TasksCounter/index.ts +0 -2
  171. package/packages/web/components/TechStackBadges/TechStackBadges.tsx +0 -28
  172. package/packages/web/components/TechStackBadges/index.ts +0 -1
  173. package/packages/web/components/TerminalDock/DockToggleTab.tsx +0 -29
  174. package/packages/web/components/TerminalDock/TerminalDock.tsx +0 -386
  175. package/packages/web/components/TerminalDock/TerminalDockTab.tsx +0 -130
  176. package/packages/web/components/TerminalDock/TerminalTabBar.tsx +0 -142
  177. package/packages/web/components/TerminalDock/index.ts +0 -2
  178. package/packages/web/components/TerminalTabs/TerminalTab.tsx +0 -95
  179. package/packages/web/components/TerminalTabs/TerminalTabs.tsx +0 -211
  180. package/packages/web/components/TerminalTabs/index.ts +0 -1
  181. package/packages/web/components/VelocityBadge/VelocityBadge.tsx +0 -32
  182. package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +0 -3
  183. package/packages/web/components/VelocityBadge/index.ts +0 -2
  184. package/packages/web/components/VelocityCard/VelocityCard.tsx +0 -73
  185. package/packages/web/components/VelocityCard/VelocityCard.types.ts +0 -7
  186. package/packages/web/components/VelocityCard/index.ts +0 -2
  187. package/packages/web/components/WeeklyReports/PrintableReport.tsx +0 -259
  188. package/packages/web/components/WeeklyReports/ReportPreviewCard.tsx +0 -187
  189. package/packages/web/components/WeeklyReports/WeekCalendar.tsx +0 -288
  190. package/packages/web/components/WeeklyReports/WeeklyReports.tsx +0 -149
  191. package/packages/web/components/WeeklyReports/index.ts +0 -4
  192. package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +0 -25
  193. package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +0 -4
  194. package/packages/web/components/WeeklySparkline/index.ts +0 -2
  195. package/packages/web/components/charts/SessionsChart.tsx +0 -175
  196. package/packages/web/components/ui/alert-dialog.tsx +0 -157
  197. package/packages/web/components/ui/badge.tsx +0 -46
  198. package/packages/web/components/ui/button.tsx +0 -60
  199. package/packages/web/components/ui/card.tsx +0 -92
  200. package/packages/web/components/ui/chart.tsx +0 -385
  201. package/packages/web/components/ui/dialog.tsx +0 -143
  202. package/packages/web/components/ui/drawer.tsx +0 -135
  203. package/packages/web/components/ui/dropdown-menu.tsx +0 -257
  204. package/packages/web/components/ui/input.tsx +0 -21
  205. package/packages/web/components/ui/scroll-area.tsx +0 -58
  206. package/packages/web/components/ui/select.tsx +0 -187
  207. package/packages/web/components/ui/sheet.tsx +0 -139
  208. package/packages/web/components/ui/tabs.tsx +0 -66
  209. package/packages/web/components/ui/tooltip.tsx +0 -61
  210. package/packages/web/components.json +0 -22
  211. package/packages/web/context/GlobalTerminalContext.tsx +0 -538
  212. package/packages/web/context/TerminalContext.tsx +0 -45
  213. package/packages/web/context/TerminalTabsContext.tsx +0 -181
  214. package/packages/web/eslint.config.mjs +0 -18
  215. package/packages/web/hooks/useClaudeTerminal.ts +0 -425
  216. package/packages/web/hooks/useProjectStats.ts +0 -93
  217. package/packages/web/hooks/useProjects.ts +0 -73
  218. package/packages/web/lib/actions/projects.ts +0 -15
  219. package/packages/web/lib/commands.ts +0 -81
  220. package/packages/web/lib/format.ts +0 -23
  221. package/packages/web/lib/generate-week-report.ts +0 -285
  222. package/packages/web/lib/parse-prjct-files.ts +0 -1123
  223. package/packages/web/lib/project-colors.ts +0 -58
  224. package/packages/web/lib/projects.ts +0 -506
  225. package/packages/web/lib/pty.ts +0 -101
  226. package/packages/web/lib/query-config.ts +0 -44
  227. package/packages/web/lib/services/index.ts +0 -9
  228. package/packages/web/lib/services/projects.server.ts +0 -66
  229. package/packages/web/lib/services/stats.server.ts +0 -562
  230. package/packages/web/lib/unified-loader.ts +0 -396
  231. package/packages/web/lib/utils.ts +0 -6
  232. package/packages/web/next-env.d.ts +0 -6
  233. package/packages/web/next.config.ts +0 -7
  234. package/packages/web/package.json +0 -57
  235. package/packages/web/postcss.config.mjs +0 -7
  236. package/packages/web/public/file.svg +0 -1
  237. package/packages/web/public/globe.svg +0 -1
  238. package/packages/web/public/next.svg +0 -1
  239. package/packages/web/public/vercel.svg +0 -1
  240. package/packages/web/public/window.svg +0 -1
  241. package/packages/web/server.ts +0 -312
  242. package/packages/web/tsconfig.json +0 -34
  243. package/templates/commands/serve.md +0 -121
@@ -1,259 +0,0 @@
1
- 'use client'
2
-
3
- import { useMemo } from 'react'
4
- import { useParams } from 'next/navigation'
5
- import Link from 'next/link'
6
- import { Rocket, CheckCircle2, Bug, Calendar, Printer, ArrowLeft } from 'lucide-react'
7
- import {
8
- filterDataByWeek,
9
- formatDateRange,
10
- type WeekData,
11
- } from '@/lib/generate-week-report'
12
- import type { StatsResult } from '@/lib/services/stats.server'
13
-
14
- interface PrintableReportProps {
15
- stats: StatsResult
16
- projectName: string
17
- selectedWeeks: number[]
18
- year: number
19
- }
20
-
21
- export function PrintableReport({
22
- stats,
23
- projectName,
24
- selectedWeeks,
25
- year,
26
- }: PrintableReportProps) {
27
- const params = useParams()
28
- const projectId = params.id as string
29
-
30
- const weekDataList = useMemo(() => {
31
- return selectedWeeks.map(w => filterDataByWeek(stats, year, w))
32
- }, [stats, year, selectedWeeks])
33
-
34
- // Aggregate data
35
- const allShipped = weekDataList.flatMap(w => w.shipped)
36
- const uniqueShipsMap = new Map<string, typeof allShipped[0]>()
37
- for (const ship of allShipped) {
38
- if (!uniqueShipsMap.has(ship.name)) {
39
- uniqueShipsMap.set(ship.name, ship)
40
- }
41
- }
42
- // Sort by date descending (most recent first)
43
- const uniqueShips = Array.from(uniqueShipsMap.values())
44
- .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
45
-
46
- // Group ships by date for display
47
- const shipsByDate = new Map<string, typeof uniqueShips>()
48
- for (const ship of uniqueShips) {
49
- const dateKey = ship.date
50
- if (!shipsByDate.has(dateKey)) {
51
- shipsByDate.set(dateKey, [])
52
- }
53
- shipsByDate.get(dateKey)!.push(ship)
54
- }
55
-
56
- const totalTasks = weekDataList.reduce((sum, w) => sum + w.tasksCompleted, 0)
57
- const totalBugs = weekDataList.reduce((sum, w) => sum + w.bugsFixed, 0)
58
- const totalDays = weekDataList.reduce((sum, w) => sum + w.activeDays, 0)
59
-
60
- // Date range
61
- const firstWeek = weekDataList[0]
62
- const lastWeek = weekDataList[weekDataList.length - 1]
63
- const dateRangeStr = weekDataList.length === 1
64
- ? formatDateRange(firstWeek.startDate, firstWeek.endDate)
65
- : formatDateRange(firstWeek.startDate, lastWeek.endDate)
66
-
67
- const weekLabel = weekDataList.length === 1
68
- ? `Semana ${firstWeek.week}`
69
- : `Semanas ${firstWeek.week}-${lastWeek.week}`
70
-
71
- const handlePrint = () => {
72
- window.print()
73
- }
74
-
75
- return (
76
- <div className="min-h-screen bg-white">
77
- {/* Action buttons - hidden when printing */}
78
- <div className="print:hidden fixed top-4 right-4 z-50 flex items-center gap-2">
79
- <Link
80
- href={`/project/${projectId}/reports`}
81
- className="flex items-center gap-2 px-4 py-2 bg-white text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors shadow-lg"
82
- >
83
- <ArrowLeft className="h-4 w-4" />
84
- Regresar
85
- </Link>
86
- <button
87
- onClick={handlePrint}
88
- className="flex items-center gap-2 px-4 py-2 bg-gray-900 text-white rounded-lg hover:bg-gray-800 transition-colors shadow-lg"
89
- >
90
- <Printer className="h-4 w-4" />
91
- Imprimir / PDF
92
- </button>
93
- </div>
94
-
95
- {/* Printable content */}
96
- <div className="max-w-2xl mx-auto p-8 print:p-0 print:max-w-none">
97
- {/* Header */}
98
- <header className="mb-8 pb-6 border-b-2 border-gray-200">
99
- <h1 className="text-3xl font-bold text-gray-900 mb-2">{projectName}</h1>
100
- <p className="text-lg text-gray-600">
101
- Reporte de Progreso - {weekLabel}
102
- </p>
103
- <p className="text-gray-500">{dateRangeStr}, {year}</p>
104
- </header>
105
-
106
- {/* Stats Summary */}
107
- <section className="mb-8">
108
- <div className="grid grid-cols-4 gap-4">
109
- <StatBox
110
- icon={<Rocket className="h-6 w-6" />}
111
- value={uniqueShips.length}
112
- label="Entregados"
113
- color="text-emerald-600"
114
- />
115
- <StatBox
116
- icon={<CheckCircle2 className="h-6 w-6" />}
117
- value={totalTasks}
118
- label="Tareas"
119
- color="text-blue-600"
120
- />
121
- <StatBox
122
- icon={<Bug className="h-6 w-6" />}
123
- value={totalBugs}
124
- label="Bugs"
125
- color="text-orange-600"
126
- />
127
- <StatBox
128
- icon={<Calendar className="h-6 w-6" />}
129
- value={totalDays}
130
- label="Dias Activos"
131
- color="text-purple-600"
132
- />
133
- </div>
134
- </section>
135
-
136
- {/* Shipped Features grouped by date */}
137
- {uniqueShips.length > 0 && (
138
- <section className="mb-8">
139
- <h2 className="text-xl font-semibold text-gray-900 mb-4 flex items-center gap-2">
140
- <Rocket className="h-5 w-5 text-emerald-600" />
141
- Entregado
142
- </h2>
143
- <div className="space-y-5">
144
- {Array.from(shipsByDate.entries()).map(([date, ships]) => (
145
- <div key={date}>
146
- <p className="text-sm font-medium text-gray-500 mb-2">
147
- {new Date(date).toLocaleDateString('es-MX', {
148
- weekday: 'long',
149
- month: 'long',
150
- day: 'numeric'
151
- })}
152
- </p>
153
- <ul className="space-y-2 pl-4 border-l-2 border-emerald-200">
154
- {ships.map((ship, i) => (
155
- <li key={i} className="pl-3 text-gray-700">
156
- <span className="font-medium">{ship.name}</span>
157
- {ship.version && (
158
- <span className="ml-2 text-sm text-gray-500 bg-gray-100 px-2 py-0.5 rounded">
159
- {ship.version}
160
- </span>
161
- )}
162
- </li>
163
- ))}
164
- </ul>
165
- </div>
166
- ))}
167
- </div>
168
- </section>
169
- )}
170
-
171
- {/* Activity Details */}
172
- {(totalTasks > 0 || totalBugs > 0) && (
173
- <section className="mb-8">
174
- <h2 className="text-xl font-semibold text-gray-900 mb-4 flex items-center gap-2">
175
- <CheckCircle2 className="h-5 w-5 text-blue-600" />
176
- Actividad
177
- </h2>
178
- <ul className="space-y-2 text-gray-700">
179
- {totalTasks > 0 && (
180
- <li className="flex items-center gap-2">
181
- <CheckCircle2 className="h-4 w-4 text-blue-500" />
182
- {totalTasks} tarea{totalTasks !== 1 ? 's' : ''} completada{totalTasks !== 1 ? 's' : ''}
183
- </li>
184
- )}
185
- {totalBugs > 0 && (
186
- <li className="flex items-center gap-2">
187
- <Bug className="h-4 w-4 text-orange-500" />
188
- {totalBugs} bug{totalBugs !== 1 ? 's' : ''} corregido{totalBugs !== 1 ? 's' : ''}
189
- </li>
190
- )}
191
- {totalDays > 0 && (
192
- <li className="flex items-center gap-2">
193
- <Calendar className="h-4 w-4 text-purple-500" />
194
- {totalDays} dia{totalDays !== 1 ? 's' : ''} activo{totalDays !== 1 ? 's' : ''}
195
- </li>
196
- )}
197
- </ul>
198
- </section>
199
- )}
200
-
201
- {/* No activity message */}
202
- {uniqueShips.length === 0 && totalTasks === 0 && totalBugs === 0 && (
203
- <section className="mb-8 p-6 bg-gray-50 rounded-lg text-center text-gray-500">
204
- Sin actividad registrada para este periodo
205
- </section>
206
- )}
207
-
208
- {/* Next Steps placeholder */}
209
- <section className="mb-8">
210
- <h2 className="text-xl font-semibold text-gray-900 mb-4">
211
- Siguiente
212
- </h2>
213
- <ul className="space-y-2 text-gray-600">
214
- <li className="flex items-center gap-2">
215
- <span className="text-gray-400">&#x2022;</span>
216
- <span className="italic text-gray-400">[Pendiente por definir]</span>
217
- </li>
218
- </ul>
219
- </section>
220
-
221
- {/* Footer */}
222
- <footer className="mt-12 pt-6 border-t border-gray-200 text-sm text-gray-400 text-center print:mt-8">
223
- <p>Generado con prjct - {new Date().toLocaleDateString('es-MX')}</p>
224
- </footer>
225
- </div>
226
-
227
- {/* Print styles */}
228
- <style jsx global>{`
229
- @media print {
230
- @page {
231
- size: letter;
232
- margin: 1in;
233
- }
234
- body {
235
- -webkit-print-color-adjust: exact;
236
- print-color-adjust: exact;
237
- }
238
- }
239
- `}</style>
240
- </div>
241
- )
242
- }
243
-
244
- interface StatBoxProps {
245
- icon: React.ReactNode
246
- value: number
247
- label: string
248
- color: string
249
- }
250
-
251
- function StatBox({ icon, value, label, color }: StatBoxProps) {
252
- return (
253
- <div className="text-center p-4 border border-gray-200 rounded-lg">
254
- <div className={`${color} flex justify-center mb-2`}>{icon}</div>
255
- <div className="text-2xl font-bold text-gray-900">{value}</div>
256
- <div className="text-sm text-gray-500">{label}</div>
257
- </div>
258
- )
259
- }
@@ -1,187 +0,0 @@
1
- 'use client'
2
-
3
- import { Rocket, CheckCircle2, Bug, Activity } from 'lucide-react'
4
- import { cn } from '@/lib/utils'
5
- import { formatDateRange } from '@/lib/generate-week-report'
6
- import type { WeekData } from '@/lib/generate-week-report'
7
-
8
- interface ReportPreviewCardProps {
9
- weekData: WeekData[]
10
- className?: string
11
- }
12
-
13
- export function ReportPreviewCard({ weekData, className }: ReportPreviewCardProps) {
14
- if (weekData.length === 0) {
15
- return (
16
- <div className={cn('rounded-xl border bg-card p-6', className)}>
17
- <p className="text-muted-foreground text-center">Select a week to preview</p>
18
- </div>
19
- )
20
- }
21
-
22
- // Aggregate data from all selected weeks
23
- const allShipped = weekData.flatMap(w => w.shipped)
24
- const uniqueShipsMap = new Map<string, typeof allShipped[0]>()
25
- for (const ship of allShipped) {
26
- if (!uniqueShipsMap.has(ship.name)) {
27
- uniqueShipsMap.set(ship.name, ship)
28
- }
29
- }
30
- // Sort by date descending (most recent first)
31
- const uniqueShips = Array.from(uniqueShipsMap.values())
32
- .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
33
-
34
- // Group ships by date for display
35
- const shipsByDate = new Map<string, typeof uniqueShips>()
36
- for (const ship of uniqueShips) {
37
- const dateKey = ship.date
38
- if (!shipsByDate.has(dateKey)) {
39
- shipsByDate.set(dateKey, [])
40
- }
41
- shipsByDate.get(dateKey)!.push(ship)
42
- }
43
-
44
- const totalTasks = weekData.reduce((sum, w) => sum + w.tasksCompleted, 0)
45
- const totalBugs = weekData.reduce((sum, w) => sum + w.bugsFixed, 0)
46
- const totalSyncs = weekData.reduce((sum, w) => sum + w.syncs, 0)
47
- const totalDays = weekData.reduce((sum, w) => sum + w.activeDays, 0)
48
-
49
- // Date range header
50
- const firstWeek = weekData[0]
51
- const lastWeek = weekData[weekData.length - 1]
52
- const dateRangeStr = weekData.length === 1
53
- ? `Week ${firstWeek.week} · ${formatDateRange(firstWeek.startDate, firstWeek.endDate)}`
54
- : `Weeks ${firstWeek.week}-${lastWeek.week} · ${formatDateRange(firstWeek.startDate, lastWeek.endDate)}`
55
-
56
- const hasNoData = uniqueShips.length === 0 && totalTasks === 0 && totalBugs === 0 && totalDays === 0
57
-
58
- return (
59
- <div className={cn('rounded-xl border bg-card overflow-hidden', className)}>
60
- {/* Header */}
61
- <div className="px-6 py-4 border-b bg-muted/30">
62
- <h3 className="font-semibold text-lg">{dateRangeStr}</h3>
63
- </div>
64
-
65
- {hasNoData ? (
66
- <div className="p-6">
67
- <p className="text-muted-foreground text-center">No activity this week</p>
68
- </div>
69
- ) : (
70
- <div className="p-6 space-y-6">
71
- {/* Stats row */}
72
- <div className="grid grid-cols-4 gap-4">
73
- <StatCard
74
- icon={Rocket}
75
- value={uniqueShips.length}
76
- label="shipped"
77
- color="text-foreground"
78
- bgColor="bg-muted"
79
- />
80
- <StatCard
81
- icon={CheckCircle2}
82
- value={totalTasks}
83
- label="tasks"
84
- color="text-foreground"
85
- bgColor="bg-muted"
86
- />
87
- <StatCard
88
- icon={Bug}
89
- value={totalBugs}
90
- label="bugs"
91
- color="text-foreground"
92
- bgColor="bg-muted"
93
- />
94
- <StatCard
95
- icon={Activity}
96
- value={totalDays}
97
- label="days"
98
- color="text-foreground"
99
- bgColor="bg-muted"
100
- />
101
- </div>
102
-
103
- {/* Shipped list grouped by date */}
104
- {uniqueShips.length > 0 && (
105
- <div>
106
- <h4 className="text-xs font-medium text-muted-foreground uppercase tracking-wider mb-3">
107
- Shipped
108
- </h4>
109
- <div className="space-y-4">
110
- {Array.from(shipsByDate.entries()).map(([date, ships]) => (
111
- <div key={date}>
112
- <p className="text-xs text-muted-foreground mb-2">
113
- {new Date(date).toLocaleDateString('es-MX', {
114
- weekday: 'short',
115
- month: 'short',
116
- day: 'numeric'
117
- })}
118
- </p>
119
- <ul className="space-y-1.5 pl-2 border-l-2 border-muted-foreground/30">
120
- {ships.map((ship, i) => (
121
- <li key={i} className="flex items-start gap-2 pl-2">
122
- <span className="flex-1">
123
- {ship.name}
124
- {ship.version && (
125
- <span className="text-muted-foreground ml-1 text-sm">({ship.version})</span>
126
- )}
127
- </span>
128
- </li>
129
- ))}
130
- </ul>
131
- </div>
132
- ))}
133
- </div>
134
- </div>
135
- )}
136
-
137
- {/* Activity summary */}
138
- {(totalTasks > 0 || totalBugs > 0 || totalSyncs > 0) && (
139
- <div>
140
- <h4 className="text-xs font-medium text-muted-foreground uppercase tracking-wider mb-3">
141
- Activity
142
- </h4>
143
- <ul className="space-y-1 text-sm text-muted-foreground">
144
- {totalTasks > 0 && (
145
- <li className="flex items-center gap-2">
146
- <CheckCircle2 className="h-3.5 w-3.5 text-muted-foreground" />
147
- {totalTasks} task{totalTasks !== 1 ? 's' : ''} completed
148
- </li>
149
- )}
150
- {totalBugs > 0 && (
151
- <li className="flex items-center gap-2">
152
- <Bug className="h-3.5 w-3.5 text-muted-foreground" />
153
- {totalBugs} bug{totalBugs !== 1 ? 's' : ''} fixed
154
- </li>
155
- )}
156
- {totalSyncs > 0 && (
157
- <li className="flex items-center gap-2">
158
- <Activity className="h-3.5 w-3.5 text-muted-foreground" />
159
- {totalSyncs} sync{totalSyncs !== 1 ? 's' : ''}
160
- </li>
161
- )}
162
- </ul>
163
- </div>
164
- )}
165
- </div>
166
- )}
167
- </div>
168
- )
169
- }
170
-
171
- interface StatCardProps {
172
- icon: React.ElementType
173
- value: number
174
- label: string
175
- color: string
176
- bgColor: string
177
- }
178
-
179
- function StatCard({ icon: Icon, value, label, color, bgColor }: StatCardProps) {
180
- return (
181
- <div className={cn('rounded-xl p-4 text-center', bgColor)}>
182
- <Icon className={cn('h-5 w-5 mx-auto mb-1', color)} />
183
- <div className="text-2xl font-bold tabular-nums">{value}</div>
184
- <div className="text-xs text-muted-foreground">{label}</div>
185
- </div>
186
- )
187
- }