📌 feat: Implement Suitable model and API endpoints for managing suitable products, including creation and listing functionalities
This commit is contained in:
parent
34611d3c00
commit
42b82fe7cb
@ -18,3 +18,41 @@ model User {
|
|||||||
created_at DateTime @default(now())
|
created_at DateTime @default(now())
|
||||||
updated_at DateTime @updatedAt
|
updated_at DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model Suitable {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
product_name String
|
||||||
|
manufacturer String?
|
||||||
|
roof_material String?
|
||||||
|
shape String?
|
||||||
|
support_roof_tile String?
|
||||||
|
support_roof_tile_memo String?
|
||||||
|
support_roof_bracket String?
|
||||||
|
support_roof_bracket_memo String?
|
||||||
|
yg_anchor String?
|
||||||
|
yg_anchor_memo String?
|
||||||
|
rg_roof_tile_part String?
|
||||||
|
rg_roof_tile_part_memo String?
|
||||||
|
dido_hunt_support_tile_2 String?
|
||||||
|
dido_hunt_support_tile_2_memo String?
|
||||||
|
takashima_power_base String?
|
||||||
|
takashima_power_base_memo String?
|
||||||
|
takashima_tile_bracket String?
|
||||||
|
takashima_tile_bracket_memo String?
|
||||||
|
slate_bracket_4 String?
|
||||||
|
slate_bracket_4_memo String?
|
||||||
|
slate_single_metal_bracket String?
|
||||||
|
slate_single_metal_bracket_memo String?
|
||||||
|
dido_hunt_short_rack_4 String?
|
||||||
|
dido_hunt_short_rack_4_memo String?
|
||||||
|
takashima_slate_bracket_slate_single String?
|
||||||
|
takashima_slate_bracket_slate_single_memo String?
|
||||||
|
df_metal_bracket String?
|
||||||
|
df_metal_bracket_memo String?
|
||||||
|
slate_metal_bracket String?
|
||||||
|
slate_metal_bracket_memo String?
|
||||||
|
takashima_slate_bracket_metal_roof String?
|
||||||
|
takashima_slate_bracket_metal_roof_memo String?
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|||||||
90
src/api/suitable.ts
Normal file
90
src/api/suitable.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { database } from '@/data'
|
||||||
|
import { axiosInstance } from '@/libs/axios'
|
||||||
|
|
||||||
|
export interface Suitable {
|
||||||
|
id?: number
|
||||||
|
product_name: string
|
||||||
|
manufacturer: string
|
||||||
|
roof_material: string
|
||||||
|
shape: string
|
||||||
|
support_roof_tile: string
|
||||||
|
support_roof_tile_memo: string
|
||||||
|
support_roof_bracket: string
|
||||||
|
support_roof_bracket_memo: string
|
||||||
|
yg_anchor: string
|
||||||
|
yg_anchor_memo: string
|
||||||
|
rg_roof_tile_part: string
|
||||||
|
rg_roof_tile_part_memo: string
|
||||||
|
dido_hunt_support_tile_2: string
|
||||||
|
dido_hunt_support_tile_2_memo: string
|
||||||
|
takashima_power_base: string
|
||||||
|
takashima_power_base_memo: string
|
||||||
|
takashima_tile_bracket: string
|
||||||
|
takashima_tile_bracket_memo: string
|
||||||
|
slate_bracket_4: string
|
||||||
|
slate_bracket_4_memo: string
|
||||||
|
slate_single_metal_bracket: string
|
||||||
|
slate_single_metal_bracket_memo: string
|
||||||
|
dido_hunt_short_rack_4: string
|
||||||
|
dido_hunt_short_rack_4_memo: string
|
||||||
|
takashima_slate_bracket_slate_single: string
|
||||||
|
takashima_slate_bracket_slate_single_memo: string
|
||||||
|
df_metal_bracket: string
|
||||||
|
df_metal_bracket_memo: string
|
||||||
|
slate_metal_bracket: string
|
||||||
|
slate_metal_bracket_memo: string
|
||||||
|
takashima_slate_bracket_metal_roof: string
|
||||||
|
takashima_slate_bracket_metal_roof_memo: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const suitableApi = {
|
||||||
|
getList: async (): Promise<Suitable[]> => {
|
||||||
|
const response = await axiosInstance.get<Suitable[]>('/api/suitable/list')
|
||||||
|
console.log('🚀 ~ getList: ~ response:', response)
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
create: async () => {
|
||||||
|
const suitableData: Suitable[] = []
|
||||||
|
|
||||||
|
database.forEach((item) => {
|
||||||
|
suitableData.push({
|
||||||
|
product_name: item[1],
|
||||||
|
manufacturer: item[2],
|
||||||
|
roof_material: item[3],
|
||||||
|
shape: item[4],
|
||||||
|
support_roof_tile: item[5],
|
||||||
|
support_roof_tile_memo: item[6],
|
||||||
|
support_roof_bracket: item[7],
|
||||||
|
support_roof_bracket_memo: item[8],
|
||||||
|
yg_anchor: item[9],
|
||||||
|
yg_anchor_memo: item[10],
|
||||||
|
rg_roof_tile_part: item[11],
|
||||||
|
rg_roof_tile_part_memo: item[12],
|
||||||
|
dido_hunt_support_tile_2: item[13],
|
||||||
|
dido_hunt_support_tile_2_memo: item[14],
|
||||||
|
takashima_power_base: item[15],
|
||||||
|
takashima_power_base_memo: item[16],
|
||||||
|
takashima_tile_bracket: item[17],
|
||||||
|
takashima_tile_bracket_memo: item[18],
|
||||||
|
slate_bracket_4: item[19],
|
||||||
|
slate_bracket_4_memo: item[20],
|
||||||
|
slate_single_metal_bracket: item[21],
|
||||||
|
slate_single_metal_bracket_memo: item[22],
|
||||||
|
dido_hunt_short_rack_4: item[23],
|
||||||
|
dido_hunt_short_rack_4_memo: item[24],
|
||||||
|
takashima_slate_bracket_slate_single: item[25],
|
||||||
|
takashima_slate_bracket_slate_single_memo: item[26],
|
||||||
|
df_metal_bracket: item[27],
|
||||||
|
df_metal_bracket_memo: item[28],
|
||||||
|
slate_metal_bracket: item[29],
|
||||||
|
slate_metal_bracket_memo: item[30],
|
||||||
|
takashima_slate_bracket_metal_roof: item[31],
|
||||||
|
takashima_slate_bracket_metal_roof_memo: item[32],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const response = await axiosInstance.post<Suitable[]>('/api/suitable', suitableData)
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
}
|
||||||
8
src/app/api/suitable/list/route.ts
Normal file
8
src/app/api/suitable/list/route.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { NextResponse } from 'next/server'
|
||||||
|
import { prisma } from '@/libs/prisma'
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
// @ts-ignore
|
||||||
|
const suitables = await prisma.suitable.findMany()
|
||||||
|
return NextResponse.json(suitables)
|
||||||
|
}
|
||||||
12
src/app/api/suitable/route.ts
Normal file
12
src/app/api/suitable/route.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { NextResponse } from 'next/server'
|
||||||
|
import { prisma } from '@/libs/prisma'
|
||||||
|
|
||||||
|
export async function POST(request: Request) {
|
||||||
|
const body = await request.json()
|
||||||
|
// @ts-ignore
|
||||||
|
const suitables = await prisma.suitable.createMany({
|
||||||
|
data: body,
|
||||||
|
})
|
||||||
|
|
||||||
|
return NextResponse.json({ message: 'Suitable created successfully' })
|
||||||
|
}
|
||||||
@ -19,6 +19,12 @@ export default async function Home() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="p-4">
|
||||||
|
<Link href="/suitable">
|
||||||
|
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">적합성 예제</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
<User />
|
<User />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
12
src/app/suitable/page.tsx
Normal file
12
src/app/suitable/page.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import Suitable from '@/components/Suitable'
|
||||||
|
import SuitableCreateBtn from '@/components/SuitableCreateBtn'
|
||||||
|
|
||||||
|
export default function suitablePage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Suitable />
|
||||||
|
{/* 최초 한번 밀어넣음 */}
|
||||||
|
{/* <SuitableCreateBtn /> */}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
20
src/components/Suitable.tsx
Normal file
20
src/components/Suitable.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { suitableApi } from '@/api/suitable'
|
||||||
|
import { useQuery } from '@tanstack/react-query'
|
||||||
|
|
||||||
|
export default function Suitable() {
|
||||||
|
const { data, error, isPending } = useQuery({
|
||||||
|
queryKey: ['suitable-list'],
|
||||||
|
queryFn: suitableApi.getList,
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h1 className="text-4xl font-bold">Suitable</h1>
|
||||||
|
{error && <div>Error: {error.message}</div>}
|
||||||
|
{isPending && <div>Loading...</div>}
|
||||||
|
{data && data.map((item) => <div key={item.id}>{item.product_name}</div>)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
29
src/components/SuitableCreateBtn.tsx
Normal file
29
src/components/SuitableCreateBtn.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { suitableApi } from '@/api/suitable'
|
||||||
|
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
||||||
|
|
||||||
|
export default function SuitableCreateBtn() {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
const {
|
||||||
|
mutate: createSuitable,
|
||||||
|
isPending,
|
||||||
|
error,
|
||||||
|
} = useMutation({
|
||||||
|
mutationFn: suitableApi.create,
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['suitable-list'] })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<button className="bg-blue-500 text-white px-4 py-2 rounded-md" onClick={() => createSuitable()}>
|
||||||
|
suitable create!!
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
76790
src/data.ts
Normal file
76790
src/data.ts
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user