mirror of
https://github.com/lukevella/rallly.git
synced 2025-05-14 17:36:49 +02:00
♻️ Update trpcs routes (#531)
This commit is contained in:
parent
d9f6a0d097
commit
18eca7cd8c
32 changed files with 300 additions and 317 deletions
|
@ -27,10 +27,10 @@
|
||||||
"@svgr/webpack": "^6.5.1",
|
"@svgr/webpack": "^6.5.1",
|
||||||
"@tailwindcss/typography": "^0.5.9",
|
"@tailwindcss/typography": "^0.5.9",
|
||||||
"@tanstack/react-query": "^4.22.0",
|
"@tanstack/react-query": "^4.22.0",
|
||||||
"@trpc/client": "^10.0.0-rc.8",
|
"@trpc/client": "^10.13.0",
|
||||||
"@trpc/next": "^10.0.0-rc.8",
|
"@trpc/next": "^10.13.0",
|
||||||
"@trpc/react-query": "^10.0.0-rc.8",
|
"@trpc/react-query": "^10.13.0",
|
||||||
"@trpc/server": "^10.0.0-rc.8",
|
"@trpc/server": "^10.13.0",
|
||||||
"@vercel/analytics": "^0.1.8",
|
"@vercel/analytics": "^0.1.8",
|
||||||
"accept-language-parser": "^1.5.0",
|
"accept-language-parser": "^1.5.0",
|
||||||
"autoprefixer": "^10.4.13",
|
"autoprefixer": "^10.4.13",
|
||||||
|
|
|
@ -23,10 +23,7 @@ export const softDeleteMiddleware = (
|
||||||
params.args["data"] = { deleted: true, deletedAt: new Date() };
|
params.args["data"] = { deleted: true, deletedAt: new Date() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (params.action === "findUnique" || params.action === "findFirst") {
|
if (params.action === "findFirst") {
|
||||||
// Change to findFirst - you cannot filter
|
|
||||||
// by anything except ID / unique with findUnique
|
|
||||||
params.action = "findFirst";
|
|
||||||
// Add 'deleted' filter
|
// Add 'deleted' filter
|
||||||
// ID filter maintained
|
// ID filter maintained
|
||||||
params.args.where["deleted"] = params.args.where["deleted"] || false;
|
params.args.where["deleted"] = params.args.where["deleted"] || false;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { useMount } from "react-use";
|
||||||
import { Button } from "@/components/button";
|
import { Button } from "@/components/button";
|
||||||
import Share from "@/components/icons/share.svg";
|
import Share from "@/components/icons/share.svg";
|
||||||
|
|
||||||
import { trpc, trpcNext } from "../utils/trpc";
|
import { trpc } from "../utils/trpc";
|
||||||
import { useParticipants } from "./participants-provider";
|
import { useParticipants } from "./participants-provider";
|
||||||
import ManagePoll from "./poll/manage-poll";
|
import ManagePoll from "./poll/manage-poll";
|
||||||
import { useUpdatePollMutation } from "./poll/mutations";
|
import { useUpdatePollMutation } from "./poll/mutations";
|
||||||
|
@ -25,7 +25,7 @@ export const AdminControls = (props: { children?: React.ReactNode }) => {
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const queryClient = trpcNext.useContext();
|
const queryClient = trpc.useContext();
|
||||||
|
|
||||||
const session = useUser();
|
const session = useUser();
|
||||||
|
|
||||||
|
@ -48,10 +48,10 @@ export const AdminControls = (props: { children?: React.ReactNode }) => {
|
||||||
}
|
}
|
||||||
}, [urlId, router, updatePollMutation, t]);
|
}, [urlId, router, updatePollMutation, t]);
|
||||||
|
|
||||||
const verifyEmail = trpc.useMutation(["polls.verification.verify"], {
|
const verifyEmail = trpc.polls.verification.verify.useMutation({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success(t("pollHasBeenVerified"));
|
toast.success(t("pollHasBeenVerified"));
|
||||||
queryClient.poll.invalidate();
|
queryClient.polls.invalidate();
|
||||||
session.refresh();
|
session.refresh();
|
||||||
posthog.capture("verified email");
|
posthog.capture("verified email");
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,7 +5,7 @@ import React from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
|
||||||
import { requiredString, validEmail } from "../../utils/form-validation";
|
import { requiredString, validEmail } from "../../utils/form-validation";
|
||||||
import { trpcNext } from "../../utils/trpc";
|
import { trpc } from "../../utils/trpc";
|
||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
import { TextInput } from "../text-input";
|
import { TextInput } from "../text-input";
|
||||||
|
|
||||||
|
@ -133,9 +133,9 @@ export const RegisterForm: React.VoidFunctionComponent<{
|
||||||
useForm<RegisterFormData>({
|
useForm<RegisterFormData>({
|
||||||
defaultValues,
|
defaultValues,
|
||||||
});
|
});
|
||||||
const requestRegistration = trpcNext.auth.requestRegistration.useMutation();
|
const requestRegistration = trpc.auth.requestRegistration.useMutation();
|
||||||
const authenticateRegistration =
|
const authenticateRegistration =
|
||||||
trpcNext.auth.authenticateRegistration.useMutation();
|
trpc.auth.authenticateRegistration.useMutation();
|
||||||
const [token, setToken] = React.useState<string>();
|
const [token, setToken] = React.useState<string>();
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
|
@ -273,8 +273,8 @@ export const LoginForm: React.VoidFunctionComponent<{
|
||||||
const { t } = useTranslation("app");
|
const { t } = useTranslation("app");
|
||||||
const { register, handleSubmit, getValues, formState, setError } =
|
const { register, handleSubmit, getValues, formState, setError } =
|
||||||
useForm<{ email: string }>();
|
useForm<{ email: string }>();
|
||||||
const requestLogin = trpcNext.auth.requestLogin.useMutation();
|
const requestLogin = trpc.auth.requestLogin.useMutation();
|
||||||
const authenticateLogin = trpcNext.auth.authenticateLogin.useMutation();
|
const authenticateLogin = trpc.auth.authenticateLogin.useMutation();
|
||||||
|
|
||||||
const [token, setToken] = React.useState<string>();
|
const [token, setToken] = React.useState<string>();
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ const Page: NextPage<CreatePollPageProps> = ({
|
||||||
|
|
||||||
const [isRedirecting, setIsRedirecting] = React.useState(false);
|
const [isRedirecting, setIsRedirecting] = React.useState(false);
|
||||||
|
|
||||||
const createPoll = trpc.useMutation(["polls.create"], {
|
const createPoll = trpc.polls.create.useMutation({
|
||||||
onSuccess: (res) => {
|
onSuccess: (res) => {
|
||||||
setIsRedirecting(true);
|
setIsRedirecting(true);
|
||||||
posthog.capture("created poll", {
|
posthog.capture("created poll", {
|
||||||
|
|
|
@ -31,19 +31,20 @@ const Discussion: React.VoidFunctionComponent = () => {
|
||||||
|
|
||||||
const pollId = poll.id;
|
const pollId = poll.id;
|
||||||
|
|
||||||
const { data: comments } = trpc.useQuery(
|
const { data: comments } = trpc.polls.comments.list.useQuery(
|
||||||
["polls.comments.list", { pollId }],
|
{ pollId },
|
||||||
{
|
{
|
||||||
refetchInterval: 10000, // refetch every 10 seconds
|
refetchInterval: 10000, // refetch every 10 seconds
|
||||||
|
trpc: {},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const addComment = trpc.useMutation("polls.comments.add", {
|
const addComment = trpc.polls.comments.add.useMutation({
|
||||||
onSuccess: (newComment) => {
|
onSuccess: (newComment) => {
|
||||||
posthog.capture("created comment");
|
posthog.capture("created comment");
|
||||||
|
|
||||||
queryClient.setQueryData(
|
queryClient.polls.comments.list.setData(
|
||||||
["polls.comments.list", { pollId }],
|
{ pollId },
|
||||||
(existingComments = []) => {
|
(existingComments = []) => {
|
||||||
return [...existingComments, newComment];
|
return [...existingComments, newComment];
|
||||||
},
|
},
|
||||||
|
@ -51,10 +52,10 @@ const Discussion: React.VoidFunctionComponent = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const deleteComment = trpc.useMutation("polls.comments.delete", {
|
const deleteComment = trpc.polls.comments.delete.useMutation({
|
||||||
onMutate: ({ commentId }) => {
|
onMutate: ({ commentId }) => {
|
||||||
queryClient.setQueryData(
|
queryClient.polls.comments.list.setData(
|
||||||
["polls.comments.list", { pollId }],
|
{ pollId },
|
||||||
(existingComments = []) => {
|
(existingComments = []) => {
|
||||||
return [...existingComments].filter(({ id }) => id !== commentId);
|
return [...existingComments].filter(({ id }) => id !== commentId);
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,10 +22,7 @@ export const ParticipantsProvider: React.VoidFunctionComponent<{
|
||||||
}> = ({ children, pollId }) => {
|
}> = ({ children, pollId }) => {
|
||||||
const { t } = useTranslation("app");
|
const { t } = useTranslation("app");
|
||||||
|
|
||||||
const { data: participants } = trpc.useQuery([
|
const { data: participants } = trpc.polls.participants.list.useQuery({ pollId });
|
||||||
"polls.participants.list",
|
|
||||||
{ pollId },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const getParticipants = (
|
const getParticipants = (
|
||||||
optionId: string,
|
optionId: string,
|
||||||
|
|
|
@ -28,8 +28,6 @@ type PollContextValue = {
|
||||||
setTargetTimeZone: (timeZone: string) => void;
|
setTargetTimeZone: (timeZone: string) => void;
|
||||||
pollType: "date" | "timeSlot";
|
pollType: "date" | "timeSlot";
|
||||||
highScore: number;
|
highScore: number;
|
||||||
isDeleted: boolean;
|
|
||||||
setDeleted: React.Dispatch<React.SetStateAction<boolean>>;
|
|
||||||
optionIds: string[];
|
optionIds: string[];
|
||||||
// TODO (Luke Vella) [2022-05-18]: Move this stuff to participants provider
|
// TODO (Luke Vella) [2022-05-18]: Move this stuff to participants provider
|
||||||
getParticipantsWhoVotedForOption: (optionId: string) => Participant[]; // maybe just attach votes to parsed options
|
getParticipantsWhoVotedForOption: (optionId: string) => Participant[]; // maybe just attach votes to parsed options
|
||||||
|
@ -60,7 +58,6 @@ export const PollContextProvider: React.VoidFunctionComponent<{
|
||||||
}> = ({ poll, urlId, admin, children }) => {
|
}> = ({ poll, urlId, admin, children }) => {
|
||||||
const { t } = useTranslation("app");
|
const { t } = useTranslation("app");
|
||||||
const { participants } = useParticipants();
|
const { participants } = useParticipants();
|
||||||
const [isDeleted, setDeleted] = React.useState(false);
|
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
const [targetTimeZone, setTargetTimeZone] =
|
const [targetTimeZone, setTargetTimeZone] =
|
||||||
React.useState(getBrowserTimeZone);
|
React.useState(getBrowserTimeZone);
|
||||||
|
@ -159,13 +156,10 @@ export const PollContextProvider: React.VoidFunctionComponent<{
|
||||||
...parsedOptions,
|
...parsedOptions,
|
||||||
targetTimeZone,
|
targetTimeZone,
|
||||||
setTargetTimeZone,
|
setTargetTimeZone,
|
||||||
isDeleted,
|
|
||||||
setDeleted,
|
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
admin,
|
admin,
|
||||||
getScore,
|
getScore,
|
||||||
isDeleted,
|
|
||||||
participants,
|
participants,
|
||||||
poll,
|
poll,
|
||||||
targetTimeZone,
|
targetTimeZone,
|
||||||
|
@ -174,7 +168,7 @@ export const PollContextProvider: React.VoidFunctionComponent<{
|
||||||
user,
|
user,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (isDeleted) {
|
if (poll.deleted) {
|
||||||
return (
|
return (
|
||||||
<ErrorPage
|
<ErrorPage
|
||||||
icon={Trash}
|
icon={Trash}
|
||||||
|
|
|
@ -27,8 +27,7 @@ const ManagePoll: React.VoidFunctionComponent<{
|
||||||
placement?: Placement;
|
placement?: Placement;
|
||||||
}> = ({ placement }) => {
|
}> = ({ placement }) => {
|
||||||
const { t } = useTranslation("app");
|
const { t } = useTranslation("app");
|
||||||
const { poll, getParticipantsWhoVotedForOption, setDeleted, urlId } =
|
const { poll, getParticipantsWhoVotedForOption, urlId } = usePoll();
|
||||||
usePoll();
|
|
||||||
|
|
||||||
const { exportToCsv } = useCsvExporter();
|
const { exportToCsv } = useCsvExporter();
|
||||||
|
|
||||||
|
@ -218,7 +217,6 @@ const ManagePoll: React.VoidFunctionComponent<{
|
||||||
<DeletePollForm
|
<DeletePollForm
|
||||||
onConfirm={async () => {
|
onConfirm={async () => {
|
||||||
close();
|
close();
|
||||||
setDeleted(true);
|
|
||||||
}}
|
}}
|
||||||
onCancel={close}
|
onCancel={close}
|
||||||
urlId={urlId}
|
urlId={urlId}
|
||||||
|
|
|
@ -21,7 +21,7 @@ export const DeletePollForm: React.VoidFunctionComponent<{
|
||||||
|
|
||||||
const confirmationText = watch("confirmation");
|
const confirmationText = watch("confirmation");
|
||||||
const canDelete = confirmationText === confirmText;
|
const canDelete = confirmationText === confirmText;
|
||||||
const deletePoll = trpc.useMutation("polls.delete", {
|
const deletePoll = trpc.polls.delete.useMutation({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
posthog.capture("deleted poll");
|
posthog.capture("deleted poll");
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import posthog from "posthog-js";
|
import posthog from "posthog-js";
|
||||||
|
|
||||||
import { trpc, trpcNext } from "../../utils/trpc";
|
import { trpc } from "../../utils/trpc";
|
||||||
import { ParticipantForm } from "./types";
|
import { ParticipantForm } from "./types";
|
||||||
|
|
||||||
export const normalizeVotes = (
|
export const normalizeVotes = (
|
||||||
|
@ -14,32 +14,24 @@ export const normalizeVotes = (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useAddParticipantMutation = () => {
|
export const useAddParticipantMutation = () => {
|
||||||
const queryClient = trpc.useContext();
|
return trpc.polls.participants.add.useMutation({
|
||||||
|
|
||||||
return trpc.useMutation(["polls.participants.add"], {
|
|
||||||
onSuccess: (participant) => {
|
onSuccess: (participant) => {
|
||||||
posthog.capture("add participant", {
|
posthog.capture("add participant", {
|
||||||
name: participant.name,
|
name: participant.name,
|
||||||
});
|
});
|
||||||
queryClient.setQueryData(
|
|
||||||
["polls.participants.list", { pollId: participant.pollId }],
|
|
||||||
(existingParticipants = []) => {
|
|
||||||
return [participant, ...existingParticipants];
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUpdateParticipantMutation = () => {
|
export const useUpdateParticipantMutation = () => {
|
||||||
const queryClient = trpc.useContext();
|
const queryClient = trpc.useContext();
|
||||||
return trpc.useMutation("polls.participants.update", {
|
return trpc.polls.participants.update.useMutation({
|
||||||
onSuccess: (participant) => {
|
onSuccess: (participant) => {
|
||||||
posthog.capture("update participant", {
|
posthog.capture("update participant", {
|
||||||
name: participant.name,
|
name: participant.name,
|
||||||
});
|
});
|
||||||
queryClient.setQueryData(
|
queryClient.polls.participants.list.setData(
|
||||||
["polls.participants.list", { pollId: participant.pollId }],
|
{ pollId: participant.pollId },
|
||||||
(existingParticipants = []) => {
|
(existingParticipants = []) => {
|
||||||
const newParticipants = [...existingParticipants];
|
const newParticipants = [...existingParticipants];
|
||||||
|
|
||||||
|
@ -60,10 +52,10 @@ export const useUpdateParticipantMutation = () => {
|
||||||
|
|
||||||
export const useDeleteParticipantMutation = () => {
|
export const useDeleteParticipantMutation = () => {
|
||||||
const queryClient = trpc.useContext();
|
const queryClient = trpc.useContext();
|
||||||
return trpc.useMutation("polls.participants.delete", {
|
return trpc.polls.participants.delete.useMutation({
|
||||||
onMutate: ({ participantId, pollId }) => {
|
onMutate: ({ participantId, pollId }) => {
|
||||||
queryClient.setQueryData(
|
queryClient.polls.participants.list.setData(
|
||||||
["polls.participants.list", { pollId: pollId }],
|
{ pollId: pollId },
|
||||||
(existingParticipants = []) => {
|
(existingParticipants = []) => {
|
||||||
return existingParticipants.filter(({ id }) => id !== participantId);
|
return existingParticipants.filter(({ id }) => id !== participantId);
|
||||||
},
|
},
|
||||||
|
@ -78,10 +70,10 @@ export const useDeleteParticipantMutation = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUpdatePollMutation = () => {
|
export const useUpdatePollMutation = () => {
|
||||||
const queryClient = trpcNext.useContext();
|
const queryClient = trpc.useContext();
|
||||||
return trpc.useMutation(["polls.update"], {
|
return trpc.polls.update.useMutation({
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
queryClient.poll.invalidate();
|
queryClient.polls.invalidate();
|
||||||
posthog.capture("updated poll", {
|
posthog.capture("updated poll", {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,9 +7,8 @@ import { usePoll } from "../poll-context";
|
||||||
export const UnverifiedPollNotice = () => {
|
export const UnverifiedPollNotice = () => {
|
||||||
const { t } = useTranslation("app");
|
const { t } = useTranslation("app");
|
||||||
const { poll } = usePoll();
|
const { poll } = usePoll();
|
||||||
const requestVerificationEmail = trpc.useMutation(
|
const requestVerificationEmail = trpc.polls.verification.request.useMutation(
|
||||||
"polls.verification.request",
|
);
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-3 rounded-md border border-amber-200 bg-amber-100 p-3 text-gray-700 shadow-sm">
|
<div className="space-y-3 rounded-md border border-amber-200 bg-amber-100 p-3 text-gray-700 shadow-sm">
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { trpc } from "../../utils/trpc";
|
||||||
* find polls that haven't been accessed for some time so that they can be deleted by house keeping.
|
* find polls that haven't been accessed for some time so that they can be deleted by house keeping.
|
||||||
*/
|
*/
|
||||||
export const useTouchBeacon = (pollId: string) => {
|
export const useTouchBeacon = (pollId: string) => {
|
||||||
const touchMutation = trpc.useMutation(["polls.touch"]);
|
const touchMutation = trpc.polls.touch.useMutation();
|
||||||
|
|
||||||
useMount(() => {
|
useMount(() => {
|
||||||
touchMutation.mutate({ pollId });
|
touchMutation.mutate({ pollId });
|
||||||
|
|
|
@ -19,7 +19,7 @@ export const Profile: React.VoidFunctionComponent = () => {
|
||||||
const { dayjs } = useDayjs();
|
const { dayjs } = useDayjs();
|
||||||
|
|
||||||
const { t } = useTranslation("app");
|
const { t } = useTranslation("app");
|
||||||
const { data: userPolls } = trpc.useQuery(["user.getPolls"]);
|
const { data: userPolls } = trpc.user.getPolls.useQuery();
|
||||||
|
|
||||||
const createdPolls = userPolls?.polls;
|
const createdPolls = userPolls?.polls;
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const UserDetails: React.VoidFunctionComponent<UserDetailsProps> = ({
|
||||||
|
|
||||||
const { refresh } = useUser();
|
const { refresh } = useUser();
|
||||||
|
|
||||||
const changeName = trpc.useMutation("user.changeName", {
|
const changeName = trpc.user.changeName.useMutation({
|
||||||
onSuccess: (_, { name }) => {
|
onSuccess: (_, { name }) => {
|
||||||
posthog.people.set({ name });
|
posthog.people.set({ name });
|
||||||
refresh();
|
refresh();
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { useMount } from "react-use";
|
||||||
|
|
||||||
import { UserSession } from "@/utils/auth";
|
import { UserSession } from "@/utils/auth";
|
||||||
|
|
||||||
import { trpcNext } from "../utils/trpc";
|
import { trpc } from "../utils/trpc";
|
||||||
import { useRequiredContext } from "./use-required-context";
|
import { useRequiredContext } from "./use-required-context";
|
||||||
|
|
||||||
export const UserContext =
|
export const UserContext =
|
||||||
|
@ -51,12 +51,12 @@ export const IfGuest = (props: { children?: React.ReactNode }) => {
|
||||||
export const UserProvider = (props: { children?: React.ReactNode }) => {
|
export const UserProvider = (props: { children?: React.ReactNode }) => {
|
||||||
const { t } = useTranslation("app");
|
const { t } = useTranslation("app");
|
||||||
|
|
||||||
const queryClient = trpcNext.useContext();
|
const queryClient = trpc.useContext();
|
||||||
const { data: user } = trpcNext.whoami.get.useQuery();
|
const { data: user } = trpc.whoami.get.useQuery();
|
||||||
|
|
||||||
const [isUpdating, setIsUpdating] = React.useState(false);
|
const [isUpdating, setIsUpdating] = React.useState(false);
|
||||||
|
|
||||||
const logout = trpcNext.whoami.destroy.useMutation({
|
const logout = trpc.whoami.destroy.useMutation({
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
setIsUpdating(true);
|
setIsUpdating(true);
|
||||||
await queryClient.whoami.invalidate();
|
await queryClient.whoami.invalidate();
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { useCrispChat } from "../components/crisp-chat";
|
||||||
import { NextPageWithLayout } from "../types";
|
import { NextPageWithLayout } from "../types";
|
||||||
import { absoluteUrl } from "../utils/absolute-url";
|
import { absoluteUrl } from "../utils/absolute-url";
|
||||||
import { UserSession } from "../utils/auth";
|
import { UserSession } from "../utils/auth";
|
||||||
import { trpcNext } from "../utils/trpc";
|
import { trpc } from "../utils/trpc";
|
||||||
|
|
||||||
const inter = Inter({
|
const inter = Inter({
|
||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
|
@ -93,4 +93,4 @@ const MyApp: NextPage<AppPropsWithLayout> = ({ Component, pageProps }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default trpcNext.withTRPC(appWithTranslation(MyApp));
|
export default trpc.withTRPC(appWithTranslation(MyApp));
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { ParticipantsProvider } from "@/components/participants-provider";
|
||||||
import { Poll } from "@/components/poll";
|
import { Poll } from "@/components/poll";
|
||||||
import { PollContextProvider } from "@/components/poll-context";
|
import { PollContextProvider } from "@/components/poll-context";
|
||||||
import { withSessionSsr } from "@/utils/auth";
|
import { withSessionSsr } from "@/utils/auth";
|
||||||
import { trpcNext } from "@/utils/trpc";
|
import { trpc } from "@/utils/trpc";
|
||||||
import { withPageTranslations } from "@/utils/with-page-translations";
|
import { withPageTranslations } from "@/utils/with-page-translations";
|
||||||
|
|
||||||
import { AdminControls } from "../../components/admin-control";
|
import { AdminControls } from "../../components/admin-control";
|
||||||
|
@ -18,7 +18,7 @@ import { NextPageWithLayout } from "../../types";
|
||||||
const Page: NextPageWithLayout<{ urlId: string }> = ({ urlId }) => {
|
const Page: NextPageWithLayout<{ urlId: string }> = ({ urlId }) => {
|
||||||
const { t } = useTranslation("app");
|
const { t } = useTranslation("app");
|
||||||
|
|
||||||
const pollQuery = trpcNext.poll.getByAdminUrlId.useQuery({ urlId });
|
const pollQuery = trpc.polls.getByAdminUrlId.useQuery({ urlId });
|
||||||
|
|
||||||
const poll = pollQuery.data;
|
const poll = pollQuery.data;
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ export const getServerSideProps: GetServerSideProps = withSessionSsr(
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
onPrefetch: async (ssg, ctx) => {
|
onPrefetch: async (ssg, ctx) => {
|
||||||
await ssg.poll.getByAdminUrlId.fetch({
|
await ssg.polls.getByAdminUrlId.fetch({
|
||||||
urlId: ctx.params?.urlId as string,
|
urlId: ctx.params?.urlId as string,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,7 +15,7 @@ const Demo: NextPage = () => {
|
||||||
const { t } = useTranslation("app");
|
const { t } = useTranslation("app");
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const createDemo = trpc.useMutation(["polls.demo.create"]);
|
const createDemo = trpc.polls.demo.create.useMutation();
|
||||||
|
|
||||||
useMount(async () => {
|
useMount(async () => {
|
||||||
const urlId = await createDemo.mutateAsync();
|
const urlId = await createDemo.mutateAsync();
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { Poll } from "@/components/poll";
|
||||||
import { PollContextProvider } from "@/components/poll-context";
|
import { PollContextProvider } from "@/components/poll-context";
|
||||||
import { useUser } from "@/components/user-provider";
|
import { useUser } from "@/components/user-provider";
|
||||||
import { withSessionSsr } from "@/utils/auth";
|
import { withSessionSsr } from "@/utils/auth";
|
||||||
import { trpcNext } from "@/utils/trpc";
|
import { trpc } from "@/utils/trpc";
|
||||||
import { withPageTranslations } from "@/utils/with-page-translations";
|
import { withPageTranslations } from "@/utils/with-page-translations";
|
||||||
|
|
||||||
import StandardLayout from "../../components/layouts/standard-layout";
|
import StandardLayout from "../../components/layouts/standard-layout";
|
||||||
|
@ -16,7 +16,7 @@ import ModalProvider from "../../components/modal/modal-provider";
|
||||||
import { NextPageWithLayout } from "../../types";
|
import { NextPageWithLayout } from "../../types";
|
||||||
|
|
||||||
const Page: NextPageWithLayout<{ urlId: string }> = ({ urlId }) => {
|
const Page: NextPageWithLayout<{ urlId: string }> = ({ urlId }) => {
|
||||||
const pollQuery = trpcNext.poll.getByParticipantUrlId.useQuery({ urlId });
|
const pollQuery = trpc.polls.getByParticipantUrlId.useQuery({ urlId });
|
||||||
|
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
const poll = pollQuery.data;
|
const poll = pollQuery.data;
|
||||||
|
@ -70,7 +70,7 @@ export const getServerSideProps: GetServerSideProps = withSessionSsr(
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
onPrefetch: async (ssg, ctx) => {
|
onPrefetch: async (ssg, ctx) => {
|
||||||
await ssg.poll.getByParticipantUrlId.fetch({
|
await ssg.polls.getByParticipantUrlId.fetch({
|
||||||
urlId: ctx.params?.urlId as string,
|
urlId: ctx.params?.urlId as string,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import * as trpc from "@trpc/server";
|
|
||||||
|
|
||||||
import { Context } from "./context";
|
|
||||||
|
|
||||||
// Helper function to create a router with your app's context
|
|
||||||
export function createRouter() {
|
|
||||||
return trpc.router<Context>();
|
|
||||||
}
|
|
|
@ -1,22 +1,17 @@
|
||||||
import { createRouter } from "../createRouter";
|
|
||||||
import { mergeRouters, router } from "../trpc";
|
import { mergeRouters, router } from "../trpc";
|
||||||
import { auth } from "./auth";
|
import { auth } from "./auth";
|
||||||
import { login } from "./login";
|
import { login } from "./login";
|
||||||
import { legacyPolls, poll } from "./polls";
|
import { polls } from "./polls";
|
||||||
import { user } from "./user";
|
import { user } from "./user";
|
||||||
import { whoami } from "./whoami";
|
import { whoami } from "./whoami";
|
||||||
|
|
||||||
const legacyRouter = createRouter()
|
|
||||||
.merge("user.", user)
|
|
||||||
.merge(login)
|
|
||||||
.merge("polls.", legacyPolls);
|
|
||||||
|
|
||||||
export const appRouter = mergeRouters(
|
export const appRouter = mergeRouters(
|
||||||
legacyRouter.interop(),
|
|
||||||
router({
|
router({
|
||||||
whoami,
|
whoami,
|
||||||
auth,
|
auth,
|
||||||
poll,
|
polls,
|
||||||
|
user,
|
||||||
|
login,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -5,35 +5,38 @@ import loginTemplate from "~/templates/login";
|
||||||
import { absoluteUrl } from "../../utils/absolute-url";
|
import { absoluteUrl } from "../../utils/absolute-url";
|
||||||
import { sendEmailTemplate } from "../../utils/api-utils";
|
import { sendEmailTemplate } from "../../utils/api-utils";
|
||||||
import { createToken } from "../../utils/auth";
|
import { createToken } from "../../utils/auth";
|
||||||
import { createRouter } from "../createRouter";
|
import { publicProcedure, router } from "../trpc";
|
||||||
|
|
||||||
export const login = createRouter().mutation("login", {
|
export const login = router({
|
||||||
input: z.object({
|
login: publicProcedure
|
||||||
email: z.string(),
|
.input(
|
||||||
path: z.string(),
|
z.object({
|
||||||
}),
|
email: z.string(),
|
||||||
resolve: async ({ ctx, input }) => {
|
path: z.string(),
|
||||||
const { email, path } = input;
|
}),
|
||||||
const homePageUrl = absoluteUrl();
|
)
|
||||||
const user = ctx.session.user;
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
const { email, path } = input;
|
||||||
|
const homePageUrl = absoluteUrl();
|
||||||
|
const user = ctx.session.user;
|
||||||
|
|
||||||
const token = await createToken({
|
const token = await createToken({
|
||||||
email,
|
email,
|
||||||
guestId: user.id,
|
guestId: user.id,
|
||||||
path,
|
path,
|
||||||
});
|
});
|
||||||
|
|
||||||
const loginUrl = `${homePageUrl}/login?code=${token}`;
|
const loginUrl = `${homePageUrl}/login?code=${token}`;
|
||||||
|
|
||||||
await sendEmailTemplate({
|
await sendEmailTemplate({
|
||||||
templateString: loginTemplate,
|
templateString: loginTemplate,
|
||||||
to: email,
|
to: email,
|
||||||
subject: "Rallly - Login",
|
subject: "Rallly - Login",
|
||||||
templateVars: {
|
templateVars: {
|
||||||
loginUrl,
|
loginUrl,
|
||||||
homePageUrl,
|
homePageUrl,
|
||||||
supportEmail: process.env.SUPPORT_EMAIL,
|
supportEmail: process.env.SUPPORT_EMAIL,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { sendEmailTemplate } from "../../utils/api-utils";
|
||||||
import { createToken } from "../../utils/auth";
|
import { createToken } from "../../utils/auth";
|
||||||
import { nanoid } from "../../utils/nanoid";
|
import { nanoid } from "../../utils/nanoid";
|
||||||
import { GetPollApiResponse } from "../../utils/trpc/types";
|
import { GetPollApiResponse } from "../../utils/trpc/types";
|
||||||
import { createRouter } from "../createRouter";
|
|
||||||
import { publicProcedure, router } from "../trpc";
|
import { publicProcedure, router } from "../trpc";
|
||||||
import { comments } from "./polls/comments";
|
import { comments } from "./polls/comments";
|
||||||
import { demo } from "./polls/demo";
|
import { demo } from "./polls/demo";
|
||||||
|
@ -38,6 +37,7 @@ const defaultSelectFields: {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
user: true;
|
user: true;
|
||||||
|
deleted: true;
|
||||||
} = {
|
} = {
|
||||||
id: true,
|
id: true,
|
||||||
timeZone: true,
|
timeZone: true,
|
||||||
|
@ -59,6 +59,7 @@ const defaultSelectFields: {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
user: true,
|
user: true,
|
||||||
|
deleted: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPollIdFromAdminUrlId = async (urlId: string) => {
|
const getPollIdFromAdminUrlId = async (urlId: string) => {
|
||||||
|
@ -77,26 +78,25 @@ const getPollIdFromAdminUrlId = async (urlId: string) => {
|
||||||
return res.id;
|
return res.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const legacyPolls = createRouter()
|
export const polls = router({
|
||||||
.merge("demo.", demo)
|
// START LEGACY ROUTES
|
||||||
.merge("participants.", participants)
|
create: publicProcedure
|
||||||
.merge("comments.", comments)
|
.input(
|
||||||
.merge("verification.", verification)
|
z.object({
|
||||||
.mutation("create", {
|
title: z.string(),
|
||||||
input: z.object({
|
type: z.literal("date"),
|
||||||
title: z.string(),
|
timeZone: z.string().optional(),
|
||||||
type: z.literal("date"),
|
location: z.string().optional(),
|
||||||
timeZone: z.string().optional(),
|
description: z.string().optional(),
|
||||||
location: z.string().optional(),
|
user: z.object({
|
||||||
description: z.string().optional(),
|
name: z.string(),
|
||||||
user: z.object({
|
email: z.string(),
|
||||||
name: z.string(),
|
}),
|
||||||
email: z.string(),
|
options: z.string().array(),
|
||||||
|
demo: z.boolean().optional(),
|
||||||
}),
|
}),
|
||||||
options: z.string().array(),
|
)
|
||||||
demo: z.boolean().optional(),
|
.mutation(async ({ ctx, input }): Promise<{ urlId: string }> => {
|
||||||
}),
|
|
||||||
resolve: async ({ ctx, input }): Promise<{ urlId: string }> => {
|
|
||||||
const adminUrlId = await nanoid();
|
const adminUrlId = await nanoid();
|
||||||
|
|
||||||
let verified = false;
|
let verified = false;
|
||||||
|
@ -188,21 +188,22 @@ export const legacyPolls = createRouter()
|
||||||
}
|
}
|
||||||
|
|
||||||
return { urlId: adminUrlId };
|
return { urlId: adminUrlId };
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation("update", {
|
|
||||||
input: z.object({
|
|
||||||
urlId: z.string(),
|
|
||||||
title: z.string().optional(),
|
|
||||||
timeZone: z.string().optional(),
|
|
||||||
location: z.string().optional(),
|
|
||||||
description: z.string().optional(),
|
|
||||||
optionsToDelete: z.string().array().optional(),
|
|
||||||
optionsToAdd: z.string().array().optional(),
|
|
||||||
notifications: z.boolean().optional(),
|
|
||||||
closed: z.boolean().optional(),
|
|
||||||
}),
|
}),
|
||||||
resolve: async ({ input }): Promise<GetPollApiResponse> => {
|
update: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
urlId: z.string(),
|
||||||
|
title: z.string().optional(),
|
||||||
|
timeZone: z.string().optional(),
|
||||||
|
location: z.string().optional(),
|
||||||
|
description: z.string().optional(),
|
||||||
|
optionsToDelete: z.string().array().optional(),
|
||||||
|
optionsToAdd: z.string().array().optional(),
|
||||||
|
notifications: z.boolean().optional(),
|
||||||
|
closed: z.boolean().optional(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }): Promise<GetPollApiResponse> => {
|
||||||
const pollId = await getPollIdFromAdminUrlId(input.urlId);
|
const pollId = await getPollIdFromAdminUrlId(input.urlId);
|
||||||
|
|
||||||
if (input.optionsToDelete && input.optionsToDelete.length > 0) {
|
if (input.optionsToDelete && input.optionsToDelete.length > 0) {
|
||||||
|
@ -241,22 +242,24 @@ export const legacyPolls = createRouter()
|
||||||
});
|
});
|
||||||
|
|
||||||
return { ...poll };
|
return { ...poll };
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation("delete", {
|
|
||||||
input: z.object({
|
|
||||||
urlId: z.string(),
|
|
||||||
}),
|
}),
|
||||||
resolve: async ({ input: { urlId } }) => {
|
delete: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
urlId: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input: { urlId } }) => {
|
||||||
const pollId = await getPollIdFromAdminUrlId(urlId);
|
const pollId = await getPollIdFromAdminUrlId(urlId);
|
||||||
await prisma.poll.delete({ where: { id: pollId } });
|
await prisma.poll.delete({ where: { id: pollId } });
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation("touch", {
|
|
||||||
input: z.object({
|
|
||||||
pollId: z.string(),
|
|
||||||
}),
|
}),
|
||||||
resolve: async ({ input: { pollId } }) => {
|
touch: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
pollId: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input: { pollId } }) => {
|
||||||
await prisma.poll.update({
|
await prisma.poll.update({
|
||||||
where: {
|
where: {
|
||||||
id: pollId,
|
id: pollId,
|
||||||
|
@ -265,10 +268,12 @@ export const legacyPolls = createRouter()
|
||||||
touchedAt: new Date(),
|
touchedAt: new Date(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
}),
|
||||||
});
|
demo,
|
||||||
|
participants,
|
||||||
export const poll = router({
|
comments,
|
||||||
|
verification,
|
||||||
|
// END LEGACY ROUTES
|
||||||
getByAdminUrlId: publicProcedure
|
getByAdminUrlId: publicProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
|
|
|
@ -3,14 +3,16 @@ import { z } from "zod";
|
||||||
import { prisma } from "~/prisma/db";
|
import { prisma } from "~/prisma/db";
|
||||||
|
|
||||||
import { sendNotification } from "../../../utils/api-utils";
|
import { sendNotification } from "../../../utils/api-utils";
|
||||||
import { createRouter } from "../../createRouter";
|
import { publicProcedure, router } from "../../trpc";
|
||||||
|
|
||||||
export const comments = createRouter()
|
export const comments = router({
|
||||||
.query("list", {
|
list: publicProcedure
|
||||||
input: z.object({
|
.input(
|
||||||
pollId: z.string(),
|
z.object({
|
||||||
}),
|
pollId: z.string(),
|
||||||
resolve: async ({ input: { pollId } }) => {
|
}),
|
||||||
|
)
|
||||||
|
.query(async ({ input: { pollId } }) => {
|
||||||
return await prisma.comment.findMany({
|
return await prisma.comment.findMany({
|
||||||
where: { pollId },
|
where: { pollId },
|
||||||
orderBy: [
|
orderBy: [
|
||||||
|
@ -19,15 +21,16 @@ export const comments = createRouter()
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation("add", {
|
|
||||||
input: z.object({
|
|
||||||
pollId: z.string(),
|
|
||||||
authorName: z.string(),
|
|
||||||
content: z.string(),
|
|
||||||
}),
|
}),
|
||||||
resolve: async ({ ctx, input: { pollId, authorName, content } }) => {
|
add: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
pollId: z.string(),
|
||||||
|
authorName: z.string(),
|
||||||
|
content: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ ctx, input: { pollId, authorName, content } }) => {
|
||||||
const user = ctx.session.user;
|
const user = ctx.session.user;
|
||||||
|
|
||||||
const newComment = await prisma.comment.create({
|
const newComment = await prisma.comment.create({
|
||||||
|
@ -45,14 +48,15 @@ export const comments = createRouter()
|
||||||
});
|
});
|
||||||
|
|
||||||
return newComment;
|
return newComment;
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation("delete", {
|
|
||||||
input: z.object({
|
|
||||||
pollId: z.string(),
|
|
||||||
commentId: z.string(),
|
|
||||||
}),
|
}),
|
||||||
resolve: async ({ input: { pollId, commentId } }) => {
|
delete: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
pollId: z.string(),
|
||||||
|
commentId: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input: { pollId, commentId } }) => {
|
||||||
await prisma.comment.delete({
|
await prisma.comment.delete({
|
||||||
where: {
|
where: {
|
||||||
id_pollId: {
|
id_pollId: {
|
||||||
|
@ -61,5 +65,5 @@ export const comments = createRouter()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@ import dayjs from "dayjs";
|
||||||
import { prisma } from "~/prisma/db";
|
import { prisma } from "~/prisma/db";
|
||||||
|
|
||||||
import { nanoid } from "../../../utils/nanoid";
|
import { nanoid } from "../../../utils/nanoid";
|
||||||
import { createRouter } from "../../createRouter";
|
import { publicProcedure, router } from "../../trpc";
|
||||||
|
|
||||||
const participantData: Array<{ name: string; votes: VoteType[] }> = [
|
const participantData: Array<{ name: string; votes: VoteType[] }> = [
|
||||||
{
|
{
|
||||||
|
@ -27,8 +27,8 @@ const participantData: Array<{ name: string; votes: VoteType[] }> = [
|
||||||
|
|
||||||
const optionValues = ["2022-12-14", "2022-12-15", "2022-12-16", "2022-12-17"];
|
const optionValues = ["2022-12-14", "2022-12-15", "2022-12-16", "2022-12-17"];
|
||||||
|
|
||||||
export const demo = createRouter().mutation("create", {
|
export const demo = router({
|
||||||
resolve: async () => {
|
create: publicProcedure.mutation(async () => {
|
||||||
const adminUrlId = await nanoid();
|
const adminUrlId = await nanoid();
|
||||||
const demoUser = { name: "John Example", email: "noreply@rallly.co" };
|
const demoUser = { name: "John Example", email: "noreply@rallly.co" };
|
||||||
|
|
||||||
|
@ -111,5 +111,5 @@ export const demo = createRouter().mutation("create", {
|
||||||
});
|
});
|
||||||
|
|
||||||
return adminUrlId;
|
return adminUrlId;
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,14 +3,16 @@ import { z } from "zod";
|
||||||
import { prisma } from "~/prisma/db";
|
import { prisma } from "~/prisma/db";
|
||||||
|
|
||||||
import { sendNotification } from "../../../utils/api-utils";
|
import { sendNotification } from "../../../utils/api-utils";
|
||||||
import { createRouter } from "../../createRouter";
|
import { publicProcedure, router } from "../../trpc";
|
||||||
|
|
||||||
export const participants = createRouter()
|
export const participants = router({
|
||||||
.query("list", {
|
list: publicProcedure
|
||||||
input: z.object({
|
.input(
|
||||||
pollId: z.string(),
|
z.object({
|
||||||
}),
|
pollId: z.string(),
|
||||||
resolve: async ({ input: { pollId } }) => {
|
}),
|
||||||
|
)
|
||||||
|
.query(async ({ input: { pollId } }) => {
|
||||||
const participants = await prisma.participant.findMany({
|
const participants = await prisma.participant.findMany({
|
||||||
where: {
|
where: {
|
||||||
pollId,
|
pollId,
|
||||||
|
@ -26,33 +28,35 @@ export const participants = createRouter()
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
return participants;
|
return participants;
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation("delete", {
|
|
||||||
input: z.object({
|
|
||||||
pollId: z.string(),
|
|
||||||
participantId: z.string(),
|
|
||||||
}),
|
}),
|
||||||
resolve: async ({ input: { participantId } }) => {
|
delete: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
pollId: z.string(),
|
||||||
|
participantId: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input: { participantId } }) => {
|
||||||
await prisma.participant.delete({
|
await prisma.participant.delete({
|
||||||
where: {
|
where: {
|
||||||
id: participantId,
|
id: participantId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation("add", {
|
|
||||||
input: z.object({
|
|
||||||
pollId: z.string(),
|
|
||||||
name: z.string().nonempty("Participant name is required"),
|
|
||||||
votes: z
|
|
||||||
.object({
|
|
||||||
optionId: z.string(),
|
|
||||||
type: z.enum(["yes", "no", "ifNeedBe"]),
|
|
||||||
})
|
|
||||||
.array(),
|
|
||||||
}),
|
}),
|
||||||
resolve: async ({ ctx, input: { pollId, votes, name } }) => {
|
add: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
pollId: z.string(),
|
||||||
|
name: z.string().nonempty("Participant name is required"),
|
||||||
|
votes: z
|
||||||
|
.object({
|
||||||
|
optionId: z.string(),
|
||||||
|
type: z.enum(["yes", "no", "ifNeedBe"]),
|
||||||
|
})
|
||||||
|
.array(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ ctx, input: { pollId, votes, name } }) => {
|
||||||
const user = ctx.session.user;
|
const user = ctx.session.user;
|
||||||
const participant = await prisma.participant.create({
|
const participant = await prisma.participant.create({
|
||||||
data: {
|
data: {
|
||||||
|
@ -80,20 +84,21 @@ export const participants = createRouter()
|
||||||
});
|
});
|
||||||
|
|
||||||
return participant;
|
return participant;
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation("update", {
|
|
||||||
input: z.object({
|
|
||||||
pollId: z.string(),
|
|
||||||
participantId: z.string(),
|
|
||||||
votes: z
|
|
||||||
.object({
|
|
||||||
optionId: z.string(),
|
|
||||||
type: z.enum(["yes", "no", "ifNeedBe"]),
|
|
||||||
})
|
|
||||||
.array(),
|
|
||||||
}),
|
}),
|
||||||
resolve: async ({ input: { pollId, participantId, votes } }) => {
|
update: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
pollId: z.string(),
|
||||||
|
participantId: z.string(),
|
||||||
|
votes: z
|
||||||
|
.object({
|
||||||
|
optionId: z.string(),
|
||||||
|
type: z.enum(["yes", "no", "ifNeedBe"]),
|
||||||
|
})
|
||||||
|
.array(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input: { pollId, participantId, votes } }) => {
|
||||||
const participant = await prisma.participant.update({
|
const participant = await prisma.participant.update({
|
||||||
where: {
|
where: {
|
||||||
id: participantId,
|
id: participantId,
|
||||||
|
@ -118,5 +123,5 @@ export const participants = createRouter()
|
||||||
});
|
});
|
||||||
|
|
||||||
return participant;
|
return participant;
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,15 +11,17 @@ import {
|
||||||
decryptToken,
|
decryptToken,
|
||||||
mergeGuestsIntoUser,
|
mergeGuestsIntoUser,
|
||||||
} from "../../../utils/auth";
|
} from "../../../utils/auth";
|
||||||
import { createRouter } from "../../createRouter";
|
import { publicProcedure, router } from "../../trpc";
|
||||||
|
|
||||||
export const verification = createRouter()
|
export const verification = router({
|
||||||
.mutation("verify", {
|
verify: publicProcedure
|
||||||
input: z.object({
|
.input(
|
||||||
pollId: z.string(),
|
z.object({
|
||||||
code: z.string(),
|
pollId: z.string(),
|
||||||
}),
|
code: z.string(),
|
||||||
resolve: async ({ ctx, input }) => {
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { pollId } = await decryptToken<{
|
const { pollId } = await decryptToken<{
|
||||||
pollId: string;
|
pollId: string;
|
||||||
}>(input.code);
|
}>(input.code);
|
||||||
|
@ -52,14 +54,15 @@ export const verification = createRouter()
|
||||||
isGuest: false,
|
isGuest: false,
|
||||||
};
|
};
|
||||||
await ctx.session.save();
|
await ctx.session.save();
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation("request", {
|
|
||||||
input: z.object({
|
|
||||||
pollId: z.string(),
|
|
||||||
adminUrlId: z.string(),
|
|
||||||
}),
|
}),
|
||||||
resolve: async ({ input: { pollId, adminUrlId } }) => {
|
request: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
pollId: z.string(),
|
||||||
|
adminUrlId: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input: { pollId, adminUrlId } }) => {
|
||||||
const poll = await prisma.poll.findUnique({
|
const poll = await prisma.poll.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: pollId,
|
id: pollId,
|
||||||
|
@ -96,5 +99,5 @@ export const verification = createRouter()
|
||||||
supportEmail: process.env.SUPPORT_EMAIL,
|
supportEmail: process.env.SUPPORT_EMAIL,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { z } from "zod";
|
||||||
|
|
||||||
import { prisma } from "~/prisma/db";
|
import { prisma } from "~/prisma/db";
|
||||||
|
|
||||||
import { createRouter } from "../createRouter";
|
import { publicProcedure, router } from "../trpc";
|
||||||
|
|
||||||
const requireUser = (user: IronSessionData["user"]) => {
|
const requireUser = (user: IronSessionData["user"]) => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
|
@ -16,42 +16,42 @@ const requireUser = (user: IronSessionData["user"]) => {
|
||||||
return user;
|
return user;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const user = createRouter()
|
export const user = router({
|
||||||
.query("getPolls", {
|
getPolls: publicProcedure.query(async ({ ctx }) => {
|
||||||
resolve: async ({ ctx }) => {
|
const user = requireUser(ctx.session.user);
|
||||||
const user = requireUser(ctx.session.user);
|
const userPolls = await prisma.user.findUnique({
|
||||||
const userPolls = await prisma.user.findUnique({
|
where: {
|
||||||
where: {
|
id: user.id,
|
||||||
id: user.id,
|
},
|
||||||
},
|
select: {
|
||||||
select: {
|
polls: {
|
||||||
polls: {
|
where: {
|
||||||
where: {
|
deleted: false,
|
||||||
deleted: false,
|
},
|
||||||
},
|
select: {
|
||||||
select: {
|
title: true,
|
||||||
title: true,
|
closed: true,
|
||||||
closed: true,
|
verified: true,
|
||||||
verified: true,
|
createdAt: true,
|
||||||
createdAt: true,
|
adminUrlId: true,
|
||||||
adminUrlId: true,
|
},
|
||||||
},
|
take: 10,
|
||||||
take: 10,
|
orderBy: {
|
||||||
orderBy: {
|
createdAt: "desc",
|
||||||
createdAt: "desc",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
return userPolls;
|
});
|
||||||
},
|
return userPolls;
|
||||||
})
|
}),
|
||||||
.mutation("changeName", {
|
changeName: publicProcedure
|
||||||
input: z.object({
|
.input(
|
||||||
userId: z.string(),
|
z.object({
|
||||||
name: z.string().min(1).max(100),
|
userId: z.string(),
|
||||||
}),
|
name: z.string().min(1).max(100),
|
||||||
resolve: async ({ input }) => {
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
await prisma.user.update({
|
await prisma.user.update({
|
||||||
where: {
|
where: {
|
||||||
id: input.userId,
|
id: input.userId,
|
||||||
|
@ -60,5 +60,5 @@ export const user = createRouter()
|
||||||
name: input.name,
|
name: input.name,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
import { MutationCache } from "@tanstack/react-query";
|
import { MutationCache } from "@tanstack/react-query";
|
||||||
import { httpBatchLink } from "@trpc/client";
|
import { httpBatchLink } from "@trpc/client";
|
||||||
import { createTRPCNext } from "@trpc/next";
|
import { createTRPCNext } from "@trpc/next";
|
||||||
import { createReactQueryHooks } from "@trpc/react-query";
|
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
|
|
||||||
import { AppRouter } from "../server/routers/_app";
|
import { AppRouter } from "../server/routers/_app";
|
||||||
|
|
||||||
export const trpc = createReactQueryHooks<AppRouter>();
|
export const trpc = createTRPCNext<AppRouter>({
|
||||||
|
|
||||||
export const trpcNext = createTRPCNext<AppRouter>({
|
|
||||||
unstable_overrides: {
|
unstable_overrides: {
|
||||||
useMutation: {
|
useMutation: {
|
||||||
async onSuccess(opts) {
|
async onSuccess(opts) {
|
||||||
|
|
|
@ -17,4 +17,5 @@ export type GetPollApiResponse = {
|
||||||
demo: boolean;
|
demo: boolean;
|
||||||
notifications: boolean;
|
notifications: boolean;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
deleted: boolean;
|
||||||
};
|
};
|
||||||
|
|
32
yarn.lock
32
yarn.lock
|
@ -2028,27 +2028,27 @@
|
||||||
"@tanstack/query-core" "4.24.4"
|
"@tanstack/query-core" "4.24.4"
|
||||||
use-sync-external-store "^1.2.0"
|
use-sync-external-store "^1.2.0"
|
||||||
|
|
||||||
"@trpc/client@^10.0.0-rc.8":
|
"@trpc/client@^10.13.0":
|
||||||
version "10.0.0-rc.8"
|
version "10.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/@trpc/client/-/client-10.0.0-rc.8.tgz#2b6b0db8ec41e4403b72d25d37a2cd9d6c6c1257"
|
resolved "https://registry.yarnpkg.com/@trpc/client/-/client-10.13.0.tgz#8999a7ba068a684629071b77a07c00a141585eca"
|
||||||
integrity sha512-NuQl7g1tkfFYn6P6dZJJkVsxnxutYpaxmpG/w5ZKW3QVu6cY1joUOrWakunKrghh3HS+svgLaPz0Xl0PlmdSlw==
|
integrity sha512-r4KuN0os2J194lxg5jn4+o3uNlqunLFYptwTHcVW4Q0XGO0ZoTKLHuxT7c9IeDivkAs6G5oVEPiKhptkag36dQ==
|
||||||
|
|
||||||
"@trpc/next@^10.0.0-rc.8":
|
"@trpc/next@^10.13.0":
|
||||||
version "10.0.0-rc.8"
|
version "10.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/@trpc/next/-/next-10.0.0-rc.8.tgz#78a4acc4404c3a8295f0b0a8da4e2c89b21e1366"
|
resolved "https://registry.yarnpkg.com/@trpc/next/-/next-10.13.0.tgz#64393f0d8dbfae7d87e54260dea532702bd1ecdf"
|
||||||
integrity sha512-l2TZF22virmC3RROD7qu0dnc3sdYfVvkOhAu1qP5+8fRgs4cgHKBFdalQ+SKBnU0RNuVLYVw0CkyvU+gHo5u2w==
|
integrity sha512-Q4rnuuiSUXDYv34f8FNUKhEMQFgLJTTJean78YjhG3Aaci+r4sew4hPmRvDRut8fBpa+EtExq+dv1EUbzlXgJg==
|
||||||
dependencies:
|
dependencies:
|
||||||
react-ssr-prepass "^1.5.0"
|
react-ssr-prepass "^1.5.0"
|
||||||
|
|
||||||
"@trpc/react-query@^10.0.0-rc.8":
|
"@trpc/react-query@^10.13.0":
|
||||||
version "10.0.0-rc.8"
|
version "10.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/@trpc/react-query/-/react-query-10.0.0-rc.8.tgz#68957743cd99e9c97fb167fb955b00bd1f9010e2"
|
resolved "https://registry.yarnpkg.com/@trpc/react-query/-/react-query-10.13.0.tgz#ca5a1da0ea126976d7435775f2ba1846cb7fad59"
|
||||||
integrity sha512-LKL29llvGtwYmfKGuCYSgNNChOL8/6PInY90i+ZgI8TLO6ZCJaVrPBSvqtxKj3MSezbK3kOxWIviKVFwV35L0A==
|
integrity sha512-y4jbojrDFdEl1KBejBoMWIofcUXDHQA8wf01eKMEDV7Jwc7lhq6R1dxYtKzeF+s5wqfnPWFOGZDmB3flzv07Dw==
|
||||||
|
|
||||||
"@trpc/server@^10.0.0-rc.8":
|
"@trpc/server@^10.13.0":
|
||||||
version "10.0.0-rc.8"
|
version "10.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/@trpc/server/-/server-10.0.0-rc.8.tgz#941cb4b06a2d59419bdbcc61241f1e8946b67a1e"
|
resolved "https://registry.yarnpkg.com/@trpc/server/-/server-10.13.0.tgz#0945b5210a18934c2284c8679cb6692ecb5b054c"
|
||||||
integrity sha512-+NsQqaJGHTiiBcOesH1bIictnnSO+SXaCOy5pM/324QBnJRt9VOO8oYDLcHSwAbJpAbOA+vl6YHs8OoykW6D2g==
|
integrity sha512-d/bu6utCC4ALxhTJkolEPAHMOSuCAu3mG79TZswa6wD2ob0/Z3AIvBF/meeSTqDxe4tvXY78lQqOkQI81dgi/g==
|
||||||
|
|
||||||
"@trysound/sax@0.2.0":
|
"@trysound/sax@0.2.0":
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue