feat(admin/migration): seed SUPER_ADMIN/SHOP_ADMIN, rotate MIGRATE_TOKEN, finalize migration flow; harden endpoints; wire OpenNext updates

This commit is contained in:
Nicholai 2025-10-06 06:41:40 -06:00
parent c4a29225af
commit aa23c905bf
73 changed files with 2574 additions and 1608 deletions

View File

@ -155,7 +155,7 @@ var DOQueueHandler = class extends DurableObject {
method: "HEAD", method: "HEAD",
headers: { headers: {
// This is defined during build // This is defined during build
"x-prerender-revalidate": "aa3e44cc5c2d8f61b9a7e308f9db0bf8", "x-prerender-revalidate": "55cfb8bce98f34386492e3e3013b3def",
"x-isr": "1" "x-isr": "1"
}, },
// This one is kind of problematic, it will always show the wall time of the revalidation to `this.revalidationTimeout` // This one is kind of problematic, it will always show the wall time of the revalidation to `this.revalidationTimeout`
@ -179,7 +179,7 @@ var DOQueueHandler = class extends DurableObject {
"INSERT OR REPLACE INTO sync (id, lastSuccess, buildId) VALUES (?, unixepoch(), ?)", "INSERT OR REPLACE INTO sync (id, lastSuccess, buildId) VALUES (?, unixepoch(), ?)",
// We cannot use the deduplication id because it's not unique per route - every time a route is revalidated, the deduplication id is different. // We cannot use the deduplication id because it's not unique per route - every time a route is revalidated, the deduplication id is different.
`${host}${url}`, `${host}${url}`,
"SVr_7PUfBPR5HoMg6Gqfy" "YY7sC6MVxKHFhQ9os9EJ-"
); );
} }
this.routeInFailedState.delete(msg.MessageDeduplicationId); this.routeInFailedState.delete(msg.MessageDeduplicationId);
@ -231,7 +231,7 @@ var DOQueueHandler = class extends DurableObject {
} }
this.routeInFailedState.set(msg.MessageDeduplicationId, updatedFailedState); this.routeInFailedState.set(msg.MessageDeduplicationId, updatedFailedState);
if (!this.disableSQLite) { if (!this.disableSQLite) {
this.sql.exec("INSERT OR REPLACE INTO failed_state (id, data, buildId) VALUES (?, ?, ?)", msg.MessageDeduplicationId, JSON.stringify(updatedFailedState), "SVr_7PUfBPR5HoMg6Gqfy"); this.sql.exec("INSERT OR REPLACE INTO failed_state (id, data, buildId) VALUES (?, ?, ?)", msg.MessageDeduplicationId, JSON.stringify(updatedFailedState), "YY7sC6MVxKHFhQ9os9EJ-");
} }
await this.addAlarm(); await this.addAlarm();
} }
@ -255,8 +255,8 @@ var DOQueueHandler = class extends DurableObject {
return; return;
this.sql.exec("CREATE TABLE IF NOT EXISTS failed_state (id TEXT PRIMARY KEY, data TEXT, buildId TEXT)"); this.sql.exec("CREATE TABLE IF NOT EXISTS failed_state (id TEXT PRIMARY KEY, data TEXT, buildId TEXT)");
this.sql.exec("CREATE TABLE IF NOT EXISTS sync (id TEXT PRIMARY KEY, lastSuccess INTEGER, buildId TEXT)"); this.sql.exec("CREATE TABLE IF NOT EXISTS sync (id TEXT PRIMARY KEY, lastSuccess INTEGER, buildId TEXT)");
this.sql.exec("DELETE FROM failed_state WHERE buildId != ?", "SVr_7PUfBPR5HoMg6Gqfy"); this.sql.exec("DELETE FROM failed_state WHERE buildId != ?", "YY7sC6MVxKHFhQ9os9EJ-");
this.sql.exec("DELETE FROM sync WHERE buildId != ?", "SVr_7PUfBPR5HoMg6Gqfy"); this.sql.exec("DELETE FROM sync WHERE buildId != ?", "YY7sC6MVxKHFhQ9os9EJ-");
const failedStateCursor = this.sql.exec("SELECT * FROM failed_state"); const failedStateCursor = this.sql.exec("SELECT * FROM failed_state");
for (const row of failedStateCursor) { for (const row of failedStateCursor) {
this.routeInFailedState.set(row.id, JSON.parse(row.data)); this.routeInFailedState.set(row.id, JSON.parse(row.data));

View File

@ -1 +1 @@
SVr_7PUfBPR5HoMg6Gqfy YY7sC6MVxKHFhQ9os9EJ-

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
CREATE TABLE IF NOT EXISTS tags (tag TEXT NOT NULL, path TEXT NOT NULL, UNIQUE(tag, path) ON CONFLICT REPLACE); CREATE TABLE IF NOT EXISTS tags (tag TEXT NOT NULL, path TEXT NOT NULL, UNIQUE(tag, path) ON CONFLICT REPLACE);
CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE); CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE);
INSERT INTO tags (tag, path) VALUES ("SVr_7PUfBPR5HoMg6Gqfy/_N_T_/layout", "SVr_7PUfBPR5HoMg6Gqfy/favicon.ico"), ("SVr_7PUfBPR5HoMg6Gqfy/_N_T_/favicon.ico/layout", "SVr_7PUfBPR5HoMg6Gqfy/favicon.ico"), ("SVr_7PUfBPR5HoMg6Gqfy/_N_T_/favicon.ico/route", "SVr_7PUfBPR5HoMg6Gqfy/favicon.ico"), ("SVr_7PUfBPR5HoMg6Gqfy/_N_T_/favicon.ico", "SVr_7PUfBPR5HoMg6Gqfy/favicon.ico"); INSERT INTO tags (tag, path) VALUES ("YY7sC6MVxKHFhQ9os9EJ-/_N_T_/layout", "YY7sC6MVxKHFhQ9os9EJ-/favicon.ico"), ("YY7sC6MVxKHFhQ9os9EJ-/_N_T_/favicon.ico/layout", "YY7sC6MVxKHFhQ9os9EJ-/favicon.ico"), ("YY7sC6MVxKHFhQ9os9EJ-/_N_T_/favicon.ico/route", "YY7sC6MVxKHFhQ9os9EJ-/favicon.ico"), ("YY7sC6MVxKHFhQ9os9EJ-/_N_T_/favicon.ico", "YY7sC6MVxKHFhQ9os9EJ-/favicon.ico");

View File

@ -49,7 +49,7 @@ function initRuntime() {
}; };
Object.assign(globalThis, { Object.assign(globalThis, {
Request: CustomRequest, Request: CustomRequest,
__BUILD_TIMESTAMP_MS__: 1759747292589, __BUILD_TIMESTAMP_MS__: 1759753791272,
__NEXT_BASE_PATH__: "", __NEXT_BASE_PATH__: "",
__ASSETS_RUN_WORKER_FIRST__: false, __ASSETS_RUN_WORKER_FIRST__: false,
__TRAILING_SLASH__: false, __TRAILING_SLASH__: false,

View File

@ -1,3 +1,3 @@
export const production = {"DATABASE_URL":"file:./local.db","DIRECT_URL":"file:./local.db","NEXTAUTH_URL":"http://localhost:3001","NEXTAUTH_SECRET":"development-secret-key-for-testing-only-32-chars-minimum","AWS_ACCESS_KEY_ID":"5cee6a21cea282a9c89d5297964402e7","AWS_SECRET_ACCESS_KEY":"e649c50203bf3763ac209f6130d57fc296ff6d92fd6690c3a8333c9de19d6389","AWS_REGION":"auto","AWS_BUCKET_NAME":"united-tattoo","AWS_ENDPOINT_URL":"https://5cee6a21cea282a9c89d5297964402e7.r2.cloudflarestorage.com/united-tattoo","NODE_ENV":"development"}; export const production = {"DATABASE_URL":"file:./local.db","DIRECT_URL":"file:./local.db","NEXTAUTH_URL":"http://localhost:3001","NEXTAUTH_SECRET":"development-secret-key-for-testing-only-32-chars-minimum","AWS_ACCESS_KEY_ID":"5cee6a21cea282a9c89d5297964402e7","AWS_SECRET_ACCESS_KEY":"e649c50203bf3763ac209f6130d57fc296ff6d92fd6690c3a8333c9de19d6389","AWS_REGION":"auto","AWS_BUCKET_NAME":"united-tattoo","AWS_ENDPOINT_URL":"https://5cee6a21cea282a9c89d5297964402e7.r2.cloudflarestorage.com/united-tattoo","NODE_ENV":"development","CLOUDFLARE_ACCOUNT_ID":"5cee6a21cea282a9c89d5297964402e7"};
export const development = {"DATABASE_URL":"file:./local.db","DIRECT_URL":"file:./local.db","NEXTAUTH_URL":"http://localhost:3001","NEXTAUTH_SECRET":"development-secret-key-for-testing-only-32-chars-minimum","AWS_ACCESS_KEY_ID":"5cee6a21cea282a9c89d5297964402e7","AWS_SECRET_ACCESS_KEY":"e649c50203bf3763ac209f6130d57fc296ff6d92fd6690c3a8333c9de19d6389","AWS_REGION":"auto","AWS_BUCKET_NAME":"united-tattoo","AWS_ENDPOINT_URL":"https://5cee6a21cea282a9c89d5297964402e7.r2.cloudflarestorage.com/united-tattoo","NODE_ENV":"development"}; export const development = {"DATABASE_URL":"file:./local.db","DIRECT_URL":"file:./local.db","NEXTAUTH_URL":"http://localhost:3001","NEXTAUTH_SECRET":"development-secret-key-for-testing-only-32-chars-minimum","AWS_ACCESS_KEY_ID":"5cee6a21cea282a9c89d5297964402e7","AWS_SECRET_ACCESS_KEY":"e649c50203bf3763ac209f6130d57fc296ff6d92fd6690c3a8333c9de19d6389","AWS_REGION":"auto","AWS_BUCKET_NAME":"united-tattoo","AWS_ENDPOINT_URL":"https://5cee6a21cea282a9c89d5297964402e7.r2.cloudflarestorage.com/united-tattoo","NODE_ENV":"development","CLOUDFLARE_ACCOUNT_ID":"5cee6a21cea282a9c89d5297964402e7"};
export const test = {}; export const test = {};

View File

@ -1 +1 @@
[{"tag":{"S":"SVr_7PUfBPR5HoMg6Gqfy/_N_T_/layout"},"path":{"S":"SVr_7PUfBPR5HoMg6Gqfy/favicon.ico"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"SVr_7PUfBPR5HoMg6Gqfy/_N_T_/favicon.ico/layout"},"path":{"S":"SVr_7PUfBPR5HoMg6Gqfy/favicon.ico"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"SVr_7PUfBPR5HoMg6Gqfy/_N_T_/favicon.ico/route"},"path":{"S":"SVr_7PUfBPR5HoMg6Gqfy/favicon.ico"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"SVr_7PUfBPR5HoMg6Gqfy/_N_T_/favicon.ico"},"path":{"S":"SVr_7PUfBPR5HoMg6Gqfy/favicon.ico"},"revalidatedAt":{"N":"1"}}] [{"tag":{"S":"YY7sC6MVxKHFhQ9os9EJ-/_N_T_/layout"},"path":{"S":"YY7sC6MVxKHFhQ9os9EJ-/favicon.ico"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"YY7sC6MVxKHFhQ9os9EJ-/_N_T_/favicon.ico/layout"},"path":{"S":"YY7sC6MVxKHFhQ9os9EJ-/favicon.ico"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"YY7sC6MVxKHFhQ9os9EJ-/_N_T_/favicon.ico/route"},"path":{"S":"YY7sC6MVxKHFhQ9os9EJ-/favicon.ico"},"revalidatedAt":{"N":"1"}},{"tag":{"S":"YY7sC6MVxKHFhQ9os9EJ-/_N_T_/favicon.ico"},"path":{"S":"YY7sC6MVxKHFhQ9os9EJ-/favicon.ico"},"revalidatedAt":{"N":"1"}}]

View File

@ -1145,7 +1145,7 @@ Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime`;
e2.PENDING = "PENDING", e2.CONFIRMED = "CONFIRMED", e2.IN_PROGRESS = "IN_PROGRESS", e2.COMPLETED = "COMPLETED", e2.CANCELLED = "CANCELLED"; e2.PENDING = "PENDING", e2.CONFIRMED = "CONFIRMED", e2.IN_PROGRESS = "IN_PROGRESS", e2.COMPLETED = "COMPLETED", e2.CANCELLED = "CANCELLED";
}(w || (w = {})); }(w || (w = {}));
let ex = (0, eP.withAuth)(function(e2) { let ex = (0, eP.withAuth)(function(e2) {
let t2 = e2.nextauth.token, { pathname: r2 } = e2.nextUrl; let t2 = e2.nextauth.token, { pathname: r2 } = e2.nextUrl, n2 = process.env.MIGRATE_TOKEN, a2 = e2.headers.get("x-migrate-token"), i2 = e2.nextUrl.searchParams.get("token"), o2 = r2.startsWith("/api/admin/migrate") && (a2 && a2 === n2 || i2 && i2 === n2);
if (r2.startsWith("/admin")) { if (r2.startsWith("/admin")) {
if (!t2) return eC.NextResponse.redirect(new URL("/auth/signin", e2.url)); if (!t2) return eC.NextResponse.redirect(new URL("/auth/signin", e2.url));
let r3 = t2.role; let r3 = t2.role;
@ -1162,14 +1162,15 @@ Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime`;
if (r3 !== y.ARTIST && r3 !== y.SHOP_ADMIN && r3 !== y.SUPER_ADMIN) return eC.NextResponse.redirect(new URL("/unauthorized", e2.url)); if (r3 !== y.ARTIST && r3 !== y.SHOP_ADMIN && r3 !== y.SUPER_ADMIN) return eC.NextResponse.redirect(new URL("/unauthorized", e2.url));
} }
if (r2.startsWith("/api/admin")) { if (r2.startsWith("/api/admin")) {
if (o2) return eC.NextResponse.next();
if (!t2) return eC.NextResponse.json({ error: "Authentication required" }, { status: 401 }); if (!t2) return eC.NextResponse.json({ error: "Authentication required" }, { status: 401 });
let e3 = t2.role; let e3 = t2.role;
if (e3 !== y.SHOP_ADMIN && e3 !== y.SUPER_ADMIN) return eC.NextResponse.json({ error: "Insufficient permissions" }, { status: 403 }); if (e3 !== y.SHOP_ADMIN && e3 !== y.SUPER_ADMIN) return eC.NextResponse.json({ error: "Insufficient permissions" }, { status: 403 });
} }
return eC.NextResponse.next(); return eC.NextResponse.next();
}, { callbacks: { authorized: ({ token: e2, req: t2 }) => { }, { callbacks: { authorized: ({ token: e2, req: t2 }) => {
let { pathname: r2 } = t2.nextUrl; let { pathname: r2 } = t2.nextUrl, n2 = process.env.MIGRATE_TOKEN, a2 = t2.headers.get("x-migrate-token"), i2 = t2.nextUrl.searchParams.get("token");
return !!(["/", "/artists", "/contact", "/book", "/aftercare", "/gift-cards", "/specials", "/terms", "/privacy", "/auth/signin", "/auth/error", "/unauthorized"].some((e3) => r2 === e3 || r2.startsWith(e3)) || r2.match(/^\/artists\/[^\/]+$/) || r2.startsWith("/api/auth") || r2.startsWith("/api/public")) || !!e2; return !!r2.startsWith("/api/admin/migrate") && (!!a2 && a2 === n2 || !!i2 && i2 === n2) || !!(["/", "/artists", "/contact", "/book", "/aftercare", "/gift-cards", "/specials", "/terms", "/privacy", "/auth/signin", "/auth/error", "/unauthorized"].some((e3) => r2 === e3 || r2.startsWith(e3)) || r2.match(/^\/artists\/[^\/]+$/) || r2.startsWith("/api/auth") || r2.startsWith("/api/public")) || !!e2;
} } }), eR = { matcher: ["/((?!_next/static|_next/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*)"] }, eT = { ...m }, eO = eT.middleware || eT.default, ek = "/middleware"; } } }), eR = { matcher: ["/((?!_next/static|_next/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*)"] }, eT = { ...m }, eO = eT.middleware || eT.default, ek = "/middleware";
if ("function" != typeof eO) throw Error(`The Middleware "${ek}" must export a \`middleware\` or a \`default\` function`); if ("function" != typeof eO) throw Error(`The Middleware "${ek}" must export a \`middleware\` or a \`default\` function`);
function eI(e2) { function eI(e2) {
@ -5260,13 +5261,13 @@ var NEXT_DIR = path.join(__dirname, ".next");
var OPEN_NEXT_DIR = path.join(__dirname, ".open-next"); var OPEN_NEXT_DIR = path.join(__dirname, ".open-next");
debug({ NEXT_DIR, OPEN_NEXT_DIR }); debug({ NEXT_DIR, OPEN_NEXT_DIR });
var NextConfig = { "env": {}, "webpack": null, "eslint": { "ignoreDuringBuilds": true }, "typescript": { "ignoreBuildErrors": true, "tsconfigPath": "tsconfig.json" }, "distDir": ".next", "cleanDistDir": true, "assetPrefix": "", "cacheMaxMemorySize": 52428800, "configOrigin": "next.config.mjs", "useFileSystemPublicRoutes": true, "generateEtags": true, "pageExtensions": ["tsx", "ts", "jsx", "js"], "poweredByHeader": true, "compress": true, "analyticsId": "", "images": { "deviceSizes": [640, 750, 828, 1080, 1200, 1920, 2048, 3840], "imageSizes": [16, 32, 48, 64, 96, 128, 256, 384], "path": "/_next/image", "loader": "default", "loaderFile": "", "domains": [], "disableStaticImages": false, "minimumCacheTTL": 60, "formats": ["image/webp"], "dangerouslyAllowSVG": false, "contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;", "contentDispositionType": "inline", "remotePatterns": [], "unoptimized": true }, "devIndicators": { "buildActivity": true, "buildActivityPosition": "bottom-right" }, "onDemandEntries": { "maxInactiveAge": 6e4, "pagesBufferLength": 5 }, "amp": { "canonicalBase": "" }, "basePath": "", "sassOptions": {}, "trailingSlash": false, "i18n": null, "productionBrowserSourceMaps": false, "optimizeFonts": true, "excludeDefaultMomentLocales": true, "serverRuntimeConfig": {}, "publicRuntimeConfig": {}, "reactProductionProfiling": false, "reactStrictMode": null, "httpAgentOptions": { "keepAlive": true }, "outputFileTracing": true, "staticPageGenerationTimeout": 60, "swcMinify": true, "output": "standalone", "modularizeImports": { "@mui/icons-material": { "transform": "@mui/icons-material/{{member}}" }, "lodash": { "transform": "lodash/{{member}}" } }, "experimental": { "multiZoneDraftMode": false, "prerenderEarlyExit": false, "serverMinification": true, "serverSourceMaps": false, "linkNoTouchStart": false, "caseSensitiveRoutes": false, "clientRouterFilter": true, "clientRouterFilterRedirects": false, "fetchCacheKeyPrefix": "", "middlewarePrefetch": "flexible", "optimisticClientCache": true, "manualClientBasePath": false, "cpus": 11, "memoryBasedWorkersCount": false, "isrFlushToDisk": true, "workerThreads": false, "optimizeCss": false, "nextScriptWorkers": false, "scrollRestoration": false, "externalDir": false, "disableOptimizedLoading": false, "gzipSize": true, "craCompat": false, "esmExternals": true, "fullySpecified": false, "outputFileTracingRoot": "/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo", "swcTraceProfiling": false, "forceSwcTransforms": false, "largePageDataBytes": 128e3, "adjustFontFallbacks": false, "adjustFontFallbacksWithSizeAdjust": false, "typedRoutes": false, "instrumentationHook": false, "bundlePagesExternals": false, "parallelServerCompiles": false, "parallelServerBuildTraces": false, "ppr": false, "missingSuspenseWithCSRBailout": true, "optimizeServerReact": true, "useEarlyImport": false, "staleTimes": { "dynamic": 30, "static": 300 }, "optimizePackageImports": ["lucide-react", "date-fns", "lodash-es", "ramda", "antd", "react-bootstrap", "ahooks", "@ant-design/icons", "@headlessui/react", "@headlessui-float/react", "@heroicons/react/20/solid", "@heroicons/react/24/solid", "@heroicons/react/24/outline", "@visx/visx", "@tremor/react", "rxjs", "@mui/material", "@mui/icons-material", "recharts", "react-use", "@material-ui/core", "@material-ui/icons", "@tabler/icons-react", "mui-core", "react-icons/ai", "react-icons/bi", "react-icons/bs", "react-icons/cg", "react-icons/ci", "react-icons/di", "react-icons/fa", "react-icons/fa6", "react-icons/fc", "react-icons/fi", "react-icons/gi", "react-icons/go", "react-icons/gr", "react-icons/hi", "react-icons/hi2", "react-icons/im", "react-icons/io", "react-icons/io5", "react-icons/lia", "react-icons/lib", "react-icons/lu", "react-icons/md", "react-icons/pi", "react-icons/ri", "react-icons/rx", "react-icons/si", "react-icons/sl", "react-icons/tb", "react-icons/tfi", "react-icons/ti", "react-icons/vsc", "react-icons/wi"], "trustHostHeader": false, "isExperimentalCompile": false }, "configFileName": "next.config.mjs" }; var NextConfig = { "env": {}, "webpack": null, "eslint": { "ignoreDuringBuilds": true }, "typescript": { "ignoreBuildErrors": true, "tsconfigPath": "tsconfig.json" }, "distDir": ".next", "cleanDistDir": true, "assetPrefix": "", "cacheMaxMemorySize": 52428800, "configOrigin": "next.config.mjs", "useFileSystemPublicRoutes": true, "generateEtags": true, "pageExtensions": ["tsx", "ts", "jsx", "js"], "poweredByHeader": true, "compress": true, "analyticsId": "", "images": { "deviceSizes": [640, 750, 828, 1080, 1200, 1920, 2048, 3840], "imageSizes": [16, 32, 48, 64, 96, 128, 256, 384], "path": "/_next/image", "loader": "default", "loaderFile": "", "domains": [], "disableStaticImages": false, "minimumCacheTTL": 60, "formats": ["image/webp"], "dangerouslyAllowSVG": false, "contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;", "contentDispositionType": "inline", "remotePatterns": [], "unoptimized": true }, "devIndicators": { "buildActivity": true, "buildActivityPosition": "bottom-right" }, "onDemandEntries": { "maxInactiveAge": 6e4, "pagesBufferLength": 5 }, "amp": { "canonicalBase": "" }, "basePath": "", "sassOptions": {}, "trailingSlash": false, "i18n": null, "productionBrowserSourceMaps": false, "optimizeFonts": true, "excludeDefaultMomentLocales": true, "serverRuntimeConfig": {}, "publicRuntimeConfig": {}, "reactProductionProfiling": false, "reactStrictMode": null, "httpAgentOptions": { "keepAlive": true }, "outputFileTracing": true, "staticPageGenerationTimeout": 60, "swcMinify": true, "output": "standalone", "modularizeImports": { "@mui/icons-material": { "transform": "@mui/icons-material/{{member}}" }, "lodash": { "transform": "lodash/{{member}}" } }, "experimental": { "multiZoneDraftMode": false, "prerenderEarlyExit": false, "serverMinification": true, "serverSourceMaps": false, "linkNoTouchStart": false, "caseSensitiveRoutes": false, "clientRouterFilter": true, "clientRouterFilterRedirects": false, "fetchCacheKeyPrefix": "", "middlewarePrefetch": "flexible", "optimisticClientCache": true, "manualClientBasePath": false, "cpus": 11, "memoryBasedWorkersCount": false, "isrFlushToDisk": true, "workerThreads": false, "optimizeCss": false, "nextScriptWorkers": false, "scrollRestoration": false, "externalDir": false, "disableOptimizedLoading": false, "gzipSize": true, "craCompat": false, "esmExternals": true, "fullySpecified": false, "outputFileTracingRoot": "/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo", "swcTraceProfiling": false, "forceSwcTransforms": false, "largePageDataBytes": 128e3, "adjustFontFallbacks": false, "adjustFontFallbacksWithSizeAdjust": false, "typedRoutes": false, "instrumentationHook": false, "bundlePagesExternals": false, "parallelServerCompiles": false, "parallelServerBuildTraces": false, "ppr": false, "missingSuspenseWithCSRBailout": true, "optimizeServerReact": true, "useEarlyImport": false, "staleTimes": { "dynamic": 30, "static": 300 }, "optimizePackageImports": ["lucide-react", "date-fns", "lodash-es", "ramda", "antd", "react-bootstrap", "ahooks", "@ant-design/icons", "@headlessui/react", "@headlessui-float/react", "@heroicons/react/20/solid", "@heroicons/react/24/solid", "@heroicons/react/24/outline", "@visx/visx", "@tremor/react", "rxjs", "@mui/material", "@mui/icons-material", "recharts", "react-use", "@material-ui/core", "@material-ui/icons", "@tabler/icons-react", "mui-core", "react-icons/ai", "react-icons/bi", "react-icons/bs", "react-icons/cg", "react-icons/ci", "react-icons/di", "react-icons/fa", "react-icons/fa6", "react-icons/fc", "react-icons/fi", "react-icons/gi", "react-icons/go", "react-icons/gr", "react-icons/hi", "react-icons/hi2", "react-icons/im", "react-icons/io", "react-icons/io5", "react-icons/lia", "react-icons/lib", "react-icons/lu", "react-icons/md", "react-icons/pi", "react-icons/ri", "react-icons/rx", "react-icons/si", "react-icons/sl", "react-icons/tb", "react-icons/tfi", "react-icons/ti", "react-icons/vsc", "react-icons/wi"], "trustHostHeader": false, "isExperimentalCompile": false }, "configFileName": "next.config.mjs" };
var BuildId = "SVr_7PUfBPR5HoMg6Gqfy"; var BuildId = "YY7sC6MVxKHFhQ9os9EJ-";
var RoutesManifest = { "basePath": "", "rewrites": { "beforeFiles": [], "afterFiles": [], "fallback": [] }, "redirects": [{ "source": "/:path+/", "destination": "/:path+", "internal": true, "statusCode": 308, "regex": "^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$" }], "routes": { "static": [{ "page": "/", "regex": "^/(?:/)?$", "routeKeys": {}, "namedRegex": "^/(?:/)?$" }, { "page": "/_not-found", "regex": "^/_not\\-found(?:/)?$", "routeKeys": {}, "namedRegex": "^/_not\\-found(?:/)?$" }, { "page": "/admin", "regex": "^/admin(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin(?:/)?$" }, { "page": "/admin/analytics", "regex": "^/admin/analytics(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/analytics(?:/)?$" }, { "page": "/admin/artists", "regex": "^/admin/artists(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/artists(?:/)?$" }, { "page": "/admin/artists/new", "regex": "^/admin/artists/new(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/artists/new(?:/)?$" }, { "page": "/admin/calendar", "regex": "^/admin/calendar(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/calendar(?:/)?$" }, { "page": "/admin/portfolio", "regex": "^/admin/portfolio(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/portfolio(?:/)?$" }, { "page": "/admin/settings", "regex": "^/admin/settings(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/settings(?:/)?$" }, { "page": "/admin/uploads", "regex": "^/admin/uploads(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/uploads(?:/)?$" }, { "page": "/aftercare", "regex": "^/aftercare(?:/)?$", "routeKeys": {}, "namedRegex": "^/aftercare(?:/)?$" }, { "page": "/artist-dashboard", "regex": "^/artist\\-dashboard(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard(?:/)?$" }, { "page": "/artist-dashboard/portfolio", "regex": "^/artist\\-dashboard/portfolio(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard/portfolio(?:/)?$" }, { "page": "/artist-dashboard/profile", "regex": "^/artist\\-dashboard/profile(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard/profile(?:/)?$" }, { "page": "/artists", "regex": "^/artists(?:/)?$", "routeKeys": {}, "namedRegex": "^/artists(?:/)?$" }, { "page": "/auth/error", "regex": "^/auth/error(?:/)?$", "routeKeys": {}, "namedRegex": "^/auth/error(?:/)?$" }, { "page": "/auth/signin", "regex": "^/auth/signin(?:/)?$", "routeKeys": {}, "namedRegex": "^/auth/signin(?:/)?$" }, { "page": "/book", "regex": "^/book(?:/)?$", "routeKeys": {}, "namedRegex": "^/book(?:/)?$" }, { "page": "/contact", "regex": "^/contact(?:/)?$", "routeKeys": {}, "namedRegex": "^/contact(?:/)?$" }, { "page": "/deposit", "regex": "^/deposit(?:/)?$", "routeKeys": {}, "namedRegex": "^/deposit(?:/)?$" }, { "page": "/favicon.ico", "regex": "^/favicon\\.ico(?:/)?$", "routeKeys": {}, "namedRegex": "^/favicon\\.ico(?:/)?$" }, { "page": "/gift-cards", "regex": "^/gift\\-cards(?:/)?$", "routeKeys": {}, "namedRegex": "^/gift\\-cards(?:/)?$" }, { "page": "/privacy", "regex": "^/privacy(?:/)?$", "routeKeys": {}, "namedRegex": "^/privacy(?:/)?$" }, { "page": "/specials", "regex": "^/specials(?:/)?$", "routeKeys": {}, "namedRegex": "^/specials(?:/)?$" }, { "page": "/terms", "regex": "^/terms(?:/)?$", "routeKeys": {}, "namedRegex": "^/terms(?:/)?$" }], "dynamic": [{ "page": "/admin/artists/[id]", "regex": "^/admin/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/admin/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/api/artists/[id]", "regex": "^/api/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/api/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/api/auth/[...nextauth]", "regex": "^/api/auth/(.+?)(?:/)?$", "routeKeys": { "nxtPnextauth": "nxtPnextauth" }, "namedRegex": "^/api/auth/(?<nxtPnextauth>.+?)(?:/)?$" }, { "page": "/api/portfolio/[id]", "regex": "^/api/portfolio/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/api/portfolio/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/artists/[id]", "regex": "^/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/artists/[id]/book", "regex": "^/artists/([^/]+?)/book(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/artists/(?<nxtPid>[^/]+?)/book(?:/)?$" }], "data": { "static": [], "dynamic": [] } }, "locales": [] }; var RoutesManifest = { "basePath": "", "rewrites": { "beforeFiles": [], "afterFiles": [], "fallback": [] }, "redirects": [{ "source": "/:path+/", "destination": "/:path+", "internal": true, "statusCode": 308, "regex": "^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$" }], "routes": { "static": [{ "page": "/", "regex": "^/(?:/)?$", "routeKeys": {}, "namedRegex": "^/(?:/)?$" }, { "page": "/_not-found", "regex": "^/_not\\-found(?:/)?$", "routeKeys": {}, "namedRegex": "^/_not\\-found(?:/)?$" }, { "page": "/admin", "regex": "^/admin(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin(?:/)?$" }, { "page": "/admin/analytics", "regex": "^/admin/analytics(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/analytics(?:/)?$" }, { "page": "/admin/artists", "regex": "^/admin/artists(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/artists(?:/)?$" }, { "page": "/admin/artists/new", "regex": "^/admin/artists/new(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/artists/new(?:/)?$" }, { "page": "/admin/calendar", "regex": "^/admin/calendar(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/calendar(?:/)?$" }, { "page": "/admin/portfolio", "regex": "^/admin/portfolio(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/portfolio(?:/)?$" }, { "page": "/admin/settings", "regex": "^/admin/settings(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/settings(?:/)?$" }, { "page": "/admin/uploads", "regex": "^/admin/uploads(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/uploads(?:/)?$" }, { "page": "/aftercare", "regex": "^/aftercare(?:/)?$", "routeKeys": {}, "namedRegex": "^/aftercare(?:/)?$" }, { "page": "/artist-dashboard", "regex": "^/artist\\-dashboard(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard(?:/)?$" }, { "page": "/artist-dashboard/portfolio", "regex": "^/artist\\-dashboard/portfolio(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard/portfolio(?:/)?$" }, { "page": "/artist-dashboard/profile", "regex": "^/artist\\-dashboard/profile(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard/profile(?:/)?$" }, { "page": "/artists", "regex": "^/artists(?:/)?$", "routeKeys": {}, "namedRegex": "^/artists(?:/)?$" }, { "page": "/auth/error", "regex": "^/auth/error(?:/)?$", "routeKeys": {}, "namedRegex": "^/auth/error(?:/)?$" }, { "page": "/auth/signin", "regex": "^/auth/signin(?:/)?$", "routeKeys": {}, "namedRegex": "^/auth/signin(?:/)?$" }, { "page": "/book", "regex": "^/book(?:/)?$", "routeKeys": {}, "namedRegex": "^/book(?:/)?$" }, { "page": "/contact", "regex": "^/contact(?:/)?$", "routeKeys": {}, "namedRegex": "^/contact(?:/)?$" }, { "page": "/deposit", "regex": "^/deposit(?:/)?$", "routeKeys": {}, "namedRegex": "^/deposit(?:/)?$" }, { "page": "/favicon.ico", "regex": "^/favicon\\.ico(?:/)?$", "routeKeys": {}, "namedRegex": "^/favicon\\.ico(?:/)?$" }, { "page": "/gift-cards", "regex": "^/gift\\-cards(?:/)?$", "routeKeys": {}, "namedRegex": "^/gift\\-cards(?:/)?$" }, { "page": "/privacy", "regex": "^/privacy(?:/)?$", "routeKeys": {}, "namedRegex": "^/privacy(?:/)?$" }, { "page": "/specials", "regex": "^/specials(?:/)?$", "routeKeys": {}, "namedRegex": "^/specials(?:/)?$" }, { "page": "/terms", "regex": "^/terms(?:/)?$", "routeKeys": {}, "namedRegex": "^/terms(?:/)?$" }], "dynamic": [{ "page": "/admin/artists/[id]", "regex": "^/admin/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/admin/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/api/artists/[id]", "regex": "^/api/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/api/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/api/auth/[...nextauth]", "regex": "^/api/auth/(.+?)(?:/)?$", "routeKeys": { "nxtPnextauth": "nxtPnextauth" }, "namedRegex": "^/api/auth/(?<nxtPnextauth>.+?)(?:/)?$" }, { "page": "/api/portfolio/[id]", "regex": "^/api/portfolio/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/api/portfolio/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/artists/[id]", "regex": "^/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/artists/[id]/book", "regex": "^/artists/([^/]+?)/book(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/artists/(?<nxtPid>[^/]+?)/book(?:/)?$" }], "data": { "static": [], "dynamic": [] } }, "locales": [] };
var ConfigHeaders = []; var ConfigHeaders = [];
var PrerenderManifest = { "version": 4, "routes": { "/favicon.ico": { "initialHeaders": { "cache-control": "public, max-age=0, must-revalidate", "content-type": "image/x-icon", "x-next-cache-tags": "_N_T_/layout,_N_T_/favicon.ico/layout,_N_T_/favicon.ico/route,_N_T_/favicon.ico" }, "experimentalBypassFor": [{ "type": "header", "key": "Next-Action" }, { "type": "header", "key": "content-type", "value": "multipart/form-data;.*" }], "initialRevalidateSeconds": false, "srcRoute": "/favicon.ico", "dataRoute": null } }, "dynamicRoutes": {}, "notFoundRoutes": [], "preview": { "previewModeId": "aa3e44cc5c2d8f61b9a7e308f9db0bf8", "previewModeSigningKey": "8aa982a30b271251dc2f1ffdd0eb252e3bc9e47f7d478e80f5dbb2abb1b39323", "previewModeEncryptionKey": "e63b6be95276873929b9ec08e113ea325ced41c2d494b0a69b62991e4c3688ab" } }; var PrerenderManifest = { "version": 4, "routes": { "/favicon.ico": { "initialHeaders": { "cache-control": "public, max-age=0, must-revalidate", "content-type": "image/x-icon", "x-next-cache-tags": "_N_T_/layout,_N_T_/favicon.ico/layout,_N_T_/favicon.ico/route,_N_T_/favicon.ico" }, "experimentalBypassFor": [{ "type": "header", "key": "Next-Action" }, { "type": "header", "key": "content-type", "value": "multipart/form-data;.*" }], "initialRevalidateSeconds": false, "srcRoute": "/favicon.ico", "dataRoute": null } }, "dynamicRoutes": {}, "notFoundRoutes": [], "preview": { "previewModeId": "55cfb8bce98f34386492e3e3013b3def", "previewModeSigningKey": "2de3a5f4686c5891b3e0b87bbf44a183fdd7bc9b2a7ef3a918a2772770dad5b4", "previewModeEncryptionKey": "5b32ca192fc7429a1bb0ed5c67f7f91fe66c60e85c5bfb60804bb73c72f79e3c" } };
var MiddlewareManifest = { "version": 3, "middleware": { "/": { "files": ["server/edge-runtime-webpack.js", "server/middleware.js"], "name": "middleware", "page": "/", "matchers": [{ "regexp": "^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/((?!_next\\/static|_next\\/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*))(.json)?[\\/#\\?]?$", "originalSource": "/((?!_next/static|_next/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*)" }], "wasm": [], "assets": [], "env": { "__NEXT_BUILD_ID": "SVr_7PUfBPR5HoMg6Gqfy", "NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "eqMtY6RQJg8ZzpGru9Ni8jGmRicvhYvppy45/3SECqU=", "__NEXT_PREVIEW_MODE_ID": "aa3e44cc5c2d8f61b9a7e308f9db0bf8", "__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "e63b6be95276873929b9ec08e113ea325ced41c2d494b0a69b62991e4c3688ab", "__NEXT_PREVIEW_MODE_SIGNING_KEY": "8aa982a30b271251dc2f1ffdd0eb252e3bc9e47f7d478e80f5dbb2abb1b39323" } } }, "functions": {}, "sortedMiddleware": ["/"] }; var MiddlewareManifest = { "version": 3, "middleware": { "/": { "files": ["server/edge-runtime-webpack.js", "server/middleware.js"], "name": "middleware", "page": "/", "matchers": [{ "regexp": "^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/((?!_next\\/static|_next\\/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*))(.json)?[\\/#\\?]?$", "originalSource": "/((?!_next/static|_next/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*)" }], "wasm": [], "assets": [], "env": { "__NEXT_BUILD_ID": "YY7sC6MVxKHFhQ9os9EJ-", "NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "dIIe8uld0IZYSR75raX3hqcoXVKi4G5ZTC9ulh2RS/M=", "__NEXT_PREVIEW_MODE_ID": "55cfb8bce98f34386492e3e3013b3def", "__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "5b32ca192fc7429a1bb0ed5c67f7f91fe66c60e85c5bfb60804bb73c72f79e3c", "__NEXT_PREVIEW_MODE_SIGNING_KEY": "2de3a5f4686c5891b3e0b87bbf44a183fdd7bc9b2a7ef3a918a2772770dad5b4" } } }, "functions": {}, "sortedMiddleware": ["/"] };
var AppPathRoutesManifest = { "/_not-found/page": "/_not-found", "/aftercare/page": "/aftercare", "/api/admin/migrate/route": "/api/admin/migrate", "/api/auth/[...nextauth]/route": "/api/auth/[...nextauth]", "/artists/[id]/book/page": "/artists/[id]/book", "/artists/page": "/artists", "/auth/error/page": "/auth/error", "/book/page": "/book", "/artists/[id]/page": "/artists/[id]", "/deposit/page": "/deposit", "/contact/page": "/contact", "/auth/signin/page": "/auth/signin", "/favicon.ico/route": "/favicon.ico", "/gift-cards/page": "/gift-cards", "/page": "/", "/privacy/page": "/privacy", "/terms/page": "/terms", "/specials/page": "/specials", "/api/admin/stats/route": "/api/admin/stats", "/api/artists/[id]/route": "/api/artists/[id]", "/api/files/bulk-delete/route": "/api/files/bulk-delete", "/api/appointments/route": "/api/appointments", "/api/artists/me/route": "/api/artists/me", "/api/files/folder/route": "/api/files/folder", "/api/artists/route": "/api/artists", "/api/files/stats/route": "/api/files/stats", "/api/files/route": "/api/files", "/api/portfolio/route": "/api/portfolio", "/api/portfolio/bulk-delete/route": "/api/portfolio/bulk-delete", "/api/portfolio/stats/route": "/api/portfolio/stats", "/api/portfolio/[id]/route": "/api/portfolio/[id]", "/api/users/route": "/api/users", "/api/settings/route": "/api/settings", "/api/upload/route": "/api/upload", "/admin/artists/[id]/page": "/admin/artists/[id]", "/admin/artists/new/page": "/admin/artists/new", "/admin/artists/page": "/admin/artists", "/admin/calendar/page": "/admin/calendar", "/admin/page": "/admin", "/artist-dashboard/page": "/artist-dashboard", "/artist-dashboard/portfolio/page": "/artist-dashboard/portfolio", "/admin/uploads/page": "/admin/uploads", "/admin/settings/page": "/admin/settings", "/admin/portfolio/page": "/admin/portfolio", "/admin/analytics/page": "/admin/analytics", "/artist-dashboard/profile/page": "/artist-dashboard/profile" }; var AppPathRoutesManifest = { "/_not-found/page": "/_not-found", "/aftercare/page": "/aftercare", "/api/admin/migrate/route": "/api/admin/migrate", "/api/auth/[...nextauth]/route": "/api/auth/[...nextauth]", "/api/public/migrate/route": "/api/public/migrate", "/artists/[id]/book/page": "/artists/[id]/book", "/artists/[id]/page": "/artists/[id]", "/artists/page": "/artists", "/auth/error/page": "/auth/error", "/auth/signin/page": "/auth/signin", "/book/page": "/book", "/contact/page": "/contact", "/deposit/page": "/deposit", "/favicon.ico/route": "/favicon.ico", "/gift-cards/page": "/gift-cards", "/page": "/", "/privacy/page": "/privacy", "/specials/page": "/specials", "/terms/page": "/terms", "/api/admin/stats/route": "/api/admin/stats", "/api/artists/me/route": "/api/artists/me", "/api/artists/[id]/route": "/api/artists/[id]", "/api/files/bulk-delete/route": "/api/files/bulk-delete", "/api/files/folder/route": "/api/files/folder", "/api/artists/route": "/api/artists", "/api/files/route": "/api/files", "/api/appointments/route": "/api/appointments", "/api/portfolio/bulk-delete/route": "/api/portfolio/bulk-delete", "/api/files/stats/route": "/api/files/stats", "/api/portfolio/stats/route": "/api/portfolio/stats", "/api/portfolio/route": "/api/portfolio", "/api/portfolio/[id]/route": "/api/portfolio/[id]", "/api/settings/route": "/api/settings", "/api/upload/route": "/api/upload", "/api/users/route": "/api/users", "/admin/artists/[id]/page": "/admin/artists/[id]", "/admin/artists/new/page": "/admin/artists/new", "/admin/artists/page": "/admin/artists", "/admin/calendar/page": "/admin/calendar", "/admin/page": "/admin", "/artist-dashboard/page": "/artist-dashboard", "/artist-dashboard/portfolio/page": "/artist-dashboard/portfolio", "/artist-dashboard/profile/page": "/artist-dashboard/profile", "/admin/portfolio/page": "/admin/portfolio", "/admin/settings/page": "/admin/settings", "/admin/uploads/page": "/admin/uploads", "/admin/analytics/page": "/admin/analytics" };
var FunctionsConfigManifest = { "version": 1, "functions": { "/api/artists/[id]": {}, "/api/admin/stats": {}, "/api/artists/me": {}, "/api/files/bulk-delete": {}, "/api/files/folder": {}, "/api/artists": {}, "/api/files": {}, "/api/files/stats": {}, "/api/appointments": {}, "/api/portfolio/[id]": {}, "/api/portfolio/stats": {}, "/api/portfolio/bulk-delete": {}, "/api/portfolio": {}, "/api/settings": {}, "/api/users": {}, "/api/upload": {}, "/admin/portfolio": {}, "/admin/settings": {}, "/admin/uploads": {}, "/admin/analytics": {} } }; var FunctionsConfigManifest = { "version": 1, "functions": { "/api/artists/me": {}, "/api/artists/[id]": {}, "/api/admin/stats": {}, "/api/files/folder": {}, "/api/artists": {}, "/api/files/bulk-delete": {}, "/api/files/stats": {}, "/api/files": {}, "/api/appointments": {}, "/api/portfolio/[id]": {}, "/api/portfolio/bulk-delete": {}, "/api/portfolio/stats": {}, "/api/portfolio": {}, "/api/users": {}, "/api/upload": {}, "/admin/analytics": {}, "/admin/portfolio": {}, "/admin/settings": {}, "/admin/uploads": {}, "/api/settings": {} } };
var PagesManifest = { "/_app": "pages/_app.js", "/_error": "pages/_error.js", "/_document": "pages/_document.js" }; var PagesManifest = { "/_app": "pages/_app.js", "/_error": "pages/_error.js", "/_document": "pages/_document.js" };
process.env.NEXT_BUILD_ID = BuildId; process.env.NEXT_BUILD_ID = BuildId;

View File

@ -1 +1 @@
SVr_7PUfBPR5HoMg6Gqfy YY7sC6MVxKHFhQ9os9EJ-

View File

@ -19,7 +19,7 @@
"static/chunks/fd9d1056-a2747418f8441a81.js", "static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/css/f677609b3bcf0e0d.css", "static/css/afa6f67553b1dc7a.css",
"static/css/273d08c2abf40b5c.css", "static/css/273d08c2abf40b5c.css",
"static/chunks/9763-93fc3f5b8786b2e4.js", "static/chunks/9763-93fc3f5b8786b2e4.js",
"static/chunks/605-b40754e541fd4ec3.js", "static/chunks/605-b40754e541fd4ec3.js",
@ -39,13 +39,13 @@
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/200-c5238abf2da840bb.js", "static/chunks/200-c5238abf2da840bb.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/aftercare/page-1d2584db6686c322.js" "static/chunks/app/aftercare/page-1ba828f04aff4f9e.js"
], ],
"/aftercare/error": [ "/aftercare/error": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -68,19 +68,19 @@
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/9363-708e3fc7c271db63.js", "static/chunks/468-a1df0f3ea00fd251.js",
"static/chunks/157-f6d67dc9e7bfe380.js", "static/chunks/6929-72d31265c3516bbc.js",
"static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/9763-93fc3f5b8786b2e4.js", "static/chunks/9763-93fc3f5b8786b2e4.js",
"static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/1713-bb0e0f8fa389af9d.js", "static/chunks/1713-bb0e0f8fa389af9d.js",
"static/chunks/2739-e61ead0ddc3259b6.js", "static/chunks/2739-e61ead0ddc3259b6.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/3621-8539d093ca543ee6.js", "static/chunks/3621-8539d093ca543ee6.js",
"static/chunks/app/artists/[id]/book/page-c54cafd7c922d389.js" "static/chunks/app/artists/[id]/book/page-4498735b58509230.js"
], ],
"/artists/[id]/book/error": [ "/artists/[id]/book/error": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -127,18 +127,34 @@
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/app/artists/loading-d293bff8cccee2c6.js" "static/chunks/app/artists/loading-d293bff8cccee2c6.js"
], ],
"/artists/[id]/page": [
"static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/9763-93fc3f5b8786b2e4.js",
"static/chunks/7447-f87f4d4fe09a3255.js",
"static/chunks/1713-bb0e0f8fa389af9d.js",
"static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/artists/[id]/page-c093324cdaebd469.js"
],
"/artists/page": [ "/artists/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js", "static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/artists/page-03f81a5bdeeb37f6.js" "static/chunks/app/artists/page-2e23b2d65ee0f7ed.js"
], ],
"/auth/error/page": [ "/auth/error/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -149,25 +165,34 @@
"static/chunks/2972-12a4e0ab28e83d4d.js", "static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/app/auth/error/page-444f8c1a5939588e.js" "static/chunks/app/auth/error/page-444f8c1a5939588e.js"
], ],
"/auth/signin/page": [
"static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/605-b40754e541fd4ec3.js",
"static/chunks/app/auth/signin/page-e3daf59216da3775.js"
],
"/book/page": [ "/book/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js", "static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/9363-708e3fc7c271db63.js", "static/chunks/468-a1df0f3ea00fd251.js",
"static/chunks/157-f6d67dc9e7bfe380.js", "static/chunks/6929-72d31265c3516bbc.js",
"static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/9763-93fc3f5b8786b2e4.js", "static/chunks/9763-93fc3f5b8786b2e4.js",
"static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/1713-bb0e0f8fa389af9d.js", "static/chunks/1713-bb0e0f8fa389af9d.js",
"static/chunks/2739-e61ead0ddc3259b6.js", "static/chunks/2739-e61ead0ddc3259b6.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/3621-8539d093ca543ee6.js", "static/chunks/3621-8539d093ca543ee6.js",
"static/chunks/app/book/page-5b1cb27b8344bd52.js" "static/chunks/app/book/page-49344a579fbd9532.js"
], ],
"/book/error": [ "/book/error": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -184,21 +209,21 @@
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/app/book/loading-3b0651f0558fc773.js" "static/chunks/app/book/loading-3b0651f0558fc773.js"
], ],
"/artists/[id]/page": [ "/contact/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js", "static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/9763-93fc3f5b8786b2e4.js", "static/chunks/468-a1df0f3ea00fd251.js",
"static/chunks/1713-bb0e0f8fa389af9d.js", "static/chunks/6929-72d31265c3516bbc.js",
"static/chunks/7447-f87f4d4fe09a3255.js", "static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/artists/[id]/page-01d23a2730cc519c.js" "static/chunks/app/contact/page-a66394c8d95e161f.js"
], ],
"/deposit/page": [ "/deposit/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -206,13 +231,13 @@
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/200-c5238abf2da840bb.js", "static/chunks/200-c5238abf2da840bb.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/deposit/page-29e5a1e2b7ddf09c.js" "static/chunks/app/deposit/page-239243487581edce.js"
], ],
"/deposit/error": [ "/deposit/error": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -229,43 +254,18 @@
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/app/deposit/loading-a9763cde0a954c13.js" "static/chunks/app/deposit/loading-a9763cde0a954c13.js"
], ],
"/contact/page": [
"static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/9363-708e3fc7c271db63.js",
"static/chunks/157-f6d67dc9e7bfe380.js",
"static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/contact/page-5932ddc7431bde26.js"
],
"/auth/signin/page": [
"static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/605-b40754e541fd4ec3.js",
"static/chunks/app/auth/signin/page-e3daf59216da3775.js"
],
"/gift-cards/page": [ "/gift-cards/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js", "static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/gift-cards/page-882baf4ae5cbeb08.js" "static/chunks/app/gift-cards/page-827ef54c98b2090b.js"
], ],
"/page": [ "/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -273,13 +273,13 @@
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/6254-d072dbeea75c6dfe.js", "static/chunks/6254-d072dbeea75c6dfe.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/page-8a0e87ab5ed7e280.js" "static/chunks/app/page-d4936bb0703f6aa7.js"
], ],
"/privacy/page": [ "/privacy/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -287,12 +287,12 @@
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/privacy/page-715def209795f7aa.js" "static/chunks/app/privacy/page-0ea48e76abbea863.js"
], ],
"/privacy/error": [ "/privacy/error": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -309,18 +309,31 @@
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/app/privacy/loading-d1d6ec4ebb33573e.js" "static/chunks/app/privacy/loading-d1d6ec4ebb33573e.js"
], ],
"/specials/page": [
"static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/specials/page-393fcc533f1770e6.js"
],
"/terms/page": [ "/terms/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js", "static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js", "static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/1506-d13534ca3a833b98.js", "static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/terms/page-51ca334ed3a6460f.js" "static/chunks/app/terms/page-baabff9be53b1282.js"
], ],
"/terms/error": [ "/terms/error": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -337,29 +350,22 @@
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/app/terms/loading-26938e980c1b83ed.js" "static/chunks/app/terms/loading-26938e980c1b83ed.js"
], ],
"/specials/page": [
"static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/2972-12a4e0ab28e83d4d.js",
"static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9792-dd4b572f6c677771.js",
"static/chunks/1506-d13534ca3a833b98.js",
"static/chunks/app/specials/page-c3cf4600a126414e.js"
],
"/admin/artists/[id]/page": [ "/admin/artists/[id]/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js", "static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/468-a1df0f3ea00fd251.js",
"static/chunks/7447-f87f4d4fe09a3255.js",
"static/chunks/1804-b6a097c7f507f6f8.js", "static/chunks/1804-b6a097c7f507f6f8.js",
"static/chunks/8722-2566700c9a0667a5.js", "static/chunks/9027-72d4e4b31ea4b417.js",
"static/chunks/6374-931bbad1688d9555.js",
"static/chunks/5845-94eecf8f83895637.js",
"static/chunks/9504-6c749d5f7d843332.js", "static/chunks/9504-6c749d5f7d843332.js",
"static/chunks/app/admin/artists/[id]/page-9669380017ebebe7.js" "static/chunks/9195-0c18cb62c42748f1.js",
"static/chunks/app/admin/artists/[id]/page-008ba33720d02901.js"
], ],
"/admin/layout": [ "/admin/layout": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -390,10 +396,10 @@
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9363-708e3fc7c271db63.js", "static/chunks/468-a1df0f3ea00fd251.js",
"static/chunks/157-f6d67dc9e7bfe380.js", "static/chunks/6929-72d31265c3516bbc.js",
"static/chunks/6210-f756268a789f4b72.js", "static/chunks/6210-f756268a789f4b72.js",
"static/chunks/app/admin/artists/page-f423289ff836c488.js" "static/chunks/app/admin/artists/page-13322d56a2be2f39.js"
], ],
"/admin/calendar/page": [ "/admin/calendar/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -406,17 +412,17 @@
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9363-708e3fc7c271db63.js", "static/chunks/468-a1df0f3ea00fd251.js",
"static/chunks/157-f6d67dc9e7bfe380.js", "static/chunks/6929-72d31265c3516bbc.js",
"static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/9763-93fc3f5b8786b2e4.js", "static/chunks/9763-93fc3f5b8786b2e4.js",
"static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/1713-bb0e0f8fa389af9d.js", "static/chunks/1713-bb0e0f8fa389af9d.js",
"static/chunks/1804-b6a097c7f507f6f8.js", "static/chunks/1804-b6a097c7f507f6f8.js",
"static/chunks/2465-d779a94bfd3f89c0.js", "static/chunks/9027-72d4e4b31ea4b417.js",
"static/chunks/3470-4efe838ab2135c44.js", "static/chunks/3470-4efe838ab2135c44.js",
"static/chunks/1432-24fb8d3b5dc2aceb.js", "static/chunks/1432-24fb8d3b5dc2aceb.js",
"static/chunks/103-326742c1ffe700c6.js", "static/chunks/8259-f8fd3a47428618ef.js",
"static/chunks/app/admin/calendar/page-2e4ec3030313e917.js" "static/chunks/app/admin/calendar/page-d1fca14f6767bea2.js"
], ],
"/admin/page": [ "/admin/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -454,21 +460,32 @@
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/7447-f87f4d4fe09a3255.js", "static/chunks/7447-f87f4d4fe09a3255.js",
"static/chunks/app/artist-dashboard/portfolio/page-9691f2ec4ab105b8.js" "static/chunks/app/artist-dashboard/portfolio/page-d4ef16f24e57cc6a.js"
], ],
"/admin/uploads/page": [ "/artist-dashboard/profile/page": [
"static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/app/artist-dashboard/profile/page-cb3c6b72b12ebe1f.js"
],
"/admin/portfolio/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js", "static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/9363-708e3fc7c271db63.js", "static/chunks/468-a1df0f3ea00fd251.js",
"static/chunks/7447-f87f4d4fe09a3255.js", "static/chunks/7447-f87f4d4fe09a3255.js",
"static/chunks/2465-d779a94bfd3f89c0.js", "static/chunks/1804-b6a097c7f507f6f8.js",
"static/chunks/1980-4b71d8da4c239cab.js", "static/chunks/9027-72d4e4b31ea4b417.js",
"static/chunks/6298-ed1f2b36c3535636.js", "static/chunks/6374-931bbad1688d9555.js",
"static/chunks/app/admin/uploads/page-e1b3703ece0ea98f.js" "static/chunks/5845-94eecf8f83895637.js",
"static/chunks/6586-99143ae3d67035df.js",
"static/chunks/9195-0c18cb62c42748f1.js",
"static/chunks/app/admin/portfolio/page-972eb5efdead4537.js"
], ],
"/admin/settings/page": [ "/admin/settings/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -478,30 +495,28 @@
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/3909-e076b2f0010bd374.js",
"static/chunks/9363-708e3fc7c271db63.js", "static/chunks/468-a1df0f3ea00fd251.js",
"static/chunks/157-f6d67dc9e7bfe380.js", "static/chunks/6929-72d31265c3516bbc.js",
"static/chunks/3865-0d3515d9486f6382.js", "static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/200-c5238abf2da840bb.js", "static/chunks/200-c5238abf2da840bb.js",
"static/chunks/7620-9bbc58135a25b1a4.js", "static/chunks/7620-9bbc58135a25b1a4.js",
"static/chunks/6298-ed1f2b36c3535636.js", "static/chunks/6586-99143ae3d67035df.js",
"static/chunks/app/admin/settings/page-9ac381b1fa6b8367.js" "static/chunks/app/admin/settings/page-570193b9022b1f2a.js"
], ],
"/admin/portfolio/page": [ "/admin/uploads/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js", "static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js", "static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js", "static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/6128-45e14c1ac294ddd7.js", "static/chunks/6128-45e14c1ac294ddd7.js",
"static/chunks/3909-e076b2f0010bd374.js", "static/chunks/468-a1df0f3ea00fd251.js",
"static/chunks/9363-708e3fc7c271db63.js",
"static/chunks/157-f6d67dc9e7bfe380.js",
"static/chunks/3865-0d3515d9486f6382.js",
"static/chunks/7447-f87f4d4fe09a3255.js", "static/chunks/7447-f87f4d4fe09a3255.js",
"static/chunks/2465-d779a94bfd3f89c0.js", "static/chunks/9027-72d4e4b31ea4b417.js",
"static/chunks/1980-4b71d8da4c239cab.js", "static/chunks/6374-931bbad1688d9555.js",
"static/chunks/6298-ed1f2b36c3535636.js", "static/chunks/3995-9a3160d28f21f94b.js",
"static/chunks/app/admin/portfolio/page-fb1abd8d259e0321.js" "static/chunks/6586-99143ae3d67035df.js",
"static/chunks/app/admin/uploads/page-b4b52ce6e0943eb5.js"
], ],
"/admin/analytics/page": [ "/admin/analytics/page": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -511,14 +526,6 @@
"static/chunks/6137-eaf7b6db0f76248f.js", "static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/200-c5238abf2da840bb.js", "static/chunks/200-c5238abf2da840bb.js",
"static/chunks/app/admin/analytics/page-d825378906a79ac8.js" "static/chunks/app/admin/analytics/page-d825378906a79ac8.js"
],
"/artist-dashboard/profile/page": [
"static/chunks/webpack-757604220b96f05e.js",
"static/chunks/fd9d1056-a2747418f8441a81.js",
"static/chunks/2117-da904839ecb5d5f9.js",
"static/chunks/main-app-ac1aded1f8d8af62.js",
"static/chunks/6137-eaf7b6db0f76248f.js",
"static/chunks/app/artist-dashboard/profile/page-cb3c6b72b12ebe1f.js"
] ]
} }
} }

