Skip to content

Commit

Permalink
Task Galaxy Visualizer and Impact Tracker Visualizer components, hub …
Browse files Browse the repository at this point in the history
…for idea submission

The tasks are represented in a structured manner where status can be changed and matched with the suitable team based on skills and experience. Impact Tracker Visualizer measures the real-world effects of the efforts. The Idea Submission Hub encourages users to submit new problems, solutions, or tasks.
  • Loading branch information
mikepsinn committed Jul 10, 2024
1 parent a4b68e8 commit ce9bbb5
Show file tree
Hide file tree
Showing 7 changed files with 807 additions and 5 deletions.
15 changes: 10 additions & 5 deletions components/HowItWorksData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { GlobalProblemSolutionsList } from "@/components/global-problem-solution
import { GlobalProblemsList } from "@/components/global-problems-list"
import { PollRandomGlobalProblemSolutions } from "@/components/poll-random-global-problem-solutions"
import { PollRandomGlobalProblems } from "@/components/poll-random-global-problems"
import ActionableTaskStrategyVisualizer from "@/components/landing-page/TaskGalaxyVisualizerWithData";
import TaskAllocationVisualizer from "@/components/landing-page/TaskAllocationVisualizer";
import ResearchEffortCataloger from "@/components/landing-page/ResearchEffortCataloger";
import ImpactTrackerVisualizer from "@/components/landing-page/ImpactTrackerVisualizer";
import IdeaSubmissionHub from "@/components/landing-page/IdeaSubmissionHub";

export interface QAItem {
question: string
Expand Down Expand Up @@ -67,37 +72,37 @@ const HowItWorksData: QAItem[] = [
answer:
"The chosen solutions are broken down into smaller, actionable tasks. " +
"Goal decomposition agents help in this process by identifying necessary steps, potential dependencies, and required skills for each task.",
//visual: <TaskBreakdownDiagram />,
visual: <ActionableTaskStrategyVisualizer />,
},
{
question: "Who carries out these tasks?",
answer:
"Tasks can be completed by anyone with the right skills – this includes " +
"both humans and AI. We use AI to match tasks with the most suitable " +
"people or teams based on their skills, experience, and interests.",
//visual: <AIAgentDiagram />,
visual: <TaskAllocationVisualizer />,
},
{
question: "How does it avoid duplicating work that's already being done?",
answer:
"AI research agents to continuously scan and catalog existing efforts " +
"related to each problem and solution. This helps us identify " +
"opportunities for collaboration and avoid reinventing the wheel.",
//visual: <AIAgentDiagram />,
visual: <ResearchEffortCataloger />,
},
{
question: "How does it track progress and measure impact?",
answer:
"AI research agents also analyze data from various sources, tracking key metrics related " +
"to each problem and solution. This allows us to measure the " +
"real-world impact of our efforts and adjust strategies as needed.",
//visual: <ExampleChart />,
visual: <ImpactTrackerVisualizer />,
},
{
question: "What if someone has a new idea or solution?",
answer:
"New ideas are always welcome! Anyone can submit new problems, solutions, or tasks. ",
//visual: <ExampleDiagram />,
visual: <IdeaSubmissionHub />,
},
]

Expand Down
114 changes: 114 additions & 0 deletions components/landing-page/IdeaSubmissionHub.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
"use client"
import React, { useState } from 'react';
import { Lightbulb, AlertCircle, Cog, List, Send } from 'lucide-react';

type IdeaType = 'problem' | 'solution' | 'task' | 'other';

interface Idea {
type: IdeaType;
title: string;
description: string;
}

const IdeaSubmissionHub: React.FC = () => {
const [ideaType, setIdeaType] = useState<IdeaType>('problem');
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const [submitted, setSubmitted] = useState(false);
const [recentIdeas, setRecentIdeas] = useState<Idea[]>([]);

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
const newIdea: Idea = { type: ideaType, title, description };
setRecentIdeas(prev => [newIdea, ...prev.slice(0, 2)]);
setSubmitted(true);
setTimeout(() => {
setSubmitted(false);
setTitle('');
setDescription('');
}, 3000);
};

