Refactor: Implement photo upload plan

This commit is contained in:
gpt-engineer-app[bot]
2025-09-29 19:41:28 +00:00
parent 63fb0a61aa
commit bbbc925b77
10 changed files with 163 additions and 11 deletions

View File

@@ -0,0 +1,23 @@
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
interface DesignerPhotoGalleryProps {
designerId: string;
designerName: string;
}
/**
* Wrapper for designer photo galleries
* Uses the generic EntityPhotoGallery component internally
*/
export function DesignerPhotoGallery({
designerId,
designerName
}: DesignerPhotoGalleryProps) {
return (
<EntityPhotoGallery
entityId={designerId}
entityType="designer"
entityName={designerName}
/>
);
}

View File

@@ -0,0 +1,23 @@
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
interface ManufacturerPhotoGalleryProps {
manufacturerId: string;
manufacturerName: string;
}
/**
* Wrapper for manufacturer photo galleries
* Uses the generic EntityPhotoGallery component internally
*/
export function ManufacturerPhotoGallery({
manufacturerId,
manufacturerName
}: ManufacturerPhotoGalleryProps) {
return (
<EntityPhotoGallery
entityId={manufacturerId}
entityType="manufacturer"
entityName={manufacturerName}
/>
);
}

View File

@@ -0,0 +1,23 @@
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
interface OperatorPhotoGalleryProps {
operatorId: string;
operatorName: string;
}
/**
* Wrapper for operator photo galleries
* Uses the generic EntityPhotoGallery component internally
*/
export function OperatorPhotoGallery({
operatorId,
operatorName
}: OperatorPhotoGalleryProps) {
return (
<EntityPhotoGallery
entityId={operatorId}
entityType="operator"
entityName={operatorName}
/>
);
}

View File

@@ -0,0 +1,23 @@
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
interface PropertyOwnerPhotoGalleryProps {
propertyOwnerId: string;
propertyOwnerName: string;
}
/**
* Wrapper for property owner photo galleries
* Uses the generic EntityPhotoGallery component internally
*/
export function PropertyOwnerPhotoGallery({
propertyOwnerId,
propertyOwnerName
}: PropertyOwnerPhotoGalleryProps) {
return (
<EntityPhotoGallery
entityId={propertyOwnerId}
entityType="property_owner"
entityName={propertyOwnerName}
/>
);
}

View File

@@ -172,8 +172,10 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
// Handle both old format (context as object) and new format (context as string)
let contextType = null;
let entityId = null;
let rideId = null;
let parkId = null;
let companyId = null;
if (typeof contentObj.context === 'object' && contentObj.context !== null) {
// OLD FORMAT: context is an object like {ride_id: "...", park_id: "..."}
@@ -183,11 +185,20 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
} else if (typeof contentObj.context === 'string') {
// NEW FORMAT: context is a string, IDs are at top level
contextType = contentObj.context;
entityId = contentObj.entity_id;
rideId = contentObj.ride_id;
parkId = contentObj.park_id;
companyId = contentObj.company_id;
}
if (contextType === 'ride' && rideId) {
// Determine entity ID based on context type
if (!entityId) {
if (contextType === 'ride') entityId = rideId;
else if (contextType === 'park') entityId = parkId;
else if (['manufacturer', 'operator', 'designer', 'property_owner'].includes(contextType)) entityId = companyId;
}
if (contextType === 'ride' && entityId) {
const { data: rideData } = await supabase
.from('rides')
.select(`
@@ -196,23 +207,34 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
name
)
`)
.eq('id', rideId)
.eq('id', entityId)
.single();
if (rideData) {
(submission as any).entity_name = rideData.name;
(submission as any).park_name = rideData.parks?.name;
}
} else if (contextType === 'park' && parkId) {
} else if (contextType === 'park' && entityId) {
const { data: parkData } = await supabase
.from('parks')
.select('name')
.eq('id', parkId)
.eq('id', entityId)
.single();
if (parkData) {
(submission as any).entity_name = parkData.name;
}
} else if (['manufacturer', 'operator', 'designer', 'property_owner'].includes(contextType) && entityId) {
const { data: companyData } = await supabase
.from('companies')
.select('name, company_type')
.eq('id', entityId)
.single();
if (companyData) {
(submission as any).entity_name = companyData.name;
(submission as any).company_type = companyData.company_type;
}
}
}
}

View File

@@ -0,0 +1,20 @@
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
interface ParkPhotoGalleryProps {
parkId: string;
parkName: string;
}
/**
* Backwards-compatible wrapper for ParkPhotoGallery
* Uses the generic EntityPhotoGallery component internally
*/
export function ParkPhotoGallery({ parkId, parkName }: ParkPhotoGalleryProps) {
return (
<EntityPhotoGallery
entityId={parkId}
entityType="park"
entityName={parkName}
/>
);
}

View File

@@ -1,3 +1,12 @@
/**
* @deprecated This component is deprecated. Use UppyPhotoSubmissionUpload instead.
* This file is kept for backwards compatibility only.
*
* For new implementations, use:
* - UppyPhotoSubmissionUpload for direct uploads
* - EntityPhotoGallery for entity-specific photo galleries
*/
import { useState } from 'react';
import { Upload, X, Camera } from 'lucide-react';
import { Button } from '@/components/ui/button';

View File

@@ -207,6 +207,15 @@ export function UppyPhotoSubmissionUpload({
},
};
// Debug logging for verification
console.log('Photo Submission Data:', {
entity_id: finalEntityId,
context: finalEntityType,
parent_id: finalParentId,
photo_count: photos.length,
submission_data: submissionData
});
const { error } = await supabase
.from('content_submissions')
.insert(submissionData);

View File

@@ -11,6 +11,7 @@ import { ReviewsSection } from '@/components/reviews/ReviewsSection';
import { RideCard } from '@/components/rides/RideCard';
import { Park, Ride } from '@/types/database';
import { ParkLocationMap } from '@/components/maps/ParkLocationMap';
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
import { supabase } from '@/integrations/supabase/client';
export default function ParkDetail() {
const {
@@ -424,13 +425,11 @@ export default function ParkDetail() {
</TabsContent>
<TabsContent value="photos" className="mt-6">
<div className="text-center py-12">
<Camera className="w-16 h-16 text-muted-foreground mx-auto mb-4" />
<h3 className="text-xl font-semibold mb-2">Photo Gallery Coming Soon</h3>
<p className="text-muted-foreground">
Photo galleries and media uploads will be available soon
</p>
</div>
<EntityPhotoGallery
entityId={park.id}
entityType="park"
entityName={park.name}
/>
</TabsContent>
</Tabs>
</main>

View File

@@ -627,6 +627,7 @@ export default function RideDetail() {
<RidePhotoGallery
rideId={ride.id}
rideName={ride.name}
parkId={(ride as any).currentParkId}
/>
</TabsContent>
</Tabs>