fix(CalendarSync): replace window.confirm() with inline confirmation and rename file
- Replace blocking window.confirm() with showRevokeConfirm state + inline confirmation dialog in CalendarSyncSection - Rename CalendarSync.tsx to CalendarSyncSection.tsx to match export convention Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
+57
-27
@@ -12,6 +12,7 @@ export function CalendarSyncSection({ staffId }: Props) {
|
|||||||
const [actionLoading, setActionLoading] = useState<"generate" | "revoke" | null>(null);
|
const [actionLoading, setActionLoading] = useState<"generate" | "revoke" | null>(null);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
|
const [showRevokeConfirm, setShowRevokeConfirm] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchToken();
|
fetchToken();
|
||||||
@@ -51,7 +52,8 @@ export function CalendarSyncSection({ staffId }: Props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function revokeToken() {
|
async function revokeToken() {
|
||||||
if (!confirm("Revoke your calendar feed link? Anyone with the current link will lose access.")) {
|
if (!showRevokeConfirm) {
|
||||||
|
setShowRevokeConfirm(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setActionLoading("revoke");
|
setActionLoading("revoke");
|
||||||
@@ -67,6 +69,7 @@ export function CalendarSyncSection({ staffId }: Props) {
|
|||||||
setError(e instanceof Error ? e.message : "Failed to revoke token");
|
setError(e instanceof Error ? e.message : "Failed to revoke token");
|
||||||
} finally {
|
} finally {
|
||||||
setActionLoading(null);
|
setActionLoading(null);
|
||||||
|
setShowRevokeConfirm(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,32 +123,59 @@ export function CalendarSyncSection({ staffId }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex gap-2">
|
{showRevokeConfirm ? (
|
||||||
<button
|
<div className="flex items-center gap-3 p-3 bg-red-50 border border-red-200 rounded-lg">
|
||||||
onClick={generateToken}
|
<p className="flex-1 text-sm text-red-700">
|
||||||
disabled={actionLoading !== null}
|
Revoke your calendar feed link? Anyone with the current link will lose access.
|
||||||
className="flex items-center gap-1.5 px-3 py-2 bg-(--color-accent) text-white rounded-lg text-sm font-medium hover:bg-(--color-accent-hover) disabled:opacity-50"
|
</p>
|
||||||
>
|
<button
|
||||||
{actionLoading === "generate" ? (
|
onClick={revokeToken}
|
||||||
<RefreshCw size={14} className="animate-spin" />
|
disabled={actionLoading !== null}
|
||||||
) : (
|
className="flex items-center gap-1.5 px-3 py-1.5 bg-red-600 text-white rounded-lg text-sm font-medium hover:bg-red-700 disabled:opacity-50"
|
||||||
<RefreshCw size={14} />
|
>
|
||||||
)}
|
{actionLoading === "revoke" ? (
|
||||||
Regenerate
|
<RefreshCw size={14} className="animate-spin" />
|
||||||
</button>
|
) : (
|
||||||
<button
|
<Trash2 size={14} />
|
||||||
onClick={revokeToken}
|
)}
|
||||||
disabled={actionLoading !== null}
|
Revoke
|
||||||
className="flex items-center gap-1.5 px-3 py-2 border border-red-200 rounded-lg text-sm text-red-600 hover:bg-red-50 disabled:opacity-50"
|
</button>
|
||||||
>
|
<button
|
||||||
{actionLoading === "revoke" ? (
|
onClick={() => setShowRevokeConfirm(false)}
|
||||||
<RefreshCw size={14} className="animate-spin" />
|
disabled={actionLoading !== null}
|
||||||
) : (
|
className="px-3 py-1.5 border border-stone-200 rounded-lg text-sm text-stone-600 hover:bg-stone-50 disabled:opacity-50"
|
||||||
<Trash2 size={14} />
|
>
|
||||||
)}
|
Cancel
|
||||||
Revoke
|
</button>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
) : (
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button
|
||||||
|
onClick={generateToken}
|
||||||
|
disabled={actionLoading !== null}
|
||||||
|
className="flex items-center gap-1.5 px-3 py-2 bg-(--color-accent) text-white rounded-lg text-sm font-medium hover:bg-(--color-accent-hover) disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{actionLoading === "generate" ? (
|
||||||
|
<RefreshCw size={14} className="animate-spin" />
|
||||||
|
) : (
|
||||||
|
<RefreshCw size={14} />
|
||||||
|
)}
|
||||||
|
Regenerate
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={revokeToken}
|
||||||
|
disabled={actionLoading !== null}
|
||||||
|
className="flex items-center gap-1.5 px-3 py-2 border border-red-200 rounded-lg text-sm text-red-600 hover:bg-red-50 disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{actionLoading === "revoke" ? (
|
||||||
|
<RefreshCw size={14} className="animate-spin" />
|
||||||
|
) : (
|
||||||
|
<Trash2 size={14} />
|
||||||
|
)}
|
||||||
|
Revoke
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<p className="text-xs text-stone-400">
|
<p className="text-xs text-stone-400">
|
||||||
Regenerating will create a new URL and invalidate the old one.
|
Regenerating will create a new URL and invalidate the old one.
|
||||||
Reference in New Issue
Block a user