modify commission ordering form
This commit is contained in:
@ -34,7 +34,7 @@ model CommissionOption {
|
|||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
sortIndex Int @default(0)
|
sortIndex Int @default(0)
|
||||||
|
|
||||||
name String @unique
|
name String
|
||||||
|
|
||||||
description String?
|
description String?
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ model CommissionExtra {
|
|||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
sortIndex Int @default(0)
|
sortIndex Int @default(0)
|
||||||
|
|
||||||
name String @unique
|
name String
|
||||||
|
|
||||||
description String?
|
description String?
|
||||||
|
|
||||||
@ -91,84 +91,3 @@ model CommissionTypeExtra {
|
|||||||
|
|
||||||
@@unique([typeId, extraId])
|
@@unique([typeId, extraId])
|
||||||
}
|
}
|
||||||
|
|
||||||
// model User {
|
|
||||||
// id String @id @default(cuid())
|
|
||||||
// email String @unique
|
|
||||||
// name String?
|
|
||||||
// role Role @default(ADMIN)
|
|
||||||
// createdAt DateTime @default(now())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// enum Role {
|
|
||||||
// ADMIN
|
|
||||||
// ARTIST
|
|
||||||
// }
|
|
||||||
|
|
||||||
// model CommissionType {
|
|
||||||
// id String @id @default(cuid())
|
|
||||||
// title String
|
|
||||||
// description String?
|
|
||||||
// basePrice Float
|
|
||||||
// deliveryEst String? // e.g. "2 weeks"
|
|
||||||
// tags String[] // e.g. shaded, sketch, full-body
|
|
||||||
// active Boolean @default(true)
|
|
||||||
// createdAt DateTime @default(now())
|
|
||||||
// CommissionRequest CommissionRequest[]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// model CommissionRequest {
|
|
||||||
// id String @id @default(cuid())
|
|
||||||
// name String
|
|
||||||
// email String
|
|
||||||
// message String
|
|
||||||
// typeId String
|
|
||||||
// status RequestStatus @default(PENDING)
|
|
||||||
// createdAt DateTime @default(now())
|
|
||||||
|
|
||||||
// type CommissionType @relation(fields: [typeId], references: [id])
|
|
||||||
// }
|
|
||||||
|
|
||||||
// enum RequestStatus {
|
|
||||||
// PENDING
|
|
||||||
// ACCEPTED
|
|
||||||
// IN_PROGRESS
|
|
||||||
// DONE
|
|
||||||
// REJECTED
|
|
||||||
// }
|
|
||||||
|
|
||||||
// model Artwork {
|
|
||||||
// id String @id @default(cuid())
|
|
||||||
// title String
|
|
||||||
// imageUrl String
|
|
||||||
// description String?
|
|
||||||
// tags String[]
|
|
||||||
// formats String[]
|
|
||||||
// isPublic Boolean @default(true)
|
|
||||||
// groupId String?
|
|
||||||
// createdAt DateTime @default(now())
|
|
||||||
|
|
||||||
// group PresentationGroup? @relation(fields: [groupId], references: [id])
|
|
||||||
// }
|
|
||||||
|
|
||||||
// model PresentationGroup {
|
|
||||||
// id String @id @default(cuid())
|
|
||||||
// name String
|
|
||||||
// description String?
|
|
||||||
// createdAt DateTime @default(now())
|
|
||||||
// Artwork Artwork[]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// model Preferences {
|
|
||||||
// id String @id @default(cuid())
|
|
||||||
// commissionOpen Boolean @default(true)
|
|
||||||
// defaultDelivery String? // e.g. "7 days"
|
|
||||||
// autoReplyMessage String?
|
|
||||||
// notifyByEmail Boolean @default(true)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// model TOS {
|
|
||||||
// id String @id @default(cuid())
|
|
||||||
// content String // Markdown or rich text
|
|
||||||
// createdAt DateTime @default(now())
|
|
||||||
// }
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import { CommissionExtra, CommissionOption, CommissionType, CommissionTypeExtra, CommissionTypeOption } from "@/generated/prisma"
|
import { CommissionExtra, CommissionOption, CommissionType, CommissionTypeExtra, CommissionTypeOption } from "@/generated/prisma"
|
||||||
// import { useState } from "react"
|
// import { useState } from "react"
|
||||||
import { Badge } from "../ui/badge"
|
// import { Badge } from "../ui/badge"
|
||||||
|
|
||||||
type CommissionTypeWithItems = CommissionType & {
|
type CommissionTypeWithItems = CommissionType & {
|
||||||
options: (CommissionTypeOption & {
|
options: (CommissionTypeOption & {
|
||||||
@ -85,13 +85,13 @@ export function CommissionCard({ commission }: { commission: CommissionTypeWithI
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-wrap gap-2">
|
{/* <div className="flex flex-wrap gap-2">
|
||||||
{commission.extras.map((extra) => (
|
{commission.extras.map((extra) => (
|
||||||
<Badge variant="outline" key={extra.id}>
|
<Badge variant="outline" key={extra.id}>
|
||||||
{extra.extra?.name}
|
{extra.extra?.name}
|
||||||
</Badge>
|
</Badge>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div> */}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
@ -77,7 +77,6 @@ export function CommissionOrderForm({ types }: Props) {
|
|||||||
|
|
||||||
async function onSubmit(values: z.infer<typeof commissionOrderSchema>) {
|
async function onSubmit(values: z.infer<typeof commissionOrderSchema>) {
|
||||||
console.log("Submit:", { ...values, files })
|
console.log("Submit:", { ...values, files })
|
||||||
// TODO: send to server
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -220,12 +219,23 @@ export function CommissionOrderForm({ types }: Props) {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div>
|
<FormItem>
|
||||||
<FormLabel>Reference Images</FormLabel>
|
<FormLabel>Reference Images</FormLabel>
|
||||||
<FileDropzone onFilesSelected={(f: File[]) => setFiles(f)} />
|
<FormControl>
|
||||||
</div>
|
<div className="space-y-2">
|
||||||
|
<FileDropzone onFilesSelected={setFiles} />
|
||||||
|
{files.length > 0 && (
|
||||||
|
<ul className="list-disc pl-4 text-sm text-muted-foreground">
|
||||||
|
{files.map((file, i) => (
|
||||||
|
<li key={i}>{file.name}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</FormControl>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
<div className="text-xl font-semibold">
|
<div className="text-lg font-semibold">
|
||||||
Estimated Price: €{price.toFixed(2)}
|
Estimated Price: €{price.toFixed(2)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,24 +1,65 @@
|
|||||||
// components/form/FileDropzone.tsx
|
|
||||||
"use client"
|
"use client"
|
||||||
import { useCallback } from "react"
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { useCallback, useRef, useState } from "react"
|
||||||
|
|
||||||
export function FileDropzone({
|
export function FileDropzone({
|
||||||
onFilesSelected,
|
onFilesSelected,
|
||||||
}: {
|
}: {
|
||||||
onFilesSelected: (files: File[]) => void
|
onFilesSelected: (files: File[]) => void
|
||||||
}) {
|
}) {
|
||||||
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
const [isDragging, setIsDragging] = useState(false)
|
||||||
if (e.target.files) {
|
const inputRef = useRef<HTMLInputElement | null>(null)
|
||||||
onFilesSelected(Array.from(e.target.files))
|
|
||||||
|
const handleFiles = (files: FileList | null) => {
|
||||||
|
if (files) {
|
||||||
|
onFilesSelected(Array.from(files))
|
||||||
}
|
}
|
||||||
}, [onFilesSelected])
|
}
|
||||||
|
|
||||||
|
const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
|
||||||
|
e.preventDefault()
|
||||||
|
setIsDragging(false)
|
||||||
|
handleFiles(e.dataTransfer.files)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
|
||||||
|
e.preventDefault()
|
||||||
|
setIsDragging(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDragLeave = () => {
|
||||||
|
setIsDragging(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChange = useCallback(
|
||||||
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
handleFiles(e.target.files)
|
||||||
|
},
|
||||||
|
[onFilesSelected]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<input
|
<div
|
||||||
type="file"
|
onClick={() => inputRef.current?.click()}
|
||||||
multiple
|
onDrop={handleDrop}
|
||||||
onChange={handleChange}
|
onDragOver={handleDragOver}
|
||||||
className="border p-2 rounded-md"
|
onDragLeave={handleDragLeave}
|
||||||
/>
|
className={cn(
|
||||||
|
"w-full border-2 border-dashed rounded-md p-6 text-center cursor-pointer transition-colors",
|
||||||
|
isDragging ? "border-primary bg-muted" : "border-muted-foreground/30"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
ref={inputRef}
|
||||||
|
type="file"
|
||||||
|
multiple
|
||||||
|
onChange={handleChange}
|
||||||
|
className="hidden"
|
||||||
|
/>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Drag & drop images here or click to upload
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user