mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 11:51:14 -05:00
Fix internal error
This commit is contained in:
@@ -97,7 +97,7 @@ export function ActivityCard({ activity }: ActivityCardProps) {
|
|||||||
|
|
||||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
<Avatar className="w-5 h-5">
|
<Avatar className="w-5 h-5">
|
||||||
<AvatarImage src={activity.moderator?.avatar_url} />
|
<AvatarImage src={activity.moderator?.avatar_url || undefined} />
|
||||||
<AvatarFallback className="text-xs">{moderatorInitial}</AvatarFallback>
|
<AvatarFallback className="text-xs">{moderatorInitial}</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
<span className="truncate">
|
<span className="truncate">
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
|
|||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{itemData?.cloudflare_image_url && typeof itemData.cloudflare_image_url === 'string' && (
|
{(itemData?.cloudflare_image_url && typeof itemData.cloudflare_image_url === 'string' && (
|
||||||
<Card className="overflow-hidden">
|
<Card className="overflow-hidden">
|
||||||
<CardContent className="p-2">
|
<CardContent className="p-2">
|
||||||
<img
|
<img
|
||||||
@@ -210,7 +210,7 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
|
|||||||
/>
|
/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
)}
|
)) as React.ReactNode}
|
||||||
|
|
||||||
{isEdit && (
|
{isEdit && (
|
||||||
<div className="space-y-2 text-sm">
|
<div className="space-y-2 text-sm">
|
||||||
@@ -229,12 +229,12 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isEdit && itemData?.reason && typeof itemData.reason === 'string' && (
|
{(!isEdit && itemData?.reason && typeof itemData.reason === 'string' && (
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
<span className="font-medium">Reason: </span>
|
<span className="font-medium">Reason: </span>
|
||||||
<span className="text-muted-foreground">{itemData.reason}</span>
|
<span className="text-muted-foreground">{itemData.reason}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)) as React.ReactNode}
|
||||||
|
|
||||||
<div className="text-xs text-muted-foreground italic">
|
<div className="text-xs text-muted-foreground italic">
|
||||||
Click "Review Items" for full details
|
Click "Review Items" for full details
|
||||||
@@ -244,7 +244,7 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build photos array for modal
|
// Build photos array for modal
|
||||||
const photos = [];
|
const photos: Array<{ id: string; url: string; caption: string | null }> = [];
|
||||||
if (bannerImageUrl) {
|
if (bannerImageUrl) {
|
||||||
photos.push({
|
photos.push({
|
||||||
id: 'banner',
|
id: 'banner',
|
||||||
@@ -336,7 +336,10 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PhotoModal
|
<PhotoModal
|
||||||
photos={photos}
|
photos={photos.map(photo => ({
|
||||||
|
...photo,
|
||||||
|
caption: photo.caption ?? undefined
|
||||||
|
}))}
|
||||||
initialIndex={selectedImageIndex}
|
initialIndex={selectedImageIndex}
|
||||||
isOpen={isModalOpen}
|
isOpen={isModalOpen}
|
||||||
onClose={() => setIsModalOpen(false)}
|
onClose={() => setIsModalOpen(false)}
|
||||||
|
|||||||
@@ -221,11 +221,11 @@ export function LocationDiff({ oldLocation, newLocation, compact = false }: Loca
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof loc === 'object') {
|
if (typeof loc === 'object') {
|
||||||
const parts = [];
|
const parts: string[] = [];
|
||||||
if (loc.city) parts.push(loc.city);
|
if (loc.city) parts.push(String(loc.city));
|
||||||
if (loc.state_province) parts.push(loc.state_province);
|
if (loc.state_province) parts.push(String(loc.state_province));
|
||||||
if (loc.country && loc.country !== loc.state_province) parts.push(loc.country);
|
if (loc.country && loc.country !== loc.state_province) parts.push(String(loc.country));
|
||||||
if (loc.postal_code) parts.push(loc.postal_code);
|
if (loc.postal_code) parts.push(String(loc.postal_code));
|
||||||
|
|
||||||
let locationStr = parts.join(', ') || 'Unknown';
|
let locationStr = parts.join(', ') || 'Unknown';
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { Textarea } from '@/components/ui/textarea';
|
|||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { useIsMobile } from '@/hooks/use-mobile';
|
import { useIsMobile } from '@/hooks/use-mobile';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
import { useUserRole } from '@/hooks/useUserRole';
|
import { useUserRole } from '@/hooks/useUserRole';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
@@ -93,6 +94,11 @@ export function ItemEditDialog({ item, items, open, onOpenChange, onComplete }:
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePhotoSubmit = async (caption: string, credit: string) => {
|
const handlePhotoSubmit = async (caption: string, credit: string) => {
|
||||||
|
if (!item?.item_data) {
|
||||||
|
logger.error('No item data available for photo submission');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const itemData = typeof item.item_data === 'object' && item.item_data !== null && !Array.isArray(item.item_data)
|
const itemData = typeof item.item_data === 'object' && item.item_data !== null && !Array.isArray(item.item_data)
|
||||||
? item.item_data as Record<string, unknown>
|
? item.item_data as Record<string, unknown>
|
||||||
: {};
|
: {};
|
||||||
|
|||||||
@@ -86,12 +86,12 @@ export function ItemReviewCard({ item, onEdit, onStatusChange, submissionId }: I
|
|||||||
<CardTitle className={isMobile ? "text-sm" : "text-base"}>
|
<CardTitle className={isMobile ? "text-sm" : "text-base"}>
|
||||||
{item.item_type.replace('_', ' ').toUpperCase()}
|
{item.item_type.replace('_', ' ').toUpperCase()}
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
{item.original_data && Object.keys(item.original_data).length > 0 && (
|
{(item.original_data && Object.keys(item.original_data).length > 0 && (
|
||||||
<Badge variant="secondary" className="text-xs bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300 border border-blue-300 dark:border-blue-700">
|
<Badge variant="secondary" className="text-xs bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300 border border-blue-300 dark:border-blue-700">
|
||||||
<Edit className="w-3 h-3 mr-1" />
|
<Edit className="w-3 h-3 mr-1" />
|
||||||
Moderator Edited
|
Moderator Edited
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)) as React.ReactNode}
|
||||||
{hasBlockingErrors && (
|
{hasBlockingErrors && (
|
||||||
<Badge variant="destructive" className="text-xs">
|
<Badge variant="destructive" className="text-xs">
|
||||||
Blocked
|
Blocked
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef, ModerationQueuePro
|
|||||||
activeEntityFilter={queueManager.filters.entityFilter}
|
activeEntityFilter={queueManager.filters.entityFilter}
|
||||||
activeStatusFilter={queueManager.filters.statusFilter}
|
activeStatusFilter={queueManager.filters.statusFilter}
|
||||||
sortConfig={queueManager.filters.sortConfig}
|
sortConfig={queueManager.filters.sortConfig}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile ?? false}
|
||||||
isLoading={queueManager.loadingState === 'loading'}
|
isLoading={queueManager.loadingState === 'loading'}
|
||||||
onEntityFilterChange={queueManager.filters.setEntityFilter}
|
onEntityFilterChange={queueManager.filters.setEntityFilter}
|
||||||
onStatusFilterChange={queueManager.filters.setStatusFilter}
|
onStatusFilterChange={queueManager.filters.setStatusFilter}
|
||||||
@@ -367,11 +367,11 @@ export const ModerationQueue = forwardRef<ModerationQueueRef, ModerationQueuePro
|
|||||||
<ModerationErrorBoundary key={item.id} submissionId={item.id}>
|
<ModerationErrorBoundary key={item.id} submissionId={item.id}>
|
||||||
<QueueItem
|
<QueueItem
|
||||||
item={item}
|
item={item}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile ?? false}
|
||||||
actionLoading={queueManager.actionLoading}
|
actionLoading={queueManager.actionLoading}
|
||||||
isLockedByMe={queueManager.queue.isLockedByMe(item.id, item.assigned_to, item.locked_until)}
|
isLockedByMe={queueManager.queue.isLockedByMe(item.id, item.assigned_to || null, item.locked_until || null)}
|
||||||
isLockedByOther={queueManager.queue.isLockedByOther(item.id, item.assigned_to, item.locked_until)}
|
isLockedByOther={queueManager.queue.isLockedByOther(item.id, item.assigned_to || null, item.locked_until || null)}
|
||||||
lockStatus={getLockStatus({ assigned_to: item.assigned_to, locked_until: item.locked_until }, user?.id || '')}
|
lockStatus={getLockStatus({ assigned_to: item.assigned_to || null, locked_until: item.locked_until || null }, user?.id || '')}
|
||||||
currentLockSubmissionId={queueManager.queue.currentLock?.submissionId}
|
currentLockSubmissionId={queueManager.queue.currentLock?.submissionId}
|
||||||
notes={notes}
|
notes={notes}
|
||||||
isAdmin={isAdmin()}
|
isAdmin={isAdmin()}
|
||||||
@@ -428,11 +428,11 @@ export const ModerationQueue = forwardRef<ModerationQueueRef, ModerationQueuePro
|
|||||||
<ModerationErrorBoundary submissionId={item.id}>
|
<ModerationErrorBoundary submissionId={item.id}>
|
||||||
<QueueItem
|
<QueueItem
|
||||||
item={item}
|
item={item}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile ?? false}
|
||||||
actionLoading={queueManager.actionLoading}
|
actionLoading={queueManager.actionLoading}
|
||||||
isLockedByMe={queueManager.queue.isLockedByMe(item.id, item.assigned_to, item.locked_until)}
|
isLockedByMe={queueManager.queue.isLockedByMe(item.id, item.assigned_to || null, item.locked_until || null)}
|
||||||
isLockedByOther={queueManager.queue.isLockedByOther(item.id, item.assigned_to, item.locked_until)}
|
isLockedByOther={queueManager.queue.isLockedByOther(item.id, item.assigned_to || null, item.locked_until || null)}
|
||||||
lockStatus={getLockStatus({ assigned_to: item.assigned_to, locked_until: item.locked_until }, user?.id || '')}
|
lockStatus={getLockStatus({ assigned_to: item.assigned_to || null, locked_until: item.locked_until || null }, user?.id || '')}
|
||||||
currentLockSubmissionId={queueManager.queue.currentLock?.submissionId}
|
currentLockSubmissionId={queueManager.queue.currentLock?.submissionId}
|
||||||
notes={notes}
|
notes={notes}
|
||||||
isAdmin={isAdmin()}
|
isAdmin={isAdmin()}
|
||||||
@@ -467,7 +467,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef, ModerationQueuePro
|
|||||||
totalPages={queueManager.pagination.totalPages}
|
totalPages={queueManager.pagination.totalPages}
|
||||||
pageSize={queueManager.pagination.pageSize}
|
pageSize={queueManager.pagination.pageSize}
|
||||||
totalCount={queueManager.pagination.totalCount}
|
totalCount={queueManager.pagination.totalCount}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile ?? false}
|
||||||
onPageChange={queueManager.pagination.setCurrentPage}
|
onPageChange={queueManager.pagination.setCurrentPage}
|
||||||
onPageSizeChange={queueManager.pagination.setPageSize}
|
onPageSizeChange={queueManager.pagination.setPageSize}
|
||||||
/>
|
/>
|
||||||
@@ -475,7 +475,10 @@ export const ModerationQueue = forwardRef<ModerationQueueRef, ModerationQueuePro
|
|||||||
|
|
||||||
{/* Modals */}
|
{/* Modals */}
|
||||||
<PhotoModal
|
<PhotoModal
|
||||||
photos={selectedPhotos}
|
photos={selectedPhotos.map(photo => ({
|
||||||
|
...photo,
|
||||||
|
caption: photo.caption ?? undefined
|
||||||
|
}))}
|
||||||
initialIndex={selectedPhotoIndex}
|
initialIndex={selectedPhotoIndex}
|
||||||
isOpen={photoModalOpen}
|
isOpen={photoModalOpen}
|
||||||
onClose={() => setPhotoModalOpen(false)}
|
onClose={() => setPhotoModalOpen(false)}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ export const QueueItem = memo(({
|
|||||||
<QueueItemHeader
|
<QueueItemHeader
|
||||||
item={item}
|
item={item}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
hasModeratorEdits={hasModeratorEdits}
|
hasModeratorEdits={hasModeratorEdits ?? false}
|
||||||
isLockedByOther={isLockedByOther}
|
isLockedByOther={isLockedByOther}
|
||||||
currentLockSubmissionId={currentLockSubmissionId}
|
currentLockSubmissionId={currentLockSubmissionId}
|
||||||
validationResult={validationResult}
|
validationResult={validationResult}
|
||||||
@@ -190,7 +190,7 @@ export const QueueItem = memo(({
|
|||||||
<div className="text-sm font-medium mb-2">Attached Photos:</div>
|
<div className="text-sm font-medium mb-2">Attached Photos:</div>
|
||||||
<PhotoGrid
|
<PhotoGrid
|
||||||
photos={reviewPhotos}
|
photos={reviewPhotos}
|
||||||
onPhotoClick={onOpenPhotos}
|
onPhotoClick={(photos, index) => onOpenPhotos(photos as any, index)}
|
||||||
maxDisplay={isMobile ? 3 : 4}
|
maxDisplay={isMobile ? 3 : 4}
|
||||||
className="grid-cols-2 md:grid-cols-3"
|
className="grid-cols-2 md:grid-cols-3"
|
||||||
/>
|
/>
|
||||||
@@ -231,7 +231,7 @@ export const QueueItem = memo(({
|
|||||||
<div className="text-sm space-y-2">
|
<div className="text-sm space-y-2">
|
||||||
<div>
|
<div>
|
||||||
<span className="text-muted-foreground">Type:</span>{' '}
|
<span className="text-muted-foreground">Type:</span>{' '}
|
||||||
<span className="font-medium">{getSubmissionTypeLabel(item.submission_type)}</span>
|
<span className="font-medium">{getSubmissionTypeLabel(item.submission_type || 'unknown')}</span>
|
||||||
</div>
|
</div>
|
||||||
{item.submission_items && item.submission_items.length > 0 && (
|
{item.submission_items && item.submission_items.length > 0 && (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -83,11 +83,11 @@ export const RecentActivity = forwardRef<RecentActivityRef>((props, ref) => {
|
|||||||
if (reviewsError) throw reviewsError;
|
if (reviewsError) throw reviewsError;
|
||||||
|
|
||||||
// Get unique moderator IDs
|
// Get unique moderator IDs
|
||||||
const moderatorIds = [
|
const moderatorIds: string[] = [
|
||||||
...(submissions?.map(s => s.reviewer_id).filter(Boolean) || []),
|
...(submissions?.map(s => s.reviewer_id).filter((id): id is string => id != null) || []),
|
||||||
...(reports?.map(r => r.reviewed_by).filter(Boolean) || []),
|
...(reports?.map(r => r.reviewed_by).filter((id): id is string => id != null) || []),
|
||||||
...(reviews?.map(r => r.moderated_by).filter(Boolean) || []),
|
...(reviews?.map(r => r.moderated_by).filter((id): id is string => id != null) || []),
|
||||||
].filter((id, index, arr) => id && arr.indexOf(id) === index);
|
].filter((id, index, arr) => arr.indexOf(id) === index);
|
||||||
|
|
||||||
// Fetch moderator profiles
|
// Fetch moderator profiles
|
||||||
const { data: profiles } = await supabase
|
const { data: profiles } = await supabase
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({
|
|||||||
}
|
}
|
||||||
|
|
||||||
setItems((itemsData || []) as SubmissionItemData[]);
|
setItems((itemsData || []) as SubmissionItemData[]);
|
||||||
setHasPhotos(photoData && photoData.length > 0);
|
setHasPhotos(!!(photoData && photoData.length > 0));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Failed to fetch submission items', { error: getErrorMessage(err) });
|
logger.error('Failed to fetch submission items', { error: getErrorMessage(err) });
|
||||||
setError('Failed to load submission details');
|
setError('Failed to load submission details');
|
||||||
|
|||||||
@@ -634,7 +634,10 @@ export function SubmissionReviewManager({
|
|||||||
<ConflictResolutionModal
|
<ConflictResolutionModal
|
||||||
open={showConflictResolutionModal}
|
open={showConflictResolutionModal}
|
||||||
onOpenChange={setShowConflictResolutionModal}
|
onOpenChange={setShowConflictResolutionModal}
|
||||||
conflictData={conflictData}
|
conflictData={conflictData || {
|
||||||
|
hasConflict: false,
|
||||||
|
clientVersion: { last_modified_at: new Date().toISOString() }
|
||||||
|
}}
|
||||||
onResolve={async (strategy) => {
|
onResolve={async (strategy) => {
|
||||||
if (strategy === 'keep-mine') {
|
if (strategy === 'keep-mine') {
|
||||||
// Log conflict resolution
|
// Log conflict resolution
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const EntitySubmissionDisplay = memo(({ item, isMobile }: EntitySubmissio
|
|||||||
<div className="text-sm space-y-2">
|
<div className="text-sm space-y-2">
|
||||||
<div>
|
<div>
|
||||||
<span className="text-muted-foreground">Type:</span>{' '}
|
<span className="text-muted-foreground">Type:</span>{' '}
|
||||||
<span className="font-medium">{getSubmissionTypeLabel(item.submission_type)}</span>
|
<span className="font-medium">{getSubmissionTypeLabel(item.submission_type || 'unknown')}</span>
|
||||||
</div>
|
</div>
|
||||||
{item.submission_items && item.submission_items.length > 0 && (
|
{item.submission_items && item.submission_items.length > 0 && (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export const PhotoSubmissionDisplay = memo(({
|
|||||||
title: photo.title,
|
title: photo.title,
|
||||||
date_taken: photo.date_taken,
|
date_taken: photo.date_taken,
|
||||||
}))}
|
}))}
|
||||||
onPhotoClick={onOpenPhotos}
|
onPhotoClick={(photos, index) => onOpenPhotos(photos as any, index)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const ReviewDisplay = memo(({ item, isMobile, onOpenPhotos }: ReviewDispl
|
|||||||
<div className="text-sm font-medium mb-2">Attached Photos:</div>
|
<div className="text-sm font-medium mb-2">Attached Photos:</div>
|
||||||
<PhotoGrid
|
<PhotoGrid
|
||||||
photos={reviewPhotos}
|
photos={reviewPhotos}
|
||||||
onPhotoClick={onOpenPhotos}
|
onPhotoClick={(photos, index) => onOpenPhotos(photos as any, index)}
|
||||||
maxDisplay={isMobile ? 3 : 4}
|
maxDisplay={isMobile ? 3 : 4}
|
||||||
className="grid-cols-2 md:grid-cols-3"
|
className="grid-cols-2 md:grid-cols-3"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export function NotificationCenter() {
|
|||||||
>
|
>
|
||||||
<Inbox
|
<Inbox
|
||||||
applicationIdentifier={applicationIdentifier}
|
applicationIdentifier={applicationIdentifier}
|
||||||
subscriberId={subscriberId}
|
subscriber={subscriberId || ''}
|
||||||
appearance={appearance}
|
appearance={appearance}
|
||||||
onNotificationClick={handleNotificationClick}
|
onNotificationClick={handleNotificationClick}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const OperatorCard = ({ company }: OperatorCardProps) => {
|
|||||||
<div className="aspect-[3/2] relative bg-gradient-to-br from-primary/20 via-primary/10 to-transparent overflow-hidden">
|
<div className="aspect-[3/2] relative bg-gradient-to-br from-primary/20 via-primary/10 to-transparent overflow-hidden">
|
||||||
{(company.card_image_url || company.card_image_id) ? (
|
{(company.card_image_url || company.card_image_id) ? (
|
||||||
<img
|
<img
|
||||||
src={company.card_image_url || getCloudflareImageUrl(company.card_image_id, 'card')}
|
src={company.card_image_url || getCloudflareImageUrl(company.card_image_id || '', 'card')}
|
||||||
srcSet={company.card_image_id ? `
|
srcSet={company.card_image_id ? `
|
||||||
${getCloudflareImageUrl(company.card_image_id, 'cardthumb')} 600w,
|
${getCloudflareImageUrl(company.card_image_id, 'cardthumb')} 600w,
|
||||||
${getCloudflareImageUrl(company.card_image_id, 'card')} 1200w
|
${getCloudflareImageUrl(company.card_image_id, 'card')} 1200w
|
||||||
@@ -111,11 +111,11 @@ const OperatorCard = ({ company }: OperatorCardProps) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{company.average_rating > 0 && (
|
{company.average_rating != null && company.average_rating > 0 && (
|
||||||
<div className="inline-flex items-center gap-1">
|
<div className="inline-flex items-center gap-1">
|
||||||
<Star className="w-4 h-4 fill-yellow-500 text-yellow-500" />
|
<Star className="w-4 h-4 fill-yellow-500 text-yellow-500" />
|
||||||
<span className="font-semibold">{company.average_rating.toFixed(1)}</span>
|
<span className="font-semibold">{company.average_rating.toFixed(1)}</span>
|
||||||
{company.review_count > 0 && (
|
{company.review_count != null && company.review_count > 0 && (
|
||||||
<span className="text-muted-foreground">({company.review_count})</span>
|
<span className="text-muted-foreground">({company.review_count})</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const ParkOwnerCard = ({ company }: ParkOwnerCardProps) => {
|
|||||||
<div className="aspect-[3/2] relative bg-gradient-to-br from-primary/20 via-primary/10 to-transparent overflow-hidden">
|
<div className="aspect-[3/2] relative bg-gradient-to-br from-primary/20 via-primary/10 to-transparent overflow-hidden">
|
||||||
{(company.card_image_url || company.card_image_id) ? (
|
{(company.card_image_url || company.card_image_id) ? (
|
||||||
<img
|
<img
|
||||||
src={company.card_image_url || getCloudflareImageUrl(company.card_image_id, 'card')}
|
src={company.card_image_url || getCloudflareImageUrl(company.card_image_id || '', 'card')}
|
||||||
srcSet={company.card_image_id ? `
|
srcSet={company.card_image_id ? `
|
||||||
${getCloudflareImageUrl(company.card_image_id, 'cardthumb')} 600w,
|
${getCloudflareImageUrl(company.card_image_id, 'cardthumb')} 600w,
|
||||||
${getCloudflareImageUrl(company.card_image_id, 'card')} 1200w
|
${getCloudflareImageUrl(company.card_image_id, 'card')} 1200w
|
||||||
@@ -111,11 +111,11 @@ const ParkOwnerCard = ({ company }: ParkOwnerCardProps) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{company.average_rating > 0 && (
|
{company.average_rating != null && company.average_rating > 0 && (
|
||||||
<div className="inline-flex items-center gap-1">
|
<div className="inline-flex items-center gap-1">
|
||||||
<Star className="w-4 h-4 fill-yellow-500 text-yellow-500" />
|
<Star className="w-4 h-4 fill-yellow-500 text-yellow-500" />
|
||||||
<span className="font-semibold">{company.average_rating.toFixed(1)}</span>
|
<span className="font-semibold">{company.average_rating.toFixed(1)}</span>
|
||||||
{company.review_count > 0 && (
|
{company.review_count != null && company.review_count > 0 && (
|
||||||
<span className="text-muted-foreground">({company.review_count})</span>
|
<span className="text-muted-foreground">({company.review_count})</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user