mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 18:51:12 -05:00
Refactor: Implement photo upload plan
This commit is contained in:
23
src/components/companies/DesignerPhotoGallery.tsx
Normal file
23
src/components/companies/DesignerPhotoGallery.tsx
Normal 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}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/components/companies/ManufacturerPhotoGallery.tsx
Normal file
23
src/components/companies/ManufacturerPhotoGallery.tsx
Normal 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}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/components/companies/OperatorPhotoGallery.tsx
Normal file
23
src/components/companies/OperatorPhotoGallery.tsx
Normal 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}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/components/companies/PropertyOwnerPhotoGallery.tsx
Normal file
23
src/components/companies/PropertyOwnerPhotoGallery.tsx
Normal 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}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -172,8 +172,10 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
|||||||
|
|
||||||
// Handle both old format (context as object) and new format (context as string)
|
// Handle both old format (context as object) and new format (context as string)
|
||||||
let contextType = null;
|
let contextType = null;
|
||||||
|
let entityId = null;
|
||||||
let rideId = null;
|
let rideId = null;
|
||||||
let parkId = null;
|
let parkId = null;
|
||||||
|
let companyId = null;
|
||||||
|
|
||||||
if (typeof contentObj.context === 'object' && contentObj.context !== null) {
|
if (typeof contentObj.context === 'object' && contentObj.context !== null) {
|
||||||
// OLD FORMAT: context is an object like {ride_id: "...", park_id: "..."}
|
// 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') {
|
} else if (typeof contentObj.context === 'string') {
|
||||||
// NEW FORMAT: context is a string, IDs are at top level
|
// NEW FORMAT: context is a string, IDs are at top level
|
||||||
contextType = contentObj.context;
|
contextType = contentObj.context;
|
||||||
|
entityId = contentObj.entity_id;
|
||||||
rideId = contentObj.ride_id;
|
rideId = contentObj.ride_id;
|
||||||
parkId = contentObj.park_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
|
const { data: rideData } = await supabase
|
||||||
.from('rides')
|
.from('rides')
|
||||||
.select(`
|
.select(`
|
||||||
@@ -196,23 +207,34 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
|||||||
name
|
name
|
||||||
)
|
)
|
||||||
`)
|
`)
|
||||||
.eq('id', rideId)
|
.eq('id', entityId)
|
||||||
.single();
|
.single();
|
||||||
|
|
||||||
if (rideData) {
|
if (rideData) {
|
||||||
(submission as any).entity_name = rideData.name;
|
(submission as any).entity_name = rideData.name;
|
||||||
(submission as any).park_name = rideData.parks?.name;
|
(submission as any).park_name = rideData.parks?.name;
|
||||||
}
|
}
|
||||||
} else if (contextType === 'park' && parkId) {
|
} else if (contextType === 'park' && entityId) {
|
||||||
const { data: parkData } = await supabase
|
const { data: parkData } = await supabase
|
||||||
.from('parks')
|
.from('parks')
|
||||||
.select('name')
|
.select('name')
|
||||||
.eq('id', parkId)
|
.eq('id', entityId)
|
||||||
.single();
|
.single();
|
||||||
|
|
||||||
if (parkData) {
|
if (parkData) {
|
||||||
(submission as any).entity_name = parkData.name;
|
(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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/components/parks/ParkPhotoGallery.tsx
Normal file
20
src/components/parks/ParkPhotoGallery.tsx
Normal 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}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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 { useState } from 'react';
|
||||||
import { Upload, X, Camera } from 'lucide-react';
|
import { Upload, X, Camera } from 'lucide-react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
|||||||
@@ -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
|
const { error } = await supabase
|
||||||
.from('content_submissions')
|
.from('content_submissions')
|
||||||
.insert(submissionData);
|
.insert(submissionData);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { ReviewsSection } from '@/components/reviews/ReviewsSection';
|
|||||||
import { RideCard } from '@/components/rides/RideCard';
|
import { RideCard } from '@/components/rides/RideCard';
|
||||||
import { Park, Ride } from '@/types/database';
|
import { Park, Ride } from '@/types/database';
|
||||||
import { ParkLocationMap } from '@/components/maps/ParkLocationMap';
|
import { ParkLocationMap } from '@/components/maps/ParkLocationMap';
|
||||||
|
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
export default function ParkDetail() {
|
export default function ParkDetail() {
|
||||||
const {
|
const {
|
||||||
@@ -424,13 +425,11 @@ export default function ParkDetail() {
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="photos" className="mt-6">
|
<TabsContent value="photos" className="mt-6">
|
||||||
<div className="text-center py-12">
|
<EntityPhotoGallery
|
||||||
<Camera className="w-16 h-16 text-muted-foreground mx-auto mb-4" />
|
entityId={park.id}
|
||||||
<h3 className="text-xl font-semibold mb-2">Photo Gallery Coming Soon</h3>
|
entityType="park"
|
||||||
<p className="text-muted-foreground">
|
entityName={park.name}
|
||||||
Photo galleries and media uploads will be available soon
|
/>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -627,6 +627,7 @@ export default function RideDetail() {
|
|||||||
<RidePhotoGallery
|
<RidePhotoGallery
|
||||||
rideId={ride.id}
|
rideId={ride.id}
|
||||||
rideName={ride.name}
|
rideName={ride.name}
|
||||||
|
parkId={(ride as any).currentParkId}
|
||||||
/>
|
/>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
Reference in New Issue
Block a user