vendor slugs routes instead of ids
This commit is contained in:
@@ -4,16 +4,16 @@ import { prisma } from '@/lib/prisma'
|
||||
import { VendorDetailPage } from '@/components/vendor/VendorDetailPage'
|
||||
|
||||
interface PageProps {
|
||||
params: {
|
||||
id: string
|
||||
}
|
||||
params: {
|
||||
slug: string
|
||||
}
|
||||
}
|
||||
|
||||
export default async function Page({ params }: PageProps) {
|
||||
const { id } = params
|
||||
const { slug } = params
|
||||
|
||||
const vendor = await prisma.vendor.findUnique({
|
||||
where: { id },
|
||||
where: { slug },
|
||||
include: {
|
||||
address: true,
|
||||
events: {
|
||||
242
app/api/vendors/[id]/route.ts
vendored
242
app/api/vendors/[id]/route.ts
vendored
@@ -2,123 +2,139 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
import { VendorType, VendorStatus } from '@prisma/client'
|
||||
import { generateUniqueSlug, slugify } from '@/lib/utils/slugify'
|
||||
|
||||
export async function PUT(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { id: string } }
|
||||
request: NextRequest,
|
||||
{ params }: { params: { id: string } }
|
||||
) {
|
||||
try {
|
||||
const id = params.id
|
||||
const body = await request.json()
|
||||
|
||||
// Check if vendor exists
|
||||
const existingVendor = await prisma.vendor.findUnique({
|
||||
where: { id },
|
||||
include: { address: true }
|
||||
})
|
||||
|
||||
if (!existingVendor) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Vendor not found' },
|
||||
{ status: 404 }
|
||||
)
|
||||
}
|
||||
|
||||
// Parse numeric values
|
||||
const parseFloatOrNull = (value: any): number | null => {
|
||||
if (value === null || value === undefined || value === '') return null
|
||||
const num = parseFloat(value)
|
||||
return isNaN(num) ? null : num
|
||||
}
|
||||
|
||||
const parseDateOrNull = (value: any): Date | null => {
|
||||
if (!value) return null
|
||||
const date = new Date(value)
|
||||
return isNaN(date.getTime()) ? null : date
|
||||
}
|
||||
|
||||
// Handle address update/creation
|
||||
let addressId = existingVendor.addressId
|
||||
const hasAddress = body.street && body.city && body.state && body.postalCode
|
||||
|
||||
if (hasAddress) {
|
||||
if (existingVendor.address) {
|
||||
// Update existing address
|
||||
await prisma.address.update({
|
||||
where: { id: existingVendor.addressId! },
|
||||
data: {
|
||||
street: body.street,
|
||||
city: body.city,
|
||||
state: body.state,
|
||||
zip: parseInt(body.postalCode),
|
||||
}
|
||||
try {
|
||||
const id = params.id
|
||||
const body = await request.json()
|
||||
|
||||
// Check if vendor exists
|
||||
const existingVendor = await prisma.vendor.findUnique({
|
||||
where: { id },
|
||||
include: { address: true }
|
||||
})
|
||||
} else {
|
||||
// Create new address
|
||||
const newAddress = await prisma.address.create({
|
||||
data: {
|
||||
street: body.street,
|
||||
city: body.city,
|
||||
state: body.state,
|
||||
zip: parseInt(body.postalCode),
|
||||
}
|
||||
|
||||
if (!existingVendor) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Vendor not found' },
|
||||
{ status: 404 }
|
||||
)
|
||||
}
|
||||
|
||||
let slug = existingVendor.slug
|
||||
if (body.name && body.name !== existingVendor.name) {
|
||||
const baseSlug = slugify(body.name)
|
||||
slug = await generateUniqueSlug(
|
||||
baseSlug,
|
||||
async (testSlug) => {
|
||||
const existing = await prisma.vendor.findUnique({
|
||||
where: { slug: testSlug }
|
||||
})
|
||||
return !!existing && existing.id !== id
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Parse numeric values
|
||||
const parseFloatOrNull = (value: any): number | null => {
|
||||
if (value === null || value === undefined || value === '') return null
|
||||
const num = parseFloat(value)
|
||||
return isNaN(num) ? null : num
|
||||
}
|
||||
|
||||
const parseDateOrNull = (value: any): Date | null => {
|
||||
if (!value) return null
|
||||
const date = new Date(value)
|
||||
return isNaN(date.getTime()) ? null : date
|
||||
}
|
||||
|
||||
// Handle address update/creation
|
||||
let addressId = existingVendor.addressId
|
||||
const hasAddress = body.street && body.city && body.state && body.postalCode
|
||||
|
||||
if (hasAddress) {
|
||||
if (existingVendor.address) {
|
||||
// Update existing address
|
||||
await prisma.address.update({
|
||||
where: { id: existingVendor.addressId! },
|
||||
data: {
|
||||
street: body.street,
|
||||
city: body.city,
|
||||
state: body.state,
|
||||
zip: parseInt(body.postalCode),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// Create new address
|
||||
const newAddress = await prisma.address.create({
|
||||
data: {
|
||||
street: body.street,
|
||||
city: body.city,
|
||||
state: body.state,
|
||||
zip: parseInt(body.postalCode),
|
||||
}
|
||||
})
|
||||
addressId = newAddress.id
|
||||
}
|
||||
} else if (existingVendor.address) {
|
||||
// Remove address if it existed but now doesn't
|
||||
await prisma.address.delete({
|
||||
where: { id: existingVendor.addressId! }
|
||||
})
|
||||
addressId = null
|
||||
}
|
||||
|
||||
// Prepare update data
|
||||
const updateData: any = {
|
||||
slug,
|
||||
name: body.name,
|
||||
type: body.type as VendorType,
|
||||
description: body.description || null,
|
||||
website: body.website || null,
|
||||
contactPerson: body.contactPerson || null,
|
||||
email: body.email || null,
|
||||
phone: body.phone || null,
|
||||
status: (body.status as VendorStatus) || 'CONTACTING',
|
||||
isBooked: Boolean(body.isBooked),
|
||||
bookedDate: parseDateOrNull(body.bookedDate),
|
||||
quotedPrice: parseFloatOrNull(body.quotedPrice),
|
||||
finalCost: parseFloatOrNull(body.finalCost),
|
||||
depositPaid: parseFloatOrNull(body.depositPaid),
|
||||
depositDueDate: parseDateOrNull(body.depositDueDate),
|
||||
finalPaymentDue: parseDateOrNull(body.finalPaymentDue),
|
||||
paymentNotes: body.paymentNotes || null,
|
||||
contractUrl: body.contractUrl || null,
|
||||
proposalUrl: body.proposalUrl || null,
|
||||
notes: body.notes || null,
|
||||
}
|
||||
|
||||
// Only include addressId if we have one
|
||||
if (addressId) {
|
||||
updateData.addressId = addressId
|
||||
} else {
|
||||
updateData.addressId = null
|
||||
}
|
||||
|
||||
// Update vendor
|
||||
const updatedVendor = await prisma.vendor.update({
|
||||
where: { id },
|
||||
data: updateData,
|
||||
include: {
|
||||
address: !!addressId
|
||||
}
|
||||
})
|
||||
addressId = newAddress.id
|
||||
}
|
||||
} else if (existingVendor.address) {
|
||||
// Remove address if it existed but now doesn't
|
||||
await prisma.address.delete({
|
||||
where: { id: existingVendor.addressId! }
|
||||
})
|
||||
addressId = null
|
||||
|
||||
return NextResponse.json(updatedVendor)
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('Error updating vendor:', error)
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to update vendor', details: error.message },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
// Prepare update data
|
||||
const updateData: any = {
|
||||
name: body.name,
|
||||
type: body.type as VendorType,
|
||||
description: body.description || null,
|
||||
website: body.website || null,
|
||||
contactPerson: body.contactPerson || null,
|
||||
email: body.email || null,
|
||||
phone: body.phone || null,
|
||||
status: (body.status as VendorStatus) || 'CONTACTING',
|
||||
isBooked: Boolean(body.isBooked),
|
||||
bookedDate: parseDateOrNull(body.bookedDate),
|
||||
quotedPrice: parseFloatOrNull(body.quotedPrice),
|
||||
finalCost: parseFloatOrNull(body.finalCost),
|
||||
depositPaid: parseFloatOrNull(body.depositPaid),
|
||||
depositDueDate: parseDateOrNull(body.depositDueDate),
|
||||
finalPaymentDue: parseDateOrNull(body.finalPaymentDue),
|
||||
paymentNotes: body.paymentNotes || null,
|
||||
contractUrl: body.contractUrl || null,
|
||||
proposalUrl: body.proposalUrl || null,
|
||||
notes: body.notes || null,
|
||||
}
|
||||
|
||||
// Only include addressId if we have one
|
||||
if (addressId) {
|
||||
updateData.addressId = addressId
|
||||
} else {
|
||||
updateData.addressId = null
|
||||
}
|
||||
|
||||
// Update vendor
|
||||
const updatedVendor = await prisma.vendor.update({
|
||||
where: { id },
|
||||
data: updateData,
|
||||
include: {
|
||||
address: !!addressId
|
||||
}
|
||||
})
|
||||
|
||||
return NextResponse.json(updatedVendor)
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('Error updating vendor:', error)
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to update vendor', details: error.message },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
13
app/api/vendors/create/route.ts
vendored
13
app/api/vendors/create/route.ts
vendored
@@ -1,6 +1,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
import { VendorType, VendorStatus } from '@prisma/client'
|
||||
import { generateUniqueSlug, slugify } from '@/lib/utils/slugify'
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
@@ -15,6 +16,17 @@ export async function POST(request: NextRequest) {
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
const baseSlug = slugify(body.name)
|
||||
const uniqueSlug = await generateUniqueSlug(
|
||||
baseSlug,
|
||||
async (slug) => {
|
||||
const existing = await prisma.vendor.findUnique({
|
||||
where: { slug }
|
||||
})
|
||||
return !!existing
|
||||
}
|
||||
)
|
||||
|
||||
// Check if we have address data
|
||||
const hasAddress = body.street && body.city && body.state && body.postalCode
|
||||
@@ -34,6 +46,7 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
// Prepare vendor data WITHOUT addressId
|
||||
const vendorData: any = {
|
||||
slug: uniqueSlug,
|
||||
name: body.name,
|
||||
type: body.type as VendorType,
|
||||
description: body.description || null,
|
||||
|
||||
Reference in New Issue
Block a user