View File

@ -1 +1 @@
{"/_not-found/page":"/_not-found","/aftercare/page":"/aftercare","/api/admin/migrate/route":"/api/admin/migrate","/api/auth/[...nextauth]/route":"/api/auth/[...nextauth]","/artists/[id]/book/page":"/artists/[id]/book","/artists/page":"/artists","/auth/error/page":"/auth/error","/book/page":"/book","/artists/[id]/page":"/artists/[id]","/deposit/page":"/deposit","/contact/page":"/contact","/auth/signin/page":"/auth/signin","/favicon.ico/route":"/favicon.ico","/gift-cards/page":"/gift-cards","/page":"/","/privacy/page":"/privacy","/terms/page":"/terms","/specials/page":"/specials","/api/admin/stats/route":"/api/admin/stats","/api/artists/[id]/route":"/api/artists/[id]","/api/files/bulk-delete/route":"/api/files/bulk-delete","/api/appointments/route":"/api/appointments","/api/artists/me/route":"/api/artists/me","/api/files/folder/route":"/api/files/folder","/api/artists/route":"/api/artists","/api/files/stats/route":"/api/files/stats","/api/files/route":"/api/files","/api/portfolio/route":"/api/portfolio","/api/portfolio/bulk-delete/route":"/api/portfolio/bulk-delete","/api/portfolio/stats/route":"/api/portfolio/stats","/api/portfolio/[id]/route":"/api/portfolio/[id]","/api/users/route":"/api/users","/api/settings/route":"/api/settings","/api/upload/route":"/api/upload","/admin/artists/[id]/page":"/admin/artists/[id]","/admin/artists/new/page":"/admin/artists/new","/admin/artists/page":"/admin/artists","/admin/calendar/page":"/admin/calendar","/admin/page":"/admin","/artist-dashboard/page":"/artist-dashboard","/artist-dashboard/portfolio/page":"/artist-dashboard/portfolio","/admin/uploads/page":"/admin/uploads","/admin/settings/page":"/admin/settings","/admin/portfolio/page":"/admin/portfolio","/admin/analytics/page":"/admin/analytics","/artist-dashboard/profile/page":"/artist-dashboard/profile"} {"/_not-found/page":"/_not-found","/aftercare/page":"/aftercare","/api/admin/migrate/route":"/api/admin/migrate","/api/auth/[...nextauth]/route":"/api/auth/[...nextauth]","/api/public/migrate/route":"/api/public/migrate","/artists/[id]/book/page":"/artists/[id]/book","/artists/[id]/page":"/artists/[id]","/artists/page":"/artists","/auth/error/page":"/auth/error","/auth/signin/page":"/auth/signin","/book/page":"/book","/contact/page":"/contact","/deposit/page":"/deposit","/favicon.ico/route":"/favicon.ico","/gift-cards/page":"/gift-cards","/page":"/","/privacy/page":"/privacy","/specials/page":"/specials","/terms/page":"/terms","/api/admin/stats/route":"/api/admin/stats","/api/artists/me/route":"/api/artists/me","/api/artists/[id]/route":"/api/artists/[id]","/api/files/bulk-delete/route":"/api/files/bulk-delete","/api/files/folder/route":"/api/files/folder","/api/artists/route":"/api/artists","/api/files/route":"/api/files","/api/appointments/route":"/api/appointments","/api/portfolio/bulk-delete/route":"/api/portfolio/bulk-delete","/api/files/stats/route":"/api/files/stats","/api/portfolio/stats/route":"/api/portfolio/stats","/api/portfolio/route":"/api/portfolio","/api/portfolio/[id]/route":"/api/portfolio/[id]","/api/settings/route":"/api/settings","/api/upload/route":"/api/upload","/api/users/route":"/api/users","/admin/artists/[id]/page":"/admin/artists/[id]","/admin/artists/new/page":"/admin/artists/new","/admin/artists/page":"/admin/artists","/admin/calendar/page":"/admin/calendar","/admin/page":"/admin","/artist-dashboard/page":"/artist-dashboard","/artist-dashboard/portfolio/page":"/artist-dashboard/portfolio","/artist-dashboard/profile/page":"/artist-dashboard/profile","/admin/portfolio/page":"/admin/portfolio","/admin/settings/page":"/admin/settings","/admin/uploads/page":"/admin/uploads","/admin/analytics/page":"/admin/analytics"}

