@devfellowship/components 1.2.2 → 1.3.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.
- package/dist/cli.js +737 -0
- package/dist/index.cjs +446 -55
- package/dist/index.d.cts +73 -1
- package/dist/index.d.ts +73 -1
- package/dist/index.js +442 -57
- package/package.json +21 -3
package/dist/index.cjs
CHANGED
|
@@ -156,6 +156,7 @@ __export(src_exports, {
|
|
|
156
156
|
FormItem: () => FormItem,
|
|
157
157
|
FormLabel: () => FormLabel,
|
|
158
158
|
FormMessage: () => FormMessage,
|
|
159
|
+
Gantt: () => Gantt,
|
|
159
160
|
HoverCard: () => HoverCard,
|
|
160
161
|
HoverCardContent: () => HoverCardContent,
|
|
161
162
|
HoverCardTrigger: () => HoverCardTrigger,
|
|
@@ -296,7 +297,9 @@ __export(src_exports, {
|
|
|
296
297
|
UserAvatar: () => UserAvatar,
|
|
297
298
|
UserMenu: () => UserMenu,
|
|
298
299
|
badgeVariants: () => badgeVariants,
|
|
300
|
+
barGridColumn: () => barGridColumn,
|
|
299
301
|
buttonVariants: () => buttonVariants,
|
|
302
|
+
clampPct: () => clampPct,
|
|
300
303
|
cn: () => cn,
|
|
301
304
|
filterPublishableAccounts: () => filterPublishableAccounts,
|
|
302
305
|
getInitials: () => getInitials,
|
|
@@ -308,6 +311,9 @@ __export(src_exports, {
|
|
|
308
311
|
memberHueVar: () => memberHueVar,
|
|
309
312
|
navigationMenuTriggerStyle: () => navigationMenuTriggerStyle,
|
|
310
313
|
parseTags: () => parseTags,
|
|
314
|
+
resolveWeekCount: () => resolveWeekCount,
|
|
315
|
+
resolveWeekLabels: () => resolveWeekLabels,
|
|
316
|
+
stageProgress: () => stageProgress,
|
|
311
317
|
toast: () => toast,
|
|
312
318
|
toggleVariants: () => toggleVariants,
|
|
313
319
|
useAuth: () => useAuth,
|
|
@@ -5065,10 +5071,389 @@ function AppNavbar({
|
|
|
5065
5071
|
);
|
|
5066
5072
|
}
|
|
5067
5073
|
|
|
5068
|
-
// src/components/organisms/
|
|
5074
|
+
// src/components/organisms/Gantt.tsx
|
|
5069
5075
|
var React44 = __toESM(require("react"), 1);
|
|
5070
|
-
var import_lucide_react23 = require("lucide-react");
|
|
5071
5076
|
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
5077
|
+
function clampPct(value) {
|
|
5078
|
+
if (value == null || Number.isNaN(value)) return 0;
|
|
5079
|
+
return Math.max(0, Math.min(100, Math.round(value)));
|
|
5080
|
+
}
|
|
5081
|
+
function stageProgress(stage) {
|
|
5082
|
+
if (stage.progress != null) return clampPct(stage.progress);
|
|
5083
|
+
const ms = stage.milestones ?? [];
|
|
5084
|
+
if (ms.length === 0) return 0;
|
|
5085
|
+
const done = ms.filter((m) => m.done).length;
|
|
5086
|
+
return clampPct(done / ms.length * 100);
|
|
5087
|
+
}
|
|
5088
|
+
function resolveWeekCount(stages, weeks) {
|
|
5089
|
+
if (Array.isArray(weeks)) return Math.max(1, weeks.length);
|
|
5090
|
+
if (typeof weeks === "number" && weeks > 0) return Math.round(weeks);
|
|
5091
|
+
let max = 1;
|
|
5092
|
+
for (const s of stages) {
|
|
5093
|
+
max = Math.max(max, s.weekStart + Math.max(1, s.weekSpan) - 1);
|
|
5094
|
+
for (const m of s.milestones ?? []) {
|
|
5095
|
+
const ws = m.weekStart ?? s.weekStart;
|
|
5096
|
+
max = Math.max(max, ws + Math.max(1, m.weekSpan ?? 1) - 1);
|
|
5097
|
+
}
|
|
5098
|
+
}
|
|
5099
|
+
return Math.max(1, max);
|
|
5100
|
+
}
|
|
5101
|
+
function resolveWeekLabels(count2, weeks) {
|
|
5102
|
+
if (Array.isArray(weeks)) return weeks;
|
|
5103
|
+
return Array.from({ length: count2 }, (_, i) => `W${i + 1}`);
|
|
5104
|
+
}
|
|
5105
|
+
function barGridColumn(weekStart, weekSpan, weekCount) {
|
|
5106
|
+
const start = Math.max(1, Math.min(weekStart, weekCount));
|
|
5107
|
+
const rawEnd = start + Math.max(1, weekSpan) - 1;
|
|
5108
|
+
const end = Math.max(start, Math.min(rawEnd, weekCount));
|
|
5109
|
+
return { start, span: end - start + 1 };
|
|
5110
|
+
}
|
|
5111
|
+
var DEFAULT_DOT = "var(--s-brand-solid, #E07A4A)";
|
|
5112
|
+
function Gantt({
|
|
5113
|
+
stages,
|
|
5114
|
+
weeks,
|
|
5115
|
+
dependencies = [],
|
|
5116
|
+
rowsHeader = "Stage / Task",
|
|
5117
|
+
stagesOnly = false,
|
|
5118
|
+
header,
|
|
5119
|
+
labelWidth = 240,
|
|
5120
|
+
weekMinWidth = 64,
|
|
5121
|
+
className,
|
|
5122
|
+
style,
|
|
5123
|
+
...rest
|
|
5124
|
+
}) {
|
|
5125
|
+
const weekCount = resolveWeekCount(stages, weeks);
|
|
5126
|
+
const weekLabels = resolveWeekLabels(weekCount, weeks);
|
|
5127
|
+
const [collapsed, setCollapsed] = React44.useState(
|
|
5128
|
+
() => Object.fromEntries(stages.filter((s) => s.collapsed).map((s) => [s.id, true]))
|
|
5129
|
+
);
|
|
5130
|
+
const toggle = (id) => setCollapsed((c) => ({ ...c, [id]: !c[id] }));
|
|
5131
|
+
const gridRef = React44.useRef(null);
|
|
5132
|
+
const barRefs = React44.useRef({});
|
|
5133
|
+
const [edges, setEdges] = React44.useState([]);
|
|
5134
|
+
const recomputeEdges = React44.useCallback(() => {
|
|
5135
|
+
const root = gridRef.current;
|
|
5136
|
+
if (!root || dependencies.length === 0) {
|
|
5137
|
+
setEdges([]);
|
|
5138
|
+
return;
|
|
5139
|
+
}
|
|
5140
|
+
const rootBox = root.getBoundingClientRect();
|
|
5141
|
+
const next = [];
|
|
5142
|
+
for (const dep of dependencies) {
|
|
5143
|
+
const a = barRefs.current[dep.from];
|
|
5144
|
+
const b = barRefs.current[dep.to];
|
|
5145
|
+
if (!a || !b) continue;
|
|
5146
|
+
const ab = a.getBoundingClientRect();
|
|
5147
|
+
const bb = b.getBoundingClientRect();
|
|
5148
|
+
next.push({
|
|
5149
|
+
id: `${dep.from}->${dep.to}`,
|
|
5150
|
+
x1: ab.right - rootBox.left,
|
|
5151
|
+
y1: ab.top - rootBox.top + ab.height / 2,
|
|
5152
|
+
x2: bb.left - rootBox.left,
|
|
5153
|
+
y2: bb.top - rootBox.top + bb.height / 2
|
|
5154
|
+
});
|
|
5155
|
+
}
|
|
5156
|
+
setEdges(next);
|
|
5157
|
+
}, [dependencies]);
|
|
5158
|
+
React44.useLayoutEffect(() => {
|
|
5159
|
+
recomputeEdges();
|
|
5160
|
+
}, [recomputeEdges, collapsed, weekCount, stages]);
|
|
5161
|
+
React44.useEffect(() => {
|
|
5162
|
+
if (dependencies.length === 0) return;
|
|
5163
|
+
const handler = () => recomputeEdges();
|
|
5164
|
+
window.addEventListener("resize", handler);
|
|
5165
|
+
return () => window.removeEventListener("resize", handler);
|
|
5166
|
+
}, [dependencies.length, recomputeEdges]);
|
|
5167
|
+
const trackTemplate = `${labelWidth}px repeat(${weekCount}, minmax(${weekMinWidth}px, 1fr))`;
|
|
5168
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
5169
|
+
"div",
|
|
5170
|
+
{
|
|
5171
|
+
className: cn(
|
|
5172
|
+
"dfl-gantt rounded-[var(--c-card-radius,10px)] border border-[var(--s-border-subtle,#2A2622)] bg-[var(--s-surface-panel,#141210)] text-[var(--s-ink-primary,#F6F1E7)] overflow-hidden",
|
|
5173
|
+
className
|
|
5174
|
+
),
|
|
5175
|
+
style,
|
|
5176
|
+
...rest,
|
|
5177
|
+
children: [
|
|
5178
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "border-b border-[var(--s-border-subtle,#2A2622)] px-5 py-4", children: header }),
|
|
5179
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { ref: gridRef, className: "relative min-w-max", children: [
|
|
5180
|
+
edges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
5181
|
+
"svg",
|
|
5182
|
+
{
|
|
5183
|
+
className: "pointer-events-none absolute inset-0 h-full w-full",
|
|
5184
|
+
"aria-hidden": "true",
|
|
5185
|
+
children: [
|
|
5186
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5187
|
+
"marker",
|
|
5188
|
+
{
|
|
5189
|
+
id: "dfl-gantt-arrow",
|
|
5190
|
+
markerWidth: "7",
|
|
5191
|
+
markerHeight: "7",
|
|
5192
|
+
refX: "5",
|
|
5193
|
+
refY: "3",
|
|
5194
|
+
orient: "auto",
|
|
5195
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5196
|
+
"path",
|
|
5197
|
+
{
|
|
5198
|
+
d: "M0,0 L6,3 L0,6 Z",
|
|
5199
|
+
fill: "var(--s-brand-solid, #E07A4A)"
|
|
5200
|
+
}
|
|
5201
|
+
)
|
|
5202
|
+
}
|
|
5203
|
+
) }),
|
|
5204
|
+
edges.map((e) => {
|
|
5205
|
+
const stub = 14;
|
|
5206
|
+
const c1x = e.x1 + stub;
|
|
5207
|
+
const c2x = e.x2 - stub;
|
|
5208
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5209
|
+
"path",
|
|
5210
|
+
{
|
|
5211
|
+
d: `M ${e.x1} ${e.y1} C ${c1x} ${e.y1}, ${c2x} ${e.y2}, ${e.x2} ${e.y2}`,
|
|
5212
|
+
fill: "none",
|
|
5213
|
+
stroke: "var(--s-brand-solid, #E07A4A)",
|
|
5214
|
+
strokeWidth: 1.5,
|
|
5215
|
+
strokeOpacity: 0.65,
|
|
5216
|
+
markerEnd: "url(#dfl-gantt-arrow)"
|
|
5217
|
+
},
|
|
5218
|
+
e.id
|
|
5219
|
+
);
|
|
5220
|
+
})
|
|
5221
|
+
]
|
|
5222
|
+
}
|
|
5223
|
+
),
|
|
5224
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
5225
|
+
"div",
|
|
5226
|
+
{
|
|
5227
|
+
className: "grid items-center border-b border-[var(--s-border-subtle,#2A2622)] bg-[var(--s-surface-raised,#1A1714)]",
|
|
5228
|
+
style: { gridTemplateColumns: trackTemplate },
|
|
5229
|
+
children: [
|
|
5230
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "px-4 py-2.5 font-[var(--s-font-mono,monospace)] text-[10.5px] font-medium uppercase tracking-[0.6px] text-[var(--s-ink-muted,#7D7568)]", children: rowsHeader }),
|
|
5231
|
+
weekLabels.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5232
|
+
"div",
|
|
5233
|
+
{
|
|
5234
|
+
className: "border-l border-[var(--s-border-subtle,#2A2622)] py-2.5 text-center font-[var(--s-font-mono,monospace)] text-[11px] tabular-nums text-[var(--s-ink-muted,#7D7568)]",
|
|
5235
|
+
children: label
|
|
5236
|
+
},
|
|
5237
|
+
i
|
|
5238
|
+
))
|
|
5239
|
+
]
|
|
5240
|
+
}
|
|
5241
|
+
),
|
|
5242
|
+
stages.map((stage) => {
|
|
5243
|
+
const pct = stageProgress(stage);
|
|
5244
|
+
const dot = stage.color || DEFAULT_DOT;
|
|
5245
|
+
const isCollapsed = !!collapsed[stage.id];
|
|
5246
|
+
const ms = stage.milestones ?? [];
|
|
5247
|
+
const done = ms.filter((m) => m.done).length;
|
|
5248
|
+
const sCol = barGridColumn(stage.weekStart, stage.weekSpan, weekCount);
|
|
5249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(React44.Fragment, { children: [
|
|
5250
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
5251
|
+
"div",
|
|
5252
|
+
{
|
|
5253
|
+
className: "grid items-center border-b border-[var(--s-border-subtle,#2A2622)]",
|
|
5254
|
+
style: { gridTemplateColumns: trackTemplate },
|
|
5255
|
+
children: [
|
|
5256
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
5257
|
+
"button",
|
|
5258
|
+
{
|
|
5259
|
+
type: "button",
|
|
5260
|
+
onClick: () => toggle(stage.id),
|
|
5261
|
+
className: "flex items-center gap-2 px-4 py-3 text-left hover:bg-[var(--s-surface-raised,#1A1714)] transition-colors",
|
|
5262
|
+
"aria-expanded": !isCollapsed,
|
|
5263
|
+
children: [
|
|
5264
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Chevron, { open: !isCollapsed }),
|
|
5265
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5266
|
+
"span",
|
|
5267
|
+
{
|
|
5268
|
+
className: "h-2.5 w-2.5 shrink-0 rounded-full",
|
|
5269
|
+
style: { background: dot }
|
|
5270
|
+
}
|
|
5271
|
+
),
|
|
5272
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "min-w-0", children: [
|
|
5273
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "block truncate text-[13px] font-semibold text-[var(--s-ink-primary,#F6F1E7)]", children: stage.title }),
|
|
5274
|
+
stage.subtitle && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "block truncate text-[11px] text-[var(--s-ink-muted,#7D7568)]", children: stage.subtitle })
|
|
5275
|
+
] }),
|
|
5276
|
+
ms.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "ml-auto shrink-0 rounded-[var(--c-badge-radius,4px)] bg-[var(--s-surface-elevated,#1F1C18)] px-1.5 py-0.5 font-[var(--s-font-mono,monospace)] text-[10px] tabular-nums text-[var(--s-ink-secondary,#C9C0B4)]", children: [
|
|
5277
|
+
done,
|
|
5278
|
+
"/",
|
|
5279
|
+
ms.length
|
|
5280
|
+
] })
|
|
5281
|
+
]
|
|
5282
|
+
}
|
|
5283
|
+
),
|
|
5284
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5285
|
+
"div",
|
|
5286
|
+
{
|
|
5287
|
+
className: "relative h-9",
|
|
5288
|
+
style: {
|
|
5289
|
+
gridColumn: `${1 + sCol.start} / span ${sCol.span}`
|
|
5290
|
+
},
|
|
5291
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
5292
|
+
"div",
|
|
5293
|
+
{
|
|
5294
|
+
ref: (el) => {
|
|
5295
|
+
barRefs.current[stage.id] = el;
|
|
5296
|
+
},
|
|
5297
|
+
className: "absolute inset-y-2 inset-x-1 overflow-hidden rounded-[var(--p-radius-sm,4px)]",
|
|
5298
|
+
style: { background: tint(dot, 0.16) },
|
|
5299
|
+
title: `${stage.title} \xB7 ${pct}%`,
|
|
5300
|
+
children: [
|
|
5301
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5302
|
+
"div",
|
|
5303
|
+
{
|
|
5304
|
+
className: "h-full rounded-[var(--p-radius-sm,4px)]",
|
|
5305
|
+
style: { width: `${pct}%`, background: dot }
|
|
5306
|
+
}
|
|
5307
|
+
),
|
|
5308
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "absolute inset-0 flex items-center px-2 font-[var(--s-font-mono,monospace)] text-[10.5px] font-medium tabular-nums text-[var(--s-ink-primary,#F6F1E7)]", children: [
|
|
5309
|
+
pct,
|
|
5310
|
+
"%"
|
|
5311
|
+
] })
|
|
5312
|
+
]
|
|
5313
|
+
}
|
|
5314
|
+
)
|
|
5315
|
+
}
|
|
5316
|
+
)
|
|
5317
|
+
]
|
|
5318
|
+
}
|
|
5319
|
+
),
|
|
5320
|
+
!stagesOnly && !isCollapsed && ms.map((m) => {
|
|
5321
|
+
const mStart = m.weekStart ?? stage.weekStart;
|
|
5322
|
+
const mCol = barGridColumn(
|
|
5323
|
+
mStart,
|
|
5324
|
+
m.weekSpan ?? 1,
|
|
5325
|
+
weekCount
|
|
5326
|
+
);
|
|
5327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
5328
|
+
"div",
|
|
5329
|
+
{
|
|
5330
|
+
className: "grid items-center border-b border-[var(--s-border-subtle,#2A2622)] bg-[var(--s-surface-page,#0A0908)]",
|
|
5331
|
+
style: { gridTemplateColumns: trackTemplate },
|
|
5332
|
+
children: [
|
|
5333
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex items-center gap-2 py-2 pl-10 pr-4", children: [
|
|
5334
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(StatusDot, { done: m.done, color: dot }),
|
|
5335
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5336
|
+
"span",
|
|
5337
|
+
{
|
|
5338
|
+
className: cn(
|
|
5339
|
+
"min-w-0 flex-1 truncate text-[13px]",
|
|
5340
|
+
m.done ? "text-[var(--s-ink-muted,#7D7568)] line-through" : "text-[var(--s-ink-secondary,#C9C0B4)]"
|
|
5341
|
+
),
|
|
5342
|
+
children: m.title
|
|
5343
|
+
}
|
|
5344
|
+
),
|
|
5345
|
+
m.points != null && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "shrink-0 font-[var(--s-font-mono,monospace)] text-[10px] tabular-nums text-[var(--s-ink-muted,#7D7568)]", children: m.points })
|
|
5346
|
+
] }),
|
|
5347
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5348
|
+
"div",
|
|
5349
|
+
{
|
|
5350
|
+
className: "relative h-6",
|
|
5351
|
+
style: {
|
|
5352
|
+
gridColumn: `${1 + mCol.start} / span ${mCol.span}`
|
|
5353
|
+
},
|
|
5354
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5355
|
+
"div",
|
|
5356
|
+
{
|
|
5357
|
+
className: cn(
|
|
5358
|
+
"absolute inset-y-1.5 inset-x-1 rounded-[var(--p-radius-sm,4px)]",
|
|
5359
|
+
m.done ? "" : "border"
|
|
5360
|
+
),
|
|
5361
|
+
style: m.done ? { background: dot } : {
|
|
5362
|
+
background: tint(dot, 0.08),
|
|
5363
|
+
borderColor: tint(dot, 0.4)
|
|
5364
|
+
}
|
|
5365
|
+
}
|
|
5366
|
+
)
|
|
5367
|
+
}
|
|
5368
|
+
)
|
|
5369
|
+
]
|
|
5370
|
+
},
|
|
5371
|
+
m.id
|
|
5372
|
+
);
|
|
5373
|
+
})
|
|
5374
|
+
] }, stage.id);
|
|
5375
|
+
}),
|
|
5376
|
+
stages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "px-4 py-8 text-center text-[13px] text-[var(--s-ink-muted,#7D7568)]", children: "No stages yet." })
|
|
5377
|
+
] }) }),
|
|
5378
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex flex-wrap items-center gap-4 border-t border-[var(--s-border-subtle,#2A2622)] px-5 py-2.5 font-[var(--s-font-mono,monospace)] text-[10.5px] uppercase tracking-[0.6px] text-[var(--s-ink-muted,#7D7568)]", children: [
|
|
5379
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(LegendItem, { swatch: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "h-2.5 w-3 rounded-[2px]", style: { background: "var(--s-brand-solid, #E07A4A)" } }), label: "Completed" }),
|
|
5380
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(LegendItem, { swatch: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "h-2.5 w-3 rounded-[2px] border", style: { background: "rgba(224,122,74,0.08)", borderColor: "rgba(224,122,74,0.4)" } }), label: "Upcoming" }),
|
|
5381
|
+
dependencies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(LegendItem, { swatch: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "block h-0.5 w-4", style: { background: "var(--s-brand-solid, #E07A4A)", opacity: 0.7 } }), label: "Depends on" })
|
|
5382
|
+
] })
|
|
5383
|
+
]
|
|
5384
|
+
}
|
|
5385
|
+
);
|
|
5386
|
+
}
|
|
5387
|
+
function Chevron({ open }) {
|
|
5388
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5389
|
+
"svg",
|
|
5390
|
+
{
|
|
5391
|
+
width: "14",
|
|
5392
|
+
height: "14",
|
|
5393
|
+
viewBox: "0 0 24 24",
|
|
5394
|
+
fill: "none",
|
|
5395
|
+
stroke: "currentColor",
|
|
5396
|
+
strokeWidth: "1.5",
|
|
5397
|
+
strokeLinecap: "round",
|
|
5398
|
+
strokeLinejoin: "round",
|
|
5399
|
+
className: "shrink-0 text-[var(--s-ink-muted,#7D7568)] transition-transform",
|
|
5400
|
+
style: { transform: open ? "rotate(90deg)" : "none" },
|
|
5401
|
+
"aria-hidden": "true",
|
|
5402
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("path", { d: "M9 18l6-6-6-6" })
|
|
5403
|
+
}
|
|
5404
|
+
);
|
|
5405
|
+
}
|
|
5406
|
+
function StatusDot({ done, color }) {
|
|
5407
|
+
if (done) {
|
|
5408
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
5409
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("circle", { cx: "12", cy: "12", r: "9", fill: color }),
|
|
5410
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5411
|
+
"path",
|
|
5412
|
+
{
|
|
5413
|
+
d: "M8 12l3 3 5-6",
|
|
5414
|
+
fill: "none",
|
|
5415
|
+
stroke: "var(--s-ink-inverse, #0A0908)",
|
|
5416
|
+
strokeWidth: "2",
|
|
5417
|
+
strokeLinecap: "round",
|
|
5418
|
+
strokeLinejoin: "round"
|
|
5419
|
+
}
|
|
5420
|
+
)
|
|
5421
|
+
] });
|
|
5422
|
+
}
|
|
5423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5424
|
+
"circle",
|
|
5425
|
+
{
|
|
5426
|
+
cx: "12",
|
|
5427
|
+
cy: "12",
|
|
5428
|
+
r: "8",
|
|
5429
|
+
fill: "none",
|
|
5430
|
+
stroke: "var(--s-border-strong, #3A3530)",
|
|
5431
|
+
strokeWidth: "2"
|
|
5432
|
+
}
|
|
5433
|
+
) });
|
|
5434
|
+
}
|
|
5435
|
+
function LegendItem({ swatch, label }) {
|
|
5436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "flex items-center gap-1.5", children: [
|
|
5437
|
+
swatch,
|
|
5438
|
+
label
|
|
5439
|
+
] });
|
|
5440
|
+
}
|
|
5441
|
+
function tint(color, alpha) {
|
|
5442
|
+
const hex = /^#([0-9a-f]{6})$/i.exec(color.trim());
|
|
5443
|
+
if (hex) {
|
|
5444
|
+
const n = parseInt(hex[1], 16);
|
|
5445
|
+
const r = n >> 16 & 255;
|
|
5446
|
+
const g = n >> 8 & 255;
|
|
5447
|
+
const b = n & 255;
|
|
5448
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
5449
|
+
}
|
|
5450
|
+
return `color-mix(in srgb, ${color} ${Math.round(alpha * 100)}%, transparent)`;
|
|
5451
|
+
}
|
|
5452
|
+
|
|
5453
|
+
// src/components/organisms/PublishDrawer.tsx
|
|
5454
|
+
var React45 = __toESM(require("react"), 1);
|
|
5455
|
+
var import_lucide_react23 = require("lucide-react");
|
|
5456
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
5072
5457
|
function parseTags(raw) {
|
|
5073
5458
|
return raw.split(/[,\n]/).map((t) => t.trim()).filter((t) => t.length > 0);
|
|
5074
5459
|
}
|
|
@@ -5104,16 +5489,16 @@ function PublishDrawer({
|
|
|
5104
5489
|
onError,
|
|
5105
5490
|
className
|
|
5106
5491
|
}) {
|
|
5107
|
-
const [title, setTitle] =
|
|
5108
|
-
const [description, setDescription] =
|
|
5109
|
-
const [tagsRaw, setTagsRaw] =
|
|
5110
|
-
const [thumbnailUrl, setThumbnailUrl] =
|
|
5111
|
-
const [accounts, setAccounts] =
|
|
5112
|
-
const [accountId, setAccountId] =
|
|
5113
|
-
const [status, setStatus] =
|
|
5114
|
-
const [errorMsg, setErrorMsg] =
|
|
5115
|
-
const [result, setResult] =
|
|
5116
|
-
|
|
5492
|
+
const [title, setTitle] = React45.useState(suggestedTitle);
|
|
5493
|
+
const [description, setDescription] = React45.useState(suggestedDescription);
|
|
5494
|
+
const [tagsRaw, setTagsRaw] = React45.useState("");
|
|
5495
|
+
const [thumbnailUrl, setThumbnailUrl] = React45.useState(suggestedThumbnailUrl);
|
|
5496
|
+
const [accounts, setAccounts] = React45.useState([]);
|
|
5497
|
+
const [accountId, setAccountId] = React45.useState(null);
|
|
5498
|
+
const [status, setStatus] = React45.useState("idle");
|
|
5499
|
+
const [errorMsg, setErrorMsg] = React45.useState(null);
|
|
5500
|
+
const [result, setResult] = React45.useState(null);
|
|
5501
|
+
React45.useEffect(() => {
|
|
5117
5502
|
if (open) {
|
|
5118
5503
|
setTitle(suggestedTitle);
|
|
5119
5504
|
setDescription(suggestedDescription);
|
|
@@ -5123,7 +5508,7 @@ function PublishDrawer({
|
|
|
5123
5508
|
setResult(null);
|
|
5124
5509
|
}
|
|
5125
5510
|
}, [open]);
|
|
5126
|
-
|
|
5511
|
+
React45.useEffect(() => {
|
|
5127
5512
|
if (!open) return;
|
|
5128
5513
|
let cancelled = false;
|
|
5129
5514
|
(async () => {
|
|
@@ -5147,7 +5532,7 @@ function PublishDrawer({
|
|
|
5147
5532
|
cancelled = true;
|
|
5148
5533
|
};
|
|
5149
5534
|
}, [open, supabase]);
|
|
5150
|
-
const fail =
|
|
5535
|
+
const fail = React45.useCallback(
|
|
5151
5536
|
(msg) => {
|
|
5152
5537
|
setStatus("error");
|
|
5153
5538
|
setErrorMsg(msg);
|
|
@@ -5249,18 +5634,18 @@ function PublishDrawer({
|
|
|
5249
5634
|
onPublished?.(publishResult);
|
|
5250
5635
|
}
|
|
5251
5636
|
const busy = status === "publishing" || status === "rendering-thumb" || status === "loading-accounts";
|
|
5252
|
-
return /* @__PURE__ */ (0,
|
|
5253
|
-
/* @__PURE__ */ (0,
|
|
5254
|
-
/* @__PURE__ */ (0,
|
|
5255
|
-
/* @__PURE__ */ (0,
|
|
5637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Sheet, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(SheetContent, { side: "right", className: cn("flex w-full flex-col gap-4 overflow-y-auto sm:max-w-md", className), children: [
|
|
5638
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(SheetHeader, { children: [
|
|
5639
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(SheetTitle, { className: "flex items-center gap-2", children: [
|
|
5640
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react23.Youtube, { className: "h-5 w-5 text-red-600" }),
|
|
5256
5641
|
"Publicar no YouTube"
|
|
5257
5642
|
] }),
|
|
5258
|
-
/* @__PURE__ */ (0,
|
|
5643
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SheetDescription, { children: "Publique o v\xEDdeo gravado cross-platform via Zernio. Preencha t\xEDtulo, descri\xE7\xE3o e palavras-chave manualmente." })
|
|
5259
5644
|
] }),
|
|
5260
|
-
status === "done" && result ? /* @__PURE__ */ (0,
|
|
5261
|
-
/* @__PURE__ */ (0,
|
|
5262
|
-
/* @__PURE__ */ (0,
|
|
5263
|
-
result.post_url && /* @__PURE__ */ (0,
|
|
5645
|
+
status === "done" && result ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "flex flex-1 flex-col items-center justify-center gap-3 text-center", children: [
|
|
5646
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react23.CheckCircle2, { className: "h-10 w-10 text-green-600" }),
|
|
5647
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "font-medium", children: "V\xEDdeo publicado!" }),
|
|
5648
|
+
result.post_url && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
5264
5649
|
"a",
|
|
5265
5650
|
{
|
|
5266
5651
|
href: result.post_url,
|
|
@@ -5270,15 +5655,15 @@ function PublishDrawer({
|
|
|
5270
5655
|
children: "Abrir no YouTube"
|
|
5271
5656
|
}
|
|
5272
5657
|
),
|
|
5273
|
-
/* @__PURE__ */ (0,
|
|
5658
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
|
|
5274
5659
|
"Zernio post id: ",
|
|
5275
5660
|
result.zernio_post_id
|
|
5276
5661
|
] }),
|
|
5277
|
-
/* @__PURE__ */ (0,
|
|
5278
|
-
] }) : /* @__PURE__ */ (0,
|
|
5279
|
-
/* @__PURE__ */ (0,
|
|
5280
|
-
/* @__PURE__ */ (0,
|
|
5281
|
-
/* @__PURE__ */ (0,
|
|
5662
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Fechar" })
|
|
5663
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "flex flex-1 flex-col gap-4", children: [
|
|
5664
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "grid gap-2", children: [
|
|
5665
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Label3, { htmlFor: "pd-title", children: "T\xEDtulo" }),
|
|
5666
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
5282
5667
|
Input,
|
|
5283
5668
|
{
|
|
5284
5669
|
id: "pd-title",
|
|
@@ -5289,9 +5674,9 @@ function PublishDrawer({
|
|
|
5289
5674
|
}
|
|
5290
5675
|
)
|
|
5291
5676
|
] }),
|
|
5292
|
-
/* @__PURE__ */ (0,
|
|
5293
|
-
/* @__PURE__ */ (0,
|
|
5294
|
-
/* @__PURE__ */ (0,
|
|
5677
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "grid gap-2", children: [
|
|
5678
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Label3, { htmlFor: "pd-desc", children: "Descri\xE7\xE3o" }),
|
|
5679
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
5295
5680
|
Textarea,
|
|
5296
5681
|
{
|
|
5297
5682
|
id: "pd-desc",
|
|
@@ -5303,9 +5688,9 @@ function PublishDrawer({
|
|
|
5303
5688
|
}
|
|
5304
5689
|
)
|
|
5305
5690
|
] }),
|
|
5306
|
-
/* @__PURE__ */ (0,
|
|
5307
|
-
/* @__PURE__ */ (0,
|
|
5308
|
-
/* @__PURE__ */ (0,
|
|
5691
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "grid gap-2", children: [
|
|
5692
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Label3, { htmlFor: "pd-tags", children: "Palavras-chave / tags" }),
|
|
5693
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
5309
5694
|
Input,
|
|
5310
5695
|
{
|
|
5311
5696
|
id: "pd-tags",
|
|
@@ -5315,11 +5700,11 @@ function PublishDrawer({
|
|
|
5315
5700
|
disabled: busy
|
|
5316
5701
|
}
|
|
5317
5702
|
),
|
|
5318
|
-
/* @__PURE__ */ (0,
|
|
5703
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-xs text-muted-foreground", children: "Separadas por v\xEDrgula. A primeira vira a keyword." })
|
|
5319
5704
|
] }),
|
|
5320
|
-
/* @__PURE__ */ (0,
|
|
5321
|
-
/* @__PURE__ */ (0,
|
|
5322
|
-
/* @__PURE__ */ (0,
|
|
5705
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "grid gap-2", children: [
|
|
5706
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Label3, { htmlFor: "pd-thumb", children: "Thumbnail" }),
|
|
5707
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
5323
5708
|
Input,
|
|
5324
5709
|
{
|
|
5325
5710
|
id: "pd-thumb",
|
|
@@ -5329,7 +5714,7 @@ function PublishDrawer({
|
|
|
5329
5714
|
disabled: busy
|
|
5330
5715
|
}
|
|
5331
5716
|
),
|
|
5332
|
-
thumbnailTemplateId && /* @__PURE__ */ (0,
|
|
5717
|
+
thumbnailTemplateId && /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
|
|
5333
5718
|
Button,
|
|
5334
5719
|
{
|
|
5335
5720
|
type: "button",
|
|
@@ -5339,12 +5724,12 @@ function PublishDrawer({
|
|
|
5339
5724
|
disabled: busy,
|
|
5340
5725
|
className: "w-fit",
|
|
5341
5726
|
children: [
|
|
5342
|
-
status === "rendering-thumb" ? /* @__PURE__ */ (0,
|
|
5727
|
+
status === "rendering-thumb" ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react23.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react23.Image, { className: "mr-2 h-4 w-4" }),
|
|
5343
5728
|
"Gerar via Thumbify"
|
|
5344
5729
|
]
|
|
5345
5730
|
}
|
|
5346
5731
|
),
|
|
5347
|
-
thumbnailUrl && /* @__PURE__ */ (0,
|
|
5732
|
+
thumbnailUrl && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
5348
5733
|
"img",
|
|
5349
5734
|
{
|
|
5350
5735
|
src: thumbnailUrl,
|
|
@@ -5353,26 +5738,26 @@ function PublishDrawer({
|
|
|
5353
5738
|
}
|
|
5354
5739
|
)
|
|
5355
5740
|
] }),
|
|
5356
|
-
/* @__PURE__ */ (0,
|
|
5357
|
-
/* @__PURE__ */ (0,
|
|
5358
|
-
/* @__PURE__ */ (0,
|
|
5359
|
-
/* @__PURE__ */ (0,
|
|
5741
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "grid gap-2", children: [
|
|
5742
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Label3, { htmlFor: "pd-account", children: "Canal do YouTube" }),
|
|
5743
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Select, { value: accountId ?? void 0, onValueChange: setAccountId, disabled: busy || accounts.length === 0, children: [
|
|
5744
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SelectTrigger, { id: "pd-account", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
5360
5745
|
SelectValue,
|
|
5361
5746
|
{
|
|
5362
5747
|
placeholder: status === "loading-accounts" ? "Carregando canais\u2026" : accounts.length === 0 ? "Nenhum canal conectado" : "Selecione um canal"
|
|
5363
5748
|
}
|
|
5364
5749
|
) }),
|
|
5365
|
-
/* @__PURE__ */ (0,
|
|
5750
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SelectContent, { children: accounts.map((a) => /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SelectItem, { value: a.account_id, children: a.account_name ?? a.account_id }, a.id)) })
|
|
5366
5751
|
] })
|
|
5367
5752
|
] }),
|
|
5368
|
-
errorMsg && /* @__PURE__ */ (0,
|
|
5369
|
-
/* @__PURE__ */ (0,
|
|
5753
|
+
errorMsg && /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("p", { className: "flex items-center gap-2 text-sm text-destructive", children: [
|
|
5754
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react23.AlertCircle, { className: "h-4 w-4" }),
|
|
5370
5755
|
errorMsg
|
|
5371
5756
|
] }),
|
|
5372
|
-
/* @__PURE__ */ (0,
|
|
5373
|
-
/* @__PURE__ */ (0,
|
|
5374
|
-
/* @__PURE__ */ (0,
|
|
5375
|
-
status === "publishing" && /* @__PURE__ */ (0,
|
|
5757
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(SheetFooter, { className: "mt-auto", children: [
|
|
5758
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: busy, children: "Cancelar" }),
|
|
5759
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Button, { onClick: handlePublish, disabled: busy, children: [
|
|
5760
|
+
status === "publishing" && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react23.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
5376
5761
|
"Publicar"
|
|
5377
5762
|
] })
|
|
5378
5763
|
] })
|
|
@@ -5401,7 +5786,7 @@ function useIframeNavigate() {
|
|
|
5401
5786
|
|
|
5402
5787
|
// src/providers/feature-flag-provider.tsx
|
|
5403
5788
|
var import_react9 = require("react");
|
|
5404
|
-
var
|
|
5789
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
5405
5790
|
var FeatureFlagContext = (0, import_react9.createContext)({
|
|
5406
5791
|
flags: {},
|
|
5407
5792
|
isEnabled: () => false
|
|
@@ -5417,7 +5802,7 @@ var FeatureFlagProvider = ({
|
|
|
5417
5802
|
}),
|
|
5418
5803
|
[flags]
|
|
5419
5804
|
);
|
|
5420
|
-
return /* @__PURE__ */ (0,
|
|
5805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(FeatureFlagContext.Provider, { value, children });
|
|
5421
5806
|
};
|
|
5422
5807
|
var useFeatureFlag = (flag) => {
|
|
5423
5808
|
const { isEnabled } = (0, import_react9.useContext)(FeatureFlagContext);
|
|
@@ -5555,6 +5940,7 @@ var useFeatureFlags = () => {
|
|
|
5555
5940
|
FormItem,
|
|
5556
5941
|
FormLabel,
|
|
5557
5942
|
FormMessage,
|
|
5943
|
+
Gantt,
|
|
5558
5944
|
HoverCard,
|
|
5559
5945
|
HoverCardContent,
|
|
5560
5946
|
HoverCardTrigger,
|
|
@@ -5695,7 +6081,9 @@ var useFeatureFlags = () => {
|
|
|
5695
6081
|
UserAvatar,
|
|
5696
6082
|
UserMenu,
|
|
5697
6083
|
badgeVariants,
|
|
6084
|
+
barGridColumn,
|
|
5698
6085
|
buttonVariants,
|
|
6086
|
+
clampPct,
|
|
5699
6087
|
cn,
|
|
5700
6088
|
filterPublishableAccounts,
|
|
5701
6089
|
getInitials,
|
|
@@ -5707,6 +6095,9 @@ var useFeatureFlags = () => {
|
|
|
5707
6095
|
memberHueVar,
|
|
5708
6096
|
navigationMenuTriggerStyle,
|
|
5709
6097
|
parseTags,
|
|
6098
|
+
resolveWeekCount,
|
|
6099
|
+
resolveWeekLabels,
|
|
6100
|
+
stageProgress,
|
|
5710
6101
|
toast,
|
|
5711
6102
|
toggleVariants,
|
|
5712
6103
|
useAuth,
|