feat: silent email rate limit — no count/cooldown shown to users
This commit is contained in:
@@ -254,7 +254,7 @@ export default function Timesheet() {
|
|||||||
try {
|
try {
|
||||||
const res = await api.post(`/timesheets/${timesheetId}/email`);
|
const res = await api.post(`/timesheets/${timesheetId}/email`);
|
||||||
setEmailStatus(s => ({ ...s, count: res.data.count, allowed: res.data.remaining > 0, cooldownMs: 30 * 60 * 1000 }));
|
setEmailStatus(s => ({ ...s, count: res.data.count, allowed: res.data.remaining > 0, cooldownMs: 30 * 60 * 1000 }));
|
||||||
setEmailResult({ ok: true, msg: `Sent! (${res.data.count}/${res.data.max} sends used for this week)` });
|
setEmailResult({ ok: true, msg: 'Sent to Office!' });
|
||||||
setEmailConfirm(false);
|
setEmailConfirm(false);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setEmailResult({ ok: false, msg: err.response?.data?.error || 'Failed to send email' });
|
setEmailResult({ ok: false, msg: err.response?.data?.error || 'Failed to send email' });
|
||||||
@@ -388,19 +388,15 @@ export default function Timesheet() {
|
|||||||
<div className="flex-1 rounded-xl border border-emerald-200 dark:border-emerald-500/30 bg-emerald-50 dark:bg-emerald-500/5 p-3 space-y-2">
|
<div className="flex-1 rounded-xl border border-emerald-200 dark:border-emerald-500/30 bg-emerald-50 dark:bg-emerald-500/5 p-3 space-y-2">
|
||||||
<p className="text-xs text-emerald-700 dark:text-emerald-400 font-medium text-center">
|
<p className="text-xs text-emerald-700 dark:text-emerald-400 font-medium text-center">
|
||||||
Send to Office@CoastalContractingFL.com?
|
Send to Office@CoastalContractingFL.com?
|
||||||
{emailStatus && (
|
|
||||||
<span className="block text-emerald-600/70 dark:text-emerald-500/70 mt-0.5">
|
|
||||||
{emailStatus.count}/{emailStatus.max} sends used this week
|
|
||||||
{emailStatus.cooldownMs > 0 ? ` · available in ${Math.ceil(emailStatus.cooldownMs / 60000)}m` : ''}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</p>
|
</p>
|
||||||
{emailStatus && !emailStatus.allowed ? (
|
{emailStatus && !emailStatus.allowed ? (
|
||||||
<p className="text-xs text-red-500 text-center">
|
<div className="flex gap-2">
|
||||||
{emailStatus.count >= emailStatus.max
|
<button disabled className="flex-1 py-1.5 rounded-lg bg-emerald-500 text-white text-xs font-semibold opacity-40 flex items-center justify-center gap-1">
|
||||||
? `Max ${emailStatus.max} sends reached for this timesheet`
|
<Mail size={12} />
|
||||||
: `Please wait ${Math.ceil(emailStatus.cooldownMs / 60000)} min before sending again`}
|
Send
|
||||||
</p>
|
</button>
|
||||||
|
<button onClick={() => { setEmailConfirm(false); setEmailResult(null); }} className="flex-1 py-1.5 rounded-lg bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 text-xs font-semibold">Cancel</button>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user