Major redesign: Enhanced card display with particle effects, improved filters, and search functionality
- Redesigned card display with 2.5:3.5 aspect ratio and image-only view - Added infinite scroll to replace pagination - Implemented authentic card back placeholders for MTG, Pokemon, and Lorcana - Added rarity-based particle effects with tiered intensity (mythic/enchanted/rare/uncommon) - Enhanced hover details panel with structured card information - Fixed search functionality with debouncing and Enter key support - Improved filter system with working TCG, rarity, set, and price filters - Added favorite system for cards in both hover and detail views - Updated card detail page with comprehensive metadata and actions - Fixed API filtering with proper Vercel Postgres implementation - Added particle animations and rarity glow effects - Improved overall UX with better visual hierarchy and interactions
This commit is contained in:
parent
c218dd53ac
commit
e75a4a6649
184 changed files with 14431 additions and 10491 deletions
38
.next/build-manifest.json
Normal file
38
.next/build-manifest.json
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"polyfillFiles": [
|
||||||
|
"static/chunks/polyfills.js"
|
||||||
|
],
|
||||||
|
"devFiles": [
|
||||||
|
"static/chunks/react-refresh.js"
|
||||||
|
],
|
||||||
|
"ampDevFiles": [],
|
||||||
|
"lowPriorityFiles": [
|
||||||
|
"static/development/_buildManifest.js",
|
||||||
|
"static/development/_ssgManifest.js"
|
||||||
|
],
|
||||||
|
"rootMainFiles": [],
|
||||||
|
"rootMainFilesTree": {},
|
||||||
|
"pages": {
|
||||||
|
"/_app": [
|
||||||
|
"static/chunks/webpack.js",
|
||||||
|
"static/chunks/main.js",
|
||||||
|
"static/chunks/pages/_app.js"
|
||||||
|
],
|
||||||
|
"/_error": [
|
||||||
|
"static/chunks/webpack.js",
|
||||||
|
"static/chunks/main.js",
|
||||||
|
"static/chunks/pages/_error.js"
|
||||||
|
],
|
||||||
|
"/admin/card-import": [
|
||||||
|
"static/chunks/webpack.js",
|
||||||
|
"static/chunks/main.js",
|
||||||
|
"static/chunks/pages/admin/card-import.js"
|
||||||
|
],
|
||||||
|
"/cards": [
|
||||||
|
"static/chunks/webpack.js",
|
||||||
|
"static/chunks/main.js",
|
||||||
|
"static/chunks/pages/cards.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ampFirstPages": []
|
||||||
|
}
|
||||||
1
.next/cache/.rscinfo
vendored
Normal file
1
.next/cache/.rscinfo
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"encryption.key":"o/3/KjisNjAoqH8UnTw+YIJZ5yKpbxNOeTedTrWeK48=","encryption.expire_at":1754507955052}
|
||||||
BIN
.next/cache/webpack/client-development-fallback/0.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development-fallback/0.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development-fallback/index.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development-fallback/index.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/0.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/0.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/1.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/1.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/10.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/10.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/11.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/11.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/12.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/12.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/13.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/13.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/14.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/14.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/15.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/15.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/2.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/2.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/3.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/3.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/4.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/4.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/5.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/5.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/6.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/6.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/7.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/7.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/8.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/8.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/9.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/9.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/index.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/client-development/index.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/client-development/index.pack.gz.old
vendored
Normal file
BIN
.next/cache/webpack/client-development/index.pack.gz.old
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/0.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/0.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/1.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/1.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/10.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/10.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/11.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/11.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/12.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/12.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/13.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/13.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/14.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/14.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/15.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/15.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/16.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/16.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/17.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/17.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/18.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/18.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/19.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/19.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/2.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/2.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/20.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/20.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/21.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/21.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/22.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/22.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/23.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/23.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/24.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/24.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/3.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/3.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/4.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/4.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/5.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/5.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/6.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/6.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/7.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/7.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/8.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/8.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/9.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/9.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/index.pack.gz
vendored
Normal file
BIN
.next/cache/webpack/server-development/index.pack.gz
vendored
Normal file
Binary file not shown.
BIN
.next/cache/webpack/server-development/index.pack.gz.old
vendored
Normal file
BIN
.next/cache/webpack/server-development/index.pack.gz.old
vendored
Normal file
Binary file not shown.
1
.next/package.json
Normal file
1
.next/package.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"type": "commonjs"}
|
||||||
11
.next/prerender-manifest.json
Normal file
11
.next/prerender-manifest.json
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"version": 4,
|
||||||
|
"routes": {},
|
||||||
|
"dynamicRoutes": {},
|
||||||
|
"notFoundRoutes": [],
|
||||||
|
"preview": {
|
||||||
|
"previewModeId": "ac69d87d469cfc0883867cbac62985a1",
|
||||||
|
"previewModeSigningKey": "f42e8072c0ccf0a25b633a0cca347d2ff35cf4136bc15882d176886cd9588e37",
|
||||||
|
"previewModeEncryptionKey": "c73779c91ac71021885e2cccce8a37ae8601cfca2f618e58f8dea7b27938b2a3"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
.next/react-loadable-manifest.json
Normal file
1
.next/react-loadable-manifest.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
||||||
1
.next/routes-manifest.json
Normal file
1
.next/routes-manifest.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"caseSensitive":false,"basePath":"","rewrites":{"beforeFiles":[],"afterFiles":[],"fallback":[]},"redirects":[{"source":"/:path+/","destination":"/:path+","permanent":true,"internal":true,"regex":"^(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))\\/$"}],"headers":[]}
|
||||||
211
.next/server/_error.js
Normal file
211
.next/server/_error.js
Normal file
File diff suppressed because one or more lines are too long
1
.next/server/interception-route-rewrite-manifest.js
Normal file
1
.next/server/interception-route-rewrite-manifest.js
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
self.__INTERCEPTION_ROUTE_REWRITE_MANIFEST="[]"
|
||||||
40
.next/server/middleware-build-manifest.js
Normal file
40
.next/server/middleware-build-manifest.js
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
globalThis.__BUILD_MANIFEST = {
|
||||||
|
"polyfillFiles": [
|
||||||
|
"static/chunks/polyfills.js"
|
||||||
|
],
|
||||||
|
"devFiles": [
|
||||||
|
"static/chunks/react-refresh.js"
|
||||||
|
],
|
||||||
|
"ampDevFiles": [],
|
||||||
|
"lowPriorityFiles": [],
|
||||||
|
"rootMainFiles": [],
|
||||||
|
"rootMainFilesTree": {},
|
||||||
|
"pages": {
|
||||||
|
"/_app": [
|
||||||
|
"static/chunks/webpack.js",
|
||||||
|
"static/chunks/main.js",
|
||||||
|
"static/chunks/pages/_app.js"
|
||||||
|
],
|
||||||
|
"/_error": [
|
||||||
|
"static/chunks/webpack.js",
|
||||||
|
"static/chunks/main.js",
|
||||||
|
"static/chunks/pages/_error.js"
|
||||||
|
],
|
||||||
|
"/admin/card-import": [
|
||||||
|
"static/chunks/webpack.js",
|
||||||
|
"static/chunks/main.js",
|
||||||
|
"static/chunks/pages/admin/card-import.js"
|
||||||
|
],
|
||||||
|
"/cards": [
|
||||||
|
"static/chunks/webpack.js",
|
||||||
|
"static/chunks/main.js",
|
||||||
|
"static/chunks/pages/cards.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ampFirstPages": []
|
||||||
|
};
|
||||||
|
globalThis.__BUILD_MANIFEST.lowPriorityFiles = [
|
||||||
|
"/static/" + process.env.__NEXT_BUILD_ID + "/_buildManifest.js",
|
||||||
|
,"/static/" + process.env.__NEXT_BUILD_ID + "/_ssgManifest.js",
|
||||||
|
|
||||||
|
];
|
||||||
6
.next/server/middleware-manifest.json
Normal file
6
.next/server/middleware-manifest.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"middleware": {},
|
||||||
|
"functions": {},
|
||||||
|
"sortedMiddleware": []
|
||||||
|
}
|
||||||
1
.next/server/middleware-react-loadable-manifest.js
Normal file
1
.next/server/middleware-react-loadable-manifest.js
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
self.__REACT_LOADABLE_MANIFEST="{}"
|
||||||
1
.next/server/next-font-manifest.js
Normal file
1
.next/server/next-font-manifest.js
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
self.__NEXT_FONT_MANIFEST="{\"pages\":{},\"app\":{},\"appUsingSizeAdjust\":false,\"pagesUsingSizeAdjust\":false}"
|
||||||
1
.next/server/next-font-manifest.json
Normal file
1
.next/server/next-font-manifest.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"pages":{},"app":{},"appUsingSizeAdjust":false,"pagesUsingSizeAdjust":false}
|
||||||
8
.next/server/pages-manifest.json
Normal file
8
.next/server/pages-manifest.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"/_app": "pages/_app.js",
|
||||||
|
"/_error": "pages/_error.js",
|
||||||
|
"/_document": "pages/_document.js",
|
||||||
|
"/admin/card-import": "pages/admin/card-import.js",
|
||||||
|
"/api/cards/import-pokemon": "pages/api/cards/import-pokemon.js",
|
||||||
|
"/cards": "pages/cards.js"
|
||||||
|
}
|
||||||
90
.next/server/pages/_app.js
Normal file
90
.next/server/pages/_app.js
Normal file
File diff suppressed because one or more lines are too long
66
.next/server/pages/_document.js
Normal file
66
.next/server/pages/_document.js
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||||
|
* This devtool is neither made for production nor for readable output files.
|
||||||
|
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||||
|
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||||
|
* or disable the default devtool with "devtool: false".
|
||||||
|
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||||
|
*/
|
||||||
|
(() => {
|
||||||
|
var exports = {};
|
||||||
|
exports.id = "pages/_document";
|
||||||
|
exports.ids = ["pages/_document"];
|
||||||
|
exports.modules = {
|
||||||
|
|
||||||
|
/***/ "next/dist/compiled/next-server/pages.runtime.dev.js":
|
||||||
|
/*!**********************************************************************!*\
|
||||||
|
!*** external "next/dist/compiled/next-server/pages.runtime.dev.js" ***!
|
||||||
|
\**********************************************************************/
|
||||||
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
module.exports = require("next/dist/compiled/next-server/pages.runtime.dev.js");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "path":
|
||||||
|
/*!***********************!*\
|
||||||
|
!*** external "path" ***!
|
||||||
|
\***********************/
|
||||||
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
module.exports = require("path");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "react":
|
||||||
|
/*!************************!*\
|
||||||
|
!*** external "react" ***!
|
||||||
|
\************************/
|
||||||
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
module.exports = require("react");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "react/jsx-runtime":
|
||||||
|
/*!************************************!*\
|
||||||
|
!*** external "react/jsx-runtime" ***!
|
||||||
|
\************************************/
|
||||||
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
module.exports = require("react/jsx-runtime");
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
};
|
||||||
|
;
|
||||||
|
|
||||||
|
// load runtime
|
||||||
|
var __webpack_require__ = require("../webpack-runtime.js");
|
||||||
|
__webpack_require__.C(exports);
|
||||||
|
var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
|
||||||
|
var __webpack_exports__ = __webpack_require__.X(0, ["vendor-chunks/next","vendor-chunks/@swc"], () => (__webpack_exec__("(pages-dir-node)/./node_modules/next/dist/pages/_document.js")));
|
||||||
|
module.exports = __webpack_exports__;
|
||||||
|
|
||||||
|
})();
|
||||||
211
.next/server/pages/_error.js
Normal file
211
.next/server/pages/_error.js
Normal file
File diff suppressed because one or more lines are too long
277
.next/server/pages/admin/card-import.js
Normal file
277
.next/server/pages/admin/card-import.js
Normal file
File diff suppressed because one or more lines are too long
106
.next/server/pages/api/auth/verify.js
Normal file
106
.next/server/pages/api/auth/verify.js
Normal file
File diff suppressed because one or more lines are too long
66
.next/server/pages/api/cards/import-pokemon.js
Normal file
66
.next/server/pages/api/cards/import-pokemon.js
Normal file
File diff suppressed because one or more lines are too long
66
.next/server/pages/api/cards/search.js
Normal file
66
.next/server/pages/api/cards/search.js
Normal file
File diff suppressed because one or more lines are too long
277
.next/server/pages/cards.js
Normal file
277
.next/server/pages/cards.js
Normal file
File diff suppressed because one or more lines are too long
35
.next/server/vendor-chunks/@swc.js
Normal file
35
.next/server/vendor-chunks/@swc.js
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||||
|
* This devtool is neither made for production nor for readable output files.
|
||||||
|
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||||
|
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||||
|
* or disable the default devtool with "devtool: false".
|
||||||
|
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||||
|
*/
|
||||||
|
exports.id = "vendor-chunks/@swc";
|
||||||
|
exports.ids = ["vendor-chunks/@swc"];
|
||||||
|
exports.modules = {
|
||||||
|
|
||||||
|
/***/ "(pages-dir-node)/./node_modules/@swc/helpers/cjs/_interop_require_default.cjs":
|
||||||
|
/*!********************************************************************!*\
|
||||||
|
!*** ./node_modules/@swc/helpers/cjs/_interop_require_default.cjs ***!
|
||||||
|
\********************************************************************/
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
eval("\n\nfunction _interop_require_default(obj) {\n return obj && obj.__esModule ? obj : { default: obj };\n}\nexports._ = _interop_require_default;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHBhZ2VzLWRpci1ub2RlKS8uL25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvY2pzL19pbnRlcm9wX3JlcXVpcmVfZGVmYXVsdC5janMiLCJtYXBwaW5ncyI6IkFBQWE7O0FBRWI7QUFDQSwyQ0FBMkM7QUFDM0M7QUFDQSxTQUFTIiwic291cmNlcyI6WyIvVXNlcnMvcnN0aWxsdy9Eb2N1bWVudHMvdGNnLXZhdWx0L25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvY2pzL19pbnRlcm9wX3JlcXVpcmVfZGVmYXVsdC5janMiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wX3JlcXVpcmVfZGVmYXVsdChvYmopIHtcbiAgICByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTtcbn1cbmV4cG9ydHMuXyA9IF9pbnRlcm9wX3JlcXVpcmVfZGVmYXVsdDtcbiJdLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOlswXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(pages-dir-node)/./node_modules/@swc/helpers/cjs/_interop_require_default.cjs\n");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "(pages-dir-node)/./node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs":
|
||||||
|
/*!*********************************************************************!*\
|
||||||
|
!*** ./node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs ***!
|
||||||
|
\*********************************************************************/
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
eval("\n\nfunction _getRequireWildcardCache(nodeInterop) {\n if (typeof WeakMap !== \"function\") return null;\n\n var cacheBabelInterop = new WeakMap();\n var cacheNodeInterop = new WeakMap();\n\n return (_getRequireWildcardCache = function(nodeInterop) {\n return nodeInterop ? cacheNodeInterop : cacheBabelInterop;\n })(nodeInterop);\n}\nfunction _interop_require_wildcard(obj, nodeInterop) {\n if (!nodeInterop && obj && obj.__esModule) return obj;\n if (obj === null || typeof obj !== \"object\" && typeof obj !== \"function\") return { default: obj };\n\n var cache = _getRequireWildcardCache(nodeInterop);\n\n if (cache && cache.has(obj)) return cache.get(obj);\n\n var newObj = { __proto__: null };\n var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;\n\n for (var key in obj) {\n if (key !== \"default\" && Object.prototype.hasOwnProperty.call(obj, key)) {\n var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;\n if (desc && (desc.get || desc.set)) Object.defineProperty(newObj, key, desc);\n else newObj[key] = obj[key];\n }\n }\n\n newObj.default = obj;\n\n if (cache) cache.set(obj, newObj);\n\n return newObj;\n}\nexports._ = _interop_require_wildcard;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHBhZ2VzLWRpci1ub2RlKS8uL25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvY2pzL19pbnRlcm9wX3JlcXVpcmVfd2lsZGNhcmQuY2pzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLHVGQUF1Rjs7QUFFdkY7O0FBRUE7O0FBRUEsbUJBQW1CO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxTQUFTIiwic291cmNlcyI6WyIvVXNlcnMvcnN0aWxsdy9Eb2N1bWVudHMvdGNnLXZhdWx0L25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvY2pzL19pbnRlcm9wX3JlcXVpcmVfd2lsZGNhcmQuY2pzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5mdW5jdGlvbiBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUobm9kZUludGVyb3ApIHtcbiAgICBpZiAodHlwZW9mIFdlYWtNYXAgIT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIG51bGw7XG5cbiAgICB2YXIgY2FjaGVCYWJlbEludGVyb3AgPSBuZXcgV2Vha01hcCgpO1xuICAgIHZhciBjYWNoZU5vZGVJbnRlcm9wID0gbmV3IFdlYWtNYXAoKTtcblxuICAgIHJldHVybiAoX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlID0gZnVuY3Rpb24obm9kZUludGVyb3ApIHtcbiAgICAgICAgcmV0dXJuIG5vZGVJbnRlcm9wID8gY2FjaGVOb2RlSW50ZXJvcCA6IGNhY2hlQmFiZWxJbnRlcm9wO1xuICAgIH0pKG5vZGVJbnRlcm9wKTtcbn1cbmZ1bmN0aW9uIF9pbnRlcm9wX3JlcXVpcmVfd2lsZGNhcmQob2JqLCBub2RlSW50ZXJvcCkge1xuICAgIGlmICghbm9kZUludGVyb3AgJiYgb2JqICYmIG9iai5fX2VzTW9kdWxlKSByZXR1cm4gb2JqO1xuICAgIGlmIChvYmogPT09IG51bGwgfHwgdHlwZW9mIG9iaiAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2Ygb2JqICE9PSBcImZ1bmN0aW9uXCIpIHJldHVybiB7IGRlZmF1bHQ6IG9iaiB9O1xuXG4gICAgdmFyIGNhY2hlID0gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKG5vZGVJbnRlcm9wKTtcblxuICAgIGlmIChjYWNoZSAmJiBjYWNoZS5oYXMob2JqKSkgcmV0dXJuIGNhY2hlLmdldChvYmopO1xuXG4gICAgdmFyIG5ld09iaiA9IHsgX19wcm90b19fOiBudWxsIH07XG4gICAgdmFyIGhhc1Byb3BlcnR5RGVzY3JpcHRvciA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xuXG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgICBpZiAoa2V5ICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgICAgICB2YXIgZGVzYyA9IGhhc1Byb3BlcnR5RGVzY3JpcHRvciA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBrZXkpIDogbnVsbDtcbiAgICAgICAgICAgIGlmIChkZXNjICYmIChkZXNjLmdldCB8fCBkZXNjLnNldCkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuZXdPYmosIGtleSwgZGVzYyk7XG4gICAgICAgICAgICBlbHNlIG5ld09ialtrZXldID0gb2JqW2tleV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZXdPYmouZGVmYXVsdCA9IG9iajtcblxuICAgIGlmIChjYWNoZSkgY2FjaGUuc2V0KG9iaiwgbmV3T2JqKTtcblxuICAgIHJldHVybiBuZXdPYmo7XG59XG5leHBvcnRzLl8gPSBfaW50ZXJvcF9yZXF1aXJlX3dpbGRjYXJkO1xuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(pages-dir-node)/./node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs\n");
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
};
|
||||||
|
;
|
||||||
1536
.next/server/vendor-chunks/next.js
Normal file
1536
.next/server/vendor-chunks/next.js
Normal file
File diff suppressed because one or more lines are too long
237
.next/server/webpack-api-runtime.js
Normal file
237
.next/server/webpack-api-runtime.js
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
/*
|
||||||
|
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||||
|
* This devtool is neither made for production nor for readable output files.
|
||||||
|
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||||
|
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||||
|
* or disable the default devtool with "devtool: false".
|
||||||
|
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||||
|
*/
|
||||||
|
/******/ (() => { // webpackBootstrap
|
||||||
|
/******/ "use strict";
|
||||||
|
/******/ var __webpack_modules__ = ({});
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/ var __webpack_module_cache__ = {};
|
||||||
|
/******/
|
||||||
|
/******/ // The require function
|
||||||
|
/******/ function __webpack_require__(moduleId) {
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||||
|
/******/ if (cachedModule !== undefined) {
|
||||||
|
/******/ return cachedModule.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||||
|
/******/ // no module.id needed
|
||||||
|
/******/ // no module.loaded needed
|
||||||
|
/******/ exports: {}
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/ var threw = true;
|
||||||
|
/******/ try {
|
||||||
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||||
|
/******/ threw = false;
|
||||||
|
/******/ } finally {
|
||||||
|
/******/ if(threw) delete __webpack_module_cache__[moduleId];
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/ return module.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/******/ // expose the modules object (__webpack_modules__)
|
||||||
|
/******/ __webpack_require__.m = __webpack_modules__;
|
||||||
|
/******/
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ /* webpack/runtime/async module */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__";
|
||||||
|
/******/ var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__";
|
||||||
|
/******/ var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__";
|
||||||
|
/******/ var resolveQueue = (queue) => {
|
||||||
|
/******/ if(queue && queue.d < 1) {
|
||||||
|
/******/ queue.d = 1;
|
||||||
|
/******/ queue.forEach((fn) => (fn.r--));
|
||||||
|
/******/ queue.forEach((fn) => (fn.r-- ? fn.r++ : fn()));
|
||||||
|
/******/ }
|
||||||
|
/******/ }
|
||||||
|
/******/ var wrapDeps = (deps) => (deps.map((dep) => {
|
||||||
|
/******/ if(dep !== null && typeof dep === "object") {
|
||||||
|
/******/ if(dep[webpackQueues]) return dep;
|
||||||
|
/******/ if(dep.then) {
|
||||||
|
/******/ var queue = [];
|
||||||
|
/******/ queue.d = 0;
|
||||||
|
/******/ dep.then((r) => {
|
||||||
|
/******/ obj[webpackExports] = r;
|
||||||
|
/******/ resolveQueue(queue);
|
||||||
|
/******/ }, (e) => {
|
||||||
|
/******/ obj[webpackError] = e;
|
||||||
|
/******/ resolveQueue(queue);
|
||||||
|
/******/ });
|
||||||
|
/******/ var obj = {};
|
||||||
|
/******/ obj[webpackQueues] = (fn) => (fn(queue));
|
||||||
|
/******/ return obj;
|
||||||
|
/******/ }
|
||||||
|
/******/ }
|
||||||
|
/******/ var ret = {};
|
||||||
|
/******/ ret[webpackQueues] = x => {};
|
||||||
|
/******/ ret[webpackExports] = dep;
|
||||||
|
/******/ return ret;
|
||||||
|
/******/ }));
|
||||||
|
/******/ __webpack_require__.a = (module, body, hasAwait) => {
|
||||||
|
/******/ var queue;
|
||||||
|
/******/ hasAwait && ((queue = []).d = -1);
|
||||||
|
/******/ var depQueues = new Set();
|
||||||
|
/******/ var exports = module.exports;
|
||||||
|
/******/ var currentDeps;
|
||||||
|
/******/ var outerResolve;
|
||||||
|
/******/ var reject;
|
||||||
|
/******/ var promise = new Promise((resolve, rej) => {
|
||||||
|
/******/ reject = rej;
|
||||||
|
/******/ outerResolve = resolve;
|
||||||
|
/******/ });
|
||||||
|
/******/ promise[webpackExports] = exports;
|
||||||
|
/******/ promise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise["catch"](x => {}));
|
||||||
|
/******/ module.exports = promise;
|
||||||
|
/******/ body((deps) => {
|
||||||
|
/******/ currentDeps = wrapDeps(deps);
|
||||||
|
/******/ var fn;
|
||||||
|
/******/ var getResult = () => (currentDeps.map((d) => {
|
||||||
|
/******/ if(d[webpackError]) throw d[webpackError];
|
||||||
|
/******/ return d[webpackExports];
|
||||||
|
/******/ }))
|
||||||
|
/******/ var promise = new Promise((resolve) => {
|
||||||
|
/******/ fn = () => (resolve(getResult));
|
||||||
|
/******/ fn.r = 0;
|
||||||
|
/******/ var fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn))));
|
||||||
|
/******/ currentDeps.map((dep) => (dep[webpackQueues](fnQueue)));
|
||||||
|
/******/ });
|
||||||
|
/******/ return fn.r ? promise : getResult();
|
||||||
|
/******/ }, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)));
|
||||||
|
/******/ queue && queue.d < 0 && (queue.d = 0);
|
||||||
|
/******/ };
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/compat get default export */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||||
|
/******/ __webpack_require__.n = (module) => {
|
||||||
|
/******/ var getter = module && module.__esModule ?
|
||||||
|
/******/ () => (module['default']) :
|
||||||
|
/******/ () => (module);
|
||||||
|
/******/ __webpack_require__.d(getter, { a: getter });
|
||||||
|
/******/ return getter;
|
||||||
|
/******/ };
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/define property getters */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ // define getter functions for harmony exports
|
||||||
|
/******/ __webpack_require__.d = (exports, definition) => {
|
||||||
|
/******/ for(var key in definition) {
|
||||||
|
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
||||||
|
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
||||||
|
/******/ }
|
||||||
|
/******/ }
|
||||||
|
/******/ };
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/ensure chunk */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ __webpack_require__.f = {};
|
||||||
|
/******/ // This file contains only the entry chunk.
|
||||||
|
/******/ // The chunk loading function for additional chunks
|
||||||
|
/******/ __webpack_require__.e = (chunkId) => {
|
||||||
|
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
|
||||||
|
/******/ __webpack_require__.f[key](chunkId, promises);
|
||||||
|
/******/ return promises;
|
||||||
|
/******/ }, []));
|
||||||
|
/******/ };
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/get javascript chunk filename */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ // This function allow to reference async chunks and sibling chunks for the entrypoint
|
||||||
|
/******/ __webpack_require__.u = (chunkId) => {
|
||||||
|
/******/ // return url for filenames based on template
|
||||||
|
/******/ return "" + chunkId + ".js";
|
||||||
|
/******/ };
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/make namespace object */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ // define __esModule on exports
|
||||||
|
/******/ __webpack_require__.r = (exports) => {
|
||||||
|
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||||
|
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||||
|
/******/ }
|
||||||
|
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||||
|
/******/ };
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/startup entrypoint */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ __webpack_require__.X = (result, chunkIds, fn) => {
|
||||||
|
/******/ // arguments: chunkIds, moduleId are deprecated
|
||||||
|
/******/ var moduleId = chunkIds;
|
||||||
|
/******/ if(!fn) chunkIds = result, fn = () => (__webpack_require__(__webpack_require__.s = moduleId));
|
||||||
|
/******/ chunkIds.map(__webpack_require__.e, __webpack_require__)
|
||||||
|
/******/ var r = fn();
|
||||||
|
/******/ return r === undefined ? result : r;
|
||||||
|
/******/ }
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/require chunk loading */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ // no baseURI
|
||||||
|
/******/
|
||||||
|
/******/ // object to store loaded chunks
|
||||||
|
/******/ // "1" means "loaded", otherwise not loaded yet
|
||||||
|
/******/ var installedChunks = {
|
||||||
|
/******/ "webpack-api-runtime": 1
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // no on chunks loaded
|
||||||
|
/******/
|
||||||
|
/******/ var installChunk = (chunk) => {
|
||||||
|
/******/ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
|
||||||
|
/******/ for(var moduleId in moreModules) {
|
||||||
|
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
||||||
|
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
||||||
|
/******/ }
|
||||||
|
/******/ }
|
||||||
|
/******/ if(runtime) runtime(__webpack_require__);
|
||||||
|
/******/ for(var i = 0; i < chunkIds.length; i++)
|
||||||
|
/******/ installedChunks[chunkIds[i]] = 1;
|
||||||
|
/******/
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // require() chunk loading for javascript
|
||||||
|
/******/ __webpack_require__.f.require = (chunkId, promises) => {
|
||||||
|
/******/ // "1" is the signal for "already loaded"
|
||||||
|
/******/ if(!installedChunks[chunkId]) {
|
||||||
|
/******/ if("webpack-api-runtime" != chunkId) {
|
||||||
|
/******/ installChunk(require("./" + __webpack_require__.u(chunkId)));
|
||||||
|
/******/ } else installedChunks[chunkId] = 1;
|
||||||
|
/******/ }
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ module.exports = __webpack_require__;
|
||||||
|
/******/ __webpack_require__.C = installChunk;
|
||||||
|
/******/
|
||||||
|
/******/ // no HMR
|
||||||
|
/******/
|
||||||
|
/******/ // no HMR manifest
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/************************************************************************/
|
||||||
|
/******/
|
||||||
|
/******/
|
||||||
|
/******/ })()
|
||||||
|
;
|
||||||
162
.next/server/webpack-runtime.js
Normal file
162
.next/server/webpack-runtime.js
Normal file
File diff suppressed because one or more lines are too long
28
.next/static/chunks/_error.js
Normal file
28
.next/static/chunks/_error.js
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||||
|
* This devtool is neither made for production nor for readable output files.
|
||||||
|
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||||
|
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||||
|
* or disable the default devtool with "devtool: false".
|
||||||
|
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||||
|
*/
|
||||||
|
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([["/_error"],{
|
||||||
|
|
||||||
|
/***/ "(pages-dir-browser)/./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=%2FUsers%2Frstillw%2FDocuments%2Ftcg-vault%2Fnode_modules%2Fnext%2Fdist%2Fpages%2F_error.js&page=%2F_error!":
|
||||||
|
/*!***************************************************************************************************************************************************************************************************************!*\
|
||||||
|
!*** ./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=%2FUsers%2Frstillw%2FDocuments%2Ftcg-vault%2Fnode_modules%2Fnext%2Fdist%2Fpages%2F_error.js&page=%2F_error! ***!
|
||||||
|
\***************************************************************************************************************************************************************************************************************/
|
||||||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||||||
|
|
||||||
|
eval(__webpack_require__.ts("\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/_error\",\n function () {\n return __webpack_require__(/*! ./node_modules/next/dist/pages/_error.js */ \"(pages-dir-browser)/./node_modules/next/dist/pages/_error.js\");\n }\n ]);\n if(true) {\n module.hot.dispose(function () {\n window.__NEXT_P.push([\"/_error\"])\n });\n }\n //# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHBhZ2VzLWRpci1icm93c2VyKS8uL25vZGVfbW9kdWxlcy9uZXh0L2Rpc3QvYnVpbGQvd2VicGFjay9sb2FkZXJzL25leHQtY2xpZW50LXBhZ2VzLWxvYWRlci5qcz9hYnNvbHV0ZVBhZ2VQYXRoPSUyRlVzZXJzJTJGcnN0aWxsdyUyRkRvY3VtZW50cyUyRnRjZy12YXVsdCUyRm5vZGVfbW9kdWxlcyUyRm5leHQlMkZkaXN0JTJGcGFnZXMlMkZfZXJyb3IuanMmcGFnZT0lMkZfZXJyb3IhIiwibWFwcGluZ3MiOiI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLG1CQUFPLENBQUMsOEdBQTBDO0FBQ2pFO0FBQ0E7QUFDQSxPQUFPLElBQVU7QUFDakIsTUFBTSxVQUFVO0FBQ2hCO0FBQ0EsT0FBTztBQUNQO0FBQ0EiLCJzb3VyY2VzIjpbIiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbiAgICAod2luZG93Ll9fTkVYVF9QID0gd2luZG93Ll9fTkVYVF9QIHx8IFtdKS5wdXNoKFtcbiAgICAgIFwiL19lcnJvclwiLFxuICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmVxdWlyZShcIi4vbm9kZV9tb2R1bGVzL25leHQvZGlzdC9wYWdlcy9fZXJyb3IuanNcIik7XG4gICAgICB9XG4gICAgXSk7XG4gICAgaWYobW9kdWxlLmhvdCkge1xuICAgICAgbW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2luZG93Ll9fTkVYVF9QLnB1c2goW1wiL19lcnJvclwiXSlcbiAgICAgIH0pO1xuICAgIH1cbiAgIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(pages-dir-browser)/./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=%2FUsers%2Frstillw%2FDocuments%2Ftcg-vault%2Fnode_modules%2Fnext%2Fdist%2Fpages%2F_error.js&page=%2F_error!\n"));
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
},
|
||||||
|
/******/ __webpack_require__ => { // webpackRuntimeModules
|
||||||
|
/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
|
||||||
|
/******/ __webpack_require__.O(0, ["main"], () => (__webpack_exec__("(pages-dir-browser)/./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=%2FUsers%2Frstillw%2FDocuments%2Ftcg-vault%2Fnode_modules%2Fnext%2Fdist%2Fpages%2F_error.js&page=%2F_error!")));
|
||||||
|
/******/ var __webpack_exports__ = __webpack_require__.O();
|
||||||
|
/******/ _N_E = __webpack_exports__;
|
||||||
|
/******/ }
|
||||||
|
]);
|
||||||
1562
.next/static/chunks/main.js
Normal file
1562
.next/static/chunks/main.js
Normal file
File diff suppressed because one or more lines are too long
126
.next/static/chunks/pages/_app.js
Normal file
126
.next/static/chunks/pages/_app.js
Normal file
File diff suppressed because one or more lines are too long
28
.next/static/chunks/pages/_error.js
Normal file
28
.next/static/chunks/pages/_error.js
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||||
|
* This devtool is neither made for production nor for readable output files.
|
||||||
|
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||||
|
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||||
|
* or disable the default devtool with "devtool: false".
|
||||||
|
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||||
|
*/
|
||||||
|
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([["pages/_error"],{
|
||||||
|
|
||||||
|
/***/ "(pages-dir-browser)/./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=private-next-pages%2F_error&page=%2F_error!":
|
||||||
|
/*!***********************************************************************************************************************************************!*\
|
||||||
|
!*** ./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=private-next-pages%2F_error&page=%2F_error! ***!
|
||||||
|
\***********************************************************************************************************************************************/
|
||||||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||||||
|
|
||||||
|
eval(__webpack_require__.ts("\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/_error\",\n function () {\n return __webpack_require__(/*! private-next-pages/_error */ \"(pages-dir-browser)/./node_modules/next/dist/pages/_error.js\");\n }\n ]);\n if(true) {\n module.hot.dispose(function () {\n window.__NEXT_P.push([\"/_error\"])\n });\n }\n //# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHBhZ2VzLWRpci1icm93c2VyKS8uL25vZGVfbW9kdWxlcy9uZXh0L2Rpc3QvYnVpbGQvd2VicGFjay9sb2FkZXJzL25leHQtY2xpZW50LXBhZ2VzLWxvYWRlci5qcz9hYnNvbHV0ZVBhZ2VQYXRoPXByaXZhdGUtbmV4dC1wYWdlcyUyRl9lcnJvciZwYWdlPSUyRl9lcnJvciEiLCJtYXBwaW5ncyI6IjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsbUJBQU8sQ0FBQywrRkFBMkI7QUFDbEQ7QUFDQTtBQUNBLE9BQU8sSUFBVTtBQUNqQixNQUFNLFVBQVU7QUFDaEI7QUFDQSxPQUFPO0FBQ1A7QUFDQSIsInNvdXJjZXMiOlsiIl0sInNvdXJjZXNDb250ZW50IjpbIlxuICAgICh3aW5kb3cuX19ORVhUX1AgPSB3aW5kb3cuX19ORVhUX1AgfHwgW10pLnB1c2goW1xuICAgICAgXCIvX2Vycm9yXCIsXG4gICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiByZXF1aXJlKFwicHJpdmF0ZS1uZXh0LXBhZ2VzL19lcnJvclwiKTtcbiAgICAgIH1cbiAgICBdKTtcbiAgICBpZihtb2R1bGUuaG90KSB7XG4gICAgICBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24gKCkge1xuICAgICAgICB3aW5kb3cuX19ORVhUX1AucHVzaChbXCIvX2Vycm9yXCJdKVxuICAgICAgfSk7XG4gICAgfVxuICAiXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(pages-dir-browser)/./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=private-next-pages%2F_error&page=%2F_error!\n"));
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
},
|
||||||
|
/******/ __webpack_require__ => { // webpackRuntimeModules
|
||||||
|
/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
|
||||||
|
/******/ __webpack_require__.O(0, ["pages/_app","main"], () => (__webpack_exec__("(pages-dir-browser)/./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=private-next-pages%2F_error&page=%2F_error!")));
|
||||||
|
/******/ var __webpack_exports__ = __webpack_require__.O();
|
||||||
|
/******/ _N_E = __webpack_exports__;
|
||||||
|
/******/ }
|
||||||
|
]);
|
||||||
125
.next/static/chunks/pages/admin/card-import.js
Normal file
125
.next/static/chunks/pages/admin/card-import.js
Normal file
File diff suppressed because one or more lines are too long
125
.next/static/chunks/pages/cards.js
Normal file
125
.next/static/chunks/pages/cards.js
Normal file
File diff suppressed because one or more lines are too long
1
.next/static/chunks/polyfills.js
Normal file
1
.next/static/chunks/polyfills.js
Normal file
File diff suppressed because one or more lines are too long
62
.next/static/chunks/react-refresh.js
vendored
Normal file
62
.next/static/chunks/react-refresh.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1216
.next/static/chunks/webpack.js
Normal file
1216
.next/static/chunks/webpack.js
Normal file
File diff suppressed because one or more lines are too long
1
.next/static/development/_buildManifest.js
Normal file
1
.next/static/development/_buildManifest.js
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
self.__BUILD_MANIFEST = (function(a){return {__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:a,__routerFilterDynamic:a,"/_error":["static\u002Fchunks\u002Fpages\u002F_error.js"],"/admin/card-import":["static\u002Fchunks\u002Fpages\u002Fadmin\u002Fcard-import.js"],"/cards":["static\u002Fchunks\u002Fpages\u002Fcards.js"],sortedPages:["\u002F_app","\u002F_error","\u002Fadmin\u002Fcard-import","\u002Fcards"]}}(void 0));self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()
|
||||||
1
.next/static/development/_ssgManifest.js
Normal file
1
.next/static/development/_ssgManifest.js
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
self.__SSG_MANIFEST=new Set;self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"c":["webpack"],"r":[],"m":[]}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"c":["webpack"],"r":["/_error"],"m":["(pages-dir-browser)/./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=%2FUsers%2Frstillw%2FDocuments%2Ftcg-vault%2Fnode_modules%2Fnext%2Fdist%2Fpages%2F_error.js&page=%2F_error!"]}
|
||||||
1
.next/static/webpack/633457081244afec._.hot-update.json
Normal file
1
.next/static/webpack/633457081244afec._.hot-update.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"c":[],"r":[],"m":[]}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"c":["webpack"],"r":[],"m":[]}
|
||||||
12
.next/static/webpack/webpack.03ca3745347cb6dc.hot-update.js
Normal file
12
.next/static/webpack/webpack.03ca3745347cb6dc.hot-update.js
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
"use strict";
|
||||||
|
self["webpackHotUpdate_N_E"]("webpack",{},
|
||||||
|
/******/ function(__webpack_require__) { // webpackRuntimeModules
|
||||||
|
/******/ /* webpack/runtime/getFullHash */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ __webpack_require__.h = () => ("dc2d66e9190850cf")
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ }
|
||||||
|
)
|
||||||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCJkYzJkNjZlOTE5MDg1MGNmXCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
|
||||||
|
;
|
||||||
12
.next/static/webpack/webpack.1a81ca931ae87a2d.hot-update.js
Normal file
12
.next/static/webpack/webpack.1a81ca931ae87a2d.hot-update.js
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
"use strict";
|
||||||
|
self["webpackHotUpdate_N_E"]("webpack",{},
|
||||||
|
/******/ function(__webpack_require__) { // webpackRuntimeModules
|
||||||
|
/******/ /* webpack/runtime/getFullHash */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ __webpack_require__.h = () => ("f07f85cab969fc85")
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ }
|
||||||
|
)
|
||||||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCJmMDdmODVjYWI5NjlmYzg1XCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
|
||||||
|
;
|
||||||
12
.next/static/webpack/webpack.dc2d66e9190850cf.hot-update.js
Normal file
12
.next/static/webpack/webpack.dc2d66e9190850cf.hot-update.js
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
"use strict";
|
||||||
|
self["webpackHotUpdate_N_E"]("webpack",{},
|
||||||
|
/******/ function(__webpack_require__) { // webpackRuntimeModules
|
||||||
|
/******/ /* webpack/runtime/getFullHash */
|
||||||
|
/******/ (() => {
|
||||||
|
/******/ __webpack_require__.h = () => ("1a81ca931ae87a2d")
|
||||||
|
/******/ })();
|
||||||
|
/******/
|
||||||
|
/******/ }
|
||||||
|
)
|
||||||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCIxYTgxY2E5MzFhZTg3YTJkXCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
|
||||||
|
;
|
||||||
12
.next/trace
Normal file
12
.next/trace
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,167 +0,0 @@
|
||||||
# 🎉 All-Vercel TCG Vault Setup Complete!
|
|
||||||
|
|
||||||
## ✅ What We've Built
|
|
||||||
|
|
||||||
Your TCG Vault is now **completely self-contained on Vercel Pro** with no external dependencies!
|
|
||||||
|
|
||||||
### **🏗️ Architecture:**
|
|
||||||
- **Frontend**: React app with OCR scanner and visual effects
|
|
||||||
- **Backend**: Vercel Functions (TypeScript) replacing FastAPI
|
|
||||||
- **Database**: JSON file with your card data (12 cards exported)
|
|
||||||
- **Deployment**: Single Vercel project
|
|
||||||
|
|
||||||
### **📁 File Structure:**
|
|
||||||
```
|
|
||||||
frontend/
|
|
||||||
├── api/ # Vercel Functions (Backend)
|
|
||||||
│ ├── health.ts # Health check endpoint
|
|
||||||
│ └── v1/cards/
|
|
||||||
│ ├── index.ts # GET /api/v1/cards/ (with search, filters)
|
|
||||||
│ └── [id].ts # GET /api/v1/cards/:id
|
|
||||||
├── src/
|
|
||||||
│ ├── data/cards.json # Card database (exported from SQLite)
|
|
||||||
│ ├── config/api.ts # Updated for local API routes
|
|
||||||
│ └── ... (all your React components)
|
|
||||||
├── vercel.json # Vercel configuration
|
|
||||||
└── deploy-vercel-all.sh # Deployment script
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 **Deployment Process**
|
|
||||||
|
|
||||||
### **1. Push to GitHub:**
|
|
||||||
```bash
|
|
||||||
cd frontend
|
|
||||||
git init
|
|
||||||
git add .
|
|
||||||
git commit -m "TCG Vault - All Vercel Setup"
|
|
||||||
git branch -M main
|
|
||||||
# Create new GitHub repo and push
|
|
||||||
git remote add origin YOUR_GITHUB_REPO_URL
|
|
||||||
git push -u origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
### **2. Deploy to Vercel Pro:**
|
|
||||||
1. Go to [vercel.com/dashboard](https://vercel.com/dashboard)
|
|
||||||
2. **"Import Project"** → Choose your GitHub repo
|
|
||||||
3. **Framework**: React (auto-detected)
|
|
||||||
4. **Root Directory**: Leave blank (uses frontend as root)
|
|
||||||
5. **Build Settings**: Auto-detected
|
|
||||||
6. **Deploy!** ✨
|
|
||||||
|
|
||||||
### **3. Done!**
|
|
||||||
Your TCG Vault will be live at `https://your-app.vercel.app`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 **What Works:**
|
|
||||||
|
|
||||||
### **✅ All Current Features:**
|
|
||||||
- 📸 **Camera OCR scanning** with Tesseract.js
|
|
||||||
- 🎨 **Beautiful visual effects** (glowing cards, animations)
|
|
||||||
- 🃏 **Card database** (12 cards from your SQLite export)
|
|
||||||
- 📱 **Mobile responsive** design
|
|
||||||
- 🔍 **Search and filtering**
|
|
||||||
- 🌟 **Card matching** for OCR results
|
|
||||||
|
|
||||||
### **✅ API Endpoints:**
|
|
||||||
- `GET /api/v1/cards/` - List cards with search/filters
|
|
||||||
- `GET /api/v1/cards/:id` - Get specific card
|
|
||||||
- `GET /api/health` - Health check
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💰 **Cost Analysis:**
|
|
||||||
|
|
||||||
### **With Vercel Pro:**
|
|
||||||
- **Your existing Vercel Pro**: $20/month (already paying)
|
|
||||||
- **Additional cost**: $0/month 🎉
|
|
||||||
- **Included with Pro**:
|
|
||||||
- 10M requests/month
|
|
||||||
- 1TB data transfer
|
|
||||||
- Serverless functions
|
|
||||||
- Global CDN
|
|
||||||
- Advanced monitoring
|
|
||||||
|
|
||||||
### **vs. Alternatives:**
|
|
||||||
- Railway: $5/month minimum + Vercel Pro
|
|
||||||
- Render + Vercel Pro: Still need two platforms
|
|
||||||
- **All-Vercel: Simplest and most cost-effective!**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔥 **Benefits of All-Vercel Setup:**
|
|
||||||
|
|
||||||
### **🎯 Simplicity:**
|
|
||||||
- **One codebase** - Everything in one repository
|
|
||||||
- **One platform** - Vercel handles everything
|
|
||||||
- **One deployment** - Push code, auto-deploy
|
|
||||||
- **One dashboard** - Monitor everything in Vercel
|
|
||||||
|
|
||||||
### **⚡ Performance:**
|
|
||||||
- **Edge functions** - API runs globally close to users
|
|
||||||
- **Static files** - Frontend cached at 40+ edge locations
|
|
||||||
- **Fast cold starts** - Vercel Functions optimized for speed
|
|
||||||
- **Integrated CDN** - Everything accelerated
|
|
||||||
|
|
||||||
### **🛡️ Enterprise Features:**
|
|
||||||
- **Advanced WAF** - DDoS protection, bot management
|
|
||||||
- **Observability** - Built-in monitoring and analytics
|
|
||||||
- **Security headers** - Automatically configured
|
|
||||||
- **SSL certificates** - Managed automatically
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ **Development Workflow:**
|
|
||||||
|
|
||||||
### **Local Development:**
|
|
||||||
```bash
|
|
||||||
npm start # React app runs on http://localhost:3000
|
|
||||||
# API functions available at http://localhost:3000/api/*
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Production Deployment:**
|
|
||||||
1. **Push to GitHub** - Automatic deployment triggered
|
|
||||||
2. **Preview deployments** - Every branch gets preview URL
|
|
||||||
3. **Instant rollbacks** - One-click revert if needed
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 **Monitoring & Analytics:**
|
|
||||||
|
|
||||||
### **Built-in with Vercel Pro:**
|
|
||||||
- **Real-time analytics** - Track page views, performance
|
|
||||||
- **Function logs** - Debug API issues
|
|
||||||
- **Performance insights** - Core Web Vitals monitoring
|
|
||||||
- **Error tracking** - Automatic error reporting
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎉 **Next Steps:**
|
|
||||||
|
|
||||||
### **Immediate:**
|
|
||||||
1. **Deploy to Vercel** using the process above
|
|
||||||
2. **Test all features** in production
|
|
||||||
3. **Set up custom domain** (optional)
|
|
||||||
|
|
||||||
### **Future Enhancements:**
|
|
||||||
1. **Add more cards** - Update `src/data/cards.json`
|
|
||||||
2. **User authentication** - Add Vercel KV for user data
|
|
||||||
3. **Live pricing** - Integrate pricing APIs
|
|
||||||
4. **Advanced features** - Collections, decks, etc.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 **Expected Results:**
|
|
||||||
|
|
||||||
After deployment, you'll have:
|
|
||||||
- ⚡ **Blazing fast worldwide** - 40+ edge locations
|
|
||||||
- 📱 **Perfect mobile OCR** - Camera scanning works flawlessly
|
|
||||||
- 🛡️ **Enterprise security** - WAF protection, DDoS mitigation
|
|
||||||
- 📊 **Professional monitoring** - Built-in observability
|
|
||||||
- 🔄 **Automatic deployments** - Push to Git, instantly live
|
|
||||||
- ✨ **All visual effects** - Enhanced with edge optimization
|
|
||||||
- 🌍 **Global scalability** - Handles any traffic automatically
|
|
||||||
|
|
||||||
**Your TCG Vault is now professional-grade and costs $0 extra!** 🚀
|
|
||||||
|
|
@ -1,251 +0,0 @@
|
||||||
# Card Data Sources Guide
|
|
||||||
|
|
||||||
This guide explains how to build out your card database using external APIs and data sources.
|
|
||||||
|
|
||||||
## 🎯 **Recommended Data Sources**
|
|
||||||
|
|
||||||
### **1. Scryfall API (Magic: The Gathering)**
|
|
||||||
**Best for MTG cards**
|
|
||||||
- **URL**: https://api.scryfall.com
|
|
||||||
- **Free**: No API key required
|
|
||||||
- **Rate Limit**: 10 requests/second
|
|
||||||
- **Coverage**: All MTG cards with images, prices, rulings
|
|
||||||
|
|
||||||
**Example Usage**:
|
|
||||||
```javascript
|
|
||||||
// Search for a card
|
|
||||||
const response = await fetch('https://api.scryfall.com/cards/named?fuzzy=lightning+bolt');
|
|
||||||
const card = await response.json();
|
|
||||||
|
|
||||||
// Search multiple cards
|
|
||||||
const searchResponse = await fetch('https://api.scryfall.com/cards/search?q=game:paper+type:creature');
|
|
||||||
const cards = await searchResponse.json();
|
|
||||||
```
|
|
||||||
|
|
||||||
### **2. Pokémon TCG API**
|
|
||||||
**Best for Pokémon cards**
|
|
||||||
- **URL**: https://api.pokemontcg.io/v2
|
|
||||||
- **Free**: No authentication required
|
|
||||||
- **Rate Limit**: Generous limits
|
|
||||||
- **Coverage**: All Pokémon cards with images
|
|
||||||
|
|
||||||
**Example Usage**:
|
|
||||||
```javascript
|
|
||||||
// Search for a card
|
|
||||||
const response = await fetch('https://api.pokemontcg.io/v2/cards?q=name:pikachu');
|
|
||||||
const cards = await response.json();
|
|
||||||
```
|
|
||||||
|
|
||||||
### **3. Yu-Gi-Oh! API**
|
|
||||||
**Best for Yu-Gi-Oh! cards**
|
|
||||||
- **URL**: https://db.ygoprodeck.com/api/v7
|
|
||||||
- **Free**: Open source API
|
|
||||||
- **Coverage**: All Yu-Gi-Oh! cards
|
|
||||||
|
|
||||||
**Example Usage**:
|
|
||||||
```javascript
|
|
||||||
// Search for a card
|
|
||||||
const response = await fetch('https://db.ygoprodeck.com/api/v7/cardinfo.php?fname=Blue-Eyes%20White%20Dragon');
|
|
||||||
const cards = await response.json();
|
|
||||||
```
|
|
||||||
|
|
||||||
### **4. Disney Lorcana (Lorcast API)**
|
|
||||||
**Best for Lorcana cards**
|
|
||||||
- **URL**: https://api.lorcast.com/v0
|
|
||||||
- **Free**: No API key required
|
|
||||||
- **Rate Limit**: 10 requests/second (50-100ms delay recommended)
|
|
||||||
- **Coverage**: All Lorcana cards with images and pricing
|
|
||||||
- **Status**: Beta API (v0) - production safe
|
|
||||||
|
|
||||||
**Example Usage**:
|
|
||||||
```javascript
|
|
||||||
// Search for a card
|
|
||||||
const response = await fetch('https://api.lorcast.com/v0/cards?q=name:Mickey%20Mouse');
|
|
||||||
const data = await response.json();
|
|
||||||
const cards = data.cards;
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 **Implementation Strategy**
|
|
||||||
|
|
||||||
### **Phase 1: Core Integration**
|
|
||||||
1. **Set up rate limiting** for each API
|
|
||||||
2. **Create unified search interface** that queries all sources
|
|
||||||
3. **Implement caching** to avoid repeated requests
|
|
||||||
4. **Add error handling** for API failures
|
|
||||||
|
|
||||||
### **Phase 2: Database Population**
|
|
||||||
1. **Fetch popular cards** from each game
|
|
||||||
2. **Store in local database** with proper metadata
|
|
||||||
3. **Update pricing** regularly
|
|
||||||
4. **Add image caching** for better performance
|
|
||||||
|
|
||||||
### **Phase 3: Advanced Features**
|
|
||||||
1. **Real-time pricing** from multiple sources
|
|
||||||
2. **Set completion tracking**
|
|
||||||
3. **Market trend analysis**
|
|
||||||
4. **Deck building suggestions**
|
|
||||||
|
|
||||||
## 📊 **Data Mapping**
|
|
||||||
|
|
||||||
### **Universal Fields**
|
|
||||||
| Field | Description | Source |
|
|
||||||
|-------|-------------|--------|
|
|
||||||
| `name` | Card name | All APIs |
|
|
||||||
| `game` | Game identifier | All APIs |
|
|
||||||
| `set_name` | Set/expansion name | All APIs |
|
|
||||||
| `set_code` | Set abbreviation | All APIs |
|
|
||||||
| `card_number` | Collector number | All APIs |
|
|
||||||
| `rarity` | Rarity level | All APIs |
|
|
||||||
| `image_url` | Card image URL | All APIs |
|
|
||||||
| `current_price` | Market price | MTG, Pokémon |
|
|
||||||
|
|
||||||
### **Game-Specific Fields**
|
|
||||||
|
|
||||||
#### **Magic: The Gathering**
|
|
||||||
- `mana_cost`: Mana symbols `{W}{U}{B}{R}{G}{C}`
|
|
||||||
- `cmc`: Converted mana cost
|
|
||||||
- `card_type`: Full type line
|
|
||||||
- `colors`: Color identity
|
|
||||||
- `oracle_text`: Rules text
|
|
||||||
- `power`/`toughness`: Creature stats
|
|
||||||
|
|
||||||
#### **Pokémon**
|
|
||||||
- `mana_cost`: Energy requirements
|
|
||||||
- `cmc`: Total energy cost
|
|
||||||
- `card_type`: Card type + stage
|
|
||||||
- `colors`: Energy types
|
|
||||||
- `power`: HP value
|
|
||||||
- `oracle_text`: Effect text
|
|
||||||
|
|
||||||
#### **Yu-Gi-Oh!**
|
|
||||||
- `mana_cost`: Level/rank
|
|
||||||
- `cmc`: Level value
|
|
||||||
- `card_type`: Card type
|
|
||||||
- `colors`: Attribute
|
|
||||||
- `oracle_text`: Effect text
|
|
||||||
- `power`/`toughness`: ATK/DEF
|
|
||||||
|
|
||||||
#### **Disney Lorcana**
|
|
||||||
- `mana_cost`: Ink cost
|
|
||||||
- `cmc`: Ink cost value
|
|
||||||
- `card_type`: Card type
|
|
||||||
- `colors`: Ink colors
|
|
||||||
- `oracle_text`: Card text
|
|
||||||
- `power`/`toughness`: Strength/Willpower
|
|
||||||
|
|
||||||
## 🛠️ **Usage Examples**
|
|
||||||
|
|
||||||
### **Search Cards from External APIs**
|
|
||||||
```javascript
|
|
||||||
import cardDataService from '../services/cardDataSources';
|
|
||||||
|
|
||||||
// Search across all games
|
|
||||||
const cards = await cardDataService.searchCards('dragon');
|
|
||||||
|
|
||||||
// Search specific game
|
|
||||||
const mtgCards = await cardDataService.searchCards('lightning', 'MTG');
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Add Cards to Database**
|
|
||||||
```javascript
|
|
||||||
// Fetch card from external API
|
|
||||||
const card = await mtgService.getCardByName('Lightning Bolt');
|
|
||||||
|
|
||||||
// Add to local database
|
|
||||||
const result = await databaseAPI.addCard(card);
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Populate Database with Popular Cards**
|
|
||||||
```bash
|
|
||||||
# Run the population script
|
|
||||||
node scripts/populate-card-database.js
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📈 **Performance Considerations**
|
|
||||||
|
|
||||||
### **Rate Limiting**
|
|
||||||
- **Scryfall**: 10 requests/second
|
|
||||||
- **Pokémon API**: 5 requests/second
|
|
||||||
- **Yu-Gi-Oh! API**: No strict limits
|
|
||||||
- **Lorcast (Lorcana)**: 10 requests/second (50-100ms delay)
|
|
||||||
|
|
||||||
### **Caching Strategy**
|
|
||||||
- **Search results**: Cache for 5 minutes
|
|
||||||
- **Card details**: Cache for 1 hour
|
|
||||||
- **Images**: Cache indefinitely
|
|
||||||
- **Pricing**: Update every 24 hours
|
|
||||||
|
|
||||||
### **Error Handling**
|
|
||||||
- **API failures**: Retry with exponential backoff
|
|
||||||
- **Rate limits**: Implement proper queuing
|
|
||||||
- **Network issues**: Graceful degradation
|
|
||||||
|
|
||||||
## 🔧 **Setup Instructions**
|
|
||||||
|
|
||||||
### **1. Install Dependencies**
|
|
||||||
```bash
|
|
||||||
npm install node-fetch
|
|
||||||
```
|
|
||||||
|
|
||||||
### **2. Set Environment Variables**
|
|
||||||
```bash
|
|
||||||
# .env
|
|
||||||
REACT_APP_API_URL=http://localhost:8000
|
|
||||||
TCG_VAULT_TOKEN=your_auth_token_here
|
|
||||||
```
|
|
||||||
|
|
||||||
### **3. Run Database Population**
|
|
||||||
```bash
|
|
||||||
# Populate with popular cards
|
|
||||||
node scripts/populate-card-database.js
|
|
||||||
|
|
||||||
# Or use the web interface
|
|
||||||
# Navigate to Cards page → "Browse Database" button
|
|
||||||
```
|
|
||||||
|
|
||||||
### **4. Test the Integration**
|
|
||||||
```javascript
|
|
||||||
// Test external API search
|
|
||||||
const cards = await cardDataService.searchCards('pikachu', 'POKEMON');
|
|
||||||
console.log('Found cards:', cards.length);
|
|
||||||
|
|
||||||
// Test database addition
|
|
||||||
const card = await mtgService.getCardByName('Lightning Bolt');
|
|
||||||
if (card) {
|
|
||||||
await databaseAPI.addCard(card);
|
|
||||||
console.log('Card added to database');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎯 **Next Steps**
|
|
||||||
|
|
||||||
### **Immediate Actions**
|
|
||||||
1. **Test the APIs** with the provided services
|
|
||||||
2. **Populate your database** with popular cards
|
|
||||||
3. **Integrate the browser component** into your app
|
|
||||||
4. **Set up regular updates** for pricing data
|
|
||||||
|
|
||||||
### **Future Enhancements**
|
|
||||||
1. **Add more games** (Lorcana, Flesh and Blood, etc.)
|
|
||||||
2. **Implement price tracking** with alerts
|
|
||||||
3. **Add set completion tracking**
|
|
||||||
4. **Create deck building suggestions**
|
|
||||||
5. **Add market analysis tools**
|
|
||||||
|
|
||||||
## 📚 **Additional Resources**
|
|
||||||
|
|
||||||
- **Scryfall API Docs**: https://scryfall.com/docs/api
|
|
||||||
- **Pokémon TCG API**: https://dev.pokemontcg.io/
|
|
||||||
- **Yu-Gi-Oh! API**: https://ygoprodeck.com/api-guide/
|
|
||||||
- **Lorcast API**: https://lorcast.com/docs/api
|
|
||||||
- **TCGPlayer API**: https://docs.tcgplayer.com/
|
|
||||||
|
|
||||||
## 🚨 **Important Notes**
|
|
||||||
|
|
||||||
1. **Respect rate limits** - Implement proper throttling
|
|
||||||
2. **Cache responses** - Avoid unnecessary API calls
|
|
||||||
3. **Handle errors gracefully** - APIs can be unreliable
|
|
||||||
4. **Update pricing regularly** - Card values change frequently
|
|
||||||
5. **Verify card data** - Cross-reference with official sources
|
|
||||||
|
|
||||||
This implementation provides a solid foundation for building a comprehensive card database that can grow with your application's needs!
|
|
||||||
188
DEPLOYMENT.md
188
DEPLOYMENT.md
|
|
@ -1,188 +0,0 @@
|
||||||
# 🚀 TCG Vault Deployment Guide
|
|
||||||
|
|
||||||
## 🏆 **OPTION 1: Vercel Pro + Railway - BEST CHOICE**
|
|
||||||
|
|
||||||
### ✅ **Perfect for You (Already Have Vercel Pro!):**
|
|
||||||
- **Frontend** → Your existing Vercel Pro account ($20/month already paying)
|
|
||||||
- **Backend** → Railway cloud service (free tier)
|
|
||||||
- **Total additional cost: $0/month** 🎉
|
|
||||||
- **Enterprise-grade performance** that crushes shared hosting
|
|
||||||
|
|
||||||
### **🔥 Why Vercel Pro Is Superior:**
|
|
||||||
- **10M edge requests/month** included (10x more than Hobby)
|
|
||||||
- **1TB data transfer/month** (vs 100GB DreamHost shared)
|
|
||||||
- **Global CDN with 40+ locations** (instant worldwide loading)
|
|
||||||
- **4-CPU build machines** (2x faster builds than Hobby)
|
|
||||||
- **Advanced WAF protection** (enterprise security)
|
|
||||||
- **Observability & monitoring** (performance insights)
|
|
||||||
- **Zero-downtime deployments** (professional reliability)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 **Step 1: Deploy Backend to Railway (5 minutes)**
|
|
||||||
|
|
||||||
### 1. **Create Railway Account**
|
|
||||||
- Visit [railway.app](https://railway.app)
|
|
||||||
- Sign up with GitHub (free)
|
|
||||||
|
|
||||||
### 2. **Push Backend to GitHub**
|
|
||||||
```bash
|
|
||||||
# In your tcg-vault directory
|
|
||||||
cd backend
|
|
||||||
git init
|
|
||||||
git add .
|
|
||||||
git commit -m "TCG Vault backend for deployment"
|
|
||||||
git branch -M main
|
|
||||||
# Create a new GitHub repo and push
|
|
||||||
git remote add origin YOUR_GITHUB_REPO_URL
|
|
||||||
git push -u origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. **Deploy to Railway**
|
|
||||||
1. In Railway dashboard: **"New Project"**
|
|
||||||
2. **"Deploy from GitHub repo"**
|
|
||||||
3. Select your backend repository
|
|
||||||
4. Railway auto-detects Python and uses our `railway.toml` config
|
|
||||||
5. **Deployment starts automatically!**
|
|
||||||
|
|
||||||
### 4. **Set Environment Variables (Important!)**
|
|
||||||
In Railway dashboard, add environment variable:
|
|
||||||
```
|
|
||||||
ALLOWED_ORIGINS=https://your-vercel-domain.vercel.app
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. **Get Your API URL**
|
|
||||||
- Copy your Railway app URL (e.g., `https://tcg-vault-backend-production-xyz.up.railway.app`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌟 **Step 2: Deploy Frontend to Vercel Pro (3 minutes)**
|
|
||||||
|
|
||||||
### 1. **Connect GitHub to Vercel**
|
|
||||||
```bash
|
|
||||||
# In your tcg-vault directory
|
|
||||||
cd frontend
|
|
||||||
git init
|
|
||||||
git add .
|
|
||||||
git commit -m "TCG Vault frontend for Vercel"
|
|
||||||
git branch -M main
|
|
||||||
# Create GitHub repo for frontend
|
|
||||||
git remote add origin YOUR_FRONTEND_GITHUB_REPO_URL
|
|
||||||
git push -u origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. **Deploy to Vercel**
|
|
||||||
1. Go to [vercel.com/dashboard](https://vercel.com/dashboard)
|
|
||||||
2. **"Import Project"** → Choose your frontend GitHub repo
|
|
||||||
3. **Framework**: React (auto-detected)
|
|
||||||
4. **Build Settings**: Use defaults
|
|
||||||
5. **Environment Variables** → Add:
|
|
||||||
```
|
|
||||||
REACT_APP_API_URL=https://your-railway-backend-url.up.railway.app/api/v1
|
|
||||||
```
|
|
||||||
6. **Deploy!** ✨
|
|
||||||
|
|
||||||
### 3. **Custom Domain (Optional)**
|
|
||||||
- Use your existing domain or get a new one
|
|
||||||
- Vercel Pro includes SSL certificates automatically
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 **Alternative Options** (If you want to compare)
|
|
||||||
|
|
||||||
### **Option 2: DreamHost (Frontend) + Railway (Backend)**
|
|
||||||
- **Cost**: $0/month (uses existing DreamHost)
|
|
||||||
- **Performance**: Good, but not as fast as Vercel Pro
|
|
||||||
- **Setup**: Manual file uploads vs automatic Git deployments
|
|
||||||
|
|
||||||
### **Option 3: DreamHost VPS ($12/month)**
|
|
||||||
- **Full Python support** - Deploy everything together
|
|
||||||
- **More expensive** than using your existing Vercel Pro
|
|
||||||
|
|
||||||
### **Option 4: All Railway**
|
|
||||||
- **Frontend + Backend** both on Railway
|
|
||||||
- **Cost**: ~$5-10/month for frontend hosting
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 **Quick Deployment Checklist**
|
|
||||||
|
|
||||||
### ✅ Backend (Railway):
|
|
||||||
- [ ] Push backend code to GitHub
|
|
||||||
- [ ] Connect Railway to repository
|
|
||||||
- [ ] Set ALLOWED_ORIGINS environment variable
|
|
||||||
- [ ] Verify deployment success
|
|
||||||
- [ ] Copy API URL
|
|
||||||
|
|
||||||
### ✅ Frontend (Vercel Pro):
|
|
||||||
- [ ] Push frontend code to GitHub
|
|
||||||
- [ ] Import project in Vercel dashboard
|
|
||||||
- [ ] Set REACT_APP_API_URL environment variable
|
|
||||||
- [ ] Deploy and verify
|
|
||||||
- [ ] Optional: Set up custom domain
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ **Troubleshooting**
|
|
||||||
|
|
||||||
### **Common Issues:**
|
|
||||||
|
|
||||||
**1. CORS Errors**
|
|
||||||
- Ensure ALLOWED_ORIGINS in Railway includes your Vercel domain
|
|
||||||
|
|
||||||
**2. API Not Found**
|
|
||||||
- Double-check REACT_APP_API_URL in Vercel environment variables
|
|
||||||
- Ensure Railway backend is running (check Railway logs)
|
|
||||||
|
|
||||||
**3. Build Failures**
|
|
||||||
- Check Vercel build logs in dashboard
|
|
||||||
- Verify all dependencies are in package.json
|
|
||||||
|
|
||||||
**4. OCR Not Working**
|
|
||||||
- OCR runs client-side with Vercel's edge computing - should work great!
|
|
||||||
- Check browser console for any errors
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 **Expected Results with Vercel Pro**
|
|
||||||
|
|
||||||
After deployment, you'll have **enterprise-grade hosting**:
|
|
||||||
- ⚡ **Blazing fast worldwide** - 40+ edge locations
|
|
||||||
- 📱 **Perfect mobile performance** - OCR scanning works flawlessly
|
|
||||||
- 🛡️ **Advanced security** - WAF protection included
|
|
||||||
- 📊 **Performance monitoring** - Built-in observability tools
|
|
||||||
- 🔄 **Automatic deployments** - Push to Git, instantly live
|
|
||||||
- ✨ **All visual effects** - Enhanced with edge optimization
|
|
||||||
- 🌍 **Global scalability** - Handles traffic spikes automatically
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💡 **Pro Tips for Vercel Pro Users**
|
|
||||||
|
|
||||||
### **Performance Optimization:**
|
|
||||||
- Your **1TB transfer limit** easily handles high-traffic
|
|
||||||
- **Cold start prevention** keeps your app instantly responsive
|
|
||||||
- **Advanced caching** speeds up repeat visits
|
|
||||||
|
|
||||||
### **Development Workflow:**
|
|
||||||
- **Preview deployments** for every Git branch
|
|
||||||
- **Automatic PR previews** for testing features
|
|
||||||
- **Instant rollbacks** if anything goes wrong
|
|
||||||
|
|
||||||
### **Monitoring:**
|
|
||||||
- Use **Observability tools** to track performance
|
|
||||||
- **Web Analytics** to see user behavior
|
|
||||||
- **Speed Insights** to optimize further
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎉 **Your TCG Vault Will Be Professional-Grade!**
|
|
||||||
|
|
||||||
With Vercel Pro + Railway, you get:
|
|
||||||
- **Netflix-level performance** for your card scanner
|
|
||||||
- **$0 additional cost** (using existing Vercel Pro)
|
|
||||||
- **Enterprise security** and reliability
|
|
||||||
- **Automatic scaling** to handle any traffic
|
|
||||||
- **Professional deployment pipeline**
|
|
||||||
|
|
||||||
**Ready to deploy to your Vercel Pro account?** This will be significantly better than any shared hosting option! 🚀
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
||||||
# Dual View System & Image Handling
|
|
||||||
|
|
||||||
## 🎨 **View Modes**
|
|
||||||
|
|
||||||
TCG Vault now supports two distinct viewing modes for your card collection:
|
|
||||||
|
|
||||||
### 🃏 **Card View**
|
|
||||||
- **Image-focused** display showing card artwork prominently
|
|
||||||
- **Responsive grid** that adapts from 1 column (mobile) to 5 columns (ultra-wide)
|
|
||||||
- **Large card images** with automatic fallbacks to game-themed placeholders
|
|
||||||
- **Clean, minimal information** focusing on visual identification
|
|
||||||
|
|
||||||
### 📊 **Table View**
|
|
||||||
- **Data-focused** tabular display for detailed card information
|
|
||||||
- **Small thumbnail** images alongside comprehensive card data
|
|
||||||
- **Sortable columns** for quick data analysis
|
|
||||||
- **Compact format** ideal for managing large collections
|
|
||||||
|
|
||||||
## 🖼️ **Dual Image System**
|
|
||||||
|
|
||||||
### Stock Images (Official Reference)
|
|
||||||
- **Purpose**: Clean, official card images for consistent presentation
|
|
||||||
- **Usage**: Primary display in both view modes
|
|
||||||
- **Features**:
|
|
||||||
- High-quality scans from official sources
|
|
||||||
- Artwork cropping coordinates for thumbnails
|
|
||||||
- Consistent lighting and framing
|
|
||||||
|
|
||||||
### User Card Photos
|
|
||||||
- **Purpose**: Photos of your actual physical cards
|
|
||||||
- **Usage**: Quality assessment and condition documentation
|
|
||||||
- **Features**:
|
|
||||||
- Multiple photos per card copy
|
|
||||||
- Condition-specific documentation
|
|
||||||
- Quality comparison with stock images
|
|
||||||
|
|
||||||
## 🔄 **Image Display Features**
|
|
||||||
|
|
||||||
### Smart Fallbacks
|
|
||||||
When card images aren't available, the system displays:
|
|
||||||
- **Game-themed gradients** (Orange for MTG, Yellow for Pokemon, Purple for Lorcana)
|
|
||||||
- **Card name** abbreviated for readability
|
|
||||||
- **Game identifier** for quick recognition
|
|
||||||
- **Consistent sizing** maintaining layout integrity
|
|
||||||
|
|
||||||
### Interactive Controls
|
|
||||||
- **📸/📋 Toggle**: Switch between stock and user photos
|
|
||||||
- **◄/► Navigation**: Browse multiple user photos
|
|
||||||
- **👤/✓ Indicators**: Visual cues for image type
|
|
||||||
- **Photo counters**: Show current photo index (e.g., "2/3")
|
|
||||||
|
|
||||||
## 📁 **Image Storage Structure**
|
|
||||||
|
|
||||||
```
|
|
||||||
frontend/public/images/cards/
|
|
||||||
├── mtg/ # Magic: The Gathering
|
|
||||||
│ ├── lightning-bolt-alpha.jpg
|
|
||||||
│ └── black-lotus-alpha.jpg
|
|
||||||
├── pokemon/ # Pokémon
|
|
||||||
│ └── pikachu-base-set.jpg
|
|
||||||
└── lorcana/ # Disney Lorcana
|
|
||||||
├── mickey-brave-tailor-tfc.jpg
|
|
||||||
├── elsa-snow-queen-tfc.jpg
|
|
||||||
├── be-prepared-tfc.jpg
|
|
||||||
└── mickey-steamboat-pilot-tfc.jpg
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠️ **Database Schema**
|
|
||||||
|
|
||||||
### Cards Table (New Fields)
|
|
||||||
- `stock_image_url`: Official card image path
|
|
||||||
- `artwork_crop_coords`: JSON with cropping coordinates `{x, y, width, height}`
|
|
||||||
- `image_url`: Legacy field for backward compatibility
|
|
||||||
|
|
||||||
### Collection Cards Table (New Fields)
|
|
||||||
- `user_images`: JSON array of user photo paths
|
|
||||||
- `condition_notes`: Detailed condition descriptions
|
|
||||||
|
|
||||||
## 🎯 **Usage Examples**
|
|
||||||
|
|
||||||
### Card Identification
|
|
||||||
- **Card View**: Visual browsing and identification
|
|
||||||
- **Stock Images**: Official reference for card verification
|
|
||||||
- **Game badges**: Quick game identification
|
|
||||||
|
|
||||||
### Collection Management
|
|
||||||
- **Table View**: Data analysis and bulk operations
|
|
||||||
- **User Photos**: Document card conditions and variations
|
|
||||||
- **Pricing**: Track market values alongside visual condition
|
|
||||||
|
|
||||||
### Quality Assessment
|
|
||||||
- **Side-by-side comparison**: Stock image vs. your card photos
|
|
||||||
- **Multiple angles**: Document different aspects of card condition
|
|
||||||
- **Condition notes**: Detailed written condition descriptions
|
|
||||||
|
|
||||||
## 🚀 **Future Enhancements**
|
|
||||||
|
|
||||||
### Image Processing
|
|
||||||
- **Automatic cropping**: Extract artwork from card images
|
|
||||||
- **Quality scoring**: AI-based condition assessment
|
|
||||||
- **OCR integration**: Extract text from user photos
|
|
||||||
|
|
||||||
### Advanced Views
|
|
||||||
- **Gallery mode**: Large image browsing
|
|
||||||
- **Comparison mode**: Side-by-side stock vs. user photos
|
|
||||||
- **3D card view**: Interactive card rotation
|
|
||||||
|
|
||||||
### Collection Features
|
|
||||||
- **Image upload**: Drag-and-drop card photo upload
|
|
||||||
- **Batch processing**: Upload multiple card photos at once
|
|
||||||
- **Cloud storage**: Backup and sync card photos across devices
|
|
||||||
|
|
||||||
This dual-view system provides the foundation for professional-grade collection management while maintaining ease of use for casual collectors.
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
# Game-Specific Features Guide
|
|
||||||
|
|
||||||
## Supported Trading Card Games
|
|
||||||
|
|
||||||
### Magic: The Gathering (MTG)
|
|
||||||
**Game Code**: `MTG`
|
|
||||||
|
|
||||||
**Key Features**:
|
|
||||||
- Mana costs with colored symbols `{W}{U}{B}{R}{G}{C}`
|
|
||||||
- Converted Mana Cost (CMC)
|
|
||||||
- Card types: Creature, Instant, Sorcery, Artifact, Enchantment, Planeswalker, Land
|
|
||||||
- Power/Toughness for creatures
|
|
||||||
- Loyalty for planeswalkers
|
|
||||||
- Colors: White, Blue, Black, Red, Green, Colorless
|
|
||||||
- Rarities: Common, Uncommon, Rare, Mythic Rare
|
|
||||||
|
|
||||||
**Sample Cards Added**:
|
|
||||||
- Lightning Bolt (Red Instant)
|
|
||||||
- Black Lotus (Artifact)
|
|
||||||
|
|
||||||
### Pokémon
|
|
||||||
**Game Code**: `POKEMON`
|
|
||||||
|
|
||||||
**Key Features**:
|
|
||||||
- Energy costs (Fighting, Fire, Water, Lightning, Psychic, Grass, Darkness, Metal, Fairy, Colorless)
|
|
||||||
- HP for Pokémon
|
|
||||||
- Attack damage
|
|
||||||
- Weakness/Resistance
|
|
||||||
- Card types: Pokémon, Trainer, Energy
|
|
||||||
- Pokémon stages: Basic, Stage 1, Stage 2, EX, GX, V, VMAX
|
|
||||||
- Rarities: Common, Uncommon, Rare, Ultra Rare, Secret Rare
|
|
||||||
|
|
||||||
**Sample Cards Added**:
|
|
||||||
- Pikachu (Basic Lightning Pokémon)
|
|
||||||
|
|
||||||
### Disney Lorcana
|
|
||||||
**Game Code**: `LORCANA`
|
|
||||||
|
|
||||||
**Key Features**:
|
|
||||||
- Ink costs (single number)
|
|
||||||
- Characters have Strength and Willpower
|
|
||||||
- Card types: Character, Action, Item, Location
|
|
||||||
- Character classifications: Storyborn, Dreamborn, Floodborn
|
|
||||||
- Ink colors: Amber, Amethyst, Emerald, Ruby, Sapphire, Steel
|
|
||||||
- Abilities: Evasive, Ward, Bodyguard, Challenger, Rush, Shift, Support
|
|
||||||
- Songs can be sung by characters
|
|
||||||
- Rarities: Common, Uncommon, Rare, Super Rare, Legendary, Enchanted
|
|
||||||
|
|
||||||
**Sample Cards Added**:
|
|
||||||
- Mickey Mouse - Brave Little Tailor (Legendary Amber Character)
|
|
||||||
- Elsa - Snow Queen (Super Rare Sapphire Character)
|
|
||||||
- Be Prepared (Rare Emerald Action/Song)
|
|
||||||
- Mickey Mouse - Steamboat Pilot (Common Amber Character)
|
|
||||||
|
|
||||||
## Database Field Mapping
|
|
||||||
|
|
||||||
### Universal Fields
|
|
||||||
- `name`: Card name
|
|
||||||
- `game`: Game code (MTG/POKEMON/LORCANA)
|
|
||||||
- `set_name`: Set/expansion name
|
|
||||||
- `set_code`: Set abbreviation
|
|
||||||
- `card_number`: Collector number
|
|
||||||
- `rarity`: Rarity level
|
|
||||||
- `current_price`: Market price
|
|
||||||
- `image_url`: Card image URL
|
|
||||||
|
|
||||||
### Game-Specific Field Usage
|
|
||||||
|
|
||||||
| Field | MTG | Pokemon | Lorcana |
|
|
||||||
|-------|-----|---------|---------|
|
|
||||||
| `mana_cost` | Mana symbols | Energy requirements | Ink cost |
|
|
||||||
| `cmc` | Converted mana cost | Total energy cost | Ink cost |
|
|
||||||
| `card_type` | Full type line | Card type + stage | Character classification |
|
|
||||||
| `colors` | Color identity | Energy types | Ink colors |
|
|
||||||
| `power` | Creature power | Attack damage | Character strength |
|
|
||||||
| `toughness` | Creature toughness | HP | Character willpower |
|
|
||||||
| `loyalty` | Planeswalker loyalty | - | - |
|
|
||||||
| `oracle_text` | Rules text | Effect text | Ability text |
|
|
||||||
|
|
||||||
## Future Implementation Ideas
|
|
||||||
|
|
||||||
### OCR Recognition Patterns
|
|
||||||
- **MTG**: Recognize mana symbols, card frames, set symbols
|
|
||||||
- **Pokemon**: Identify energy symbols, HP values, stage indicators
|
|
||||||
- **Lorcana**: Detect ink costs, character stats, Disney artwork style
|
|
||||||
|
|
||||||
### Deck Building Rules
|
|
||||||
- **MTG**: 60-card minimum, 4-of limit, format restrictions
|
|
||||||
- **Pokemon**: 60-card decks, prize cards, energy requirements
|
|
||||||
- **Lorcana**: 60-card decks, ink system, character limits
|
|
||||||
|
|
||||||
### Pricing Sources
|
|
||||||
- **MTG**: TCGPlayer, MTG Goldfish, EDHREC
|
|
||||||
- **Pokemon**: TCGPlayer, PTCGO prices, PokeBeach
|
|
||||||
- **Lorcana**: TCGPlayer, eBay sold listings (newer game)
|
|
||||||
|
|
@ -1,191 +0,0 @@
|
||||||
# Gradient Border System with Mouse-Tracking Glow
|
|
||||||
|
|
||||||
## 🌈 **Overview**
|
|
||||||
|
|
||||||
TCG Vault now features stunning gradient borders that replace the old solid borders with dynamic, multi-colored gradients that respond to mouse movement with localized glow effects.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✨ **Gradient Border Features**
|
|
||||||
|
|
||||||
### **Multi-Layer Gradient Design**
|
|
||||||
- **Dual-background technique**: Uses CSS `padding-box` and `border-box` to create clean content areas with gradient borders
|
|
||||||
- **Progressive intensity**: Higher rarity cards get more complex, multi-stop gradients
|
|
||||||
- **Color harmony**: Each rarity uses a carefully crafted color palette that transitions smoothly
|
|
||||||
|
|
||||||
### **Rarity-Specific Gradients**
|
|
||||||
|
|
||||||
| Rarity | Gradient Colors | Effect Intensity |
|
|
||||||
|--------|----------------|------------------|
|
|
||||||
| **Common** | Gray (`#6B7280` → `#9CA3AF` → `#6B7280`) | Subtle 2-stop gradient |
|
|
||||||
| **Uncommon** | Green (`#22C55E` → `#4ADE80` → `#22C55E`) | Medium 2-stop gradient |
|
|
||||||
| **Rare** | Blue (`#3B82F6` → `#6366F1` → `#3B82F6`) | Bright 2-stop gradient |
|
|
||||||
| **Super Rare** | Purple (`#9333EA` → `#A855F7` → `#C4B5FD` → `#A855F7` → `#9333EA`) | Complex 5-stop gradient |
|
|
||||||
| **Legendary** | Gold (`#F59E0B` → `#FBBF24` → `#FEF08A` → `#FBBF24` → `#F59E0B`) | Intense 5-stop gradient |
|
|
||||||
| **Mythic** | Red (`#EF4444` → `#F87171` → `#FECACA` → `#F87171` → `#EF4444`) | Maximum 5-stop gradient |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 **Mouse-Tracking Glow System**
|
|
||||||
|
|
||||||
### **Dynamic Glow Effect**
|
|
||||||
- **Real-time tracking**: Mouse position is tracked at 60fps with throttling for performance
|
|
||||||
- **Radial glow**: 150px radius circular glow that follows the cursor within card boundaries
|
|
||||||
- **Progressive opacity**: Glow fades from center to edges with multiple intensity stops
|
|
||||||
- **Blur enhancement**: 2px blur filter creates a soft, professional glow effect
|
|
||||||
|
|
||||||
### **Technical Implementation**
|
|
||||||
|
|
||||||
#### **Custom Hook: `useMouseGlow`**
|
|
||||||
```typescript
|
|
||||||
const { ref, glowStyles, isHovering } = useMouseGlow({
|
|
||||||
glowIntensity: 0.8, // Brightness of the glow (0-1)
|
|
||||||
glowRadius: 150, // Size of the glow circle in pixels
|
|
||||||
updateThrottle: 16 // Update frequency (~60fps)
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **CSS Custom Properties**
|
|
||||||
```css
|
|
||||||
--glow-x: 50%; /* Horizontal glow position */
|
|
||||||
--glow-y: 50%; /* Vertical glow position */
|
|
||||||
--glow-intensity: 0.8; /* Glow brightness */
|
|
||||||
--rarity-shadow-color: rgba(...); /* Rarity-specific shadow color */
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 **Visual Enhancement Effects**
|
|
||||||
|
|
||||||
### **Hover Animations**
|
|
||||||
- **Scale transform**: Cards scale up 2-3% on hover based on rarity
|
|
||||||
- **Brightness filter**: Enhanced brightness (1.1× - 1.2×) for premium feel
|
|
||||||
- **Saturation boost**: Higher rarity cards get increased color saturation
|
|
||||||
- **Pulse animation**: Super Rare+ cards get a breathing glow effect
|
|
||||||
|
|
||||||
### **Performance Optimizations**
|
|
||||||
- **Hardware acceleration**: Uses `transform3d()` and `will-change`
|
|
||||||
- **Throttled updates**: Mouse tracking limited to 60fps
|
|
||||||
- **Event cleanup**: Proper cleanup on component unmount
|
|
||||||
- **CSS-only animations**: Smooth 60fps animations without JavaScript
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ **Component Architecture**
|
|
||||||
|
|
||||||
### **GlowingCard Component**
|
|
||||||
```typescript
|
|
||||||
<GlowingCard rarity={card.rarity} className="card-container">
|
|
||||||
{/* Card content */}
|
|
||||||
</GlowingCard>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Automatic rarity detection and intensity adjustment
|
|
||||||
- Built-in mouse tracking and glow effects
|
|
||||||
- Seamless integration with existing card components
|
|
||||||
- Responsive glow radius and intensity
|
|
||||||
|
|
||||||
### **Rarity-Specific Intensities**
|
|
||||||
- **Common**: 0.4 intensity - Subtle glow
|
|
||||||
- **Uncommon**: 0.5 intensity - Light glow
|
|
||||||
- **Rare**: 0.6 intensity - Medium glow
|
|
||||||
- **Super Rare**: 0.7 intensity - Strong glow
|
|
||||||
- **Legendary**: 0.8 intensity - Intense glow
|
|
||||||
- **Mythic**: 0.8 intensity - Maximum glow
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💫 **Advanced Effects**
|
|
||||||
|
|
||||||
### **Pulse Animation for Premium Cards**
|
|
||||||
Super Rare, Legendary, and Mythic cards feature a continuous pulse animation:
|
|
||||||
- **Shadow expansion**: Box shadow grows and contracts rhythmically
|
|
||||||
- **2-second cycle**: Smooth, non-intrusive breathing effect
|
|
||||||
- **Rarity-specific colors**: Each rarity pulses with its signature color
|
|
||||||
- **Hover enhancement**: Pulse becomes more pronounced on hover
|
|
||||||
|
|
||||||
### **Multi-Layer Shadow System**
|
|
||||||
```css
|
|
||||||
box-shadow:
|
|
||||||
0 0 30px var(--rarity-shadow-color), /* Inner glow */
|
|
||||||
0 0 60px var(--rarity-shadow-color); /* Outer glow */
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎮 **Interactive Behavior**
|
|
||||||
|
|
||||||
### **Mouse Enter/Leave**
|
|
||||||
1. **Mouse Enter**: Glow effect activates and begins tracking cursor
|
|
||||||
2. **Mouse Move**: Glow position updates in real-time following cursor
|
|
||||||
3. **Mouse Leave**: Glow fades out and resets to center position
|
|
||||||
|
|
||||||
### **Smooth Transitions**
|
|
||||||
- **0.2s opacity transitions**: Glow fades in/out smoothly
|
|
||||||
- **0.3s transform transitions**: Hover scaling with easing
|
|
||||||
- **Continuous tracking**: No lag between mouse movement and glow position
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📱 **Responsive Design**
|
|
||||||
|
|
||||||
### **Screen Size Adaptations**
|
|
||||||
- **Desktop**: Full 150px glow radius with maximum intensity
|
|
||||||
- **Tablet**: Scaled glow effects for touch interaction
|
|
||||||
- **Mobile**: Reduced complexity while maintaining visual appeal
|
|
||||||
|
|
||||||
### **Performance Considerations**
|
|
||||||
- **Reduced motion support**: Respects `prefers-reduced-motion` settings
|
|
||||||
- **Battery optimization**: Effects pause when not visible
|
|
||||||
- **GPU acceleration**: Smooth 60fps on all supported devices
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 **Integration Examples**
|
|
||||||
|
|
||||||
### **Card View Mode**
|
|
||||||
```typescript
|
|
||||||
// Large cards with prominent gradient borders and mouse tracking
|
|
||||||
<GlowingCard rarity="Legendary" className="card-large">
|
|
||||||
<CardImageDisplay card={card} size="large" />
|
|
||||||
{/* Card content */}
|
|
||||||
</GlowingCard>
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Table View Mode**
|
|
||||||
```typescript
|
|
||||||
// Table rows with subtle left-border gradient accents
|
|
||||||
<tr style={{borderLeftColor: getRarityColor(card.rarity)}}>
|
|
||||||
{/* Table content */}
|
|
||||||
</tr>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 **Future Enhancements**
|
|
||||||
|
|
||||||
### **Planned Features**
|
|
||||||
- **Gesture support**: Touch-based glow interactions for mobile
|
|
||||||
- **Particle effects**: Floating sparkles for Mythic+ cards
|
|
||||||
- **Color animation**: Shifting gradient hues over time
|
|
||||||
- **3D depth**: Layered glow effects with perspective
|
|
||||||
|
|
||||||
### **Performance Improvements**
|
|
||||||
- **WebGL acceleration**: GPU-based glow rendering
|
|
||||||
- **Intersection observer**: Only animate visible cards
|
|
||||||
- **Worker threads**: Offload calculations from main thread
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 **Design Philosophy**
|
|
||||||
|
|
||||||
**Visual Hierarchy**: Gradient intensity reflects card rarity and importance
|
|
||||||
|
|
||||||
**Performance First**: All effects maintain 60fps with hardware acceleration
|
|
||||||
|
|
||||||
**Accessibility Aware**: Respects motion preferences and maintains readability
|
|
||||||
|
|
||||||
**Progressive Enhancement**: Works gracefully across all device capabilities
|
|
||||||
|
|
||||||
This gradient border system elevates the visual experience while maintaining the clean, professional aesthetic that makes TCG Vault feel premium and modern! ✨🌈🎮
|
|
||||||
160
README.md
160
README.md
|
|
@ -1,99 +1,121 @@
|
||||||
# TCG Vault - Trading Card Collection Manager
|
# TCG Vault
|
||||||
|
|
||||||
A comprehensive trading card database system with OCR scanning, AI-powered deck building, and real-time pricing.
|
A modern trading card game collection manager built with Next.js and Neon Database.
|
||||||
|
|
||||||
## Features
|
## 🚀 Features
|
||||||
|
|
||||||
🃏 **Complete Card Database**
|
- **Card Management**: Track your MTG, Pokémon, and Lorcana cards
|
||||||
- Store and organize your entire trading card collection
|
- **Collection Organization**: Create and manage card collections
|
||||||
- Track card conditions, quantities, and locations
|
- **Deck Building**: Build and share decks
|
||||||
- Support for multiple TCG formats (Magic: The Gathering, Pokémon, Yu-Gi-Oh!, etc.)
|
- **Authentication**: Secure user accounts with JWT
|
||||||
|
- **Admin Panel**: Manage cards and users
|
||||||
|
- **Real-time Pricing**: Track card values
|
||||||
|
|
||||||
📸 **OCR Card Scanning**
|
## 🛠️ Tech Stack
|
||||||
- Scan physical cards using your camera or smartphone
|
|
||||||
- Automatic card recognition and data extraction
|
|
||||||
- Bulk scanning support for efficient collection entry
|
|
||||||
|
|
||||||
🤖 **AI-Powered Features**
|
- **Frontend**: Next.js 15, React 18, TypeScript
|
||||||
- Intelligent deck building recommendations based on your collection
|
- **Backend**: Next.js API Routes
|
||||||
- Natural language queries for searching your database
|
- **Database**: Neon PostgreSQL (serverless)
|
||||||
- Meta analysis and card synergy suggestions
|
- **Authentication**: JWT with bcrypt
|
||||||
|
- **Styling**: Tailwind CSS
|
||||||
|
- **Deployment**: Vercel
|
||||||
|
|
||||||
💰 **Real-time Pricing**
|
## 📦 Installation
|
||||||
- Live price tracking from multiple sources
|
|
||||||
- Collection valuation and price alerts
|
|
||||||
- Historical price charts and market trends
|
|
||||||
|
|
||||||
🎨 **Modern Web Interface**
|
1. **Clone the repository**
|
||||||
- Responsive design for desktop and mobile
|
|
||||||
- Drag-and-drop deck building
|
|
||||||
- Advanced filtering and search capabilities
|
|
||||||
|
|
||||||
## Tech Stack
|
|
||||||
|
|
||||||
- **Backend**: Python FastAPI with SQLAlchemy ORM
|
|
||||||
- **Database**: SQLite (production-ready, can scale to PostgreSQL)
|
|
||||||
- **Frontend**: React with TypeScript and Tailwind CSS
|
|
||||||
- **OCR**: OpenCV + Tesseract with cloud vision APIs
|
|
||||||
- **AI**: OpenAI GPT integration for intelligent features
|
|
||||||
- **Pricing**: TCGPlayer and MTGJSON API integration
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
1. **Backend Setup**:
|
|
||||||
```bash
|
```bash
|
||||||
cd backend
|
git clone <repository-url>
|
||||||
pip install -r requirements.txt
|
cd tcg-vault
|
||||||
uvicorn main:app --reload
|
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Frontend Setup**:
|
2. **Install dependencies**
|
||||||
```bash
|
```bash
|
||||||
cd frontend
|
|
||||||
npm install
|
npm install
|
||||||
npm start
|
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Database Initialize**:
|
3. **Set up environment variables**
|
||||||
```bash
|
```bash
|
||||||
python backend/init_db.py
|
cp .env.example .env.local
|
||||||
```
|
```
|
||||||
|
|
||||||
## Project Structure
|
Update `.env.local` with your Neon database URL:
|
||||||
|
```env
|
||||||
|
POSTGRES_URL="postgresql://your-username:your-password@your-host/your-database"
|
||||||
|
JWT_SECRET="your-super-secret-jwt-key"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Set up the database**
|
||||||
|
```bash
|
||||||
|
npm run setup-db
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Start development server**
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🗄️ Database Schema
|
||||||
|
|
||||||
|
The application uses the following tables:
|
||||||
|
- `users` - User accounts and authentication
|
||||||
|
- `cards` - Card information and metadata
|
||||||
|
- `user_cards` - User's card collections
|
||||||
|
- `collections` - Named card collections
|
||||||
|
- `collection_cards` - Cards in collections
|
||||||
|
- `decks` - Deck definitions
|
||||||
|
- `deck_cards` - Cards in decks
|
||||||
|
|
||||||
|
## 🔧 API Endpoints
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
- `POST /api/auth/register` - User registration
|
||||||
|
- `POST /api/auth/login` - User login
|
||||||
|
|
||||||
|
### Admin
|
||||||
|
- `GET /api/admin` - Admin panel data
|
||||||
|
|
||||||
|
### Health Check
|
||||||
|
- `GET /api/health` - Application health
|
||||||
|
- `GET /api/test-db` - Database connection test
|
||||||
|
|
||||||
|
## 🚀 Deployment
|
||||||
|
|
||||||
|
This app is configured for deployment on Vercel:
|
||||||
|
|
||||||
|
1. **Connect your repository** to Vercel
|
||||||
|
2. **Set environment variables** in Vercel dashboard
|
||||||
|
3. **Deploy automatically** on push to main branch
|
||||||
|
|
||||||
|
## 📁 Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
tcg-vault/
|
tcg-vault/
|
||||||
├── backend/ # FastAPI backend
|
├── pages/ # Next.js pages and API routes
|
||||||
│ ├── app/
|
│ ├── api/ # API endpoints
|
||||||
│ │ ├── models/ # SQLAlchemy models
|
│ │ ├── auth/ # Authentication routes
|
||||||
│ │ ├── routers/ # API route handlers
|
│ │ └── admin/ # Admin routes
|
||||||
│ │ ├── services/ # Business logic
|
│ ├── _app.js # App wrapper
|
||||||
│ │ └── utils/ # Utilities (OCR, AI, pricing)
|
│ └── index.js # Home page
|
||||||
│ ├── tests/ # Backend tests
|
├── lib/ # Utility libraries
|
||||||
│ └── requirements.txt
|
│ └── database.js # Database adapter
|
||||||
├── frontend/ # React frontend
|
├── scripts/ # Database setup scripts
|
||||||
│ ├── src/
|
├── public/ # Static assets
|
||||||
│ │ ├── components/
|
└── .env.local # Environment variables
|
||||||
│ │ ├── pages/
|
|
||||||
│ │ ├── services/ # API clients
|
|
||||||
│ │ └── utils/
|
|
||||||
│ └── package.json
|
|
||||||
├── docs/ # Documentation
|
|
||||||
└── docker-compose.yml # Container orchestration
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development
|
## 🔐 Default Admin Account
|
||||||
|
|
||||||
This project is designed for easy development and deployment. See the individual README files in `backend/` and `frontend/` for detailed setup instructions.
|
After running the database setup:
|
||||||
|
- **Email**: admin@tcgvault.com
|
||||||
|
- **Password**: admin123
|
||||||
|
|
||||||
## Contributing
|
## 🤝 Contributing
|
||||||
|
|
||||||
1. Fork the repository
|
1. Fork the repository
|
||||||
2. Create a feature branch
|
2. Create a feature branch
|
||||||
3. Make your changes
|
3. Make your changes
|
||||||
4. Add tests
|
4. Submit a pull request
|
||||||
5. Submit a pull request
|
|
||||||
|
|
||||||
## License
|
## 📄 License
|
||||||
|
|
||||||
MIT License - feel free to use this project for your own collection management needs!
|
MIT License - see LICENSE file for details
|
||||||
|
|
@ -1,220 +0,0 @@
|
||||||
# Visual Effects & 3D Card System
|
|
||||||
|
|
||||||
## 🎨 **Overview**
|
|
||||||
|
|
||||||
TCG Vault now features stunning visual effects that bring your trading cards to life with premium 3D interactions, foil shimmer effects, and rarity-based visual flair.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✨ **3D Card Tilt Effects**
|
|
||||||
|
|
||||||
### **Interactive Mouse Tracking**
|
|
||||||
- **Real-time 3D rotation** based on cursor position within card areas
|
|
||||||
- **Perspective-correct transforms** that create realistic depth
|
|
||||||
- **Smooth animations** with customizable easing curves
|
|
||||||
- **Performance optimized** with `will-change` and `transform3d` acceleration
|
|
||||||
|
|
||||||
### **Configuration**
|
|
||||||
```typescript
|
|
||||||
// Configurable tilt settings with smooth expansion
|
|
||||||
{
|
|
||||||
maxTilt: 15, // Maximum rotation degrees
|
|
||||||
perspective: 1000, // 3D perspective depth
|
|
||||||
scale: 1.06, // Hover scale factor (increased for premium feel)
|
|
||||||
speed: 700, // Animation speed in ms (slower for elegance)
|
|
||||||
reset: true, // Auto-reset on mouse leave
|
|
||||||
easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)' // Smooth organic easing
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Size-Responsive Behavior**
|
|
||||||
- **Large cards**: 15° max tilt, 1.06× scale
|
|
||||||
- **Medium cards**: 10° max tilt, 1.03× scale
|
|
||||||
- **Small cards**: 10° max tilt, 1.03× scale
|
|
||||||
|
|
||||||
### **Smooth Expansion System**
|
|
||||||
- **Organic Timing**: 0.6s → 0.8s gradual expansion with elegant easing curves
|
|
||||||
- **Premium Rarities**: Ultra-smooth 0.8s → 1.2s expansion for Legendary/Mythic cards
|
|
||||||
- **Mythic Enhancement**: Special 1.4s breathe-like expansion for maximum premium feel
|
|
||||||
- **Layered Animation**: Different card elements animate with subtle 0.05s delays
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌟 **Foil & Shimmer Effects**
|
|
||||||
|
|
||||||
### **Foil Cards**
|
|
||||||
Applied to: **Super Rare**, **Legendary**, and **Mythic** cards
|
|
||||||
- **Sweep shimmer**: Elegant light sweep on hover
|
|
||||||
- **Semi-transparent overlay**: Maintains card visibility
|
|
||||||
- **Performance optimized**: CSS-only animations
|
|
||||||
|
|
||||||
### **Holographic Effect**
|
|
||||||
Applied to: **Legendary** and **Mythic** cards only
|
|
||||||
- **Rainbow gradient animation**: Continuously shifting spectrum
|
|
||||||
- **Multi-layer composition**: Background holo with content preservation
|
|
||||||
- **Subtle transparency**: Maintains readability while adding premium feel
|
|
||||||
|
|
||||||
### **Foil Types by Rarity**
|
|
||||||
- **Super Rare**: Basic foil shimmer
|
|
||||||
- **Legendary**: Holographic rainbow + foil shimmer
|
|
||||||
- **Mythic**: Holographic rainbow + foil shimmer
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌈 **Rarity Border System**
|
|
||||||
|
|
||||||
### **Color-Coded Glows**
|
|
||||||
Each rarity gets a distinctive border color and glow effect:
|
|
||||||
|
|
||||||
| Rarity | Border Color | Glow Effect | Usage |
|
|
||||||
|--------|--------------|-------------|-------|
|
|
||||||
| **Common** | Gray (`#6B7280`) | Subtle glow | Everyday cards |
|
|
||||||
| **Uncommon** | Green (`#22C55E`) | Medium glow | Notable cards |
|
|
||||||
| **Rare** | Blue (`#3B82F6`) | Bright glow | Special cards |
|
|
||||||
| **Super Rare** | Purple (`#9333EA`) | Strong glow + foil | Premium cards |
|
|
||||||
| **Legendary** | Gold (`#F59E0B`) | Intense glow + holo | Ultra-rare cards |
|
|
||||||
| **Mythic** | Red (`#EF4444`) | Max glow + holo | Legendary cards |
|
|
||||||
|
|
||||||
### **Progressive Enhancement**
|
|
||||||
- **Static**: Subtle border with light glow
|
|
||||||
- **Hover**: Enhanced glow and border brightness
|
|
||||||
- **Animation**: Breathing glow effect for premium rarities
|
|
||||||
|
|
||||||
### **Contextual Application**
|
|
||||||
- **Card View**: Full border glow on card containers
|
|
||||||
- **Table View**: Subtle left-border accent in rows
|
|
||||||
- **Image Placeholders**: Integrated with game-themed gradients
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎮 **Interactive Behavior**
|
|
||||||
|
|
||||||
### **Mouse Events**
|
|
||||||
1. **Mouse Enter**: Activate 3D tilt tracking
|
|
||||||
2. **Mouse Move**: Update tilt angles in real-time
|
|
||||||
3. **Mouse Leave**: Smooth reset to neutral position
|
|
||||||
4. **Hover**: Enhance border glow and trigger foil effects
|
|
||||||
|
|
||||||
### **Touch Support**
|
|
||||||
- **Mobile optimized**: Reduced tilt angles for touch devices
|
|
||||||
- **Performance aware**: Smooth 60fps animations on mobile
|
|
||||||
- **Fallback graceful**: Standard hover effects where 3D isn't supported
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ **Technical Implementation**
|
|
||||||
|
|
||||||
### **Custom Hook: `use3DTilt`**
|
|
||||||
```typescript
|
|
||||||
const { ref, tiltStyles, tiltState } = use3DTilt({
|
|
||||||
maxTilt: 15,
|
|
||||||
scale: 1.05,
|
|
||||||
speed: 300
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### **CSS Classes**
|
|
||||||
```css
|
|
||||||
/* 3D Effects */
|
|
||||||
.card-3d // 3D container setup
|
|
||||||
.card-3d-inner // Inner element transforms
|
|
||||||
.card-transition // Smooth transitions
|
|
||||||
|
|
||||||
/* Foil Effects */
|
|
||||||
.foil-card // Basic shimmer sweep
|
|
||||||
.foil-rainbow // Rainbow gradient animation
|
|
||||||
.holographic // Full holographic effect
|
|
||||||
|
|
||||||
/* Rarity Borders */
|
|
||||||
.rarity-border-{rarity} // Color-specific borders
|
|
||||||
.rarity-border-glow // Breathing glow animation
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Performance Features**
|
|
||||||
- **Hardware acceleration**: Uses `transform3d()` and `will-change`
|
|
||||||
- **Optimized animations**: 60fps with CSS transitions
|
|
||||||
- **Memory efficient**: Event cleanup on unmount
|
|
||||||
- **Battery friendly**: Animation only during interaction
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 **Visual Hierarchy**
|
|
||||||
|
|
||||||
### **Information Priority**
|
|
||||||
1. **3D Tilt**: Primary interaction feedback
|
|
||||||
2. **Rarity Borders**: Secondary visual classification
|
|
||||||
3. **Foil Effects**: Premium card enhancement
|
|
||||||
4. **Holographic**: Ultra-rare card distinction
|
|
||||||
|
|
||||||
### **Accessibility**
|
|
||||||
- **Reduced motion support**: Respects `prefers-reduced-motion`
|
|
||||||
- **High contrast**: All effects maintain text readability
|
|
||||||
- **Focus indicators**: Clear keyboard navigation support
|
|
||||||
- **Screen reader**: Effects don't interfere with content
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 **Card Collection Experience**
|
|
||||||
|
|
||||||
### **Card View Mode**
|
|
||||||
- **Large 3D cards** with prominent tilt effects
|
|
||||||
- **Rarity glow borders** surrounding each card container
|
|
||||||
- **Foil shimmer** on premium cards during hover
|
|
||||||
- **Holographic animation** for legendary/mythic cards
|
|
||||||
|
|
||||||
### **Table View Mode**
|
|
||||||
- **Small thumbnails** with subtle 3D tilt
|
|
||||||
- **Border accent** on table rows matching rarity
|
|
||||||
- **Consistent effects** scaled appropriately for compact view
|
|
||||||
|
|
||||||
### **Placeholder Cards**
|
|
||||||
- **Game-themed gradients** as fallback for missing images
|
|
||||||
- **Full effect integration** - borders, foil, and 3D work on placeholders
|
|
||||||
- **Rarity-appropriate styling** even without card images
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 **Effect Combinations**
|
|
||||||
|
|
||||||
### **Common Cards**
|
|
||||||
- ✅ 3D Tilt Effect
|
|
||||||
- ✅ Gray Border Glow
|
|
||||||
- ❌ No Foil Effects
|
|
||||||
|
|
||||||
### **Rare Cards**
|
|
||||||
- ✅ 3D Tilt Effect
|
|
||||||
- ✅ Blue Border Glow
|
|
||||||
- ❌ No Foil Effects
|
|
||||||
|
|
||||||
### **Super Rare Cards**
|
|
||||||
- ✅ 3D Tilt Effect
|
|
||||||
- ✅ Purple Border Glow
|
|
||||||
- ✅ Foil Shimmer Effect
|
|
||||||
|
|
||||||
### **Legendary Cards**
|
|
||||||
- ✅ 3D Tilt Effect
|
|
||||||
- ✅ Gold Border Glow
|
|
||||||
- ✅ Foil Shimmer Effect
|
|
||||||
- ✅ Holographic Animation
|
|
||||||
|
|
||||||
### **Mythic Cards**
|
|
||||||
- ✅ 3D Tilt Effect
|
|
||||||
- ✅ Red Border Glow
|
|
||||||
- ✅ Foil Shimmer Effect
|
|
||||||
- ✅ Holographic Animation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 **Design Philosophy**
|
|
||||||
|
|
||||||
**Progressive Enhancement**: Effects enhance the experience without overwhelming content
|
|
||||||
|
|
||||||
**Performance First**: All animations target 60fps with hardware acceleration
|
|
||||||
|
|
||||||
**Accessibility Aware**: Visual effects complement rather than replace core functionality
|
|
||||||
|
|
||||||
**Mobile Optimized**: Reduced complexity on touch devices while maintaining premium feel
|
|
||||||
|
|
||||||
**Contextually Appropriate**: Effect intensity matches card rarity and importance
|
|
||||||
|
|
||||||
This visual effects system transforms TCG Vault from a simple database into a premium, interactive collection experience that honors the beauty and rarity of your trading cards! ✨🃏
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue