Skip to content

Commit

Permalink
Merge pull request #34 from kcoderhtml/dev
Browse files Browse the repository at this point in the history
v0.2.4
  • Loading branch information
kcoderhtml authored May 2, 2024
2 parents 823fb3b + b9fef85 commit 3634c99
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 16 deletions.
13 changes: 13 additions & 0 deletions auth.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ const logsnag = new LogSnag({
project: "magicsnap",
});

function generateRandomString() {
const chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
for (let i = 0; i < 16; i++) {
const randomIndex = Math.floor(Math.random() * chars.length);
result += chars.charAt(randomIndex);
}
return result;
}

export default defineConfig({
providers: [
Slack({
Expand Down Expand Up @@ -50,6 +61,7 @@ export default defineConfig({
if (users.length === 0) {
await db.insert(User).values({
userId: profile["https://slack.com/user_id"],
hash: generateRandomString(),
name: profile.name,
email: profile.email,
image: profile.picture,
Expand Down Expand Up @@ -97,6 +109,7 @@ export default defineConfig({
} else {
await db.insert(User).values({
userId: profile["https://slack.com/user_id"],
hash: generateRandomString(),
name: profile.name,
email: profile.email,
image: profile.picture,
Expand Down
1 change: 1 addition & 0 deletions db/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const Organization = defineTable({
const User = defineTable({
columns: {
userId: column.text({ primaryKey: true }),
hash: column.text(),
team: column.text(),
name: column.text(),
email: column.text(),
Expand Down
13 changes: 0 additions & 13 deletions src/pages/api/remind.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import type { APIRoute } from "astro"
import { db, User, Organization, Event } from "astro:db";
import { LogSnag } from "logsnag";

const logsnag = new LogSnag({
token: process.env.LOGSNAG_TOKEN || "",
project: "magicsnap",
});

export const POST: APIRoute = async ({ request }) => {
// get authorization header
Expand All @@ -26,13 +20,6 @@ export const POST: APIRoute = async ({ request }) => {
return diffHours < 24 && diffHours > 0
})

await logsnag.track({
channel: "api",
event: "reminder-sent",
description: `Sent reminder to ${users.length} users in ${organizations.length} different organizations about ${eventsHappeningToday.length} events happening today`,
icon: "📬",
});

return new Response(JSON.stringify({
ok: true, eventsHappeningToday: eventsHappeningToday, users: users, organizations: organizations
}), { status: 200 })
Expand Down
9 changes: 6 additions & 3 deletions src/pages/messages.astro
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,15 @@ if (Astro.request.method === "POST") {
.map((user) => ({ email: user.email, name: user.name }));
}
message += " \n\n-----\n\n";
message += `*This email was sent by MagicSnap because you are a member of ${session.teamName}. If you have any questions or need assistance, please contact us at [email protected].*`;
const email = {
to: "[email protected]",
bcc: userList,
from: "[email protected]",
subject: subject,
text: message,
markdown: message,
};
const lastEmailHash = (
Expand All @@ -102,7 +105,7 @@ if (Astro.request.method === "POST") {
.from(Organization)
.where(
and(
like(Organization.lastMessageHash, Md5.hashStr(email.text)),
like(Organization.lastMessageHash, Md5.hashStr(email.markdown)),
like(Organization.team, session.team)
)
)
Expand Down Expand Up @@ -139,7 +142,7 @@ if (Astro.request.method === "POST") {
await db
.update(Organization)
.set({
lastMessageHash: Md5.hashStr(email.text),
lastMessageHash: Md5.hashStr(email.markdown),
})
.where(like(Organization.team, session.team));
Expand Down
158 changes: 158 additions & 0 deletions src/pages/update/[team]/[eventID]/[userID].astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
---
import Base from "../../../../Layouts/Base.astro";
import ThreeWayToggle from "../../../../components/ThreeWayToggle.astro";
import { LogSnag } from "logsnag";
import { db, like, and, Event, User } from "astro:db";
const logsnag = new LogSnag({
token: process.env.LOGSNAG_TOKEN || "",
project: "magicsnap",
});
const { team, eventID, userID } = Astro.params as {
team: string;
eventID: string;
userID: string;
};
const user = (
await db
.select()
.from(User)
.where(and(like(User.team, team), like(User.userId, userID)))
.all()
)[0];
const hash = Astro.url.searchParams.get("hash");
if (Astro.request.method === "POST" && user && hash === user.hash) {
try {
const data = await Astro.request.formData();
if (data.get("availability") != null) {
const eventID = data.get("eventID") as string;
const status = data.get("selected") as string;
const event = (
await db.select().from(Event).where(like(Event.id, eventID))
)?.[0];
if (event) {
let statusGoing = event.statusGoing
.split(",")
.filter((id) => id !== "");
let statusMaybe = event.statusMaybe
.split(",")
.filter((id) => id !== "");
let statusNotGoing = event.statusNotGoing
.split(",")
.filter((id) => id !== "");
const currentStatus = statusGoing.includes(user.userId)
? "yes"
: statusMaybe.includes(user.userId)
? "maybe"
: "no";
if (currentStatus !== status) {
if (status === "yes") {
statusGoing.push(user.userId);
statusMaybe = statusMaybe.filter((id) => id !== user.userId);
statusNotGoing = statusNotGoing.filter((id) => id !== user.userId);
} else if (status === "maybe") {
statusMaybe.push(user.userId);
statusGoing = statusGoing.filter((id) => id !== user.userId);
statusNotGoing = statusNotGoing.filter((id) => id !== user.userId);
} else if (status === "no" && currentStatus !== "no") {
statusNotGoing.push(user.userId);
statusGoing = statusGoing.filter((id) => id !== user.userId);
statusMaybe = statusMaybe.filter((id) => id !== user.userId);
}
}
await db
.update(Event)
.set({
statusGoing: statusGoing.join(","),
statusMaybe: statusMaybe.join(","),
statusNotGoing: statusNotGoing.join(","),
})
.where(like(Event.id, eventID));
await logsnag.track({
channel: "actions",
event: "event_status_change",
icon: "📅",
user_id: user.userId,
});
}
}
} catch (error) {
if (error instanceof Error) {
await logsnag.track({
channel: "errors",
event: "event_status_change_error",
icon: "📅",
user_id: user.userId,
tags: {
error: error.message,
},
});
}
}
}
const event = (
await db
.select()
.from(Event)
.where(and(like(Event.team, team), like(Event.id, eventID)))
.all()
)[0];
---

<Base title="Update Your Availability">
<section class="event">
{user && user.hash === hash && event && (
<h2>{event.name}</h2>
<p>
{event.name} is being held at {event.location} on {
event.date.toLocaleDateString() +
" at " +
event.date.toLocaleTimeString([], {
hour: "numeric",
minute: "2-digit",
})
}
</p>
<p>{event.comments}</p>
<h3>Are you going?</h3>
<section class="availability-container">
<ThreeWayToggle
eventID=`${event.id}`
selected=`${event.statusGoing?.includes(userID) ? "yes" : event.statusMaybe?.includes(userID) ? "maybe" : "no"}`
/>
</section>
)}
{!user && <p>Sorry, we couldn't find your user account.</p>}
{user && user.hash !== hash && <p>Sorry, the link you used is invalid.</p>}
{!event && <p>Sorry, we couldn't find the event you're looking for.</p>}
</section>
</Base>

<style>
.event {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
}
.availability-container {
display: flex;
flex-direction: column;
border: 1px solid #ccc;
width: fit-content;
padding-left: 4rem;
}
</style>

0 comments on commit 3634c99

Please sign in to comment.