diff --git a/src/components/FeatureIdeaCloud.tsx b/src/components/FeatureIdeaCloud.tsx index 09e7604..5094c67 100644 --- a/src/components/FeatureIdeaCloud.tsx +++ b/src/components/FeatureIdeaCloud.tsx @@ -31,6 +31,7 @@ import prioritiesData from './FeatureIdeaCloud/data/priorities.json' import statusesData from './FeatureIdeaCloud/data/statuses.json' import groupColorsData from './FeatureIdeaCloud/data/group-colors.json' import { nodeTypes } from './FeatureIdeaCloud/nodes' +import { dispatchConnectionCountUpdate } from './FeatureIdeaCloud/dispatchConnectionCountUpdate' type SeedIdeaJson = Omit & { createdAtOffsetMs: number } @@ -133,10 +134,7 @@ export function FeatureIdeaCloud() { bottom: connections.bottom.size, } - const event = new CustomEvent('updateConnectionCounts', { - detail: { nodeId, counts } - }) - window.dispatchEvent(event) + dispatchConnectionCountUpdate(nodeId, counts) }) }, []) diff --git a/src/components/FeatureIdeaCloud/GroupNode.tsx b/src/components/FeatureIdeaCloud/GroupNode.tsx new file mode 100644 index 0000000..61a1968 --- /dev/null +++ b/src/components/FeatureIdeaCloud/GroupNode.tsx @@ -0,0 +1,44 @@ +import { NodeProps } from 'reactflow' +import { Button } from '@/components/ui/button' +import { DotsThree } from '@phosphor-icons/react' +import { IdeaGroup } from './types' +import { GROUP_COLORS } from './constants' +import { dispatchEditGroup } from './dispatchEditGroup' + +export function GroupNode({ data, selected }: NodeProps) { + const colorScheme = GROUP_COLORS.find(c => c.value === data.color) || GROUP_COLORS[0] + + return ( +
+
+ {data.label} +
+ +
+ ) +} diff --git a/src/components/FeatureIdeaCloud/IdeaNode.tsx b/src/components/FeatureIdeaCloud/IdeaNode.tsx new file mode 100644 index 0000000..1b1ed52 --- /dev/null +++ b/src/components/FeatureIdeaCloud/IdeaNode.tsx @@ -0,0 +1,72 @@ +import { useState, useEffect } from 'react' +import { NodeProps, Position } from 'reactflow' +import { Button } from '@/components/ui/button' +import { Card } from '@/components/ui/card' +import { Badge } from '@/components/ui/badge' +import { DotsThree } from '@phosphor-icons/react' +import { FeatureIdea } from './types' +import { PRIORITY_COLORS, STATUS_COLORS } from './constants' +import { generateHandles } from './generateHandles' +import { dispatchEditIdea } from './dispatchEditIdea' + +export function IdeaNode({ data, selected, id }: NodeProps & { id: string }) { + const [connectionCounts, setConnectionCounts] = useState>({ + left: 0, + right: 0, + top: 0, + bottom: 0, + }) + + useEffect(() => { + const updateConnectionCounts = (event: CustomEvent) => { + const { nodeId, counts } = event.detail + if (nodeId === id) { + setConnectionCounts(counts) + } + } + + window.addEventListener('updateConnectionCounts' as any, updateConnectionCounts as EventListener) + return () => { + window.removeEventListener('updateConnectionCounts' as any, updateConnectionCounts as EventListener) + } + }, [id]) + + return ( +
+ {generateHandles({ position: Position.Left, type: 'target', side: 'left', count: connectionCounts.left })} + {generateHandles({ position: Position.Right, type: 'source', side: 'right', count: connectionCounts.right })} + {generateHandles({ position: Position.Top, type: 'target', side: 'top', count: connectionCounts.top })} + {generateHandles({ position: Position.Bottom, type: 'source', side: 'bottom', count: connectionCounts.bottom })} + + +
+
+

{data.title}

+ +
+

+ {data.description} +

+
+ + {data.category} + + + {data.status} + +
+
+
+
+ ) +} diff --git a/src/components/FeatureIdeaCloud/dispatchConnectionCountUpdate.ts b/src/components/FeatureIdeaCloud/dispatchConnectionCountUpdate.ts new file mode 100644 index 0000000..3d7f85c --- /dev/null +++ b/src/components/FeatureIdeaCloud/dispatchConnectionCountUpdate.ts @@ -0,0 +1,6 @@ +export function dispatchConnectionCountUpdate(nodeId: string, counts: Record) { + const event = new CustomEvent('updateConnectionCounts', { + detail: { nodeId, counts } + }) + window.dispatchEvent(event) +} diff --git a/src/components/FeatureIdeaCloud/dispatchEditGroup.ts b/src/components/FeatureIdeaCloud/dispatchEditGroup.ts new file mode 100644 index 0000000..3af9800 --- /dev/null +++ b/src/components/FeatureIdeaCloud/dispatchEditGroup.ts @@ -0,0 +1,6 @@ +import { IdeaGroup } from './types' + +export function dispatchEditGroup(group: IdeaGroup) { + const event = new CustomEvent('editGroup', { detail: group }) + window.dispatchEvent(event) +} diff --git a/src/components/FeatureIdeaCloud/dispatchEditIdea.ts b/src/components/FeatureIdeaCloud/dispatchEditIdea.ts new file mode 100644 index 0000000..2a7bfdd --- /dev/null +++ b/src/components/FeatureIdeaCloud/dispatchEditIdea.ts @@ -0,0 +1,6 @@ +import { FeatureIdea } from './types' + +export function dispatchEditIdea(idea: FeatureIdea) { + const event = new CustomEvent('editIdea', { detail: idea }) + window.dispatchEvent(event) +} diff --git a/src/components/FeatureIdeaCloud/utils.tsx b/src/components/FeatureIdeaCloud/generateHandles.tsx similarity index 69% rename from src/components/FeatureIdeaCloud/utils.tsx rename to src/components/FeatureIdeaCloud/generateHandles.tsx index 1a08ee7..01411c6 100644 --- a/src/components/FeatureIdeaCloud/utils.tsx +++ b/src/components/FeatureIdeaCloud/generateHandles.tsx @@ -11,7 +11,7 @@ interface GenerateHandlesProps { export function generateHandles({ position, type, side, count }: GenerateHandlesProps): ReactElement[] { const totalHandles = Math.max(2, count + 1) const handles: ReactElement[] = [] - + for (let i = 0; i < totalHandles; i++) { const handleId = `${side}-${i}` const isVertical = position === Position.Top || position === Position.Bottom @@ -20,7 +20,7 @@ export function generateHandles({ position, type, side, count }: GenerateHandles const positionStyle = isVertical ? { left: `${leftPercent}%` } : { top: `${topPercent}%` } - + const element = ( ) { - const event = new CustomEvent('updateConnectionCounts', { - detail: { nodeId, counts } - }) - window.dispatchEvent(event) -} - -export function dispatchEditIdea(idea: any) { - const event = new CustomEvent('editIdea', { detail: idea }) - window.dispatchEvent(event) -} - -export function dispatchEditGroup(group: any) { - const event = new CustomEvent('editGroup', { detail: group }) - window.dispatchEvent(event) -} diff --git a/src/components/FeatureIdeaCloud/utils.ts b/src/components/FeatureIdeaCloud/utils.ts deleted file mode 100644 index b096f6a..0000000 --- a/src/components/FeatureIdeaCloud/utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -export function dispatchConnectionCountUpdate(nodeId: string, counts: Record) { - const event = new CustomEvent('updateConnectionCounts', { - detail: { nodeId, counts } - }) - window.dispatchEvent(event) -} - -export function dispatchEditIdea(idea: any) { - const event = new CustomEvent('editIdea', { detail: idea }) - window.dispatchEvent(event) -} - -export function dispatchEditGroup(group: any) { - const event = new CustomEvent('editGroup', { detail: group }) - window.dispatchEvent(event) -}