View File

@ -5,8 +5,8 @@
"devFiles": [], "devFiles": [],
"ampDevFiles": [], "ampDevFiles": [],
"lowPriorityFiles": [ "lowPriorityFiles": [
"static/SVr_7PUfBPR5HoMg6Gqfy/_buildManifest.js", "static/YY7sC6MVxKHFhQ9os9EJ-/_buildManifest.js",
"static/SVr_7PUfBPR5HoMg6Gqfy/_ssgManifest.js" "static/YY7sC6MVxKHFhQ9os9EJ-/_ssgManifest.js"
], ],
"rootMainFiles": [ "rootMainFiles": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
@ -18,13 +18,13 @@
"/_app": [ "/_app": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/framework-8e0e0f4a6b83a956.js", "static/chunks/framework-8e0e0f4a6b83a956.js",
"static/chunks/main-4d7158e9aface35a.js", "static/chunks/main-2f3a5803e67948e4.js",
"static/chunks/pages/_app-3c9ca398d360b709.js" "static/chunks/pages/_app-3c9ca398d360b709.js"
], ],
"/_error": [ "/_error": [
"static/chunks/webpack-757604220b96f05e.js", "static/chunks/webpack-757604220b96f05e.js",
"static/chunks/framework-8e0e0f4a6b83a956.js", "static/chunks/framework-8e0e0f4a6b83a956.js",
"static/chunks/main-4d7158e9aface35a.js", "static/chunks/main-2f3a5803e67948e4.js",
"static/chunks/pages/_error-cf5ca766ac8f493f.js" "static/chunks/pages/_error-cf5ca766ac8f493f.js"
] ]
}, },

