This commit is contained in:
Marco Pedone 2025-10-28 10:54:42 +01:00
parent 208deeac28
commit b83527eb97
17 changed files with 29 additions and 992 deletions

View file

@ -1,13 +0,0 @@
console.log(
"\x1b[34m%s\x1b[0m",
`
____ _______ __ _ _ _____ _____ ____ ____
| _ \\| ____\\ \\ / / | | | |_ _|_ _| _ \\/ ___|
| | | | _| \\ \\ / / | |_| | | | | | | |_) \\___ \\
| |_| | |___ \\ V / | _ | | | | | | __/ ___) |
|____/|_____| \\_/ |_| |_| |_| |_| |_| |____/
🩺 Running Development...
`,
);

View file

@ -1,13 +0,0 @@
console.log(
"\x1b[32m%s\x1b[0m",
`
____ _______ __
| _ \\| ____\\ \\ / /
| | | | _| \\ \\ / /
| |_| | |___ \\ V /
|____/|_____| \\_/
🩺 Running Development...
`,
);

View file

@ -1,13 +0,0 @@
console.log(
"\x1b[33m%s\x1b[0m",
`
_ _ _
| | (_) | |
| | _ _ __ | |_
| | | | '_ \\| __|
| |____| | | | | |_
\\_____/|_|_| |_|\\__|
🔍 Linting ...
`,
);

View file

@ -1,13 +0,0 @@
console.log(
"\x1b[36m%s\x1b[0m",
`
____ ____ _____
| _ \\ / ___| |_ _| _ _ __ ___ __ _ ___ _ __
| |_) | | _ | || | | | \'_ \\ / _ \\/ _\` |/ _ \\ \'_ \\
| __/| |_| | | || |_| | |_) | __/ (_| | __/ | | |
|_| \\____| |_| \\__, | .__/ \\___|\\__, |\\___|_| |_|
|___/|_| |___/
📢 Importing Postgres schema...
`,
);

View file

@ -1,13 +0,0 @@
console.log(
"\x1b[31m%s\x1b[0m",
`
_____ ____ _ _
|_ _| _ _ __ ___ / ___| |__ ___ ___| | __
| || | | | \'_ \\ / _ \\ | | | \'_ \\ / _ \\/ __| |/ /
| || |_| | |_) | __/ | |___| | | | __/ (__| <
|_| \\__, | .__/ \\___| \\____|_| |_|\\___|\\___|_|\\_\\
|___/|_|
🌶 Typescript type check...
`,
);

View file

@ -18,6 +18,7 @@
],
"ignoreBinaries": ["stripe"],
"ignoreDependencies": [
"pdfjs-dist",
"kysely-plugin-serialize",
"sharp",
"uuid",
@ -34,7 +35,9 @@
"@radix-ui/react-label",
"@radix-ui/react-slot",
"@radix-ui/react-tooltip",
"@radix-ui/react-popover"
"@radix-ui/react-popover",
"@radix-ui/react-toggle-group",
"tailwindcss"
],
"project": ["src/**", "**", "!src/schemas/public/*.ts", "!emails/**"]
}

View file

