Update components/roi-calculator.tsx
This commit is contained in:
parent
26aa2e8e43
commit
060517f8c4
|
|
@ -0,0 +1,160 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Container } from "@/components/container";
|
||||||
|
import { Heading } from "@/components/heading";
|
||||||
|
import { Subheading } from "@/components/subheading";
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Badge } from "@/components/badge";
|
||||||
|
import { Share2, Save, Calculator, Info, CheckCircle2 } from "lucide-react";
|
||||||
|
|
||||||
|
export function RoiCalculator() {
|
||||||
|
const [investment, setInvestment] = useState<number>(10000);
|
||||||
|
const [revenue, setRevenue] = useState<number>(15000);
|
||||||
|
const [roi, setRoi] = useState<number>(0);
|
||||||
|
const [profit, setProfit] = useState<number>(0);
|
||||||
|
const [saved, setSaved] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const p = revenue - investment;
|
||||||
|
const r = investment > 0 ? (p / investment) * 100 : 0;
|
||||||
|
setProfit(p);
|
||||||
|
setRoi(r);
|
||||||
|
}, [investment, revenue]);
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
setSaved(true);
|
||||||
|
setTimeout(() => setSaved(false), 2000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleShare = () => {
|
||||||
|
if (navigator.share) {
|
||||||
|
navigator.share({
|
||||||
|
title: 'ROI Calculation Result',
|
||||||
|
text: `My ROI is ${roi.toFixed(2)}% with a profit of $${profit.toLocaleString()}`,
|
||||||
|
url: window.location.href,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
alert("Sharing not supported on this browser. Link copied to clipboard!");
|
||||||
|
navigator.clipboard.writeText(window.location.href);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="py-12 md:py-20 bg-neutral-50/50">
|
||||||
|
<Container>
|
||||||
|
<div className="max-w-4xl mx-auto">
|
||||||
|
<div className="text-center mb-12">
|
||||||
|
<Badge className="mb-4">ROI Calculator</Badge>
|
||||||
|
<Heading>Calculate Your Return on Investment</Heading>
|
||||||
|
<Subheading className="mt-4">
|
||||||
|
Enter your investment and expected revenue to see your potential profit and ROI percentage instantly.
|
||||||
|
</Subheading>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
|
{/* Inputs */}
|
||||||
|
<Card className="border-neutral-200 shadow-sm">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="flex items-center gap-2">
|
||||||
|
<Calculator className="w-5 h-5 text-blue-600" />
|
||||||
|
Input Details
|
||||||
|
</CardTitle>
|
||||||
|
<CardDescription>Enter your financial figures below</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-6">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="investment">Total Investment ($)</Label>
|
||||||
|
<Input
|
||||||
|
id="investment"
|
||||||
|
type="number"
|
||||||
|
value={investment}
|
||||||
|
onChange={(e) => setInvestment(Number(e.target.value))}
|
||||||
|
placeholder="e.g. 10000"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="revenue">Total Revenue ($)</Label>
|
||||||
|
<Input
|
||||||
|
id="revenue"
|
||||||
|
type="number"
|
||||||
|
value={revenue}
|
||||||
|
onChange={(e) => setRevenue(Number(e.target.value))}
|
||||||
|
placeholder="e.g. 15000"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-3 pt-4">
|
||||||
|
<Button onClick={handleSave} variant="outline" className="flex-1 gap-2">
|
||||||
|
{saved ? <CheckCircle2 className="w-4 h-4 text-green-500" /> : <Save className="w-4 h-4" />}
|
||||||
|
{saved ? "Saved" : "Save Result"}
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleShare} variant="outline" className="flex-1 gap-2">
|
||||||
|
<Share2 className="w-4 h-4" />
|
||||||
|
Share
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* Results */}
|
||||||
|
<Card className="border-blue-100 bg-blue-50/30 shadow-sm">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="text-blue-900">Calculation Results</CardTitle>
|
||||||
|
<CardDescription>Your financial performance summary</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-8">
|
||||||
|
<div className="text-center p-6 bg-white rounded-xl border border-blue-100 shadow-sm">
|
||||||
|
<p className="text-sm font-medium text-blue-600 uppercase tracking-wider">ROI Percentage</p>
|
||||||
|
<p className={`text-5xl font-bold mt-2 ${roi >= 0 ? 'text-green-600' : 'text-red-600'}`}>
|
||||||
|
{roi.toFixed(2)}%
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div className="p-4 bg-white rounded-lg border border-neutral-100">
|
||||||
|
<p className="text-xs text-neutral-500 uppercase">Net Profit</p>
|
||||||
|
<p className={`text-xl font-bold ${profit >= 0 ? 'text-neutral-900' : 'text-red-600'}`}>
|
||||||
|
${profit.toLocaleString()}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="p-4 bg-white rounded-lg border border-neutral-100">
|
||||||
|
<p className="text-xs text-neutral-500 uppercase">Multiplier</p>
|
||||||
|
<p className="text-xl font-bold text-neutral-900">
|
||||||
|
{(revenue / (investment || 1)).toFixed(2)}x
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Explanation */}
|
||||||
|
<div className="mt-12">
|
||||||
|
<Card className="border-neutral-200">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="flex items-center gap-2 text-lg">
|
||||||
|
<Info className="w-5 h-5 text-neutral-500" />
|
||||||
|
How it works
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="text-neutral-600 space-y-4 text-sm leading-relaxed">
|
||||||
|
<p>
|
||||||
|
Return on Investment (ROI) is a performance measure used to evaluate the efficiency or profitability of an investment. It measures the amount of return on an investment, relative to the investment’s cost.
|
||||||
|
</p>
|
||||||
|
<div className="bg-neutral-100 p-4 rounded-md font-mono text-neutral-800">
|
||||||
|
ROI = ((Net Profit) / Cost of Investment) × 100
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
In this calculator, <strong>Net Profit</strong> is calculated as <strong>Total Revenue - Total Investment</strong>. A positive ROI indicates that the investment has generated more money than it cost, while a negative ROI indicates a loss.
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue