mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-23 12:31:13 -05:00
Fix blog post foreign key
This commit is contained in:
@@ -117,7 +117,22 @@ export type Database = {
|
|||||||
updated_at?: string | null
|
updated_at?: string | null
|
||||||
view_count?: number | null
|
view_count?: number | null
|
||||||
}
|
}
|
||||||
Relationships: []
|
Relationships: [
|
||||||
|
{
|
||||||
|
foreignKeyName: "blog_posts_author_id_fkey"
|
||||||
|
columns: ["author_id"]
|
||||||
|
isOneToOne: false
|
||||||
|
referencedRelation: "filtered_profiles"
|
||||||
|
referencedColumns: ["user_id"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
foreignKeyName: "blog_posts_author_id_fkey"
|
||||||
|
columns: ["author_id"]
|
||||||
|
isOneToOne: false
|
||||||
|
referencedRelation: "profiles"
|
||||||
|
referencedColumns: ["user_id"]
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
companies: {
|
companies: {
|
||||||
Row: {
|
Row: {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@
|
|||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { UppyPhotoUpload } from '@/components/upload/UppyPhotoUpload';
|
import { UppyPhotoUpload } from '@/components/upload/UppyPhotoUpload';
|
||||||
import { generateSlugFromName } from '@/lib/slugUtils';
|
import { generateSlugFromName } from '@/lib/slugUtils';
|
||||||
|
import { extractCloudflareImageId } from '@/lib/cloudflareImageUtils';
|
||||||
import { Edit, Trash2, Eye, Plus } from 'lucide-react';
|
import { Edit, Trash2, Eye, Plus } from 'lucide-react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { formatDistanceToNow } from 'date-fns';
|
import { formatDistanceToNow } from 'date-fns';
|
||||||
@@ -284,11 +285,14 @@ export default function AdminBlog() {
|
|||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Featured Image</Label>
|
<Label>Featured Image</Label>
|
||||||
<UppyPhotoUpload
|
<UppyPhotoUpload
|
||||||
onUploadComplete={(results) => {
|
onUploadComplete={(urls) => {
|
||||||
if (results.length > 0) {
|
if (urls.length > 0) {
|
||||||
const result = results[0];
|
const url = urls[0];
|
||||||
handleImageUpload(result.cloudflareImageId, result.cloudflareImageUrl);
|
const imageId = extractCloudflareImageId(url);
|
||||||
toast.success('Image uploaded');
|
if (imageId) {
|
||||||
|
handleImageUpload(imageId, url);
|
||||||
|
toast.success('Image uploaded');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
maxFiles={1}
|
maxFiles={1}
|
||||||
|
|||||||
@@ -20,14 +20,7 @@ export default function BlogIndex() {
|
|||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
let query = supabase
|
let query = supabase
|
||||||
.from('blog_posts')
|
.from('blog_posts')
|
||||||
.select(`
|
.select('*, profiles!inner(username, display_name, avatar_url)', { count: 'exact' })
|
||||||
*,
|
|
||||||
author:profiles(
|
|
||||||
username,
|
|
||||||
display_name,
|
|
||||||
avatar_url
|
|
||||||
)
|
|
||||||
`, { count: 'exact' })
|
|
||||||
.eq('status', 'published')
|
.eq('status', 'published')
|
||||||
.order('published_at', { ascending: false })
|
.order('published_at', { ascending: false })
|
||||||
.range((page - 1) * POSTS_PER_PAGE, page * POSTS_PER_PAGE - 1);
|
.range((page - 1) * POSTS_PER_PAGE, page * POSTS_PER_PAGE - 1);
|
||||||
@@ -36,9 +29,9 @@ export default function BlogIndex() {
|
|||||||
query = query.or(`title.ilike.%${searchQuery}%,content.ilike.%${searchQuery}%`);
|
query = query.or(`title.ilike.%${searchQuery}%,content.ilike.%${searchQuery}%`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data, count, error } = await query;
|
const { data: posts, count, error } = await query;
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
return { posts: data, totalCount: count || 0 };
|
return { posts, totalCount: count || 0 };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -92,9 +85,9 @@ export default function BlogIndex() {
|
|||||||
content={post.content}
|
content={post.content}
|
||||||
featuredImageId={post.featured_image_id}
|
featuredImageId={post.featured_image_id}
|
||||||
author={{
|
author={{
|
||||||
username: post.author.username,
|
username: post.profiles.username,
|
||||||
displayName: post.author.display_name,
|
displayName: post.profiles.display_name,
|
||||||
avatarUrl: post.author.avatar_url,
|
avatarUrl: post.profiles.avatar_url,
|
||||||
}}
|
}}
|
||||||
publishedAt={post.published_at!}
|
publishedAt={post.published_at!}
|
||||||
viewCount={post.view_count}
|
viewCount={post.view_count}
|
||||||
|
|||||||
@@ -18,21 +18,14 @@ export default function BlogPost() {
|
|||||||
const { data: post, isLoading } = useQuery({
|
const { data: post, isLoading } = useQuery({
|
||||||
queryKey: ['blog-post', slug],
|
queryKey: ['blog-post', slug],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data, error } = await supabase
|
const query = supabase
|
||||||
.from('blog_posts')
|
.from('blog_posts')
|
||||||
.select(`
|
.select('*, profiles!inner(username, display_name, avatar_url, avatar_image_id)')
|
||||||
*,
|
|
||||||
author:profiles(
|
|
||||||
username,
|
|
||||||
display_name,
|
|
||||||
avatar_url,
|
|
||||||
avatar_image_id
|
|
||||||
)
|
|
||||||
`)
|
|
||||||
.eq('slug', slug)
|
.eq('slug', slug)
|
||||||
.eq('status', 'published')
|
.eq('status', 'published')
|
||||||
.single();
|
.single();
|
||||||
|
|
||||||
|
const { data, error } = await query;
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
@@ -98,14 +91,14 @@ export default function BlogPost() {
|
|||||||
<div className="flex items-center justify-between mb-8 pb-6 border-b">
|
<div className="flex items-center justify-between mb-8 pb-6 border-b">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Avatar className="w-12 h-12">
|
<Avatar className="w-12 h-12">
|
||||||
<AvatarImage src={post.author.avatar_url} />
|
<AvatarImage src={post.profiles.avatar_url} />
|
||||||
<AvatarFallback>
|
<AvatarFallback>
|
||||||
{post.author.display_name?.[0] || post.author.username[0]}
|
{post.profiles.display_name?.[0] || post.profiles.username[0]}
|
||||||
</AvatarFallback>
|
</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium">
|
<p className="font-medium">
|
||||||
{post.author.display_name || post.author.username}
|
{post.profiles.display_name || post.profiles.username}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-3 text-sm text-muted-foreground">
|
<div className="flex items-center gap-3 text-sm text-muted-foreground">
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Fix blog_posts foreign key to reference profiles
|
||||||
|
ALTER TABLE blog_posts DROP CONSTRAINT IF EXISTS blog_posts_author_id_fkey;
|
||||||
|
ALTER TABLE blog_posts ADD CONSTRAINT blog_posts_author_id_fkey
|
||||||
|
FOREIGN KEY (author_id) REFERENCES profiles(user_id) ON DELETE CASCADE;
|
||||||
Reference in New Issue
Block a user