@ -13,7 +13,6 @@
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-popover": "^1.1.14",
"@radix-ui/react-scroll-area": "^1.2.9",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-toggle-group": "^1.1.10",
"@radix-ui/react-tooltip": "^1.2.8",
@ -38,7 +37,6 @@
"@trpc/next": "^11.4.3",
"@trpc/react-query": "^11.1.0",
"@trpc/server": "^11.1.0",
"@vercel/og": "^0.8.5",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
@ -90,7 +88,6 @@
"type-fest": "^4.41.0",
"uuid": "^11.1.0",
"vaul": "^1.1.2",
"yaml": "^2.8.1",
"zod": "^4.1.12"
},
"devDependencies": {
@ -7168,15 +7165,6 @@
"integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==",
"license": "MIT"
},
"node_modules/@resvg/resvg-wasm": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@resvg/resvg-wasm/-/resvg-wasm-2.4.0.tgz",
"integrity": "sha512-C7c51Nn4yTxXFKvgh2txJFNweaVcfUPQxwEUFw4aWsCmfiBDJsTSwviIF8EcwjQ6k8bPyMWCl1vw4BdxE569Cg==",
"license": "MPL-2.0",
"engines": {
"node": ">= 10"
}
},
"node_modules/@selderee/plugin-htmlparser2": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz",
@ -7190,22 +7178,6 @@
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/@shuding/opentype.js": {
"version": "1.4.0-beta.0",
"resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz",
"integrity": "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==",
"license": "MIT",
"dependencies": {
"fflate": "^0.7.3",
"string.prototype.codepointat": "^0.2.1"
},
"bin": {
"ot": "bin/ot"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/@smithy/abort-controller": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.5.tgz",
@ -9162,19 +9134,6 @@
"webpack": "^5"
}
},
"node_modules/@vercel/og": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/@vercel/og/-/og-0.8.5.tgz",
"integrity": "sha512-fHqnxfBYcwkamlEgcIzaZqL8IHT09hR7FZL7UdMTdGJyoaBzM/dY6ulO5Swi4ig30FrBJI9I2C+GLV9sb9vexA==",
"license": "MPL-2.0",
"dependencies": {
"@resvg/resvg-wasm": "2.4.0",
"satori": "0.16.0"
},
"engines": {
"node": ">=16"
}
},
"node_modules/@webassemblyjs/ast": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
@ -9887,15 +9846,6 @@
"node": ">= 6"
}
},
"node_modules/camelize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001735",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001735.tgz",
@ -10308,36 +10258,6 @@
"node": ">= 8"
}
},
"node_modules/css-background-parser": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz",
"integrity": "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==",
"license": "MIT"
},
"node_modules/css-box-shadow": {
"version": "1.0.0-3",
"resolved": "https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz",
"integrity": "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==",
"license": "MIT"
},
"node_modules/css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
"license": "ISC",
"engines": {
"node": ">=4"
}
},
"node_modules/css-gradient-parser": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/css-gradient-parser/-/css-gradient-parser-0.0.16.tgz",
"integrity": "sha512-3O5QdqgFRUbXvK1x5INf1YkBz1UKSWqrd63vWsum8MNHDBYD5urm3QtxZbKU259OrEXNM26lP/MPY3d1IGkBgA==",
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"node_modules/css-in-js-utils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz",
@ -10364,17 +10284,6 @@
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
"license": "MIT",
"dependencies": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"node_modules/css-tree": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
@ -10907,15 +10816,6 @@
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"license": "MIT"
},
"node_modules/emoji-regex-xs": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-2.0.1.tgz",
"integrity": "sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/engine.io": {
"version": "6.6.4",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
@ -11235,12 +11135,6 @@
"node": ">=6"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@ -11459,12 +11353,6 @@
"walk-up-path": "^4.0.0"
}
},
"node_modules/fflate": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
"integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==",
"license": "MIT"
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@ -11988,18 +11876,6 @@
"he": "bin/he"
}
},
"node_modules/hex-rgb": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz",
"integrity": "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==",
"license": "MIT",
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -13328,25 +13204,6 @@
"node": ">=10"
}
},
"node_modules/linebreak": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz",
"integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==",
"license": "MIT",
"dependencies": {
"base64-js": "0.0.8",
"unicode-trie": "^2.0.0"
}
},
"node_modules/linebreak/node_modules/base64-js": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
"integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
@ -14622,12 +14479,6 @@
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"license": "BlueOak-1.0.0"
},
"node_modules/pako": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
"integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==",
"license": "MIT"
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -14640,16 +14491,6 @@
"node": ">=6"
}
},
"node_modules/parse-css-color": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/parse-css-color/-/parse-css-color-0.2.1.tgz",
"integrity": "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==",
"license": "MIT",
"dependencies": {
"color-name": "^1.1.4",
"hex-rgb": "^4.1.0"
}
},
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@ -15038,6 +14879,7 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true,
"license": "MIT"
},
"node_modules/postgres-array": {
@ -16692,28 +16534,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/satori": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/satori/-/satori-0.16.0.tgz",
"integrity": "sha512-ZvHN3ygzZ8FuxjSNB+mKBiF/NIoqHzlBGbD0MJiT+MvSsFOvotnWOhdTjxKzhHRT2wPC1QbhLzx2q/Y83VhfYQ==",
"license": "MPL-2.0",
"dependencies": {
"@shuding/opentype.js": "1.4.0-beta.0",
"css-background-parser": "^0.1.0",
"css-box-shadow": "1.0.0-3",
"css-gradient-parser": "^0.0.16",
"css-to-react-native": "^3.0.0",
"emoji-regex-xs": "^2.0.1",
"escape-html": "^1.0.3",
"linebreak": "^1.1.0",
"parse-css-color": "^0.2.1",
"postcss-value-parser": "^4.2.0",
"yoga-layout": "^3.2.1"
},
"engines": {
"node": ">=16"
}
},
"node_modules/scheduler": {
"version": "0.26.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
@ -17463,12 +17283,6 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/string.prototype.codepointat": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
"license": "MIT"
},
"node_modules/string.prototype.padend": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz",
@ -17986,12 +17800,6 @@
"node": ">=8"
}
},
"node_modules/tiny-inflate": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
"integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
"license": "MIT"
},
"node_modules/tiny-invariant": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
@ -18198,16 +18006,6 @@
"integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
"license": "MIT"
},
"node_modules/unicode-trie": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz",
"integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==",
"license": "MIT",
"dependencies": {
"pako": "^0.2.5",
"tiny-inflate": "^1.0.0"
}
},
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
@ -18797,6 +18595,7 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
"integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
"dev": true,
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
@ -18817,12 +18616,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/yoga-layout": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz",
"integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==",
"license": "MIT"
},
"node_modules/zod": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",

