mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-02-22 09:02:01 +00:00
- Added a new `bun.lockb` file for dependency management. - Updated `next.config.ts` to set output to "standalone" for better deployment options. - Removed `package-lock.json` to streamline package management. - Modified `package.json` to update dependencies, including `@prisma/client` and `sonner`, and adjusted build scripts for improved functionality. - Enhanced Tailwind CSS configuration to include new animations and color schemes. - Refactored various dashboard components to improve UI consistency, including adding a new `My Wallet` page and updating existing pages to use a unified styling approach. - Introduced a new `BlockDeviceDialog` component for managing device blocking with user-defined reasons. - Improved logging and error handling in payment verification and device management functions. These changes enhance the overall functionality, maintainability, and user experience of the application.
91 lines
3.0 KiB
TypeScript
91 lines
3.0 KiB
TypeScript
"use client";
|
|
import {
|
|
discountPercentageAtom,
|
|
formulaResultAtom,
|
|
initialPriceAtom,
|
|
numberOfDaysAtom,
|
|
numberOfDevicesAtom,
|
|
} from "@/lib/atoms";
|
|
import { useAtom } from "jotai";
|
|
import { useEffect } from "react";
|
|
import NumberInput from "./number-input";
|
|
|
|
|
|
export default function PriceCalculator() {
|
|
const [initialPrice, setInitialPrice] = useAtom(initialPriceAtom);
|
|
const [discountPercentage, setDiscountPercentage] = useAtom(
|
|
discountPercentageAtom,
|
|
);
|
|
const [numberOfDevices, setNumberOfDevices] = useAtom(numberOfDevicesAtom);
|
|
const [numberOfDays, setNumberOfDays] = useAtom(numberOfDaysAtom);
|
|
const [formulaResult, setFormulaResult] = useAtom(formulaResultAtom);
|
|
|
|
useEffect(() => {
|
|
const basePrice = initialPrice + (numberOfDevices - 1) * discountPercentage;
|
|
setFormulaResult(
|
|
`Price for ${numberOfDevices} device(s) over ${numberOfDays} day(s): MVR ${basePrice.toFixed(2)}`,
|
|
);
|
|
}, [
|
|
initialPrice,
|
|
discountPercentage,
|
|
numberOfDevices,
|
|
numberOfDays,
|
|
setFormulaResult,
|
|
]);
|
|
|
|
return (
|
|
<div className="border p-2 rounded-xl">
|
|
<div className="flex justify-between items-center border-[1px] rounded-md border-dashed font-bold title-bg py-4 px-2 mb-4">
|
|
<h3 className="text-sarLinkOrange text-2xl">
|
|
Price Calculator
|
|
</h3>
|
|
</div>
|
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
{/* Initial Price Input */}
|
|
<NumberInput
|
|
label="Initial Price"
|
|
value={initialPrice}
|
|
onChange={(value) => setInitialPrice(value)}
|
|
/>
|
|
{/* Number of Devices Input */}
|
|
<NumberInput
|
|
label="Number of Devices"
|
|
value={numberOfDevices}
|
|
onChange={(value) => setNumberOfDevices(value)}
|
|
/>
|
|
{/* Number of Days Input */}
|
|
<NumberInput
|
|
label="Number of Days"
|
|
value={numberOfDays}
|
|
onChange={(value) => setNumberOfDays(value)}
|
|
/>
|
|
|
|
{/* Discount Percentage Input */}
|
|
<NumberInput
|
|
label="Discount Percentage"
|
|
value={discountPercentage}
|
|
onChange={(value) => setDiscountPercentage(value)}
|
|
/>
|
|
</div>
|
|
|
|
<div className="mt-4">
|
|
<div className="title-bg relative rounded-lg border border-input shadow-sm shadow-black/5 transition-shadow focus-within:border-ring focus-within:outline-none focus-within:ring-[3px] focus-within:ring-ring/20 has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50 [&:has(input:is(:disabled))_*]:pointer-events-none">
|
|
<label
|
|
htmlFor=""
|
|
className="block px-3 pt-2 text-md font-medium text-foreground"
|
|
>
|
|
Total
|
|
</label>
|
|
<input
|
|
className="flex font-mono font-semibold h-10 w-full bg-transparent px-3 pb-2 text-sm text-foreground placeholder:text-muted-foreground/70 focus-visible:outline-none"
|
|
value={formulaResult}
|
|
readOnly
|
|
placeholder={"Result"}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|