feat: Enable TypeScript strict mode

This commit is contained in:
gpt-engineer-app[bot]
2025-11-03 00:58:42 +00:00
parent 061c06be29
commit d126be2908
15 changed files with 308 additions and 68 deletions

View File

@@ -79,7 +79,7 @@ interface ParkFormProps {
onSubmit: (data: ParkFormData & {
operator_id?: string;
property_owner_id?: string;
_compositeSubmission?: any;
_compositeSubmission?: import('@/types/composite-submission').ParkCompositeSubmission;
}) => Promise<void>;
onCancel?: () => void;
initialData?: Partial<ParkFormData & {
@@ -214,7 +214,7 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }:
}
// Build composite submission if new entities were created
const submissionContent: any = {
const submissionContent: import('@/types/composite-submission').ParkCompositeSubmission = {
park: data,
};

View File

@@ -90,7 +90,11 @@ export function ConflictResolutionDialog({
<AlertCircle className="h-4 w-4" />
<AlertDescription>
<p className="font-medium">
{item?.item_type.replace('_', ' ').toUpperCase()}: {item?.item_data.name}
{item?.item_type.replace('_', ' ').toUpperCase()}: {
item && typeof item.item_data === 'object' && item.item_data !== null && !Array.isArray(item.item_data) && 'name' in item.item_data
? String((item.item_data as Record<string, unknown>).name)
: 'Unnamed'
}
</p>
<p className="text-sm mt-1">{conflict.message}</p>
</AlertDescription>

View File

@@ -24,8 +24,10 @@ export function DependencyTreeView({ items }: DependencyTreeViewProps) {
};
const getItemLabel = (item: SubmissionItemWithDeps): string => {
const data = item.item_data;
const name = data.name || 'Unnamed';
const data = typeof item.item_data === 'object' && item.item_data !== null && !Array.isArray(item.item_data)
? item.item_data as Record<string, unknown>
: {};
const name = 'name' in data && typeof data.name === 'string' ? data.name : 'Unnamed';
const type = item.item_type.replace('_', ' ');
return `${name} (${type})`;
};

View File

@@ -104,7 +104,9 @@ export function DependencyVisualizer({ items, selectedIds }: DependencyVisualize
</CardHeader>
<CardContent className={isMobile ? "p-4 pt-0" : ""}>
<p className={`font-medium ${isMobile ? 'text-sm' : 'text-sm'}`}>
{item.item_data.name || 'Unnamed'}
{typeof item.item_data === 'object' && item.item_data !== null && !Array.isArray(item.item_data) && 'name' in item.item_data
? String((item.item_data as Record<string, unknown>).name)
: 'Unnamed'}
</p>
{item.dependents && item.dependents.length > 0 && (
<p className={`text-muted-foreground mt-1 ${isMobile ? 'text-xs' : 'text-xs'}`}>

View File

@@ -93,15 +93,21 @@ export function ItemEditDialog({ item, items, open, onOpenChange, onComplete }:
};
const handlePhotoSubmit = async (caption: string, credit: string) => {
const itemData = typeof item.item_data === 'object' && item.item_data !== null && !Array.isArray(item.item_data)
? item.item_data as Record<string, unknown>
: {};
const photos = 'photos' in itemData && Array.isArray(itemData.photos)
? itemData.photos
: [];
const photoData = {
...item.item_data,
photos: Array.isArray(item.item_data.photos)
? item.item_data.photos.map((photo: unknown) => ({
...(typeof photo === 'object' && photo !== null ? photo : {}),
caption,
credit,
}))
: [],
...itemData,
photos: photos.map((photo: unknown) => ({
...(typeof photo === 'object' && photo !== null ? photo as Record<string, unknown> : {}),
caption,
credit,
})),
};
await handleSubmit(photoData);
};

View File

@@ -127,7 +127,7 @@ export function ItemReviewCard({ item, onEdit, onStatusChange, submissionId }: I
<ValidationSummary
item={{
item_type: item.item_type,
item_data: item.item_data,
item_data: item.item_data as Record<string, unknown>,
id: item.id,
}}
onValidationChange={handleValidationChange}

View File

@@ -87,9 +87,9 @@ export function ItemSelectorDialog({
<span className="font-medium capitalize">
{item.item_type.replace('_', ' ')}
</span>
{item.item_data.name && (
{typeof item.item_data === 'object' && item.item_data !== null && !Array.isArray(item.item_data) && 'name' in item.item_data && (
<span className="text-sm text-muted-foreground">
{String(item.item_data.name)}
{String((item.item_data as Record<string, unknown>).name)}
</span>
)}
{item.dependencies && item.dependencies.length > 0 && (

View File

@@ -145,7 +145,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef, ModerationQueuePro
};
// Wrapped delete with confirmation
const handleDeleteSubmission = useCallback((item: any) => {
const handleDeleteSubmission = useCallback((item: { id: string; submission_type?: string }) => {
setConfirmDialog({
open: true,
title: 'Delete Submission',
@@ -198,7 +198,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef, ModerationQueuePro
enabled: true,
});
const handleOpenPhotos = (photos: any[], index: number) => {
const handleOpenPhotos = (photos: PhotoItem[], index: number) => {
setSelectedPhotos(photos);
setSelectedPhotoIndex(index);
setPhotoModalOpen(true);

View File

@@ -605,9 +605,12 @@ export function SubmissionReviewManager({
open={showValidationBlockerDialog}
onClose={() => setShowValidationBlockerDialog(false)}
blockingErrors={Array.from(validationResults.values()).flatMap(r => r.blockingErrors)}
itemNames={items.filter(i => selectedItemIds.has(i.id)).map(i =>
i.item_data?.name || i.item_type.replace('_', ' ')
)}
itemNames={items.filter(i => selectedItemIds.has(i.id)).map(i => {
const name = typeof i.item_data === 'object' && i.item_data !== null && !Array.isArray(i.item_data) && 'name' in i.item_data
? String((i.item_data as Record<string, unknown>).name)
: i.item_type.replace('_', ' ');
return name;
})}
/>
<WarningConfirmDialog
@@ -619,9 +622,12 @@ export function SubmissionReviewManager({
handleApprove();
}}
warnings={Array.from(validationResults.values()).flatMap(r => r.warnings)}
itemNames={items.filter(i => selectedItemIds.has(i.id)).map(i =>
i.item_data?.name || i.item_type.replace('_', ' ')
)}
itemNames={items.filter(i => selectedItemIds.has(i.id)).map(i => {
const name = typeof i.item_data === 'object' && i.item_data !== null && !Array.isArray(i.item_data) && 'name' in i.item_data
? String((i.item_data as Record<string, unknown>).name)
: i.item_type.replace('_', ' ');
return name;
})}
/>
<ConflictResolutionModal

View File

@@ -91,14 +91,7 @@ const ChartTooltip = RechartsPrimitive.Tooltip;
const ChartTooltipContent = React.forwardRef<
HTMLDivElement,
React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
React.ComponentProps<"div"> & {
hideLabel?: boolean;
hideIndicator?: boolean;
indicator?: "line" | "dot" | "dashed";
nameKey?: string;
labelKey?: string;
}
import('@/types/recharts').TooltipProps
>(
(
{
@@ -115,7 +108,7 @@ const ChartTooltipContent = React.forwardRef<
color,
nameKey,
labelKey,
}: any,
},
ref,
) => {
const { config } = useChart();
@@ -163,7 +156,11 @@ const ChartTooltipContent = React.forwardRef<
{payload.map((item, index) => {
const key = `${nameKey || item.name || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const indicatorColor = color || item.payload.fill || item.color;
const indicatorColor = color ||
(typeof item.payload === 'object' && item.payload !== null && 'fill' in item.payload
? (item.payload as Record<string, unknown>).fill as string
: undefined) ||
item.color;
return (
<div
@@ -229,12 +226,7 @@ const ChartLegend = RechartsPrimitive.Legend;
const ChartLegendContent = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div"> & {
hideIcon?: boolean;
nameKey?: string;
payload?: any[];
verticalAlign?: "top" | "bottom";
}
import('@/types/recharts').LegendProps
>(({ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey }, ref) => {
const { config } = useChart();
@@ -247,7 +239,7 @@ const ChartLegendContent = React.forwardRef<
ref={ref}
className={cn("flex items-center justify-center gap-4", verticalAlign === "top" ? "pb-3" : "pt-3", className)}
>
{payload.map((item: any) => {
{payload.map((item) => {
const key = `${nameKey || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);