Skip to content

Commit

Permalink
Repeat session create (#224)
Browse files Browse the repository at this point in the history
* add new sessions modal in new game flow

* pre seat members with email notification and community setting

* update types

* add changelog component

* remove console log

* more cleanup
  • Loading branch information
jongrim authored Dec 9, 2023
1 parent a7afa12 commit 0e4ebb9
Show file tree
Hide file tree
Showing 33 changed files with 1,002 additions and 265 deletions.
27 changes: 0 additions & 27 deletions .github/workflows/staging.yml

This file was deleted.

2 changes: 1 addition & 1 deletion docs/developing.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The storage buckets have to be manually created after any database setup or rese

Create each as a public bucket, with 1 MB upload limit.

Next, you have to add the RLS policies. For each bucket, you can do the quick start option and use the **Give users access to only their own a top level folder named as uid** template. Enable all operations and save. This will allow each user full access to their own bucket which is stored under their ID. And since the buckets are public, anyone can read the contents.
Next, you have to add the RLS policies. For each bucket, you can do the quick start option and use the **Give users access to only their own top level folder named as uid** template. Enable all operations and save. This will allow each user full access to their own bucket which is stored under their ID. And since the buckets are public, anyone can read the contents.

### Replication

Expand Down
6 changes: 0 additions & 6 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,5 @@
<noscript>
Opinionated, production ready template for Vite and Vue 3
</noscript>
<script
async
src="https://platform.twitter.com/widgets.js"
charset="utf-8"
type="module"
></script>
</body>
</html>
4 changes: 2 additions & 2 deletions netlify/functions/dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const handler: Handler = async (event) => {
.order("start_time", { ascending: true });

if (managingError) {
// logError(gamesError);
logError(managingError);
}

// load info about facilitators they're playing with
Expand All @@ -89,7 +89,7 @@ export const handler: Handler = async (event) => {
.in("id", [...uniquePlayers]);

if (playerProfilesError) {
//
logError(playerProfilesError);
}

const { data: facilitatorProfiles, error: facilitatorProfilesError } =
Expand Down
73 changes: 63 additions & 10 deletions netlify/functions/notify.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { Handler } from "@netlify/functions";
import { buildCommunityAdminMessage, sendEmail } from "../utils";
import { buildCommunityAdminMessage, logError, sendEmail } from "../utils";

/**
* This function is called any time a record is written to the
* notifications table. This is where you can respond to the
* record type and send an email.
*/

export const handler: Handler = async (event) => {
const { authorization } = event.headers;
const { record } = JSON.parse(event.body);

if (authorization !== process.env.WEB_MAIL_PASSWORD) {
console.warn(
"Unauthorized connection. Dropping notification ID",
record.id
);
logError({
message: "Unauthorized connection. Dropping record:" + record.id,
});
return {
statusCode: 403,
body: JSON.stringify({
Expand All @@ -28,7 +33,25 @@ export const handler: Handler = async (event) => {
});
console.info("successfully sent rsvp email");
} catch (error) {
console.error("failed to send rsvp email", error);
logError({
message: `failed to send rsvp email: ${error}`,
});
}
}
if (record.type === "pre_seated_rsvp") {
const adminMessage = sendPreSeatEmail({
name: record.user_name,
email: record.email,
relatedUrl: record.related_url,
gameName: record.custom_fields?.game_name,
});
try {
await sendEmail(adminMessage);
console.info("successfully sent community admin email");
} catch (error) {
logError({
message: `failed to send pre_seat email: ${error}`,
});
}
}
if (record.type === "cancel") {
Expand All @@ -40,7 +63,9 @@ export const handler: Handler = async (event) => {
});
console.info("successfully sent cancel email");
} catch (error) {
console.error("failed to send cancel email", error);
logError({
message: `failed to send cancel email: ${error}`,
});
}
}
if (record.type === "notify_creator_of_rsvp") {
Expand All @@ -53,7 +78,9 @@ export const handler: Handler = async (event) => {
});
console.info("successfully sent new join email");
} catch (error) {
console.error("failed to send new join email", error);
logError({
message: `failed to send join email: ${error}`,
});
}
}
}
Expand All @@ -67,7 +94,9 @@ export const handler: Handler = async (event) => {
});
console.info("successfully sent membership approval email");
} catch (error) {
console.error("failed to send membership approval email", error);
logError({
message: `failed to send membership_request email: ${error}`,
});
}
}
if (
Expand All @@ -85,7 +114,9 @@ export const handler: Handler = async (event) => {
await sendEmail(adminMessage);
console.info("successfully sent community admin email");
} catch (error) {
console.error("failed to send community admin email", error);
logError({
message: `failed to send community_admin email: ${error}`,
});
}
}

