[feat] negodata/front: 협상대화 카드내용 렌더 + 견적상세 헤더·테이블 UI 정리
- 협상대화: 사용 카드 번호/멘트(Slate 서식본)/와일드 조건·메모 표시, SlateRenderer
밑줄·헥스색·{변수} 치환 보정, 말풍선 우측정렬·발신자 아바타 제거
- 견적상세 헤더: DB 컬럼명 라벨 제거, 견적정보/(진행상태+세팅)/상품(이미지) 2열 재배치,
협상카드 탭에 사용 카드 수 표시
- DataTable 행 패딩 축소, 협력사명 아바타 제거, 카드관리 본인 카드 안내문
- orval 재생성(QuotationCardData 신규 필드)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
df68609c49
commit
7186446068
525
negodata/front/package-lock.json
generated
525
negodata/front/package-lock.json
generated
@ -14,7 +14,6 @@
|
||||
"@hookform/resolvers": "^5.4.0",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@tanstack/react-query": "^5.62.0",
|
||||
"@tanstack/react-router": "^1.170.15",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
@ -27,6 +26,10 @@
|
||||
"react-hook-form": "^7.79.0",
|
||||
"react-router": "^7.17.0",
|
||||
"shadcn": "^4.11.0",
|
||||
"slate": "^0.118.1",
|
||||
"slate-dom": "^0.119.0",
|
||||
"slate-history": "^0.113.1",
|
||||
"slate-react": "^0.119.0",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
@ -36,8 +39,6 @@
|
||||
"zustand": "^5.0.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tanstack/router-cli": "^1.167.17",
|
||||
"@tanstack/router-plugin": "^1.168.18",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^22.14.0",
|
||||
"@types/react": "^19.2.17",
|
||||
@ -1456,6 +1457,12 @@
|
||||
"jsep": "^0.4.0||^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@juggle/resize-observer": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
|
||||
"integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@modelcontextprotocol/sdk": {
|
||||
"version": "1.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz",
|
||||
@ -3533,19 +3540,6 @@
|
||||
"vite": "^5.2.0 || ^6 || ^7 || ^8"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/history": {
|
||||
"version": "1.162.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/history/-/history-1.162.0.tgz",
|
||||
"integrity": "sha512-79pf/RkhteYZTRgcR4F9kbk84P2N8rugQJswxfIqovlbRiT3yI7eBE+5QorIrZaOKktsgzRlXh1l/du/xpl4iA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.19"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/query-core": {
|
||||
"version": "5.101.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.101.0.tgz",
|
||||
@ -3572,269 +3566,6 @@
|
||||
"react": "^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/react-router": {
|
||||
"version": "1.170.15",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.170.15.tgz",
|
||||
"integrity": "sha512-GawYz7HEjj8rTUUDoT/SemDEVm63pZUO+2mOcXHY9Jl3EwMS5gFBnPu/2UvcrwRm1jN1k79fokc0d4aFmrLatg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/history": "1.162.0",
|
||||
"@tanstack/react-store": "^0.9.3",
|
||||
"@tanstack/router-core": "1.171.13",
|
||||
"isbot": "^5.1.22"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18.0.0 || >=19.0.0",
|
||||
"react-dom": ">=18.0.0 || >=19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/react-store": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.9.3.tgz",
|
||||
"integrity": "sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/store": "0.9.3",
|
||||
"use-sync-external-store": "^1.6.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-cli": {
|
||||
"version": "1.167.17",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-cli/-/router-cli-1.167.17.tgz",
|
||||
"integrity": "sha512-kws9PNdspkHbeZG6aLDjjpgH/hg7Q565BdSW9hHrjKmXPq/at7OKxQnA76aw9dJiJqy9OmST2RdOKlMEog43+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/router-generator": "1.167.17",
|
||||
"chokidar": "^5.0.0",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"bin": {
|
||||
"tsr": "bin/tsr.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-cli/node_modules/chokidar": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
|
||||
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readdirp": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-cli/node_modules/readdirp": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
|
||||
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-core": {
|
||||
"version": "1.171.13",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.171.13.tgz",
|
||||
"integrity": "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/history": "1.162.0",
|
||||
"cookie-es": "^3.0.0",
|
||||
"seroval": "^1.5.4",
|
||||
"seroval-plugins": "^1.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-generator": {
|
||||
"version": "1.167.17",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-generator/-/router-generator-1.167.17.tgz",
|
||||
"integrity": "sha512-xtB9tB2Ws0tWR6Pi7nc3Qk9IYgoh1mQCKWjHqIl9tf6BNUpKoqniJoPAQ4+LGrK8FeZYU0o0p/qlZEyj9FAulA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.28.5",
|
||||
"@tanstack/router-core": "1.171.13",
|
||||
"@tanstack/router-utils": "1.162.2",
|
||||
"@tanstack/virtual-file-routes": "1.162.0",
|
||||
"jiti": "^2.7.0",
|
||||
"magic-string": "^0.30.21",
|
||||
"prettier": "^3.5.0",
|
||||
"zod": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-plugin": {
|
||||
"version": "1.168.18",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-plugin/-/router-plugin-1.168.18.tgz",
|
||||
"integrity": "sha512-MofS28/axfnfnhOD2RSgJEaU882aX5RsAzhGz5Vc4XhAmvCjy919u9JrNs4QsTWFbTD1P7IJ8WFlFVsrg0pStg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.28.5",
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@tanstack/router-core": "1.171.13",
|
||||
"@tanstack/router-generator": "1.167.17",
|
||||
"@tanstack/router-utils": "1.162.2",
|
||||
"chokidar": "^5.0.0",
|
||||
"unplugin": "^3.0.0",
|
||||
"zod": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@rsbuild/core": ">=1.0.2 || ^2.0.0",
|
||||
"@tanstack/react-router": "^1.170.15",
|
||||
"vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0",
|
||||
"vite-plugin-solid": "^2.11.10 || ^3.0.0-0",
|
||||
"webpack": ">=5.92.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@rsbuild/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@tanstack/react-router": {
|
||||
"optional": true
|
||||
},
|
||||
"vite": {
|
||||
"optional": true
|
||||
},
|
||||
"vite-plugin-solid": {
|
||||
"optional": true
|
||||
},
|
||||
"webpack": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-plugin/node_modules/chokidar": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
|
||||
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readdirp": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-plugin/node_modules/readdirp": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
|
||||
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-utils": {
|
||||
"version": "1.162.2",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-utils/-/router-utils-1.162.2.tgz",
|
||||
"integrity": "sha512-hTWqJtqIFFdvuCl8WXNyrodp2L9zo2G37xKRrcVmVRWpAB2h+U1LuRAfS4tsFTiWOIoE/B+WDVFB8JpoEdw6jQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/generator": "^7.28.5",
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/types": "^7.28.5",
|
||||
"ansis": "^4.1.0",
|
||||
"babel-dead-code-elimination": "^1.0.12",
|
||||
"diff": "^8.0.2",
|
||||
"pathe": "^2.0.3",
|
||||
"tinyglobby": "^0.2.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/store": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.9.3.tgz",
|
||||
"integrity": "sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/virtual-file-routes": {
|
||||
"version": "1.162.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/virtual-file-routes/-/virtual-file-routes-1.162.0.tgz",
|
||||
"integrity": "sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.19"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@ts-morph/common": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz",
|
||||
@ -4243,16 +3974,6 @@
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ansis": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ansis/-/ansis-4.3.1.tgz",
|
||||
"integrity": "sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
@ -4411,19 +4132,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-dead-code-elimination": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/babel-dead-code-elimination/-/babel-dead-code-elimination-1.0.12.tgz",
|
||||
"integrity": "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.23.7",
|
||||
"@babel/parser": "^7.23.6",
|
||||
"@babel/traverse": "^7.23.7",
|
||||
"@babel/types": "^7.23.6"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
|
||||
@ -4839,6 +4547,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/compute-scroll-into-view": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz",
|
||||
"integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@ -4882,12 +4596,6 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-es": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz",
|
||||
"integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
|
||||
@ -5236,6 +4944,19 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/direction": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz",
|
||||
"integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"direction": "cli.js"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "17.4.2",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz",
|
||||
@ -6839,6 +6560,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-hotkey": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.2.0.tgz",
|
||||
"integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-in-ssh": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz",
|
||||
@ -6957,6 +6684,15 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-promise": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||
@ -7166,15 +6902,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/isbot": {
|
||||
"version": "5.1.42",
|
||||
"resolved": "https://registry.npmjs.org/isbot/-/isbot-5.1.42.tgz",
|
||||
"integrity": "sha512-/SXsVh7KpPRISrD4ffrGSxnTLlUBzEQUfWIusaJPrpJ93FW1P0YEZri5vAUkFsA0m2HRUhQRQadk2wJ+EeKowQ==",
|
||||
"license": "Unlicense",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz",
|
||||
@ -7684,7 +7411,6 @@
|
||||
"version": "4.18.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
|
||||
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isempty": {
|
||||
@ -8823,13 +8549,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/pathe": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
@ -8937,22 +8656,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.8.4",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.4.tgz",
|
||||
"integrity": "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-ms": {
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz",
|
||||
@ -9598,6 +9301,15 @@
|
||||
"integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/scroll-into-view-if-needed": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz",
|
||||
"integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"compute-scroll-into-view": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
@ -9646,27 +9358,6 @@
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/seroval": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/seroval/-/seroval-1.5.4.tgz",
|
||||
"integrity": "sha512-46uFvgrXTVxZcUorgSSRZ4y+ieqLLQRMlG4bnCZKW3qI6BZm7Rg4ntMW4p1mILEEBZWrFlcpp0AyIIlM6jD9iw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/seroval-plugins": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.5.4.tgz",
|
||||
"integrity": "sha512-S0xQPhUTefAhNvNWFg0c1J8qJArHt5KdtJ/cFAofo06KD1MVSeFWyl4iiu+ApDIuw0WhjpOfCdgConOfAnLgkw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"seroval": "^1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/serve-static": {
|
||||
"version": "1.16.3",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz",
|
||||
@ -9977,6 +9668,88 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/slate": {
|
||||
"version": "0.118.1",
|
||||
"resolved": "https://registry.npmjs.org/slate/-/slate-0.118.1.tgz",
|
||||
"integrity": "sha512-6H1DNgnSwAFhq/pIgf+tLvjNzH912M5XrKKhP9Frmbds2zFXdSJ6L/uFNyVKxQIkPzGWPD0m+wdDfmEuGFH5Tg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"immer": "^10.0.3",
|
||||
"tiny-warning": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/slate-dom": {
|
||||
"version": "0.119.0",
|
||||
"resolved": "https://registry.npmjs.org/slate-dom/-/slate-dom-0.119.0.tgz",
|
||||
"integrity": "sha512-foc8a2NkE+1SldDIYaoqjhVKupt8RSuvHI868rfYOcypD4we5TT7qunjRKJ852EIRh/Ql8sSTepXgXKOUJnt1w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@juggle/resize-observer": "^3.4.0",
|
||||
"direction": "^1.0.4",
|
||||
"is-hotkey": "^0.2.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"scroll-into-view-if-needed": "^3.1.0",
|
||||
"tiny-invariant": "1.3.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"slate": ">=0.99.0"
|
||||
}
|
||||
},
|
||||
"node_modules/slate-dom/node_modules/tiny-invariant": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
|
||||
"integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/slate-history": {
|
||||
"version": "0.113.1",
|
||||
"resolved": "https://registry.npmjs.org/slate-history/-/slate-history-0.113.1.tgz",
|
||||
"integrity": "sha512-J9NSJ+UG2GxoW0lw5mloaKcN0JI0x2IA5M5FxyGiInpn+QEutxT1WK7S/JneZCMFJBoHs1uu7S7e6pxQjubHmQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-plain-object": "^5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"slate": ">=0.65.3"
|
||||
}
|
||||
},
|
||||
"node_modules/slate-react": {
|
||||
"version": "0.119.0",
|
||||
"resolved": "https://registry.npmjs.org/slate-react/-/slate-react-0.119.0.tgz",
|
||||
"integrity": "sha512-snHqhQ1NkZXyuqG4JTxywRg1accho/hnioM2JIYqziaQQcgfqLi2Pe1AHL82WIC1pLWdzPjy2O7drnSbO0DBsQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@juggle/resize-observer": "^3.4.0",
|
||||
"direction": "^1.0.4",
|
||||
"is-hotkey": "^0.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"scroll-into-view-if-needed": "^3.1.0",
|
||||
"tiny-invariant": "1.3.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18.2.0",
|
||||
"react-dom": ">=18.2.0",
|
||||
"slate": ">=0.114.0",
|
||||
"slate-dom": ">=0.116.0"
|
||||
}
|
||||
},
|
||||
"node_modules/slate-react/node_modules/tiny-invariant": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
|
||||
"integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/slate/node_modules/immer": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz",
|
||||
"integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/immer"
|
||||
}
|
||||
},
|
||||
"node_modules/sonner": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz",
|
||||
@ -10311,6 +10084,12 @@
|
||||
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tiny-warning": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.17",
|
||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
|
||||
@ -11109,21 +10888,6 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz",
|
||||
"integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/remapping": "^2.3.5",
|
||||
"picomatch": "^4.0.3",
|
||||
"webpack-virtual-modules": "^0.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
|
||||
@ -11369,13 +11133,6 @@
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/webpack-virtual-modules": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
|
||||
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
|
||||
@ -30,6 +30,10 @@
|
||||
"react-hook-form": "^7.79.0",
|
||||
"react-router": "^7.17.0",
|
||||
"shadcn": "^4.11.0",
|
||||
"slate": "^0.118.1",
|
||||
"slate-dom": "^0.119.0",
|
||||
"slate-history": "^0.113.1",
|
||||
"slate-react": "^0.119.0",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
|
||||
@ -4,7 +4,10 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
useMutation,
|
||||
useQuery
|
||||
} from '@tanstack/react-query';
|
||||
import type {
|
||||
DataTag,
|
||||
DefinedInitialDataOptions,
|
||||
@ -17,8 +20,8 @@ import type {
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
UseQueryResult
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
import type {
|
||||
HTTPValidationError,
|
||||
@ -27,361 +30,299 @@ import type {
|
||||
ResCreateAccount,
|
||||
ResLogin,
|
||||
ResMe,
|
||||
ResRefreshToken,
|
||||
} from ".././model";
|
||||
ResRefreshToken
|
||||
} from '.././model';
|
||||
|
||||
import { customFetch } from '../../mutator/custom-fetch';
|
||||
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
|
||||
import { customFetch } from "../../mutator/custom-fetch";
|
||||
|
||||
/**
|
||||
* id/pw 로 로그인하고 JWT 토큰을 발급한다.
|
||||
* @summary 로그인
|
||||
*/
|
||||
export const login = (reqLogin: ReqLogin, signal?: AbortSignal) => {
|
||||
return customFetch<ResLogin>({
|
||||
url: `/v1/auth/login`,
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
data: reqLogin,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
export const login = (
|
||||
reqLogin: ReqLogin,
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
|
||||
|
||||
return customFetch<ResLogin>(
|
||||
{url: `/v1/auth/login`, method: 'POST',
|
||||
headers: {'Content-Type': 'application/json', },
|
||||
data: reqLogin, signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
export const getLoginMutationOptions = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof login>>,
|
||||
TError,
|
||||
{ data: ReqLogin },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof login>>,
|
||||
TError,
|
||||
{ data: ReqLogin },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["login"];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
"mutationKey" in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof login>>,
|
||||
{ data: ReqLogin }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
export const getLoginMutationOptions = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof login>>, TError,{data: ReqLogin}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof login>>, TError,{data: ReqLogin}, TContext> => {
|
||||
|
||||
return login(data);
|
||||
};
|
||||
const mutationKey = ['login'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
|
||||
export type LoginMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof login>>
|
||||
>;
|
||||
export type LoginMutationBody = ReqLogin;
|
||||
export type LoginMutationError = void | HTTPValidationError;
|
||||
|
||||
/**
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof login>>, {data: ReqLogin}> = (props) => {
|
||||
const {data} = props ?? {};
|
||||
|
||||
return login(data,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type LoginMutationResult = NonNullable<Awaited<ReturnType<typeof login>>>
|
||||
export type LoginMutationBody = ReqLogin
|
||||
export type LoginMutationError = void | HTTPValidationError
|
||||
|
||||
/**
|
||||
* @summary 로그인
|
||||
*/
|
||||
export const useLogin = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof login>>,
|
||||
TError,
|
||||
{ data: ReqLogin },
|
||||
TContext
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof login>>,
|
||||
TError,
|
||||
{ data: ReqLogin },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getLoginMutationOptions(options);
|
||||
export const useLogin = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof login>>, TError,{data: ReqLogin}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof login>>,
|
||||
TError,
|
||||
{data: ReqLogin},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
};
|
||||
/**
|
||||
const mutationOptions = getLoginMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
/**
|
||||
* 새 계정을 생성한다.
|
||||
* @summary 계정 생성
|
||||
*/
|
||||
export const createAccount = (
|
||||
reqCreateAccount: ReqCreateAccount,
|
||||
signal?: AbortSignal,
|
||||
reqCreateAccount: ReqCreateAccount,
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
return customFetch<ResCreateAccount>({
|
||||
url: `/v1/auth/create`,
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
data: reqCreateAccount,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return customFetch<ResCreateAccount>(
|
||||
{url: `/v1/auth/create`, method: 'POST',
|
||||
headers: {'Content-Type': 'application/json', },
|
||||
data: reqCreateAccount, signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
export const getCreateAccountMutationOptions = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createAccount>>,
|
||||
TError,
|
||||
{ data: ReqCreateAccount },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createAccount>>,
|
||||
TError,
|
||||
{ data: ReqCreateAccount },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["createAccount"];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
"mutationKey" in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof createAccount>>,
|
||||
{ data: ReqCreateAccount }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
export const getCreateAccountMutationOptions = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof createAccount>>, TError,{data: ReqCreateAccount}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof createAccount>>, TError,{data: ReqCreateAccount}, TContext> => {
|
||||
|
||||
return createAccount(data);
|
||||
};
|
||||
const mutationKey = ['createAccount'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
|
||||
export type CreateAccountMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createAccount>>
|
||||
>;
|
||||
export type CreateAccountMutationBody = ReqCreateAccount;
|
||||
export type CreateAccountMutationError = void | HTTPValidationError;
|
||||
|
||||
/**
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof createAccount>>, {data: ReqCreateAccount}> = (props) => {
|
||||
const {data} = props ?? {};
|
||||
|
||||
return createAccount(data,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type CreateAccountMutationResult = NonNullable<Awaited<ReturnType<typeof createAccount>>>
|
||||
export type CreateAccountMutationBody = ReqCreateAccount
|
||||
export type CreateAccountMutationError = void | HTTPValidationError
|
||||
|
||||
/**
|
||||
* @summary 계정 생성
|
||||
*/
|
||||
export const useCreateAccount = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createAccount>>,
|
||||
TError,
|
||||
{ data: ReqCreateAccount },
|
||||
TContext
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createAccount>>,
|
||||
TError,
|
||||
{ data: ReqCreateAccount },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getCreateAccountMutationOptions(options);
|
||||
export const useCreateAccount = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof createAccount>>, TError,{data: ReqCreateAccount}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createAccount>>,
|
||||
TError,
|
||||
{data: ReqCreateAccount},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
};
|
||||
/**
|
||||
const mutationOptions = getCreateAccountMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
/**
|
||||
* refresh 토큰으로 access 토큰을 재발급한다.
|
||||
* @summary 액세스 토큰 갱신
|
||||
*/
|
||||
export const refreshToken = (signal?: AbortSignal) => {
|
||||
return customFetch<ResRefreshToken>({
|
||||
url: `/v1/auth/refresh_token`,
|
||||
method: "POST",
|
||||
signal,
|
||||
});
|
||||
};
|
||||
export const refreshToken = (
|
||||
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
|
||||
|
||||
return customFetch<ResRefreshToken>(
|
||||
{url: `/v1/auth/refresh_token`, method: 'POST', signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
export const getRefreshTokenMutationOptions = <
|
||||
TError = void,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof refreshToken>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof refreshToken>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["refreshToken"];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
"mutationKey" in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof refreshToken>>,
|
||||
void
|
||||
> = () => {
|
||||
return refreshToken();
|
||||
};
|
||||
export const getRefreshTokenMutationOptions = <TError = void,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof refreshToken>>, TError,void, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof refreshToken>>, TError,void, TContext> => {
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
const mutationKey = ['refreshToken'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
export type RefreshTokenMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof refreshToken>>
|
||||
>;
|
||||
|
||||
|
||||
export type RefreshTokenMutationError = void;
|
||||
|
||||
/**
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof refreshToken>>, void> = () => {
|
||||
|
||||
|
||||
return refreshToken(requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type RefreshTokenMutationResult = NonNullable<Awaited<ReturnType<typeof refreshToken>>>
|
||||
|
||||
export type RefreshTokenMutationError = void
|
||||
|
||||
/**
|
||||
* @summary 액세스 토큰 갱신
|
||||
*/
|
||||
export const useRefreshToken = <TError = void, TContext = unknown>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof refreshToken>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof refreshToken>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getRefreshTokenMutationOptions(options);
|
||||
export const useRefreshToken = <TError = void,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof refreshToken>>, TError,void, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof refreshToken>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
> => {
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
};
|
||||
/**
|
||||
const mutationOptions = getRefreshTokenMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
/**
|
||||
* 유효한 access 토큰이 있어야 호출 가능. 토큰의 유저+회사 정보를 반환한다.
|
||||
* @summary 내 정보
|
||||
*/
|
||||
export const me = (signal?: AbortSignal) => {
|
||||
return customFetch<ResMe>({ url: `/v1/auth/me`, method: "GET", signal });
|
||||
};
|
||||
export const me = (
|
||||
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
|
||||
|
||||
return customFetch<ResMe>(
|
||||
{url: `/v1/auth/me`, method: 'GET', signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const getMeQueryKey = () => {
|
||||
return [`/v1/auth/me`] as const;
|
||||
};
|
||||
return [
|
||||
`/v1/auth/me`
|
||||
] as const;
|
||||
}
|
||||
|
||||
export const getMeQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof me>>,
|
||||
TError = void,
|
||||
>(options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
|
||||
>;
|
||||
}) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
export const getMeQueryOptions = <TData = Awaited<ReturnType<typeof me>>, TError = void>( options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
) => {
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getMeQueryKey();
|
||||
const {query: queryOptions, request: requestOptions} = options ?? {};
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof me>>> = ({ signal }) =>
|
||||
me(signal);
|
||||
const queryKey = queryOptions?.queryKey ?? getMeQueryKey();
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof me>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof me>>> = ({ signal }) => me(requestOptions, signal);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
}
|
||||
|
||||
export type MeQueryResult = NonNullable<Awaited<ReturnType<typeof me>>>
|
||||
export type MeQueryError = void
|
||||
|
||||
export type MeQueryResult = NonNullable<Awaited<ReturnType<typeof me>>>;
|
||||
export type MeQueryError = void;
|
||||
|
||||
export function useMe<TData = Awaited<ReturnType<typeof me>>, TError = void>(
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>> & Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof me>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof me>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useMe<TData = Awaited<ReturnType<typeof me>>, TError = void>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>> & Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof me>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof me>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useMe<TData = Awaited<ReturnType<typeof me>>, TError = void>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
/**
|
||||
* @summary 내 정보
|
||||
*/
|
||||
|
||||
export function useMe<TData = Awaited<ReturnType<typeof me>>, TError = void>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getMeQueryOptions(options);
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
const queryOptions = getMeQueryOptions(options)
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
query.queryKey = queryOptions.queryKey ;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -4,7 +4,10 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
useMutation,
|
||||
useQuery
|
||||
} from '@tanstack/react-query';
|
||||
import type {
|
||||
DataTag,
|
||||
DefinedInitialDataOptions,
|
||||
@ -17,8 +20,8 @@ import type {
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
UseQueryResult
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
import type {
|
||||
HTTPValidationError,
|
||||
@ -27,525 +30,388 @@ import type {
|
||||
ReqUpdateCard,
|
||||
ResCard,
|
||||
ResCardList,
|
||||
ResDeleteCard,
|
||||
} from ".././model";
|
||||
ResDeleteCard
|
||||
} from '.././model';
|
||||
|
||||
import { customFetch } from '../../mutator/custom-fetch';
|
||||
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
|
||||
import { customFetch } from "../../mutator/custom-fetch";
|
||||
|
||||
/**
|
||||
* @summary 협상카드 목록
|
||||
*/
|
||||
export const listCards = (params?: ListCardsParams, signal?: AbortSignal) => {
|
||||
return customFetch<ResCardList>({
|
||||
url: `/v1/card/list`,
|
||||
method: "GET",
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getListCardsQueryKey = (params?: ListCardsParams) => {
|
||||
return [`/v1/card/list`, ...(params ? [params] : [])] as const;
|
||||
};
|
||||
|
||||
export const getListCardsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listCards>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
params?: ListCardsParams,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
export const listCards = (
|
||||
params?: ListCardsParams,
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
|
||||
return customFetch<ResCardList>(
|
||||
{url: `/v1/card/list`, method: 'GET',
|
||||
params, signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getListCardsQueryKey(params);
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listCards>>> = ({
|
||||
signal,
|
||||
}) => listCards(params, signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listCards>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
export const getListCardsQueryKey = (params?: ListCardsParams,) => {
|
||||
return [
|
||||
`/v1/card/list`, ...(params ? [params]: [])
|
||||
] as const;
|
||||
}
|
||||
|
||||
export type ListCardsQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listCards>>
|
||||
>;
|
||||
export type ListCardsQueryError = void | HTTPValidationError;
|
||||
|
||||
export const getListCardsQueryOptions = <TData = Awaited<ReturnType<typeof listCards>>, TError = void | HTTPValidationError>(params?: ListCardsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
) => {
|
||||
|
||||
export function useListCards<
|
||||
TData = Awaited<ReturnType<typeof listCards>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
params: undefined | ListCardsParams,
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
const {query: queryOptions, request: requestOptions} = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getListCardsQueryKey(params);
|
||||
|
||||
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listCards>>> = ({ signal }) => listCards(params, requestOptions, signal);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
}
|
||||
|
||||
export type ListCardsQueryResult = NonNullable<Awaited<ReturnType<typeof listCards>>>
|
||||
export type ListCardsQueryError = void | HTTPValidationError
|
||||
|
||||
|
||||
export function useListCards<TData = Awaited<ReturnType<typeof listCards>>, TError = void | HTTPValidationError>(
|
||||
params: undefined | ListCardsParams, options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>> & Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listCards>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listCards>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListCards<
|
||||
TData = Awaited<ReturnType<typeof listCards>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
params?: ListCardsParams,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useListCards<TData = Awaited<ReturnType<typeof listCards>>, TError = void | HTTPValidationError>(
|
||||
params?: ListCardsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>> & Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listCards>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listCards>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListCards<
|
||||
TData = Awaited<ReturnType<typeof listCards>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
params?: ListCardsParams,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useListCards<TData = Awaited<ReturnType<typeof listCards>>, TError = void | HTTPValidationError>(
|
||||
params?: ListCardsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
/**
|
||||
* @summary 협상카드 목록
|
||||
*/
|
||||
|
||||
export function useListCards<
|
||||
TData = Awaited<ReturnType<typeof listCards>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
params?: ListCardsParams,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getListCardsQueryOptions(params, options);
|
||||
export function useListCards<TData = Awaited<ReturnType<typeof listCards>>, TError = void | HTTPValidationError>(
|
||||
params?: ListCardsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listCards>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
const queryOptions = getListCardsQueryOptions(params,options)
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
query.queryKey = queryOptions.queryKey ;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @summary 협상카드 등록
|
||||
*/
|
||||
export const createCard = (
|
||||
reqCreateCard: ReqCreateCard,
|
||||
signal?: AbortSignal,
|
||||
reqCreateCard: ReqCreateCard,
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
return customFetch<ResCard>({
|
||||
url: `/v1/card/create`,
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
data: reqCreateCard,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return customFetch<ResCard>(
|
||||
{url: `/v1/card/create`, method: 'POST',
|
||||
headers: {'Content-Type': 'application/json', },
|
||||
data: reqCreateCard, signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
export const getCreateCardMutationOptions = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createCard>>,
|
||||
TError,
|
||||
{ data: ReqCreateCard },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createCard>>,
|
||||
TError,
|
||||
{ data: ReqCreateCard },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["createCard"];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
"mutationKey" in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof createCard>>,
|
||||
{ data: ReqCreateCard }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
export const getCreateCardMutationOptions = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof createCard>>, TError,{data: ReqCreateCard}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof createCard>>, TError,{data: ReqCreateCard}, TContext> => {
|
||||
|
||||
return createCard(data);
|
||||
};
|
||||
const mutationKey = ['createCard'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
|
||||
export type CreateCardMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createCard>>
|
||||
>;
|
||||
export type CreateCardMutationBody = ReqCreateCard;
|
||||
export type CreateCardMutationError = void | HTTPValidationError;
|
||||
|
||||
/**
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof createCard>>, {data: ReqCreateCard}> = (props) => {
|
||||
const {data} = props ?? {};
|
||||
|
||||
return createCard(data,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type CreateCardMutationResult = NonNullable<Awaited<ReturnType<typeof createCard>>>
|
||||
export type CreateCardMutationBody = ReqCreateCard
|
||||
export type CreateCardMutationError = void | HTTPValidationError
|
||||
|
||||
/**
|
||||
* @summary 협상카드 등록
|
||||
*/
|
||||
export const useCreateCard = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createCard>>,
|
||||
TError,
|
||||
{ data: ReqCreateCard },
|
||||
TContext
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createCard>>,
|
||||
TError,
|
||||
{ data: ReqCreateCard },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getCreateCardMutationOptions(options);
|
||||
export const useCreateCard = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof createCard>>, TError,{data: ReqCreateCard}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createCard>>,
|
||||
TError,
|
||||
{data: ReqCreateCard},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
};
|
||||
/**
|
||||
const mutationOptions = getCreateCardMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
/**
|
||||
* @summary 협상카드 조회
|
||||
*/
|
||||
export const getCard = (cardId: string, signal?: AbortSignal) => {
|
||||
return customFetch<ResCard>({
|
||||
url: `/v1/card/${cardId}`,
|
||||
method: "GET",
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetCardQueryKey = (cardId?: string) => {
|
||||
return [`/v1/card/${cardId}`] as const;
|
||||
};
|
||||
|
||||
export const getGetCardQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getCard>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
cardId: string,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
export const getCard = (
|
||||
cardId: string,
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
|
||||
return customFetch<ResCard>(
|
||||
{url: `/v1/card/${cardId}`, method: 'GET', signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetCardQueryKey(cardId);
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getCard>>> = ({
|
||||
signal,
|
||||
}) => getCard(cardId, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!cardId,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
};
|
||||
export const getGetCardQueryKey = (cardId?: string,) => {
|
||||
return [
|
||||
`/v1/card/${cardId}`
|
||||
] as const;
|
||||
}
|
||||
|
||||
export type GetCardQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getCard>>
|
||||
>;
|
||||
export type GetCardQueryError = void | HTTPValidationError;
|
||||
|
||||
export const getGetCardQueryOptions = <TData = Awaited<ReturnType<typeof getCard>>, TError = void | HTTPValidationError>(cardId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
) => {
|
||||
|
||||
export function useGetCard<
|
||||
TData = Awaited<ReturnType<typeof getCard>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
cardId: string,
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
const {query: queryOptions, request: requestOptions} = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetCardQueryKey(cardId);
|
||||
|
||||
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getCard>>> = ({ signal }) => getCard(cardId, requestOptions, signal);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return { queryKey, queryFn, enabled: !!(cardId), ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
}
|
||||
|
||||
export type GetCardQueryResult = NonNullable<Awaited<ReturnType<typeof getCard>>>
|
||||
export type GetCardQueryError = void | HTTPValidationError
|
||||
|
||||
|
||||
export function useGetCard<TData = Awaited<ReturnType<typeof getCard>>, TError = void | HTTPValidationError>(
|
||||
cardId: string, options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>> & Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof getCard>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof getCard>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useGetCard<
|
||||
TData = Awaited<ReturnType<typeof getCard>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
cardId: string,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useGetCard<TData = Awaited<ReturnType<typeof getCard>>, TError = void | HTTPValidationError>(
|
||||
cardId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>> & Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof getCard>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof getCard>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useGetCard<
|
||||
TData = Awaited<ReturnType<typeof getCard>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
cardId: string,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useGetCard<TData = Awaited<ReturnType<typeof getCard>>, TError = void | HTTPValidationError>(
|
||||
cardId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
/**
|
||||
* @summary 협상카드 조회
|
||||
*/
|
||||
|
||||
export function useGetCard<
|
||||
TData = Awaited<ReturnType<typeof getCard>>,
|
||||
TError = void | HTTPValidationError,
|
||||
>(
|
||||
cardId: string,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getGetCardQueryOptions(cardId, options);
|
||||
export function useGetCard<TData = Awaited<ReturnType<typeof getCard>>, TError = void | HTTPValidationError>(
|
||||
cardId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getCard>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
const queryOptions = getGetCardQueryOptions(cardId,options)
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
query.queryKey = queryOptions.queryKey ;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary 협상카드 수정
|
||||
*/
|
||||
export const updateCard = (cardId: string, reqUpdateCard: ReqUpdateCard) => {
|
||||
return customFetch<ResCard>({
|
||||
url: `/v1/card/update/${cardId}`,
|
||||
method: "PATCH",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
data: reqUpdateCard,
|
||||
});
|
||||
};
|
||||
|
||||
export const getUpdateCardMutationOptions = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateCard>>,
|
||||
TError,
|
||||
{ cardId: string; data: ReqUpdateCard },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateCard>>,
|
||||
TError,
|
||||
{ cardId: string; data: ReqUpdateCard },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["updateCard"];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
"mutationKey" in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof updateCard>>,
|
||||
{ cardId: string; data: ReqUpdateCard }
|
||||
> = (props) => {
|
||||
const { cardId, data } = props ?? {};
|
||||
|
||||
return updateCard(cardId, data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type UpdateCardMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateCard>>
|
||||
>;
|
||||
export type UpdateCardMutationBody = ReqUpdateCard;
|
||||
export type UpdateCardMutationError = void | HTTPValidationError;
|
||||
|
||||
/**
|
||||
* @summary 협상카드 수정
|
||||
*/
|
||||
export const useUpdateCard = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateCard>>,
|
||||
TError,
|
||||
{ cardId: string; data: ReqUpdateCard },
|
||||
TContext
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateCard>>,
|
||||
TError,
|
||||
{ cardId: string; data: ReqUpdateCard },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getUpdateCardMutationOptions(options);
|
||||
export const updateCard = (
|
||||
cardId: string,
|
||||
reqUpdateCard: ReqUpdateCard,
|
||||
options?: SecondParameter<typeof customFetch>,) => {
|
||||
|
||||
|
||||
return customFetch<ResCard>(
|
||||
{url: `/v1/card/update/${cardId}`, method: 'PATCH',
|
||||
headers: {'Content-Type': 'application/json', },
|
||||
data: reqUpdateCard
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
};
|
||||
/**
|
||||
|
||||
export const getUpdateCardMutationOptions = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof updateCard>>, TError,{cardId: string;data: ReqUpdateCard}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof updateCard>>, TError,{cardId: string;data: ReqUpdateCard}, TContext> => {
|
||||
|
||||
const mutationKey = ['updateCard'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
|
||||
|
||||
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof updateCard>>, {cardId: string;data: ReqUpdateCard}> = (props) => {
|
||||
const {cardId,data} = props ?? {};
|
||||
|
||||
return updateCard(cardId,data,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type UpdateCardMutationResult = NonNullable<Awaited<ReturnType<typeof updateCard>>>
|
||||
export type UpdateCardMutationBody = ReqUpdateCard
|
||||
export type UpdateCardMutationError = void | HTTPValidationError
|
||||
|
||||
/**
|
||||
* @summary 협상카드 수정
|
||||
*/
|
||||
export const useUpdateCard = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof updateCard>>, TError,{cardId: string;data: ReqUpdateCard}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateCard>>,
|
||||
TError,
|
||||
{cardId: string;data: ReqUpdateCard},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
const mutationOptions = getUpdateCardMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
/**
|
||||
* @summary 협상카드 삭제
|
||||
*/
|
||||
export const deleteCard = (cardId: string) => {
|
||||
return customFetch<ResDeleteCard>({
|
||||
url: `/v1/card/delete/${cardId}`,
|
||||
method: "DELETE",
|
||||
});
|
||||
};
|
||||
export const deleteCard = (
|
||||
cardId: string,
|
||||
options?: SecondParameter<typeof customFetch>,) => {
|
||||
|
||||
|
||||
return customFetch<ResDeleteCard>(
|
||||
{url: `/v1/card/delete/${cardId}`, method: 'DELETE'
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
export const getDeleteCardMutationOptions = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteCard>>,
|
||||
TError,
|
||||
{ cardId: string },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteCard>>,
|
||||
TError,
|
||||
{ cardId: string },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["deleteCard"];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
"mutationKey" in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof deleteCard>>,
|
||||
{ cardId: string }
|
||||
> = (props) => {
|
||||
const { cardId } = props ?? {};
|
||||
export const getDeleteCardMutationOptions = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof deleteCard>>, TError,{cardId: string}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof deleteCard>>, TError,{cardId: string}, TContext> => {
|
||||
|
||||
return deleteCard(cardId);
|
||||
};
|
||||
const mutationKey = ['deleteCard'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
|
||||
export type DeleteCardMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof deleteCard>>
|
||||
>;
|
||||
|
||||
export type DeleteCardMutationError = void | HTTPValidationError;
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof deleteCard>>, {cardId: string}> = (props) => {
|
||||
const {cardId} = props ?? {};
|
||||
|
||||
/**
|
||||
return deleteCard(cardId,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type DeleteCardMutationResult = NonNullable<Awaited<ReturnType<typeof deleteCard>>>
|
||||
|
||||
export type DeleteCardMutationError = void | HTTPValidationError
|
||||
|
||||
/**
|
||||
* @summary 협상카드 삭제
|
||||
*/
|
||||
export const useDeleteCard = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteCard>>,
|
||||
TError,
|
||||
{ cardId: string },
|
||||
TContext
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteCard>>,
|
||||
TError,
|
||||
{ cardId: string },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getDeleteCardMutationOptions(options);
|
||||
export const useDeleteCard = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof deleteCard>>, TError,{cardId: string}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteCard>>,
|
||||
TError,
|
||||
{cardId: string},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
};
|
||||
const mutationOptions = getDeleteCardMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
|
||||
@ -4,7 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
useQuery
|
||||
} from '@tanstack/react-query';
|
||||
import type {
|
||||
DataTag,
|
||||
DefinedInitialDataOptions,
|
||||
@ -14,150 +16,105 @@ import type {
|
||||
QueryKey,
|
||||
UndefinedInitialDataOptions,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
UseQueryResult
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
import { customFetch } from '../../mutator/custom-fetch';
|
||||
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
|
||||
import { customFetch } from "../../mutator/custom-fetch";
|
||||
|
||||
/**
|
||||
* @summary Healthz
|
||||
*/
|
||||
export const healthzHealthzGet = (signal?: AbortSignal) => {
|
||||
return customFetch<unknown>({ url: `/healthz`, method: "GET", signal });
|
||||
};
|
||||
export const healthzHealthzGet = (
|
||||
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
|
||||
|
||||
return customFetch<unknown>(
|
||||
{url: `/healthz`, method: 'GET', signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const getHealthzHealthzGetQueryKey = () => {
|
||||
return [`/healthz`] as const;
|
||||
};
|
||||
return [
|
||||
`/healthz`
|
||||
] as const;
|
||||
}
|
||||
|
||||
export const getHealthzHealthzGetQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = void,
|
||||
>(options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
}) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
export const getHealthzHealthzGetQueryOptions = <TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>( options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
) => {
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getHealthzHealthzGetQueryKey();
|
||||
const {query: queryOptions, request: requestOptions} = options ?? {};
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>
|
||||
> = ({ signal }) => healthzHealthzGet(signal);
|
||||
const queryKey = queryOptions?.queryKey ?? getHealthzHealthzGetQueryKey();
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
|
||||
export type HealthzHealthzGetQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>
|
||||
>;
|
||||
export type HealthzHealthzGetQueryError = void;
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof healthzHealthzGet>>> = ({ signal }) => healthzHealthzGet(requestOptions, signal);
|
||||
|
||||
export function useHealthzHealthzGet<
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = void,
|
||||
>(
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
|
||||
|
||||
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
}
|
||||
|
||||
export type HealthzHealthzGetQueryResult = NonNullable<Awaited<ReturnType<typeof healthzHealthzGet>>>
|
||||
export type HealthzHealthzGetQueryError = void
|
||||
|
||||
|
||||
export function useHealthzHealthzGet<TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>(
|
||||
options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>> & Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useHealthzHealthzGet<
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = void,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useHealthzHealthzGet<TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>(
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>> & Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useHealthzHealthzGet<
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = void,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useHealthzHealthzGet<TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>(
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
/**
|
||||
* @summary Healthz
|
||||
*/
|
||||
|
||||
export function useHealthzHealthzGet<
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = void,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getHealthzHealthzGetQueryOptions(options);
|
||||
export function useHealthzHealthzGet<TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>(
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
const queryOptions = getHealthzHealthzGetQueryOptions(options)
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
query.queryKey = queryOptions.queryKey ;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -4,7 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
useQuery
|
||||
} from '@tanstack/react-query';
|
||||
import type {
|
||||
DataTag,
|
||||
DefinedInitialDataOptions,
|
||||
@ -14,132 +16,109 @@ import type {
|
||||
QueryKey,
|
||||
UndefinedInitialDataOptions,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
UseQueryResult
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
import type {
|
||||
ResEnums
|
||||
} from '.././model';
|
||||
|
||||
import { customFetch } from '../../mutator/custom-fetch';
|
||||
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
import type { ResEnums } from ".././model";
|
||||
|
||||
import { customFetch } from "../../mutator/custom-fetch";
|
||||
|
||||
/**
|
||||
* @summary 도메인 코드 enum 전체
|
||||
*/
|
||||
export const listEnums = (signal?: AbortSignal) => {
|
||||
return customFetch<ResEnums>({ url: `/v1/enums`, method: "GET", signal });
|
||||
};
|
||||
export const listEnums = (
|
||||
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
|
||||
|
||||
return customFetch<ResEnums>(
|
||||
{url: `/v1/enums`, method: 'GET', signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const getListEnumsQueryKey = () => {
|
||||
return [`/v1/enums`] as const;
|
||||
};
|
||||
return [
|
||||
`/v1/enums`
|
||||
] as const;
|
||||
}
|
||||
|
||||
export const getListEnumsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listEnums>>,
|
||||
TError = void,
|
||||
>(options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>
|
||||
>;
|
||||
}) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
export const getListEnumsQueryOptions = <TData = Awaited<ReturnType<typeof listEnums>>, TError = void>( options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
) => {
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getListEnumsQueryKey();
|
||||
const {query: queryOptions, request: requestOptions} = options ?? {};
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listEnums>>> = ({
|
||||
signal,
|
||||
}) => listEnums(signal);
|
||||
const queryKey = queryOptions?.queryKey ?? getListEnumsQueryKey();
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listEnums>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
|
||||
export type ListEnumsQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listEnums>>
|
||||
>;
|
||||
export type ListEnumsQueryError = void;
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listEnums>>> = ({ signal }) => listEnums(requestOptions, signal);
|
||||
|
||||
export function useListEnums<
|
||||
TData = Awaited<ReturnType<typeof listEnums>>,
|
||||
TError = void,
|
||||
>(
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
|
||||
|
||||
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
}
|
||||
|
||||
export type ListEnumsQueryResult = NonNullable<Awaited<ReturnType<typeof listEnums>>>
|
||||
export type ListEnumsQueryError = void
|
||||
|
||||
|
||||
export function useListEnums<TData = Awaited<ReturnType<typeof listEnums>>, TError = void>(
|
||||
options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>> & Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listEnums>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listEnums>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListEnums<
|
||||
TData = Awaited<ReturnType<typeof listEnums>>,
|
||||
TError = void,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useListEnums<TData = Awaited<ReturnType<typeof listEnums>>, TError = void>(
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>> & Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listEnums>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listEnums>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListEnums<
|
||||
TData = Awaited<ReturnType<typeof listEnums>>,
|
||||
TError = void,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useListEnums<TData = Awaited<ReturnType<typeof listEnums>>, TError = void>(
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
/**
|
||||
* @summary 도메인 코드 enum 전체
|
||||
*/
|
||||
|
||||
export function useListEnums<
|
||||
TData = Awaited<ReturnType<typeof listEnums>>,
|
||||
TError = void,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getListEnumsQueryOptions(options);
|
||||
export function useListEnums<TData = Awaited<ReturnType<typeof listEnums>>, TError = void>(
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listEnums>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
const queryOptions = getListEnumsQueryOptions(options)
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
query.queryKey = queryOptions.queryKey ;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,6 @@
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface BodyUploadItemsExcelV1ItemUploadExcelPost {
|
||||
export interface BodyUploadItemImageV1ItemImagePost {
|
||||
file: string;
|
||||
}
|
||||
@ -4,15 +4,15 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { CardDataUserId } from "./cardDataUserId";
|
||||
import type { CardDataName } from "./cardDataName";
|
||||
import type { CardDataNumber } from "./cardDataNumber";
|
||||
import type { CardDataScript } from "./cardDataScript";
|
||||
import type { CardDataEditScript } from "./cardDataEditScript";
|
||||
import type { CardDataCondition } from "./cardDataCondition";
|
||||
import type { CardDataMemo } from "./cardDataMemo";
|
||||
import type { CardDataCreatedAt } from "./cardDataCreatedAt";
|
||||
import type { CardDataUpdatedAt } from "./cardDataUpdatedAt";
|
||||
import type { CardDataUserId } from './cardDataUserId';
|
||||
import type { CardDataName } from './cardDataName';
|
||||
import type { CardDataNumber } from './cardDataNumber';
|
||||
import type { CardDataScript } from './cardDataScript';
|
||||
import type { CardDataEditScript } from './cardDataEditScript';
|
||||
import type { CardDataCondition } from './cardDataCondition';
|
||||
import type { CardDataMemo } from './cardDataMemo';
|
||||
import type { CardDataCreatedAt } from './cardDataCreatedAt';
|
||||
import type { CardDataUpdatedAt } from './cardDataUpdatedAt';
|
||||
|
||||
export interface CardData {
|
||||
nego_card_id: string;
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ChatMessageDataCardId } from "./chatMessageDataCardId";
|
||||
import type { ChatMessageDataCardUsedYn } from "./chatMessageDataCardUsedYn";
|
||||
import type { ChatMessageDataIndicatorValue } from "./chatMessageDataIndicatorValue";
|
||||
import type { ChatMessageDataCardType } from "./chatMessageDataCardType";
|
||||
import type { ChatMessageDataCardId } from './chatMessageDataCardId';
|
||||
import type { ChatMessageDataCardUsedYn } from './chatMessageDataCardUsedYn';
|
||||
import type { ChatMessageDataIndicatorValue } from './chatMessageDataIndicatorValue';
|
||||
import type { ChatMessageDataCardType } from './chatMessageDataCardType';
|
||||
|
||||
export interface ChatMessageData {
|
||||
chat_id: string;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfoSuccess } from "./errorInfoSuccess";
|
||||
import type { ErrorInfoCode } from "./errorInfoCode";
|
||||
import type { ErrorInfoDesc } from "./errorInfoDesc";
|
||||
import type { ErrorInfoSuccess } from './errorInfoSuccess';
|
||||
import type { ErrorInfoCode } from './errorInfoCode';
|
||||
import type { ErrorInfoDesc } from './errorInfoDesc';
|
||||
|
||||
/**
|
||||
* 모든 응답에 공통으로 실리는 결과 정보. result.success / code / desc 로 내려간다.
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ValidationError } from "./validationError";
|
||||
import type { ValidationError } from './validationError';
|
||||
|
||||
export interface HTTPValidationError {
|
||||
detail?: ValidationError[];
|
||||
|
||||
@ -5,248 +5,253 @@
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export * from "./asyncJob";
|
||||
export * from "./bodyUploadItemsExcelV1ItemUploadExcelPost";
|
||||
export * from "./bodyUploadSuppliersExcelV1SupplierUploadExcelPost";
|
||||
export * from "./cardData";
|
||||
export * from "./cardDataCondition";
|
||||
export * from "./cardDataCreatedAt";
|
||||
export * from "./cardDataEditScript";
|
||||
export * from "./cardDataMemo";
|
||||
export * from "./cardDataName";
|
||||
export * from "./cardDataNumber";
|
||||
export * from "./cardDataScript";
|
||||
export * from "./cardDataUpdatedAt";
|
||||
export * from "./cardDataUserId";
|
||||
export * from "./chatMessageData";
|
||||
export * from "./chatMessageDataCardId";
|
||||
export * from "./chatMessageDataCardType";
|
||||
export * from "./chatMessageDataCardUsedYn";
|
||||
export * from "./chatMessageDataIndicatorValue";
|
||||
export * from "./companyData";
|
||||
export * from "./enumOption";
|
||||
export * from "./errorInfo";
|
||||
export * from "./errorInfoCode";
|
||||
export * from "./errorInfoDesc";
|
||||
export * from "./errorInfoSuccess";
|
||||
export * from "./hTTPValidationError";
|
||||
export * from "./itemCategory";
|
||||
export * from "./itemData";
|
||||
export * from "./itemDataCategory";
|
||||
export * from "./itemDataCode";
|
||||
export * from "./itemDataCreatedAt";
|
||||
export * from "./itemDataDeliveryFeeYn";
|
||||
export * from "./itemDataDeliveryType";
|
||||
export * from "./itemDataImageUrl";
|
||||
export * from "./itemDataLeadTime";
|
||||
export * from "./itemDataMadeIn";
|
||||
export * from "./itemDataManufacturer";
|
||||
export * from "./itemDataModelName";
|
||||
export * from "./itemDataMoq";
|
||||
export * from "./itemDataPrice";
|
||||
export * from "./itemDataQuantityUnit";
|
||||
export * from "./itemDataSpec";
|
||||
export * from "./itemDataUpdatedAt";
|
||||
export * from "./itemDataVatYn";
|
||||
export * from "./listCardsParams";
|
||||
export * from "./listItemsParams";
|
||||
export * from "./listQuotationsParams";
|
||||
export * from "./listSuppliersParams";
|
||||
export * from "./quotationCardData";
|
||||
export * from "./quotationCardDataName";
|
||||
export * from "./quotationCardDataNegoCardId";
|
||||
export * from "./quotationCardDataQtId";
|
||||
export * from "./quotationCardDataScript";
|
||||
export * from "./quotationCardDataType";
|
||||
export * from "./quotationCardDataWildCardId";
|
||||
export * from "./quotationData";
|
||||
export * from "./quotationDataCreatedAt";
|
||||
export * from "./quotationDataEqualBidData";
|
||||
export * from "./quotationDataEqualBidYn";
|
||||
export * from "./quotationDataManagerContactNumber";
|
||||
export * from "./quotationDataManagerEmail";
|
||||
export * from "./quotationDataManagerName";
|
||||
export * from "./quotationDataMemo";
|
||||
export * from "./quotationDataPreferredSpId";
|
||||
export * from "./quotationDataPreferredSpName";
|
||||
export * from "./quotationDataPreferredSpYn";
|
||||
export * from "./quotationDataUpdatedAt";
|
||||
export * from "./quotationSettingData";
|
||||
export * from "./quotationSettingDataCreatedAt";
|
||||
export * from "./quotationSettingDataUpdatedAt";
|
||||
export * from "./quotationSettingDataUserId";
|
||||
export * from "./reqCheckCodes";
|
||||
export * from "./reqCreateAccount";
|
||||
export * from "./reqCreateCard";
|
||||
export * from "./reqCreateCardCondition";
|
||||
export * from "./reqCreateCardEditScript";
|
||||
export * from "./reqCreateCardMemo";
|
||||
export * from "./reqCreateCardName";
|
||||
export * from "./reqCreateCardNumber";
|
||||
export * from "./reqCreateCardScript";
|
||||
export * from "./reqCreateItem";
|
||||
export * from "./reqCreateItemCategory";
|
||||
export * from "./reqCreateItemCode";
|
||||
export * from "./reqCreateItemDeliveryFeeYn";
|
||||
export * from "./reqCreateItemDeliveryType";
|
||||
export * from "./reqCreateItemImageUrl";
|
||||
export * from "./reqCreateItemLeadTime";
|
||||
export * from "./reqCreateItemMadeIn";
|
||||
export * from "./reqCreateItemManufacturer";
|
||||
export * from "./reqCreateItemModelName";
|
||||
export * from "./reqCreateItemMoq";
|
||||
export * from "./reqCreateItemPrice";
|
||||
export * from "./reqCreateItemQuantityUnit";
|
||||
export * from "./reqCreateItemSpec";
|
||||
export * from "./reqCreateItemVatYn";
|
||||
export * from "./reqCreateQuotation";
|
||||
export * from "./reqCreateQuotationManagerContactNumber";
|
||||
export * from "./reqCreateQuotationManagerEmail";
|
||||
export * from "./reqCreateQuotationManagerName";
|
||||
export * from "./reqCreateQuotationMemo";
|
||||
export * from "./reqCreateQuotationSetting";
|
||||
export * from "./reqCreateSupplier";
|
||||
export * from "./reqCreateSupplierCode";
|
||||
export * from "./reqCreateSupplierManagerContactNumber";
|
||||
export * from "./reqCreateSupplierManagerEmail";
|
||||
export * from "./reqCreateSupplierManagerName";
|
||||
export * from "./reqCreateSupplierPriority";
|
||||
export * from "./reqLogin";
|
||||
export * from "./reqUpdateCard";
|
||||
export * from "./reqUpdateCardCondition";
|
||||
export * from "./reqUpdateCardEditScript";
|
||||
export * from "./reqUpdateCardMemo";
|
||||
export * from "./reqUpdateCardName";
|
||||
export * from "./reqUpdateCardNumber";
|
||||
export * from "./reqUpdateCardScript";
|
||||
export * from "./reqUpdateCardStatus";
|
||||
export * from "./reqUpdateItem";
|
||||
export * from "./reqUpdateItemCategory";
|
||||
export * from "./reqUpdateItemCategoryType";
|
||||
export * from "./reqUpdateItemCode";
|
||||
export * from "./reqUpdateItemDeliveryFeeYn";
|
||||
export * from "./reqUpdateItemDeliveryType";
|
||||
export * from "./reqUpdateItemImageUrl";
|
||||
export * from "./reqUpdateItemInternetLowestPriceYn";
|
||||
export * from "./reqUpdateItemLeadTime";
|
||||
export * from "./reqUpdateItemMadeIn";
|
||||
export * from "./reqUpdateItemManufacturer";
|
||||
export * from "./reqUpdateItemModelName";
|
||||
export * from "./reqUpdateItemMoq";
|
||||
export * from "./reqUpdateItemName";
|
||||
export * from "./reqUpdateItemPrice";
|
||||
export * from "./reqUpdateItemQuantityUnit";
|
||||
export * from "./reqUpdateItemSpec";
|
||||
export * from "./reqUpdateItemVatYn";
|
||||
export * from "./reqUpdateQuotationSetting";
|
||||
export * from "./reqUpdateQuotationSettingAnchoringValue";
|
||||
export * from "./reqUpdateQuotationSettingCardCount";
|
||||
export * from "./reqUpdateQuotationSettingTargetMarginRate";
|
||||
export * from "./reqUpdateSupplier";
|
||||
export * from "./reqUpdateSupplierCode";
|
||||
export * from "./reqUpdateSupplierManagerContactNumber";
|
||||
export * from "./reqUpdateSupplierManagerEmail";
|
||||
export * from "./reqUpdateSupplierManagerName";
|
||||
export * from "./reqUpdateSupplierName";
|
||||
export * from "./reqUpdateSupplierPriority";
|
||||
export * from "./resCard";
|
||||
export * from "./resCardCard";
|
||||
export * from "./resCardList";
|
||||
export * from "./resCardListMsg";
|
||||
export * from "./resCardMsg";
|
||||
export * from "./resCheckCodes";
|
||||
export * from "./resCheckCodesMsg";
|
||||
export * from "./resCreateAccount";
|
||||
export * from "./resCreateAccountMsg";
|
||||
export * from "./resCreateQuotation";
|
||||
export * from "./resCreateQuotationAsyncJob";
|
||||
export * from "./resCreateQuotationMsg";
|
||||
export * from "./resCreateQuotationQuotation";
|
||||
export * from "./resDeleteCard";
|
||||
export * from "./resDeleteCardMsg";
|
||||
export * from "./resDeleteItem";
|
||||
export * from "./resDeleteItemMsg";
|
||||
export * from "./resDeleteQuotation";
|
||||
export * from "./resDeleteQuotationMsg";
|
||||
export * from "./resDeleteQuotationSetting";
|
||||
export * from "./resDeleteQuotationSettingMsg";
|
||||
export * from "./resDeleteSupplier";
|
||||
export * from "./resDeleteSupplierMsg";
|
||||
export * from "./resEnums";
|
||||
export * from "./resEnumsEnums";
|
||||
export * from "./resEnumsMsg";
|
||||
export * from "./resExcelUpload";
|
||||
export * from "./resExcelUploadMsg";
|
||||
export * from "./resExcelUploadReceivedFilename";
|
||||
export * from "./resItem";
|
||||
export * from "./resItemCategories";
|
||||
export * from "./resItemCategoriesMsg";
|
||||
export * from "./resItemItem";
|
||||
export * from "./resItemList";
|
||||
export * from "./resItemListMsg";
|
||||
export * from "./resItemMsg";
|
||||
export * from "./resLogin";
|
||||
export * from "./resLoginMsg";
|
||||
export * from "./resLowestPriceResult";
|
||||
export * from "./resLowestPriceResultMsg";
|
||||
export * from "./resLowestPriceTrigger";
|
||||
export * from "./resLowestPriceTriggerMsg";
|
||||
export * from "./resMe";
|
||||
export * from "./resMeCompany";
|
||||
export * from "./resMeContactNumber";
|
||||
export * from "./resMeEmail";
|
||||
export * from "./resMeMsg";
|
||||
export * from "./resMeName";
|
||||
export * from "./resQuotation";
|
||||
export * from "./resQuotationCards";
|
||||
export * from "./resQuotationCardsMsg";
|
||||
export * from "./resQuotationCardsQtId";
|
||||
export * from "./resQuotationList";
|
||||
export * from "./resQuotationListMsg";
|
||||
export * from "./resQuotationMsg";
|
||||
export * from "./resQuotationQuotation";
|
||||
export * from "./resQuotationResult";
|
||||
export * from "./resQuotationResultEqualBidData";
|
||||
export * from "./resQuotationResultIsEqualBid";
|
||||
export * from "./resQuotationResultMsg";
|
||||
export * from "./resQuotationResultQtId";
|
||||
export * from "./resQuotationResultWinnerSupplierId";
|
||||
export * from "./resQuotationResultWinnerSupplierName";
|
||||
export * from "./resQuotationSessions";
|
||||
export * from "./resQuotationSessionsMsg";
|
||||
export * from "./resQuotationSessionsQtId";
|
||||
export * from "./resQuotationSetting";
|
||||
export * from "./resQuotationSettingList";
|
||||
export * from "./resQuotationSettingListMsg";
|
||||
export * from "./resQuotationSettingMsg";
|
||||
export * from "./resQuotationSettingSetting";
|
||||
export * from "./resQuotationStatus";
|
||||
export * from "./resQuotationStatusMsg";
|
||||
export * from "./resQuotationStatusQtId";
|
||||
export * from "./resRefreshToken";
|
||||
export * from "./resRefreshTokenMsg";
|
||||
export * from "./resSessionChat";
|
||||
export * from "./resSessionChatMsg";
|
||||
export * from "./resSessionChatSessionId";
|
||||
export * from "./resSupplier";
|
||||
export * from "./resSupplierList";
|
||||
export * from "./resSupplierListMsg";
|
||||
export * from "./resSupplierMsg";
|
||||
export * from "./resSupplierSupplier";
|
||||
export * from "./sessionData";
|
||||
export * from "./sessionDataBidAt";
|
||||
export * from "./sessionDataBidPrice";
|
||||
export * from "./sessionDataRejectDeliveryType";
|
||||
export * from "./sessionDataRejectPrice";
|
||||
export * from "./sessionDataRejectReason";
|
||||
export * from "./supplierData";
|
||||
export * from "./supplierDataCode";
|
||||
export * from "./supplierDataCreatedAt";
|
||||
export * from "./supplierDataManagerContactNumber";
|
||||
export * from "./supplierDataManagerEmail";
|
||||
export * from "./supplierDataManagerName";
|
||||
export * from "./supplierDataPriority";
|
||||
export * from "./supplierDataUpdatedAt";
|
||||
export * from "./validationError";
|
||||
export * from "./validationErrorCtx";
|
||||
export * from "./validationErrorLocItem";
|
||||
export * from './asyncJob';
|
||||
export * from './bodyUploadItemImageV1ItemImagePost';
|
||||
export * from './cardData';
|
||||
export * from './cardDataCondition';
|
||||
export * from './cardDataCreatedAt';
|
||||
export * from './cardDataEditScript';
|
||||
export * from './cardDataMemo';
|
||||
export * from './cardDataName';
|
||||
export * from './cardDataNumber';
|
||||
export * from './cardDataScript';
|
||||
export * from './cardDataUpdatedAt';
|
||||
export * from './cardDataUserId';
|
||||
export * from './chatMessageData';
|
||||
export * from './chatMessageDataCardId';
|
||||
export * from './chatMessageDataCardType';
|
||||
export * from './chatMessageDataCardUsedYn';
|
||||
export * from './chatMessageDataIndicatorValue';
|
||||
export * from './companyData';
|
||||
export * from './enumOption';
|
||||
export * from './errorInfo';
|
||||
export * from './errorInfoCode';
|
||||
export * from './errorInfoDesc';
|
||||
export * from './errorInfoSuccess';
|
||||
export * from './hTTPValidationError';
|
||||
export * from './itemCategory';
|
||||
export * from './itemData';
|
||||
export * from './itemDataCategory';
|
||||
export * from './itemDataCode';
|
||||
export * from './itemDataCreatedAt';
|
||||
export * from './itemDataDeliveryFeeYn';
|
||||
export * from './itemDataDeliveryType';
|
||||
export * from './itemDataImageUrl';
|
||||
export * from './itemDataLeadTime';
|
||||
export * from './itemDataMadeIn';
|
||||
export * from './itemDataManufacturer';
|
||||
export * from './itemDataModelName';
|
||||
export * from './itemDataMoq';
|
||||
export * from './itemDataPrice';
|
||||
export * from './itemDataQuantityUnit';
|
||||
export * from './itemDataSpec';
|
||||
export * from './itemDataUpdatedAt';
|
||||
export * from './itemDataVatYn';
|
||||
export * from './listCardsParams';
|
||||
export * from './listItemsParams';
|
||||
export * from './listQuotationsParams';
|
||||
export * from './listSuppliersParams';
|
||||
export * from './quotationCardData';
|
||||
export * from './quotationCardDataCondition';
|
||||
export * from './quotationCardDataEditScript';
|
||||
export * from './quotationCardDataMemo';
|
||||
export * from './quotationCardDataName';
|
||||
export * from './quotationCardDataNegoCardId';
|
||||
export * from './quotationCardDataNumber';
|
||||
export * from './quotationCardDataQtId';
|
||||
export * from './quotationCardDataScript';
|
||||
export * from './quotationCardDataType';
|
||||
export * from './quotationCardDataWildCardId';
|
||||
export * from './quotationData';
|
||||
export * from './quotationDataCreatedAt';
|
||||
export * from './quotationDataEqualBidData';
|
||||
export * from './quotationDataEqualBidYn';
|
||||
export * from './quotationDataManagerContactNumber';
|
||||
export * from './quotationDataManagerEmail';
|
||||
export * from './quotationDataManagerName';
|
||||
export * from './quotationDataMemo';
|
||||
export * from './quotationDataPreferredSpId';
|
||||
export * from './quotationDataPreferredSpName';
|
||||
export * from './quotationDataPreferredSpYn';
|
||||
export * from './quotationDataUpdatedAt';
|
||||
export * from './quotationSettingData';
|
||||
export * from './quotationSettingDataCreatedAt';
|
||||
export * from './quotationSettingDataUpdatedAt';
|
||||
export * from './quotationSettingDataUserId';
|
||||
export * from './reqCheckCodes';
|
||||
export * from './reqCreateAccount';
|
||||
export * from './reqCreateCard';
|
||||
export * from './reqCreateCardCondition';
|
||||
export * from './reqCreateCardEditScript';
|
||||
export * from './reqCreateCardMemo';
|
||||
export * from './reqCreateCardName';
|
||||
export * from './reqCreateCardNumber';
|
||||
export * from './reqCreateCardScript';
|
||||
export * from './reqCreateItem';
|
||||
export * from './reqCreateItemCategory';
|
||||
export * from './reqCreateItemCode';
|
||||
export * from './reqCreateItemDeliveryFeeYn';
|
||||
export * from './reqCreateItemDeliveryType';
|
||||
export * from './reqCreateItemImageUrl';
|
||||
export * from './reqCreateItemLeadTime';
|
||||
export * from './reqCreateItemMadeIn';
|
||||
export * from './reqCreateItemManufacturer';
|
||||
export * from './reqCreateItemModelName';
|
||||
export * from './reqCreateItemMoq';
|
||||
export * from './reqCreateItemPrice';
|
||||
export * from './reqCreateItemQuantityUnit';
|
||||
export * from './reqCreateItemSpec';
|
||||
export * from './reqCreateItemVatYn';
|
||||
export * from './reqCreateQuotation';
|
||||
export * from './reqCreateQuotationManagerContactNumber';
|
||||
export * from './reqCreateQuotationManagerEmail';
|
||||
export * from './reqCreateQuotationManagerName';
|
||||
export * from './reqCreateQuotationMemo';
|
||||
export * from './reqCreateQuotationSetting';
|
||||
export * from './reqCreateSupplier';
|
||||
export * from './reqCreateSupplierCode';
|
||||
export * from './reqCreateSupplierManagerContactNumber';
|
||||
export * from './reqCreateSupplierManagerEmail';
|
||||
export * from './reqCreateSupplierManagerName';
|
||||
export * from './reqCreateSupplierPriority';
|
||||
export * from './reqLogin';
|
||||
export * from './reqUpdateCard';
|
||||
export * from './reqUpdateCardCondition';
|
||||
export * from './reqUpdateCardEditScript';
|
||||
export * from './reqUpdateCardMemo';
|
||||
export * from './reqUpdateCardName';
|
||||
export * from './reqUpdateCardNumber';
|
||||
export * from './reqUpdateCardScript';
|
||||
export * from './reqUpdateCardStatus';
|
||||
export * from './reqUpdateItem';
|
||||
export * from './reqUpdateItemCategory';
|
||||
export * from './reqUpdateItemCategoryType';
|
||||
export * from './reqUpdateItemCode';
|
||||
export * from './reqUpdateItemDeliveryFeeYn';
|
||||
export * from './reqUpdateItemDeliveryType';
|
||||
export * from './reqUpdateItemImageUrl';
|
||||
export * from './reqUpdateItemInternetLowestPriceYn';
|
||||
export * from './reqUpdateItemLeadTime';
|
||||
export * from './reqUpdateItemMadeIn';
|
||||
export * from './reqUpdateItemManufacturer';
|
||||
export * from './reqUpdateItemModelName';
|
||||
export * from './reqUpdateItemMoq';
|
||||
export * from './reqUpdateItemName';
|
||||
export * from './reqUpdateItemPrice';
|
||||
export * from './reqUpdateItemQuantityUnit';
|
||||
export * from './reqUpdateItemSpec';
|
||||
export * from './reqUpdateItemVatYn';
|
||||
export * from './reqUpdateQuotationSetting';
|
||||
export * from './reqUpdateQuotationSettingAnchoringValue';
|
||||
export * from './reqUpdateQuotationSettingCardCount';
|
||||
export * from './reqUpdateQuotationSettingTargetMarginRate';
|
||||
export * from './reqUpdateSupplier';
|
||||
export * from './reqUpdateSupplierCode';
|
||||
export * from './reqUpdateSupplierManagerContactNumber';
|
||||
export * from './reqUpdateSupplierManagerEmail';
|
||||
export * from './reqUpdateSupplierManagerName';
|
||||
export * from './reqUpdateSupplierName';
|
||||
export * from './reqUpdateSupplierPriority';
|
||||
export * from './resCard';
|
||||
export * from './resCardCard';
|
||||
export * from './resCardList';
|
||||
export * from './resCardListMsg';
|
||||
export * from './resCardMsg';
|
||||
export * from './resCheckCodes';
|
||||
export * from './resCheckCodesMsg';
|
||||
export * from './resCreateAccount';
|
||||
export * from './resCreateAccountMsg';
|
||||
export * from './resCreateQuotation';
|
||||
export * from './resCreateQuotationAsyncJob';
|
||||
export * from './resCreateQuotationMsg';
|
||||
export * from './resCreateQuotationQuotation';
|
||||
export * from './resDeleteCard';
|
||||
export * from './resDeleteCardMsg';
|
||||
export * from './resDeleteItem';
|
||||
export * from './resDeleteItemMsg';
|
||||
export * from './resDeleteQuotation';
|
||||
export * from './resDeleteQuotationMsg';
|
||||
export * from './resDeleteQuotationSetting';
|
||||
export * from './resDeleteQuotationSettingMsg';
|
||||
export * from './resDeleteSupplier';
|
||||
export * from './resDeleteSupplierMsg';
|
||||
export * from './resEnums';
|
||||
export * from './resEnumsEnums';
|
||||
export * from './resEnumsMsg';
|
||||
export * from './resItem';
|
||||
export * from './resItemCategories';
|
||||
export * from './resItemCategoriesMsg';
|
||||
export * from './resItemImage';
|
||||
export * from './resItemImageFilename';
|
||||
export * from './resItemImageImageUrl';
|
||||
export * from './resItemImageMsg';
|
||||
export * from './resItemImageSize';
|
||||
export * from './resItemItem';
|
||||
export * from './resItemList';
|
||||
export * from './resItemListMsg';
|
||||
export * from './resItemMsg';
|
||||
export * from './resLogin';
|
||||
export * from './resLoginMsg';
|
||||
export * from './resLowestPriceResult';
|
||||
export * from './resLowestPriceResultMsg';
|
||||
export * from './resLowestPriceTrigger';
|
||||
export * from './resLowestPriceTriggerMsg';
|
||||
export * from './resMe';
|
||||
export * from './resMeCompany';
|
||||
export * from './resMeContactNumber';
|
||||
export * from './resMeEmail';
|
||||
export * from './resMeMsg';
|
||||
export * from './resMeName';
|
||||
export * from './resQuotation';
|
||||
export * from './resQuotationCards';
|
||||
export * from './resQuotationCardsMsg';
|
||||
export * from './resQuotationCardsQtId';
|
||||
export * from './resQuotationList';
|
||||
export * from './resQuotationListMsg';
|
||||
export * from './resQuotationMsg';
|
||||
export * from './resQuotationQuotation';
|
||||
export * from './resQuotationResult';
|
||||
export * from './resQuotationResultEqualBidData';
|
||||
export * from './resQuotationResultIsEqualBid';
|
||||
export * from './resQuotationResultMsg';
|
||||
export * from './resQuotationResultQtId';
|
||||
export * from './resQuotationResultWinnerSupplierId';
|
||||
export * from './resQuotationResultWinnerSupplierName';
|
||||
export * from './resQuotationSessions';
|
||||
export * from './resQuotationSessionsMsg';
|
||||
export * from './resQuotationSessionsQtId';
|
||||
export * from './resQuotationSetting';
|
||||
export * from './resQuotationSettingList';
|
||||
export * from './resQuotationSettingListMsg';
|
||||
export * from './resQuotationSettingMsg';
|
||||
export * from './resQuotationSettingSetting';
|
||||
export * from './resQuotationStatus';
|
||||
export * from './resQuotationStatusMsg';
|
||||
export * from './resQuotationStatusQtId';
|
||||
export * from './resRefreshToken';
|
||||
export * from './resRefreshTokenMsg';
|
||||
export * from './resSessionChat';
|
||||
export * from './resSessionChatMsg';
|
||||
export * from './resSessionChatSessionId';
|
||||
export * from './resSupplier';
|
||||
export * from './resSupplierList';
|
||||
export * from './resSupplierListMsg';
|
||||
export * from './resSupplierMsg';
|
||||
export * from './resSupplierSupplier';
|
||||
export * from './sessionData';
|
||||
export * from './sessionDataBidAt';
|
||||
export * from './sessionDataBidPrice';
|
||||
export * from './sessionDataRejectDeliveryType';
|
||||
export * from './sessionDataRejectPrice';
|
||||
export * from './sessionDataRejectReason';
|
||||
export * from './supplierData';
|
||||
export * from './supplierDataCode';
|
||||
export * from './supplierDataCreatedAt';
|
||||
export * from './supplierDataManagerContactNumber';
|
||||
export * from './supplierDataManagerEmail';
|
||||
export * from './supplierDataManagerName';
|
||||
export * from './supplierDataPriority';
|
||||
export * from './supplierDataUpdatedAt';
|
||||
export * from './validationError';
|
||||
export * from './validationErrorCtx';
|
||||
export * from './validationErrorLocItem';
|
||||
@ -4,22 +4,22 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ItemDataCode } from "./itemDataCode";
|
||||
import type { ItemDataCategory } from "./itemDataCategory";
|
||||
import type { ItemDataImageUrl } from "./itemDataImageUrl";
|
||||
import type { ItemDataModelName } from "./itemDataModelName";
|
||||
import type { ItemDataSpec } from "./itemDataSpec";
|
||||
import type { ItemDataManufacturer } from "./itemDataManufacturer";
|
||||
import type { ItemDataMadeIn } from "./itemDataMadeIn";
|
||||
import type { ItemDataPrice } from "./itemDataPrice";
|
||||
import type { ItemDataMoq } from "./itemDataMoq";
|
||||
import type { ItemDataLeadTime } from "./itemDataLeadTime";
|
||||
import type { ItemDataQuantityUnit } from "./itemDataQuantityUnit";
|
||||
import type { ItemDataDeliveryType } from "./itemDataDeliveryType";
|
||||
import type { ItemDataVatYn } from "./itemDataVatYn";
|
||||
import type { ItemDataDeliveryFeeYn } from "./itemDataDeliveryFeeYn";
|
||||
import type { ItemDataCreatedAt } from "./itemDataCreatedAt";
|
||||
import type { ItemDataUpdatedAt } from "./itemDataUpdatedAt";
|
||||
import type { ItemDataCode } from './itemDataCode';
|
||||
import type { ItemDataCategory } from './itemDataCategory';
|
||||
import type { ItemDataImageUrl } from './itemDataImageUrl';
|
||||
import type { ItemDataModelName } from './itemDataModelName';
|
||||
import type { ItemDataSpec } from './itemDataSpec';
|
||||
import type { ItemDataManufacturer } from './itemDataManufacturer';
|
||||
import type { ItemDataMadeIn } from './itemDataMadeIn';
|
||||
import type { ItemDataPrice } from './itemDataPrice';
|
||||
import type { ItemDataMoq } from './itemDataMoq';
|
||||
import type { ItemDataLeadTime } from './itemDataLeadTime';
|
||||
import type { ItemDataQuantityUnit } from './itemDataQuantityUnit';
|
||||
import type { ItemDataDeliveryType } from './itemDataDeliveryType';
|
||||
import type { ItemDataVatYn } from './itemDataVatYn';
|
||||
import type { ItemDataDeliveryFeeYn } from './itemDataDeliveryFeeYn';
|
||||
import type { ItemDataCreatedAt } from './itemDataCreatedAt';
|
||||
import type { ItemDataUpdatedAt } from './itemDataUpdatedAt';
|
||||
|
||||
export interface ItemData {
|
||||
item_id: string;
|
||||
|
||||
@ -6,17 +6,17 @@
|
||||
*/
|
||||
|
||||
export type ListCardsParams = {
|
||||
/**
|
||||
* 카드명/카드번호/스크립트 검색
|
||||
*/
|
||||
search?: string | null;
|
||||
/**
|
||||
* @minimum 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 카드명/카드번호/스크립트 검색
|
||||
*/
|
||||
search?: string | null;
|
||||
/**
|
||||
* @minimum 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
size?: number;
|
||||
};
|
||||
|
||||
@ -6,21 +6,21 @@
|
||||
*/
|
||||
|
||||
export type ListItemsParams = {
|
||||
/**
|
||||
* 상품명/상품코드 검색
|
||||
*/
|
||||
search?: string | null;
|
||||
/**
|
||||
* 카테고리 필터
|
||||
*/
|
||||
category?: string | null;
|
||||
/**
|
||||
* @minimum 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 상품명/상품코드 검색
|
||||
*/
|
||||
search?: string | null;
|
||||
/**
|
||||
* 카테고리 필터
|
||||
*/
|
||||
category?: string | null;
|
||||
/**
|
||||
* @minimum 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
size?: number;
|
||||
};
|
||||
|
||||
@ -6,29 +6,29 @@
|
||||
*/
|
||||
|
||||
export type ListQuotationsParams = {
|
||||
/**
|
||||
* 상태 필터(정확히 일치)
|
||||
*/
|
||||
status?: string | null;
|
||||
/**
|
||||
* 유형 필터(정확히 일치)
|
||||
*/
|
||||
type?: string | null;
|
||||
/**
|
||||
* 시작일시 이후(ISO)
|
||||
*/
|
||||
start_from?: string | null;
|
||||
/**
|
||||
* 시작일시 이전(ISO)
|
||||
*/
|
||||
start_to?: string | null;
|
||||
/**
|
||||
* @minimum 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 상태 필터(정확히 일치)
|
||||
*/
|
||||
status?: string | null;
|
||||
/**
|
||||
* 유형 필터(정확히 일치)
|
||||
*/
|
||||
type?: string | null;
|
||||
/**
|
||||
* 시작일시 이후(ISO)
|
||||
*/
|
||||
start_from?: string | null;
|
||||
/**
|
||||
* 시작일시 이전(ISO)
|
||||
*/
|
||||
start_to?: string | null;
|
||||
/**
|
||||
* @minimum 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
size?: number;
|
||||
};
|
||||
|
||||
@ -6,21 +6,21 @@
|
||||
*/
|
||||
|
||||
export type ListSuppliersParams = {
|
||||
/**
|
||||
* 협력사명/코드/담당자명 검색
|
||||
*/
|
||||
search?: string | null;
|
||||
/**
|
||||
* 우선순위 필터(HIGH/MEDIUM/LOW)
|
||||
*/
|
||||
priority?: string | null;
|
||||
/**
|
||||
* @minimum 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 협력사명/코드/담당자명 검색
|
||||
*/
|
||||
search?: string | null;
|
||||
/**
|
||||
* 우선순위 필터(HIGH/MEDIUM/LOW)
|
||||
*/
|
||||
priority?: string | null;
|
||||
/**
|
||||
* @minimum 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
size?: number;
|
||||
};
|
||||
|
||||
@ -4,12 +4,16 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { QuotationCardDataQtId } from "./quotationCardDataQtId";
|
||||
import type { QuotationCardDataNegoCardId } from "./quotationCardDataNegoCardId";
|
||||
import type { QuotationCardDataWildCardId } from "./quotationCardDataWildCardId";
|
||||
import type { QuotationCardDataType } from "./quotationCardDataType";
|
||||
import type { QuotationCardDataName } from "./quotationCardDataName";
|
||||
import type { QuotationCardDataScript } from "./quotationCardDataScript";
|
||||
import type { QuotationCardDataQtId } from './quotationCardDataQtId';
|
||||
import type { QuotationCardDataNegoCardId } from './quotationCardDataNegoCardId';
|
||||
import type { QuotationCardDataWildCardId } from './quotationCardDataWildCardId';
|
||||
import type { QuotationCardDataType } from './quotationCardDataType';
|
||||
import type { QuotationCardDataNumber } from './quotationCardDataNumber';
|
||||
import type { QuotationCardDataName } from './quotationCardDataName';
|
||||
import type { QuotationCardDataScript } from './quotationCardDataScript';
|
||||
import type { QuotationCardDataEditScript } from './quotationCardDataEditScript';
|
||||
import type { QuotationCardDataCondition } from './quotationCardDataCondition';
|
||||
import type { QuotationCardDataMemo } from './quotationCardDataMemo';
|
||||
|
||||
export interface QuotationCardData {
|
||||
session_card_id: string;
|
||||
@ -17,6 +21,10 @@ export interface QuotationCardData {
|
||||
nego_card_id?: QuotationCardDataNegoCardId;
|
||||
wild_card_id?: QuotationCardDataWildCardId;
|
||||
type?: QuotationCardDataType;
|
||||
number?: QuotationCardDataNumber;
|
||||
name?: QuotationCardDataName;
|
||||
script?: QuotationCardDataScript;
|
||||
edit_script?: QuotationCardDataEditScript;
|
||||
condition?: QuotationCardDataCondition;
|
||||
memo?: QuotationCardDataMemo;
|
||||
}
|
||||
|
||||
@ -5,4 +5,4 @@
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ResExcelUploadReceivedFilename = string | null;
|
||||
export type QuotationCardDataCondition = string | null;
|
||||
@ -5,6 +5,4 @@
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface BodyUploadSuppliersExcelV1SupplierUploadExcelPost {
|
||||
file: string;
|
||||
}
|
||||
export type QuotationCardDataEditScript = unknown | null;
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v7.21.0 🍺
|
||||
* Do not edit manually.
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type QuotationCardDataMemo = string | null;
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v7.21.0 🍺
|
||||
* Do not edit manually.
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type QuotationCardDataNumber = string | null;
|
||||
@ -4,17 +4,17 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { QuotationDataManagerName } from "./quotationDataManagerName";
|
||||
import type { QuotationDataManagerEmail } from "./quotationDataManagerEmail";
|
||||
import type { QuotationDataManagerContactNumber } from "./quotationDataManagerContactNumber";
|
||||
import type { QuotationDataMemo } from "./quotationDataMemo";
|
||||
import type { QuotationDataPreferredSpYn } from "./quotationDataPreferredSpYn";
|
||||
import type { QuotationDataPreferredSpId } from "./quotationDataPreferredSpId";
|
||||
import type { QuotationDataPreferredSpName } from "./quotationDataPreferredSpName";
|
||||
import type { QuotationDataEqualBidYn } from "./quotationDataEqualBidYn";
|
||||
import type { QuotationDataEqualBidData } from "./quotationDataEqualBidData";
|
||||
import type { QuotationDataCreatedAt } from "./quotationDataCreatedAt";
|
||||
import type { QuotationDataUpdatedAt } from "./quotationDataUpdatedAt";
|
||||
import type { QuotationDataManagerName } from './quotationDataManagerName';
|
||||
import type { QuotationDataManagerEmail } from './quotationDataManagerEmail';
|
||||
import type { QuotationDataManagerContactNumber } from './quotationDataManagerContactNumber';
|
||||
import type { QuotationDataMemo } from './quotationDataMemo';
|
||||
import type { QuotationDataPreferredSpYn } from './quotationDataPreferredSpYn';
|
||||
import type { QuotationDataPreferredSpId } from './quotationDataPreferredSpId';
|
||||
import type { QuotationDataPreferredSpName } from './quotationDataPreferredSpName';
|
||||
import type { QuotationDataEqualBidYn } from './quotationDataEqualBidYn';
|
||||
import type { QuotationDataEqualBidData } from './quotationDataEqualBidData';
|
||||
import type { QuotationDataCreatedAt } from './quotationDataCreatedAt';
|
||||
import type { QuotationDataUpdatedAt } from './quotationDataUpdatedAt';
|
||||
|
||||
export interface QuotationData {
|
||||
qt_id: string;
|
||||
@ -38,6 +38,7 @@ export interface QuotationData {
|
||||
preferred_sp_name?: QuotationDataPreferredSpName;
|
||||
equal_bid_yn?: QuotationDataEqualBidYn;
|
||||
equal_bid_data?: QuotationDataEqualBidData;
|
||||
participation_count?: number;
|
||||
created_at?: QuotationDataCreatedAt;
|
||||
updated_at?: QuotationDataUpdatedAt;
|
||||
}
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { QuotationSettingDataUserId } from "./quotationSettingDataUserId";
|
||||
import type { QuotationSettingDataCreatedAt } from "./quotationSettingDataCreatedAt";
|
||||
import type { QuotationSettingDataUpdatedAt } from "./quotationSettingDataUpdatedAt";
|
||||
import type { QuotationSettingDataUserId } from './quotationSettingDataUserId';
|
||||
import type { QuotationSettingDataCreatedAt } from './quotationSettingDataCreatedAt';
|
||||
import type { QuotationSettingDataUpdatedAt } from './quotationSettingDataUpdatedAt';
|
||||
|
||||
export interface QuotationSettingData {
|
||||
qt_setting_id: string;
|
||||
|
||||
@ -4,12 +4,12 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ReqCreateCardName } from "./reqCreateCardName";
|
||||
import type { ReqCreateCardNumber } from "./reqCreateCardNumber";
|
||||
import type { ReqCreateCardScript } from "./reqCreateCardScript";
|
||||
import type { ReqCreateCardEditScript } from "./reqCreateCardEditScript";
|
||||
import type { ReqCreateCardCondition } from "./reqCreateCardCondition";
|
||||
import type { ReqCreateCardMemo } from "./reqCreateCardMemo";
|
||||
import type { ReqCreateCardName } from './reqCreateCardName';
|
||||
import type { ReqCreateCardNumber } from './reqCreateCardNumber';
|
||||
import type { ReqCreateCardScript } from './reqCreateCardScript';
|
||||
import type { ReqCreateCardEditScript } from './reqCreateCardEditScript';
|
||||
import type { ReqCreateCardCondition } from './reqCreateCardCondition';
|
||||
import type { ReqCreateCardMemo } from './reqCreateCardMemo';
|
||||
|
||||
export interface ReqCreateCard {
|
||||
is_wildcard?: boolean;
|
||||
|
||||
@ -4,20 +4,20 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ReqCreateItemCode } from "./reqCreateItemCode";
|
||||
import type { ReqCreateItemCategory } from "./reqCreateItemCategory";
|
||||
import type { ReqCreateItemImageUrl } from "./reqCreateItemImageUrl";
|
||||
import type { ReqCreateItemModelName } from "./reqCreateItemModelName";
|
||||
import type { ReqCreateItemSpec } from "./reqCreateItemSpec";
|
||||
import type { ReqCreateItemManufacturer } from "./reqCreateItemManufacturer";
|
||||
import type { ReqCreateItemMadeIn } from "./reqCreateItemMadeIn";
|
||||
import type { ReqCreateItemPrice } from "./reqCreateItemPrice";
|
||||
import type { ReqCreateItemMoq } from "./reqCreateItemMoq";
|
||||
import type { ReqCreateItemLeadTime } from "./reqCreateItemLeadTime";
|
||||
import type { ReqCreateItemQuantityUnit } from "./reqCreateItemQuantityUnit";
|
||||
import type { ReqCreateItemDeliveryType } from "./reqCreateItemDeliveryType";
|
||||
import type { ReqCreateItemVatYn } from "./reqCreateItemVatYn";
|
||||
import type { ReqCreateItemDeliveryFeeYn } from "./reqCreateItemDeliveryFeeYn";
|
||||
import type { ReqCreateItemCode } from './reqCreateItemCode';
|
||||
import type { ReqCreateItemCategory } from './reqCreateItemCategory';
|
||||
import type { ReqCreateItemImageUrl } from './reqCreateItemImageUrl';
|
||||
import type { ReqCreateItemModelName } from './reqCreateItemModelName';
|
||||
import type { ReqCreateItemSpec } from './reqCreateItemSpec';
|
||||
import type { ReqCreateItemManufacturer } from './reqCreateItemManufacturer';
|
||||
import type { ReqCreateItemMadeIn } from './reqCreateItemMadeIn';
|
||||
import type { ReqCreateItemPrice } from './reqCreateItemPrice';
|
||||
import type { ReqCreateItemMoq } from './reqCreateItemMoq';
|
||||
import type { ReqCreateItemLeadTime } from './reqCreateItemLeadTime';
|
||||
import type { ReqCreateItemQuantityUnit } from './reqCreateItemQuantityUnit';
|
||||
import type { ReqCreateItemDeliveryType } from './reqCreateItemDeliveryType';
|
||||
import type { ReqCreateItemVatYn } from './reqCreateItemVatYn';
|
||||
import type { ReqCreateItemDeliveryFeeYn } from './reqCreateItemDeliveryFeeYn';
|
||||
|
||||
export interface ReqCreateItem {
|
||||
name?: string;
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ReqCreateQuotationManagerName } from "./reqCreateQuotationManagerName";
|
||||
import type { ReqCreateQuotationManagerEmail } from "./reqCreateQuotationManagerEmail";
|
||||
import type { ReqCreateQuotationManagerContactNumber } from "./reqCreateQuotationManagerContactNumber";
|
||||
import type { ReqCreateQuotationMemo } from "./reqCreateQuotationMemo";
|
||||
import type { ReqCreateQuotationManagerName } from './reqCreateQuotationManagerName';
|
||||
import type { ReqCreateQuotationManagerEmail } from './reqCreateQuotationManagerEmail';
|
||||
import type { ReqCreateQuotationManagerContactNumber } from './reqCreateQuotationManagerContactNumber';
|
||||
import type { ReqCreateQuotationMemo } from './reqCreateQuotationMemo';
|
||||
|
||||
export interface ReqCreateQuotation {
|
||||
qt_setting_id: string;
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ReqCreateSupplierCode } from "./reqCreateSupplierCode";
|
||||
import type { ReqCreateSupplierManagerName } from "./reqCreateSupplierManagerName";
|
||||
import type { ReqCreateSupplierManagerEmail } from "./reqCreateSupplierManagerEmail";
|
||||
import type { ReqCreateSupplierManagerContactNumber } from "./reqCreateSupplierManagerContactNumber";
|
||||
import type { ReqCreateSupplierPriority } from "./reqCreateSupplierPriority";
|
||||
import type { ReqCreateSupplierCode } from './reqCreateSupplierCode';
|
||||
import type { ReqCreateSupplierManagerName } from './reqCreateSupplierManagerName';
|
||||
import type { ReqCreateSupplierManagerEmail } from './reqCreateSupplierManagerEmail';
|
||||
import type { ReqCreateSupplierManagerContactNumber } from './reqCreateSupplierManagerContactNumber';
|
||||
import type { ReqCreateSupplierPriority } from './reqCreateSupplierPriority';
|
||||
|
||||
export interface ReqCreateSupplier {
|
||||
name?: string;
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ReqUpdateCardName } from "./reqUpdateCardName";
|
||||
import type { ReqUpdateCardNumber } from "./reqUpdateCardNumber";
|
||||
import type { ReqUpdateCardScript } from "./reqUpdateCardScript";
|
||||
import type { ReqUpdateCardEditScript } from "./reqUpdateCardEditScript";
|
||||
import type { ReqUpdateCardStatus } from "./reqUpdateCardStatus";
|
||||
import type { ReqUpdateCardCondition } from "./reqUpdateCardCondition";
|
||||
import type { ReqUpdateCardMemo } from "./reqUpdateCardMemo";
|
||||
import type { ReqUpdateCardName } from './reqUpdateCardName';
|
||||
import type { ReqUpdateCardNumber } from './reqUpdateCardNumber';
|
||||
import type { ReqUpdateCardScript } from './reqUpdateCardScript';
|
||||
import type { ReqUpdateCardEditScript } from './reqUpdateCardEditScript';
|
||||
import type { ReqUpdateCardStatus } from './reqUpdateCardStatus';
|
||||
import type { ReqUpdateCardCondition } from './reqUpdateCardCondition';
|
||||
import type { ReqUpdateCardMemo } from './reqUpdateCardMemo';
|
||||
|
||||
export interface ReqUpdateCard {
|
||||
name?: ReqUpdateCardName;
|
||||
|
||||
@ -4,23 +4,23 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ReqUpdateItemName } from "./reqUpdateItemName";
|
||||
import type { ReqUpdateItemCode } from "./reqUpdateItemCode";
|
||||
import type { ReqUpdateItemCategory } from "./reqUpdateItemCategory";
|
||||
import type { ReqUpdateItemCategoryType } from "./reqUpdateItemCategoryType";
|
||||
import type { ReqUpdateItemImageUrl } from "./reqUpdateItemImageUrl";
|
||||
import type { ReqUpdateItemModelName } from "./reqUpdateItemModelName";
|
||||
import type { ReqUpdateItemSpec } from "./reqUpdateItemSpec";
|
||||
import type { ReqUpdateItemManufacturer } from "./reqUpdateItemManufacturer";
|
||||
import type { ReqUpdateItemMadeIn } from "./reqUpdateItemMadeIn";
|
||||
import type { ReqUpdateItemPrice } from "./reqUpdateItemPrice";
|
||||
import type { ReqUpdateItemInternetLowestPriceYn } from "./reqUpdateItemInternetLowestPriceYn";
|
||||
import type { ReqUpdateItemMoq } from "./reqUpdateItemMoq";
|
||||
import type { ReqUpdateItemLeadTime } from "./reqUpdateItemLeadTime";
|
||||
import type { ReqUpdateItemQuantityUnit } from "./reqUpdateItemQuantityUnit";
|
||||
import type { ReqUpdateItemDeliveryType } from "./reqUpdateItemDeliveryType";
|
||||
import type { ReqUpdateItemVatYn } from "./reqUpdateItemVatYn";
|
||||
import type { ReqUpdateItemDeliveryFeeYn } from "./reqUpdateItemDeliveryFeeYn";
|
||||
import type { ReqUpdateItemName } from './reqUpdateItemName';
|
||||
import type { ReqUpdateItemCode } from './reqUpdateItemCode';
|
||||
import type { ReqUpdateItemCategory } from './reqUpdateItemCategory';
|
||||
import type { ReqUpdateItemCategoryType } from './reqUpdateItemCategoryType';
|
||||
import type { ReqUpdateItemImageUrl } from './reqUpdateItemImageUrl';
|
||||
import type { ReqUpdateItemModelName } from './reqUpdateItemModelName';
|
||||
import type { ReqUpdateItemSpec } from './reqUpdateItemSpec';
|
||||
import type { ReqUpdateItemManufacturer } from './reqUpdateItemManufacturer';
|
||||
import type { ReqUpdateItemMadeIn } from './reqUpdateItemMadeIn';
|
||||
import type { ReqUpdateItemPrice } from './reqUpdateItemPrice';
|
||||
import type { ReqUpdateItemInternetLowestPriceYn } from './reqUpdateItemInternetLowestPriceYn';
|
||||
import type { ReqUpdateItemMoq } from './reqUpdateItemMoq';
|
||||
import type { ReqUpdateItemLeadTime } from './reqUpdateItemLeadTime';
|
||||
import type { ReqUpdateItemQuantityUnit } from './reqUpdateItemQuantityUnit';
|
||||
import type { ReqUpdateItemDeliveryType } from './reqUpdateItemDeliveryType';
|
||||
import type { ReqUpdateItemVatYn } from './reqUpdateItemVatYn';
|
||||
import type { ReqUpdateItemDeliveryFeeYn } from './reqUpdateItemDeliveryFeeYn';
|
||||
|
||||
export interface ReqUpdateItem {
|
||||
name?: ReqUpdateItemName;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ReqUpdateQuotationSettingTargetMarginRate } from "./reqUpdateQuotationSettingTargetMarginRate";
|
||||
import type { ReqUpdateQuotationSettingAnchoringValue } from "./reqUpdateQuotationSettingAnchoringValue";
|
||||
import type { ReqUpdateQuotationSettingCardCount } from "./reqUpdateQuotationSettingCardCount";
|
||||
import type { ReqUpdateQuotationSettingTargetMarginRate } from './reqUpdateQuotationSettingTargetMarginRate';
|
||||
import type { ReqUpdateQuotationSettingAnchoringValue } from './reqUpdateQuotationSettingAnchoringValue';
|
||||
import type { ReqUpdateQuotationSettingCardCount } from './reqUpdateQuotationSettingCardCount';
|
||||
|
||||
export interface ReqUpdateQuotationSetting {
|
||||
target_margin_rate?: ReqUpdateQuotationSettingTargetMarginRate;
|
||||
|
||||
@ -4,12 +4,12 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ReqUpdateSupplierName } from "./reqUpdateSupplierName";
|
||||
import type { ReqUpdateSupplierCode } from "./reqUpdateSupplierCode";
|
||||
import type { ReqUpdateSupplierManagerName } from "./reqUpdateSupplierManagerName";
|
||||
import type { ReqUpdateSupplierManagerEmail } from "./reqUpdateSupplierManagerEmail";
|
||||
import type { ReqUpdateSupplierManagerContactNumber } from "./reqUpdateSupplierManagerContactNumber";
|
||||
import type { ReqUpdateSupplierPriority } from "./reqUpdateSupplierPriority";
|
||||
import type { ReqUpdateSupplierName } from './reqUpdateSupplierName';
|
||||
import type { ReqUpdateSupplierCode } from './reqUpdateSupplierCode';
|
||||
import type { ReqUpdateSupplierManagerName } from './reqUpdateSupplierManagerName';
|
||||
import type { ReqUpdateSupplierManagerEmail } from './reqUpdateSupplierManagerEmail';
|
||||
import type { ReqUpdateSupplierManagerContactNumber } from './reqUpdateSupplierManagerContactNumber';
|
||||
import type { ReqUpdateSupplierPriority } from './reqUpdateSupplierPriority';
|
||||
|
||||
export interface ReqUpdateSupplier {
|
||||
name?: ReqUpdateSupplierName;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResCardMsg } from "./resCardMsg";
|
||||
import type { ResCardCard } from "./resCardCard";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResCardMsg } from './resCardMsg';
|
||||
import type { ResCardCard } from './resCardCard';
|
||||
|
||||
export interface ResCard {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { CardData } from "./cardData";
|
||||
import type { CardData } from './cardData';
|
||||
|
||||
export type ResCardCard = CardData | null;
|
||||
|
||||
@ -4,15 +4,15 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResCardListMsg } from "./resCardListMsg";
|
||||
import type { CardData } from "./cardData";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResCardListMsg } from './resCardListMsg';
|
||||
import type { CardData } from './cardData';
|
||||
|
||||
export interface ResCardList {
|
||||
result?: ErrorInfo;
|
||||
msg?: ResCardListMsg;
|
||||
cards?: CardData[];
|
||||
total?: number;
|
||||
page?: number;
|
||||
size?: number;
|
||||
cards?: CardData[];
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResCheckCodesMsg } from "./resCheckCodesMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResCheckCodesMsg } from './resCheckCodesMsg';
|
||||
|
||||
export interface ResCheckCodes {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResCreateAccountMsg } from "./resCreateAccountMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResCreateAccountMsg } from './resCreateAccountMsg';
|
||||
|
||||
export interface ResCreateAccount {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResCreateQuotationMsg } from "./resCreateQuotationMsg";
|
||||
import type { ResCreateQuotationQuotation } from "./resCreateQuotationQuotation";
|
||||
import type { ResCreateQuotationAsyncJob } from "./resCreateQuotationAsyncJob";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResCreateQuotationMsg } from './resCreateQuotationMsg';
|
||||
import type { ResCreateQuotationQuotation } from './resCreateQuotationQuotation';
|
||||
import type { ResCreateQuotationAsyncJob } from './resCreateQuotationAsyncJob';
|
||||
|
||||
export interface ResCreateQuotation {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { AsyncJob } from "./asyncJob";
|
||||
import type { AsyncJob } from './asyncJob';
|
||||
|
||||
export type ResCreateQuotationAsyncJob = AsyncJob | null;
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { QuotationData } from "./quotationData";
|
||||
import type { QuotationData } from './quotationData';
|
||||
|
||||
export type ResCreateQuotationQuotation = QuotationData | null;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResDeleteCardMsg } from "./resDeleteCardMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResDeleteCardMsg } from './resDeleteCardMsg';
|
||||
|
||||
export interface ResDeleteCard {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResDeleteItemMsg } from "./resDeleteItemMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResDeleteItemMsg } from './resDeleteItemMsg';
|
||||
|
||||
export interface ResDeleteItem {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResDeleteQuotationMsg } from "./resDeleteQuotationMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResDeleteQuotationMsg } from './resDeleteQuotationMsg';
|
||||
|
||||
export interface ResDeleteQuotation {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResDeleteQuotationSettingMsg } from "./resDeleteQuotationSettingMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResDeleteQuotationSettingMsg } from './resDeleteQuotationSettingMsg';
|
||||
|
||||
export interface ResDeleteQuotationSetting {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResDeleteSupplierMsg } from "./resDeleteSupplierMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResDeleteSupplierMsg } from './resDeleteSupplierMsg';
|
||||
|
||||
export interface ResDeleteSupplier {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResEnumsMsg } from "./resEnumsMsg";
|
||||
import type { ResEnumsEnums } from "./resEnumsEnums";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResEnumsMsg } from './resEnumsMsg';
|
||||
import type { ResEnumsEnums } from './resEnumsEnums';
|
||||
|
||||
export interface ResEnums {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { EnumOption } from "./enumOption";
|
||||
import type { EnumOption } from './enumOption';
|
||||
|
||||
export type ResEnumsEnums = { [key: string]: EnumOption[] };
|
||||
export type ResEnumsEnums = {[key: string]: EnumOption[]};
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
/**
|
||||
* Generated by orval v7.21.0 🍺
|
||||
* Do not edit manually.
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResExcelUploadMsg } from "./resExcelUploadMsg";
|
||||
import type { ResExcelUploadReceivedFilename } from "./resExcelUploadReceivedFilename";
|
||||
|
||||
export interface ResExcelUpload {
|
||||
result?: ErrorInfo;
|
||||
msg?: ResExcelUploadMsg;
|
||||
received_filename?: ResExcelUploadReceivedFilename;
|
||||
status?: string;
|
||||
message?: string;
|
||||
}
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResItemMsg } from "./resItemMsg";
|
||||
import type { ResItemItem } from "./resItemItem";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResItemMsg } from './resItemMsg';
|
||||
import type { ResItemItem } from './resItemItem';
|
||||
|
||||
export interface ResItem {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResItemCategoriesMsg } from "./resItemCategoriesMsg";
|
||||
import type { ItemCategory } from "./itemCategory";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResItemCategoriesMsg } from './resItemCategoriesMsg';
|
||||
import type { ItemCategory } from './itemCategory';
|
||||
|
||||
export interface ResItemCategories {
|
||||
result?: ErrorInfo;
|
||||
|
||||
19
negodata/front/src/api/generated/model/resItemImage.ts
Normal file
19
negodata/front/src/api/generated/model/resItemImage.ts
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Generated by orval v7.21.0 🍺
|
||||
* Do not edit manually.
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResItemImageMsg } from './resItemImageMsg';
|
||||
import type { ResItemImageImageUrl } from './resItemImageImageUrl';
|
||||
import type { ResItemImageFilename } from './resItemImageFilename';
|
||||
import type { ResItemImageSize } from './resItemImageSize';
|
||||
|
||||
export interface ResItemImage {
|
||||
result?: ErrorInfo;
|
||||
msg?: ResItemImageMsg;
|
||||
image_url?: ResItemImageImageUrl;
|
||||
filename?: ResItemImageFilename;
|
||||
size?: ResItemImageSize;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v7.21.0 🍺
|
||||
* Do not edit manually.
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ResItemImageFilename = string | null;
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v7.21.0 🍺
|
||||
* Do not edit manually.
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ResItemImageImageUrl = string | null;
|
||||
@ -5,4 +5,4 @@
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ResExcelUploadMsg = string | null;
|
||||
export type ResItemImageMsg = string | null;
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v7.21.0 🍺
|
||||
* Do not edit manually.
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ResItemImageSize = number | null;
|
||||
@ -4,6 +4,6 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ItemData } from "./itemData";
|
||||
import type { ItemData } from './itemData';
|
||||
|
||||
export type ResItemItem = ItemData | null;
|
||||
|
||||
@ -4,15 +4,15 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResItemListMsg } from "./resItemListMsg";
|
||||
import type { ItemData } from "./itemData";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResItemListMsg } from './resItemListMsg';
|
||||
import type { ItemData } from './itemData';
|
||||
|
||||
export interface ResItemList {
|
||||
result?: ErrorInfo;
|
||||
msg?: ResItemListMsg;
|
||||
items?: ItemData[];
|
||||
total?: number;
|
||||
page?: number;
|
||||
size?: number;
|
||||
items?: ItemData[];
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResLoginMsg } from "./resLoginMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResLoginMsg } from './resLoginMsg';
|
||||
|
||||
export interface ResLogin {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResLowestPriceResultMsg } from "./resLowestPriceResultMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResLowestPriceResultMsg } from './resLowestPriceResultMsg';
|
||||
|
||||
export interface ResLowestPriceResult {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResLowestPriceTriggerMsg } from "./resLowestPriceTriggerMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResLowestPriceTriggerMsg } from './resLowestPriceTriggerMsg';
|
||||
|
||||
export interface ResLowestPriceTrigger {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,12 +4,12 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResMeMsg } from "./resMeMsg";
|
||||
import type { ResMeName } from "./resMeName";
|
||||
import type { ResMeEmail } from "./resMeEmail";
|
||||
import type { ResMeContactNumber } from "./resMeContactNumber";
|
||||
import type { ResMeCompany } from "./resMeCompany";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResMeMsg } from './resMeMsg';
|
||||
import type { ResMeName } from './resMeName';
|
||||
import type { ResMeEmail } from './resMeEmail';
|
||||
import type { ResMeContactNumber } from './resMeContactNumber';
|
||||
import type { ResMeCompany } from './resMeCompany';
|
||||
|
||||
export interface ResMe {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { CompanyData } from "./companyData";
|
||||
import type { CompanyData } from './companyData';
|
||||
|
||||
export type ResMeCompany = CompanyData | null;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResQuotationMsg } from "./resQuotationMsg";
|
||||
import type { ResQuotationQuotation } from "./resQuotationQuotation";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResQuotationMsg } from './resQuotationMsg';
|
||||
import type { ResQuotationQuotation } from './resQuotationQuotation';
|
||||
|
||||
export interface ResQuotation {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResQuotationCardsMsg } from "./resQuotationCardsMsg";
|
||||
import type { ResQuotationCardsQtId } from "./resQuotationCardsQtId";
|
||||
import type { QuotationCardData } from "./quotationCardData";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResQuotationCardsMsg } from './resQuotationCardsMsg';
|
||||
import type { ResQuotationCardsQtId } from './resQuotationCardsQtId';
|
||||
import type { QuotationCardData } from './quotationCardData';
|
||||
|
||||
export interface ResQuotationCards {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,15 +4,15 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResQuotationListMsg } from "./resQuotationListMsg";
|
||||
import type { QuotationData } from "./quotationData";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResQuotationListMsg } from './resQuotationListMsg';
|
||||
import type { QuotationData } from './quotationData';
|
||||
|
||||
export interface ResQuotationList {
|
||||
result?: ErrorInfo;
|
||||
msg?: ResQuotationListMsg;
|
||||
quotations?: QuotationData[];
|
||||
total?: number;
|
||||
page?: number;
|
||||
size?: number;
|
||||
quotations?: QuotationData[];
|
||||
}
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { QuotationData } from "./quotationData";
|
||||
import type { QuotationData } from './quotationData';
|
||||
|
||||
export type ResQuotationQuotation = QuotationData | null;
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResQuotationResultMsg } from "./resQuotationResultMsg";
|
||||
import type { ResQuotationResultQtId } from "./resQuotationResultQtId";
|
||||
import type { ResQuotationResultWinnerSupplierId } from "./resQuotationResultWinnerSupplierId";
|
||||
import type { ResQuotationResultWinnerSupplierName } from "./resQuotationResultWinnerSupplierName";
|
||||
import type { ResQuotationResultIsEqualBid } from "./resQuotationResultIsEqualBid";
|
||||
import type { ResQuotationResultEqualBidData } from "./resQuotationResultEqualBidData";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResQuotationResultMsg } from './resQuotationResultMsg';
|
||||
import type { ResQuotationResultQtId } from './resQuotationResultQtId';
|
||||
import type { ResQuotationResultWinnerSupplierId } from './resQuotationResultWinnerSupplierId';
|
||||
import type { ResQuotationResultWinnerSupplierName } from './resQuotationResultWinnerSupplierName';
|
||||
import type { ResQuotationResultIsEqualBid } from './resQuotationResultIsEqualBid';
|
||||
import type { ResQuotationResultEqualBidData } from './resQuotationResultEqualBidData';
|
||||
|
||||
export interface ResQuotationResult {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResQuotationSessionsMsg } from "./resQuotationSessionsMsg";
|
||||
import type { ResQuotationSessionsQtId } from "./resQuotationSessionsQtId";
|
||||
import type { SessionData } from "./sessionData";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResQuotationSessionsMsg } from './resQuotationSessionsMsg';
|
||||
import type { ResQuotationSessionsQtId } from './resQuotationSessionsQtId';
|
||||
import type { SessionData } from './sessionData';
|
||||
|
||||
export interface ResQuotationSessions {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResQuotationSettingMsg } from "./resQuotationSettingMsg";
|
||||
import type { ResQuotationSettingSetting } from "./resQuotationSettingSetting";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResQuotationSettingMsg } from './resQuotationSettingMsg';
|
||||
import type { ResQuotationSettingSetting } from './resQuotationSettingSetting';
|
||||
|
||||
export interface ResQuotationSetting {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResQuotationSettingListMsg } from "./resQuotationSettingListMsg";
|
||||
import type { QuotationSettingData } from "./quotationSettingData";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResQuotationSettingListMsg } from './resQuotationSettingListMsg';
|
||||
import type { QuotationSettingData } from './quotationSettingData';
|
||||
|
||||
export interface ResQuotationSettingList {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { QuotationSettingData } from "./quotationSettingData";
|
||||
import type { QuotationSettingData } from './quotationSettingData';
|
||||
|
||||
export type ResQuotationSettingSetting = QuotationSettingData | null;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResQuotationStatusMsg } from "./resQuotationStatusMsg";
|
||||
import type { ResQuotationStatusQtId } from "./resQuotationStatusQtId";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResQuotationStatusMsg } from './resQuotationStatusMsg';
|
||||
import type { ResQuotationStatusQtId } from './resQuotationStatusQtId';
|
||||
|
||||
export interface ResQuotationStatus {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResRefreshTokenMsg } from "./resRefreshTokenMsg";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResRefreshTokenMsg } from './resRefreshTokenMsg';
|
||||
|
||||
export interface ResRefreshToken {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResSessionChatMsg } from "./resSessionChatMsg";
|
||||
import type { ResSessionChatSessionId } from "./resSessionChatSessionId";
|
||||
import type { ChatMessageData } from "./chatMessageData";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResSessionChatMsg } from './resSessionChatMsg';
|
||||
import type { ResSessionChatSessionId } from './resSessionChatSessionId';
|
||||
import type { ChatMessageData } from './chatMessageData';
|
||||
|
||||
export interface ResSessionChat {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResSupplierMsg } from "./resSupplierMsg";
|
||||
import type { ResSupplierSupplier } from "./resSupplierSupplier";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResSupplierMsg } from './resSupplierMsg';
|
||||
import type { ResSupplierSupplier } from './resSupplierSupplier';
|
||||
|
||||
export interface ResSupplier {
|
||||
result?: ErrorInfo;
|
||||
|
||||
@ -4,15 +4,15 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ErrorInfo } from "./errorInfo";
|
||||
import type { ResSupplierListMsg } from "./resSupplierListMsg";
|
||||
import type { SupplierData } from "./supplierData";
|
||||
import type { ErrorInfo } from './errorInfo';
|
||||
import type { ResSupplierListMsg } from './resSupplierListMsg';
|
||||
import type { SupplierData } from './supplierData';
|
||||
|
||||
export interface ResSupplierList {
|
||||
result?: ErrorInfo;
|
||||
msg?: ResSupplierListMsg;
|
||||
suppliers?: SupplierData[];
|
||||
total?: number;
|
||||
page?: number;
|
||||
size?: number;
|
||||
suppliers?: SupplierData[];
|
||||
}
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { SupplierData } from "./supplierData";
|
||||
import type { SupplierData } from './supplierData';
|
||||
|
||||
export type ResSupplierSupplier = SupplierData | null;
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { SessionDataBidPrice } from "./sessionDataBidPrice";
|
||||
import type { SessionDataBidAt } from "./sessionDataBidAt";
|
||||
import type { SessionDataRejectReason } from "./sessionDataRejectReason";
|
||||
import type { SessionDataRejectPrice } from "./sessionDataRejectPrice";
|
||||
import type { SessionDataRejectDeliveryType } from "./sessionDataRejectDeliveryType";
|
||||
import type { SessionDataBidPrice } from './sessionDataBidPrice';
|
||||
import type { SessionDataBidAt } from './sessionDataBidAt';
|
||||
import type { SessionDataRejectReason } from './sessionDataRejectReason';
|
||||
import type { SessionDataRejectPrice } from './sessionDataRejectPrice';
|
||||
import type { SessionDataRejectDeliveryType } from './sessionDataRejectDeliveryType';
|
||||
|
||||
export interface SessionData {
|
||||
session_id: string;
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { SupplierDataCode } from "./supplierDataCode";
|
||||
import type { SupplierDataManagerName } from "./supplierDataManagerName";
|
||||
import type { SupplierDataManagerEmail } from "./supplierDataManagerEmail";
|
||||
import type { SupplierDataManagerContactNumber } from "./supplierDataManagerContactNumber";
|
||||
import type { SupplierDataPriority } from "./supplierDataPriority";
|
||||
import type { SupplierDataCreatedAt } from "./supplierDataCreatedAt";
|
||||
import type { SupplierDataUpdatedAt } from "./supplierDataUpdatedAt";
|
||||
import type { SupplierDataCode } from './supplierDataCode';
|
||||
import type { SupplierDataManagerName } from './supplierDataManagerName';
|
||||
import type { SupplierDataManagerEmail } from './supplierDataManagerEmail';
|
||||
import type { SupplierDataManagerContactNumber } from './supplierDataManagerContactNumber';
|
||||
import type { SupplierDataPriority } from './supplierDataPriority';
|
||||
import type { SupplierDataCreatedAt } from './supplierDataCreatedAt';
|
||||
import type { SupplierDataUpdatedAt } from './supplierDataUpdatedAt';
|
||||
|
||||
export interface SupplierData {
|
||||
supplier_id: string;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ValidationErrorLocItem } from "./validationErrorLocItem";
|
||||
import type { ValidationErrorCtx } from "./validationErrorCtx";
|
||||
import type { ValidationErrorLocItem } from './validationErrorLocItem';
|
||||
import type { ValidationErrorCtx } from './validationErrorCtx';
|
||||
|
||||
export interface ValidationError {
|
||||
loc: ValidationErrorLocItem[];
|
||||
|
||||
@ -4,7 +4,10 @@
|
||||
* Negodata Api Server
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
useMutation,
|
||||
useQuery
|
||||
} from '@tanstack/react-query';
|
||||
import type {
|
||||
DataTag,
|
||||
DefinedInitialDataOptions,
|
||||
@ -17,8 +20,8 @@ import type {
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
UseQueryResult
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
import type {
|
||||
HTTPValidationError,
|
||||
@ -26,383 +29,295 @@ import type {
|
||||
ReqUpdateQuotationSetting,
|
||||
ResDeleteQuotationSetting,
|
||||
ResQuotationSetting,
|
||||
ResQuotationSettingList,
|
||||
} from ".././model";
|
||||
ResQuotationSettingList
|
||||
} from '.././model';
|
||||
|
||||
import { customFetch } from '../../mutator/custom-fetch';
|
||||
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
|
||||
import { customFetch } from "../../mutator/custom-fetch";
|
||||
|
||||
/**
|
||||
* @summary 견적 설정 목록
|
||||
*/
|
||||
export const listSettings = (signal?: AbortSignal) => {
|
||||
return customFetch<ResQuotationSettingList>({
|
||||
url: `/v1/quotation-setting/list`,
|
||||
method: "GET",
|
||||
signal,
|
||||
});
|
||||
};
|
||||
export const listSettings = (
|
||||
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
|
||||
|
||||
return customFetch<ResQuotationSettingList>(
|
||||
{url: `/v1/quotation-setting/list`, method: 'GET', signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const getListSettingsQueryKey = () => {
|
||||
return [`/v1/quotation-setting/list`] as const;
|
||||
};
|
||||
return [
|
||||
`/v1/quotation-setting/list`
|
||||
] as const;
|
||||
}
|
||||
|
||||
export const getListSettingsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listSettings>>,
|
||||
TError = void,
|
||||
>(options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>
|
||||
>;
|
||||
}) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
export const getListSettingsQueryOptions = <TData = Awaited<ReturnType<typeof listSettings>>, TError = void>( options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
) => {
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getListSettingsQueryKey();
|
||||
const {query: queryOptions, request: requestOptions} = options ?? {};
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listSettings>>> = ({
|
||||
signal,
|
||||
}) => listSettings(signal);
|
||||
const queryKey = queryOptions?.queryKey ?? getListSettingsQueryKey();
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listSettings>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
|
||||
export type ListSettingsQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listSettings>>
|
||||
>;
|
||||
export type ListSettingsQueryError = void;
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listSettings>>> = ({ signal }) => listSettings(requestOptions, signal);
|
||||
|
||||
export function useListSettings<
|
||||
TData = Awaited<ReturnType<typeof listSettings>>,
|
||||
TError = void,
|
||||
>(
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
|
||||
|
||||
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
}
|
||||
|
||||
export type ListSettingsQueryResult = NonNullable<Awaited<ReturnType<typeof listSettings>>>
|
||||
export type ListSettingsQueryError = void
|
||||
|
||||
|
||||
export function useListSettings<TData = Awaited<ReturnType<typeof listSettings>>, TError = void>(
|
||||
options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>> & Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listSettings>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listSettings>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListSettings<
|
||||
TData = Awaited<ReturnType<typeof listSettings>>,
|
||||
TError = void,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>
|
||||
> &
|
||||
Pick<
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useListSettings<TData = Awaited<ReturnType<typeof listSettings>>, TError = void>(
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>> & Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listSettings>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listSettings>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListSettings<
|
||||
TData = Awaited<ReturnType<typeof listSettings>>,
|
||||
TError = void,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
> , 'initialData'
|
||||
>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
export function useListSettings<TData = Awaited<ReturnType<typeof listSettings>>, TError = void>(
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
|
||||
/**
|
||||
* @summary 견적 설정 목록
|
||||
*/
|
||||
|
||||
export function useListSettings<
|
||||
TData = Awaited<ReturnType<typeof listSettings>>,
|
||||
TError = void,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getListSettingsQueryOptions(options);
|
||||
export function useListSettings<TData = Awaited<ReturnType<typeof listSettings>>, TError = void>(
|
||||
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listSettings>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient
|
||||
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
const queryOptions = getListSettingsQueryOptions(options)
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
query.queryKey = queryOptions.queryKey ;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @summary 견적 설정 등록
|
||||
*/
|
||||
export const createSetting = (
|
||||
reqCreateQuotationSetting: ReqCreateQuotationSetting,
|
||||
signal?: AbortSignal,
|
||||
reqCreateQuotationSetting: ReqCreateQuotationSetting,
|
||||
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
|
||||
) => {
|
||||
return customFetch<ResQuotationSetting>({
|
||||
url: `/v1/quotation-setting/create`,
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
data: reqCreateQuotationSetting,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return customFetch<ResQuotationSetting>(
|
||||
{url: `/v1/quotation-setting/create`, method: 'POST',
|
||||
headers: {'Content-Type': 'application/json', },
|
||||
data: reqCreateQuotationSetting, signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
export const getCreateSettingMutationOptions = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSetting>>,
|
||||
TError,
|
||||
{ data: ReqCreateQuotationSetting },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSetting>>,
|
||||
TError,
|
||||
{ data: ReqCreateQuotationSetting },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["createSetting"];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
"mutationKey" in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof createSetting>>,
|
||||
{ data: ReqCreateQuotationSetting }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
export const getCreateSettingMutationOptions = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof createSetting>>, TError,{data: ReqCreateQuotationSetting}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof createSetting>>, TError,{data: ReqCreateQuotationSetting}, TContext> => {
|
||||
|
||||
return createSetting(data);
|
||||
};
|
||||
const mutationKey = ['createSetting'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
|
||||
export type CreateSettingMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createSetting>>
|
||||
>;
|
||||
export type CreateSettingMutationBody = ReqCreateQuotationSetting;
|
||||
export type CreateSettingMutationError = void | HTTPValidationError;
|
||||
|
||||
/**
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof createSetting>>, {data: ReqCreateQuotationSetting}> = (props) => {
|
||||
const {data} = props ?? {};
|
||||
|
||||
return createSetting(data,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type CreateSettingMutationResult = NonNullable<Awaited<ReturnType<typeof createSetting>>>
|
||||
export type CreateSettingMutationBody = ReqCreateQuotationSetting
|
||||
export type CreateSettingMutationError = void | HTTPValidationError
|
||||
|
||||
/**
|
||||
* @summary 견적 설정 등록
|
||||
*/
|
||||
export const useCreateSetting = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSetting>>,
|
||||
TError,
|
||||
{ data: ReqCreateQuotationSetting },
|
||||
TContext
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createSetting>>,
|
||||
TError,
|
||||
{ data: ReqCreateQuotationSetting },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getCreateSettingMutationOptions(options);
|
||||
export const useCreateSetting = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof createSetting>>, TError,{data: ReqCreateQuotationSetting}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createSetting>>,
|
||||
TError,
|
||||
{data: ReqCreateQuotationSetting},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
};
|
||||
/**
|
||||
const mutationOptions = getCreateSettingMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
/**
|
||||
* @summary 견적 설정 수정
|
||||
*/
|
||||
export const updateSetting = (
|
||||
qtSettingId: string,
|
||||
reqUpdateQuotationSetting: ReqUpdateQuotationSetting,
|
||||
) => {
|
||||
return customFetch<ResQuotationSetting>({
|
||||
url: `/v1/quotation-setting/update/${qtSettingId}`,
|
||||
method: "PATCH",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
data: reqUpdateQuotationSetting,
|
||||
});
|
||||
};
|
||||
qtSettingId: string,
|
||||
reqUpdateQuotationSetting: ReqUpdateQuotationSetting,
|
||||
options?: SecondParameter<typeof customFetch>,) => {
|
||||
|
||||
|
||||
return customFetch<ResQuotationSetting>(
|
||||
{url: `/v1/quotation-setting/update/${qtSettingId}`, method: 'PATCH',
|
||||
headers: {'Content-Type': 'application/json', },
|
||||
data: reqUpdateQuotationSetting
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
export const getUpdateSettingMutationOptions = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSetting>>,
|
||||
TError,
|
||||
{ qtSettingId: string; data: ReqUpdateQuotationSetting },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSetting>>,
|
||||
TError,
|
||||
{ qtSettingId: string; data: ReqUpdateQuotationSetting },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["updateSetting"];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
"mutationKey" in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof updateSetting>>,
|
||||
{ qtSettingId: string; data: ReqUpdateQuotationSetting }
|
||||
> = (props) => {
|
||||
const { qtSettingId, data } = props ?? {};
|
||||
export const getUpdateSettingMutationOptions = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof updateSetting>>, TError,{qtSettingId: string;data: ReqUpdateQuotationSetting}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof updateSetting>>, TError,{qtSettingId: string;data: ReqUpdateQuotationSetting}, TContext> => {
|
||||
|
||||
return updateSetting(qtSettingId, data);
|
||||
};
|
||||
const mutationKey = ['updateSetting'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
|
||||
export type UpdateSettingMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateSetting>>
|
||||
>;
|
||||
export type UpdateSettingMutationBody = ReqUpdateQuotationSetting;
|
||||
export type UpdateSettingMutationError = void | HTTPValidationError;
|
||||
|
||||
/**
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof updateSetting>>, {qtSettingId: string;data: ReqUpdateQuotationSetting}> = (props) => {
|
||||
const {qtSettingId,data} = props ?? {};
|
||||
|
||||
return updateSetting(qtSettingId,data,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type UpdateSettingMutationResult = NonNullable<Awaited<ReturnType<typeof updateSetting>>>
|
||||
export type UpdateSettingMutationBody = ReqUpdateQuotationSetting
|
||||
export type UpdateSettingMutationError = void | HTTPValidationError
|
||||
|
||||
/**
|
||||
* @summary 견적 설정 수정
|
||||
*/
|
||||
export const useUpdateSetting = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSetting>>,
|
||||
TError,
|
||||
{ qtSettingId: string; data: ReqUpdateQuotationSetting },
|
||||
TContext
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateSetting>>,
|
||||
TError,
|
||||
{ qtSettingId: string; data: ReqUpdateQuotationSetting },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getUpdateSettingMutationOptions(options);
|
||||
export const useUpdateSetting = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof updateSetting>>, TError,{qtSettingId: string;data: ReqUpdateQuotationSetting}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateSetting>>,
|
||||
TError,
|
||||
{qtSettingId: string;data: ReqUpdateQuotationSetting},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
};
|
||||
/**
|
||||
const mutationOptions = getUpdateSettingMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
/**
|
||||
* @summary 견적 설정 삭제
|
||||
*/
|
||||
export const deleteSetting = (qtSettingId: string) => {
|
||||
return customFetch<ResDeleteQuotationSetting>({
|
||||
url: `/v1/quotation-setting/delete/${qtSettingId}`,
|
||||
method: "DELETE",
|
||||
});
|
||||
};
|
||||
export const deleteSetting = (
|
||||
qtSettingId: string,
|
||||
options?: SecondParameter<typeof customFetch>,) => {
|
||||
|
||||
|
||||
return customFetch<ResDeleteQuotationSetting>(
|
||||
{url: `/v1/quotation-setting/delete/${qtSettingId}`, method: 'DELETE'
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
export const getDeleteSettingMutationOptions = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteSetting>>,
|
||||
TError,
|
||||
{ qtSettingId: string },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteSetting>>,
|
||||
TError,
|
||||
{ qtSettingId: string },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["deleteSetting"];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
"mutationKey" in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof deleteSetting>>,
|
||||
{ qtSettingId: string }
|
||||
> = (props) => {
|
||||
const { qtSettingId } = props ?? {};
|
||||
export const getDeleteSettingMutationOptions = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof deleteSetting>>, TError,{qtSettingId: string}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof deleteSetting>>, TError,{qtSettingId: string}, TContext> => {
|
||||
|
||||
return deleteSetting(qtSettingId);
|
||||
};
|
||||
const mutationKey = ['deleteSetting'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
|
||||
export type DeleteSettingMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof deleteSetting>>
|
||||
>;
|
||||
|
||||
export type DeleteSettingMutationError = void | HTTPValidationError;
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof deleteSetting>>, {qtSettingId: string}> = (props) => {
|
||||
const {qtSettingId} = props ?? {};
|
||||
|
||||
/**
|
||||
return deleteSetting(qtSettingId,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type DeleteSettingMutationResult = NonNullable<Awaited<ReturnType<typeof deleteSetting>>>
|
||||
|
||||
export type DeleteSettingMutationError = void | HTTPValidationError
|
||||
|
||||
/**
|
||||
* @summary 견적 설정 삭제
|
||||
*/
|
||||
export const useDeleteSetting = <
|
||||
TError = void | HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteSetting>>,
|
||||
TError,
|
||||
{ qtSettingId: string },
|
||||
TContext
|
||||
>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteSetting>>,
|
||||
TError,
|
||||
{ qtSettingId: string },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getDeleteSettingMutationOptions(options);
|
||||
export const useDeleteSetting = <TError = void | HTTPValidationError,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof deleteSetting>>, TError,{qtSettingId: string}, TContext>, request?: SecondParameter<typeof customFetch>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteSetting>>,
|
||||
TError,
|
||||
{qtSettingId: string},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
};
|
||||
const mutationOptions = getDeleteSettingMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -94,13 +94,19 @@ export const customFetch = async <T>(
|
||||
(url.startsWith('http') ? url : `${BASE_URL}${url}`) +
|
||||
(queryString ? `?${queryString}` : '');
|
||||
|
||||
// 파일 업로드(FormData)는 ① 브라우저가 boundary 포함 Content-Type 을 직접 설정해야 하고
|
||||
// ② 본문을 JSON.stringify 하면 "{}" 가 되어 파일이 통째로 누락된다. 분기 처리.
|
||||
const isFormData = typeof FormData !== 'undefined' && data instanceof FormData;
|
||||
|
||||
// [요청 인터셉터] 토큰을 받아 헤더를 구성하고 한 번 호출(만료 재시도 시 새 토큰으로 재구성).
|
||||
const doFetch = (token: string | null) => {
|
||||
const headers = new Headers(config.headers);
|
||||
if (options?.headers) {
|
||||
new Headers(options.headers).forEach((v, k) => headers.set(k, v));
|
||||
}
|
||||
if (data != null && !headers.has('Content-Type')) {
|
||||
if (isFormData) {
|
||||
headers.delete('Content-Type'); // 생성 클라이언트가 박은 boundary 없는 multipart 헤더 제거 → 브라우저가 재설정
|
||||
} else if (data != null && !headers.has('Content-Type')) {
|
||||
headers.set('Content-Type', 'application/json');
|
||||
}
|
||||
if (token) headers.set('Authorization', `Bearer ${token}`);
|
||||
@ -108,7 +114,7 @@ export const customFetch = async <T>(
|
||||
...options,
|
||||
method,
|
||||
headers,
|
||||
body: data != null ? JSON.stringify(data) : options?.body,
|
||||
body: data != null ? (isFormData ? data : JSON.stringify(data)) : options?.body,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
|
||||
import {useState, type ReactNode} from 'react';
|
||||
import {Toaster} from 'sonner';
|
||||
import {ConfirmHost} from '@/lib/confirm';
|
||||
|
||||
export function Providers({children}: {children: ReactNode}) {
|
||||
const [queryClient] = useState(
|
||||
@ -19,6 +20,7 @@ export function Providers({children}: {children: ReactNode}) {
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{children}
|
||||
<Toaster richColors position="top-center" />
|
||||
<ConfirmHost />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,41 +1,63 @@
|
||||
import React, { useState, useRef, DragEvent, ChangeEvent } from 'react';
|
||||
import { Upload, Image as ImageIcon, X, AlertCircle } from 'lucide-react';
|
||||
import { Upload, Image as ImageIcon, X, AlertCircle, Link2, Loader2 } from 'lucide-react';
|
||||
|
||||
interface ImageDropzoneProps {
|
||||
value: string;
|
||||
onChange: (base64Url: string) => void;
|
||||
onChange: (url: string) => void;
|
||||
onClear: () => void;
|
||||
/**
|
||||
* 파일을 받아 업로드하고 저장 URL 을 돌려준다(예: Azure Blob).
|
||||
* 주어지면 드롭/선택한 파일을 업로드해 그 URL 을 value 로 쓴다.
|
||||
* 없으면 과거처럼 base64 data URL 로 폴백한다(재사용 컴포넌트 호환).
|
||||
*/
|
||||
onUpload?: (file: File) => Promise<string>;
|
||||
label?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const MAX_SIZE = 4 * 1024 * 1024; // 백엔드 max_image_mb=4 와 일치
|
||||
|
||||
export default function ImageDropzone({
|
||||
value,
|
||||
onChange,
|
||||
onClear,
|
||||
onUpload,
|
||||
label = '상품 대표 이미지 업로드',
|
||||
className = ''
|
||||
}: ImageDropzoneProps) {
|
||||
const [isDragActive, setIsDragActive] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const [urlDraft, setUrlDraft] = useState('');
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const processFile = (file: File) => {
|
||||
const processFile = async (file: File) => {
|
||||
setError(null);
|
||||
|
||||
// Validate file type
|
||||
|
||||
if (!file.type.startsWith('image/')) {
|
||||
setError('이미지 파일(*.png, *.jpg, *.jpeg, *.gif)만 업로드할 수 있습니다.');
|
||||
setError('이미지 파일(*.png, *.jpg, *.jpeg, *.gif, *.webp)만 업로드할 수 있습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate size (e.g., max 4MB for high-fidelity base64 storage)
|
||||
const maxSize = 4 * 1024 * 1024;
|
||||
if (file.size > maxSize) {
|
||||
if (file.size > MAX_SIZE) {
|
||||
setError('이미지 최댓값은 4MB입니다. 더 작고 최적화된 이미지를 권장합니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
// 업로드 핸들러가 있으면 서버(blob)로 올리고 URL 을 받는다.
|
||||
if (onUpload) {
|
||||
setUploading(true);
|
||||
try {
|
||||
const url = await onUpload(file);
|
||||
onChange(url);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : '이미지 업로드에 실패했습니다.');
|
||||
} finally {
|
||||
setUploading(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 폴백: base64 data URL.
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
if (e.target?.result && typeof e.target.result === 'string') {
|
||||
@ -44,16 +66,14 @@ export default function ImageDropzone({
|
||||
setError('이미지 해독 과정에 이상이 발생했습니다.');
|
||||
}
|
||||
};
|
||||
reader.onerror = () => {
|
||||
setError('파일을 수집하지 못했습니다.');
|
||||
};
|
||||
reader.onerror = () => setError('파일을 수집하지 못했습니다.');
|
||||
reader.readAsDataURL(file);
|
||||
};
|
||||
|
||||
const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsDragActive(true);
|
||||
if (!uploading) setIsDragActive(true);
|
||||
};
|
||||
|
||||
const handleDragLeave = (e: DragEvent<HTMLDivElement>) => {
|
||||
@ -66,20 +86,29 @@ export default function ImageDropzone({
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsDragActive(false);
|
||||
|
||||
if (uploading) return;
|
||||
if (e.dataTransfer.files && e.dataTransfer.files[0]) {
|
||||
processFile(e.dataTransfer.files[0]);
|
||||
void processFile(e.dataTransfer.files[0]);
|
||||
}
|
||||
};
|
||||
|
||||
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
if (e.target.files && e.target.files[0]) {
|
||||
processFile(e.target.files[0]);
|
||||
void processFile(e.target.files[0]);
|
||||
}
|
||||
e.target.value = ''; // 같은 파일 재선택 허용
|
||||
};
|
||||
|
||||
const handleButtonClick = () => {
|
||||
fileInputRef.current?.click();
|
||||
if (!uploading) fileInputRef.current?.click();
|
||||
};
|
||||
|
||||
const applyUrl = () => {
|
||||
const url = urlDraft.trim();
|
||||
if (!url) return;
|
||||
setError(null);
|
||||
onChange(url);
|
||||
setUrlDraft('');
|
||||
};
|
||||
|
||||
return (
|
||||
@ -90,7 +119,7 @@ export default function ImageDropzone({
|
||||
</label>
|
||||
|
||||
{value ? (
|
||||
// Preview Mode with image loaded
|
||||
// 미리보기 (blob URL / 외부 URL / base64 모두 동일하게 표시)
|
||||
<div className="relative group border border-border rounded-lg overflow-hidden bg-background h-44 flex items-center justify-center">
|
||||
<img
|
||||
src={value}
|
||||
@ -98,7 +127,6 @@ export default function ImageDropzone({
|
||||
referrerPolicy="no-referrer"
|
||||
className="h-full w-full object-contain"
|
||||
/>
|
||||
{/* Hover overlay control */}
|
||||
<div className="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex flex-col items-center justify-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
@ -118,15 +146,17 @@ export default function ImageDropzone({
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
// Active Dropzone Area
|
||||
// 드롭존
|
||||
<div
|
||||
onDragOver={handleDragOver}
|
||||
onDragLeave={handleDragLeave}
|
||||
onDrop={handleDrop}
|
||||
onClick={handleButtonClick}
|
||||
className={`border-2 border-dashed rounded-lg p-6 flex flex-col items-center justify-center text-center cursor-pointer min-h-44 transition-all ${
|
||||
isDragActive
|
||||
? 'border-primary bg-primary/5'
|
||||
className={`relative border-2 border-dashed rounded-lg p-6 flex flex-col items-center justify-center text-center min-h-44 transition-all ${
|
||||
uploading ? 'cursor-wait' : 'cursor-pointer'
|
||||
} ${
|
||||
isDragActive
|
||||
? 'border-primary bg-primary/5'
|
||||
: 'border-border hover:border-foreground/30 bg-muted/20'
|
||||
}`}
|
||||
>
|
||||
@ -136,27 +166,64 @@ export default function ImageDropzone({
|
||||
onChange={handleFileChange}
|
||||
accept="image/*"
|
||||
className="hidden"
|
||||
disabled={uploading}
|
||||
/>
|
||||
|
||||
<div className="p-2.5 bg-background border border-border rounded-full shadow-xs mb-3 text-muted-foreground">
|
||||
{isDragActive ? (
|
||||
<Upload size={22} className="animate-bounce text-primary" />
|
||||
) : (
|
||||
<ImageIcon size={22} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<p className="font-semibold text-foreground text-xs">
|
||||
{isDragActive ? '여기에 드롭하여 업로드' : '이지지 드래그 앤 드롭 또는 파일 탐색'}
|
||||
</p>
|
||||
<p className="text-[10px] text-muted-foreground max-w-[280px] leading-relaxed">
|
||||
PNG, JPG, JPEG, GIF 파일 지원 (최대 4MB)
|
||||
</p>
|
||||
</div>
|
||||
{uploading ? (
|
||||
<div className="flex flex-col items-center gap-2 text-muted-foreground">
|
||||
<Loader2 size={22} className="animate-spin text-primary" />
|
||||
<p className="font-semibold text-foreground text-xs">업로드 중…</p>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="p-2.5 bg-background border border-border rounded-full shadow-xs mb-3 text-muted-foreground">
|
||||
{isDragActive ? (
|
||||
<Upload size={22} className="animate-bounce text-primary" />
|
||||
) : (
|
||||
<ImageIcon size={22} />
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="font-semibold text-foreground text-xs">
|
||||
{isDragActive ? '여기에 드롭하여 업로드' : '이미지 드래그 앤 드롭 또는 파일 탐색'}
|
||||
</p>
|
||||
<p className="text-[10px] text-muted-foreground max-w-[280px] leading-relaxed">
|
||||
PNG, JPG, JPEG, GIF, WEBP 파일 지원 (최대 4MB)
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 이미지 URL 직접 입력 */}
|
||||
<div className="flex items-center gap-1.5 pt-1">
|
||||
<div className="relative flex-1">
|
||||
<Link2 size={12} className="absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground" />
|
||||
<input
|
||||
type="url"
|
||||
value={urlDraft}
|
||||
onChange={(e) => setUrlDraft(e.target.value)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
applyUrl();
|
||||
}
|
||||
}}
|
||||
placeholder="또는 이미지 URL 붙여넣기 (https://…)"
|
||||
className="w-full pl-6 pr-2 py-1.5 text-[11px] rounded border border-border bg-background text-foreground placeholder:text-muted-foreground/70 focus:outline-none focus:border-primary"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={applyUrl}
|
||||
disabled={!urlDraft.trim()}
|
||||
className="px-2.5 py-1.5 text-[11px] font-bold rounded bg-primary text-primary-foreground hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer shrink-0"
|
||||
>
|
||||
적용
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div className="flex items-center gap-1.5 text-[10px] text-destructive mt-1">
|
||||
<AlertCircle size={12} />
|
||||
|
||||
@ -1,12 +1,23 @@
|
||||
import React from 'react';
|
||||
import { variableLabel } from '@/features/cards/editor/variables';
|
||||
|
||||
interface SlateLeaf {
|
||||
text: string;
|
||||
bold?: boolean;
|
||||
italic?: boolean;
|
||||
color?: 'primary' | 'success' | 'warning' | 'destructive';
|
||||
underline?: boolean;
|
||||
// 'primary'|'success'|'warning'|'destructive' 프리셋 토큰 또는 임의 CSS 색(예: '#ED2024')
|
||||
color?: string;
|
||||
}
|
||||
|
||||
// 프리셋 색 토큰 → 클래스. 카드 에디터는 헥스(#ED2024)를 쓰므로 토큰에 없으면 인라인 style 로 처리.
|
||||
const NAMED_COLOR: Record<string, string> = {
|
||||
primary: 'text-primary font-bold underline decoration-2 decoration-gray-400 dark:decoration-gray-600',
|
||||
success: 'text-success font-semibold px-1 py-0.5 rounded bg-emerald-50 dark:bg-emerald-950/40 border border-emerald-200/50 dark:border-emerald-900/40',
|
||||
warning: 'text-warning font-semibold px-1 py-0.5 rounded bg-amber-50 dark:bg-amber-950/40 border border-amber-200/50',
|
||||
destructive: 'text-destructive font-semibold',
|
||||
};
|
||||
|
||||
interface SlateNode {
|
||||
type?: 'paragraph' | 'block-quote' | 'heading-one' | 'heading-two' | 'list-item';
|
||||
children: (SlateLeaf | SlateNode)[];
|
||||
@ -41,45 +52,17 @@ export default function SlateRenderer({ nodes, variables = {} }: SlateRendererPr
|
||||
const renderLeaf = (leaf: SlateLeaf, key: string) => {
|
||||
const text = replaceVariables(leaf.text);
|
||||
let classes = '';
|
||||
|
||||
if (leaf.bold) {
|
||||
classes += ' font-bold ';
|
||||
}
|
||||
if (leaf.italic) {
|
||||
classes += ' italic ';
|
||||
}
|
||||
if (leaf.bold) classes += ' font-bold';
|
||||
if (leaf.italic) classes += ' italic';
|
||||
if (leaf.underline) classes += ' underline';
|
||||
|
||||
if (leaf.color === 'primary') {
|
||||
return (
|
||||
<span key={key} className={`${classes} text-primary font-bold underline decoration-2 decoration-gray-400 dark:decoration-gray-600`}>
|
||||
{text}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (leaf.color === 'success') {
|
||||
return (
|
||||
<span key={key} className={`${classes} text-success font-semibold px-1 py-0.5 rounded bg-emerald-50 dark:bg-emerald-950/40 border border-emerald-200/50 dark:border-emerald-900/40`}>
|
||||
{text}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (leaf.color === 'warning') {
|
||||
return (
|
||||
<span key={key} className={`${classes} text-warning font-semibold px-1 py-0.5 rounded bg-amber-50 dark:bg-amber-950/40 border border-amber-200/50`}>
|
||||
{text}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (leaf.color === 'destructive') {
|
||||
return (
|
||||
<span key={key} className={`${classes} text-destructive font-semibold`}>
|
||||
{text}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
// color 가 프리셋 토큰이면 클래스, 임의 CSS 색(헥스 등)이면 인라인 style 로 적용.
|
||||
const named = leaf.color ? NAMED_COLOR[leaf.color] : undefined;
|
||||
const style = leaf.color && !named ? { color: leaf.color } : undefined;
|
||||
const cls = `${classes}${named ? ` ${named}` : ''}`.trim();
|
||||
|
||||
return (
|
||||
<span key={key} className={classes || undefined}>
|
||||
<span key={key} className={cls || undefined} style={style}>
|
||||
{text}
|
||||
</span>
|
||||
);
|
||||
@ -93,6 +76,22 @@ export default function SlateRenderer({ nodes, variables = {} }: SlateRendererPr
|
||||
return renderLeaf(node as SlateLeaf, key);
|
||||
}
|
||||
|
||||
// 변수 노드(void inline): {type:'variable', name}. variables 에 값 있으면 치환, 없으면 라벨 칩.
|
||||
if (node.type === 'variable') {
|
||||
const raw = variables[node.name];
|
||||
const hasValue = raw !== undefined && raw !== null && raw !== '';
|
||||
if (hasValue) {
|
||||
const text = typeof raw === 'number' ? raw.toLocaleString('ko-KR') : String(raw);
|
||||
return <span key={key} className="font-semibold text-primary">{text}</span>;
|
||||
}
|
||||
// 값 없으면 치환하지 않고 {라벨} 형태로 그대로 노출.
|
||||
return (
|
||||
<span key={key} className="text-muted-foreground">
|
||||
{`{${variableLabel(node.name)}}`}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const childrenElements = (node.children || []).map((child: any, childIdx: number) => {
|
||||
if (child.text !== undefined) {
|
||||
return renderLeaf(child as SlateLeaf, `${key}-${childIdx}`);
|
||||
|
||||
@ -15,6 +15,8 @@ import {
|
||||
Moon,
|
||||
Building,
|
||||
ChevronRight,
|
||||
Menu,
|
||||
X,
|
||||
} from 'lucide-react';
|
||||
|
||||
interface LayoutProps {
|
||||
@ -46,7 +48,11 @@ export default function Layout({ children, currentPage, setPage, onLogout }: Lay
|
||||
const today = new Date().toLocaleDateString('sv-SE');
|
||||
|
||||
const [isDark, setIsDark] = useState(false);
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState(true); // 데스크톱 접기 토글
|
||||
const [isMobileOpen, setIsMobileOpen] = useState(false); // 모바일 드로어 열림
|
||||
|
||||
// 사이드바 펼침 여부(라벨/프로필 노출 기준). 모바일 드로어는 항상 펼친 상태로 본다.
|
||||
const expanded = isMobileOpen || isSidebarOpen;
|
||||
|
||||
const toggleDarkMode = () => {
|
||||
setIsDark(!isDark);
|
||||
@ -61,44 +67,62 @@ export default function Layout({ children, currentPage, setPage, onLogout }: Lay
|
||||
<div className="min-h-screen bg-background text-foreground flex">
|
||||
{/* 토스트는 sonner <Toaster/>(main.tsx)가 전역으로 처리한다 */}
|
||||
|
||||
{/* 모바일 드로어 백드롭 */}
|
||||
{isMobileOpen && (
|
||||
<div
|
||||
className="fixed inset-0 z-30 bg-black/40 backdrop-blur-xs md:hidden"
|
||||
onClick={() => setIsMobileOpen(false)}
|
||||
aria-hidden
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Main Sidebar */}
|
||||
<aside
|
||||
className={cn(
|
||||
'bg-card border-r border-border flex flex-col justify-between transition-all duration-300 z-30 fixed h-full',
|
||||
isSidebarOpen ? 'w-60' : 'w-16'
|
||||
'bg-card border-r border-border flex flex-col justify-between transition-all duration-300 z-40 fixed inset-y-0 left-0',
|
||||
// 폭: 모바일은 항상 펼친 드로어(w-60), 데스크톱만 접기 토글
|
||||
'w-60',
|
||||
isSidebarOpen ? 'md:w-60' : 'md:w-16',
|
||||
// 모바일 슬라이드 인/아웃 — 데스크톱은 항상 보임
|
||||
isMobileOpen ? 'translate-x-0' : '-translate-x-full',
|
||||
'md:translate-x-0'
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
{/* Sidebar Brand Header */}
|
||||
<div className="h-14 flex items-center justify-between px-4 border-b border-border">
|
||||
{isSidebarOpen ? (
|
||||
<>
|
||||
<Typography as="div" variant="body" className="text-primary font-extrabold tracking-tighter">
|
||||
NegoData
|
||||
</Typography>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => setIsSidebarOpen(false)}
|
||||
className="p-1 h-auto rounded text-muted-foreground"
|
||||
title="메뉴 접기"
|
||||
>
|
||||
<ChevronRight size={14} className="rotate-180 size-3.5" />
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => setIsSidebarOpen(true)}
|
||||
className="mx-auto p-1.5 h-auto rounded bg-muted/65 text-muted-foreground"
|
||||
title="메뉴 열기"
|
||||
>
|
||||
<ChevronRight size={14} className="size-3.5" />
|
||||
</Button>
|
||||
{expanded && (
|
||||
<Typography as="div" variant="body" className="text-primary font-extrabold tracking-tighter">
|
||||
NegoData
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{/* 데스크톱: 사이드바 접기/펼치기 */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => setIsSidebarOpen((v) => !v)}
|
||||
className={cn(
|
||||
'hidden md:inline-flex p-1 h-auto rounded text-muted-foreground',
|
||||
!isSidebarOpen && 'mx-auto bg-muted/65'
|
||||
)}
|
||||
title={isSidebarOpen ? '메뉴 접기' : '메뉴 열기'}
|
||||
>
|
||||
<ChevronRight size={14} className={cn('size-3.5', isSidebarOpen && 'rotate-180')} />
|
||||
</Button>
|
||||
|
||||
{/* 모바일: 드로어 닫기 */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => setIsMobileOpen(false)}
|
||||
className="md:hidden p-1 h-auto rounded text-muted-foreground"
|
||||
title="메뉴 닫기"
|
||||
>
|
||||
<X size={16} className="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Nav User Profile Card */}
|
||||
{isSidebarOpen && <SidebarProfileCard user={user} />}
|
||||
{expanded && <SidebarProfileCard user={user} />}
|
||||
|
||||
{/* Nav Items */}
|
||||
<nav className="mt-2 px-3 space-y-1">
|
||||
@ -107,8 +131,11 @@ export default function Layout({ children, currentPage, setPage, onLogout }: Lay
|
||||
key={item.type}
|
||||
item={item}
|
||||
isActive={currentPage === item.type}
|
||||
isOpen={isSidebarOpen}
|
||||
onClick={() => setPage(item.type)}
|
||||
isOpen={expanded}
|
||||
onClick={() => {
|
||||
setPage(item.type);
|
||||
setIsMobileOpen(false);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</nav>
|
||||
@ -123,7 +150,7 @@ export default function Layout({ children, currentPage, setPage, onLogout }: Lay
|
||||
className="w-full justify-start gap-3 py-1.5 px-3 h-auto rounded text-[11px] font-semibold text-muted-foreground"
|
||||
>
|
||||
{isDark ? <Sun size={14} className="text-warning size-3.5" /> : <Moon size={14} className="size-3.5" />}
|
||||
{isSidebarOpen && <span>{isDark ? '라이트 모드' : '다크 모드'}</span>}
|
||||
{expanded && <span>{isDark ? '라이트 모드' : '다크 모드'}</span>}
|
||||
</Button>
|
||||
|
||||
{/* Logout btn */}
|
||||
@ -134,20 +161,33 @@ export default function Layout({ children, currentPage, setPage, onLogout }: Lay
|
||||
className="w-full justify-start gap-3 py-1.5 px-3 h-auto rounded text-[11px] font-semibold text-destructive hover:bg-destructive/10 hover:text-destructive"
|
||||
>
|
||||
<LogOut size={14} className="size-3.5" />
|
||||
{isSidebarOpen && <span>시스템 로그아웃</span>}
|
||||
{expanded && <span>시스템 로그아웃</span>}
|
||||
</Button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{/* Main Container Wrapper */}
|
||||
<div
|
||||
className="flex-1 flex flex-col transition-all duration-300"
|
||||
style={{ paddingLeft: isSidebarOpen ? '15rem' : '4rem' }}
|
||||
className={cn(
|
||||
'flex-1 flex flex-col transition-all duration-300',
|
||||
// 모바일: 사이드바가 오버레이라 패딩 없음 / 데스크톱: 사이드바 폭만큼 확보
|
||||
isSidebarOpen ? 'md:pl-60' : 'md:pl-16'
|
||||
)}
|
||||
>
|
||||
{/* Global Header */}
|
||||
<header className="h-14 bg-card border-b border-border flex items-center justify-between px-8 sticky top-0 z-20 shadow-xs backdrop-blur-md bg-opacity-95">
|
||||
<div className="flex items-center gap-4">
|
||||
<Typography as="div" variant="small" className="font-bold">
|
||||
<header className="h-14 bg-card border-b border-border flex items-center justify-between px-4 md:px-8 sticky top-0 z-20 shadow-xs backdrop-blur-md bg-opacity-95">
|
||||
<div className="flex items-center gap-2 md:gap-4 min-w-0">
|
||||
{/* 모바일 햄버거 */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => setIsMobileOpen(true)}
|
||||
className="md:hidden p-1.5 h-auto rounded text-muted-foreground"
|
||||
title="메뉴 열기"
|
||||
>
|
||||
<Menu size={18} className="size-[18px]" />
|
||||
</Button>
|
||||
{/* 현재 페이지 — 모바일·데스크톱 모두 표시(로고는 사이드바/드로어 몫) */}
|
||||
<Typography as="div" variant="small" className="font-bold truncate">
|
||||
{pageLabelMap[currentPage]}
|
||||
</Typography>
|
||||
</div>
|
||||
@ -156,12 +196,12 @@ export default function Layout({ children, currentPage, setPage, onLogout }: Lay
|
||||
</header>
|
||||
|
||||
{/* Content Body Area */}
|
||||
<main className="flex-1 p-8 overflow-y-auto bg-background">
|
||||
<main className="flex-1 p-4 md:p-8 overflow-y-auto bg-background">
|
||||
<div className="max-w-7xl mx-auto space-y-6">{children}</div>
|
||||
</main>
|
||||
|
||||
{/* Compact Admin footer info */}
|
||||
<footer className="h-10 border-t border-border/60 bg-card flex items-center justify-between px-8">
|
||||
<footer className="h-10 border-t border-border/60 bg-card flex items-center justify-between px-4 md:px-8">
|
||||
<Typography variant="mono">Copyright © O2O Inc. All rights reserved</Typography>
|
||||
</footer>
|
||||
</div>
|
||||
@ -254,27 +294,27 @@ function NavItem({
|
||||
/** 글로벌 헤더 우측 메타 정보 */
|
||||
function HeaderMeta({ user, today }: { user: SidebarUser; today: string }) {
|
||||
return (
|
||||
<div className="flex items-center gap-4">
|
||||
<Typography as="div" variant="caption" className="hidden md:block">
|
||||
<div className="flex items-center gap-3 md:gap-4">
|
||||
<Typography as="div" variant="caption" className="hidden lg:block">
|
||||
기준일시: <span className="font-semibold text-foreground">{today}</span>
|
||||
</Typography>
|
||||
<div className="h-4 w-px bg-border hidden md:block" />
|
||||
<div className="h-4 w-px bg-border hidden lg:block" />
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="inline-block h-2 w-2 rounded-full bg-success animate-pulse" />
|
||||
<Typography as="span" variant="caption">회사:</Typography>
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
<span className="inline-block h-2 w-2 rounded-full bg-success animate-pulse shrink-0" />
|
||||
<Typography as="span" variant="caption" className="shrink-0">회사:</Typography>
|
||||
<Typography
|
||||
as="span"
|
||||
variant="caption"
|
||||
id="header-company-name"
|
||||
className="font-bold text-foreground underline decoration-1"
|
||||
className="font-bold text-foreground underline decoration-1 truncate max-w-[140px] md:max-w-none"
|
||||
>
|
||||
{user?.company}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
<div className="h-4 w-px bg-border" />
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="h-4 w-px bg-border hidden lg:block" />
|
||||
<div className="hidden lg:flex items-center gap-2">
|
||||
<Typography as="span" variant="caption">관리자:</Typography>
|
||||
<Typography as="span" variant="caption" className="font-semibold text-foreground">
|
||||
{user?.name} ({user?.loginId})
|
||||
|
||||
@ -21,7 +21,7 @@ export function PageToolbar({
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-1 flex-col sm:flex-row gap-3">{children}</div>
|
||||
{actions && <div className="flex items-center gap-2">{actions}</div>}
|
||||
{actions && <div className="flex flex-wrap items-center gap-2">{actions}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import {
|
||||
|
||||
// 컬럼 설정형 데이터 테이블. 래퍼/헤더/행/빈상태/정렬·패딩, 그리고 행 선택(체크박스)까지
|
||||
// 여기서 책임지고, 페이지는 컬럼 정의(header/cell)와 선택 상태만 넘긴다. 표 룩의 단일 출처.
|
||||
// md 미만(모바일)에서는 같은 컬럼 정의로 카드(라벨:값) 리스트를 렌더해 가로 스크롤을 없앤다.
|
||||
export type Column<T> = {
|
||||
id?: string
|
||||
header: ReactNode
|
||||
@ -21,6 +22,12 @@ export type Column<T> = {
|
||||
cellClassName?: string
|
||||
// 셀 단위 클릭 핸들러 (예: 행 클릭 전파 차단)
|
||||
onCellClick?: (row: T, e: MouseEvent) => void
|
||||
// 모바일 카드뷰에서 라벨 없이 카드 헤더로 단독 표기(보통 첫 컬럼=식별값). 미지정 시 첫 컬럼이 자동 헤더.
|
||||
mobileHeader?: boolean
|
||||
// 모바일 카드뷰에서 이 컬럼 숨김
|
||||
mobileHidden?: boolean
|
||||
// 모바일 카드뷰에서 라벨:값 한 줄이 아니라 라벨 아래 값 풀폭 스택으로(여러 줄/긴 블록 셀용)
|
||||
mobileBlock?: boolean
|
||||
}
|
||||
|
||||
// 행 선택 기능. 넘기면 맨 앞에 체크박스 컬럼(전체선택 헤더 포함)이 자동으로 붙는다.
|
||||
@ -83,88 +90,172 @@ export function DataTable<T>({
|
||||
|
||||
const colCount = columns.length + (selection ? 1 : 0)
|
||||
|
||||
// 모바일 카드뷰 컬럼 분류: 헤더(식별값) 1개 + 나머지(라벨:값).
|
||||
const mobileCols = columns.filter((c) => !c.mobileHidden)
|
||||
const headerIdx = mobileCols.findIndex((c) => c.mobileHeader)
|
||||
const primaryCol = headerIdx >= 0 ? mobileCols[headerIdx] : mobileCols[0]
|
||||
const detailCols = mobileCols.filter((c) => c !== primaryCol)
|
||||
|
||||
return (
|
||||
<div className={cn("border border-border rounded-lg bg-card overflow-hidden", className)}>
|
||||
<Table className="w-full text-xs">
|
||||
<TableHeader>
|
||||
<TableRow className="bg-muted/50 border-b border-border hover:bg-transparent">
|
||||
{selection && (
|
||||
<TableHead className="p-4 w-12 text-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isAllSelected}
|
||||
onChange={(e) => toggleAll(e.target.checked)}
|
||||
className={checkboxClass}
|
||||
/>
|
||||
</TableHead>
|
||||
)}
|
||||
{columns.map((c, i) => (
|
||||
<TableHead
|
||||
key={c.id ?? i}
|
||||
className={cn(
|
||||
"p-4 font-semibold text-foreground",
|
||||
c.align && alignClass[c.align],
|
||||
c.headClassName
|
||||
)}
|
||||
>
|
||||
{c.header}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{data.length > 0 ? (
|
||||
data.map((row) => {
|
||||
const key = rowKey(row)
|
||||
const selected = !!selection && selection.selectedKeys.includes(key)
|
||||
return (
|
||||
<TableRow
|
||||
key={key}
|
||||
// 전환 기준은 뷰포트가 아니라 '표가 들어갈 실제 폭'(컨테이너). 사이드바가 폭을 먹어도
|
||||
// 어긋나지 않는다. 컨테이너 ≥ 48rem(@3xl)이면 표, 그 미만은 카드 리스트. (Tailwind v4 내장 @container)
|
||||
<div className={cn("@container border border-border rounded-lg bg-card overflow-hidden", className)}>
|
||||
{/* 넓을 때: 표 — 그래도 넘치면 Table 내부에서 가로 스크롤 */}
|
||||
<div className="hidden @3xl:block">
|
||||
<Table className="w-full text-xs">
|
||||
<TableHeader>
|
||||
<TableRow className="bg-muted/50 border-b border-border hover:bg-transparent">
|
||||
{selection && (
|
||||
<TableHead className="p-4 w-12 text-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isAllSelected}
|
||||
onChange={(e) => toggleAll(e.target.checked)}
|
||||
className={checkboxClass}
|
||||
/>
|
||||
</TableHead>
|
||||
)}
|
||||
{columns.map((c, i) => (
|
||||
<TableHead
|
||||
key={c.id ?? i}
|
||||
className={cn(
|
||||
"border-b border-border/50 transition-colors",
|
||||
onRowClick && "cursor-pointer hover:bg-muted/35",
|
||||
selected && "bg-primary/5 hover:bg-primary/10",
|
||||
rowClassName?.(row)
|
||||
"px-4 py-2.5 font-semibold text-foreground",
|
||||
c.align && alignClass[c.align],
|
||||
c.headClassName
|
||||
)}
|
||||
onClick={onRowClick ? () => onRowClick(row) : undefined}
|
||||
>
|
||||
{selection && (
|
||||
<TableCell
|
||||
className="p-4 text-center w-12"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{c.header}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{data.length > 0 ? (
|
||||
data.map((row) => {
|
||||
const key = rowKey(row)
|
||||
const selected = !!selection && selection.selectedKeys.includes(key)
|
||||
return (
|
||||
<TableRow
|
||||
key={key}
|
||||
className={cn(
|
||||
"border-b border-border/50 transition-colors",
|
||||
onRowClick && "cursor-pointer hover:bg-muted/35",
|
||||
selected && "bg-primary/5 hover:bg-primary/10",
|
||||
rowClassName?.(row)
|
||||
)}
|
||||
onClick={onRowClick ? () => onRowClick(row) : undefined}
|
||||
>
|
||||
{selection && (
|
||||
<TableCell
|
||||
className="p-4 text-center w-12"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selected}
|
||||
onChange={(e) => toggleOne(key, e.target.checked)}
|
||||
className={checkboxClass}
|
||||
/>
|
||||
</TableCell>
|
||||
)}
|
||||
{columns.map((c, i) => (
|
||||
<TableCell
|
||||
key={c.id ?? i}
|
||||
className={cn("px-4 py-2", c.align && alignClass[c.align], c.cellClassName)}
|
||||
onClick={c.onCellClick ? (e) => c.onCellClick!(row, e) : undefined}
|
||||
>
|
||||
{c.cell(row)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={colCount}
|
||||
className="p-12 text-center text-muted-foreground font-mono"
|
||||
>
|
||||
{empty}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
{/* 좁을 때(컨테이너 < 48rem): 카드 리스트 — 행=카드, 컬럼=라벨:값 */}
|
||||
<div className="@3xl:hidden divide-y divide-border">
|
||||
{data.length > 0 ? (
|
||||
data.map((row) => {
|
||||
const key = rowKey(row)
|
||||
const selected = !!selection && selection.selectedKeys.includes(key)
|
||||
return (
|
||||
<div
|
||||
key={key}
|
||||
className={cn(
|
||||
"p-3 transition-colors",
|
||||
onRowClick && "cursor-pointer active:bg-muted/40",
|
||||
selected && "bg-primary/5"
|
||||
)}
|
||||
onClick={onRowClick ? () => onRowClick(row) : undefined}
|
||||
>
|
||||
{/* 헤더: 선택 체크박스 + 식별 컬럼 */}
|
||||
{(selection || primaryCol) && (
|
||||
<div className="flex items-center gap-2.5">
|
||||
{selection && (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selected}
|
||||
onChange={(e) => toggleOne(key, e.target.checked)}
|
||||
className={checkboxClass}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className={cn(checkboxClass, "shrink-0")}
|
||||
/>
|
||||
</TableCell>
|
||||
)}
|
||||
{columns.map((c, i) => (
|
||||
<TableCell
|
||||
key={c.id ?? i}
|
||||
className={cn("p-4", c.align && alignClass[c.align], c.cellClassName)}
|
||||
onClick={c.onCellClick ? (e) => c.onCellClick!(row, e) : undefined}
|
||||
>
|
||||
{c.cell(row)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={colCount}
|
||||
className="p-12 text-center text-muted-foreground font-mono"
|
||||
>
|
||||
{empty}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
{primaryCol && (
|
||||
<div className="min-w-0 flex-1">{primaryCol.cell(row)}</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 상세: 기본=라벨:값 한 줄(컴팩트) / mobileBlock=라벨 아래 풀폭 */}
|
||||
{detailCols.length > 0 && (
|
||||
<dl className="mt-2.5 space-y-1.5 border-t border-border/40 pt-2.5 text-[11px] leading-tight">
|
||||
{detailCols.map((c, i) =>
|
||||
c.mobileBlock ? (
|
||||
<div key={c.id ?? i} className="space-y-1">
|
||||
<dt className="text-muted-foreground">{c.header}</dt>
|
||||
<dd
|
||||
className={cn("text-foreground", c.cellClassName)}
|
||||
onClick={c.onCellClick ? (e) => c.onCellClick!(row, e) : undefined}
|
||||
>
|
||||
{c.cell(row)}
|
||||
</dd>
|
||||
</div>
|
||||
) : (
|
||||
<div key={c.id ?? i} className="flex items-start justify-between gap-3">
|
||||
<dt className="shrink-0 text-muted-foreground">{c.header}</dt>
|
||||
<dd
|
||||
className={cn("min-w-0 text-right text-foreground", c.cellClassName)}
|
||||
onClick={c.onCellClick ? (e) => c.onCellClick!(row, e) : undefined}
|
||||
>
|
||||
{c.cell(row)}
|
||||
</dd>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</dl>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<div className="p-12 text-center text-muted-foreground font-mono text-xs">
|
||||
{empty}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{footer}
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -1,317 +0,0 @@
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { z } from 'zod';
|
||||
import { X, Layers } from 'lucide-react';
|
||||
import { showToast } from '@/lib/notify';
|
||||
import { Typography } from '@/components/ui/typography';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { type NegotiationCard, type CardTab, generateCardCode } from '../types';
|
||||
import type { CardInput } from '../hooks/useCards';
|
||||
|
||||
const schema = z.object({
|
||||
isWildcard: z.boolean(),
|
||||
code: z.string().trim().min(1, '카드번호는 필수 기입 사항입니다.'),
|
||||
title: z.string().trim().min(1, '카드이름은 필수 기입 사항입니다.'),
|
||||
scriptPreview: z.string().trim().min(1, '스크립트를 작성해 주십시오.'),
|
||||
status: z.enum(['ACTIVE', 'INACTIVE']),
|
||||
triggerCondition: z.string(),
|
||||
memo: z.string(),
|
||||
});
|
||||
|
||||
type FormValues = z.infer<typeof schema>;
|
||||
|
||||
type CardFormModalProps = {
|
||||
open: boolean;
|
||||
mode: 'create' | 'edit';
|
||||
card: NegotiationCard | null; // edit 모드 초기값 출처
|
||||
activeTab: CardTab; // create 시 기본 카드 종류 결정
|
||||
onCreate: (input: CardInput) => Promise<void>;
|
||||
onUpdate: (id: string, input: CardInput) => Promise<void>;
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
function buildDefaults(
|
||||
mode: 'create' | 'edit',
|
||||
card: NegotiationCard | null,
|
||||
activeTab: CardTab,
|
||||
): FormValues {
|
||||
if (mode === 'edit' && card) {
|
||||
return {
|
||||
isWildcard: card.isWildcard,
|
||||
code: card.code,
|
||||
title: card.title,
|
||||
scriptPreview: card.scriptPreview,
|
||||
status: card.status,
|
||||
triggerCondition: card.triggerCondition || '',
|
||||
memo: card.memo || '',
|
||||
};
|
||||
}
|
||||
const wild = activeTab === 'WILD';
|
||||
return {
|
||||
isWildcard: wild,
|
||||
code: generateCardCode(wild),
|
||||
title: '',
|
||||
scriptPreview: '',
|
||||
status: 'ACTIVE',
|
||||
triggerCondition: '',
|
||||
memo: '',
|
||||
};
|
||||
}
|
||||
|
||||
// 협상카드/와일드카드 등록·수정 모달. react-hook-form + zod로 검증.
|
||||
// 페이지는 key={mode + card?.id}로 리마운트시켜 초기값을 주입한다.
|
||||
export function CardFormModal({
|
||||
open,
|
||||
mode,
|
||||
card,
|
||||
activeTab,
|
||||
onCreate,
|
||||
onUpdate,
|
||||
onClose,
|
||||
}: CardFormModalProps) {
|
||||
const {
|
||||
register,
|
||||
control,
|
||||
handleSubmit,
|
||||
watch,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: buildDefaults(mode, card, activeTab),
|
||||
});
|
||||
|
||||
const isWildcard = watch('isWildcard');
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
const onValid = async (v: FormValues) => {
|
||||
const input: CardInput = {
|
||||
title: v.title,
|
||||
code: v.code,
|
||||
scriptPreview: v.scriptPreview,
|
||||
status: v.status,
|
||||
isWildcard: v.isWildcard,
|
||||
triggerCondition: v.triggerCondition,
|
||||
memo: v.memo,
|
||||
};
|
||||
const kind = v.isWildcard ? '와일드카드' : '협상카드';
|
||||
try {
|
||||
if (mode === 'create') {
|
||||
await onCreate(input);
|
||||
showToast(`${kind}가 추가되었습니다.`, 'success');
|
||||
} else if (card) {
|
||||
await onUpdate(card.id, input);
|
||||
showToast('정보가 수정되었습니다.', 'success');
|
||||
}
|
||||
onClose();
|
||||
} catch (err) {
|
||||
showToast(err instanceof Error ? err.message : `${kind} 저장 실패`, 'error');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-xs p-4">
|
||||
<div className="w-full max-w-lg bg-card border border-border rounded-lg shadow-2xl p-6 overflow-y-auto max-h-[90vh] animate-scale-up font-mono text-xs">
|
||||
|
||||
<div className="flex items-center justify-between pb-4 border-b border-border mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Layers className="text-foreground" size={16} />
|
||||
<Typography variant="h3" className="text-sm">
|
||||
{mode === 'create'
|
||||
? isWildcard
|
||||
? '신규 와일드카드 등록'
|
||||
: '신규 협상카드 등록'
|
||||
: isWildcard
|
||||
? '와일드카드 정보 수정'
|
||||
: '협상카드 정보 수정'}
|
||||
</Typography>
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="p-1 rounded text-muted-foreground hover:bg-muted cursor-pointer"
|
||||
>
|
||||
<X size={18} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit(onValid)} className="space-y-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
|
||||
{/* Card Type Selection */}
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">카드 종류</Typography>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isWildcard"
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
value={field.value ? 'WILD' : 'CARD'}
|
||||
onValueChange={(v) => {
|
||||
// 카드 종류는 등록 시에만 정한다(수정 시 테이블 이동 불가 → 고정).
|
||||
if (mode !== 'create') return;
|
||||
const wild = v === 'WILD';
|
||||
field.onChange(wild);
|
||||
setValue('code', generateCardCode(wild));
|
||||
}}
|
||||
>
|
||||
<SelectTrigger id="form-card-is-wildcard" className="w-full" disabled={mode === 'edit'}>
|
||||
<SelectValue>
|
||||
{(value) => (value === 'WILD' ? '와일드카드' : '일반 협상카드')}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="CARD">일반 협상카드</SelectItem>
|
||||
<SelectItem value="WILD">와일드카드</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Code */}
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">카드번호</Typography>
|
||||
<Input
|
||||
id="form-card-code"
|
||||
type="text"
|
||||
{...register('code')}
|
||||
placeholder="CARD-XXX 또는 WILD-XXX"
|
||||
/>
|
||||
{errors.code && <p className="text-[10px] text-rose-500">{errors.code.message}</p>}
|
||||
</div>
|
||||
|
||||
{/* Status */}
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold block mb-1">협상 적용 여부</Typography>
|
||||
{isWildcard ? (
|
||||
<Controller
|
||||
control={control}
|
||||
name="status"
|
||||
render={({ field }) => (
|
||||
<div className="flex items-center gap-3 p-2 bg-muted/30 border border-border rounded-md h-[34px]">
|
||||
<button
|
||||
id="form-card-status-switch"
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={field.value === 'ACTIVE'}
|
||||
onClick={() => field.onChange(field.value === 'ACTIVE' ? 'INACTIVE' : 'ACTIVE')}
|
||||
className={`relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-all duration-200 focus:outline-none ${
|
||||
field.value === 'ACTIVE' ? 'bg-emerald-600 dark:bg-emerald-500' : 'bg-zinc-300 dark:bg-zinc-700'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`pointer-events-none block h-4 w-4 rounded-full bg-white shadow transition-all duration-200 ${
|
||||
field.value === 'ACTIVE' ? 'translate-x-4' : 'translate-x-0'
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
<span className="text-[11px] font-bold text-foreground">
|
||||
{field.value === 'ACTIVE' ? '적용 승인' : '적용 대기'}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex items-center gap-3 p-2 bg-muted/60 border border-border/60 rounded-md h-[34px] cursor-not-allowed select-none">
|
||||
<button
|
||||
type="button"
|
||||
disabled
|
||||
className="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border-2 border-transparent transition-all duration-200 bg-blue-400/40 dark:bg-blue-600/30 cursor-not-allowed"
|
||||
>
|
||||
<span className="pointer-events-none block h-4 w-4 rounded-full bg-white/70 dark:bg-zinc-400 translate-x-4" />
|
||||
</button>
|
||||
<span className="text-[11px] text-muted-foreground font-semibold">상시 항상 적용</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">카드이름</Typography>
|
||||
<Input
|
||||
id="form-card-title"
|
||||
type="text"
|
||||
{...register('title')}
|
||||
placeholder="예: 최우수 등급 부여 카드"
|
||||
/>
|
||||
{errors.title && <p className="text-[10px] text-rose-500">{errors.title.message}</p>}
|
||||
</div>
|
||||
|
||||
{/* Script */}
|
||||
<div className="space-y-1.5">
|
||||
<div className="flex items-center justify-between">
|
||||
<Typography as="label" variant="small" className="font-bold flex items-center gap-1.5">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-primary" />
|
||||
스크립트
|
||||
</Typography>
|
||||
<div className="text-[10px] text-muted-foreground bg-muted px-2 py-0.5 rounded border border-border">
|
||||
치환 변수 사용: {'{target_price}'}, {'{partner_name}'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="border border-border rounded-md overflow-hidden bg-background focus-within:border-foreground/30 transition-all">
|
||||
<div className="bg-muted/45 px-3 py-1.5 border-b border-border flex items-center justify-between text-[10px] text-muted-foreground select-none">
|
||||
<span>에디터</span>
|
||||
</div>
|
||||
<textarea
|
||||
id="form-card-script"
|
||||
{...register('scriptPreview')}
|
||||
rows={3}
|
||||
className="w-full p-3 bg-transparent text-xs leading-relaxed resize-none focus:outline-none font-sans border-none"
|
||||
placeholder="협상 중에 상대에게 발송할 멘트 스크립트를 기술하십시오."
|
||||
/>
|
||||
</div>
|
||||
{errors.scriptPreview && <p className="text-[10px] text-rose-500">{errors.scriptPreview.message}</p>}
|
||||
</div>
|
||||
|
||||
{/* Wildcard-only fields */}
|
||||
{isWildcard && (
|
||||
<div className="space-y-4 p-3 bg-muted/40 rounded border border-border">
|
||||
<Typography variant="label" className="font-bold text-[10px] block">와일드카드 세부조항</Typography>
|
||||
<div className="space-y-3 font-mono">
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">사용 조건</Typography>
|
||||
<Input
|
||||
id="form-card-trigger"
|
||||
type="text"
|
||||
{...register('triggerCondition')}
|
||||
placeholder="예: 원부자재 시세가 계약일 대조 3.5% 상회 시"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">메모</Typography>
|
||||
<Input
|
||||
id="form-card-memo"
|
||||
type="text"
|
||||
{...register('memo')}
|
||||
placeholder="예: 특정 원재료 포함 입찰에만 적용"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Footer */}
|
||||
<div className="pt-4 flex items-center gap-2 border-t border-border mt-8">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
className="flex-1 py-1.5 border border-border rounded text-foreground cursor-pointer text-center"
|
||||
>
|
||||
취소
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
id="form-card-submit"
|
||||
className="flex-1 py-1.5 bg-primary text-primary-foreground font-bold rounded hover:opacity-95 cursor-pointer text-center"
|
||||
>
|
||||
{mode === 'create' ? '저장' : '수정'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
311
negodata/front/src/features/cards/components/CardFormSheet.tsx
Normal file
311
negodata/front/src/features/cards/components/CardFormSheet.tsx
Normal file
@ -0,0 +1,311 @@
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { z } from 'zod';
|
||||
import type { Descendant } from 'slate';
|
||||
import { showToast } from '@/lib/notify';
|
||||
import { Typography } from '@/components/ui/typography';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Sheet } from '@/components/ui/sheet';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { type NegotiationCard, type CardTab, generateCardCode } from '../types';
|
||||
import type { CardInput } from '../hooks/useCards';
|
||||
import { CardScriptEditor, deserialize, serializeToText } from '../editor';
|
||||
|
||||
const schema = z.object({
|
||||
isWildcard: z.boolean(),
|
||||
code: z.string().trim().min(1, '카드번호는 필수 기입 사항입니다.'),
|
||||
title: z.string().trim().min(1, '카드이름은 필수 기입 사항입니다.'),
|
||||
editorScript: z
|
||||
.custom<Descendant[]>((v) => Array.isArray(v))
|
||||
.refine((v) => serializeToText(v).trim().length > 0, '스크립트를 작성해 주십시오.'),
|
||||
status: z.enum(['ACTIVE', 'INACTIVE']),
|
||||
triggerCondition: z.string(),
|
||||
memo: z.string(),
|
||||
});
|
||||
|
||||
type FormValues = z.infer<typeof schema>;
|
||||
|
||||
type CardFormSheetProps = {
|
||||
open: boolean;
|
||||
mode: 'create' | 'edit';
|
||||
card: NegotiationCard | null; // edit 모드 초기값 출처
|
||||
activeTab: CardTab; // create 시 기본 카드 종류 결정
|
||||
onCreate: (input: CardInput) => Promise<void>;
|
||||
onUpdate: (id: string, input: CardInput) => Promise<void>;
|
||||
onDelete: (id: string, title: string) => void;
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
function buildDefaults(
|
||||
mode: 'create' | 'edit',
|
||||
card: NegotiationCard | null,
|
||||
activeTab: CardTab,
|
||||
): FormValues {
|
||||
if (mode === 'edit' && card) {
|
||||
return {
|
||||
isWildcard: card.isWildcard,
|
||||
code: card.code,
|
||||
title: card.title,
|
||||
// 저장된 Slate JSON 우선, 없으면 레거시 평문 script 를 변수 노드로 복원.
|
||||
editorScript: deserialize(card.editorScript, card.scriptPreview),
|
||||
status: card.status,
|
||||
triggerCondition: card.triggerCondition || '',
|
||||
memo: card.memo || '',
|
||||
};
|
||||
}
|
||||
const wild = activeTab === 'WILD';
|
||||
return {
|
||||
isWildcard: wild,
|
||||
code: generateCardCode(wild),
|
||||
title: '',
|
||||
editorScript: deserialize(), // 새 빈 값(공용 상수 mutate 방지)
|
||||
status: 'ACTIVE',
|
||||
triggerCondition: '',
|
||||
memo: '',
|
||||
};
|
||||
}
|
||||
|
||||
// 협상카드/와일드카드 등록·수정 우측 드로어 폼. react-hook-form + zod로 검증.
|
||||
// 상품·협력사 폼과 동일하게 공통 Sheet 셸을 쓴다(우측 슬라이드).
|
||||
// 페이지는 key={mode + card?.id}로 리마운트시켜 초기값을 주입한다.
|
||||
export function CardFormSheet({
|
||||
open,
|
||||
mode,
|
||||
card,
|
||||
activeTab,
|
||||
onCreate,
|
||||
onUpdate,
|
||||
onDelete,
|
||||
onClose,
|
||||
}: CardFormSheetProps) {
|
||||
const {
|
||||
register,
|
||||
control,
|
||||
handleSubmit,
|
||||
watch,
|
||||
setValue,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: buildDefaults(mode, card, activeTab),
|
||||
});
|
||||
|
||||
const isWildcard = watch('isWildcard');
|
||||
|
||||
const onValid = async (v: FormValues) => {
|
||||
const input: CardInput = {
|
||||
title: v.title,
|
||||
code: v.code,
|
||||
editorScript: v.editorScript,
|
||||
status: v.status,
|
||||
isWildcard: v.isWildcard,
|
||||
triggerCondition: v.triggerCondition,
|
||||
memo: v.memo,
|
||||
};
|
||||
const kind = v.isWildcard ? '와일드카드' : '협상카드';
|
||||
try {
|
||||
if (mode === 'create') {
|
||||
await onCreate(input);
|
||||
showToast(`${kind}가 추가되었습니다.`, 'success');
|
||||
} else if (card) {
|
||||
await onUpdate(card.id, input);
|
||||
showToast('정보가 수정되었습니다.', 'success');
|
||||
}
|
||||
onClose();
|
||||
} catch (err) {
|
||||
showToast(err instanceof Error ? err.message : `${kind} 저장 실패`, 'error');
|
||||
}
|
||||
};
|
||||
|
||||
const title =
|
||||
mode === 'create'
|
||||
? isWildcard
|
||||
? '신규 와일드카드 등록'
|
||||
: '신규 협상카드 등록'
|
||||
: isWildcard
|
||||
? '와일드카드 정보 수정'
|
||||
: '협상카드 정보 수정';
|
||||
|
||||
return (
|
||||
<Sheet open={open} title={title} onClose={onClose}>
|
||||
<form onSubmit={handleSubmit(onValid)} className="mt-6 space-y-4 text-xs font-mono">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
|
||||
{/* Card Type Selection */}
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">카드 종류</Typography>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isWildcard"
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
value={field.value ? 'WILD' : 'CARD'}
|
||||
onValueChange={(v) => {
|
||||
// 카드 종류는 등록 시에만 정한다(수정 시 테이블 이동 불가 → 고정).
|
||||
if (mode !== 'create') return;
|
||||
const wild = v === 'WILD';
|
||||
field.onChange(wild);
|
||||
setValue('code', generateCardCode(wild));
|
||||
}}
|
||||
>
|
||||
<SelectTrigger id="form-card-is-wildcard" className="w-full" disabled={mode === 'edit'}>
|
||||
<SelectValue>
|
||||
{(value) => (value === 'WILD' ? '와일드카드' : '일반 협상카드')}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="CARD">일반 협상카드</SelectItem>
|
||||
<SelectItem value="WILD">와일드카드</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Code */}
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">카드번호</Typography>
|
||||
<Input
|
||||
id="form-card-code"
|
||||
type="text"
|
||||
{...register('code')}
|
||||
placeholder="CARD-XXX 또는 WILD-XXX"
|
||||
/>
|
||||
{errors.code && <p className="text-[10px] text-rose-500">{errors.code.message}</p>}
|
||||
</div>
|
||||
|
||||
{/* Status */}
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold block mb-1">협상 적용 여부</Typography>
|
||||
{isWildcard ? (
|
||||
<Controller
|
||||
control={control}
|
||||
name="status"
|
||||
render={({ field }) => (
|
||||
<div className="flex items-center gap-3 p-2 bg-muted/30 border border-border rounded-md h-[34px]">
|
||||
<button
|
||||
id="form-card-status-switch"
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={field.value === 'ACTIVE'}
|
||||
onClick={() => field.onChange(field.value === 'ACTIVE' ? 'INACTIVE' : 'ACTIVE')}
|
||||
className={`relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-all duration-200 focus:outline-none ${
|
||||
field.value === 'ACTIVE' ? 'bg-emerald-600 dark:bg-emerald-500' : 'bg-zinc-300 dark:bg-zinc-700'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`pointer-events-none block h-4 w-4 rounded-full bg-white shadow transition-all duration-200 ${
|
||||
field.value === 'ACTIVE' ? 'translate-x-4' : 'translate-x-0'
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
<span className="text-[11px] font-bold text-foreground">
|
||||
{field.value === 'ACTIVE' ? '적용 승인' : '적용 대기'}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex items-center gap-3 p-2 bg-muted/60 border border-border/60 rounded-md h-[34px] cursor-not-allowed select-none">
|
||||
<button
|
||||
type="button"
|
||||
disabled
|
||||
className="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border-2 border-transparent transition-all duration-200 bg-blue-400/40 dark:bg-blue-600/30 cursor-not-allowed"
|
||||
>
|
||||
<span className="pointer-events-none block h-4 w-4 rounded-full bg-white/70 dark:bg-zinc-400 translate-x-4" />
|
||||
</button>
|
||||
<span className="text-[11px] text-muted-foreground font-semibold">상시 항상 적용</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">카드이름</Typography>
|
||||
<Input
|
||||
id="form-card-title"
|
||||
type="text"
|
||||
{...register('title')}
|
||||
placeholder="예: 최우수 등급 부여 카드"
|
||||
/>
|
||||
{errors.title && <p className="text-[10px] text-rose-500">{errors.title.message}</p>}
|
||||
</div>
|
||||
|
||||
{/* Script */}
|
||||
<div className="space-y-1.5">
|
||||
<Typography as="label" variant="small" className="font-bold flex items-center gap-1.5">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-primary" />
|
||||
스크립트
|
||||
</Typography>
|
||||
<Controller
|
||||
control={control}
|
||||
name="editorScript"
|
||||
render={({ field }) => (
|
||||
<CardScriptEditor
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="협상 중에 상대에게 발송할 멘트 스크립트를 기술하십시오. 굵게·색상·변수 칩을 활용하세요."
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.editorScript && (
|
||||
<p className="text-[10px] text-rose-500">{errors.editorScript.message as string}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Wildcard-only fields */}
|
||||
{isWildcard && (
|
||||
<div className="space-y-4 p-3 bg-muted/40 rounded border border-border">
|
||||
<Typography variant="label" className="font-bold text-[10px] block">와일드카드 세부조항</Typography>
|
||||
<div className="space-y-3 font-mono">
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">사용 조건</Typography>
|
||||
<Input
|
||||
id="form-card-trigger"
|
||||
type="text"
|
||||
{...register('triggerCondition')}
|
||||
placeholder="예: 원부자재 시세가 계약일 대조 3.5% 상회 시"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Typography as="label" variant="small" className="font-semibold">메모</Typography>
|
||||
<Input
|
||||
id="form-card-memo"
|
||||
type="text"
|
||||
{...register('memo')}
|
||||
placeholder="예: 특정 원재료 포함 입찰에만 적용"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Footer — 다른 폼 sheet와 동일: 좌측 삭제(edit), 우측 취소/저장 */}
|
||||
<div className="pt-4 flex items-center justify-between gap-2 border-t border-border mt-8">
|
||||
{mode === 'edit' && card && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
onDelete(card.id, card.title);
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
삭제
|
||||
</Button>
|
||||
)}
|
||||
<div className="flex items-center gap-2 flex-1 justify-end">
|
||||
<Button type="button" variant="outline" size="sm" onClick={onClose}>
|
||||
취소
|
||||
</Button>
|
||||
<Button type="submit" id="form-card-submit" size="sm" disabled={isSubmitting}>
|
||||
{mode === 'create' ? '저장' : '수정'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Sheet>
|
||||
);
|
||||
}
|
||||
@ -1,14 +1,12 @@
|
||||
import { Edit3, Trash2 } from 'lucide-react';
|
||||
import { DataTable } from '@/components/ui/data-table';
|
||||
import type { NegotiationCard } from '../types';
|
||||
|
||||
type CardTableProps = {
|
||||
data: NegotiationCard[];
|
||||
onEdit: (card: NegotiationCard) => void;
|
||||
onDelete: (id: string, title: string) => void;
|
||||
};
|
||||
|
||||
export function CardTable({ data, onEdit, onDelete }: CardTableProps) {
|
||||
export function CardTable({ data, onEdit }: CardTableProps) {
|
||||
return (
|
||||
<DataTable
|
||||
data={data}
|
||||
@ -39,6 +37,7 @@ export function CardTable({ data, onEdit, onDelete }: CardTableProps) {
|
||||
{
|
||||
header: '카드이름',
|
||||
headClassName: 'w-52',
|
||||
mobileHeader: true, // 모바일 카드뷰 제목(첫 컬럼 '구분' 배지 대신)
|
||||
cell: (card) => (
|
||||
<>
|
||||
<div className="font-semibold text-foreground text-sm">{card.title}</div>
|
||||
@ -53,8 +52,9 @@ export function CardTable({ data, onEdit, onDelete }: CardTableProps) {
|
||||
{
|
||||
header: '스크립트',
|
||||
cellClassName: 'font-mono text-muted-foreground',
|
||||
mobileBlock: true, // 긴 미리보기 블록 → 모바일 카드뷰에서 라벨 아래 풀폭
|
||||
cell: (card) => (
|
||||
<div className="line-clamp-2 bg-muted/20 p-2.5 rounded border border-border/30 text-[11px] leading-relaxed">
|
||||
<div className="line-clamp-1 bg-muted/20 px-2 py-1 rounded border border-border/30 text-[11px] leading-snug">
|
||||
{card.scriptPreview}
|
||||
</div>
|
||||
),
|
||||
@ -84,35 +84,6 @@ export function CardTable({ data, onEdit, onDelete }: CardTableProps) {
|
||||
<span className="text-muted-foreground font-mono font-medium opacity-65">-</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: '관리',
|
||||
align: 'center',
|
||||
headClassName: 'w-24',
|
||||
cell: (card) => (
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onEdit(card);
|
||||
}}
|
||||
className="p-1.5 text-foreground hover:bg-muted rounded cursor-pointer transition-colors"
|
||||
title="수정"
|
||||
>
|
||||
<Edit3 size={14} />
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onDelete(card.id, card.title);
|
||||
}}
|
||||
className="p-1.5 text-muted-foreground hover:bg-red-50 hover:text-red-500 rounded cursor-pointer transition-colors"
|
||||
title="삭제"
|
||||
>
|
||||
<Trash2 size={14} />
|
||||
</button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
import { useCallback } from 'react';
|
||||
import { Slate, Editable } from 'slate-react';
|
||||
import type { RenderElementProps, RenderLeafProps } from 'slate-react';
|
||||
import type { Descendant } from 'slate';
|
||||
import { useCardScriptEditor } from './useCardScriptEditor';
|
||||
import { CardScriptToolbar } from './CardScriptToolbar';
|
||||
import { variableLabel } from './variables';
|
||||
|
||||
type CardScriptEditorProps = {
|
||||
value: Descendant[]; // 마운트 시 초기값(폼 리마운트로 갱신)
|
||||
onChange: (value: Descendant[]) => void;
|
||||
disabled?: boolean;
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
// 협상카드 스크립트 리치텍스트 에디터. 굵게/밑줄/색상 마크 + {변수} 칩 지원.
|
||||
// 값(Slate JSON)은 폼이 들고, 평문(script) 직렬화는 저장 시 serializeToText 로 파생한다.
|
||||
export function CardScriptEditor({ value, onChange, disabled, placeholder }: CardScriptEditorProps) {
|
||||
const editor = useCardScriptEditor();
|
||||
|
||||
const renderElement = useCallback((props: RenderElementProps) => <Element {...props} />, []);
|
||||
const renderLeaf = useCallback((props: RenderLeafProps) => <Leaf {...props} />, []);
|
||||
|
||||
// 선택(set_selection)만 바뀐 경우는 폼 상태를 건드리지 않는다(불필요한 dirty/검증 방지).
|
||||
const handleChange = (next: Descendant[]) => {
|
||||
const contentChanged = editor.operations.some((op) => op.type !== 'set_selection');
|
||||
if (contentChanged) onChange(next);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="border border-border rounded-md overflow-hidden bg-background focus-within:border-foreground/30 transition-all">
|
||||
<Slate editor={editor} initialValue={value} onChange={handleChange}>
|
||||
{!disabled && <CardScriptToolbar />}
|
||||
<Editable
|
||||
readOnly={disabled}
|
||||
spellCheck={false}
|
||||
renderElement={renderElement}
|
||||
renderLeaf={renderLeaf}
|
||||
placeholder={placeholder}
|
||||
className="min-h-[88px] w-full p-3 text-xs leading-relaxed font-sans focus:outline-none [&_[data-slate-placeholder]]:text-muted-foreground"
|
||||
/>
|
||||
</Slate>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Leaf({ attributes, children, leaf }: RenderLeafProps) {
|
||||
let node = children;
|
||||
if (leaf.bold) node = <strong>{node}</strong>;
|
||||
if (leaf.underline) node = <u>{node}</u>;
|
||||
return (
|
||||
<span {...attributes} style={leaf.color ? { color: leaf.color } : undefined}>
|
||||
{node}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// 인라인 void 옆에 커서를 못 두는 Chromium 버그 회피용 zero-width 스페이서(Slate 공식 패턴).
|
||||
const InlineChromiumBugfix = () => (
|
||||
<span contentEditable={false} style={{ fontSize: 0 }}>
|
||||
{String.fromCodePoint(160) /* nbsp */}
|
||||
</span>
|
||||
);
|
||||
|
||||
function Element(props: RenderElementProps) {
|
||||
const { attributes, children, element } = props;
|
||||
if (element.type === 'variable') {
|
||||
return (
|
||||
<span
|
||||
{...attributes}
|
||||
contentEditable={false}
|
||||
className="mx-0.5 rounded-md border border-amber-300/60 bg-amber-100/70 px-1.5 py-0.5 text-[11px] font-semibold text-amber-900 dark:border-amber-400/30 dark:bg-amber-400/15 dark:text-amber-200"
|
||||
>
|
||||
<InlineChromiumBugfix />
|
||||
{variableLabel(element.name)}
|
||||
{children}
|
||||
<InlineChromiumBugfix />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return <p {...attributes}>{children}</p>;
|
||||
}
|
||||
111
negodata/front/src/features/cards/editor/CardScriptToolbar.tsx
Normal file
111
negodata/front/src/features/cards/editor/CardScriptToolbar.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
import type { MouseEvent, ReactNode } from 'react';
|
||||
import { useSlate } from 'slate-react';
|
||||
import { Bold, Underline } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import {
|
||||
activeColor,
|
||||
isMarkActive,
|
||||
insertVariable,
|
||||
setColor,
|
||||
toggleMark,
|
||||
type TextMark,
|
||||
} from './slate';
|
||||
import { CARD_VARIABLES } from './variables';
|
||||
|
||||
// 색상 프리셋 — 기본/강조(빨강)/보조(파랑).
|
||||
// negowiz 동일 프리셋: 검정 / 빨강 / 파랑.
|
||||
const COLORS: { value: string; label: string }[] = [
|
||||
{ value: '#151515', label: '검정' },
|
||||
{ value: '#ED2024', label: '빨강' },
|
||||
{ value: '#4880EF', label: '파랑' },
|
||||
];
|
||||
|
||||
// 툴바 버튼은 onMouseDown + preventDefault 로 에디터 선택/포커스를 유지해야 한다(클릭 시 blur 방지).
|
||||
function hold(handler: () => void) {
|
||||
return (e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
handler();
|
||||
};
|
||||
}
|
||||
|
||||
export function CardScriptToolbar() {
|
||||
const editor = useSlate();
|
||||
const curColor = activeColor(editor);
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap items-center gap-1 bg-muted/45 px-2 py-1.5 border-b border-border select-none">
|
||||
<MarkButton mark="bold" active={isMarkActive(editor, 'bold')} onToggle={() => toggleMark(editor, 'bold')}>
|
||||
<Bold size={13} />
|
||||
</MarkButton>
|
||||
<MarkButton
|
||||
mark="underline"
|
||||
active={isMarkActive(editor, 'underline')}
|
||||
onToggle={() => toggleMark(editor, 'underline')}
|
||||
>
|
||||
<Underline size={13} />
|
||||
</MarkButton>
|
||||
|
||||
<Divider />
|
||||
|
||||
{COLORS.map((c) => (
|
||||
<button
|
||||
key={c.value}
|
||||
type="button"
|
||||
title={`색상: ${c.label}`}
|
||||
onMouseDown={hold(() => setColor(editor, c.value))}
|
||||
className={cn(
|
||||
'h-5 w-5 rounded-full border transition-all',
|
||||
curColor === c.value ? 'ring-2 ring-foreground/40 ring-offset-1' : 'border-border',
|
||||
)}
|
||||
style={{ backgroundColor: c.value }}
|
||||
/>
|
||||
))}
|
||||
|
||||
<Divider />
|
||||
|
||||
<span className="text-[10px] text-muted-foreground mr-0.5">변수</span>
|
||||
{CARD_VARIABLES.map((v) => (
|
||||
<button
|
||||
key={v.name}
|
||||
type="button"
|
||||
title={`{${v.name}} 삽입`}
|
||||
onMouseDown={hold(() => insertVariable(editor, v.name))}
|
||||
className="px-1.5 py-0.5 rounded border border-border bg-background text-[10px] font-semibold text-foreground hover:bg-muted cursor-pointer"
|
||||
>
|
||||
{v.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function MarkButton({
|
||||
mark,
|
||||
active,
|
||||
onToggle,
|
||||
children,
|
||||
}: {
|
||||
mark: TextMark;
|
||||
active: boolean;
|
||||
onToggle: () => void;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
aria-pressed={active}
|
||||
title={mark === 'bold' ? '굵게' : '밑줄'}
|
||||
onMouseDown={hold(onToggle)}
|
||||
className={cn(
|
||||
'flex h-6 w-6 items-center justify-center rounded border transition-all cursor-pointer',
|
||||
active
|
||||
? 'bg-foreground text-background border-foreground'
|
||||
: 'bg-background text-foreground border-border hover:bg-muted',
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
const Divider = () => <span className="mx-1 h-4 w-px bg-border" />;
|
||||
4
negodata/front/src/features/cards/editor/index.ts
Normal file
4
negodata/front/src/features/cards/editor/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export { CardScriptEditor } from './CardScriptEditor';
|
||||
// deserialize() 는 항상 새 배열을 반환 → Slate initialValue 로 안전. 공용 mutable 상수는 export 하지 않는다.
|
||||
export { deserialize, serializeToText } from './slate';
|
||||
export { CARD_VARIABLES } from './variables';
|
||||
144
negodata/front/src/features/cards/editor/slate.ts
Normal file
144
negodata/front/src/features/cards/editor/slate.ts
Normal file
@ -0,0 +1,144 @@
|
||||
import { createEditor, Editor, Element as SlateElement, Transforms } from 'slate';
|
||||
import type { BaseEditor, Descendant } from 'slate';
|
||||
import type { ReactEditor } from 'slate-react';
|
||||
import type { HistoryEditor } from 'slate-history';
|
||||
import { isKnownVariable } from './variables';
|
||||
|
||||
// ── 스키마 ────────────────────────────────────────────────
|
||||
// negowiz 는 곳곳에서 `as any` 로 노드 타입을 우회했지만, 여기선 Slate 의 CustomTypes
|
||||
// 모듈 보강으로 editor/element/text 를 정적 타입화한다(툴바·렌더·커맨드 전부 타입 안전).
|
||||
export type TextMark = 'bold' | 'underline';
|
||||
|
||||
export type CustomText = {
|
||||
text: string;
|
||||
bold?: boolean;
|
||||
underline?: boolean;
|
||||
color?: string; // 색상 코드(#RRGGBB)
|
||||
};
|
||||
|
||||
export type VariableElement = {
|
||||
type: 'variable';
|
||||
name: string; // CardVariable.name
|
||||
children: CustomText[]; // void 라 비어있음([{text:''}])
|
||||
};
|
||||
|
||||
export type ParagraphElement = {
|
||||
type: 'paragraph';
|
||||
children: (CustomText | VariableElement)[];
|
||||
};
|
||||
|
||||
export type CustomElement = ParagraphElement | VariableElement;
|
||||
|
||||
declare module 'slate' {
|
||||
interface CustomTypes {
|
||||
Editor: BaseEditor & ReactEditor & HistoryEditor;
|
||||
Element: CustomElement;
|
||||
Text: CustomText;
|
||||
}
|
||||
}
|
||||
|
||||
// 항상 새 배열을 만든다(Slate 가 initialValue 를 직접 mutate 하므로 공유 금지).
|
||||
const cloneEmpty = (): Descendant[] => [{ type: 'paragraph', children: [{ text: '' }] }];
|
||||
|
||||
// ── 플러그인 ──────────────────────────────────────────────
|
||||
// 변수 노드를 인라인 + void(내용 수정 불가) + markableVoid(마크는 허용)로 동작시킨다.
|
||||
export function withVariables<T extends Editor>(editor: T): T {
|
||||
const { isInline, isVoid, markableVoid } = editor;
|
||||
editor.isInline = (el) => el.type === 'variable' || isInline(el);
|
||||
editor.isVoid = (el) => el.type === 'variable' || isVoid(el);
|
||||
editor.markableVoid = (el) => el.type === 'variable' || markableVoid(el);
|
||||
return editor;
|
||||
}
|
||||
|
||||
export const createCardEditor = () => createEditor();
|
||||
|
||||
// ── 마크/색상/변수 커맨드 ──────────────────────────────────
|
||||
export function isMarkActive(editor: Editor, mark: TextMark): boolean {
|
||||
const marks = Editor.marks(editor);
|
||||
return marks ? marks[mark] === true : false;
|
||||
}
|
||||
|
||||
export function toggleMark(editor: Editor, mark: TextMark): void {
|
||||
if (isMarkActive(editor, mark)) Editor.removeMark(editor, mark);
|
||||
else Editor.addMark(editor, mark, true);
|
||||
}
|
||||
|
||||
export function activeColor(editor: Editor): string | undefined {
|
||||
const marks = Editor.marks(editor) as CustomText | null;
|
||||
return marks?.color;
|
||||
}
|
||||
|
||||
export function setColor(editor: Editor, color: string): void {
|
||||
Editor.addMark(editor, 'color', color);
|
||||
}
|
||||
|
||||
export function clearColor(editor: Editor): void {
|
||||
Editor.removeMark(editor, 'color');
|
||||
}
|
||||
|
||||
export function insertVariable(editor: Editor, name: string): void {
|
||||
const node: VariableElement = { type: 'variable', name, children: [{ text: '' }] };
|
||||
Transforms.insertNodes(editor, node);
|
||||
Transforms.move(editor); // 삽입된 void 뒤로 커서 이동
|
||||
}
|
||||
|
||||
// ── 직렬화: Slate 값 → 평문(script) ─────────────────────────
|
||||
// 변수는 {name} 토큰으로, 마크는 버리고 텍스트만. 백엔드 script(미리보기) 컬럼에 저장.
|
||||
export function serializeToText(nodes: Descendant[]): string {
|
||||
return nodes.map(serializeNode).join('\n');
|
||||
}
|
||||
|
||||
function serializeNode(node: Descendant): string {
|
||||
if (SlateElement.isElement(node)) {
|
||||
if (node.type === 'variable') return `{${node.name}}`;
|
||||
return node.children.map(serializeNode).join('');
|
||||
}
|
||||
return node.text;
|
||||
}
|
||||
|
||||
// ── 역직렬화: edit_script(JSON) 또는 평문(script) → Slate 값 ──
|
||||
// 저장된 edit_script 가 있으면 그대로, 없으면(레거시 평문 카드) {name} 토큰을 변수 노드로 복원.
|
||||
// Slate 는 initialValue 를 레퍼런스로 직접 변경하므로 항상 새 배열을 돌려준다
|
||||
// (react-query 캐시·공용 상수 오염 방지).
|
||||
export function deserialize(editScript?: unknown, plainText?: string): Descendant[] {
|
||||
if (Array.isArray(editScript) && editScript.length > 0) {
|
||||
return JSON.parse(JSON.stringify(editScript)) as Descendant[];
|
||||
}
|
||||
if (plainText && plainText.trim()) return textToNodes(plainText);
|
||||
return cloneEmpty();
|
||||
}
|
||||
|
||||
function textToNodes(text: string): Descendant[] {
|
||||
return text.split('\n').map((line) => ({ type: 'paragraph' as const, children: lineToChildren(line) }));
|
||||
}
|
||||
|
||||
function lineToChildren(line: string): (CustomText | VariableElement)[] {
|
||||
const children: (CustomText | VariableElement)[] = [];
|
||||
const re = /\{(\w+)\}/g;
|
||||
let last = 0;
|
||||
let m: RegExpExecArray | null;
|
||||
while ((m = re.exec(line)) !== null) {
|
||||
if (m.index > last) children.push({ text: line.slice(last, m.index) });
|
||||
if (isKnownVariable(m[1])) children.push({ type: 'variable', name: m[1], children: [{ text: '' }] });
|
||||
else children.push({ text: m[0] }); // 미등록 토큰은 평문 그대로
|
||||
last = re.lastIndex;
|
||||
}
|
||||
if (last < line.length) children.push({ text: line.slice(last) });
|
||||
return ensureTextEdges(children);
|
||||
}
|
||||
|
||||
// 인라인 void(변수)는 앞뒤·사이에 텍스트 노드가 있어야 한다(Slate normalize 규칙 선반영).
|
||||
function ensureTextEdges(
|
||||
children: (CustomText | VariableElement)[],
|
||||
): (CustomText | VariableElement)[] {
|
||||
const out: (CustomText | VariableElement)[] = [];
|
||||
for (const child of children) {
|
||||
const isVar = 'type' in child;
|
||||
const prev = out[out.length - 1];
|
||||
if (isVar && (!prev || 'type' in prev)) out.push({ text: '' });
|
||||
out.push(child);
|
||||
}
|
||||
const last = out[out.length - 1];
|
||||
if (!out.length || (last && 'type' in last)) out.push({ text: '' });
|
||||
return out;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
import { useMemo } from 'react';
|
||||
import { withReact } from 'slate-react';
|
||||
import { withHistory } from 'slate-history';
|
||||
import { createCardEditor, withVariables } from './slate';
|
||||
|
||||
// 카드 스크립트용 Slate 에디터 인스턴스.
|
||||
// 조합 순서: createEditor → withReact(React 바인딩) → withHistory(undo/redo) → withVariables(변수 노드).
|
||||
export function useCardScriptEditor() {
|
||||
return useMemo(() => withVariables(withHistory(withReact(createCardEditor()))), []);
|
||||
}
|
||||
22
negodata/front/src/features/cards/editor/variables.ts
Normal file
22
negodata/front/src/features/cards/editor/variables.ts
Normal file
@ -0,0 +1,22 @@
|
||||
// 협상카드 스크립트에 끼워 넣는 치환 변수 카탈로그.
|
||||
// negowiz 는 Zustand 전역 스토어로 들고 있었지만, 여기선 결합도를 낮추려 순수 상수로 둔다.
|
||||
// 저장 포맷의 토큰은 {name} (단일 중괄호) — 백엔드/기존 카드 hint 와 동일 표기.
|
||||
|
||||
export type CardVariable = {
|
||||
name: string; // 토큰/직렬화 키 (예: target_price)
|
||||
label: string; // 칩·툴바에 보이는 한글 라벨 (예: 목표가)
|
||||
};
|
||||
|
||||
export const CARD_VARIABLES: CardVariable[] = [
|
||||
{ name: 'target_price', label: '목표가' },
|
||||
{ name: 'anchor_price', label: '앵커가' },
|
||||
{ name: 'partner_name', label: '협력사명' },
|
||||
{ name: 'product_name', label: '상품명' },
|
||||
];
|
||||
|
||||
const VARIABLE_NAMES = new Set(CARD_VARIABLES.map((v) => v.name));
|
||||
|
||||
export const isKnownVariable = (name: string): boolean => VARIABLE_NAMES.has(name);
|
||||
|
||||
export const variableLabel = (name: string): string =>
|
||||
CARD_VARIABLES.find((v) => v.name === name)?.label ?? name;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user