feat: modify inquriy create parameter
- 문의 등록 시 이메일 파라미터 추가
This commit is contained in:
parent
4d6f5c0e01
commit
7066d01060
@ -6,10 +6,19 @@ export async function GET(request: Request) {
|
||||
const encodeFileNo = searchParams.get('encodeFileNo')
|
||||
|
||||
if (!encodeFileNo) {
|
||||
return NextResponse.json({ error: 'fileNo is required' }, { status: 400 })
|
||||
return NextResponse.json({ error: 'encodeFileNo is required' }, { status: 400 })
|
||||
}
|
||||
const response = await axios.get(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/file/downloadFile?encodeFileNo=${encodeFileNo}`)
|
||||
try {
|
||||
const response = await axios.get(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/file/downloadFile`, {
|
||||
params: {
|
||||
encodeFileNo,
|
||||
},
|
||||
})
|
||||
console.log('response.data:: ', response.data)
|
||||
|
||||
return NextResponse.json(response.data)
|
||||
} catch (error: any) {
|
||||
console.error(error.response)
|
||||
return NextResponse.json({ error: error.response.data }, { status: 500 })
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,6 @@ export async function GET(request: Request) {
|
||||
if (response.status === 200) {
|
||||
return NextResponse.json(response.data)
|
||||
}
|
||||
|
||||
return NextResponse.json({ error: 'Failed to fetch qna list' }, { status: response.status })
|
||||
} catch (error: any) {
|
||||
console.error('Error fetching qna list:', error.response.data)
|
||||
|
||||
@ -4,12 +4,9 @@ import { NextResponse } from 'next/server'
|
||||
export async function POST(request: Request) {
|
||||
const formData = await request.formData()
|
||||
console.log('formData:: ', formData)
|
||||
// const body = await request.json()
|
||||
// console.log('body:: ', body)
|
||||
|
||||
try {
|
||||
const response = await axios.post(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/qna/save`, formData)
|
||||
console.log('response.data:: ', response.data)
|
||||
|
||||
if (response.status === 200) {
|
||||
return NextResponse.json(response.data)
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
import ListForm from '@/components/inquiry/list/ListForm'
|
||||
import ListTable from '@/components/inquiry/list/ListTable'
|
||||
|
||||
export default function page() {
|
||||
return (
|
||||
<>
|
||||
<div className="sale-contents">
|
||||
<ListForm />
|
||||
<ListTable />
|
||||
</div>
|
||||
</>
|
||||
|
||||
@ -3,19 +3,13 @@
|
||||
import Answer from './Answer'
|
||||
import { useInquiry } from '@/hooks/useInquiry'
|
||||
import { useParams, useRouter } from 'next/navigation'
|
||||
import { useState } from 'react'
|
||||
|
||||
export default function Detail() {
|
||||
//todo: 답변 완료 표시를 위해 임시로 추가 해 놓은 state
|
||||
// 추후에 api 작업 완료후 삭제
|
||||
// 답변 완료 클래스 & 하단 답변내용 출력도
|
||||
|
||||
const params = useParams()
|
||||
const id = params.id
|
||||
|
||||
const { inquiryDetail, downloadFile } = useInquiry(Number(id), '5200')
|
||||
const router = useRouter()
|
||||
const [inquiry, setInquiry] = useState<Boolean>(true)
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -39,15 +33,7 @@ export default function Detail() {
|
||||
</tr>
|
||||
<tr>
|
||||
<th>作者</th>
|
||||
<td>Hong gi</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>名前</th>
|
||||
<td>Kim</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>番号</th>
|
||||
<td>070-1234-5678</td>
|
||||
<td>{inquiryDetail?.regNm}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>販売店</th>
|
||||
@ -66,17 +52,9 @@ export default function Detail() {
|
||||
</div>
|
||||
<div className="inquiry-detail-data">
|
||||
<div className="inquiry-detail-category">
|
||||
<span>屋根</span>
|
||||
<span>適合性</span>
|
||||
<span>屋根材</span>
|
||||
</div>
|
||||
<div className="inquiry-detail-tit">屋根材適合性確認依頼</div>
|
||||
<div className="inquiry-detail-txt">
|
||||
入力した内容が表示されます.
|
||||
<br />
|
||||
インストール可能であることを確認してください.
|
||||
<br />
|
||||
屋根の写真を添付しました.
|
||||
<span>{inquiryDetail?.qnaClsLrgCd}</span>
|
||||
<span>{inquiryDetail?.qnaClsMidCd}</span>
|
||||
<span>{inquiryDetail?.qnaClsSmlCd}</span>
|
||||
</div>
|
||||
<div className="inquiry-detail-tit">{inquiryDetail?.qstTitle}</div>
|
||||
<div className="inquiry-detail-txt">{inquiryDetail?.qstContents}</div>
|
||||
@ -91,6 +69,11 @@ export default function Detail() {
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
<li className="file-item">
|
||||
<button className="file-item-bx" onClick={() => downloadFile(Number(1))}>
|
||||
<div className="file-item-name">Test File</div>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -4,7 +4,7 @@ import { useInquiry } from '@/hooks/useInquiry'
|
||||
import { useSessionStore } from '@/store/session'
|
||||
import { InquiryRequest } from '@/types/Inquiry'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
export default function RegistForm() {
|
||||
const { saveInquiry, isSavingInquiry } = useInquiry()
|
||||
@ -20,14 +20,15 @@ export default function RegistForm() {
|
||||
compCd: '5200',
|
||||
siteTpCd: 'QC',
|
||||
qnaClsLrgCd: '',
|
||||
qnaClsMidCd: 'B02',
|
||||
qnaClsMidCd: '',
|
||||
qnaClsSmlCd: null,
|
||||
title: '',
|
||||
contents: null,
|
||||
contents: '',
|
||||
regId: 'X112',
|
||||
regUserNm: 'TEST',
|
||||
regUserTelNo: null,
|
||||
storeId: null,
|
||||
storeId: 'X112',
|
||||
qstMail: '',
|
||||
})
|
||||
|
||||
const [attachedFiles, setAttachedFiles] = useState<File[]>([])
|
||||
@ -45,12 +46,30 @@ export default function RegistForm() {
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (confirm('お問い合わせを登録しますか? Hanwha Japanの担当者にお問い合わせメールが送信されます。')) {
|
||||
const res = await saveInquiry({ inquiryRequest, files: attachedFiles })
|
||||
const formData = new FormData()
|
||||
attachedFiles.forEach((file) => {
|
||||
formData.append('files', file)
|
||||
})
|
||||
Object.entries(inquiryRequest).forEach(([key, value]) => {
|
||||
formData.append(key, value ?? '')
|
||||
})
|
||||
|
||||
// FormData를 객체로 변환하여 확인
|
||||
const formDataObj: Record<string, any> = {}
|
||||
formData.forEach((value, key) => {
|
||||
formDataObj[key] = value
|
||||
})
|
||||
console.log('formData contents:', formDataObj)
|
||||
|
||||
window.neoConfirm(
|
||||
'お問い合わせを登録しますか? Hanwha Japanの担当者にお問い合わせメールが送信されます。',
|
||||
async () => {
|
||||
const res = await saveInquiry(formData)
|
||||
alert('保存されました。')
|
||||
router.push(`/inquiry/${res.qnaNo}`)
|
||||
}
|
||||
return
|
||||
},
|
||||
() => null,
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
@ -62,30 +81,42 @@ export default function RegistForm() {
|
||||
お問い合わせタイプ <i className="import">*</i>
|
||||
</div>
|
||||
<div className="data-input">
|
||||
<select className="select-form" name="" id="">
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<select
|
||||
className="select-form"
|
||||
name=""
|
||||
id="qnaClsLrgCd"
|
||||
value={inquiryRequest.qnaClsLrgCd}
|
||||
onChange={(e) => setInquiryRequest({ ...inquiryRequest, qnaClsLrgCd: e.target.value })}
|
||||
>
|
||||
<option value="">選択してください</option>
|
||||
<option value="A01">A01</option>
|
||||
<option value="A01">屋根適合</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="data-input mt5">
|
||||
<select className="select-form" name="" id="">
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<select
|
||||
className="select-form"
|
||||
name=""
|
||||
id="qnaClsMidCd"
|
||||
value={inquiryRequest.qnaClsMidCd}
|
||||
onChange={(e) => setInquiryRequest({ ...inquiryRequest, qnaClsMidCd: e.target.value })}
|
||||
>
|
||||
<option value="">選択してください</option>
|
||||
<option value="B02">B02</option>
|
||||
<option value="B02">屋根適合</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="data-input mt5">
|
||||
<select className="select-form" name="" id="">
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<option value="">屋根適合</option>
|
||||
<select
|
||||
className="select-form"
|
||||
name=""
|
||||
id="qnaClsSmlCd"
|
||||
value={inquiryRequest.qnaClsSmlCd ?? ''}
|
||||
onChange={(e) => setInquiryRequest({ ...inquiryRequest, qnaClsSmlCd: e.target.value })}
|
||||
>
|
||||
<option value="">選択してください</option>
|
||||
<option value="C05">C05</option>
|
||||
<option value="C05">屋根適合</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -94,27 +125,36 @@ export default function RegistForm() {
|
||||
名前 <i className="import">*</i>
|
||||
</div>
|
||||
<div className="data-input">
|
||||
<input className="input-frame" type="text" placeholder="名前を書いてください" />
|
||||
<input
|
||||
className="input-frame"
|
||||
type="text"
|
||||
placeholder="名前を書いてください"
|
||||
onChange={(e) => setInquiryRequest({ ...inquiryRequest, regUserNm: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="data-input-form-bx">
|
||||
<div className="data-input-form-tit">電話番号</div>
|
||||
<div className="data-input">
|
||||
<input className="input-frame" type="text" placeholder="電話番号を書き留めてください" />
|
||||
<input
|
||||
className="input-frame"
|
||||
type="text"
|
||||
placeholder="電話番号を書き留めてください"
|
||||
onChange={(e) => setInquiryRequest({ ...inquiryRequest, regUserTelNo: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="data-input-form-bx">
|
||||
<div className="data-input-form-tit">
|
||||
名前 <i className="import">*</i>
|
||||
E-mail <i className="import">*</i>
|
||||
</div>
|
||||
<div className="data-input">
|
||||
<input className="input-frame" type="text" placeholder="名前を書いてください" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="data-input-form-bx">
|
||||
<div className="data-input-form-tit">電話番号</div>
|
||||
<div className="data-input">
|
||||
<input className="input-frame" type="text" placeholder="電話番号を書き留めてください" />
|
||||
<input
|
||||
className="input-frame"
|
||||
type="text"
|
||||
placeholder="E-mailを書いてください"
|
||||
onChange={(e) => setInquiryRequest({ ...inquiryRequest, qstMail: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="data-input-form-bx">
|
||||
@ -122,7 +162,12 @@ export default function RegistForm() {
|
||||
お問い合わせタイトル <i className="import">*</i>
|
||||
</div>
|
||||
<div className="data-input">
|
||||
<input className="input-frame" type="text" placeholder="お問い合わせタイトルを記入してください" />
|
||||
<input
|
||||
className="input-frame"
|
||||
type="text"
|
||||
placeholder="お問い合わせタイトルを記入してください"
|
||||
onChange={(e) => setInquiryRequest({ ...inquiryRequest, title: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="data-input-form-bx">
|
||||
|
||||
@ -5,8 +5,8 @@ import { useState } from 'react'
|
||||
|
||||
export default function ListForm() {
|
||||
const router = useRouter()
|
||||
const [searchKeyword, setSearchKeyword] = useState('')
|
||||
const { inquiryListRequest, setInquiryListRequest } = useInquiryFilterStore()
|
||||
const [searchKeyword, setSearchKeyword] = useState(inquiryListRequest.schTitle ?? '')
|
||||
|
||||
const handleSearch = () => {
|
||||
if (searchKeyword.length >= 2) {
|
||||
|
||||
@ -7,6 +7,7 @@ import { InquiryList } from '@/types/Inquiry'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { useInquiryFilterStore } from '@/store/inquiryFilterStore'
|
||||
import { useSessionStore } from '@/store/session'
|
||||
import ListForm from './ListForm'
|
||||
|
||||
const badgeStyle = [
|
||||
{
|
||||
@ -29,14 +30,23 @@ export default function ListTable() {
|
||||
const { inquiryList } = useInquiry()
|
||||
const { inquiryListRequest, setInquiryListRequest } = useInquiryFilterStore()
|
||||
|
||||
const [heldInquiryList, setHeldInquiryList] = useState<typeof inquiryList>([])
|
||||
|
||||
const { session } = useSessionStore()
|
||||
|
||||
useEffect(() => {
|
||||
if (inquiryList.length !== 0) {
|
||||
const hasMoreItems = inquiryList[0].totCnt > offset + 10
|
||||
setHasMore(hasMoreItems)
|
||||
if (inquiryList.length > 0) {
|
||||
if (offset === 0) {
|
||||
setHeldInquiryList(inquiryList)
|
||||
} else {
|
||||
setHasMore(false)
|
||||
const remainingList = heldInquiryList.slice(offset, offset + 10)
|
||||
if (JSON.stringify(remainingList) !== JSON.stringify(inquiryList)) {
|
||||
setHeldInquiryList((prev) => [...prev, ...inquiryList])
|
||||
}
|
||||
}
|
||||
setHasMore(inquiryList.length > offset + 10)
|
||||
} else {
|
||||
setHeldInquiryList([])
|
||||
}
|
||||
}, [inquiryList, offset])
|
||||
|
||||
@ -49,8 +59,19 @@ export default function ListTable() {
|
||||
setInquiryListRequest({ ...inquiryListRequest, startRow: offset, endRow: offset + 10 })
|
||||
}
|
||||
|
||||
const handleFilter = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
console.log(e.target.value)
|
||||
setHeldInquiryList(inquiryList.filter((inquiry: InquiryList) => inquiry.answerYn === e.target.value))
|
||||
if (e.target.value === '') {
|
||||
setHeldInquiryList(inquiryList)
|
||||
}
|
||||
}
|
||||
|
||||
console.log('heldInquiryList:: ', heldInquiryList)
|
||||
|
||||
return (
|
||||
<>
|
||||
<ListForm />
|
||||
<div className="sale-frame">
|
||||
<div className="inquiry-table-filter">
|
||||
<div className="filter-check">
|
||||
@ -60,7 +81,7 @@ export default function ListTable() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="filter-select">
|
||||
<select className="select-form" name="" id="">
|
||||
<select className="select-form" name="" id="" onChange={(e) => handleFilter(e)}>
|
||||
<option value="">全体</option>
|
||||
<option value="N">回答待ち</option>
|
||||
<option value="Y">回答完了</option>
|
||||
@ -69,11 +90,11 @@ export default function ListTable() {
|
||||
</div>
|
||||
<div className="inquiry-list-wrap">
|
||||
<div className="inquiry-list-tit">
|
||||
合計 <span>{inquiryList.length}</span>個
|
||||
合計 <span>{heldInquiryList.length > 0 ? heldInquiryList[0].totCnt : 0}</span>個
|
||||
</div>
|
||||
<ul className="inquiry-list">
|
||||
{inquiryList.length > 0 &&
|
||||
inquiryList.map((inquiry: InquiryList) => (
|
||||
{heldInquiryList.length > 0 &&
|
||||
heldInquiryList.map((inquiry: InquiryList) => (
|
||||
<li className="inquiry-item" key={inquiry.qnaNo} onClick={() => router.push(`/inquiry/${inquiry.qnaNo}`)}>
|
||||
<div className="inquiry-item-bx">
|
||||
<div className="inquiry-item-category">{inquiry.qnaClsLrgCd}</div>
|
||||
|
||||
@ -12,10 +12,10 @@ export function useInquiry(
|
||||
inquiryDetail: Inquiry | null
|
||||
isLoadingInquiryDetail: boolean
|
||||
isSavingInquiry: boolean
|
||||
saveInquiry: (params: { inquiryRequest: InquiryRequest; files: File[] }) => Promise<InquirySaveResponse>
|
||||
saveInquiry: (formData: FormData) => Promise<InquirySaveResponse>
|
||||
downloadFile: (encodeFileNo: number) => Promise<File>
|
||||
} {
|
||||
const { session } = useSessionStore()
|
||||
// const { session } = useSessionStore()
|
||||
const queryClient = useQueryClient()
|
||||
const { inquiryListRequest } = useInquiryFilterStore()
|
||||
|
||||
@ -41,6 +41,7 @@ export function useInquiry(
|
||||
const resp = await axiosInstance(null).get<{ data: Inquiry }>(`/api/qna/detail`, {
|
||||
params: { qnoNo, compCd, langCd: 'JA', loginId: 'x112' },
|
||||
})
|
||||
console.log('resp.data.data:: ', resp.data.data)
|
||||
return resp.data.data
|
||||
} catch (error: any) {
|
||||
console.error(error.response)
|
||||
@ -51,15 +52,7 @@ export function useInquiry(
|
||||
})
|
||||
|
||||
const { mutateAsync: saveInquiry, isPending: isSavingInquiry } = useMutation({
|
||||
mutationFn: async ({ inquiryRequest, files }: { inquiryRequest: InquiryRequest; files: File[] }) => {
|
||||
const formData = new FormData()
|
||||
Object.entries(inquiryRequest).forEach(([key, value]) => {
|
||||
formData.append(key, value ?? '')
|
||||
})
|
||||
files.forEach((file) => {
|
||||
formData.append('files', file)
|
||||
})
|
||||
|
||||
mutationFn: async (formData: FormData) => {
|
||||
const resp = await axiosInstance(null).post<{ data: InquirySaveResponse }>('/api/qna/save', formData)
|
||||
return resp.data.data
|
||||
},
|
||||
|
||||
@ -75,11 +75,12 @@ export type InquiryRequest = {
|
||||
qnaClsMidCd: string //qna CLS Mid Code
|
||||
qnaClsSmlCd: string | null //qna CLS Small Code
|
||||
title: string //title
|
||||
contents: string | null //contents
|
||||
contents: string //contents
|
||||
regId: string //registration Userid
|
||||
storeId: string | null //store id
|
||||
storeId: string //store id
|
||||
regUserNm: string //registration User name
|
||||
regUserTelNo: string | null //registration User tel number
|
||||
qstMail: string //mail
|
||||
}
|
||||
|
||||
export type InquirySaveResponse = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user