const getIcon = (type: IdeaType) => {
switch (type) {
case 'problem': return <AlertCircle size={20} />;
case 'solution': return <Lightbulb size={20} />;
case 'task': return <Cog size={20} />;
default: return <List size={20} />;
}
};

return (
<div className="p-4 rounded-lg shadow-md max-w-4xl mx-auto my-8">
<h2 className="text-2xl font-bold mb-4">Idea Submission Hub</h2>
<div className="mb-4 p-2 border rounded">
<h3 className="font-bold flex items-center"><Lightbulb size={16} className="mr-2" /> New Ideas Welcome!</h3>
<p className="text-sm">We encourage everyone to submit new problems, solutions, or tasks. Your ideas can make a difference!</p>
</div>
<form onSubmit={handleSubmit} className="mb-6">
<div className="mb-4">
<label className="block mb-2 text-sm font-bold">Idea Type</label>
<div className="flex space-x-2">
{(['problem', 'solution', 'task', 'other'] as IdeaType[]).map(type => (
<button
key={type}
type="button"
onClick={() => setIdeaType(type)}
className={`px-3 py-2 rounded border ${ideaType === type ? 'border-2' : 'border'}`}
>
{type.charAt(0).toUpperCase() + type.slice(1)}
</button>
))}
</div>
</div>
<div className="mb-4">
<label htmlFor="title" className="block mb-2 text-sm font-bold">Title</label>
<input
type="text"
id="title"
value={title}
onChange={(e) => setTitle(e.target.value)}
className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2"
required
/>
</div>
<div className="mb-4">
<label htmlFor="description" className="block mb-2 text-sm font-bold">Description</label>
<textarea
id="description"
value={description}
onChange={(e) => setDescription(e.target.value)}
className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2"
rows={4}
required
/>
</div>
<button
type="submit"
className="px-4 py-2 font-bold rounded-full border hover:border-2 focus:outline-none focus:ring-2"
>
Submit Idea
</button>
</form>
{submitted && (
<div className="mb-4 p-2 border rounded">
<p className="text-sm font-bold">Thank you for your submission! Our team will review your idea shortly.</p>
</div>
)}
<div>
<h3 className="font-bold mb-2">Recent Submissions</h3>
{recentIdeas.map((idea, index) => (
<div key={index} className="mb-2 p-2 border rounded">
<div className="flex items-center">
{getIcon(idea.type)}
<span className="ml-2 font-bold">{idea.title}</span>
</div>
<p className="text-sm mt-1">{idea.description}</p>
</div>
))}
</div>
</div>
);
};

export default IdeaSubmissionHub;
151 changes: 151 additions & 0 deletions components/landing-page/ImpactTrackerVisualizer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
"use client"
import React, { useState, useEffect } from 'react';
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
import { TrendingUp, TrendingDown, RefreshCw, AlertTriangle } from 'lucide-react';

interface Metric {
name: string;
value: number;
trend: 'up' | 'down' | 'stable';
impact: 'positive' | 'negative' | 'neutral';
}

interface DataSource {
name: string;
reliability: number;
}

