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**
|
||||
- Store and organize your entire trading card collection
|
||||
- Track card conditions, quantities, and locations
|
||||
- Support for multiple TCG formats (Magic: The Gathering, Pokémon, Yu-Gi-Oh!, etc.)
|
||||
- **Card Management**: Track your MTG, Pokémon, and Lorcana cards
|
||||
- **Collection Organization**: Create and manage card collections
|
||||
- **Deck Building**: Build and share decks
|
||||
- **Authentication**: Secure user accounts with JWT
|
||||
- **Admin Panel**: Manage cards and users
|
||||
- **Real-time Pricing**: Track card values
|
||||
|
||||
📸 **OCR Card Scanning**
|
||||
- Scan physical cards using your camera or smartphone
|
||||
- Automatic card recognition and data extraction
|
||||
- Bulk scanning support for efficient collection entry
|
||||
## 🛠️ Tech Stack
|
||||
|
||||
🤖 **AI-Powered Features**
|
||||
- Intelligent deck building recommendations based on your collection
|
||||
- Natural language queries for searching your database
|
||||
- Meta analysis and card synergy suggestions
|
||||
- **Frontend**: Next.js 15, React 18, TypeScript
|
||||
- **Backend**: Next.js API Routes
|
||||
- **Database**: Neon PostgreSQL (serverless)
|
||||
- **Authentication**: JWT with bcrypt
|
||||
- **Styling**: Tailwind CSS
|
||||
- **Deployment**: Vercel
|
||||
|
||||
💰 **Real-time Pricing**
|
||||
- Live price tracking from multiple sources
|
||||
- Collection valuation and price alerts
|
||||
- Historical price charts and market trends
|
||||
## 📦 Installation
|
||||
|
||||
🎨 **Modern Web Interface**
|
||||
- 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**:
|
||||
1. **Clone the repository**
|
||||
```bash
|
||||
cd backend
|
||||
pip install -r requirements.txt
|
||||
uvicorn main:app --reload
|
||||
git clone <repository-url>
|
||||
cd tcg-vault
|
||||
```
|
||||
|
||||
2. **Frontend Setup**:
|
||||
2. **Install dependencies**
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
3. **Database Initialize**:
|
||||
3. **Set up environment variables**
|
||||
```bash
|
||||
python backend/init_db.py
|
||||
cp .env.example .env.local
|
||||
```
|
||||
|
||||
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"
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
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/
|
||||
├── backend/ # FastAPI backend
|
||||
│ ├── app/
|
||||
│ │ ├── models/ # SQLAlchemy models
|
||||
│ │ ├── routers/ # API route handlers
|
||||
│ │ ├── services/ # Business logic
|
||||
│ │ └── utils/ # Utilities (OCR, AI, pricing)
|
||||
│ ├── tests/ # Backend tests
|
||||
│ └── requirements.txt
|
||||
├── frontend/ # React frontend
|
||||
│ ├── src/
|
||||
│ │ ├── components/
|
||||
│ │ ├── pages/
|
||||
│ │ ├── services/ # API clients
|
||||
│ │ └── utils/
|
||||
│ └── package.json
|
||||
├── docs/ # Documentation
|
||||
└── docker-compose.yml # Container orchestration
|
||||
├── pages/ # Next.js pages and API routes
|
||||
│ ├── api/ # API endpoints
|
||||
│ │ ├── auth/ # Authentication routes
|
||||
│ │ └── admin/ # Admin routes
|
||||
│ ├── _app.js # App wrapper
|
||||
│ └── index.js # Home page
|
||||
├── lib/ # Utility libraries
|
||||
│ └── database.js # Database adapter
|
||||
├── scripts/ # Database setup scripts
|
||||
├── public/ # Static assets
|
||||
└── .env.local # Environment variables
|
||||
```
|
||||
|
||||
## 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
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Add tests
|
||||
5. Submit a pull request
|
||||
4. 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