Expand Down Expand Up @@ -116,6 +147,28 @@ function sendMembershipApprovalEmail({ name, email, relatedUrl, message }) {
};
return sendEmail(mailjetMessage);
}
function sendPreSeatEmail({ name, email, relatedUrl, gameName }) {
const mailjetMessage = {
From: {
Email: "[email protected]",
Name: "Playabl Notifications",
},
To: [
{
Email: email,
Name: name,
},
],
TemplateID: 5423059,
TemplateLanguage: true,
Subject: `Playabl - You've been pre-seated for ${gameName}!`,
Variables: {
game_name: gameName,
related_url: relatedUrl,
},
};
return sendEmail(mailjetMessage);
}
function sendRsvpEmail({ name, email, relatedUrl, gameName }) {
const mailjetMessage = {
From: {
Expand Down
59 changes: 59 additions & 0 deletions netlify/functions/notifyPreSeat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Handler } from "@netlify/functions";
import { addNotificationRecord, authenticateUser, supabase } from "../utils";

export const handler: Handler = async (event) => {
const user = await authenticateUser(event);
if (!user) {
return {
statusCode: 403,
body: "not authorized",
};
}

const sessions = JSON.parse(event.body);

const { data: game } = await supabase
.from("games")
.select("*")
.eq("id", sessions[0].game_id)
.single();

if (game.creator_id !== user.data.user.id) {
return {
statusCode: 403,
body: "not authorized",
};
}

const toNotify = new Set(
sessions.reduce((users, curSession) => {
if (curSession?.rsvps?.length > 0) {
return users.concat(curSession.rsvps);
}
return users;
}, []),
);

const { data: profiles } = await supabase
.from("profiles")
.select("*")
.in("id", [...toNotify]);

for (const user of profiles) {
await addNotificationRecord({
user_id: user.id,
user_name: user.username,
email: user.email,
message: `You have been pre-seated in the game ${game.title}`,
related_url: `https://app.playabl.io/games/${game.id}`,
type: "pre_seated_rsvp",
custom_fields: {
game_name: game.title,
},
});
}

return {
statusCode: 201,
};
};
7 changes: 6 additions & 1 deletion netlify/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,12 @@ export async function addNotificationRecord(notification: {
email: string;
message: string;
related_url: string;
type: "community_admin_message";
type:
| "community_admin_message"
| "rsvp"
| "pre_seated_rsvp"
| "cancel"
| "notify_creator_of_rsvp";
custom_fields: unknown;
}) {
const { error } = await supabase.from("notifications").insert(notification);
Expand Down
4 changes: 2 additions & 2 deletions public/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ self.addEventListener("install", function (event) {
"/src/assets/Paytone_One/PaytoneOne-Regular.ttf",
"/playabl_192.png",
]);
})
}),
);
});

Expand All @@ -16,6 +16,6 @@ self.addEventListener("fetch", function (event) {
event.respondWith(
fetch(event.request).catch(function () {
return caches.match(event.request);
})
}),
);
});
3 changes: 3 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@close="showNewProfileModal = false"
/>
<OfflineIndicator />
<ChangelogWidget />
</AppShell>
</template>
<script setup lang="ts">
Expand All @@ -26,6 +27,7 @@ import { loadProfile } from "./api/profiles";
import { log } from "./util/logger";
import AppShell from "./layouts/AppShell.vue";
import { Notification } from "./typings/Notification";
import ChangelogWidget from "./ChangelogWidget.vue";
const route = useRoute();
const router = useRouter();
Expand Down Expand Up @@ -68,6 +70,7 @@ supabase.auth.onAuthStateChange(async (event, session) => {
case "SIGNED_OUT":
store.user = null;
store.userSession = null;
document.getElementById("changelogfy-client")?.remove();
break;
}
});
Expand Down
46 changes: 46 additions & 0 deletions src/ChangelogWidget.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<template>
<button
id="headway-trigger"
class="fixed bottom-12 right-12 bg-white rounded-full px-3 py-2 shadow-lg flex items-center z-20"
>
<BellAlertIcon class="w-5 h-5 text-slate-700" />
<div class="absolute -top-2 -right-2">
<span class="headway" />
</div>
</button>
</template>
<script setup lang="ts">
import { BellAlertIcon } from "@heroicons/vue/24/outline";
import { onMounted, ref } from "vue";
const loaded = ref(false);
const APP_ID = "7vbAk7";
const loadScript = async () => {
const script = document.createElement("script");
script.setAttribute("src", "//cdn.headwayapp.co/widget.js");
script.addEventListener("load", () => {
loaded.value = true;
initHeadway();
});
script.async = true;
document.head.appendChild(script);
};
function initHeadway() {
const config = {
selector: ".headway",
account: APP_ID,
trigger: "#headway-trigger",
translations: {
title: "Latest updates",
},
};
// @ts-expect-error doesn't know about Headway
window.Headway?.init(config);
}
onMounted(async () => {
await loadScript();
});
</script>
4 changes: 1 addition & 3 deletions src/api/communities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { Community } from "@/typings/Community";
import axios from "axios";

export async function loadCreatorAndAdminCommunities() {
if (!store.user) return;

return Object.values(store.userCommunityMembership)
.filter((membership) => {
return membership.communityMembership.role_id < 3;
Expand Down Expand Up @@ -178,7 +176,7 @@ export async function leaveCommunity(communityId: string, userId = "") {
headers: {
token: session.access_token,
},
}
},
)
.catch((error) => {
log({ error });
Expand Down
Loading

0 comments on commit 0e4ebb9

Please sign in to comment.