← back to Calc 67

components/TipCalculator.tsx

174 lines

'use client'

import { useState } from 'react'

export default function TipCalculator() {
  const [billAmount, setBillAmount] = useState('')
  const [tipPercent, setTipPercent] = useState('15')
  const [numPeople, setNumPeople] = useState('1')
  const [result, setResult] = useState<{ total: string; perPerson: string; tip: string } | null>(null)
  const [celebrating, setCelebrating] = useState(false)

  const calculateTip = () => {
    setCelebrating(true)
    setTimeout(() => {
      setResult({
        total: '67',
        perPerson: '67',
        tip: '67',
      })
      setTimeout(() => setCelebrating(false), 2000)
    }, 800)
  }

  const reset = () => {
    setBillAmount('')
    setTipPercent('15')
    setNumPeople('1')
    setResult(null)
    setCelebrating(false)
  }

  const quickTipButtons = ['10', '15', '18', '20', '25']

  return (
    <div className="bg-white rounded-xl shadow-2xl p-3 sm:p-4 max-w-2xl mx-auto">
      <h2 className="text-2xl sm:text-3xl md:text-4xl font-bold text-gray-800 mb-3 text-center">
        💵 Tip
      </h2>

      <div className="space-y-2 sm:space-y-3 mb-3">
        {/* Bill Amount & People Split */}
        <div className="grid grid-cols-2 gap-2 sm:gap-3">
          <div>
            <label className="block text-sm sm:text-base font-bold text-gray-700 mb-1">
              Bill ($)
            </label>
            <input
              type="number"
              value={billAmount}
              onChange={(e) => setBillAmount(e.target.value)}
              placeholder="100"
              className="w-full p-2 sm:p-3 border-3 border-gray-300 rounded-lg focus:border-purple-500 focus:outline-none text-lg sm:text-xl font-bold"
            />
          </div>
          <div>
            <label className="block text-sm sm:text-base font-bold text-gray-700 mb-1">
              People
            </label>
            <input
              type="number"
              min="1"
              value={numPeople}
              onChange={(e) => setNumPeople(e.target.value)}
              placeholder="1"
              className="w-full p-2 sm:p-3 border-3 border-gray-300 rounded-lg focus:border-purple-500 focus:outline-none text-lg sm:text-xl font-bold"
            />
          </div>
        </div>

        {/* Tip Percentage */}
        <div>
          <label className="block text-sm sm:text-base font-bold text-gray-700 mb-1">
            Tip: {tipPercent}%
          </label>
          <div className="flex gap-2 mb-2 flex-wrap justify-center">
            {quickTipButtons.map((percent) => (
              <button
                key={percent}
                onClick={(e) => {
                  e.preventDefault();
                  setTipPercent(percent);
                }}
                onTouchEnd={(e) => {
                  e.preventDefault();
                  setTipPercent(percent);
                }}
                className={`px-3 sm:px-4 py-2 rounded-lg font-bold text-base sm:text-lg shadow-lg select-none cursor-pointer ${
                  tipPercent === percent
                    ? 'bg-purple-500 text-white scale-105'
                    : 'bg-gray-200'
                }`}
                style={{ WebkitTapHighlightColor: 'transparent' }}
              >
                {percent}%
              </button>
            ))}
          </div>
          <input
            type="range"
            min="0"
            max="50"
            value={tipPercent}
            onChange={(e) => setTipPercent(e.target.value)}
            className="w-full h-3 accent-purple-500"
          />
        </div>
      </div>

      {result && (
        <div className="mb-3 p-3 bg-gradient-to-r from-green-50 to-emerald-50 rounded-lg border-3 border-green-200">
          <div className="grid grid-cols-3 gap-2">
            <div className="text-center">
              <p className="text-xs sm:text-sm text-gray-600 font-bold">Tip</p>
              <p className="text-xl sm:text-2xl font-bold text-green-600">
                ${result.tip}
              </p>
            </div>
            <div className="text-center">
              <p className="text-xs sm:text-sm text-gray-600 font-bold">Total</p>
              <p className="text-xl sm:text-2xl font-bold text-blue-600">
                ${result.total}
              </p>
            </div>
            <div className="text-center">
              <p className="text-xs sm:text-sm text-gray-600 font-bold">Each</p>
              <p className="text-xl sm:text-2xl font-bold text-purple-600">
                ${result.perPerson}
              </p>
            </div>
          </div>
          <p className="text-center text-sm sm:text-base text-gray-600 mt-2 font-semibold">
            ✨ Perfect! ✨
          </p>
        </div>
      )}

      <div className="flex gap-2 sm:gap-3 mb-2">
        <button
          onClick={(e) => {
            e.preventDefault();
            calculateTip();
          }}
          onTouchEnd={(e) => {
            e.preventDefault();
            calculateTip();
          }}
          className="flex-1 bg-gradient-to-r from-purple-500 to-pink-500 text-white py-3 sm:py-4 rounded-lg font-bold text-lg sm:text-xl shadow-lg select-none cursor-pointer"
          style={{ WebkitTapHighlightColor: 'transparent' }}
        >
          Calculate
        </button>
        <button
          onClick={(e) => {
            e.preventDefault();
            reset();
          }}
          onTouchEnd={(e) => {
            e.preventDefault();
            reset();
          }}
          className="flex-1 bg-gray-200 py-3 sm:py-4 rounded-lg font-bold text-lg sm:text-xl select-none cursor-pointer shadow-lg"
          style={{ WebkitTapHighlightColor: 'transparent' }}
        >
          Reset
        </button>
      </div>

      <div className="text-center text-xs sm:text-sm text-gray-600 font-semibold">
        <p>Easy Tip Calculator</p>
      </div>
    </div>
  )
}