feat: add admin content module actions
This commit is contained in:
1 parent
b9525c8e6b
commit
f422bb4a0b
6 files changed
+596
No files matched your search
@@ -0,0 +1,185 @@
|
||||
'use server'
|
||||
|
||||
import { z } from 'zod'
|
||||
import { PERMS } from '@/lib/permissions'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
import { adminAction } from '@/lib/safe-action'
|
||||
import { ActionError, actionOk } from '@/lib/safe-action-shared'
|
||||
import { logAudit } from '@/lib/services/audit'
|
||||
import {
|
||||
createEventSchema,
|
||||
eventPrizeSchema,
|
||||
eventTypeSchema,
|
||||
eventWinnerSchema,
|
||||
updateEventSchema,
|
||||
} from '@/lib/validators/event'
|
||||
|
||||
// ── Event Types ─────────────────────────────────────────────────────
|
||||
|
||||
export const createEventType = adminAction(
|
||||
{ permission: PERMS.EVENTS_EDIT, schema: eventTypeSchema },
|
||||
async (ctx) => {
|
||||
const eventType = await prisma.websiteEventType.create({
|
||||
data: ctx.data,
|
||||
})
|
||||
logAudit({
|
||||
userId: ctx.session.user.id,
|
||||
action: 'event_type_create',
|
||||
target: 'WebsiteEventType',
|
||||
targetId: eventType.id,
|
||||
after: { name: eventType.name },
|
||||
})
|
||||
return actionOk({ id: eventType.id })
|
||||
},
|
||||
)
|
||||
|
||||
const updateEventTypeInput = eventTypeSchema.partial().extend({
|
||||
id: z.coerce.number().int().positive(),
|
||||
})
|
||||
|
||||
export const updateEventType = adminAction(
|
||||
{ permission: PERMS.EVENTS_EDIT, schema: updateEventTypeInput },
|
||||
async (ctx) => {
|
||||
const { id, ...data } = ctx.data
|
||||
const existing = await prisma.websiteEventType.findUnique({ where: { id } })
|
||||
if (!existing) throw new ActionError('Event type not found')
|
||||
|
||||
await prisma.websiteEventType.update({ where: { id }, data })
|
||||
logAudit({
|
||||
userId: ctx.session.user.id,
|
||||
action: 'event_type_update',
|
||||
target: 'WebsiteEventType',
|
||||
targetId: id,
|
||||
before: { name: existing.name },
|
||||
after: data,
|
||||
})
|
||||
return actionOk({ id })
|
||||
},
|
||||
)
|
||||
|
||||
const deleteEventTypeInput = z.object({
|
||||
id: z.coerce.number().int().positive(),
|
||||
})
|
||||
|
||||
export const deleteEventType = adminAction(
|
||||
{ permission: PERMS.EVENTS_EDIT, schema: deleteEventTypeInput },
|
||||
async (ctx) => {
|
||||
const existing = await prisma.websiteEventType.findUnique({ where: { id: ctx.data.id } })
|
||||
if (!existing) throw new ActionError('Event type not found')
|
||||
|
||||
await prisma.websiteEventType.delete({ where: { id: ctx.data.id } })
|
||||
logAudit({
|
||||
userId: ctx.session.user.id,
|
||||
action: 'event_type_delete',
|
||||
target: 'WebsiteEventType',
|
||||
targetId: ctx.data.id,
|
||||
before: { name: existing.name },
|
||||
})
|
||||
return actionOk()
|
||||
},
|
||||
)
|
||||
|
||||
// ── Events ──────────────────────────────────────────────────────────
|
||||
|
||||
export const createEvent = adminAction(
|
||||
{ permission: PERMS.EVENTS_EDIT, schema: createEventSchema },
|
||||
async (ctx) => {
|
||||
const event = await prisma.websiteEvent.create({
|
||||
data: {
|
||||
...ctx.data,
|
||||
hostUserId: Number(ctx.session.user.id),
|
||||
},
|
||||
})
|
||||
logAudit({
|
||||
userId: ctx.session.user.id,
|
||||
action: 'event_create',
|
||||
target: 'WebsiteEvent',
|
||||
targetId: event.id,
|
||||
after: { title: event.title },
|
||||
})
|
||||
return actionOk({ id: event.id })
|
||||
},
|
||||
)
|
||||
|
||||
const updateEventInput = updateEventSchema.extend({
|
||||
id: z.coerce.number().int().positive(),
|
||||
})
|
||||
|
||||
export const updateEvent = adminAction(
|
||||
{ permission: PERMS.EVENTS_EDIT, schema: updateEventInput },
|
||||
async (ctx) => {
|
||||
const { id, ...data } = ctx.data
|
||||
const existing = await prisma.websiteEvent.findUnique({ where: { id } })
|
||||
if (!existing) throw new ActionError('Event not found')
|
||||
|
||||
await prisma.websiteEvent.update({ where: { id }, data })
|
||||
logAudit({
|
||||
userId: ctx.session.user.id,
|
||||
action: 'event_update',
|
||||
target: 'WebsiteEvent',
|
||||
targetId: id,
|
||||
before: { title: existing.title, status: existing.status },
|
||||
after: data,
|
||||
})
|
||||
return actionOk({ id })
|
||||
},
|
||||
)
|
||||
|
||||
const deleteEventInput = z.object({
|
||||
id: z.coerce.number().int().positive(),
|
||||
})
|
||||
|
||||
export const deleteEvent = adminAction(
|
||||
{ permission: PERMS.EVENTS_EDIT, schema: deleteEventInput },
|
||||
async (ctx) => {
|
||||
const existing = await prisma.websiteEvent.findUnique({ where: { id: ctx.data.id } })
|
||||
if (!existing) throw new ActionError('Event not found')
|
||||
|
||||
await prisma.websiteEvent.delete({ where: { id: ctx.data.id } })
|
||||
logAudit({
|
||||
userId: ctx.session.user.id,
|
||||
action: 'event_delete',
|
||||
target: 'WebsiteEvent',
|
||||
targetId: ctx.data.id,
|
||||
before: { title: existing.title },
|
||||
})
|
||||
return actionOk()
|
||||
},
|
||||
)
|
||||
|
||||
// ── Prizes ──────────────────────────────────────────────────────────
|
||||
|
||||
export const addEventPrize = adminAction(
|
||||
{ permission: PERMS.EVENTS_EDIT, schema: eventPrizeSchema },
|
||||
async (ctx) => {
|
||||
const prize = await prisma.websiteEventPrize.create({ data: ctx.data })
|
||||
return actionOk({ id: prize.id })
|
||||
},
|
||||
)
|
||||
|
||||
const deletePrizeInput = z.object({ id: z.coerce.number().int().positive() })
|
||||
|
||||
export const deleteEventPrize = adminAction(
|
||||
{ permission: PERMS.EVENTS_EDIT, schema: deletePrizeInput },
|
||||
async (ctx) => {
|
||||
await prisma.websiteEventPrize.delete({ where: { id: ctx.data.id } })
|
||||
return actionOk()
|
||||
},
|
||||
)
|
||||
|
||||
// ── Winners ─────────────────────────────────────────────────────────
|
||||
|
||||
export const addEventWinner = adminAction(
|
||||
{ permission: PERMS.EVENTS_EDIT, schema: eventWinnerSchema },
|
||||
async (ctx) => {
|
||||
const winner = await prisma.websiteEventWinner.create({ data: ctx.data })
|
||||
logAudit({
|
||||
userId: ctx.session.user.id,
|
||||
action: 'event_winner_add',
|
||||
target: 'WebsiteEventWinner',
|
||||
targetId: winner.id,
|
||||
after: { eventId: ctx.data.eventId, userId: ctx.data.userId, position: ctx.data.position },
|
||||
})
|
||||
return actionOk({ id: winner.id })
|
||||
},
|
||||
)
|
||||
Reference in new issue
Block a user