Skip to content

Commit

Permalink
feat: add tags
Browse files Browse the repository at this point in the history
  • Loading branch information
sadmann7 committed May 26, 2024
1 parent 2923f4a commit 5b7689b
Show file tree
Hide file tree
Showing 21 changed files with 179 additions and 117 deletions.
3 changes: 0 additions & 3 deletions drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { env } from "@/env.js"
import { type Config } from "drizzle-kit"

import { dbPrefix } from "@/lib/constants"

export default {
schema: "./src/db/schema/index.ts",
dialect: "postgresql",
out: "./drizzle",
dbCredentials: {
url: env.DATABASE_URL,
},
tablesFilter: [`${dbPrefix}_*`],
} satisfies Config
10 changes: 7 additions & 3 deletions src/components/layouts/auth-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,13 @@ export async function AuthDropdown({
</DropdownMenuLabel>
<DropdownMenuSeparator />
<React.Suspense
fallback={Array.from({ length: 3 }).map((_, i) => (
<Skeleton key={i} className="h-4 w-full" />
))}
fallback={
<div className="flex flex-col space-y-1.5 p-1">
{Array.from({ length: 3 }).map((_, i) => (
<Skeleton key={i} className="h-6 w-full" />
))}
</div>
}
>
<AuthDropdownGroup storePromise={storePromise} />
</React.Suspense>
Expand Down
22 changes: 13 additions & 9 deletions src/components/layouts/sidebar-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,19 @@ export function SidebarNav({ items, className, ...props }: SidebarNavProps) {
{items.map((item, index) => {
const Icon = Icons[item.icon ?? "chevronLeft"]

return item.href ? (
if (!item.href) {
return (
<span
key={index}
className="flex w-full cursor-not-allowed items-center rounded-md p-2 text-muted-foreground hover:underline"
>
<Icon className="mr-2 size-4" aria-hidden="true" />
{item.title}
</span>
)
}

return (
<Link
aria-label={item.title}
key={index}
Expand All @@ -48,14 +60,6 @@ export function SidebarNav({ items, className, ...props }: SidebarNavProps) {
<span>{item.title}</span>
</span>
</Link>
) : (
<span
key={index}
className="flex w-full cursor-not-allowed items-center rounded-md p-2 text-muted-foreground hover:underline"
>
<Icon className="mr-2 size-4" aria-hidden="true" />
{item.title}
</span>
)
})}
</div>
Expand Down
3 changes: 1 addition & 2 deletions src/db/schema/addresses.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { pgTable } from "@/db/utils"
import { varchar } from "drizzle-orm/pg-core"
import { pgTable, varchar } from "drizzle-orm/pg-core"

import { generateId } from "@/lib/id"

Expand Down
3 changes: 1 addition & 2 deletions src/db/schema/carts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { pgTable } from "@/db/utils"
import { boolean, json, varchar } from "drizzle-orm/pg-core"
import { boolean, json, pgTable, varchar } from "drizzle-orm/pg-core"

import { generateId } from "@/lib/id"
import { type CartItemSchema } from "@/lib/validations/cart"
Expand Down
3 changes: 1 addition & 2 deletions src/db/schema/categories.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { pgTable } from "@/db/utils"
import { relations } from "drizzle-orm"
import { text, varchar } from "drizzle-orm/pg-core"
import { pgTable, text, varchar } from "drizzle-orm/pg-core"

import { generateId } from "@/lib/id"

Expand Down
2 changes: 2 additions & 0 deletions src/db/schema/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export * from "./stores"
export * from "./tags"
export * from "./products"
export * from "./categories"
export * from "./subcategories"
export * from "./product-tags"
export * from "./carts"
export * from "./subscriptions"
export * from "./payments"
Expand Down
3 changes: 1 addition & 2 deletions src/db/schema/notifications.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { pgTable } from "@/db/utils"
import { boolean, varchar } from "drizzle-orm/pg-core"
import { boolean, pgTable, varchar } from "drizzle-orm/pg-core"

import { generateId } from "@/lib/id"

Expand Down
17 changes: 10 additions & 7 deletions src/db/schema/orders.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { pgTable } from "@/db/utils"
import { decimal, index, integer, json, varchar } from "drizzle-orm/pg-core"
import {
decimal,
index,
integer,
json,
pgTable,
varchar,
} from "drizzle-orm/pg-core"

import { dbPrefix } from "@/lib/constants"
import { generateId } from "@/lib/id"
import { type CheckoutItemSchema } from "@/lib/validations/cart"

Expand Down Expand Up @@ -38,10 +43,8 @@ export const orders = pgTable(
...lifecycleDates,
},
(table) => ({
storeIdIdx: index(`${dbPrefix}_orders_store_id_idx`).on(table.storeId),
addressIdIdx: index(`${dbPrefix}_orders_address_id_idx`).on(
table.addressId
),
storeIdIdx: index("orders_store_id_idx").on(table.storeId),
addressIdIdx: index("orders_address_id_idx").on(table.addressId),
})
)

Expand Down
6 changes: 2 additions & 4 deletions src/db/schema/payments.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { pgTable } from "@/db/utils"
import { relations } from "drizzle-orm"
import { boolean, index, integer, varchar } from "drizzle-orm/pg-core"
import { boolean, index, integer, pgTable, varchar } from "drizzle-orm/pg-core"

import { dbPrefix } from "@/lib/constants"
import { generateId } from "@/lib/id"

import { stores } from "./stores"
Expand All @@ -25,7 +23,7 @@ export const payments = pgTable(
...lifecycleDates,
},
(table) => ({
storeIdIdx: index(`${dbPrefix}_payments_store_id_idx`).on(table.storeId),
storeIdIdx: index("payments_store_id_idx").on(table.storeId),
})
)

Expand Down
36 changes: 36 additions & 0 deletions src/db/schema/product-tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { relations } from "drizzle-orm"
import { index, pgTable, varchar } from "drizzle-orm/pg-core"

import { products } from "./products"
import { tags } from "./tags"
import { lifecycleDates } from "./utils"

export const productTags = pgTable(
"product_tags",
{
productId: varchar("product_id", { length: 30 })
.references(() => products.id, { onDelete: "cascade" })
.notNull(),
tagId: varchar("tag_id", { length: 30 })
.references(() => tags.id, { onDelete: "cascade" })
.notNull(),
...lifecycleDates,
},
(table) => ({
productTagIdx: index("product_tags_product_id_tag_id_idx").on(
table.productId,
table.tagId
),
})
)

export const productTagsRelations = relations(productTags, ({ one }) => ({
product: one(products, {
fields: [productTags.productId],
references: [products.id],
}),
tag: one(tags, { fields: [productTags.tagId], references: [tags.id] }),
}))

export type ProductTag = typeof productTags.$inferSelect
export type NewProductTag = typeof productTags.$inferInsert
39 changes: 39 additions & 0 deletions src/db/schema/product-variants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { relations } from "drizzle-orm"
import { decimal, index, integer, pgTable, varchar } from "drizzle-orm/pg-core"

import { generateId } from "@/lib/id"

import { products } from "./products"
import { lifecycleDates } from "./utils"

export const productVariants = pgTable(
"product_variants",
{
id: varchar("id", { length: 30 })
.$defaultFn(() => generateId())
.primaryKey(),
productId: varchar("product_id", { length: 30 })
.references(() => products.id, { onDelete: "cascade" })
.notNull(),
name: varchar("name", { length: 256 }).notNull(),
price: decimal("price", { precision: 10, scale: 2 }).notNull().default("0"),
quantity: integer("quantity").notNull().default(0),
...lifecycleDates,
},
(table) => ({
productIdIdx: index("product_variants_product_id_idx").on(table.productId),
})
)

export const productVariantsRelations = relations(
productVariants,
({ one }) => ({
product: one(products, {
fields: [productVariants.productId],
references: [products.id],
}),
})
)

export type ProductVariant = typeof productVariants.$inferSelect
export type NewProductVariant = typeof productVariants.$inferInsert
24 changes: 16 additions & 8 deletions src/db/schema/products.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import { pgTable } from "@/db/utils"
import type { StoredFile } from "@/types"
import { relations } from "drizzle-orm"
import {
decimal,
index,
integer,
json,
pgEnum,
pgTable,
text,
varchar,
} from "drizzle-orm/pg-core"

import { dbPrefix } from "@/lib/constants"
import { generateId } from "@/lib/id"

import { categories } from "./categories"
import { stores } from "./stores"
import { subcategories } from "./subcategories"
import { lifecycleDates } from "./utils"

export const productStatusEnum = pgEnum("product_status", [
"active",
"draft",
"archived",
])

export const products = pgTable(
"products",
{
Expand All @@ -39,20 +45,22 @@ export const products = pgTable(
* @see https://www.postgresql.org/docs/current/datatype-numeric.html#:~:text=9223372036854775808%20to%20%2B9223372036854775807-,decimal,the%20decimal%20point%3B%20up%20to%2016383%20digits%20after%20the%20decimal%20point,-real
*/
price: decimal("price", { precision: 10, scale: 2 }).notNull().default("0"),
originalPrice: decimal("original_price", {
precision: 10,
scale: 2,
}).default("0"),
inventory: integer("inventory").notNull().default(0),
rating: integer("rating").notNull().default(0),
tags: json("tags").$type<string[] | null>().default(null),
status: productStatusEnum("status").notNull().default("active"),
storeId: varchar("store_id", { length: 30 })
.references(() => stores.id, { onDelete: "cascade" })
.notNull(),
...lifecycleDates,
},
(table) => ({
storeIdIdx: index(`${dbPrefix}_products_store_id_idx`).on(table.storeId),
categoryIdIdx: index(`${dbPrefix}_products_category_id_idx`).on(
table.categoryId
),
subcategoryIdIdx: index(`${dbPrefix}_products_subcategory_id_idx`).on(
storeIdIdx: index("products_store_id_idx").on(table.storeId),
categoryIdIdx: index("products_category_id_idx").on(table.categoryId),
subcategoryIdIdx: index("products_subcategory_id_idx").on(
table.subcategoryId
),
})
Expand Down
4 changes: 2 additions & 2 deletions src/db/schema/stores.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { pgTable } from "@/db/utils"
import { relations } from "drizzle-orm"
import { boolean, text, varchar } from "drizzle-orm/pg-core"
import { boolean, integer, pgTable, text, varchar } from "drizzle-orm/pg-core"

import { generateId } from "@/lib/id"

Expand All @@ -17,6 +16,7 @@ export const stores = pgTable("stores", {
description: text("description"),
slug: text("slug").unique(),
active: boolean("active").notNull().default(false),
tagLimit: integer("tag_limit").notNull().default(5),
stripeAccountId: varchar("stripe_account_id"),
...lifecycleDates,
})
Expand Down
10 changes: 4 additions & 6 deletions src/db/schema/subcategories.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { pgTable } from "@/db/utils"
import { relations } from "drizzle-orm"
import { index, text, varchar } from "drizzle-orm/pg-core"
import { index, pgTable, text, varchar } from "drizzle-orm/pg-core"

import { dbPrefix } from "@/lib/constants"
import { generateId } from "@/lib/id"

import { categories } from "./categories"
Expand All @@ -23,9 +21,9 @@ export const subcategories = pgTable(
...lifecycleDates,
},
(table) => ({
subcategoriesCategoryIdIdx: index(
`${dbPrefix}_subcategories_category_id_idx`
).on(table.categoryId),
subcategoriesCategoryIdIdx: index("subcategories_category_id_idx").on(
table.categoryId
),
})
)

Expand Down
3 changes: 1 addition & 2 deletions src/db/schema/subscriptions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { pgTable } from "@/db/utils"
import { timestamp, varchar } from "drizzle-orm/pg-core"
import { pgTable, timestamp, varchar } from "drizzle-orm/pg-core"

import { generateId } from "@/lib/id"

Expand Down
34 changes: 34 additions & 0 deletions src/db/schema/tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { relations } from "drizzle-orm"
import { index, pgTable, varchar } from "drizzle-orm/pg-core"

import { generateId } from "@/lib/id"

import { products } from "./products"
import { stores } from "./stores"

export const tags = pgTable(
"tags",
{
id: varchar("id", { length: 30 })
.$defaultFn(() => generateId())
.primaryKey(),
name: varchar("name", { length: 50 }).notNull(),
color: varchar("color", { length: 50 }).notNull().default("#000000"),
storeId: varchar("store_id", { length: 30 })
.references(() => stores.id, { onDelete: "cascade" })
.notNull(),
},
(table) => ({
storeIdIdx: index("tags_store_id_idx").on(table.storeId),
})
)

export const tagsRelations = relations(tags, ({ one, many }) => ({
store: one(stores, { fields: [tags.storeId], references: [stores.id] }),
products: many(products, {
relationName: "productTags",
}),
}))

export type Tag = typeof tags.$inferSelect
export type NewTag = typeof tags.$inferInsert
12 changes: 0 additions & 12 deletions src/db/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
import { pgTableCreator } from "drizzle-orm/pg-core"

import { dbPrefix } from "@/lib/constants"

/**
* This lets us use the multi-project schema feature of Drizzle ORM. So the same
* database instance can be used for multiple projects.
*
* @see https://orm.drizzle.team/docs/goodies#multi-project-schema
*/
export const pgTable = pgTableCreator((name) => `${dbPrefix}_${name}`)

// @see https://gist.github.com/rphlmr/0d1722a794ed5a16da0fdf6652902b15

export function takeFirst<T>(items: T[]) {
Expand Down
1 change: 0 additions & 1 deletion src/lib/actions/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ export async function getProducts(input: SearchParams) {
price: products.price,
inventory: products.inventory,
rating: products.rating,
tags: products.tags,
storeId: products.storeId,
createdAt: products.createdAt,
updatedAt: products.updatedAt,
Expand Down
Loading

0 comments on commit 5b7689b

Please sign in to comment.