diff --git a/server.ts b/server.ts index 52c06d5..6da2e42 100644 --- a/server.ts +++ b/server.ts @@ -7,7 +7,7 @@ app.use(cors()) app.use(express.json()) app.post('/api/execute', (req, res) => { - const { description, validation } = req.body + const { description } = req.body const child = spawn('opencode', ['run', description], { stdio: ['pipe', 'pipe', 'pipe'], diff --git a/src/App.tsx b/src/App.tsx index 8ebf8e4..91e6853 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,15 +4,18 @@ function App() { return (
-
+
-

+

WorkBoard

-

AI-powered task management

+

AI-powered task management

-
-
+
+
+
+ +
AI Agent Ready
diff --git a/src/components/Column.tsx b/src/components/Column.tsx index 4403b9d..6a6cb66 100644 --- a/src/components/Column.tsx +++ b/src/components/Column.tsx @@ -41,38 +41,43 @@ const Column = ({ title, status, items, onUpdate, onDelete, onAdd, color }: Colu const colorStyles = { blue: { - header: 'bg-gradient-to-r from-blue-500 to-cyan-500', - bg: 'bg-gradient-to-br from-blue-500/10 to-cyan-500/5', - border: 'border-blue-500/20', - button: 'bg-gradient-to-r from-blue-600 to-cyan-600 hover:from-blue-700 hover:to-cyan-700', - pulse: 'from-blue-500/20 to-cyan-500/20', + header: 'bg-gradient-to-r from-blue-600 via-blue-500 to-cyan-500', + bg: 'from-blue-500/10 via-cyan-500/5 to-blue-500/10', + border: 'border-blue-500/30', + button: 'bg-gradient-to-r from-blue-600 via-blue-500 to-cyan-500 hover:from-blue-700 hover:via-blue-600 hover:to-cyan-600', + pulse: 'bg-gradient-to-r from-blue-500/20 via-cyan-500/20 to-blue-500/20', + glow: 'shadow-blue-500/30', }, purple: { - header: 'bg-gradient-to-r from-purple-500 to-pink-500', - bg: 'bg-gradient-to-br from-purple-500/10 to-pink-500/5', - border: 'border-purple-500/20', - button: 'bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700', - pulse: 'from-purple-500/20 to-pink-500/20', + header: 'bg-gradient-to-r from-purple-600 via-purple-500 to-pink-500', + bg: 'from-purple-500/10 via-pink-500/5 to-purple-500/10', + border: 'border-purple-500/30', + button: 'bg-gradient-to-r from-purple-600 via-purple-500 to-pink-500 hover:from-purple-700 hover:via-purple-600 hover:to-pink-600', + pulse: 'bg-gradient-to-r from-purple-500/20 via-pink-500/20 to-purple-500/20', + glow: 'shadow-purple-500/30', }, green: { - header: 'bg-gradient-to-r from-emerald-500 to-teal-500', - bg: 'bg-gradient-to-br from-emerald-500/10 to-teal-500/5', - border: 'border-emerald-500/20', - button: 'bg-gradient-to-r from-emerald-600 to-teal-600 hover:from-emerald-700 hover:to-teal-700', - pulse: 'from-emerald-500/20 to-teal-500/20', + header: 'bg-gradient-to-r from-emerald-600 via-emerald-500 to-teal-500', + bg: 'from-emerald-500/10 via-teal-500/5 to-emerald-500/10', + border: 'border-emerald-500/30', + button: 'bg-gradient-to-r from-emerald-600 via-emerald-500 to-teal-500 hover:from-emerald-700 hover:via-emerald-600 hover:to-teal-600', + pulse: 'bg-gradient-to-r from-emerald-500/20 via-teal-500/20 to-emerald-500/20', + glow: 'shadow-emerald-500/30', }, } const styles = colorStyles[color] return ( -
-
+
+
-
-

{title}

+
+ +
+

{title}

- + {items.length}
@@ -86,9 +91,9 @@ const Column = ({ title, status, items, onUpdate, onDelete, onAdd, color }: Colu /> ))} {status === 'active' && items.some(i => i.status === 'active') && ( -
+
-
+

AI agent is working on this task...

@@ -97,16 +102,16 @@ const Column = ({ title, status, items, onUpdate, onDelete, onAdd, color }: Colu {status === 'queued' && ( )} {isModalOpen && ( -
-
-

New Work Item

+
+
+

New Work Item

@@ -131,8 +137,9 @@ const Column = ({ title, status, items, onUpdate, onDelete, onAdd, color }: Colu onChange={(e) => setFormData({ ...formData, description: e.target.value }) } - className="w-full px-4 py-3 bg-slate-950 border border-slate-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" + className="w-full px-4 py-3 bg-slate-950 border border-slate-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all text-white placeholder-slate-600" rows={3} + placeholder="Describe the task in detail" required />
@@ -145,15 +152,16 @@ const Column = ({ title, status, items, onUpdate, onDelete, onAdd, color }: Colu onChange={(e) => setFormData({ ...formData, validation: e.target.value }) } - className="w-full px-4 py-3 bg-slate-950 border border-slate-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" + className="w-full px-4 py-3 bg-slate-950 border border-slate-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all text-white placeholder-slate-600" rows={3} + placeholder="Define validation conditions" required />
diff --git a/src/components/WorkItem.tsx b/src/components/WorkItem.tsx index 6941540..b38ade6 100644 --- a/src/components/WorkItem.tsx +++ b/src/components/WorkItem.tsx @@ -37,23 +37,23 @@ const WorkItemComponent = ({ workItem, onUpdate, onDelete }: Props) => { } return ( -
= 3 ? 'border-red-500/50' : ''}`}> +
= 3 ? 'border-red-500/50' : ''}`}> {!isExpanded ? ( <>
-
+
- -

{workItem.title}

+ +

{workItem.title}

-

{workItem.description}

+

{workItem.description}

{workItem.failedAttempts > 0 && ( -
- +
+ {workItem.failedAttempts}/3 attempts {workItem.errorMessage && ( - + {workItem.errorMessage} )} @@ -63,11 +63,11 @@ const WorkItemComponent = ({ workItem, onUpdate, onDelete }: Props) => {
) : ( - +
@@ -101,7 +101,7 @@ const WorkItemComponent = ({ workItem, onUpdate, onDelete }: Props) => { onChange={(e) => setFormData({ ...formData, description: e.target.value }) } - className="w-full px-4 py-3 bg-slate-950 border border-slate-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all text-white" + className="w-full px-4 py-3 bg-slate-950 border border-slate-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all text-white placeholder-slate-600" rows={3} required /> @@ -115,7 +115,7 @@ const WorkItemComponent = ({ workItem, onUpdate, onDelete }: Props) => { onChange={(e) => setFormData({ ...formData, validation: e.target.value }) } - className="w-full px-4 py-3 bg-slate-950 border border-slate-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all text-white" + className="w-full px-4 py-3 bg-slate-950 border border-slate-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all text-white placeholder-slate-600" rows={3} required /> @@ -138,7 +138,7 @@ const WorkItemComponent = ({ workItem, onUpdate, onDelete }: Props) => {

{workItem.errorMessage && ( -
+

Error: {workItem.errorMessage}

@@ -147,21 +147,21 @@ const WorkItemComponent = ({ workItem, onUpdate, onDelete }: Props) => {
diff --git a/src/index.css b/src/index.css index 961f3c5..a19709c 100644 --- a/src/index.css +++ b/src/index.css @@ -9,31 +9,94 @@ body { sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); + background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%); + background-size: 200% 200%; + animation: gradientShift 15s ease infinite; min-height: 100vh; } +@keyframes gradientShift { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} + code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } .glass-card { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border: 1px solid rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.03); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 16px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.glass-card:hover { + background: rgba(255, 255, 255, 0.05); + transform: translateY(-2px); + box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.3); + border-color: rgba(255, 255, 255, 0.12); } .glass-btn { - transition: all 0.2s ease; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); } .glass-btn:hover { - transform: translateY(-1px); + transform: translateY(-2px); + box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.3); } .glass-btn:active { - transform: scale(0.95); + transform: scale(0.98); +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateX(-20px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes gradientText { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +.animate-fade-in { + animation: fadeIn 0.4s cubic-bezier(0.4, 0, 0.2, 1); +} + +.animate-slide-in { + animation: slideIn 0.4s cubic-bezier(0.4, 0, 0.2, 1); +} + +.animate-gradient-text { + animation: gradientText 3s ease infinite; } \ No newline at end of file