prjct-cli 0.18.2 → 0.20.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 (246) hide show
  1. package/CHANGELOG.md +82 -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/agents/uxui.md +210 -0
  11. package/templates/commands/bug.md +219 -41
  12. package/templates/commands/done.md +57 -258
  13. package/templates/commands/feature.md +368 -80
  14. package/templates/commands/now.md +72 -277
  15. package/templates/commands/ship.md +167 -246
  16. package/templates/commands/sync.md +62 -3
  17. package/templates/commands/test.md +160 -20
  18. package/templates/global/CLAUDE.md +40 -205
  19. package/templates/global/docs/agents.md +88 -0
  20. package/templates/global/docs/architecture.md +103 -0
  21. package/templates/global/docs/commands.md +98 -0
  22. package/templates/global/docs/validation.md +95 -0
  23. package/bin/dev.js +0 -216
  24. package/bin/serve.js +0 -361
  25. package/packages/web/README.md +0 -36
  26. package/packages/web/app/api/claude/sessions/route.ts +0 -44
  27. package/packages/web/app/api/claude/status/route.ts +0 -34
  28. package/packages/web/app/api/projects/[id]/icon/route.ts +0 -33
  29. package/packages/web/app/api/projects/[id]/momentum/route.ts +0 -257
  30. package/packages/web/app/api/projects/[id]/route.ts +0 -29
  31. package/packages/web/app/api/projects/[id]/stats/route.ts +0 -41
  32. package/packages/web/app/api/projects/[id]/status/route.ts +0 -21
  33. package/packages/web/app/api/projects/route.ts +0 -16
  34. package/packages/web/app/api/sessions/current/route.ts +0 -132
  35. package/packages/web/app/api/sessions/history/route.ts +0 -204
  36. package/packages/web/app/error.tsx +0 -34
  37. package/packages/web/app/favicon.ico +0 -0
  38. package/packages/web/app/globals.css +0 -198
  39. package/packages/web/app/layout.tsx +0 -53
  40. package/packages/web/app/loading.tsx +0 -7
  41. package/packages/web/app/not-found.tsx +0 -25
  42. package/packages/web/app/page.tsx +0 -12
  43. package/packages/web/app/project/[id]/code/layout.tsx +0 -18
  44. package/packages/web/app/project/[id]/code/page.tsx +0 -408
  45. package/packages/web/app/project/[id]/error.tsx +0 -41
  46. package/packages/web/app/project/[id]/loading.tsx +0 -9
  47. package/packages/web/app/project/[id]/not-found.tsx +0 -27
  48. package/packages/web/app/project/[id]/page.tsx +0 -384
  49. package/packages/web/app/project/[id]/reports/page.tsx +0 -59
  50. package/packages/web/app/project/[id]/reports/print/page.tsx +0 -58
  51. package/packages/web/app/sessions/page.tsx +0 -165
  52. package/packages/web/app/settings/page.tsx +0 -151
  53. package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +0 -2
  54. package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +0 -49
  55. package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +0 -8
  56. package/packages/web/components/ActivityTimeline/hooks/index.ts +0 -2
  57. package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +0 -9
  58. package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +0 -23
  59. package/packages/web/components/ActivityTimeline/index.ts +0 -2
  60. package/packages/web/components/AgentsCard/AgentsCard.tsx +0 -93
  61. package/packages/web/components/AgentsCard/AgentsCard.types.ts +0 -14
  62. package/packages/web/components/AgentsCard/index.ts +0 -2
  63. package/packages/web/components/AppSidebar/AppSidebar.tsx +0 -316
  64. package/packages/web/components/AppSidebar/index.ts +0 -1
  65. package/packages/web/components/BackLink/BackLink.tsx +0 -18
  66. package/packages/web/components/BackLink/BackLink.types.ts +0 -5
  67. package/packages/web/components/BackLink/index.ts +0 -2
  68. package/packages/web/components/BentoCard/BentoCard.constants.ts +0 -16
  69. package/packages/web/components/BentoCard/BentoCard.tsx +0 -48
  70. package/packages/web/components/BentoCard/BentoCard.types.ts +0 -15
  71. package/packages/web/components/BentoCard/index.ts +0 -2
  72. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +0 -9
  73. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +0 -18
  74. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +0 -5
  75. package/packages/web/components/BentoCardSkeleton/index.ts +0 -2
  76. package/packages/web/components/BentoGrid/BentoGrid.tsx +0 -18
  77. package/packages/web/components/BentoGrid/BentoGrid.types.ts +0 -4
  78. package/packages/web/components/BentoGrid/index.ts +0 -2
  79. package/packages/web/components/BlockersCard/BlockersCard.tsx +0 -75
  80. package/packages/web/components/BlockersCard/BlockersCard.types.ts +0 -12
  81. package/packages/web/components/BlockersCard/index.ts +0 -2
  82. package/packages/web/components/CommandBar/CommandBar.tsx +0 -67
  83. package/packages/web/components/CommandBar/index.ts +0 -1
  84. package/packages/web/components/CommandButton/CommandButton.tsx +0 -46
  85. package/packages/web/components/CommandButton/index.ts +0 -1
  86. package/packages/web/components/ConnectionStatus/ConnectionStatus.tsx +0 -29
  87. package/packages/web/components/ConnectionStatus/index.ts +0 -1
  88. package/packages/web/components/DashboardContent/DashboardContent.tsx +0 -284
  89. package/packages/web/components/DashboardContent/index.ts +0 -1
  90. package/packages/web/components/DateGroup/DateGroup.tsx +0 -18
  91. package/packages/web/components/DateGroup/DateGroup.types.ts +0 -6
  92. package/packages/web/components/DateGroup/DateGroup.utils.ts +0 -11
  93. package/packages/web/components/DateGroup/index.ts +0 -2
  94. package/packages/web/components/EmptyState/EmptyState.tsx +0 -76
  95. package/packages/web/components/EmptyState/EmptyState.types.ts +0 -11
  96. package/packages/web/components/EmptyState/index.ts +0 -2
  97. package/packages/web/components/EventRow/EventRow.constants.ts +0 -10
  98. package/packages/web/components/EventRow/EventRow.tsx +0 -49
  99. package/packages/web/components/EventRow/EventRow.types.ts +0 -7
  100. package/packages/web/components/EventRow/EventRow.utils.ts +0 -49
  101. package/packages/web/components/EventRow/index.ts +0 -2
  102. package/packages/web/components/ExpandButton/ExpandButton.tsx +0 -18
  103. package/packages/web/components/ExpandButton/ExpandButton.types.ts +0 -6
  104. package/packages/web/components/ExpandButton/index.ts +0 -2
  105. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +0 -14
  106. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +0 -5
  107. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +0 -13
  108. package/packages/web/components/HealthGradientBackground/index.ts +0 -2
  109. package/packages/web/components/HeroSection/HeroSection.tsx +0 -92
  110. package/packages/web/components/HeroSection/HeroSection.types.ts +0 -14
  111. package/packages/web/components/HeroSection/HeroSection.utils.ts +0 -11
  112. package/packages/web/components/HeroSection/hooks/index.ts +0 -2
  113. package/packages/web/components/HeroSection/hooks/useCountUp.ts +0 -45
  114. package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +0 -18
  115. package/packages/web/components/HeroSection/index.ts +0 -2
  116. package/packages/web/components/IdeasCard/IdeasCard.tsx +0 -115
  117. package/packages/web/components/IdeasCard/IdeasCard.types.ts +0 -10
  118. package/packages/web/components/IdeasCard/index.ts +0 -2
  119. package/packages/web/components/InsightMessage/InsightMessage.tsx +0 -9
  120. package/packages/web/components/InsightMessage/InsightMessage.types.ts +0 -3
  121. package/packages/web/components/InsightMessage/index.ts +0 -2
  122. package/packages/web/components/Logo/Logo.tsx +0 -65
  123. package/packages/web/components/Logo/index.ts +0 -1
  124. package/packages/web/components/MarkdownContent/MarkdownContent.tsx +0 -123
  125. package/packages/web/components/MarkdownContent/index.ts +0 -1
  126. package/packages/web/components/MasonryGrid/MasonryGrid.tsx +0 -18
  127. package/packages/web/components/MasonryGrid/index.ts +0 -1
  128. package/packages/web/components/MomentumWidget/MomentumWidget.tsx +0 -119
  129. package/packages/web/components/MomentumWidget/MomentumWidget.types.ts +0 -16
  130. package/packages/web/components/MomentumWidget/index.ts +0 -2
  131. package/packages/web/components/NowCard/NowCard.tsx +0 -118
  132. package/packages/web/components/NowCard/NowCard.types.ts +0 -16
  133. package/packages/web/components/NowCard/index.ts +0 -2
  134. package/packages/web/components/PageHeader/PageHeader.tsx +0 -24
  135. package/packages/web/components/PageHeader/index.ts +0 -1
  136. package/packages/web/components/ProgressRing/ProgressRing.constants.ts +0 -20
  137. package/packages/web/components/ProgressRing/ProgressRing.tsx +0 -51
  138. package/packages/web/components/ProgressRing/ProgressRing.types.ts +0 -11
  139. package/packages/web/components/ProgressRing/index.ts +0 -2
  140. package/packages/web/components/ProjectAvatar/ProjectAvatar.tsx +0 -54
  141. package/packages/web/components/ProjectAvatar/index.ts +0 -1
  142. package/packages/web/components/ProjectColorDot/ProjectColorDot.tsx +0 -37
  143. package/packages/web/components/ProjectColorDot/index.ts +0 -1
  144. package/packages/web/components/ProjectSelectorModal/ProjectSelectorModal.tsx +0 -104
  145. package/packages/web/components/ProjectSelectorModal/index.ts +0 -1
  146. package/packages/web/components/Providers/Providers.tsx +0 -48
  147. package/packages/web/components/Providers/index.ts +0 -1
  148. package/packages/web/components/QueueCard/QueueCard.tsx +0 -125
  149. package/packages/web/components/QueueCard/QueueCard.types.ts +0 -12
  150. package/packages/web/components/QueueCard/QueueCard.utils.ts +0 -12
  151. package/packages/web/components/QueueCard/index.ts +0 -2
  152. package/packages/web/components/RecoverCard/RecoverCard.tsx +0 -72
  153. package/packages/web/components/RecoverCard/RecoverCard.types.ts +0 -16
  154. package/packages/web/components/RecoverCard/index.ts +0 -2
  155. package/packages/web/components/RoadmapCard/RoadmapCard.tsx +0 -145
  156. package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +0 -16
  157. package/packages/web/components/RoadmapCard/index.ts +0 -2
  158. package/packages/web/components/ShipsCard/ShipsCard.tsx +0 -95
  159. package/packages/web/components/ShipsCard/ShipsCard.types.ts +0 -14
  160. package/packages/web/components/ShipsCard/ShipsCard.utils.ts +0 -4
  161. package/packages/web/components/ShipsCard/index.ts +0 -2
  162. package/packages/web/components/SparklineChart/SparklineChart.tsx +0 -40
  163. package/packages/web/components/SparklineChart/SparklineChart.types.ts +0 -6
  164. package/packages/web/components/SparklineChart/index.ts +0 -2
  165. package/packages/web/components/StatsMasonry/StatsMasonry.tsx +0 -95
  166. package/packages/web/components/StatsMasonry/index.ts +0 -1
  167. package/packages/web/components/StreakCard/StreakCard.constants.ts +0 -2
  168. package/packages/web/components/StreakCard/StreakCard.tsx +0 -55
  169. package/packages/web/components/StreakCard/StreakCard.types.ts +0 -4
  170. package/packages/web/components/StreakCard/index.ts +0 -2
  171. package/packages/web/components/TasksCounter/TasksCounter.tsx +0 -14
  172. package/packages/web/components/TasksCounter/TasksCounter.types.ts +0 -3
  173. package/packages/web/components/TasksCounter/index.ts +0 -2
  174. package/packages/web/components/TechStackBadges/TechStackBadges.tsx +0 -28
  175. package/packages/web/components/TechStackBadges/index.ts +0 -1
  176. package/packages/web/components/TerminalDock/DockToggleTab.tsx +0 -29
  177. package/packages/web/components/TerminalDock/TerminalDock.tsx +0 -386
  178. package/packages/web/components/TerminalDock/TerminalDockTab.tsx +0 -130
  179. package/packages/web/components/TerminalDock/TerminalTabBar.tsx +0 -142
  180. package/packages/web/components/TerminalDock/index.ts +0 -2
  181. package/packages/web/components/TerminalTabs/TerminalTab.tsx +0 -95
  182. package/packages/web/components/TerminalTabs/TerminalTabs.tsx +0 -211
  183. package/packages/web/components/TerminalTabs/index.ts +0 -1
  184. package/packages/web/components/VelocityBadge/VelocityBadge.tsx +0 -32
  185. package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +0 -3
  186. package/packages/web/components/VelocityBadge/index.ts +0 -2
  187. package/packages/web/components/VelocityCard/VelocityCard.tsx +0 -73
  188. package/packages/web/components/VelocityCard/VelocityCard.types.ts +0 -7
  189. package/packages/web/components/VelocityCard/index.ts +0 -2
  190. package/packages/web/components/WeeklyReports/PrintableReport.tsx +0 -259
  191. package/packages/web/components/WeeklyReports/ReportPreviewCard.tsx +0 -187
  192. package/packages/web/components/WeeklyReports/WeekCalendar.tsx +0 -288
  193. package/packages/web/components/WeeklyReports/WeeklyReports.tsx +0 -149
  194. package/packages/web/components/WeeklyReports/index.ts +0 -4
  195. package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +0 -25
  196. package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +0 -4
  197. package/packages/web/components/WeeklySparkline/index.ts +0 -2
  198. package/packages/web/components/charts/SessionsChart.tsx +0 -175
  199. package/packages/web/components/ui/alert-dialog.tsx +0 -157
  200. package/packages/web/components/ui/badge.tsx +0 -46
  201. package/packages/web/components/ui/button.tsx +0 -60
  202. package/packages/web/components/ui/card.tsx +0 -92
  203. package/packages/web/components/ui/chart.tsx +0 -385
  204. package/packages/web/components/ui/dialog.tsx +0 -143
  205. package/packages/web/components/ui/drawer.tsx +0 -135
  206. package/packages/web/components/ui/dropdown-menu.tsx +0 -257
  207. package/packages/web/components/ui/input.tsx +0 -21
  208. package/packages/web/components/ui/scroll-area.tsx +0 -58
  209. package/packages/web/components/ui/select.tsx +0 -187
  210. package/packages/web/components/ui/sheet.tsx +0 -139
  211. package/packages/web/components/ui/tabs.tsx +0 -66
  212. package/packages/web/components/ui/tooltip.tsx +0 -61
  213. package/packages/web/components.json +0 -22
  214. package/packages/web/context/GlobalTerminalContext.tsx +0 -538
  215. package/packages/web/context/TerminalContext.tsx +0 -45
  216. package/packages/web/context/TerminalTabsContext.tsx +0 -181
  217. package/packages/web/eslint.config.mjs +0 -18
  218. package/packages/web/hooks/useClaudeTerminal.ts +0 -425
  219. package/packages/web/hooks/useProjectStats.ts +0 -93
  220. package/packages/web/hooks/useProjects.ts +0 -73
  221. package/packages/web/lib/actions/projects.ts +0 -15
  222. package/packages/web/lib/commands.ts +0 -81
  223. package/packages/web/lib/format.ts +0 -23
  224. package/packages/web/lib/generate-week-report.ts +0 -285
  225. package/packages/web/lib/parse-prjct-files.ts +0 -1123
  226. package/packages/web/lib/project-colors.ts +0 -58
  227. package/packages/web/lib/projects.ts +0 -506
  228. package/packages/web/lib/pty.ts +0 -101
  229. package/packages/web/lib/query-config.ts +0 -44
  230. package/packages/web/lib/services/index.ts +0 -9
  231. package/packages/web/lib/services/projects.server.ts +0 -66
  232. package/packages/web/lib/services/stats.server.ts +0 -562
  233. package/packages/web/lib/unified-loader.ts +0 -396
  234. package/packages/web/lib/utils.ts +0 -6
  235. package/packages/web/next-env.d.ts +0 -6
  236. package/packages/web/next.config.ts +0 -7
  237. package/packages/web/package.json +0 -57
  238. package/packages/web/postcss.config.mjs +0 -7
  239. package/packages/web/public/file.svg +0 -1
  240. package/packages/web/public/globe.svg +0 -1
  241. package/packages/web/public/next.svg +0 -1
  242. package/packages/web/public/vercel.svg +0 -1
  243. package/packages/web/public/window.svg +0 -1
  244. package/packages/web/server.ts +0 -312
  245. package/packages/web/tsconfig.json +0 -34
  246. package/templates/commands/serve.md +0 -121
