Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conference hotfix #76

Merged
merged 5 commits into from Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/app/admin/conferences/create-conference.form.tsx
Expand Up @@ -59,6 +59,7 @@ export const CreateConferenceForm: FC<CreateConferenceProps> = ({
ticketPrice: 0.0,
startDate: new Date().toISOString(),
endDate: new Date().toISOString(),
stripeId: "",
},
})

Expand Down Expand Up @@ -165,6 +166,8 @@ export const CreateConferenceForm: FC<CreateConferenceProps> = ({
</div>
<div className="flex-1">
<FormField
control={form.control}
name={"ticketCurrency"}
render={({ field }) => (
<FormItem>
<FormLabel>Currency</FormLabel>
Expand All @@ -187,8 +190,6 @@ export const CreateConferenceForm: FC<CreateConferenceProps> = ({
<FormMessage />
</FormItem>
)}
name={"ticketCurrency"}
control={form.control}
/>
</div>
</div>
Expand Down
Expand Up @@ -3,6 +3,7 @@ import { eq } from "drizzle-orm"
import { ConferenceEventArchivedPayload } from "@/contracts/events/conference"
import { db } from "@/database"
import { conferences } from "@/database/schemas"
import { archiveProduct } from "@/lib/stripe/product"
suuunly marked this conversation as resolved.
Show resolved Hide resolved

export default async function conferenceArchived(payload: unknown) {
console.log("Got archived event", payload)
Expand All @@ -13,6 +14,9 @@ export default async function conferenceArchived(payload: unknown) {
if (!exists) {
return
}

await archiveProduct(exists.stripeId)

await db
.update(conferences)
.set({
Expand Down
11 changes: 11 additions & 0 deletions src/app/api/transform/conference.0/route-conference-created.ts
Expand Up @@ -3,6 +3,7 @@ import { eq } from "drizzle-orm"
import { ConferenceEventCreatedPayload } from "@/contracts/events/conference"
import { db } from "@/database"
import { conferences } from "@/database/schemas"
import { createProduct } from "@/lib/stripe/product"

export default async function conferenceCreated(payload: unknown) {
console.log("Got created event", payload)
Expand All @@ -13,5 +14,15 @@ export default async function conferenceCreated(payload: unknown) {
if (exists) {
return
}

await createProduct({
id: parsedPayload.stripeId,
conferenceId: parsedPayload.id,
name: parsedPayload.name,
price: parsedPayload.ticketPrice,
currency: parsedPayload.ticketCurrency,
description: parsedPayload.ticketDescription,
})

await db.insert(conferences).values(parsedPayload)
}
10 changes: 10 additions & 0 deletions src/app/api/transform/conference.0/route-conference-updated.ts
Expand Up @@ -3,6 +3,7 @@ import { eq } from "drizzle-orm"
import { ConferenceEventUpdatedPayload } from "@/contracts/events/conference"
import { db } from "@/database"
import { conferences } from "@/database/schemas"
import { updateProduct } from "@/lib/stripe/product"

export default async function conferenceUpdated(payload: unknown) {
console.log("Got updated event", payload)
Expand All @@ -13,6 +14,15 @@ export default async function conferenceUpdated(payload: unknown) {
if (!exists) {
return
}

await updateProduct({
id: exists.stripeId,
name: parsedPayload.name,
description: parsedPayload.ticketDescription,
price: parsedPayload.ticketPrice,
currency: parsedPayload.ticketCurrency,
})

await db
.update(conferences)
.set(parsedPayload)
Expand Down
20 changes: 11 additions & 9 deletions src/app/conferences/page.tsx
Expand Up @@ -37,7 +37,12 @@ export default function ConferencesPage() {
const { data: conferences, isLoading } = api.conference.list.useQuery()
return (
<main className="mx-auto w-full">
<div className="mb-6 text-3xl font-bold">Conferences</div>
<div className="mb-6 text-3xl font-bold">
Conferences
<Link href="/admin/conferences" className="float-right text-sm">
Admin
</Link>
</div>
{isLoading || !conferences ? (
<Skeleton />
) : (
Expand All @@ -53,7 +58,9 @@ interface ConferencesListProps {
conferences: RouterOutput["conference"]["list"]
}
function ConferencesList({ conferences }: ConferencesListProps) {
return conferences.map((conference) => <Conference conference={conference} />)
return conferences.map((conference) => (
<Conference conference={conference} key={conference.id} />
))
}

const CheckoutResponse = z.object({
Expand Down Expand Up @@ -120,13 +127,8 @@ function Conference({ conference }: ConferenceProps) {
}, [ticketQuantity, conference.id])

return (
<div key={conference.id}>
<div className="mb-4 text-xl font-bold">
{conference.name}
<Link href="/admin/conferences" className="float-right">
Admin
</Link>
</div>
<div key={conference.id} className="mb-6">
<div className="mb-4 text-xl font-bold">{conference.name}</div>
<div className="mb-2">{conference.description}</div>
<div className="mb-2 text-sm italic">
{dayjs(conference.startDate).format("MMMM D, YYYY")}
Expand Down
13 changes: 1 addition & 12 deletions src/app/me/tickets/page.tsx
Expand Up @@ -18,19 +18,14 @@ import { Input } from "@/components/ui/input"
import { api } from "@/trpc/react"

export default function Tickets() {
const [conferenceId, setConferenceId] = useState<string>()
const { data: conferences } = api.conference.list.useQuery()
const router = useRouter()
const pathname = usePathname()
const searchParams = useSearchParams()
const { isLoaded, userId } = useAuth()
const [ticketRedeemDialogOpened, setTicketRedeemDialogOpened] =
useState(false)
const [transferId, setTransferId] = useState("")
const { data: tickets, refetch } = api.ticket.list.useQuery(
{ conferenceId: conferenceId! },
{ enabled: !!conferenceId },
)
const { data: tickets, refetch } = api.ticket.list.useQuery()

useEffect(() => {
const success = searchParams.get("success")
Expand All @@ -42,12 +37,6 @@ export default function Tickets() {
router.replace(pathname)
}, [])

useEffect(() => {
if (conferences) {
setConferenceId(conferences[0]?.id)
}
}, [conferences])

const apiAcceptTicketTransfer = api.ticket.acceptTransfer.useMutation()
const acceptTicketTransfer = useCallback(async () => {
if (!transferId) {
Expand Down
5 changes: 4 additions & 1 deletion src/app/me/tickets/ticket.component.tsx
Expand Up @@ -32,6 +32,9 @@ export function Ticket({ ticket, refetch }: TicketProps) {
const [loading, setLoading] = useState(false)
const [ticketDialogOpened, setTicketDialogOpened] = useState(false)
const { Canvas } = useQRCode()
const { data: conference } = api.conference.get.useQuery({
id: ticket.conferenceId,
})

const apiArchiveTicket = api.ticket.archive.useMutation()
const archiveTicket = useCallback(async () => {
Expand Down Expand Up @@ -93,7 +96,7 @@ export function Ticket({ ticket, refetch }: TicketProps) {
/>
</div>
<div className={"flex-1 self-stretch"}>
<div className={"font-bold"}>Tonik 2024</div>
<div className={"font-bold"}>{conference?.name}</div>
<div className={"text-sm text-gray-500"}>
Ticket State: {ticket.state}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/nav.tsx
Expand Up @@ -65,7 +65,7 @@ export function Nav({ isSidebarOpen, setIsSidebarOpen, links }: NavProps) {
setIsSidebarOpen(false)
}
}}>
<link.icon className="mr-3 mr-5 h-6 w-6" />{" "}
<link.icon className="mr-5 h-6 w-6" />{" "}
{/* Increased icon size and right margin */}
{link.title}
{link.label && (
Expand Down
6 changes: 2 additions & 4 deletions src/database/index.ts
Expand Up @@ -4,16 +4,14 @@ import { Pool } from "pg"
import * as schemas from "@/database/schemas"
import { registerService } from "@/lib/register-service"

const client = registerService<Pool>(
const pool = registerService<Pool>(
"pgpool",
() =>
new Pool({
connectionString: process.env.POSTGRES_URL!,
}),
)

client.connect().catch((err: unknown) => console.error(err))

export const db = drizzle(client, {
export const db = drizzle(pool, {
schema: schemas,
})
Expand Up @@ -13,7 +13,7 @@ const ArchiveConferenceInputDto = z.object({

export type ArchiveConferenceInput = z.infer<typeof ArchiveConferenceInputDto>

export const archiveConferenceRouter = protectedProcedure
export const archiveConferenceProcedure = protectedProcedure
.input(ArchiveConferenceInputDto)
.mutation(async ({ input }) => {
await sendConferenceArchivedEvent({ id: input.id })
Expand Down
Expand Up @@ -11,7 +11,7 @@ import { conferences } from "@/database/schemas"
import waitForPredicate from "@/lib/wait-for-predicate"
import { protectedProcedure } from "@/server/api/trpc"

export const createConferenceRouter = protectedProcedure
export const createConferenceProcedure = protectedProcedure
.input(CreateConferenceInputDto)
.mutation(async ({ input }) => {
// TODO: make sure user has correct permissions
Expand All @@ -28,8 +28,9 @@ export const createConferenceRouter = protectedProcedure
}

const id = shortUuid.generate()
const stripeId = shortUuid.generate()

await sendConferenceCreatedEvent({ id, ...input })
await sendConferenceCreatedEvent({ ...input, stripeId, id })
try {
await waitForPredicate(
() =>
Expand Down
Expand Up @@ -9,7 +9,7 @@ const GetConferenceInput = z.object({
id: z.string(),
})

export const getConferenceRouter = protectedProcedure
export const getConferenceProcedure = protectedProcedure
.input(GetConferenceInput)
.query(({ input }) => {
return db.query.conferences.findFirst({
Expand Down
Expand Up @@ -4,7 +4,7 @@ import { db } from "@/database"
import { conferences } from "@/database/schemas"
import { protectedProcedure } from "@/server/api/trpc"

export const getConferencesRouter = protectedProcedure.query(async () => {
export const getConferencesProcedure = protectedProcedure.query(async () => {
return (
(await db
.select({
Expand Down
Expand Up @@ -7,7 +7,7 @@ import { conferences } from "@/database/schemas"
import waitForPredicate from "@/lib/wait-for-predicate"
import { protectedProcedure } from "@/server/api/trpc"

export const updateConferenceRouter = protectedProcedure
export const updateConferenceProcedure = protectedProcedure
.input(UpdateConferenceInputDto)
.mutation(async ({ input }) => {
if (
Expand Down
20 changes: 10 additions & 10 deletions src/server/api/routers/conference/conference.router.ts
@@ -1,14 +1,14 @@
import { archiveConferenceRouter } from "@/server/api/routers/conference/conference-archive"
import { createConferenceRouter } from "@/server/api/routers/conference/conference-create"
import { getConferenceRouter } from "@/server/api/routers/conference/conference-get"
import { getConferencesRouter } from "@/server/api/routers/conference/conference-list"
import { updateConferenceRouter } from "@/server/api/routers/conference/conference-update"
import { archiveConferenceProcedure } from "@/server/api/routers/conference/conference-archive.procedure"
import { createConferenceProcedure } from "@/server/api/routers/conference/conference-create.procedure"
import { getConferenceProcedure } from "@/server/api/routers/conference/conference-get.procedure"
import { getConferencesProcedure } from "@/server/api/routers/conference/conference-list.procedure"
import { updateConferenceProcedure } from "@/server/api/routers/conference/conference-update.procedure"
import { createTRPCRouter } from "@/server/api/trpc"

export const conferenceRouter = createTRPCRouter({
get: getConferenceRouter,
list: getConferencesRouter,
create: createConferenceRouter,
update: updateConferenceRouter,
archive: archiveConferenceRouter,
get: getConferenceProcedure,
list: getConferencesProcedure,
create: createConferenceProcedure,
update: updateConferenceProcedure,
archive: archiveConferenceProcedure,
})
Expand Up @@ -11,7 +11,7 @@ const ArchiveTicketInput = z.object({
id: z.string(),
})

export const archiveTicketRouter = protectedProcedure
export const archiveTicketProcedure = protectedProcedure
.input(ArchiveTicketInput)
.mutation(async ({ input }) => {
// TODO: Check if user is allowed to archive ticket
Expand Down
Expand Up @@ -11,7 +11,7 @@ const CheckInTicketInput = z.object({
id: z.string(),
})

export const checkInTicketRouter = protectedProcedure
export const checkInTicketProcedure = protectedProcedure
.input(CheckInTicketInput)
.mutation(async ({ input }) => {
await sendTicketUpdatedEvent({ id: input.id, state: "checked-in" })
Expand Down
Expand Up @@ -13,7 +13,7 @@ const CreateTicketInput = z.object({
quantity: z.number(),
})

export const createTicketRouter = protectedProcedure
export const createTicketProcedure = protectedProcedure
.input(CreateTicketInput)
.mutation(async ({ ctx, input }) => {
// TODO: Check if user is allowed to create ticket
Expand Down
Expand Up @@ -9,7 +9,7 @@ const GetTicketByIdInput = z.object({
id: z.string(),
})

export const getTicketRouter = protectedProcedure
export const getTicketProcedure = protectedProcedure
.input(GetTicketByIdInput)
.query(async ({ input }) => {
const results = await db
Expand Down
27 changes: 27 additions & 0 deletions src/server/api/routers/ticket/ticket-list.procedure.ts
@@ -0,0 +1,27 @@
import { and, eq } from "drizzle-orm"

import { db } from "@/database"
import { tickets, ticketTransfers } from "@/database/schemas"
import { protectedProcedure } from "@/server/api/trpc"

export const getTicketsProcedure = protectedProcedure.query(({ ctx }) => {
const userId = ctx.user.id
return db
.select({
id: tickets.id,
userId: tickets.userId,
conferenceId: tickets.conferenceId,
state: tickets.state,
transferId: ticketTransfers.id,
})
.from(tickets)
.leftJoin(
ticketTransfers,
and(
eq(tickets.id, ticketTransfers.ticketId),
eq(ticketTransfers.state, "open"),
),
)
.where(eq(tickets.userId, userId))
.execute()
})
39 changes: 0 additions & 39 deletions src/server/api/routers/ticket/ticket-list.ts

This file was deleted.