final touches for beta skymoney (at least i think)
This commit is contained in:
81
web/src/components/EarlyFundingModal.tsx
Normal file
81
web/src/components/EarlyFundingModal.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import { useState } from "react";
|
||||
import { apiPatch } from "../api/http";
|
||||
import { formatDateInTimezone } from "../utils/timezone";
|
||||
|
||||
interface EarlyFundingModalProps {
|
||||
planId: string;
|
||||
planName: string;
|
||||
nextDueDate?: string;
|
||||
timezone: string;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export default function EarlyFundingModal({ planId, planName, nextDueDate, timezone, onClose }: EarlyFundingModalProps) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleResponse = async (enableEarlyFunding: boolean) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await apiPatch(`/fixed-plans/${planId}/early-funding`, { enableEarlyFunding });
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error("Failed to update early funding:", error);
|
||||
// Still close the modal even if it fails
|
||||
onClose();
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const nextDueLabel = nextDueDate
|
||||
? formatDateInTimezone(nextDueDate, timezone, {
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
year: 'numeric'
|
||||
})
|
||||
: "next billing cycle";
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-md w-full p-6 space-y-4">
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">
|
||||
Start Funding Early?
|
||||
</h2>
|
||||
|
||||
<p className="text-gray-700 dark:text-gray-300">
|
||||
You've paid <strong>{planName}</strong> which is due on <strong>{nextDueLabel}</strong>.
|
||||
</p>
|
||||
|
||||
<p className="text-gray-700 dark:text-gray-300">
|
||||
Would you like to start funding for the next payment now, or wait until closer to the due date?
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-3 pt-4">
|
||||
<button
|
||||
onClick={() => handleResponse(true)}
|
||||
disabled={loading}
|
||||
className="flex-1 px-4 py-2 bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400
|
||||
text-white font-medium rounded-md transition-colors"
|
||||
>
|
||||
{loading ? "Starting..." : "Yes, Start Now"}
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => handleResponse(false)}
|
||||
disabled={loading}
|
||||
className="flex-1 px-4 py-2 bg-gray-200 hover:bg-gray-300 dark:bg-gray-700
|
||||
dark:hover:bg-gray-600 disabled:bg-gray-100 text-gray-900 dark:text-white
|
||||
font-medium rounded-md transition-colors"
|
||||
>
|
||||
Wait Until Rollover
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 pt-2">
|
||||
<strong>Start Now:</strong> Your next income will begin funding this bill.<br/>
|
||||
<strong>Wait:</strong> Funding will resume automatically on {nextDueLabel}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user