Files
trading_bot_v4/app/roadmap/page.tsx
mindesbunister ff42115035 feat: Add roadmap navigation to homepage with back button
Changes:
- Homepage: Added roadmap card with indigo/violet gradient
- Changed grid from 3 to 4 columns (responsive: 2 on mobile, 4 on desktop)
- Roadmap page: Added back button to header for easy navigation
- Visual consistency: Matches existing card design patterns

Navigation Flow:
- Homepage → Roadmap card → /roadmap page
- Roadmap page → Back button → Homepage

Files Modified:
- app/page.tsx (navigation grid + roadmap card)
- app/roadmap/page.tsx (back button in header)
2025-11-24 13:08:31 +01:00

193 lines
7.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import { useEffect, useState } from 'react'
interface RoadmapItem {
phase: string
title: string
status: 'complete' | 'in-progress' | 'planned'
description: string
impact: string
completed?: string
items?: string[]
}
export default function RoadmapPage() {
const [roadmap, setRoadmap] = useState<RoadmapItem[]>([])
const [loading, setLoading] = useState(true)
useEffect(() => {
fetchRoadmap()
}, [])
const fetchRoadmap = async () => {
try {
const response = await fetch('/api/roadmap')
const data = await response.json()
setRoadmap(data.roadmap || [])
} catch (error) {
console.error('Failed to fetch roadmap:', error)
} finally {
setLoading(false)
}
}
const getStatusColor = (status: string) => {
switch (status) {
case 'complete':
return 'bg-green-500/20 text-green-400 border-green-500/30'
case 'in-progress':
return 'bg-blue-500/20 text-blue-400 border-blue-500/30'
case 'planned':
return 'bg-gray-500/20 text-gray-400 border-gray-500/30'
default:
return 'bg-gray-500/20 text-gray-400 border-gray-500/30'
}
}
const getStatusIcon = (status: string) => {
switch (status) {
case 'complete':
return '✅'
case 'in-progress':
return '🔄'
case 'planned':
return '📋'
default:
return '❓'
}
}
const stats = {
total: roadmap.length,
complete: roadmap.filter(item => item.status === 'complete').length,
inProgress: roadmap.filter(item => item.status === 'in-progress').length,
planned: roadmap.filter(item => item.status === 'planned').length,
}
const completionRate = stats.total > 0 ? Math.round((stats.complete / stats.total) * 100) : 0
if (loading) {
return (
<div className="min-h-screen bg-gradient-to-br from-gray-900 via-gray-800 to-gray-900 p-8">
<div className="max-w-6xl mx-auto">
<div className="text-center text-gray-400">Loading roadmap...</div>
</div>
</div>
)
}
return (
<div className="min-h-screen bg-gradient-to-br from-gray-900 via-gray-800 to-gray-900 p-8">
<div className="max-w-6xl mx-auto space-y-8">
{/* Header */}
<div className="bg-gray-800/50 backdrop-blur-sm border border-gray-700 rounded-xl p-6">
<div className="flex items-center justify-between mb-4">
<h1 className="text-3xl font-bold text-white">🗺 Trading Bot Roadmap</h1>
<a
href="/"
className="px-4 py-2 bg-gray-700 hover:bg-gray-600 text-white rounded-lg transition-colors flex items-center gap-2"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Back to Home
</a>
</div>
<p className="text-gray-400">Track development progress and upcoming features</p>
</div>
{/* Stats Overview */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div className="bg-gray-800/50 backdrop-blur-sm border border-gray-700 rounded-xl p-6">
<div className="text-gray-400 text-sm mb-1">Total Items</div>
<div className="text-3xl font-bold text-white">{stats.total}</div>
</div>
<div className="bg-green-500/10 backdrop-blur-sm border border-green-500/30 rounded-xl p-6">
<div className="text-green-400 text-sm mb-1"> Completed</div>
<div className="text-3xl font-bold text-green-400">{stats.complete}</div>
</div>
<div className="bg-blue-500/10 backdrop-blur-sm border border-blue-500/30 rounded-xl p-6">
<div className="text-blue-400 text-sm mb-1">🔄 In Progress</div>
<div className="text-3xl font-bold text-blue-400">{stats.inProgress}</div>
</div>
<div className="bg-gray-500/10 backdrop-blur-sm border border-gray-500/30 rounded-xl p-6">
<div className="text-gray-400 text-sm mb-1">📋 Planned</div>
<div className="text-3xl font-bold text-gray-400">{stats.planned}</div>
</div>
</div>
{/* Progress Bar */}
<div className="bg-gray-800/50 backdrop-blur-sm border border-gray-700 rounded-xl p-6">
<div className="flex items-center justify-between mb-2">
<div className="text-white font-semibold">Overall Completion</div>
<div className="text-green-400 font-bold">{completionRate}%</div>
</div>
<div className="w-full bg-gray-700 rounded-full h-4 overflow-hidden">
<div
className="bg-gradient-to-r from-green-500 to-emerald-500 h-full transition-all duration-500 rounded-full"
style={{ width: `${completionRate}%` }}
/>
</div>
</div>
{/* Roadmap Items */}
<div className="space-y-4">
{roadmap.map((item, index) => (
<div
key={index}
className={`bg-gray-800/50 backdrop-blur-sm border rounded-xl p-6 ${getStatusColor(item.status)}`}
>
<div className="flex items-start justify-between mb-4">
<div className="flex-1">
<div className="flex items-center gap-3 mb-2">
<span className="text-2xl">{getStatusIcon(item.status)}</span>
<h3 className="text-xl font-bold text-white">{item.title}</h3>
<span className="px-3 py-1 rounded-full text-xs font-semibold bg-gray-700/50 text-gray-300">
{item.phase}
</span>
</div>
<p className="text-gray-300 mb-3">{item.description}</p>
<div className="bg-gray-900/50 rounded-lg p-3 mb-3">
<div className="text-xs text-gray-400 mb-1">Expected Impact</div>
<div className="text-sm text-white font-semibold">{item.impact}</div>
</div>
{item.completed && (
<div className="text-xs text-green-400">
Completed: {item.completed}
</div>
)}
</div>
</div>
{item.items && item.items.length > 0 && (
<div className="border-t border-gray-700 pt-4 mt-4">
<div className="text-sm text-gray-400 mb-2">Implementation Details:</div>
<ul className="space-y-1">
{item.items.map((subItem, subIndex) => (
<li key={subIndex} className="text-sm text-gray-300 flex items-start gap-2">
<span className="text-gray-500 mt-1"></span>
<span>{subItem}</span>
</li>
))}
</ul>
</div>
)}
</div>
))}
</div>
{/* Footer */}
<div className="bg-gray-800/50 backdrop-blur-sm border border-gray-700 rounded-xl p-6 text-center">
<p className="text-gray-400 text-sm">
Last updated: {new Date().toLocaleDateString()} Trading Bot v4
</p>
</div>
</div>
</div>
)
}