mirror of
https://github.com/jordienr/zenblog.git
synced 2026-10-07 06:14:34 -04:00
fix tags crud
This commit is contained in:
@@ -44,7 +44,7 @@ export const useCreateBlogTag = () => {
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(["tags"]);
|
||||
queryClient.invalidateQueries(["blog-tags"]);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
@@ -37,19 +37,19 @@ export function CreateTagDialog({ blogId }: PropsWithChildren<Props>) {
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const target = e.target as HTMLFormElement;
|
||||
const formData = new FormData(target);
|
||||
const name = formData.get("name") as string;
|
||||
const slug = formData.get("slug") as string;
|
||||
if (!name || !slug) {
|
||||
if (!title || !slug) {
|
||||
toast.error("Name and slug are required");
|
||||
return;
|
||||
}
|
||||
await createTag.mutateAsync({ name, slug, blog_id: blogId });
|
||||
formData.set("name", "");
|
||||
formData.set("slug", "");
|
||||
await createTag.mutateAsync({
|
||||
name: title,
|
||||
slug,
|
||||
blog_id: blogId,
|
||||
});
|
||||
|
||||
setTitle("");
|
||||
setSlug("");
|
||||
|
||||
target.reset();
|
||||
toast.success("Tag created");
|
||||
setOpen(false);
|
||||
}}
|
||||
|
||||
@@ -3,18 +3,29 @@ import { Button } from "../ui/button";
|
||||
import { Dialog, DialogContent } from "../ui/dialog";
|
||||
import { Input } from "../ui/input";
|
||||
import { Label } from "../ui/label";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
type Props = {
|
||||
tag: {
|
||||
tag_id: string | null;
|
||||
tag_name: string | null;
|
||||
slug: string | null;
|
||||
};
|
||||
onSubmit: (tag: { tag_name: string; slug: string }) => void;
|
||||
tag:
|
||||
| {
|
||||
tag_id: string | null;
|
||||
tag_name: string | null;
|
||||
slug: string | null;
|
||||
}
|
||||
| undefined;
|
||||
onSubmit: (tag: { tag_name: string; slug: string; tag_id: string }) => void;
|
||||
open: boolean;
|
||||
onOpenChange: (value: boolean) => void;
|
||||
};
|
||||
export function UpdateTagDialog({ onSubmit, tag, open, onOpenChange }: Props) {
|
||||
const [newTitle, setNewTitle] = useState(tag?.tag_name || "");
|
||||
const [newSlug, setNewSlug] = useState(tag?.slug || "");
|
||||
|
||||
useEffect(() => {
|
||||
setNewTitle(tag?.tag_name || "");
|
||||
setNewSlug(tag?.slug || "");
|
||||
}, [tag]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="md:max-w-sm">
|
||||
@@ -24,26 +35,39 @@ export function UpdateTagDialog({ onSubmit, tag, open, onOpenChange }: Props) {
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const target = e.target as HTMLFormElement;
|
||||
const formData = new FormData(target);
|
||||
const tag_name = formData.get("tag_name") as string;
|
||||
const slug = formData.get("slug") as string;
|
||||
if (!tag_name || !slug) {
|
||||
toast.error("Name and slug are required");
|
||||
if (!tag?.tag_id) {
|
||||
return;
|
||||
}
|
||||
onSubmit({ tag_name, slug });
|
||||
formData.set("name", "");
|
||||
formData.set("slug", "");
|
||||
onSubmit({
|
||||
tag_name: newTitle,
|
||||
slug: newSlug,
|
||||
tag_id: tag?.tag_id,
|
||||
});
|
||||
|
||||
target.reset();
|
||||
toast.success("Tag updated");
|
||||
setNewTitle("");
|
||||
setNewSlug("");
|
||||
}}
|
||||
>
|
||||
<Label>Name</Label>
|
||||
<Input name="tag_name" required defaultValue={tag.tag_name!} />
|
||||
<Input
|
||||
name="tag_name"
|
||||
required
|
||||
onChange={(e) => {
|
||||
setNewTitle(e.target.value);
|
||||
}}
|
||||
value={newTitle}
|
||||
/>
|
||||
<Label>Slug</Label>
|
||||
<Input name="slug" required defaultValue={tag.slug!} />
|
||||
<Input
|
||||
name="slug"
|
||||
required
|
||||
value={newSlug}
|
||||
onChange={(e) => {
|
||||
// if the user writes a space, we should replace it with a dash
|
||||
const value = e.target.value.replace(/\s/g, "-");
|
||||
setNewSlug(value);
|
||||
}}
|
||||
/>
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<Button type="submit">Update</Button>
|
||||
</div>
|
||||
|
||||
@@ -86,7 +86,11 @@ export default function BlogPosts() {
|
||||
});
|
||||
const deleteMedia = useDeleteMediaMutation();
|
||||
const [selectedImages, setSelectedImages] = useState<Image[]>([]);
|
||||
const [selectedTag, setSelectedTag] = useState<{ tag_id?: string | null }>();
|
||||
const [selectedTag, setSelectedTag] = useState<{
|
||||
tag_id: string | null;
|
||||
tag_name: string | null;
|
||||
slug: string | null;
|
||||
}>();
|
||||
|
||||
const tags = useTagsWithUsageQuery(
|
||||
{ blogId },
|
||||
@@ -118,8 +122,8 @@ export default function BlogPosts() {
|
||||
},
|
||||
});
|
||||
|
||||
const deleteTagMutation = useDeleteTagMutation();
|
||||
const updateTagMutation = useUpdateTagMutation();
|
||||
const deleteTagMutation = useDeleteTagMutation(blogId);
|
||||
const updateTagMutation = useUpdateTagMutation(blogId);
|
||||
|
||||
function getPostViews(slug: string) {
|
||||
const post = postViews.data?.find((p: any) => p.post_slug === slug);
|
||||
@@ -378,7 +382,7 @@ export default function BlogPosts() {
|
||||
<div className="grid grid-cols-4 items-center p-2 text-sm font-medium text-zinc-600">
|
||||
<div>Tag</div>
|
||||
<div>Slug</div>
|
||||
<div>Posts with tag</div>
|
||||
<div className="text-right">Posts with tag</div>
|
||||
<div></div>
|
||||
</div>
|
||||
) : null}
|
||||
@@ -400,7 +404,9 @@ export default function BlogPosts() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="font-mono">{tag.post_count}</div>
|
||||
<div className="text-right font-mono">
|
||||
{tag.post_count}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-end">
|
||||
<DropdownMenu modal={false}>
|
||||
@@ -412,6 +418,10 @@ export default function BlogPosts() {
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
if (!tag) {
|
||||
return;
|
||||
}
|
||||
setSelectedTag(tag);
|
||||
setUpdateTagDialogOpen(true);
|
||||
}}
|
||||
>
|
||||
@@ -420,7 +430,9 @@ export default function BlogPosts() {
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
console.log("selected tag", tag);
|
||||
if (!tag) {
|
||||
return;
|
||||
}
|
||||
setSelectedTag(tag);
|
||||
setDeleteTagDialogOpen(true);
|
||||
}}
|
||||
@@ -431,23 +443,6 @@ export default function BlogPosts() {
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
<UpdateTagDialog
|
||||
tag={tag}
|
||||
onSubmit={async (newTag) => {
|
||||
const res = await updateTagMutation.mutateAsync({
|
||||
name: newTag.tag_name,
|
||||
slug: newTag.slug,
|
||||
id: tag.tag_id!,
|
||||
});
|
||||
if (res.error) {
|
||||
toast.error("Failed to update tag");
|
||||
return;
|
||||
}
|
||||
toast.success("Tag updated");
|
||||
}}
|
||||
open={updateTagDialogOpen}
|
||||
onOpenChange={setUpdateTagDialogOpen}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
@@ -456,6 +451,25 @@ export default function BlogPosts() {
|
||||
</TabSection>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
<UpdateTagDialog
|
||||
tag={selectedTag}
|
||||
onSubmit={async (newTag) => {
|
||||
if (!newTag.tag_id) return;
|
||||
const res = await updateTagMutation.mutateAsync({
|
||||
name: newTag.tag_name,
|
||||
slug: newTag.slug,
|
||||
id: newTag.tag_id,
|
||||
});
|
||||
if (res.error) {
|
||||
toast.error("Failed to update tag");
|
||||
return;
|
||||
}
|
||||
setUpdateTagDialogOpen(false);
|
||||
toast.success("Tag updated");
|
||||
}}
|
||||
open={updateTagDialogOpen}
|
||||
onOpenChange={setUpdateTagDialogOpen}
|
||||
/>
|
||||
<ConfirmDialog
|
||||
title="Delete tag"
|
||||
description="Are you sure you want to delete this tag? This action cannot be undone."
|
||||
|
||||
@@ -2,8 +2,8 @@ import { getSupabaseBrowserClient } from "@/lib/supabase";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
export const tagKeys = {
|
||||
tags: (keys: string[]) => ["tags", ...keys],
|
||||
tag: (tagId: string) => ["tag", tagId],
|
||||
tags: (keys: string[]) => ["blog-tags", ...keys],
|
||||
tag: (tagId: string) => ["blog-tag", tagId],
|
||||
};
|
||||
|
||||
export function useTagsWithUsageQuery(
|
||||
@@ -30,13 +30,17 @@ export function useTagsWithUsageQuery(
|
||||
});
|
||||
}
|
||||
|
||||
export function useDeleteTagMutation() {
|
||||
export function useDeleteTagMutation(blogId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
const supa = getSupabaseBrowserClient();
|
||||
|
||||
return useMutation(
|
||||
async (tagId: string) => {
|
||||
const res = await supa.from("blog_tags").delete().eq("id", tagId);
|
||||
const res = await supa
|
||||
.from("blog_tags")
|
||||
.delete()
|
||||
.eq("id", tagId)
|
||||
.eq("blog_id", blogId);
|
||||
|
||||
if (res.error) {
|
||||
throw new Error(res.error.message);
|
||||
@@ -46,13 +50,13 @@ export function useDeleteTagMutation() {
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(tagKeys.tags([""]));
|
||||
queryClient.invalidateQueries(tagKeys.tags([blogId]));
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function useUpdateTagMutation() {
|
||||
export function useUpdateTagMutation(blogId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
const supa = getSupabaseBrowserClient();
|
||||
|
||||
@@ -68,7 +72,7 @@ export function useUpdateTagMutation() {
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(tagKeys.tags([""]));
|
||||
queryClient.invalidateQueries(tagKeys.tags([blogId]));
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
+196
-18
@@ -6,7 +6,7 @@ export type Json =
|
||||
| { [key: string]: Json | undefined }
|
||||
| Json[]
|
||||
|
||||
export interface Database {
|
||||
export type Database = {
|
||||
public: {
|
||||
Tables: {
|
||||
blog_tags: {
|
||||
@@ -41,9 +41,10 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "blog_tags_blog_id_fkey"
|
||||
columns: ["blog_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blogs"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
blogs: {
|
||||
@@ -52,7 +53,7 @@ export interface Database {
|
||||
description: string | null
|
||||
emoji: string
|
||||
id: string
|
||||
slug: string | null
|
||||
slug: string
|
||||
title: string
|
||||
user_id: string
|
||||
}
|
||||
@@ -61,7 +62,7 @@ export interface Database {
|
||||
description?: string | null
|
||||
emoji: string
|
||||
id?: string
|
||||
slug?: string | null
|
||||
slug: string
|
||||
title: string
|
||||
user_id?: string
|
||||
}
|
||||
@@ -70,7 +71,7 @@ export interface Database {
|
||||
description?: string | null
|
||||
emoji?: string
|
||||
id?: string
|
||||
slug?: string | null
|
||||
slug?: string
|
||||
title?: string
|
||||
user_id?: string
|
||||
}
|
||||
@@ -78,15 +79,17 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "blogs_user_id_fkey"
|
||||
columns: ["user_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "users"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "blogs_user_id_fkey"
|
||||
columns: ["user_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "users"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
feedback: {
|
||||
@@ -157,61 +160,71 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "post_tags_blog_id_fkey"
|
||||
columns: ["blog_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blogs"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts_with_blog_and_subscription_status"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts_with_blog_and_subscription_status_v2"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts_with_tags"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts_with_tags_v2"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "public_posts_v1"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_tag_id_fkey"
|
||||
columns: ["tag_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blog_tags"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_tag_id_fkey"
|
||||
columns: ["tag_id"]
|
||||
referencedRelation: "tag_usage_count_v1"
|
||||
isOneToOne: false
|
||||
referencedRelation: "tag_usage_count_v2"
|
||||
referencedColumns: ["tag_id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
posts: {
|
||||
Row: {
|
||||
abstract: string
|
||||
blog_id: string
|
||||
content: Json
|
||||
cover_image: string | null
|
||||
@@ -227,6 +240,7 @@ export interface Database {
|
||||
user_id: string
|
||||
}
|
||||
Insert: {
|
||||
abstract?: string
|
||||
blog_id: string
|
||||
content?: Json
|
||||
cover_image?: string | null
|
||||
@@ -242,6 +256,7 @@ export interface Database {
|
||||
user_id?: string
|
||||
}
|
||||
Update: {
|
||||
abstract?: string
|
||||
blog_id?: string
|
||||
content?: Json
|
||||
cover_image?: string | null
|
||||
@@ -260,21 +275,24 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "posts_blog_id_fkey"
|
||||
columns: ["blog_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blogs"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "public_posts_user_id_fkey"
|
||||
columns: ["user_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "users"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "public_posts_user_id_fkey"
|
||||
columns: ["user_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "users"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
prices: {
|
||||
@@ -345,15 +363,17 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "subscriptions_user_id_fkey"
|
||||
columns: ["user_id"]
|
||||
isOneToOne: true
|
||||
referencedRelation: "users"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "subscriptions_user_id_fkey"
|
||||
columns: ["user_id"]
|
||||
isOneToOne: true
|
||||
referencedRelation: "users"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
teams: {
|
||||
@@ -382,19 +402,90 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "public_teams_owner_id_fkey"
|
||||
columns: ["owner_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "users"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "public_teams_owner_id_fkey"
|
||||
columns: ["owner_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "users"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
Views: {
|
||||
post_tags_with_tags: {
|
||||
Row: {
|
||||
created_at: string | null
|
||||
id: number | null
|
||||
post_id: string | null
|
||||
tag_description: string | null
|
||||
tag_id: string | null
|
||||
tag_name: string | null
|
||||
tag_slug: string | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts_with_blog_and_subscription_status"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts_with_blog_and_subscription_status_v2"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts_with_tags"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "posts_with_tags_v2"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_post_id_fkey"
|
||||
columns: ["post_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "public_posts_v1"
|
||||
referencedColumns: ["post_id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_tag_id_fkey"
|
||||
columns: ["tag_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blog_tags"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "post_tags_tag_id_fkey"
|
||||
columns: ["tag_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "tag_usage_count_v2"
|
||||
referencedColumns: ["tag_id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
posts_with_blog_and_subscription_status: {
|
||||
Row: {
|
||||
blog_id: string | null
|
||||
@@ -415,9 +506,10 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "posts_blog_id_fkey"
|
||||
columns: ["blog_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blogs"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
posts_with_blog_and_subscription_status_v2: {
|
||||
@@ -441,9 +533,10 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "posts_blog_id_fkey"
|
||||
columns: ["blog_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blogs"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
posts_with_tags: {
|
||||
@@ -465,9 +558,10 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "posts_blog_id_fkey"
|
||||
columns: ["blog_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blogs"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
posts_with_tags_v2: {
|
||||
@@ -490,9 +584,10 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "posts_blog_id_fkey"
|
||||
columns: ["blog_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blogs"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
public_posts_v1: {
|
||||
@@ -517,12 +612,13 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "posts_blog_id_fkey"
|
||||
columns: ["blog_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blogs"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
tag_usage_count_v1: {
|
||||
tag_usage_count_v2: {
|
||||
Row: {
|
||||
blog_id: string | null
|
||||
created_at: string | null
|
||||
@@ -536,9 +632,10 @@ export interface Database {
|
||||
{
|
||||
foreignKeyName: "blog_tags_blog_id_fkey"
|
||||
columns: ["blog_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "blogs"
|
||||
referencedColumns: ["id"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
users: {
|
||||
@@ -687,3 +784,84 @@ export interface Database {
|
||||
}
|
||||
}
|
||||
|
||||
type PublicSchema = Database[Extract<keyof Database, "public">]
|
||||
|
||||
export type Tables<
|
||||
PublicTableNameOrOptions extends
|
||||
| keyof (PublicSchema["Tables"] & PublicSchema["Views"])
|
||||
| { schema: keyof Database },
|
||||
TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
|
||||
? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
|
||||
Database[PublicTableNameOrOptions["schema"]]["Views"])
|
||||
: never = never,
|
||||
> = PublicTableNameOrOptions extends { schema: keyof Database }
|
||||
? (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
|
||||
Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends {
|
||||
Row: infer R
|
||||
}
|
||||
? R
|
||||
: never
|
||||
: PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] &
|
||||
PublicSchema["Views"])
|
||||
? (PublicSchema["Tables"] &
|
||||
PublicSchema["Views"])[PublicTableNameOrOptions] extends {
|
||||
Row: infer R
|
||||
}
|
||||
? R
|
||||
: never
|
||||
: never
|
||||
|
||||
export type TablesInsert<
|
||||
PublicTableNameOrOptions extends
|
||||
| keyof PublicSchema["Tables"]
|
||||
| { schema: keyof Database },
|
||||
TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
|
||||
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
|
||||
: never = never,
|
||||
> = PublicTableNameOrOptions extends { schema: keyof Database }
|
||||
? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
|
||||
Insert: infer I
|
||||
}
|
||||
? I
|
||||
: never
|
||||
: PublicTableNameOrOptions extends keyof PublicSchema["Tables"]
|
||||
? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
|
||||
Insert: infer I
|
||||
}
|
||||
? I
|
||||
: never
|
||||
: never
|
||||
|
||||
export type TablesUpdate<
|
||||
PublicTableNameOrOptions extends
|
||||
| keyof PublicSchema["Tables"]
|
||||
| { schema: keyof Database },
|
||||
TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
|
||||
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
|
||||
: never = never,
|
||||
> = PublicTableNameOrOptions extends { schema: keyof Database }
|
||||
? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
|
||||
Update: infer U
|
||||
}
|
||||
? U
|
||||
: never
|
||||
: PublicTableNameOrOptions extends keyof PublicSchema["Tables"]
|
||||
? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
|
||||
Update: infer U
|
||||
}
|
||||
? U
|
||||
: never
|
||||
: never
|
||||
|
||||
export type Enums<
|
||||
PublicEnumNameOrOptions extends
|
||||
| keyof PublicSchema["Enums"]
|
||||
| { schema: keyof Database },
|
||||
EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database }
|
||||
? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"]
|
||||
: never = never,
|
||||
> = PublicEnumNameOrOptions extends { schema: keyof Database }
|
||||
? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName]
|
||||
: PublicEnumNameOrOptions extends keyof PublicSchema["Enums"]
|
||||
? PublicSchema["Enums"][PublicEnumNameOrOptions]
|
||||
: never
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"start": "concurrently --names \"APP,STRIPE\" -c \"bgBlue.bold,bgMagenta.bold\" \"npm run dev\" \"npm run stripe:webhook\"",
|
||||
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
|
||||
"db:typegen": "npx supabase gen types typescript --local --schema public > apps/web/src/types/supabase.ts",
|
||||
"db:typegen:remote": "npx supabase gen types typescript --project-id ppfseefimhneysnokffx --schema public > apps/web/src/types/supabase.ts",
|
||||
"db:start": "npx supabase start",
|
||||
"db:stop": "npx supabase stop",
|
||||
"db:open": "open http://localhost:54323",
|
||||
|
||||
Reference in New Issue
Block a user