View file

@ -4,18 +4,17 @@
"scripts": {
"build": "next build",
"d": "npm run-p dev stripe-dev -cl",
"dev": "node ./headers/dev.js && next dev --turbopack",
"dev-https": "node ./headers/dev-https.js && cross-env NEXT_PUBLIC_BASE_URL='https://localhost:3000' INTERNAL_BASE_URL='https://localhost:3000' next dev --experimental-https --turbopack",
"dev": "next dev --turbopack",
"dev-https": "cross-env NEXT_PUBLIC_BASE_URL='https://localhost:3000' INTERNAL_BASE_URL='https://localhost:3000' next dev --experimental-https --turbopack",
"email": "cross-env NEXT_PUBLIC_BASE_URL='https://localhost:3000' email dev --port 3500",
"idev": "cross-env NODE_OPTIONS='--inspect' next dev --turbopack",
"knip": "knip --no-exit-code",
"lint": "node ./headers/lint.js && biome lint",
"pg-typegen": "node ./headers/pg-typegen.js && npx kanel",
"knip": "knip --no-exit-code --no-config-hints",
"lint": "biome lint",
"pg-typegen": "npx kanel",
"start": "next start",
"stripe-dev": "stripe listen --forward-to https://localhost:3000/api/stripe-webhook",
"test": "npm run lint && npm run types",
"test-kr": "node ./kyselyRules/rules/select.test.js && node ./kyselyRules/rules/where.test.js&& node ./kyselyRules/rules/null.test.js",
"types": "node ./headers/type.js && tsc --noEmit"
"types": "tsc --noEmit"
},
"version": "0.1.0",
"dependencies": {
@ -24,7 +23,6 @@
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-popover": "^1.1.14",
"@radix-ui/react-scroll-area": "^1.2.9",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-toggle-group": "^1.1.10",
"@radix-ui/react-tooltip": "^1.2.8",
@ -49,7 +47,6 @@
"@trpc/next": "^11.4.3",
"@trpc/react-query": "^11.1.0",
"@trpc/server": "^11.1.0",
"@vercel/og": "^0.8.5",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
@ -101,7 +98,6 @@
"type-fest": "^4.41.0",
"uuid": "^11.1.0",
"vaul": "^1.1.2",
"yaml": "^2.8.1",
"zod": "^4.1.12"
},
"devDependencies": {

View file

@ -103,7 +103,7 @@ export const AcquistoProcessing = ({
);
};
export const PricePreparation = ({
const PricePreparation = ({
packId,
onProcedi,
}: {

View file

@ -111,11 +111,7 @@ const ServizioInteraction = ({
return <InteressatoButton annuncioId={annuncioId} />;
};
export const InteressatoButton = ({
annuncioId,
}: {
annuncioId: AnnunciId;
}) => {
const InteressatoButton = ({ annuncioId }: { annuncioId: AnnunciId }) => {
const { data: hasInterest, isLoading } =
api.intrests.hasUserInterest.useQuery({
annuncioId,

View file

@ -1363,7 +1363,7 @@ interface FileUploadClearProps extends React.ComponentProps<"button"> {
asChild?: boolean;
}
function FileUploadClear(props: FileUploadClearProps) {
function _FileUploadClear(props: FileUploadClearProps) {
const {
asChild,
forceMount,
@ -1418,20 +1418,20 @@ export {
FileUploadItemMetadata,
FileUploadItemProgress,
FileUploadItemDelete,
FileUploadClear,
//FileUploadClear,
//
FileUploadRoot as Root,
FileUploadDropzone as Dropzone,
FileUploadTrigger as Trigger,
FileUploadList as List,
FileUploadItem as Item,
FileUploadItemPreview as ItemPreview,
FileUploadItemMetadata as ItemMetadata,
FileUploadItemProgress as ItemProgress,
FileUploadItemDelete as ItemDelete,
FileUploadClear as Clear,
//FileUploadRoot as Root,
//FileUploadDropzone as Dropzone,
//FileUploadTrigger as Trigger,
//FileUploadList as List,
//FileUploadItem as Item,
// FileUploadItemPreview as ItemPreview,
// FileUploadItemMetadata as ItemMetadata,
// FileUploadItemProgress as ItemProgress,
// FileUploadItemDelete as ItemDelete,
//FileUploadClear as Clear,
//
useStore as useFileUpload,
//useStore as useFileUpload,
//
type FileUploadRootProps as FileUploadProps,
//type FileUploadRootProps as FileUploadProps,
};

View file

@ -1,352 +0,0 @@
"use client";
import { CheckIcon, ChevronsUpDownIcon, XIcon } from "lucide-react";
import {
type ComponentPropsWithoutRef,
createContext,
type ReactNode,
useCallback,
useContext,
useEffect,
useLayoutEffect,
useRef,
useState,
} from "react";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "~/components/ui/command";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import { cn } from "~/lib/utils";
type MultiSelectContextType = {
open: boolean;
setOpen: (open: boolean) => void;
selectedValues: Set<string>;
toggleValue: (value: string) => void;
items: Map<string, ReactNode>;
onItemAdded: (value: string, label: ReactNode) => void;
};
const MultiSelectContext = createContext<MultiSelectContextType | null>(null);
export function MultiSelect({
children,
values,
defaultValues,
onValuesChange,
}: {
children: ReactNode;
values?: string[];
defaultValues?: string[];
onValuesChange?: (values: string[]) => void;
}) {
const [open, setOpen] = useState(false);
const [selectedValues, setSelectedValues] = useState(
new Set<string>(values ?? defaultValues),
);
const [items, setItems] = useState<Map<string, ReactNode>>(new Map());
function toggleValue(value: string) {
const getNewSet = (prev: Set<string>) => {
const newSet = new Set(prev);
if (newSet.has(value)) {
newSet.delete(value);
} else {
newSet.add(value);
}
return newSet;
};
setSelectedValues(getNewSet);
onValuesChange?.([...getNewSet(selectedValues)]);
}
const onItemAdded = useCallback((value: string, label: ReactNode) => {
setItems((prev) => {
if (prev.get(value) === label) return prev;
return new Map(prev).set(value, label);
});
}, []);
return (
<MultiSelectContext
value={{
items,
onItemAdded,
open,
selectedValues: values ? new Set(values) : selectedValues,
setOpen,
toggleValue,
}}
>
<Popover onOpenChange={setOpen} open={open}>
{children}
</Popover>
</MultiSelectContext>
);
}
export function MultiSelectTrigger({
className,
children,
...props
}: {
className?: string;
children?: ReactNode;
} & ComponentPropsWithoutRef<typeof Button>) {
const { open } = useMultiSelectContext();
return (
<PopoverTrigger asChild>
<Button
{...props}
aria-expanded={props["aria-expanded"] ?? open}
className={cn(
"flex h-auto min-h-9 w-fit items-center justify-between gap-2 overflow-hidden whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-1.5 text-sm shadow-xs outline-hidden transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground dark:bg-input/30 dark:aria-invalid:ring-destructive/40 dark:hover:bg-input/50 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0",
className,
)}
role={props.role ?? "combobox"}
variant={props.variant ?? "outline"}
>
{children}
<ChevronsUpDownIcon className="size-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
);
}
export function MultiSelectValue({
placeholder,
clickToRemove = true,
className,
overflowBehavior = "wrap-when-open",
...props
}: {
placeholder?: string;
clickToRemove?: boolean;
overflowBehavior?: "wrap" | "wrap-when-open" | "cutoff";
} & Omit<ComponentPropsWithoutRef<"div">, "children">) {
const { selectedValues, toggleValue, items, open } = useMultiSelectContext();
const [overflowAmount, setOverflowAmount] = useState(0);
const valueRef = useRef<HTMLDivElement>(null);
const overflowRef = useRef<HTMLDivElement>(null);
const itemsRef = useRef<Set<HTMLElement>>(new Set());
const shouldWrap =
overflowBehavior === "wrap" ||
(overflowBehavior === "wrap-when-open" && open);
useEffect(() => {
if (!shouldWrap) return;
itemsRef.current.forEach((child) => child.style.removeProperty("display"));
}, [shouldWrap]);
const checkOverflow = useCallback(() => {
if (valueRef.current == null) return;
const containerElement = valueRef.current;
const overflowElement = overflowRef.current;
if (overflowElement != null) overflowElement.style.display = "none";
itemsRef.current.forEach((child) => child.style.removeProperty("display"));
let amount = 0;
for (let i = itemsRef.current.size - 1; i >= 0; i--) {
const child = [...itemsRef.current][i];
if (
containerElement.scrollWidth <= containerElement.clientWidth ||
!child
) {
break;
}
amount = itemsRef.current.size - i;
child.style.display = "none";
overflowElement?.style.removeProperty("display");
}
setOverflowAmount(amount);
}, []);
useEffect(() => {
if (valueRef.current == null) return;
const observer = new ResizeObserver(checkOverflow);
observer.observe(valueRef.current);
return () => observer.disconnect();
}, [checkOverflow]);
useLayoutEffect(() => {
checkOverflow();
}, [selectedValues, checkOverflow]);
if (selectedValues.size === 0 && placeholder) {
return (
<span className="font-normal text-muted-foreground">{placeholder}</span>
);
}
return (
<div
{...props}
className={cn(
"flex w-full gap-1.5 overflow-hidden",
shouldWrap && "h-full flex-wrap",
className,
)}
ref={valueRef}
>
{[...selectedValues]
.filter((value) => items.has(value))
.map((value) => (
<Badge
className="group flex items-center gap-1"
key={value}
onClick={
clickToRemove
? (e) => {
e.stopPropagation();
toggleValue(value);
}
: undefined
}
ref={(el) => {
if (el == null) return;
itemsRef.current.add(el);
return () => {
itemsRef.current.delete(el);
};
}}
variant="outline"
>
{items.get(value)}
{clickToRemove && (
<XIcon className="size-2 text-muted-foreground group-hover:text-destructive" />
)}
</Badge>
))}
<Badge
ref={overflowRef}
style={{
display: overflowAmount > 0 && !shouldWrap ? "block" : "none",
}}
variant="outline"
>
+{overflowAmount}
</Badge>
</div>
);
}
export function MultiSelectContent({
search = true,
children,
...props
}: {
search?: boolean | { placeholder?: string; emptyMessage?: string };
children: ReactNode;
} & Omit<ComponentPropsWithoutRef<typeof Command>, "children">) {
const canSearch = typeof search === "object" ? true : search;
return (
<>
<div style={{ display: "none" }}>
<Command>
<CommandList>{children}</CommandList>
</Command>
</div>
<PopoverContent className="min-w-[var(--radix-popover-trigger-width)] p-0">
<Command {...props}>
{canSearch ? (
<CommandInput
placeholder={
typeof search === "object" ? search.placeholder : undefined
}
/>
) : (
// biome-ignore lint/a11y/noAriaHiddenOnFocusable: <intended>
<button
aria-hidden="true"
autoFocus
className="sr-only"
type="button"
/>
)}
<CommandList>
{canSearch && (
<CommandEmpty>
{typeof search === "object" ? search.emptyMessage : undefined}
</CommandEmpty>
)}
{children}
</CommandList>
</Command>
</PopoverContent>
</>
);
}
export function MultiSelectItem({
value,
children,
badgeLabel,
onSelect,
...props
}: {
badgeLabel?: ReactNode;
value: string;
} & Omit<ComponentPropsWithoutRef<typeof CommandItem>, "value">) {
const { toggleValue, selectedValues, onItemAdded } = useMultiSelectContext();
const isSelected = selectedValues.has(value);
useEffect(() => {
onItemAdded(value, badgeLabel ?? children);
}, [value, children, onItemAdded, badgeLabel]);
return (
<CommandItem
{...props}
onSelect={(v) => {
toggleValue(v);
onSelect?.(v);
}}
value={value}
>
<CheckIcon
className={cn("mr-2 size-4", isSelected ? "opacity-100" : "opacity-0")}
/>
{children}
</CommandItem>
);
}
export function MultiSelectGroup(
props: ComponentPropsWithoutRef<typeof CommandGroup>,
) {
return <CommandGroup {...props} />;
}
export function MultiSelectSeparator(
props: ComponentPropsWithoutRef<typeof CommandSeparator>,
) {
return <CommandSeparator {...props} />;
}
function useMultiSelectContext() {
const context = useContext(MultiSelectContext);
if (context == null) {
throw new Error(
"useMultiSelectContext must be used within a MultiSelectContext",
);
}
return context;
}

View file

@ -11,7 +11,7 @@ type UploadResponse =
error: string;
};
// Helper to handle file uploads
export async function uploadFile(
async function uploadFile(
file: File,
expiresAt: string | undefined,
): Promise<UploadResponse> {

View file

@ -1,296 +0,0 @@
export const ita = {
customErrors: {
azienda_o_pf: "Seleziona un'opzione",
codice_fiscale: "Codice fiscale non valido",
data_nascita: "Data di nascita non valida",
nazione: "Seleziona una nazione",
provincia: "Seleziona una provincia",
tipologia: "Seleziona una tipologia",
},
errors: {
custom: "Input non valido",
invalid_arguments: "Argomenti della funzione non validi",
invalid_date: "Data non valida",
invalid_enum_value:
"Valore dell'enum non valido. Atteso {{- options}}, ricevuto '{{received}}'",
invalid_intersection_types:
"Il risultato dell'intersezione non può essere unito",
invalid_literal: "Valore literal non valido, atteso {{expected}}",
invalid_return_type: "Tipo di ritorno della funzione non valido",
invalid_string: {
cuid: "{{validation}} non valido",
datetime: "{{validation}} non valido",
email: "{{validation}} non valida",
endsWith: 'Input non valido: deve finire con "{{endsWith}}"',
regex: "Non valida",
startsWith: 'Input non valido: deve iniziare con "{{startsWith}}"',
url: "{{validation}} non valido",
uuid: "{{validation}} non valido",
},
invalid_type: "Atteso {{expected}}, ricevuto {{received}}",
invalid_type_received_undefined: "Obbligatorio",
invalid_union: "Input non valido",
invalid_union_discriminator:
"Valore discriminante non valido. Atteso {{- options}}",
not_finite: "Il numero deve essere finito",
not_multiple_of: "Il numero deve essere un multiplo di {{multipleOf}}",
too_big: {
array: {
exact: "L'array deve contenere esattamente {{maximum}} elementi",
inclusive: "L'array deve contenere al massimo {{maximum}} elementi",
not_inclusive: "L'array deve contenere meno di {{maximum}} elementi",
},
date: {
exact: "La data deve essere esattamente {{- maximum, datetime}}",
inclusive:
"La data deve essere minore di o uguale a {{- maximum, datetime}}",
not_inclusive: "La data deve essere minore di {{- maximum, datetime}}",
},
number: {
exact: "Il numero deve essere esattamente {{maximum}}",
inclusive: "Il numero deve essere minore di o uguale a {{maximum}}",
not_inclusive: "Il numero deve essere minore di {{maximum}}",
},
set: {
exact: "Input non valido",
inclusive: "Input non valido",
not_inclusive: "Input non valido",
},
string: {
exact: "La stringa deve contenere esattamente {{maximum}} caratteri",
inclusive: "La stringa deve contenere al massimo {{maximum}} caratteri",
not_inclusive:
"La stringa deve contenere meno di {{maximum}} caratteri",
},
},
too_small: {
array: {
exact: "L'array deve contenere esattamente {{minimum}} elementi",
inclusive: "L'array deve contenere almeno {{minimum}} elementi",
not_inclusive: "L'array deve contenere più di {{minimum}} elementi",
},
date: {
exact: "La data deve essere esattamente {{- minimum, datetime}}",
inclusive:
"La data deve essere maggiore di o uguale a {{- minimum, datetime}}",
not_inclusive: "La data deve essere maggiore {{- minimum, datetime}}",
},
number: {
exact: "Il numero deve essere esattamente {{minimum}}",
inclusive: "Il numero deve essere maggiore o uguale a {{minimum}}",
not_inclusive: "Il numero deve essere maggiore di {{minimum}}",
},
set: {
exact: "Input non valido",
inclusive: "Input non valido",
not_inclusive: "Input non valido",
},
string: {
exact: "La stringa deve contenere esattamente {{minimum}} caratteri",
//inclusive: "La stringa deve contenere almeno {{minimum}} caratteri",
inclusive: "Il campo non può essere vuoto",
not_inclusive: "La stringa deve contenere più di {{minimum}} caratteri",
},
},
unrecognized_keys: "Campo/i non riconosciuto nell'oggetto: {{- keys}}",
},
local_types: {
array: "lista",
bigint: "numero",
boolean: "si/no",
date: "data",
float: "numero",
function: "funzione",
integer: "numero",
map: "mappa",
nan: "vuoto",
never: "mai",
null: "vuoto",
number: "numero",
object: "oggetto",
promise: "promessa",
set: "lista",
string: "testo",
symbol: "simbolo",
undefined: "indefinito",
unknown: "sconosciuto",
void: "vuoto",
},
types: {
array: "array",
bigint: "bigint",
boolean: "boolean",
date: "date",
float: "float",
function: "function",
integer: "integer",
map: "map",
nan: "nan",
never: "never",
null: "null",
number: "number",
object: "object",
promise: "promise",
set: "set",
string: "string",
symbol: "symbol",
undefined: "undefined",
unknown: "unknown",
void: "void",
},
validations: {
cuid: "cuid",
datetime: "datetime",
email: "email",
regex: "regex",
url: "url",
uuid: "uuid",
},
};
export const eng = {
customErrors: {
azienda_o_pf: "Select an option",
codice_fiscale: "Tax code not valid",
data_nascita: "Select a date",
nazione: "Select a nation",
provincia: "Select a province",
tipologia: "Select a type",
},
errors: {
custom: "Invalid input",
invalid_arguments: "Invalid function arguments",
invalid_date: "Invalid date",
invalid_enum_value:
"Invalid enum value. Expected {{- options}}, received '{{received}}'",
invalid_intersection_types: "Intersection results could not be merged",
invalid_literal: "Invalid literal value, expected {{expected}}",
invalid_return_type: "Invalid function return type",
invalid_string: {
cuid: "Invalid {{validation}}",
datetime: "Invalid {{validation}}",
email: "Invalid {{validation}}",
endsWith: 'Invalid input: must end with "{{endsWith}}"',
regex: "Invalid",
startsWith: 'Invalid input: must start with "{{startsWith}}"',
url: "Invalid {{validation}}",
uuid: "Invalid {{validation}}",
},
invalid_type: "Expected {{expected}}, received {{received}}",
invalid_type_received_undefined: "Required",
invalid_union: "Invalid input",
invalid_union_discriminator:
"Invalid discriminator value. Expected {{- options}}",
not_finite: "Number must be finite",
not_multiple_of: "Number must be a multiple of {{multipleOf}}",
too_big: {
array: {
exact: "Array must contain exactly {{maximum}} element(s)",
inclusive: "Array must contain at most {{maximum}} element(s)",
not_inclusive: "Array must contain less than {{maximum}} element(s)",
},
date: {
exact: "Date must be exactly {{- maximum, datetime}}",
inclusive:
"Date must be smaller than or equal to {{- maximum, datetime}}",
not_inclusive: "Date must be smaller than {{- maximum, datetime}}",
},
number: {
exact: "Number must be exactly {{maximum}}",
inclusive: "Number must be less than or equal to {{maximum}}",
not_inclusive: "Number must be less than {{maximum}}",
},
set: {
exact: "Invalid input",
inclusive: "Invalid input",
not_inclusive: "Invalid input",
},
string: {
exact: "String must contain exactly {{maximum}} character(s)",
inclusive: "String must contain at most {{maximum}} character(s)",
not_inclusive: "String must contain under {{maximum}} character(s)",
},
},
too_small: {
array: {
exact: "Array must contain exactly {{minimum}} element(s)",
inclusive: "Array must contain at least {{minimum}} element(s)",
not_inclusive: "Array must contain more than {{minimum}} element(s)",
},
date: {
exact: "Date must be exactly {{- minimum, datetime}}",
inclusive:
"Date must be greater than or equal to {{- minimum, datetime}}",
not_inclusive: "Date must be greater than {{- minimum, datetime}}",
},
number: {
exact: "Number must be exactly {{minimum}}",
inclusive: "Number must be greater than or equal to {{minimum}}",
not_inclusive: "Number must be greater than {{minimum}}",
},
set: {
exact: "Invalid input",
inclusive: "Invalid input",
not_inclusive: "Invalid input",
},
string: {
exact: "String must contain exactly {{minimum}} character(s)",
inclusive: "String must contain at least {{minimum}} character(s)",
not_inclusive: "String must contain over {{minimum}} character(s)",
},
},
unrecognized_keys: "Unrecognized key(s) in object: {{- keys}}",
},
local_types: {
array: "array",
bigint: "bigint",
boolean: "boolean",
date: "date",
float: "float",
function: "function",
integer: "integer",
map: "map",
nan: "nan",
never: "never",
null: "null",
number: "number",
object: "object",
promise: "promise",
set: "set",
string: "string",
symbol: "symbol",
undefined: "undefined",
unknown: "unknown",
void: "void",
},
types: {
array: "array",
bigint: "bigint",
boolean: "boolean",
date: "date",
float: "float",
function: "function",
integer: "integer",
map: "map",
nan: "nan",
never: "never",
null: "null",
number: "number",
object: "object",
promise: "promise",
set: "set",
string: "string",
symbol: "symbol",
undefined: "undefined",
unknown: "unknown",
void: "void",
},
validations: {
cuid: "cuid",
datetime: "datetime",
email: "email",
regex: "regex",
url: "url",
uuid: "uuid",
},
};

View file

@ -11,7 +11,6 @@ import type { default as UsersStorageTable } from './UsersStorage';
import type { default as ServizioAnnunciTable } from './ServizioAnnunci';
import type { default as EmailsTable } from './Emails';
import type { default as PaymentsTable } from './Payments';
import type { default as TempTokensTable } from './TempTokens';
import type { default as EventQueueTable } from './EventQueue';
import type { default as OrdiniTable } from './Ordini';
import type { default as PrezziarioTable } from './Prezziario';
@ -46,8 +45,6 @@ export default interface PublicSchema {
payments: PaymentsTable;
temp_tokens: TempTokensTable;
event_queue: EventQueueTable;
ordini: OrdiniTable;

View file

@ -1,20 +0,0 @@
// @generated
// This file is automatically generated by Kanel. Do not modify manually.
import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely';
/** Identifier type for public.temp_tokens */
export type TempTokensToken = string & { __brand: 'public.temp_tokens' };
/** Represents the table public.temp_tokens */
export default interface TempTokensTable {
token: ColumnType<TempTokensToken, TempTokensToken | undefined, TempTokensToken>;
elapse: ColumnType<Date, Date | string | undefined, Date | string>;
}
export type TempTokens = Selectable<TempTokensTable>;
export type NewTempTokens = Insertable<TempTokensTable>;
export type TempTokensUpdate = Updateable<TempTokensTable>;

View file

@ -124,21 +124,6 @@ export const addUserStorage = async (data: NewUsersStorage) => {
}
};
export const getUserStorage = async ({ userId }: { userId: UsersId }) => {
try {
return await db
.selectFrom("users_storage")
.where("userId", "=", userId)
.selectAll()
.execute();
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while getting user storage: ${(e as Error).message}`,
});
}
};
export const deleteUserStorageEntry = async ({
userId,
storageId,