mirror of
https://github.com/lukevella/rallly.git
synced 2025-06-05 20:21:50 +02:00
Run autofix
This commit is contained in:
parent
cfb9ec8e8a
commit
1a5b2f206d
20 changed files with 132 additions and 141 deletions
|
@ -1,6 +1,6 @@
|
||||||
import fs from "fs";
|
import fs from "node:fs";
|
||||||
import matter from "gray-matter";
|
import matter from "gray-matter";
|
||||||
import { join } from "path";
|
import { join } from "node:path";
|
||||||
|
|
||||||
const postsDirectory = join(process.cwd(), "src", "posts");
|
const postsDirectory = join(process.cwd(), "src", "posts");
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const ICU = require("i18next-icu/i18nextICU.js");
|
const ICU = require("i18next-icu/i18nextICU.js");
|
||||||
const path = require("path");
|
const path = require("node:path");
|
||||||
const i18n = require("./i18n.config.js");
|
const i18n = require("./i18n.config.js");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -55,7 +55,7 @@ export function EventList({ data }: { data: ScheduledEvent[] }) {
|
||||||
style={{
|
style={{
|
||||||
background: generateGradient(row.original.id),
|
background: generateGradient(row.original.id),
|
||||||
}}
|
}}
|
||||||
></span>
|
/>
|
||||||
<h2 className="truncate text-base font-semibold">
|
<h2 className="truncate text-base font-semibold">
|
||||||
{row.original.title}
|
{row.original.title}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
|
@ -81,7 +81,7 @@ const MonthCalendar: React.FunctionComponent<DateTimePickerProps> = ({
|
||||||
|
|
||||||
const datepickerSelection = React.useMemo(() => {
|
const datepickerSelection = React.useMemo(() => {
|
||||||
return Object.keys(optionsByDay).map(
|
return Object.keys(optionsByDay).map(
|
||||||
(dateString) => new Date(dateString + "T12:00:00"),
|
(dateString) => new Date(`${dateString}T12:00:00`),
|
||||||
);
|
);
|
||||||
}, [optionsByDay]);
|
}, [optionsByDay]);
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ const MonthCalendar: React.FunctionComponent<DateTimePickerProps> = ({
|
||||||
? "border-primary-300 group-hover:border-primary-400 border-dashed shadow-sm"
|
? "border-primary-300 group-hover:border-primary-400 border-dashed shadow-sm"
|
||||||
: "border-dashed border-transparent group-hover:border-gray-400 group-active:bg-gray-200",
|
: "border-dashed border-transparent group-hover:border-gray-400 group-active:bg-gray-200",
|
||||||
)}
|
)}
|
||||||
></span>
|
/>
|
||||||
<span className="z-10">{day.day}</span>
|
<span className="z-10">{day.day}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -272,7 +272,7 @@ const MonthCalendar: React.FunctionComponent<DateTimePickerProps> = ({
|
||||||
className="space-y-3 p-3 sm:flex sm:items-start sm:space-x-4 sm:space-y-0 sm:p-4"
|
className="space-y-3 p-3 sm:flex sm:items-start sm:space-x-4 sm:space-y-0 sm:p-4"
|
||||||
>
|
>
|
||||||
<DateCard
|
<DateCard
|
||||||
{...getDateProps(new Date(dateString + "T12:00:00"))}
|
{...getDateProps(new Date(`${dateString}T12:00:00`))}
|
||||||
/>
|
/>
|
||||||
<div className="grow space-y-3">
|
<div className="grow space-y-3">
|
||||||
{optionsForDay.map(({ option, index }) => {
|
{optionsForDay.map(({ option, index }) => {
|
||||||
|
|
|
@ -95,7 +95,7 @@ export const ParticipantRowView: React.FunctionComponent<{
|
||||||
</td>
|
</td>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<td className="bg-diagonal-lines border-l"></td>
|
<td className="bg-diagonal-lines border-l" />
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -109,7 +109,7 @@ const ParticipantRow: React.FunctionComponent<ParticipantRowProps> = ({
|
||||||
const { user, ownsObject } = useUser();
|
const { user, ownsObject } = useUser();
|
||||||
const { getVote, optionIds } = usePoll();
|
const { getVote, optionIds } = usePoll();
|
||||||
|
|
||||||
const isYou = user && ownsObject(participant) ? true : false;
|
const isYou = !!(user && ownsObject(participant) );
|
||||||
|
|
||||||
const { canEditParticipant } = usePermissions();
|
const { canEditParticipant } = usePermissions();
|
||||||
const canEdit = canEditParticipant(participant.id);
|
const canEdit = canEditParticipant(participant.id);
|
||||||
|
|
|
@ -50,9 +50,9 @@ const TimelineRow = ({
|
||||||
<th
|
<th
|
||||||
style={{ minWidth: 240, top }}
|
style={{ minWidth: 240, top }}
|
||||||
className="sticky left-0 z-30 bg-white pl-4 pr-4"
|
className="sticky left-0 z-30 bg-white pl-4 pr-4"
|
||||||
></th>
|
/>
|
||||||
{children}
|
{children}
|
||||||
<th className="w-full min-w-4 border-l"></th>
|
<th className="w-full min-w-4 border-l" />
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,7 +93,7 @@ function PauseResumeToggle() {
|
||||||
<Trans i18nKey="resumePoll" />
|
<Trans i18nKey="resumePoll" />
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
return (
|
return (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -119,7 +119,6 @@ function PauseResumeToggle() {
|
||||||
<Trans i18nKey="pausePoll" />
|
<Trans i18nKey="pausePoll" />
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ManagePoll: React.FunctionComponent<{
|
const ManagePoll: React.FunctionComponent<{
|
||||||
|
@ -189,8 +188,7 @@ const ManagePoll: React.FunctionComponent<{
|
||||||
</Link>
|
</Link>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<>
|
{poll.status === "finalized" ? (
|
||||||
{poll.status === "finalized" ? (
|
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
reopen.mutate({ pollId: poll.id });
|
reopen.mutate({ pollId: poll.id });
|
||||||
|
@ -227,7 +225,6 @@ const ManagePoll: React.FunctionComponent<{
|
||||||
<PauseResumeToggle />
|
<PauseResumeToggle />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem onClick={exportToCsv}>
|
<DropdownMenuItem onClick={exportToCsv}>
|
||||||
<DropdownMenuItemIconLabel icon={DownloadIcon}>
|
<DropdownMenuItemIconLabel icon={DownloadIcon}>
|
||||||
|
|
|
@ -23,7 +23,7 @@ export const truncateLink = (href: string, text: string, key: number) => {
|
||||||
{finalText}
|
{finalText}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
finalText += "…";
|
finalText += "…";
|
||||||
return (
|
return (
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
|
@ -42,7 +42,6 @@ export const truncateLink = (href: string, text: string, key: number) => {
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const TruncatedLinkify = ({ children }: { children: React.ReactNode }) => {
|
const TruncatedLinkify = ({ children }: { children: React.ReactNode }) => {
|
||||||
|
|
|
@ -16,7 +16,7 @@ export const RegisterLink = React.forwardRef<
|
||||||
onClick={async (e) => {
|
onClick={async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
props.onClick?.(e);
|
props.onClick?.(e);
|
||||||
router.push("/register?callbackUrl=" + encodeURIComponent(pathname));
|
router.push(`/register?callbackUrl=${encodeURIComponent(pathname)}`);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const VoteSummaryProgressBar = (props: {
|
||||||
<div
|
<div
|
||||||
className="h-full bg-green-500 opacity-75 hover:opacity-100"
|
className="h-full bg-green-500 opacity-75 hover:opacity-100"
|
||||||
style={{
|
style={{
|
||||||
width: (props.yes.length / props.total) * 100 + "%",
|
width: `${(props.yes.length / props.total) * 100}%`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
@ -46,7 +46,7 @@ export const VoteSummaryProgressBar = (props: {
|
||||||
<div
|
<div
|
||||||
className="h-full bg-amber-400 opacity-75 hover:opacity-100"
|
className="h-full bg-amber-400 opacity-75 hover:opacity-100"
|
||||||
style={{
|
style={{
|
||||||
width: (props.ifNeedBe.length / props.total) * 100 + "%",
|
width: `${(props.ifNeedBe.length / props.total) * 100}%`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
@ -59,7 +59,7 @@ export const VoteSummaryProgressBar = (props: {
|
||||||
<div
|
<div
|
||||||
className="h-full bg-gray-300 opacity-75 hover:opacity-100"
|
className="h-full bg-gray-300 opacity-75 hover:opacity-100"
|
||||||
style={{
|
style={{
|
||||||
width: (props.no.length / props.total) * 100 + "%",
|
width: `${(props.no.length / props.total) * 100}%`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|
|
@ -34,7 +34,7 @@ function usePostHogPageView() {
|
||||||
if (pathname && posthog) {
|
if (pathname && posthog) {
|
||||||
let url = window.origin + pathname;
|
let url = window.origin + pathname;
|
||||||
if (searchParams?.toString()) {
|
if (searchParams?.toString()) {
|
||||||
url = url + `?${searchParams.toString()}`;
|
url = `${url}?${searchParams.toString()}`;
|
||||||
}
|
}
|
||||||
if (previousUrl.current !== url) {
|
if (previousUrl.current !== url) {
|
||||||
posthog.capture("$pageview", {
|
posthog.capture("$pageview", {
|
||||||
|
|
|
@ -20,7 +20,7 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||||
props: {},
|
props: {},
|
||||||
redirect: {
|
redirect: {
|
||||||
destination:
|
destination:
|
||||||
"/login?callbackUrl=" + encodeURIComponent(ctx.req.url ?? "/"),
|
`/login?callbackUrl=${encodeURIComponent(ctx.req.url ?? "/")}`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ export default function Document() {
|
||||||
<body>
|
<body>
|
||||||
<Main />
|
<Main />
|
||||||
<NextScript />
|
<NextScript />
|
||||||
<div id="portal"></div>
|
<div id="portal" />
|
||||||
</body>
|
</body>
|
||||||
</Html>
|
</Html>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Original source: https://gist.github.com/dsumer/3594cda57e84a93a9019cddc71831882
|
// Original source: https://gist.github.com/dsumer/3594cda57e84a93a9019cddc71831882
|
||||||
import { prisma } from "@rallly/database";
|
import { prisma } from "@rallly/database";
|
||||||
import crypto from "crypto";
|
import crypto from "node:crypto";
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
import * as Serialize from "php-serialize";
|
import * as Serialize from "php-serialize";
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ export function validateWebhook(req: NextApiRequest) {
|
||||||
// Grab p_signature
|
// Grab p_signature
|
||||||
const mySig = Buffer.from(jsonObj.p_signature, "base64");
|
const mySig = Buffer.from(jsonObj.p_signature, "base64");
|
||||||
// Remove p_signature from object - not included in array of fields used in verification.
|
// Remove p_signature from object - not included in array of fields used in verification.
|
||||||
delete jsonObj.p_signature;
|
jsonObj.p_signature = undefined;
|
||||||
// Need to sort array by key in ascending order
|
// Need to sort array by key in ascending order
|
||||||
jsonObj = ksort(jsonObj);
|
jsonObj = ksort(jsonObj);
|
||||||
for (const property in jsonObj) {
|
for (const property in jsonObj) {
|
||||||
|
@ -113,7 +113,7 @@ export default async function handler(
|
||||||
passthrough = JSON.parse(payload.passthrough) as PaddlePassthrough;
|
passthrough = JSON.parse(payload.passthrough) as PaddlePassthrough;
|
||||||
} catch {}
|
} catch {}
|
||||||
if (!passthrough) {
|
if (!passthrough) {
|
||||||
res.status(400).send("Invalid passthrough: " + payload.passthrough);
|
res.status(400).send(`Invalid passthrough: ${payload.passthrough}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +204,5 @@ export default async function handler(
|
||||||
|
|
||||||
// If everything went well, send a 200 OK
|
// If everything went well, send a 200 OK
|
||||||
return res.status(200).json({ success: true });
|
return res.status(200).json({ success: true });
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ export const polls = router({
|
||||||
let nextCursor: typeof cursor | undefined = undefined;
|
let nextCursor: typeof cursor | undefined = undefined;
|
||||||
if (polls.length > input.limit) {
|
if (polls.length > input.limit) {
|
||||||
const nextItem = polls.pop();
|
const nextItem = polls.pop();
|
||||||
nextCursor = nextItem!.id;
|
nextCursor = nextItem?.id;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
polls,
|
polls,
|
||||||
|
@ -304,12 +304,11 @@ export const polls = router({
|
||||||
duration: dayjs(end).diff(dayjs(start), "minute"),
|
duration: dayjs(end).diff(dayjs(start), "minute"),
|
||||||
pollId,
|
pollId,
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
startTime: dayjs(start).utc(true).toDate(),
|
|
||||||
pollId,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
startTime: dayjs(start).utc(true).toDate(),
|
||||||
|
pollId,
|
||||||
|
};
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -513,9 +512,8 @@ export const polls = router({
|
||||||
|
|
||||||
if (ctx.user.id === res.userId || res.adminUrlId === input.adminToken) {
|
if (ctx.user.id === res.userId || res.adminUrlId === input.adminToken) {
|
||||||
return { ...res, inviteLink };
|
return { ...res, inviteLink };
|
||||||
} else {
|
|
||||||
return { ...res, adminUrlId: "", inviteLink };
|
|
||||||
}
|
}
|
||||||
|
return { ...res, adminUrlId: "", inviteLink };
|
||||||
}),
|
}),
|
||||||
transfer: possiblyPublicProcedure
|
transfer: possiblyPublicProcedure
|
||||||
.input(
|
.input(
|
||||||
|
@ -876,104 +874,104 @@ export const polls = router({
|
||||||
code: "INTERNAL_SERVER_ERROR",
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
message: "Failed to generate ics",
|
message: "Failed to generate ics",
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
const timeZoneAbbrev = poll.timeZone
|
|
||||||
? getTimeZoneAbbreviation(eventStart.toDate(), poll.timeZone)
|
|
||||||
: "";
|
|
||||||
const date = eventStart.format("dddd, MMMM D, YYYY");
|
|
||||||
const day = eventStart.format("D");
|
|
||||||
const dow = eventStart.format("ddd");
|
|
||||||
const startTime = eventStart.format("hh:mm A");
|
|
||||||
const endTime = eventEnd.format("hh:mm A");
|
|
||||||
|
|
||||||
const time =
|
|
||||||
option.duration > 0
|
|
||||||
? `${startTime} - ${endTime} ${timeZoneAbbrev}`
|
|
||||||
: "All-day";
|
|
||||||
|
|
||||||
const participantsToEmail: Array<{
|
|
||||||
name: string;
|
|
||||||
email: string;
|
|
||||||
locale: string | undefined;
|
|
||||||
}> = [];
|
|
||||||
|
|
||||||
if (input.notify === "all") {
|
|
||||||
poll.participants.forEach((p) => {
|
|
||||||
if (p.email) {
|
|
||||||
participantsToEmail.push({
|
|
||||||
name: p.name,
|
|
||||||
email: p.email,
|
|
||||||
locale: p.locale ?? undefined,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.notify === "attendees") {
|
|
||||||
attendees.forEach((p) => {
|
|
||||||
if (p.email) {
|
|
||||||
participantsToEmail.push({
|
|
||||||
name: p.name,
|
|
||||||
email: p.email,
|
|
||||||
locale: p.locale ?? undefined,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.user.getEmailClient().queueTemplate("FinalizeHostEmail", {
|
|
||||||
to: poll.user.email,
|
|
||||||
props: {
|
|
||||||
name: poll.user.name,
|
|
||||||
pollUrl: absoluteUrl(`/poll/${poll.id}`),
|
|
||||||
location: poll.location,
|
|
||||||
title: poll.title,
|
|
||||||
attendees: poll.participants
|
|
||||||
.filter((p) =>
|
|
||||||
p.votes.some(
|
|
||||||
(v) => v.optionId === input.optionId && v.type !== "no",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.map((p) => p.name),
|
|
||||||
date,
|
|
||||||
day,
|
|
||||||
dow,
|
|
||||||
time,
|
|
||||||
},
|
|
||||||
attachments: [{ filename: "event.ics", content: event.value }],
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const p of participantsToEmail) {
|
|
||||||
getEmailClient(p.locale ?? undefined).queueTemplate(
|
|
||||||
"FinalizeParticipantEmail",
|
|
||||||
{
|
|
||||||
to: p.email,
|
|
||||||
props: {
|
|
||||||
pollUrl: absoluteUrl(`/invite/${poll.id}`),
|
|
||||||
title: poll.title,
|
|
||||||
hostName: poll.user?.name ?? "",
|
|
||||||
date,
|
|
||||||
day,
|
|
||||||
dow,
|
|
||||||
time,
|
|
||||||
},
|
|
||||||
attachments: [{ filename: "event.ics", content: event.value }],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
posthog?.capture({
|
|
||||||
distinctId: ctx.user.id,
|
|
||||||
event: "finalize poll",
|
|
||||||
properties: {
|
|
||||||
poll_id: poll.id,
|
|
||||||
poll_time_zone: poll.timeZone,
|
|
||||||
number_of_participants: poll.participants.length,
|
|
||||||
number_of_attendees: attendees.length,
|
|
||||||
days_since_created: dayjs().diff(poll.createdAt, "day"),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const timeZoneAbbrev = poll.timeZone
|
||||||
|
? getTimeZoneAbbreviation(eventStart.toDate(), poll.timeZone)
|
||||||
|
: "";
|
||||||
|
const date = eventStart.format("dddd, MMMM D, YYYY");
|
||||||
|
const day = eventStart.format("D");
|
||||||
|
const dow = eventStart.format("ddd");
|
||||||
|
const startTime = eventStart.format("hh:mm A");
|
||||||
|
const endTime = eventEnd.format("hh:mm A");
|
||||||
|
|
||||||
|
const time =
|
||||||
|
option.duration > 0
|
||||||
|
? `${startTime} - ${endTime} ${timeZoneAbbrev}`
|
||||||
|
: "All-day";
|
||||||
|
|
||||||
|
const participantsToEmail: Array<{
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
locale: string | undefined;
|
||||||
|
}> = [];
|
||||||
|
|
||||||
|
// if (input.notify === "all") {
|
||||||
|
// poll.participants.forEach((p) => {
|
||||||
|
// if (p.email) {
|
||||||
|
// participantsToEmail.push({
|
||||||
|
// name: p.name,
|
||||||
|
// email: p.email,
|
||||||
|
// locale: p.locale ?? undefined,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (input.notify === "attendees") {
|
||||||
|
// attendees.forEach((p) => {
|
||||||
|
// if (p.email) {
|
||||||
|
// participantsToEmail.push({
|
||||||
|
// name: p.name,
|
||||||
|
// email: p.email,
|
||||||
|
// locale: p.locale ?? undefined,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
ctx.user.getEmailClient().queueTemplate("FinalizeHostEmail", {
|
||||||
|
to: poll.user.email,
|
||||||
|
props: {
|
||||||
|
name: poll.user.name,
|
||||||
|
pollUrl: absoluteUrl(`/poll/${poll.id}`),
|
||||||
|
location: poll.location,
|
||||||
|
title: poll.title,
|
||||||
|
attendees: poll.participants
|
||||||
|
.filter((p) =>
|
||||||
|
p.votes.some(
|
||||||
|
(v) => v.optionId === input.optionId && v.type !== "no",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map((p) => p.name),
|
||||||
|
date,
|
||||||
|
day,
|
||||||
|
dow,
|
||||||
|
time,
|
||||||
|
},
|
||||||
|
attachments: [{ filename: "event.ics", content: event.value }],
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const p of participantsToEmail) {
|
||||||
|
getEmailClient(p.locale ?? undefined).queueTemplate(
|
||||||
|
"FinalizeParticipantEmail",
|
||||||
|
{
|
||||||
|
to: p.email,
|
||||||
|
props: {
|
||||||
|
pollUrl: absoluteUrl(`/invite/${poll.id}`),
|
||||||
|
title: poll.title,
|
||||||
|
hostName: poll.user?.name ?? "",
|
||||||
|
date,
|
||||||
|
day,
|
||||||
|
dow,
|
||||||
|
time,
|
||||||
|
},
|
||||||
|
attachments: [{ filename: "event.ics", content: event.value }],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
posthog?.capture({
|
||||||
|
distinctId: ctx.user.id,
|
||||||
|
event: "finalize poll",
|
||||||
|
properties: {
|
||||||
|
poll_id: poll.id,
|
||||||
|
poll_time_zone: poll.timeZone,
|
||||||
|
number_of_participants: poll.participants.length,
|
||||||
|
number_of_attendees: attendees.length,
|
||||||
|
days_since_created: dayjs().diff(poll.createdAt, "day"),
|
||||||
|
},
|
||||||
|
});
|
||||||
}),
|
}),
|
||||||
reopen: possiblyPublicProcedure
|
reopen: possiblyPublicProcedure
|
||||||
.input(
|
.input(
|
||||||
|
|
|
@ -21,7 +21,7 @@ export function objectToQueryString(obj: Record<string, string>) {
|
||||||
if (obj.hasOwnProperty(key)) {
|
if (obj.hasOwnProperty(key)) {
|
||||||
const value = obj[key];
|
const value = obj[key];
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
|
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ const avatarBackgroundColors: RGBColor[] = [
|
||||||
function isBright(color: RGBColor): boolean {
|
function isBright(color: RGBColor): boolean {
|
||||||
const [r, g, b] = color;
|
const [r, g, b] = color;
|
||||||
const L = (0.2126 * r) / 255 + (0.7152 * g) / 255 + (0.0722 * b) / 255;
|
const L = (0.2126 * r) / 255 + (0.7152 * g) / 255 + (0.0722 * b) / 255;
|
||||||
return L > 0.6 ? true : false;
|
return L > 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getRandomAvatarColor = (str: string) => {
|
export const getRandomAvatarColor = (str: string) => {
|
||||||
|
|
|
@ -224,9 +224,8 @@ export const DayjsProvider: React.FunctionComponent<{
|
||||||
(date: dayjs.ConfigType, localTime = false) => {
|
(date: dayjs.ConfigType, localTime = false) => {
|
||||||
if (!localTime) {
|
if (!localTime) {
|
||||||
return dayjs(date).tz(preferredTimeZone);
|
return dayjs(date).tz(preferredTimeZone);
|
||||||
} else {
|
|
||||||
return dayjs(date).utc();
|
|
||||||
}
|
}
|
||||||
|
return dayjs(date).utc();
|
||||||
},
|
},
|
||||||
[preferredTimeZone],
|
[preferredTimeZone],
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import path from "path";
|
import path from "node:path";
|
||||||
import { defineConfig } from "vitest/config";
|
import { defineConfig } from "vitest/config";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
|
|
@ -25,9 +25,8 @@ async function getSubscriptionsWithMissingMetadata(
|
||||||
subscriptions.data[subscriptions.data.length - 1].id,
|
subscriptions.data[subscriptions.data.length - 1].id,
|
||||||
)),
|
)),
|
||||||
];
|
];
|
||||||
} else {
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function normalizeSubscriptionMetadata() {
|
async function normalizeSubscriptionMetadata() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue