Refactor: Implement entity type safety plan

This commit is contained in:
gpt-engineer-app[bot]
2025-10-16 13:48:41 +00:00
parent 2106142150
commit 4efdeaa104
9 changed files with 34 additions and 38 deletions

View File

@@ -7,6 +7,7 @@ export interface CompanyFormData {
name: string; name: string;
slug: string; slug: string;
description?: string; description?: string;
company_type: 'manufacturer' | 'designer' | 'operator' | 'property_owner';
person_type: 'company' | 'individual' | 'firm' | 'organization'; person_type: 'company' | 'individual' | 'firm' | 'organization';
website_url?: string; website_url?: string;
founded_year?: number; founded_year?: number;

View File

@@ -341,7 +341,8 @@ export default function DesignerDetail() {
name: designer.name, name: designer.name,
slug: designer.slug, slug: designer.slug,
description: designer.description, description: designer.description,
person_type: designer.person_type as any, company_type: 'designer',
person_type: designer.person_type,
website_url: designer.website_url, website_url: designer.website_url,
founded_year: designer.founded_year, founded_year: designer.founded_year,
headquarters_location: designer.headquarters_location, headquarters_location: designer.headquarters_location,

View File

@@ -68,9 +68,9 @@ export default function DesignerRides() {
case 'speed': case 'speed':
query = query.order('max_speed_kmh', { ascending: false, nullsFirst: false }); query = query.order('max_speed_kmh', { ascending: false, nullsFirst: false });
break; break;
case 'height': case 'height':
query = query.order('max_height_meters', { ascending: false, nullsFirst: false }); query = query.order('height_meters', { ascending: false, nullsFirst: false });
break; break;
case 'reviews': case 'reviews':
query = query.order('review_count', { ascending: false }); query = query.order('review_count', { ascending: false });
break; break;
@@ -102,10 +102,6 @@ export default function DesignerRides() {
const handleCreateSubmit = async (data: any) => { const handleCreateSubmit = async (data: any) => {
try { try {
if (!user || !designer) {
return;
}
if (!designer) { if (!designer) {
toast({ toast({
title: "Error", title: "Error",
@@ -130,10 +126,11 @@ export default function DesignerRides() {
setIsCreateModalOpen(false); setIsCreateModalOpen(false);
fetchData(); fetchData();
} catch (error: any) { } catch (error) {
const message = error instanceof Error ? error.message : "Failed to submit ride.";
toast({ toast({
title: "Error", title: "Error",
description: error.message || "Failed to submit ride.", description: message,
variant: "destructive" variant: "destructive"
}); });
} }

View File

@@ -375,7 +375,8 @@ export default function ManufacturerDetail() {
name: manufacturer.name, name: manufacturer.name,
slug: manufacturer.slug, slug: manufacturer.slug,
description: manufacturer.description, description: manufacturer.description,
person_type: manufacturer.person_type as any, company_type: 'manufacturer',
person_type: manufacturer.person_type,
website_url: manufacturer.website_url, website_url: manufacturer.website_url,
founded_year: manufacturer.founded_year, founded_year: manufacturer.founded_year,
headquarters_location: manufacturer.headquarters_location, headquarters_location: manufacturer.headquarters_location,

View File

@@ -22,7 +22,7 @@ export default function ManufacturerModels() {
const { user } = useAuth(); const { user } = useAuth();
const { requireAuth } = useAuthModal(); const { requireAuth } = useAuthModal();
const [manufacturer, setManufacturer] = useState<Company | null>(null); const [manufacturer, setManufacturer] = useState<Company | null>(null);
const [models, setModels] = useState<RideModel[]>([]); const [models, setModels] = useState<RideModelWithCount[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const [sortBy, setSortBy] = useState('name'); const [sortBy, setSortBy] = useState('name');
@@ -68,12 +68,12 @@ export default function ManufacturerModels() {
if (modelsError) throw modelsError; if (modelsError) throw modelsError;
// Transform data to include ride count // Transform data to include ride count
const modelsWithCounts = (modelsData || []).map(model => ({ const modelsWithCounts: RideModelWithCount[] = (modelsData || []).map(model => ({
...model, ...model,
ride_count: Array.isArray(model.rides) ? model.rides[0]?.count || 0 : 0 ride_count: Array.isArray(model.rides) ? model.rides[0]?.count || 0 : 0
})); }));
setModels(modelsWithCounts as RideModel[]); setModels(modelsWithCounts);
} }
} catch (error) { } catch (error) {
console.error('Error fetching data:', error); console.error('Error fetching data:', error);
@@ -95,10 +95,6 @@ export default function ManufacturerModels() {
const handleCreateSubmit = async (data: any) => { const handleCreateSubmit = async (data: any) => {
try { try {
if (!user || !manufacturer) {
return;
}
if (!manufacturer) { if (!manufacturer) {
toast({ toast({
title: "Error", title: "Error",
@@ -123,10 +119,11 @@ export default function ManufacturerModels() {
setIsCreateModalOpen(false); setIsCreateModalOpen(false);
fetchData(); fetchData();
} catch (error: any) { } catch (error) {
const message = error instanceof Error ? error.message : "Failed to submit ride model.";
toast({ toast({
title: "Error", title: "Error",
description: error.message || "Failed to submit ride model.", description: message,
variant: "destructive" variant: "destructive"
}); });
} }

View File

@@ -68,9 +68,9 @@ export default function ManufacturerRides() {
case 'speed': case 'speed':
query = query.order('max_speed_kmh', { ascending: false, nullsFirst: false }); query = query.order('max_speed_kmh', { ascending: false, nullsFirst: false });
break; break;
case 'height': case 'height':
query = query.order('max_height_meters', { ascending: false, nullsFirst: false }); query = query.order('height_meters', { ascending: false, nullsFirst: false });
break; break;
case 'reviews': case 'reviews':
query = query.order('review_count', { ascending: false }); query = query.order('review_count', { ascending: false });
break; break;
@@ -102,10 +102,6 @@ export default function ManufacturerRides() {
const handleCreateSubmit = async (data: any) => { const handleCreateSubmit = async (data: any) => {
try { try {
if (!user || !manufacturer) {
return;
}
if (!manufacturer) { if (!manufacturer) {
toast({ toast({
title: "Error", title: "Error",
@@ -130,10 +126,11 @@ export default function ManufacturerRides() {
setIsCreateModalOpen(false); setIsCreateModalOpen(false);
fetchData(); fetchData();
} catch (error: any) { } catch (error) {
const message = error instanceof Error ? error.message : "Failed to submit ride.";
toast({ toast({
title: "Error", title: "Error",
description: error.message || "Failed to submit ride.", description: message,
variant: "destructive" variant: "destructive"
}); });
} }

View File

@@ -26,7 +26,7 @@ export default function OperatorDetail() {
const { slug } = useParams<{ slug: string }>(); const { slug } = useParams<{ slug: string }>();
const navigate = useNavigate(); const navigate = useNavigate();
const [operator, setOperator] = useState<Company | null>(null); const [operator, setOperator] = useState<Company | null>(null);
const [parks, setParks] = useState<any[]>([]); const [parks, setParks] = useState<Park[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [parksLoading, setParksLoading] = useState(true); const [parksLoading, setParksLoading] = useState(true);
const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false);
@@ -427,7 +427,8 @@ export default function OperatorDetail() {
name: operator.name, name: operator.name,
slug: operator.slug, slug: operator.slug,
description: operator.description, description: operator.description,
person_type: operator.person_type as any, company_type: 'operator',
person_type: operator.person_type,
website_url: operator.website_url, website_url: operator.website_url,
founded_year: operator.founded_year, founded_year: operator.founded_year,
headquarters_location: operator.headquarters_location, headquarters_location: operator.headquarters_location,

View File

@@ -26,7 +26,7 @@ export default function PropertyOwnerDetail() {
const { slug } = useParams<{ slug: string }>(); const { slug } = useParams<{ slug: string }>();
const navigate = useNavigate(); const navigate = useNavigate();
const [owner, setOwner] = useState<Company | null>(null); const [owner, setOwner] = useState<Company | null>(null);
const [parks, setParks] = useState<any[]>([]); const [parks, setParks] = useState<Park[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [parksLoading, setParksLoading] = useState(true); const [parksLoading, setParksLoading] = useState(true);
const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false);
@@ -427,7 +427,8 @@ export default function PropertyOwnerDetail() {
name: owner.name, name: owner.name,
slug: owner.slug, slug: owner.slug,
description: owner.description, description: owner.description,
person_type: owner.person_type as any, company_type: 'property_owner',
person_type: owner.person_type,
website_url: owner.website_url, website_url: owner.website_url,
founded_year: owner.founded_year, founded_year: owner.founded_year,
headquarters_location: owner.headquarters_location, headquarters_location: owner.headquarters_location,

View File

@@ -16,7 +16,7 @@ export interface Company {
slug: string; slug: string;
description?: string; description?: string;
company_type: string; // Allow any string from database company_type: string; // Allow any string from database
person_type: string; // 'company', 'individual', 'firm', 'organization' person_type: 'company' | 'individual' | 'firm' | 'organization';
website_url?: string; website_url?: string;
founded_year?: number; // Legacy field founded_year?: number; // Legacy field
founded_date?: string; founded_date?: string;