StepProgress.tsx 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import React from 'react';
  2. import { useNavigate } from 'react-router-dom';
  3. import { useTranslation } from 'react-i18next';
  4. import { Check } from 'lucide-react';
  5. interface StepProgressProps {
  6. currentStep: 1 | 2 | 3;
  7. theme?: 'light' | 'dark';
  8. }
  9. const StepProgress: React.FC<StepProgressProps> = ({ currentStep, theme = 'dark' }) => {
  10. const { t } = useTranslation();
  11. const navigate = useNavigate();
  12. const steps = [
  13. { id: 1, path: '/step1', label: t('nav.consulting', 'AI Consulting') },
  14. { id: 2, path: '/step2', label: t('nav.tourism', 'Tourism Ops') },
  15. { id: 3, path: '/step3', label: t('nav.dev', 'Infrastructure') },
  16. ];
  17. const isDark = theme === 'dark';
  18. const textColor = isDark ? 'text-stone-400' : 'text-stone-500';
  19. const activeColor = isDark ? 'text-white' : 'text-black';
  20. const accentColor = currentStep === 1 ? 'text-blue-500' : currentStep === 2 ? 'text-orange-500' : 'text-cyan-400';
  21. const borderColor = isDark ? 'border-stone-800' : 'border-stone-200';
  22. return (
  23. <div className={`w-full py-4 mb-8 border-b ${borderColor} transition-colors duration-300`}>
  24. <div className="max-w-4xl mx-auto px-4">
  25. <div className="relative flex items-center justify-between">
  26. {/* Progress Bar Background */}
  27. <div className={`absolute left-0 top-1/2 -translate-y-1/2 w-full h-0.5 ${isDark ? 'bg-stone-800' : 'bg-stone-200'} -z-10`}></div>
  28. {/* Active Progress Line */}
  29. <div
  30. className={`absolute left-0 top-1/2 -translate-y-1/2 h-0.5 transition-all duration-500 ease-out -z-10 bg-gradient-to-r from-blue-500 via-orange-500 to-cyan-500`}
  31. style={{ width: `${((currentStep - 1) / 2) * 100}%` }}
  32. ></div>
  33. {steps.map((step) => {
  34. const isCompleted = currentStep > step.id;
  35. const isCurrent = currentStep === step.id;
  36. return (
  37. <div
  38. key={step.id}
  39. onClick={() => navigate(step.path)}
  40. className="flex flex-col items-center cursor-pointer group"
  41. >
  42. <div
  43. className={`
  44. w-8 h-8 rounded-full flex items-center justify-center border-2 transition-all duration-300 bg-white dark:bg-stone-900
  45. ${isCompleted || isCurrent ? 'scale-110' : 'scale-100'}
  46. ${isCurrent ? `${accentColor} border-current` : ''}
  47. ${isCompleted ? 'border-stone-400 text-stone-400 hover:border-stone-500' : ''}
  48. ${!isCurrent && !isCompleted ? `border-stone-200 dark:border-stone-700 text-stone-300` : ''}
  49. `}
  50. >
  51. {isCompleted ? (
  52. <Check className="w-4 h-4" />
  53. ) : (
  54. <span className="text-xs font-bold font-mono">{step.id}</span>
  55. )}
  56. </div>
  57. <span
  58. className={`
  59. mt-3 text-xs font-bold tracking-wider uppercase transition-colors
  60. ${isCurrent ? activeColor : textColor}
  61. group-hover:${activeColor}
  62. `}
  63. >
  64. {step.label}
  65. </span>
  66. </div>
  67. );
  68. })}
  69. </div>
  70. </div>
  71. </div>
  72. );
  73. };
  74. export default StepProgress;