View File

@ -1 +1 @@
{"version":4,"routes":{"/favicon.ico":{"initialHeaders":{"cache-control":"public, max-age=0, must-revalidate","content-type":"image/x-icon","x-next-cache-tags":"_N_T_/layout,_N_T_/favicon.ico/layout,_N_T_/favicon.ico/route,_N_T_/favicon.ico"},"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/favicon.ico","dataRoute":null}},"dynamicRoutes":{},"notFoundRoutes":[],"preview":{"previewModeId":"aa3e44cc5c2d8f61b9a7e308f9db0bf8","previewModeSigningKey":"8aa982a30b271251dc2f1ffdd0eb252e3bc9e47f7d478e80f5dbb2abb1b39323","previewModeEncryptionKey":"e63b6be95276873929b9ec08e113ea325ced41c2d494b0a69b62991e4c3688ab"}} {"version":4,"routes":{"/favicon.ico":{"initialHeaders":{"cache-control":"public, max-age=0, must-revalidate","content-type":"image/x-icon","x-next-cache-tags":"_N_T_/layout,_N_T_/favicon.ico/layout,_N_T_/favicon.ico/route,_N_T_/favicon.ico"},"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/favicon.ico","dataRoute":null}},"dynamicRoutes":{},"notFoundRoutes":[],"preview":{"previewModeId":"55cfb8bce98f34386492e3e3013b3def","previewModeSigningKey":"2de3a5f4686c5891b3e0b87bbf44a183fdd7bc9b2a7ef3a918a2772770dad5b4","previewModeEncryptionKey":"5b32ca192fc7429a1bb0ed5c67f7f91fe66c60e85c5bfb60804bb73c72f79e3c"}}

View File

@ -3,36 +3,37 @@
"/aftercare/page": "app/aftercare/page.js", "/aftercare/page": "app/aftercare/page.js",
"/api/admin/migrate/route": "app/api/admin/migrate/route.js", "/api/admin/migrate/route": "app/api/admin/migrate/route.js",
"/api/auth/[...nextauth]/route": "app/api/auth/[...nextauth]/route.js", "/api/auth/[...nextauth]/route": "app/api/auth/[...nextauth]/route.js",
"/api/public/migrate/route": "app/api/public/migrate/route.js",
"/artists/[id]/book/page": "app/artists/[id]/book/page.js", "/artists/[id]/book/page": "app/artists/[id]/book/page.js",
"/artists/[id]/page": "app/artists/[id]/page.js",
"/artists/page": "app/artists/page.js", "/artists/page": "app/artists/page.js",
"/auth/error/page": "app/auth/error/page.js", "/auth/error/page": "app/auth/error/page.js",
"/book/page": "app/book/page.js",
"/artists/[id]/page": "app/artists/[id]/page.js",
"/deposit/page": "app/deposit/page.js",
"/contact/page": "app/contact/page.js",
"/auth/signin/page": "app/auth/signin/page.js", "/auth/signin/page": "app/auth/signin/page.js",
"/book/page": "app/book/page.js",
"/contact/page": "app/contact/page.js",
"/deposit/page": "app/deposit/page.js",
"/favicon.ico/route": "app/favicon.ico/route.js", "/favicon.ico/route": "app/favicon.ico/route.js",
"/gift-cards/page": "app/gift-cards/page.js", "/gift-cards/page": "app/gift-cards/page.js",
"/page": "app/page.js", "/page": "app/page.js",
"/privacy/page": "app/privacy/page.js", "/privacy/page": "app/privacy/page.js",
"/terms/page": "app/terms/page.js",
"/specials/page": "app/specials/page.js", "/specials/page": "app/specials/page.js",
"/terms/page": "app/terms/page.js",
"/api/admin/stats/route": "app/api/admin/stats/route.js", "/api/admin/stats/route": "app/api/admin/stats/route.js",
"/api/artists/me/route": "app/api/artists/me/route.js",
"/api/artists/[id]/route": "app/api/artists/[id]/route.js", "/api/artists/[id]/route": "app/api/artists/[id]/route.js",
"/api/files/bulk-delete/route": "app/api/files/bulk-delete/route.js", "/api/files/bulk-delete/route": "app/api/files/bulk-delete/route.js",
"/api/appointments/route": "app/api/appointments/route.js",
"/api/artists/me/route": "app/api/artists/me/route.js",
"/api/files/folder/route": "app/api/files/folder/route.js", "/api/files/folder/route": "app/api/files/folder/route.js",
"/api/artists/route": "app/api/artists/route.js", "/api/artists/route": "app/api/artists/route.js",
"/api/files/stats/route": "app/api/files/stats/route.js",
"/api/files/route": "app/api/files/route.js", "/api/files/route": "app/api/files/route.js",
"/api/portfolio/route": "app/api/portfolio/route.js", "/api/appointments/route": "app/api/appointments/route.js",
"/api/portfolio/bulk-delete/route": "app/api/portfolio/bulk-delete/route.js", "/api/portfolio/bulk-delete/route": "app/api/portfolio/bulk-delete/route.js",
"/api/files/stats/route": "app/api/files/stats/route.js",
"/api/portfolio/stats/route": "app/api/portfolio/stats/route.js", "/api/portfolio/stats/route": "app/api/portfolio/stats/route.js",
"/api/portfolio/route": "app/api/portfolio/route.js",
"/api/portfolio/[id]/route": "app/api/portfolio/[id]/route.js", "/api/portfolio/[id]/route": "app/api/portfolio/[id]/route.js",
"/api/users/route": "app/api/users/route.js",
"/api/settings/route": "app/api/settings/route.js", "/api/settings/route": "app/api/settings/route.js",
"/api/upload/route": "app/api/upload/route.js", "/api/upload/route": "app/api/upload/route.js",
"/api/users/route": "app/api/users/route.js",
"/admin/artists/[id]/page": "app/admin/artists/[id]/page.js", "/admin/artists/[id]/page": "app/admin/artists/[id]/page.js",
"/admin/artists/new/page": "app/admin/artists/new/page.js", "/admin/artists/new/page": "app/admin/artists/new/page.js",
"/admin/artists/page": "app/admin/artists/page.js", "/admin/artists/page": "app/admin/artists/page.js",
@ -40,9 +41,9 @@
"/admin/page": "app/admin/page.js", "/admin/page": "app/admin/page.js",
"/artist-dashboard/page": "app/artist-dashboard/page.js", "/artist-dashboard/page": "app/artist-dashboard/page.js",
"/artist-dashboard/portfolio/page": "app/artist-dashboard/portfolio/page.js", "/artist-dashboard/portfolio/page": "app/artist-dashboard/portfolio/page.js",
"/admin/uploads/page": "app/admin/uploads/page.js", "/artist-dashboard/profile/page": "app/artist-dashboard/profile/page.js",
"/admin/settings/page": "app/admin/settings/page.js",
"/admin/portfolio/page": "app/admin/portfolio/page.js", "/admin/portfolio/page": "app/admin/portfolio/page.js",
"/admin/analytics/page": "app/admin/analytics/page.js", "/admin/settings/page": "app/admin/settings/page.js",
"/artist-dashboard/profile/page": "app/artist-dashboard/profile/page.js" "/admin/uploads/page": "app/admin/uploads/page.js",
"/admin/analytics/page": "app/admin/analytics/page.js"
} }

View File

