prjct-cli 0.18.1 → 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 (245) hide show
  1. package/CHANGELOG.md +53 -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/agentic/subagent-generation.md +8 -6
  11. package/templates/commands/done.md +57 -258
  12. package/templates/commands/now.md +72 -277
  13. package/templates/commands/ship.md +55 -261
  14. package/templates/commands/sync.md +7 -7
  15. package/templates/commands/test.md +328 -21
  16. package/templates/global/CLAUDE.md +40 -205
  17. package/templates/global/docs/agents.md +88 -0
  18. package/templates/global/docs/architecture.md +103 -0
  19. package/templates/global/docs/commands.md +98 -0
  20. package/templates/global/docs/validation.md +95 -0
  21. package/templates/mcp-config.json +36 -0
  22. package/bin/dev.js +0 -216
  23. package/bin/serve.js +0 -361
  24. package/packages/web/README.md +0 -36
  25. package/packages/web/app/api/claude/sessions/route.ts +0 -44
  26. package/packages/web/app/api/claude/status/route.ts +0 -34
  27. package/packages/web/app/api/projects/[id]/icon/route.ts +0 -33
  28. package/packages/web/app/api/projects/[id]/momentum/route.ts +0 -257
  29. package/packages/web/app/api/projects/[id]/route.ts +0 -29
  30. package/packages/web/app/api/projects/[id]/stats/route.ts +0 -41
  31. package/packages/web/app/api/projects/[id]/status/route.ts +0 -21
  32. package/packages/web/app/api/projects/route.ts +0 -16
  33. package/packages/web/app/api/sessions/current/route.ts +0 -132
  34. package/packages/web/app/api/sessions/history/route.ts +0 -204
  35. package/packages/web/app/error.tsx +0 -34
  36. package/packages/web/app/favicon.ico +0 -0
  37. package/packages/web/app/globals.css +0 -198
  38. package/packages/web/app/layout.tsx +0 -53
  39. package/packages/web/app/loading.tsx +0 -7
  40. package/packages/web/app/not-found.tsx +0 -25
  41. package/packages/web/app/page.tsx +0 -12
  42. package/packages/web/app/project/[id]/code/layout.tsx +0 -18
  43. package/packages/web/app/project/[id]/code/page.tsx +0 -408
  44. package/packages/web/app/project/[id]/error.tsx +0 -41
  45. package/packages/web/app/project/[id]/loading.tsx +0 -9
  46. package/packages/web/app/project/[id]/not-found.tsx +0 -27
  47. package/packages/web/app/project/[id]/page.tsx +0 -384
  48. package/packages/web/app/project/[id]/reports/page.tsx +0 -59
  49. package/packages/web/app/project/[id]/reports/print/page.tsx +0 -58
  50. package/packages/web/app/sessions/page.tsx +0 -165
  51. package/packages/web/app/settings/page.tsx +0 -151
  52. package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +0 -2
  53. package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +0 -49
  54. package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +0 -8
  55. package/packages/web/components/ActivityTimeline/hooks/index.ts +0 -2
  56. package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +0 -9
  57. package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +0 -23
  58. package/packages/web/components/ActivityTimeline/index.ts +0 -2
  59. package/packages/web/components/AgentsCard/AgentsCard.tsx +0 -93
  60. package/packages/web/components/AgentsCard/AgentsCard.types.ts +0 -14
  61. package/packages/web/components/AgentsCard/index.ts +0 -2
  62. package/packages/web/components/AppSidebar/AppSidebar.tsx +0 -316
  63. package/packages/web/components/AppSidebar/index.ts +0 -1
  64. package/packages/web/components/BackLink/BackLink.tsx +0 -18
  65. package/packages/web/components/BackLink/BackLink.types.ts +0 -5
  66. package/packages/web/components/BackLink/index.ts +0 -2
  67. package/packages/web/components/BentoCard/BentoCard.constants.ts +0 -16
  68. package/packages/web/components/BentoCard/BentoCard.tsx +0 -48
  69. package/packages/web/components/BentoCard/BentoCard.types.ts +0 -15
  70. package/packages/web/components/BentoCard/index.ts +0 -2
  71. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +0 -9
  72. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +0 -18
  73. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +0 -5
  74. package/packages/web/components/BentoCardSkeleton/index.ts +0 -2
  75. package/packages/web/components/BentoGrid/BentoGrid.tsx +0 -18
  76. package/packages/web/components/BentoGrid/BentoGrid.types.ts +0 -4
  77. package/packages/web/components/BentoGrid/index.ts +0 -2
  78. package/packages/web/components/BlockersCard/BlockersCard.tsx +0 -75
  79. package/packages/web/components/BlockersCard/BlockersCard.types.ts +0 -12
  80. package/packages/web/components/BlockersCard/index.ts +0 -2
  81. package/packages/web/components/CommandBar/CommandBar.tsx +0 -67
  82. package/packages/web/components/CommandBar/index.ts +0 -1
  83. package/packages/web/components/CommandButton/CommandButton.tsx +0 -46
  84. package/packages/web/components/CommandButton/index.ts +0 -1
  85. package/packages/web/components/ConnectionStatus/ConnectionStatus.tsx +0 -29
  86. package/packages/web/components/ConnectionStatus/index.ts +0 -1
  87. package/packages/web/components/DashboardContent/DashboardContent.tsx +0 -284
  88. package/packages/web/components/DashboardContent/index.ts +0 -1
  89. package/packages/web/components/DateGroup/DateGroup.tsx +0 -18
  90. package/packages/web/components/DateGroup/DateGroup.types.ts +0 -6
  91. package/packages/web/components/DateGroup/DateGroup.utils.ts +0 -11
  92. package/packages/web/components/DateGroup/index.ts +0 -2
  93. package/packages/web/components/EmptyState/EmptyState.tsx +0 -76
  94. package/packages/web/components/EmptyState/EmptyState.types.ts +0 -11
  95. package/packages/web/components/EmptyState/index.ts +0 -2
  96. package/packages/web/components/EventRow/EventRow.constants.ts +0 -10
  97. package/packages/web/components/EventRow/EventRow.tsx +0 -49
  98. package/packages/web/components/EventRow/EventRow.types.ts +0 -7
  99. package/packages/web/components/EventRow/EventRow.utils.ts +0 -49
  100. package/packages/web/components/EventRow/index.ts +0 -2
  101. package/packages/web/components/ExpandButton/ExpandButton.tsx +0 -18
  102. package/packages/web/components/ExpandButton/ExpandButton.types.ts +0 -6
  103. package/packages/web/components/ExpandButton/index.ts +0 -2
  104. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +0 -14
  105. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +0 -5
  106. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +0 -13
  107. package/packages/web/components/HealthGradientBackground/index.ts +0 -2
  108. package/packages/web/components/HeroSection/HeroSection.tsx +0 -92
  109. package/packages/web/components/HeroSection/HeroSection.types.ts +0 -14
  110. package/packages/web/components/HeroSection/HeroSection.utils.ts +0 -11
  111. package/packages/web/components/HeroSection/hooks/index.ts +0 -2
  112. package/packages/web/components/HeroSection/hooks/useCountUp.ts +0 -45
  113. package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +0 -18
  114. package/packages/web/components/HeroSection/index.ts +0 -2
  115. package/packages/web/components/IdeasCard/IdeasCard.tsx +0 -115
  116. package/packages/web/components/IdeasCard/IdeasCard.types.ts +0 -10
  117. package/packages/web/components/IdeasCard/index.ts +0 -2
  118. package/packages/web/components/InsightMessage/InsightMessage.tsx +0 -9
  119. package/packages/web/components/InsightMessage/InsightMessage.types.ts +0 -3
  120. package/packages/web/components/InsightMessage/index.ts +0 -2
  121. package/packages/web/components/Logo/Logo.tsx +0 -65
  122. package/packages/web/components/Logo/index.ts +0 -1
  123. package/packages/web/components/MarkdownContent/MarkdownContent.tsx +0 -123
  124. package/packages/web/components/MarkdownContent/index.ts +0 -1
  125. package/packages/web/components/MasonryGrid/MasonryGrid.tsx +0 -18
  126. package/packages/web/components/MasonryGrid/index.ts +0 -1
  127. package/packages/web/components/MomentumWidget/MomentumWidget.tsx +0 -119
  128. package/packages/web/components/MomentumWidget/MomentumWidget.types.ts +0 -16
  129. package/packages/web/components/MomentumWidget/index.ts +0 -2
  130. package/packages/web/components/NowCard/NowCard.tsx +0 -118
  131. package/packages/web/components/NowCard/NowCard.types.ts +0 -16
  132. package/packages/web/components/NowCard/index.ts +0 -2
  133. package/packages/web/components/PageHeader/PageHeader.tsx +0 -24
  134. package/packages/web/components/PageHeader/index.ts +0 -1
  135. package/packages/web/components/ProgressRing/ProgressRing.constants.ts +0 -20
  136. package/packages/web/components/ProgressRing/ProgressRing.tsx +0 -51
  137. package/packages/web/components/ProgressRing/ProgressRing.types.ts +0 -11
  138. package/packages/web/components/ProgressRing/index.ts +0 -2
  139. package/packages/web/components/ProjectAvatar/ProjectAvatar.tsx +0 -54
  140. package/packages/web/components/ProjectAvatar/index.ts +0 -1
  141. package/packages/web/components/ProjectColorDot/ProjectColorDot.tsx +0 -37
  142. package/packages/web/components/ProjectColorDot/index.ts +0 -1
  143. package/packages/web/components/ProjectSelectorModal/ProjectSelectorModal.tsx +0 -104
  144. package/packages/web/components/ProjectSelectorModal/index.ts +0 -1
  145. package/packages/web/components/Providers/Providers.tsx +0 -48
  146. package/packages/web/components/Providers/index.ts +0 -1
  147. package/packages/web/components/QueueCard/QueueCard.tsx +0 -125
  148. package/packages/web/components/QueueCard/QueueCard.types.ts +0 -12
  149. package/packages/web/components/QueueCard/QueueCard.utils.ts +0 -12
  150. package/packages/web/components/QueueCard/index.ts +0 -2
  151. package/packages/web/components/RecoverCard/RecoverCard.tsx +0 -72
  152. package/packages/web/components/RecoverCard/RecoverCard.types.ts +0 -16
  153. package/packages/web/components/RecoverCard/index.ts +0 -2
  154. package/packages/web/components/RoadmapCard/RoadmapCard.tsx +0 -145
  155. package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +0 -16
  156. package/packages/web/components/RoadmapCard/index.ts +0 -2
  157. package/packages/web/components/ShipsCard/ShipsCard.tsx +0 -95
  158. package/packages/web/components/ShipsCard/ShipsCard.types.ts +0 -14
  159. package/packages/web/components/ShipsCard/ShipsCard.utils.ts +0 -4
  160. package/packages/web/components/ShipsCard/index.ts +0 -2
  161. package/packages/web/components/SparklineChart/SparklineChart.tsx +0 -40
  162. package/packages/web/components/SparklineChart/SparklineChart.types.ts +0 -6
  163. package/packages/web/components/SparklineChart/index.ts +0 -2
  164. package/packages/web/components/StatsMasonry/StatsMasonry.tsx +0 -95
  165. package/packages/web/components/StatsMasonry/index.ts +0 -1
  166. package/packages/web/components/StreakCard/StreakCard.constants.ts +0 -2
  167. package/packages/web/components/StreakCard/StreakCard.tsx +0 -55
  168. package/packages/web/components/StreakCard/StreakCard.types.ts +0 -4
  169. package/packages/web/components/StreakCard/index.ts +0 -2
  170. package/packages/web/components/TasksCounter/TasksCounter.tsx +0 -14
  171. package/packages/web/components/TasksCounter/TasksCounter.types.ts +0 -3
  172. package/packages/web/components/TasksCounter/index.ts +0 -2
  173. package/packages/web/components/TechStackBadges/TechStackBadges.tsx +0 -28
  174. package/packages/web/components/TechStackBadges/index.ts +0 -1
  175. package/packages/web/components/TerminalDock/DockToggleTab.tsx +0 -29
  176. package/packages/web/components/TerminalDock/TerminalDock.tsx +0 -386
  177. package/packages/web/components/TerminalDock/TerminalDockTab.tsx +0 -130
  178. package/packages/web/components/TerminalDock/TerminalTabBar.tsx +0 -142
  179. package/packages/web/components/TerminalDock/index.ts +0 -2
  180. package/packages/web/components/TerminalTabs/TerminalTab.tsx +0 -95
  181. package/packages/web/components/TerminalTabs/TerminalTabs.tsx +0 -211
  182. package/packages/web/components/TerminalTabs/index.ts +0 -1
  183. package/packages/web/components/VelocityBadge/VelocityBadge.tsx +0 -32
  184. package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +0 -3
  185. package/packages/web/components/VelocityBadge/index.ts +0 -2
  186. package/packages/web/components/VelocityCard/VelocityCard.tsx +0 -73
  187. package/packages/web/components/VelocityCard/VelocityCard.types.ts +0 -7
  188. package/packages/web/components/VelocityCard/index.ts +0 -2
  189. package/packages/web/components/WeeklyReports/PrintableReport.tsx +0 -259
  190. package/packages/web/components/WeeklyReports/ReportPreviewCard.tsx +0 -187
  191. package/packages/web/components/WeeklyReports/WeekCalendar.tsx +0 -288
  192. package/packages/web/components/WeeklyReports/WeeklyReports.tsx +0 -149
  193. package/packages/web/components/WeeklyReports/index.ts +0 -4
  194. package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +0 -25
  195. package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +0 -4
  196. package/packages/web/components/WeeklySparkline/index.ts +0 -2
  197. package/packages/web/components/charts/SessionsChart.tsx +0 -175
  198. package/packages/web/components/ui/alert-dialog.tsx +0 -157
  199. package/packages/web/components/ui/badge.tsx +0 -46
  200. package/packages/web/components/ui/button.tsx +0 -60
  201. package/packages/web/components/ui/card.tsx +0 -92
  202. package/packages/web/components/ui/chart.tsx +0 -385
  203. package/packages/web/components/ui/dialog.tsx +0 -143
  204. package/packages/web/components/ui/drawer.tsx +0 -135
  205. package/packages/web/components/ui/dropdown-menu.tsx +0 -257
  206. package/packages/web/components/ui/input.tsx +0 -21
  207. package/packages/web/components/ui/scroll-area.tsx +0 -58
  208. package/packages/web/components/ui/select.tsx +0 -187
  209. package/packages/web/components/ui/sheet.tsx +0 -139
  210. package/packages/web/components/ui/tabs.tsx +0 -66
  211. package/packages/web/components/ui/tooltip.tsx +0 -61
  212. package/packages/web/components.json +0 -22
  213. package/packages/web/context/GlobalTerminalContext.tsx +0 -538
  214. package/packages/web/context/TerminalContext.tsx +0 -45
  215. package/packages/web/context/TerminalTabsContext.tsx +0 -181
  216. package/packages/web/eslint.config.mjs +0 -18
  217. package/packages/web/hooks/useClaudeTerminal.ts +0 -425
  218. package/packages/web/hooks/useProjectStats.ts +0 -93
  219. package/packages/web/hooks/useProjects.ts +0 -73
  220. package/packages/web/lib/actions/projects.ts +0 -15
  221. package/packages/web/lib/commands.ts +0 -81
  222. package/packages/web/lib/format.ts +0 -23
  223. package/packages/web/lib/generate-week-report.ts +0 -285
  224. package/packages/web/lib/parse-prjct-files.ts +0 -1123
  225. package/packages/web/lib/project-colors.ts +0 -58
  226. package/packages/web/lib/projects.ts +0 -506
  227. package/packages/web/lib/pty.ts +0 -101
  228. package/packages/web/lib/query-config.ts +0 -44
  229. package/packages/web/lib/services/index.ts +0 -9
  230. package/packages/web/lib/services/projects.server.ts +0 -66
  231. package/packages/web/lib/services/stats.server.ts +0 -562
  232. package/packages/web/lib/unified-loader.ts +0 -396
  233. package/packages/web/lib/utils.ts +0 -6
  234. package/packages/web/next-env.d.ts +0 -6
  235. package/packages/web/next.config.ts +0 -7
  236. package/packages/web/package.json +0 -57
  237. package/packages/web/postcss.config.mjs +0 -7
  238. package/packages/web/public/file.svg +0 -1
  239. package/packages/web/public/globe.svg +0 -1
  240. package/packages/web/public/next.svg +0 -1
  241. package/packages/web/public/vercel.svg +0 -1
  242. package/packages/web/public/window.svg +0 -1
  243. package/packages/web/server.ts +0 -312
  244. package/packages/web/tsconfig.json +0 -34
  245. 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
- }