mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-11-01 18:19:43 +00:00
Add lifecycle push notifications and refine UI
Send push notifications when partner disconnects, resets progress, or deletes relationship. Update Matches screen with new styling and remove legacy premium elements. Remove message content preview from admin User Activity page.
This commit is contained in:
1 parent
a567fba349
commit
994dd2a295
5 files changed
+174
-123
No files matched your search
@@ -6,6 +6,34 @@ const corsHeaders = {
|
||||
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
|
||||
};
|
||||
|
||||
interface ExpoPushMessage {
|
||||
to: string;
|
||||
title: string;
|
||||
body: string;
|
||||
sound?: string;
|
||||
data?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
async function sendExpoPushNotifications(messages: ExpoPushMessage[]) {
|
||||
if (messages.length === 0) return;
|
||||
|
||||
const response = await fetch("https://exp.host/--/api/v2/push/send", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: JSON.stringify(messages),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
console.error("Expo push error:", error);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
Deno.serve(async (req) => {
|
||||
// Handle CORS preflight
|
||||
if (req.method === "OPTIONS") {
|
||||
@@ -62,6 +90,14 @@ Deno.serve(async (req) => {
|
||||
|
||||
const coupleId = profile.couple_id;
|
||||
|
||||
// Get partner's push token BEFORE clearing data
|
||||
const { data: partnerProfile } = await supabase
|
||||
.from("profiles")
|
||||
.select("push_token")
|
||||
.eq("couple_id", coupleId)
|
||||
.neq("id", user.id)
|
||||
.maybeSingle();
|
||||
|
||||
// Get all match IDs for this couple (needed for storage cleanup)
|
||||
const { data: matches } = await supabase
|
||||
.from("matches")
|
||||
@@ -112,6 +148,17 @@ Deno.serve(async (req) => {
|
||||
);
|
||||
}
|
||||
|
||||
// Notify partner about the deletion
|
||||
if (partnerProfile?.push_token) {
|
||||
await sendExpoPushNotifications([{
|
||||
to: partnerProfile.push_token,
|
||||
title: "Relationship Deleted",
|
||||
body: "Your partner has deleted all shared data. You can start fresh with a new partner anytime.",
|
||||
sound: "default",
|
||||
data: { type: "relationship_deleted" },
|
||||
}]);
|
||||
}
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({ success: true, message: "Relationship data deleted successfully" }),
|
||||
{ headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
||||
|
||||
@@ -10,6 +10,34 @@ interface JoinCoupleBody {
|
||||
invite_code: string;
|
||||
}
|
||||
|
||||
interface ExpoPushMessage {
|
||||
to: string;
|
||||
title: string;
|
||||
body: string;
|
||||
sound?: string;
|
||||
data?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
async function sendExpoPushNotifications(messages: ExpoPushMessage[]) {
|
||||
if (messages.length === 0) return;
|
||||
|
||||
const response = await fetch("https://exp.host/--/api/v2/push/send", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: JSON.stringify(messages),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
console.error("Expo push error:", error);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
Deno.serve(async (req) => {
|
||||
// Handle CORS preflight
|
||||
if (req.method === "OPTIONS") {
|
||||
@@ -183,18 +211,13 @@ Deno.serve(async (req) => {
|
||||
|
||||
const coupleId = profile.couple_id;
|
||||
|
||||
// Count members in this couple
|
||||
const { count, error: countError } = await supabase
|
||||
// Get partner's push token BEFORE clearing couple_id
|
||||
const { data: partnerProfile } = await supabase
|
||||
.from("profiles")
|
||||
.select("*", { count: "exact", head: true })
|
||||
.eq("couple_id", coupleId);
|
||||
|
||||
if (countError) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Failed to check couple members" }),
|
||||
{ status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
||||
);
|
||||
}
|
||||
.select("push_token")
|
||||
.eq("couple_id", coupleId)
|
||||
.neq("id", user.id)
|
||||
.maybeSingle();
|
||||
|
||||
// Remove ALL members from couple (both partners get unlinked)
|
||||
// This ensures the remaining partner isn't left in a "waiting" state
|
||||
@@ -221,6 +244,17 @@ Deno.serve(async (req) => {
|
||||
// Don't fail the request, users already unlinked
|
||||
}
|
||||
|
||||
// Notify partner about the unpair
|
||||
if (partnerProfile?.push_token) {
|
||||
await sendExpoPushNotifications([{
|
||||
to: partnerProfile.push_token,
|
||||
title: "Partner Disconnected",
|
||||
body: "Your partner has ended the connection. You can invite a new partner anytime.",
|
||||
sound: "default",
|
||||
data: { type: "unpair" },
|
||||
}]);
|
||||
}
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({ success: true, couple_deleted: true }),
|
||||
{ headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
||||
|
||||
@@ -6,6 +6,34 @@ const corsHeaders = {
|
||||
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
|
||||
};
|
||||
|
||||
interface ExpoPushMessage {
|
||||
to: string;
|
||||
title: string;
|
||||
body: string;
|
||||
sound?: string;
|
||||
data?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
async function sendExpoPushNotifications(messages: ExpoPushMessage[]) {
|
||||
if (messages.length === 0) return;
|
||||
|
||||
const response = await fetch("https://exp.host/--/api/v2/push/send", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: JSON.stringify(messages),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
console.error("Expo push error:", error);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
Deno.serve(async (req) => {
|
||||
// Handle CORS preflight
|
||||
if (req.method === "OPTIONS") {
|
||||
@@ -62,6 +90,14 @@ Deno.serve(async (req) => {
|
||||
|
||||
const coupleId = profile.couple_id;
|
||||
|
||||
// Get partner's push token BEFORE clearing data
|
||||
const { data: partnerProfile } = await supabase
|
||||
.from("profiles")
|
||||
.select("push_token")
|
||||
.eq("couple_id", coupleId)
|
||||
.neq("id", user.id)
|
||||
.maybeSingle();
|
||||
|
||||
// Get all match IDs for this couple (needed for storage cleanup)
|
||||
const { data: matches } = await supabase
|
||||
.from("matches")
|
||||
@@ -112,6 +148,17 @@ Deno.serve(async (req) => {
|
||||
);
|
||||
}
|
||||
|
||||
// Notify partner about the progress reset
|
||||
if (partnerProfile?.push_token) {
|
||||
await sendExpoPushNotifications([{
|
||||
to: partnerProfile.push_token,
|
||||
title: "Progress Reset",
|
||||
body: "Your partner has reset all progress. Your matches and chats have been cleared to start fresh.",
|
||||
sound: "default",
|
||||
data: { type: "progress_reset" },
|
||||
}]);
|
||||
}
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({ success: true, message: "Progress reset successfully" }),
|
||||
{ headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
||||
|
||||
Reference in new issue
Block a user