@ -1 +1 @@
(()=>{var t={};t.id=2139,t.ids=[2139],t.modules={72934:t=>{"use strict";t.exports=require("next/dist/client/components/action-async-storage.external.js")},54580:t=>{"use strict";t.exports=require("next/dist/client/components/request-async-storage.external.js")},45869:t=>{"use strict";t.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},20399:t=>{"use strict";t.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},27790:t=>{"use strict";t.exports=require("assert")},78893:t=>{"use strict";t.exports=require("buffer")},84770:t=>{"use strict";t.exports=require("crypto")},17702:t=>{"use strict";t.exports=require("events")},32615:t=>{"use strict";t.exports=require("http")},35240:t=>{"use strict";t.exports=require("https")},55315:t=>{"use strict";t.exports=require("path")},86624:t=>{"use strict";t.exports=require("querystring")},17360:t=>{"use strict";t.exports=require("url")},21764:t=>{"use strict";t.exports=require("util")},71568:t=>{"use strict";t.exports=require("zlib")},33464:(t,e,i)=>{"use strict";i.r(e),i.d(e,{GlobalError:()=>o.a,__next_app__:()=>p,originalPathname:()=>c,pages:()=>l,routeModule:()=>m,tree:()=>u}),i(39211),i(49446),i(40656),i(40509),i(70546);var r=i(30170),s=i(45002),a=i(83876),o=i.n(a),n=i(66299),d={};for(let t in n)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(t)&&(d[t]=()=>n[t]);i.d(e,d);let u=["",{children:["admin",{children:["artists",{children:["[id]",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(i.bind(i,39211)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/admin/artists/[id]/page.tsx"]}]},{}]},{}]},{layout:[()=>Promise.resolve().then(i.bind(i,49446)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/admin/layout.tsx"],metadata:{icon:[async t=>(await Promise.resolve().then(i.bind(i,57481))).default(t)],apple:[],openGraph:[],twitter:[],manifest:void 0}}]},{layout:[()=>Promise.resolve().then(i.bind(i,40656)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/layout.tsx"],error:[()=>Promise.resolve().then(i.bind(i,40509)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/error.tsx"],"not-found":[()=>Promise.resolve().then(i.bind(i,70546)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/not-found.tsx"],metadata:{icon:[async t=>(await Promise.resolve().then(i.bind(i,57481))).default(t)],apple:[],openGraph:[],twitter:[],manifest:void 0}}],l=["/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/admin/artists/[id]/page.tsx"],c="/admin/artists/[id]/page",p={require:i,loadChunk:()=>Promise.resolve()},m=new r.AppPageRouteModule({definition:{kind:s.x.APP_PAGE,page:"/admin/artists/[id]/page",pathname:"/admin/artists/[id]",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:u}})},24350:(t,e,i)=>{Promise.resolve().then(i.bind(i,7796))},7796:(t,e,i)=>{"use strict";i.r(e),i.d(e,{default:()=>d});var r=i(97247),s=i(28964),a=i(34178),o=i(72171),n=i(10906);function d(){let t=(0,a.useParams)(),{toast:e}=(0,n.pm)(),[i,d]=(0,s.useState)(null),[u,l]=(0,s.useState)(!0),c=async()=>{try{let e=await fetch(`/api/artists/${t.id}`);if(!e.ok)throw Error("Failed to fetch artist");let i=await e.json();d(i.artist)}catch(t){console.error("Error fetching artist:",t),e({title:"Error",description:"Failed to load artist",variant:"destructive"})}finally{l(!1)}};return u?r.jsx("div",{className:"flex items-center justify-center h-64",children:r.jsx("div",{className:"text-lg",children:"Loading artist..."})}):i?(0,r.jsxs)("div",{className:"space-y-6",children:[(0,r.jsxs)("div",{children:[r.jsx("h1",{className:"text-3xl font-bold tracking-tight",children:"Edit Artist"}),(0,r.jsxs)("p",{className:"text-muted-foreground",children:["Update ",i.name,"'s information and portfolio"]})]}),r.jsx(o.ArtistForm,{artist:i,onSuccess:()=>{e({title:"Success",description:"Artist updated successfully"}),c()}})]}):r.jsx("div",{className:"flex items-center justify-center h-64",children:r.jsx("div",{className:"text-lg",children:"Artist not found"})})}},39211:(t,e,i)=>{"use strict";i.r(e),i.d(e,{default:()=>r});let r=(0,i(45347).createProxy)(String.raw`/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/admin/artists/[id]/page.tsx#default`)}};var e=require("../../../../webpack-runtime.js");e.C(t);var i=t=>e(e.s=t),r=e.X(0,[9379,3670,1488,1511,4080,4128,6609,23,4106,5593,5160],()=>i(33464));module.exports=r})(); (()=>{var t={};t.id=2139,t.ids=[2139],t.modules={72934:t=>{"use strict";t.exports=require("next/dist/client/components/action-async-storage.external.js")},54580:t=>{"use strict";t.exports=require("next/dist/client/components/request-async-storage.external.js")},45869:t=>{"use strict";t.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},20399:t=>{"use strict";t.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},27790:t=>{"use strict";t.exports=require("assert")},78893:t=>{"use strict";t.exports=require("buffer")},84770:t=>{"use strict";t.exports=require("crypto")},17702:t=>{"use strict";t.exports=require("events")},32615:t=>{"use strict";t.exports=require("http")},35240:t=>{"use strict";t.exports=require("https")},55315:t=>{"use strict";t.exports=require("path")},86624:t=>{"use strict";t.exports=require("querystring")},17360:t=>{"use strict";t.exports=require("url")},21764:t=>{"use strict";t.exports=require("util")},71568:t=>{"use strict";t.exports=require("zlib")},33464:(t,e,i)=>{"use strict";i.r(e),i.d(e,{GlobalError:()=>o.a,__next_app__:()=>p,originalPathname:()=>c,pages:()=>l,routeModule:()=>m,tree:()=>u}),i(39211),i(49446),i(40656),i(40509),i(70546);var r=i(30170),s=i(45002),a=i(83876),o=i.n(a),n=i(66299),d={};for(let t in n)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(t)&&(d[t]=()=>n[t]);i.d(e,d);let u=["",{children:["admin",{children:["artists",{children:["[id]",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(i.bind(i,39211)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/admin/artists/[id]/page.tsx"]}]},{}]},{}]},{layout:[()=>Promise.resolve().then(i.bind(i,49446)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/admin/layout.tsx"],metadata:{icon:[async t=>(await Promise.resolve().then(i.bind(i,57481))).default(t)],apple:[],openGraph:[],twitter:[],manifest:void 0}}]},{layout:[()=>Promise.resolve().then(i.bind(i,40656)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/layout.tsx"],error:[()=>Promise.resolve().then(i.bind(i,40509)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/error.tsx"],"not-found":[()=>Promise.resolve().then(i.bind(i,70546)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/not-found.tsx"],metadata:{icon:[async t=>(await Promise.resolve().then(i.bind(i,57481))).default(t)],apple:[],openGraph:[],twitter:[],manifest:void 0}}],l=["/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/admin/artists/[id]/page.tsx"],c="/admin/artists/[id]/page",p={require:i,loadChunk:()=>Promise.resolve()},m=new r.AppPageRouteModule({definition:{kind:s.x.APP_PAGE,page:"/admin/artists/[id]/page",pathname:"/admin/artists/[id]",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:u}})},24350:(t,e,i)=>{Promise.resolve().then(i.bind(i,7796))},7796:(t,e,i)=>{"use strict";i.r(e),i.d(e,{default:()=>u});var r=i(97247),s=i(28964),a=i(34178),o=i(72171),n=i(64890),d=i(10906);function u(){let t=(0,a.useParams)(),{toast:e}=(0,d.pm)(),[i,u]=(0,s.useState)(null),[l,c]=(0,s.useState)(!0),p=async()=>{try{let e=await fetch(`/api/artists/${t.id}`);if(!e.ok)throw Error("Failed to fetch artist");let i=await e.json();u(i.artist)}catch(t){console.error("Error fetching artist:",t),e({title:"Error",description:"Failed to load artist",variant:"destructive"})}finally{c(!1)}};return l?r.jsx("div",{className:"flex items-center justify-center h-64",children:r.jsx("div",{className:"text-lg",children:"Loading artist..."})}):i?(0,r.jsxs)("div",{className:"space-y-6",children:[(0,r.jsxs)("div",{children:[r.jsx("h1",{className:"text-3xl font-bold tracking-tight",children:"Edit Artist"}),(0,r.jsxs)("p",{className:"text-muted-foreground",children:["Update ",i.name,"'s information and portfolio"]})]}),r.jsx(o.ArtistForm,{artist:i,onSuccess:()=>{e({title:"Success",description:"Artist updated successfully"}),p()}}),r.jsx(n.PortfolioManager,{artistId:i.id,onImagesUpdate:()=>{p()}})]}):r.jsx("div",{className:"flex items-center justify-center h-64",children:r.jsx("div",{className:"text-lg",children:"Artist not found"})})}},39211:(t,e,i)=>{"use strict";i.r(e),i.d(e,{default:()=>r});let r=(0,i(45347).createProxy)(String.raw`/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/admin/artists/[id]/page.tsx#default`)}};var e=require("../../../../webpack-runtime.js");e.C(t);var i=t=>e(e.s=t),r=e.X(0,[9379,3670,1488,1511,4080,4128,6082,2092,6887,4882,921,4245,4106,5593,2171,4890],()=>i(33464));module.exports=r})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
(()=>{var e={};e.id=3886,e.ids=[3886],e.modules={72934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},54580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},45869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},20399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},55315:e=>{"use strict";e.exports=require("path")},17360:e=>{"use strict";e.exports=require("url")},16543:(e,t,s)=>{"use strict";s.r(t),s.d(t,{GlobalError:()=>r.a,__next_app__:()=>m,originalPathname:()=>u,pages:()=>d,routeModule:()=>p,tree:()=>c}),s(8696),s(84172),s(96141),s(40656),s(40509),s(70546);var a=s(30170),o=s(45002),i=s(83876),r=s.n(i),n=s(66299),l={};for(let e in n)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(l[e]=()=>n[e]);s.d(t,l);let c=["",{children:["book",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(s.bind(s,8696)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/page.tsx"]}]},{error:[()=>Promise.resolve().then(s.bind(s,84172)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/error.tsx"],loading:[()=>Promise.resolve().then(s.bind(s,96141)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/loading.tsx"],metadata:{icon:[async e=>(await Promise.resolve().then(s.bind(s,57481))).default(e)],apple:[],openGraph:[],twitter:[],manifest:void 0}}]},{layout:[()=>Promise.resolve().then(s.bind(s,40656)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/layout.tsx"],error:[()=>Promise.resolve().then(s.bind(s,40509)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/error.tsx"],"not-found":[()=>Promise.resolve().then(s.bind(s,70546)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/not-found.tsx"],metadata:{icon:[async e=>(await Promise.resolve().then(s.bind(s,57481))).default(e)],apple:[],openGraph:[],twitter:[],manifest:void 0}}],d=["/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/page.tsx"],u="/book/page",m={require:s,loadChunk:()=>Promise.resolve()},p=new a.AppPageRouteModule({definition:{kind:o.x.APP_PAGE,page:"/book/page",pathname:"/book",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:c}})},99633:(e,t,s)=>{Promise.resolve().then(s.bind(s,95808))},95808:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>n});var a=s(97247),o=s(2502),i=s(58053),r=s(35921);function n({reset:e}){return a.jsx("div",{className:"container mx-auto px-4 py-8",children:(0,a.jsxs)(o.bZ,{variant:"destructive",className:"max-w-2xl mx-auto",children:[a.jsx(r.Z,{className:"h-4 w-4"}),a.jsx(o.Cd,{children:"Something went wrong!"}),(0,a.jsxs)(o.X,{className:"space-y-4",children:[a.jsx("p",{children:"We encountered an error while loading the booking form. Please try again or contact support if the problem persists."}),a.jsx(i.z,{onClick:e,variant:"outline",size:"sm",children:"Try again"})]})]})})}},84172:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>a});let a=(0,s(45347).createProxy)(String.raw`/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/error.tsx#default`)},96141:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>i});var a=s(72051),o=s(58030);function i(){return(0,a.jsxs)("div",{className:"container mx-auto px-4 py-8 space-y-8",children:[(0,a.jsxs)("div",{className:"text-center space-y-4",children:[a.jsx(o.O,{className:"h-12 w-72 mx-auto"}),a.jsx(o.O,{className:"h-6 w-96 mx-auto"})]}),(0,a.jsxs)("div",{className:"max-w-2xl mx-auto space-y-6",children:[(0,a.jsxs)("div",{className:"grid gap-6 md:grid-cols-2",children:[(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-20"}),a.jsx(o.O,{className:"h-10 w-full"})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-24"}),a.jsx(o.O,{className:"h-10 w-full"})]})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-16"}),a.jsx(o.O,{className:"h-10 w-full"})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-20"}),a.jsx(o.O,{className:"h-10 w-full"})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-28"}),a.jsx(o.O,{className:"h-24 w-full"})]}),a.jsx(o.O,{className:"h-12 w-32"})]})]})}},8696:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>n});var a=s(72051),o=s(94604),i=s(38252),r=s(86006);function n(){return(0,a.jsxs)("main",{className:"min-h-screen",children:[a.jsx(o.W,{}),a.jsx("div",{className:"pt-16",children:a.jsx(i.F,{})}),a.jsx(r.$,{})]})}}};var t=require("../../webpack-runtime.js");t.C(e);var s=e=>t(t.s=e),a=t.X(0,[9379,1488,1511,4080,6082,6758,1181,6626,6967,2133,817,490,3744,4106,4298,4012],()=>s(16543));module.exports=a})(); (()=>{var e={};e.id=3886,e.ids=[3886],e.modules={72934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},54580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},45869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},20399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},55315:e=>{"use strict";e.exports=require("path")},17360:e=>{"use strict";e.exports=require("url")},16543:(e,t,s)=>{"use strict";s.r(t),s.d(t,{GlobalError:()=>r.a,__next_app__:()=>m,originalPathname:()=>u,pages:()=>d,routeModule:()=>p,tree:()=>c}),s(8696),s(84172),s(96141),s(40656),s(40509),s(70546);var a=s(30170),o=s(45002),i=s(83876),r=s.n(i),n=s(66299),l={};for(let e in n)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(l[e]=()=>n[e]);s.d(t,l);let c=["",{children:["book",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(s.bind(s,8696)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/page.tsx"]}]},{error:[()=>Promise.resolve().then(s.bind(s,84172)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/error.tsx"],loading:[()=>Promise.resolve().then(s.bind(s,96141)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/loading.tsx"],metadata:{icon:[async e=>(await Promise.resolve().then(s.bind(s,57481))).default(e)],apple:[],openGraph:[],twitter:[],manifest:void 0}}]},{layout:[()=>Promise.resolve().then(s.bind(s,40656)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/layout.tsx"],error:[()=>Promise.resolve().then(s.bind(s,40509)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/error.tsx"],"not-found":[()=>Promise.resolve().then(s.bind(s,70546)),"/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/not-found.tsx"],metadata:{icon:[async e=>(await Promise.resolve().then(s.bind(s,57481))).default(e)],apple:[],openGraph:[],twitter:[],manifest:void 0}}],d=["/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/page.tsx"],u="/book/page",m={require:s,loadChunk:()=>Promise.resolve()},p=new a.AppPageRouteModule({definition:{kind:o.x.APP_PAGE,page:"/book/page",pathname:"/book",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:c}})},99633:(e,t,s)=>{Promise.resolve().then(s.bind(s,95808))},95808:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>n});var a=s(97247),o=s(2502),i=s(58053),r=s(35921);function n({reset:e}){return a.jsx("div",{className:"container mx-auto px-4 py-8",children:(0,a.jsxs)(o.bZ,{variant:"destructive",className:"max-w-2xl mx-auto",children:[a.jsx(r.Z,{className:"h-4 w-4"}),a.jsx(o.Cd,{children:"Something went wrong!"}),(0,a.jsxs)(o.X,{className:"space-y-4",children:[a.jsx("p",{children:"We encountered an error while loading the booking form. Please try again or contact support if the problem persists."}),a.jsx(i.z,{onClick:e,variant:"outline",size:"sm",children:"Try again"})]})]})})}},84172:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>a});let a=(0,s(45347).createProxy)(String.raw`/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo/app/book/error.tsx#default`)},96141:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>i});var a=s(72051),o=s(58030);function i(){return(0,a.jsxs)("div",{className:"container mx-auto px-4 py-8 space-y-8",children:[(0,a.jsxs)("div",{className:"text-center space-y-4",children:[a.jsx(o.O,{className:"h-12 w-72 mx-auto"}),a.jsx(o.O,{className:"h-6 w-96 mx-auto"})]}),(0,a.jsxs)("div",{className:"max-w-2xl mx-auto space-y-6",children:[(0,a.jsxs)("div",{className:"grid gap-6 md:grid-cols-2",children:[(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-20"}),a.jsx(o.O,{className:"h-10 w-full"})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-24"}),a.jsx(o.O,{className:"h-10 w-full"})]})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-16"}),a.jsx(o.O,{className:"h-10 w-full"})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-20"}),a.jsx(o.O,{className:"h-10 w-full"})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[a.jsx(o.O,{className:"h-4 w-28"}),a.jsx(o.O,{className:"h-24 w-full"})]}),a.jsx(o.O,{className:"h-12 w-32"})]})]})}},8696:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>n});var a=s(72051),o=s(94604),i=s(38252),r=s(86006);function n(){return(0,a.jsxs)("main",{className:"min-h-screen",children:[a.jsx(o.W,{}),a.jsx("div",{className:"pt-16",children:a.jsx(i.F,{})}),a.jsx(r.$,{})]})}}};var t=require("../../webpack-runtime.js");t.C(e);var s=e=>t(t.s=e),a=t.X(0,[9379,1488,1511,4080,6082,6758,1181,6626,2092,7837,817,490,3744,4106,4298,4012],()=>s(16543));module.exports=a})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
self.__BUILD_MANIFEST={polyfillFiles:["static/chunks/polyfills-42372ed130431b0a.js"],devFiles:[],ampDevFiles:[],lowPriorityFiles:[],rootMainFiles:["static/chunks/webpack-757604220b96f05e.js","static/chunks/fd9d1056-a2747418f8441a81.js","static/chunks/2117-da904839ecb5d5f9.js","static/chunks/main-app-ac1aded1f8d8af62.js"],pages:{"/_app":["static/chunks/webpack-757604220b96f05e.js","static/chunks/framework-8e0e0f4a6b83a956.js","static/chunks/main-4d7158e9aface35a.js","static/chunks/pages/_app-3c9ca398d360b709.js"],"/_error":["static/chunks/webpack-757604220b96f05e.js","static/chunks/framework-8e0e0f4a6b83a956.js","static/chunks/main-4d7158e9aface35a.js","static/chunks/pages/_error-cf5ca766ac8f493f.js"]},ampFirstPages:[]},self.__BUILD_MANIFEST.lowPriorityFiles=["/static/"+process.env.__NEXT_BUILD_ID+"/_buildManifest.js",,"/static/"+process.env.__NEXT_BUILD_ID+"/_ssgManifest.js"]; self.__BUILD_MANIFEST={polyfillFiles:["static/chunks/polyfills-42372ed130431b0a.js"],devFiles:[],ampDevFiles:[],lowPriorityFiles:[],rootMainFiles:["static/chunks/webpack-757604220b96f05e.js","static/chunks/fd9d1056-a2747418f8441a81.js","static/chunks/2117-da904839ecb5d5f9.js","static/chunks/main-app-ac1aded1f8d8af62.js"],pages:{"/_app":["static/chunks/webpack-757604220b96f05e.js","static/chunks/framework-8e0e0f4a6b83a956.js","static/chunks/main-2f3a5803e67948e4.js","static/chunks/pages/_app-3c9ca398d360b709.js"],"/_error":["static/chunks/webpack-757604220b96f05e.js","static/chunks/framework-8e0e0f4a6b83a956.js","static/chunks/main-2f3a5803e67948e4.js","static/chunks/pages/_error-cf5ca766ac8f493f.js"]},ampFirstPages:[]},self.__BUILD_MANIFEST.lowPriorityFiles=["/static/"+process.env.__NEXT_BUILD_ID+"/_buildManifest.js",,"/static/"+process.env.__NEXT_BUILD_ID+"/_ssgManifest.js"];

View File

@ -17,11 +17,11 @@
"wasm": [], "wasm": [],
"assets": [], "assets": [],
"env": { "env": {
"__NEXT_BUILD_ID": "SVr_7PUfBPR5HoMg6Gqfy", "__NEXT_BUILD_ID": "YY7sC6MVxKHFhQ9os9EJ-",
"NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "eqMtY6RQJg8ZzpGru9Ni8jGmRicvhYvppy45/3SECqU=", "NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "dIIe8uld0IZYSR75raX3hqcoXVKi4G5ZTC9ulh2RS/M=",
"__NEXT_PREVIEW_MODE_ID": "aa3e44cc5c2d8f61b9a7e308f9db0bf8", "__NEXT_PREVIEW_MODE_ID": "55cfb8bce98f34386492e3e3013b3def",
"__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "e63b6be95276873929b9ec08e113ea325ced41c2d494b0a69b62991e4c3688ab", "__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "5b32ca192fc7429a1bb0ed5c67f7f91fe66c60e85c5bfb60804bb73c72f79e3c",
"__NEXT_PREVIEW_MODE_SIGNING_KEY": "8aa982a30b271251dc2f1ffdd0eb252e3bc9e47f7d478e80f5dbb2abb1b39323" "__NEXT_PREVIEW_MODE_SIGNING_KEY": "2de3a5f4686c5891b3e0b87bbf44a183fdd7bc9b2a7ef3a918a2772770dad5b4"
} }
} }
}, },

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"node":{},"edge":{},"encryptionKey":"eqMtY6RQJg8ZzpGru9Ni8jGmRicvhYvppy45/3SECqU="} {"node":{},"edge":{},"encryptionKey":"dIIe8uld0IZYSR75raX3hqcoXVKi4G5ZTC9ulh2RS/M="}

View File

