File size: 7,010 Bytes
be02369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

import React, { useState, useMemo } from 'react';
import { BeakerIcon } from '../components/icons';

type WaterUnit = 'L' | 'gal';
type ConcentrateUnit = 'ml' | 'tsp' | 'tbsp';
type Strength = 'full' | 'half' | 'quarter';

const STRENGTH_MULTIPLIERS: Record<Strength, number> = {
    full: 1,
    half: 0.5,
    quarter: 0.25,
};

const CONVERSION_TO_ML = {
    ml: 1,
    tsp: 4.92892,
    tbsp: 14.7868,
};

const CONVERSION_TO_LITER = {
    L: 1,
    gal: 3.78541,
};

const FertilizerMixerView: React.FC = () => {
    const [waterAmount, setWaterAmount] = useState(1);
    const [waterUnit, setWaterUnit] = useState<WaterUnit>('gal');
    const [concentrateAmount, setConcentrateAmount] = useState(1);
    const [concentrateUnit, setConcentrateUnit] = useState<ConcentrateUnit>('tsp');
    const [strength, setStrength] = useState<Strength>('half');
    const [baseWaterAmount, setBaseWaterAmount] = useState(1);
    const [baseWaterUnit, setBaseWaterUnit] = useState<WaterUnit>('gal');

    const result = useMemo(() => {
        try {
            const desiredWaterL = waterAmount * CONVERSION_TO_LITER[waterUnit];
            const baseWaterL = baseWaterAmount * CONVERSION_TO_LITER[baseWaterUnit];
            const baseConcentrateMl = concentrateAmount * CONVERSION_TO_ML[concentrateUnit];
            
            if (baseWaterL === 0) return { amount: 0, unit: 'ml' };

            const ratio = baseConcentrateMl / baseWaterL; // ml of concentrate per L of water
            const strengthMultiplier = STRENGTH_MULTIPLIERS[strength];
            
            const neededMl = desiredWaterL * ratio * strengthMultiplier;

            // Return result in a user-friendly unit
            if (neededMl < 15 && concentrateUnit !== 'ml') return { amount: neededMl / CONVERSION_TO_ML.tsp, unit: 'tsp' };
            if (neededMl < 45 && concentrateUnit !== 'ml') return { amount: neededMl / CONVERSION_TO_ML.tbsp, unit: 'tbsp' };
            return { amount: neededMl, unit: 'ml' };

        } catch (e) {
            return { amount: 0, unit: 'ml' };
        }
    }, [waterAmount, waterUnit, concentrateAmount, concentrateUnit, strength, baseWaterAmount, baseWaterUnit]);

    const renderUnitSelector = (value: string, setter: (val: any) => void, units: string[]) => (
        <div className="flex gap-1 bg-stone-100 p-1 rounded-lg">
            {units.map(unit => (
                <button key={unit} onClick={() => setter(unit)} className={`px-3 py-1 text-sm font-medium rounded-md ${value === unit ? 'bg-white shadow' : ''}`}>
                    {unit}
                </button>
            ))}
        </div>
    );

    return (
        <div className="space-y-8 max-w-2xl mx-auto">
            <header className="text-center">
                <h2 className="text-3xl font-bold tracking-tight text-stone-900 sm:text-4xl flex items-center justify-center gap-3">
                    <BeakerIcon className="w-8 h-8 text-cyan-600" />
                    Fertilizer Mixer
                </h2>
                <p className="mt-4 text-lg leading-8 text-stone-600">
                    Calculate the perfect fertilizer dilution every time. No more over or under-feeding.
                </p>
            </header>

            <div className="grid grid-cols-1 md:grid-cols-2 gap-8 items-start">
                <div className="bg-white p-6 rounded-xl shadow-lg border border-stone-200 space-y-6">
                    <div>
                        <h3 className="font-semibold text-stone-800 mb-2">1. Dosage from Bottle</h3>
                        <p className="text-xs text-stone-500 mb-2">Enter the recommended full-strength dose from the fertilizer label.</p>
                         <div className="flex items-center gap-2">
                             <input type="number" value={concentrateAmount} onChange={e => setConcentrateAmount(Number(e.target.value))} className="w-full p-2 border rounded-md" />
                             {renderUnitSelector(concentrateUnit, setConcentrateUnit, ['ml', 'tsp', 'tbsp'])}
                         </div>
                         <p className="text-center my-1 text-stone-600 font-medium">per</p>
                         <div className="flex items-center gap-2">
                             <input type="number" value={baseWaterAmount} onChange={e => setBaseWaterAmount(Number(e.target.value))} className="w-full p-2 border rounded-md" />
                             {renderUnitSelector(baseWaterUnit, setBaseWaterUnit, ['L', 'gal'])}
                         </div>
                    </div>
                     <div>
                        <h3 className="font-semibold text-stone-800 mb-2">2. Your Watering Can</h3>
                        <p className="text-xs text-stone-500 mb-2">How much water are you preparing?</p>
                        <div className="flex items-center gap-2">
                            <input type="number" value={waterAmount} onChange={e => setWaterAmount(Number(e.target.value))} className="w-full p-2 border rounded-md" />
                            {renderUnitSelector(waterUnit, setWaterUnit, ['L', 'gal'])}
                        </div>
                    </div>
                    <div>
                        <h3 className="font-semibold text-stone-800 mb-2">3. Desired Strength</h3>
                        <div className="flex gap-1 bg-stone-100 p-1 rounded-lg">
                            <button onClick={() => setStrength('full')} className={`flex-1 py-2 text-sm font-medium rounded-md ${strength === 'full' ? 'bg-white shadow' : ''}`}>Full (100%)</button>
                            <button onClick={() => setStrength('half')} className={`flex-1 py-2 text-sm font-medium rounded-md ${strength === 'half' ? 'bg-white shadow' : ''}`}>Half (50%)</button>
                            <button onClick={() => setStrength('quarter')} className={`flex-1 py-2 text-sm font-medium rounded-md ${strength === 'quarter' ? 'bg-white shadow' : ''}`}>Quarter (25%)</button>
                        </div>
                    </div>
                </div>

                <div className="bg-white p-6 rounded-xl shadow-lg border-2 border-cyan-600 space-y-4 text-center">
                    <h3 className="text-xl font-bold text-stone-900">Your Custom Mix</h3>
                    <p className="text-stone-600">Add this much concentrate to your watering can:</p>
                    <div>
                        <p className="text-5xl font-bold text-cyan-700">{result.amount.toFixed(2)}</p>
                        <p className="text-lg text-stone-600">{result.unit}</p>
                    </div>
                    <div className="mt-4 pt-4 border-t-2 border-dashed">
                        <p className="text-sm text-stone-700">
                            This creates a {strength}-strength solution of {waterAmount} {waterUnit} of fertilizer.
                        </p>
                    </div>
                </div>
            </div>
        </div>
    );
};

export default FertilizerMixerView;