diff --git a/app/dashboard/assets/page.tsx b/app/dashboard/assets/page.tsx
index fca5edb..8679f11 100644
--- a/app/dashboard/assets/page.tsx
+++ b/app/dashboard/assets/page.tsx
@@ -1,6 +1,6 @@
import { getAssets } from '@/actions/asset';
import { AddAssetDialog } from '@/components/assets/add-asset-dialog';
-import { UpdatePriceDialog } from '@/components/assets/update-price-dialog';
+import { SyncButton } from '@/components/assets/sync-button';
import {
Table,
TableBody,
@@ -25,7 +25,10 @@ export default async function AssetsPage() {
@@ -38,13 +41,12 @@ export default async function AssetsPage() {
基礎幣種
當前市價 (Latest Price)
創建時間
-
操作
{assets.length === 0 ? (
-
+
暫無資產,點擊"添加資產"按鈕錄入第一個資產
@@ -60,9 +62,6 @@ export default async function AssetsPage() {
? new Date(asset.createdAt).toLocaleString('zh-CN')
: '-'}
-
-
-
))
)}
diff --git a/package-lock.json b/package-lock.json
index 29995b3..e4d1262 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,6 +29,7 @@
"recharts": "^3.8.1",
"tailwind-merge": "^3.5.0",
"tailwindcss-animate": "^1.0.7",
+ "yahoo-finance2": "^3.14.0",
"zod": "^4.3.6"
},
"devDependencies": {
@@ -299,6 +300,46 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@deno/shim-deno": {
+ "version": "0.18.2",
+ "resolved": "https://registry.npmmirror.com/@deno/shim-deno/-/shim-deno-0.18.2.tgz",
+ "integrity": "sha512-oQ0CVmOio63wlhwQF75zA4ioolPvOwAoK0yuzcS5bDC1JUvH3y1GS8xPh8EOpcoDQRU4FTG8OQfxhpR+c6DrzA==",
+ "license": "MIT",
+ "dependencies": {
+ "@deno/shim-deno-test": "^0.5.0",
+ "which": "^4.0.0"
+ }
+ },
+ "node_modules/@deno/shim-deno-test": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmmirror.com/@deno/shim-deno-test/-/shim-deno-test-0.5.0.tgz",
+ "integrity": "sha512-4nMhecpGlPi0cSzT67L+Tm+GOJqvuk8gqHBziqcUQOarnuIax1z96/gJHCSIz2Z0zhxE6Rzwb3IZXPtFh51j+w==",
+ "license": "MIT"
+ },
+ "node_modules/@deno/shim-deno/node_modules/isexe": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-3.1.5.tgz",
+ "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@deno/shim-deno/node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
"node_modules/@drizzle-team/brocli": {
"version": "0.10.2",
"resolved": "https://registry.npmmirror.com/@drizzle-team/brocli/-/brocli-0.10.2.tgz",
@@ -4547,7 +4588,6 @@
"version": "4.4.3",
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -5556,6 +5596,16 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fetch-mock-cache": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/fetch-mock-cache/-/fetch-mock-cache-2.3.1.tgz",
+ "integrity": "sha512-hDk+Nbt0Y8Aq7KTEU6ASQAcpB34UjhkpD3QjzD6yvEKP4xVElAqXrjQ7maL+LYMGafx51Zq6qUfDM57PNu/qMw==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4",
+ "filenamify-url": "2.1.2"
+ }
+ },
"node_modules/file-entry-cache": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
@@ -5569,6 +5619,48 @@
"node": ">=16.0.0"
}
},
+ "node_modules/filename-reserved-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
+ "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/filenamify": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/filenamify/-/filenamify-4.3.0.tgz",
+ "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==",
+ "license": "MIT",
+ "dependencies": {
+ "filename-reserved-regex": "^2.0.0",
+ "strip-outer": "^1.0.1",
+ "trim-repeated": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/filenamify-url": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/filenamify-url/-/filenamify-url-2.1.2.tgz",
+ "integrity": "sha512-3rMbAr7vDNMOGsj1aMniQFl749QjgM+lMJ/77ZRSPTIgxvolZwoQbn8dXLs7xfd+hAdli+oTnSWZNkJJLWQFEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "filenamify": "^4.3.0",
+ "humanize-url": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
@@ -5967,6 +6059,18 @@
"hermes-estree": "0.25.1"
}
},
+ "node_modules/humanize-url": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/humanize-url/-/humanize-url-2.1.1.tgz",
+ "integrity": "sha512-V4nxsPGNE7mPjr1qDp471YfW8nhBiTRWrG/4usZlpvFU8I7gsV7Jvrrzv/snbLm5dWO3dr1ennu2YqnhTWFmYA==",
+ "license": "MIT",
+ "dependencies": {
+ "normalize-url": "^4.5.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz",
@@ -6542,6 +6646,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "license": "(AFL-2.1 OR BSD-3-Clause)"
+ },
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -6761,7 +6871,6 @@
"version": "2.1.3",
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
"license": "MIT"
},
"node_modules/mz": {
@@ -6942,6 +7051,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/normalize-url": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmmirror.com/normalize-url/-/normalize-url-4.5.1.tgz",
+ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
@@ -7396,16 +7514,33 @@
"react-is": "^16.13.1"
}
},
+ "node_modules/psl": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmmirror.com/psl/-/psl-1.15.0.tgz",
+ "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/lupomontero"
+ }
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
+ "node_modules/querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "license": "MIT"
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -7671,6 +7806,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "license": "MIT"
+ },
"node_modules/reselect": {
"version": "5.1.1",
"resolved": "https://registry.npmmirror.com/reselect/-/reselect-5.1.1.tgz",
@@ -8218,6 +8359,27 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/strip-outer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/strip-outer/-/strip-outer-1.0.1.tgz",
+ "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-outer/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/styled-jsx": {
"version": "5.1.6",
"resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.6.tgz",
@@ -8500,6 +8662,24 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmmirror.com/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmmirror.com/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "license": "MIT"
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -8512,6 +8692,66 @@
"node": ">=8.0"
}
},
+ "node_modules/tough-cookie": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tldts": "^6.1.32"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tough-cookie-file-store": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/tough-cookie-file-store/-/tough-cookie-file-store-2.0.3.tgz",
+ "integrity": "sha512-sMpZVcmFf6EYFHFFl+SYH4W1/OnXBYMGDsv2IlbQ2caHyFElW/UR/gpj/KYU1JwmP4dE9xqwv2+vWcmlXHojSw==",
+ "license": "MIT",
+ "dependencies": {
+ "tough-cookie": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tough-cookie-file-store/node_modules/tough-cookie": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-4.1.4.tgz",
+ "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/trim-repeated": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/trim-repeated/-/trim-repeated-1.0.0.tgz",
+ "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/trim-repeated/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/ts-api-utils": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
@@ -9222,6 +9462,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
"node_modules/unrs-resolver": {
"version": "1.11.1",
"resolved": "https://registry.npmmirror.com/unrs-resolver/-/unrs-resolver-1.11.1.tgz",
@@ -9298,6 +9547,16 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
"node_modules/use-callback-ref": {
"version": "1.3.3",
"resolved": "https://registry.npmmirror.com/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
@@ -9493,6 +9752,25 @@
"node": ">=0.10.0"
}
},
+ "node_modules/yahoo-finance2": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmmirror.com/yahoo-finance2/-/yahoo-finance2-3.14.0.tgz",
+ "integrity": "sha512-gsT/tqgeizKtMxbIIWFiFyuhM/6MZE4yEyNLmPekr88AX14JL2HWw0/QNMOR081jVtzTjihqDW0zV7IayH1Wcw==",
+ "license": "MIT",
+ "dependencies": {
+ "@deno/shim-deno": "~0.18.0",
+ "fetch-mock-cache": "npm:fetch-mock-cache@^2.1.3",
+ "json-schema": "^0.4.0",
+ "tough-cookie": "npm:tough-cookie@^5.1.1",
+ "tough-cookie-file-store": "npm:tough-cookie-file-store@^2.0.3"
+ },
+ "bin": {
+ "yahoo-finance": "esm/bin/yahoo-finance.js"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
diff --git a/package.json b/package.json
index 8574403..c365d24 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
"recharts": "^3.8.1",
"tailwind-merge": "^3.5.0",
"tailwindcss-animate": "^1.0.7",
+ "yahoo-finance2": "^3.14.0",
"zod": "^4.3.6"
},
"devDependencies": {
diff --git a/src/actions/market.ts b/src/actions/market.ts
new file mode 100644
index 0000000..303f473
--- /dev/null
+++ b/src/actions/market.ts
@@ -0,0 +1,36 @@
+'use server';
+
+import yahooFinance from 'yahoo-finance2';
+import { db } from '@/db';
+import { assets } from '@/db/schema';
+import { eq } from 'drizzle-orm';
+import { revalidatePath } from 'next/cache';
+
+export async function syncAllStockPrices() {
+ const stockAssets = await db
+ .select()
+ .from(assets)
+ .where(eq(assets.type, 'STOCK'));
+
+ let successCount = 0;
+
+ for (const asset of stockAssets) {
+ try {
+ const quote = await yahooFinance.quote(asset.symbol);
+ if (quote && quote.regularMarketPrice !== undefined) {
+ await db
+ .update(assets)
+ .set({ latestPrice: quote.regularMarketPrice.toString() })
+ .where(eq(assets.id, asset.id));
+ successCount++;
+ }
+ } catch (error) {
+ console.error(`Failed to fetch price for ${asset.symbol}:`, error);
+ }
+ }
+
+ revalidatePath('/dashboard');
+ revalidatePath('/dashboard/assets');
+
+ return { success: true, count: successCount };
+}
diff --git a/src/components/assets/sync-button.tsx b/src/components/assets/sync-button.tsx
new file mode 100644
index 0000000..d416187
--- /dev/null
+++ b/src/components/assets/sync-button.tsx
@@ -0,0 +1,23 @@
+'use client';
+
+import { useState, useTransition } from 'react';
+import { Button } from '@/components/ui/button';
+import { RefreshCw } from 'lucide-react';
+import { syncAllStockPrices } from '@/actions/market';
+
+export function SyncButton() {
+ const [isPending, startTransition] = useTransition();
+
+ function handleClick() {
+ startTransition(async () => {
+ await syncAllStockPrices();
+ });
+ }
+
+ return (
+
+ );
+}
diff --git a/src/components/assets/update-price-dialog.tsx b/src/components/assets/update-price-dialog.tsx
deleted file mode 100644
index c161fb3..0000000
--- a/src/components/assets/update-price-dialog.tsx
+++ /dev/null
@@ -1,101 +0,0 @@
-'use client';
-
-import { useState, useTransition } from 'react';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { z } from 'zod';
-import { useForm } from 'react-hook-form';
-import { useRouter } from 'next/navigation';
-import {
- Dialog,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogTitle,
- DialogTrigger,
-} from '@/components/ui/dialog';
-import { Button } from '@/components/ui/button';
-import { Input } from '@/components/ui/input';
-import {
- Form,
- FormControl,
- FormField,
- FormItem,
- FormLabel,
- FormMessage,
-} from '@/components/ui/form';
-import { RefreshCw } from 'lucide-react';
-import { updateAssetPrice } from '@/actions/asset';
-
-const updatePriceSchema = z.object({
- newPrice: z.string().min(1, '價格不能為空'),
-});
-
-type UpdatePriceForm = z.infer;
-
-interface UpdatePriceDialogProps {
- assetId: string;
- currentPrice: string;
-}
-
-export function UpdatePriceDialog({ assetId, currentPrice }: UpdatePriceDialogProps) {
- const [open, setOpen] = useState(false);
- const [isPending, startTransition] = useTransition();
- const router = useRouter();
-
- const form = useForm({
- resolver: zodResolver(updatePriceSchema),
- defaultValues: {
- newPrice: currentPrice,
- },
- });
-
- function onSubmit(values: UpdatePriceForm) {
- startTransition(async () => {
- await updateAssetPrice({ assetId, newPrice: values.newPrice });
- setOpen(false);
- router.refresh();
- });
- }
-
- return (
-
- );
-}