@@ -1,385 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as RechartsPrimitive from "recharts"
5
-
6
- import { cn } from "@/lib/utils"
7
-
8
- // Format: { THEME_NAME: CSS_SELECTOR }
9
- const THEMES = { light: "", dark: ".dark" } as const
10
-
11
- export type ChartConfig = {
12
- [k in string]: {
13
- label?: React.ReactNode
14
- icon?: React.ComponentType
15
- } & (
16
- | { color?: string; theme?: never }
17
- | { color?: never; theme: Record<keyof typeof THEMES, string> }
18
- )
19
- }
20
-
21
- type ChartContextProps = {
22
- config: ChartConfig
23
- }
24
-
25
- const ChartContext = React.createContext<ChartContextProps | null>(null)
26
-
27
- function useChart() {
28
- const context = React.useContext(ChartContext)
29
-
30
- if (!context) {
31
- throw new Error("useChart must be used within a <ChartContainer />")
32
- }
33
-
34
- return context
35
- }
36
-
37
- const ChartContainer = React.forwardRef<
38
- HTMLDivElement,
39
- React.ComponentProps<"div"> & {
40
- config: ChartConfig
41
- children: React.ComponentProps<
42
- typeof RechartsPrimitive.ResponsiveContainer
43
- >["children"]
44
- }
45
- >(({ id, className, children, config, ...props }, ref) => {
46
- const uniqueId = React.useId()
47
- const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
48
-
49
- return (
50
- <ChartContext.Provider value={{ config }}>
51
- <div
52
- data-chart={chartId}
53
- ref={ref}
54
- className={cn(
55
- "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
56
- className
57
- )}
58
- {...props}
59
- >
60
- <ChartStyle id={chartId} config={config} />
61
- <RechartsPrimitive.ResponsiveContainer>
62
- {children}
63
- </RechartsPrimitive.ResponsiveContainer>
64
- </div>
65
- </ChartContext.Provider>
66
- )
67
- })
68
- ChartContainer.displayName = "Chart"
69
-
70
- const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
71
- const colorConfig = Object.entries(config).filter(
72
- ([, config]) => config.theme || config.color
73
- )
74
-
75
- if (!colorConfig.length) {
76
- return null
77
- }
78
-
79
- return (
80
- <style
81
- dangerouslySetInnerHTML={{
82
- __html: Object.entries(THEMES)
83
- .map(
84
- ([theme, prefix]) => `
85
- ${prefix} [data-chart=${id}] {
86
- ${colorConfig
87
- .map(([key, itemConfig]) => {
88
- const color =
89
- itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||
90
- itemConfig.color
91
- return color ? ` --color-${key}: ${color};` : null
92
- })
93
- .join("\n")}
94
- }
95
- `
96
- )
97
- .join("\n"),
98
- }}
99
- />
100
- )
101
- }
102
-
103
- const ChartTooltip = RechartsPrimitive.Tooltip
104
-
105
- interface PayloadItem {
106
- dataKey?: string | number
107
- name?: string
108
- value?: number
109
- color?: string
110
- fill?: string
111
- payload?: Record<string, unknown>
112
- }
113
-
114
- interface ChartTooltipContentProps extends React.ComponentProps<"div"> {
115
- active?: boolean
116
- payload?: PayloadItem[]
117
- label?: string
118
- labelFormatter?: (label: string, payload: PayloadItem[]) => React.ReactNode
119
- labelClassName?: string
120
- formatter?: (value: number, name: string, item: PayloadItem, index: number, payload: PayloadItem) => React.ReactNode
121
- color?: string
122
- hideLabel?: boolean
123
- hideIndicator?: boolean
124
- indicator?: "line" | "dot" | "dashed"
125
- nameKey?: string
126
- labelKey?: string
127
- }
128
-
129
- const ChartTooltipContent = React.forwardRef<HTMLDivElement, ChartTooltipContentProps>(
130
- (
131
- {
132
- active,
133
- payload,
134
- className,
135
- indicator = "dot",
136
- hideLabel = false,
137
- hideIndicator = false,
138
- label,
139
- labelFormatter,
140
- labelClassName,
141
- formatter,
142
- color,
143
- nameKey,
144
- labelKey,
145
- },
146
- ref
147
- ) => {
148
- const { config } = useChart()
149
-
150
- const tooltipLabel = React.useMemo(() => {
151
- if (hideLabel || !payload?.length) {
152
- return null
153
- }
154
-
155
- const [item] = payload
156
- const key = `${labelKey || item.dataKey || item.name || "value"}`
157
- const itemConfig = getPayloadConfigFromPayload(config, item, key)
158
- const value =
159
- !labelKey && typeof label === "string"
160
- ? config[label as keyof typeof config]?.label || label
161
- : itemConfig?.label
162
-
163
- if (labelFormatter) {
164
- return (
165
- <div className={cn("font-medium", labelClassName)}>
166
- {labelFormatter(String(value ?? ''), payload)}
167
- </div>
168
- )
169
- }
170
-
171
- if (!value) {
172
- return null
173
- }
174
-
175
- return <div className={cn("font-medium", labelClassName)}>{value}</div>
176
- }, [
177
- label,
178
- labelFormatter,
179
- payload,
180
- hideLabel,
181
- labelClassName,
182
- config,
183
- labelKey,
184
- ])
185
-
186
- if (!active || !payload?.length) {
187
- return null
188
- }
189
-
190
- const nestLabel = payload.length === 1 && indicator !== "dot"
191
-
192
- return (
193
- <div
194
- ref={ref}
195
- className={cn(
196
- "grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
197
- className
198
- )}
199
- >
200
- {!nestLabel ? tooltipLabel : null}
201
- <div className="grid gap-1.5">
202
- {payload.map((item: PayloadItem, index: number) => {
203
- const key = `${nameKey || item.name || item.dataKey || "value"}`
204
- const itemConfig = getPayloadConfigFromPayload(config, item, key)
205
- const indicatorColor = color || (item.payload?.fill as string) || item.color
206
-
207
- return (
208
- <div
209
- key={String(item.dataKey)}
210
- className={cn(
211
- "flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
212
- indicator === "dot" && "items-center"
213
- )}
214
- >
215
- {formatter && item?.value !== undefined && item.name ? (
216
- formatter(item.value, item.name, item, index, item)
217
- ) : (
218
- <>
219
- {itemConfig?.icon ? (
220
- <itemConfig.icon />
221
- ) : (
222
- !hideIndicator && (
223
- <div
224
- className={cn(
225
- "shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]",
226
- {
227
- "h-2.5 w-2.5": indicator === "dot",
228
- "w-1": indicator === "line",
229
- "w-0 border-[1.5px] border-dashed bg-transparent":
230
- indicator === "dashed",
231
- "my-0.5": nestLabel && indicator === "dashed",
232
- }
233
- )}
234
- style={
235
- {
236
- "--color-bg": indicatorColor,
237
- "--color-border": indicatorColor,
238
- } as React.CSSProperties
239
- }
240
- />
241
- )
242
- )}
243
- <div
244
- className={cn(
245
- "flex flex-1 justify-between leading-none",
246
- nestLabel ? "items-end" : "items-center"
247
- )}
248
- >
249
- <div className="grid gap-1.5">
250
- {nestLabel ? tooltipLabel : null}
251
- <span className="text-muted-foreground">
252
- {itemConfig?.label || item.name}
253
- </span>
254
- </div>
255
- {item.value && (
256
- <span className="font-mono font-medium tabular-nums text-foreground">
257
- {item.value.toLocaleString()}
258
- </span>
259
- )}
260
- </div>
261
- </>
262
- )}
263
- </div>
264
- )
265
- })}
266
- </div>
267
- </div>
268
- )
269
- }
270
- )
271
- ChartTooltipContent.displayName = "ChartTooltip"
272
-
273
- const ChartLegend = RechartsPrimitive.Legend
274
-
275
- interface LegendPayloadItem {
276
- value?: string
277
- dataKey?: string
278
- color?: string
279
- }
280
-
281
- interface ChartLegendContentProps extends React.ComponentProps<"div"> {
282
- payload?: LegendPayloadItem[]
283
- verticalAlign?: "top" | "bottom"
284
- hideIcon?: boolean
285
- nameKey?: string
286
- }
287
-
288
- const ChartLegendContent = React.forwardRef<HTMLDivElement, ChartLegendContentProps>(
289
- (
290
- { className, hideIcon = false, payload, verticalAlign = "bottom", nameKey },
291
- ref
292
- ) => {
293
- const { config } = useChart()
294
-
295
- if (!payload?.length) {
296
- return null
297
- }
298
-
299
- return (
300
- <div
301
- ref={ref}
302
- className={cn(
303
- "flex items-center justify-center gap-4",
304
- verticalAlign === "top" ? "pb-3" : "pt-3",
305
- className
306
- )}
307
- >
308
- {payload.map((item: LegendPayloadItem) => {
309
- const key = `${nameKey || item.dataKey || "value"}`
310
- const itemConfig = getPayloadConfigFromPayload(config, item, key)
311
-
312
- return (
313
- <div
314
- key={item.value}
315
- className={cn(
316
- "flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
317
- )}
318
- >
319
- {itemConfig?.icon && !hideIcon ? (
320
- <itemConfig.icon />
321
- ) : (
322
- <div
323
- className="h-2 w-2 shrink-0 rounded-[2px]"
324
- style={{
325
- backgroundColor: item.color,
326
- }}
327
- />
328
- )}
329
- {itemConfig?.label}
330
- </div>
331
- )
332
- })}
333
- </div>
334
- )
335
- }
336
- )
337
- ChartLegendContent.displayName = "ChartLegend"
338
-
339
- // Helper to extract item config from a payload.
340
- function getPayloadConfigFromPayload(
341
- config: ChartConfig,
342
- payload: unknown,
343
- key: string
344
- ) {
345
- if (typeof payload !== "object" || payload === null) {
346
- return undefined
347
- }
348
-
349
- const payloadPayload =
350
- "payload" in payload &&
351
- typeof payload.payload === "object" &&
352
- payload.payload !== null
353
- ? payload.payload
354
- : undefined
355
-
356
- let configLabelKey: string = key
357
-
358
- if (
359
- key in payload &&
360
- typeof payload[key as keyof typeof payload] === "string"
361
- ) {
362
- configLabelKey = payload[key as keyof typeof payload] as string
363
- } else if (
364
- payloadPayload &&
365
- key in payloadPayload &&
366
- typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
367
- ) {
368
- configLabelKey = payloadPayload[
369
- key as keyof typeof payloadPayload
370
- ] as string
371
- }
372
-
373
- return configLabelKey in config
374
- ? config[configLabelKey]
375
- : config[key as keyof typeof config]
376
- }
377
-
378
- export {
379
- ChartContainer,
380
- ChartTooltip,
381
- ChartTooltipContent,
382
- ChartLegend,
383
- ChartLegendContent,
384
- ChartStyle,
385
- }
@@ -1,143 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as DialogPrimitive from "@radix-ui/react-dialog"
5
- import { XIcon } from "lucide-react"
6
-
7
- import { cn } from "@/lib/utils"
8
-
9
- function Dialog({
10
- ...props
11
- }: React.ComponentProps<typeof DialogPrimitive.Root>) {
12
- return <DialogPrimitive.Root data-slot="dialog" {...props} />
13
- }
14
-
15
- function DialogTrigger({
16
- ...props
17
- }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
18
- return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
19
- }
20
-
21
- function DialogPortal({
22
- ...props
23
- }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
24
- return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
25
- }
26
-
27
- function DialogClose({
28
- ...props
29
- }: React.ComponentProps<typeof DialogPrimitive.Close>) {
30
- return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
31
- }
32
-
33
- function DialogOverlay({
34
- className,
35
- ...props
36
- }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
37
- return (
38
- <DialogPrimitive.Overlay
39
- data-slot="dialog-overlay"
40
- className={cn(
41
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
42
- className
43
- )}
44
- {...props}
45
- />
46
- )
47
- }
48
-
49
- function DialogContent({
50
- className,
51
- children,
52
- showCloseButton = true,
53
- ...props
54
- }: React.ComponentProps<typeof DialogPrimitive.Content> & {
55
- showCloseButton?: boolean
56
- }) {
57
- return (
58
- <DialogPortal data-slot="dialog-portal">
59
- <DialogOverlay />
60
- <DialogPrimitive.Content
61
- data-slot="dialog-content"
62
- className={cn(
63
- "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
64
- className
65
- )}
66
- {...props}
67
- >
68
- {children}
69
- {showCloseButton && (
70
- <DialogPrimitive.Close
71
- data-slot="dialog-close"
72
- className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
73
- >
74
- <XIcon />
75
- <span className="sr-only">Close</span>
76
- </DialogPrimitive.Close>
77
- )}
78
- </DialogPrimitive.Content>
79
- </DialogPortal>
80
- )
81
- }
82
-
83
- function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
84
- return (
85
- <div
86
- data-slot="dialog-header"
87
- className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
88
- {...props}
89
- />
90
- )
91
- }
92
-
93
- function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
94
- return (
95
- <div
96
- data-slot="dialog-footer"
97
- className={cn(
98
- "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
99
- className
100
- )}
101
- {...props}
102
- />
103
- )
104
- }
105
-
106
- function DialogTitle({
107
- className,
108
- ...props
109
- }: React.ComponentProps<typeof DialogPrimitive.Title>) {
110
- return (
111
- <DialogPrimitive.Title
112
- data-slot="dialog-title"
113
- className={cn("text-lg leading-none font-semibold", className)}
114
- {...props}
115
- />
116
- )
117
- }
118
-
119
- function DialogDescription({
120
- className,
121
- ...props
122
- }: React.ComponentProps<typeof DialogPrimitive.Description>) {
123
- return (
124
- <DialogPrimitive.Description
125
- data-slot="dialog-description"
126
- className={cn("text-muted-foreground text-sm", className)}
127
- {...props}
128
- />
129
- )
130
- }
131
-
132
- export {
133
- Dialog,
134
- DialogClose,
135
- DialogContent,
136
- DialogDescription,
137
- DialogFooter,
138
- DialogHeader,
139
- DialogOverlay,
140
- DialogPortal,
141
- DialogTitle,
142
- DialogTrigger,
143
- }
@@ -1,135 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { Drawer as DrawerPrimitive } from "vaul"
5
-
6
- import { cn } from "@/lib/utils"
7
-
8
- function Drawer({
9
- ...props
10
- }: React.ComponentProps<typeof DrawerPrimitive.Root>) {
11
- return <DrawerPrimitive.Root data-slot="drawer" {...props} />
12
- }
13
-
14
- function DrawerTrigger({
15
- ...props
16
- }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
17
- return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
18
- }
19
-
20
- function DrawerPortal({
21
- ...props
22
- }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
23
- return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
24
- }
25
-
26
- function DrawerClose({
27
- ...props
28
- }: React.ComponentProps<typeof DrawerPrimitive.Close>) {
29
- return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
30
- }
31
-
32
- function DrawerOverlay({
33
- className,
34
- ...props
35
- }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
36
- return (
37
- <DrawerPrimitive.Overlay
38
- data-slot="drawer-overlay"
39
- className={cn(
40
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
41
- className
42
- )}
43
- {...props}
44
- />
45
- )
46
- }
47
-
48
- function DrawerContent({
49
- className,
50
- children,
51
- ...props
52
- }: React.ComponentProps<typeof DrawerPrimitive.Content>) {
53
- return (
54
- <DrawerPortal data-slot="drawer-portal">
55
- <DrawerOverlay />
56
- <DrawerPrimitive.Content
57
- data-slot="drawer-content"
58
- className={cn(
59
- "group/drawer-content bg-background fixed z-50 flex h-auto flex-col",
60
- "data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b",
61
- "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t",
62
- "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm",
63
- "data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm",
64
- className
65
- )}
66
- {...props}
67
- >
68
- <div className="bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
69
- {children}
70
- </DrawerPrimitive.Content>
71
- </DrawerPortal>
72
- )
73
- }
74
-
75
- function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
76
- return (
77
- <div
78
- data-slot="drawer-header"
79
- className={cn(
80
- "flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left",
81
- className
82
- )}
83
- {...props}
84
- />
85
- )
86
- }
87
-
88
- function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
89
- return (
90
- <div
91
- data-slot="drawer-footer"
92
- className={cn("mt-auto flex flex-col gap-2 p-4", className)}
93
- {...props}
94
- />
95
- )
96
- }
97
-
98
- function DrawerTitle({
99
- className,
100
- ...props
101
- }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
102
- return (
103
- <DrawerPrimitive.Title
104
- data-slot="drawer-title"
105
- className={cn("text-foreground font-semibold", className)}
106
- {...props}
107
- />
108
- )
109
- }
110
-
111
- function DrawerDescription({
112
- className,
113
- ...props
114
- }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
115
- return (
116
- <DrawerPrimitive.Description
117
- data-slot="drawer-description"
118
- className={cn("text-muted-foreground text-sm", className)}
119
- {...props}
120
- />
121
- )
122
- }
123
-
124
- export {
125
- Drawer,
126
- DrawerPortal,
127
- DrawerOverlay,
128
- DrawerTrigger,
129
- DrawerClose,
130
- DrawerContent,
131
- DrawerHeader,
132
- DrawerFooter,
133
- DrawerTitle,
134
- DrawerDescription,
135
- }