@ -2,14 +2,16 @@
if (!e[o]) { if (!e[o]) {
switch (o) { switch (o) {
case 1035: r(require("./chunks/1035.js")); break; case 1035: r(require("./chunks/1035.js")); break;
case 111: r(require("./chunks/111.js")); break;
case 1181: r(require("./chunks/1181.js")); break; case 1181: r(require("./chunks/1181.js")); break;
case 1222: r(require("./chunks/1222.js")); break; case 1222: r(require("./chunks/1222.js")); break;
case 1488: r(require("./chunks/1488.js")); break; case 1488: r(require("./chunks/1488.js")); break;
case 1511: r(require("./chunks/1511.js")); break; case 1511: r(require("./chunks/1511.js")); break;
case 2064: r(require("./chunks/2064.js")); break; case 2064: r(require("./chunks/2064.js")); break;
case 2133: r(require("./chunks/2133.js")); break; case 2092: r(require("./chunks/2092.js")); break;
case 23: r(require("./chunks/23.js")); break; case 2171: r(require("./chunks/2171.js")); break;
case 2882: r(require("./chunks/2882.js")); break; case 2882: r(require("./chunks/2882.js")); break;
case 3364: r(require("./chunks/3364.js")); break;
case 3664: r(require("./chunks/3664.js")); break; case 3664: r(require("./chunks/3664.js")); break;
case 3670: r(require("./chunks/3670.js")); break; case 3670: r(require("./chunks/3670.js")); break;
case 3744: r(require("./chunks/3744.js")); break; case 3744: r(require("./chunks/3744.js")); break;
@ -18,23 +20,23 @@
case 4080: r(require("./chunks/4080.js")); break; case 4080: r(require("./chunks/4080.js")); break;
case 4106: r(require("./chunks/4106.js")); break; case 4106: r(require("./chunks/4106.js")); break;
case 4128: r(require("./chunks/4128.js")); break; case 4128: r(require("./chunks/4128.js")); break;
case 4245: r(require("./chunks/4245.js")); break;
case 4298: r(require("./chunks/4298.js")); break; case 4298: r(require("./chunks/4298.js")); break;
case 4833: r(require("./chunks/4833.js")); break; case 4833: r(require("./chunks/4833.js")); break;
case 4882: r(require("./chunks/4882.js")); break;
case 4890: r(require("./chunks/4890.js")); break;
case 490: r(require("./chunks/490.js")); break; case 490: r(require("./chunks/490.js")); break;
case 4926: r(require("./chunks/4926.js")); break; case 5314: r(require("./chunks/5314.js")); break;
case 5160: r(require("./chunks/5160.js")); break;
case 5593: r(require("./chunks/5593.js")); break; case 5593: r(require("./chunks/5593.js")); break;
case 6082: r(require("./chunks/6082.js")); break; case 6082: r(require("./chunks/6082.js")); break;
case 6194: r(require("./chunks/6194.js")); break;
case 6609: r(require("./chunks/6609.js")); break;
case 6626: r(require("./chunks/6626.js")); break; case 6626: r(require("./chunks/6626.js")); break;
case 6694: r(require("./chunks/6694.js")); break;
case 6758: r(require("./chunks/6758.js")); break; case 6758: r(require("./chunks/6758.js")); break;
case 6887: r(require("./chunks/6887.js")); break; case 6887: r(require("./chunks/6887.js")); break;
case 6967: r(require("./chunks/6967.js")); break; case 7837: r(require("./chunks/7837.js")); break;
case 7542: r(require("./chunks/7542.js")); break;
case 817: r(require("./chunks/817.js")); break; case 817: r(require("./chunks/817.js")); break;
case 8673: r(require("./chunks/8673.js")); break;
case 9161: r(require("./chunks/9161.js")); break; case 9161: r(require("./chunks/9161.js")); break;
case 921: r(require("./chunks/921.js")); break;
case 9379: r(require("./chunks/9379.js")); break; case 9379: r(require("./chunks/9379.js")); break;
case 6658: e[o] = 1; break; case 6658: e[o] = 1; break;
default: throw new Error(`Unknown chunk ${o}`); default: throw new Error(`Unknown chunk ${o}`);

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -673,12 +673,12 @@ var NEXT_DIR = path.join(__dirname, ".next");
var OPEN_NEXT_DIR = path.join(__dirname, ".open-next"); var OPEN_NEXT_DIR = path.join(__dirname, ".open-next");
debug({ NEXT_DIR, OPEN_NEXT_DIR }); debug({ NEXT_DIR, OPEN_NEXT_DIR });
var NextConfig = { "env": {}, "webpack": null, "eslint": { "ignoreDuringBuilds": true }, "typescript": { "ignoreBuildErrors": true, "tsconfigPath": "tsconfig.json" }, "distDir": ".next", "cleanDistDir": true, "assetPrefix": "", "cacheMaxMemorySize": 52428800, "configOrigin": "next.config.mjs", "useFileSystemPublicRoutes": true, "generateEtags": true, "pageExtensions": ["tsx", "ts", "jsx", "js"], "poweredByHeader": true, "compress": true, "analyticsId": "", "images": { "deviceSizes": [640, 750, 828, 1080, 1200, 1920, 2048, 3840], "imageSizes": [16, 32, 48, 64, 96, 128, 256, 384], "path": "/_next/image", "loader": "default", "loaderFile": "", "domains": [], "disableStaticImages": false, "minimumCacheTTL": 60, "formats": ["image/webp"], "dangerouslyAllowSVG": false, "contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;", "contentDispositionType": "inline", "remotePatterns": [], "unoptimized": true }, "devIndicators": { "buildActivity": true, "buildActivityPosition": "bottom-right" }, "onDemandEntries": { "maxInactiveAge": 6e4, "pagesBufferLength": 5 }, "amp": { "canonicalBase": "" }, "basePath": "", "sassOptions": {}, "trailingSlash": false, "i18n": null, "productionBrowserSourceMaps": false, "optimizeFonts": true, "excludeDefaultMomentLocales": true, "serverRuntimeConfig": {}, "publicRuntimeConfig": {}, "reactProductionProfiling": false, "reactStrictMode": null, "httpAgentOptions": { "keepAlive": true }, "outputFileTracing": true, "staticPageGenerationTimeout": 60, "swcMinify": true, "output": "standalone", "modularizeImports": { "@mui/icons-material": { "transform": "@mui/icons-material/{{member}}" }, "lodash": { "transform": "lodash/{{member}}" } }, "experimental": { "multiZoneDraftMode": false, "prerenderEarlyExit": false, "serverMinification": true, "serverSourceMaps": false, "linkNoTouchStart": false, "caseSensitiveRoutes": false, "clientRouterFilter": true, "clientRouterFilterRedirects": false, "fetchCacheKeyPrefix": "", "middlewarePrefetch": "flexible", "optimisticClientCache": true, "manualClientBasePath": false, "cpus": 11, "memoryBasedWorkersCount": false, "isrFlushToDisk": true, "workerThreads": false, "optimizeCss": false, "nextScriptWorkers": false, "scrollRestoration": false, "externalDir": false, "disableOptimizedLoading": false, "gzipSize": true, "craCompat": false, "esmExternals": true, "fullySpecified": false, "outputFileTracingRoot": "/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo", "swcTraceProfiling": false, "forceSwcTransforms": false, "largePageDataBytes": 128e3, "adjustFontFallbacks": false, "adjustFontFallbacksWithSizeAdjust": false, "typedRoutes": false, "instrumentationHook": false, "bundlePagesExternals": false, "parallelServerCompiles": false, "parallelServerBuildTraces": false, "ppr": false, "missingSuspenseWithCSRBailout": true, "optimizeServerReact": true, "useEarlyImport": false, "staleTimes": { "dynamic": 30, "static": 300 }, "optimizePackageImports": ["lucide-react", "date-fns", "lodash-es", "ramda", "antd", "react-bootstrap", "ahooks", "@ant-design/icons", "@headlessui/react", "@headlessui-float/react", "@heroicons/react/20/solid", "@heroicons/react/24/solid", "@heroicons/react/24/outline", "@visx/visx", "@tremor/react", "rxjs", "@mui/material", "@mui/icons-material", "recharts", "react-use", "@material-ui/core", "@material-ui/icons", "@tabler/icons-react", "mui-core", "react-icons/ai", "react-icons/bi", "react-icons/bs", "react-icons/cg", "react-icons/ci", "react-icons/di", "react-icons/fa", "react-icons/fa6", "react-icons/fc", "react-icons/fi", "react-icons/gi", "react-icons/go", "react-icons/gr", "react-icons/hi", "react-icons/hi2", "react-icons/im", "react-icons/io", "react-icons/io5", "react-icons/lia", "react-icons/lib", "react-icons/lu", "react-icons/md", "react-icons/pi", "react-icons/ri", "react-icons/rx", "react-icons/si", "react-icons/sl", "react-icons/tb", "react-icons/tfi", "react-icons/ti", "react-icons/vsc", "react-icons/wi"], "trustHostHeader": false, "isExperimentalCompile": false }, "configFileName": "next.config.mjs" }; var NextConfig = { "env": {}, "webpack": null, "eslint": { "ignoreDuringBuilds": true }, "typescript": { "ignoreBuildErrors": true, "tsconfigPath": "tsconfig.json" }, "distDir": ".next", "cleanDistDir": true, "assetPrefix": "", "cacheMaxMemorySize": 52428800, "configOrigin": "next.config.mjs", "useFileSystemPublicRoutes": true, "generateEtags": true, "pageExtensions": ["tsx", "ts", "jsx", "js"], "poweredByHeader": true, "compress": true, "analyticsId": "", "images": { "deviceSizes": [640, 750, 828, 1080, 1200, 1920, 2048, 3840], "imageSizes": [16, 32, 48, 64, 96, 128, 256, 384], "path": "/_next/image", "loader": "default", "loaderFile": "", "domains": [], "disableStaticImages": false, "minimumCacheTTL": 60, "formats": ["image/webp"], "dangerouslyAllowSVG": false, "contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;", "contentDispositionType": "inline", "remotePatterns": [], "unoptimized": true }, "devIndicators": { "buildActivity": true, "buildActivityPosition": "bottom-right" }, "onDemandEntries": { "maxInactiveAge": 6e4, "pagesBufferLength": 5 }, "amp": { "canonicalBase": "" }, "basePath": "", "sassOptions": {}, "trailingSlash": false, "i18n": null, "productionBrowserSourceMaps": false, "optimizeFonts": true, "excludeDefaultMomentLocales": true, "serverRuntimeConfig": {}, "publicRuntimeConfig": {}, "reactProductionProfiling": false, "reactStrictMode": null, "httpAgentOptions": { "keepAlive": true }, "outputFileTracing": true, "staticPageGenerationTimeout": 60, "swcMinify": true, "output": "standalone", "modularizeImports": { "@mui/icons-material": { "transform": "@mui/icons-material/{{member}}" }, "lodash": { "transform": "lodash/{{member}}" } }, "experimental": { "multiZoneDraftMode": false, "prerenderEarlyExit": false, "serverMinification": true, "serverSourceMaps": false, "linkNoTouchStart": false, "caseSensitiveRoutes": false, "clientRouterFilter": true, "clientRouterFilterRedirects": false, "fetchCacheKeyPrefix": "", "middlewarePrefetch": "flexible", "optimisticClientCache": true, "manualClientBasePath": false, "cpus": 11, "memoryBasedWorkersCount": false, "isrFlushToDisk": true, "workerThreads": false, "optimizeCss": false, "nextScriptWorkers": false, "scrollRestoration": false, "externalDir": false, "disableOptimizedLoading": false, "gzipSize": true, "craCompat": false, "esmExternals": true, "fullySpecified": false, "outputFileTracingRoot": "/home/Nicholai/Documents/Dev/united_v03/united-tattoo/united-tattoo", "swcTraceProfiling": false, "forceSwcTransforms": false, "largePageDataBytes": 128e3, "adjustFontFallbacks": false, "adjustFontFallbacksWithSizeAdjust": false, "typedRoutes": false, "instrumentationHook": false, "bundlePagesExternals": false, "parallelServerCompiles": false, "parallelServerBuildTraces": false, "ppr": false, "missingSuspenseWithCSRBailout": true, "optimizeServerReact": true, "useEarlyImport": false, "staleTimes": { "dynamic": 30, "static": 300 }, "optimizePackageImports": ["lucide-react", "date-fns", "lodash-es", "ramda", "antd", "react-bootstrap", "ahooks", "@ant-design/icons", "@headlessui/react", "@headlessui-float/react", "@heroicons/react/20/solid", "@heroicons/react/24/solid", "@heroicons/react/24/outline", "@visx/visx", "@tremor/react", "rxjs", "@mui/material", "@mui/icons-material", "recharts", "react-use", "@material-ui/core", "@material-ui/icons", "@tabler/icons-react", "mui-core", "react-icons/ai", "react-icons/bi", "react-icons/bs", "react-icons/cg", "react-icons/ci", "react-icons/di", "react-icons/fa", "react-icons/fa6", "react-icons/fc", "react-icons/fi", "react-icons/gi", "react-icons/go", "react-icons/gr", "react-icons/hi", "react-icons/hi2", "react-icons/im", "react-icons/io", "react-icons/io5", "react-icons/lia", "react-icons/lib", "react-icons/lu", "react-icons/md", "react-icons/pi", "react-icons/ri", "react-icons/rx", "react-icons/si", "react-icons/sl", "react-icons/tb", "react-icons/tfi", "react-icons/ti", "react-icons/vsc", "react-icons/wi"], "trustHostHeader": false, "isExperimentalCompile": false }, "configFileName": "next.config.mjs" };
var BuildId = "SVr_7PUfBPR5HoMg6Gqfy"; var BuildId = "YY7sC6MVxKHFhQ9os9EJ-";
var HtmlPages = []; var HtmlPages = [];
var RoutesManifest = { "basePath": "", "rewrites": { "beforeFiles": [], "afterFiles": [], "fallback": [] }, "redirects": [{ "source": "/:path+/", "destination": "/:path+", "internal": true, "statusCode": 308, "regex": "^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$" }], "routes": { "static": [{ "page": "/", "regex": "^/(?:/)?$", "routeKeys": {}, "namedRegex": "^/(?:/)?$" }, { "page": "/_not-found", "regex": "^/_not\\-found(?:/)?$", "routeKeys": {}, "namedRegex": "^/_not\\-found(?:/)?$" }, { "page": "/admin", "regex": "^/admin(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin(?:/)?$" }, { "page": "/admin/analytics", "regex": "^/admin/analytics(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/analytics(?:/)?$" }, { "page": "/admin/artists", "regex": "^/admin/artists(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/artists(?:/)?$" }, { "page": "/admin/artists/new", "regex": "^/admin/artists/new(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/artists/new(?:/)?$" }, { "page": "/admin/calendar", "regex": "^/admin/calendar(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/calendar(?:/)?$" }, { "page": "/admin/portfolio", "regex": "^/admin/portfolio(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/portfolio(?:/)?$" }, { "page": "/admin/settings", "regex": "^/admin/settings(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/settings(?:/)?$" }, { "page": "/admin/uploads", "regex": "^/admin/uploads(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/uploads(?:/)?$" }, { "page": "/aftercare", "regex": "^/aftercare(?:/)?$", "routeKeys": {}, "namedRegex": "^/aftercare(?:/)?$" }, { "page": "/artist-dashboard", "regex": "^/artist\\-dashboard(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard(?:/)?$" }, { "page": "/artist-dashboard/portfolio", "regex": "^/artist\\-dashboard/portfolio(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard/portfolio(?:/)?$" }, { "page": "/artist-dashboard/profile", "regex": "^/artist\\-dashboard/profile(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard/profile(?:/)?$" }, { "page": "/artists", "regex": "^/artists(?:/)?$", "routeKeys": {}, "namedRegex": "^/artists(?:/)?$" }, { "page": "/auth/error", "regex": "^/auth/error(?:/)?$", "routeKeys": {}, "namedRegex": "^/auth/error(?:/)?$" }, { "page": "/auth/signin", "regex": "^/auth/signin(?:/)?$", "routeKeys": {}, "namedRegex": "^/auth/signin(?:/)?$" }, { "page": "/book", "regex": "^/book(?:/)?$", "routeKeys": {}, "namedRegex": "^/book(?:/)?$" }, { "page": "/contact", "regex": "^/contact(?:/)?$", "routeKeys": {}, "namedRegex": "^/contact(?:/)?$" }, { "page": "/deposit", "regex": "^/deposit(?:/)?$", "routeKeys": {}, "namedRegex": "^/deposit(?:/)?$" }, { "page": "/favicon.ico", "regex": "^/favicon\\.ico(?:/)?$", "routeKeys": {}, "namedRegex": "^/favicon\\.ico(?:/)?$" }, { "page": "/gift-cards", "regex": "^/gift\\-cards(?:/)?$", "routeKeys": {}, "namedRegex": "^/gift\\-cards(?:/)?$" }, { "page": "/privacy", "regex": "^/privacy(?:/)?$", "routeKeys": {}, "namedRegex": "^/privacy(?:/)?$" }, { "page": "/specials", "regex": "^/specials(?:/)?$", "routeKeys": {}, "namedRegex": "^/specials(?:/)?$" }, { "page": "/terms", "regex": "^/terms(?:/)?$", "routeKeys": {}, "namedRegex": "^/terms(?:/)?$" }], "dynamic": [{ "page": "/admin/artists/[id]", "regex": "^/admin/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/admin/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/api/artists/[id]", "regex": "^/api/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/api/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/api/auth/[...nextauth]", "regex": "^/api/auth/(.+?)(?:/)?$", "routeKeys": { "nxtPnextauth": "nxtPnextauth" }, "namedRegex": "^/api/auth/(?<nxtPnextauth>.+?)(?:/)?$" }, { "page": "/api/portfolio/[id]", "regex": "^/api/portfolio/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/api/portfolio/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/artists/[id]", "regex": "^/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/artists/[id]/book", "regex": "^/artists/([^/]+?)/book(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/artists/(?<nxtPid>[^/]+?)/book(?:/)?$" }], "data": { "static": [], "dynamic": [] } }, "locales": [] }; var RoutesManifest = { "basePath": "", "rewrites": { "beforeFiles": [], "afterFiles": [], "fallback": [] }, "redirects": [{ "source": "/:path+/", "destination": "/:path+", "internal": true, "statusCode": 308, "regex": "^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$" }], "routes": { "static": [{ "page": "/", "regex": "^/(?:/)?$", "routeKeys": {}, "namedRegex": "^/(?:/)?$" }, { "page": "/_not-found", "regex": "^/_not\\-found(?:/)?$", "routeKeys": {}, "namedRegex": "^/_not\\-found(?:/)?$" }, { "page": "/admin", "regex": "^/admin(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin(?:/)?$" }, { "page": "/admin/analytics", "regex": "^/admin/analytics(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/analytics(?:/)?$" }, { "page": "/admin/artists", "regex": "^/admin/artists(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/artists(?:/)?$" }, { "page": "/admin/artists/new", "regex": "^/admin/artists/new(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/artists/new(?:/)?$" }, { "page": "/admin/calendar", "regex": "^/admin/calendar(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/calendar(?:/)?$" }, { "page": "/admin/portfolio", "regex": "^/admin/portfolio(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/portfolio(?:/)?$" }, { "page": "/admin/settings", "regex": "^/admin/settings(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/settings(?:/)?$" }, { "page": "/admin/uploads", "regex": "^/admin/uploads(?:/)?$", "routeKeys": {}, "namedRegex": "^/admin/uploads(?:/)?$" }, { "page": "/aftercare", "regex": "^/aftercare(?:/)?$", "routeKeys": {}, "namedRegex": "^/aftercare(?:/)?$" }, { "page": "/artist-dashboard", "regex": "^/artist\\-dashboard(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard(?:/)?$" }, { "page": "/artist-dashboard/portfolio", "regex": "^/artist\\-dashboard/portfolio(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard/portfolio(?:/)?$" }, { "page": "/artist-dashboard/profile", "regex": "^/artist\\-dashboard/profile(?:/)?$", "routeKeys": {}, "namedRegex": "^/artist\\-dashboard/profile(?:/)?$" }, { "page": "/artists", "regex": "^/artists(?:/)?$", "routeKeys": {}, "namedRegex": "^/artists(?:/)?$" }, { "page": "/auth/error", "regex": "^/auth/error(?:/)?$", "routeKeys": {}, "namedRegex": "^/auth/error(?:/)?$" }, { "page": "/auth/signin", "regex": "^/auth/signin(?:/)?$", "routeKeys": {}, "namedRegex": "^/auth/signin(?:/)?$" }, { "page": "/book", "regex": "^/book(?:/)?$", "routeKeys": {}, "namedRegex": "^/book(?:/)?$" }, { "page": "/contact", "regex": "^/contact(?:/)?$", "routeKeys": {}, "namedRegex": "^/contact(?:/)?$" }, { "page": "/deposit", "regex": "^/deposit(?:/)?$", "routeKeys": {}, "namedRegex": "^/deposit(?:/)?$" }, { "page": "/favicon.ico", "regex": "^/favicon\\.ico(?:/)?$", "routeKeys": {}, "namedRegex": "^/favicon\\.ico(?:/)?$" }, { "page": "/gift-cards", "regex": "^/gift\\-cards(?:/)?$", "routeKeys": {}, "namedRegex": "^/gift\\-cards(?:/)?$" }, { "page": "/privacy", "regex": "^/privacy(?:/)?$", "routeKeys": {}, "namedRegex": "^/privacy(?:/)?$" }, { "page": "/specials", "regex": "^/specials(?:/)?$", "routeKeys": {}, "namedRegex": "^/specials(?:/)?$" }, { "page": "/terms", "regex": "^/terms(?:/)?$", "routeKeys": {}, "namedRegex": "^/terms(?:/)?$" }], "dynamic": [{ "page": "/admin/artists/[id]", "regex": "^/admin/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/admin/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/api/artists/[id]", "regex": "^/api/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/api/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/api/auth/[...nextauth]", "regex": "^/api/auth/(.+?)(?:/)?$", "routeKeys": { "nxtPnextauth": "nxtPnextauth" }, "namedRegex": "^/api/auth/(?<nxtPnextauth>.+?)(?:/)?$" }, { "page": "/api/portfolio/[id]", "regex": "^/api/portfolio/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/api/portfolio/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/artists/[id]", "regex": "^/artists/([^/]+?)(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/artists/(?<nxtPid>[^/]+?)(?:/)?$" }, { "page": "/artists/[id]/book", "regex": "^/artists/([^/]+?)/book(?:/)?$", "routeKeys": { "nxtPid": "nxtPid" }, "namedRegex": "^/artists/(?<nxtPid>[^/]+?)/book(?:/)?$" }], "data": { "static": [], "dynamic": [] } }, "locales": [] };
var MiddlewareManifest = { "version": 3, "middleware": { "/": { "files": ["server/edge-runtime-webpack.js", "server/middleware.js"], "name": "middleware", "page": "/", "matchers": [{ "regexp": "^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/((?!_next\\/static|_next\\/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*))(.json)?[\\/#\\?]?$", "originalSource": "/((?!_next/static|_next/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*)" }], "wasm": [], "assets": [], "env": { "__NEXT_BUILD_ID": "SVr_7PUfBPR5HoMg6Gqfy", "NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "eqMtY6RQJg8ZzpGru9Ni8jGmRicvhYvppy45/3SECqU=", "__NEXT_PREVIEW_MODE_ID": "aa3e44cc5c2d8f61b9a7e308f9db0bf8", "__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "e63b6be95276873929b9ec08e113ea325ced41c2d494b0a69b62991e4c3688ab", "__NEXT_PREVIEW_MODE_SIGNING_KEY": "8aa982a30b271251dc2f1ffdd0eb252e3bc9e47f7d478e80f5dbb2abb1b39323" } } }, "functions": {}, "sortedMiddleware": ["/"] }; var MiddlewareManifest = { "version": 3, "middleware": { "/": { "files": ["server/edge-runtime-webpack.js", "server/middleware.js"], "name": "middleware", "page": "/", "matchers": [{ "regexp": "^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/((?!_next\\/static|_next\\/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*))(.json)?[\\/#\\?]?$", "originalSource": "/((?!_next/static|_next/image|favicon.ico|public|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$).*)" }], "wasm": [], "assets": [], "env": { "__NEXT_BUILD_ID": "YY7sC6MVxKHFhQ9os9EJ-", "NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "dIIe8uld0IZYSR75raX3hqcoXVKi4G5ZTC9ulh2RS/M=", "__NEXT_PREVIEW_MODE_ID": "55cfb8bce98f34386492e3e3013b3def", "__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "5b32ca192fc7429a1bb0ed5c67f7f91fe66c60e85c5bfb60804bb73c72f79e3c", "__NEXT_PREVIEW_MODE_SIGNING_KEY": "2de3a5f4686c5891b3e0b87bbf44a183fdd7bc9b2a7ef3a918a2772770dad5b4" } } }, "functions": {}, "sortedMiddleware": ["/"] };
var AppPathRoutesManifest = { "/_not-found/page": "/_not-found", "/aftercare/page": "/aftercare", "/api/admin/migrate/route": "/api/admin/migrate", "/api/auth/[...nextauth]/route": "/api/auth/[...nextauth]", "/artists/[id]/book/page": "/artists/[id]/book", "/artists/page": "/artists", "/auth/error/page": "/auth/error", "/book/page": "/book", "/artists/[id]/page": "/artists/[id]", "/deposit/page": "/deposit", "/contact/page": "/contact", "/auth/signin/page": "/auth/signin", "/favicon.ico/route": "/favicon.ico", "/gift-cards/page": "/gift-cards", "/page": "/", "/privacy/page": "/privacy", "/terms/page": "/terms", "/specials/page": "/specials", "/api/admin/stats/route": "/api/admin/stats", "/api/artists/[id]/route": "/api/artists/[id]", "/api/files/bulk-delete/route": "/api/files/bulk-delete", "/api/appointments/route": "/api/appointments", "/api/artists/me/route": "/api/artists/me", "/api/files/folder/route": "/api/files/folder", "/api/artists/route": "/api/artists", "/api/files/stats/route": "/api/files/stats", "/api/files/route": "/api/files", "/api/portfolio/route": "/api/portfolio", "/api/portfolio/bulk-delete/route": "/api/portfolio/bulk-delete", "/api/portfolio/stats/route": "/api/portfolio/stats", "/api/portfolio/[id]/route": "/api/portfolio/[id]", "/api/users/route": "/api/users", "/api/settings/route": "/api/settings", "/api/upload/route": "/api/upload", "/admin/artists/[id]/page": "/admin/artists/[id]", "/admin/artists/new/page": "/admin/artists/new", "/admin/artists/page": "/admin/artists", "/admin/calendar/page": "/admin/calendar", "/admin/page": "/admin", "/artist-dashboard/page": "/artist-dashboard", "/artist-dashboard/portfolio/page": "/artist-dashboard/portfolio", "/admin/uploads/page": "/admin/uploads", "/admin/settings/page": "/admin/settings", "/admin/portfolio/page": "/admin/portfolio", "/admin/analytics/page": "/admin/analytics", "/artist-dashboard/profile/page": "/artist-dashboard/profile" }; var AppPathRoutesManifest = { "/_not-found/page": "/_not-found", "/aftercare/page": "/aftercare", "/api/admin/migrate/route": "/api/admin/migrate", "/api/auth/[...nextauth]/route": "/api/auth/[...nextauth]", "/api/public/migrate/route": "/api/public/migrate", "/artists/[id]/book/page": "/artists/[id]/book", "/artists/[id]/page": "/artists/[id]", "/artists/page": "/artists", "/auth/error/page": "/auth/error", "/auth/signin/page": "/auth/signin", "/book/page": "/book", "/contact/page": "/contact", "/deposit/page": "/deposit", "/favicon.ico/route": "/favicon.ico", "/gift-cards/page": "/gift-cards", "/page": "/", "/privacy/page": "/privacy", "/specials/page": "/specials", "/terms/page": "/terms", "/api/admin/stats/route": "/api/admin/stats", "/api/artists/me/route": "/api/artists/me", "/api/artists/[id]/route": "/api/artists/[id]", "/api/files/bulk-delete/route": "/api/files/bulk-delete", "/api/files/folder/route": "/api/files/folder", "/api/artists/route": "/api/artists", "/api/files/route": "/api/files", "/api/appointments/route": "/api/appointments", "/api/portfolio/bulk-delete/route": "/api/portfolio/bulk-delete", "/api/files/stats/route": "/api/files/stats", "/api/portfolio/stats/route": "/api/portfolio/stats", "/api/portfolio/route": "/api/portfolio", "/api/portfolio/[id]/route": "/api/portfolio/[id]", "/api/settings/route": "/api/settings", "/api/upload/route": "/api/upload", "/api/users/route": "/api/users", "/admin/artists/[id]/page": "/admin/artists/[id]", "/admin/artists/new/page": "/admin/artists/new", "/admin/artists/page": "/admin/artists", "/admin/calendar/page": "/admin/calendar", "/admin/page": "/admin", "/artist-dashboard/page": "/artist-dashboard", "/artist-dashboard/portfolio/page": "/artist-dashboard/portfolio", "/artist-dashboard/profile/page": "/artist-dashboard/profile", "/admin/portfolio/page": "/admin/portfolio", "/admin/settings/page": "/admin/settings", "/admin/uploads/page": "/admin/uploads", "/admin/analytics/page": "/admin/analytics" };
var FunctionsConfigManifest = { "version": 1, "functions": { "/api/artists/[id]": {}, "/api/admin/stats": {}, "/api/artists/me": {}, "/api/files/bulk-delete": {}, "/api/files/folder": {}, "/api/artists": {}, "/api/files": {}, "/api/files/stats": {}, "/api/appointments": {}, "/api/portfolio/[id]": {}, "/api/portfolio/stats": {}, "/api/portfolio/bulk-delete": {}, "/api/portfolio": {}, "/api/settings": {}, "/api/users": {}, "/api/upload": {}, "/admin/portfolio": {}, "/admin/settings": {}, "/admin/uploads": {}, "/admin/analytics": {} } }; var FunctionsConfigManifest = { "version": 1, "functions": { "/api/artists/me": {}, "/api/artists/[id]": {}, "/api/admin/stats": {}, "/api/files/folder": {}, "/api/artists": {}, "/api/files/bulk-delete": {}, "/api/files/stats": {}, "/api/files": {}, "/api/appointments": {}, "/api/portfolio/[id]": {}, "/api/portfolio/bulk-delete": {}, "/api/portfolio/stats": {}, "/api/portfolio": {}, "/api/users": {}, "/api/upload": {}, "/admin/analytics": {}, "/admin/portfolio": {}, "/admin/settings": {}, "/admin/uploads": {}, "/api/settings": {} } };
var PagesManifest = { "/_app": "pages/_app.js", "/_error": "pages/_error.js", "/_document": "pages/_document.js" }; var PagesManifest = { "/_app": "pages/_app.js", "/_error": "pages/_error.js", "/_document": "pages/_document.js" };
process.env.NEXT_BUILD_ID = BuildId; process.env.NEXT_BUILD_ID = BuildId;

View File

@ -0,0 +1,119 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { GET } from '@/app/api/artists/route'
import { NextRequest } from 'next/server'
// Mock the database functions
vi.mock('@/lib/db', () => ({
getPublicArtists: vi.fn(),
}))
import { getPublicArtists } from '@/lib/db'
describe('GET /api/artists', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('should return artists successfully', async () => {
const mockArtists = [
{
id: '1',
slug: 'test-artist',
name: 'Test Artist',
bio: 'Test bio',
specialties: ['Traditional', 'Realism'],
instagramHandle: '@testartist',
portfolioImages: [],
isActive: true,
hourlyRate: 150,
},
]
vi.mocked(getPublicArtists).mockResolvedValue(mockArtists)
const request = new NextRequest('http://localhost:3000/api/artists')
const response = await GET(request)
const data = await response.json()
expect(response.status).toBe(200)
expect(data.artists).toHaveLength(1)
expect(data.artists[0].name).toBe('Test Artist')
})
it('should apply specialty filter', async () => {
const mockArtists = [
{
id: '1',
slug: 'traditional-artist',
name: 'Traditional Artist',
bio: 'Test bio',
specialties: ['Traditional'],
portfolioImages: [],
isActive: true,
},
]
vi.mocked(getPublicArtists).mockResolvedValue(mockArtists)
const request = new NextRequest('http://localhost:3000/api/artists?specialty=Traditional')
await GET(request)
expect(getPublicArtists).toHaveBeenCalledWith(
expect.objectContaining({
specialty: 'Traditional',
}),
undefined
)
})
it('should apply search filter', async () => {
vi.mocked(getPublicArtists).mockResolvedValue([])
const request = new NextRequest('http://localhost:3000/api/artists?search=John')
await GET(request)
expect(getPublicArtists).toHaveBeenCalledWith(
expect.objectContaining({
search: 'John',
}),
undefined
)
})
it('should apply pagination', async () => {
vi.mocked(getPublicArtists).mockResolvedValue([])
const request = new NextRequest('http://localhost:3000/api/artists?limit=10&page=2')
await GET(request)
expect(getPublicArtists).toHaveBeenCalledWith(
expect.objectContaining({
limit: 10,
offset: 10, // page 2 with limit 10 = offset 10
}),
undefined
)
})
it('should handle database errors gracefully', async () => {
vi.mocked(getPublicArtists).mockRejectedValue(new Error('Database error'))
const request = new NextRequest('http://localhost:3000/api/artists')
const response = await GET(request)
expect(response.status).toBe(500)
const data = await response.json()
expect(data).toHaveProperty('error')
})
it('should return empty array when no artists found', async () => {
vi.mocked(getPublicArtists).mockResolvedValue([])
const request = new NextRequest('http://localhost:3000/api/artists')
const response = await GET(request)
const data = await response.json()
expect(response.status).toBe(200)
expect(data.artists).toEqual([])
})
})

View File

@ -0,0 +1,202 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import { ArtistsGrid } from '@/components/artists-grid'
import '@testing-library/jest-dom'
// Mock the custom hook
vi.mock('@/hooks/use-artist-data', () => ({
useArtists: vi.fn(),
}))
import { useArtists } from '@/hooks/use-artist-data'
describe('ArtistsGrid Component', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('should display loading state', () => {
vi.mocked(useArtists).mockReturnValue({
data: undefined,
isLoading: true,
error: null,
} as any)
render(<ArtistsGrid />)
expect(screen.getByRole('status')).toBeInTheDocument()
})
it('should display artists when loaded', async () => {
const mockArtists = [
{
id: '1',
slug: 'test-artist',
name: 'Test Artist',
bio: 'Test bio',
specialties: ['Traditional', 'Realism'],
instagramHandle: '@testartist',
portfolioImages: [
{
id: '1',
artistId: '1',
url: 'https://example.com/image.jpg',
caption: 'Test image',
tags: ['Traditional'],
isPublic: true,
orderIndex: 0,
createdAt: new Date(),
},
],
isActive: true,
hourlyRate: 150,
},
]
vi.mocked(useArtists).mockReturnValue({
data: mockArtists,
isLoading: false,
error: null,
} as any)
render(<ArtistsGrid />)
await waitFor(() => {
expect(screen.getByText('Test Artist')).toBeInTheDocument()
})
expect(screen.getByText(/Traditional, Realism/i)).toBeInTheDocument()
expect(screen.getByText('Available')).toBeInTheDocument()
})
it('should display error state', () => {
vi.mocked(useArtists).mockReturnValue({
data: undefined,
isLoading: false,
error: new Error('Failed to fetch'),
} as any)
render(<ArtistsGrid />)
expect(screen.getByText(/Failed to load artists/i)).toBeInTheDocument()
expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument()
})
it('should display empty state when no artists match filter', async () => {
vi.mocked(useArtists).mockReturnValue({
data: [],
isLoading: false,
error: null,
} as any)
render(<ArtistsGrid />)
await waitFor(() => {
expect(screen.getByText(/No artists found/i)).toBeInTheDocument()
})
})
it('should display artist cards with portfolio images', async () => {
const mockArtists = [
{
id: '1',
slug: 'artist-one',
name: 'Artist One',
bio: 'Bio one',
specialties: ['Traditional'],
portfolioImages: [
{
id: '1',
artistId: '1',
url: 'https://example.com/img1.jpg',
tags: ['profile'],
isPublic: true,
orderIndex: 0,
createdAt: new Date(),
},
],
isActive: true,
hourlyRate: 100,
},
]
vi.mocked(useArtists).mockReturnValue({
data: mockArtists,
isLoading: false,
error: null,
} as any)
render(<ArtistsGrid />)
await waitFor(() => {
// Check for View Portfolio link
const portfolioLink = screen.getByRole('link', { name: /View Portfolio/i })
expect(portfolioLink).toHaveAttribute('href', '/artists/artist-one')
// Check for Book Now link
const bookLink = screen.getByRole('link', { name: /Book Now/i })
expect(bookLink).toHaveAttribute('href', '/book?artist=artist-one')
// Check for hourly rate display
expect(screen.getByText(/\$100\/hr/i)).toBeInTheDocument()
})
})
it('should display specialties as badges', async () => {
const mockArtists = [
{
id: '1',
slug: 'multi-specialty-artist',
name: 'Multi Specialty Artist',
bio: 'Expert in multiple styles',
specialties: ['Traditional', 'Realism', 'Fine Line', 'Japanese'],
portfolioImages: [],
isActive: true,
},
]
vi.mocked(useArtists).mockReturnValue({
data: mockArtists,
isLoading: false,
error: null,
} as any)
render(<ArtistsGrid />)
await waitFor(() => {
// Should show first 3 specialties
expect(screen.getByText('Traditional')).toBeInTheDocument()
expect(screen.getByText('Realism')).toBeInTheDocument()
expect(screen.getByText('Fine Line')).toBeInTheDocument()
// Should show "+1 more" badge for the 4th specialty
expect(screen.getByText('+1 more')).toBeInTheDocument()
})
})
it('should show inactive badge for inactive artists', async () => {
const mockArtists = [
{
id: '1',
slug: 'inactive-artist',
name: 'Inactive Artist',
bio: 'Currently unavailable',
specialties: ['Traditional'],
portfolioImages: [],
isActive: false,
},
]
vi.mocked(useArtists).mockReturnValue({
data: mockArtists,
isLoading: false,
error: null,
} as any)
render(<ArtistsGrid />)
await waitFor(() => {
expect(screen.getByText('Unavailable')).toBeInTheDocument()
})
})
})

269
__tests__/lib/db.test.ts Normal file
View File

@ -0,0 +1,269 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import {
getArtists,
getArtistWithPortfolio,
getPublicArtists,
getArtistBySlug,
updateArtist,
addPortfolioImage,
updatePortfolioImage,
deletePortfolioImage,
} from '@/lib/db'
// Mock D1 database
const createMockD1 = () => ({
prepare: vi.fn().mockReturnThis(),
bind: vi.fn().mockReturnThis(),
first: vi.fn(),
all: vi.fn(),
run: vi.fn(),
})
describe('Database Functions', () => {
let mockEnv: { DB: ReturnType<typeof createMockD1> }
beforeEach(() => {
mockEnv = {
DB: createMockD1(),
}
vi.clearAllMocks()
})
describe('getArtists', () => {
it('should fetch all artists and parse JSON fields', async () => {
const mockArtists = [
{
id: '1',
name: 'Test Artist',
bio: 'Test bio',
specialties: '["Traditional","Realism"]',
isActive: 1,
},
]
mockEnv.DB.all.mockResolvedValue({
results: mockArtists,
success: true,
})
const result = await getArtists(mockEnv)
expect(result).toHaveLength(1)
expect(result[0].specialties).toEqual(['Traditional', 'Realism'])
expect(result[0].isActive).toBe(true)
})
it('should handle empty results', async () => {
mockEnv.DB.all.mockResolvedValue({
results: [],
success: true,
})
const result = await getArtists(mockEnv)
expect(result).toEqual([])
})
it('should handle database errors', async () => {
mockEnv.DB.all.mockRejectedValue(new Error('Database error'))
await expect(getArtists(mockEnv)).rejects.toThrow('Database error')
})
})
describe('getArtistWithPortfolio', () => {
it('should fetch artist with portfolio images', async () => {
const mockArtist = {
id: '1',
name: 'Test Artist',
bio: 'Test bio',
specialties: '["Traditional"]',
isActive: 1,
}
const mockImages = [
{
id: '1',
artistId: '1',
url: 'https://example.com/image.jpg',
caption: 'Test image',
tags: '["Traditional","Portrait"]',
isPublic: 1,
orderIndex: 0,
},
]
mockEnv.DB.first.mockResolvedValueOnce(mockArtist)
mockEnv.DB.all.mockResolvedValueOnce({
results: mockImages,
success: true,
})
const result = await getArtistWithPortfolio('1', mockEnv)
expect(result).toBeDefined()
expect(result?.name).toBe('Test Artist')
expect(result?.portfolioImages).toHaveLength(1)
expect(result?.portfolioImages[0].tags).toEqual(['Traditional', 'Portrait'])
})
it('should return null for non-existent artist', async () => {
mockEnv.DB.first.mockResolvedValue(null)
const result = await getArtistWithPortfolio('999', mockEnv)
expect(result).toBeNull()
})
})
describe('getPublicArtists', () => {
it('should return only active artists with public images', async () => {
const mockArtists = [
{
id: '1',
name: 'Active Artist',
specialties: '["Traditional"]',
isActive: 1,
},
{
id: '2',
name: 'Inactive Artist',
specialties: '["Realism"]',
isActive: 0,
},
]
mockEnv.DB.all.mockResolvedValue({
results: mockArtists.filter(a => a.isActive),
success: true,
})
const result = await getPublicArtists({}, mockEnv)
expect(result).toHaveLength(1)
expect(result[0].name).toBe('Active Artist')
})
it('should filter by specialty', async () => {
const mockArtists = [
{
id: '1',
name: 'Traditional Artist',
specialties: '["Traditional"]',
isActive: 1,
},
]
mockEnv.DB.all.mockResolvedValue({
results: mockArtists,
success: true,
})
await getPublicArtists({ specialty: 'Traditional' }, mockEnv)
// Verify the bind was called (specialty filter applied)
expect(mockEnv.DB.bind).toHaveBeenCalled()
})
})
describe('getArtistBySlug', () => {
it('should fetch artist by slug', async () => {
const mockArtist = {
id: '1',
slug: 'test-artist',
name: 'Test Artist',
specialties: '["Traditional"]',
}
mockEnv.DB.first.mockResolvedValue(mockArtist)
mockEnv.DB.all.mockResolvedValue({
results: [],
success: true,
})
const result = await getArtistBySlug('test-artist', mockEnv)
expect(result).toBeDefined()
expect(result?.slug).toBe('test-artist')
expect(mockEnv.DB.bind).toHaveBeenCalledWith('test-artist')
})
})
describe('updateArtist', () => {
it('should update artist and stringify JSON fields', async () => {
const updateData = {
id: '1',
name: 'Updated Name',
bio: 'Updated bio',
specialties: ['Traditional', 'Realism'],
hourlyRate: 150,
}
mockEnv.DB.run.mockResolvedValue({
success: true,
meta: { changes: 1 },
})
await updateArtist('1', updateData, mockEnv)
// Verify the update was called
expect(mockEnv.DB.run).toHaveBeenCalled()
expect(mockEnv.DB.bind).toHaveBeenCalled()
})
})
describe('Portfolio Image Operations', () => {
it('should add portfolio image', async () => {
const imageData = {
url: 'https://example.com/image.jpg',
caption: 'Test caption',
tags: ['Traditional'],
isPublic: true,
orderIndex: 0,
}
mockEnv.DB.run.mockResolvedValue({
success: true,
meta: { last_row_id: 1 },
})
mockEnv.DB.first.mockResolvedValue({
id: '1',
...imageData,
artistId: '1',
tags: JSON.stringify(imageData.tags),
})
const result = await addPortfolioImage('1', imageData, mockEnv)
expect(result).toBeDefined()
expect(result.caption).toBe('Test caption')
})
it('should update portfolio image', async () => {
const updateData = {
caption: 'Updated caption',
tags: ['Traditional', 'Portrait'],
isPublic: false,
}
mockEnv.DB.run.mockResolvedValue({
success: true,
meta: { changes: 1 },
})
await updatePortfolioImage('1', updateData, mockEnv)
expect(mockEnv.DB.run).toHaveBeenCalled()
})
it('should delete portfolio image', async () => {
mockEnv.DB.run.mockResolvedValue({
success: true,
meta: { changes: 1 },
})
await deletePortfolioImage('1', mockEnv)
expect(mockEnv.DB.run).toHaveBeenCalled()
})
})
})

View File

@ -5,9 +5,14 @@ import { migrateArtistData, getMigrationStats, clearMigratedData } from '@/lib/d
export async function POST(request: NextRequest) { export async function POST(request: NextRequest) {
try { try {
// Check authentication and admin role // Check authentication and admin role (allow token bypass)
const token = request.headers.get('x-migrate-token') || new URL(request.url).searchParams.get('token')
const bypass = token && token === process.env.MIGRATE_TOKEN
const session = await getServerSession(authOptions) const session = await getServerSession(authOptions)
if (!session?.user || session.user.role !== 'SUPER_ADMIN') { const isAdmin = session?.user?.role === 'SUPER_ADMIN'
if (!bypass && !isAdmin) {
return NextResponse.json( return NextResponse.json(
{ error: 'Unauthorized. Admin access required.' }, { error: 'Unauthorized. Admin access required.' },
{ status: 401 } { status: 401 }
@ -53,9 +58,14 @@ export async function POST(request: NextRequest) {
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
try { try {
// Check authentication and admin role // Check authentication and admin role (allow token bypass)
const token = request.headers.get('x-migrate-token') || new URL(request.url).searchParams.get('token')
const bypass = token && token === process.env.MIGRATE_TOKEN
const session = await getServerSession(authOptions) const session = await getServerSession(authOptions)
if (!session?.user || session.user.role !== 'SUPER_ADMIN') { const isAdmin = session?.user?.role === 'SUPER_ADMIN'
if (!bypass && !isAdmin) {
return NextResponse.json( return NextResponse.json(
{ error: 'Unauthorized. Admin access required.' }, { error: 'Unauthorized. Admin access required.' },
{ status: 401 } { status: 401 }

View File

@ -0,0 +1,69 @@
import { NextRequest, NextResponse } from "next/server"
import { migrateArtistData, getMigrationStats } from "@/lib/data-migration"
// Public migration endpoint guarded by MIGRATE_TOKEN (bypasses next-auth + middleware auth)
export async function POST(request: NextRequest) {
const token =
request.headers.get("x-migrate-token") ||
new URL(request.url).searchParams.get("token")
// Require strict MIGRATE_TOKEN match
const MIGRATE_TOKEN = process.env.MIGRATE_TOKEN
if (!token || token !== MIGRATE_TOKEN) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 })
}
try {
await migrateArtistData()
const stats = await getMigrationStats()
return NextResponse.json(
{
success: true,
message: "Artist data migration completed successfully",
stats,
},
{ status: 200 }
)
} catch (error) {
console.error("Public migration error:", error)
return NextResponse.json(
{
error: "Migration failed",
details: error instanceof Error ? error.message : "Unknown error",
},
{ status: 500 }
)
}
}
export async function GET(request: NextRequest) {
const token =
request.headers.get("x-migrate-token") ||
new URL(request.url).searchParams.get("token")
// Require strict MIGRATE_TOKEN match
const MIGRATE_TOKEN = process.env.MIGRATE_TOKEN
if (!token || token !== MIGRATE_TOKEN) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 })
}
try {
const stats = await getMigrationStats()
return NextResponse.json(
{
success: true,
stats,
},
{ status: 200 }
)
} catch (error) {
console.error("Public migration stats error:", error)
return NextResponse.json(
{
error: "Failed to get migration stats",
details: error instanceof Error ? error.message : "Unknown error",
},
{ status: 500 }
)
}
}

View File

@ -1,16 +1,7 @@
import { artists } from '@/data/artists' import { artists } from '@/data/artists'
import type { CreateArtistInput } from '@/types/database' import type { CreateArtistInput } from '@/types/database'
import { getDB as getCloudflareDB } from '@/lib/db'
// Type for Cloudflare D1 database binding
interface Env {
DB: D1Database;
}
// Get the database instance from the environment
function getDB(): D1Database {
// @ts-ignore - This will be available in the Cloudflare Workers runtime
return globalThis.DB || (globalThis as any).env?.DB;
}
/** /**
* Migration utility to populate D1 database with existing artist data * Migration utility to populate D1 database with existing artist data
@ -19,7 +10,7 @@ export class DataMigrator {
private db: D1Database; private db: D1Database;
constructor() { constructor() {
this.db = getDB(); this.db = getCloudflareDB();
} }
/** /**

View File

@ -7,6 +7,14 @@ export default withAuth(
const token = req.nextauth.token const token = req.nextauth.token
const { pathname } = req.nextUrl const { pathname } = req.nextUrl
// Allow token-based bypass for admin migrate endpoint (non-interactive deployments)
const migrateToken = process.env.MIGRATE_TOKEN
const headerToken = req.headers.get("x-migrate-token")
const urlToken = req.nextUrl.searchParams.get("token")
const hasMigrateBypass =
pathname.startsWith("/api/admin/migrate") &&
((headerToken && headerToken === migrateToken) || (urlToken && urlToken === migrateToken))
// Admin routes protection // Admin routes protection
if (pathname.startsWith("/admin")) { if (pathname.startsWith("/admin")) {
if (!token) { if (!token) {
@ -46,6 +54,11 @@ export default withAuth(
// API routes protection // API routes protection
if (pathname.startsWith("/api/admin")) { if (pathname.startsWith("/api/admin")) {
// Bypass for migration endpoint with valid token (used for automated deploys)
if (hasMigrateBypass) {
return NextResponse.next()
}
if (!token) { if (!token) {
return NextResponse.json({ error: "Authentication required" }, { status: 401 }) return NextResponse.json({ error: "Authentication required" }, { status: 401 })
} }
@ -63,6 +76,17 @@ export default withAuth(
authorized: ({ token, req }) => { authorized: ({ token, req }) => {
const { pathname } = req.nextUrl const { pathname } = req.nextUrl
// Token-based bypass for migration endpoint (before auth checks)
const migrateToken = process.env.MIGRATE_TOKEN
const headerToken = req.headers.get("x-migrate-token")
const urlToken = req.nextUrl.searchParams.get("token")
if (
pathname.startsWith("/api/admin/migrate") &&
((headerToken && headerToken === migrateToken) || (urlToken && urlToken === migrateToken))
) {
return true
}
// Public routes that don't require authentication // Public routes that don't require authentication
const publicRoutes = [ const publicRoutes = [
"/", "/",

View File

@ -0,0 +1,10 @@
-- Add slug column to artists table for SEO-friendly URLs (migrated after initial schema)
-- Supersedes 0001_add_artist_slug.sql to ensure correct ordering
-- Add slug column
ALTER TABLE artists ADD COLUMN slug TEXT;
-- Create unique index on slug
CREATE UNIQUE INDEX IF NOT EXISTS idx_artists_slug ON artists(slug);
-- Note: Existing artists will need slugs populated via migration script

View File

@ -0,0 +1,138 @@
-- United Tattoo Studio Database Baseline Migration (UP)
-- Execute with wrangler:
-- Preview: wrangler d1 execute united-tattoo --file=sql/migrations_up/0001_initial.sql
-- Prod: wrangler d1 execute united-tattoo --remote --file=sql/migrations_up/0001_initial.sql
-- Users table
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
role TEXT NOT NULL CHECK (role IN ('SUPER_ADMIN', 'SHOP_ADMIN', 'ARTIST', 'CLIENT')),
avatar TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Artists table
CREATE TABLE IF NOT EXISTS artists (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
name TEXT NOT NULL,
bio TEXT NOT NULL,
specialties TEXT NOT NULL, -- JSON array as text
instagram_handle TEXT,
is_active BOOLEAN DEFAULT TRUE,
hourly_rate REAL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Portfolio images table
CREATE TABLE IF NOT EXISTS portfolio_images (
id TEXT PRIMARY KEY,
artist_id TEXT NOT NULL,
url TEXT NOT NULL,
caption TEXT,
tags TEXT, -- JSON array as text
order_index INTEGER DEFAULT 0,
is_public BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (artist_id) REFERENCES artists(id) ON DELETE CASCADE
);
-- Appointments table
CREATE TABLE IF NOT EXISTS appointments (
id TEXT PRIMARY KEY,
artist_id TEXT NOT NULL,
client_id TEXT NOT NULL,
title TEXT NOT NULL,
description TEXT,
start_time DATETIME NOT NULL,
end_time DATETIME NOT NULL,
status TEXT NOT NULL CHECK (status IN ('PENDING', 'CONFIRMED', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED')),
deposit_amount REAL,
total_amount REAL,
notes TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (artist_id) REFERENCES artists(id) ON DELETE CASCADE,
FOREIGN KEY (client_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Artist availability table
CREATE TABLE IF NOT EXISTS availability (
id TEXT PRIMARY KEY,
artist_id TEXT NOT NULL,
day_of_week INTEGER NOT NULL CHECK (day_of_week >= 0 AND day_of_week <= 6),
start_time TEXT NOT NULL, -- HH:mm format
end_time TEXT NOT NULL, -- HH:mm format
is_active BOOLEAN DEFAULT TRUE,
FOREIGN KEY (artist_id) REFERENCES artists(id) ON DELETE CASCADE
);
-- Site settings table
CREATE TABLE IF NOT EXISTS site_settings (
id TEXT PRIMARY KEY,
studio_name TEXT NOT NULL,
description TEXT NOT NULL,
address TEXT NOT NULL,
phone TEXT NOT NULL,
email TEXT NOT NULL,
social_media TEXT, -- JSON object as text
business_hours TEXT, -- JSON array as text
hero_image TEXT,
logo_url TEXT,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- File uploads table
CREATE TABLE IF NOT EXISTS file_uploads (
id TEXT PRIMARY KEY,
filename TEXT NOT NULL,
original_name TEXT NOT NULL,
mime_type TEXT NOT NULL,
size INTEGER NOT NULL,
url TEXT NOT NULL,
uploaded_by TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (uploaded_by) REFERENCES users(id) ON DELETE CASCADE
);
-- Create indexes for better performance
CREATE INDEX IF NOT EXISTS idx_artists_user_id ON artists(user_id);
CREATE INDEX IF NOT EXISTS idx_artists_is_active ON artists(is_active);
CREATE INDEX IF NOT EXISTS idx_portfolio_images_artist_id ON portfolio_images(artist_id);
CREATE INDEX IF NOT EXISTS idx_portfolio_images_is_public ON portfolio_images(is_public);
CREATE INDEX IF NOT EXISTS idx_appointments_artist_id ON appointments(artist_id);
CREATE INDEX IF NOT EXISTS idx_appointments_client_id ON appointments(client_id);
CREATE INDEX IF NOT EXISTS idx_appointments_start_time ON appointments(start_time);
CREATE INDEX IF NOT EXISTS idx_appointments_status ON appointments(status);
CREATE INDEX IF NOT EXISTS idx_availability_artist_id ON availability(artist_id);
CREATE INDEX IF NOT EXISTS idx_file_uploads_uploaded_by ON file_uploads(uploaded_by);
-- Insert default site settings
INSERT OR IGNORE INTO site_settings (
id,
studio_name,
description,
address,
phone,
email,
social_media,
business_hours,
hero_image,
logo_url
) VALUES (
'default',
'United Tattoo Studio',
'Premier tattoo studio specializing in custom artwork and professional tattooing services.',
'123 Main Street, Denver, CO 80202',
'+1 (555) 123-4567',
'info@unitedtattoo.com',
'{"instagram":"https://instagram.com/unitedtattoo","facebook":"https://facebook.com/unitedtattoo","twitter":"https://twitter.com/unitedtattoo","tiktok":"https://tiktok.com/@unitedtattoo"}',
'[{"dayOfWeek":1,"openTime":"10:00","closeTime":"20:00","isClosed":false},{"dayOfWeek":2,"openTime":"10:00","closeTime":"20:00","isClosed":false},{"dayOfWeek":3,"openTime":"10:00","closeTime":"20:00","isClosed":false},{"dayOfWeek":4,"openTime":"10:00","closeTime":"20:00","isClosed":false},{"dayOfWeek":5,"openTime":"10:00","closeTime":"22:00","isClosed":false},{"dayOfWeek":6,"openTime":"10:00","closeTime":"22:00","isClosed":false},{"dayOfWeek":0,"openTime":"12:00","closeTime":"18:00","isClosed":false}]',
'/united-studio-main.jpg',
'/united-logo-website.jpg'
);

View File

@ -0,0 +1,9 @@
-- Add slug column to artists table for SEO-friendly URLs (UP-only sequence)
-- Add slug column
ALTER TABLE artists ADD COLUMN slug TEXT;
-- Create unique index on slug
CREATE UNIQUE INDEX IF NOT EXISTS idx_artists_slug ON artists(slug);
-- Note: Existing artists will need slugs populated via migration script

View File

@ -1,8 +1,12 @@
name = "united-tattoo" name = "united-tattoo"
account_id = "5cee6a21cea282a9c89d5297964402e7"
compatibility_date = "2024-09-23" compatibility_date = "2024-09-23"
compatibility_flags = ["nodejs_compat"] compatibility_flags = ["nodejs_compat"]
main = ".open-next/worker.js" main = ".open-next/worker.js"
[vars]
MIGRATE_TOKEN = "ut_migrate_20251006_rotated_1a2b3c"
[assets] [assets]
directory = ".open-next/assets" directory = ".open-next/assets"
binding = "ASSETS" binding = "ASSETS"
@ -12,6 +16,7 @@ binding = "ASSETS"
binding = "DB" binding = "DB"
database_name = "united-tattoo" database_name = "united-tattoo"
database_id = "7191a4c4-e3b2-49c6-bd8d-9cc3394977ec" database_id = "7191a4c4-e3b2-49c6-bd8d-9cc3394977ec"
migrations_dir = "sql/migrations_up"
# R2 bucket binding # R2 bucket binding
[[r2_buckets]] [[r2_buckets]]
@ -31,11 +36,13 @@ service = "united-tattoo"
[env.production.vars] [env.production.vars]
NEXTAUTH_URL = "https://united-tattoos.com" NEXTAUTH_URL = "https://united-tattoos.com"
NODE_ENV = "production" NODE_ENV = "production"
MIGRATE_TOKEN = "ut_migrate_20251006_rotated_1a2b3c"
# Environment variables for preview # Environment variables for preview
[env.preview.vars] [env.preview.vars]
NEXTAUTH_URL = "https://united-tattoos.com" NEXTAUTH_URL = "https://united-tattoos.com"
NODE_ENV = "production" NODE_ENV = "production"
MIGRATE_TOKEN = "ut_migrate_20251006_rotated_1a2b3c"
[dev] [dev]
ip = "0.0.0.0" ip = "0.0.0.0"