Skip to content

Commit d36cabb

Browse files
committed
kanban
1 parent 644e056 commit d36cabb

File tree

2 files changed

+201
-109
lines changed

2 files changed

+201
-109
lines changed

reference/schema.json

Lines changed: 88 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3925,90 +3925,6 @@
39253925
},
39263926
"x-collection": "generic_request"
39273927
},
3928-
"ItemsHiringIntent": {
3929-
"type": "object",
3930-
"properties": {
3931-
"id": {
3932-
"nullable": false,
3933-
"type": "integer"
3934-
},
3935-
"user_created": {
3936-
"nullable": true,
3937-
"oneOf": [
3938-
{
3939-
"type": "string",
3940-
"format": "uuid"
3941-
},
3942-
{
3943-
"$ref": "#/components/schemas/Users"
3944-
}
3945-
]
3946-
},
3947-
"date_created": {
3948-
"nullable": true,
3949-
"type": "string",
3950-
"format": "timestamp"
3951-
},
3952-
"user_updated": {
3953-
"nullable": true,
3954-
"oneOf": [
3955-
{
3956-
"type": "string",
3957-
"format": "uuid"
3958-
},
3959-
{
3960-
"$ref": "#/components/schemas/Users"
3961-
}
3962-
]
3963-
},
3964-
"date_updated": {
3965-
"nullable": true,
3966-
"type": "string",
3967-
"format": "timestamp"
3968-
},
3969-
"company_profile": {
3970-
"nullable": true,
3971-
"oneOf": [
3972-
{
3973-
"type": "integer"
3974-
},
3975-
{
3976-
"$ref": "#/components/schemas/ItemsCompanyProfile"
3977-
}
3978-
]
3979-
},
3980-
"reason": {
3981-
"nullable": true,
3982-
"type": "string"
3983-
},
3984-
"potential_role": {
3985-
"nullable": true
3986-
},
3987-
"skill": {
3988-
"nullable": true
3989-
},
3990-
"category": {
3991-
"nullable": true,
3992-
"description": "options: [\"funding\", \"growth\", \"replacement\"]"
3993-
},
3994-
"space": {
3995-
"nullable": true,
3996-
"oneOf": [
3997-
{
3998-
"type": "integer"
3999-
},
4000-
{
4001-
"$ref": "#/components/schemas/ItemsSpace"
4002-
}
4003-
]
4004-
},
4005-
"confidence": {
4006-
"nullable": true,
4007-
"type": "integer"
4008-
}
4009-
},
4010-
"x-collection": "hiring_intent"
4011-
},
40123928
"ItemsCompanyReference": {
40133929
"type": "object",
40143930
"properties": {
@@ -4385,6 +4301,94 @@
43854301
},
43864302
"x-collection": "hiring_intent_contact"
43874303
},
4304+
"ItemsHiringIntent": {
4305+
"type": "object",
4306+
"properties": {
4307+
"id": {
4308+
"nullable": false,
4309+
"type": "integer"
4310+
},
4311+
"user_created": {
4312+
"nullable": true,
4313+
"oneOf": [
4314+
{
4315+
"type": "string",
4316+
"format": "uuid"
4317+
},
4318+
{
4319+
"$ref": "#/components/schemas/Users"
4320+
}
4321+
]
4322+
},
4323+
"date_created": {
4324+
"nullable": true,
4325+
"type": "string",
4326+
"format": "timestamp"
4327+
},
4328+
"user_updated": {
4329+
"nullable": true,
4330+
"oneOf": [
4331+
{
4332+
"type": "string",
4333+
"format": "uuid"
4334+
},
4335+
{
4336+
"$ref": "#/components/schemas/Users"
4337+
}
4338+
]
4339+
},
4340+
"date_updated": {
4341+
"nullable": true,
4342+
"type": "string",
4343+
"format": "timestamp"
4344+
},
4345+
"company_profile": {
4346+
"nullable": true,
4347+
"oneOf": [
4348+
{
4349+
"type": "integer"
4350+
},
4351+
{
4352+
"$ref": "#/components/schemas/ItemsCompanyProfile"
4353+
}
4354+
]
4355+
},
4356+
"reason": {
4357+
"nullable": true,
4358+
"type": "string"
4359+
},
4360+
"potential_role": {
4361+
"nullable": true
4362+
},
4363+
"skill": {
4364+
"nullable": true
4365+
},
4366+
"space": {
4367+
"nullable": true,
4368+
"oneOf": [
4369+
{
4370+
"type": "integer"
4371+
},
4372+
{
4373+
"$ref": "#/components/schemas/ItemsSpace"
4374+
}
4375+
]
4376+
},
4377+
"confidence": {
4378+
"nullable": true,
4379+
"type": "integer"
4380+
},
4381+
"category": {
4382+
"nullable": true,
4383+
"type": "string"
4384+
},
4385+
"url": {
4386+
"nullable": true,
4387+
"type": "string"
4388+
}
4389+
},
4390+
"x-collection": "hiring_intent"
4391+
},
43884392
"ItemsHiringIntentAction": {
43894393
"type": "object",
43904394
"properties": {

src/components/interactive/HiringIntentDashboard.tsx

Lines changed: 113 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ export default function HiringIntentDashboard() {
214214
);
215215

216216
return (
217-
<div className="space-y-8">
217+
<div className="space-y-6">
218218
{/* Space Selector */}
219219
<div className="flex items-center justify-between">
220220
<div className="flex items-center gap-3">
@@ -263,32 +263,120 @@ export default function HiringIntentDashboard() {
263263
</Card>
264264
)}
265265

266-
{/* Actions Section */}
267-
{!isLoading && !error && actionIntents.length > 0 && (
268-
<div className="space-y-4">
269-
<div className="flex items-center gap-2">
270-
<h2 className="text-xl font-semibold text-gray-900">Actions</h2>
271-
<Badge variant="secondary" className="bg-green-100 text-green-800">
272-
{actionIntents.length}
273-
</Badge>
274-
</div>
275-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
276-
{actionIntents.map((intent) => renderIntentCard(intent, false))}
266+
{/* Kanban Layout */}
267+
{!isLoading && !error && hiringIntents.length > 0 && (
268+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 h-[calc(100vh-250px)]">
269+
{/* Left Column - Signals */}
270+
<div className="flex flex-col">
271+
<div className="flex items-center gap-2 mb-4">
272+
<h2 className="text-xl font-semibold text-gray-900">Signals</h2>
273+
<Badge variant="secondary" className="bg-blue-100 text-blue-800">
274+
{pendingIntents.length}
275+
</Badge>
276+
</div>
277+
<div className="flex-1 overflow-y-auto space-y-4 pr-2">
278+
{pendingIntents.length === 0 ? (
279+
<Card className="border-dashed">
280+
<CardContent className="pt-6">
281+
<div className="text-center py-8">
282+
<p className="text-gray-500">No pending signals</p>
283+
<p className="text-gray-400 text-sm mt-2">
284+
All signals have been processed
285+
</p>
286+
</div>
287+
</CardContent>
288+
</Card>
289+
) : (
290+
pendingIntents.map((intent) => renderIntentCard(intent, true))
291+
)}
292+
</div>
277293
</div>
278-
</div>
279-
)}
280294

281-
{/* Orbit Signals Grid */}
282-
{!isLoading && !error && pendingIntents.length > 0 && (
283-
<div className="space-y-4">
284-
<div className="flex items-center gap-2">
285-
<h2 className="text-xl font-semibold text-gray-900">Orbit Signals</h2>
286-
<Badge variant="secondary">
287-
{pendingIntents.length}
288-
</Badge>
289-
</div>
290-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
291-
{pendingIntents.map((intent) => renderIntentCard(intent, true))}
295+
{/* Right Column - Actions */}
296+
<div className="flex flex-col">
297+
<div className="flex items-center gap-2 mb-4">
298+
<h2 className="text-xl font-semibold text-gray-900">Actions</h2>
299+
<Badge variant="secondary" className="bg-green-100 text-green-800">
300+
{actionIntents.length}
301+
</Badge>
302+
</div>
303+
<div className="flex-1 overflow-y-auto space-y-3 pr-2">
304+
{actionIntents.length === 0 ? (
305+
<Card className="border-dashed">
306+
<CardContent className="pt-6">
307+
<div className="text-center py-8">
308+
<p className="text-gray-500">No actions yet</p>
309+
<p className="text-gray-400 text-sm mt-2">
310+
Add signals to actions to see them here
311+
</p>
312+
</div>
313+
</CardContent>
314+
</Card>
315+
) : (
316+
actionIntents.map((intent) => (
317+
<Card key={intent.id} className="hover:shadow-md transition-shadow border-l-4 border-l-green-500">
318+
<CardContent className="pt-4">
319+
<div className="flex items-start gap-3">
320+
<CheckCircle2 className="w-5 h-5 text-green-600 mt-0.5 flex-shrink-0" />
321+
<div className="flex-1 min-w-0">
322+
<div className="flex items-center gap-2 mb-2">
323+
<h3 className="font-semibold text-gray-900 truncate">
324+
{intent.company_profile?.name || "Unknown Company"}
325+
</h3>
326+
{intent.category && (
327+
<Badge className={getCategoryColor(intent.category)} variant="secondary">
328+
{intent.category}
329+
</Badge>
330+
)}
331+
</div>
332+
333+
{/* Potential Role */}
334+
{intent.potential_role && (
335+
<div className="mb-2">
336+
<p className="text-xs font-medium text-gray-500 mb-0.5">Role</p>
337+
<p className="text-sm text-gray-700">
338+
{typeof intent.potential_role === "string"
339+
? intent.potential_role
340+
: JSON.stringify(intent.potential_role)}
341+
</p>
342+
</div>
343+
)}
344+
345+
{/* Reason */}
346+
{intent.reason && (
347+
<div className="mb-2">
348+
<p className="text-xs font-medium text-gray-500 mb-0.5">Reason</p>
349+
<p className="text-sm text-gray-600 line-clamp-2">{intent.reason}</p>
350+
</div>
351+
)}
352+
353+
{/* Skills */}
354+
{intent.skill && (
355+
<div className="mb-2">
356+
<p className="text-xs font-medium text-gray-500 mb-0.5">Skills</p>
357+
<p className="text-sm text-gray-600 line-clamp-1">
358+
{typeof intent.skill === "string"
359+
? intent.skill
360+
: JSON.stringify(intent.skill)}
361+
</p>
362+
</div>
363+
)}
364+
365+
{/* Actions metadata */}
366+
{intent.actions && intent.actions.length > 0 && (
367+
<div className="mt-2 pt-2 border-t border-gray-100">
368+
<p className="text-xs text-gray-400">
369+
Added {formatDate(intent.actions[0].date_created)}
370+
</p>
371+
</div>
372+
)}
373+
</div>
374+
</div>
375+
</CardContent>
376+
</Card>
377+
))
378+
)}
379+
</div>
292380
</div>
293381
</div>
294382
)}

0 commit comments

Comments
 (0)