refactor: remove explicit any across admin forms and catalog actions
Local Build and Deploy / deploy (push) Canceled after 40s
Local Build and Deploy / deploy (push) Canceled after 40s
- Type resolveAsChild generically over Base UI render-prop type - Type catalog/rooms/catalog-items Prisma updates with Prisma.*UpdateInput - Type EventForm/PollForm with explicit form-value interfaces - Type EventPrizesManager/PollQuestionsManager with validator input types - All typecheck, lint, and 312 tests pass
This commit is contained in:
1 parent
907a4399d0
commit
3eaffe658d
8 files changed
+61
-23
No files matched your search
@@ -1,6 +1,7 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import type { Prisma } from "@/generated/prisma/client";
|
||||
import { requirePermission } from "@/lib/admin/guard";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
@@ -55,7 +56,10 @@ export async function updateBcPage({
|
||||
if (Object.keys(data).length === 0) {
|
||||
return { ok: false as const, error: "No valid fields to update" };
|
||||
}
|
||||
await prisma.catalogPagesBc.update({ where: { id }, data: data as any });
|
||||
await prisma.catalogPagesBc.update({
|
||||
where: { id },
|
||||
data: data as Prisma.CatalogPagesBcUpdateInput,
|
||||
});
|
||||
await rcon.updateCatalog();
|
||||
await logStaffActivity({
|
||||
staffId: staff.id,
|
||||
@@ -98,7 +102,10 @@ export async function updateBcItem({
|
||||
if (Object.keys(safe).length === 0) {
|
||||
return { ok: false as const, error: "No valid fields to update" };
|
||||
}
|
||||
await prisma.catalogItemsBc.update({ where: { id }, data: safe as any });
|
||||
await prisma.catalogItemsBc.update({
|
||||
where: { id },
|
||||
data: safe as Prisma.CatalogItemsBcUpdateInput,
|
||||
});
|
||||
await rcon.updateCatalog();
|
||||
await logStaffActivity({
|
||||
staffId: staff.id,
|
||||
|
||||
@@ -301,7 +301,7 @@ export async function updateCatalogItem({
|
||||
if (Object.keys(safeCatalog).length > 0) {
|
||||
await prisma.catalogItems.update({
|
||||
where: { id },
|
||||
data: safeCatalog as any,
|
||||
data: safeCatalog as Prisma.CatalogItemsUpdateInput,
|
||||
});
|
||||
}
|
||||
if (baseItem) {
|
||||
@@ -309,7 +309,7 @@ export async function updateCatalogItem({
|
||||
if (Object.keys(safeBase).length > 0) {
|
||||
await prisma.itemsBase.update({
|
||||
where: { id: baseItem.id },
|
||||
data: safeBase as any,
|
||||
data: safeBase as Prisma.ItemsBaseUpdateInput,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import type { Prisma } from "@/generated/prisma/client";
|
||||
import { requirePermission } from "@/lib/admin/guard";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
@@ -54,7 +55,10 @@ export async function updateCatalogPage({
|
||||
if (typeof data.caption === "string" && !data.captionSave) {
|
||||
data.captionSave = data.caption.slice(0, 25);
|
||||
}
|
||||
await prisma.catalogPages.update({ where: { id }, data: data as any });
|
||||
await prisma.catalogPages.update({
|
||||
where: { id },
|
||||
data: data as Prisma.CatalogPagesUpdateInput,
|
||||
});
|
||||
await rcon.updateCatalog();
|
||||
await logStaffActivity({
|
||||
staffId: staff.id,
|
||||
|
||||
@@ -15,7 +15,10 @@ export async function updateRoomItem(payload: Record<string, unknown>) {
|
||||
itemId: number;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
await prisma.items.update({ where: { id: itemId }, data: data as any });
|
||||
await prisma.items.update({
|
||||
where: { id: itemId },
|
||||
data: data as Prisma.ItemsUpdateInput,
|
||||
});
|
||||
await logStaffActivity({
|
||||
staffId: staff.id,
|
||||
action: "room_item_update",
|
||||
|
||||
@@ -16,7 +16,10 @@ import {
|
||||
} from "@/components/ui/select";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { useServerAction } from "@/hooks/use-server-action";
|
||||
import type { CreateEventInput, UpdateEventInput } from "@/lib/validators/event";
|
||||
import type {
|
||||
CreateEventInput,
|
||||
UpdateEventInput,
|
||||
} from "@/lib/validators/event";
|
||||
|
||||
interface EventType {
|
||||
id: number;
|
||||
@@ -34,8 +37,8 @@ interface EventFormValues {
|
||||
title: string;
|
||||
description: string;
|
||||
image?: string | null;
|
||||
maxPlayers?: string | null;
|
||||
roomId?: string | null;
|
||||
maxPlayers?: string | number | null;
|
||||
roomId?: string | number | null;
|
||||
typeId: number;
|
||||
status: string;
|
||||
isRecurring: number;
|
||||
@@ -60,9 +63,15 @@ export function EventForm({ eventTypes, defaultValues }: EventFormProps) {
|
||||
|
||||
function onSubmit(data: EventFormValues) {
|
||||
if (isEditing && defaultValues?.id) {
|
||||
run(() => updateEvent({ id: defaultValues.id!, ...data } as UpdateEventInput), {
|
||||
successMessage: "Event updated!",
|
||||
});
|
||||
run(
|
||||
() =>
|
||||
updateEvent({ id: defaultValues.id!, ...data } as UpdateEventInput & {
|
||||
id: number;
|
||||
}),
|
||||
{
|
||||
successMessage: "Event updated!",
|
||||
},
|
||||
);
|
||||
} else {
|
||||
run(() => createEvent(data as CreateEventInput), {
|
||||
successMessage: "Event created!",
|
||||
|
||||
@@ -75,9 +75,16 @@ export function PollQuestionsManager({ pollId, questions }: Props) {
|
||||
function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
if (editingId) {
|
||||
run(() => updatePollQuestion({ id: editingId, ...form } as PollQuestionUpdateInput), {
|
||||
successMessage: "Question updated!",
|
||||
});
|
||||
run(
|
||||
() =>
|
||||
updatePollQuestion({
|
||||
id: editingId,
|
||||
...form,
|
||||
} as PollQuestionUpdateInput),
|
||||
{
|
||||
successMessage: "Question updated!",
|
||||
},
|
||||
);
|
||||
} else {
|
||||
run(() => addPollQuestion(form), {
|
||||
successMessage: "Question added!",
|
||||
|
||||
@@ -50,9 +50,15 @@ export function PollForm({ defaultValues }: PollFormProps) {
|
||||
|
||||
function onSubmit(data: PollFormValues) {
|
||||
if (isEditing) {
|
||||
run(() => updatePoll({ id: defaultValues!.id, ...data } as UpdatePollInput), {
|
||||
successMessage: "Poll updated!",
|
||||
});
|
||||
run(
|
||||
() =>
|
||||
updatePoll({ id: defaultValues!.id, ...data } as UpdatePollInput & {
|
||||
id: number;
|
||||
}),
|
||||
{
|
||||
successMessage: "Poll updated!",
|
||||
},
|
||||
);
|
||||
} else {
|
||||
run(() => createPoll(data as CreatePollInput), {
|
||||
successMessage: "Poll created!",
|
||||
|
||||
+7
-5
@@ -1,20 +1,22 @@
|
||||
import { isValidElement, type ReactNode } from "react";
|
||||
import { isValidElement, type ReactElement, type ReactNode } from "react";
|
||||
|
||||
/**
|
||||
* Map Radix-style `asChild` onto Base UI's `render` prop.
|
||||
* Generic over the render-prop type so component-specific Base UI render
|
||||
* signatures (e.g. `UseRenderRenderProp<ButtonState>`) are preserved.
|
||||
*/
|
||||
export function resolveAsChild(
|
||||
export function resolveAsChild<R = ReactElement | undefined>(
|
||||
asChild: boolean | undefined,
|
||||
children: ReactNode,
|
||||
render?: any,
|
||||
render?: R,
|
||||
): {
|
||||
render?: any;
|
||||
render?: R;
|
||||
children: ReactNode;
|
||||
} {
|
||||
if (render != null) return { render, children };
|
||||
if (asChild && isValidElement(children)) {
|
||||
return {
|
||||
render: children,
|
||||
render: children as R,
|
||||
children: (children.props as { children?: ReactNode }).children,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user