[
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# database\n/prisma/db.sqlite\n/prisma/db.sqlite-journal\n\n# next.js\n/.next/\n/out/\nnext-env.d.ts\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.pnpm-debug.log*\n\n# local env files\n# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables\n.env\n.env.legacy\n.env*.local\n\n# vercel\n.vercel\n\n# typescript\n*.tsbuildinfo\n"
  },
  {
    "path": "README.md",
    "content": "The platform starter kit has been archived and is no longer maintained.\n\nFind more, smaller examples here: https://github.com/calcom/examples\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/.eslintrc.cjs",
    "content": "/** @type {import(\"eslint\").Linter.Config} */\nconst config = {\n  root: true,\n  parser: \"@typescript-eslint/parser\",\n  ignorePatterns: [\"*.config.mjs\", \"*.config.js\", \"*.config.cjs\"],\n  parserOptions: {\n    tsconfigRootDir: __dirname,\n    project: [\"./tsconfig.json\"],\n  },\n  plugins: [\"@typescript-eslint\", \"unused-imports\"],\n  extends: [\n    \"next/core-web-vitals\",\n    \"plugin:@typescript-eslint/recommended-type-checked\",\n    \"plugin:@typescript-eslint/stylistic-type-checked\",\n  ],\n  rules: {\n    \"@typescript-eslint/ban-ts-comment\": [\n      \"error\",\n      {\n        \"ts-expect-error\": \"allow-with-description\",\n        \"ts-ignore\": \"allow-with-description\",\n        \"ts-nocheck\": \"allow-with-description\",\n        \"ts-check\": \"allow-with-description\",\n      },\n    ],\n    \"@typescript-eslint/no-unnecessary-type-assertion\": \"off\",\n    \"@typescript-eslint/no-explicit-any\": \"off\",\n    \"@typescript-eslint/no-unsafe-call\": \"off\",\n    \"@typescript-eslint/no-unsafe-member-access\": \"off\",\n    \"@typescript-eslint/prefer-nullish-coalescing\": \"off\",\n    \"@typescript-eslint/array-type\": \"off\",\n    \"@typescript-eslint/consistent-type-definitions\": \"off\",\n    \"@typescript-eslint/no-unsafe-assignment\": \"warn\",\n    \"@typescript-eslint/consistent-type-imports\": [\n      \"warn\",\n      {\n        prefer: \"type-imports\",\n        fixStyle: \"inline-type-imports\",\n      },\n    ],\n    \"@typescript-eslint/no-unused-vars\": [\n      \"warn\",\n      {\n        argsIgnorePattern: \"^_\",\n      },\n    ],\n    \"@typescript-eslint/require-await\": \"off\",\n    \"@typescript-eslint/no-misused-promises\": [\n      \"error\",\n      {\n        checksVoidReturn: false,\n      },\n    ],\n  },\n};\nmodule.exports = config;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/LICENSE",
    "content": "Copyright (c) 2024 Cal.com, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/README.md",
    "content": "<!-- PROJECT LOGO -->\n<p align=\"center\">\n  <a href=\"https://github.com/calcom/cal.com\">\n   <img src=\"https://github.com/calcom/platform-starter-kit/assets/8019099/6f0a8337-6d18-42de-aa00-44a57764e19b\" alt=\"Logo\">\n  </a>\n\n  <h3 align=\"center\">Cal.com Platform Starter Kit</h3>\n\n  <p align=\"center\">\n    Build your pixel-perfect booking experience\n    <br />\n    <br />\n    <a href=\"https://experts.cal.com\"><strong>Demo</strong></a>\n    ·\n    <a href=\"https://www.youtube.com/watch?v=wwo07ghiNn4\"><strong>Video Tutorial</strong></a>\n    ·\n    <a href=\"https://cal.com/docs/platform\"><strong>Docs</strong></a>\n    ·\n    <a href=\"https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Ftree%2Fmain&env=NEXT_PUBLIC_REFRESH_URL,AUTH_SECRET,AUTH_TRUST_HOST,NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID,NEXT_PUBLIC_CAL_API_URL,CAL_SECRET&envDescription=You%20can%20see%20how%20to%20populate%20the%20environment%20variables%20in%20our%20starter%20example%20→&envLink=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Ftree%2Fmain%2F.env.example&project-name=cal-platform-starter&repository-name=cal-platform-starter&demo-title=Cal.com%20Experts&demo-description=A%20marketplace%20to%20book%20appointments%20with%20experts&demo-url=https%3A%2F%2Fexperts.cal.com&demo-image=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Fassets%2F8019099%2F2e58f8da-a110-4a45-b9a4-dcffb45f9baa&integration-ids=oac_VqOgBHqhEoFTPzGkPd7L0iH6&external-id=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Ftree%2Fmain\"><strong>Deploy on Vercel</strong></a>\n    <br />\n    <br />\n    <a href=\"https://go.cal.com/discord\">Discord</a>\n    ·\n    <a href=\"https://cal.com/platform\">Website</a>\n    ·\n    <a href=\"https://github.com/calcom/cal.com/issues\">Issues</a>\n\n  </p>\n</p>\n\n# Platform Starter Kit Example\n\nCal.com Platform Starter Kit showcases the new Cal.com Platform API and Cal.com Atoms. It was built using the [T3 Stack](https://create.t3.gg/) with [Supabase](https://supabase.com/) as the Postgres Database and Image Storage host.\n\n## Deploy your own\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Ftree%2Fmain&env=NEXT_PUBLIC_REFRESH_URL,AUTH_SECRET,AUTH_TRUST_HOST,NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID,NEXT_PUBLIC_CAL_API_URL,CAL_SECRET&envDescription=You%20can%20see%20how%20to%20populate%20the%20environment%20variables%20in%20our%20starter%20example%20→&envLink=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Ftree%2Fmain%2F.env.example&project-name=cal-platform-starter&repository-name=cal-platform-starter&demo-title=Cal.com%20Experts&demo-description=A%20marketplace%20to%20book%20appointments%20with%20experts&demo-url=https%3A%2F%2Fexperts.cal.com&demo-image=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Fassets%2F8019099%2F2e58f8da-a110-4a45-b9a4-dcffb45f9baa&integration-ids=oac_VqOgBHqhEoFTPzGkPd7L0iH6&external-id=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Ftree%2Fmain)\n\n## How to use\n\n```bash\nnpx @calcom/starter-kit my-platform\n```\n\nOR\n\n**1. Clone the repository**\n\nHTTPS:\n\n```bash\ngit clone https://github.com/calcom/platform-starter-kit.git\n```\n\nGitHub CLI:\n\n```bash\ngh repo clone calcom/platform-starter-kit\n```\n\n**2. Move into the Starter**\n\n```bash\ncd platform-starter-kit/\n```\n\n**3. Install dependencies**\n\n<!-- note(richard): We require pnpm since we have this version deployed; if we separate example source from our deployed version, we free up the package manager choice. -->\n\n> [!IMPORTANT]  \n> **Package Manager:** This repository is deployed as-is and therefore contains a `pnpm-lock.yaml` file. As a result, you currently have to use `pnpm` as your package manager to ensure that the dependencies are installed correctly.\n\n```bash\npnpm install\n```\n\n**4. Set Environment Variables**\n\nWe provide most environment variables out of the box (including Cal-related variables).\n\nSo get started by copying the `.env.example`:\n\n```bash\ncp .env.example .env\n```\n\n_4.1 Database_\n\nThis project uses Postgres with Supabase. You can create a free project at [database.new](https://database.new/).\n\nThen, get the Database URL from the [Supabase dashboard](https://supabase.com/dashboard/project/_/settings/database) and update the respective values in your `.env` file:\n\n```.env\nPOSTGRES_PRISMA_URL=\"postgres://postgres.YOUR-PROJECT-REF:[YOUR-PASSWORD]@aws-0-[REGION].pooler.supabase.com:6543/postgres?pgbouncer=true&connection_limit=1\" # Transaction Mode\nPOSTGRES_URL_NON_POOLING=\"postgres://postgres.YOUR-PROJECT-REF:[YOUR-PASSWORD]@aws-0-[REGION].pooler.supabase.com:5432/postgres\"  # Session Mode\n```\n\nWhen working locally you can use the DB URL: `postgresql://postgres:postgres@127.0.0.1:54322/postgres` outputted by the `supabase start` command for both vairables.\n\n[Only needed when deploying manually] Initialize the database:\n\nNote that if you used the Vercel Deploy link from above, the Supabase Vercel integration sets this up automatically for you!\n\n```bash\npnpm db:init\npnpm db:seed # Will throw an error if DB is already seeded, which you can ignore.\n```\n\nPrisma will create a `_prisma_migrations` table on the `public` database schema. In Supabase, the public schema is exposed via the API by default. To secure the table, navigate to the [Table Editor](https://supabase.com/dashboard/project/_/editor), click on \"RLS diasbaled\" > \"Enable RLS for this table\".\n\nAlternatively, you can run the follow SQL statement on your database, e.g. via the [SQL Editor](https://supabase.com/dashboard/project/_/sql/new) in the Supabase Dashboard:\n\n```sql\nALTER TABLE \"public\".\"_prisma_migrations\" ENABLE ROW LEVEL SECURITY;\n```\n\nLastly, in your [Supabase Dashboard](https://supabase.com/dashboard/project/_/storage/buckets) create a public `avatars` bucket to store the profile pictures.\n\n_4.2 Authentication_\n\nGenerate a NextAuth secret and add it to your `.env` file:\n\n```bash\nopenssl rand -hex 32\n```\n\n```.env\n# Next Auth\n# You can generate a new secret on the command line with\n# openssl rand -base64 32\n# <https://next-auth.js.org/configuration/options#secret>\n\nAUTH_SECRET=\"SQhGk****\"\n```\n\n_4.3 Cal_\n\nFor **development**, you're all set! We've provided you with our sandbox keys that you can find the `.env.example` file.\n\nFor **production**, keep in mind that you'll have to update the `NEXT_PUBLIC_REFRESH_URL` variable to make it point to your deployment, e.g.:\n\n```.env\n# 3/ *REFRESH URL.* You have to expose an endpoint that will be used from calcom: https://cal.com/docs/platform/quick-start#4.-backend:-setting-up-refresh-token-endpoint\n\nNEXT_PUBLIC_REFRESH_URL=\"https://<your-project>.vercel.app/api/cal/refresh\"\n```\n\n**5. Development Server**\nFrom here, you're all set. Just start the development server & get going.\n\n```bash\npnpm dev\n```\n\n## What's next? How do I make an app with this?\n\nWe try to keep this project as simple as possible, so you can start with Cal.com Platform and the scaffolding we set up for you, and add additional things later when they become necessary.\n\nIf you are not familiar with the different technologies used in this project, please refer to the respective docs.\n\n- [Cal.com Platform](https://cal.com/platform)\n- [Next.js](https://nextjs.org)\n- [Supabase](https://supabase.com)\n- [NextAuth.js](https://next-auth.js.org)\n- [Prisma](https://prisma.io)\n- [Tailwind CSS](https://tailwindcss.com)\n- [tRPC](https://trpc.io)\n\n## Learn More about Cal.com Platform\n\nVisit our documentation at [cal.com/docs/platform](https://cal.com/docs/platform) or join our [Discord](https://go.cal.com/discord).\n\nContact sales to purchase a commercial API key here: [cal.com/sales](https://cal.com/sales).\n\n## Learn More about T3\n\nTo learn more about the [T3 Stack](https://create.t3.gg/), take a look at the following resources:\n\n- [Documentation](https://create.t3.gg/)\n- [Learn the T3 Stack](https://create.t3.gg/en/faq#what-learning-resources-are-currently-available) — Check out these awesome tutorials\n\nYou can check out the [create-t3-app GitHub repository](https://github.com/t3-oss/create-t3-app) — your feedback and contributions are welcome!\n\n## Learn More about Supabase\n\nSupabase is the fastest way to get up and running with Next.js and Postgres. Check out [this video](https://youtu.be/WdA6b0jPNv4?si=eeWpu03PI3W-t5pC) to learn more!\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/components.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"default\",\n  \"rsc\": true,\n  \"tsx\": true,\n  \"tailwind\": {\n    \"config\": \"tailwind.config.ts\",\n    \"css\": \"src/styles/globals.css\",\n    \"baseColor\": \"stone\",\n    \"cssVariables\": true,\n    \"prefix\": \"\"\n  },\n  \"aliases\": {\n    \"components\": \"@/components\",\n    \"utils\": \"@/lib/utils\"\n  }\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/next.config.js",
    "content": "import { resolve } from \"path\";\n\n/**\n * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful\n * for Docker builds.\n */\nawait import(\"./src/env.js\");\n\n/** @type {import(\"next\").NextConfig} */\nconst config = {\n  experimental: {\n    ppr: true,\n  },\n  images: {\n    formats: [\"image/avif\", \"image/webp\"],\n    remotePatterns: [\n      {\n        protocol: \"https\",\n        hostname: \"picsum.photos\",\n      },\n    ],\n    loader: \"custom\",\n    loaderFile: \"./src/lib/supabase-image-loader.ts\",\n  },\n};\n\nexport default config;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/package.json",
    "content": "{\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"next build\",\n    \"db:studio\": \"prisma studio\",\n    \"db:seed\": \"NODE_ENV=development prisma db seed\",\n    \"db:init\": \"pnpm prisma migrate dev --name=init\",\n    \"dev\": \"next dev\",\n    \"postinstall\": \"prisma generate\",\n    \"lint\": \"NODE_OPTIONS='--max-old-space-size=4096' next lint --fix\",\n    \"start\": \"next start\",\n    \"cal:generate\": \"openapi-endpoint-trimmer -u https://raw.githubusercontent.com/calcom/cal.com/51428087ef0a20f4d775fccbd3a34c2d885aed2b/apps/api/v2/swagger/documentation.json -p /v2/bookings,/v2/event-types,/v2/schedules,/v2/oauth-clients,/v2/oauth -o ./src/cal/__generated/cal-sdk.yml && typed-openapi ./src/cal/__generated/cal-sdk.yml --r zod -o ./src/cal/__generated/cal-sdk.ts\",\n    \"typecheck\": \"tsc --noEmit\"\n  },\n  \"prisma\": {\n    \"seed\": \"tsx prisma/seed.ts\"\n  },\n  \"dependencies\": {\n    \"@auth/prisma-adapter\": \"^1.4.0\",\n    \"@calcom/atoms\": \"^1.0.44\",\n    \"@hookform/resolvers\": \"^3.3.4\",\n    \"@libsql/client\": \"^0.6.0\",\n    \"@opentelemetry/api\": \"^1.8.0\",\n    \"@prisma/adapter-libsql\": \"^5.12.1\",\n    \"@prisma/client\": \"^5.15.0\",\n    \"@radix-ui/react-accordion\": \"^1.1.2\",\n    \"@radix-ui/react-avatar\": \"^1.0.4\",\n    \"@radix-ui/react-checkbox\": \"^1.0.4\",\n    \"@radix-ui/react-collapsible\": \"^1.0.3\",\n    \"@radix-ui/react-dialog\": \"^1.0.5\",\n    \"@radix-ui/react-dropdown-menu\": \"2.0.2\",\n    \"@radix-ui/react-label\": \"^2.0.2\",\n    \"@radix-ui/react-navigation-menu\": \"^1.1.4\",\n    \"@radix-ui/react-popover\": \"^1.0.7\",\n    \"@radix-ui/react-progress\": \"^1.0.3\",\n    \"@radix-ui/react-select\": \"^2.0.0\",\n    \"@radix-ui/react-separator\": \"^1.0.3\",\n    \"@radix-ui/react-slot\": \"^1.0.2\",\n    \"@radix-ui/react-tabs\": \"^1.0.4\",\n    \"@radix-ui/react-toast\": \"^1.1.5\",\n    \"@radix-ui/react-tooltip\": \"^1.0.7\",\n    \"@supabase/supabase-js\": \"^2.43.5\",\n    \"@t3-oss/env-nextjs\": \"^0.10.1\",\n    \"@tanstack/react-query\": \"^5.25.0\",\n    \"@trpc/client\": \"next\",\n    \"@trpc/next\": \"next\",\n    \"@trpc/react-query\": \"next\",\n    \"@trpc/server\": \"next\",\n    \"@vercel/analytics\": \"^1.2.2\",\n    \"@zodios/core\": \"^10.9.6\",\n    \"class-variance-authority\": \"^0.7.0\",\n    \"clsx\": \"^2.1.0\",\n    \"cmdk\": \"^1.0.0\",\n    \"dayjs\": \"^1.11.10\",\n    \"lucide-react\": \"^0.364.0\",\n    \"next\": \"14.3.0-canary.37\",\n    \"next-auth\": \"5.0.0-beta.16\",\n    \"next-axiom\": \"^1.1.1\",\n    \"next-themes\": \"^0.3.0\",\n    \"nuqs\": \"^1.17.4\",\n    \"pino\": \"^8.20.0\",\n    \"react\": \"^18.3.1\",\n    \"react-dom\": \"^18.3.1\",\n    \"react-dropzone\": \"^14.2.3\",\n    \"react-hook-form\": \"^7.51.4\",\n    \"react-wrap-balancer\": \"^1.1.0\",\n    \"remeda\": \"^2.0.3\",\n    \"server-only\": \"^0.0.1\",\n    \"sonner\": \"^1.4.41\",\n    \"superjson\": \"^2.2.1\",\n    \"tailwind-merge\": \"^2.2.2\",\n    \"tailwindcss-animate\": \"^1.0.7\",\n    \"typed-openapi\": \"^0.4.1\",\n    \"usehooks-ts\": \"^3.1.0\",\n    \"zod\": \"^3.23.7\"\n  },\n  \"devDependencies\": {\n    \"@next/eslint-plugin-next\": \"^14.2.3\",\n    \"@trivago/prettier-plugin-sort-imports\": \"^4.3.0\",\n    \"@types/eslint\": \"^8.56.2\",\n    \"@types/node\": \"^20.11.20\",\n    \"@types/react\": \"^18.2.75\",\n    \"@types/react-dom\": \"^18.2.24\",\n    \"@typescript-eslint/eslint-plugin\": \"^7.1.1\",\n    \"@typescript-eslint/parser\": \"^7.1.1\",\n    \"eslint\": \"^8.57.0\",\n    \"eslint-config-next\": \"^14.1.3\",\n    \"eslint-config-turbo\": \"^1.13.3\",\n    \"eslint-plugin-import\": \"^2.29.1\",\n    \"eslint-plugin-jsx-a11y\": \"^6.8.0\",\n    \"eslint-plugin-react\": \"^7.34.1\",\n    \"eslint-plugin-react-hooks\": \"^4.6.2\",\n    \"eslint-plugin-unused-imports\": \"^3.1.0\",\n    \"openapi-endpoint-trimmer\": \"^2.0.0\",\n    \"postcss\": \"^8.4.34\",\n    \"prettier\": \"^3.2.5\",\n    \"prettier-plugin-tailwindcss\": \"^0.5.11\",\n    \"prisma\": \"^5.15.0\",\n    \"tailwindcss\": \"^3.4.1\",\n    \"tsx\": \"^4.7.2\",\n    \"typescript\": \"^5.4.5\",\n    \"typescript-eslint\": \"^7.8.0\"\n  },\n  \"ct3aMetadata\": {\n    \"initVersion\": \"7.30.0\"\n  }\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/postcss.config.cjs",
    "content": "const config = {\n  plugins: {\n    tailwindcss: {},\n  },\n};\n\nmodule.exports = config;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/prettier.config.mjs",
    "content": "/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */\nconst config = {\n  bracketSpacing: true,\n  bracketSameLine: true,\n  singleQuote: false,\n  jsxSingleQuote: false,\n  trailingComma: \"es5\",\n  semi: true,\n  printWidth: 110,\n  arrowParens: \"always\",\n  endOfLine: \"auto\",\n  plugins: [\"@trivago/prettier-plugin-sort-imports\", \"prettier-plugin-tailwindcss\"],\n};\n\nexport default config;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/prisma/client.ts",
    "content": "import { env } from \"@/env\";\nimport { PrismaClient } from \"@prisma/client\";\n\nconst createPrismaClient = () =>\n  new PrismaClient({\n    log: env.NODE_ENV === \"development\" ? [\"query\", \"error\", \"warn\"] : [\"error\"],\n  });\n\nconst globalForPrisma = globalThis as unknown as {\n  prisma: ReturnType<typeof createPrismaClient> | undefined;\n};\n\nexport const db = globalForPrisma.prisma ?? createPrismaClient();\n\nif (env.NODE_ENV !== \"production\") globalForPrisma.prisma = db;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/prisma/migrations/0_init/migration.sql",
    "content": "-- CreateSchema\nCREATE SCHEMA IF NOT EXISTS \"prisma\";\n\n-- CreateEnum\nCREATE TYPE \"prisma\".\"UserStatus\" AS ENUM ('APPROVED', 'PENDING');\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"Account\" (\n    \"id\" TEXT NOT NULL,\n    \"userId\" TEXT NOT NULL,\n    \"type\" TEXT NOT NULL,\n    \"provider\" TEXT NOT NULL,\n    \"providerAccountId\" TEXT NOT NULL,\n    \"refresh_token\" TEXT,\n    \"access_token\" TEXT,\n    \"expires_at\" INTEGER,\n    \"token_type\" TEXT,\n    \"scope\" TEXT,\n    \"id_token\" TEXT,\n    \"session_state\" TEXT,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n\n    CONSTRAINT \"Account_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"Session\" (\n    \"id\" TEXT NOT NULL,\n    \"sessionToken\" TEXT NOT NULL,\n    \"userId\" TEXT NOT NULL,\n    \"expires\" TIMESTAMP(3) NOT NULL,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n\n    CONSTRAINT \"Session_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"User\" (\n    \"id\" TEXT NOT NULL,\n    \"name\" TEXT,\n    \"username\" TEXT,\n    \"bio\" TEXT,\n    \"email\" TEXT,\n    \"emailVerified\" TIMESTAMP(3),\n    \"hashedPassword\" TEXT,\n    \"image\" TEXT,\n    \"calAccountId\" INTEGER,\n    \"calAccessToken\" TEXT,\n    \"calRefreshToken\" TEXT,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n    \"status\" \"prisma\".\"UserStatus\" NOT NULL DEFAULT 'PENDING',\n\n    CONSTRAINT \"User_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"CalAccount\" (\n    \"id\" INTEGER NOT NULL,\n    \"username\" TEXT,\n    \"email\" TEXT NOT NULL,\n    \"timeZone\" TEXT NOT NULL,\n    \"weekStart\" TEXT NOT NULL,\n    \"createdDate\" TEXT NOT NULL,\n    \"timeFormat\" INTEGER,\n    \"defaultScheduleId\" INTEGER,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n\n    CONSTRAINT \"CalAccount_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"VerificationToken\" (\n    \"identifier\" TEXT NOT NULL,\n    \"token\" TEXT NOT NULL,\n    \"expires\" TIMESTAMP(3) NOT NULL,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"FilterOption\" (\n    \"fieldId\" TEXT NOT NULL,\n    \"fieldValue\" TEXT NOT NULL,\n    \"fieldLabel\" TEXT NOT NULL,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n    \"filterCategoryFieldId\" TEXT NOT NULL,\n    \"filterCategoryValue\" TEXT NOT NULL,\n    \"filterCategoryLabel\" TEXT NOT NULL\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"FilterOptionsOnUser\" (\n    \"userId\" TEXT NOT NULL,\n    \"filterOptionFieldId\" TEXT NOT NULL,\n    \"filterCategoryFieldId\" TEXT NOT NULL,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Account_provider_providerAccountId_key\" ON \"prisma\".\"Account\"(\"provider\", \"providerAccountId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Session_sessionToken_key\" ON \"prisma\".\"Session\"(\"sessionToken\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_username_key\" ON \"prisma\".\"User\"(\"username\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_email_key\" ON \"prisma\".\"User\"(\"email\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_calAccountId_key\" ON \"prisma\".\"User\"(\"calAccountId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_calAccessToken_key\" ON \"prisma\".\"User\"(\"calAccessToken\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_calRefreshToken_key\" ON \"prisma\".\"User\"(\"calRefreshToken\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"CalAccount_username_key\" ON \"prisma\".\"CalAccount\"(\"username\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"CalAccount_email_key\" ON \"prisma\".\"CalAccount\"(\"email\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"VerificationToken_token_key\" ON \"prisma\".\"VerificationToken\"(\"token\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"VerificationToken_identifier_token_key\" ON \"prisma\".\"VerificationToken\"(\"identifier\", \"token\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"FilterOption_fieldId_key\" ON \"prisma\".\"FilterOption\"(\"fieldId\");\n\n-- CreateIndex\nCREATE INDEX \"FilterOption_fieldId_filterCategoryFieldId_idx\" ON \"prisma\".\"FilterOption\"(\"fieldId\", \"filterCategoryFieldId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"FilterOption_fieldId_filterCategoryFieldId_key\" ON \"prisma\".\"FilterOption\"(\"fieldId\", \"filterCategoryFieldId\");\n\n-- CreateIndex\nCREATE INDEX \"FilterOptionsOnUser_userId_filterOptionFieldId_filterCatego_idx\" ON \"prisma\".\"FilterOptionsOnUser\"(\"userId\", \"filterOptionFieldId\", \"filterCategoryFieldId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"FilterOptionsOnUser_userId_filterOptionFieldId_filterCatego_key\" ON \"prisma\".\"FilterOptionsOnUser\"(\"userId\", \"filterOptionFieldId\", \"filterCategoryFieldId\");\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"Account\" ADD CONSTRAINT \"Account_userId_fkey\" FOREIGN KEY (\"userId\") REFERENCES \"prisma\".\"User\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"Session\" ADD CONSTRAINT \"Session_userId_fkey\" FOREIGN KEY (\"userId\") REFERENCES \"prisma\".\"User\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"User\" ADD CONSTRAINT \"User_calAccountId_fkey\" FOREIGN KEY (\"calAccountId\") REFERENCES \"prisma\".\"CalAccount\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"FilterOptionsOnUser\" ADD CONSTRAINT \"FilterOptionsOnUser_filterOptionFieldId_filterCategoryFiel_fkey\" FOREIGN KEY (\"filterOptionFieldId\", \"filterCategoryFieldId\") REFERENCES \"prisma\".\"FilterOption\"(\"fieldId\", \"filterCategoryFieldId\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"FilterOptionsOnUser\" ADD CONSTRAINT \"FilterOptionsOnUser_userId_fkey\" FOREIGN KEY (\"userId\") REFERENCES \"prisma\".\"User\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/prisma/schema.prisma",
    "content": "generator client {\n  provider        = \"prisma-client-js\"\n  previewFeatures = [\"multiSchema\"]\n}\n\ndatasource db {\n  provider  = \"postgresql\"\n  url       = env(\"POSTGRES_PRISMA_URL\")\n  directUrl = env(\"POSTGRES_URL_NON_POOLING\")\n  schemas   = [\"prisma\"]\n}\n\nmodel Account {\n  id                String    @id @default(cuid())\n  userId            String\n  type              String\n  provider          String\n  providerAccountId String\n  refresh_token     String?\n  access_token      String?\n  expires_at        Int?\n  token_type        String?\n  scope             String?\n  id_token          String?\n  session_state     String?\n  createdAt         DateTime? @default(now())\n  user              User      @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n  @@unique([provider, providerAccountId])\n  @@schema(\"prisma\")\n}\n\nmodel Session {\n  id           String    @id @default(cuid())\n  sessionToken String    @unique\n  userId       String\n  expires      DateTime\n  createdAt    DateTime? @default(now())\n  user         User      @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n  @@schema(\"prisma\")\n}\n\nmodel User {\n  id                    String                @id @default(cuid())\n  name                  String?\n  username              String?               @unique\n  bio                   String?\n  email                 String?               @unique\n  emailVerified         DateTime?\n  hashedPassword        String?\n  image                 String?\n  calAccountId          Int?                  @unique\n  calAccessToken        String?               @unique\n  calRefreshToken       String?               @unique\n  createdAt             DateTime?             @default(now())\n  status                UserStatus            @default(PENDING)\n  accounts              Account[]\n  selectedFilterOptions FilterOptionsOnUser[]\n  sessions              Session[]\n  calAccount            CalAccount?           @relation(fields: [calAccountId], references: [id], onDelete: Cascade)\n\n  @@schema(\"prisma\")\n}\n\nmodel CalAccount {\n  id                Int       @id\n  username          String?   @unique\n  email             String    @unique\n  timeZone          String\n  weekStart         String\n  createdDate       String\n  timeFormat        Int?\n  defaultScheduleId Int?\n  createdAt         DateTime? @default(now())\n  user              User?\n\n  @@schema(\"prisma\")\n}\n\nmodel VerificationToken {\n  identifier String\n  token      String    @unique\n  expires    DateTime\n  createdAt  DateTime? @default(now())\n\n  @@unique([identifier, token])\n  @@schema(\"prisma\")\n}\n\nmodel FilterOption {\n  fieldId               String                @id @unique\n  fieldValue            String\n  fieldLabel            String\n  createdAt             DateTime?             @default(now())\n  filterCategoryFieldId String\n  filterCategoryValue   String\n  filterCategoryLabel   String\n  selectedByUsers       FilterOptionsOnUser[]\n\n  @@unique([fieldId, filterCategoryFieldId])\n  @@index([fieldId, filterCategoryFieldId])\n  @@schema(\"prisma\")\n}\n\nmodel FilterOptionsOnUser {\n  userId                String\n  filterOptionFieldId   String\n  filterCategoryFieldId String\n  createdAt             DateTime?    @default(now())\n  filterOption          FilterOption @relation(fields: [filterOptionFieldId, filterCategoryFieldId], references: [fieldId, filterCategoryFieldId])\n  user                  User         @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n  @@unique([userId, filterOptionFieldId, filterCategoryFieldId])\n  @@index([userId, filterOptionFieldId, filterCategoryFieldId])\n  @@schema(\"prisma\")\n}\n\nenum UserStatus {\n  APPROVED\n  PENDING\n\n  @@schema(\"prisma\")\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/prisma/seed.ts",
    "content": "import { filterOptions } from \"@/app/_hardcoded\";\nimport { PrismaClient } from \"@prisma/client\";\n\nconst devDb = new PrismaClient();\n\nasync function main() {\n  for (const filterOption of filterOptions) {\n    console.log(`attempting to upsert ${filterOption.fieldId}`);\n    await devDb.filterOption.upsert({\n      where: { fieldId: filterOption.fieldId },\n      create: filterOption,\n      update: filterOption,\n    });\n    console.log(`✅ {filterOption.fieldId} upserted`);\n  }\n}\n\nmain()\n  .then(async () => {\n    await devDb.$disconnect();\n  })\n  .catch(async (e) => {\n    console.error(e);\n    await devDb.$disconnect();\n    process.exit(1);\n  });\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/[expertUsername]/[eventSlug]/page.tsx",
    "content": "import ExpertBooker from \"../_components/expert-booker\";\nimport { cal } from \"@/cal/api\";\nimport Image from \"next/image\";\nimport { db } from \"prisma/client\";\n\nexport const dynamic = \"force-dynamic\";\n\nexport default async function BookerPage({\n  params,\n}: {\n  params: { expertUsername: string; eventSlug: string };\n}) {\n  const expert = await db.user.findUnique({\n    where: { username: params.expertUsername },\n    select: {\n      id: true,\n      calAccessToken: true,\n      calRefreshToken: true,\n      calAccountId: true,\n      name: true,\n      username: true,\n      calAccount: {\n        select: {\n          id: true,\n          username: true,\n        },\n      },\n    },\n  });\n  if (!expert?.calAccount?.username) {\n    console.warn(\"Expert not found\", params.expertUsername);\n    return <div>Expert not found</div>;\n  }\n  const eventType = await cal({\n    user: {\n      calAccessToken: expert.calAccessToken,\n      calRefreshToken: expert.calRefreshToken,\n      calAccountId: expert.calAccountId,\n      id: expert.id,\n    },\n  }).get(\"/v2/event-types/{username}/{eventSlug}/public\", {\n    path: {\n      username: expert.calAccount.username,\n      eventSlug: params.eventSlug,\n    },\n    query: {\n      isTeamEvent: false,\n    },\n  });\n  if (eventType.status === \"error\") {\n    console.warn(\n      `[BookerPage] Event not found for event slug '${params.eventSlug}'. Check logs above for more info.`\n    );\n    return <div>Event not found</div>;\n  }\n\n  const descriptionWithoutHtmlTags = eventType.data?.description.replace(/<[^>]*>?/gm, \"\");\n  return (\n    <div className=\"mb-4 flex flex-1 flex-col items-center gap-4 overflow-auto\">\n      <header className=\"flex w-full flex-col justify-between gap-4 rounded-md bg-muted/50 px-8 py-4  sm:px-10 lg:flex-row lg:px-12 2xl:px-36\">\n        <div className=\"flex items-center gap-x-6\">\n          <Image\n            alt=\"Expert image\"\n            className=\"aspect-square rounded-md object-cover\"\n            src={`avatars/${expert.id}`}\n            height=\"64\"\n            width=\"64\"\n          />\n          <div className=\"space-y-2\">\n            <h1 className=\"text-2xl font-semibold capitalize leading-none tracking-tight\">\n              {expert.name}: {eventType.data?.title}\n            </h1>\n            <p className=\"text-sm text-muted-foreground\">{descriptionWithoutHtmlTags}</p>\n          </div>\n        </div>\n      </header>\n      <div className=\"mx-auto mt-4 grid w-full gap-2 px-8 sm:px-10 lg:px-12 2xl:px-36\">\n        {Boolean(expert.calAccount) && (\n          <ExpertBooker\n            calAccount={{ username: expert.calAccount.username }}\n            expert={{\n              name: expert.name,\n              username: expert.username,\n            }}\n            eventSlug={eventType.data?.slug}\n            customClassNames={{ bookerContainer: \"custom-grid border\" }}\n          />\n        )}\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/[expertUsername]/_components/AboutSection.tsx",
    "content": "'use client'\n\nimport { useState } from 'react'\nimport clsx from 'clsx'\nimport { Info } from 'lucide-react'\n\n\n\nexport function AboutSection(props: React.ComponentPropsWithoutRef<'section'>) {\n  const [isExpanded, setIsExpanded] = useState(false)\n\n  return (\n    <section {...props}>\n      <h2 className=\"flex items-center font-mono text-sm font-medium leading-7 text-slate-900\">\n        <Info\n          // colors={['fill-violet-300', 'fill-pink-300']}\n          className=\"h-2.5 w-2.5\"\n        />\n        <span className=\"ml-2.5\">About</span>\n      </h2>\n      <p\n        className={clsx(\n          'mt-2 text-base leading-7 text-slate-700',\n          !isExpanded && 'lg:line-clamp-4',\n        )}\n      >\n        In this show, Eric and Wes dig deep to get to the facts with guests who\n        have been labeled villains by a society quick to judge, without actually\n        getting the full story. Tune in every Thursday to get to the truth with\n        another misunderstood outcast as they share the missing context in their\n        tragic tale.\n      </p>\n      {!isExpanded && (\n        <button\n          type=\"button\"\n          className=\"mt-2 hidden text-sm font-bold leading-6 text-pink-500 hover:text-pink-700 active:text-pink-900 lg:inline-block\"\n          onClick={() => setIsExpanded(true)}\n        >\n          Show more\n        </button>\n      )}\n    </section>\n  )\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/[expertUsername]/_components/Container.tsx",
    "content": "import { cn } from \"@/lib/utils\";\n\nexport function Container({ className, children, ...props }: React.ComponentPropsWithoutRef<\"div\">) {\n  return (\n    <div className={cn(\"lg:px-8\", className)} {...props}>\n      <div className=\"lg:max-w-4xl\">\n        <div className=\"mx-auto px-4 sm:px-6 md:max-w-2xl md:px-4 lg:px-0\">{children}</div>\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/[expertUsername]/_components/expert-booker.tsx",
    "content": "\"use client\";\n\nimport { Booker, useEventTypesPublic } from \"@calcom/atoms\";\nimport type { CalAccount, User } from \"@prisma/client\";\nimport { Loader } from \"lucide-react\";\nimport { useRouter, useSearchParams } from \"next/navigation\";\nimport { toast } from \"sonner\";\n\n/**\n * [@calcom] Make sure to wrap your app with our `CalProvider` to enable the use of our hooks.\n * @link https://cal.com/docs/platform/quick-start#5.3-setup-root-of-your-app\n */\ntype BookerProps = Parameters<typeof Booker>[number];\nexport const ExpertBooker = (\n  props: {\n    className?: string;\n    calAccount: Pick<CalAccount, \"username\">;\n    expert: Pick<User, \"name\" | \"username\">;\n  } & Partial<BookerProps>\n) => {\n  const { className, calAccount, expert, ...rest } = props;\n  const router = useRouter();\n  const searchParams = useSearchParams();\n  const rescheduleUid = searchParams.get(\"rescheduleUid\") ?? undefined;\n  const { isLoading: isLoadingEvents, data: eventTypes } = useEventTypesPublic(calAccount.username ?? \"\");\n  if (!calAccount.username) {\n    return <div className=\"w-full text-center\">Sorry. We couldn&apos;t find this experts&apos; user.</div>;\n  }\n  if (isLoadingEvents) {\n    return (\n      <div className=\"flex items-center justify-center\">\n        <Loader className=\"z-50 animate-spin\" />\n      </div>\n    );\n  }\n  if (!eventTypes?.length) {\n    return (\n      <div className=\"w-full text-center\">Sorry. Unable to load ${expert.name}&apos;s availabilities.</div>\n    );\n  }\n\n  return (\n    <Booker\n      eventSlug={eventTypes[0]?.slug ?? \"\"}\n      username={calAccount.username}\n      onCreateBookingSuccess={(booking) => {\n        toast.success(\"Booking successful! \");\n        router.push(\n          `/${expert.username}/booking/${booking.data.uid}${booking.data.fromReschedule ? `?${new URLSearchParams({ fromReschedule: booking.data.fromReschedule }).toString()}` : \"\"}`\n        );\n      }}\n      rescheduleUid={rescheduleUid}\n      {...rest}\n    />\n  );\n};\nexport default ExpertBooker;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/[expertUsername]/booking/[bookingUid]/page.tsx",
    "content": "import { BookingResult } from \"@/app/_components/booking-result\";\nimport { Suspense } from \"react\";\n\nexport default function Booking() {\n  return (\n    <div className=\"flex items-center justify-center py-20\">\n      <Suspense>\n        <BookingResult />\n      </Suspense>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/[expertUsername]/layout.tsx",
    "content": "import { Logo } from \"../_components/universal/logo\";\nimport { SignedIn, SignedOut } from \"@/auth\";\nimport { Button } from \"@/components/ui/button\";\nimport { LogIn } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { type ReactNode } from \"react\";\n\nexport default function ExpertLayout({ children }: { children?: ReactNode }) {\n  return (\n    <div>\n      <header className=\"sticky top-0 z-50 flex h-14 items-center justify-between border-b border-border/40 bg-muted/90 px-4 py-2 backdrop-blur lg:h-[60px] lg:px-6\">\n        <Logo />\n        {/* \n        Tip: Use this for your own navigation\n        <Navigation /> */}\n        <div>\n          <SignedIn>\n            {(_user) => (\n              <Link href=\"/dashboard\">\n                <Button className=\"w-full\">\n                  Dashboard\n                  <LogIn className=\"ml-1 size-4\" />\n                </Button>\n              </Link>\n            )}\n          </SignedIn>\n          <SignedOut>\n            <Link href=\"/signup\">\n              <Button className=\"w-full\">Sign Up</Button>\n            </Link>\n          </SignedOut>\n        </div>\n      </header>\n\n      <main>{children}</main>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/[expertUsername]/page.tsx",
    "content": "import { cal } from \"@/cal/api\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"@/components/ui/table\";\nimport { ArrowRight } from \"lucide-react\";\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { db } from \"prisma/client\";\n\nexport const dynamic = \"force-dynamic\";\nexport default async function ExpertDetails({ params }: { params: { expertUsername: string } }) {\n  const expert = await db.user.findUnique({\n    where: { username: params.expertUsername },\n    select: {\n      id: true,\n      calAccessToken: true,\n      calRefreshToken: true,\n      calAccountId: true,\n      name: true,\n      username: true,\n      bio: true,\n      calAccount: {\n        select: {\n          id: true,\n          username: true,\n        },\n      },\n    },\n  });\n  if (!expert?.calAccount?.username) {\n    console.warn(\"Expert not found\", params.expertUsername);\n    return <div>Expert not found</div>;\n  }\n  const eventTypes = await cal({\n    user: {\n      calAccessToken: expert.calAccessToken,\n      calRefreshToken: expert.calRefreshToken,\n      calAccountId: expert.calAccountId,\n      id: expert.id,\n    },\n  }).get(\"/v2/event-types/{username}/public\", {\n    path: {\n      username: expert.calAccount.username,\n    },\n  });\n  if (eventTypes.status === \"error\") {\n    console.warn(\n      `[ExpertDetails] Event not found for expert username '${params.expertUsername}'. Check logs above for more info.`\n    );\n  }\n  return (\n    <div className=\"mb-4 flex flex-1 flex-col items-center gap-4 overflow-auto\">\n      <header className=\"flex w-full flex-col justify-between gap-4 rounded-md bg-muted/50 px-8 py-4  sm:px-10 lg:flex-row lg:px-12 2xl:px-36\">\n        <div className=\"flex items-center gap-x-6\">\n          <Image\n            alt=\"Expert image\"\n            className=\"aspect-square rounded-md object-cover\"\n            src={`avatars/${expert.id}`}\n            height=\"64\"\n            width=\"64\"\n          />\n          <div>\n            <h1 className=\"text-2xl font-semibold capitalize leading-none tracking-tight\">{expert.name}</h1>\n          </div>\n        </div>\n      </header>\n      <div className=\"mx-auto mt-4 grid w-full gap-2 px-8 sm:px-10 lg:px-12 2xl:px-36\">\n        <Card className=\"sm:col-span-2\">\n          <CardHeader className=\"pb-3\">\n            <CardTitle>About Us</CardTitle>\n            <p className=\"max-w-lg text-balance leading-relaxed\">{expert.bio}</p>\n          </CardHeader>\n        </Card>\n      </div>\n      <div className=\"mx-auto mt-4 grid w-full gap-2 px-8 sm:px-10 lg:px-12 2xl:px-36\">\n        {eventTypes.status === \"error\" ? (\n          <div>User Events not found</div>\n        ) : (\n          <Card>\n            <CardHeader>\n              <CardTitle>Book Us</CardTitle>\n              <CardDescription>Book us for any of the below events.</CardDescription>\n            </CardHeader>\n            <CardContent>\n              <Table>\n                <TableHeader>\n                  <TableRow>\n                    <TableHead>Name</TableHead>\n                    <TableHead className=\"hidden md:table-cell\">Description</TableHead>\n                    <TableHead>Duration (min)</TableHead>\n                    <TableHead>\n                      <span className=\"sr-only\">Availability</span>\n                    </TableHead>\n                  </TableRow>\n                </TableHeader>\n                <TableBody>\n                  {eventTypes.data.map((eventType) => (\n                    <TableRow key={eventType.id}>\n                      <TableCell>\n                        <Link href={`/${expert.username}/${eventType.slug}`}>\n                          <div className=\"font-medium capitalize\">{eventType.title}</div>\n                          <div className=\"text-sm text-muted-foreground\">/{eventType.slug}</div>\n                        </Link>\n                      </TableCell>\n                      <TableCell>\n                        <div className=\"hidden text-sm text-muted-foreground md:inline\">\n                          {eventType.description}\n                        </div>\n                      </TableCell>\n                      <TableCell>{eventType.length}</TableCell>\n                      <TableCell>\n                        <Link href={`/${expert.username}/${eventType.slug}`}>\n                          <Button variant=\"ghost\" size=\"icon\">\n                            <ArrowRight className=\"size-5 hover:size-6\" />\n                          </Button>\n                        </Link>\n                      </TableCell>\n                    </TableRow>\n                  ))}\n                </TableBody>\n              </Table>\n            </CardContent>\n            <CardFooter>\n              <div className=\"text-xs text-muted-foreground\">\n                Showing{\" \"}\n                <strong>\n                  {eventTypes.data.length > 0 ? 1 : 0}-\n                  {eventTypes.data.length > 10 ? 10 : eventTypes.data.length}\n                </strong>{\" \"}\n                of <strong>{eventTypes.data.length}</strong> event types\n              </div>\n            </CardFooter>\n          </Card>\n        )}\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_actions.tsx",
    "content": "\"use server\";\n\nimport { type LoginFormState } from \"./login/_components/login\";\nimport { LoginSchema, SignupSchema, auth, signIn, unstable_update, FiltersSchema } from \"@/auth\";\nimport { type User } from \"@prisma/client\";\nimport { type Prisma } from \"@prisma/client\";\nimport { AuthError } from \"next-auth\";\nimport { revalidatePath } from \"next/cache\";\nimport { isRedirectError } from \"next/dist/client/components/redirect\";\nimport { db } from \"prisma/client\";\nimport { z } from \"zod\";\n\nexport async function signInWithCredentials(_prevState: LoginFormState, formData: FormData) {\n  try {\n    const credentials = LoginSchema.safeParse({\n      email: formData.get(\"email\"),\n      password: formData.get(\"password\"),\n    });\n\n    if (!credentials.success) {\n      return {\n        inputErrors: credentials.error.flatten().fieldErrors,\n      };\n    }\n\n    await signIn(\"credentials\", formData);\n    return { error: null };\n  } catch (error) {\n    if (isRedirectError(error)) throw error;\n\n    if (error instanceof AuthError) {\n      switch (error.type) {\n        case \"CredentialsSignin\":\n          return { error: \"Invalid credentials.\" };\n        default:\n          console.error(\"Uncaught error signing in (AuthError): \", error);\n          return { error: \"Something went wrong.\" };\n      }\n    }\n    console.error(\"Uncaught error signing in\", error);\n    throw error;\n  }\n}\n\nexport async function addUserFilters(_prevState: { error?: string | null }, formData: FormData) {\n  try {\n    const sesh = await auth();\n\n    if (!sesh?.user?.id) return { error: \"User not logged in \" };\n\n    const filters = FiltersSchema.safeParse({\n      categories: formData.get(\"categories\"),\n      capabilities: formData.get(\"capabilities\"),\n      frameworks: formData.get(\"frameworks\"),\n      budgets: formData.get(\"budgets\"),\n      languages: formData.get(\"languages\"),\n      regions: formData.get(\"regions\"),\n    });\n\n    if (!filters.success) {\n      return {\n        inputErrors: filters.error.flatten().fieldErrors,\n      };\n    }\n\n    const selectedFilterOptions = [\n      { filterOpdtionFieldIds: filters.data.budgets, filterCategoryFieldId: \"budgets\" },\n      { filterOpdtionFieldIds: filters.data.capabilities, filterCategoryFieldId: \"capabilities\" },\n      { filterOpdtionFieldIds: filters.data.categories, filterCategoryFieldId: \"categories\" },\n      { filterOpdtionFieldIds: filters.data.frameworks, filterCategoryFieldId: \"frameworks\" },\n      { filterOpdtionFieldIds: filters.data.languages, filterCategoryFieldId: \"languages\" },\n    ]\n      .map(({ filterOpdtionFieldIds, filterCategoryFieldId }) => {\n        return filterOpdtionFieldIds.map((fieldId) => {\n          return {\n            filterCategoryFieldId,\n            filterOptionFieldId: fieldId,\n            userId: sesh?.user.id,\n          };\n        });\n      })\n      // to filter out any null values:\n      .filter(Boolean) as Prisma.FilterOptionsOnUserCreateManyInput[][];\n\n    const data = selectedFilterOptions.flat();\n\n    const createOrUpdateFilterPromises: Array<Promise<any>> = [];\n\n    for (const filter of data) {\n      createOrUpdateFilterPromises.push(\n        db.filterOptionsOnUser.upsert({\n          where: {\n            userId_filterOptionFieldId_filterCategoryFieldId: {\n              userId: filter.userId,\n              filterOptionFieldId: filter.filterOptionFieldId,\n              filterCategoryFieldId: filter.filterCategoryFieldId,\n            },\n          },\n          update: filter,\n          create: filter,\n        })\n      );\n    }\n\n    await Promise.all(createOrUpdateFilterPromises);\n\n    return { success: true };\n  } catch (err) {\n    throw err;\n  }\n}\n\nexport async function signUpWithCredentials(_prevState: { error?: string | null }, formData: FormData) {\n  try {\n    const credentials = SignupSchema.safeParse({\n      name: formData.get(\"name\"),\n      username: formData.get(\"username\"),\n      email: formData.get(\"email\"),\n      password: formData.get(\"password\"),\n    });\n\n    if (!credentials.success) {\n      return {\n        inputErrors: credentials.error.flatten().fieldErrors,\n      };\n    }\n\n    await signIn(\"credentials\", formData);\n    return { error: null };\n  } catch (error) {\n    if (isRedirectError(error)) throw error;\n\n    if (error instanceof AuthError) {\n      switch (error.type) {\n        case \"CredentialsSignin\":\n          return { error: \"Invalid credentials.\" };\n        default:\n          console.error(\"Uncaught error signing in (AuthError): \", error);\n          return { error: \"Something went wrong.\" };\n      }\n    }\n    console.error(\"Uncaught error signing in\", error);\n    throw error;\n  }\n}\n\nexport async function expertEdit(\n  _prevState: { error: null | string } | { success: null | string },\n  formData: FormData\n) {\n  console.log(\"[_actions] Updating expert with form data: \", formData);\n  const sesh = await auth();\n  if (!sesh?.user.id) {\n    console.log(\"[_actions] Unauthorized user edit\", formData);\n    return { error: \"Unauthorized\" };\n  }\n  const formDataWithoutActionFields = Object.fromEntries(\n    Array.from(formData.entries()).filter(([key]) => !key.toLowerCase().startsWith(\"$action\"))\n  );\n  const userEdit = z\n    .object({\n      name: z.string().min(1).max(255),\n    })\n    .or(z.object({ bio: z.string().min(1).max(255) }))\n    .safeParse(formDataWithoutActionFields);\n\n  if (!userEdit.success) {\n    console.log(\"[_actions] Inavlid form data\", formData);\n    return { error: \"Invalid form data\" };\n  }\n\n  const key = Object.keys(userEdit.data)[0];\n  if (!key) {\n    console.error(\"[_actions] Invalid form data\", formData);\n    return { error: \"Invalid form data\" };\n  }\n  let user: User | null;\n  try {\n    user = await db.user.update({\n      where: { id: sesh.user.id },\n      data: {\n        // @ts-expect-error - key as \"name\" | \"bio\" didn't work -- not sure why\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n        [key]: userEdit.data[key],\n      },\n    });\n  } catch (error) {\n    console.error(\"Uncaught error updating expert\", error);\n    return { error: \"Internal Server Error\" };\n  }\n  revalidatePath(\"/dashboard/settings/profile\");\n  await unstable_update({ user: { name: user.name } });\n\n  // @ts-expect-error - key as \"name\" | \"bio\" didn't work -- not sure why\n  return { success: `Successfully updated your ${key} to: '${userEdit.data[key]}'.` };\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/autocomplete.tsx",
    "content": "\"use client\";\n\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@/components/ui/command\";\nimport { cn } from \"@/lib/utils\";\nimport { Check } from \"lucide-react\";\nimport { useRouter } from \"next/navigation\";\nimport React, { forwardRef, useState } from \"react\";\n\nexport const defaultSort = {\n  title: \"Relevance\",\n  slug: null,\n  sortKey: \"RELEVANCE\",\n  reverse: false,\n};\n\nexport const sorting = [\n  defaultSort,\n  {\n    title: \"Availability\",\n    slug: \"available-desc\",\n    sortKey: \"MOST_AVAILABLE\",\n    reverse: false,\n  }, // asc\n];\nexport type Option = { value: string; label: string };\n\nexport interface AutocompleteSearchProps extends React.ComponentPropsWithoutRef<typeof Command> {\n  className?: string;\n  options: Array<Option>;\n  initialSearch?: string;\n  placement?: \"header\";\n}\nexport const AutocompleteSearch = forwardRef<HTMLDivElement, AutocompleteSearchProps>(\n  ({ className, placement, options, initialSearch, ...props }, ref) => {\n    const initialSeletion = options.find((option) => option.value === initialSearch);\n    const [value, setValue] = useState(initialSeletion?.value ?? \"\");\n    const [open, setOpen] = useState(false);\n    const [query, setQuery] = useState(initialSeletion?.label ?? \"\");\n    const router = useRouter();\n\n    return (\n      <div\n        className=\"relative z-10\"\n        onBlur={(e) => {\n          if (e.currentTarget.contains(e.relatedTarget)) return;\n\n          if (value && !query) {\n            setQuery(options.find((option) => option.value === value)?.label ?? \"\");\n          }\n          setOpen(false);\n        }}>\n        <Command\n          data-open={open}\n          className={cn(\"data-[open=true]:rounded-b-none\", placement === \"header\" && \"border\", className)}\n          ref={ref}\n          {...props}>\n          <CommandInput\n            value={query}\n            placeholder=\"Search an expert...\"\n            onFocus={() => {\n              setOpen(true);\n              if (query === options.find((option) => option.value === value)?.label) {\n                setQuery(\"\");\n              }\n            }}\n            onValueChange={(value) => setQuery(value)}\n            className=\"h-full justify-center leading-[2.75rem]\"\n          />\n\n          <CommandList>\n            {open && (\n              <div\n                data-open={open}\n                className={cn(\n                  \"absolute left-0 right-0 top-full rounded-b-md bg-background p-0 shadow !duration-150 data-[open=true]:animate-in data-[open=true]:fade-in\",\n                  placement === \"header\" && \"border-x border-b\"\n                )}>\n                <CommandEmpty>No expert found.</CommandEmpty>\n                <CommandGroup>\n                  {options.map((option) => (\n                    <CommandItem\n                      key={option.value}\n                      value={option.value}\n                      onSelect={(newValue) => {\n                        setValue(newValue);\n                        setQuery(options.find((option) => option.value === newValue)?.label ?? \"\");\n\n                        setOpen(false);\n\n                        router.push(`/experts?${new URLSearchParams({ q: newValue }).toString()}`, {\n                          scroll: false,\n                        });\n                      }}>\n                      <Check\n                        className={cn(\"mr-2 h-4 w-4\", value === option.value ? \"opacity-100\" : \"opacity-0\")}\n                      />\n                      {option.label}\n                    </CommandItem>\n                  ))}\n                </CommandGroup>\n              </div>\n            )}\n          </CommandList>\n        </Command>\n      </div>\n    );\n  }\n);\n\nAutocompleteSearch.displayName = \"AutocompleteSearch\";\n\nexport default AutocompleteSearch;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/banner.tsx",
    "content": "import { Button } from \"@/components/ui/button\";\n\nexport default function Banner({\n  title,\n  description,\n  ctaLink,\n}: {\n  title: string;\n  description: string;\n  ctaLink: string;\n}) {\n  return (\n    <div className=\"relative isolate z-50 flex items-center gap-x-6 overflow-hidden bg-gray-50 px-6 py-2.5 sm:px-3.5 sm:before:flex-1\">\n      <div\n        className=\"absolute left-[max(-7rem,calc(50%-52rem))] top-1/2 -z-10 -translate-y-1/2 transform-gpu blur-2xl\"\n        aria-hidden=\"true\">\n        <div\n          className=\"aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-[#ff80b5] to-[#9089fc] opacity-30\"\n          style={{\n            clipPath:\n              \"polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)\",\n          }}\n        />\n      </div>\n      <div\n        className=\"absolute left-[max(45rem,calc(50%+8rem))] top-1/2 -z-10 -translate-y-1/2 transform-gpu blur-2xl\"\n        aria-hidden=\"true\">\n        <div\n          className=\"aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-[#ff80b5] to-[#9089fc] opacity-30\"\n          style={{\n            clipPath:\n              \"polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)\",\n          }}\n        />\n      </div>\n      <div className=\"flex flex-wrap items-center gap-x-4 gap-y-2\">\n        <p className=\"text-sm leading-6 text-gray-900\">\n          <strong className=\"font-semibold\">{title}</strong>\n          <svg viewBox=\"0 0 2 2\" className=\"mx-2 inline h-0.5 w-0.5 fill-current\" aria-hidden=\"true\">\n            <circle cx={1} cy={1} r={1} />\n          </svg>\n          {description}\n        </p>\n\n        <a href=\"https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Ftree%2Fmain&env=NEXT_PUBLIC_REFRESH_URL,AUTH_SECRET,AUTH_TRUST_HOST,NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID,NEXT_PUBLIC_CAL_API_URL,CAL_SECRET&envDescription=You%20can%20see%20how%20to%20populate%20the%20environment%20variables%20in%20our%20starter%20example%20→&envLink=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Ftree%2Fmain%2F.env.example&project-name=cal-platform-starter&repository-name=cal-platform-starter&demo-title=Cal.com%20Experts&demo-description=A%20marketplace%20to%20book%20appointments%20with%20experts&demo-url=https%3A%2F%2Fexperts.cal.com&demo-image=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Fassets%2F8019099%2F2e58f8da-a110-4a45-b9a4-dcffb45f9baa&integration-ids=oac_VqOgBHqhEoFTPzGkPd7L0iH6&external-id=https%3A%2F%2Fgithub.com%2Fcalcom%2Fplatform-starter-kit%2Ftree%2Fmain\">\n          <Button size=\"sm\" className=\"flex h-[32px] w-[103px] gap-2\" variant=\"default\">\n            <svg\n              className=\"size-5\"\n              // width=\"24\"\n              // height=\"24\"\n              viewBox=\"0 0 76 65\"\n              fill=\"#fff\"\n              xmlns=\"http://www.w3.org/2000/svg\">\n              <path d=\"M37.5274 0L75.0548 65H0L37.5274 0Z\" fill=\"#fff\" />\n            </svg>\n            Deploy\n          </Button>\n        </a>\n        <a href={ctaLink}>\n          <Button size=\"icon\" className=\"flex h-[32px] gap-2\" variant=\"ghost\">\n            <svg\n              className=\"size-5 fill-black\"\n              // width=\"24\"\n              // height=\"24\"\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              xmlns=\"http://www.w3.org/2000/svg\">\n              <path\n                fillRule=\"evenodd\"\n                clipRule=\"evenodd\"\n                d=\"M12 2C6.477 2 2 6.484 2 12.017C2 16.442 4.865 20.197 8.839 21.521C9.339 21.613 9.521 21.304 9.521 21.038C9.521 20.801 9.513 20.17 9.508 19.335C6.726 19.94 6.139 17.992 6.139 17.992C5.685 16.834 5.029 16.526 5.029 16.526C4.121 15.906 5.098 15.918 5.098 15.918C6.101 15.988 6.629 16.95 6.629 16.95C7.521 18.48 8.97 18.038 9.539 17.782C9.631 17.135 9.889 16.694 10.175 16.444C7.955 16.191 5.62 15.331 5.62 11.493C5.62 10.4 6.01 9.505 6.649 8.805C6.546 8.552 6.203 7.533 6.747 6.155C6.747 6.155 7.587 5.885 9.497 7.181C10.3128 6.95851 11.1544 6.84519 12 6.844C12.85 6.848 13.705 6.959 14.504 7.181C16.413 5.885 17.251 6.154 17.251 6.154C17.797 7.533 17.453 8.552 17.351 8.805C17.991 9.505 18.379 10.4 18.379 11.493C18.379 15.341 16.04 16.188 13.813 16.436C14.172 16.745 14.491 17.356 14.491 18.291C14.491 19.629 14.479 20.71 14.479 21.038C14.479 21.306 14.659 21.618 15.167 21.52C17.1583 20.8521 18.8893 19.5753 20.1155 17.87C21.3416 16.1648 22.0009 14.1173 22 12.017C22 6.484 17.522 2 12 2Z\"></path>\n            </svg>\n          </Button>\n        </a>\n      </div>\n      <div className=\"flex flex-1 justify-end\">\n        <button type=\"button\" className=\"-m-3 p-3 focus-visible:outline-offset-[-4px]\">\n          <span className=\"sr-only\">Dismiss</span>\n        </button>\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/booking-result.tsx",
    "content": "\"use client\";\n\nimport { stripCalOAuthClientIdFromEmail, stripCalOAuthClientIdFromText } from \"@/cal/utils\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Card, CardContent, CardFooter, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { cn } from \"@/lib/utils\";\nimport { useGetBooking, useCancelBooking } from \"@calcom/atoms\";\nimport dayjs from \"dayjs\";\nimport { Check, ExternalLinkIcon, Loader, X } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { useParams, useSearchParams } from \"next/navigation\";\nimport type { BookingStatus } from \"node_modules/@calcom/atoms/dist/packages/prisma/enums\";\n\nexport const BookingResult = (props: {\n  expertusername?: string;\n  bookingUid?: string;\n  fromReschedule?: string;\n}) => {\n  const params = useParams<{ expertUsername: string; bookingUid: string }>();\n  const expertUsername = props?.expertusername ?? params.expertUsername;\n  const bookingUid = props?.bookingUid ?? params.bookingUid;\n  const searchParams = useSearchParams();\n  const fromReschedule = props?.fromReschedule ?? searchParams.get(\"fromReschedule\");\n  const { isLoading, data: booking, refetch } = useGetBooking(bookingUid ?? \"\");\n  // TODO: We're doing this to cast the type since @calcom/atoms doesn't type them properly\n  const bookingStatus = booking && \"status\" in booking ? (booking.status as BookingStatus) : undefined;\n  const { mutate: cancelBooking } = useCancelBooking({\n    // eslint-disable-next-line @typescript-eslint/no-misused-promises\n    onSuccess: async () => {\n      await refetch();\n    },\n  });\n  //   [@calcom] The API returns the UID of the previous booking in case you'd like to show changed booking details in your UI.\n  const bookingPrevious = useGetBooking(fromReschedule ?? \"\");\n  if (!bookingUid) {\n    return <div>No Booking UID.</div>;\n  }\n\n  if (isLoading) {\n    return <Loader className=\"z-50 animate-spin place-self-center\" />;\n  }\n\n  if (!booking) {\n    return <div>Booking not found</div>;\n  }\n\n  const what = stripCalOAuthClientIdFromText(booking.title) ?? booking.title;\n  const formerWhat = bookingPrevious?.data\n    ? stripCalOAuthClientIdFromText(bookingPrevious?.data?.title)\n    : null;\n\n  const when = `${dayjs(booking.startTime).format(\"dddd, MMMM DD YYYY @ h:mma\")} (${booking?.user?.timeZone})`;\n  const formerWhen = bookingPrevious.data\n    ? `${dayjs(bookingPrevious.data.startTime).format(\"dddd, MMMM DD YYYY @ h:mma\")} (${bookingPrevious?.data?.user?.timeZone})`\n    : null;\n\n  const who = {\n    host: `${booking?.user?.name} (Host) - ${stripCalOAuthClientIdFromEmail(booking?.user?.email ?? \"\")}`,\n    attendees: booking.attendees.map(\n      (attendee) => `${attendee.name ? `${stripCalOAuthClientIdFromText(attendee.name)} - ` : \"\"} \n${stripCalOAuthClientIdFromEmail(attendee.email)}`\n    ),\n  };\n  const formerWho = bookingPrevious?.data\n    ? {\n        host: `${bookingPrevious.data?.user?.name} (Host) - ${stripCalOAuthClientIdFromEmail(bookingPrevious.data?.user?.email ?? \"\")}`,\n        attendees: bookingPrevious.data.attendees.map(\n          (\n            previousAttendee\n          ) => `${previousAttendee.name ? `${stripCalOAuthClientIdFromText(previousAttendee.name)} - ` : \"\"} \n${stripCalOAuthClientIdFromEmail(previousAttendee.email)}`\n        ),\n      }\n    : null;\n\n  return (\n    <Card className=\"w-full max-w-lg\">\n      <CardHeader className=\"space-y-4 px-8\">\n        <div className=\"flex items-center justify-center space-x-2\">\n          {bookingStatus?.toLowerCase() === \"cancelled\" && (\n            <div className=\"flex flex-col items-center space-y-4\">\n              <div className=\"mx-auto flex size-12 items-center justify-center rounded-full bg-destructive/50\">\n                <X className=\"size-6 text-destructive\" />\n              </div>\n              <CardTitle className=\"text-2xl\">Meeting Cancelled</CardTitle>\n            </div>\n          )}\n          {bookingStatus?.toLowerCase() === \"accepted\" && (\n            <div className=\"flex flex-col items-center space-y-4\">\n              <div className=\"mx-auto flex size-12 items-center justify-center rounded-full bg-success\">\n                <Check className=\"size-6 text-green-600\" />\n              </div>\n              <CardTitle className=\"text-2xl\">Meeting scheduled successfully</CardTitle>\n            </div>\n          )}\n        </div>\n      </CardHeader>\n      <CardContent className=\"p-6 px-8 pt-2 text-sm\">\n        <Separator className=\"mb-8\" />\n        <div className=\"grid gap-3\">\n          <ul className=\"grid gap-3\">\n            <li className=\"flex flex-col\">\n              <span className=\"space-y-0.5 font-semibold\">What</span>\n              {formerWhat !== what && (\n                <span className={cn(\"text-muted-foreground line-through\")}>{formerWhat}</span>\n              )}\n              <span\n                className={cn(\n                  \"text-muted-foreground\",\n                  bookingStatus?.toLowerCase() === \"cancelled\" && \"line-through\"\n                )}>\n                {what}\n              </span>\n            </li>\n            <li className=\"flex flex-col\">\n              <span className=\"space-y-0.5 font-semibold\">When</span>\n              {formerWhen !== when && (\n                <span className={cn(\"text-muted-foreground line-through\")}>{formerWhen}</span>\n              )}\n              <span\n                className={cn(\n                  \"text-muted-foreground\",\n                  bookingStatus?.toLowerCase() === \"cancelled\" && \"line-through\"\n                )}>\n                {when}\n              </span>\n            </li>\n            <li className=\"flex flex-col\">\n              <span className=\"font-semibold\">Who</span>\n              <ul className=\"space-y-0.5\">\n                <li\n                  className={cn(\n                    \"text-muted-foreground\",\n                    bookingStatus?.toLowerCase() === \"cancelled\" && \"line-through\"\n                  )}>\n                  {who.host}\n                </li>\n                {who.attendees.map((attendee, idx) => (\n                  <li\n                    key={idx}\n                    className={cn(\n                      \"text-muted-foreground\",\n                      bookingStatus?.toLowerCase() === \"cancelled\" && \"line-through\"\n                      // // if the attendee is not in the previous booking, we'll highlight them\n                      // formerWho?.attendees?.findIndex((formerAttendee) => formerAttendee === attendee) ===\n                      //   -1 && \"font-semibold italic\"\n                    )}>\n                    {attendee}\n                    {formerWho?.attendees?.findIndex((formerAttendee) => formerAttendee === attendee) ===\n                      -1 && (\n                      <Badge className=\"ml-2 px-1.5 py-[0.05rem] text-xs font-normal leading-none\">New</Badge>\n                    )}\n                  </li>\n                ))}\n                {formerWho?.attendees?.map(\n                  (formerAttendee, idx) =>\n                    // if the attendee is in the current booking, we've already displayed them\n                    who.attendees.findIndex((attendee) => attendee === formerAttendee) === -1 && (\n                      <li\n                        key={idx}\n                        className={cn(\n                          \"text-muted-foreground\",\n                          // if the attendee is not in the current booking, we'll strike them out\n                          who.attendees.findIndex((attendee) => attendee === formerAttendee) === -1 &&\n                            \"line-through\"\n                        )}>\n                        {formerAttendee}\n                      </li>\n                    )\n                )}\n              </ul>\n            </li>\n            <li className=\"flex flex-col\">\n              <span className=\"space-y-0.5 font-semibold\">Where</span>\n              {/* Display the previous location only if it's different from the current booking */}\n              {bookingPrevious.data?.location !== booking.location && (\n                <span className={cn(\"text-muted-foreground\")}>\n                  {bookingPrevious.data?.location === \"integrations:daily\" ? (\n                    <span className=\"border-b-0 border-transparent hover:border-b hover:border-current\">\n                      <Link\n                        className={cn(\"inline-flex items-center gap-1\")}\n                        href={\n                          (bookingPrevious.data?.metadata as { videoCallUrl?: string })?.videoCallUrl ?? \"#\"\n                        }>\n                        Online (Cal Video)\n                      </Link>\n                    </span>\n                  ) : (\n                    bookingPrevious.data?.location\n                  )}\n                </span>\n              )}\n              {/* Display the location of the current booking */}\n              <span\n                className={cn(\n                  \"text-muted-foreground\",\n                  bookingPrevious.data?.location !== booking.location && \"line-through\"\n                )}>\n                {booking?.location === \"integrations:daily\" ? (\n                  <span className=\"border-b-0 border-transparent hover:border-b hover:border-current\">\n                    <Link\n                      className={cn(\n                        \"inline-flex items-center gap-1\",\n                        bookingStatus?.toLowerCase() === \"cancelled\" && \"line-through\",\n                        bookingStatus?.toLowerCase() === \"cancelled\" && \"cursor-not-allowed\"\n                      )}\n                      href={\n                        bookingStatus?.toLowerCase() === \"cancelled\"\n                          ? \"#\"\n                          : (booking?.metadata as { videoCallUrl?: string })?.videoCallUrl ?? \"#\"\n                      }>\n                      Online (Cal Video)\n                      <ExternalLinkIcon className=\"size-4\" />\n                    </Link>\n                  </span>\n                ) : (\n                  booking.location\n                )}\n              </span>\n            </li>\n            {booking.description && (\n              <li className=\"flex flex-col\">\n                <span className=\"space-y-0.5 font-semibold\">Event Description</span>\n                {booking.description !== bookingPrevious.data?.description && (\n                  <span className={cn(\"text-muted-foreground line-through\")}>\n                    {bookingPrevious?.data?.description}\n                  </span>\n                )}\n                <span\n                  className={cn(\n                    \"text-muted-foreground\",\n                    bookingStatus?.toLowerCase() === \"cancelled\" && \"line-through\"\n                  )}>\n                  {booking.description}\n                </span>\n              </li>\n            )}\n          </ul>\n        </div>\n        <Separator className=\"mt-8\" />\n      </CardContent>\n      <CardFooter className=\"flex flex-col px-8\">\n        {bookingStatus?.toLowerCase() === \"cancelled\" ? (\n          <div>\n            <span>Want to book {booking?.user?.name}?</span>\n            <span>\n              {\" \"}\n              See{\" \"}\n              <Link href={`/${expertUsername}`} className=\"underline\">\n                availabilities\n              </Link>\n            </span>\n          </div>\n        ) : (\n          <div>\n            <span>Need to make changes?</span>\n            <span>\n              {\" \"}\n              <Link href={`/${expertUsername}?rescheduleUid=${bookingUid}`} className=\"underline\">\n                Reschedule\n              </Link>{\" \"}\n              or{\" \"}\n              <div\n                className=\"cursor-pointer underline\"\n                onClick={() => {\n                  return cancelBooking({\n                    id: booking.id,\n                    uid: booking.uid,\n                    cancellationReason: \"User request\",\n                    allRemainingBookings: true,\n                  });\n                }}>\n                Cancel\n              </div>\n            </span>\n          </div>\n        )}\n      </CardFooter>\n    </Card>\n  );\n};\n\nexport default BookingResult;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/home/results.tsx",
    "content": "\"use client\";\n\nimport { SearchBar } from \"../search-bar\";\nimport SidebarItem from \"./sidebar-item\";\nimport { filterOptions } from \"@/app/_hardcoded\";\nimport { filterSearchParamSchema } from \"@/app/_searchParams\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Label } from \"@/components/ui/label\";\nimport { Sheet, SheetContent, SheetTrigger } from \"@/components/ui/sheet\";\nimport { cn } from \"@/lib/utils\";\nimport { type FilterOption, type User } from \"@prisma/client\";\nimport { ListFilter, Loader } from \"lucide-react\";\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { useQueryState, parseAsString, parseAsJson } from \"nuqs\";\nimport { type db } from \"prisma/client\";\nimport { Fragment, type ReactEventHandler, useState, type SyntheticEvent } from \"react\";\nimport React, { Suspense } from \"react\";\nimport { Balancer } from \"react-wrap-balancer\";\nimport { prop, uniqueBy } from \"remeda\";\n\nexport default function ResultsCard({\n  slug,\n  userId,\n  title,\n  description,\n  query,\n}: {\n  slug: string;\n  userId?: string;\n  title: string;\n  description: string;\n  query?: string;\n}) {\n  const queryIndexTitle = title.toLowerCase().indexOf(query?.toLowerCase() ?? \"\");\n  const queryIndexDescription = description.toLowerCase().indexOf(query?.toLowerCase() ?? \"\");\n  const [error, setError] = useState<SyntheticEvent<HTMLImageElement, Event> | null>(null);\n  const [isLoading, setIsLoading] = useState(true);\n\n  return (\n    <Link href={\"/\" + slug} className=\"col-span-1 flex\">\n      <Card className=\"mx-auto overflow-hidden transition-all ease-in-out hover:rotate-1 hover:scale-105 hover:shadow-lg\">\n        <div\n          className={cn(\n            \"h-[265px] w-[380px] rounded-md\",\n            error && \"bg-muted\",\n            isLoading && \"animate-pulse bg-muted\"\n          )}>\n          {!error && (\n            <Image\n              src={`avatars/${userId}?width=380&height=265`}\n              alt={title}\n              className=\"h-full w-full rounded-md object-cover\"\n              height={265}\n              width={380}\n              objectFit=\"cover\"\n              onLoadingComplete={() => setIsLoading(false)}\n              onError={setError}\n            />\n          )}\n        </div>\n        <CardHeader>\n          <CardTitle className=\"text-xl\">\n            {/* this highlights the search query for the title */}\n            {queryIndexTitle != undefined && query ? (\n              <>\n                {title.substring(0, queryIndexTitle)}\n                <span className=\"bg-yellow-300\">\n                  {title.substring(queryIndexTitle, queryIndexTitle + query.length)}\n                </span>\n                {title.substring(queryIndexTitle + query.length)}\n              </>\n            ) : (\n              title\n            )}\n          </CardTitle>\n          <CardDescription>\n            {/* this highlights the search query for the title */}\n            {queryIndexDescription != undefined && query ? (\n              <>\n                {description.substring(0, queryIndexDescription)}\n                <span className=\"bg-yellow-300\">\n                  {description.substring(queryIndexDescription, queryIndexDescription + query.length)}\n                </span>\n                {description.substring(queryIndexDescription + query.length)}\n              </>\n            ) : (\n              description\n            )}\n          </CardDescription>\n        </CardHeader>\n      </Card>\n    </Link>\n  );\n}\ntype UsersWithFilterOptions = Awaited<\n  ReturnType<\n    typeof db.user.findMany<{\n      include: { selectedFilterOptions: { include: { filterOption: true } } };\n    }>\n  >\n>;\nexport function Results(props: { experts: UsersWithFilterOptions; signedOut: JSX.Element }) {\n  const [query] = useQueryState(\"q\", parseAsString);\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  const [filters] = useQueryState(\"f\", parseAsJson(filterSearchParamSchema.parse));\n  const filtersByCategory = uniqueBy(filterOptions, prop(\"filterCategoryFieldId\"));\n\n  // this is the query string search:\n  const experts = props.experts\n    .filter((expert) => {\n      if (!query) return true;\n      return (\n        expert?.name?.toLowerCase().includes(query?.toLowerCase()) ||\n        expert?.bio?.toLowerCase().includes(query?.toLowerCase())\n      );\n    })\n    // this is the filter search:\n    .filter((expert) => {\n      if (!filters) return true;\n      const expertSelectedOptions = expert.selectedFilterOptions ?? [];\n      // if we have filters selected, let's only show the experts who have all the selected filters:\n      return Object.entries(filters).every(([_filterCategoryFieldId, filterValues]) => {\n        if (!filterValues) return true;\n        return filterValues.every((filterValue) =>\n          expertSelectedOptions.find((option) => option.filterOption.fieldValue === filterValue)\n        );\n      });\n    });\n  return (\n    <Fragment>\n      <div\n        className=\"flex min-h-96 flex-col justify-center bg-cover bg-center bg-no-repeat py-20\"\n        style={{ backgroundImage: \"url('/hero.jpg')\" }}>\n        <div className=\"container mt-16 flex flex-col items-center justify-center gap-12 px-4 py-6\">\n          <h1 className=\"font-display text-5xl font-extrabold tracking-tight text-white\">\n            <Balancer>Find your Cal.com Expert</Balancer>\n          </h1>\n          <SearchBar />\n        </div>\n      </div>\n      <div className=\"flex-1\">\n        <div className=\"sm:my-10\">\n          <Suspense\n            fallback={\n              <div className=\"relative h-max w-full max-w-sm place-self-center\">\n                <div className=\"absolute inset-0 z-40 grid rounded-2xl bg-slate-900 text-white\">\n                  <Loader className=\"z-50 animate-spin place-self-center\" />\n                </div>\n              </div>\n            }>\n            <div className=\"block sm:flex\">\n              <div className=\"flex items-center gap-2 p-4\">\n                <Sheet>\n                  <SheetTrigger asChild>\n                    <Button variant=\"outline\" size=\"sm\" className=\"h-8 gap-1 sm:hidden\">\n                      <span>Filter</span>\n                      <ListFilter className=\"size-5\" />\n                    </Button>\n                  </SheetTrigger>\n                  <SheetContent side=\"left\" className=\"sm:max-w-xs\">\n                    {filtersByCategory.map((section) => (\n                      <div\n                        key={section.filterCategoryValue}\n                        className=\"mb-8 space-y-4 border-b border-gray-200 pb-8\">\n                        <p className=\"text-base font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n                          {section.filterCategoryLabel}\n                        </p>\n                        {filterOptions\n                          .filter(\n                            (filterOption) =>\n                              filterOption.filterCategoryFieldId === section.filterCategoryFieldId\n                          )\n                          .map((filterOption) => (\n                            <SidebarItem\n                              category={section.filterCategoryFieldId}\n                              key={filterOption.fieldId}\n                              id={filterOption.fieldId}\n                              label={filterOption.fieldLabel}\n                            />\n                          ))}\n                      </div>\n                    ))}\n                  </SheetContent>\n                </Sheet>\n              </div>\n              <aside className=\"hidden w-full overflow-scroll border-r border-gray-300 p-4 sm:max-h-full sm:w-72 sm:border-0 md:block\">\n                {filtersByCategory.map((section) => (\n                  <div\n                    key={section.filterCategoryValue}\n                    className=\"mb-8 space-y-4 border-b border-gray-200 pb-8\">\n                    <p className=\"text-base font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n                      {section.filterCategoryLabel}\n                    </p>\n                    {filterOptions\n                      .filter(\n                        (filterOption) => filterOption.filterCategoryFieldId === section.filterCategoryFieldId\n                      )\n                      .map((filterOption) => (\n                        <SidebarItem\n                          category={section.filterCategoryValue}\n                          key={filterOption.fieldId}\n                          id={filterOption.fieldId}\n                          label={filterOption.fieldLabel}\n                        />\n                      ))}\n                  </div>\n                ))}\n              </aside>\n              <main className=\"w-full p-4 pt-0\">\n                <div className=\"grid grid-cols-1 gap-4 space-x-2 md:grid-cols-3 2xl:grid-cols-4\">\n                  {!query && props.signedOut}\n                  {experts.length ? (\n                    experts.map(({ username, name, bio, id }) => (\n                      <ResultsCard\n                        key={username}\n                        slug={username ?? \"\"}\n                        userId={id ?? \"\"}\n                        title={name ?? \"Your title\"}\n                        description={bio ?? \"Your bio\"}\n                        query={query ?? undefined}\n                      />\n                    ))\n                  ) : (\n                    <Card className=\"mx-auto flex items-center\">\n                      <div>\n                        <CardHeader>\n                          <CardTitle className=\"text-xl\">No experts found</CardTitle>\n                          <CardDescription>\n                            We&rsquo;ve filtered our experts based on your search query and selected filters:\n                          </CardDescription>\n                        </CardHeader>\n                        <CardContent>\n                          <div className=\"grid gap-4 py-4\">\n                            <div className=\"grid grid-cols-4 items-center gap-4\">\n                              <Label className=\"text-right\">Query</Label>\n                              <p className=\"col-span-3 max-w-lg text-balance text-sm leading-relaxed\">\n                                {query ?? \"No search query provided\"}\n                              </p>\n                              <Label className=\"text-right\">Filters</Label>\n                              <p className=\"col-span-3 max-w-lg text-balance text-sm capitalize leading-relaxed\">\n                                {Object.keys(filters ?? {}).length\n                                  ? Object.entries(filters ?? {})\n                                      .map(([filterCategory, filterValues]) => {\n                                        return `${filterCategory}: ${filterValues.join(\", \")}`;\n                                      })\n                                      .join(\", \")\n                                  : \"No filters selected\"}\n                              </p>\n                            </div>\n                          </div>\n                        </CardContent>\n                      </div>\n                    </Card>\n                  )}\n                </div>\n              </main>\n            </div>\n          </Suspense>\n        </div>\n      </div>\n    </Fragment>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/home/sidebar-item.tsx",
    "content": "\"use client\";\n\nimport { type filterOptions } from \"@/app/_hardcoded\";\nimport { filterSearchParamSchema } from \"@/app/_searchParams\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Label } from \"@/components/ui/label\";\nimport { cn } from \"@/lib/utils\";\nimport { useQueryState, parseAsJson } from \"nuqs\";\n\nexport default function SidebarItem({\n  id,\n  label,\n  className,\n  category,\n  ...props\n}: {\n  className?: string;\n  id: (typeof filterOptions)[number][\"fieldId\"];\n  label: (typeof filterOptions)[number][\"fieldLabel\"];\n  category: (typeof filterOptions)[number][\"filterCategoryFieldId\"];\n} & React.ComponentPropsWithoutRef<typeof Checkbox>) {\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  const [filters, setFilters] = useQueryState(\"f\", parseAsJson(filterSearchParamSchema.parse));\n  const selectedIds = filters?.[category];\n\n  return (\n    <div className=\"flex items-center space-x-2\">\n      <Checkbox\n        id={id}\n        className={cn(className)}\n        // @ts-expect-error id could be anything\n        defaultChecked={selectedIds?.includes(id)}\n        onCheckedChange={async (checked) => {\n          const newSelectedIds = [\n            ...(selectedIds?.filter((selectedId) => selectedId !== id) || []),\n            ...(checked ? [id] : []),\n          ];\n          const newCategoryFilter = { [category]: newSelectedIds };\n\n          const { [category]: _, ...withoutCurrentCategory } = newCategoryFilter; // remove current category from filters\n\n          // include new category filter if there are selected ids\n          const newFilters = {\n            ...withoutCurrentCategory,\n            ...(newSelectedIds.length > 0 ? newCategoryFilter : {}),\n          };\n          await setFilters(newFilters);\n        }}\n        {...props}\n      />\n      <Label\n        htmlFor={id}\n        className=\"text-sm font-normal leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n        {label}\n      </Label>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/home/signup-card.tsx",
    "content": "import { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport Link from \"next/link\";\n\nexport const SignupCard = () => {\n  return (\n    <Card className=\"mx-auto flex items-center\">\n      <div>\n        <CardHeader>\n          <CardTitle className=\"text-xl\">\n            Are you an expert of <span className=\"font-display\">Cal.com</span>?\n          </CardTitle>\n          <CardDescription>\n            Sign up, connect your calendar and fill your schedule with exciting customers who need help with\n            anything Cal.com-related!\n          </CardDescription>\n        </CardHeader>\n        <CardContent>\n          <div className=\"grid gap-4\">\n            <Link href=\"/signup\">\n              <Button className=\"w-full\">Sign Up</Button>\n            </Link>\n          </div>\n          <div className=\"mt-4 text-center text-sm\">\n            Already have an account?{\" \"}\n            <Link href=\"/login\" className=\"underline\">\n              Log in\n            </Link>\n          </div>\n        </CardContent>\n      </div>\n    </Card>\n  );\n};\nexport default SignupCard;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/multi-select.tsx",
    "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Command, CommandGroup, CommandItem, CommandList } from \"@/components/ui/command\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { X } from \"lucide-react\";\nimport * as React from \"react\";\n\nexport type Option = Record<\"value\" | \"label\", string>;\n\nexport function FancyMultiSelect(\n  props: {\n    options: Array<Option>;\n    placeholder: string;\n  } & React.ComponentProps<typeof CommandPrimitive.Input>\n) {\n  const { options, id, name, ...inputProps } = props;\n  const initiallySelected = options?.[0];\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const [open, setOpen] = React.useState(false);\n  const [selected, setSelected] = React.useState<Array<Option | null>>([initiallySelected ?? null]);\n  const [inputValue, setInputValue] = React.useState(\"\");\n\n  const handleUnselect = React.useCallback((option: Option) => {\n    setSelected((prev) => prev.filter((s) => s?.value !== option.value));\n  }, []);\n\n  const handleKeyDown = React.useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {\n    const input = inputRef.current;\n    if (input) {\n      if (e.key === \"Delete\" || e.key === \"Backspace\") {\n        if (input.value === \"\") {\n          setSelected((prev) => {\n            const newSelected = [...prev];\n            newSelected.pop();\n            return newSelected;\n          });\n        }\n      }\n      // This is not a default behaviour of the <input /> field\n      if (e.key === \"Escape\") {\n        input.blur();\n      }\n    }\n  }, []);\n\n  const selectables = options.filter((option) => {\n    // Filter out already selected options\n    return !selected.some((selectedOption) => selectedOption?.value === option.value);\n  });\n\n  return (\n    <Command onKeyDown={handleKeyDown} className=\"overflow-visible bg-transparent\">\n      <div className=\"group rounded-md border border-input px-3 py-2 text-sm ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2\">\n        <div className=\"flex flex-wrap gap-1\">\n          {selected.map((option) => {\n            if (!option) return null;\n            return (\n              <Badge key={option.value} variant=\"secondary\">\n                {option.label}\n                <button\n                  className=\"ml-1 rounded-full outline-none ring-offset-background focus:ring-2 focus:ring-ring focus:ring-offset-2\"\n                  onKeyDown={(e) => {\n                    if (e.key === \"Enter\") {\n                      handleUnselect(option);\n                    }\n                  }}\n                  onMouseDown={(e) => {\n                    e.preventDefault();\n                    e.stopPropagation();\n                  }}\n                  onClick={() => handleUnselect(option)}>\n                  <X className=\"h-3 w-3 text-muted-foreground hover:text-foreground\" />\n                </button>\n              </Badge>\n            );\n          })}\n          {/* Avoid having the \"Search\" Icon */}\n          <CommandPrimitive.Input\n            ref={inputRef}\n            value={inputValue}\n            onValueChange={setInputValue}\n            onBlur={() => {\n              setOpen(false);\n            }}\n            onFocus={() => setOpen(true)}\n            className=\"ml-2 flex-1 bg-transparent outline-none placeholder:text-muted-foreground\"\n            {...inputProps}\n          />\n          <input hidden id={id} name={name} value={JSON.stringify(selected.map((s) => s?.value))} readOnly />\n        </div>\n      </div>\n      <div className=\"relative mt-2\">\n        {open && selectables.length > 0 ? (\n          <div className=\"absolute top-0 z-10 w-full rounded-md border bg-popover text-popover-foreground shadow-md outline-none animate-in\">\n            <CommandList>\n              <CommandGroup className=\"h-full overflow-auto\">\n                {selectables.map((option) => {\n                  return (\n                    <CommandItem\n                      key={option.value}\n                      onMouseDown={(e) => {\n                        e.preventDefault();\n                        e.stopPropagation();\n                      }}\n                      onSelect={(_value) => {\n                        setInputValue(\"\");\n                        setSelected((prev) => [...prev, option]);\n                      }}\n                      className={\"cursor-pointer\"}>\n                      {option.label}\n                    </CommandItem>\n                  );\n                })}\n              </CommandGroup>\n            </CommandList>\n          </div>\n        ) : null}\n      </div>\n    </Command>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/navigation.tsx",
    "content": "\"use client\";\n\nimport {\n  NavigationMenu,\n  NavigationMenuContent,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  NavigationMenuTrigger,\n  navigationMenuTriggerStyle,\n} from \"@/components/ui/navigation-menu\";\nimport { cn } from \"@/lib/utils\";\nimport Link from \"next/link\";\nimport * as React from \"react\";\n\nconst components: { title: string; href: string; description: string }[] = [\n  {\n    title: \"Alert Dialog\",\n    href: \"/docs/primitives/alert-dialog\",\n    description: \"A modal dialog that interrupts the user with important content and expects a response.\",\n  },\n  {\n    title: \"Hover Card\",\n    href: \"/docs/primitives/hover-card\",\n    description: \"For sighted users to preview content available behind a link.\",\n  },\n  {\n    title: \"Progress\",\n    href: \"/docs/primitives/progress\",\n    description:\n      \"Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.\",\n  },\n  {\n    title: \"Scroll-area\",\n    href: \"/docs/primitives/scroll-area\",\n    description: \"Visually or semantically separates content.\",\n  },\n  {\n    title: \"Tabs\",\n    href: \"/docs/primitives/tabs\",\n    description: \"A set of layered sections of content—known as tab panels—that are displayed one at a time.\",\n  },\n  {\n    title: \"Tooltip\",\n    href: \"/docs/primitives/tooltip\",\n    description:\n      \"A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.\",\n  },\n];\n\nexport function Navigation() {\n  return (\n    <NavigationMenu className=\"hidden rounded-full border-2 border-black p-0.5 md:block\">\n      <NavigationMenuList>\n        <NavigationMenuItem>\n          <NavigationMenuTrigger>Getting started</NavigationMenuTrigger>\n          <NavigationMenuContent>\n            <ul className=\"grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]\">\n              <li className=\"row-span-3\">\n                <NavigationMenuLink asChild>\n                  <a\n                    className=\"flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md\"\n                    href=\"/\">\n                    {/* \n                    <Icons.logo className=\"h-6 w-6\" /> */}\n                    <div className=\"mb-2 mt-4 text-lg font-medium\">shadcn/ui</div>\n                    <p className=\"text-sm leading-tight text-muted-foreground\">\n                      Beautifully designed components that you can copy and paste into your apps. Accessible.\n                      Customizable. Open Source.\n                    </p>\n                  </a>\n                </NavigationMenuLink>\n              </li>\n              <ListItem href=\"/docs\" title=\"Introduction\">\n                Re-usable components built using Radix UI and Tailwind CSS.\n              </ListItem>\n              <ListItem href=\"/docs/installation\" title=\"Installation\">\n                How to install dependencies and structure your app.\n              </ListItem>\n              <ListItem href=\"/docs/primitives/typography\" title=\"Typography\">\n                Styles for headings, paragraphs, lists...etc\n              </ListItem>\n            </ul>\n          </NavigationMenuContent>\n        </NavigationMenuItem>\n        <NavigationMenuItem>\n          <NavigationMenuTrigger>Components</NavigationMenuTrigger>\n          <NavigationMenuContent>\n            <ul className=\"grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] \">\n              {components.map((component) => (\n                <ListItem key={component.title} title={component.title} href={component.href}>\n                  {component.description}\n                </ListItem>\n              ))}\n            </ul>\n          </NavigationMenuContent>\n        </NavigationMenuItem>\n        <NavigationMenuItem>\n          <Link href=\"/docs\" legacyBehavior passHref>\n            <NavigationMenuLink className={navigationMenuTriggerStyle()}>Documentation</NavigationMenuLink>\n          </Link>\n        </NavigationMenuItem>\n      </NavigationMenuList>\n    </NavigationMenu>\n  );\n}\n\nconst ListItem = React.forwardRef<React.ElementRef<\"a\">, React.ComponentPropsWithoutRef<\"a\">>(\n  ({ className, title, children, ...props }, ref) => {\n    return (\n      <li>\n        <NavigationMenuLink asChild>\n          <a\n            ref={ref}\n            className={cn(\n              \"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent/50 hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\",\n              className\n            )}\n            {...props}>\n            <div className=\"text-sm font-medium leading-none\">{title}</div>\n            <p className=\"line-clamp-2 text-sm leading-snug text-muted-foreground\">{children}</p>\n          </a>\n        </NavigationMenuLink>\n      </li>\n    );\n  }\n);\nListItem.displayName = \"ListItem\";\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/search-bar.tsx",
    "content": "\"use client\";\n\nimport { Input } from \"@/components/ui/input\";\nimport { useQueryState, parseAsString } from \"nuqs\";\n\nexport const SearchBar = () => {\n  const [query, setQuery] = useQueryState(\"q\", parseAsString);\n\n  return (\n    <div className=\"w-full max-w-2xl\">\n      <Input\n        placeholder=\"Search for your expert, topic or more\"\n        className=\"h-14 w-full shadow-md\"\n        defaultValue={query ?? \"\"}\n        onChange={async (e) => {\n          // append the query to the URL\n          await setQuery(e.target.value);\n        }}\n      />\n      {/*  <AutocompleteSearch options={professions} /> */}\n    </div>\n  );\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/submit-button.tsx",
    "content": "\"use client\";\n\nimport { Button, type ButtonProps } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { Loader } from \"lucide-react\";\nimport { type ReactNode } from \"react\";\nimport { useFormStatus } from \"react-dom\";\n\nexport const ButtonSubmit = ({\n  className,\n  children,\n  ...props\n}: {\n  children: ReactNode;\n  className?: string;\n} & ButtonProps) => {\n  const { pending } = useFormStatus();\n\n  return (\n    <>\n      <Button\n        type=\"submit\"\n        variant=\"secondary\"\n        disabled={pending}\n        className={cn(\"w-48 font-normal\", className)}\n        {...props}>\n        {pending ? (\n          <div className=\"flex w-full flex-row justify-evenly\">\n            <Loader\n              className=\"stroke-offset-foreground/25 h-5 w-5 animate-spin\"\n              // 1s feels a bit fast\n              style={{ animationDuration: \"2s\" }}\n            />\n          </div>\n        ) : (\n          children\n        )}\n      </Button>\n    </>\n  );\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/universal/hero.tsx",
    "content": "import { Balancer } from \"react-wrap-balancer\";\n\ninterface HeroProps {\n  title: string;\n  children?: React.ReactNode;\n}\n\nexport const Hero = ({ title, children }: HeroProps) => {\n  return (\n    <div\n      className=\"flex min-h-96 flex-col justify-center bg-cover bg-center bg-no-repeat py-20\"\n      style={{ backgroundImage: \"url('/hero.jpg')\" }}>\n      <div className=\"container mt-16 flex flex-col items-center justify-center gap-12 px-4 py-6\">\n        <h1 className=\"font-display text-5xl font-extrabold tracking-tight text-white\">\n          <Balancer>{title}</Balancer>\n        </h1>\n        {children}\n      </div>\n    </div>\n  );\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/universal/layout.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport React from \"react\";\n\ntype BaseProps = {\n  children: React.ReactNode;\n  className?: string;\n};\n\ntype LayoutProps = BaseProps & {\n  flex?: boolean;\n  fullWidth?: boolean;\n  align?: \"center\" | \"start\" | \"end\";\n};\n\nexport const LayoutAside = ({ children, className }: BaseProps) => {\n  return <aside className={cn(\"layout-aside min-w-[260px] p-4\", className)}>{children}</aside>;\n};\n\nexport const LayoutMain = ({ children, className }: BaseProps) => {\n  return <main className={cn(\"layout-main p-4\", className)}>{children}</main>;\n};\n\nexport const Layout = ({\n  children,\n  className,\n  flex = false,\n  fullWidth = true,\n  align,\n}: BaseProps & LayoutProps) => {\n  return (\n    <div\n      className={cn(\n        \"layout mx-auto my-0\",\n        flex && \"flex flex-1\",\n        align && `justify-${align}`,\n        !fullWidth && `max-w-screen-2xl`,\n        className\n      )}>\n      {children}\n    </div>\n  );\n};\n\nLayout.Aside = LayoutAside;\nLayout.Main = LayoutMain;\n\nexport default Layout;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/universal/logo.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport Link from \"next/link\";\n\nexport const Logo = ({ href, className }: { href?: string; className?: string }) => {\n  return (\n    <Link href={href ?? \"/\"} className={cn(\"flex font-display text-2xl\", className)}>\n      Cal.com <span className=\"font-display text-sm\">®</span>\n    </Link>\n  );\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_components/use-cal.tsx",
    "content": "\"use client\";\n\nimport { env } from \"@/env\";\nimport { CalProvider } from \"@calcom/atoms\";\nimport { use } from \"react\";\n\n/**\n * [@calcom] This is necessary since the CalProvider currently doesn't have the \"use client\" directive set (it's written for pre-server-components react)\n * \n * *Important*: You have to provide this component with a promise passed from the server compoent\n * @Usage\n    ```tsx\n    import { currentUser} from \"@/auth\";\n    export default async function RootLayout(props: { children: ReactNode }) {\n      return (\n        <Suspense>\n        {* note how we're passing the unresolved promise as props*}\n          <UseCalAtoms calAccessToken={currentUser().then((dbUser) => dbUser?.calAccessToken ?? undefined)}>\n            {props.children}\n          </UseCalAtoms>\n        </Suspense>\n      )\n    }\n    ```\n*/\nexport default function UseCalAtoms(props: {\n  children: React.ReactNode;\n  calAccessToken: Promise<string | null>;\n}) {\n  const accessToken = use(props.calAccessToken);\n  return (\n    <CalProvider\n      clientId={env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}\n      options={{\n        apiUrl: env.NEXT_PUBLIC_CAL_API_URL,\n        refreshUrl: env.NEXT_PUBLIC_REFRESH_URL,\n      }}\n      {...(accessToken && { accessToken: accessToken })}>\n      {props.children}\n    </CalProvider>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_hardcoded.ts",
    "content": "import type { FilterOption } from \"@prisma/client\";\n\n// TODO: move to database after signup\nexport const categoryOptions = [\n  {\n    fieldId: \"freelancer\",\n    fieldLabel: \"Freelancer\",\n    fieldValue: \"freelancer\",\n    filterCategoryFieldId: \"categories\",\n    filterCategoryLabel: \"Category\",\n    filterCategoryValue: \"categories\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"agency\",\n    fieldLabel: \"Agency\",\n    fieldValue: \"agency\",\n    filterCategoryFieldId: \"categories\",\n    filterCategoryLabel: \"Category\",\n    filterCategoryValue: \"categories\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"product_studio\",\n    fieldLabel: \"Product Studio\",\n    fieldValue: \"product_studio\",\n    filterCategoryFieldId: \"categories\",\n    filterCategoryLabel: \"Category\",\n    filterCategoryValue: \"categories\",\n    createdAt: new Date(),\n  },\n] as const satisfies FilterOption[];\n\nexport const capabilityOptions = [\n  {\n    fieldId: \"ecommerce\",\n    fieldLabel: \"Ecommerce\",\n    fieldValue: \"ecommerce\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"product_management\",\n    fieldLabel: \"Product Management\",\n    fieldValue: \"product_management\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"app_development\",\n    fieldLabel: \"App Development\",\n    fieldValue: \"app_development\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"design\",\n    fieldLabel: \"Design\",\n    fieldValue: \"design\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"ui_ux\",\n    fieldLabel: \"UI/UX Development\",\n    fieldValue: \"ui_ux\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"integration_services\",\n    fieldLabel: \"Integration Services\",\n    fieldValue: \"integration_services\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"branding\",\n    fieldLabel: \"Branding\",\n    fieldValue: \"branding\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"digital_marketing\",\n    fieldLabel: \"Digital Marketing\",\n    fieldValue: \"digital_marketing\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"mobile_development\",\n    fieldLabel: \"Mobile Development\",\n    fieldValue: \"mobile_development\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"ai\",\n    fieldLabel: \"AI\",\n    fieldValue: \"ai\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"web3-crypto\",\n    fieldLabel: \"Web3 / Crypto\",\n    fieldValue: \"web3-crypto\",\n    filterCategoryFieldId: \"capabilities\",\n    filterCategoryLabel: \"Capabilities\",\n    filterCategoryValue: \"capabilities\",\n    createdAt: new Date(),\n  },\n] as const satisfies FilterOption[];\n\nexport const frameworkOptions = [\n  {\n    fieldId: \"nextjs\",\n    fieldLabel: \"Next.js\",\n    fieldValue: \"nextjs\",\n    filterCategoryFieldId: \"frameworks\",\n    filterCategoryLabel: \"Frameworks\",\n    filterCategoryValue: \"frameworks\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"nuxtjs\",\n    fieldLabel: \"Nuxt.js\",\n    fieldValue: \"nuxtjs\",\n    filterCategoryFieldId: \"frameworks\",\n    filterCategoryLabel: \"Frameworks\",\n    filterCategoryValue: \"frameworks\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"svelte\",\n    fieldLabel: \"Svelte\",\n    fieldValue: \"svelte\",\n    filterCategoryFieldId: \"frameworks\",\n    filterCategoryLabel: \"Frameworks\",\n    filterCategoryValue: \"frameworks\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"gatsby\",\n    fieldLabel: \"Gatsby\",\n    fieldValue: \"gatsby\",\n    filterCategoryFieldId: \"frameworks\",\n    filterCategoryLabel: \"Frameworks\",\n    filterCategoryValue: \"frameworks\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"angular\",\n    fieldLabel: \"Angular\",\n    fieldValue: \"angular\",\n    filterCategoryFieldId: \"frameworks\",\n    filterCategoryLabel: \"Frameworks\",\n    filterCategoryValue: \"frameworks\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"ember\",\n    fieldLabel: \"Ember\",\n    fieldValue: \"ember\",\n    filterCategoryFieldId: \"frameworks\",\n    filterCategoryLabel: \"Frameworks\",\n    filterCategoryValue: \"frameworks\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"vue\",\n    fieldLabel: \"Vue\",\n    fieldValue: \"vue\",\n    filterCategoryFieldId: \"frameworks\",\n    filterCategoryLabel: \"Frameworks\",\n    filterCategoryValue: \"frameworks\",\n    createdAt: new Date(),\n  },\n] as const satisfies FilterOption[];\n\nexport const budgetOptions = [\n  {\n    fieldId: \"1000\",\n    fieldLabel: \"$1,000 - $4,999\",\n    fieldValue: \"1000\",\n    filterCategoryFieldId: \"budgets\",\n    filterCategoryLabel: \"Budgets\",\n    filterCategoryValue: \"budgets\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"5000\",\n    fieldLabel: \"$5,000 - $9,999\",\n    fieldValue: \"5000\",\n    filterCategoryFieldId: \"budgets\",\n    filterCategoryLabel: \"Budgets\",\n    filterCategoryValue: \"budgets\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"10000\",\n    fieldLabel: \"$10,000 - $49,999\",\n    fieldValue: \"10000\",\n    filterCategoryFieldId: \"budgets\",\n    filterCategoryLabel: \"Budgets\",\n    filterCategoryValue: \"budgets\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"50000\",\n    fieldLabel: \"$50,000 - $99,999\",\n    fieldValue: \"50000\",\n    filterCategoryFieldId: \"budgets\",\n    filterCategoryLabel: \"Budgets\",\n    filterCategoryValue: \"budgets\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"100000\",\n    fieldLabel: \"$100,000+\",\n    fieldValue: \"100000\",\n    filterCategoryFieldId: \"budgets\",\n    filterCategoryLabel: \"Budgets\",\n    filterCategoryValue: \"budgets\",\n    createdAt: new Date(),\n  },\n] as const satisfies FilterOption[];\n\nexport const languageOptions = [\n  {\n    fieldId: \"english\",\n    fieldLabel: \"English\",\n    fieldValue: \"english\",\n    filterCategoryFieldId: \"languages\",\n    filterCategoryLabel: \"Languages Spoken\",\n    filterCategoryValue: \"languages\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"portugese\",\n    fieldLabel: \"Portuguese\",\n    fieldValue: \"portugese\",\n    filterCategoryFieldId: \"languages\",\n    filterCategoryLabel: \"Languages Spoken\",\n    filterCategoryValue: \"languages\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"spanish\",\n    fieldLabel: \"Spanish\",\n    fieldValue: \"spanish\",\n    filterCategoryFieldId: \"languages\",\n    filterCategoryLabel: \"Languages Spoken\",\n    filterCategoryValue: \"languages\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"chinese\",\n    fieldLabel: \"Chinese\",\n    fieldValue: \"chinese\",\n    filterCategoryFieldId: \"languages\",\n    filterCategoryLabel: \"Languages Spoken\",\n    filterCategoryValue: \"languages\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"french\",\n    fieldLabel: \"French\",\n    fieldValue: \"french\",\n    filterCategoryFieldId: \"languages\",\n    filterCategoryLabel: \"Languages Spoken\",\n    filterCategoryValue: \"languages\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"japanese\",\n    fieldLabel: \"Japanese\",\n    fieldValue: \"japanese\",\n    filterCategoryFieldId: \"languages\",\n    filterCategoryLabel: \"Languages Spoken\",\n    filterCategoryValue: \"languages\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"german\",\n    fieldLabel: \"German\",\n    fieldValue: \"german\",\n    filterCategoryFieldId: \"languages\",\n    filterCategoryLabel: \"Languages Spoken\",\n    filterCategoryValue: \"languages\",\n    createdAt: new Date(),\n  },\n] as const satisfies FilterOption[];\n\nexport const regions = [\n  {\n    fieldId: \"asia\",\n    fieldLabel: \"Asia\",\n    fieldValue: \"asia\",\n    filterCategoryFieldId: \"regions\",\n    filterCategoryLabel: \"Region\",\n    filterCategoryValue: \"regions\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"australia\",\n    fieldLabel: \"Australia and New Zealand\",\n    fieldValue: \"australia\",\n    filterCategoryFieldId: \"regions\",\n    filterCategoryLabel: \"Region\",\n    filterCategoryValue: \"regions\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"europe\",\n    fieldLabel: \"Europe\",\n    fieldValue: \"europe\",\n    filterCategoryFieldId: \"regions\",\n    filterCategoryLabel: \"Region\",\n    filterCategoryValue: \"regions\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"latin_america\",\n    fieldLabel: \"Latin America\",\n    fieldValue: \"latin_america\",\n    filterCategoryFieldId: \"regions\",\n    filterCategoryLabel: \"Region\",\n    filterCategoryValue: \"regions\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"middle_east\",\n    fieldLabel: \"Middle East\",\n    fieldValue: \"middle_east\",\n    filterCategoryFieldId: \"regions\",\n    filterCategoryLabel: \"Region\",\n    filterCategoryValue: \"regions\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"north_america\",\n    fieldLabel: \"North America\",\n    fieldValue: \"north_america\",\n    filterCategoryFieldId: \"regions\",\n    filterCategoryLabel: \"Region\",\n    filterCategoryValue: \"regions\",\n    createdAt: new Date(),\n  },\n  {\n    fieldId: \"remote\",\n    fieldLabel: \"Remote\",\n    fieldValue: \"remote\",\n    filterCategoryFieldId: \"regions\",\n    filterCategoryLabel: \"Region\",\n    filterCategoryValue: \"regions\",\n    createdAt: new Date(),\n  },\n] as const satisfies FilterOption[];\n\nexport const filterOptions = [\n  ...categoryOptions,\n  ...capabilityOptions,\n  ...frameworkOptions,\n  ...budgetOptions,\n  ...languageOptions,\n  ...regions,\n] as const satisfies FilterOption[];\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/_searchParams.ts",
    "content": "import {\n  capabilityOptions,\n  categoryOptions,\n  budgetOptions,\n  frameworkOptions,\n  languageOptions,\n  regions,\n} from \"./_hardcoded\";\nimport { z } from \"zod\";\n\nexport const renderingOptions = [\"server\", \"client\"] as const;\nexport type RenderingOptions = (typeof renderingOptions)[number];\nfunction nonEmptyArray<ElementType>(arr: Array<ElementType>): [ElementType, ...ElementType[]] {\n  return [arr[0]!, ...arr.slice(1)];\n}\n\nconst categoriesEnum = z.enum(nonEmptyArray(categoryOptions.flatMap((option) => option.fieldValue)));\nconst capabilitiesEnum = z.enum(nonEmptyArray(capabilityOptions.flatMap((option) => option.fieldValue)));\nconst budgetsEnum = z.enum(nonEmptyArray(budgetOptions.flatMap((option) => option.fieldValue)));\nconst frameworksEnum = z.enum(nonEmptyArray(frameworkOptions.flatMap((option) => option.fieldValue)));\nconst languagesEnum = z.enum(nonEmptyArray(languageOptions.flatMap((option) => option.fieldValue)));\nconst regionsEnum = z.enum(nonEmptyArray(regions.flatMap((option) => option.fieldValue)));\nexport const querySearchParamSchema = z.string().optional();\n\nexport const filterSearchParamSchema = z\n  .object({\n    categories: z.array(categoriesEnum).optional(),\n    capabilities: z.array(capabilitiesEnum).optional(),\n    budgets: z.array(budgetsEnum).optional(),\n    frameworks: z.array(frameworksEnum).optional(),\n    languages: z.array(languagesEnum).optional(),\n    regions: z.array(regionsEnum).optional(),\n  })\n  .optional();\nexport const searchParamsSchema = z\n  .object({\n    q: z.string().optional(),\n    f: z\n      .object({\n        categories: z.array(categoriesEnum).optional(),\n        capabilities: z.array(capabilitiesEnum).optional(),\n        budgets: z.array(budgetsEnum).optional(),\n        frameworks: z.array(frameworksEnum).optional(),\n        languages: z.array(languagesEnum).optional(),\n        regions: z.array(regionsEnum).optional(),\n      })\n      .optional(),\n  })\n  .optional();\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/api/auth/[...nextauth]/route.ts",
    "content": "export { GET, POST } from \"@/auth\";\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/api/cal/refresh/route.ts",
    "content": "import { authConfig } from \"@/auth/config.edge\";\nimport { type KeysResponseDto } from \"@/cal/__generated/cal-sdk\";\nimport { refreshTokens } from \"@/cal/api\";\nimport NextAuth from \"next-auth\";\nimport { db } from \"prisma/client\";\n\nexport const dynamic = \"force-dynamic\"; // defaults to auto\nexport const GET = NextAuth(authConfig).auth(async function GET(request) {\n  const authorizationHeader = request.headers.get(\"Authorization\");\n  const token = authorizationHeader?.replace(\"Bearer \", \"\");\n\n  if (!request.auth) {\n    // deny any request that doesn't come from a browser from our website\n    console.warn(`[Cal Refresh] Refresh route was triggered without a session attached.`);\n    return new Response(JSON.stringify({ data: \"Unauthorized\" }), { status: 401 });\n  }\n  if (!token) {\n    console.warn(`[Cal Refresh] Refresh route was triggered without an Authorization token.`);\n    return new Response(JSON.stringify({ data: \"Unauthorized\" }), { status: 401 });\n  }\n\n  // try to look up the user\n  const user = await db.user.findUnique({\n    where: {\n      calAccessToken: token,\n    },\n    include: { calAccount: true },\n  });\n  // if we can't lookup the user from the provided token, return a 404\n  if (!user) {\n    return new Response(JSON.stringify({ data: \"Not Found\" }), { status: 404 });\n  }\n\n  try {\n    if (!user.calAccount || !user.calRefreshToken) {\n      throw new Error(`[Cal Refresh] User with id ${user.id} does not have a calAccount or a refresh token.`);\n    }\n    /** [@calcom] Attempt to refresh the token via the refresh flow\n     */\n    const refreshFlow = await refreshTokens({\n      refreshToken: user.calRefreshToken,\n      calAccountId: user.calAccount.id,\n    });\n\n    if (refreshFlow.status === \"error\") {\n      console.error(`[Cal Refresh] Unable to refresh token. Check logs above`);\n      return new Response(JSON.stringify({ data: \"Internal Server Error\" }), { status: 500 });\n    }\n\n    const updatedDb = await db.user.update({\n      where: { id: user.id },\n      data: {\n        calAccessToken: refreshFlow.data.accessToken,\n        calRefreshToken: refreshFlow.data.refreshToken,\n        // TODO: uncomment this once the endpoint returns expiration as well\n        // calAccessTokenExpiresAt: body.data.accessTokenExpiresAt,\n      },\n    });\n    if (!updatedDb.calAccessToken || !updatedDb.calRefreshToken) {\n      throw new Error(`[Cal Refresh] Unable to update user with id ${user.id} with the new tokens.`);\n    }\n\n    /** [@calcom] You have to return the accessToken back to calcom/atoms api for future refresh requests. */\n    return new Response(\n      JSON.stringify({\n        accessToken: updatedDb.calAccessToken,\n        refreshToken: updatedDb.calRefreshToken,\n      } satisfies KeysResponseDto[\"data\"]),\n      {\n        status: 200,\n      }\n    );\n  } catch (e) {\n    console.error(e);\n    return new Response(JSON.stringify({ data: \"Internal Server Error\" }), { status: 500 });\n  }\n});\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/api/supabase/storage/route.ts",
    "content": "import { auth } from \"@/auth\";\nimport { env } from \"@/env\";\nimport { createClient } from \"@supabase/supabase-js\";\n\nexport const dynamic = \"force-dynamic\"; // defaults to auto\nexport async function GET(request: Request) {\n  try {\n    const session = await auth();\n    if (!session?.user.id) {\n      return new Response(\"Unauthorized\", { status: 401 });\n    }\n    const {\n      user: { id },\n    } = session;\n    // Generate signed upload url to use on client.\n    const supabaseAdmin = createClient(env.NEXT_PUBLIC_SUPABASE_URL, env.SUPABASE_SERVICE_ROLE_KEY);\n\n    const { data, error } = await supabaseAdmin.storage\n      .from(\"avatars\")\n      .createSignedUploadUrl(id, { upsert: true });\n    console.log(error);\n    if (error) throw error;\n\n    return new Response(JSON.stringify(data), {\n      status: 200,\n    });\n  } catch (e) {\n    console.error(e);\n    return new Response(\"Internal Server Error\", { status: 500 });\n  }\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/@breadcrumbs/[...dashboardSegments]/page.tsx",
    "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\";\nimport Link from \"next/link\";\nimport { Fragment } from \"react\";\n\nexport default function BreadcrumbsSlot(props: {\n  params: {\n    dashboardSegments: string[];\n  };\n}) {\n  const { dashboardSegments } = props.params;\n  // the last section is always our \"BreadcrumbPage\", the remaining segments are our \"BreadcrumbItems\":\n  const breadcrumbPage = dashboardSegments.pop();\n\n  return (\n    <Breadcrumb>\n      <BreadcrumbList>\n        {dashboardSegments.map((segment, idx) => {\n          const parentSegments = dashboardSegments.slice(0, idx);\n          const parentPath = parentSegments.length > 0 ? `/${parentSegments.join(\"/\")}` : \"\";\n          const href = `${parentPath}/${segment}`;\n\n          return (\n            <Fragment key={href}>\n              {idx > 0 && <BreadcrumbSeparator />}\n              <BreadcrumbItem>\n                <BreadcrumbLink asChild>\n                  <Link className=\"capitalize transition-colors hover:text-foreground\" href={href}>\n                    {segment}\n                  </Link>\n                </BreadcrumbLink>\n              </BreadcrumbItem>\n            </Fragment>\n          );\n        })}\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbPage className=\"capitalize\">{breadcrumbPage}</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/@breadcrumbs/page.tsx",
    "content": "import { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbPage } from \"@/components/ui/breadcrumb\";\n\n// Note: The root breadcrum is required since optional catch-all routes aren't supported yet by Nextjs parallel routes\nexport default function BreadcrumbsSlot() {\n  return (\n    <Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbPage>Dashboard</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/@dashboardNavigationDesktop/[...dashboardSegments]/page.tsx",
    "content": "import { dashboardNavigationData } from \"../../data\";\nimport { cn } from \"@/lib/utils\";\nimport Link from \"next/link\";\n\nexport default function DashboardNavigationDesktopSlot(props: {\n  params: {\n    dashboardSegments: string[];\n  };\n}) {\n  const { dashboardSegments } = props.params;\n  const pathname = `/${dashboardSegments.join(\"/\")}`;\n  return (\n    <nav className=\"grid items-start px-2 text-sm font-medium lg:px-4\">\n      {dashboardNavigationData.map((navigationItem) => {\n        return (\n          <Link\n            key={navigationItem.href}\n            href={navigationItem.href}\n            className={cn(\n              \"flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:bg-muted/50 hover:text-primary\",\n              pathname === navigationItem.href && \"bg-muted text-primary\"\n            )}\n            prefetch={false}>\n            <navigationItem.icon className=\"size-4\" />\n            {navigationItem.label}\n          </Link>\n        );\n      })}\n    </nav>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/@dashboardNavigationDesktop/page.tsx",
    "content": "import { dashboardNavigationData } from \"../data\";\nimport { cn } from \"@/lib/utils\";\nimport Link from \"next/link\";\n\n// Note: The root breadcrum is required since optional catch-all routes aren't supported yet by Nextjs parallel routes\nexport default function DashboardNavigationDesktopDefault() {\n  const pathname = \"/dashboard\";\n  return (\n    <nav className=\"grid items-start px-2 text-sm font-medium lg:px-4\">\n      {dashboardNavigationData.map((navigationItem) => {\n        return (\n          <Link\n            key={navigationItem.href}\n            href={navigationItem.href}\n            className={cn(\n              \"flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:bg-muted/50 hover:text-primary\",\n              pathname === navigationItem.href && \"bg-muted text-primary\"\n            )}\n            prefetch={false}>\n            <navigationItem.icon className=\"size-4\" />\n            {navigationItem.label}\n          </Link>\n        );\n      })}\n    </nav>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/@dashboardNavigationMobile/[...dashboardSegments]/page.tsx",
    "content": "import { dashboardNavigationData } from \"../../data\";\nimport { Logo } from \"@/app/_components/universal/logo\";\nimport { cn } from \"@/lib/utils\";\nimport Link from \"next/link\";\n\nexport default function DashboardNavigationMobileSlot(props: {\n  params: {\n    dashboardSegments: string[];\n  };\n}) {\n  const { dashboardSegments } = props.params;\n  const pathname = `/${dashboardSegments.join(\"/\")}`;\n  return (\n    <nav className=\"grid gap-6 text-lg font-medium\">\n      <Logo\n        href=\"/dashboard\"\n        className=\"group h-10 shrink-0 font-display text-lg font-semibold md:text-base\"\n      />\n      {dashboardNavigationData.map((navigationItem) => {\n        return (\n          <Link\n            key={navigationItem.href}\n            href={navigationItem.href}\n            className={cn(\n              \"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\",\n              navigationItem.href === pathname && \"text-muted-foreground\"\n            )}>\n            <navigationItem.icon className=\"size-5 transition-all group-hover:scale-110\" />\n            {navigationItem.label}\n          </Link>\n        );\n      })}\n    </nav>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/@dashboardNavigationMobile/page.tsx",
    "content": "import { dashboardNavigationData } from \"../data\";\nimport { Logo } from \"@/app/_components/universal/logo\";\nimport { cn } from \"@/lib/utils\";\nimport Link from \"next/link\";\n\n// Note: The root breadcrum is required since optional catch-all routes aren't supported yet by Nextjs parallel routes\nexport default function DashboardNavigationMobileDefault() {\n  const pathname = \"/dashboard\";\n  return (\n    <nav className=\"grid gap-6 text-lg font-medium\">\n      <Logo\n        href=\"/dashboard\"\n        className=\"group h-10 shrink-0 font-display text-lg font-semibold md:text-base\"\n      />\n      {dashboardNavigationData.map((navigationItem) => {\n        return (\n          <Link\n            key={navigationItem.href}\n            href={navigationItem.href}\n            className={cn(\n              \"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\",\n              navigationItem.href === pathname && \"text-muted-foreground\"\n            )}>\n            <navigationItem.icon className=\"size-5 transition-all group-hover:scale-110\" />\n            {navigationItem.label}\n          </Link>\n        );\n      })}\n    </nav>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/_components/bookings-table.tsx",
    "content": "\"use client\";\n\nimport { type GetBookingsDataEntry } from \"@/cal/__generated/cal-sdk\";\nimport { stripCalOAuthClientIdFromEmail, stripCalOAuthClientIdFromText } from \"@/cal/utils\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Pagination, PaginationContent, PaginationItem } from \"@/components/ui/pagination\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"@/components/ui/table\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { cn } from \"@/lib/utils\";\nimport { type User, type CalAccount } from \"@prisma/client\";\nimport { Separator } from \"@radix-ui/react-separator\";\nimport dayjs from \"dayjs\";\nimport { ChevronLeft, ChevronRight, Copy } from \"lucide-react\";\nimport { type BookingStatus } from \"node_modules/@calcom/atoms/dist/packages/prisma-client\";\nimport { Fragment, useState } from \"react\";\n\nexport const BookingsTable = (props: {\n  bookings: {\n    all: Array<GetBookingsDataEntry>;\n    currentWeek: Array<GetBookingsDataEntry>;\n    currentMonth: Array<GetBookingsDataEntry>;\n    currentYear: Array<GetBookingsDataEntry>;\n  };\n  user: { timeZone: CalAccount[\"timeZone\"]; username: User[\"username\"]; email: User[\"email\"] };\n}) => {\n  // send this ref to: rable-row-hoverable element\n  // then use it in order-details element to read the currently hovered event\n  const [selectedElement, setSelectedElement] = useState<GetBookingsDataEntry | null | undefined>(\n    props.bookings?.currentWeek?.[0] ?? null\n  );\n  const [selectedTab, setSelectedTab] = useState<\"week\" | \"month\" | \"year\">(\"week\");\n  const tabs = [\n    { label: \"Week\", value: \"week\" },\n    { label: \"Month\", value: \"month\" },\n    { label: \"Year\", value: \"year\" },\n  ] as const;\n\n  // to display the booking detail's attendees\n  const who = {\n    host: `${selectedElement?.user?.name} (Host) - ${stripCalOAuthClientIdFromEmail(props.user.email ?? \"\")}`,\n    attendees: selectedElement?.attendees.map((attendee) => {\n      return {\n        name: stripCalOAuthClientIdFromText(attendee?.name ?? \"\"),\n        email: stripCalOAuthClientIdFromEmail(attendee?.email ?? \"\"),\n      };\n    }),\n  };\n\n  const bookings =\n    selectedTab === \"week\"\n      ? props.bookings.currentWeek\n      : selectedTab === \"month\"\n        ? props.bookings.currentMonth\n        : props.bookings.currentYear;\n  return (\n    <Fragment>\n      <Tabs\n        defaultValue=\"week\"\n        className=\"grid gap-4 md:gap-8 lg:grid-cols-2 xl:grid-cols-3\"\n        onValueChange={(val) => setSelectedTab(val as \"week\" | \"month\" | \"year\")}>\n        <div className=\"flex items-center lg:col-span-2 xl:col-span-3\">\n          <TabsList>\n            {tabs.map((tab, idx) => (\n              <TabsTrigger key={idx} value={tab.value}>\n                {tab.label}\n              </TabsTrigger>\n            ))}\n          </TabsList>\n        </div>\n\n        {tabs.map((tab, idx) => {\n          return (\n            <TabsContent value={tab.value} key={idx} className=\"xl:col-span-2\">\n              <Card>\n                <CardHeader className=\"px-7\">\n                  <CardTitle>Bookings</CardTitle>\n                  <CardDescription>Bookings from potential customers.</CardDescription>\n                </CardHeader>\n                <CardContent>\n                  <Table>\n                    <TableHeader>\n                      <TableRow>\n                        <TableHead>Initiator</TableHead>\n                        <TableHead className=\"hidden sm:table-cell\">Event Type</TableHead>\n                        <TableHead className=\"hidden sm:table-cell\">Status</TableHead>\n                        <TableHead className=\"hidden md:table-cell\">Date</TableHead>\n                        <TableHead className=\"text-right\">Time</TableHead>\n                      </TableRow>\n                    </TableHeader>\n                    <TableBody>\n                      {bookings.length ? (\n                        bookings.map((booking, idx) => {\n                          const initiator = booking.attendees[0];\n                          const isEven = idx % 2 === 0;\n                          return (\n                            <TableRow\n                              key={booking.id}\n                              className={cn(\n                                \"data-[current=true]:bg-muted-foreground/30\",\n                                isEven && \"bg-accent\"\n                              )}\n                              data-current={\n                                bookings.findIndex((booking) => booking.id === selectedElement?.id) === idx\n                              }\n                              onClick={() => setSelectedElement(booking)}>\n                              <TableCell>\n                                <div className=\"font-medium capitalize\">\n                                  {stripCalOAuthClientIdFromText(initiator?.name ?? \"\")}\n                                </div>\n                                <div className=\"hidden text-sm text-muted-foreground md:inline\">\n                                  {stripCalOAuthClientIdFromEmail(initiator?.email ?? \"\")}\n                                </div>\n                              </TableCell>\n                              <TableCell className=\"hidden sm:table-cell\">{booking.eventType.slug}</TableCell>\n                              <TableCell className=\"hidden sm:table-cell\">\n                                <Badge\n                                  variant={\n                                    // so that we show the destructive badge for cancelled meetings, and success badge for confirmed meetings\n                                    ([\"CANCELLED\", \"REJECTED\"] as Array<BookingStatus>).includes(\n                                      // @ts-expect-error: There are missing types in the openapi specs for cal's api, this should likely be: BookingStatus\n                                      booking.status\n                                    )\n                                      ? \"destructive\"\n                                      : ([\"PENDING\", \"ACCEPTED\", \"AWAITING HOST\"] as Array<BookingStatus>)\n                                            // @ts-expect-error: There are missing types in the openapi specs for cal's api, this should likely be: BookingStatus\n                                            .includes(booking.status)\n                                        ? \"success\"\n                                        : \"default\"\n                                  }\n                                  className={cn(\n                                    \"text-xs\",\n                                    // so that we show a gray badge for pending meetings\n                                    (booking.status as BookingStatus) === \"PENDING\" &&\n                                      \"border-transparent bg-muted text-muted-foreground hover:bg-muted/80\"\n                                  )}>\n                                  {/* @ts-expect-error: There are missing types in the openapi specs for cal's api, this should likely be: BookingStatus */}\n                                  {booking.status}\n                                </Badge>\n                              </TableCell>\n                              <TableCell className=\"hidden md:table-cell\">\n                                {dayjs(booking.startTime).format(\"YYYY-MM-DD\")}\n                              </TableCell>\n                              <TableCell className=\"text-right\">\n                                <div className=\"font-medium capitalize\">\n                                  {dayjs(booking.startTime).format(\"h:mma\")}\n                                </div>\n                                <div className=\"hidden text-sm text-muted-foreground md:inline\">\n                                  {props.user.timeZone}\n                                </div>\n                              </TableCell>\n                            </TableRow>\n                          );\n                        })\n                      ) : (\n                        <TableRow>\n                          <TableCell>\n                            <p className=\"text-sm text-muted-foreground\">\n                              In the current {tab.label.toLocaleLowerCase()}, you don&rsquo;t have any\n                              bookings.\n                            </p>\n                          </TableCell>\n                        </TableRow>\n                      )}\n                    </TableBody>\n                  </Table>\n                </CardContent>\n              </Card>\n            </TabsContent>\n          );\n        })}\n        <Card className=\"mt-2\" x-chunk=\"dashboard-05-chunk-4\">\n          <CardHeader className=\"flex flex-row items-start bg-muted/50\">\n            <div className=\"grid gap-0.5\">\n              <CardTitle className=\"group flex items-center gap-2 text-lg\">\n                {stripCalOAuthClientIdFromText(selectedElement?.title ?? \"No booking selected\")}\n                <Button\n                  size=\"icon\"\n                  variant=\"outline\"\n                  className=\"h-6 w-6 opacity-0 transition-opacity group-hover:opacity-100\">\n                  <Copy className=\"h-3 w-3\" />\n                  <span className=\"sr-only\">Copy Booking ID</span>\n                </Button>\n              </CardTitle>\n              <CardDescription className=\"flex flex-col\"></CardDescription>\n            </div>\n          </CardHeader>\n          <CardContent className=\"p-6 text-sm\">\n            <div className=\"grid gap-3\">\n              <div className=\"font-semibold\">Booking Details</div>\n              <ul className=\"grid gap-3\">\n                <li className=\"flex items-center justify-between text-muted-foreground\">\n                  <span>Booking Uid:</span>\n                  <span>{selectedElement?.uid}</span>\n                </li>\n                <li className=\"flex items-center justify-between text-muted-foreground\">\n                  <span>Date:</span>\n                  <span>\n                    {selectedElement?.startTime\n                      ? dayjs(selectedElement?.startTime).format(\"MMMM DD, YYYY\")\n                      : \"MMMM DD, YYYY\"}\n                  </span>\n                </li>\n                <li className=\"flex items-center justify-between text-muted-foreground\">\n                  <span>Status:</span>\n                  <span>\n                    <Badge\n                      variant={\n                        // so that we show the destructive badge for cancelled meetings, and success badge for confirmed meetings\n                        ([\"CANCELLED\", \"REJECTED\"] as Array<BookingStatus>).includes(\n                          // @ts-expect-error: There are missing types in the openapi specs for cal's api, this should likely be: BookingStatus\n                          selectedElement?.status\n                        )\n                          ? \"destructive\"\n                          : ([\"PENDING\", \"ACCEPTED\", \"AWAITING HOST\"] as Array<BookingStatus>)\n                                // @ts-expect-error: There are missing types in the openapi specs for cal's api, this should likely be: BookingStatus\n                                .includes(selectedElement?.status)\n                            ? \"success\"\n                            : \"default\"\n                      }\n                      className={cn(\n                        \"w-fit text-xs\",\n                        // so that we show a gray badge for pending meetings\n                        (selectedElement?.status as BookingStatus) === \"PENDING\" &&\n                          \"border-transparent bg-muted text-muted-foreground hover:bg-muted/80\"\n                      )}>\n                      {/* @ts-expect-error: There are missing types in the openapi specs for cal's api, this should likely be: BookingStatus */}\n                      {selectedElement?.status}\n                    </Badge>\n                  </span>\n                </li>\n              </ul>\n              <Separator className=\"my-2\" />\n              <div className=\"font-semibold\">Attendees</div>\n              <ul className=\"grid gap-3\">\n                {who.attendees?.map((attendee, idx) => (\n                  <li key={idx} className=\"flex items-center justify-between\">\n                    <span className=\"capitalize text-muted-foreground\">{attendee.name}</span>\n                    <span>{attendee.email}</span>\n                  </li>\n                ))}\n              </ul>\n            </div>\n            <Separator className=\"my-4\" />\n            <div className=\"grid gap-3\">\n              <div className=\"font-semibold\">Customer Information</div>\n              <dl className=\"grid gap-3\">\n                <div className=\"flex items-center justify-between\">\n                  <dt className=\"text-muted-foreground\">Customer</dt>\n                  <dd className=\"capitalize\">\n                    {stripCalOAuthClientIdFromText(selectedElement?.attendees[0]?.name ?? \"\")}\n                  </dd>\n                </div>\n                <div className=\"flex items-center justify-between\">\n                  <dt className=\"text-muted-foreground\">Email</dt>\n                  <dd>\n                    <a href=\"mailto:\">\n                      {stripCalOAuthClientIdFromEmail(selectedElement?.attendees[0]?.email ?? \"\")}\n                    </a>\n                  </dd>\n                </div>\n                <div className=\"flex items-center justify-between\">\n                  <dt className=\"text-muted-foreground\">Language</dt>\n                  <dd>\n                    {selectedElement?.attendees[0]?.locale\n                      ? new Intl.DisplayNames([navigator.language], { type: \"language\" }).of(\n                          selectedElement?.attendees[0]?.locale ?? \"English\"\n                        )\n                      : \"\"}{\" \"}\n                    {selectedElement?.attendees[0]?.locale\n                      ? `(${selectedElement?.attendees[0]?.locale})`\n                      : \"\"}\n                  </dd>\n                </div>\n              </dl>\n            </div>\n          </CardContent>\n          <CardFooter className=\"flex flex-row items-center border-t bg-muted/50 px-6 py-3\">\n            <div className=\"text-xs text-muted-foreground\">\n              Updated <time dateTime={Date.now().toLocaleString()}>Today</time>\n            </div>\n            <Pagination className=\"ml-auto mr-0 w-auto\">\n              <PaginationContent>\n                <PaginationItem>\n                  <Button\n                    size=\"icon\"\n                    variant=\"outline\"\n                    className=\"h-6 w-6\"\n                    onClick={() =>\n                      setSelectedElement((prev) => {\n                        if (!prev) return bookings[0] ?? null;\n                        const currentIndex = bookings?.findIndex((booking) => booking.id === prev.id);\n                        return bookings[currentIndex - 1];\n                      })\n                    }\n                    disabled={\n                      bookings.findIndex((booking) => booking.id === selectedElement?.id) === 0 ||\n                      bookings.length < 2\n                    }>\n                    <ChevronLeft className=\"h-3.5 w-3.5\" />\n                    <span className=\"sr-only\">Previous Booking</span>\n                  </Button>\n                </PaginationItem>\n                <PaginationItem>\n                  <Button\n                    size=\"icon\"\n                    variant=\"outline\"\n                    className=\"h-6 w-6\"\n                    onClick={() =>\n                      setSelectedElement((prev) => {\n                        if (!prev) return bookings[0] ?? null;\n                        const currentIndex = bookings.findIndex((booking) => booking.id === prev?.id);\n                        return bookings[currentIndex + 1];\n                      })\n                    }\n                    disabled={\n                      bookings.findIndex((booking) => booking.id === selectedElement?.id) ===\n                        bookings.length - 1 || bookings.length < 2\n                    }>\n                    <ChevronRight className=\"h-3.5 w-3.5\" />\n                    <span className=\"sr-only\">Next Booking</span>\n                  </Button>\n                </PaginationItem>\n              </PaginationContent>\n            </Pagination>\n          </CardFooter>\n        </Card>\n      </Tabs>\n    </Fragment>\n  );\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/_components/connect-calendar-step.tsx",
    "content": "import { ButtonSubmit } from \"@/app/_components/submit-button\";\nimport { Card, CardDescription, CardFooter, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { useStepper } from \"@/components/ui/stepper\";\nimport { GcalConnect } from \"@calcom/atoms\";\nimport { Loader } from \"lucide-react\";\nimport { Suspense } from \"react\";\n\nconst ConnectCalendarStep = () => {\n  const { nextStep } = useStepper();\n\n  return (\n    <>\n      <Card className=\"mx-auto mt-10 w-full max-w-sm\">\n        <CardHeader>\n          <CardTitle className=\"text-2xl\">Getting Started</CardTitle>\n          <CardDescription>Connect your calendar to get started.</CardDescription>\n        </CardHeader>\n        <CardFooter className=\"[&>div]:w-full\">\n          <Suspense\n            fallback={\n              <div className=\"relative h-max w-full max-w-sm place-self-center\">\n                <div className=\" absolute inset-0 z-40 grid rounded-2xl bg-slate-900 text-white\">\n                  <Loader className=\"z-50 animate-spin place-self-center\" />\n                </div>\n              </div>\n            }>\n            <GcalConnect className=\"flex w-full items-center justify-center [&>svg]:mr-2\" />\n          </Suspense>\n        </CardFooter>\n      </Card>\n      <div className=\"flex w-full justify-end\">\n        <ButtonSubmit variant=\"default\" onClick={nextStep} size=\"sm\">\n          Next\n        </ButtonSubmit>\n      </div>\n    </>\n  );\n};\n\nexport default ConnectCalendarStep;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/_components/getting-started-steps.tsx",
    "content": "\"use client\";\n\nimport ConnectCalendarStep from \"./connect-calendar-step\";\nimport UserFilters from \"./user-filters-step\";\nimport UserDetailsStep from \"./user-details-step\";\nimport { Step, Stepper, type StepItem } from \"@/components/ui/stepper\";\nimport { type FilterOption } from \"@prisma/client\";\n\nconst steps = [\n  { id: \"connect-calendar\", label: \"Step 1\" },\n  { id: \"filters\", label: \"Step 2\" },\n  { id: \"avatar-and-bio\", label: \"Step 3\" },\n] satisfies StepItem[];\n\nconst GettingStarted = ({\n  userId,\n  filterOptions,\n}: {\n  userId: string;\n  filterOptions: Array<FilterOption>;\n}) => {\n  return (\n    <main className=\"flex-1 bg-muted/40\">\n      <div className=\"flex items-center justify-center p-10\">\n        <div className=\"w-3/4\">\n          <Stepper initialStep={0} steps={steps}>\n            {steps.map(({ id, label }, index) => {\n              return (\n                <Step key={id} label={label}>\n                  {index === 0 && (\n                    <div className=\"flex h-full min-h-96 flex-col items-center justify-between\">\n                      <ConnectCalendarStep />\n                    </div>\n                  )}\n                  {index === 1 && <UserFilters filterOptions={filterOptions} />}\n                  {index === 2 && <UserDetailsStep userId={userId} />}\n                </Step>\n              );\n            })}\n          </Stepper>\n        </div>\n      </div>\n    </main>\n  );\n};\n\nexport default GettingStarted;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/_components/user-details-step.tsx",
    "content": "import SupabaseReactDropzone from \"../settings/_components/supabase-react-dropzone\";\nimport { expertEdit } from \"@/app/_actions\";\nimport { ButtonSubmit } from \"@/app/_components/submit-button\";\nimport { Button } from \"@/components/ui/button\";\nimport { Label } from \"@/components/ui/label\";\nimport { useStepper } from \"@/components/ui/stepper\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { useRouter } from \"next/navigation\";\nimport { useEffect } from \"react\";\nimport { useFormState } from \"react-dom\";\n\ntype UserDetailsFormState = { error: null | string } | { success: null | string };\n\nconst UserDetailsStep = ({ userId }: { userId: string }) => {\n  const router = useRouter();\n\n  const [userDetailsFormState, dispatch] = useFormState<UserDetailsFormState, FormData>(expertEdit, {\n    error: null,\n  });\n\n  const { isDisabledStep, prevStep } = useStepper();\n\n  useEffect(() => {\n    if (\"success\" in userDetailsFormState && userDetailsFormState?.success) {\n      router.push(\"/dashboard\");\n    }\n  }, [userDetailsFormState]);\n\n  return (\n    <form className=\"mt-10\" action={dispatch}>\n      <SupabaseReactDropzone userId={userId ?? \"clxj4quka0000gebuthdxi1cp\"} />\n      <div>\n        <Label htmlFor=\"bio\">Bio</Label>\n        <Textarea\n          placeholder=\"Tell us a little bit about yourself\"\n          className=\"resize-none\"\n          id=\"bio\"\n          name=\"bio\"\n          maxLength={500}\n        />\n      </div>\n      <div className=\"mt-4 flex justify-end gap-2\">\n        <Button disabled={isDisabledStep} onClick={prevStep} size=\"sm\" variant=\"secondary\">\n          Prev\n        </Button>\n        <ButtonSubmit variant=\"default\" size=\"sm\">\n          Finish\n        </ButtonSubmit>\n      </div>\n    </form>\n  );\n};\n\nexport default UserDetailsStep;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/_components/user-filters-step.tsx",
    "content": "import { addUserFilters } from \"@/app/_actions\";\nimport { FancyMultiSelect, type Option } from \"@/app/_components/multi-select\";\nimport { ButtonSubmit } from \"@/app/_components/submit-button\";\nimport { Button } from \"@/components/ui/button\";\nimport { Label } from \"@/components/ui/label\";\nimport { useStepper } from \"@/components/ui/stepper\";\nimport { type FilterOption } from \"@prisma/client\";\nimport { useEffect } from \"react\";\nimport { useFormState } from \"react-dom\";\nimport { uniqueBy, prop } from \"remeda\";\n\ntype TUserFiltersFormState = {\n  error?: string | null;\n  inputErrors?: {\n    categories?: string[];\n    capabilities?: string[];\n    frameworks?: string[];\n    budgets?: string[];\n    languages?: string[];\n    regions?: string[];\n  };\n};\n\nconst UserFilters = ({ filterOptions }: { filterOptions: Array<FilterOption> }) => {\n  const [formState, dispatch] = useFormState<TUserFiltersFormState, FormData>(addUserFilters, {\n    error: null,\n  });\n  const { isDisabledStep, prevStep, nextStep } = useStepper();\n\n  const filtersByCategory = uniqueBy(filterOptions, prop(\"filterCategoryFieldId\"));\n\n  useEffect(() => {\n    if (\"success\" in formState && !!formState?.success) {\n      nextStep();\n    }\n  }, [formState]);\n\n  return (\n    <form action={dispatch} className=\"mt-10\">\n      {filtersByCategory.map(({ filterCategoryFieldId, filterCategoryLabel }) => (\n        <div className=\"grid gap-2\" key={filterCategoryFieldId}>\n          <Label htmlFor=\"email\">{filterCategoryLabel}</Label>\n          <FancyMultiSelect\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n            options={filterOptions\n              .filter((filterOption) => filterOption.filterCategoryLabel === filterCategoryLabel)\n              .map(\n                (filterOption) =>\n                  ({\n                    label: filterOption.fieldLabel,\n                    value: filterOption.fieldValue,\n                  }) satisfies Option\n              )}\n            placeholder={`Select your ${filterCategoryLabel.toLowerCase()}`}\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n            name={filterCategoryFieldId.toLowerCase()}\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n            id={filterCategoryFieldId.toLowerCase()}\n          />\n          {formState?.inputErrors?.[filterCategoryFieldId as keyof TUserFiltersFormState[\"inputErrors\"]] ? (\n            <div className=\"text-sm font-medium text-red-700\" aria-live=\"polite\">\n              {\n                formState.inputErrors?.[\n                  filterCategoryFieldId as keyof TUserFiltersFormState[\"inputErrors\"]\n                ]?.[0]\n              }\n            </div>\n          ) : null}\n        </div>\n      ))}\n\n      <div className=\"mt-4 flex justify-end gap-2\">\n        <Button disabled={isDisabledStep} onClick={prevStep} size=\"sm\" variant=\"secondary\">\n          Prev\n        </Button>\n        <ButtonSubmit variant=\"default\" size=\"sm\">\n          Next\n        </ButtonSubmit>\n      </div>\n    </form>\n  );\n};\n\nexport default UserFilters;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/data.tsx",
    "content": "import { Calendar, Clock, Home, User } from \"lucide-react\";\n\nexport const dashboardNavigationData = [\n  {\n    label: \"Dashboard\",\n    href: \"/dashboard\",\n    icon: (props: { className?: string }) => <Home className={props.className} />,\n  },\n  {\n    label: \"Booking Events\",\n    href: \"/dashboard/settings/booking-events\",\n    icon: (props: { className?: string }) => <Calendar className={props.className} />,\n  },\n  {\n    label: \"Profile\",\n    href: \"/dashboard/settings/profile\",\n    icon: (props: { className?: string }) => <User className={props.className} />,\n  },\n  {\n    label: \"Availability\",\n    href: \"/dashboard/settings/availability\",\n    icon: (props: { className?: string }) => <Clock className={props.className} />,\n  },\n];\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/getting-started/page.tsx",
    "content": "import GettingStarted from \"../_components/getting-started-steps\";\nimport { auth } from \"@/auth\";\nimport { db } from \"prisma/client\";\n\nexport default async function Dashboard() {\n  const sesh = await auth();\n  const filterOptions = await db.filterOption.findMany();\n\n  if (!sesh?.user?.id) {\n    return <div>Not logged in</div>;\n  }\n\n  return <GettingStarted userId={sesh.user.id}  filterOptions={filterOptions} />;\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/layout.tsx",
    "content": "import { ButtonSubmit } from \"@/app/_components/submit-button\";\nimport { Logo } from \"@/app/_components/universal/logo\";\nimport { SignedIn, signOut } from \"@/auth\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Sheet, SheetContent, SheetTrigger } from \"@/components/ui/sheet\";\nimport { PanelLeft, User } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { type ReactNode } from \"react\";\n\nexport default async function Layout({\n  children,\n  breadcrumbs,\n  dashboardNavigationDesktop,\n  dashboardNavigationMobile,\n}: {\n  children: ReactNode;\n  breadcrumbs: ReactNode;\n  dashboardNavigationDesktop: ReactNode;\n  dashboardNavigationMobile: ReactNode;\n}) {\n  return (\n    <SignedIn>\n      {({ user }) => (\n        <div className=\"grid min-h-screen w-full lg:grid-cols-[220px_1fr] 2xl:grid-cols-[280px_1fr]\">\n          <div className=\"hidden border-r bg-muted/40 md:block\">\n            <div className=\"sticky top-0 z-40 flex h-full max-h-screen flex-col gap-2\">\n              <div className=\"flex h-14 items-center border-b px-4 lg:h-[60px] lg:px-6\">\n                <Logo />\n              </div>\n              <div className=\"flex-1\">{dashboardNavigationDesktop}</div>\n            </div>\n          </div>\n          <div className=\"flex flex-col\">\n            <header className=\"sticky top-0 z-40 flex h-14 items-center gap-4 border-b border-border/40 bg-muted/40 px-4 backdrop-blur-[2px] lg:h-[60px] lg:px-6\">\n              <Sheet>\n                <SheetTrigger asChild>\n                  <Button size=\"icon\" variant=\"outline\" className=\"sm:hidden\">\n                    <PanelLeft className=\"h-5 w-5\" />\n                    <span className=\"sr-only\">Toggle Menu</span>\n                  </Button>\n                </SheetTrigger>\n                <SheetContent side=\"left\" className=\"sm:max-w-xs\">\n                  {dashboardNavigationMobile}\n                </SheetContent>\n              </Sheet>\n              {breadcrumbs}\n              <div className=\"relative ml-auto flex-1 md:grow-0\">\n                <div className=\"flex flex-row items-center justify-end gap-4\">\n                  <div className=\"flex flex-row items-center gap-2\">\n                    <span className=\"hidden text-sm text-muted-foreground [width:max-content] md:block\">\n                      Logged in as <b>{user?.username}</b>\n                    </span>\n                    <DropdownMenu>\n                      <DropdownMenuTrigger asChild>\n                        <Button variant=\"secondary\" size=\"icon\" className=\"overflow-hidden rounded-full\">\n                          <User className=\"\" />\n                        </Button>\n                      </DropdownMenuTrigger>\n                      <DropdownMenuContent align=\"end\">\n                        <DropdownMenuLabel>My Account</DropdownMenuLabel>\n                        <DropdownMenuSeparator />\n                        <DropdownMenuItem>\n                          <Link href=\"/dashboard/settings\">Settings</Link>\n                        </DropdownMenuItem>\n                        <DropdownMenuSeparator />\n                        <DropdownMenuLabel>\n                          <form\n                            action={async () => {\n                              \"use server\";\n                              await signOut({ redirectTo: \"/\" });\n                            }}>\n                            <ButtonSubmit className=\"w-full\">Logout</ButtonSubmit>\n                          </form>\n                        </DropdownMenuLabel>\n                      </DropdownMenuContent>\n                    </DropdownMenu>\n                  </div>\n                </div>\n              </div>\n            </header>\n            {children}\n          </div>\n        </div>\n      )}\n    </SignedIn>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/page.tsx",
    "content": "/* eslint-disable */\n// @ts-nocheck\nimport { BookingsTable } from \"./_components/bookings-table\";\nimport { CalAccount, auth } from \"@/auth\";\nimport { cal } from \"@/cal/api\";\nimport { stripCalOAuthClientIdFromEmail } from \"@/cal/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Progress } from \"@/components/ui/progress\";\nimport { cn } from \"@/lib/utils\";\nimport dayjs from \"dayjs\";\nimport { ArrowRight } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { type GetBookingsInput } from \"node_modules/@calcom/atoms/dist/packages/platform/types\";\nimport { Suspense } from \"react\";\n\nexport default async function Dashboard() {\n  const sesh = await auth();\n  if (!sesh.user.id) {\n    return <div>Not logged in</div>;\n  }\n  /** [@calcom] We're fetching the bookings on the server to display them here\n   * Since `filters` is currently a required parameter, we have to iterate a bit and create our flatMap in the end\n   */\n  const filters = [\"upcoming\", \"recurring\", \"past\", \"cancelled\", \"unconfirmed\"] satisfies Array<\n    GetBookingsInput[\"filters\"][\"status\"]\n  >;\n\n  const bookingResponses = await Promise.all(\n    filters.map((filter) =>\n      cal({ user: { id: sesh?.user.id } }).get(\"/v2/bookings\", {\n        query: { \"filters[status]\": filter, cursor: 0, limit: 20 },\n      })\n    )\n  );\n\n  const bookings = bookingResponses.flatMap((response, idx) => {\n    if (response.status === \"error\") {\n      console.warn(\n        `Unable to fetch bookings for filter '${filters[idx]}' with status '${response.status}'`,\n        response\n      );\n      return [];\n    }\n    return response.data.bookings;\n  });\n  /** [@calcom] End of fetching bookings */\n\n  const lastWeekBookings = bookings.filter((booking) => {\n    const startOfWeek = dayjs().startOf(\"week\").subtract(1, \"week\");\n    const endOfWeek = dayjs().endOf(\"week\").subtract(1, \"week\");\n    return dayjs(booking.startTime).isAfter(startOfWeek) && dayjs(booking.startTime).isBefore(endOfWeek);\n  });\n\n  const thisWeekBookings = bookings.filter((booking) => {\n    const startOfWeek = dayjs().startOf(\"week\");\n    const endOfWeek = dayjs().endOf(\"week\");\n    return dayjs(booking.startTime).isAfter(startOfWeek) && dayjs(booking.startTime).isBefore(endOfWeek);\n  });\n\n  const lastMonthBookings = bookings.filter((booking) => {\n    const startOfMonth = dayjs().startOf(\"month\").subtract(1, \"month\");\n    const endOfMonth = dayjs().endOf(\"month\").subtract(1, \"month\");\n    return dayjs(booking.startTime).isAfter(startOfMonth) && dayjs(booking.startTime).isBefore(endOfMonth);\n  });\n\n  const thisMonthBookings = bookings.filter((booking) => {\n    const startOfMonth = dayjs().startOf(\"month\");\n    const endOfMonth = dayjs().endOf(\"month\");\n    return dayjs(booking.startTime).isAfter(startOfMonth) && dayjs(booking.startTime).isBefore(endOfMonth);\n  });\n\n  const thisYearBookings = bookings.filter((booking) => {\n    // only show the bookings with booking.startTime for the current year:\n    const startOfYear = dayjs().startOf(\"year\");\n    const endOfYear = dayjs().endOf(\"year\");\n    return dayjs(booking.startTime).isAfter(startOfYear) && dayjs(booking.startTime).isBefore(endOfYear);\n  });\n\n  const changeFromPrevious = (current: number, previous: number) => {\n    return previous === 0 ? 100 : Math.round(((current - previous) / previous) * 100);\n  };\n\n  return (\n    <main className=\"flex flex-1 flex-col gap-4 bg-muted/40 p-4 md:gap-8 md:p-8\">\n      <div className=\"grid gap-4 md:grid-cols-2 md:gap-8 lg:grid-cols-4\">\n        <Card className=\"sm:col-span-2\" x-chunk=\"dashboard-05-chunk-0\">\n          <CardHeader className=\"pb-3\">\n            <CardTitle>Your Bookings</CardTitle>\n            <CardDescription className=\"max-w-lg text-balance leading-relaxed\">\n              See all your bookings for your services.\n            </CardDescription>\n          </CardHeader>\n          <CardFooter className=\"pt-6\">\n            <Link href=\"/dashboard/settings/booking-events\">\n              <Button>\n                Manage booking events\n                <ArrowRight className=\"ml-1 size-4\" />\n              </Button>\n            </Link>\n          </CardFooter>\n        </Card>\n        <Card x-chunk=\"dashboard-05-chunk-1\">\n          <CardHeader className=\"pb-2\">\n            <CardDescription>This Week</CardDescription>\n            <CardTitle className=\"text-4xl\">{thisWeekBookings.length}</CardTitle>\n          </CardHeader>\n          <CardContent>\n            <div className=\"text-xs text-muted-foreground\">\n              {lastWeekBookings.length > 0\n                ? `${changeFromPrevious(thisWeekBookings.length, lastWeekBookings.length)}% from last week`\n                : \"From 0 last week\"}\n            </div>\n          </CardContent>\n          <CardFooter>\n            <Progress\n              value={Math.abs(changeFromPrevious(thisWeekBookings.length, lastWeekBookings.length))}\n              aria-label={\n                lastWeekBookings.length > 0\n                  ? `${changeFromPrevious(thisWeekBookings.length, lastWeekBookings.length)}% from last week`\n                  : \"Unknown percentage from last week (no bookings)\"\n              }\n              className={cn(\n                Math.round(\n                  ((thisWeekBookings.length - lastWeekBookings.length) / lastWeekBookings.length) * 100\n                ) < 0\n                  ? \"[&>div]:bg-destructive/80\"\n                  : \"[&>div]:bg-success\"\n              )}\n            />\n          </CardFooter>\n        </Card>\n        <Card x-chunk=\"dashboard-05-chunk-2\">\n          <CardHeader className=\"pb-2\">\n            <CardDescription>This Month</CardDescription>\n            <CardTitle className=\"text-4xl\">{thisMonthBookings.length}</CardTitle>\n          </CardHeader>\n          <CardContent>\n            <div className=\"text-xs text-muted-foreground\">\n              {lastMonthBookings.length > 0\n                ? `${changeFromPrevious(thisMonthBookings.length, lastMonthBookings.length)}% from last week`\n                : \"From 0 last month\"}\n            </div>\n          </CardContent>\n          <CardFooter>\n            <Progress\n              value={Math.abs(changeFromPrevious(thisMonthBookings.length, lastMonthBookings.length))}\n              aria-label={\n                lastMonthBookings.length > 0\n                  ? `${changeFromPrevious(thisMonthBookings.length, lastMonthBookings.length)}% from last week`\n                  : \"Unknown percentage from last month (no bookings)\"\n              }\n              className={cn(\n                Math.round(\n                  ((thisMonthBookings.length - lastMonthBookings.length) / lastMonthBookings.length) * 100\n                ) < 0\n                  ? \"[&>div]:bg-destructive/80\"\n                  : \"[&>div]:bg-success\"\n              )}\n            />\n          </CardFooter>\n        </Card>\n      </div>\n      <Suspense>\n        <CalAccount>\n          {(calAccount) => (\n            <BookingsTable\n              bookings={{\n                all: bookings,\n                currentWeek: thisWeekBookings,\n                currentMonth: thisMonthBookings,\n                currentYear: thisYearBookings,\n              }}\n              user={{\n                timeZone: calAccount.timeZone,\n                username: calAccount.username,\n                email: stripCalOAuthClientIdFromEmail(calAccount.email),\n              }}\n            />\n          )}\n        </CalAccount>\n      </Suspense>\n    </main>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/_components/expert-edit.tsx",
    "content": "\"use client\";\n\nimport { expertEdit } from \"@/app/_actions\";\nimport { ButtonSubmit } from \"@/app/_components/submit-button\";\nimport { CardDescription } from \"@/components/ui/card\";\nimport { Input, type InputProps } from \"@/components/ui/input\";\nimport { Textarea, type TextareaProps } from \"@/components/ui/textarea\";\nimport { useActionState } from \"react\";\n\nexport default function ExpertEditForm(props: InputProps | TextareaProps) {\n  const [state, submitAction, isPendingAction] = useActionState<\n    { error: null | string } | { success: null | string },\n    FormData\n  >(expertEdit, { error: null }, \"/dashboard/settings/profile\");\n\n  return (\n    <form action={submitAction} className=\"flex flex-col gap-4\">\n      {props.name === \"bio\" ? (\n        <Textarea\n          {...(props as TextareaProps)}\n          className=\"min-w-72 text-balance text-sm leading-relaxed text-muted-foreground\"\n          disabled={isPendingAction}\n        />\n      ) : (\n        <Input {...(props as InputProps)} disabled={isPendingAction} />\n      )}\n      {/* display action states (pending, idle, success & error) */}\n      {isPendingAction ? (\n        <CardDescription>Saving...</CardDescription>\n      ) : \"success\" in state && state.success ? (\n        <CardDescription>{state.success}</CardDescription>\n      ) : \"error\" in state && state.error ? (\n        <CardDescription className=\"text-red-900\">{state.error}</CardDescription>\n      ) : (\n        <CardDescription>\n          Provide a new {props.name} and hit save to reflect the changes on your public page.\n        </CardDescription>\n      )}\n      <ButtonSubmit size=\"sm\" variant=\"default\">\n        Save\n      </ButtonSubmit>\n    </form>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/_components/settings-content.tsx",
    "content": "\"use client\";\n\nimport { AvailabilitySettings } from \"@calcom/atoms\";\n\n/**\n * [@calcom] Make sure to wrap your app with our `CalProvider` to enable the use of our hooks.\n * @link https://cal.com/docs/platform/quick-start#5.3-setup-root-of-your-app\n */\nexport const SettingsContent = () => {\n  return (\n    <div className=\"grid gap-6 [&>div]:rounded-lg [&>div]:border [&>div]:bg-card [&>div]:text-card-foreground [&>div]:shadow-sm\">\n      <AvailabilitySettings\n        customClassNames={{\n          // this is to avoid layout shift when toggling days\n          scheduleClassNames: {\n            scheduleDay: \"min-w-[480px]\",\n          },\n          containerClassName: \"!font-sans !p-6\",\n          editableHeadingClassName:\n            \"!text-2xl !font-semibold !leading-none !tracking-tight !pr-4  !text-foreground min-w-[20rem]\",\n          subtitlesClassName: \"!text-sm !leading-relaxed !max-w-lg !text-balance !text-muted-foreground\",\n        }}\n        onUpdateSuccess={() => {\n          console.log(\"[@calcom/atoms]: Updated successfully\");\n        }}\n        onUpdateError={() => {\n          console.log(\"[@calcom/atoms]: Update error\");\n        }}\n        onDeleteError={() => {\n          console.log(\"[@calcom/atoms]: Deletion error\");\n        }}\n        onDeleteSuccess={() => {\n          console.log(\"[@calcom/atoms]: Deleted successfully\");\n        }}\n      />\n    </div>\n  );\n};\nexport default SettingsContent;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/_components/supabase-react-dropzone.tsx",
    "content": "\"use client\";\n\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { env } from \"@/env\";\nimport slugify, { cn } from \"@/lib/utils\";\nimport { createClient } from \"@supabase/supabase-js\";\nimport Image from \"next/image\";\nimport type StorageFileApi from \"node_modules/.pnpm/@supabase+storage-js@2.6.0/node_modules/@supabase/storage-js/src/packages/StorageFileApi\";\nimport React, { useState, useEffect } from \"react\";\nimport { useDropzone } from \"react-dropzone\";\n\ntype SupabaseStorage = (typeof StorageFileApi)[\"prototype\"];\ntype FileBody = Parameters<SupabaseStorage[\"uploadToSignedUrl\"]>[2];\nexport default function SupabaseReactDropzone({ userId }: { userId: string; userInitials?: string }) {\n  const [status, setStatus] = useState<\"idle\" | \"loading\" | \"error\" | \"success\">(\"idle\");\n\n  const supabaseBrowserClient = createClient(env.NEXT_PUBLIC_SUPABASE_URL, env.NEXT_PUBLIC_SUPABASE_ANON_KEY);\n  const [avatar, setAvatar] = useState<string | null>(`avatars/${userId}`);\n  useEffect(() => {\n    setStatus(\"idle\");\n  }, [avatar]);\n  const { acceptedFiles, fileRejections, getRootProps, getInputProps } = useDropzone({\n    maxFiles: 1,\n    accept: {\n      \"image/jpeg\": [],\n      \"image/png\": [],\n      // avif as well:\n      \"image/avif\": [],\n    },\n    onDropAccepted: async (acceptedFiles) => {\n      setAvatar(null);\n      const { path, token }: { path: string; token: string } = await fetch(\"/api/supabase/storage\").then(\n        (res) => res.json()\n      );\n\n      const { data, error } = await supabaseBrowserClient.storage\n        .from(\"avatars\")\n        .uploadToSignedUrl(path, token, acceptedFiles[0] as FileBody);\n      if (typeof data?.fullPath === \"string\") {\n        // @ts-expect-error acceptedFiles isn't typed\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n        setAvatar(`${data?.fullPath}?filename=${encodeURIComponent(slugify(acceptedFiles[0].path))}`);\n      }\n    },\n  });\n\n  // const acceptedFileItems = acceptedFiles.map((file) => (\n  //   <li key={file.path}>\n  //     {file.path} - {file.size} bytes\n  //   </li>\n  // ));\n\n  // const fileRejectionItems = fileRejections.map(({ file, errors }) => (\n  //   <li key={file.path}>\n  //     {file.path} - {file.size} bytes\n  //     <ul>\n  //       {errors.map((e) => (\n  //         <li key={e.code}>{e.message}</li>\n  //       ))}\n  //     </ul>\n  //   </li>\n  // ));\n\n  return (\n    <div className=\"mx-auto grid w-full gap-4\">\n      {status === \"error\" ? (\n        <div className=\"aspect-square size-16 rounded-md bg-muted\" />\n      ) : status === \"loading\" || !avatar ? (\n        <Skeleton className=\"aspect-square size-16 rounded-md\" />\n      ) : (\n        <Image\n          alt=\"Expert image\"\n          className=\"aspect-square rounded-md object-cover\"\n          src={avatar}\n          height=\"64\"\n          width=\"64\"\n          onLoadingComplete={() => setStatus(\"success\")}\n          onLoad={() => setStatus(\"loading\")}\n          onError={() => setStatus(\"error\")}\n        />\n      )}\n      <div\n        {...getRootProps({\n          className: cn(\n            \"dropzone border-dashed border px-3 py-8 rounded-md hover:border-foreground/40 cursor-pointer\"\n          ),\n        })}>\n        <input {...getInputProps()} />\n        <p className=\"text-sm text-muted-foreground\">Only *.jpeg, *.png and *.avif images will be accepted</p>\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/availability/page.tsx",
    "content": "import SettingsContent from \"../_components/settings-content\";\n\nexport default async function DashboardSettingsAvailability() {\n  return <SettingsContent />;\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/booking-events/_actions.ts",
    "content": "\"use server\";\n\nimport { auth } from \"@/auth\";\nimport { post_EventTypesController_createEventType } from \"@/cal/__generated/cal-sdk\";\nimport { cal } from \"@/cal/api\";\nimport { revalidatePath } from \"next/cache\";\nimport { type z } from \"zod\";\n\nexport async function createEventType(\n  _prevState: { error: null | string } | { success: null | string },\n  formData: FormData\n) {\n  const sesh = await auth();\n  if (!sesh?.user.id) {\n    console.log(\"[_actions] Unauthorized user edit\", formData);\n    return { error: \"Unauthorized\" };\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n  const updateEventTypeBodyData = Object.fromEntries(\n    Array.from(formData.entries())\n      .filter(([key]) => !key.toLowerCase().startsWith(\"$action\"))\n      .map(([key, value]) => {\n        if (key === \"length\") return [key, Number(value)];\n        return [key, value];\n      })\n  );\n  const updateEventTypeParameters = {\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n    body: updateEventTypeBodyData,\n  } satisfies z.infer<typeof post_EventTypesController_createEventType.parameters>;\n\n  const input = post_EventTypesController_createEventType.parameters.safeParse(updateEventTypeParameters);\n\n  if (!input.success) {\n    console.log(\"[_actions] Invalid form data\", formData);\n    return { error: \"Invalid form data\" };\n  }\n\n  const res = await cal({ user: { id: sesh?.user.id } }).post(\"/v2/event-types\", {\n    body: input.data.body,\n  });\n  if (res.status === \"error\") {\n    console.error(\n      `[_actions] Error creating event type for user with id '${sesh.user.id}'. Bad response from Cal Platform API\n      \n        -- REQUEST DETAILS --\n        Endpoint URL: POST /v2/event-types\n\n        Options: ${JSON.stringify(input.data.body)}\n\n        -- RESPONSE DETAILS --\n        responseStatus: ${JSON.stringify(res.status)}\n        \n        responseData: ${JSON.stringify(res.data)}\n      `\n    );\n    return { error: \"Unable to create the booking event (something went wrong).\" };\n  }\n\n  const permalink = String(formData.get(\"permalink\"));\n  permalink && revalidatePath(permalink);\n  return { success: `Event type '${res.data.title}' created successfully.` };\n}\n\nexport async function deleteEventType(\n  _prevState: { error: null | string } | { success: null | string },\n  eventTypeId: number\n) {\n  const sesh = await auth();\n  if (!sesh?.user.id) {\n    console.error(\"[_actions] Unauthorized user delete\");\n    return { error: \"Unauthorized\" };\n  }\n\n  const res = await cal({ user: { id: sesh?.user.id } }).delete(`/v2/event-types/{eventTypeId}`, {\n    path: { eventTypeId },\n  });\n  if (res.status === \"error\") {\n    console.error(\n      `[_actions] Error deleting event type for user with id '${sesh.user.id}'. Bad response from Cal Platform API\n      \n        -- REQUEST DETAILS --\n        Endpoint URL: DELETE /v2/event-types/{eventTypeId}\n\n        -- RESPONSE DETAILS --\n        responseStatus: ${JSON.stringify(res.status)}\n        \n        responseData: ${JSON.stringify(res.data)}\n      `\n    );\n    return { error: \"Unable to delete the booking event (something went wrong).\" };\n  }\n\n  return { success: `Event type '${res.data.title}' created successfully.` };\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/booking-events/event-type-create.tsx",
    "content": "\"use client\";\n\nimport { createEventType } from \"./_actions\";\nimport { DialogDescription } from \"@/components/ui/dialog\";\nimport { cn } from \"@/lib/utils\";\nimport { useActionState } from \"react\";\n\nexport default function EventTypeCreateForm({\n  children,\n  className,\n  ...props\n}: {\n  children?: React.ReactNode;\n  className?: string;\n} & { permalink?: NonNullable<Parameters<typeof useActionState>[\"2\"]> }) {\n  const [state, submitAction, isPendingAction] = useActionState<\n    { error: string | null } | { success: string | null },\n    FormData\n  >(createEventType, { error: null }, props.permalink);\n  return (\n    <form action={submitAction} className={cn(className)}>\n      {isPendingAction ? (\n        <DialogDescription>Saving...</DialogDescription>\n      ) : \"success\" in state && state.success ? (\n        <DialogDescription>{state.success} You can close the dialog now.</DialogDescription>\n      ) : \"error\" in state && state.error ? (\n        <DialogDescription>{state.error.replace(\"'\", \"&rsquo;\")}</DialogDescription>\n      ) : (\n        <DialogDescription>\n          Create your new booking event here. Click save when you&rsquo;re done.\n        </DialogDescription>\n      )}\n      {children}\n    </form>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/booking-events/event-type-delete.tsx",
    "content": "\"use client\";\n\nimport { deleteEventType } from \"./_actions\";\nimport { DropdownMenuItem } from \"@/components/ui/dropdown-menu\";\nimport { useRouter } from \"next/navigation\";\nimport { useActionState } from \"react\";\n\nexport function EventTypeDelete({ eventTypeId }: { eventTypeId: number }) {\n  const router = useRouter();\n  const [_, submitAction, isPendingAction] = useActionState<\n    { error: string | null } | { success: string | null },\n    number\n  >(deleteEventType, { error: null });\n\n  const handleDelete = async () => {\n    submitAction(eventTypeId);\n    router.refresh();\n  };\n\n  return (\n    <DropdownMenuItem className=\"cursor-pointer\" onClick={handleDelete}>\n      {isPendingAction ? \"Deleting...\" : \"Delete\"}\n    </DropdownMenuItem>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/booking-events/page.tsx",
    "content": "import EventTypeCreateForm from \"./event-type-create\";\nimport { EventTypeDelete } from \"./event-type-delete\";\nimport { ButtonSubmit } from \"@/app/_components/submit-button\";\nimport { auth } from \"@/auth\";\nimport { cal } from \"@/cal/api\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuLabel,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"@/components/ui/table\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { MoreHorizontal, PlusCircle, Video } from \"lucide-react\";\nimport { Fragment } from \"react\";\n\nexport default async function DashboardSettingsBookingEvents() {\n  const sesh = await auth();\n  if (!sesh?.user.id) {\n    return <div>Not logged in</div>;\n  }\n  const getEventTypes = await cal({ user: { id: sesh?.user.id } }).get(\"/v2/event-types\");\n  if (getEventTypes.status === \"error\") {\n    console.error(\"[dashboard/settings/booking-events/page.tsx] Error fetching event types\", getEventTypes);\n    // TODO debug this error\n    console.warn(`[dashboard/settings/booking-events/page.tsx] Error fetching event types. Check logs above`);\n  }\n  const eventTypes = getEventTypes?.data?.eventTypeGroups?.flatMap((group) => group.eventTypes) ?? [\n    {\n      length: 60,\n      slug: \"60min\",\n      title: \"60min\",\n      description: \"A 60 minute session\",\n      locations: [\n        {\n          type: \"location\",\n          link: \"https://cal.com/locations/1\",\n        },\n      ],\n      id: 1,\n    },\n    {\n      length: 30,\n      slug: \"30min\",\n      title: \"30min\",\n      description: \"A 30 minute session\",\n      locations: [\n        {\n          type: \"location\",\n          link: \"https://cal.com/locations/1\",\n        },\n      ],\n      id: 2,\n    },\n  ];\n  return (\n    <Fragment>\n      <div className=\"flex items-center\">\n        <div className=\"mr-auto flex items-center gap-2\">\n          {/* TODO: add filter logic via url params */}\n          {/* <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <Button variant=\"outline\" size=\"sm\" className=\"h-8 gap-1\">\n                <ListFilter className=\"h-3.5 w-3.5\" />\n                <span className=\"sr-only sm:not-sr-only sm:whitespace-nowrap\">Filter</span>\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\">\n              <DropdownMenuLabel>Filter by</DropdownMenuLabel>\n              <DropdownMenuSeparator />\n              <DropdownMenuCheckboxItem checked>Active</DropdownMenuCheckboxItem>\n              <DropdownMenuCheckboxItem>Draft</DropdownMenuCheckboxItem>\n              <DropdownMenuCheckboxItem>Archived</DropdownMenuCheckboxItem>\n            </DropdownMenuContent>\n          </DropdownMenu> */}\n          <Dialog>\n            <DialogTrigger asChild>\n              <Button size=\"sm\" className=\"h-8 gap-1\">\n                <PlusCircle className=\"size-3.5\" />\n                <span className=\"sr-only sm:not-sr-only sm:whitespace-nowrap\">Add Event Type</span>\n              </Button>\n            </DialogTrigger>\n            <DialogContent className=\"sm:max-w-[425px]\">\n              <DialogHeader>\n                <DialogTitle>Create a new Booking Event</DialogTitle>\n              </DialogHeader>\n              <EventTypeCreateForm permalink=\"/dashboard/settings/booking-events\">\n                <div className=\"grid gap-4 py-4\">\n                  <div className=\"grid grid-cols-4 items-center gap-4\">\n                    {(\n                      [\n                        {\n                          name: \"length\",\n                          label: \"Duration\",\n                          type: \"number\",\n                          min: \"15\",\n                          step: \"15\",\n                          max: \"300\",\n                          required: true,\n                        },\n                        {\n                          name: \"slug\",\n                          label: \"URL Slug\",\n                          pattern: \"^[a-z0-9]+(?:-[a-z0-9]+)*$\",\n                          required: true,\n                        },\n                        {\n                          name: \"title\",\n                          label: \"Title\",\n                          type: \"text\",\n                          minlength: \"3\",\n                          maxlength: \"30\",\n                          required: true,\n                        },\n                        {\n                          name: \"description\",\n                          label: \"Description\",\n                          type: \"text\",\n                          minlength: \"3\",\n                          maxlength: \"300\",\n                        },\n                      ] as const\n                    ).map(({ name, label, ...inputAttributes }) => (\n                      <Fragment key={name}>\n                        <Label htmlFor={name} className=\"text-right\">\n                          {label}\n                        </Label>\n                        {name === \"description\" ? (\n                          <Textarea id={name} name={name} {...inputAttributes} className=\"col-span-3\" />\n                        ) : (\n                          <Input id={name} name={name} {...inputAttributes} className=\"col-span-3\" />\n                        )}\n                      </Fragment>\n                    ))}\n                  </div>\n                </div>\n                <DialogFooter className=\"sm:justify-content justify-center\">\n                  <ButtonSubmit variant=\"default\">Save</ButtonSubmit>\n                </DialogFooter>\n              </EventTypeCreateForm>\n            </DialogContent>\n          </Dialog>\n        </div>\n      </div>\n      <Card>\n        <CardHeader>\n          <CardTitle>Event Types</CardTitle>\n          <CardDescription>Manage your event type and view their sales performance.</CardDescription>\n        </CardHeader>\n        <CardContent>\n          <Table>\n            <TableHeader>\n              <TableRow>\n                <TableHead>Name</TableHead>\n                <TableHead>Description</TableHead>\n                <TableHead>Locations</TableHead>\n                <TableHead className=\"hidden md:table-cell\">Duration (min)</TableHead>\n                <TableHead>\n                  <span className=\"sr-only\">Actions</span>\n                </TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {eventTypes.map((eventType) => (\n                <TableRow key={eventType.id}>\n                  <TableCell>\n                    <div className=\"font-medium capitalize\">{eventType.title}</div>\n                    <div className=\"hidden text-sm text-muted-foreground md:inline\">/{eventType.slug}</div>\n                  </TableCell>\n                  <TableCell>\n                    <div className=\"hidden text-sm text-muted-foreground md:inline\">\n                      {eventType.description}\n                    </div>\n                  </TableCell>\n                  <TableCell>\n                    {eventType.locations?.map((location, idx) => (\n                      <Badge key={idx} variant=\"default\">\n                        {location.type === \"integrations:daily\" && (\n                          <div className=\"text-emphasis inline-flex items-center justify-center gap-x-1 text-xs font-medium leading-3\">\n                            <Video className=\"size-3\" />\n                            Cal Video\n                          </div>\n                        )}\n                      </Badge>\n                    ))}\n                  </TableCell>\n                  <TableCell className=\"hidden md:table-cell\">{eventType.length}</TableCell>\n                  <TableCell>\n                    <DropdownMenu>\n                      <DropdownMenuTrigger asChild>\n                        <Button aria-haspopup=\"true\" size=\"icon\" variant=\"ghost\">\n                          <MoreHorizontal className=\"h-4 w-4\" />\n                          <span className=\"sr-only\">Toggle menu</span>\n                        </Button>\n                      </DropdownMenuTrigger>\n                      <DropdownMenuContent align=\"end\">\n                        <DropdownMenuLabel>Actions</DropdownMenuLabel>\n                        <EventTypeDelete eventTypeId={eventType.id} />\n                      </DropdownMenuContent>\n                    </DropdownMenu>\n                  </TableCell>\n                </TableRow>\n              ))}\n            </TableBody>\n          </Table>\n        </CardContent>\n        <CardFooter>\n          <div className=\"text-xs text-muted-foreground\">\n            Showing{\" \"}\n            <strong>\n              {eventTypes.length > 0 ? 1 : 0}-{eventTypes.length > 10 ? 10 : eventTypes.length}\n            </strong>{\" \"}\n            of <strong>{eventTypes.length}</strong> event types\n          </div>\n        </CardFooter>\n      </Card>\n    </Fragment>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/layout.tsx",
    "content": "export default function SettingsLayout(props: { children: React.ReactNode }) {\n  return (\n    <main className=\"flex min-h-[calc(100vh_-_theme(spacing.16))] flex-1 flex-col gap-4 bg-muted/40 p-4 md:gap-8 md:p-8\">\n      {props.children}\n    </main>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/page.tsx",
    "content": "export default function SettingsOutlet() {\n  return null;\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/dashboard/settings/profile/page.tsx",
    "content": "import ExpertEditForm from \"../_components/expert-edit\";\nimport SupabaseReactDropzone from \"../_components/supabase-react-dropzone\";\nimport { currentUser } from \"@/auth\";\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Info } from \"lucide-react\";\n\nexport const dynamic = \"force-dynamic\";\n\nexport default async function DashboardSettingsProfile() {\n  const expert = await currentUser();\n  if (!expert) {\n    return <div>Not logged in</div>;\n  }\n  return (\n    <div className=\"grid gap-6\">\n      <Card x-chunk=\"dashboard-04-chunk-1\">\n        <CardHeader>\n          <CardTitle>Image</CardTitle>\n          <CardDescription>Used on your public profile, once it is approved.</CardDescription>\n        </CardHeader>\n        <CardContent>\n          <div className=\"flex flex-col gap-4\">\n            <SupabaseReactDropzone userId={expert.id} />\n          </div>\n        </CardContent>\n        <CardFooter className=\"border-t px-6 py-6\">\n          <CardDescription className=\"flex items-center gap-1\">\n            <Info className=\"size-3.5\" />\n            The Image upload auto-saves.\n          </CardDescription>\n        </CardFooter>\n      </Card>\n      <Card x-chunk=\"dashboard-04-chunk-1\">\n        <CardHeader>\n          <CardTitle>Name</CardTitle>\n          <CardDescription>Used on your public profile, once it is approved.</CardDescription>\n        </CardHeader>\n        <CardContent>\n          <ExpertEditForm id=\"name\" name=\"name\" placeholder={expert.name ?? \"Your name\"} />\n        </CardContent>\n      </Card>\n      <Card x-chunk=\"dashboard-04-chunk-2\">\n        <CardHeader>\n          <CardTitle>Bio</CardTitle>\n          <CardDescription>\n            A couple of sentences about yourself. This will be displayed on your public profile.\n          </CardDescription>\n        </CardHeader>\n        <CardContent>\n          <ExpertEditForm id=\"bio\" name=\"bio\" placeholder={expert.bio ?? \"Your Bio\"} />\n        </CardContent>\n      </Card>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/layout.tsx",
    "content": "import Banner from \"./_components/banner\";\nimport UseCalAtoms from \"./_components/use-cal\";\nimport { Providers } from \"./providers\";\nimport { TailwindIndicator } from \"./tailwind-indicator\";\nimport { currentUser } from \"@/auth\";\nimport { cn } from \"@/lib/utils\";\nimport \"@/styles/globals.css\";\nimport \"@/styles/globals.css\";\n\n/**\n * [@calcom] In your root layout, make sure you import the atoms' global styles so that you get our shiny styles\n * @link https://cal.com/docs/platform/quick-start#5.3-setup-root-of-your-app\n */\nimport \"@calcom/atoms/globals.min.css\";\nimport { Analytics } from \"@vercel/analytics/react\";\nimport { type Metadata } from \"next\";\nimport { AxiomWebVitals } from \"next-axiom\";\nimport { Inter } from \"next/font/google\";\nimport localFont from \"next/font/local\";\nimport { Toaster } from \"sonner\";\n\nconst interFont = Inter({ subsets: [\"latin\"], variable: \"--font-inter\", preload: true, display: \"swap\" });\nconst calFont = localFont({\n  src: \"../fonts/CalSans-SemiBold.woff2\",\n  variable: \"--font-cal\",\n  preload: true,\n  display: \"block\",\n  weight: \"600\",\n});\n\nexport const metadata: Metadata = {\n  title: {\n    default: \"Cal.com Platform: Showcase App\",\n    template: `Cal.com Platform | %s`,\n  },\n  description: \"Cal.com Platform example app: Showcase usage of the 'Cal Atoms' React Components\",\n  keywords: [\n    \"cal.com\",\n    \"platform\",\n    \"example\",\n    \"app\",\n    \"scheduling software\",\n    \"scheduling components\",\n    \"scheduling react\",\n  ],\n  authors: [\n    {\n      name: \"Richard Poelderl\",\n      url: \"https://x.com/richardpoelderl\",\n    },\n    { name: \"Peer Richelsen\", url: \"https://x.com/peerrich\" },\n  ],\n  creator: \"Cal.com\",\n  icons: [{ rel: \"icon\", url: \"/favicon.ico\" }],\n};\n\nexport default async function RootLayout({ children }: { children: React.ReactNode }) {\n  return (\n    /** [@calcom] Ensure to set the diretion (either 'ltr' or 'rtl') since the calcom/atoms use their styles */\n    <html lang=\"en\" dir=\"ltr\">\n      <head />\n      <AxiomWebVitals />\n      <body className={cn(\"antialiased\", calFont.variable, interFont.variable)}>\n        <Providers defaultTheme=\"system\" enableSystem attribute=\"class\">\n          <div className=\"flex min-h-screen flex-col\">\n            <Banner\n              title=\"Build your own marketplace\"\n              description=\"Use our Platform Starter Kit to go live in 15 minutes.\"\n              ctaLink=\"https://go.cal.com/starter-kit\"\n            />\n            <UseCalAtoms\n              calAccessToken={currentUser().then((dbUser) => dbUser?.calAccessToken ?? null) ?? null}>\n              {children}\n            </UseCalAtoms>\n          </div>\n          <TailwindIndicator />\n        </Providers>\n        <Toaster />\n      </body>\n      <Analytics />\n    </html>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/login/_components/input.tsx",
    "content": "import { Input, type InputProps } from \"@/components/ui/input\";\nimport { cn } from \"@/lib/utils\";\nimport { type ReactNode } from \"react\";\n\nexport const AddonFieldPrefix = (props: { children?: ReactNode; prefix: string }) => {\n  return (\n    <div className=\"flex rounded-md bg-muted shadow-sm ring-1 ring-inset ring-input ring-offset-background focus-within:outline-none focus-within:ring-2 focus-within:ring-inset focus-within:ring-ring focus-within:ring-offset-2 sm:max-w-md\">\n      <span className=\"flex h-10 select-none items-center border-none pl-3 text-muted-foreground sm:text-sm\">\n        {props.prefix}\n      </span>\n      {props.children}\n    </div>\n  );\n};\nexport const AddonFieldInput = (props: { className?: string } & InputProps) => {\n  const { className } = props;\n  return (\n    <Input\n      {...props}\n      className={cn(\n        \"ml-1 rounded-l-none border-0 ring-0 ring-input focus:ring-0 focus-visible:outline-0 focus-visible:ring-0 focus-visible:ring-inset\",\n        className\n      )}\n    />\n  );\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/login/_components/login.tsx",
    "content": "\"use client\";\n\nimport { signInWithCredentials } from \"@/app/_actions\";\nimport { ButtonSubmit } from \"@/app/_components/submit-button\";\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport Link from \"next/link\";\nimport { useFormState } from \"react-dom\";\n\nexport type LoginFormState =\n  | {\n      inputErrors: {\n        email?: string[] | undefined;\n        password?: string[] | undefined;\n      };\n      error?: undefined;\n    }\n  | {\n      error: null;\n      inputErrors?: undefined;\n    }\n  | {\n      error: string;\n      inputErrors?: undefined;\n    };\n\nexport function LoginForm() {\n  const [formState, dispatch] = useFormState<LoginFormState, FormData>(signInWithCredentials, {\n    error: null,\n  });\n\n  return (\n    <form action={dispatch}>\n      <Card className=\"w-full max-w-sm\">\n        <CardHeader>\n          <CardTitle className=\"text-2xl\">Login</CardTitle>\n          <CardDescription>Enter your email below to login in to your account.</CardDescription>\n        </CardHeader>\n        <CardContent className=\"grid gap-4\">\n          <div className=\"grid gap-2\">\n            <Label htmlFor=\"email\">Email</Label>\n            <Input id=\"email\" name=\"email\" type=\"email\" placeholder=\"m@example.com\" required />\n            {formState?.inputErrors?.email ? (\n              <div className=\"text-sm font-medium text-red-700\" aria-live=\"polite\">\n                {formState.inputErrors.email[0]}\n              </div>\n            ) : null}\n          </div>\n          <div className=\"grid gap-2\">\n            <Label htmlFor=\"password\">Password</Label>\n            <Input id=\"password\" name=\"password\" type=\"password\" required />\n            {formState?.inputErrors?.password ? (\n              <div className=\"text-sm font-medium text-red-700\" aria-live=\"polite\">\n                {formState.inputErrors.password[0]}\n              </div>\n            ) : null}\n          </div>\n          <input hidden name=\"redirectTo\" value=\"/dashboard/getting-started\" readOnly />\n          {!!formState?.error && <p className=\"text-sm font-medium text-red-900\">{formState.error}</p>}\n        </CardContent>\n        <CardFooter>\n          <div className=\"flex w-full flex-col\">\n            <ButtonSubmit variant=\"default\" className=\"w-full\">\n              Log in\n            </ButtonSubmit>\n            <div className=\"mt-4 text-center text-sm\">\n              Don&apos;t have an account?{\" \"}\n              <Link href=\"/signup\" className=\"underline\">\n                Sign up\n              </Link>{\" \"}\n              instead.\n            </div>\n          </div>\n        </CardFooter>\n      </Card>\n    </form>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/login/layout.tsx",
    "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\";\nimport { Button } from \"@/components/ui/button\";\nimport { Sheet, SheetContent, SheetTrigger } from \"@/components/ui/sheet\";\nimport { Home, Package2, PanelLeft } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { type ReactNode } from \"react\";\n\nexport default function LoginLayout({ children }: { children?: ReactNode }) {\n  return (\n    <>\n      <header className=\"sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60\">\n        <div className=\"container flex h-14 max-w-screen-2xl items-center\">\n          <Sheet>\n            <SheetTrigger asChild>\n              <Button size=\"icon\" variant=\"outline\" className=\"sm:hidden\">\n                <PanelLeft className=\"h-5 w-5\" />\n                <span className=\"sr-only\">Toggle Menu</span>\n              </Button>\n            </SheetTrigger>\n            <SheetContent side=\"left\" className=\"sm:max-w-xs\">\n              <nav className=\"grid gap-6 text-lg font-medium\">\n                <Link\n                  href=\"/\"\n                  className=\"group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:text-base\">\n                  <Package2 className=\"h-5 w-5 transition-all group-hover:scale-110\" />\n                  <span className=\"sr-only\">Home</span>\n                </Link>\n                <Link\n                  href=\"#\"\n                  className=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\">\n                  <Home className=\"h-5 w-5\" />\n                  Login\n                </Link>\n              </nav>\n            </SheetContent>\n          </Sheet>\n          <Breadcrumb className=\"hidden md:flex\">\n            <BreadcrumbList>\n              <BreadcrumbItem>\n                <BreadcrumbLink asChild>\n                  <Link href=\"/\">Home</Link>\n                </BreadcrumbLink>\n              </BreadcrumbItem>\n              <BreadcrumbSeparator />\n              <BreadcrumbItem>\n                <BreadcrumbPage>Login</BreadcrumbPage>\n              </BreadcrumbItem>\n            </BreadcrumbList>\n          </Breadcrumb>\n        </div>\n      </header>\n      <main className=\"flex flex-1 flex-1 items-center justify-center\">{children}</main>\n    </>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/login/page.tsx",
    "content": "import { LoginForm } from \"@/app/login/_components/login\";\n\nexport default function LoginPage() {\n  return <LoginForm />;\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/page.tsx",
    "content": "import { Results } from \"./_components/home/results\";\nimport SignupCard from \"./_components/home/signup-card\";\nimport { ButtonSubmit } from \"./_components/submit-button\";\nimport { Logo } from \"./_components/universal/logo\";\nimport { SignedIn, SignedOut, signOut } from \"@/auth\";\nimport { Button } from \"@/components/ui/button\";\nimport { LogIn } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { db } from \"prisma/client\";\nimport React, { Suspense } from \"react\";\n\nexport default async function Home() {\n  const experts = await db.user.findMany({\n    where: { status: \"APPROVED\" },\n    include: { selectedFilterOptions: { include: { filterOption: true } } },\n  });\n\n  return (\n    <React.Fragment>\n      <header className=\"sticky top-0 z-50 flex h-14 items-center justify-between border-b border-border/40 bg-muted/90 px-4 py-2 backdrop-blur lg:h-[60px] lg:px-6\">\n        <Logo />\n        {/*\n        Tip: Use this for your own navigation\n         <Navigation /> */}\n        <div>\n          <SignedIn>\n            {(_user) => (\n              <div className=\"flex gap-2\">\n                <form\n                  action={async () => {\n                    \"use server\";\n                    await signOut({ redirectTo: \"/\" });\n                  }}>\n                  <ButtonSubmit className=\"w-full\" variant=\"outline\">\n                    Logout\n                  </ButtonSubmit>\n                </form>\n                <Link href=\"/dashboard\">\n                  <Button className=\"w-full\">\n                    Dashboard\n                    <LogIn className=\"ml-1 size-4\" />\n                  </Button>\n                </Link>\n              </div>\n            )}\n          </SignedIn>\n          <SignedOut>\n            <div className=\"flex gap-2\">\n              <Link href=\"/login\">\n                <Button variant=\"outline\" className=\"w-full\">\n                  Login\n                </Button>\n              </Link>\n              <Link href=\"/signup\">\n                <Button className=\"w-full\">Sign Up</Button>\n              </Link>\n            </div>\n          </SignedOut>\n        </div>\n      </header>\n      <main className=\"flex-1\">\n        <Suspense>\n          <Results\n            experts={experts}\n            signedOut={\n              <SignedOut>\n                <SignupCard />\n              </SignedOut>\n            }\n          />\n        </Suspense>\n      </main>\n    </React.Fragment>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/providers.tsx",
    "content": "\"use client\";\n\nimport { TooltipProvider } from \"@radix-ui/react-tooltip\";\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\";\nimport type { ThemeProviderProps } from \"next-themes/dist/types\";\nimport * as React from \"react\";\n\nexport function Providers({ children, ...props }: ThemeProviderProps) {\n  return (\n    <NextThemesProvider {...props}>\n      <TooltipProvider>{children}</TooltipProvider>\n    </NextThemesProvider>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/signup/_components/input.tsx",
    "content": "import { Input, type InputProps } from \"@/components/ui/input\";\nimport { cn } from \"@/lib/utils\";\nimport { type ReactNode } from \"react\";\n\nexport const AddonFieldPrefix = (props: { children?: ReactNode; prefix: string }) => {\n  return (\n    <div className=\"flex rounded-md bg-muted shadow-sm ring-1 ring-inset ring-input ring-offset-background focus-within:outline-none focus-within:ring-2 focus-within:ring-inset focus-within:ring-ring focus-within:ring-offset-2 sm:max-w-md\">\n      <span className=\"flex h-10 select-none items-center border-none pl-3 text-muted-foreground sm:text-sm\">\n        {props.prefix}\n      </span>\n      {props.children}\n    </div>\n  );\n};\nexport const AddonFieldInput = (props: { className?: string } & InputProps) => {\n  const { className } = props;\n  return (\n    <Input\n      {...props}\n      className={cn(\n        \"ml-1 rounded-l-none border-0 ring-0 ring-input focus:ring-0 focus-visible:outline-0 focus-visible:ring-0 focus-visible:ring-inset\",\n        className\n      )}\n    />\n  );\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/signup/_components/signup.tsx",
    "content": "\"use client\";\n\nimport { signUpWithCredentials } from \"@/app/_actions\";\nimport { AddonFieldInput, AddonFieldPrefix } from \"@/app/signup/_components/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport Link from \"next/link\";\nimport { useFormState } from \"react-dom\";\n\ntype TSignUpFormState = {\n  error?: string | null;\n  inputErrors?: {\n    name?: string[];\n    username?: string[];\n    email?: string[];\n    password?: string[];\n    bio?: string[];\n    categories?: string[];\n    capabilities?: string[];\n    frameworks?: string[];\n    budgets?: string[];\n    languages?: string[];\n    regions?: string[];\n  };\n};\n\nexport const SignupForm = () => {\n  const [formState, dispatch] = useFormState<TSignUpFormState, FormData>(signUpWithCredentials, {\n    error: null,\n  });\n\n  return (\n    <form action={dispatch}>\n      <Card className=\"mx-auto max-w-sm\">\n        <CardHeader>\n          <CardTitle className=\"text-xl\">Sign Up</CardTitle>\n          <CardDescription>Enter your information to create an account</CardDescription>\n        </CardHeader>\n        <CardContent>\n          <div className=\"grid gap-4\">\n            <div className=\"grid gap-2\">\n              <Label htmlFor=\"name\">Name</Label>\n              <Input id=\"name\" name=\"name\" placeholder=\"John Doe\" required />\n              {formState?.inputErrors?.name ? (\n                <div className=\"text-sm font-medium text-red-700\" aria-live=\"polite\">\n                  {formState.inputErrors.name[0]}\n                </div>\n              ) : null}\n            </div>\n            <div className=\"grid gap-2\">\n              <Label htmlFor=\"username\">Username</Label>\n              <AddonFieldPrefix prefix=\"experts.cal.com/\">\n                <AddonFieldInput id=\"username\" name=\"username\" placeholder=\"john-doe\" required />\n              </AddonFieldPrefix>\n              {formState?.inputErrors?.username ? (\n                <div className=\"text-sm font-medium text-red-700\" aria-live=\"polite\">\n                  {formState.inputErrors.username[0]}\n                </div>\n              ) : null}\n            </div>\n            <div className=\"grid gap-2\">\n              <Label htmlFor=\"email\">Email</Label>\n              <Input id=\"email\" name=\"email\" type=\"email\" placeholder=\"m@example.com\" required />\n              {formState?.inputErrors?.email ? (\n                <div className=\"text-sm font-medium text-red-700\" aria-live=\"polite\">\n                  {formState.inputErrors.email[0]}\n                </div>\n              ) : null}\n            </div>\n            <div className=\"grid gap-2\">\n              <Label htmlFor=\"password\">Password</Label>\n              <Input id=\"password\" name=\"password\" type=\"password\" />\n              {formState?.inputErrors?.password ? (\n                <div className=\"text-sm font-medium text-red-700\" aria-live=\"polite\">\n                  {formState.inputErrors.password[0]}\n                </div>\n              ) : null}\n            </div>\n\n            {formState?.error ? (\n              <div className=\"text-sm font-medium text-red-700\" aria-live=\"polite\">\n                {formState.error}\n              </div>\n            ) : null}\n            <input hidden name=\"redirectTo\" value=\"/dashboard/getting-started\" readOnly />\n            <Button type=\"submit\" className=\"w-full\">\n              Create an account\n            </Button>\n          </div>\n          <div className=\"mt-4 text-center text-sm\">\n            Already have an account?{\" \"}\n            <Link href=\"/login\" className=\"underline\">\n              Log in\n            </Link>\n          </div>\n        </CardContent>\n      </Card>\n    </form>\n  );\n};\nexport default SignupForm;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/signup/layout.tsx",
    "content": "import {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\";\nimport { Button } from \"@/components/ui/button\";\nimport { Sheet, SheetContent, SheetTrigger } from \"@/components/ui/sheet\";\nimport { Home, Package2, PanelLeft } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { type ReactNode } from \"react\";\n\nexport default function SignupLayout({ children }: { children?: ReactNode }) {\n  return (\n    <>\n      <header className=\"sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60\">\n        <div className=\"container flex h-14 max-w-screen-2xl items-center\">\n          <Sheet>\n            <SheetTrigger asChild>\n              <Button size=\"icon\" variant=\"outline\" className=\"sm:hidden\">\n                <PanelLeft className=\"h-5 w-5\" />\n                <span className=\"sr-only\">Toggle Menu</span>\n              </Button>\n            </SheetTrigger>\n            <SheetContent side=\"left\" className=\"sm:max-w-xs\">\n              <nav className=\"grid gap-6 text-lg font-medium\">\n                <Link\n                  href=\"/\"\n                  className=\"group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:text-base\">\n                  <Package2 className=\"h-5 w-5 transition-all group-hover:scale-110\" />\n                  <span className=\"sr-only\">Home</span>\n                </Link>\n                <Link\n                  href=\"#\"\n                  className=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\">\n                  <Home className=\"h-5 w-5\" />\n                  Signup\n                </Link>\n              </nav>\n            </SheetContent>\n          </Sheet>\n          <Breadcrumb className=\"hidden md:flex\">\n            <BreadcrumbList>\n              <BreadcrumbItem>\n                <BreadcrumbLink asChild>\n                  <Link href=\"/\">Home</Link>\n                </BreadcrumbLink>\n              </BreadcrumbItem>\n              <BreadcrumbSeparator />\n              <BreadcrumbItem>\n                <BreadcrumbPage>Signup</BreadcrumbPage>\n              </BreadcrumbItem>\n            </BreadcrumbList>\n          </Breadcrumb>\n        </div>\n      </header>\n      <main className=\"flex-1\">{children}</main>\n    </>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/signup/page.tsx",
    "content": "import { SignupForm } from \"@/app/signup/_components/signup\";\n\nexport default async function SignupPage() {\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <SignupForm  />\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/app/tailwind-indicator.tsx",
    "content": "import { IS_PRODUCTION } from \"@/lib/constants\";\n\nexport function TailwindIndicator() {\n  if (IS_PRODUCTION) return null;\n\n  return (\n    <div className=\"fixed bottom-1 left-1 z-50 flex h-6 w-6 items-center justify-center rounded-full bg-gray-800 p-3 font-mono text-xs text-white\">\n      <div className=\"block sm:hidden\">xs</div>\n      <div className=\"hidden sm:block md:hidden lg:hidden xl:hidden 2xl:hidden\">sm</div>\n      <div className=\"hidden md:block lg:hidden xl:hidden 2xl:hidden\">md</div>\n      <div className=\"hidden lg:block xl:hidden 2xl:hidden\">lg</div>\n      <div className=\"hidden xl:block 2xl:hidden\">xl</div>\n      <div className=\"hidden 2xl:block\">2xl</div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/auth/config.edge.ts",
    "content": "import { signUp } from \"@/cal/auth\";\nimport { PrismaAdapter } from \"@auth/prisma-adapter\";\nimport { type User } from \"@prisma/client\";\nimport { type NextAuthConfig, type DefaultSession } from \"next-auth\";\nimport { type DefaultJWT } from \"next-auth/jwt\";\nimport { db } from \"prisma/client\";\nimport \"server-only\";\nimport { z } from \"zod\";\n\ndeclare module \"next-auth\" {\n  interface Session {\n    user: DefaultSession[\"user\"] & {\n      username: string;\n    };\n  }\n}\ndeclare module \"next-auth/jwt\" {\n  interface JWT extends DefaultJWT {\n    username?: string;\n  }\n}\n\nconst SessionUpdateSchema = z.object({\n  user: z.object({\n    // default fields\n    name: z.string().optional(),\n    email: z.string().optional(),\n    picture: z.string().optional(),\n    // augmented fields\n    username: z.string().optional(),\n  }),\n});\n\nexport const authConfig = {\n  logger: {\n    debug: (message, metadata) => console.debug(message, { metadata }),\n    error: (error) => console.error(error),\n    warn: (message) => console.warn(message),\n  },\n  adapter: PrismaAdapter(db),\n  session: { strategy: \"jwt\" },\n  pages: { signIn: \"/login\" },\n  callbacks: {\n    signIn: async ({ user }) => {\n      if (user.id) {\n        return true;\n      }\n      return false;\n    },\n    jwt: async ({ token, user, trigger, session, account }) => {\n      if (user) {\n        // update the token with the user's data\n        token.sub = user.id;\n        token.email = user.email;\n        token.username = (user as User).username ?? undefined;\n        token.name = user.name;\n      }\n\n      let dbUser: User | null = null;\n      // if this is an update, let's update the token with the provided user data\n      if (trigger === \"update\") {\n        const updateSessionValidation = SessionUpdateSchema.parse(session);\n        const keysToUpdate = Object.keys(updateSessionValidation.user) as Array<\n          keyof z.infer<typeof SessionUpdateSchema.shape.user>\n        >;\n        for (const key of keysToUpdate) {\n          console.info(\n            `\n            \n            [NextAuth.callbacks.jwt] Update user's token (userId: '${token.sub}') with key '${key}' to the value: ${updateSessionValidation.user[key]}\n            The previous value was: ${String(token?.[key])}\n            `\n          );\n          token[key] = updateSessionValidation.user[key];\n        }\n        dbUser = await db.user.update({\n          where: { id: token.sub },\n          data: {\n            name: token.name,\n            email: token.email,\n            username: token.username,\n            // picture: token.picture,\n          },\n        });\n        // update the token with the user's data\n        token.sub = dbUser.id;\n        token.email = dbUser.email;\n        token.username = dbUser.username ?? undefined;\n        token.name = dbUser.name;\n      }\n\n      return token;\n    },\n\n    session: async ({ session, token }) => {\n      // make the token's user fields available on the session, so that we can call auth() to fetch it (no db call needed)\n      if (token?.sub) {\n        session.user.id = token.sub;\n      }\n      if (token?.email) {\n        session.user.email = token.email;\n      }\n      if (token?.username) {\n        session.user.username = token.username;\n      }\n      if (token?.name) {\n        session.user.name = token.name;\n      }\n      if (token?.picture) {\n        session.user.image = token.picture;\n      }\n      return session;\n    },\n\n    authorized({ auth, request: { nextUrl } }) {\n      const isLoggedIn = !!auth?.user;\n      const isOnDashboard = nextUrl.pathname.startsWith(\"/dashboard\");\n      if (isOnDashboard) {\n        // so that we return to login page if isLoggedIn is false\n        return isLoggedIn;\n      }\n      // we explicitly allow our public pages to be accessed by anyone\n      return true;\n    },\n  },\n  // NB: we avoid the credentials provider definition here, so that we can use node-native apis (pw hash) but use this config in the Vercel Edge runtime (middleware)\n  providers: [],\n} satisfies NextAuthConfig;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/auth/index.tsx",
    "content": "import { authConfig } from \"./config.edge\";\nimport { signUp } from \"@/cal/auth\";\nimport { env } from \"@/env\";\nimport { type Prisma, type User, type CalAccount } from \"@prisma/client\";\nimport NextAuth from \"next-auth\";\nimport type { Session } from \"next-auth\";\nimport Credentials from \"next-auth/providers/credentials\";\nimport { randomBytes, scrypt, timingSafeEqual } from \"node:crypto\";\nimport { db } from \"prisma/client\";\nimport { cache } from \"react\";\nimport \"server-only\";\nimport { z } from \"zod\";\n\n// would've loved to use webcrypto apis (supported on edge as well), but: TypeError: randomBytes is not a function\n// globalThis.crypto ??= import(\"node:crypto\").then((m) => m.webcrypto);\n// const Crypto = globalThis.crypto;\nasync function hash(password: string) {\n  return new Promise<string>((resolve, reject) => {\n    const salt = randomBytes(16).toString(\"hex\");\n    scrypt(password, salt, 64, (err, derivedKey) => {\n      if (err) {\n        console.error(\"Error hashing password\", err);\n        reject(err);\n      }\n      resolve(`${salt}.${derivedKey.toString(\"hex\")}`);\n    });\n  });\n}\n\nasync function compare(password: string, hash: string) {\n  return new Promise<boolean>((resolve, reject) => {\n    const [salt, hashKey] = hash.split(\".\") as [string, string];\n    scrypt(password, salt, 64, (err, derivedKey) => {\n      if (err) {\n        console.error(\"Error comparing password\", err);\n        reject(err);\n      }\n      resolve(timingSafeEqual(Buffer.from(hashKey, \"hex\"), derivedKey));\n    });\n  });\n}\n\nexport const LoginSchema = z.object({\n  email: z.string().min(1).max(42),\n  password: z.string().min(6).max(32),\n});\n\nexport const FiltersSchema = z.object({\n  categories: z.preprocess((val) => {\n    if (typeof val !== \"string\") return val; // should error\n    return JSON.parse(val);\n  }, z.array(z.string())),\n  capabilities: z.preprocess((val) => {\n    if (typeof val !== \"string\") return val; // should error\n    return JSON.parse(val);\n  }, z.array(z.string())),\n  frameworks: z.preprocess((val) => {\n    if (typeof val !== \"string\") return val; // should error\n    return JSON.parse(val);\n  }, z.array(z.string())),\n  budgets: z.preprocess((val) => {\n    if (typeof val !== \"string\") return val; // should error\n    return JSON.parse(val);\n  }, z.array(z.string())),\n  languages: z.preprocess((val) => {\n    if (typeof val !== \"string\") return val; // should error\n    return JSON.parse(val);\n  }, z.array(z.string())),\n  regions: z.preprocess((val) => {\n    if (typeof val !== \"string\") return val; // should error\n    return JSON.parse(val);\n  }, z.array(z.string())),\n});\n\nexport const SignupSchema = LoginSchema.merge(\n  z.object({\n    username: z.string().min(1).max(32),\n    name: z.string().min(1).max(32),\n  })\n);\n\ntype UserAfterSignUp = User & { calAccount?: CalAccount };\nconst {\n  auth,\n  handlers: { GET, POST },\n  signIn,\n  signOut,\n  unstable_update,\n} = NextAuth({\n  ...authConfig,\n  /**\n   * [@calcom] 2️⃣ Attach the Credentials provider to NextAuth:\n   */\n  // NB: `withCal` isn't edge ready as it uses node-native apis; we therefore avoid importing it in `confige.edge.ts`\n  providers: [\n    Credentials({\n      name: \"Credentials\",\n      authorize: async (c) => {\n        const credentials = LoginSchema.safeParse(c);\n\n        if (!credentials.success) {\n          console.error(\n            `[auth] Invalid sign in submission because of missing credentials: ${credentials.error.errors.map((e) => e.message).join(\", \")}`\n          );\n          // return `null` to indicate that the credentials are invalid\n          return null;\n        }\n\n        let user: UserAfterSignUp | null = null;\n        try {\n          user = await db.user.findUnique({\n            where: { email: credentials.data.email },\n          });\n\n          if (user) {\n            // if user exists, this comes from our login page, let's check the password\n            console.info(`User ${user.id} attempted login with password`);\n            if (!user.hashedPassword) {\n              console.debug(`OAuth User ${user.id} attempted signin with password`);\n              return null;\n            }\n            const pwMatch = await compare(credentials.data.password, user.hashedPassword);\n            if (!pwMatch) {\n              console.debug(`User ${user.id} attempted login with bad password`);\n              return null;\n            }\n            return user;\n          } else {\n            // if user doesn't exist, this comes from our signup page w/ additional fields\n            const signupData = SignupSchema.safeParse(c);\n            if (!signupData.success) {\n              console.error(\n                `[auth] Invalid sign in submission because of missing signup data: ${signupData.error.errors\n                  .map((e) => {\n                    // return the path of the error with the message:\n                    return `${e.path.join(\".\")} (${e.message}) -> '${e.code}'`;\n                  })\n                  .join(\", \")}`\n              );\n              return null;\n            }\n            user = await db.user.create({\n              data: {\n                username: signupData.data.username,\n                name: signupData.data.name,\n                hashedPassword: await hash(credentials.data.password),\n                email: credentials.data.email,\n              },\n            });\n            if (!user) {\n              console.error(`[auth] Unable to create user with email ${credentials.data.email}`);\n              return null;\n            }\n\n            const toCreate = await signUp({\n              email: credentials.data.email,\n              name: signupData.data.name,\n              user: { id: user.id }, // we don't have the user id yet, so we'll use a placeholder\n            });\n\n            // update the user with the cal account info:\n            user = await db.user.update({ where: { id: user.id }, data: toCreate });\n\n            return user satisfies UserAfterSignUp;\n          }\n        } catch (e) {\n          console.error(e);\n          return null;\n        }\n      },\n    }),\n  ],\n});\n\nexport { signIn, signOut, GET, POST, unstable_update, auth };\n\nexport const currentUser = cache(async () => {\n  const sesh = await auth();\n  if (!sesh?.user.id) return null;\n  return db.user.findUnique({\n    where: { id: sesh.user.id },\n  });\n});\nexport const currentUserWithCalAccount = cache(async () => {\n  const sesh = await auth();\n  if (!sesh?.user.id) throw new Error(\"somehting's wrong here\");\n  return db.calAccount.findUnique({\n    where: { email: sesh?.user?.email?.replace(\"@\", `+${env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}@`) },\n  });\n});\n\nexport async function SignedIn(props: { children: (props: { user: Session[\"user\"] }) => React.ReactNode }) {\n  const sesh = await auth();\n  return sesh?.user ? <>{props.children({ user: sesh.user })}</> : null;\n}\n\nexport async function SignedOut(props: { children: React.ReactNode }) {\n  const sesh = await auth();\n  return sesh?.user ? null : <>{props.children}</>;\n}\n\nexport async function CurrentUser(props: { children: (props: User) => React.ReactNode }) {\n  const user = await currentUser();\n\n  return !!user ? <>{props.children(user)}</> : null;\n}\nexport async function CalAccount(props: { children: (props: CalAccount) => React.ReactNode }) {\n  const calAccount = await currentUserWithCalAccount();\n  return !!calAccount ? <>{props.children(calAccount)}</> : null;\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/cal/__generated/cal-sdk.ts",
    "content": "// @ts-nocheck generated file\nimport z from \"zod\";\n\nexport type ManagedUserOutput = z.infer<typeof ManagedUserOutput>;\nexport const ManagedUserOutput = z.object({\n  id: z.number(),\n  email: z.string(),\n  username: z.union([z.string(), z.null()]),\n  timeZone: z.string(),\n  weekStart: z.string(),\n  createdDate: z.string(),\n  timeFormat: z.union([z.number(), z.null()]),\n  defaultScheduleId: z.union([z.number(), z.null()]),\n});\n\nexport type GetManagedUsersOutput = z.infer<typeof GetManagedUsersOutput>;\nexport const GetManagedUsersOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: z.array(ManagedUserOutput),\n});\n\nexport type CreateManagedUserInput = z.infer<typeof CreateManagedUserInput>;\nexport const CreateManagedUserInput = z.object({\n  email: z.string(),\n  timeFormat: z.union([z.literal(12), z.literal(24), z.undefined()]).optional(),\n  weekStart: z\n    .union([\n      z.literal(\"Monday\"),\n      z.literal(\"Tuesday\"),\n      z.literal(\"Wednesday\"),\n      z.literal(\"Thursday\"),\n      z.literal(\"Friday\"),\n      z.literal(\"Saturday\"),\n      z.literal(\"Sunday\"),\n      z.undefined(),\n    ])\n    .optional(),\n  timeZone: z.union([z.string(), z.undefined()]).optional(),\n  name: z.union([z.string(), z.undefined()]).optional(),\n});\n\nexport type CreateManagedUserData = z.infer<typeof CreateManagedUserData>;\nexport const CreateManagedUserData = z.object({\n  user: ManagedUserOutput,\n  accessToken: z.string(),\n  refreshToken: z.string(),\n});\n\nexport type CreateManagedUserOutput = z.infer<typeof CreateManagedUserOutput>;\nexport const CreateManagedUserOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: CreateManagedUserData,\n});\n\nexport type GetManagedUserOutput = z.infer<typeof GetManagedUserOutput>;\nexport const GetManagedUserOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: ManagedUserOutput,\n});\n\nexport type UpdateManagedUserInput = z.infer<typeof UpdateManagedUserInput>;\nexport const UpdateManagedUserInput = z.object({\n  timeFormat: z.union([z.literal(12), z.literal(24)]).optional(),\n  weekStart: z\n    .union([\n      z.literal(\"Monday\"),\n      z.literal(\"Tuesday\"),\n      z.literal(\"Wednesday\"),\n      z.literal(\"Thursday\"),\n      z.literal(\"Friday\"),\n      z.literal(\"Saturday\"),\n      z.literal(\"Sunday\"),\n    ])\n    .optional(),\n  email: z.string().optional(),\n  name: z.string().optional(),\n  defaultScheduleId: z.number().optional(),\n  timeZone: z.string().optional(),\n});\n\nexport type KeysDto = z.infer<typeof KeysDto>;\nexport const KeysDto = z.object({\n  accessToken: z.string(),\n  refreshToken: z.string(),\n});\n\nexport type KeysResponseDto = z.infer<typeof KeysResponseDto>;\nexport const KeysResponseDto = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: KeysDto,\n});\n\nexport type CreateOAuthClientInput = z.infer<typeof CreateOAuthClientInput>;\nexport const CreateOAuthClientInput = z.object({});\n\nexport type DataDto = z.infer<typeof DataDto>;\nexport const DataDto = z.object({\n  clientId: z.string(),\n  clientSecret: z.string(),\n});\n\nexport type CreateOAuthClientResponseDto = z.infer<typeof CreateOAuthClientResponseDto>;\nexport const CreateOAuthClientResponseDto = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: DataDto,\n});\n\nexport type PlatformOAuthClientDto = z.infer<typeof PlatformOAuthClientDto>;\nexport const PlatformOAuthClientDto = z.object({\n  id: z.string(),\n  name: z.string(),\n  secret: z.string(),\n  permissions: z.number(),\n  logo: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  redirectUris: z.array(z.string()),\n  organizationId: z.number(),\n  createdAt: z.string(),\n});\n\nexport type GetOAuthClientsResponseDto = z.infer<typeof GetOAuthClientsResponseDto>;\nexport const GetOAuthClientsResponseDto = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: z.array(PlatformOAuthClientDto),\n});\n\nexport type GetOAuthClientResponseDto = z.infer<typeof GetOAuthClientResponseDto>;\nexport const GetOAuthClientResponseDto = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: PlatformOAuthClientDto,\n});\n\nexport type UpdateOAuthClientInput = z.infer<typeof UpdateOAuthClientInput>;\nexport const UpdateOAuthClientInput = z.object({\n  logo: z.string().optional(),\n  name: z.string().optional(),\n  redirectUris: z.array(z.string()).optional(),\n  bookingRedirectUri: z.string().optional(),\n  bookingCancelRedirectUri: z.string().optional(),\n  bookingRescheduleRedirectUri: z.string().optional(),\n  areEmailsEnabled: z.boolean().optional(),\n});\n\nexport type OAuthAuthorizeInput = z.infer<typeof OAuthAuthorizeInput>;\nexport const OAuthAuthorizeInput = z.object({\n  redirectUri: z.string(),\n});\n\nexport type ExchangeAuthorizationCodeInput = z.infer<typeof ExchangeAuthorizationCodeInput>;\nexport const ExchangeAuthorizationCodeInput = z.object({\n  clientSecret: z.string(),\n});\n\nexport type RefreshTokenInput = z.infer<typeof RefreshTokenInput>;\nexport const RefreshTokenInput = z.object({\n  refreshToken: z.string(),\n});\n\nexport type EventTypeLocation = z.infer<typeof EventTypeLocation>;\nexport const EventTypeLocation = z.object({\n  type: z.string(),\n  link: z.union([z.string(), z.undefined()]).optional(),\n});\n\nexport type CreateEventTypeInput = z.infer<typeof CreateEventTypeInput>;\nexport const CreateEventTypeInput = z.object({\n  length: z.number(),\n  slug: z.string(),\n  title: z.string(),\n  description: z.union([z.string(), z.undefined()]).optional(),\n  locations: z.union([z.array(EventTypeLocation), z.undefined()]).optional(),\n  disableGuests: z.union([z.boolean(), z.undefined()]).optional(),\n});\n\nexport type EventTypeOutput = z.infer<typeof EventTypeOutput>;\nexport const EventTypeOutput = z.object({\n  id: z.number(),\n  length: z.number(),\n  slug: z.string(),\n  title: z.string(),\n  description: z.union([z.string(), z.null()]),\n  locations: z.union([z.array(EventTypeLocation), z.null()]),\n});\n\nexport type CreateEventTypeOutput = z.infer<typeof CreateEventTypeOutput>;\nexport const CreateEventTypeOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: EventTypeOutput,\n});\n\nexport type Data = z.infer<typeof Data>;\nexport const Data = z.object({\n  eventType: EventTypeOutput,\n});\n\nexport type GetEventTypeOutput = z.infer<typeof GetEventTypeOutput>;\nexport const GetEventTypeOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: Data,\n});\n\nexport type EventTypeGroup = z.infer<typeof EventTypeGroup>;\nexport const EventTypeGroup = z.object({\n  eventTypes: z.array(EventTypeOutput),\n});\n\nexport type GetEventTypesData = z.infer<typeof GetEventTypesData>;\nexport const GetEventTypesData = z.object({\n  eventTypeGroups: z.array(EventTypeGroup),\n});\n\nexport type GetEventTypesOutput = z.infer<typeof GetEventTypesOutput>;\nexport const GetEventTypesOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: GetEventTypesData,\n});\n\nexport type Location = z.infer<typeof Location>;\nexport const Location = z.object({\n  type: z.string(),\n});\n\nexport type Source = z.infer<typeof Source>;\nexport const Source = z.object({\n  id: z.string(),\n  type: z.string(),\n  label: z.string(),\n});\n\nexport type BookingField = z.infer<typeof BookingField>;\nexport const BookingField = z.object({\n  name: z.string(),\n  type: z.string(),\n  defaultLabel: z.union([z.string(), z.undefined()]).optional(),\n  label: z.union([z.string(), z.undefined()]).optional(),\n  placeholder: z.union([z.string(), z.undefined()]).optional(),\n  required: z.union([z.boolean(), z.undefined()]).optional(),\n  getOptionsAt: z.union([z.string(), z.undefined()]).optional(),\n  hideWhenJustOneOption: z.union([z.boolean(), z.undefined()]).optional(),\n  editable: z.union([z.string(), z.undefined()]).optional(),\n  sources: z.union([z.array(Source), z.undefined()]).optional(),\n});\n\nexport type Organization = z.infer<typeof Organization>;\nexport const Organization = z.object({\n  id: z.number(),\n  slug: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  name: z.string(),\n  metadata: z.unknown(),\n});\n\nexport type Profile = z.infer<typeof Profile>;\nexport const Profile = z.object({\n  username: z.union([z.string(), z.null()]),\n  id: z.union([z.number(), z.null()]),\n  userId: z.union([z.number(), z.undefined()]).optional(),\n  uid: z.union([z.string(), z.undefined()]).optional(),\n  name: z.union([z.string(), z.undefined()]).optional(),\n  organizationId: z.union([z.number(), z.null()]),\n  organization: z.union([Organization, z.null(), z.undefined()]).optional(),\n  upId: z.string(),\n  image: z.union([z.string(), z.undefined()]).optional(),\n  brandColor: z.union([z.string(), z.undefined()]).optional(),\n  darkBrandColor: z.union([z.string(), z.undefined()]).optional(),\n  theme: z.union([z.string(), z.undefined()]).optional(),\n  bookerLayouts: z.union([z.unknown(), z.undefined()]).optional(),\n});\n\nexport type Owner = z.infer<typeof Owner>;\nexport const Owner = z.object({\n  id: z.number(),\n  avatarUrl: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  username: z.union([z.string(), z.null()]),\n  name: z.union([z.string(), z.null()]),\n  weekStart: z.string(),\n  brandColor: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  darkBrandColor: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  theme: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  metadata: z.unknown(),\n  defaultScheduleId: z.union([z.number(), z.null(), z.undefined()]).optional(),\n  nonProfileUsername: z.union([z.string(), z.null()]),\n  profile: Profile,\n});\n\nexport type Schedule = z.infer<typeof Schedule>;\nexport const Schedule = z.object({\n  id: z.number(),\n  timeZone: z.union([z.string(), z.null()]),\n});\n\nexport type User = z.infer<typeof User>;\nexport const User = z.object({\n  username: z.union([z.string(), z.null()]),\n  name: z.union([z.string(), z.null()]),\n  weekStart: z.string(),\n  organizationId: z.union([z.number(), z.undefined()]).optional(),\n  avatarUrl: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  profile: Profile,\n  bookerUrl: z.string(),\n});\n\nexport type PublicEventTypeOutput = z.infer<typeof PublicEventTypeOutput>;\nexport const PublicEventTypeOutput = z.object({\n  id: z.number(),\n  title: z.string(),\n  description: z.string(),\n  eventName: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  slug: z.string(),\n  isInstantEvent: z.boolean(),\n  aiPhoneCallConfig: z.union([z.unknown(), z.undefined()]).optional(),\n  schedulingType: z.union([z.unknown(), z.undefined()]).optional(),\n  length: z.number(),\n  locations: z.array(Location),\n  customInputs: z.array(z.unknown()),\n  disableGuests: z.boolean(),\n  metadata: z.union([z.unknown(), z.null()]),\n  lockTimeZoneToggleOnBookingPage: z.boolean(),\n  requiresConfirmation: z.boolean(),\n  requiresBookerEmailVerification: z.boolean(),\n  recurringEvent: z.union([z.unknown(), z.undefined()]).optional(),\n  price: z.number(),\n  currency: z.string(),\n  seatsPerTimeSlot: z.union([z.number(), z.null(), z.undefined()]).optional(),\n  seatsShowAvailabilityCount: z.union([z.boolean(), z.null()]),\n  bookingFields: z.array(BookingField),\n  team: z.union([z.unknown(), z.undefined()]).optional(),\n  successRedirectUrl: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  workflows: z.array(z.unknown()),\n  hosts: z.array(z.unknown()),\n  owner: z.union([Owner, z.null()]),\n  schedule: z.union([Schedule, z.null()]),\n  hidden: z.boolean(),\n  assignAllTeamMembers: z.boolean(),\n  bookerLayouts: z.union([z.unknown(), z.undefined()]).optional(),\n  users: z.array(User),\n  entity: z.unknown(),\n  isDynamic: z.boolean(),\n});\n\nexport type GetEventTypePublicOutput = z.infer<typeof GetEventTypePublicOutput>;\nexport const GetEventTypePublicOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: z.union([PublicEventTypeOutput, z.null()]),\n});\n\nexport type PublicEventType = z.infer<typeof PublicEventType>;\nexport const PublicEventType = z.object({\n  id: z.number(),\n  length: z.number(),\n  slug: z.string(),\n  title: z.string(),\n  description: z.union([z.string(), z.null(), z.undefined()]).optional(),\n});\n\nexport type GetEventTypesPublicOutput = z.infer<typeof GetEventTypesPublicOutput>;\nexport const GetEventTypesPublicOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: z.array(PublicEventType),\n});\n\nexport type UpdateEventTypeInput = z.infer<typeof UpdateEventTypeInput>;\nexport const UpdateEventTypeInput = z.object({\n  length: z.number().optional(),\n  slug: z.string().optional(),\n  title: z.string().optional(),\n  description: z.string().optional(),\n  hidden: z.boolean().optional(),\n  locations: z.array(EventTypeLocation).optional(),\n  disableGuests: z.boolean().optional(),\n});\n\nexport type UpdateEventTypeOutput = z.infer<typeof UpdateEventTypeOutput>;\nexport const UpdateEventTypeOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: EventTypeOutput,\n});\n\nexport type DeleteData = z.infer<typeof DeleteData>;\nexport const DeleteData = z.object({\n  id: z.number(),\n  length: z.number(),\n  slug: z.string(),\n  title: z.string(),\n});\n\nexport type DeleteEventTypeOutput = z.infer<typeof DeleteEventTypeOutput>;\nexport const DeleteEventTypeOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: DeleteData,\n});\n\nexport type CreateAvailabilityInput = z.infer<typeof CreateAvailabilityInput>;\nexport const CreateAvailabilityInput = z.object({\n  days: z.array(z.number()),\n  startTime: z.string(),\n  endTime: z.string(),\n});\n\nexport type CreateScheduleInput = z.infer<typeof CreateScheduleInput>;\nexport const CreateScheduleInput = z.object({\n  name: z.string(),\n  timeZone: z.string(),\n  availabilities: z.union([z.array(CreateAvailabilityInput), z.undefined()]).optional(),\n  isDefault: z.boolean(),\n});\n\nexport type WorkingHours = z.infer<typeof WorkingHours>;\nexport const WorkingHours = z.object({\n  days: z.array(z.number()),\n  startTime: z.number(),\n  endTime: z.number(),\n  userId: z.union([z.number(), z.null(), z.undefined()]).optional(),\n});\n\nexport type AvailabilityModel = z.infer<typeof AvailabilityModel>;\nexport const AvailabilityModel = z.object({\n  id: z.number(),\n  userId: z.union([z.number(), z.null(), z.undefined()]).optional(),\n  eventTypeId: z.union([z.number(), z.null(), z.undefined()]).optional(),\n  days: z.array(z.number()),\n  startTime: z.string(),\n  endTime: z.string(),\n  date: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  scheduleId: z.union([z.number(), z.null(), z.undefined()]).optional(),\n});\n\nexport type TimeRange = z.infer<typeof TimeRange>;\nexport const TimeRange = z.object({\n  userId: z.union([z.number(), z.null(), z.undefined()]).optional(),\n  start: z.string(),\n  end: z.string(),\n});\n\nexport type ScheduleOutput = z.infer<typeof ScheduleOutput>;\nexport const ScheduleOutput = z.object({\n  id: z.number(),\n  name: z.string(),\n  isManaged: z.boolean(),\n  workingHours: z.array(WorkingHours),\n  schedule: z.array(AvailabilityModel),\n  availability: z.array(z.array(TimeRange)),\n  timeZone: z.string(),\n  dateOverrides: z.array(z.unknown()),\n  isDefault: z.boolean(),\n  isLastSchedule: z.boolean(),\n  readOnly: z.boolean(),\n});\n\nexport type CreateScheduleOutput = z.infer<typeof CreateScheduleOutput>;\nexport const CreateScheduleOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: ScheduleOutput,\n});\n\nexport type GetDefaultScheduleOutput = z.infer<typeof GetDefaultScheduleOutput>;\nexport const GetDefaultScheduleOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: z.union([ScheduleOutput, z.null()]),\n});\n\nexport type GetScheduleOutput = z.infer<typeof GetScheduleOutput>;\nexport const GetScheduleOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: ScheduleOutput,\n});\n\nexport type GetSchedulesOutput = z.infer<typeof GetSchedulesOutput>;\nexport const GetSchedulesOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: ScheduleOutput,\n});\n\nexport type UpdateScheduleInput = z.infer<typeof UpdateScheduleInput>;\nexport const UpdateScheduleInput = z.object({\n  timeZone: z.string(),\n  name: z.string(),\n  isDefault: z.boolean(),\n  schedule: z.array(z.array(z.any())),\n  dateOverrides: z.union([z.array(z.array(z.any())), z.undefined()]).optional(),\n});\n\nexport type EventTypeModel = z.infer<typeof EventTypeModel>;\nexport const EventTypeModel = z.object({\n  id: z.number(),\n  eventName: z.union([z.string(), z.null(), z.undefined()]).optional(),\n});\n\nexport type ScheduleModel = z.infer<typeof ScheduleModel>;\nexport const ScheduleModel = z.object({\n  id: z.number(),\n  userId: z.number(),\n  name: z.string(),\n  timeZone: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  eventType: z.union([z.array(EventTypeModel), z.undefined()]).optional(),\n  availability: z.union([z.array(AvailabilityModel), z.undefined()]).optional(),\n});\n\nexport type UpdatedScheduleOutput = z.infer<typeof UpdatedScheduleOutput>;\nexport const UpdatedScheduleOutput = z.object({\n  schedule: ScheduleModel,\n  isDefault: z.boolean(),\n  timeZone: z.union([z.string(), z.undefined()]).optional(),\n  prevDefaultId: z.union([z.number(), z.null(), z.undefined()]).optional(),\n  currentDefaultId: z.union([z.number(), z.null(), z.undefined()]).optional(),\n});\n\nexport type UpdateScheduleOutput = z.infer<typeof UpdateScheduleOutput>;\nexport const UpdateScheduleOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: UpdatedScheduleOutput,\n});\n\nexport type DeleteScheduleOutput = z.infer<typeof DeleteScheduleOutput>;\nexport const DeleteScheduleOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n});\n\nexport type AuthUrlData = z.infer<typeof AuthUrlData>;\nexport const AuthUrlData = z.object({\n  authUrl: z.string(),\n});\n\nexport type GcalAuthUrlOutput = z.infer<typeof GcalAuthUrlOutput>;\nexport const GcalAuthUrlOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: AuthUrlData,\n});\n\nexport type GcalSaveRedirectOutput = z.infer<typeof GcalSaveRedirectOutput>;\nexport const GcalSaveRedirectOutput = z.object({\n  url: z.string(),\n});\n\nexport type GcalCheckOutput = z.infer<typeof GcalCheckOutput>;\nexport const GcalCheckOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n});\n\nexport type ProviderVerifyClientOutput = z.infer<typeof ProviderVerifyClientOutput>;\nexport const ProviderVerifyClientOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n});\n\nexport type ProviderVerifyAccessTokenOutput = z.infer<typeof ProviderVerifyAccessTokenOutput>;\nexport const ProviderVerifyAccessTokenOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n});\n\nexport type MeOutput = z.infer<typeof MeOutput>;\nexport const MeOutput = z.object({\n  id: z.number(),\n  username: z.string(),\n  email: z.string(),\n  timeFormat: z.number(),\n  defaultScheduleId: z.union([z.number(), z.null()]),\n  weekStart: z.string(),\n  timeZone: z.string(),\n});\n\nexport type GetMeOutput = z.infer<typeof GetMeOutput>;\nexport const GetMeOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: MeOutput,\n});\n\nexport type UpdateMeOutput = z.infer<typeof UpdateMeOutput>;\nexport const UpdateMeOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: MeOutput,\n});\n\nexport type BusyTimesOutput = z.infer<typeof BusyTimesOutput>;\nexport const BusyTimesOutput = z.object({\n  start: z.string(),\n  end: z.string(),\n  source: z.union([z.string(), z.null(), z.undefined()]).optional(),\n});\n\nexport type GetBusyTimesOutput = z.infer<typeof GetBusyTimesOutput>;\nexport const GetBusyTimesOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: z.array(BusyTimesOutput),\n});\n\nexport type Integration = z.infer<typeof Integration>;\nexport const Integration = z.object({\n  appData: z.union([z.unknown(), z.null(), z.undefined()]).optional(),\n  dirName: z.union([z.string(), z.undefined()]).optional(),\n  __template: z.union([z.string(), z.undefined()]).optional(),\n  name: z.string(),\n  description: z.string(),\n  installed: z.union([z.boolean(), z.undefined()]).optional(),\n  type: z.string(),\n  title: z.union([z.string(), z.undefined()]).optional(),\n  variant: z.string(),\n  category: z.union([z.string(), z.undefined()]).optional(),\n  categories: z.array(z.string()),\n  logo: z.string(),\n  publisher: z.string(),\n  slug: z.string(),\n  url: z.string(),\n  email: z.string(),\n  locationOption: z.union([z.unknown(), z.null()]),\n});\n\nexport type Primary = z.infer<typeof Primary>;\nexport const Primary = z.object({\n  externalId: z.string(),\n  integration: z.union([z.string(), z.undefined()]).optional(),\n  name: z.union([z.string(), z.undefined()]).optional(),\n  primary: z.union([z.boolean(), z.null()]),\n  readOnly: z.boolean(),\n  email: z.union([z.string(), z.undefined()]).optional(),\n  isSelected: z.boolean(),\n  credentialId: z.number(),\n});\n\nexport type Calendar = z.infer<typeof Calendar>;\nexport const Calendar = z.object({\n  externalId: z.string(),\n  integration: z.union([z.string(), z.undefined()]).optional(),\n  name: z.union([z.string(), z.undefined()]).optional(),\n  primary: z.union([z.boolean(), z.null(), z.undefined()]).optional(),\n  readOnly: z.boolean(),\n  email: z.union([z.string(), z.undefined()]).optional(),\n  isSelected: z.boolean(),\n  credentialId: z.number(),\n});\n\nexport type ConnectedCalendar = z.infer<typeof ConnectedCalendar>;\nexport const ConnectedCalendar = z.object({\n  integration: Integration,\n  credentialId: z.number(),\n  primary: z.union([Primary, z.undefined()]).optional(),\n  calendars: z.union([z.array(Calendar), z.undefined()]).optional(),\n});\n\nexport type DestinationCalendar = z.infer<typeof DestinationCalendar>;\nexport const DestinationCalendar = z.object({\n  id: z.number(),\n  integration: z.string(),\n  externalId: z.string(),\n  primaryEmail: z.union([z.string(), z.null()]),\n  userId: z.union([z.number(), z.null()]),\n  eventTypeId: z.union([z.number(), z.null()]),\n  credentialId: z.union([z.number(), z.null()]),\n  name: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  primary: z.union([z.boolean(), z.undefined()]).optional(),\n  readOnly: z.union([z.boolean(), z.undefined()]).optional(),\n  email: z.union([z.string(), z.undefined()]).optional(),\n  integrationTitle: z.union([z.string(), z.undefined()]).optional(),\n});\n\nexport type ConnectedCalendarsData = z.infer<typeof ConnectedCalendarsData>;\nexport const ConnectedCalendarsData = z.object({\n  connectedCalendars: z.array(ConnectedCalendar),\n  destinationCalendar: DestinationCalendar,\n});\n\nexport type ConnectedCalendarsOutput = z.infer<typeof ConnectedCalendarsOutput>;\nexport const ConnectedCalendarsOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: ConnectedCalendarsData,\n});\n\nexport type Attendee = z.infer<typeof Attendee>;\nexport const Attendee = z.object({\n  id: z.number(),\n  email: z.string(),\n  name: z.string(),\n  timeZone: z.string(),\n  locale: z.union([z.string(), z.null()]),\n  bookingId: z.union([z.number(), z.null()]),\n});\n\nexport type EventType = z.infer<typeof EventType>;\nexport const EventType = z.object({\n  slug: z.union([z.string(), z.undefined()]).optional(),\n  id: z.union([z.number(), z.undefined()]).optional(),\n  eventName: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  price: z.number(),\n  recurringEvent: z.union([z.unknown(), z.undefined()]).optional(),\n  currency: z.string(),\n  metadata: z.unknown(),\n  seatsShowAttendees: z.union([z.unknown(), z.undefined()]).optional(),\n  seatsShowAvailabilityCount: z.union([z.unknown(), z.undefined()]).optional(),\n  team: z.union([z.unknown(), z.null(), z.undefined()]).optional(),\n});\n\nexport type Reference = z.infer<typeof Reference>;\nexport const Reference = z.object({\n  id: z.number(),\n  type: z.string(),\n  uid: z.string(),\n  meetingId: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  thirdPartyRecurringEventId: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  meetingPassword: z.union([z.string(), z.null()]),\n  meetingUrl: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  bookingId: z.union([z.number(), z.null()]),\n  externalCalendarId: z.union([z.string(), z.null()]),\n  deleted: z.union([z.unknown(), z.undefined()]).optional(),\n  credentialId: z.union([z.number(), z.null()]),\n});\n\nexport type GetBookingsDataEntry = z.infer<typeof GetBookingsDataEntry>;\nexport const GetBookingsDataEntry = z.object({\n  id: z.number(),\n  title: z.string(),\n  userPrimaryEmail: z.union([z.string(), z.null(), z.undefined()]).optional(),\n  description: z.union([z.string(), z.null()]),\n  customInputs: z.unknown(),\n  startTime: z.string(),\n  endTime: z.string(),\n  attendees: z.array(Attendee),\n  metadata: z.unknown(),\n  uid: z.string(),\n  recurringEventId: z.union([z.string(), z.null()]),\n  location: z.union([z.string(), z.null()]),\n  eventType: EventType,\n  status: z.unknown(),\n  paid: z.boolean(),\n  payment: z.array(z.unknown()),\n  references: z.array(Reference),\n  isRecorded: z.boolean(),\n  seatsReferences: z.array(z.unknown()),\n  user: z.union([User, z.null()]),\n  rescheduled: z.union([z.unknown(), z.undefined()]).optional(),\n});\n\nexport type GetBookingsData = z.infer<typeof GetBookingsData>;\nexport const GetBookingsData = z.object({\n  bookings: z.array(GetBookingsDataEntry),\n  recurringInfo: z.array(z.unknown()),\n  nextCursor: z.union([z.number(), z.null()]),\n});\n\nexport type GetBookingsOutput = z.infer<typeof GetBookingsOutput>;\nexport const GetBookingsOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: GetBookingsData,\n});\n\nexport type GetBookingData = z.infer<typeof GetBookingData>;\nexport const GetBookingData = z.object({\n  title: z.string(),\n  id: z.number(),\n  uid: z.string(),\n  description: z.union([z.string(), z.null()]),\n  customInputs: z.unknown(),\n  smsReminderNumber: z.union([z.string(), z.null()]),\n  recurringEventId: z.union([z.string(), z.null()]),\n  startTime: z.string(),\n  endTime: z.string(),\n  location: z.union([z.string(), z.null()]),\n  status: z.string(),\n  metadata: z.unknown(),\n  cancellationReason: z.union([z.string(), z.null()]),\n  responses: z.unknown(),\n  rejectionReason: z.union([z.string(), z.null()]),\n  userPrimaryEmail: z.union([z.string(), z.null()]),\n  user: z.union([User, z.null()]),\n  attendees: z.array(Attendee),\n  eventTypeId: z.union([z.number(), z.null()]),\n  eventType: z.union([EventType, z.null()]),\n});\n\nexport type GetBookingOutput = z.infer<typeof GetBookingOutput>;\nexport const GetBookingOutput = z.object({\n  status: z.union([z.literal(\"success\"), z.literal(\"error\")]),\n  data: GetBookingData,\n});\n\nexport type Response = z.infer<typeof Response>;\nexport const Response = z.object({\n  name: z.string(),\n  email: z.string(),\n  guests: z.array(z.string()),\n  location: z.union([Location, z.undefined()]).optional(),\n  notes: z.union([z.string(), z.undefined()]).optional(),\n});\n\nexport type CreateBookingInput = z.infer<typeof CreateBookingInput>;\nexport const CreateBookingInput = z.object({\n  end: z.union([z.string(), z.undefined()]).optional(),\n  start: z.string(),\n  eventTypeId: z.number(),\n  eventTypeSlug: z.union([z.string(), z.undefined()]).optional(),\n  rescheduleUid: z.union([z.string(), z.undefined()]).optional(),\n  recurringEventId: z.union([z.string(), z.undefined()]).optional(),\n  timeZone: z.string(),\n  user: z.union([z.array(z.string()), z.undefined()]).optional(),\n  language: z.string(),\n  bookingUid: z.union([z.string(), z.undefined()]).optional(),\n  metadata: z.unknown(),\n  hasHashedBookingLink: z.union([z.boolean(), z.undefined()]).optional(),\n  hashedLink: z.union([z.string(), z.null()]),\n  seatReferenceUid: z.union([z.string(), z.undefined()]).optional(),\n  responses: Response,\n  orgSlug: z.union([z.string(), z.undefined()]).optional(),\n  locationUrl: z.union([z.string(), z.undefined()]).optional(),\n});\n\nexport type CancelBookingInput = z.infer<typeof CancelBookingInput>;\nexport const CancelBookingInput = z.object({\n  id: z.number(),\n  uid: z.string(),\n  allRemainingBookings: z.boolean(),\n  cancellationReason: z.string(),\n  seatReferenceUid: z.string(),\n});\n\nexport type ReserveSlotInput = z.infer<typeof ReserveSlotInput>;\nexport const ReserveSlotInput = z.object({});\n\nexport type get_OAuthClientUsersController_getManagedUsers =\n  typeof get_OAuthClientUsersController_getManagedUsers;\nexport const get_OAuthClientUsersController_getManagedUsers = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}/users\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n    }),\n  }),\n  response: GetManagedUsersOutput,\n};\n\nexport type post_OAuthClientUsersController_createUser = typeof post_OAuthClientUsersController_createUser;\nexport const post_OAuthClientUsersController_createUser = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}/users\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n    }),\n    body: CreateManagedUserInput,\n  }),\n  response: CreateManagedUserOutput,\n};\n\nexport type get_OAuthClientUsersController_getUserById = typeof get_OAuthClientUsersController_getUserById;\nexport const get_OAuthClientUsersController_getUserById = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}/users/{userId}\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n      userId: z.number(),\n    }),\n  }),\n  response: GetManagedUserOutput,\n};\n\nexport type patch_OAuthClientUsersController_updateUser = typeof patch_OAuthClientUsersController_updateUser;\nexport const patch_OAuthClientUsersController_updateUser = {\n  method: z.literal(\"PATCH\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}/users/{userId}\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n      userId: z.number(),\n    }),\n    body: UpdateManagedUserInput,\n  }),\n  response: GetManagedUserOutput,\n};\n\nexport type delete_OAuthClientUsersController_deleteUser =\n  typeof delete_OAuthClientUsersController_deleteUser;\nexport const delete_OAuthClientUsersController_deleteUser = {\n  method: z.literal(\"DELETE\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}/users/{userId}\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n      userId: z.number(),\n    }),\n  }),\n  response: GetManagedUserOutput,\n};\n\nexport type post_OAuthClientUsersController_forceRefresh =\n  typeof post_OAuthClientUsersController_forceRefresh;\nexport const post_OAuthClientUsersController_forceRefresh = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}/users/{userId}/force-refresh\"),\n  parameters: z.object({\n    path: z.object({\n      userId: z.number(),\n      clientId: z.string(),\n    }),\n  }),\n  response: KeysResponseDto,\n};\n\nexport type post_OAuthClientsController_createOAuthClient =\n  typeof post_OAuthClientsController_createOAuthClient;\nexport const post_OAuthClientsController_createOAuthClient = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/oauth-clients\"),\n  parameters: z.object({\n    body: CreateOAuthClientInput,\n  }),\n  response: CreateOAuthClientResponseDto,\n};\n\nexport type get_OAuthClientsController_getOAuthClients = typeof get_OAuthClientsController_getOAuthClients;\nexport const get_OAuthClientsController_getOAuthClients = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/oauth-clients\"),\n  parameters: z.never(),\n  response: GetOAuthClientsResponseDto,\n};\n\nexport type get_OAuthClientsController_getOAuthClientById =\n  typeof get_OAuthClientsController_getOAuthClientById;\nexport const get_OAuthClientsController_getOAuthClientById = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n    }),\n  }),\n  response: GetOAuthClientResponseDto,\n};\n\nexport type patch_OAuthClientsController_updateOAuthClient =\n  typeof patch_OAuthClientsController_updateOAuthClient;\nexport const patch_OAuthClientsController_updateOAuthClient = {\n  method: z.literal(\"PATCH\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n    }),\n    body: UpdateOAuthClientInput,\n  }),\n  response: GetOAuthClientResponseDto,\n};\n\nexport type delete_OAuthClientsController_deleteOAuthClient =\n  typeof delete_OAuthClientsController_deleteOAuthClient;\nexport const delete_OAuthClientsController_deleteOAuthClient = {\n  method: z.literal(\"DELETE\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n    }),\n  }),\n  response: GetOAuthClientResponseDto,\n};\n\nexport type get_OAuthClientsController_getOAuthClientManagedUsersById =\n  typeof get_OAuthClientsController_getOAuthClientManagedUsersById;\nexport const get_OAuthClientsController_getOAuthClientManagedUsersById = z.object({\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/oauth-clients/{clientId}/managed-users\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n    }),\n  }),\n  response: GetManagedUsersOutput,\n});\n\nexport type post_OAuthFlowController_authorize = typeof post_OAuthFlowController_authorize;\nexport const post_OAuthFlowController_authorize = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/oauth/{clientId}/authorize\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n    }),\n    body: OAuthAuthorizeInput,\n  }),\n  response: z.unknown(),\n};\n\nexport type post_OAuthFlowController_exchange = typeof post_OAuthFlowController_exchange;\nexport const post_OAuthFlowController_exchange = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/oauth/{clientId}/exchange\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n    }),\n    header: z.object({\n      Authorization: z.string(),\n    }),\n    body: ExchangeAuthorizationCodeInput,\n  }),\n  response: KeysResponseDto,\n};\n\nexport type post_OAuthFlowController_refreshAccessToken = typeof post_OAuthFlowController_refreshAccessToken;\nexport const post_OAuthFlowController_refreshAccessToken = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/oauth/{clientId}/refresh\"),\n  parameters: z.object({\n    path: z.object({\n      clientId: z.string(),\n    }),\n    header: z.object({\n      \"x-cal-secret-key\": z.string(),\n    }),\n    body: RefreshTokenInput,\n  }),\n  response: KeysResponseDto,\n};\n\nexport type post_EventTypesController_createEventType = typeof post_EventTypesController_createEventType;\nexport const post_EventTypesController_createEventType = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/event-types\"),\n  parameters: z.object({\n    body: CreateEventTypeInput,\n  }),\n  response: CreateEventTypeOutput,\n};\n\nexport type get_EventTypesController_getEventTypes = typeof get_EventTypesController_getEventTypes;\nexport const get_EventTypesController_getEventTypes = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/event-types\"),\n  parameters: z.never(),\n  response: GetEventTypesOutput,\n};\n\nexport type get_EventTypesController_getEventType = typeof get_EventTypesController_getEventType;\nexport const get_EventTypesController_getEventType = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/event-types/{eventTypeId}\"),\n  parameters: z.object({\n    path: z.object({\n      eventTypeId: z.string(),\n    }),\n  }),\n  response: GetEventTypeOutput,\n};\n\nexport type patch_EventTypesController_updateEventType = typeof patch_EventTypesController_updateEventType;\nexport const patch_EventTypesController_updateEventType = {\n  method: z.literal(\"PATCH\"),\n  path: z.literal(\"/v2/event-types/{eventTypeId}\"),\n  parameters: z.object({\n    path: z.object({\n      eventTypeId: z.number(),\n    }),\n    body: UpdateEventTypeInput,\n  }),\n  response: UpdateEventTypeOutput,\n};\n\nexport type delete_EventTypesController_deleteEventType = typeof delete_EventTypesController_deleteEventType;\nexport const delete_EventTypesController_deleteEventType = {\n  method: z.literal(\"DELETE\"),\n  path: z.literal(\"/v2/event-types/{eventTypeId}\"),\n  parameters: z.object({\n    path: z.object({\n      eventTypeId: z.number(),\n    }),\n  }),\n  response: DeleteEventTypeOutput,\n};\n\nexport type get_EventTypesController_getPublicEventType = typeof get_EventTypesController_getPublicEventType;\nexport const get_EventTypesController_getPublicEventType = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/event-types/{username}/{eventSlug}/public\"),\n  parameters: z.object({\n    query: z.object({\n      isTeamEvent: z.boolean().optional(),\n      org: z.union([z.string(), z.null()]).optional(),\n    }),\n    path: z.object({\n      username: z.string(),\n      eventSlug: z.string(),\n    }),\n  }),\n  response: GetEventTypePublicOutput,\n};\n\nexport type get_EventTypesController_getPublicEventTypes =\n  typeof get_EventTypesController_getPublicEventTypes;\nexport const get_EventTypesController_getPublicEventTypes = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/event-types/{username}/public\"),\n  parameters: z.object({\n    path: z.object({\n      username: z.string(),\n    }),\n  }),\n  response: GetEventTypesPublicOutput,\n};\n\nexport type post_SchedulesController_createSchedule = typeof post_SchedulesController_createSchedule;\nexport const post_SchedulesController_createSchedule = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/schedules\"),\n  parameters: z.object({\n    body: CreateScheduleInput,\n  }),\n  response: CreateScheduleOutput,\n};\n\nexport type get_SchedulesController_getSchedules = typeof get_SchedulesController_getSchedules;\nexport const get_SchedulesController_getSchedules = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/schedules\"),\n  parameters: z.never(),\n  response: GetSchedulesOutput,\n};\n\nexport type get_SchedulesController_getDefaultSchedule = typeof get_SchedulesController_getDefaultSchedule;\nexport const get_SchedulesController_getDefaultSchedule = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/schedules/default\"),\n  parameters: z.never(),\n  response: GetDefaultScheduleOutput,\n};\n\nexport type get_SchedulesController_getSchedule = typeof get_SchedulesController_getSchedule;\nexport const get_SchedulesController_getSchedule = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/schedules/{scheduleId}\"),\n  parameters: z.object({\n    path: z.object({\n      scheduleId: z.number(),\n    }),\n  }),\n  response: GetScheduleOutput,\n};\n\nexport type patch_SchedulesController_updateSchedule = typeof patch_SchedulesController_updateSchedule;\nexport const patch_SchedulesController_updateSchedule = {\n  method: z.literal(\"PATCH\"),\n  path: z.literal(\"/v2/schedules/{scheduleId}\"),\n  parameters: z.object({\n    path: z.object({\n      scheduleId: z.string(),\n    }),\n    body: UpdateScheduleInput,\n  }),\n  response: UpdateScheduleOutput,\n};\n\nexport type delete_SchedulesController_deleteSchedule = typeof delete_SchedulesController_deleteSchedule;\nexport const delete_SchedulesController_deleteSchedule = {\n  method: z.literal(\"DELETE\"),\n  path: z.literal(\"/v2/schedules/{scheduleId}\"),\n  parameters: z.object({\n    path: z.object({\n      scheduleId: z.number(),\n    }),\n  }),\n  response: DeleteScheduleOutput,\n};\n\nexport type get_BookingsController_getBookings = typeof get_BookingsController_getBookings;\nexport const get_BookingsController_getBookings = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/bookings\"),\n  parameters: z.object({\n    query: z.object({\n      cursor: z.number(),\n      limit: z.number(),\n      \"filters[status]\": z.union([\n        z.literal(\"upcoming\"),\n        z.literal(\"recurring\"),\n        z.literal(\"past\"),\n        z.literal(\"cancelled\"),\n        z.literal(\"unconfirmed\"),\n      ]),\n    }),\n  }),\n  response: GetBookingsOutput,\n};\n\nexport type post_BookingsController_createBooking = typeof post_BookingsController_createBooking;\nexport const post_BookingsController_createBooking = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/bookings\"),\n  parameters: z.object({\n    header: z.object({\n      \"x-cal-client-id\": z.string(),\n    }),\n    body: CreateBookingInput,\n  }),\n  response: z.unknown(),\n};\n\nexport type get_BookingsController_getBooking = typeof get_BookingsController_getBooking;\nexport const get_BookingsController_getBooking = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/bookings/{bookingUid}\"),\n  parameters: z.object({\n    path: z.object({\n      bookingUid: z.string(),\n    }),\n  }),\n  response: GetBookingOutput,\n};\n\nexport type get_BookingsController_getBookingForReschedule =\n  typeof get_BookingsController_getBookingForReschedule;\nexport const get_BookingsController_getBookingForReschedule = {\n  method: z.literal(\"GET\"),\n  path: z.literal(\"/v2/bookings/{bookingUid}/reschedule\"),\n  parameters: z.object({\n    path: z.object({\n      bookingUid: z.string(),\n    }),\n  }),\n  response: z.unknown(),\n};\n\nexport type post_BookingsController_cancelBooking = typeof post_BookingsController_cancelBooking;\nexport const post_BookingsController_cancelBooking = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/bookings/{bookingId}/cancel\"),\n  parameters: z.object({\n    path: z.object({\n      bookingId: z.string(),\n    }),\n    header: z.object({\n      \"x-cal-client-id\": z.string(),\n    }),\n    body: CancelBookingInput,\n  }),\n  response: z.unknown(),\n};\n\nexport type post_BookingsController_createRecurringBooking =\n  typeof post_BookingsController_createRecurringBooking;\nexport const post_BookingsController_createRecurringBooking = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/bookings/recurring\"),\n  parameters: z.object({\n    header: z.object({\n      \"x-cal-client-id\": z.string(),\n    }),\n    body: z.array(z.string()),\n  }),\n  response: z.unknown(),\n};\n\nexport type post_BookingsController_createInstantBooking =\n  typeof post_BookingsController_createInstantBooking;\nexport const post_BookingsController_createInstantBooking = {\n  method: z.literal(\"POST\"),\n  path: z.literal(\"/v2/bookings/instant\"),\n  parameters: z.object({\n    header: z.object({\n      \"x-cal-client-id\": z.string(),\n    }),\n    body: CreateBookingInput,\n  }),\n  response: z.unknown(),\n};\n\n// <EndpointByMethod>\nexport const EndpointByMethod = {\n  get: {\n    \"/v2/oauth-clients/{clientId}/users\": get_OAuthClientUsersController_getManagedUsers,\n    \"/v2/oauth-clients/{clientId}/users/{userId}\": get_OAuthClientUsersController_getUserById,\n    \"/v2/oauth-clients\": get_OAuthClientsController_getOAuthClients,\n    \"/v2/oauth-clients/{clientId}\": get_OAuthClientsController_getOAuthClientById,\n    \"/v2/oauth-clients/{clientId}/managed-users\": get_OAuthClientsController_getOAuthClientManagedUsersById,\n    \"/v2/event-types\": get_EventTypesController_getEventTypes,\n    \"/v2/event-types/{eventTypeId}\": get_EventTypesController_getEventType,\n    \"/v2/event-types/{username}/{eventSlug}/public\": get_EventTypesController_getPublicEventType,\n    \"/v2/event-types/{username}/public\": get_EventTypesController_getPublicEventTypes,\n    \"/v2/schedules\": get_SchedulesController_getSchedules,\n    \"/v2/schedules/default\": get_SchedulesController_getDefaultSchedule,\n    \"/v2/schedules/{scheduleId}\": get_SchedulesController_getSchedule,\n    \"/v2/bookings\": get_BookingsController_getBookings,\n    \"/v2/bookings/{bookingUid}\": get_BookingsController_getBooking,\n    \"/v2/bookings/{bookingUid}/reschedule\": get_BookingsController_getBookingForReschedule,\n  },\n  post: {\n    \"/v2/oauth-clients/{clientId}/users\": post_OAuthClientUsersController_createUser,\n    \"/v2/oauth-clients/{clientId}/users/{userId}/force-refresh\": post_OAuthClientUsersController_forceRefresh,\n    \"/v2/oauth-clients\": post_OAuthClientsController_createOAuthClient,\n    \"/v2/oauth/{clientId}/authorize\": post_OAuthFlowController_authorize,\n    \"/v2/oauth/{clientId}/exchange\": post_OAuthFlowController_exchange,\n    \"/v2/oauth/{clientId}/refresh\": post_OAuthFlowController_refreshAccessToken,\n    \"/v2/event-types\": post_EventTypesController_createEventType,\n    \"/v2/schedules\": post_SchedulesController_createSchedule,\n    \"/v2/bookings\": post_BookingsController_createBooking,\n    \"/v2/bookings/{bookingId}/cancel\": post_BookingsController_cancelBooking,\n    \"/v2/bookings/recurring\": post_BookingsController_createRecurringBooking,\n    \"/v2/bookings/instant\": post_BookingsController_createInstantBooking,\n  },\n  patch: {\n    \"/v2/oauth-clients/{clientId}/users/{userId}\": patch_OAuthClientUsersController_updateUser,\n    \"/v2/oauth-clients/{clientId}\": patch_OAuthClientsController_updateOAuthClient,\n    \"/v2/event-types/{eventTypeId}\": patch_EventTypesController_updateEventType,\n    \"/v2/schedules/{scheduleId}\": patch_SchedulesController_updateSchedule,\n  },\n  delete: {\n    \"/v2/oauth-clients/{clientId}/users/{userId}\": delete_OAuthClientUsersController_deleteUser,\n    \"/v2/oauth-clients/{clientId}\": delete_OAuthClientsController_deleteOAuthClient,\n    \"/v2/event-types/{eventTypeId}\": delete_EventTypesController_deleteEventType,\n    \"/v2/schedules/{scheduleId}\": delete_SchedulesController_deleteSchedule,\n  },\n};\nexport type EndpointByMethod = typeof EndpointByMethod;\n// </EndpointByMethod>\n\n// <EndpointByMethod.Shorthands>\nexport type GetEndpoints = EndpointByMethod[\"get\"];\nexport type PostEndpoints = EndpointByMethod[\"post\"];\nexport type PatchEndpoints = EndpointByMethod[\"patch\"];\nexport type DeleteEndpoints = EndpointByMethod[\"delete\"];\nexport type AllEndpoints = EndpointByMethod[keyof EndpointByMethod];\n// </EndpointByMethod.Shorthands>\n\n// <ApiClientTypes>\nexport type EndpointParameters = {\n  body?: unknown;\n  query?: Record<string, unknown>;\n  header?: Record<string, unknown>;\n  path?: Record<string, unknown>;\n};\n\nexport type MutationMethod = \"post\" | \"put\" | \"patch\" | \"delete\";\nexport type Method = \"get\" | \"head\" | MutationMethod;\n\nexport type DefaultEndpoint = {\n  parameters?: EndpointParameters | undefined;\n  response: unknown;\n};\n\nexport type Endpoint<TConfig extends DefaultEndpoint = DefaultEndpoint> = {\n  operationId: string;\n  method: Method;\n  path: string;\n  parameters?: TConfig[\"parameters\"];\n  meta: {\n    alias: string;\n    hasParameters: boolean;\n    areParametersRequired: boolean;\n  };\n  response: TConfig[\"response\"];\n};\n\ntype Fetcher = (\n  method: Method,\n  url: string,\n  parameters?: EndpointParameters | undefined\n) => Promise<Endpoint[\"response\"]>;\n\ntype RequiredKeys<T> = {\n  [P in keyof T]-?: undefined extends T[P] ? never : P;\n}[keyof T];\n\ntype MaybeOptionalArg<T> = RequiredKeys<T> extends never ? [config?: T] : [config: T];\n\n// </ApiClientTypes>\n\n// <ApiClient>\nexport class ApiClient {\n  baseUrl = \"\";\n\n  constructor(public fetcher: Fetcher) {}\n\n  setBaseUrl(baseUrl: string) {\n    this.baseUrl = baseUrl;\n    return this;\n  }\n\n  // <ApiClient.get>\n  get<Path extends keyof GetEndpoints, TEndpoint extends GetEndpoints[Path]>(\n    path: Path,\n    ...params: MaybeOptionalArg<z.infer<TEndpoint[\"parameters\"]>>\n  ): Promise<z.infer<TEndpoint[\"response\"]>> {\n    return this.fetcher(\"get\", this.baseUrl + path, params[0]) as Promise<z.infer<TEndpoint[\"response\"]>>;\n  }\n  // </ApiClient.get>\n\n  // <ApiClient.post>\n  post<Path extends keyof PostEndpoints, TEndpoint extends PostEndpoints[Path]>(\n    path: Path,\n    ...params: MaybeOptionalArg<z.infer<TEndpoint[\"parameters\"]>>\n  ): Promise<z.infer<TEndpoint[\"response\"]>> {\n    return this.fetcher(\"post\", this.baseUrl + path, params[0]) as Promise<z.infer<TEndpoint[\"response\"]>>;\n  }\n  // </ApiClient.post>\n\n  // <ApiClient.patch>\n  patch<Path extends keyof PatchEndpoints, TEndpoint extends PatchEndpoints[Path]>(\n    path: Path,\n    ...params: MaybeOptionalArg<z.infer<TEndpoint[\"parameters\"]>>\n  ): Promise<z.infer<TEndpoint[\"response\"]>> {\n    return this.fetcher(\"patch\", this.baseUrl + path, params[0]) as Promise<z.infer<TEndpoint[\"response\"]>>;\n  }\n  // </ApiClient.patch>\n\n  // <ApiClient.delete>\n  delete<Path extends keyof DeleteEndpoints, TEndpoint extends DeleteEndpoints[Path]>(\n    path: Path,\n    ...params: MaybeOptionalArg<z.infer<TEndpoint[\"parameters\"]>>\n  ): Promise<z.infer<TEndpoint[\"response\"]>> {\n    return this.fetcher(\"delete\", this.baseUrl + path, params[0]) as Promise<z.infer<TEndpoint[\"response\"]>>;\n  }\n  // </ApiClient.delete>\n}\n\nexport function createApiClient(fetcher: Fetcher, baseUrl?: string) {\n  return new ApiClient(fetcher).setBaseUrl(baseUrl ?? \"\");\n}\n\n/**\n Example usage:\n const api = createApiClient((method, url, params) =>\n   fetch(url, { method, body: JSON.stringify(params) }).then((res) => res.json()),\n );\n api.get(\"/users\").then((users) => console.log(users));\n api.post(\"/users\", { body: { name: \"John\" } }).then((user) => console.log(user));\n api.put(\"/users/:id\", { path: { id: 1 }, body: { name: \"John\" } }).then((user) => console.log(user));\n*/\n\n// </ApiClient\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/cal/__generated/cal-sdk.yml",
    "content": "openapi: 3.0.0\npaths:\n  /v2/oauth-clients/{clientId}/users:\n    get:\n      operationId: OAuthClientUsersController_getManagedUsers\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetManagedUsersOutput'\n      tags:\n        - Managed users\n    post:\n      operationId: OAuthClientUsersController_createUser\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateManagedUserInput'\n      responses:\n        '201':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CreateManagedUserOutput'\n      tags:\n        - Managed users\n  /v2/oauth-clients/{clientId}/users/{userId}:\n    get:\n      operationId: OAuthClientUsersController_getUserById\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n        - name: userId\n          required: true\n          in: path\n          schema:\n            type: number\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetManagedUserOutput'\n      tags:\n        - Managed users\n    patch:\n      operationId: OAuthClientUsersController_updateUser\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n        - name: userId\n          required: true\n          in: path\n          schema:\n            type: number\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateManagedUserInput'\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetManagedUserOutput'\n      tags:\n        - Managed users\n    delete:\n      operationId: OAuthClientUsersController_deleteUser\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n        - name: userId\n          required: true\n          in: path\n          schema:\n            type: number\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetManagedUserOutput'\n      tags:\n        - Managed users\n  /v2/oauth-clients/{clientId}/users/{userId}/force-refresh:\n    post:\n      operationId: OAuthClientUsersController_forceRefresh\n      parameters:\n        - name: userId\n          required: true\n          in: path\n          schema:\n            type: number\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/KeysResponseDto'\n      tags:\n        - Managed users\n  /v2/oauth-clients:\n    post:\n      operationId: OAuthClientsController_createOAuthClient\n      summary: ''\n      description: >-\n        ⚠️ First, this endpoint requires `Cookie:\n        next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using\n        owner of organization that was created after visiting\n        `/settings/organizations/new`, refresh swagger docs, and the cookie will\n        be added to requests automatically to pass the NextAuthGuard.\n\n        Second, make sure that the logged in user has organizationId set to pass\n        the OrganizationRolesGuard guard.\n      parameters: []\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateOAuthClientInput'\n      responses:\n        '201':\n          description: Create an OAuth client\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CreateOAuthClientResponseDto'\n      tags:\n        - OAuth - development only\n    get:\n      operationId: OAuthClientsController_getOAuthClients\n      summary: ''\n      description: >-\n        ⚠️ First, this endpoint requires `Cookie:\n        next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using\n        owner of organization that was created after visiting\n        `/settings/organizations/new`, refresh swagger docs, and the cookie will\n        be added to requests automatically to pass the NextAuthGuard.\n\n        Second, make sure that the logged in user has organizationId set to pass\n        the OrganizationRolesGuard guard.\n      parameters: []\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetOAuthClientsResponseDto'\n      tags:\n        - OAuth - development only\n  /v2/oauth-clients/{clientId}:\n    get:\n      operationId: OAuthClientsController_getOAuthClientById\n      summary: ''\n      description: >-\n        ⚠️ First, this endpoint requires `Cookie:\n        next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using\n        owner of organization that was created after visiting\n        `/settings/organizations/new`, refresh swagger docs, and the cookie will\n        be added to requests automatically to pass the NextAuthGuard.\n\n        Second, make sure that the logged in user has organizationId set to pass\n        the OrganizationRolesGuard guard.\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetOAuthClientResponseDto'\n      tags:\n        - OAuth - development only\n    patch:\n      operationId: OAuthClientsController_updateOAuthClient\n      summary: ''\n      description: >-\n        ⚠️ First, this endpoint requires `Cookie:\n        next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using\n        owner of organization that was created after visiting\n        `/settings/organizations/new`, refresh swagger docs, and the cookie will\n        be added to requests automatically to pass the NextAuthGuard.\n\n        Second, make sure that the logged in user has organizationId set to pass\n        the OrganizationRolesGuard guard.\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateOAuthClientInput'\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetOAuthClientResponseDto'\n      tags:\n        - OAuth - development only\n    delete:\n      operationId: OAuthClientsController_deleteOAuthClient\n      summary: ''\n      description: >-\n        ⚠️ First, this endpoint requires `Cookie:\n        next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using\n        owner of organization that was created after visiting\n        `/settings/organizations/new`, refresh swagger docs, and the cookie will\n        be added to requests automatically to pass the NextAuthGuard.\n\n        Second, make sure that the logged in user has organizationId set to pass\n        the OrganizationRolesGuard guard.\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetOAuthClientResponseDto'\n      tags:\n        - OAuth - development only\n  /v2/oauth-clients/{clientId}/managed-users:\n    get:\n      operationId: OAuthClientsController_getOAuthClientManagedUsersById\n      summary: ''\n      description: >-\n        ⚠️ First, this endpoint requires `Cookie:\n        next-auth.session-token=eyJhbGciOiJ` header. Log into Cal web app using\n        owner of organization that was created after visiting\n        `/settings/organizations/new`, refresh swagger docs, and the cookie will\n        be added to requests automatically to pass the NextAuthGuard.\n\n        Second, make sure that the logged in user has organizationId set to pass\n        the OrganizationRolesGuard guard.\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetManagedUsersOutput'\n      tags:\n        - OAuth - development only\n  /v2/oauth/{clientId}/authorize:\n    post:\n      operationId: OAuthFlowController_authorize\n      summary: Authorize an OAuth client\n      description: >-\n        Redirects the user to the specified 'redirect_uri' with an authorization\n        code in query parameter if the client is authorized successfully. The\n        code is then exchanged for access and refresh tokens via the `/exchange`\n        endpoint.\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/OAuthAuthorizeInput'\n      responses:\n        '200':\n          description: >-\n            The user is redirected to the 'redirect_uri' with an authorization\n            code in query parameter e.g. `redirectUri?code=secretcode.`\n        '400':\n          description: >-\n            Bad request if the OAuth client is not found, if the redirect URI is\n            invalid, or if the user has already authorized the client.\n      tags:\n        - OAuth - development only\n  /v2/oauth/{clientId}/exchange:\n    post:\n      operationId: OAuthFlowController_exchange\n      summary: Exchange authorization code for access tokens\n      description: >-\n        Exchanges the authorization code received from the `/authorize` endpoint\n        for access and refresh tokens. The authorization code should be provided\n        in the 'Authorization' header prefixed with 'Bearer '.\n      parameters:\n        - name: Authorization\n          required: true\n          in: header\n          schema:\n            type: string\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/ExchangeAuthorizationCodeInput'\n      responses:\n        '200':\n          description: >-\n            Successfully exchanged authorization code for access and refresh\n            tokens.\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/KeysResponseDto'\n        '400':\n          description: >-\n            Bad request if the authorization code is missing, invalid, or if the\n            client ID and secret do not match.\n      tags:\n        - OAuth - development only\n  /v2/oauth/{clientId}/refresh:\n    post:\n      operationId: OAuthFlowController_refreshAccessToken\n      parameters:\n        - name: clientId\n          required: true\n          in: path\n          schema:\n            type: string\n        - name: x-cal-secret-key\n          required: true\n          in: header\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/RefreshTokenInput'\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/KeysResponseDto'\n      tags:\n        - OAuth - development only\n  /v2/event-types:\n    post:\n      operationId: EventTypesController_createEventType\n      parameters: []\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateEventTypeInput'\n      responses:\n        '201':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CreateEventTypeOutput'\n      tags:\n        - Event types\n    get:\n      operationId: EventTypesController_getEventTypes\n      parameters: []\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetEventTypesOutput'\n      tags:\n        - Event types\n  /v2/event-types/{eventTypeId}:\n    get:\n      operationId: EventTypesController_getEventType\n      parameters:\n        - name: eventTypeId\n          required: true\n          in: path\n          schema:\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetEventTypeOutput'\n      tags:\n        - Event types\n    patch:\n      operationId: EventTypesController_updateEventType\n      parameters:\n        - name: eventTypeId\n          required: true\n          in: path\n          schema:\n            type: number\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateEventTypeInput'\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/UpdateEventTypeOutput'\n      tags:\n        - Event types\n    delete:\n      operationId: EventTypesController_deleteEventType\n      parameters:\n        - name: eventTypeId\n          required: true\n          in: path\n          schema:\n            type: number\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/DeleteEventTypeOutput'\n      tags:\n        - Event types\n  /v2/event-types/{username}/{eventSlug}/public:\n    get:\n      operationId: EventTypesController_getPublicEventType\n      parameters:\n        - name: username\n          required: true\n          in: path\n          schema:\n            type: string\n        - name: eventSlug\n          required: true\n          in: path\n          schema:\n            type: string\n        - name: isTeamEvent\n          required: false\n          in: query\n          schema:\n            type: boolean\n        - name: org\n          required: false\n          in: query\n          schema:\n            nullable: true\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetEventTypePublicOutput'\n      tags:\n        - Event types\n  /v2/event-types/{username}/public:\n    get:\n      operationId: EventTypesController_getPublicEventTypes\n      parameters:\n        - name: username\n          required: true\n          in: path\n          schema:\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetEventTypesPublicOutput'\n      tags:\n        - Event types\n  /v2/schedules:\n    post:\n      operationId: SchedulesController_createSchedule\n      parameters: []\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateScheduleInput'\n      responses:\n        '201':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CreateScheduleOutput'\n      tags:\n        - Schedules\n    get:\n      operationId: SchedulesController_getSchedules\n      parameters: []\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetSchedulesOutput'\n      tags:\n        - Schedules\n  /v2/schedules/default:\n    get:\n      operationId: SchedulesController_getDefaultSchedule\n      parameters: []\n      responses:\n        '200':\n          description: Returns the default schedule\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetDefaultScheduleOutput'\n      tags:\n        - Schedules\n  /v2/schedules/{scheduleId}:\n    get:\n      operationId: SchedulesController_getSchedule\n      parameters:\n        - name: scheduleId\n          required: true\n          in: path\n          schema:\n            type: number\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetScheduleOutput'\n      tags:\n        - Schedules\n    patch:\n      operationId: SchedulesController_updateSchedule\n      parameters:\n        - name: scheduleId\n          required: true\n          in: path\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateScheduleInput'\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/UpdateScheduleOutput'\n      tags:\n        - Schedules\n    delete:\n      operationId: SchedulesController_deleteSchedule\n      parameters:\n        - name: scheduleId\n          required: true\n          in: path\n          schema:\n            type: number\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/DeleteScheduleOutput'\n      tags:\n        - Schedules\n  /v2/bookings:\n    get:\n      operationId: BookingsController_getBookings\n      parameters:\n        - name: cursor\n          required: false\n          in: query\n          schema:\n            type: number\n        - name: limit\n          required: false\n          in: query\n          schema:\n            type: number\n        - name: filters[status]\n          required: true\n          in: query\n          schema:\n            enum:\n              - upcoming\n              - recurring\n              - past\n              - cancelled\n              - unconfirmed\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetBookingsOutput'\n      tags:\n        - Bookings\n    post:\n      operationId: BookingsController_createBooking\n      parameters:\n        - name: x-cal-client-id\n          required: true\n          in: header\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateBookingInput'\n      responses:\n        '201':\n          description: ''\n          content:\n            application/json:\n              schema:\n                type: object\n      tags:\n        - Bookings\n  /v2/bookings/{bookingUid}:\n    get:\n      operationId: BookingsController_getBooking\n      parameters:\n        - name: bookingUid\n          required: true\n          in: path\n          schema:\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GetBookingOutput'\n      tags:\n        - Bookings\n  /v2/bookings/{bookingUid}/reschedule:\n    get:\n      operationId: BookingsController_getBookingForReschedule\n      parameters:\n        - name: bookingUid\n          required: true\n          in: path\n          schema:\n            type: string\n      responses:\n        '200':\n          description: ''\n          content:\n            application/json:\n              schema:\n                type: object\n      tags:\n        - Bookings\n  /v2/bookings/{bookingId}/cancel:\n    post:\n      operationId: BookingsController_cancelBooking\n      parameters:\n        - name: bookingId\n          required: true\n          in: path\n          schema:\n            type: string\n        - name: x-cal-client-id\n          required: true\n          in: header\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CancelBookingInput'\n      responses:\n        '201':\n          description: ''\n          content:\n            application/json:\n              schema:\n                type: object\n      tags:\n        - Bookings\n  /v2/bookings/recurring:\n    post:\n      operationId: BookingsController_createRecurringBooking\n      parameters:\n        - name: x-cal-client-id\n          required: true\n          in: header\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              type: array\n              items:\n                type: string\n      responses:\n        '201':\n          description: ''\n          content:\n            application/json:\n              schema:\n                type: object\n      tags:\n        - Bookings\n  /v2/bookings/instant:\n    post:\n      operationId: BookingsController_createInstantBooking\n      parameters:\n        - name: x-cal-client-id\n          required: true\n          in: header\n          schema:\n            type: string\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateBookingInput'\n      responses:\n        '201':\n          description: ''\n          content:\n            application/json:\n              schema:\n                type: object\n      tags:\n        - Bookings\ninfo:\n  title: Cal.com v2 API\n  description: ''\n  version: 1.0.0\n  contact: {}\ntags: []\nservers: []\ncomponents:\n  schemas:\n    ManagedUserOutput:\n      type: object\n      properties:\n        id:\n          type: number\n          example: 1\n        email:\n          type: string\n          example: alice+cluo37fwd0001khkzqqynkpj3@example.com\n        username:\n          type: string\n          nullable: true\n          example: alice\n        timeZone:\n          type: string\n          example: America/New_York\n        weekStart:\n          type: string\n          example: Sunday\n        createdDate:\n          type: string\n          example: '2024-04-01T00:00:00.000Z'\n        timeFormat:\n          type: number\n          nullable: true\n          example: 12\n        defaultScheduleId:\n          type: number\n          nullable: true\n          example: null\n      required:\n        - id\n        - email\n        - username\n        - timeZone\n        - weekStart\n        - createdDate\n        - timeFormat\n        - defaultScheduleId\n    GetManagedUsersOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          type: array\n          items:\n            $ref: '#/components/schemas/ManagedUserOutput'\n      required:\n        - status\n        - data\n    CreateManagedUserInput:\n      type: object\n      properties:\n        email:\n          type: string\n          example: alice@example.com\n        timeFormat:\n          type: number\n          example: 12\n          enum:\n            - 12\n            - 24\n          description: Must be 12 or 24\n        weekStart:\n          type: string\n          example: Monday\n          enum:\n            - Monday\n            - Tuesday\n            - Wednesday\n            - Thursday\n            - Friday\n            - Saturday\n            - Sunday\n        timeZone:\n          type: string\n          example: America/New_York\n        name:\n          type: string\n      required:\n        - email\n    CreateManagedUserData:\n      type: object\n      properties:\n        user:\n          $ref: '#/components/schemas/ManagedUserOutput'\n        accessToken:\n          type: string\n        refreshToken:\n          type: string\n      required:\n        - user\n        - accessToken\n        - refreshToken\n    CreateManagedUserOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/CreateManagedUserData'\n      required:\n        - status\n        - data\n    GetManagedUserOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/ManagedUserOutput'\n      required:\n        - status\n        - data\n    UpdateManagedUserInput:\n      type: object\n      properties:\n        timeFormat:\n          type: number\n          example: 12\n          enum:\n            - 12\n            - 24\n          description: Must be 12 or 24\n        weekStart:\n          type: string\n          example: Monday\n          enum:\n            - Monday\n            - Tuesday\n            - Wednesday\n            - Thursday\n            - Friday\n            - Saturday\n            - Sunday\n        email:\n          type: string\n        name:\n          type: string\n        defaultScheduleId:\n          type: number\n        timeZone:\n          type: string\n    KeysDto:\n      type: object\n      properties:\n        accessToken:\n          type: string\n          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\n        refreshToken:\n          type: string\n          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\n      required:\n        - accessToken\n        - refreshToken\n    KeysResponseDto:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/KeysDto'\n      required:\n        - status\n        - data\n    CreateOAuthClientInput:\n      type: object\n      properties: {}\n    DataDto:\n      type: object\n      properties:\n        clientId:\n          type: string\n          example: clsx38nbl0001vkhlwin9fmt0\n        clientSecret:\n          type: string\n          example: >-\n            eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoib2F1dGgtY2xpZW50Iiwi\n      required:\n        - clientId\n        - clientSecret\n    CreateOAuthClientResponseDto:\n      type: object\n      properties:\n        status:\n          type: string\n          enum:\n            - success\n            - error\n          example: success\n        data:\n          example:\n            clientId: clsx38nbl0001vkhlwin9fmt0\n            clientSecret: >-\n              eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoib2F1dGgtY2xpZW50Iiwi\n          allOf:\n            - $ref: '#/components/schemas/DataDto'\n      required:\n        - status\n        - data\n    PlatformOAuthClientDto:\n      type: object\n      properties:\n        id:\n          type: string\n          example: clsx38nbl0001vkhlwin9fmt0\n        name:\n          type: string\n          example: MyClient\n        secret:\n          type: string\n          example: secretValue\n        permissions:\n          type: number\n          example: 3\n        logo:\n          type: string\n          nullable: true\n          example: https://example.com/logo.png\n        redirectUris:\n          example:\n            - https://example.com/callback\n          type: array\n          items:\n            type: string\n        organizationId:\n          type: number\n          example: 1\n        createdAt:\n          format: date-time\n          type: string\n          example: '2024-03-23T08:33:21.851Z'\n      required:\n        - id\n        - name\n        - secret\n        - permissions\n        - redirectUris\n        - organizationId\n        - createdAt\n    GetOAuthClientsResponseDto:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          type: array\n          items:\n            $ref: '#/components/schemas/PlatformOAuthClientDto'\n      required:\n        - status\n        - data\n    GetOAuthClientResponseDto:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/PlatformOAuthClientDto'\n      required:\n        - status\n        - data\n    UpdateOAuthClientInput:\n      type: object\n      properties:\n        logo:\n          type: string\n        name:\n          type: string\n        redirectUris:\n          default: []\n          type: array\n          items:\n            type: string\n        bookingRedirectUri:\n          type: string\n        bookingCancelRedirectUri:\n          type: string\n        bookingRescheduleRedirectUri:\n          type: string\n        areEmailsEnabled:\n          type: boolean\n    OAuthAuthorizeInput:\n      type: object\n      properties:\n        redirectUri:\n          type: string\n      required:\n        - redirectUri\n    ExchangeAuthorizationCodeInput:\n      type: object\n      properties:\n        clientSecret:\n          type: string\n      required:\n        - clientSecret\n    RefreshTokenInput:\n      type: object\n      properties:\n        refreshToken:\n          type: string\n      required:\n        - refreshToken\n    EventTypeLocation:\n      type: object\n      properties:\n        type:\n          type: string\n          example: link\n        link:\n          type: string\n          example: https://masterchief.com/argentina/flan/video/9129412\n      required:\n        - type\n    CreateEventTypeInput:\n      type: object\n      properties:\n        length:\n          type: number\n          minimum: 1\n          example: 60\n        slug:\n          type: string\n          example: cooking-class\n        title:\n          type: string\n          example: Learn the secrets of masterchief!\n        description:\n          type: string\n          example: >-\n            Discover the culinary wonders of the Argentina by making the best\n            flan ever!\n        locations:\n          type: array\n          items:\n            $ref: '#/components/schemas/EventTypeLocation'\n        disableGuests:\n          type: boolean\n      required:\n        - length\n        - slug\n        - title\n    EventTypeOutput:\n      type: object\n      properties:\n        id:\n          type: number\n          example: 1\n        length:\n          type: number\n          example: 60\n        slug:\n          type: string\n          example: cooking-class\n        title:\n          type: string\n          example: Learn the secrets of masterchief!\n        description:\n          type: string\n          nullable: true\n          example: >-\n            Discover the culinary wonders of the Argentina by making the best\n            flan ever!\n        locations:\n          nullable: true\n          type: array\n          items:\n            $ref: '#/components/schemas/EventTypeLocation'\n      required:\n        - id\n        - length\n        - slug\n        - title\n        - description\n        - locations\n    CreateEventTypeOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/EventTypeOutput'\n      required:\n        - status\n        - data\n    Data:\n      type: object\n      properties:\n        eventType:\n          $ref: '#/components/schemas/EventTypeOutput'\n      required:\n        - eventType\n    GetEventTypeOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/Data'\n      required:\n        - status\n        - data\n    EventTypeGroup:\n      type: object\n      properties:\n        eventTypes:\n          type: array\n          items:\n            $ref: '#/components/schemas/EventTypeOutput'\n      required:\n        - eventTypes\n    GetEventTypesData:\n      type: object\n      properties:\n        eventTypeGroups:\n          type: array\n          items:\n            $ref: '#/components/schemas/EventTypeGroup'\n      required:\n        - eventTypeGroups\n    GetEventTypesOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/GetEventTypesData'\n      required:\n        - status\n        - data\n    Location:\n      type: object\n      properties:\n        type:\n          type: string\n      required:\n        - type\n    Source:\n      type: object\n      properties:\n        id:\n          type: string\n        type:\n          type: string\n        label:\n          type: string\n      required:\n        - id\n        - type\n        - label\n    BookingField:\n      type: object\n      properties:\n        name:\n          type: string\n        type:\n          type: string\n        defaultLabel:\n          type: string\n        label:\n          type: string\n        placeholder:\n          type: string\n        required:\n          type: boolean\n        getOptionsAt:\n          type: string\n        hideWhenJustOneOption:\n          type: boolean\n        editable:\n          type: string\n        sources:\n          type: array\n          items:\n            $ref: '#/components/schemas/Source'\n      required:\n        - name\n        - type\n    Organization:\n      type: object\n      properties:\n        id:\n          type: number\n        slug:\n          type: string\n          nullable: true\n        name:\n          type: string\n        metadata:\n          type: object\n      required:\n        - id\n        - name\n        - metadata\n    Profile:\n      type: object\n      properties:\n        username:\n          type: string\n          nullable: true\n        id:\n          type: number\n          nullable: true\n        userId:\n          type: number\n        uid:\n          type: string\n        name:\n          type: string\n        organizationId:\n          type: number\n          nullable: true\n        organization:\n          nullable: true\n          allOf:\n            - $ref: '#/components/schemas/Organization'\n        upId:\n          type: string\n        image:\n          type: string\n        brandColor:\n          type: string\n        darkBrandColor:\n          type: string\n        theme:\n          type: string\n        bookerLayouts:\n          type: object\n      required:\n        - username\n        - id\n        - organizationId\n        - upId\n    Owner:\n      type: object\n      properties:\n        id:\n          type: number\n        avatarUrl:\n          type: string\n          nullable: true\n        username:\n          type: string\n          nullable: true\n        name:\n          type: string\n          nullable: true\n        weekStart:\n          type: string\n        brandColor:\n          type: string\n          nullable: true\n        darkBrandColor:\n          type: string\n          nullable: true\n        theme:\n          type: string\n          nullable: true\n        metadata:\n          type: object\n        defaultScheduleId:\n          type: number\n          nullable: true\n        nonProfileUsername:\n          type: string\n          nullable: true\n        profile:\n          $ref: '#/components/schemas/Profile'\n      required:\n        - id\n        - username\n        - name\n        - weekStart\n        - metadata\n        - nonProfileUsername\n        - profile\n    Schedule:\n      type: object\n      properties:\n        id:\n          type: number\n        timeZone:\n          type: string\n          nullable: true\n      required:\n        - id\n        - timeZone\n    User:\n      type: object\n      properties:\n        username:\n          type: string\n          nullable: true\n        name:\n          type: string\n          nullable: true\n        weekStart:\n          type: string\n        organizationId:\n          type: number\n        avatarUrl:\n          type: string\n          nullable: true\n        profile:\n          $ref: '#/components/schemas/Profile'\n        bookerUrl:\n          type: string\n      required:\n        - username\n        - name\n        - weekStart\n        - profile\n        - bookerUrl\n    PublicEventTypeOutput:\n      type: object\n      properties:\n        id:\n          type: number\n        title:\n          type: string\n        description:\n          type: string\n        eventName:\n          type: string\n          nullable: true\n        slug:\n          type: string\n        isInstantEvent:\n          type: boolean\n        aiPhoneCallConfig:\n          type: object\n        schedulingType:\n          type: object\n        length:\n          type: number\n        locations:\n          type: array\n          items:\n            $ref: '#/components/schemas/Location'\n        customInputs:\n          type: array\n          items:\n            type: object\n        disableGuests:\n          type: boolean\n        metadata:\n          type: object\n          nullable: true\n        lockTimeZoneToggleOnBookingPage:\n          type: boolean\n        requiresConfirmation:\n          type: boolean\n        requiresBookerEmailVerification:\n          type: boolean\n        recurringEvent:\n          type: object\n        price:\n          type: number\n        currency:\n          type: string\n        seatsPerTimeSlot:\n          type: number\n          nullable: true\n        seatsShowAvailabilityCount:\n          type: boolean\n          nullable: true\n        bookingFields:\n          type: array\n          items:\n            $ref: '#/components/schemas/BookingField'\n        team:\n          type: object\n        successRedirectUrl:\n          type: string\n          nullable: true\n        workflows:\n          type: array\n          items:\n            type: object\n        hosts:\n          type: array\n          items:\n            type: object\n        owner:\n          nullable: true\n          allOf:\n            - $ref: '#/components/schemas/Owner'\n        schedule:\n          nullable: true\n          allOf:\n            - $ref: '#/components/schemas/Schedule'\n        hidden:\n          type: boolean\n        assignAllTeamMembers:\n          type: boolean\n        bookerLayouts:\n          type: object\n        users:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n        entity:\n          type: object\n        isDynamic:\n          type: boolean\n      required:\n        - id\n        - title\n        - description\n        - slug\n        - isInstantEvent\n        - length\n        - locations\n        - customInputs\n        - disableGuests\n        - metadata\n        - lockTimeZoneToggleOnBookingPage\n        - requiresConfirmation\n        - requiresBookerEmailVerification\n        - price\n        - currency\n        - seatsShowAvailabilityCount\n        - bookingFields\n        - workflows\n        - hosts\n        - owner\n        - schedule\n        - hidden\n        - assignAllTeamMembers\n        - users\n        - entity\n        - isDynamic\n    GetEventTypePublicOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          nullable: true\n          allOf:\n            - $ref: '#/components/schemas/PublicEventTypeOutput'\n      required:\n        - status\n        - data\n    PublicEventType:\n      type: object\n      properties:\n        id:\n          type: number\n          example: 1\n        length:\n          type: number\n          example: 60\n        slug:\n          type: string\n          example: cooking-class\n        title:\n          type: string\n          example: Learn the secrets of masterchief!\n        description:\n          type: string\n          nullable: true\n      required:\n        - id\n        - length\n        - slug\n        - title\n    GetEventTypesPublicOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          type: array\n          items:\n            $ref: '#/components/schemas/PublicEventType'\n      required:\n        - status\n        - data\n    UpdateEventTypeInput:\n      type: object\n      properties:\n        length:\n          type: number\n          minimum: 1\n        slug:\n          type: string\n        title:\n          type: string\n        description:\n          type: string\n        hidden:\n          type: boolean\n        locations:\n          type: array\n          items:\n            $ref: '#/components/schemas/EventTypeLocation'\n        disableGuests:\n          type: boolean\n    UpdateEventTypeOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/EventTypeOutput'\n      required:\n        - status\n        - data\n    DeleteData:\n      type: object\n      properties:\n        id:\n          type: number\n          example: 1\n        length:\n          type: number\n          example: 60\n        slug:\n          type: string\n          example: cooking-class\n        title:\n          type: string\n          example: Learn the secrets of masterchief!\n      required:\n        - id\n        - length\n        - slug\n        - title\n    DeleteEventTypeOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/DeleteData'\n      required:\n        - status\n        - data\n    CreateAvailabilityInput:\n      type: object\n      properties:\n        days:\n          example:\n            - 1\n            - 2\n          type: array\n          items:\n            type: number\n        startTime:\n          format: date-time\n          type: string\n        endTime:\n          format: date-time\n          type: string\n      required:\n        - days\n        - startTime\n        - endTime\n    CreateScheduleInput:\n      type: object\n      properties:\n        name:\n          type: string\n        timeZone:\n          type: string\n        availabilities:\n          type: array\n          items:\n            $ref: '#/components/schemas/CreateAvailabilityInput'\n        isDefault:\n          type: boolean\n      required:\n        - name\n        - timeZone\n        - isDefault\n    WorkingHours:\n      type: object\n      properties:\n        days:\n          type: array\n          items:\n            type: number\n        startTime:\n          type: number\n        endTime:\n          type: number\n        userId:\n          type: number\n          nullable: true\n      required:\n        - days\n        - startTime\n        - endTime\n    AvailabilityModel:\n      type: object\n      properties:\n        id:\n          type: number\n        userId:\n          type: number\n          nullable: true\n        eventTypeId:\n          type: number\n          nullable: true\n        days:\n          type: array\n          items:\n            type: number\n        startTime:\n          format: date-time\n          type: string\n        endTime:\n          format: date-time\n          type: string\n        date:\n          format: date-time\n          type: string\n          nullable: true\n        scheduleId:\n          type: number\n          nullable: true\n      required:\n        - id\n        - days\n        - startTime\n        - endTime\n    TimeRange:\n      type: object\n      properties:\n        userId:\n          type: number\n          nullable: true\n        start:\n          format: date-time\n          type: string\n        end:\n          format: date-time\n          type: string\n      required:\n        - start\n        - end\n    ScheduleOutput:\n      type: object\n      properties:\n        id:\n          type: number\n        name:\n          type: string\n        isManaged:\n          type: boolean\n        workingHours:\n          type: array\n          items:\n            $ref: '#/components/schemas/WorkingHours'\n        schedule:\n          type: array\n          items:\n            $ref: '#/components/schemas/AvailabilityModel'\n        availability:\n          type: array\n          items:\n            required: true\n            type: array\n            items:\n              $ref: '#/components/schemas/TimeRange'\n        timeZone:\n          type: string\n        dateOverrides:\n          type: array\n          items:\n            type: object\n        isDefault:\n          type: boolean\n        isLastSchedule:\n          type: boolean\n        readOnly:\n          type: boolean\n      required:\n        - id\n        - name\n        - isManaged\n        - workingHours\n        - schedule\n        - availability\n        - timeZone\n        - dateOverrides\n        - isDefault\n        - isLastSchedule\n        - readOnly\n    CreateScheduleOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/ScheduleOutput'\n      required:\n        - status\n        - data\n    GetDefaultScheduleOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          nullable: true\n          allOf:\n            - $ref: '#/components/schemas/ScheduleOutput'\n      required:\n        - status\n        - data\n    GetScheduleOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/ScheduleOutput'\n      required:\n        - status\n        - data\n    GetSchedulesOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/ScheduleOutput'\n      required:\n        - status\n        - data\n    UpdateScheduleInput:\n      type: object\n      properties:\n        timeZone:\n          type: string\n        name:\n          type: string\n        isDefault:\n          type: boolean\n        schedule:\n          example:\n            - []\n            - - start: '2022-01-01T00:00:00.000Z'\n                end: '2022-01-02T00:00:00.000Z'\n            - []\n            - []\n            - []\n            - []\n            - []\n          items:\n            type: array\n          type: array\n        dateOverrides:\n          example:\n            - []\n            - - start: '2022-01-01T00:00:00.000Z'\n                end: '2022-01-02T00:00:00.000Z'\n            - []\n            - []\n            - []\n            - []\n            - []\n          items:\n            type: array\n          type: array\n      required:\n        - timeZone\n        - name\n        - isDefault\n        - schedule\n    EventTypeModel:\n      type: object\n      properties:\n        id:\n          type: number\n        eventName:\n          type: string\n          nullable: true\n      required:\n        - id\n    ScheduleModel:\n      type: object\n      properties:\n        id:\n          type: number\n        userId:\n          type: number\n        name:\n          type: string\n        timeZone:\n          type: string\n          nullable: true\n        eventType:\n          type: array\n          items:\n            $ref: '#/components/schemas/EventTypeModel'\n        availability:\n          type: array\n          items:\n            $ref: '#/components/schemas/AvailabilityModel'\n      required:\n        - id\n        - userId\n        - name\n    UpdatedScheduleOutput:\n      type: object\n      properties:\n        schedule:\n          $ref: '#/components/schemas/ScheduleModel'\n        isDefault:\n          type: boolean\n        timeZone:\n          type: string\n        prevDefaultId:\n          type: number\n          nullable: true\n        currentDefaultId:\n          type: number\n          nullable: true\n      required:\n        - schedule\n        - isDefault\n    UpdateScheduleOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/UpdatedScheduleOutput'\n      required:\n        - status\n        - data\n    DeleteScheduleOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n      required:\n        - status\n    AuthUrlData:\n      type: object\n      properties:\n        authUrl:\n          type: string\n      required:\n        - authUrl\n    GcalAuthUrlOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/AuthUrlData'\n      required:\n        - status\n        - data\n    GcalSaveRedirectOutput:\n      type: object\n      properties:\n        url:\n          type: string\n      required:\n        - url\n    GcalCheckOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n      required:\n        - status\n    ProviderVerifyClientOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n      required:\n        - status\n    ProviderVerifyAccessTokenOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n      required:\n        - status\n    MeOutput:\n      type: object\n      properties:\n        id:\n          type: number\n        username:\n          type: string\n        email:\n          type: string\n        timeFormat:\n          type: number\n        defaultScheduleId:\n          type: number\n          nullable: true\n        weekStart:\n          type: string\n        timeZone:\n          type: string\n      required:\n        - id\n        - username\n        - email\n        - timeFormat\n        - defaultScheduleId\n        - weekStart\n        - timeZone\n    GetMeOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/MeOutput'\n      required:\n        - status\n        - data\n    UpdateMeOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/MeOutput'\n      required:\n        - status\n        - data\n    BusyTimesOutput:\n      type: object\n      properties:\n        start:\n          format: date-time\n          type: string\n        end:\n          format: date-time\n          type: string\n        source:\n          type: string\n          nullable: true\n      required:\n        - start\n        - end\n    GetBusyTimesOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          type: array\n          items:\n            $ref: '#/components/schemas/BusyTimesOutput'\n      required:\n        - status\n        - data\n    Integration:\n      type: object\n      properties:\n        appData:\n          type: object\n          nullable: true\n        dirName:\n          type: string\n        __template:\n          type: string\n        name:\n          type: string\n        description:\n          type: string\n        installed:\n          type: boolean\n        type:\n          type: string\n        title:\n          type: string\n        variant:\n          type: string\n        category:\n          type: string\n        categories:\n          type: array\n          items:\n            type: string\n        logo:\n          type: string\n        publisher:\n          type: string\n        slug:\n          type: string\n        url:\n          type: string\n        email:\n          type: string\n        locationOption:\n          type: object\n          nullable: true\n      required:\n        - name\n        - description\n        - type\n        - variant\n        - categories\n        - logo\n        - publisher\n        - slug\n        - url\n        - email\n        - locationOption\n    Primary:\n      type: object\n      properties:\n        externalId:\n          type: string\n        integration:\n          type: string\n        name:\n          type: string\n        primary:\n          type: boolean\n          nullable: true\n        readOnly:\n          type: boolean\n        email:\n          type: string\n        isSelected:\n          type: boolean\n        credentialId:\n          type: number\n      required:\n        - externalId\n        - primary\n        - readOnly\n        - isSelected\n        - credentialId\n    Calendar:\n      type: object\n      properties:\n        externalId:\n          type: string\n        integration:\n          type: string\n        name:\n          type: string\n        primary:\n          type: boolean\n          nullable: true\n        readOnly:\n          type: boolean\n        email:\n          type: string\n        isSelected:\n          type: boolean\n        credentialId:\n          type: number\n      required:\n        - externalId\n        - readOnly\n        - isSelected\n        - credentialId\n    ConnectedCalendar:\n      type: object\n      properties:\n        integration:\n          $ref: '#/components/schemas/Integration'\n        credentialId:\n          type: number\n        primary:\n          $ref: '#/components/schemas/Primary'\n        calendars:\n          type: array\n          items:\n            $ref: '#/components/schemas/Calendar'\n      required:\n        - integration\n        - credentialId\n    DestinationCalendar:\n      type: object\n      properties:\n        id:\n          type: number\n        integration:\n          type: string\n        externalId:\n          type: string\n        primaryEmail:\n          type: string\n          nullable: true\n        userId:\n          type: number\n          nullable: true\n        eventTypeId:\n          type: number\n          nullable: true\n        credentialId:\n          type: number\n          nullable: true\n        name:\n          type: string\n          nullable: true\n        primary:\n          type: boolean\n        readOnly:\n          type: boolean\n        email:\n          type: string\n        integrationTitle:\n          type: string\n      required:\n        - id\n        - integration\n        - externalId\n        - primaryEmail\n        - userId\n        - eventTypeId\n        - credentialId\n    ConnectedCalendarsData:\n      type: object\n      properties:\n        connectedCalendars:\n          type: array\n          items:\n            $ref: '#/components/schemas/ConnectedCalendar'\n        destinationCalendar:\n          $ref: '#/components/schemas/DestinationCalendar'\n      required:\n        - connectedCalendars\n        - destinationCalendar\n    ConnectedCalendarsOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/ConnectedCalendarsData'\n      required:\n        - status\n        - data\n    Attendee:\n      type: object\n      properties:\n        id:\n          type: number\n        email:\n          type: string\n        name:\n          type: string\n        timeZone:\n          type: string\n        locale:\n          type: string\n          nullable: true\n        bookingId:\n          type: number\n          nullable: true\n      required:\n        - id\n        - email\n        - name\n        - timeZone\n        - locale\n        - bookingId\n    EventType:\n      type: object\n      properties:\n        slug:\n          type: string\n        id:\n          type: number\n        eventName:\n          type: string\n          nullable: true\n        price:\n          type: number\n        recurringEvent:\n          type: object\n        currency:\n          type: string\n        metadata:\n          type: object\n        seatsShowAttendees:\n          type: object\n        seatsShowAvailabilityCount:\n          type: object\n        team:\n          type: object\n          nullable: true\n      required:\n        - price\n        - currency\n        - metadata\n    Reference:\n      type: object\n      properties:\n        id:\n          type: number\n        type:\n          type: string\n        uid:\n          type: string\n        meetingId:\n          type: string\n          nullable: true\n        thirdPartyRecurringEventId:\n          type: string\n          nullable: true\n        meetingPassword:\n          type: string\n          nullable: true\n        meetingUrl:\n          type: string\n          nullable: true\n        bookingId:\n          type: number\n          nullable: true\n        externalCalendarId:\n          type: string\n          nullable: true\n        deleted:\n          type: object\n        credentialId:\n          type: number\n          nullable: true\n      required:\n        - id\n        - type\n        - uid\n        - meetingPassword\n        - bookingId\n        - externalCalendarId\n        - credentialId\n    GetBookingsDataEntry:\n      type: object\n      properties:\n        id:\n          type: number\n        title:\n          type: string\n        userPrimaryEmail:\n          type: string\n          nullable: true\n        description:\n          type: string\n          nullable: true\n        customInputs:\n          type: object\n        startTime:\n          type: string\n        endTime:\n          type: string\n        attendees:\n          type: array\n          items:\n            $ref: '#/components/schemas/Attendee'\n        metadata:\n          type: object\n        uid:\n          type: string\n        recurringEventId:\n          type: string\n          nullable: true\n        location:\n          type: string\n          nullable: true\n        eventType:\n          $ref: '#/components/schemas/EventType'\n        status:\n          type: object\n        paid:\n          type: boolean\n        payment:\n          type: array\n          items:\n            type: object\n        references:\n          type: array\n          items:\n            $ref: '#/components/schemas/Reference'\n        isRecorded:\n          type: boolean\n        seatsReferences:\n          type: array\n          items:\n            type: object\n        user:\n          nullable: true\n          allOf:\n            - $ref: '#/components/schemas/User'\n        rescheduled:\n          type: object\n      required:\n        - id\n        - title\n        - description\n        - customInputs\n        - startTime\n        - endTime\n        - attendees\n        - metadata\n        - uid\n        - recurringEventId\n        - location\n        - eventType\n        - status\n        - paid\n        - payment\n        - references\n        - isRecorded\n        - seatsReferences\n        - user\n    GetBookingsData:\n      type: object\n      properties:\n        bookings:\n          type: array\n          items:\n            $ref: '#/components/schemas/GetBookingsDataEntry'\n        recurringInfo:\n          type: array\n          items:\n            type: object\n        nextCursor:\n          type: number\n          nullable: true\n      required:\n        - bookings\n        - recurringInfo\n        - nextCursor\n    GetBookingsOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/GetBookingsData'\n      required:\n        - status\n        - data\n    GetBookingData:\n      type: object\n      properties:\n        title:\n          type: string\n        id:\n          type: number\n        uid:\n          type: string\n        description:\n          type: string\n          nullable: true\n        customInputs:\n          type: object\n        smsReminderNumber:\n          type: string\n          nullable: true\n        recurringEventId:\n          type: string\n          nullable: true\n        startTime:\n          format: date-time\n          type: string\n        endTime:\n          format: date-time\n          type: string\n        location:\n          type: string\n          nullable: true\n        status:\n          type: string\n        metadata:\n          type: object\n        cancellationReason:\n          type: string\n          nullable: true\n        responses:\n          type: object\n        rejectionReason:\n          type: string\n          nullable: true\n        userPrimaryEmail:\n          type: string\n          nullable: true\n        user:\n          nullable: true\n          allOf:\n            - $ref: '#/components/schemas/User'\n        attendees:\n          type: array\n          items:\n            $ref: '#/components/schemas/Attendee'\n        eventTypeId:\n          type: number\n          nullable: true\n        eventType:\n          nullable: true\n          allOf:\n            - $ref: '#/components/schemas/EventType'\n      required:\n        - title\n        - id\n        - uid\n        - description\n        - customInputs\n        - smsReminderNumber\n        - recurringEventId\n        - startTime\n        - endTime\n        - location\n        - status\n        - metadata\n        - cancellationReason\n        - responses\n        - rejectionReason\n        - userPrimaryEmail\n        - user\n        - attendees\n        - eventTypeId\n        - eventType\n    GetBookingOutput:\n      type: object\n      properties:\n        status:\n          type: string\n          example: success\n          enum:\n            - success\n            - error\n        data:\n          $ref: '#/components/schemas/GetBookingData'\n      required:\n        - status\n        - data\n    Response:\n      type: object\n      properties:\n        name:\n          type: string\n        email:\n          type: string\n        guests:\n          type: array\n          items:\n            type: string\n        location:\n          $ref: '#/components/schemas/Location'\n        notes:\n          type: string\n      required:\n        - name\n        - email\n        - guests\n    CreateBookingInput:\n      type: object\n      properties:\n        end:\n          type: string\n        start:\n          type: string\n        eventTypeId:\n          type: number\n        eventTypeSlug:\n          type: string\n        rescheduleUid:\n          type: string\n        recurringEventId:\n          type: string\n        timeZone:\n          type: string\n        user:\n          type: array\n          items:\n            type: string\n        language:\n          type: string\n        bookingUid:\n          type: string\n        metadata:\n          type: object\n        hasHashedBookingLink:\n          type: boolean\n        hashedLink:\n          type: string\n          nullable: true\n        seatReferenceUid:\n          type: string\n        responses:\n          $ref: '#/components/schemas/Response'\n        orgSlug:\n          type: string\n        locationUrl:\n          type: string\n      required:\n        - start\n        - eventTypeId\n        - timeZone\n        - language\n        - metadata\n        - hashedLink\n        - responses\n    CancelBookingInput:\n      type: object\n      properties:\n        id:\n          type: number\n        uid:\n          type: string\n        allRemainingBookings:\n          type: boolean\n        cancellationReason:\n          type: string\n        seatReferenceUid:\n          type: string\n      required:\n        - id\n        - uid\n        - allRemainingBookings\n        - cancellationReason\n        - seatReferenceUid\n    ReserveSlotInput:\n      type: object\n      properties: {}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/cal/api.ts",
    "content": "import {\n  KeysResponseDto,\n  createApiClient,\n  RefreshTokenInput,\n  ManagedUserOutput,\n  type CreateManagedUserInput,\n  type CreateManagedUserOutput,\n} from \"./__generated/cal-sdk\";\nimport { isCalSandbox } from \"./utils\";\nimport { env } from \"@/env\";\nimport { type Prisma, type User } from \"@prisma/client\";\nimport { unstable_noStore } from \"next/cache\";\nimport { db } from \"prisma/client\";\nimport \"server-only\";\nimport { type z } from \"zod\";\n\nconst calApiUrl = new URL(env.NEXT_PUBLIC_CAL_API_URL);\nconst baseUrl = `${calApiUrl.protocol}//${calApiUrl.hostname}`;\n// create a class instance of the Cal SDK that requires a user id as an input & returns the createApiClient's return:\ntype SDKInput = Pick<User, \"id\"> & Partial<Pick<User, \"calAccessToken\" | \"calRefreshToken\" | \"calAccountId\">>;\nexport const cal = (input: { user: SDKInput }) =>\n  createApiClient(async (method, url, params) => {\n    unstable_noStore(); // TODO: whenever we upgrade to next15, replace this with `unstable_rethrow` to support react's throwing mechanism under the hood @link: https://nextjs.org/docs/messages/ppr-caught-error\n    const fullUrl = new URL(url);\n    // the pathname contains variables that need to be replaced with our params.path (if defined). e.g. `v2/oauth-clients/%7BclientId%7D/users` should be rpelaced with the params.path[\"clientId\"]:\n    if (params?.path && Object.keys(params.path).length > 0)\n      fullUrl.pathname = fullUrl.pathname.replace(\n        // a regex, that takes the key inside `%7B` and `%7D` and replaces this with the value from the params.path object\n        /%7B([^%7D]+)%7D/g,\n        (match, key) => params.path?.[key as keyof typeof params.path] as string\n      );\n\n    try {\n      if (!input.user.id) {\n        console.warn(`[Cal SDK] Unable to use the Cal API: No user is authenticated'`);\n        throw new Error(`[Cal SDK] Unauthorized`);\n      }\n\n      // instantiate with 'let' so that we can re-assign this variable after a potential retry with a refreshed token (syncs the dbUser)\n      let dbUser: SDKInput | null = input.user;\n      if (!dbUser.calAccessToken || !dbUser.calRefreshToken || !dbUser.calAccountId) {\n        dbUser = await db.user.findUnique({\n          where: { id: input.user.id },\n          select: { id: true, calAccessToken: true, calAccountId: true, calRefreshToken: true },\n        });\n      }\n      if (!dbUser) {\n        console.warn(\n          `[Cal SDK] Unable to use the Cal API: No user found in the database with id '${input.user.id}'.`\n        );\n        throw new Error(`[Cal SDK] Unauthorized`);\n      }\n\n      if (!dbUser.calAccessToken && !isAdminEndpoint(fullUrl.pathname)) {\n        console.warn(\n          `[Cal SDK] Unable to use the Cal API on a non-admin endpoint ('${fullUrl.pathname}'): The user ${dbUser.id} has no access token for Cal set.`\n        );\n        throw new Error(`[Cal SDK] Unauthorized`);\n      }\n      /*\n       * [Validation] End.\n       **/\n\n      // compose the fetch parameters in a variable to re-use later (for logs & retries)\n      // @ts-expect-error - query has `unknown` values, but we're in a try/catch to handle that case\n      if (params?.query) fullUrl.search = new URLSearchParams(params.query).toString();\n\n      const options = {\n        headers: {\n          ...calHeaders,\n          Authorization: `Bearer ${dbUser.calAccessToken}`,\n        },\n        method,\n        body: JSON.stringify(params?.body),\n        cache: \"no-store\",\n      } satisfies RequestInit;\n      const fetchParameters = [fullUrl.href, options] satisfies Parameters<typeof fetch>;\n\n      // instantiate response variables (assign with `let` so that we can re-assign after retries)\n      unstable_noStore(); // TODO: whenever we upgrade to next15, replace this with `unstable_rethrow` to support react's throwing mechanism under the hood @link: https://nextjs.org/docs/messages/ppr-caught-error\n      let res = await fetch(fetchParameters[0], fetchParameters[1]);\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n      let json = await res.json();\n\n      // [@calcom] This means the token has expired, we refresh it and retry the request (re-assigns to res & json)\n      if (res.status === 498) {\n        if (!dbUser.calRefreshToken || !dbUser.calAccountId) {\n          console.warn(\n            `[Cal SDK] Unable to use the Cal API: The user ${dbUser.id} has no refresh token for Cal set and the access token has expired.`\n          );\n          throw new Error(`[Cal SDK] Unauthorized`);\n        }\n        const refreshFlowData = await refreshTokens({\n          refreshToken: dbUser.calRefreshToken,\n          calAccountId: dbUser.calAccountId,\n        });\n        // if we were unable to refresh the tokens, we throw an error\n        if (refreshFlowData.status === \"error\") {\n          console.error(\n            `[Cal SDK] Unable to fetch the Cal API: Entire refresh flow for user with refreshToken '${dbUser.calRefreshToken}' (user id: '${dbUser.id}') failed.`\n          );\n          throw new Error(`[Cal SDK] Application Error`);\n        }\n\n        // with fresh tokens, let's update the database & retry the request in parallel:\n        const [_updatedUser, retryRes] = await updateDbAndRetryFetch({\n          fetch: fetchParameters,\n          update: {\n            where: { id: dbUser.id },\n            data: {\n              calAccessToken: refreshFlowData.data.accessToken,\n              calRefreshToken: refreshFlowData.data.refreshToken,\n            },\n          },\n        });\n\n        // if the retry with fresh tokens didn't work, we log the fetch debug info (not throwing, so that we return the error to the application)\n        if (!retryRes.res.ok) {\n          console.error(\n            `[Cal SDK] Unable to fetch cal api on endpoint '${fullUrl.pathname}' after the refreshFlow: Invalid response from Cal with fresh tokens.`\n          );\n        }\n\n        // re-assign the variables so that the outer closure can use it, we're done with 498 handling\n        dbUser = _updatedUser;\n        res = retryRes.res;\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n        json = retryRes.json;\n      }\n\n      // [@calcom] This means the used token has been rotated, but the token we used is outdated (ie our DB *could* be out-of-sync), let's force-refresh:\n      if (res.status === 403) {\n        if (!dbUser.calAccountId) {\n          console.warn(\n            `[Cal SDK] Unable to use the Cal API: The user ${dbUser.id} has no refresh token for Cal set and the access token has expired.`\n          );\n          throw new Error(`[Cal SDK] Unauthorized`);\n        }\n        const forceRefreshData = await forceRefresh({ calAccountId: dbUser.calAccountId });\n        // if the force-refresh doesn't work, we have to throw an error, it's a dead end\n        if (forceRefreshData.status === \"error\") throw new Error(`[Cal SDK] Application Error`);\n\n        const [_updatedUser, retryRes] = await updateDbAndRetryFetch({\n          fetch: [fullUrl, options],\n          update: {\n            where: { id: dbUser.id },\n            data: {\n              calAccessToken: forceRefreshData.data.accessToken,\n              calRefreshToken: forceRefreshData.data.refreshToken,\n            },\n          },\n        });\n        // if the retry with fresh tokens didn't work, we log the fetch debug info (not throwing, so that we return the error to the application)\n        if (!retryRes.res.ok) {\n          console.error(\n            `\n          \n          [Cal SDK] Unable to fetch cal api on endpoint '${fullUrl.pathname}' after the forceRefresh: Invalid response from Cal with fresh tokens.\n          \n          `\n          );\n        }\n\n        // re-assign the variables so that the outer closure can use it, we're done with 403 handling\n        dbUser = _updatedUser;\n        res = retryRes.res;\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n        json = retryRes.json;\n      }\n\n      // apart from 498 & 403 (requires token rotation), we return all other responses as-is to show the error to the application consumer and/or end-user\n      // but first, let's log the initial request if it failed\n      if (!res.ok) {\n        console.warn(\n          `[Cal SDK] Unable to fetch cal api on endpoint '${fullUrl.pathname}': Invalid response from Cal.\n      \n      ${composeFetchLogs({ fetch: fetchParameters, res, json, ...(dbUser.calAccountId && { cal: { id: dbUser.calAccountId } }) })}\n      `\n        );\n      }\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n      return json;\n    } catch (e) {\n      console.error(\"[Cal SDK] Unknown error encountered: \", e);\n      throw e;\n    }\n  }, baseUrl);\n\n/**\n * =================\n * TOKEN REFRESH\n * =================\n */\nexport const KeysSuccessDto = KeysResponseDto.shape.data;\ntype KeysSuccessData = z.infer<typeof KeysSuccessDto>;\n\nexport const refreshTokens = async (\n  input: z.infer<typeof RefreshTokenInput> & { calAccountId: User[\"calAccountId\"] }\n) => {\n  const inputValidation = RefreshTokenInput.extend({\n    calAccountId: ManagedUserOutput.shape.id,\n  }).safeParse(input);\n\n  if (!inputValidation.success) {\n    console.error(\n      `[Cal SDK] Invalid input provided to refreshTokens: ${inputValidation.error.errors.map((e) => e.message).join(\", \")}`\n    );\n    return { status: \"error\" } as { status: \"error\" };\n  }\n\n  // first attempt is to use the /refresh endpoint on `/oauth/`:\n  const url = new URL(calApiUrl);\n  url.pathname = `/v2/oauth/${env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}/refresh`;\n  const fetchParameters = [\n    url.href,\n    {\n      method: \"POST\",\n      headers: calHeaders,\n      cache: \"no-store\",\n      body: JSON.stringify({ refreshToken: input.refreshToken } satisfies RefreshTokenInput),\n    },\n  ] satisfies Parameters<typeof fetch>;\n\n  unstable_noStore(); // TODO: whenever we upgrade to next15, replace this with `unstable_rethrow` to support react's throwing mechanism under the hood @link: https://nextjs.org/docs/messages/ppr-caught-error\n  const response = await fetch(fetchParameters[0], fetchParameters[1]);\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n  const json = await response.json();\n\n  // early return if that worked\n  if (response.ok) {\n    console.info(`[Cal SDK] 🔁 Refreshed the token for user with refreshToken '${input.refreshToken}'`);\n    return json as { status: \"success\"; data: KeysSuccessData };\n  }\n\n  // log for debugging if that didn't work:\n  console.warn(`\n    [Cal SDK] Unable to refresh the user token for user with refreshToken '${input.refreshToken}': Invalid response from Cal after attempting to refresh the token.\n    Resorting to force-refresh now.\n    \n    ${composeFetchLogs({ fetch: fetchParameters, res: response, json, cal: { refreshToken: input.refreshToken } })}\n    `);\n\n  // second attempt is to use the /force-refresh endpoint on `/oauth-clients/`. We need the accountId for this:\n  return forceRefresh({ calAccountId: input.calAccountId });\n};\n\nexport const forceRefresh = async (input: { calAccountId: User[\"calAccountId\"] }) => {\n  const url = new URL(calApiUrl);\n  url.pathname = `/v2/oauth-clients/${env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}/users/${input.calAccountId}/force-refresh`;\n  const fetchParameters = [\n    url.href,\n    {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"x-cal-secret-key\": env.CAL_SECRET,\n        origin: \"http://localhost:3000\",\n      },\n    },\n  ] satisfies Parameters<typeof fetch>;\n\n  const response = await fetch(fetchParameters[0], fetchParameters[1]);\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n  const json = await response.json();\n\n  // if this doesn't work, log for debugging:\n  if (!response.ok) {\n    console.warn(\n      `[Cal SDK] Unable to force-refresh the user token for user with calAccountId '${input.calAccountId}': Invalid response from Cal after attempting to refresh the token.\n      \n      ${composeFetchLogs({ fetch: fetchParameters, res: response, json, cal: { id: input.calAccountId } })}\n      `\n    );\n    return { status: \"error\" } as { status: \"error\" };\n  }\n\n  // response.ok === true\n  console.info(`[Cal SDK] 🔁 Force-refreshed the token for user with calAccountId '${input.calAccountId}'`);\n  return json as Promise<{ status: \"success\"; data: KeysSuccessData }>;\n};\n\nexport const updateDbAndRetryFetch = async (input: {\n  fetch: FetchParametersLike;\n  update: Pick<Prisma.UserUpdateArgs, \"where\" | \"data\">;\n}) => {\n  // with fresh tokens, let's update the database & retry the request in parallel:\n  const inputUrl = input.fetch[0];\n  const retryUrl = (typeof inputUrl === \"string\" ? new URL(inputUrl) : inputUrl) satisfies URL;\n  // overwrite the previous headers with the new access token\n  const retryOptions = {\n    ...input.fetch[1],\n    headers: {\n      ...input.fetch[1].headers,\n      Authorization: `Bearer ${input.update.data.calAccessToken as string}`,\n    },\n  } satisfies RequestInit;\n  const [updatedUser, retryRes] = await Promise.all([\n    db.user.update({\n      where: input.update.where,\n      data: input.update.data,\n    }),\n    fetch(retryUrl.href, retryOptions),\n  ]);\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n  const retryJson = await retryRes.json();\n\n  // if the retry with fresh tokens didn't work, we log the fetch debug info (not throwing, so that we return the error to the application)\n  if (!retryRes.ok) {\n    console.error(\n      `\n      \n      [Cal SDK] Unable to fetch cal api on endpoint '${retryUrl.pathname}' after the forceRefresh: Invalid response from Cal with fresh tokens.\n      \n      ${composeFetchLogs({ fetch: [retryUrl.href, retryOptions], res: retryRes, json: retryJson, ...(updatedUser.calAccountId && { cal: { id: updatedUser.calAccountId } }) })}\n      `\n    );\n  }\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n  return [updatedUser, { res: retryRes, json: retryJson }] as const;\n};\n\n/**\n * =================\n * USER MANAGEMENT\n * =================\n */\n\nexport const createUser = async (input: CreateManagedUserInput) => {\n  const url = new URL(calApiUrl);\n  url.pathname = `/v2/oauth-clients/${env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}/users`;\n  const fetchParameters = [\n    url.href,\n    {\n      method: \"POST\",\n      headers: calHeaders,\n      body: JSON.stringify(input),\n    },\n  ] satisfies Parameters<typeof fetch>;\n\n  const response = await fetch(fetchParameters[0], fetchParameters[1]);\n\n  // if the initial response fails, there is a possibility that we attempted to create a duplicate user -- let's handle this\n  if (!response.ok) {\n    const text = await response.text();\n    // if the response is bad and anything but a duplicate response, we log for debugging & throw\n    if (!text.includes(\"already exists\")) {\n      console.error(\n        `[Cal SDK] Unable to create Managed User '${input.email.slice(0, 4)}*****': Invalid response from Cal after attempting to create the user.\n        \n        ${composeFetchLogs({ fetch: fetchParameters, res: response, json: text })}\n        `\n      );\n      // TODO: should we return cal's error message here?\n      return { status: \"error\" } as { status: \"error\" };\n    }\n\n    // otherwise, it means that Cal already has this user signed up\n    if (isCalSandbox) {\n      // in the sandbox, we have to return an error as we there are potentially multiple apps using the same Cal OAuth sandbox client, have the user create a unique email:\n      console.warn(`\n        [Cal SDK] Unable to create Managed User '${input.email.slice(0, 4)}*****': User already exists in Cal. \n        \n        ℹ️ In Cal's OAuth sandbox, the user must provide a unique email address. ℹ️\n        `);\n      return { status: \"error\" } as { status: \"error\" };\n    }\n\n    // let's try to reconcile our user from Cal's OAuth Managed users\n    const users = await getUsers();\n    if (users.status === \"error\") {\n      console.error(\n        `[Cal SDK] Unable to create user '${input.email.slice(0, 4)}*****': The user exists in Cal but we couldn't fetch the user list. Check logs above.`\n      );\n      return { status: \"error\" } as { status: \"error\" };\n    }\n\n    // [@calcom] 💡 Find our using by adding `+<clientId>` before the @ in the email -- that's what Cal does internally.\n    const user = users.data.find((calUser) => {\n      const ourEmailAsCal = input.email.replace(\"@\", `+${env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}@`);\n      return calUser.email === ourEmailAsCal;\n    });\n\n    // if we couldn't find it, the signup fails\n    if (!user) {\n      console.error(\n        `[Cal SDK] Unable to create user '${input.email.slice(0, 4)}*****': The user exists in Cal but we couldn't reconcile it from the response. Is there anything wrong with the 'users.data.find' predicate?`\n      );\n      return { status: \"error\" } as { status: \"error\" };\n    }\n    // We have found the user, but are missing the accessToken, let's force-refresh them:\n    const refreshedTokens = await forceRefresh({ calAccountId: user.id });\n    if (refreshedTokens.status === \"error\") {\n      // this is somewhat of a weird state as we found the user but couldn't refresh the tokens, try to force-refresh manually.\n      console.error(\n        `[Cal SDK] Unable to create user '${input.email.slice(0, 4)}*****': You need to force-refresh tokens manually for the calAccountId§ '${user.id}'.`\n      );\n      return { status: \"error\" } as { status: \"error\" };\n    }\n\n    return { status: \"success\", data: { ...refreshedTokens.data, user } } satisfies {\n      status: \"success\";\n      data: CreateManagedUserOutput[\"data\"];\n    };\n  }\n\n  return response.json() as Promise<{ status: \"success\"; data: CreateManagedUserOutput[\"data\"] }>;\n};\n\nexport const getUsers = async () => {\n  const url = new URL(calApiUrl);\n  url.pathname = `/v2/oauth-clients/${env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}/users`;\n  const fetchParameters = [\n    url.href,\n    {\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"x-cal-secret-key\": env.CAL_SECRET,\n      },\n    },\n  ] satisfies Parameters<typeof fetch>;\n\n  const response = await fetch(fetchParameters[0], fetchParameters[1]);\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n  const json = response.json();\n\n  if (!response.ok) {\n    console.error(\n      `\n      [Cal SDK] Unable to fetch all users: Invalid response from Cal after attempting to fetch all users.\n\n      ${composeFetchLogs({ fetch: fetchParameters, res: response, json })}\n      `\n    );\n    return { status: \"error\" } as { status: \"error\" };\n  }\n\n  return json as Promise<{ status: \"success\"; data: Array<ManagedUserOutput> }>;\n};\n\n/**\n * =================\n * UTILITIES\n * =================\n */\ntype FetchParametersLike = [string | URL, Parameters<typeof fetch>[\"1\"] & { body?: string }];\nexport const composeFetchLogs = (ctx: {\n  fetch: FetchParametersLike;\n  res: Pick<Response, \"status\" | \"statusText\">;\n  json: unknown;\n  cal?: { id: User[\"calAccountId\"] } | { refreshToken: User[\"calRefreshToken\"] };\n}) => {\n  const { fetch, res, cal, json } = ctx;\n  const [input, init] = fetch;\n  const url = typeof input === \"string\" ? new URL(input) : input;\n\n  return `\n  \n  -- REQUEST DETAILS --\n\n  URL: ${url.href}\n  Method: ${init?.method ?? \"GET\"}\n  Headers: ${JSON.stringify(init?.headers)}\n  Body: ${init?.body}\n\n\n  -- RESPONSE DETAILS --\n\n  Error Code: ${res.status}\n  Error Message: ${res.statusText}\n  Error Body: ${JSON.stringify(json)}\n  Timestamp: ${Date.now()}\n  \n  -- CAL API DETAILS --\n\n  OAuthClient: ${env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}\n  API Host: ${calApiUrl.host}\n  ${!cal && \"Manaded User id: Not available\"}\n  ${cal && (\"id\" in cal ? `Managed User id: ${cal.id}}` : `Managed User refresh token: ${cal.refreshToken}`)}\n  Endpoint: ${url.pathname}\n  \n  `;\n};\n\nexport const isCalError = (res: any): res is CalErrorResponse => res.status === \"error\";\n\nexport type CalErrorResponse = {\n  status: \"error\";\n  timestamp: string;\n  path: string;\n  error: {\n    code: string;\n    message: string;\n    details: {\n      message: string;\n      error: string;\n      statusCode: number;\n    };\n  };\n};\n\nexport const calHeaders = {\n  \"x-cal-secret-key\": env.CAL_SECRET,\n  // \"cal-api-version\": \"2024-05-21\", 06-11 -> latest version & 07-15 is the previous\n  \"cal-api-version\": \"2024-06-11\", // 06-11 -> latest version & 07-15 is the previous\n  Origin: new URL(env.NEXT_PUBLIC_REFRESH_URL).origin ?? \"http://localhost:3000\",\n  // ⚠️ NestJS requires this header otherwise it won't consume the body\n  \"Content-type\": \"application/json\",\n} as const;\n\nexport const isAdminEndpoint = (pathname: string) => pathname.startsWith(\"/v2/oauth\");\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/cal/auth.ts",
    "content": "import { type CreateManagedUserInput } from \"./__generated/cal-sdk\";\nimport { cal } from \"./api\";\nimport { env } from \"@/env\";\nimport { type User, type Prisma } from \"@prisma/client\";\n\nexport async function signUp({ email, name, user }: CreateManagedUserInput & { user: Pick<User, \"id\"> }) {\n  /** [@calcom] 1. Let's first create a managed user on the Cal Platform: */\n  const userCreation = await cal({ user }).post(\"/v2/oauth-clients/{clientId}/users\", {\n    path: { clientId: env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID },\n    body: {\n      email,\n      name,\n      // [@calcom] If we supply the timeZone as wwell, we create a default schedule for the managed user\n      timeZone: new Intl.DateTimeFormat().resolvedOptions().timeZone.toString(),\n    },\n  });\n\n  if (userCreation.status === \"error\") {\n    console.log(\n      `[Cal auth] Unable to create user '${email}' on Cal Platform. Check the logs above for more details`\n    );\n    throw new Error(`Unable to create user '${email}' on Cal Platform`);\n  }\n\n  /** [@calcom] 3. Finally, return the user as an object in the form of prisma's UserUpdateInput payload */\n  const toUpdate = {\n    calAccessToken: userCreation.data.accessToken,\n    calRefreshToken: userCreation.data.refreshToken,\n    // calAccessTokenExpiresAt: calUser.accessTokenExpiresAt,\n    calAccount: {\n      connectOrCreate: {\n        where: { id: userCreation.data.user.id },\n        create: {\n          id: userCreation.data.user.id,\n          email: userCreation.data.user.email,\n          username: userCreation.data.user.username,\n          timeZone: userCreation.data.user.timeZone,\n          weekStart: userCreation.data.user.weekStart,\n          createdDate: userCreation.data.user.createdDate,\n          timeFormat: userCreation.data.user.timeFormat,\n          defaultScheduleId: userCreation.data.user.defaultScheduleId,\n        },\n      },\n    },\n  } satisfies Prisma.UserUpdateInput;\n  return toUpdate;\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/cal/utils.ts",
    "content": "import { env } from \"@/env\";\n\nexport const stripCalOAuthClientIdFromText = (str: string) => {\n  if (str === \"\") return str;\n  return str.split(`-${env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}`)?.[0]?.replace(\".\", \" \");\n};\n\nexport const stripCalOAuthClientIdFromEmail = (str: string) => {\n  if (str === \"\") return str;\n  return str.replace(`+${env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID}`, \"\");\n};\n\nexport const isCalSandbox =\n  env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID === \"cluwyp9yb0001p61n2dkqdmo1\" &&\n  \"https://api.cal.dev/v2\" === env.NEXT_PUBLIC_CAL_API_URL;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/accordion.tsx",
    "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\"\nimport { ChevronDown } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Accordion = AccordionPrimitive.Root\n\nconst AccordionItem = React.forwardRef<\n  React.ElementRef<typeof AccordionPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n>(({ className, ...props }, ref) => (\n  <AccordionPrimitive.Item\n    ref={ref}\n    className={cn(\"border-b\", className)}\n    {...props}\n  />\n))\nAccordionItem.displayName = \"AccordionItem\"\n\nconst AccordionTrigger = React.forwardRef<\n  React.ElementRef<typeof AccordionPrimitive.Trigger>,\n  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n  <AccordionPrimitive.Header className=\"flex\">\n    <AccordionPrimitive.Trigger\n      ref={ref}\n      className={cn(\n        \"flex flex-1 items-center justify-between py-4 font-medium transition-all [&[data-state=open]>svg]:rotate-180\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronDown className=\"h-4 w-4 shrink-0 transition-transform duration-200\" />\n    </AccordionPrimitive.Trigger>\n  </AccordionPrimitive.Header>\n))\nAccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName\n\nconst AccordionContent = React.forwardRef<\n  React.ElementRef<typeof AccordionPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n  <AccordionPrimitive.Content\n    ref={ref}\n    className=\"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n    {...props}\n  >\n    <div className={cn(\"pb-4 pt-0\", className)}>{children}</div>\n  </AccordionPrimitive.Content>\n))\n\nAccordionContent.displayName = AccordionPrimitive.Content.displayName\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent }\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/avatar.tsx",
    "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Avatar = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n  <AvatarPrimitive.Root\n    ref={ref}\n    className={cn(\n      \"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full\",\n      className\n    )}\n    {...props}\n  />\n))\nAvatar.displayName = AvatarPrimitive.Root.displayName\n\nconst AvatarImage = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Image>,\n  React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => (\n  <AvatarPrimitive.Image\n    ref={ref}\n    className={cn(\"aspect-square h-full w-full\", className)}\n    {...props}\n  />\n))\nAvatarImage.displayName = AvatarPrimitive.Image.displayName\n\nconst AvatarFallback = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Fallback>,\n  React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => (\n  <AvatarPrimitive.Fallback\n    ref={ref}\n    className={cn(\n      \"flex h-full w-full items-center justify-center rounded-full bg-muted\",\n      className\n    )}\n    {...props}\n  />\n))\nAvatarFallback.displayName = AvatarPrimitive.Fallback.displayName\n\nexport { Avatar, AvatarImage, AvatarFallback }\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/badge.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nconst badgeVariants = cva(\n  \"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n  {\n    variants: {\n      variant: {\n        default: \"border-transparent bg-primary text-primary-foreground hover:bg-primary/80\",\n        secondary: \"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        destructive: \"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80\",\n        outline: \"text-foreground\",\n        success: \"border-transparent bg-success text-success-foreground hover:bg-success/80\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n);\n\nexport interface BadgeProps\n  extends React.HTMLAttributes<HTMLDivElement>,\n    VariantProps<typeof badgeVariants> {}\n\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n  return <div className={cn(badgeVariants({ variant }), className)} {...props} />;\n}\n\nexport { Badge, badgeVariants };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/breadcrumb.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { ChevronRight, MoreHorizontal } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst Breadcrumb = React.forwardRef<\n  HTMLElement,\n  React.ComponentPropsWithoutRef<\"nav\"> & {\n    separator?: React.ReactNode;\n  }\n>(({ ...props }, ref) => <nav ref={ref} aria-label=\"breadcrumb\" {...props} />);\nBreadcrumb.displayName = \"Breadcrumb\";\n\nconst BreadcrumbList = React.forwardRef<HTMLOListElement, React.ComponentPropsWithoutRef<\"ol\">>(\n  ({ className, ...props }, ref) => (\n    <ol\n      ref={ref}\n      className={cn(\n        \"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5\",\n        className\n      )}\n      {...props}\n    />\n  )\n);\nBreadcrumbList.displayName = \"BreadcrumbList\";\n\nconst BreadcrumbItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<\"li\">>(\n  ({ className, ...props }, ref) => (\n    <li ref={ref} className={cn(\"inline-flex items-center gap-1.5\", className)} {...props} />\n  )\n);\nBreadcrumbItem.displayName = \"BreadcrumbItem\";\n\nconst BreadcrumbLink = React.forwardRef<\n  HTMLAnchorElement,\n  React.ComponentPropsWithoutRef<\"a\"> & {\n    asChild?: boolean;\n  }\n>(({ asChild, className, ...props }, ref) => {\n  const Comp = asChild ? Slot : \"a\";\n\n  return <Comp ref={ref} className={cn(\"transition-colors hover:text-foreground\", className)} {...props} />;\n});\nBreadcrumbLink.displayName = \"BreadcrumbLink\";\n\nconst BreadcrumbPage = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<\"span\">>(\n  ({ className, ...props }, ref) => (\n    <span\n      ref={ref}\n      role=\"link\"\n      aria-disabled=\"true\"\n      aria-current=\"page\"\n      className={cn(\"font-normal text-foreground\", className)}\n      {...props}\n    />\n  )\n);\nBreadcrumbPage.displayName = \"BreadcrumbPage\";\n\nconst BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentProps<\"li\">) => (\n  <li role=\"presentation\" aria-hidden=\"true\" className={cn(\"[&>svg]:size-3.5\", className)} {...props}>\n    {children ?? <ChevronRight />}\n  </li>\n);\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\";\n\nconst BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<\"span\">) => (\n  <span\n    role=\"presentation\"\n    aria-hidden=\"true\"\n    className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n    {...props}>\n    <MoreHorizontal className=\"h-4 w-4\" />\n    <span className=\"sr-only\">More</span>\n  </span>\n);\nBreadcrumbEllipsis.displayName = \"BreadcrumbElipssis\";\n\nexport {\n  Breadcrumb,\n  BreadcrumbList,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n  BreadcrumbEllipsis,\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/button.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive: \"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\n        outline: \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n        secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-10 px-4 py-2\",\n        sm: \"h-9 rounded-md px-3\",\n        lg: \"h-11 rounded-md px-8\",\n        icon: \"h-10 w-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n);\n\nexport interface ButtonProps\n  extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n    VariantProps<typeof buttonVariants> {\n  asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n  ({ className, variant, size, asChild = false, ...props }, ref) => {\n    const Comp = asChild ? Slot : \"button\";\n    return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;\n  }\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/card.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\n\nconst Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div\n      ref={ref}\n      className={cn(\"rounded-lg border bg-card text-card-foreground shadow-sm\", className)}\n      {...props}\n    />\n  )\n);\nCard.displayName = \"Card\";\n\nconst CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(\"flex flex-col space-y-1.5 p-6\", className)} {...props} />\n  )\n);\nCardHeader.displayName = \"CardHeader\";\n\nconst CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(\n  ({ className, ...props }, ref) => (\n    <h3\n      ref={ref}\n      className={cn(\"text-2xl font-semibold leading-none tracking-tight\", className)}\n      {...props}\n    />\n  )\n);\nCardTitle.displayName = \"CardTitle\";\n\nconst CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n  ({ className, ...props }, ref) => (\n    <p ref={ref} className={cn(\"text-sm text-muted-foreground\", className)} {...props} />\n  )\n);\nCardDescription.displayName = \"CardDescription\";\n\nconst CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n);\nCardContent.displayName = \"CardContent\";\n\nconst CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(\"flex items-center p-6 pt-0\", className)} {...props} />\n  )\n);\nCardFooter.displayName = \"CardFooter\";\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/checkbox.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport { Check } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst Checkbox = React.forwardRef<\n  React.ElementRef<typeof CheckboxPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>\n>(({ className, ...props }, ref) => (\n  <CheckboxPrimitive.Root\n    ref={ref}\n    className={cn(\n      \"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:!bg-primary data-[state=checked]:text-primary-foreground\",\n      className\n    )}\n    {...props}>\n    <CheckboxPrimitive.Indicator className={cn(\"flex items-center justify-center text-current\")}>\n      <Check className=\"h-4 w-4\" />\n    </CheckboxPrimitive.Indicator>\n  </CheckboxPrimitive.Root>\n));\nCheckbox.displayName = CheckboxPrimitive.Root.displayName;\n\nexport { Checkbox };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/collapsible.tsx",
    "content": "\"use client\"\n\nimport * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\"\n\nconst Collapsible = CollapsiblePrimitive.Root\n\nconst CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger\n\nconst CollapsibleContent = CollapsiblePrimitive.CollapsibleContent\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/command.tsx",
    "content": "\"use client\";\n\nimport { Dialog, DialogContent } from \"@/components/ui/dialog\";\nimport { cn } from \"@/lib/utils\";\nimport { type DialogProps } from \"@radix-ui/react-dialog\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { Search } from \"lucide-react\";\nimport * as React from \"react\";\n\nexport type CommandProps = React.ElementRef<typeof CommandPrimitive> &\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive>;\nconst Command = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive\n    ref={ref}\n    className={cn(\n      \"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground\",\n      className\n    )}\n    {...props}\n  />\n));\nCommand.displayName = CommandPrimitive.displayName;\n\ntype CommandDialogProps = DialogProps;\n\nconst CommandDialog = ({ children, ...props }: CommandDialogProps) => {\n  return (\n    <Dialog {...props}>\n      <DialogContent className=\"overflow-hidden p-0 shadow-lg\">\n        <Command className=\"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  );\n};\n\nconst CommandInput = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Input>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ className, ...props }, ref) => (\n  <div className=\"flex items-center border-b px-3\" cmdk-input-wrapper=\"\">\n    <Search className=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n    <CommandPrimitive.Input\n      ref={ref}\n      className={cn(\n        \"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n        className\n      )}\n      {...props}\n    />\n  </div>\n));\n\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nconst CommandList = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.List>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.List\n    ref={ref}\n    className={cn(\"max-h-[300px] overflow-y-auto overflow-x-hidden\", className)}\n    {...props}\n  />\n));\n\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nconst CommandEmpty = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Empty>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => <CommandPrimitive.Empty ref={ref} className=\"py-6 text-center text-sm\" {...props} />);\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nconst CommandGroup = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Group>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.Group\n    ref={ref}\n    className={cn(\n      \"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground\",\n      className\n    )}\n    {...props}\n  />\n));\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nconst CommandSeparator = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.Separator ref={ref} className={cn(\"-mx-1 h-px bg-border\", className)} {...props} />\n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\nconst CommandItem = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.Item\n    ref={ref}\n    className={cn(\n      \"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50\",\n      className\n    )}\n    {...props}\n  />\n));\n\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n\nconst CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {\n  return (\n    <span className={cn(\"ml-auto text-xs tracking-widest text-muted-foreground\", className)} {...props} />\n  );\n};\nCommandShortcut.displayName = \"CommandShortcut\";\n\nexport {\n  Command,\n  CommandDialog,\n  CommandInput,\n  CommandList,\n  CommandEmpty,\n  CommandGroup,\n  CommandItem,\n  CommandShortcut,\n  CommandSeparator,\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/dialog.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { X } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst Dialog = DialogPrimitive.Root;\n\nconst DialogTrigger = DialogPrimitive.Trigger;\n\nconst DialogPortal = DialogPrimitive.Portal;\n\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <DialogPrimitive.Overlay\n    ref={ref}\n    className={cn(\n      \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n      className\n    )}\n    {...props}\n  />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n  <DialogPortal>\n    <DialogOverlay />\n    <DialogPrimitive.Content\n      ref={ref}\n      className={cn(\n        \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg\",\n        className\n      )}\n      {...props}>\n      {children}\n      <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\">\n        <X className=\"h-4 w-4\" />\n        <span className=\"sr-only\">Close</span>\n      </DialogPrimitive.Close>\n    </DialogPrimitive.Content>\n  </DialogPortal>\n));\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex flex-col space-y-1.5 text-center sm:text-left\", className)} {...props} />\n);\nDialogHeader.displayName = \"DialogHeader\";\n\nconst DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\", className)}\n    {...props}\n  />\n);\nDialogFooter.displayName = \"DialogFooter\";\n\nconst DialogTitle = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n  <DialogPrimitive.Title\n    ref={ref}\n    className={cn(\"text-lg font-semibold leading-none tracking-tight\", className)}\n    {...props}\n  />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <DialogPrimitive.Description\n    ref={ref}\n    className={cn(\"text-sm text-muted-foreground\", className)}\n    {...props}\n  />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n  Dialog,\n  DialogPortal,\n  DialogOverlay,\n  DialogClose,\n  DialogTrigger,\n  DialogContent,\n  DialogHeader,\n  DialogFooter,\n  DialogTitle,\n  DialogDescription,\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/dropdown-menu.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { Check, ChevronRight, Circle } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst DropdownMenu = DropdownMenuPrimitive.Root;\n\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group;\n\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal;\n\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub;\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n    inset?: boolean;\n  }\n>(({ className, inset, children, ...props }, ref) => (\n  <DropdownMenuPrimitive.SubTrigger\n    ref={ref}\n    className={cn(\n      \"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent\",\n      inset && \"pl-8\",\n      className\n    )}\n    {...props}>\n    {children}\n    <ChevronRight className=\"ml-auto h-4 w-4\" />\n  </DropdownMenuPrimitive.SubTrigger>\n));\nDropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;\nconst DropdownMenuSubContent = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.SubContent\n    ref={ref}\n    className={cn(\n      \"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n      className\n    )}\n    {...props}\n  />\n));\nDropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;\n\nconst DropdownMenuContent = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n  <DropdownMenuPrimitive.Portal>\n    <DropdownMenuPrimitive.Content\n      ref={ref}\n      sideOffset={sideOffset}\n      className={cn(\n        \"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n        className\n      )}\n      {...props}\n    />\n  </DropdownMenuPrimitive.Portal>\n));\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;\n\nconst DropdownMenuItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n    inset?: boolean;\n  }\n>(({ className, inset, ...props }, ref) => (\n  <DropdownMenuPrimitive.Item\n    ref={ref}\n    className={cn(\n      \"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n      inset && \"pl-8\",\n      className\n    )}\n    {...props}\n  />\n));\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n  <DropdownMenuPrimitive.CheckboxItem\n    ref={ref}\n    className={cn(\n      \"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n      className\n    )}\n    checked={checked}\n    {...props}>\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <DropdownMenuPrimitive.ItemIndicator>\n        <Check className=\"h-4 w-4\" />\n      </DropdownMenuPrimitive.ItemIndicator>\n    </span>\n    {children}\n  </DropdownMenuPrimitive.CheckboxItem>\n));\nDropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;\n\nconst DropdownMenuRadioItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n  <DropdownMenuPrimitive.RadioItem\n    ref={ref}\n    className={cn(\n      \"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n      className\n    )}\n    {...props}>\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <DropdownMenuPrimitive.ItemIndicator>\n        <Circle className=\"h-2 w-2 fill-current\" />\n      </DropdownMenuPrimitive.ItemIndicator>\n    </span>\n    {children}\n  </DropdownMenuPrimitive.RadioItem>\n));\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;\n\nconst DropdownMenuLabel = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n    inset?: boolean;\n  }\n>(({ className, inset, ...props }, ref) => (\n  <DropdownMenuPrimitive.Label\n    ref={ref}\n    className={cn(\"px-2 py-1.5 text-sm font-semibold\", inset && \"pl-8\", className)}\n    {...props}\n  />\n));\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;\n\nconst DropdownMenuSeparator = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.Separator\n    ref={ref}\n    className={cn(\"-mx-1 my-1 h-px bg-muted\", className)}\n    {...props}\n  />\n));\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;\n\nconst DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {\n  return <span className={cn(\"ml-auto text-xs tracking-widest opacity-60\", className)} {...props} />;\n};\nDropdownMenuShortcut.displayName = \"DropdownMenuShortcut\";\n\nexport {\n  DropdownMenu,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuGroup,\n  DropdownMenuPortal,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuRadioGroup,\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/form.tsx",
    "content": "import { Label } from \"@/components/ui/label\";\nimport { cn } from \"@/lib/utils\";\nimport type * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport {\n  Controller,\n  type ControllerProps,\n  type FieldPath,\n  type FieldValues,\n  FormProvider,\n  useFormContext,\n} from \"react-hook-form\";\n\nconst Form = FormProvider;\n\ntype FormFieldContextValue<\n  TFieldValues extends FieldValues = FieldValues,\n  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n  name: TName;\n};\n\nconst FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);\n\nconst FormField = <\n  TFieldValues extends FieldValues = FieldValues,\n  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n  ...props\n}: ControllerProps<TFieldValues, TName>) => {\n  return (\n    <FormFieldContext.Provider value={{ name: props.name }}>\n      <Controller {...props} />\n    </FormFieldContext.Provider>\n  );\n};\n\nconst useFormField = () => {\n  const fieldContext = React.useContext(FormFieldContext);\n  const itemContext = React.useContext(FormItemContext);\n  const { getFieldState, formState } = useFormContext();\n\n  const fieldState = getFieldState(fieldContext.name, formState);\n\n  if (!fieldContext) {\n    throw new Error(\"useFormField should be used within <FormField>\");\n  }\n\n  const { id } = itemContext;\n\n  return {\n    id,\n    name: fieldContext.name,\n    formItemId: `${id}-form-item`,\n    formDescriptionId: `${id}-form-item-description`,\n    formMessageId: `${id}-form-item-message`,\n    ...fieldState,\n  };\n};\n\ntype FormItemContextValue = {\n  id: string;\n};\n\nconst FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);\n\nconst FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => {\n    const id = React.useId();\n\n    return (\n      <FormItemContext.Provider value={{ id }}>\n        <div ref={ref} className={cn(\"space-y-2\", className)} {...props} />\n      </FormItemContext.Provider>\n    );\n  }\n);\nFormItem.displayName = \"FormItem\";\n\nconst FormLabel = React.forwardRef<\n  React.ElementRef<typeof LabelPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>\n>(({ className, ...props }, ref) => {\n  const { error, formItemId } = useFormField();\n\n  return (\n    <Label ref={ref} className={cn(error && \"text-destructive\", className)} htmlFor={formItemId} {...props} />\n  );\n});\nFormLabel.displayName = \"FormLabel\";\n\nconst FormControl = React.forwardRef<\n  React.ElementRef<typeof Slot>,\n  React.ComponentPropsWithoutRef<typeof Slot>\n>(({ ...props }, ref) => {\n  const { error, formItemId, formDescriptionId, formMessageId } = useFormField();\n\n  return (\n    <Slot\n      ref={ref}\n      id={formItemId}\n      aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}\n      aria-invalid={!!error}\n      {...props}\n    />\n  );\n});\nFormControl.displayName = \"FormControl\";\n\nconst FormDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n  ({ className, ...props }, ref) => {\n    const { formDescriptionId } = useFormField();\n\n    return (\n      <p\n        ref={ref}\n        id={formDescriptionId}\n        className={cn(\"text-sm text-muted-foreground\", className)}\n        {...props}\n      />\n    );\n  }\n);\nFormDescription.displayName = \"FormDescription\";\n\nconst FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n  ({ className, children, ...props }, ref) => {\n    const { error, formMessageId } = useFormField();\n    const body = error ? String(error?.message) : children;\n\n    if (!body) {\n      return null;\n    }\n\n    return (\n      <p\n        ref={ref}\n        id={formMessageId}\n        className={cn(\"text-sm font-medium text-destructive\", className)}\n        {...props}>\n        {body}\n      </p>\n    );\n  }\n);\nFormMessage.displayName = \"FormMessage\";\n\nexport { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/input.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\n\nexport type InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(({ className, type, ...props }, ref) => {\n  return (\n    <input\n      type={type}\n      className={cn(\n        \"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n        className\n      )}\n      ref={ref}\n      {...props}\n    />\n  );\n});\nInput.displayName = \"Input\";\n\nexport { Input };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/label.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nconst labelVariants = cva(\n  \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n);\n\nconst Label = React.forwardRef<\n  React.ElementRef<typeof LabelPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n  <LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/navigation-menu.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport * as NavigationMenuPrimitive from \"@radix-ui/react-navigation-menu\";\nimport { cva } from \"class-variance-authority\";\nimport { ChevronDown } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst NavigationMenu = React.forwardRef<\n  React.ElementRef<typeof NavigationMenuPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>\n>(({ className, children, ...props }, ref) => (\n  <NavigationMenuPrimitive.Root\n    ref={ref}\n    className={cn(\"relative z-10 flex max-w-max flex-1 items-center justify-center\", className)}\n    {...props}>\n    {children}\n    <NavigationMenuViewport />\n  </NavigationMenuPrimitive.Root>\n));\nNavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;\n\nconst NavigationMenuList = React.forwardRef<\n  React.ElementRef<typeof NavigationMenuPrimitive.List>,\n  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>\n>(({ className, ...props }, ref) => (\n  <NavigationMenuPrimitive.List\n    ref={ref}\n    className={cn(\"group flex flex-1 list-none items-center justify-center space-x-1\", className)}\n    {...props}\n  />\n));\nNavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;\n\nconst NavigationMenuItem = NavigationMenuPrimitive.Item;\n\nconst navigationMenuTriggerStyle = cva(\n  \"group inline-flex h-10 w-max items-center justify-center uppercase rounded-full px-4 py-2 text-sm font-medium hover:bg-black hover:text-white focus:bg-black focus:text-black-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active] data-[active]:bg-black data-[state=open]:bg-black data-[state=open]:text-white\"\n);\n\nconst NavigationMenuTrigger = React.forwardRef<\n  React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,\n  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n  <NavigationMenuPrimitive.Trigger\n    ref={ref}\n    className={cn(navigationMenuTriggerStyle(), \"group\", className)}\n    {...props}>\n    {children}{\" \"}\n    <ChevronDown\n      className=\"relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180\"\n      aria-hidden=\"true\"\n    />\n  </NavigationMenuPrimitive.Trigger>\n));\nNavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;\n\nconst NavigationMenuContent = React.forwardRef<\n  React.ElementRef<typeof NavigationMenuPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>\n>(({ className, ...props }, ref) => (\n  <NavigationMenuPrimitive.Content\n    ref={ref}\n    className={cn(\n      \"left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto \",\n      className\n    )}\n    {...props}\n  />\n));\nNavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;\n\nconst NavigationMenuLink = NavigationMenuPrimitive.Link;\n\nconst NavigationMenuViewport = React.forwardRef<\n  React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,\n  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>\n>(({ className, ...props }, ref) => (\n  <div className={cn(\"absolute left-0 top-full flex justify-center\")}>\n    <NavigationMenuPrimitive.Viewport\n      className={cn(\n        \"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]\",\n        className\n      )}\n      ref={ref}\n      {...props}\n    />\n  </div>\n));\nNavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport.displayName;\n\nconst NavigationMenuIndicator = React.forwardRef<\n  React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,\n  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>\n>(({ className, ...props }, ref) => (\n  <NavigationMenuPrimitive.Indicator\n    ref={ref}\n    className={cn(\n      \"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in\",\n      className\n    )}\n    {...props}>\n    <div className=\"relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md\" />\n  </NavigationMenuPrimitive.Indicator>\n));\nNavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName;\n\nexport {\n  navigationMenuTriggerStyle,\n  NavigationMenu,\n  NavigationMenuList,\n  NavigationMenuItem,\n  NavigationMenuContent,\n  NavigationMenuTrigger,\n  NavigationMenuLink,\n  NavigationMenuIndicator,\n  NavigationMenuViewport,\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/pagination.tsx",
    "content": "import { type ButtonProps, buttonVariants } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst Pagination = ({ className, ...props }: React.ComponentProps<\"nav\">) => (\n  <nav\n    role=\"navigation\"\n    aria-label=\"pagination\"\n    className={cn(\"mx-auto flex w-full justify-center\", className)}\n    {...props}\n  />\n);\nPagination.displayName = \"Pagination\";\n\nconst PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentProps<\"ul\">>(\n  ({ className, ...props }, ref) => (\n    <ul ref={ref} className={cn(\"flex flex-row items-center gap-1\", className)} {...props} />\n  )\n);\nPaginationContent.displayName = \"PaginationContent\";\n\nconst PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentProps<\"li\">>(\n  ({ className, ...props }, ref) => <li ref={ref} className={cn(\"\", className)} {...props} />\n);\nPaginationItem.displayName = \"PaginationItem\";\n\ntype PaginationLinkProps = {\n  isActive?: boolean;\n} & Pick<ButtonProps, \"size\"> &\n  React.ComponentProps<\"a\">;\n\nconst PaginationLink = ({ className, isActive, size = \"icon\", ...props }: PaginationLinkProps) => (\n  <a\n    aria-current={isActive ? \"page\" : undefined}\n    className={cn(\n      buttonVariants({\n        variant: isActive ? \"outline\" : \"ghost\",\n        size,\n      }),\n      className\n    )}\n    {...props}\n  />\n);\nPaginationLink.displayName = \"PaginationLink\";\n\nconst PaginationPrevious = ({ className, ...props }: React.ComponentProps<typeof PaginationLink>) => (\n  <PaginationLink\n    aria-label=\"Go to previous page\"\n    size=\"default\"\n    className={cn(\"gap-1 pl-2.5\", className)}\n    {...props}>\n    <ChevronLeft className=\"h-4 w-4\" />\n    <span>Previous</span>\n  </PaginationLink>\n);\nPaginationPrevious.displayName = \"PaginationPrevious\";\n\nconst PaginationNext = ({ className, ...props }: React.ComponentProps<typeof PaginationLink>) => (\n  <PaginationLink\n    aria-label=\"Go to next page\"\n    size=\"default\"\n    className={cn(\"gap-1 pr-2.5\", className)}\n    {...props}>\n    <span>Next</span>\n    <ChevronRight className=\"h-4 w-4\" />\n  </PaginationLink>\n);\nPaginationNext.displayName = \"PaginationNext\";\n\nconst PaginationEllipsis = ({ className, ...props }: React.ComponentProps<\"span\">) => (\n  <span aria-hidden className={cn(\"flex h-9 w-9 items-center justify-center\", className)} {...props}>\n    <MoreHorizontal className=\"h-4 w-4\" />\n    <span className=\"sr-only\">More pages</span>\n  </span>\n);\nPaginationEllipsis.displayName = \"PaginationEllipsis\";\n\nexport {\n  Pagination,\n  PaginationContent,\n  PaginationEllipsis,\n  PaginationItem,\n  PaginationLink,\n  PaginationNext,\n  PaginationPrevious,\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/popover.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport * as React from \"react\";\n\nconst Popover = PopoverPrimitive.Root;\n\nconst PopoverTrigger = PopoverPrimitive.Trigger;\n\nconst PopoverContent = React.forwardRef<\n  React.ElementRef<typeof PopoverPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n  <PopoverPrimitive.Portal>\n    <PopoverPrimitive.Content\n      ref={ref}\n      align={align}\n      sideOffset={sideOffset}\n      className={cn(\n        \"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n        className\n      )}\n      {...props}\n    />\n  </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverTrigger, PopoverContent };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/progress.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as ProgressPrimitive from \"@radix-ui/react-progress\";\nimport * as React from \"react\";\n\nconst Progress = React.forwardRef<\n  React.ElementRef<typeof ProgressPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>\n>(({ className, value, ...props }, ref) => (\n  <ProgressPrimitive.Root\n    ref={ref}\n    className={cn(\"relative h-4 w-full overflow-hidden rounded-full bg-secondary\", className)}\n    {...props}>\n    <ProgressPrimitive.Indicator\n      className=\"h-full w-full flex-1 bg-primary transition-all\"\n      style={{ transform: `translateX(-${100 - (value ?? 0)}%)` }}\n    />\n  </ProgressPrimitive.Root>\n));\nProgress.displayName = ProgressPrimitive.Root.displayName;\n\nexport { Progress };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/select.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { Check, ChevronDown, ChevronUp } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst Select = SelectPrimitive.Root;\n\nconst SelectGroup = SelectPrimitive.Group;\n\nconst SelectValue = SelectPrimitive.Value;\n\nconst SelectTrigger = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Trigger>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n  <SelectPrimitive.Trigger\n    ref={ref}\n    className={cn(\n      \"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1\",\n      className\n    )}\n    {...props}>\n    {children}\n    <SelectPrimitive.Icon asChild>\n      <ChevronDown className=\"h-4 w-4 opacity-50\" />\n    </SelectPrimitive.Icon>\n  </SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nconst SelectScrollUpButton = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.ScrollUpButton\n    ref={ref}\n    className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n    {...props}>\n    <ChevronUp className=\"h-4 w-4\" />\n  </SelectPrimitive.ScrollUpButton>\n));\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nconst SelectScrollDownButton = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.ScrollDownButton\n    ref={ref}\n    className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n    {...props}>\n    <ChevronDown className=\"h-4 w-4\" />\n  </SelectPrimitive.ScrollDownButton>\n));\nSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;\n\nconst SelectContent = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = \"popper\", ...props }, ref) => (\n  <SelectPrimitive.Portal>\n    <SelectPrimitive.Content\n      ref={ref}\n      className={cn(\n        \"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n        position === \"popper\" &&\n          \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n        className\n      )}\n      position={position}\n      {...props}>\n      <SelectScrollUpButton />\n      <SelectPrimitive.Viewport\n        className={cn(\n          \"p-1\",\n          position === \"popper\" &&\n            \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\"\n        )}>\n        {children}\n      </SelectPrimitive.Viewport>\n      <SelectScrollDownButton />\n    </SelectPrimitive.Content>\n  </SelectPrimitive.Portal>\n));\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nconst SelectLabel = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Label>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.Label\n    ref={ref}\n    className={cn(\"py-1.5 pl-8 pr-2 text-sm font-semibold\", className)}\n    {...props}\n  />\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nconst SelectItem = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n  <SelectPrimitive.Item\n    ref={ref}\n    className={cn(\n      \"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n      className\n    )}\n    {...props}>\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <SelectPrimitive.ItemIndicator>\n        <Check className=\"h-4 w-4\" />\n      </SelectPrimitive.ItemIndicator>\n    </span>\n\n    <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n  </SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nconst SelectSeparator = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.Separator ref={ref} className={cn(\"-mx-1 my-1 h-px bg-muted\", className)} {...props} />\n));\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n\nexport {\n  Select,\n  SelectGroup,\n  SelectValue,\n  SelectTrigger,\n  SelectContent,\n  SelectLabel,\n  SelectItem,\n  SelectSeparator,\n  SelectScrollUpButton,\n  SelectScrollDownButton,\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/separator.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\";\nimport * as React from \"react\";\n\nconst Separator = React.forwardRef<\n  React.ElementRef<typeof SeparatorPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>\n>(({ className, orientation = \"horizontal\", decorative = true, ...props }, ref) => (\n  <SeparatorPrimitive.Root\n    ref={ref}\n    decorative={decorative}\n    orientation={orientation}\n    className={cn(\n      \"shrink-0 bg-border\",\n      orientation === \"horizontal\" ? \"h-[1px] w-full\" : \"h-full w-[1px]\",\n      className\n    )}\n    {...props}\n  />\n));\nSeparator.displayName = SeparatorPrimitive.Root.displayName;\n\nexport { Separator };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/sheet.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst Sheet = SheetPrimitive.Root;\n\nconst SheetTrigger = SheetPrimitive.Trigger;\n\nconst SheetClose = SheetPrimitive.Close;\n\nconst SheetPortal = SheetPrimitive.Portal;\n\nconst SheetOverlay = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Overlay\n    className={cn(\n      \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n      className\n    )}\n    {...props}\n    ref={ref}\n  />\n));\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName;\n\nconst sheetVariants = cva(\n  \"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n  {\n    variants: {\n      side: {\n        top: \"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n        bottom:\n          \"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n        left: \"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm\",\n        right:\n          \"inset-y-0 right-0 h-full w-3/4  border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm\",\n      },\n    },\n    defaultVariants: {\n      side: \"right\",\n    },\n  }\n);\n\ninterface SheetContentProps\n  extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,\n    VariantProps<typeof sheetVariants> {}\n\nconst SheetContent = React.forwardRef<React.ElementRef<typeof SheetPrimitive.Content>, SheetContentProps>(\n  ({ side = \"right\", className, children, ...props }, ref) => (\n    <SheetPortal>\n      <SheetOverlay />\n      <SheetPrimitive.Content ref={ref} className={cn(sheetVariants({ side }), className)} {...props}>\n        {children}\n        <SheetPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\">\n          <X className=\"h-4 w-4\" />\n          <span className=\"sr-only\">Close</span>\n        </SheetPrimitive.Close>\n      </SheetPrimitive.Content>\n    </SheetPortal>\n  )\n);\nSheetContent.displayName = SheetPrimitive.Content.displayName;\n\nconst SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex flex-col space-y-2 text-center sm:text-left\", className)} {...props} />\n);\nSheetHeader.displayName = \"SheetHeader\";\n\nconst SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\", className)}\n    {...props}\n  />\n);\nSheetFooter.displayName = \"SheetFooter\";\n\nconst SheetTitle = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Title\n    ref={ref}\n    className={cn(\"text-lg font-semibold text-foreground\", className)}\n    {...props}\n  />\n));\nSheetTitle.displayName = SheetPrimitive.Title.displayName;\n\nconst SheetDescription = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Description\n    ref={ref}\n    className={cn(\"text-sm text-muted-foreground\", className)}\n    {...props}\n  />\n));\nSheetDescription.displayName = SheetPrimitive.Description.displayName;\n\nexport {\n  Sheet,\n  SheetPortal,\n  SheetOverlay,\n  SheetTrigger,\n  SheetClose,\n  SheetContent,\n  SheetHeader,\n  SheetFooter,\n  SheetTitle,\n  SheetDescription,\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/skeleton.tsx",
    "content": "import { cn } from \"@/lib/utils\";\n\nfunction Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return <div className={cn(\"animate-pulse rounded-md bg-muted\", className)} {...props} />;\n}\n\nexport { Skeleton };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/stepper.tsx",
    "content": "\"use client\";\n\n/* eslint-disable @typescript-eslint/no-empty-function */\nimport { Button } from \"./button\";\nimport { Collapsible, CollapsibleContent } from \"./collapsible\";\nimport { cn } from \"@/lib/utils\";\nimport { cva } from \"class-variance-authority\";\nimport { CheckIcon, Loader2, LucideIcon, X } from \"lucide-react\";\nimport * as React from \"react\";\n\n// <---------- CONTEXT ---------->\n\ninterface StepperContextValue extends StepperProps {\n  clickable?: boolean;\n  isError?: boolean;\n  isLoading?: boolean;\n  isVertical?: boolean;\n  stepCount?: number;\n  expandVerticalSteps?: boolean;\n  activeStep: number;\n  initialStep: number;\n}\n\nconst StepperContext = React.createContext<\n  StepperContextValue & {\n    nextStep: () => void;\n    prevStep: () => void;\n    resetSteps: () => void;\n    setStep: (step: number) => void;\n  }\n>({\n  steps: [],\n  activeStep: 0,\n  initialStep: 0,\n  nextStep: () => {},\n  prevStep: () => {},\n  resetSteps: () => {},\n  setStep: () => {},\n});\n\ntype StepperContextProviderProps = {\n  value: Omit<StepperContextValue, \"activeStep\">;\n  children: React.ReactNode;\n};\n\nconst StepperProvider = ({ value, children }: StepperContextProviderProps) => {\n  const isError = value.state === \"error\";\n  const isLoading = value.state === \"loading\";\n\n  const [activeStep, setActiveStep] = React.useState(value.initialStep);\n\n  const nextStep = () => {\n    setActiveStep((prev) => prev + 1);\n  };\n\n  const prevStep = () => {\n    setActiveStep((prev) => prev - 1);\n  };\n\n  const resetSteps = () => {\n    setActiveStep(value.initialStep);\n  };\n\n  const setStep = (step: number) => {\n    setActiveStep(step);\n  };\n\n  return (\n    <StepperContext.Provider\n      value={{\n        ...value,\n        isError,\n        isLoading,\n        activeStep,\n        nextStep,\n        prevStep,\n        resetSteps,\n        setStep,\n      }}>\n      {children}\n    </StepperContext.Provider>\n  );\n};\n\n// <---------- HOOKS ---------->\n\nfunction usePrevious<T>(value: T): T | undefined {\n  const ref = React.useRef<T>();\n\n  React.useEffect(() => {\n    ref.current = value;\n  }, [value]);\n\n  return ref.current;\n}\n\nfunction useStepper() {\n  const context = React.useContext(StepperContext);\n\n  if (context === undefined) {\n    throw new Error(\"useStepper must be used within a StepperProvider\");\n  }\n\n  const { children, className, ...rest } = context;\n\n  const isLastStep = context.activeStep === context.steps.length - 1;\n  const hasCompletedAllSteps = context.activeStep === context.steps.length;\n\n  const previousActiveStep = usePrevious(context.activeStep);\n\n  const currentStep = context.steps[context.activeStep];\n  const isOptionalStep = !!currentStep?.optional;\n\n  const isDisabledStep = context.activeStep === 0;\n\n  return {\n    ...rest,\n    isLastStep,\n    hasCompletedAllSteps,\n    isOptionalStep,\n    isDisabledStep,\n    currentStep,\n    previousActiveStep,\n  };\n}\n\nfunction useMediaQuery(query: string) {\n  const [value, setValue] = React.useState(false);\n\n  React.useEffect(() => {\n    function onChange(event: MediaQueryListEvent) {\n      setValue(event.matches);\n    }\n\n    const result = matchMedia(query);\n    result.addEventListener(\"change\", onChange);\n    setValue(result.matches);\n\n    return () => result.removeEventListener(\"change\", onChange);\n  }, [query]);\n\n  return value;\n}\n\n// <---------- STEPS ---------->\n\ntype StepItem = {\n  id?: string;\n  label?: string;\n  description?: string;\n  icon?: IconType;\n  optional?: boolean;\n  onNextClick?: () => void;\n};\n\ninterface StepOptions {\n  orientation?: \"vertical\" | \"horizontal\";\n  state?: \"loading\" | \"error\";\n  responsive?: boolean;\n  checkIcon?: IconType;\n  errorIcon?: IconType;\n  onClickStep?: (step: number, setStep: (step: number) => void) => void;\n  mobileBreakpoint?: string;\n  variant?: \"circle\" | \"circle-alt\" | \"line\";\n  expandVerticalSteps?: boolean;\n  size?: \"sm\" | \"md\" | \"lg\";\n  styles?: {\n    /** Styles for the main container */\n    \"main-container\"?: string;\n    /** Styles for the horizontal step */\n    \"horizontal-step\"?: string;\n    /** Styles for the horizontal step container (button and labels) */\n    \"horizontal-step-container\"?: string;\n    /** Styles for the vertical step */\n    \"vertical-step\"?: string;\n    /** Styles for the vertical step container (button and labels) */\n    \"vertical-step-container\"?: string;\n    /** Styles for the vertical step content */\n    \"vertical-step-content\"?: string;\n    /** Styles for the step button container */\n    \"step-button-container\"?: string;\n    /** Styles for the label and description container */\n    \"step-label-container\"?: string;\n    /** Styles for the step label */\n    \"step-label\"?: string;\n    /** Styles for the step description */\n    \"step-description\"?: string;\n  };\n  variables?: {\n    \"--step-icon-size\"?: string;\n    \"--step-gap\"?: string;\n  };\n  scrollTracking?: boolean;\n}\ninterface StepperProps extends StepOptions {\n  children?: React.ReactNode;\n  className?: string;\n  initialStep: number;\n  steps: StepItem[];\n}\n\nconst VARIABLE_SIZES = {\n  sm: \"36px\",\n  md: \"40px\",\n  lg: \"44px\",\n};\n\nconst Stepper = React.forwardRef<HTMLDivElement, StepperProps>((props, ref: React.Ref<HTMLDivElement>) => {\n  const {\n    className,\n    children,\n    orientation: orientationProp,\n    state,\n    responsive,\n    checkIcon,\n    errorIcon,\n    onClickStep,\n    mobileBreakpoint,\n    expandVerticalSteps = false,\n    initialStep = 0,\n    size,\n    steps,\n    variant,\n    styles,\n    variables,\n    scrollTracking = false,\n    ...rest\n  } = props;\n\n  const childArr = React.Children.toArray(children);\n\n  const items = [] as React.ReactElement[];\n\n  const footer = childArr.map((child, _index) => {\n    if (!React.isValidElement(child)) {\n      throw new Error(\"Stepper children must be valid React elements.\");\n    }\n    if (child.type === Step) {\n      items.push(child);\n      return null;\n    }\n\n    return child;\n  });\n\n  const stepCount = items.length;\n\n  const isMobile = useMediaQuery(`(max-width: ${mobileBreakpoint || \"768px\"})`);\n\n  const clickable = !!onClickStep;\n\n  const orientation = isMobile && responsive ? \"vertical\" : orientationProp;\n\n  const isVertical = orientation === \"vertical\";\n\n  return (\n    <StepperProvider\n      value={{\n        initialStep,\n        orientation,\n        state,\n        size,\n        responsive,\n        checkIcon,\n        errorIcon,\n        onClickStep,\n        clickable,\n        stepCount,\n        isVertical,\n        variant: variant || \"circle\",\n        expandVerticalSteps,\n        steps,\n        scrollTracking,\n        styles,\n      }}>\n      <div\n        ref={ref}\n        className={cn(\n          \"stepper__main-container\",\n          \"flex w-full flex-wrap\",\n          stepCount === 1 ? \"justify-end\" : \"justify-between\",\n          orientation === \"vertical\" ? \"flex-col\" : \"flex-row\",\n          variant === \"line\" && orientation === \"horizontal\" && \"gap-4\",\n          className,\n          styles?.[\"main-container\"]\n        )}\n        style={\n          {\n            \"--step-icon-size\": variables?.[\"--step-icon-size\"] || `${VARIABLE_SIZES[size || \"md\"]}`,\n            \"--step-gap\": variables?.[\"--step-gap\"] || \"8px\",\n          } as React.CSSProperties\n        }\n        {...rest}>\n        <VerticalContent>{items}</VerticalContent>\n      </div>\n      {orientation === \"horizontal\" && <HorizontalContent>{items}</HorizontalContent>}\n      {footer}\n    </StepperProvider>\n  );\n});\n\nStepper.defaultProps = {\n  size: \"md\",\n  orientation: \"horizontal\",\n  responsive: true,\n};\n\nconst VerticalContent = ({ children }: { children: React.ReactNode }) => {\n  const { activeStep } = useStepper();\n\n  const childArr = React.Children.toArray(children);\n  const stepCount = childArr.length;\n\n  return (\n    <>\n      {React.Children.map(children, (child, i) => {\n        const isCompletedStep =\n          (React.isValidElement(child) && (child.props as any).isCompletedStep) ?? i < activeStep;\n        const isLastStep = i === stepCount - 1;\n        const isCurrentStep = i === activeStep;\n\n        const stepProps = {\n          index: i,\n          isCompletedStep,\n          isCurrentStep,\n          isLastStep,\n        };\n\n        if (React.isValidElement(child)) {\n          return React.cloneElement(child, stepProps);\n        }\n        return null;\n      })}\n    </>\n  );\n};\n\nconst HorizontalContent = ({ children }: { children: React.ReactNode }) => {\n  const { activeStep } = useStepper();\n  const childArr = React.Children.toArray(children);\n\n  if (activeStep > childArr.length) {\n    return null;\n  }\n\n  return (\n    <>\n      {React.Children.map(childArr[activeStep], (node) => {\n        if (!React.isValidElement(node)) {\n          return null;\n        }\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n        return React.Children.map(node.props.children, (childNode) => childNode);\n      })}\n    </>\n  );\n};\n\n// <---------- STEP ---------->\n\ninterface StepProps extends React.HTMLAttributes<HTMLLIElement> {\n  label?: string | React.ReactNode;\n  description?: string;\n  icon?: IconType;\n  state?: \"loading\" | \"error\";\n  checkIcon?: IconType;\n  errorIcon?: IconType;\n  isCompletedStep?: boolean;\n  isKeepError?: boolean;\n  onClickStep?: (step: number, setStep: (step: number) => void) => void;\n}\n\ninterface StepSharedProps extends StepProps {\n  isLastStep?: boolean;\n  isCurrentStep?: boolean;\n  index?: number;\n  hasVisited: boolean | undefined;\n  isError?: boolean;\n  isLoading?: boolean;\n}\n\n// Props which shouldn't be passed to to the Step component from the user\ninterface StepInternalConfig {\n  index: number;\n  isCompletedStep?: boolean;\n  isCurrentStep?: boolean;\n  isLastStep?: boolean;\n}\n\ninterface FullStepProps extends StepProps, StepInternalConfig {}\n\nconst Step = React.forwardRef<HTMLLIElement, StepProps>((props, ref: React.Ref<any>) => {\n  const {\n    children,\n    description,\n    icon,\n    state,\n    checkIcon,\n    errorIcon,\n    index,\n    isCompletedStep,\n    isCurrentStep,\n    isLastStep,\n    isKeepError,\n    label,\n    onClickStep,\n  } = props as FullStepProps;\n\n  const { isVertical, isError, isLoading, clickable } = useStepper();\n\n  const hasVisited = isCurrentStep || isCompletedStep;\n\n  const sharedProps = {\n    isLastStep,\n    isCompletedStep,\n    isCurrentStep,\n    index,\n    isError,\n    isLoading,\n    clickable,\n    label,\n    description,\n    hasVisited,\n    icon,\n    isKeepError,\n    checkIcon,\n    state,\n    errorIcon,\n    onClickStep,\n  };\n\n  const renderStep = () => {\n    switch (isVertical) {\n      case true:\n        return (\n          <VerticalStep ref={ref} {...sharedProps}>\n            {children}\n          </VerticalStep>\n        );\n      default:\n        return <HorizontalStep ref={ref} {...sharedProps} />;\n    }\n  };\n\n  return renderStep();\n});\n\nStep.displayName = \"Step\";\n\n// <---------- VERTICAL STEP ---------->\n\ntype VerticalStepProps = StepSharedProps & {\n  children?: React.ReactNode;\n};\n\nconst verticalStepVariants = cva(\n  [\n    \"flex flex-col relative transition-all duration-200\",\n    \"data-[completed=true]:[&:not(:last-child)]:after:bg-primary\",\n    \"data-[invalid=true]:[&:not(:last-child)]:after:bg-destructive\",\n  ],\n  {\n    variants: {\n      variant: {\n        circle: cn(\n          \"[&:not(:last-child)]:pb-[var(--step-gap)] [&:not(:last-child)]:gap-[var(--step-gap)]\",\n          \"[&:not(:last-child)]:after:content-[''] [&:not(:last-child)]:after:w-[2px] [&:not(:last-child)]:after:bg-border\",\n          \"[&:not(:last-child)]:after:inset-x-[calc(var(--step-icon-size)/2)]\",\n          \"[&:not(:last-child)]:after:absolute\",\n          \"[&:not(:last-child)]:after:top-[calc(var(--step-icon-size)+var(--step-gap))]\",\n          \"[&:not(:last-child)]:after:bottom-[var(--step-gap)]\",\n          \"[&:not(:last-child)]:after:transition-all [&:not(:last-child)]:after:duration-200\"\n        ),\n        line: \"flex-1 border-t-0 mb-4\",\n      },\n    },\n  }\n);\n\nconst VerticalStep = React.forwardRef<HTMLDivElement, VerticalStepProps>((props, ref) => {\n  const {\n    children,\n    index,\n    isCompletedStep,\n    isCurrentStep,\n    label,\n    description,\n    icon,\n    hasVisited,\n    state,\n    checkIcon: checkIconProp,\n    errorIcon: errorIconProp,\n    onClickStep,\n  } = props;\n\n  const {\n    checkIcon: checkIconContext,\n    errorIcon: errorIconContext,\n    isError,\n    isLoading,\n    variant,\n    onClickStep: onClickStepGeneral,\n    clickable,\n    expandVerticalSteps,\n    styles,\n    scrollTracking,\n    orientation,\n    steps,\n    setStep,\n    isLastStep: isLastStepCurrentStep,\n    previousActiveStep,\n  } = useStepper();\n\n  const opacity = hasVisited ? 1 : 0.8;\n  const localIsLoading = isLoading || state === \"loading\";\n  const localIsError = isError || state === \"error\";\n\n  const isLastStep = index === steps.length - 1;\n\n  const active = variant === \"line\" ? isCompletedStep || isCurrentStep : isCompletedStep;\n  const checkIcon = checkIconProp || checkIconContext;\n  const errorIcon = errorIconProp || errorIconContext;\n\n  const renderChildren = () => {\n    if (!expandVerticalSteps) {\n      return (\n        <Collapsible open={isCurrentStep}>\n          <CollapsibleContent\n            ref={(node) => {\n              if (\n                // If the step is the first step and the previous step\n                // was the last step or if the step is not the first step\n                // This prevents initial scrolling when the stepper\n                // is located anywhere other than the top of the view.\n                scrollTracking &&\n                ((index === 0 && previousActiveStep && previousActiveStep === steps.length) ||\n                  (index && index > 0))\n              ) {\n                node?.scrollIntoView({\n                  behavior: \"smooth\",\n                  block: \"center\",\n                });\n              }\n            }}\n            className=\"data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up overflow-hidden\">\n            {children}\n          </CollapsibleContent>\n        </Collapsible>\n      );\n    }\n    return children;\n  };\n\n  return (\n    <div\n      ref={ref}\n      className={cn(\n        \"stepper__vertical-step\",\n        verticalStepVariants({\n          variant: variant?.includes(\"circle\") ? \"circle\" : \"line\",\n        }),\n        isLastStepCurrentStep && \"gap-[var(--step-gap)]\",\n        styles?.[\"vertical-step\"]\n      )}\n      data-optional={steps[index || 0]?.optional}\n      data-completed={isCompletedStep}\n      data-active={active}\n      data-clickable={clickable || !!onClickStep}\n      data-invalid={localIsError}\n      onClick={() =>\n        !!onClickStep ? onClickStep(index || 0, setStep) : onClickStepGeneral?.(index || 0, setStep)\n      }>\n      <div\n        data-vertical={true}\n        data-active={active}\n        className={cn(\n          \"stepper__vertical-step-container\",\n          \"flex items-center\",\n          variant === \"line\" && \"border-s-[3px] py-2 ps-3 data-[active=true]:border-primary\",\n          styles?.[\"vertical-step-container\"]\n        )}>\n        <StepButtonContainer {...{ isLoading: localIsLoading, isError: localIsError, ...props }}>\n          <StepIcon\n            {...{\n              index,\n              isError: localIsError,\n              isLoading: localIsLoading,\n              isCurrentStep,\n              isCompletedStep,\n            }}\n            icon={icon}\n            checkIcon={checkIcon}\n            errorIcon={errorIcon}\n          />\n        </StepButtonContainer>\n        <StepLabel label={label} description={description} {...{ isCurrentStep, opacity }} />\n      </div>\n      <div\n        className={cn(\n          \"stepper__vertical-step-content\",\n          !isLastStep && \"min-h-4\",\n          variant !== \"line\" && \"ps-[--step-icon-size]\",\n          variant === \"line\" && orientation === \"vertical\" && \"min-h-0\",\n          styles?.[\"vertical-step-content\"]\n        )}>\n        {renderChildren()}\n      </div>\n    </div>\n  );\n});\n\nVerticalStep.displayName = \"VerticalStep\";\n\n// <---------- HORIZONTAL STEP ---------->\n\nconst HorizontalStep = React.forwardRef<HTMLDivElement, StepSharedProps>((props, ref) => {\n  const {\n    isError,\n    isLoading,\n    onClickStep,\n    variant,\n    clickable,\n    checkIcon: checkIconContext,\n    errorIcon: errorIconContext,\n    styles,\n    steps,\n    setStep,\n  } = useStepper();\n\n  const {\n    index,\n    isCompletedStep,\n    isCurrentStep,\n    hasVisited,\n    icon,\n    label,\n    description,\n    isKeepError,\n    state,\n    checkIcon: checkIconProp,\n    errorIcon: errorIconProp,\n  } = props;\n\n  const localIsLoading = isLoading || state === \"loading\";\n  const localIsError = isError || state === \"error\";\n\n  const opacity = hasVisited ? 1 : 0.8;\n\n  const active = variant === \"line\" ? isCompletedStep || isCurrentStep : isCompletedStep;\n\n  const checkIcon = checkIconProp || checkIconContext;\n  const errorIcon = errorIconProp || errorIconContext;\n\n  return (\n    <div\n      aria-disabled={!hasVisited}\n      className={cn(\n        \"stepper__horizontal-step\",\n        \"relative flex items-center transition-all duration-200\",\n        \"[&:not(:last-child)]:flex-1\",\n        \"[&:not(:last-child)]:after:transition-all [&:not(:last-child)]:after:duration-200\",\n        \"[&:not(:last-child)]:after:h-[2px] [&:not(:last-child)]:after:bg-border [&:not(:last-child)]:after:content-['']\",\n        \"data-[completed=true]:[&:not(:last-child)]:after:bg-primary\",\n        \"data-[invalid=true]:[&:not(:last-child)]:after:bg-destructive\",\n        variant === \"circle-alt\" &&\n          \"flex-1 flex-col justify-start [&:not(:last-child)]:after:relative [&:not(:last-child)]:after:end-[50%] [&:not(:last-child)]:after:start-[50%] [&:not(:last-child)]:after:top-[calc(var(--step-icon-size)/2)] [&:not(:last-child)]:after:order-[-1] [&:not(:last-child)]:after:w-[calc((100%-var(--step-icon-size))-(var(--step-gap)))]\",\n        variant === \"circle\" &&\n          \"[&:not(:last-child)]:after:me-[var(--step-gap)] [&:not(:last-child)]:after:ms-[var(--step-gap)] [&:not(:last-child)]:after:flex-1\",\n        variant === \"line\" && \"flex-1 flex-col border-t-[3px] data-[active=true]:border-primary\",\n        styles?.[\"horizontal-step\"]\n      )}\n      data-optional={steps[index || 0]?.optional}\n      data-completed={isCompletedStep}\n      data-active={active}\n      data-invalid={localIsError}\n      data-clickable={clickable}\n      onClick={() => onClickStep?.(index || 0, setStep)}\n      ref={ref}>\n      <div\n        className={cn(\n          \"stepper__horizontal-step-container\",\n          \"flex items-center\",\n          variant === \"circle-alt\" && \"flex-col justify-center gap-1\",\n          variant === \"line\" && \"w-full\",\n          styles?.[\"horizontal-step-container\"]\n        )}>\n        <StepButtonContainer {...{ ...props, isError: localIsError, isLoading: localIsLoading }}>\n          <StepIcon\n            {...{\n              index,\n              isCompletedStep,\n              isCurrentStep,\n              isError: localIsError,\n              isKeepError,\n              isLoading: localIsLoading,\n            }}\n            icon={icon}\n            checkIcon={checkIcon}\n            errorIcon={errorIcon}\n          />\n        </StepButtonContainer>\n        <StepLabel label={label} description={description} {...{ isCurrentStep, opacity }} />\n      </div>\n    </div>\n  );\n});\n\nHorizontalStep.displayName = \"HorizontalStep\";\n\n// <---------- STEP BUTTON CONTAINER ---------->\n\ntype StepButtonContainerProps = StepSharedProps & {\n  children?: React.ReactNode;\n};\n\nconst StepButtonContainer = ({\n  isCurrentStep,\n  isCompletedStep,\n  children,\n  isError,\n  isLoading: isLoadingProp,\n  onClickStep,\n}: StepButtonContainerProps) => {\n  const { clickable, isLoading: isLoadingContext, variant, styles } = useStepper();\n\n  const currentStepClickable = clickable || !!onClickStep;\n\n  const isLoading = isLoadingProp || isLoadingContext;\n\n  if (variant === \"line\") {\n    return null;\n  }\n\n  return (\n    <Button\n      variant=\"ghost\"\n      tabIndex={currentStepClickable ? 0 : -1}\n      className={cn(\n        \"stepper__step-button-container\",\n        \"pointer-events-none rounded-full p-0\",\n        \"h-[var(--step-icon-size)] w-[var(--step-icon-size)]\",\n        \"flex items-center justify-center rounded-full border-2\",\n        \"data-[clickable=true]:pointer-events-auto\",\n        \"data-[active=true]:border-primary data-[active=true]:bg-primary data-[active=true]:text-primary-foreground\",\n        \"data-[current=true]:border-primary data-[current=true]:bg-secondary\",\n        \"data-[invalid=true]:border-destructive data-[invalid=true]:bg-destructive data-[invalid=true]:text-destructive-foreground\",\n        styles?.[\"step-button-container\"]\n      )}\n      aria-current={isCurrentStep ? \"step\" : undefined}\n      data-current={isCurrentStep}\n      data-invalid={isError && (isCurrentStep || isCompletedStep)}\n      data-active={isCompletedStep}\n      data-clickable={currentStepClickable}\n      data-loading={isLoading && (isCurrentStep || isCompletedStep)}>\n      {children}\n    </Button>\n  );\n};\n\n// <---------- STEP ICON ---------->\n\ntype IconType = LucideIcon | React.ComponentType<any> | undefined;\n\nconst iconVariants = cva(\"\", {\n  variants: {\n    size: {\n      sm: \"size-4\",\n      md: \"size-4\",\n      lg: \"size-5\",\n    },\n  },\n  defaultVariants: {\n    size: \"md\",\n  },\n});\n\ninterface StepIconProps {\n  isCompletedStep?: boolean;\n  isCurrentStep?: boolean;\n  isError?: boolean;\n  isLoading?: boolean;\n  isKeepError?: boolean;\n  icon?: IconType;\n  index?: number;\n  checkIcon?: IconType;\n  errorIcon?: IconType;\n}\n\nconst StepIcon = React.forwardRef<HTMLDivElement, StepIconProps>((props, ref) => {\n  const { size } = useStepper();\n\n  const {\n    isCompletedStep,\n    isCurrentStep,\n    isError,\n    isLoading,\n    isKeepError,\n    icon: CustomIcon,\n    index,\n    checkIcon: CustomCheckIcon,\n    errorIcon: CustomErrorIcon,\n  } = props;\n\n  const Icon = React.useMemo(() => (CustomIcon ? CustomIcon : null), [CustomIcon]);\n\n  const ErrorIcon = React.useMemo(() => (CustomErrorIcon ? CustomErrorIcon : null), [CustomErrorIcon]);\n\n  const Check = React.useMemo(() => (CustomCheckIcon ? CustomCheckIcon : CheckIcon), [CustomCheckIcon]);\n\n  return React.useMemo(() => {\n    if (isCompletedStep) {\n      if (isError && isKeepError) {\n        return (\n          <div key=\"icon\">\n            <X className={cn(iconVariants({ size }))} />\n          </div>\n        );\n      }\n      return (\n        <div key=\"check-icon\">\n          <Check className={cn(iconVariants({ size }))} />\n        </div>\n      );\n    }\n    if (isCurrentStep) {\n      if (isError && ErrorIcon) {\n        return (\n          <div key=\"error-icon\">\n            <ErrorIcon className={cn(iconVariants({ size }))} />\n          </div>\n        );\n      }\n      if (isError) {\n        return (\n          <div key=\"icon\">\n            <X className={cn(iconVariants({ size }))} />\n          </div>\n        );\n      }\n      if (isLoading) {\n        return <Loader2 className={cn(iconVariants({ size }), \"animate-spin\")} />;\n      }\n    }\n    if (Icon) {\n      return (\n        <div key=\"step-icon\">\n          <Icon className={cn(iconVariants({ size }))} />\n        </div>\n      );\n    }\n    return (\n      <span ref={ref} key=\"label\" className={cn(\"text-md text-center font-medium\")}>\n        {(index || 0) + 1}\n      </span>\n    );\n  }, [\n    isCompletedStep,\n    isCurrentStep,\n    isError,\n    isLoading,\n    Icon,\n    index,\n    Check,\n    ErrorIcon,\n    isKeepError,\n    ref,\n    size,\n  ]);\n});\n\nStepIcon.displayName = \"StepIcon\";\n\n// <---------- STEP LABEL ---------->\n\ninterface StepLabelProps {\n  isCurrentStep?: boolean;\n  opacity: number;\n  label?: string | React.ReactNode;\n  description?: string | null;\n}\n\nconst labelVariants = cva(\"\", {\n  variants: {\n    size: {\n      sm: \"text-sm\",\n      md: \"text-sm\",\n      lg: \"text-base\",\n    },\n  },\n  defaultVariants: {\n    size: \"md\",\n  },\n});\n\nconst descriptionVariants = cva(\"\", {\n  variants: {\n    size: {\n      sm: \"text-xs\",\n      md: \"text-xs\",\n      lg: \"text-sm\",\n    },\n  },\n  defaultVariants: {\n    size: \"md\",\n  },\n});\n\nconst StepLabel = ({ isCurrentStep, opacity, label, description }: StepLabelProps) => {\n  const { variant, styles, size, orientation } = useStepper();\n  const shouldRender = !!label || !!description;\n\n  return shouldRender ? (\n    <div\n      aria-current={isCurrentStep ? \"step\" : undefined}\n      className={cn(\n        \"stepper__step-label-container\",\n        \"flex flex-col\",\n        variant !== \"line\" ? \"ms-2\" : orientation === \"horizontal\" && \"my-2\",\n        variant === \"circle-alt\" && \"text-center\",\n        variant === \"circle-alt\" && orientation === \"horizontal\" && \"ms-0\",\n        variant === \"circle-alt\" && orientation === \"vertical\" && \"text-start\",\n        styles?.[\"step-label-container\"]\n      )}\n      style={{\n        opacity,\n      }}>\n      {!!label && (\n        <span className={cn(\"stepper__step-label\", labelVariants({ size }), styles?.[\"step-label\"])}>\n          {label}\n        </span>\n      )}\n      {!!description && (\n        <span\n          className={cn(\n            \"stepper__step-description\",\n            \"text-muted-foreground\",\n            descriptionVariants({ size }),\n            styles?.[\"step-description\"]\n          )}>\n          {description}\n        </span>\n      )}\n    </div>\n  ) : null;\n};\n\nexport { Stepper, Step, useStepper };\nexport type { StepProps, StepperProps, StepItem };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/table.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\n\nconst Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(\n  ({ className, ...props }, ref) => (\n    <div className=\"relative w-full overflow-auto\">\n      <table ref={ref} className={cn(\"w-full caption-bottom text-sm\", className)} {...props} />\n    </div>\n  )\n);\nTable.displayName = \"Table\";\n\nconst TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n  ({ className, ...props }, ref) => (\n    <thead ref={ref} className={cn(\"[&_tr]:border-b\", className)} {...props} />\n  )\n);\nTableHeader.displayName = \"TableHeader\";\n\nconst TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n  ({ className, ...props }, ref) => (\n    <tbody ref={ref} className={cn(\"[&_tr:last-child]:border-0\", className)} {...props} />\n  )\n);\nTableBody.displayName = \"TableBody\";\n\nconst TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n  ({ className, ...props }, ref) => (\n    <tfoot\n      ref={ref}\n      className={cn(\"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0\", className)}\n      {...props}\n    />\n  )\n);\nTableFooter.displayName = \"TableFooter\";\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(\n  ({ className, ...props }, ref) => (\n    <tr ref={ref} className={cn(\"border-b transition-colors hover:bg-muted/50\", className)} {...props} />\n  )\n);\nTableRow.displayName = \"TableRow\";\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(\n  ({ className, ...props }, ref) => (\n    <th\n      ref={ref}\n      className={cn(\n        \"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n);\nTableHead.displayName = \"TableHead\";\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(\n  ({ className, ...props }, ref) => (\n    <td ref={ref} className={cn(\"p-4 align-middle [&:has([role=checkbox])]:pr-0\", className)} {...props} />\n  )\n);\nTableCell.displayName = \"TableCell\";\n\nconst TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(\n  ({ className, ...props }, ref) => (\n    <caption ref={ref} className={cn(\"mt-4 text-sm text-muted-foreground\", className)} {...props} />\n  )\n);\nTableCaption.displayName = \"TableCaption\";\n\nexport { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/tabs.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\";\nimport * as React from \"react\";\n\nconst Tabs = TabsPrimitive.Root;\n\nconst TabsList = React.forwardRef<\n  React.ElementRef<typeof TabsPrimitive.List>,\n  React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>\n>(({ className, ...props }, ref) => (\n  <TabsPrimitive.List\n    ref={ref}\n    className={cn(\n      \"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground\",\n      className\n    )}\n    {...props}\n  />\n));\nTabsList.displayName = TabsPrimitive.List.displayName;\n\nconst TabsTrigger = React.forwardRef<\n  React.ElementRef<typeof TabsPrimitive.Trigger>,\n  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>\n>(({ className, ...props }, ref) => (\n  <TabsPrimitive.Trigger\n    ref={ref}\n    className={cn(\n      \"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm\",\n      className\n    )}\n    {...props}\n  />\n));\nTabsTrigger.displayName = TabsPrimitive.Trigger.displayName;\n\nconst TabsContent = React.forwardRef<\n  React.ElementRef<typeof TabsPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n>(({ className, ...props }, ref) => (\n  <TabsPrimitive.Content\n    ref={ref}\n    className={cn(\n      \"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n      className\n    )}\n    {...props}\n  />\n));\nTabsContent.displayName = TabsPrimitive.Content.displayName;\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/textarea.tsx",
    "content": "import { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\n\nexport type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({ className, ...props }, ref) => {\n  return (\n    <textarea\n      className={cn(\n        \"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n        className\n      )}\n      ref={ref}\n      {...props}\n    />\n  );\n});\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/toast.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst ToastProvider = ToastPrimitives.Provider;\n\nconst ToastViewport = React.forwardRef<\n  React.ElementRef<typeof ToastPrimitives.Viewport>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>\n>(({ className, ...props }, ref) => (\n  <ToastPrimitives.Viewport\n    ref={ref}\n    className={cn(\n      \"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]\",\n      className\n    )}\n    {...props}\n  />\n));\nToastViewport.displayName = ToastPrimitives.Viewport.displayName;\n\nconst toastVariants = cva(\n  \"group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full\",\n  {\n    variants: {\n      variant: {\n        default: \"border bg-background text-foreground\",\n        destructive: \"destructive group border-destructive bg-destructive text-destructive-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n);\n\nconst Toast = React.forwardRef<\n  React.ElementRef<typeof ToastPrimitives.Root>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> & VariantProps<typeof toastVariants>\n>(({ className, variant, ...props }, ref) => {\n  return <ToastPrimitives.Root ref={ref} className={cn(toastVariants({ variant }), className)} {...props} />;\n});\nToast.displayName = ToastPrimitives.Root.displayName;\n\nconst ToastAction = React.forwardRef<\n  React.ElementRef<typeof ToastPrimitives.Action>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>\n>(({ className, ...props }, ref) => (\n  <ToastPrimitives.Action\n    ref={ref}\n    className={cn(\n      \"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive\",\n      className\n    )}\n    {...props}\n  />\n));\nToastAction.displayName = ToastPrimitives.Action.displayName;\n\nconst ToastClose = React.forwardRef<\n  React.ElementRef<typeof ToastPrimitives.Close>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>\n>(({ className, ...props }, ref) => (\n  <ToastPrimitives.Close\n    ref={ref}\n    className={cn(\n      \"absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600\",\n      className\n    )}\n    toast-close=\"\"\n    {...props}>\n    <X className=\"h-4 w-4\" />\n  </ToastPrimitives.Close>\n));\nToastClose.displayName = ToastPrimitives.Close.displayName;\n\nconst ToastTitle = React.forwardRef<\n  React.ElementRef<typeof ToastPrimitives.Title>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>\n>(({ className, ...props }, ref) => (\n  <ToastPrimitives.Title ref={ref} className={cn(\"text-sm font-semibold\", className)} {...props} />\n));\nToastTitle.displayName = ToastPrimitives.Title.displayName;\n\nconst ToastDescription = React.forwardRef<\n  React.ElementRef<typeof ToastPrimitives.Description>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>\n>(({ className, ...props }, ref) => (\n  <ToastPrimitives.Description ref={ref} className={cn(\"text-sm opacity-90\", className)} {...props} />\n));\nToastDescription.displayName = ToastPrimitives.Description.displayName;\n\ntype ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;\n\ntype ToastActionElement = React.ReactElement<typeof ToastAction>;\n\nexport {\n  type ToastProps,\n  type ToastActionElement,\n  ToastProvider,\n  ToastViewport,\n  Toast,\n  ToastTitle,\n  ToastDescription,\n  ToastClose,\n  ToastAction,\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/toaster.tsx",
    "content": "\"use client\";\n\nimport {\n  Toast,\n  ToastClose,\n  ToastDescription,\n  ToastProvider,\n  ToastTitle,\n  ToastViewport,\n} from \"@/components/ui/toast\";\nimport { useToast } from \"@/components/ui/use-toast\";\n\nexport function Toaster() {\n  const { toasts } = useToast();\n\n  return (\n    <ToastProvider>\n      {toasts.map(function ({ id, title, description, action, ...props }) {\n        return (\n          <Toast key={id} {...props}>\n            <div className=\"grid gap-1\">\n              {title && <ToastTitle>{title}</ToastTitle>}\n              {description && <ToastDescription>{description}</ToastDescription>}\n            </div>\n            {action}\n            <ToastClose />\n          </Toast>\n        );\n      })}\n      <ToastViewport />\n    </ToastProvider>\n  );\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/tooltip.tsx",
    "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport * as React from \"react\";\n\nconst TooltipProvider = TooltipPrimitive.Provider;\n\nconst Tooltip = TooltipPrimitive.Root;\n\nconst TooltipTrigger = TooltipPrimitive.Trigger;\n\nconst TooltipContent = React.forwardRef<\n  React.ElementRef<typeof TooltipPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n  <TooltipPrimitive.Content\n    ref={ref}\n    sideOffset={sideOffset}\n    className={cn(\n      \"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n      className\n    )}\n    {...props}\n  />\n));\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/components/ui/use-toast.ts",
    "content": "\"use client\"\n\n// Inspired by react-hot-toast library\nimport * as React from \"react\"\n\nimport type {\n  ToastActionElement,\n  ToastProps,\n} from \"@/components/ui/toast\"\n\nconst TOAST_LIMIT = 1\nconst TOAST_REMOVE_DELAY = 1000000\n\ntype ToasterToast = ToastProps & {\n  id: string\n  title?: React.ReactNode\n  description?: React.ReactNode\n  action?: ToastActionElement\n}\n\nconst actionTypes = {\n  ADD_TOAST: \"ADD_TOAST\",\n  UPDATE_TOAST: \"UPDATE_TOAST\",\n  DISMISS_TOAST: \"DISMISS_TOAST\",\n  REMOVE_TOAST: \"REMOVE_TOAST\",\n} as const\n\nlet count = 0\n\nfunction genId() {\n  count = (count + 1) % Number.MAX_SAFE_INTEGER\n  return count.toString()\n}\n\ntype ActionType = typeof actionTypes\n\ntype Action =\n  | {\n      type: ActionType[\"ADD_TOAST\"]\n      toast: ToasterToast\n    }\n  | {\n      type: ActionType[\"UPDATE_TOAST\"]\n      toast: Partial<ToasterToast>\n    }\n  | {\n      type: ActionType[\"DISMISS_TOAST\"]\n      toastId?: ToasterToast[\"id\"]\n    }\n  | {\n      type: ActionType[\"REMOVE_TOAST\"]\n      toastId?: ToasterToast[\"id\"]\n    }\n\ninterface State {\n  toasts: ToasterToast[]\n}\n\nconst toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()\n\nconst addToRemoveQueue = (toastId: string) => {\n  if (toastTimeouts.has(toastId)) {\n    return\n  }\n\n  const timeout = setTimeout(() => {\n    toastTimeouts.delete(toastId)\n    dispatch({\n      type: \"REMOVE_TOAST\",\n      toastId: toastId,\n    })\n  }, TOAST_REMOVE_DELAY)\n\n  toastTimeouts.set(toastId, timeout)\n}\n\nexport const reducer = (state: State, action: Action): State => {\n  switch (action.type) {\n    case \"ADD_TOAST\":\n      return {\n        ...state,\n        toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),\n      }\n\n    case \"UPDATE_TOAST\":\n      return {\n        ...state,\n        toasts: state.toasts.map((t) =>\n          t.id === action.toast.id ? { ...t, ...action.toast } : t\n        ),\n      }\n\n    case \"DISMISS_TOAST\": {\n      const { toastId } = action\n\n      // ! Side effects ! - This could be extracted into a dismissToast() action,\n      // but I'll keep it here for simplicity\n      if (toastId) {\n        addToRemoveQueue(toastId)\n      } else {\n        state.toasts.forEach((toast) => {\n          addToRemoveQueue(toast.id)\n        })\n      }\n\n      return {\n        ...state,\n        toasts: state.toasts.map((t) =>\n          t.id === toastId || toastId === undefined\n            ? {\n                ...t,\n                open: false,\n              }\n            : t\n        ),\n      }\n    }\n    case \"REMOVE_TOAST\":\n      if (action.toastId === undefined) {\n        return {\n          ...state,\n          toasts: [],\n        }\n      }\n      return {\n        ...state,\n        toasts: state.toasts.filter((t) => t.id !== action.toastId),\n      }\n  }\n}\n\nconst listeners: Array<(state: State) => void> = []\n\nlet memoryState: State = { toasts: [] }\n\nfunction dispatch(action: Action) {\n  memoryState = reducer(memoryState, action)\n  listeners.forEach((listener) => {\n    listener(memoryState)\n  })\n}\n\ntype Toast = Omit<ToasterToast, \"id\">\n\nfunction toast({ ...props }: Toast) {\n  const id = genId()\n\n  const update = (props: ToasterToast) =>\n    dispatch({\n      type: \"UPDATE_TOAST\",\n      toast: { ...props, id },\n    })\n  const dismiss = () => dispatch({ type: \"DISMISS_TOAST\", toastId: id })\n\n  dispatch({\n    type: \"ADD_TOAST\",\n    toast: {\n      ...props,\n      id,\n      open: true,\n      onOpenChange: (open) => {\n        if (!open) dismiss()\n      },\n    },\n  })\n\n  return {\n    id: id,\n    dismiss,\n    update,\n  }\n}\n\nfunction useToast() {\n  const [state, setState] = React.useState<State>(memoryState)\n\n  React.useEffect(() => {\n    listeners.push(setState)\n    return () => {\n      const index = listeners.indexOf(setState)\n      if (index > -1) {\n        listeners.splice(index, 1)\n      }\n    }\n  }, [state])\n\n  return {\n    ...state,\n    toast,\n    dismiss: (toastId?: string) => dispatch({ type: \"DISMISS_TOAST\", toastId }),\n  }\n}\n\nexport { useToast, toast }\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/env.js",
    "content": "import { createEnv } from \"@t3-oss/env-nextjs\";\nimport { vercel } from \"@t3-oss/env-nextjs/presets\";\nimport { z } from \"zod\";\n\nexport const env = createEnv({\n  /**\n   * Specify your server-side environment variables schema here. This way you can ensure the app\n   * isn't built with invalid env vars.\n   */\n  server: {\n    POSTGRES_PRISMA_URL: z.string(),\n    POSTGRES_URL_NON_POOLING: z.string(),\n    NODE_ENV: z.enum([\"development\", \"test\", \"production\"]).default(\"development\"),\n    AUTH_SECRET: process.env.NODE_ENV === \"production\" ? z.string() : z.string().optional(),\n    /**\n     * [@calcom] These are the server environment variables to make our atoms work:\n     * - CAL_SECRET: The secret key to authenticate our SDK requests. Follow this guide to get it 👇\n     * @link: https://cal.com/docs/platform/quick-start#2.-setting-up-an-oauth-client\n     */\n    CAL_SECRET: z.string(),\n    /** Supabase secret key to generate signed storage upload urls */\n    SUPABASE_SERVICE_ROLE_KEY: z.string(),\n  },\n\n  /**\n   * Specify your client-side environment variables schema here. This way you can ensure the app\n   * isn't built with invalid env vars. To expose them to the client, prefix them with\n   * `NEXT_PUBLIC_`.\n   */\n  client: {\n    NEXT_PUBLIC_APP_URL: z.string().default(\"http://localhost:3000\"),\n    /** [@calcom] These are the server environment variables to make our atoms work:\n     * - *NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID*: The OAuth client ID to authenticate our SDK requests. Follow this guide to get it 👇\n     * @link: https://cal.com/docs/platform/quick-start#2.-setting-up-an-oauth-client\n     * - *NEXT_PUBLIC_CAL_API_URL*: Use our sandbox 'https://api.cal.dev/api/v2' for development & for production use: 'https://api.cal.com/v2'\n     * @link: https://cal.com/docs/platform/quick-start#5.2-setup-environment-variables\n     * - *NEXT_PUBLIC_REFRESH_URL*:You have to expose this URL webhook for cal to update\n     * @link: https://cal.com/docs/platform/quick-start#4.-backend:-setting-up-refresh-token-endpoint\n     */\n    NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID: z.string(),\n    NEXT_PUBLIC_CAL_API_URL: z.string(),\n    NEXT_PUBLIC_REFRESH_URL: z.string(),\n    NEXT_PUBLIC_SUPABASE_URL: z.string(),\n    NEXT_PUBLIC_SUPABASE_ANON_KEY: z.string(),\n  },\n\n  /**\n   * You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g.\n   * middlewares) or client-side so we need to destruct manually.\n   */\n  runtimeEnv: {\n    POSTGRES_PRISMA_URL: process.env.POSTGRES_PRISMA_URL,\n    POSTGRES_URL_NON_POOLING: process.env.POSTGRES_URL_NON_POOLING,\n    NODE_ENV: process.env.NODE_ENV,\n    AUTH_SECRET: process.env.AUTH_SECRET,\n    NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,\n    /** [@calcom] Make sure to add the calcom variables to your runtime environment variables, so that you can use them */\n    CAL_SECRET: process.env.CAL_SECRET,\n    NEXT_PUBLIC_CAL_API_URL: process.env.NEXT_PUBLIC_CAL_API_URL,\n    NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID: process.env.NEXT_PUBLIC_CAL_OAUTH_CLIENT_ID,\n    NEXT_PUBLIC_REFRESH_URL: process.env.NEXT_PUBLIC_REFRESH_URL,\n    /** [@supabase] Add Supabase env vars */\n    NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL,\n    NEXT_PUBLIC_SUPABASE_ANON_KEY: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,\n    SUPABASE_SERVICE_ROLE_KEY: process.env.SUPABASE_SERVICE_ROLE_KEY,\n  },\n  /**\n   * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially\n   * useful for Docker builds.\n   */\n  skipValidation: !!process.env.SKIP_ENV_VALIDATION,\n  /**\n   * Makes it so that empty strings are treated as undefined. `SOME_VAR: z.string()` and\n   * `SOME_VAR=''` will throw an error.\n   */\n  emptyStringAsUndefined: true,\n  extends: [vercel()],\n});\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/lib/constants.ts",
    "content": "import { type Option } from \"@/app/_components/autocomplete\";\n\nexport const professions = [\n  { label: \"Hair dresser\", value: \"hair-dresser\" },\n  { label: \"Therapist\", value: \"therapist\" },\n  { label: \"Dermatologist\", value: \"dermatologist\" },\n] satisfies Array<Option>;\n\nexport const services = [\n  { name: \"Haircut\", isRemote: false, profession: \"hair-dresser\" },\n  { name: \"Hair coloring\", isRemote: false, profession: \"hair-dresser\" },\n  { name: \"Hair styling\", isRemote: false, profession: \"hair-dresser\" },\n  { name: \"Beard trimming\", isRemote: true, profession: \"hair-dresser\" },\n  { name: \"Therapy\", isRemote: true, profession: \"therapist\" },\n  { name: \"Skin consultation\", isRemote: false, profession: \"dermatologist\" },\n] satisfies Array<{ name: string; isRemote: boolean; profession: string }>;\n\nexport const defaultSort = {\n  title: \"Relevance\",\n  slug: null,\n  sortKey: \"RELEVANCE\",\n  reverse: false,\n};\n\nexport const sorting = [\n  defaultSort,\n  {\n    title: \"Availability\",\n    slug: \"available-desc\",\n    sortKey: \"MOST_AVAILABLE\",\n    reverse: false,\n  }, // asc\n];\n\nexport const IS_PRODUCTION = process.env.NODE_ENV === \"production\";\nexport const IS_SANDBOX = process.env.NEXT_PUBLIC_CAL_API_URL === \"https://api.cal.dev/v2\";\nexport const IS_CALCOM = process.env.VERCEL_URL === \"experts.cal.com\";\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/lib/supabase-image-loader.ts",
    "content": "import { env } from \"@/env\";\n\nexport default function supabaseLoader({\n  src,\n  width,\n  quality,\n}: {\n  src: string;\n  width: number;\n  quality?: number;\n}) {\n  return `${env.NEXT_PUBLIC_SUPABASE_URL}/storage/v1/object/public/${src}?width=${width}&quality=${quality || 75}`;\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/lib/utils.ts",
    "content": "import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\nexport const relativeTime = (time: ReturnType<Date[\"getTime\"]>) => {\n  const elapsed = Date.now() - time;\n  const rtf = new Intl.RelativeTimeFormat(\"en\", { numeric: \"auto\" });\n\n  const units = {\n    year: 24 * 60 * 60 * 1000 * 365,\n    month: 24 * 60 * 60 * 1000 * 30,\n    day: 24 * 60 * 60 * 1000,\n    hour: 60 * 60 * 1000,\n    minute: 60 * 1000,\n    second: 1000,\n  } as const;\n  type Unit = keyof typeof units;\n\n  for (const u in units) {\n    if (Math.abs(elapsed) > units[u as Unit] || u === \"second\") {\n      return rtf.format(-Math.sign(elapsed) * Math.round(elapsed / units[u as Unit]), u as Unit);\n    }\n  }\n};\n\nexport const slugify = (str: string, forDisplayingInput?: boolean) => {\n  if (!str) {\n    return \"\";\n  }\n\n  const s = str\n    .toLowerCase() // Convert to lowercase\n    .trim() // Remove whitespace from both sides\n    .normalize(\"NFD\") // Normalize to decomposed form for handling accents\n    .replace(/\\p{Diacritic}/gu, \"\") // Remove any diacritics (accents) from characters\n    .replace(/[^.\\p{L}\\p{N}\\p{Zs}\\p{Emoji}]+/gu, \"-\") // Replace any non-alphanumeric characters (including Unicode and except \".\" period) with a dash\n    .replace(/[\\s_#]+/g, \"-\") // Replace whitespace, # and underscores with a single dash\n    .replace(/^-+/, \"\") // Remove dashes from start\n    .replace(/\\.{2,}/g, \".\") // Replace consecutive periods with a single period\n    .replace(/^\\.+/, \"\") // Remove periods from the start\n    .replace(\n      /([\\u2700-\\u27BF]|[\\uE000-\\uF8FF]|\\uD83C[\\uDC00-\\uDFFF]|\\uD83D[\\uDC00-\\uDFFF]|[\\u2011-\\u26FF]|\\uD83E[\\uDD10-\\uDDFF])/g,\n      \"\"\n    ) // Removes emojis\n    .replace(/\\s+/g, \" \")\n    .replace(/-+/g, \"-\"); // Replace consecutive dashes with a single dash\n\n  return forDisplayingInput ? s : s.replace(/-+$/, \"\").replace(/\\.*$/, \"\"); // Remove dashes and period from end\n};\n\nexport default slugify;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/middleware.ts",
    "content": "import { authConfig } from \"./auth/config.edge\";\nimport NextAuth from \"next-auth\";\nimport { NextResponse, type MiddlewareConfig } from \"next/server\";\n\nexport default NextAuth(authConfig).auth((req) => {\n  if (req.nextUrl.pathname === \"/dashboard/settings\") {\n    return NextResponse.redirect(new URL(\"/dashboard/settings/profile\", req.url));\n  }\n});\n\nexport const config: MiddlewareConfig = {\n  // https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher\n  matcher: [\"/((?!api|_next/static|_next/image|.*\\\\.png$).*)\"],\n};\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/src/styles/globals.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n  :root {\n    --background: 0 0% 100%;\n    --foreground: 222.2 84% 4.9%;\n\n    --card: 0 0% 100%;\n    --card-foreground: 222.2 84% 4.9%;\n\n    --popover: 0 0% 100%;\n    --popover-foreground: 222.2 84% 4.9%;\n\n    --primary: 222.2 47.4% 11.2%;\n    --primary-foreground: 210 40% 98%;\n\n    --secondary: 210 40% 96.1%;\n    --secondary-foreground: 222.2 47.4% 11.2%;\n\n    --muted: 210 40% 96.1%;\n    --muted-foreground: 215.4 16.3% 46.9%;\n\n    --accent: 210 40% 96.1%;\n    --accent-foreground: 222.2 47.4% 11.2%;\n\n    --destructive: 0 84.2% 60.2%;\n    --destructive-foreground: 210 40% 98%;\n\n    --success: 134 76% 94%;\n    --success-foreground: 133 34% 24%;\n\n    --border: 214.3 31.8% 91.4%;\n    --input: 214.3 31.8% 91.4%;\n    --ring: 222.2 84% 4.9%;\n\n    --radius: 0.5rem;\n  }\n\n  .dark {\n    --background: 222.2 84% 4.9%;\n    --foreground: 210 40% 98%;\n\n    --card: 222.2 84% 4.9%;\n    --card-foreground: 210 40% 98%;\n\n    --popover: 222.2 84% 4.9%;\n    --popover-foreground: 210 40% 98%;\n\n    --primary: 210 40% 98%;\n    --primary-foreground: 222.2 47.4% 11.2%;\n\n    --secondary: 217.2 32.6% 17.5%;\n    --secondary-foreground: 210 40% 98%;\n\n    --muted: 217.2 32.6% 17.5%;\n    --muted-foreground: 215 20.2% 65.1%;\n\n    --accent: 217.2 32.6% 17.5%;\n    --accent-foreground: 210 40% 98%;\n\n    --destructive: 0 62.8% 30.6%;\n    --destructive-foreground: 210 40% 98%;\n\n    --success: 120 100% 50%;\n    --success-foreground: 210 40% 98%;\n\n    --border: 217.2 32.6% 17.5%;\n    --input: 217.2 32.6% 17.5%;\n    --ring: 212.7 26.8% 83.9%;\n  }\n}\n\n@font-face {\n  font-family: \"Cal Sans\";\n  font-weight: 200 900;\n  font-display: block;\n  font-style: normal;\n  font-stretch: 75% 125%;\n  src: url(\"../fonts/CalSans-SemiBold.woff2\") format(\"woff2\");\n}\n\n.pretty-scrollbar::-webkit-scrollbar {\n  width: 5px;\n  height: 8px;\n  background-color: #fff;\n}\n\n.pretty-scrollbar:hover::-webkit-scrollbar-thumb {\n  background: #c1c1c1;\n  border-radius: 2px;\n  transition: background-color 0.3s ease-in-out;\n}\n\n.custom-grid {\n  display: grid;\n  grid-template-areas: \"meta main timeslots\" \"meta main timeslots\";\n  width: calc(var(--booker-meta-width) + var(--booker-main-width) + var(--booker-timeslots-width));\n  grid-template-columns: var(--booker-meta-width) 1fr var(--booker-timeslots-width);\n  grid-template-rows: 1fr 0fr;\n  min-height: 450px;\n  height: auto;\n}\n\n@layer base {\n  * {\n    @apply border-border;\n  }\n  body {\n    @apply bg-background text-foreground;\n  }\n}\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/supabase/.gitignore",
    "content": "# Supabase\n.branches\n.temp\n.env\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/supabase/config.toml",
    "content": "# A string used to distinguish different Supabase projects on the same host. Defaults to the\n# working directory name when running `supabase init`.\nproject_id = \"calcom-platform-starter-kit\"\n\n[api]\nenabled = false\n# Port to use for the API URL.\nport = 54321\n# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API\n# endpoints. `public` is always included.\nschemas = [\"public\", \"graphql_public\"]\n# Extra schemas to add to the search_path of every request. `public` is always included.\nextra_search_path = [\"public\", \"extensions\"]\n# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size\n# for accidental or malicious requests.\nmax_rows = 1000\n\n[db]\n# Port to use for the local database URL.\nport = 54322\n# Port used by db diff command to initialize the shadow database.\nshadow_port = 54320\n# The database major version to use. This has to be the same as your remote database's. Run `SHOW\n# server_version;` on the remote database to check.\nmajor_version = 15\n\n[db.pooler]\nenabled = false\n# Port to use for the local connection pooler.\nport = 54329\n# Specifies when a server connection can be reused by other clients.\n# Configure one of the supported pooler modes: `transaction`, `session`.\npool_mode = \"transaction\"\n# How many server connections to allow per user/database pair.\ndefault_pool_size = 20\n# Maximum number of client connections allowed.\nmax_client_conn = 100\n\n[realtime]\nenabled = false\n# Bind realtime via either IPv4 or IPv6. (default: IPv4)\n# ip_version = \"IPv6\"\n# The maximum length in bytes of HTTP request headers. (default: 4096)\n# max_header_length = 4096\n\n[studio]\nenabled = true\n# Port to use for Supabase Studio.\nport = 54323\n# External URL of the API server that frontend connects to.\napi_url = \"http://127.0.0.1\"\n# OpenAI API Key to use for Supabase AI in the Supabase Studio.\nopenai_api_key = \"env(OPENAI_API_KEY)\"\n\n# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they\n# are monitored, and you can view the emails that would have been sent from the web interface.\n[inbucket]\nenabled = false\n# Port to use for the email testing server web interface.\nport = 54324\n# Uncomment to expose additional ports for testing user applications that send emails.\n# smtp_port = 54325\n# pop3_port = 54326\n\n[storage]\nenabled = true\n# The maximum file size allowed (e.g. \"5MB\", \"500KB\").\nfile_size_limit = \"50MiB\"\n\n[storage.image_transformation]\nenabled = true\n\n[auth]\nenabled = false\n# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used\n# in emails.\nsite_url = \"http://127.0.0.1:3000\"\n# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.\nadditional_redirect_urls = [\"https://127.0.0.1:3000\"]\n# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).\njwt_expiry = 3600\n# If disabled, the refresh token will never expire.\nenable_refresh_token_rotation = true\n# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.\n# Requires enable_refresh_token_rotation = true.\nrefresh_token_reuse_interval = 10\n# Allow/disallow new user signups to your project.\nenable_signup = true\n# Allow/disallow anonymous sign-ins to your project.\nenable_anonymous_sign_ins = false\n# Allow/disallow testing manual linking of accounts\nenable_manual_linking = false\n\n[auth.email]\n# Allow/disallow new user signups via email to your project.\nenable_signup = true\n# If enabled, a user will be required to confirm any email change on both the old, and new email\n# addresses. If disabled, only the new email is required to confirm.\ndouble_confirm_changes = true\n# If enabled, users need to confirm their email address before signing in.\nenable_confirmations = false\n# Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email.\nmax_frequency = \"1s\"\n\n# Uncomment to customize email template\n# [auth.email.template.invite]\n# subject = \"You have been invited\"\n# content_path = \"./supabase/templates/invite.html\"\n\n[auth.sms]\n# Allow/disallow new user signups via SMS to your project.\nenable_signup = true\n# If enabled, users need to confirm their phone number before signing in.\nenable_confirmations = false\n# Template for sending OTP to users\ntemplate = \"Your code is {{ .Code }} .\"\n# Controls the minimum amount of time that must pass before sending another sms otp.\nmax_frequency = \"5s\"\n\n# Use pre-defined map of phone number to OTP for testing.\n# [auth.sms.test_otp]\n# 4152127777 = \"123456\"\n\n# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used.\n# [auth.hook.custom_access_token]\n# enabled = true\n# uri = \"pg-functions://<database>/<schema>/<hook_name>\"\n\n# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`.\n[auth.sms.twilio]\nenabled = false\naccount_sid = \"\"\nmessage_service_sid = \"\"\n# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead:\nauth_token = \"env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)\"\n\n# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,\n# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`,\n# `twitter`, `slack`, `spotify`, `workos`, `zoom`.\n[auth.external.apple]\nenabled = false\nclient_id = \"\"\n# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:\nsecret = \"env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)\"\n# Overrides the default auth redirectUrl.\nredirect_uri = \"\"\n# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,\n# or any other third-party OIDC providers.\nurl = \"\"\n# If enabled, the nonce check will be skipped. Required for local sign in with Google auth.\nskip_nonce_check = false\n\n[edge_runtime]\nenabled = false\n# Configure one of the supported request policies: `oneshot`, `per_worker`.\n# Use `oneshot` for hot reload, or `per_worker` for load testing.\npolicy = \"oneshot\"\ninspector_port = 8083\n\n[analytics]\nenabled = false\nport = 54327\nvector_port = 54328\n# Configure one of the supported backends: `postgres`, `bigquery`.\nbackend = \"postgres\"\n\n# Experimental features may be deprecated any time\n[experimental]\n# Configures Postgres storage engine to use OrioleDB (S3)\norioledb_version = \"\"\n# Configures S3 bucket URL, eg. <bucket_name>.s3-<region>.amazonaws.com\ns3_host = \"env(S3_HOST)\"\n# Configures S3 bucket region, eg. us-east-1\ns3_region = \"env(S3_REGION)\"\n# Configures AWS_ACCESS_KEY_ID for S3 bucket\ns3_access_key = \"env(S3_ACCESS_KEY)\"\n# Configures AWS_SECRET_ACCESS_KEY for S3 bucket\ns3_secret_key = \"env(S3_SECRET_KEY)\"\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/supabase/migrations/20240615093934_init.sql",
    "content": "-- CreateSchema\nCREATE SCHEMA IF NOT EXISTS \"prisma\";\n\n-- CreateEnum\nCREATE TYPE \"prisma\".\"UserStatus\" AS ENUM ('APPROVED', 'PENDING');\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"Account\" (\n    \"id\" TEXT NOT NULL,\n    \"userId\" TEXT NOT NULL,\n    \"type\" TEXT NOT NULL,\n    \"provider\" TEXT NOT NULL,\n    \"providerAccountId\" TEXT NOT NULL,\n    \"refresh_token\" TEXT,\n    \"access_token\" TEXT,\n    \"expires_at\" INTEGER,\n    \"token_type\" TEXT,\n    \"scope\" TEXT,\n    \"id_token\" TEXT,\n    \"session_state\" TEXT,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n\n    CONSTRAINT \"Account_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"Session\" (\n    \"id\" TEXT NOT NULL,\n    \"sessionToken\" TEXT NOT NULL,\n    \"userId\" TEXT NOT NULL,\n    \"expires\" TIMESTAMP(3) NOT NULL,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n\n    CONSTRAINT \"Session_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"User\" (\n    \"id\" TEXT NOT NULL,\n    \"name\" TEXT,\n    \"username\" TEXT,\n    \"bio\" TEXT,\n    \"email\" TEXT,\n    \"emailVerified\" TIMESTAMP(3),\n    \"hashedPassword\" TEXT,\n    \"image\" TEXT,\n    \"calAccountId\" INTEGER,\n    \"calAccessToken\" TEXT,\n    \"calRefreshToken\" TEXT,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n    \"status\" \"prisma\".\"UserStatus\" NOT NULL DEFAULT 'PENDING',\n\n    CONSTRAINT \"User_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"CalAccount\" (\n    \"id\" INTEGER NOT NULL,\n    \"username\" TEXT,\n    \"email\" TEXT NOT NULL,\n    \"timeZone\" TEXT NOT NULL,\n    \"weekStart\" TEXT NOT NULL,\n    \"createdDate\" TEXT NOT NULL,\n    \"timeFormat\" INTEGER,\n    \"defaultScheduleId\" INTEGER,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n\n    CONSTRAINT \"CalAccount_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"VerificationToken\" (\n    \"identifier\" TEXT NOT NULL,\n    \"token\" TEXT NOT NULL,\n    \"expires\" TIMESTAMP(3) NOT NULL,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"FilterOption\" (\n    \"fieldId\" TEXT NOT NULL,\n    \"fieldValue\" TEXT NOT NULL,\n    \"fieldLabel\" TEXT NOT NULL,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,\n    \"filterCategoryFieldId\" TEXT NOT NULL,\n    \"filterCategoryValue\" TEXT NOT NULL,\n    \"filterCategoryLabel\" TEXT NOT NULL\n);\n\n-- CreateTable\nCREATE TABLE \"prisma\".\"FilterOptionsOnUser\" (\n    \"userId\" TEXT NOT NULL,\n    \"filterOptionFieldId\" TEXT NOT NULL,\n    \"filterCategoryFieldId\" TEXT NOT NULL,\n    \"createdAt\" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Account_provider_providerAccountId_key\" ON \"prisma\".\"Account\"(\"provider\", \"providerAccountId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Session_sessionToken_key\" ON \"prisma\".\"Session\"(\"sessionToken\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_username_key\" ON \"prisma\".\"User\"(\"username\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_email_key\" ON \"prisma\".\"User\"(\"email\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_calAccountId_key\" ON \"prisma\".\"User\"(\"calAccountId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_calAccessToken_key\" ON \"prisma\".\"User\"(\"calAccessToken\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"User_calRefreshToken_key\" ON \"prisma\".\"User\"(\"calRefreshToken\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"CalAccount_username_key\" ON \"prisma\".\"CalAccount\"(\"username\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"CalAccount_email_key\" ON \"prisma\".\"CalAccount\"(\"email\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"VerificationToken_token_key\" ON \"prisma\".\"VerificationToken\"(\"token\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"VerificationToken_identifier_token_key\" ON \"prisma\".\"VerificationToken\"(\"identifier\", \"token\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"FilterOption_fieldId_key\" ON \"prisma\".\"FilterOption\"(\"fieldId\");\n\n-- CreateIndex\nCREATE INDEX \"FilterOption_fieldId_filterCategoryFieldId_idx\" ON \"prisma\".\"FilterOption\"(\"fieldId\", \"filterCategoryFieldId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"FilterOption_fieldId_filterCategoryFieldId_key\" ON \"prisma\".\"FilterOption\"(\"fieldId\", \"filterCategoryFieldId\");\n\n-- CreateIndex\nCREATE INDEX \"FilterOptionsOnUser_userId_filterOptionFieldId_filterCatego_idx\" ON \"prisma\".\"FilterOptionsOnUser\"(\"userId\", \"filterOptionFieldId\", \"filterCategoryFieldId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"FilterOptionsOnUser_userId_filterOptionFieldId_filterCatego_key\" ON \"prisma\".\"FilterOptionsOnUser\"(\"userId\", \"filterOptionFieldId\", \"filterCategoryFieldId\");\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"Account\" ADD CONSTRAINT \"Account_userId_fkey\" FOREIGN KEY (\"userId\") REFERENCES \"prisma\".\"User\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"Session\" ADD CONSTRAINT \"Session_userId_fkey\" FOREIGN KEY (\"userId\") REFERENCES \"prisma\".\"User\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"User\" ADD CONSTRAINT \"User_calAccountId_fkey\" FOREIGN KEY (\"calAccountId\") REFERENCES \"prisma\".\"CalAccount\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"FilterOptionsOnUser\" ADD CONSTRAINT \"FilterOptionsOnUser_filterOptionFieldId_filterCategoryFiel_fkey\" FOREIGN KEY (\"filterOptionFieldId\", \"filterCategoryFieldId\") REFERENCES \"prisma\".\"FilterOption\"(\"fieldId\", \"filterCategoryFieldId\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"prisma\".\"FilterOptionsOnUser\" ADD CONSTRAINT \"FilterOptionsOnUser_userId_fkey\" FOREIGN KEY (\"userId\") REFERENCES \"prisma\".\"User\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- IMPORTANT DO NOTE REMOVE\n-- Prisma migrations table\nCREATE TABLE IF NOT EXISTS \"public\".\"_prisma_migrations\" (\n    \"id\" character varying(36) NOT NULL,\n    \"checksum\" character varying(64) NOT NULL,\n    \"finished_at\" timestamp with time zone,\n    \"migration_name\" character varying(255) NOT NULL,\n    \"logs\" \"text\",\n    \"rolled_back_at\" timestamp with time zone,\n    \"started_at\" timestamp with time zone DEFAULT \"now\"() NOT NULL,\n    \"applied_steps_count\" integer DEFAULT 0 NOT NULL\n);\n\nALTER TABLE \"public\".\"_prisma_migrations\" OWNER TO \"postgres\";\n\nALTER TABLE ONLY \"public\".\"_prisma_migrations\"\n    ADD CONSTRAINT \"_prisma_migrations_pkey\" PRIMARY KEY (\"id\");\n\nALTER TABLE \"public\".\"_prisma_migrations\" ENABLE ROW LEVEL SECURITY;"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/supabase/seed.sql",
    "content": "--\n-- Data for Name: FilterOption; Type: TABLE DATA; Schema: public; Owner: postgres\n--\n\nINSERT INTO \"prisma\".\"FilterOption\" (\"fieldId\", \"fieldValue\", \"fieldLabel\", \"createdAt\", \"filterCategoryFieldId\", \"filterCategoryValue\", \"filterCategoryLabel\") VALUES\n\t('freelancer', 'freelancer', 'Freelancer', '2024-06-12 16:34:56.508', 'categories', 'categories', 'Category'),\n\t('agency', 'agency', 'Agency', '2024-06-12 16:34:56.508', 'categories', 'categories', 'Category'),\n\t('product_studio', 'product_studio', 'Product Studio', '2024-06-12 16:34:56.508', 'categories', 'categories', 'Category'),\n\t('ecommerce', 'ecommerce', 'Ecommerce', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('product_management', 'product_management', 'Product Management', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('app_development', 'app_development', 'App Development', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('design', 'design', 'Design', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('ui_ux', 'ui_ux', 'UI/UX Development', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('integration_services', 'integration_services', 'Integration Services', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('branding', 'branding', 'Branding', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('digital_marketing', 'digital_marketing', 'Digital Marketing', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('mobile_development', 'mobile_development', 'Mobile Development', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('ai', 'ai', 'AI', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('web3-crypto', 'web3-crypto', 'Web3 / Crypto', '2024-06-12 16:34:56.508', 'capabilities', 'capabilities', 'Capabilities'),\n\t('nextjs', 'nextjs', 'Next.js', '2024-06-12 16:34:56.508', 'frameworks', 'frameworks', 'Frameworks'),\n\t('nuxtjs', 'nuxtjs', 'Nuxt.js', '2024-06-12 16:34:56.508', 'frameworks', 'frameworks', 'Frameworks'),\n\t('svelte', 'svelte', 'Svelte', '2024-06-12 16:34:56.508', 'frameworks', 'frameworks', 'Frameworks'),\n\t('gatsby', 'gatsby', 'Gatsby', '2024-06-12 16:34:56.508', 'frameworks', 'frameworks', 'Frameworks'),\n\t('angular', 'angular', 'Angular', '2024-06-12 16:34:56.508', 'frameworks', 'frameworks', 'Frameworks'),\n\t('ember', 'ember', 'Ember', '2024-06-12 16:34:56.508', 'frameworks', 'frameworks', 'Frameworks'),\n\t('vue', 'vue', 'Vue', '2024-06-12 16:34:56.508', 'frameworks', 'frameworks', 'Frameworks'),\n\t('1000', '1000', '$1,000 - $4,999', '2024-06-12 16:34:56.508', 'budgets', 'budgets', 'Budgets'),\n\t('5000', '5000', '$5,000 - $9,999', '2024-06-12 16:34:56.508', 'budgets', 'budgets', 'Budgets'),\n\t('10000', '10000', '$10,000 - $49,999', '2024-06-12 16:34:56.508', 'budgets', 'budgets', 'Budgets'),\n\t('50000', '50000', '$50,000 - $99,999', '2024-06-12 16:34:56.508', 'budgets', 'budgets', 'Budgets'),\n\t('100000', '100000', '$100,000+', '2024-06-12 16:34:56.508', 'budgets', 'budgets', 'Budgets'),\n\t('english', 'english', 'English', '2024-06-12 16:34:56.508', 'languages', 'languages', 'Languages Spoken'),\n\t('portugese', 'portugese', 'Portuguese', '2024-06-12 16:34:56.508', 'languages', 'languages', 'Languages Spoken'),\n\t('spanish', 'spanish', 'Spanish', '2024-06-12 16:34:56.508', 'languages', 'languages', 'Languages Spoken'),\n\t('chinese', 'chinese', 'Chinese', '2024-06-12 16:34:56.508', 'languages', 'languages', 'Languages Spoken'),\n\t('french', 'french', 'French', '2024-06-12 16:34:56.508', 'languages', 'languages', 'Languages Spoken'),\n\t('japanese', 'japanese', 'Japanese', '2024-06-12 16:34:56.508', 'languages', 'languages', 'Languages Spoken'),\n\t('german', 'german', 'German', '2024-06-12 16:34:56.508', 'languages', 'languages', 'Languages Spoken'),\n\t('asia', 'asia', 'Asia', '2024-06-12 16:34:56.508', 'regions', 'regions', 'Region'),\n\t('australia', 'australia', 'Australia and New Zealand', '2024-06-12 16:34:56.508', 'regions', 'regions', 'Region'),\n\t('europe', 'europe', 'Europe', '2024-06-12 16:34:56.508', 'regions', 'regions', 'Region'),\n\t('latin_america', 'latin_america', 'Latin America', '2024-06-12 16:34:56.508', 'regions', 'regions', 'Region'),\n\t('middle_east', 'middle_east', 'Middle East', '2024-06-12 16:34:56.508', 'regions', 'regions', 'Region'),\n\t('north_america', 'north_america', 'North America', '2024-06-12 16:34:56.508', 'regions', 'regions', 'Region'),\n\t('remote', 'remote', 'Remote', '2024-06-12 16:34:56.508', 'regions', 'regions', 'Region');\n\n\n--\n-- Data for Name: _prisma_migrations; Type: TABLE DATA; Schema: public; Owner: postgres\n--\n\nINSERT INTO \"public\".\"_prisma_migrations\" (\"id\", \"checksum\", \"finished_at\", \"migration_name\", \"logs\", \"rolled_back_at\", \"started_at\", \"applied_steps_count\") VALUES\n\t('c5d8d6fe-8be5-4476-8aca-f102e63be12e', '3f5160803fe82395ea1343a296457bd40a893640b02a6cc4e5389c15736825fb', '2024-06-15 09:39:06.676328+00', '20240615093906_init', NULL, NULL, '2024-06-15 09:39:06.628549+00', 1);\n\n\n--\n-- Data for Name: buckets; Type: TABLE DATA; Schema: storage; Owner: supabase_storage_admin\n--\n-- commenting out as this currently doesn't work with vercel integration\n-- INSERT INTO \"storage\".\"buckets\" (\"id\", \"name\", \"owner\", \"created_at\", \"updated_at\", \"public\", \"avif_autodetection\", \"file_size_limit\", \"allowed_mime_types\", \"owner_id\") VALUES\n-- \t('avatars', 'avatars', NULL, '2024-06-14 11:51:12.750831+00', '2024-06-14 11:51:12.750831+00', true, false, NULL, '{image/jpeg,image/png}', NULL);"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/tailwind.config.ts",
    "content": "import type { Config } from \"tailwindcss\";\n\nconst config = {\n  darkMode: [\"class\"],\n  content: [\n    \"./pages/**/*.{ts,tsx}\",\n    \"./components/**/*.{ts,tsx}\",\n    \"./app/**/*.{ts,tsx}\",\n    \"./src/**/*.{ts,tsx}\",\n  ],\n  prefix: \"\",\n  theme: {\n    container: {\n      center: true,\n      padding: \"2rem\",\n      screens: {\n        \"2xl\": \"1400px\",\n      },\n    },\n    extend: {\n      fontFamily: {\n        display: [[\"Cal Sans\", \"sans-serif\"], { fontVariationSettings: '\"wdth\" 125' }],\n      },\n      colors: {\n        border: \"hsl(var(--border))\",\n        input: \"hsl(var(--input))\",\n        ring: \"hsl(var(--ring))\",\n        background: \"hsl(var(--background))\",\n        foreground: \"hsl(var(--foreground))\",\n        primary: {\n          DEFAULT: \"hsl(var(--primary))\",\n          foreground: \"hsl(var(--primary-foreground))\",\n        },\n        secondary: {\n          DEFAULT: \"hsl(var(--secondary))\",\n          foreground: \"hsl(var(--secondary-foreground))\",\n        },\n        destructive: {\n          DEFAULT: \"hsl(var(--destructive))\",\n          foreground: \"hsl(var(--destructive-foreground))\",\n        },\n        success: {\n          DEFAULT: \"hsl(var(--success))\",\n          foreground: \"hsl(var(--success-foreground))\",\n        },\n        muted: {\n          DEFAULT: \"hsl(var(--muted))\",\n          foreground: \"hsl(var(--muted-foreground))\",\n        },\n        accent: {\n          DEFAULT: \"hsl(var(--accent))\",\n          foreground: \"hsl(var(--accent-foreground))\",\n        },\n        popover: {\n          DEFAULT: \"hsl(var(--popover))\",\n          foreground: \"hsl(var(--popover-foreground))\",\n        },\n        card: {\n          DEFAULT: \"hsl(var(--card))\",\n          foreground: \"hsl(var(--card-foreground))\",\n        },\n      },\n      borderRadius: {\n        lg: \"var(--radius)\",\n        md: \"calc(var(--radius) - 2px)\",\n        sm: \"calc(var(--radius) - 4px)\",\n      },\n      keyframes: {\n        \"accordion-down\": {\n          from: { height: \"0\" },\n          to: { height: \"var(--radix-accordion-content-height)\" },\n        },\n        \"accordion-up\": {\n          from: { height: \"var(--radix-accordion-content-height)\" },\n          to: { height: \"0\" },\n        },\n        \"collapsible-down\": {\n          from: { height: \"0\" },\n          to: { height: \"var(--radix-collapsible-content-height)\" },\n        },\n        \"collapsible-up\": {\n          from: { height: \"var(--radix-collapsible-content-height)\" },\n          to: { height: \"0\" },\n        },\n      },\n      animation: {\n        \"accordion-down\": \"accordion-down 0.2s ease-out\",\n        \"accordion-up\": \"accordion-up 0.2s ease-out\",\n        \"collapsible-down\": \"collapsible-down 0.2s ease-out\",\n        \"collapsible-up\": \"collapsible-up 0.2s ease-out\",\n      },\n    },\n  },\n  plugins: [require(\"tailwindcss-animate\")],\n} satisfies Config;\n\nexport default config;\n"
  },
  {
    "path": "with-platform-supabase-tailwind-prisma/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    /* Base Options: */\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"target\": \"es2022\",\n    \"allowJs\": true,\n    \"resolveJsonModule\": true,\n    \"moduleDetection\": \"force\",\n    \"isolatedModules\": true,\n\n    /* Strictness */\n    \"strict\": true,\n    \"noUncheckedIndexedAccess\": true,\n    \"checkJs\": true,\n    \"moduleResolution\": \"Bundler\",\n\n    /* Bundled projects */\n    \"lib\": [\"dom\", \"dom.iterable\", \"ES2022\"],\n    \"noEmit\": true,\n    \"module\": \"ESNext\",\n    \"jsx\": \"preserve\",\n    \"plugins\": [{ \"name\": \"next\" }],\n    \"incremental\": true,\n\n    /* Path Aliases */\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"@/*\": [\"./src/*\"]\n    }\n  },\n  \"include\": [\n    \".eslintrc.cjs\",\n    \"next-env.d.ts\",\n    \"**/*.ts\",\n    \"**/*.tsx\",\n    \"**/*.cjs\",\n    \"**/*.js\",\n    \".next/types/**/*.ts\"\n  ],\n  \"exclude\": [\"node_modules\"]\n}\n"
  }
]