Skip to content

Commit c6d128f

Browse files
fix: re-invite replaces existing invite, search empty state uses searched flag (#136) (#141)
Co-authored-by: Ona <no-reply@ona.com>
1 parent efa1038 commit c6d128f

2 files changed

Lines changed: 20 additions & 5 deletions

File tree

src/components/members/invite-form.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ export function InviteForm({
6565
return;
6666
}
6767

68-
// Check for existing pending invite
68+
// Remove any existing pending invite so re-inviting is idempotent.
69+
// This covers the case where a previous revoke failed silently (e.g.
70+
// RLS-blocked deletes return success with 0 rows) or the user simply
71+
// wants to refresh the invite expiry.
6972
const { data: existingInvite } = await supabase
7073
.from("workspace_invites")
7174
.select("id")
@@ -75,9 +78,16 @@ export function InviteForm({
7578
.maybeSingle();
7679

7780
if (existingInvite) {
78-
onError("An invite has already been sent to this email.");
79-
setSending(false);
80-
return;
81+
const { error: deleteError } = await supabase
82+
.from("workspace_invites")
83+
.delete()
84+
.eq("id", existingInvite.id);
85+
86+
if (deleteError) {
87+
onError("Failed to replace existing invite. Try revoking it first.");
88+
setSending(false);
89+
return;
90+
}
8191
}
8292

8393
// Generate token and expiry

src/components/sidebar/page-search.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export function PageSearch() {
2828
const [selectedIndex, setSelectedIndex] = useState(0);
2929
const [workspaceId, setWorkspaceId] = useState<string | null>(null);
3030
const [workspaceResolved, setWorkspaceResolved] = useState(false);
31+
const [searched, setSearched] = useState(false);
3132
const containerRef = useRef<HTMLDivElement>(null);
3233
const inputRef = useRef<HTMLInputElement>(null);
3334
const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
@@ -88,6 +89,7 @@ export function PageSearch() {
8889
setResults([]);
8990
} finally {
9091
setLoading(false);
92+
setSearched(true);
9193
}
9294
},
9395
[workspaceId]
@@ -106,6 +108,7 @@ export function PageSearch() {
106108
if (!query.trim()) {
107109
setResults([]);
108110
setLoading(false);
111+
setSearched(false);
109112
return;
110113
}
111114

@@ -147,6 +150,7 @@ export function PageSearch() {
147150
setOpen(false);
148151
setQuery("");
149152
setResults([]);
153+
setSearched(false);
150154
}
151155

152156
function handleKeyDown(e: React.KeyboardEvent) {
@@ -182,6 +186,7 @@ export function PageSearch() {
182186
function handleClear() {
183187
setQuery("");
184188
setResults([]);
189+
setSearched(false);
185190
setOpen(false);
186191
inputRef.current?.focus();
187192
}
@@ -282,7 +287,7 @@ export function PageSearch() {
282287
</div>
283288
)}
284289

285-
{!loading && workspaceResolved && results.length === 0 && query.trim().length > 0 && (
290+
{!loading && searched && results.length === 0 && query.trim().length > 0 && (
286291
<div className="px-3 py-4 text-center text-xs text-muted-foreground">
287292
No pages match your search
288293
</div>

0 commit comments

Comments
 (0)