Skip to content
one08498-beep edited this page Aug 25, 2025 · 74 revisions

import React, { useState } from 'react'; import { Clock, DollarSign, Users, Code, Database, Smartphone, Monitor, Globe } from 'lucide-react';

const StockAppEstimate = () => { const [selectedPlatform, setSelectedPlatform] = useState('web'); const [selectedDataSource, setSelectedDataSource] = useState('free');

const platforms = { web: { name: 'Web App', icon: Globe, multiplier: 1 }, mobile: { name: 'Mobile App', icon: Smartphone, multiplier: 1.3 }, desktop: { name: 'Desktop App', icon: Monitor, multiplier: 1.2 } };

const dataSources = { free: { name: 'Free API (Terbatas)', cost: 0, multiplier: 1 }, basic: { name: 'Basic Financial API', cost: 500000, multiplier: 1.1 }, premium: { name: 'Premium Real-time IDX', cost: 2000000, multiplier: 1.3 } };

const baseFeatures = [ { name: 'Watchlist Management', hours: 16, description: 'CRUD watchlist saham' }, { name: 'Portfolio Dashboard', hours: 24, description: 'Tracking posisi & P&L' }, { name: 'Real-time Monitor', hours: 20, description: 'Live price & volume tracking' }, { name: 'Data Integration', hours: 12, description: 'API integration untuk data saham' }, { name: 'Auto Refresh System', hours: 8, description: 'Background sync setiap 5 menit' }, { name: 'Basic Authentication', hours: 12, description: 'User login & session management' }, { name: 'Responsive UI/UX', hours: 20, description: 'Modern interface design' }, { name: 'Testing & Debugging', hours: 16, description: 'Unit tests & bug fixes' } ];

const platformMultiplier = platforms[selectedPlatform].multiplier; const dataMultiplier = dataSources[selectedDataSource].multiplier;

const totalHours = Math.ceil(baseFeatures.reduce((sum, f) => sum + f.hours, 0) * platformMultiplier * dataMultiplier); const hourlyRate = 150000; // IDR per hour const developmentCost = totalHours * hourlyRate; const dataCost = dataSources[selectedDataSource].cost * 12; // Annual const totalCost = developmentCost + dataCost; const timelineWeeks = Math.ceil(totalHours / 40);

return (

Estimasi Proyek Stock Watchlist App

Berdasarkan fitur dari Google Apps Script yang Anda berikan

  {/* Platform Selection */}
  <div className="mb-6 p-4 bg-blue-50 rounded-lg">
    <h3 className="text-lg font-semibold mb-3 text-blue-800">Pilih Platform Target</h3>
    <div className="grid grid-cols-3 gap-3">
      {Object.entries(platforms).map(([key, platform]) => {
        const IconComponent = platform.icon;
        return (
          <button
            key={key}
            onClick={() => setSelectedPlatform(key)}
            className={`p-3 rounded-lg border-2 transition-all ${
              selectedPlatform === key 
                ? 'border-blue-500 bg-blue-100' 
                : 'border-gray-300 hover:border-blue-300'
            }`}
          >
            <IconComponent className="w-6 h-6 mx-auto mb-2" />
            <div className="font-medium">{platform.name}</div>
          </button>
        );
      })}
    </div>
  </div>
  
  {/* Data Source Selection */}
  <div className="mb-6 p-4 bg-green-50 rounded-lg">
    <h3 className="text-lg font-semibold mb-3 text-green-800">Pilih Sumber Data Saham</h3>
    <div className="space-y-2">
      {Object.entries(dataSources).map(([key, source]) => (
        <button
          key={key}
          onClick={() => setSelectedDataSource(key)}
          className={`w-full p-3 text-left rounded-lg border-2 transition-all ${
            selectedDataSource === key 
              ? 'border-green-500 bg-green-100' 
              : 'border-gray-300 hover:border-green-300'
          }`}
        >
          <div className="font-medium">{source.name}</div>
          <div className="text-sm text-gray-600">
            Biaya: {source.cost === 0 ? 'Gratis' : `Rp ${source.cost.toLocaleString()}/bulan`}
          </div>
        </button>
      ))}
    </div>
  </div>
  
  {/* Summary Cards */}
  <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8">
    <div className="bg-purple-100 p-4 rounded-lg text-center">
      <Clock className="w-8 h-8 mx-auto mb-2 text-purple-600" />
      <div className="text-2xl font-bold text-purple-800">{totalHours}h</div>
      <div className="text-sm text-purple-600">Total Development</div>
    </div>
    <div className="bg-blue-100 p-4 rounded-lg text-center">
      <Code className="w-8 h-8 mx-auto mb-2 text-blue-600" />
      <div className="text-2xl font-bold text-blue-800">{timelineWeeks} minggu</div>
      <div className="text-sm text-blue-600">Timeline</div>
    </div>
    <div className="bg-green-100 p-4 rounded-lg text-center">
      <DollarSign className="w-8 h-8 mx-auto mb-2 text-green-600" />
      <div className="text-2xl font-bold text-green-800">
        Rp {(developmentCost/1000000).toFixed(0)}jt
      </div>
      <div className="text-sm text-green-600">Development Cost</div>
    </div>
    <div className="bg-orange-100 p-4 rounded-lg text-center">
      <Database className="w-8 h-8 mx-auto mb-2 text-orange-600" />
      <div className="text-2xl font-bold text-orange-800">
        Rp {(dataCost/1000000).toFixed(0)}jt
      </div>
      <div className="text-sm text-orange-600">Data Cost (1 tahun)</div>
    </div>
  </div>
  
  {/* Feature Breakdown */}
  <div className="mb-8">
    <h3 className="text-xl font-semibold mb-4">Breakdown Fitur & Estimasi</h3>
    <div className="bg-gray-50 rounded-lg overflow-hidden">
      <div className="grid grid-cols-3 gap-4 p-4 bg-gray-200 font-semibold">
        <div>Fitur</div>
        <div className="text-center">Estimasi Jam</div>
        <div>Deskripsi</div>
      </div>
      {baseFeatures.map((feature, idx) => (
        <div key={idx} className="grid grid-cols-3 gap-4 p-4 border-b border-gray-200">
          <div className="font-medium">{feature.name}</div>
          <div className="text-center">
            {Math.ceil(feature.hours * platformMultiplier * dataMultiplier)}h
          </div>
          <div className="text-sm text-gray-600">{feature.description}</div>
        </div>
      ))}
    </div>
  </div>
  
  {/* Timeline */}
  <div className="mb-8">
    <h3 className="text-xl font-semibold mb-4">Timeline Pengembangan</h3>
    <div className="space-y-3">
      <div className="flex items-center p-3 bg-blue-50 rounded-lg">
        <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white font-bold text-sm mr-4">1</div>
        <div>
          <div className="font-medium">Setup & Planning (1 minggu)</div>
          <div className="text-sm text-gray-600">Architecture, database design, API setup</div>
        </div>
      </div>
      <div className="flex items-center p-3 bg-green-50 rounded-lg">
        <div className="w-8 h-8 bg-green-500 rounded-full flex items-center justify-center text-white font-bold text-sm mr-4">2</div>
        <div>
          <div className="font-medium">Core Development ({Math.ceil(timelineWeeks * 0.6)} minggu)</div>
          <div className="text-sm text-gray-600">Watchlist, dashboard, data integration</div>
        </div>
      </div>
      <div className="flex items-center p-3 bg-yellow-50 rounded-lg">
        <div className="w-8 h-8 bg-yellow-500 rounded-full flex items-center justify-center text-white font-bold text-sm mr-4">3</div>
        <div>
          <div className="font-medium">Testing & Polish ({Math.ceil(timelineWeeks * 0.3)} minggu)</div>
          <div className="text-sm text-gray-600">Bug fixes, performance optimization, UI polish</div>
        </div>
      </div>
    </div>
  </div>
  
  {/* Total Cost */}
  <div className="bg-gradient-to-r from-blue-500 to-purple-600 text-white p-6 rounded-lg">
    <h3 className="text-2xl font-bold mb-2">Total Estimasi Proyek</h3>
    <div className="grid grid-cols-2 gap-4">
      <div>
        <div className="text-blue-100">Development Cost</div>
        <div className="text-2xl font-bold">Rp {(developmentCost/1000000).toFixed(1)}jt</div>
      </div>
      <div>
        <div className="text-blue-100">Operational Cost (1 tahun)</div>
        <div className="text-2xl font-bold">Rp {(dataCost/1000000).toFixed(1)}jt</div>
      </div>
    </div>
    <div className="mt-4 pt-4 border-t border-blue-400">
      <div className="text-blue-100">Grand Total</div>
      <div className="text-3xl font-bold">Rp {(totalCost/1000000).toFixed(1)} juta</div>
    </div>
  </div>
  
  {/* Notes */}
  <div className="mt-6 p-4 bg-yellow-50 rounded-lg">
    <h4 className="font-semibold text-yellow-800 mb-2">Catatan Penting:</h4>
    <ul className="text-sm text-yellow-700 space-y-1">
      <li>• Estimasi berdasarkan developer rate Rp 150k/jam</li>
      <li>• Data real-time IDX memerlukan API berbayar untuk akurasi tinggi</li>
      <li>• Timeline bisa berubah tergantung kompleksitas requirement tambahan</li>
      <li>• Maintenance & support belum termasuk dalam estimasi</li>
    </ul>
  </div>
</div>

); };

export default StockAppEstimate;

Clone this wiki locally