const ImpactTrackerVisualizer: React.FC = () => {
const [metrics, setMetrics] = useState<Metric[]>([]);
const [dataSources, setDataSources] = useState<DataSource[]>([]);
const [selectedMetric, setSelectedMetric] = useState<string | null>(null);
const [historicalData, setHistoricalData] = useState<any[]>([]);

useEffect(() => {
// Simulated initial data
const initialMetrics: Metric[] = [
{ name: 'Drug candidates identified', value: 150, trend: 'up', impact: 'positive' },
{ name: 'Clinical trials initiated', value: 12, trend: 'up', impact: 'positive' },
{ name: 'Average drug development time (months)', value: 60, trend: 'down', impact: 'positive' },
{ name: 'Research collaborations', value: 45, trend: 'up', impact: 'positive' },
{ name: 'Publications cited', value: 230, trend: 'up', impact: 'positive' },
];
setMetrics(initialMetrics);

const initialDataSources: DataSource[] = [
{ name: 'Clinical trial databases', reliability: 0.95 },
{ name: 'Scientific journals', reliability: 0.9 },
{ name: 'Patent offices', reliability: 0.85 },
{ name: 'Research institutions', reliability: 0.8 },
{ name: 'Industry reports', reliability: 0.75 },
];
setDataSources(initialDataSources);
}, []);

const generateHistoricalData = (metricName: string) => {
const data = [];
let value = Math.floor(Math.random() * 100);
for (let i = 12; i > 0; i--) {
value += Math.floor(Math.random() * 20) - 10;
data.push({
month: i,
[metricName]: Math.max(0, value),
});
}
setHistoricalData(data.reverse());
};

const handleMetricClick = (metricName: string) => {
setSelectedMetric(metricName);
generateHistoricalData(metricName);
};

const getTrendIcon = (trend: string) => {
switch (trend) {
case 'up':
return <TrendingUp size={16} className="text-green-500" />;
case 'down':
return <TrendingDown size={16} className="text-red-500" />;
default:
return <RefreshCw size={16} className="text-yellow-500" />;
}
};

const getImpactColor = (impact: string) => {
switch (impact) {
case 'positive':
return 'text-green-500';
case 'negative':
return 'text-red-500';
default:
return 'text-yellow-500';
}
};

return (
<div className="p-4 bg-white dark:bg-gray-800 rounded-lg shadow-md max-w-4xl mx-auto my-8">
<h2 className="text-2xl font-bold mb-4 text-gray-800 dark:text-gray-200">AI Impact Tracker</h2>
<div className="mb-4 p-2 bg-blue-100 dark:bg-blue-900 rounded">
<h3 className="font-bold flex items-center"><AlertTriangle size={16} className="mr-2" /> Real-time Impact Analysis</h3>
<p className="text-sm">Our AI agents continuously analyze data from various sources to track key metrics and measure the real-world impact of our efforts.</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<h3 className="font-bold mb-2">Key Metrics</h3>
{metrics.map(metric => (
<div
key={metric.name}
className="p-2 mb-2 bg-gray-100 dark:bg-gray-700 rounded cursor-pointer hover:bg-gray-200 dark:hover:bg-gray-600"
onClick={() => handleMetricClick(metric.name)}
>
<div className="flex justify-between items-center">
<span>{metric.name}</span>
<span className="font-bold">{metric.value}</span>
</div>
<div className="flex justify-between items-center mt-1">
<span className="flex items-center">
{getTrendIcon(metric.trend)}
<span className="ml-1 text-sm">{metric.trend}</span>
</span>
<span className={`text-sm ${getImpactColor(metric.impact)}`}>
Impact: {metric.impact}
</span>
</div>
</div>
))}
</div>
<div>
<h3 className="font-bold mb-2">Data Sources</h3>
{dataSources.map(source => (
<div key={source.name} className="p-2 mb-2 bg-gray-100 dark:bg-gray-700 rounded">
<div className="flex justify-between items-center">
<span>{source.name}</span>
<span className="text-sm">Reliability: {(source.reliability * 100).toFixed(0)}%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-600 mt-1">
<div className="bg-blue-600 h-2.5 rounded-full" style={{ width: `${source.reliability * 100}%` }}></div>
</div>
</div>
))}
</div>
</div>
{selectedMetric && (
<div>
<h3 className="font-bold mb-2">Historical Data: {selectedMetric}</h3>
<ResponsiveContainer width="100%" height={300}>
<BarChart data={historicalData}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey={selectedMetric} fill="#8884d8" />
</BarChart>
</ResponsiveContainer>
</div>
)}
</div>
);
};

export default ImpactTrackerVisualizer;
Loading

0 comments on commit ce9bbb5

Please sign in to comment.