[{"data":1,"prerenderedAt":409},["ShallowReactive",2],{"search-api":3},[4,12,19,27,34,41,48,55,63,70,77,84,91,98,104,112,118,125,131,138,145,151,158,165,171,178,185,192,199,205,212,219,226,233,240,247,253,261,268,275,282,289,296,304,312,320,328,334,344,351,359,367,390,400],{"id":5,"path":6,"dir":7,"title":8,"description":9,"keywords":10,"body":11},"content:0.index.md","/","","Welcome","This frontend documentation will guide you through our practices of building beautiful and interactive web interfaces.",[],"  Welcome  This frontend documentation will guide you through our practices of building beautiful and interactive web interfaces.  Happy coding!  For more detailed information, explore the sections in this documentation.",{"id":13,"path":14,"dir":15,"title":16,"description":7,"keywords":17,"body":18},"content:1.Nuxt3 Setup:1.introduction.md","/nuxt3-setup/introduction","nuxt3-setup","Introduction",[16],"  Introduction  Setting up a Nuxt 3 project involves preparing the development environment, structuring the project, installing necessary dependencies, and configuring various settings before coding.  By following this guide, developers can ensure a well-structured, scalable, and maintainable Nuxt 3 application.  This Nuxt 3 Setup Includes  1. Getting Started   Setting up the development environment (Prerequisite)  Creating a Nuxt 3 project.  Understanding the structure of a Nuxt 3 project.  Managing runtime configurations and environment variables.  Set up new relic for APM  2. Configurations   Installing and configuring Tailwind CSS  Setting up PrimeVue for UI components  Assets management.  Installing and configuring Pinia for state management  Enforcing code quality with ESLint and Prettier  Create error page (404 Page)  3. Data Integration   Handling errors response in API requests  Setting up API endpoints  Using useFetch and the composable folder for data integration  Implementing middleware for authentication and navigation  Set up reUseFunction file for dynamic functions  5. Common Features   Custom Icons  Buttons  Input Field  Layout  Loaders  Themes  Form Validation  Seo Optimization  Recaptcha",{"id":20,"path":21,"dir":22,"title":23,"description":7,"keywords":24,"body":26},"content:1.Nuxt3 Setup:2.Getting started:1.prerequisite.md","/nuxt3-setup/getting-started/prerequisite","getting-started","Prerequisite",[25],"Setting up the Development Environment","  Setting up the Development Environment   Install Node.js - Node.js is a runtime environment that allows JavaScript to be executed outside web browsers, essentially enabling server-side and local machine JavaScript development.to download go to the official Node.js website.  NPM (Node Package Manager) - When starting with web development, you'll need to choose a package manager. npm comes bundled with Node.js and is the default choice for most developers, offering the largest package repository and simplest setup.  Yarn - An alternative package manager to npm. You can install it via npm:     npm   install   --global   yarn\n  to verify installation and check the versions you have installed using your terminal:     # Check if Node.js is installed\n   node   -v\n   \n   # Check if npm is installed\n   npm   -v\n   \n   # Check if Yarn is installed\n   yarn   -v\n  Development Tools   Code Editor (Recommended: VS Code)\nA good code editor is essential for an efficient development workflow. VS Code offers excellent support for Vue.js and Nuxt 3, with many useful extensions (e.g., Vetur, ESLint, Prettier) that enhance the development experience.  Terminal/Command Prompt\nYou'll use the terminal or command prompt to run development commands like starting the development server, installing dependencies, or managing version control.  Git (recommended)\nGit helps manage version control and collaboration. It's highly recommended to use Git to track changes in your codebase and work with teams effectively. You can install Git from the official Git website.  Browser Support: Browsers compatible with Nuxt 3.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":28,"path":29,"dir":22,"title":30,"description":7,"keywords":31,"body":33},"content:1.Nuxt3 Setup:2.Getting started:2.create-nuxt3-project.md","/nuxt3-setup/getting-started/create-nuxt3-project","Create Nuxt3 Project",[32],"Install and Create a Nuxt3 Project","  Install and Create a Nuxt3 Project  You can set up a Nuxt 3 project using nuxi, the official Nuxt 3 CLI tool.  Using npx:  In your terminal, run the following command:     npx   nuxi   init   \u003C  project-nam  e  >\n  Navigate to project and install dependencies  Once the project is created, navigate to your project folder and install the necessary dependencies:     cd   \u003C  project-nam  e  >\n   \n   # To open code editor\n   code   .\n   \n   npm   install\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":35,"path":36,"dir":22,"title":37,"description":7,"keywords":38,"body":40},"content:1.Nuxt3 Setup:2.Getting started:3.Setup.md","/nuxt3-setup/getting-started/setup","Setup",[39],"Setting Up a Nuxt 3 Project with Git, Dependencies, and Configuration","  Setting Up a Nuxt 3 Project with Git, Dependencies, and Configuration  This guide walks you through setting up a Nuxt 3 project with Git, installing necessary dependencies, configuring modules, and preparing your project structure.    Initialize Git and Connect to a Remote Repository  Run the following commands to initialize Git and link it to your repository:     git   init\n   git   remote   add   origin   https://github.com/SGSTeamDev/frontend-starter-lib.git\n  git init: Initializes a new Git repository in your project.  git remote add origin   https://github.com/SGSTeamDev/frontend-starter-lib.git : Links your project to a remote repository.     git   remote   -v\n   git   add   .\n   git   commit   -m   \"initial commit\"\n  git remote -v: Verifies that the remote repository is correctly set.  git add . and git commit -m \"initial commit\": Stages and commits all     git   pull   --allow-unrelated-histories   origin   main\n   git   remote   remove   origin\n  git pull --allow-unrelated-histories origin main: Pulls the latest changes from the remote repository, allowing unrelated histories to merge.  git remote remove origin: Removes the existing remote origin.     git   remote   add   origin   \u003C  new-project-repository-ur  l  >\n   git   remote   -v\n  git remote add origin   : Re-adds the correct remote repository.  git remote -v: Confirms that the repository has been set up correctly.    Install Dependencies  Run the following command to install essential dependencies:     npm   install   primevue@4.1.0   @primevue/themes   primeicons   pinia-plugin-persistedstate   @vueuse/core   vite-svg-loader   joi   moment\n  This installs:\nprimevue - UI component library  @primevue/themes - Theme support for PrimeVue  primeicons - Icon library  pinia-plugin-persistedstate - Enables persistent state management for Pinia  @vueuse/core - Utility functions for Vue  Install Development Dependencies     npm   install   -D   tailwindcss@3.4.17   postcss   autoprefixer   @primevue/nuxt-module@4.1.0   prettier   eslint-plugin-prettier   eslint-config-prettier\n  This installs:\ntailwindcss - Utility-first CSS framework  postcss & autoprefixer - Required for TailwindCSS  @primevue/nuxt-module - Integration module for PrimeVue in Nuxt  prettier, eslint-plugin-prettier, eslint-config-prettier - Code formatting & linting    Add Nuxt Modules     npx   nuxi@latest   module   add   pinia\n   npx   nuxi   module   add   eslint\n  This automatically sets up Pinia (state management) and ESLint (linting) in your Nuxt project.    Replace Example Files with Original Files  Your project includes example files that need to be copied and replaced with the original files.\nThe existing example files are:     app.example.vue\n   nuxt.config.example.ts\n   package.example.json\n  Replace them with the actual project files:   Copy the content from the example files into the corresponding real files:     Copy app.example.vue → Paste into app.vue\n   Copy nuxt.config.example.ts → Paste into nuxt.config.ts\n   Copy package.example.json → Paste into package.json script\n   Once the copying is complete, delete the example files: Git Bash Terminal     rm   app.example.vue   nuxt.config.example.ts   package.example.json\n  This ensures that your project is correctly structured and ready for further development.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":42,"path":43,"dir":22,"title":44,"description":7,"keywords":45,"body":47},"content:1.Nuxt3 Setup:2.Getting started:4.project-structure.md","/nuxt3-setup/getting-started/project-structure","Project Structure",[46],"Understanding the Project Structure","  Understanding the Project Structure  A Nuxt 3 project typically follows a specific folder structure. During installation, some folders are created automatically, while others need to be manually created based on the project’s requirements. Below is a guide to the main folders and files, along with their purposes:  These folders are generated when you install Nuxt 3:    nuxt.config.ts : Nuxt configuration file.   package.json : Contains project metadata and dependencies.   tsconfig.json : TypeScript configuration file.   .nuxt : Auto-generated build files (do not edit).   node_modules : Installed dependencies.   public : Static assets like images, fonts, and favicons.   app.vue : The main Vue component that acts as the root component for your application.  Folders You Need to Create Manually  Some folders are not included by default but are commonly needed in Nuxt 3 projects:    assets : Contains uncompiled assets that will be processed by the build tool (e.g., stylesheets, images, and icons).   components : Contains Vue components that help in writing clean, reusable, and maintainable code (e.g., a button component that can be used across pages).   composables : Stores reusable functions built with Vue’s Composition API to manage shared logic across multiple components (e.g., API call functions, error handling functions).   plugins : Contains JavaScript plugins that need to be run before instantiating the root Vue.js application.   store : Initializes Pinia for global state management to store things like auth tokens and user data.   middleware : Contains custom middleware functions that run before rendering a page or a group of pages.   layouts : Contains layout components that wrap around page components.   .env : Contains environment variables for managing configuration settings securely (e.g., base URL).  Example Structure     my-nuxt-app/\n   ├──   assets/\n   │     ├──   css/\n   │     ├──   icons\n   │     └──   images\n   ├──   components/\n   │     ├──   base/\n   │     │     └──   customIcon.vue\n   │     │     └──   button.vue\n   │     │     └──   loader.vue\n   │     ├──   input/\n   │     │     └──   formSelect.vue\n   │     │     └──   formText.vue\n   │     ├──   header.vue\n   │     └──   Footer.vue\n   ├──   pages/\n   │     ├──   index.vue\n   │     ├──   users/\n   │     │     └──   [id].vue\n   │     └──   dashboard.vue\n   ├──   composables/\n   │     ├──   api.js\n   │     └──   endpoints.js\n   │     └──   error.js\n   │     └──   reUseFunctions.ts\n   ├──   layouts/\n   │     └──   default.vue\n   ├──   middleware/\n   │     └──   auth.ts\n   ├──   plugins/\n   │     └──   primevue.js\n   ├──   public/\n   │     └──   favicon.ico\n   ├──   server/\n   │     └──   api/\n   │         └──   users.ts\n   ├──   stores/\n   │     └──   user.ts\n   ├──   types/\n   │     └──   index.ts\n   ├──   app.vue\n   ├──   nuxt.config.ts\n   ├──   package.json\n   ├──   tsconfig.json\n   └──   .env\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":49,"path":50,"dir":22,"title":51,"description":7,"keywords":52,"body":54},"content:1.Nuxt3 Setup:2.Getting started:5.environment-variable.md","/nuxt3-setup/getting-started/environment-variable","Environment Variable",[53],"Managing Runtime Configurations and Environment Variables","  Managing Runtime Configurations and Environment Variables  Runtime configurations and environment variables are essential for managing application settings that need to be dynamically adjustable. They allow applications to adapt to different environments (development, staging, production) without modifying source code.  Benefits of Using Environment Variables  Security: Keeps sensitive information like API keys and database credentials out of source code.  Flexibility: Enables easy switching between different environments.  Scalability: Allows seamless configuration updates without code changes.  Maintainability: Reduces hardcoded values, making applications easier to manage.  To manage the environment variables We can use Infisical, a secret management tool, to securely store and manage environment variables.  Setting Up Infisical in Nuxt 3  Use Node Version 18    Global Installation  To install the Infisical CLI globally on your system, run:     npm   install   -g   @infisical/cli\n  To set up the Infisical CLI with your account:  run this in your project terminal     infisical   login\n  This command will prompt you to log in to your Infisical account.\nIf you don’t have an account, you will need to create one first.\nOnce logged in, Infisical will generate the necessary credentials to securely access your environment secrets.     infisical   init\n  This command will create a .infisical.json configuration file in your project.\nThis file contains project-specific settings that allow Infisical to fetch and manage your environment secrets seamlessly.    Start the Development Server \nFinally, run the following command to start your Nuxt 3 development server:     npm   run   dev\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":56,"path":57,"dir":58,"title":59,"description":7,"keywords":60,"body":62},"content:1.Nuxt3 Setup:3.Configurations:1.tailwind-setup.md","/nuxt3-setup/configurations/tailwind-setup","configurations","Tailwind Setup",[61],"Tailwind CSS Setup","  Tailwind CSS Setup  Tailwind CSS is a utility-first CSS framework that enables you to rapidly build custom designs without writing custom CSS. It's highly customizable and works well with Vue and Nuxt, providing you with utility classes to style your components directly in the HTML.\nTo install Tailwind CSS, follow these steps:    Install Tailwind CSS via npm :     npm   install   -D   tailwindcss@3.4.17   postcss   autoprefixer\n    Create a Tailwind configuration file :      # This will generate a `tailwind.config.js` file in your project root.\n   npx   tailwindcss   init\n  This will generate a   tailwind.config.js  file in your project    Update Tailwind configuration file :  Tailwind CSS configuration allows developers to customize and extend the default design system for their Nuxt 3 project. The configuration file provides comprehensive control over colors, spacing, breakpoints, and other design tokens.     // tailwind.config.js\n   // Configure the paths to all of your template files.\n   \n   /**   @type   {import('tailwindcss').Config}   */\n   export   default   {\n     darkMode:   'class'  ,\n     content: [\n       \"./components/**/*.{js,vue,ts}\"  ,\n       \"./layouts/**/*.vue\"  ,\n       \"./pages/**/*.vue\"  ,\n       \"./plugins/**/*.{js,ts}\"  ,\n       \"./app.vue\"  ,\n       \"./error.vue\"  ,\n     ],\n     theme: {\n       extend: {\n         fontFamily: {},\n         colors:{},\n         spacing: {},\n   },\n     },\n     plugins: []\n   }\n    Import the Postcss and CSS file in your   nuxt.config.ts :     // nuxt.config.ts\n   export   default   defineNuxtConfig  ({\n     postcss: {\n       plugins: {\n         tailwindcss: {},\n         autoprefixer: {},\n       },\n     },\n     css: [  \"~/assets/css/global.css\"  ],\n   });\n    Create a CSS file  (e.g.,   ./assets/css/global.css ) and add the following lines:     @tailwind   base;\n   @tailwind   components;\n   @tailwind   utilities;\n  Usage Example     \u003C  template  >\n     \u003C  div  >\n       \u003C  h1   class  =  \"text-3xl font-bold underline text-red-500\"  >\n         Hello world!\n       \u003C/  h1  >\n     \u003C/  div  >\n   \u003C/  template  >\n  Conclusion  You have successfully set up Tailwind CSS in your project. You can now use Tailwind's utility classes to style your application.  For more information, refer to the   Tailwind CSS documentation .  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":64,"path":65,"dir":58,"title":66,"description":7,"keywords":67,"body":69},"content:1.Nuxt3 Setup:3.Configurations:2..assest-management.md","/nuxt3-setup/configurations/.assest-management","Assest Management",[68],"Global Styling and Assest Management","  Global Styling and Assest Management  The /assets folder is where you store uncompiled resources like images, icons, styles, and fonts. These files are automatically processed by your build tool during project compilation.\nStructure     /assets\n   ├──   /images         # Store image files (png, jpg, etc.)\n   ├──   /icons          # Store SVG icons\n   ├──   /css         # Store CSS and styling files\n   │     ├──   global.css\n   └──   └──   colors.css\n  Usage  To reference these assets in your components or pages, you can use the ~assets alias:     \u003C  template  >\n     \u003C  div  >\n       \u003C  img   src  =  \"~assets/images/logo.png\"   alt  =  \"Logo\"  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   '~/assets/css/global.css'\n   \u003C/  script  >\n  Global Styling  To apply global styles, define them in assets/css/global.css and import them into nuxt.config.ts:      /* assets/css/global.css */\n   body   {\n   font-family  :   'Arial'  ,   sans-serif  ;\n   background-color  :   #f5f5f5  ;\n   margin  :   0  ;\n   padding  :   0  ;\n   }\n  Registering Global Styles in Nuxt     // Modify your nuxt.config.ts to include the global styles:\n   export   default   defineNuxtConfig  ({\n   css: [  '~/assets/css/global.css'  ]\n   })\n  Best Practices  Naming: Use clear, consistent file names\nOptimization: Compress images and fonts before adding\nModularity: Create separate style files for different components\nGlobal Styles: Keep base styles and variables in a single global file  Performance Benefits  Organized: Separates raw assets from compiled files\nOptimized: Assets are processed for better performance\nEasy Referencing: Use ~assets alias for simple imports  By following these guidelines, you'll effectively manage assets and styling in your Nuxt 3 project.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":71,"path":72,"dir":58,"title":73,"description":74,"keywords":75,"body":76},"content:1.Nuxt3 Setup:3.Configurations:3.primevue-integration.md","/nuxt3-setup/configurations/primevue-integration","PrimeVue Setup","PrimeVue is a rich set of open-source UI component library for Vue applications. This guide will help you set up PrimeVue in your project.",[],"  PrimeVue Setup  PrimeVue is a rich set of open-source UI component library for Vue applications. This guide will help you set up PrimeVue in your project.   Install PrimeVue and its dependencies:     npm   install   primevue   @primevue/themes   primeicons\n   npm   install   --save-dev   @primevue/nuxt-module\n   Register PrimeVue in your   nuxt.config.ts :     import   {definePreset}   from   '@primevue/themes'  ;\n   import   Aura   from   '@primevue/themes/aura'  ;\n   \n   const   MyPreset   =   definePreset  (Aura, {\n       semantic: {\n           primary: {}\n       }\n   });\n   \n   \n   export   default   defineNuxtConfig  ({\n       modules: [\n           '@primevue/nuxt-module'\n       ],\n       primevue: {\n           options: {\n         theme: {\n             preset: MyPreset,\n             options: {\n                 darkModeSelector:   '.dark'\n             }\n           }\n         }\n       }\n   })\n   Add PrimeVue CSS to your   nuxt.config.ts :       css  : [\n       \"primeicons/primeicons.css\"  ,\n     ],\n   Add code to plugins/primevue.js:     // ./plugins/primevue.js\n   import   { defineNuxtPlugin }   from   \"#app\"  ;\n   import   PrimeVue   from   \"primevue/config\"  ;\n   import   ToastService   from   \"primevue/toastservice\"  ;\n   import   Button   from   \"primevue/button\"  ;\n   \n   export   default   defineNuxtPlugin  ((  nuxtApp  )   =>   {\n     nuxtApp.vueApp.  use  (PrimeVue);\n     nuxtApp.vueApp.  use  (ToastService);\n     nuxtApp.vueApp.  component  (  \"Button\"  , Button);\n   })\n  Conclusion  PrimeVue provides a wide range of UI components that can be easily integrated into your Vue application. For more information and detailed documentation, visit the   PrimeVue website .  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":78,"path":79,"dir":58,"title":80,"description":81,"keywords":82,"body":83},"content:1.Nuxt3 Setup:3.Configurations:4.pinia-setup.md","/nuxt3-setup/configurations/pinia-setup","Pinia Setup","Pinia is the recommended state management library for Vue 3, providing a simple and efficient way to manage application state.",[],"  Pinia Setup  Pinia is the recommended state management library for Vue 3, providing a simple and efficient way to manage application state.  1. To install Pinia, run the following command:     \n   npx   nuxi@latest   module   add   pinia\n   #  follow the instructions to install correctly then setup pinia for persisted state also\n   \n   npm   install   pinia-plugin-persistedstate\n   \n   npm   install   @vueuse/core\n  2.Register Pinia in your   nuxt.config.ts :     export   default   {\n     modules: [  \"@pinia/nuxt\"  ,   \"pinia-plugin-persistedstate/nuxt\"  ],\n   };\n  3. Create a Pinia Store     // add code to file stores/userDetailsStore.ts\n   import   {defineStore}   from   'pinia'  ;\n   import   {useLocalStorage}   from   \"@vueuse/core\"\n   import   {ref}   from   \"vue\"  ;\n   \n   export   const   useUserDetailsStore   =   defineStore  (  'userDetails'  , {\n       const user   =   useLocalStorage  (  'user'  , {});\n   \n       return {user};\n   })\n  With these steps, you have successfully set up and used Pinia in your Vue application. You can now create additional stores and manage your application's state more effectively.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":85,"path":86,"dir":58,"title":87,"description":7,"keywords":88,"body":90},"content:1.Nuxt3 Setup:3.Configurations:5.eslint.md","/nuxt3-setup/configurations/eslint","Eslint",[87,89],"Prettier","  Eslint  ESLint is a linter that helps to enforce code quality through standards and patterns, such as flagging unused variables, disallowing globals, and requiring Error objects as Promise rejection reasons.  Prettier  Prettier is a formatter that helps in tidying up documents, such as maximum line length, mixed spaces and tabs, keyword spacing, and comma style.  By using these tools together, we can spend more of our development time on our actual code, instead of nitpicking a file's indenting, casing and bracket placement.  Installing:   First, install ESLint and the necessary dependencies:     # Install ESLint\n   npx   nuxi   module   add   eslint\n   Create an .eslintrc.js file in your project root     // eslintrc.js\n   module  .  exports   =   {\n     root:   true  ,\n     extends: [  '@nuxt/eslint-config'  ],\n     rules: {\n       // Your custom rules\n     }\n   }\n   Add ESLint scripts to your package.json:     // package.json\n   \"scripts\"  : {\n     \"lint\"  :   \"eslint .\"  ,\n     \"lint:fix\"  :   \"eslint . --fix\"\n   }\n   Prettier Integration     npm   install   --save-dev   prettier   eslint-plugin-prettier   eslint-config-prettier\n  Then update your .eslintrc.js:     // eslintrc.js\n   module  .  exports   =   {\n     root:   true  ,\n     extends: [\n       '@nuxt/eslint-config'  ,\n       'prettier'\n     ],\n     plugins: [  'prettier'  ],\n     rules: {\n       'prettier/prettier'  :   'error'\n     }\n   }\n  Add a .prettierrc file:     // prettierrc\n   {\n     \"semi\"  :   false  ,\n     \"singleQuote\"  :   true  ,\n     \"tabWidth\"  :   2  ,\n     \"trailingComma\"  :   \"none\"  ,\n     \"printWidth\"  :   100\n   }\n   VS Code Integration\nFor VS Code users, create a .vscode/settings.json file:     // vscode/settings.json\n   {\n     \"editor.formatOnSave\"  :   false  ,\n     \"editor.codeActionsOnSave\"  : {\n       \"source.fixAll.eslint\"  :   true\n     }\n   }\n  Usage     # to check for Linting Errors\n   npm   run   lint\n   # This will only check for errors without making any changes.\n   \n   # Automatically Fix Errors\n   npm   run   lintfix\n   # This will automatically format and fix your code.\n   \n   # After fixing errors, you can verify with:\n   npm   run   lint\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":92,"path":93,"dir":58,"title":94,"description":7,"keywords":95,"body":97},"content:1.Nuxt3 Setup:3.Configurations:6.error-page.md","/nuxt3-setup/configurations/error-page","Error Page",[96],"404 Error Page","  404 Error Page  A 404 Error Page is a standard response when a user tries to access a page that does not exist. This can happen due to:   Incorrect or broken links  Deleted or moved content  Typographical errors in the URL  A well-designed 404 page enhances user experience by guiding users back to relevant sections instead of leaving them frustrated.  Basic 404 Page Setup   Create an error.vue file in your project root (not inside the pages directory):     my-nuxt-project/\n   ├──   app.vue\n   ├──   error.vue    \u003C  --   Place   it   here\n   ├──   pages/\n   │     ├──   index.vue\n   │     └──   ...\n   ├──   layouts/\n   │     ├──   default.vue\n   │     └──   ...\n   └──   ...\n  Add the following code to your   error.vue  file:     \u003C!-- error.vue -->\n     \u003C  template  >\n       \u003C  div   class  =  \"min-h-screen flex items-center justify-center bg-primary-50\"  >\n         \u003C  div\n           class  =  \"max-w-md w-full px-6 py-12 bg-white rounded-lg shadow-lg text-center\"\n         >\n           \u003C  div   class  =  \"mb-8\"  >\n             \u003C  h1   class  =  \"text-9xl font-bold text-gray-200\"  >{{ error.statusCode }}\u003C/  h1  >\n             \u003C  div\n               class  =  \"absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2\"\n             >\n                   \u003C  BaseCustomIcon   name  =  \"error\"   />\n             \u003C/  div  >\n           \u003C/  div  >\n           \u003C!-- Message -->\n           \u003C  h2   class  =  \"text-2xl font-bold text-gray-900 mb-4\"  >{{ error.message   ||   \"Page not found\"   }}\u003C/  h2  >\n           \u003C  p   class  =  \"text-gray-600 mb-8\"  >\n             The page you are looking for doesn't exist or has been moved.\n           \u003C/  p  >\n     \n           \u003C  button   @  click  =  \"  handleError  \"   class  =  \" bg-primary-500 p-3 rounded-lg\"   > Back to Home\u003C/  button  >\n         \u003C/  div  >\n       \u003C/  div  >\n     \u003C/  template  >\n     \n     \u003C  script   setup  >\n     import   { useError }   from   '#app'\n     \n     // Get the error from Nuxt's error handling system\n     const   error   =   useError  ()\n     \n     // Function to clear the error and redirect\n     const   handleError   =   ()   =>   {\n       clearError  ({ redirect:   '/'   })\n     }\n     \u003C/  script  >\n   Create an   check-route.global.js  file in your middleware folder:  Add the following code to your   check-route.global.js  file:     // middleware/check-route.global.js\n   export   default   defineNuxtRouteMiddleware  ((  to  )   =>   {\n     // For demo purposes, list all your valid routes\n     // In a real app, you might check against your router's routes\n     const   validRoutes   =   [  '/'  ,   '/about'  ,   '/contact'  ,   '/products'  ]\n     \n     if   (  !  validRoutes.  includes  (to.path)) {\n       // For specific routes you want to check\n       if   (to.path   ===   '/test'  ) {\n         // This will show the 404 page\n         throw   createError  ({\n           statusCode:   404  ,\n           message:   'The test page does not exist'\n         })\n       }\n     }\n   })\n  The middleware runs automatically once it's created with the .global.js suffix. No additional configuration is needed.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":99,"path":100,"dir":58,"title":101,"description":7,"keywords":102,"body":103},"content:1.Nuxt3 Setup:3.Configurations:7.new-relic.md","/nuxt3-setup/configurations/new-relic","New Relic",[101],"  New Relic  New Relic: is a performance monitoring and observability platform that provides insights into the performance, reliability, and health of your software applications and infrastructure.  It is used to ensure real-time detection of issues, error tracking and Proactive alerting for timely resolution and enhanced system reliability.  How to use   Create a New Relic Application: request the new relic credentials, Log in to your New Relic account and create a new New Relic Browser application by selecting the frontend framework.  Get the New Relic Browser Code: Once your application is created, you'll be provided with a JavaScript snippet that you need to include in your web application.  Add the New Relic Browser JavaScript snippet Code to Your project:     # Create a js file in your public folder and paste the JavaScript snippet Code, remember to remove the script tag\u003Cscript>\u003C/script>\n   /public/newRelic.js\n   Open the app.vue file located in the project directory of your Nuxt 3 project.     \u003C  script  >\n   export   default   defineNuxtComponent  ({\n     setup  () {\n       const   config   =   useRuntimeConfig  ();\n       const   isProduction   =   config.public.env   ===   \"production\"  ;\n   \n       useHead  ({\n         script: isProduction\n           ?   [\n               {\n                 src:   \"/newRelic.js\"  ,\n                 async:   true  ,\n                 defer:   true  ,\n               },\n             ]\n           :   [],\n       });\n     },\n   });\n   \u003C/  script  >\n  Ensure nuxt.config.ts includes:     export   default   defineNuxtConfig  ({\n     runtimeConfig: {\n       public: {\n         env: process.env.  NUXT_PUBLIC_ENV   ||   \"development\"  ,\n       },\n     },\n   });\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":105,"path":106,"dir":107,"title":108,"description":7,"keywords":109,"body":111},"content:1.Nuxt3 Setup:4.Data integration:1.api-error-response.md","/nuxt3-setup/data-integration/api-error-response","data-integration","Api Error Response",[110],"API Error response handling","  API Error response handling  This provides a centralized way to handle API errors by extracting status codes, mapping them to user-friendly messages, and managing session expirations. It ensures consistent error handling across the application.  The composable maintains two reactive state variables:   error , which stores the error message, and   statusCode , which holds the HTTP status code. These values are updated whenever an error occurs.  The   handleError  function processes API errors by extracting the status code from the response. It then assigns an appropriate message from a predefined list or uses the original message for specific errors like 409, 498, 423, 429, and 422. If the error is 401 (Unauthorized), the function clears local storage and redirects the user to the login page with a session expiration message.  The   clearError  function resets both   error  and   statusCode  to null, allowing for error state management.  To use this composable, call   handleError(err)  whenever an API request fails, and use   clearError()  when you need to reset the error state.  Example Structure  Add to composables/error.js     // composables/error.js\n   import   { ref }   from   'vue'\n   \n   export   function   useErrorHandler  () {\n     const   error   =   ref  (  null  )\n     const   statusCode   =   ref  (  null  )\n   \n     const   statusMessages   =   {\n       400  :   'Please check your input and try again.'  ,\n       409  :   'Conflict error. Please try again later.'  ,\n       498  :   'Invalid token. Please log in again.'  ,\n       423  :   'Resource is locked. Please try again later.'  ,\n       429  :   'Too many requests. Please try again later.'  ,\n       422  :   'Unprocessable entity. Please check your input.'  ,\n       default:   'An unexpected error occurred. Please try again.'  ,\n     }\n   \n     function   handleError  (  err  ) {\n       const   errorResponse   =   err.response   ||   err\n       statusCode.value   =   errorResponse.status   ||   500\n       error.value   =   statusMessages[statusCode.value]   ||   errorResponse.message   ||   statusMessages.default\n   \n       if   (statusCode.value   ===   401  ) {\n         localStorage.  clear  ()\n         window.location.href   =   '/login?message=session-expired'\n       }\n   \n           // Handle 409 with original message\n       if   (statusCode.value   ===   409   &&   errorResponse.message) {\n         error.value   =   errorResponse.message;\n       }   else   {\n           error.value   =   errorResponse.message   ?   statusMessages[statusCode.value]   ||   statusMessages.default   :   statusMessages.default;\n       }\n   \n   \n       return   { error: error.value, statusCode: statusCode.value }\n     }\n   \n     function   clearError  () {\n       error.value   =   null\n       statusCode.value   =   null\n     }\n   \n     return   { error, statusCode, handleError, clearError }\n   }\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":113,"path":114,"dir":107,"title":115,"description":7,"keywords":116,"body":117},"content:1.Nuxt3 Setup:4.Data integration:2.endpoints.md","/nuxt3-setup/data-integration/endpoints","Endpoints",[115],"  Endpoints  Create a file in your composable folder   endpoints.js .  This file defines a centralized list of API endpoints used in the application. It helps maintain consistency and makes API calls easier to manage across different modules. The endpoints object categorizes API routes based on their functionality.  Example Structure     // composables/endpoints.js\n   const   endpoints   =   {\n     // Auth Endpoints\n     loginUser:   \"/users/auth\"  ,\n     logoutUser:   \"/users/logout\"  ,\n   \n     // User Endpoints\n     getUserProfile:   \"/users/profile\"  ,\n   };\n   \n   export   { endpoints };\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":119,"path":120,"dir":107,"title":121,"description":7,"keywords":122,"body":124},"content:1.Nuxt3 Setup:4.Data integration:3.api-structure.md","/nuxt3-setup/data-integration/api-structure","Api Structure",[123],"Data fetching","  Data fetching  One of Nuxt 3 key features is the ability to seamlessly integrate data from various sources, making it easy to handle asynchronous data fetching and provide a consistent API for working with data.  Setting up a reusable data integration structure via the composable folder.  The composables folder is used to store reusable functions in a Nuxt 3 project. These functions provide shared logic that can be accessed globally without needing to import them manually in every file.  The process of integrating data into a Nuxt 3 application using a custom composable approach involves handling errors, managing endpoints and API requests.  Example Structure     // composables/api.js\n   \n   import   { ref }   from   'vue'\n   import   { useUserDetailsStore }   from   '@/store/userDetailsStore'\n   import   { storeToRefs, createPinia }   from   'pinia'\n   \n   const   pinia   =   createPinia  ();\n   const   userDetailsStore   =   useUserDetailsStore  (pinia);\n   const   {   token   }   =   storeToRefs  (userDetailsStore);\n   \n   export   function   useApiRequest  () {\n     const   runtimeConfig   =   useRuntimeConfig  ()\n     const   baseURL   =   runtimeConfig.public.  BASE_URL\n   \n     const   sendRequest   =   async   (  params  )   =>   {\n       const   {\n         method   =   'GET'  ,    // HTTP method, default to 'GET'\n         endpoint  ,          // API endpoint\n         data   =   null  ,       // Data for POST, PUT, PATCH requests\n         queryParams   =   {},  // Query parameters\n         customOptions   =   {},   // Additional options (e.g., headers)\n         id   =   null          // Optional ID to append to the URL\n       }   =   params;\n   \n       const   {   handleError   }   =   useErrorHandler  ()\n       const   queryString   =   new   URLSearchParams  (queryParams).  toString  ()\n       let   url;\n       if   (endpoints[endpoint]) {\n         url   =\n           baseURL   +   endpoints[endpoint]   +   (id   ?   `/${  id  }`   :   ''  )   +   (queryString   ?   `?${  queryString  }`   :   \"\"  );\n       }   else   {\n         url   =   baseURL   +   endpoint   +   (queryString   ?   `?${  queryString  }`   :   \"\"  );\n       }\n   \n       const   headers   =   {\n         Authorization:   `Bearer ${  token  .  value  }`  ,\n         'Content-Type'  :   'application/json'  ,\n         ...  customOptions.headers,\n       }\n   \n       const   requestOptions   =   {\n         method,\n         headers,\n         ...  customOptions,\n       }\n     // If it's not a GET request and data exists\n     if   (method   !==   'GET'   &&   data) {\n       // Check if data is an instance of FormData\n       if   (data   instanceof   FormData  ) {\n         // Let the browser automatically handle Content-Type for FormData\n         delete   requestOptions.headers[  'Content-Type'  ];\n         requestOptions.body   =   data;\n       }   else   {\n         // If it's not FormData, handle it as JSON\n         requestOptions.body   =   JSON  .  stringify  (data);\n       }\n     }\n   \n       try   {\n         const   response   =   await   useFetch  (url, requestOptions)\n   \n         if   (response.error.value) {\n   \n           throw   response.error.value.data\n         }\n         return   response.data.value\n       }   catch   (err) {\n         await   handleError  (err)\n         throw   err\n       }\n     }\n   \n     return   { sendRequest }\n   }\n  Functions    useApiRequest : Initializes the API request function.    Parameters :\n    params : An object containing the request details.   method  (string): HTTP method (default is 'GET').   endpoint  (string): API endpoint.   data  (object|null): Data for POST, PUT, PATCH requests.   queryParams  (object): Query parameters.   customOptions  (object): Additional options (e.g., headers).   id  (string|null): Optional ID to append to the URL.   Returns : An object containing the   sendRequest  function.   sendRequest : Sends an API request based on the provided parameters.    Parameters :   Returns : The response data.   Throws : An error if the request fails.  Example Usage Structure     import   { ref }   from   'vue'\n   \n   const   {   handleError   }   =   useErrorHandler  ();\n   const   {   sendRequest   }   =   useApiRequest  ();\n   const   errors   =   ref  ({});\n   \n   const   useApiStructure   =   async   ()   =>   {\n     isLoading.value   =   true  ;\n   \n     try   {\n       const   Data   =   {};\n       const   queryParams   =   {};\n   \n       const   Params   =   {\n           method:   \"\"  ,\n           endpoint:   \"\"  ,\n           data: ,\n           queryParams: queryParams\n         }\n       const   {   data   }   =   await   sendRequest  (Params);\n     }   catch   (err) {\n       handleError  (err);   // Call the error handler\n     }   finally   {\n       isLoading.value   =   false  ;   // Stop loading\n     }\n   };\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":126,"path":127,"dir":107,"title":128,"description":7,"keywords":129,"body":130},"content:1.Nuxt3 Setup:4.Data integration:4.middleware.md","/nuxt3-setup/data-integration/middleware","Middleware",[128],"  Middleware  Middleware in Nuxt 3 allows you to execute custom logic before rendering a page or API route. Middleware functions run before a page or layout is loaded, making them useful for authentication, redirects, logging, or other pre-processing tasks.  Creating Middleware  To create a middleware, add a new file in the   middleware  directory of your Nuxt 3 project. For example, to create an authentication middleware:     // middleware/auth.js\n   import   { useUserDetailsStore }   from   \"@/store/userDetailsStore\"  ;\n   import   { storeToRefs }   from   \"pinia\"  ;\n   \n   export   default   defineNuxtRouteMiddleware  (()   =>   {\n     const   {   user   }   =   storeToRefs  (  useUserDetailsStore  ());\n   \n       const   localUser   =   JSON  .  parse  (localStorage.  getItem  (  'user'  )   ||   '{}'  );\n     \n       user.value   =   localUser;\n    \n   \n       if   (  !  ( user.value ))   return   navigateTo  (  '/login'  );\n     });\n  to use the different types of Middleware  Global Middleware - Applied to all pages and layouts.     //   nuxt.config.ts\n   export   default defineNuxtConfig({\n       router:   {\n           middleware:   [  'auth'  ]\n       }\n   });\n  Route Middleware - Applied to specific pages or layouts.     // layouts/default.vue or pages/index.vue\n   \u003C  script   setup  >\n   definePageMeta({\n       middleware:   'auth'\n   });\n   \u003C/  script  >\n  Conclusion  Nuxt 3 middleware provides a powerful way to handle tasks before rendering pages. By understanding how to create and apply middleware, you can enhance the functionality and security of your Nuxt 3 applications.  For more information, refer to the   Nuxt 3 documentation .  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":132,"path":133,"dir":107,"title":134,"description":7,"keywords":135,"body":137},"content:1.Nuxt3 Setup:4.Data integration:reUseFunction-file.md","/nuxt3-setup/data-integration/reusefunction-file","ReUseFunction File",[136],"reUseFunction File","  reUseFunction File  reUseFunction.ts file (composable/reUseFunction.ts) is an utility file that contains reusable functions that help with common operations. These functions help improve code maintainability by centralizing frequently used logic and providing common functionalities that can be used throughout the application.  Usage in Pages  Each function in this file serves a specific purpose, such as modifying text, cleaning data, formatting values, or retrieving external resources. These utilities are useful in various parts of the application, including UI components, API requests, and state management.\ncommon reusable functions include console logs, date and time formatting, cleaning up queryparameter, currency and amount functions, word/text truncating, getting user initials  Examples     \n   // Recursively clean and return query parameters by removing empty string, null, or undefined values.\n    export   const   useQueryParams   =   (  params  )   =>   {\n       export   const   useQueryParams   =   (  params  )   =>   {\n         const   cleanQueryParams   =   (  obj  )   =>   {\n           const   cleanedParams   =   {};\n           for   (  const   key   in   obj) {\n             const   value   =   obj[key];\n             if   (value   &&   typeof   value   ===   'object'   &&   !  Array.  isArray  (value)   &&   !  (value   instanceof   Date  )) {\n               const   cleanedNested   =   cleanQueryParams  (value);\n               if   (Object.  keys  (cleanedNested).  length   >   0  ) {\n                 cleanedParams[key]   =   cleanedNested;\n               }\n             }\n             else   if   (value   instanceof   Date   ||   (  typeof   value   ===   'string'   &&   !  isNaN  (Date.  parse  (value)))) {\n               cleanedParams[key]   =   value;\n             else   if   (value   !==   ''   &&   value   !==   null   &&   value   !==   undefined  ) {\n               cleanedParams[key]   =   value;\n             }\n           }\n           return   cleanedParams;\n         };\n         return   cleanQueryParams  (params);\n       };\n     // truncate words to return a defined number\n   export   const   truncateWord   =   (  word  ?:   string  ,   maxLength  )   =>   {\n       if   (  !  word)   return   ''  ;   // Return empty string if word is undefined/null/empty\n       return   word.  length   >   maxLength   ?   `${  word  .  slice  (  0  ,   maxLength  )  }...`   :   word;\n   }\n     // formats a given numerical value by adding commas as thousands separators, making large numbers more readable.\n   export   function   amountFunction  (  amount  ) {\n       const   newAmount   =   amount.  toString  ()\n               .  replace  (  /  \\B  (?=(  \\d  {3}  )  +  (?!  \\d  ))  /  g  ,   \",\"  );\n         return   newAmount\n       }\n     // format date and time using momemt\n   \n   install moment using   `npm i moment`\n   then   in   your file    **import   momoment   from   moment.js  **\n   \n    export   const   useFormatTime   =   ()   =>   {\n           const   timeFormatRegex   =   /  ^  (0  ?  [1-9]  |  1  [0-2]  ):(  [0-5][0-9]  ) (am  |  pm)  $  /  i  ;\n   \n           const   formatTime   =   (  timeValue  )   =>   {\n             if   (timeFormatRegex.  test  (timeValue)) {\n               // If the time is already in hh:mm:a format, return it as is\n               return   timeValue;\n             }   else   {\n               // Otherwise, use moment to format it\n               return   moment  (timeValue).  format  (  \"hh:mm a\"  );\n             }\n           };\n   \n           return   { formatTime };\n         };\n     // Map through each word and take the first letter, then join them to form initials\n   export   const   getInitials   =   (  phrase  )   =>   {\n   if   (  !  phrase)   return   ''  ;\n           const   words   =   phrase.  split  (  ' '  );\n           const   initials   =   words.  map  (  word   =>   word[  0  ].  toUpperCase  ()).  join  (  ''  );\n   \n   return   initials;\n   }\n     // console log response/error\n   export   const   useLogger   =   ()   =>   {\n     const   log   =   (  ...  args  )   =>   {\n       console.  log  (  ...  args);\n     };\n     return   { log};\n   };\n  Usage Example  The functions are structured as composables, allowing them to be used globally within Vue components.     const   {   log   }   =   useLogger  ();\n   log  (  \"log data\"  ,   \"data.value\"  );\n   \n   const   {   formatTime   }   =   useFormatTime  ();\n   formatTime  (  \"15:30\"  );   // \"03:30 pm\"\n  Benefits   Reduces code duplication by centralizing common logic.  Improves readability and maintainability of the project.  Ensures consistency in formatting and data handling across the application.  Enhances performance by optimizing repetitive tasks.  This file can be expanded as needed, ensuring that frequently used utility functions remain accessible and reusable.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":139,"path":140,"dir":141,"title":142,"description":7,"keywords":143,"body":144},"content:1.Nuxt3 Setup:5.Common Features:1.custom-icons.md","/nuxt3-setup/common-features/custom-icons","common-features","Custom Icons",[142],"  Custom Icons  The Dynamic Icon Component is designed to efficiently load and display SVG icons dynamically in a Nuxt project. It provides a placeholder while the icon is loading and includes transition effects when the icon is active. This component can also be used to easily change the color of SVG icons dynamically, without needing separate icon files for each color.   Ensure that SVG icons are stored in the   ~/assets/icons/  directory.  Icons are dynamically imported using   import() .  If an icon is missing, an error is logged in the console.  You can change the color of an icon by modifying the fill attribute of the SVG code.  Usage     \u003C  template  >\n     \u003C  template  >\n       \u003C  component   :  is  =  \"  iconComponent  \"   class  =  \"svg-icon\"   v-if  =  \"  iconComponent  \"   />\n     \u003C/  template  >\n   \n     \u003C  script   setup  >\n       const   props   =   defineProps  ({\n         name: {\n           type: String,\n           required:   true  ,\n         },\n       });\n   \n       const   iconComponent   =   shallowRef  (  null  );\n   \n       const   loadIcon   =   async   (  name  )   =>   {\n         try   {\n           iconComponent.  value   =   (\n             await   import  (  `~/assets/icons/${  name  }.svg?component`  )\n           ).default;\n         }   catch   (error) {\n           console.  error  (  `Icon ${  name  } not found in assets/icons directory.`  );\n         }\n       };\n   \n       onMounted  (()   =>   {\n         loadIcon  (props.name);\n       });\n   \n       watch  (\n         ()   =>   props.name,\n         (  newName  )   =>   {\n           loadIcon  (newName);\n         }\n       );\n     \u003C/  script  >\n   \u003C/  template  >\n  Props     Prop Name  Type  Default  Description     name  String  Required  The name of the icon file (without .svg extension).    isActive  Boolean  false  Enables an active state that modifies the icon's color.    placeholderWidth  String  24px  Defines the width of the placeholder.    placeholderHeight  String  24px  Defines the height of the placeholder.    placeholderClass  String  ''  Additional CSS classes for the placeholder.  Example usage     \u003C  template  >\n     \u003C  DynamicIcon\n       name  =  \"settings\"\n       :  isActive  =  \"  true  \"\n       placeholderWidth  =  \"32px\"\n       placeholderHeight  =  \"32px\"\n     />\n   \u003C/  template  >\n  Step to Enable Color Change in Icons  Update your SVG icon to enable color flexibility, modify the fill attribute in your SVG files stored in the ~/assets/icons/ directory. Change any fill=\"#color\" to fill=\"currentColor\". This allows the icon's color to be controlled via CSS, using the color property.     -   SVG   color\n   fill  =  \"#fffff\"\n   \n   -   To   update   SVG   color\n   fill  =  \"currentColor\"\n  Conclusion  The Dynamic Icon Component provides a flexible and efficient solution for handling SVG icons in a Nuxt project. It enhances performance by dynamically loading assets while offering customization options for a seamless UI experience. Also, By using the currentColor property in your SVGs, you can easily modify the icon color dynamically with CSS, making your project more efficient and reducing the need to store multiple versions of the same icon.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":146,"path":147,"dir":141,"title":148,"description":7,"keywords":149,"body":150},"content:1.Nuxt3 Setup:5.Common Features:2.buttons.md","/nuxt3-setup/common-features/buttons","Buttons",[148],"  Buttons  Dynamic buttons in Nuxt 3 allows reusable and customizable button components that can adapt to different styles, sizes, and behaviors based on props. This ensures flexibility while maintaining a consistent UI.  Why Use Dynamic Buttons?  Reusability: A single button component can be used across multiple pages with different styles and functionalities.  Consistency: Ensures a uniform look and feel across the application.  Scalability: Easy to extend with new features such as loading states, icons, or additional styles.  Maintainability: Reduces duplicate code and simplifies updates.  Using a dynamic button component is one of the best approaches for managing buttons in a Nuxt 3 application. It allows for flexibility while maintaining DRY (Don't Repeat Yourself) principles. However, if an application has very specific button requirements, using separate components for different button types might be a better alternative. Ultimately, this approach is optimal for most projects needing scalable UI components.  Creating a Dynamic Button Component  Create a new component BaseButton.vue inside the components folder.     \u003C  template  >\n     \u003C  button\n       :  class  =  \"  computedClasses  \"\n       :  disabled  =  \"  disabled  \"\n       @  click  =  \"  handleClick  \"\n     >\n       \u003C  slot   name  =  \"icon-left\"  >\u003C/  slot  >\n       \u003C  span  >\u003C  slot  >\u003C/  slot  >\u003C/  span  >\n       \u003C  slot   name  =  \"icon-right\"  >\u003C/  slot  >\n     \u003C/  button  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   { computed }   from   'vue'  ;\n   \n   const   props   =   defineProps  ({\n     type: {\n       type: String,\n       default:   'button'  ,\n     },\n     color: {\n       type: String,\n       default:   'primary'  ,\n     },\n     size: {\n       type: String,\n       default:   'md'  ,\n     },\n     disabled: {\n       type: Boolean,\n       default:   false  ,\n     },\n   });\n   \n   const   emit   =   defineEmits  ([  'click'  ]);\n   \n   const   computedClasses   =   computed  (()   =>   {\n     return   [\n       'rounded-lg px-4 py-2 font-semibold transition-all duration-200'  ,\n       props.disabled   ?   'opacity-50 cursor-not-allowed'   :   ''  ,\n       props.color   ===   'primary'   ?   'bg-blue-500 text-white hover:bg-blue-600'   :   ''  ,\n       props.color   ===   'secondary'   ?   'bg-gray-500 text-white hover:bg-gray-600'   :   ''  ,\n       props.size   ===   'sm'   ?   'text-sm py-1 px-2'   :   ''  ,\n       props.size   ===   'lg'   ?   'text-lg py-3 px-6'   :   ''  ,\n     ];\n   });\n   \n   const   handleClick   =   ()   =>   {\n     if   (  !  props.disabled) {\n       emit  (  'click'  );\n     }\n   };\n   \u003C/  script  >\n   \n   \u003C  style   scoped  >\n   button   {\n     display  :   inline-flex  ;\n     align-items  :   center  ;\n     gap  :   0.5  rem  ;\n   }\n   \u003C/  style  >\n  You can use the BaseButton component in different parts of your Nuxt 3 application.  Example Usage     \u003C  script   setup  >\n   import   BaseButton   from   '~/components/BaseButton.vue'  ;\n   \n   const   handleButtonClick   =   ()   =>   {\n     console.  log  (  'Button clicked!'  );\n   };\n   \u003C/  script  >\n   \n   \u003C  template  >\n     \u003C  div  >\n       \u003C  BaseButton   color  =  \"primary\"   size  =  \"md\"   @  click  =  \"  handleButtonClick  \"  >\n         Click Me\n       \u003C/  BaseButton  >\n   \n       \u003C  BaseButton   color  =  \"secondary\"   size  =  \"lg\"   disabled  >\n         Disabled Button\n       \u003C/  BaseButton  >\n     \u003C/  div  >\n   \u003C/  template  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":152,"path":153,"dir":141,"title":154,"description":7,"keywords":155,"body":157},"content:1.Nuxt3 Setup:5.Common Features:3.input field.md","/nuxt3-setup/common-features/input-field","Input Field",[156],"Input fields","  Input fields  This documentation covers reusable Vue components for handling dynamic form inputs in Nuxt 3 projects: a basic input component. These components support various input types and provide consistent styling and behavior.  Dynamic Input Component  A versatile Vue component for Nuxt 3 that supports multiple input types including text, number, textarea, checkbox, and password fields. The component provides consistent styling and behavior across different input types.  Props     Prop Name  Type  Default  Required  Description     name  String  -  Yes  Input field name attribute    placeholder  String  \"\"  No  Enables Placeholder text    required  Boolean  false  No  Whether the field is required    label  String  -  No  Label text above the input    value  String  -  No  Input value    disabled  Boolean  -  No  Disables the input field    type  String  \"text\"  No  Input type ('text', 'number', 'textarea', 'editor', 'checkbox', 'password')     \u003C!-- component FormText.vue -->\n   \u003C  template  >\n     \u003C  div   class  =  \"flex flex-col gap-1 font-inter\"  >\n       \u003C  label   v-if  =  \"  label  \"   class  =  \"body-xsmall text-neutral-500 mb-1\"\n         >{{ label }}\n       \u003C/  label  >\n       \u003C  DatePicker\n         v-if  =  \"  type   ===   'date'\"\n         v-model  =  \"  value  \"\n         :  name  =  \"  name  \"\n         showIcon\n         iconDisplay  =  \"input\"\n         class  =  \"h-10\"\n         :  placeholder  =  \"  placeholder  \"\n         @  change  =  \"  onChange  \"\n         :  class  =  \"  {   'p-invalid'  : errorMessage }  \"\n       />\n   \n       \u003C  Textarea\n         v-else-if  =  \"  type   ===   'textarea'\"\n         v-model  =  \"  value  \"\n         :  name  =  \"  name  \"\n         class  =  \"border px-3 py-2 focus:outline-none text-sm\"\n         autoResize\n         rows  =  \"5\"\n         :  placeholder  =  \"  placeholder  \"\n         @  input  =  \"  onChange  \"\n         :  class  =  \"  {   'p-invalid'  : errorMessage }  \"\n         style  =  \"  box-shadow  :   0  px   1  px   2  px   0  px   #1018280d  \"\n         :  pt  =  \"  {\n           root: {\n             style:   'font-size: 0.875rem; color: #97989A; '\n           }\n         }  \"\n       /  >\n       \u003C  Checkbox\n         v-model  =  \"  value  \"\n         :  name  =  \"  name  \"\n         :  class  =  \"  {   'p-invalid'  : errorMessage }  \"\n         v-else-if  =  \"  type   ===   'checkbox'\"\n         :  binary  =  \"  true  \"\n         :  inputId  =  \"  inputId  \"\n       >\u003C/  Checkbox  >\n       \u003C  Password\n         v-else-if  =  \"  type   ===   'password'\"\n         v-model  =  \"  value  \"\n         :  name  =  \"  name  \"\n         class  =  \"h-10\"\n         :  placeholder  =  \"  placeholder  \"\n         :  type  =  \"  type  \"\n         :  feedback  =  \"  false  \"\n         :  inputProps  =  \"  { autocomplete:   'on'   }  \"\n         toggleMask\n         @  input  =  \"  onChange  \"\n       />\n       \u003C  InputText\n         v-else\n         v-model  =  \"  value  \"\n         :  name  =  \"  name  \"\n         class  =  \"w-full h-10 shadow-none\"\n         :  placeholder  =  \"  placeholder  \"\n         :  class  =  \"  {   'p-invalid'  : errorMessage }  \"\n         @  input  =  \"  onChange  \"\n         :  type  =  \"  type  \"\n         :  disabled  =  \"  disabled  \"\n       />\n     \u003C/  div  >\n   \u003C/  template  >\n   \u003C  script   setup  >\n   const   props   =   defineProps  ({\n     name: { type: String },\n     init: { type: String },\n     placeholder: { type: String, default:   ''   },\n     required: { type: Boolean, default:   false   },\n     disabled: { type: Boolean, default:   false   },\n     label: { type: String },\n     inputId: { type: String },\n     value: { type: String },\n     type: { type: String, default:   'text'   }\n   })\n   \n   // const value = ref(props.init);\n   const   value   =   ref  (props.value)\n   \n   const   errorMessage   =   ref  (  ''  )\n   const   emit   =   defineEmits  ([  'update:modelValue'  ])\n   \n   const   onChange   =   (  e  )   =>   {\n     emit  (  'update:modelValue'  , e.target.value)\n     // validate();\n   }\n   \n   watch  (\n     ()   =>   props.value,\n     (  newValue  )   =>   {\n       value.value   =   newValue\n     }\n   )\n   \u003C/  script  >\n     .p-textarea:enabled:hover   {\n     border-color  :   transparent   !important  ;\n   }\n   .p-inputtext   {\n     border-radius  :   8  px   !important  ;\n     border-color  :   transparent   !important  ;\n     background  :   #fafafa   !important  ;\n     color  :   #121212   !important  ;\n     font-size  :   14  px   !important  ;\n     font-weight  :   600  ;\n   }\n   \n   .dark   {\n     .  p-inputtext   {\n       border-color  :   transparent   !important  ;\n     }\n   }\n   .p-inputtext::placeholder   {\n     color  :   #97989a   !important  ;\n     font-size  :   14  px  ;\n     font-weight  :   600  ;\n   }\n   .p-password   .p-inputtext   {\n     width  :   100  %   !important  ;\n   }\n  Example Usage               \u003C  FormText\n               label  =  \"Name\"\n               v-model  =  \"  name  \"\n               type  =  \"text\"\n               placeholder  =  \"Enter Name\"\n             />\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":159,"path":160,"dir":141,"title":161,"description":7,"keywords":162,"body":164},"content:1.Nuxt3 Setup:5.Common Features:4.Select-field.md","/nuxt3-setup/common-features/select-field","Select Field",[163],"Select fields","  Select fields  Dynamic Select Component  A select component that supports both single and multiple selection modes using PrimeVue's Dropdown and MultiSelect components. The component provides a consistent interface for handling selection inputs with various configuration options.  Props     Prop Name  Type  Default  Required  Description     options  Array    Yes  Array of options to select from    itemText  String  \"name\"  No  Property name for option label    itemValue  String  \"name\"  No  Property name for option value    multiple  Boolean  false  No  Label Enable multiple selection    filter  Boolean  false  No  Enable filtering options    display  String  \"comma\"  No  Display mode for multiple selection    showClear  Boolean  false  No  Show clear selection button     \u003C!-- component FormSelect.vue -->\n   \u003C  template  >\n     \u003C  div   class  =  \"flex flex-col gap-1 rounded-lg\"  >\n       \u003C  label   v-if  =  \"  label  \"   class  =  \" body-xsmall text-neutral-500 mb-2\"\n         >{{ label }}\n       \u003C/  label  >\n       \u003C  MultiSelect\n         :  name  =  \"  name  \"\n         v-model  =  \"  value  \"\n         :  options  =  \"  options  \"\n         :  optionLabel  =  \"  itemText  \"\n         :  optionValue  =  \"  itemValue  \"\n         class  =  \"h-[48px] bg-card-light dark:bg-card-dark\"\n         :  showClear  =  \"  showClear  \"\n         :  placeholder  =  \"  placeholder  \"\n         @  change  =  \"  onChange  \"\n         v-if  =  \"  multiple  \"\n         :  disabled  =  \"  disabled  \"\n       />\n       \u003C  Dropdown\n         :  name  =  \"  name  \"\n         v-model  =  \"  value  \"\n         :  options  =  \"  options  \"\n         :  optionLabel  =  \"  itemText  \"\n         :  optionValue  =  \"  itemValue  \"\n         :  optionLogo  =  \"  itemLogo  \"\n         class  =  \"w-full h-[48px] px-3 dark:bg-[transparent]\"\n         :  showClear  =  \"  showClear  \"\n         :  placeholder  =  \"  placeholder  \"\n         @  change  =  \"  onChange  \"\n         :  option-disabled  =  \"  isOptionDisabled  \"\n         v-else\n       >\n       \u003C  template   v-if  =  \"  action  \"   #  option  =  \"  slotProps  \"  >\n           \u003C  div   class  =  \" flex items-center w-full gap-1\"  >\n             \u003C  div   class  =  \" \"  >\n               \u003C  img\n                 :  src  =  \"  slotProps.option.logo  \"\n                 alt  =  \"logo\"\n                 class  =  \"rounded-[100px] w-6 h-6\"\n               />\n             \u003C/  div  >\n             \u003C  div  >\n               \u003C  p   class  =  \" body-small\"  >{{ slotProps.option.name }}\u003C/  p  >\n               \u003C  p   class  =  \"body-small text-neutral-200\"  >{{ slotProps.option.value }}\u003C/  p  >\n             \u003C/  div  >\n           \u003C/  div  >\n         \u003C/  template  >\n     \u003C/  Dropdown  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \u003C  script   setup  >\n   const   props   =   defineProps  ({\n     name: { type: String, required:   true   },\n     placeholder: { type: String, required:   false   },\n     required: { type: Boolean, default:   false   },\n     action: { type: Boolean, default:   false   },\n     options: { type: Array,   default  : ()   =>   [] },\n     value: { type: [String, Array, Object], required:   true   },\n     itemText: { type: String, default:   \"name\"   },\n     itemValue: { type: String, default:   \"value\"   },\n     itemLogo: { type: String, default:   \"logo\"   },\n     label: { type: String },\n     multiple: { type: Boolean, default:   false   },\n     hideError: { type: Boolean, default:   false   },\n     showClear: { type: Boolean, default:   false   },\n     disabled: { type: Boolean, default:   false   },\n   });\n   const   value   =   ref  (props.multiple   ?   []   :   props.value);\n   const   errorMessage   =   ref  (  \"\"  );\n   \n   const   emit   =   defineEmits  ([  \"update:modelValue\"  ,   \"change\"  ,   \"onAction\"  ]);\n   \n   const   onChange   =   (  e  )   =>   {\n     if   (props.multiple) {\n       // If in multiple mode, update value directly\n       value.value   =   e.value;\n     }   else   {\n       // If in single mode, update value as a string\n       value.value   =   e.value;\n     }\n     emit  (  \"update:modelValue\"  , value.value);\n     emit  (  \"change\"  );\n   };\n   \n   watch  (\n     ()   =>   props.value,\n     (  newValue  )   =>   {\n       value.value   =   newValue;\n     }\n   );\n   \n   const   isOptionDisabled   =   (  option  )   =>   {\n     return   option[props.itemText]   ===   props.disabledOption;   // Disable specific option\n   };\n   \n   // Delete Option API Call\n   const   actionOption   =   async   (  optionValue  )   =>   {\n     emit  (  \"onAction\"  , optionValue);\n   };\n   \u003C/  script  >\n  Example Usage     .p-select-label   {\n     margin-top  :   auto  ;\n     margin-bottom  :   auto  ;\n   }\n   \n   .p-placeholder   {\n     color  :   #97989a   !important  ;\n     font-size  :   14  px  ;\n     font-weight  :   600  ;\n   }\n   \n   .p-select   {\n     border-radius  :   8  px   !important  ;\n     border-color  :   transparent   !important  ;\n     background  :   #fafafa   !important  ;\n     box-shadow  :   none   !important  ;\n     font-size  :   14  px   !important  ;\n     .  p-select-label   {\n       padding  :   0   !important  ;\n       /* color: #121212 !important; */\n       font-weight  :   600  ;\n     }\n     &  ::placeholder   {\n       color  :   #97989a   !important  ;\n     }\n   }\n   \n   \n   .p-select-list   {\n     font-size  :   14  px  ;\n   }\n  Example Usage               \u003C  FormSelect\n               label  =  \"Plan Status\"\n               v-model  =  \"  status  \"\n               placeholder  =  \"Select option\"\n               :  options  =  \"  statusOption  \"\n               type  =  \"text\"\n               name  =  \"status\"\n               item-text  =  \"name\"\n               item-value  =  \"value\"\n             />\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":166,"path":167,"dir":141,"title":168,"description":7,"keywords":169,"body":170},"content:1.Nuxt3 Setup:5.Common Features:5.Form.md","/nuxt3-setup/common-features/form","Form",[168],"  Form  This component provides a structured and validated form for creating or editing subscription plans. It utilizes Vue's Composition API along with Joi for form validation and emits an event upon submission or cancellation.  Features\nInput fields for Plan Name, Subscription Fee, and Plan Status  Field-level validation with real-time error display  Custom form input components (FormText, FormSelect)  Submission loading state handling  Emits close event on cancel or successful validation  Template Structure     \u003C  template  >\n     \u003C  form   @  submit  .  prevent  =  \"  onSubmit  \"  >\n       \u003C!-- Plan Name Field -->\n       \u003C  FormText\n         label  =  \"Plan Name\"\n         v-model  =  \"  planName  \"\n         placeholder  =  \"Standard\"\n         @  input  =  \"  validateField  (  'planName'  )  \"\n       />\n       \u003C  span   v-if  =  \"  errors.planName  \"  >{{ errors.planName }}\u003C/  span  >\n   \n       \u003C!-- Subscription Fee Field -->\n       \u003C  FormText\n         label  =  \"Subscription Fee\"\n         v-model  =  \"  subscription  \"\n         placeholder  =  \"Enter amount\"\n         @  input  =  \"  validateField  (  'subscription'  )  \"\n       />\n       \u003C  span   v-if  =  \"  errors.subscription  \"  >{{ errors.subscription }}\u003C/  span  >\n   \n       \u003C!-- Plan Status Dropdown -->\n       \u003C  FormSelect\n         label  =  \"Plan Status\"\n         v-model  =  \"  status  \"\n         :  options  =  \"  statusOption  \"\n         placeholder  =  \"Select option\"\n       />\n       \u003C  span   v-if  =  \"  errors.status  \"  >{{ errors.status }}\u003C/  span  >\n   \n       \u003C!-- Form Actions -->\n       \u003C  div   class  =  \"flex gap-4 pt-3\"  >\n         \u003C  CommonButton   title  =  \"Cancel\"   type  =  \"button\"   @  click  =  \"  emit  (  'close'  )  \"   />\n         \u003C  CommonButton   title  =  \"Save\"   type  =  \"submit\"   :  loading  =  \"  isLoading  \"   />\n       \u003C/  div  >\n     \u003C/  form  >\n   \u003C/  template  >\n  Script Setup     \u003C  script   setup  >\n   import   { ref, computed }   from   'vue'\n   import   Joi   from   'joi'\n   import   FormSelect   from   '../components/common/input/FormSelect.vue'\n   import   FormText   from   '~/components/common/input/FormText.vue'\n   \n   const   emit   =   defineEmits  ([  'close'  ])\n   \n   const   statusOption   =   [\n     { name:   'Active'  , value:   'Active'   },\n     { name:   'Inactive'  , value:   'Inactive'   }\n   ]\n   \n   const   planName   =   ref  (  ''  )\n   const   subscription   =   ref  (  ''  )\n   const   status   =   ref  (  ''  )\n   const   errors   =   ref  ({})\n   const   isLoading   =   ref  (  false  )\n   \n   const   isFormValid   =   computed  (()   =>   {\n     return   (\n       planName.value   &&   subscription.value   &&   status.value   &&   Object.  keys  (errors.value).  length   ===   0\n     )\n   })\n   \n   // Validation is handled using Joi schema:\n   const   validationSchema   =   Joi.  object  ({\n     planName: Joi.  string  ().  trim  ().  required  ().  messages  ({\n       'any.required'  :   'Plan name is required'  ,\n       'string.empty'  :   'Plan name is required'\n     }),\n     subscription: Joi.  number  ().  min  (  0  ).  required  ().  messages  ({\n       'any.required'  :   'Subscription fee is required'  ,\n       'number.base'  :   'Subscription fee must be a number'  ,\n       'number.min'  :   'Subscription fee must be at least 0'  ,\n       'string.empty'  :   'Subscription fee is required'\n     }),\n     status: Joi.  string  ().  required  ().  messages  ({\n       'any.required'  :   'Plan status is required'  ,\n       'string.empty'  :   'Plan status is required'\n     })\n   })\n   \n   // The validateForm function checks all fields and assigns error messages to the errors object:\n   const   validateForm   =   ()   =>   {\n     const   formData   =   {\n       planName: planName.value,\n       subscription: subscription.value,\n       status: status.value\n     }\n   \n     const   {   error   }   =   validationSchema.  validate  (formData, { abortEarly:   false   })\n     errors.value   =   {}\n   \n     if   (error) {\n       error.details.  forEach  ((  err  )   =>   {\n         errors.value[err.path[  0  ]]   =   err.message\n       })\n     }\n   }\n   \n   // The onSubmit function validates the form and emits the close event if valid:\n   const   onSubmit   =   async   ()   =>   {\n     validateForm  ()\n     if   (isFormValid.value) {\n       // Call Api \n     }\n   }\n   \u003C/  script  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":172,"path":173,"dir":141,"title":174,"description":7,"keywords":175,"body":177},"content:1.Nuxt3 Setup:5.Common Features:6.form-validation.md","/nuxt3-setup/common-features/form-validation","Form Validation",[176],"Validation","  Validation  Joi is a powerful schema validation library that helps enforce rules on user input. In a Nuxt 3 application, Joi can be used to validate form data before submission, ensuring data integrity and preventing incorrect or malicious input.  Installation     # To use Joi in your Nuxt 3 project, install it via npm or yarn:\n   \n   npm   install   joi\n   # or\n   yarn   add   joi\n  Using the Validation Schema in a Component  In your Nuxt 3 component, you can use the validation schema to validate form data.     \u003C  template  >\n   \u003C  form   @  submit  .  prevent  =  \"  onSubmit  \"  >\n       \u003C  div   class  =  \"mb-6\"  >\n           \u003C  FormText\n               label  =  \"Username\"\n               required\n               v-model  =  \"  Username  \"\n               placeholder  =  \"Enter Username\"\n               type  =  \"text\"\n               @  input  =  \"  validateField  (  'Username'  )  \"\n               >\u003C/  FormText  >\n           \u003C  span   v-if  =  \"  errors.username  \"   class  =  \"text-danger-300 pt-8 text-xs\"  >\n           {{ errors.username }}\n           \u003C/  span  >\n          />\n       \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   { ref }   from   'vue'  ;\n   import   Joi   from   \"joi\"  ;\n   const   userName   =   ref  (  \"\"  );\n   \n   const   errors   =   ref  ([]);\n   \n   const   isFormValid   =   computed  (()   =>   {\n     return   userName.value   &&   !  errors.value.userName;\n   });\n   const   validationSchema   =   {\n     userName: Joi.  string  ().  required  ().  messages  ({\n       \"string.empty\"  :   \"Username is required\"  ,\n       \"any.required\"  :   \"Username is required.\"  ,\n     }),\n   };\n   \n   const   validateField   =   (  field  )   =>   {\n     const   value   =   {\n       userName: userName.value,\n     }[field];\n   \n     const   {   error   }   =   validationSchema[field].  validate  (value);\n   \n     if   (error) {\n       errors.value[field]   =   error.details[  0  ].message;\n     }   else   {\n       delete   errors.value[field];\n     }\n   };\n   \n   const   onSubmit   =   async   ()   =>   {\n     Object.  keys  (validationSchema).  forEach  ((  field  )   =>   validateField  (field));\n     if   (isFormValid.value) {\n       // await apiCall();\n     }\n   };\n   \u003C/  script  >\n  Explanation  Using Joi for Validation: The validationSchema object defines the validation rules using Joi. Each field is validated with specific rules, such as required().  Reactive Variables: userName holds the form input value, while errors stores validation error messages.  Validation on Input: The validateField function checks for errors when a user types in the field.  Form Submission: The onSubmit function ensures all fields are validated before allowing form submission.  Computed Property for Form Validity: isFormValid checks whether the form is ready for submission by ensuring there are no validation errors.  Conclusion  By following this guide, you can implement form validation in your Nuxt 3 application using the Joi validation library. This ensures that your form data is validated before submission, providing a better user experience and reducing errors.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":179,"path":180,"dir":141,"title":181,"description":7,"keywords":182,"body":184},"content:1.Nuxt3 Setup:5.Common Features:7.seo optimization.md","/nuxt3-setup/common-features/seo-optimization","Seo Optimization",[183],"SEO Optimization","  SEO Optimization  Search Engine Optimization (SEO) is crucial for improving the visibility of your website on search engines.  Meta Tags  Nuxt 3 allows you to easily manage meta tags using the   useHead  or   useSeoMeta  composable. Meta tags are essential for SEO as they provide search engines with information about your pages.    Server-Side Rendering (SSR) for SEO  By default, Nuxt 3 supports SSR, which ensures search engines can index your content efficiently.     #To enable SSR:\n   export   default defineNuxtConfig({\n     ssr:   true\n   });\n    Meta Tags Management     \u003C!-- # On the script part of your page add your meta tags -->\n   \u003C  script   setup  >\n   // # using useHead\n   useHead  ({\n     title:   'Home - My Nuxt 3 App'\n   });\n   \n   #  using   useSeoMeta\n   useSeoMeta  ({\n     description:   'This is a Nuxt 3 application optimized for SEO'  ,\n     keywords:   'Nuxt3, SEO, Vue, Web Development'  ,\n     ogTitle:   'Home - My Nuxt 3 App'  ,\n     ogDescription:   'Learn how to optimize SEO in Nuxt 3'  ,\n     ogImage:   '/og-image.jpg'  ,\n     twitterCard:   'summary_large_image'\n   });\n   \u003C/  script  >\n  3.  Dynamic SEO Data with useAsyncData     \u003C!-- # For dynamic pages, you can set meta tags based on the content of the page. -->\n   \u003C  script   setup  >\n   const   {   data  :   seoData   }   =   useAsyncData  (  'seo'  , ()   =>   UseFetch  (  '/api/seo'  ));\n   \n   useSeoMeta  ({\n     title: seoData.value?.title,\n     description: seoData.value?.description,\n     ogTitle: seoData.value?.ogTitle,\n     ogDescription: seoData.value?.ogDescription,\n     ogImage: seoData.value?.ogImage\n   });\n   \u003C/  script  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":186,"path":187,"dir":141,"title":188,"description":7,"keywords":189,"body":191},"content:1.Nuxt3 Setup:5.Common Features:8.google recaptcha.md","/nuxt3-setup/common-features/google-recaptcha","Google Recaptcha",[190],"Setting Up Google reCAPTCHA in Nuxt 3","  Setting Up Google reCAPTCHA in Nuxt 3   1. Get reCAPTCHA API Keys  Before integrating reCAPTCHA into your Nuxt 3 project, you need API keys from Google.\nGo to Google reCAPTCHA Admin, Register a new site and select reCAPTCHA v3. Then, Add your domain (for production) or localhost (for development). Copy the Site Key and Secret Key.   2. Install vue-recaptcha-v3 \nTo integrate reCAPTCHA, install the vue-recaptcha-v3 package:     npm   install   vue-recaptcha-v3\n   3. Configure reCAPTCHA in Nuxt 3 \nAdd Plugin for reCAPTCHA by Creating a new plugin file plugins/google-recaptcha.js in your Nuxt 3 project:     // plugins/google-recaptcha.js\n   import   { defineNuxtPlugin }   from   \"#app\"  ;\n   import   { VueReCaptcha }   from   'vue-recaptcha-v3'  ;\n   \n   \n   export   default   defineNuxtPlugin  ((  nuxtApp  )   =>   {\n       const   config   =   useRuntimeConfig  ();\n       nuxtApp.vueApp.  use  (VueReCaptcha, {\n           siteKey: config.public.  CAPTCHA_SITEKEY  ,   // add your sitekey here\n       });\n   });\n  Create a new composables file composables/useGlobalRecaptcha.ts in your Nuxt 3 project:     // composables/useGlobalRecaptcha.ts\n   import   { useReCaptcha }   from   'vue-recaptcha-v3'  ;\n   \n   export   const   useGlobalRecaptcha   =   ()   =>   {\n       const   recaptchaInstance   =   useReCaptcha  ();\n   \n       const   getRecaptchaToken   =   async   (  action  :   string  )   =>   {\n           await   recaptchaInstance?.  recaptchaLoaded  ();\n           const   token   =   await   recaptchaInstance?.  executeRecaptcha  (action);\n           return   token;\n       };\n   \n       return   {\n           getRecaptchaToken,\n       };\n   };\n   3. Use reCAPTCHA in a Component  Example: Protecting a Form Submission  Edit your component (e.g., components/MyForm.vue):     \n   \u003C  script   setup  >\n   const   {   getRecaptchaToken   }   =   useGlobalRecaptcha  ();\n   \n   \n   const   onSubmit   =   async   ()   =>   {\n         const   captcha_token   =   await   getRecaptchaToken  (  \"yourActionHere\"  );\n     const   {   data  ,   error   }   =   await   useFetch  (  '/api/verify-recaptcha'  , {\n       method:   ''  ,\n       body: { \n           captcha_token: captcha_token\n       }\n     });\n   \n     if   (error.value) {\n       console.  error  (  'reCAPTCHA validation failed:'  , error.value);\n     }   else   {\n       console.  log  (  'Form submitted successfully:'  , data.value);\n     }\n   };\n   \u003C/  script  >\n   \n   \u003C  template  >\n     \u003C  form   @  submit  .  prevent  =  \"  onSubmit  \"  >\n       \u003C  button   type  =  \"submit\"  >Submit\u003C/  button  >\n     \u003C/  form  >\n   \u003C/  template  >\n  Deployment Considerations  Ensure your reCAPTCHA keys are set correctly in your environment.  Use separate keys for development and production.  Monitor reCAPTCHA scores to prevent false positives.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":193,"path":194,"dir":141,"title":195,"description":7,"keywords":196,"body":198},"content:1.Nuxt3 Setup:5.Common Features:9.cloudflare captcha.md","/nuxt3-setup/common-features/cloudflare-captcha","Cloudflare Captcha",[197],"Setting Up Cloudflare Turnstile CAPTCHA in Nuxt 3","  Setting Up Cloudflare Turnstile CAPTCHA in Nuxt 3   1. Get reCAPTCHA API Keys  Before integrating CAPTCHA into your Nuxt 3 project, you need API keys from Cloudflare Turnstile.\nGo to Cloudflare Turnstile CAPTCHA Admin, Register a new site. Then, Add your domain (for production) or localhost (for development). Copy the Site Key.   2. composables \nCreate a new composables file composables/useGlobalRecaptcha.ts in your Nuxt 3 project:     // composables/useGlobalRecaptcha.ts\n   import   { ref }   from   'vue'\n   \n   export   const   useTurnstile   =   (  siteKey  :   string  )   =>   {\n     // Ensure a container element exists for Turnstile\n     const   ensureTurnstileContainer   =   ()  :   HTMLElement   =>   {\n       // Check if an existing container exists\n       let   container   =   document.  getElementById  (  'cf-turnstile-container'  )\n       \n       // If not, create a hidden container\n       if   (  !  container) {\n         container   =   document.  createElement  (  'div'  )\n         container.id   =   'cf-turnstile-container'\n         container.style.display   =   'none'\n         document.body.  appendChild  (container)\n       }\n       \n       return   container\n     }\n   \n     // Load Turnstile script dynamically\n     const   loadTurnstileScript   =   ()  :   Promise  \u003C  any  >   =>   {\n       return   new   Promise  ((  resolve  ,   reject  )   =>   {\n         // Check if script is already loaded\n         if   (window.turnstile) {\n           resolve  (window.turnstile)\n           return\n         }\n   \n         const   script   =   document.  createElement  (  'script'  )\n         script.src   =   'https://challenges.cloudflare.com/turnstile/v0/api.js'\n         script.async   =   true\n   \n         script.  onload   =   ()   =>   {\n           if   (window.turnstile) {\n             resolve  (window.turnstile)\n           }   else   {\n             reject  (  new   Error  (  'Turnstile script failed to load'  ))\n           }\n         }\n   \n         script.  onerror   =   ()   =>   {\n           reject  (  new   Error  (  'Failed to load Turnstile script'  ))\n         }\n   \n         document.head.  appendChild  (script)\n       })\n     }\n   \n     // Generate token without rendering visible widget\n     const   generateToken   =   async   ()  :   Promise  \u003C  string  >   =>   {\n       try   {\n         // Ensure script is loaded\n         await   loadTurnstileScript  ()\n   \n         // Create a container element\n         const   container   =   ensureTurnstileContainer  ()\n   \n         // Return a promise that resolves with the token\n         return   new   Promise  ((  resolve  ,   reject  )   =>   {\n           window.turnstile.  render  (container, {\n             sitekey: siteKey,\n             action:   'login'  ,\n             callback  : (  token  )   =>   {\n               // Remove the container after token generation\n               container.  remove  ()\n               resolve  (token)\n             },\n             'error-callback'  : (  error  )   =>   {\n               container.  remove  ()\n               reject  (error)\n             }\n           })\n         })\n       }   catch   (error) {\n         console.  error  (  'Token generation error:'  , error)\n         throw   error\n       }\n     }\n   \n     return   {\n       generateToken\n     }\n   }\n   3. Use CAPTCHA in a Component  Example: Protecting a Form Submission  Edit your component (e.g., components/MyForm.vue):     \n   \u003C  script   setup  >\n   const   config   =   useRuntimeConfig  ();\n   const   SITE_KEY   =   config.public.  CAPTCHA_SITEKEY  ;\n   \n   // Initialize Turnstile composable\n   const   {   generateToken   }   =   useTurnstile  (  SITE_KEY  );\n   \n   \n   const   onSubmit   =   async   ()   =>   {\n             // Generate token without visible challenge\n       const   captcha_token   =   await   generateToken  ();\n     const   {   data  ,   error   }   =   await   useFetch  (  '/api/verify-recaptcha'  , {\n       method:   ''  ,\n       body: { \n           captcha_token: captcha_token\n       }\n     });\n   \n     if   (error.value) {\n       console.  error  (  'reCAPTCHA validation failed:'  , error.value);\n     }   else   {\n       console.  log  (  'Form submitted successfully:'  , data.value);\n     }\n   };\n   \u003C/  script  >\n   \n   \u003C  template  >\n     \u003C  form   @  submit  .  prevent  =  \"  onSubmit  \"  >\n       \u003C  button   type  =  \"submit\"  >Submit\u003C/  button  >\n     \u003C/  form  >\n   \u003C/  template  >\n  Deployment Considerations  Ensure your CAPTCHA keys are set correctly in your environment.  Use separate keys for development and production.  Monitor CAPTCHA scores to prevent false positives.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":200,"path":201,"dir":141,"title":202,"description":7,"keywords":203,"body":204},"content:1.Nuxt3 Setup:5.Common Features:10.cookie-consent.md","/nuxt3-setup/common-features/cookie-consent","Cookie Consent",[202],"  Cookie Consent  Cookie consent is essential for ensuring compliance with privacy regulations such as the GDPR and CCPA. it involves creating a Cookie Banner – To inform users about cookies and provide options to accept,decline or customize settings.  This guide will walk you through implementing a cookie consent system .  Implementation   Create a Cookie Consent Component     \u003C  template  >\n     \u003C  div\n       v-if  =  \"cookieAccepted !== null && !cookieAccepted\"\n       class  =  \"fixed bottom-0 left-0 w-full bg-black-300 text-white py-6 px-4 md:px-8 lg:px-16 flex flex-col md:flex-row justify-between items-center gap-4 shadow-lg z-50 backdrop-blur-sm\"\n     >\n       \u003C  div   class  =  \"text-base md:text-lg max-w-3xl\"  >\n         We use cookies to enhance your experience. By continuing to use our\n         website, you acknowledge that you have read and understand our\n         \u003C  NuxtLink\n           to  =  \"/privacy-policy\"\n           class  =  \"text-blue-400 hover:text-blue-200 underline underline-offset-2\"\n         >\n           Privacy Policy\n         \u003C/  NuxtLink  >\n         and\n         \u003C  NuxtLink\n           to  =  \"/terms-of-service\"\n           class  =  \"text-blue-400 hover:text-blue-200 underline underline-offset-2\"\n         >\n           Terms of Service\n         \u003C/  NuxtLink  >\n         , and consent to our use of cookies.\n       \u003C/  div  >\n       \u003C  div   class  =  \"flex gap-3 whitespace-nowrap\"  >\n         \u003C  button\n           @click=\"acceptCookies\"\n           class  =  \"bg-blue-600 hover:bg-blue-500 text-white px-6 py-2.5 rounded-lg transition-colors duration-200 font-medium\"\n         >\n           Accept\n         \u003C/  button  >\n         \u003C  button\n           @click=\"declineCookies\"\n           class  =  \"bg-red-500 hover:bg-red-400 text-white px-6 py-2.5 rounded-lg transition-colors duration-200 font-medium\"\n         >\n           Decline\n         \u003C/  button  >\n       \u003C/  div  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import { ref, onMounted } from \"vue\";\n   \n   const emit = defineEmits([\"consent-update\"]);\n   const cookieAccepted = ref(null);\n   const COOKIE_CONSENT_KEY = \"cookieConsent\";\n   const CONSENT_DURATION_DAYS = 30;\n   \n   onMounted(() => {\n     checkCookieConsent  ();\n   });\n   \n   const checkCookieConsent = () => {\n     const storedConsent   =   localStorage.  getItem  (  COOKIE_CONSENT_KEY  );\n     if   (  !  storedConsent) {\n       cookieAccepted.value   =   false  ;\n       return;\n     }\n   \n     try {\n       const { value, timestamp } = JSON.parse(storedConsent);\n       const now   =   new   Date  ().  getTime  ();\n       const daysSinceConsent   =   (now   -   timestamp)   /   (  1000   *   60   *   60   *   24  );\n   \n       if   (  daysSinceConsent   \u003C   CONSENT_DURATION_DAYS  ) {\n         cookieAccepted.value   =   true  ;\n       } else {\n         localStorage.  removeItem  (  COOKIE_CONSENT_KEY  );\n         cookieAccepted.value   =   false  ;\n       }\n     }   catch   (error) {\n       console.error(  \"Error parsing cookie consent:\"  , error);\n       localStorage.removeItem(COOKIE_CONSENT_KEY);\n       cookieAccepted.value   =   false  ;\n     }\n   };\n   \n   const saveConsent = (value) => {\n     const consent   =   {\n       value,\n       timestamp:   new   Date  ().  getTime  (),\n     };\n     localStorage.  setItem  (  COOKIE_CONSENT_KEY  ,   JSON  .  stringify  (consent));\n     cookieAccepted.value   =   true  ;\n   };\n   \n   const acceptCookies = () => {\n     saveConsent  (  \"accepted\"  );\n     emit  (  \"consent-update\"  ,   \"accepted\"  );\n   };\n   \n   const declineCookies = () => {\n     saveConsent  (  \"declined\"  );\n     emit  (  \"consent-update\"  ,   \"declined\"  );\n   };\n   \u003C/  script  >\n   Add the Component to Layouts  Include CookieConsent.vue in your default layout (layouts/default.vue) to display the banner on all pages.     \u003C  template  >\n     \u003C  div  >\n       \u003C  slot   />\n       \u003C  CookieConsent   />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import CookieConsent from '~/components/CookieConsent.vue';\n   \u003C/  script  >\n  This implementation ensures users can give or revoke cookie consent, complying with privacy regulations. You can enhance it by categorizing cookies and integrating a consent management tool if needed.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":206,"path":207,"dir":141,"title":208,"description":7,"keywords":209,"body":211},"content:1.Nuxt3 Setup:5.Common Features:11.loaders.md","/nuxt3-setup/common-features/loaders","Loaders",[210],"Page loader","  Page loader  A reusable loading overlay component that displays a progress spinner on a semi-transparent background. This component is designed to indicate loading states across your Nuxt 3 application.  1. Create a component base/loadingOverlay.vue with a styling that best suit project need.     \u003C  template  >\n       \u003C  div\n           class  =  \"fixed left-0 top-0 h-full w-full z-50 flex justify-center items-center bg-[#000000a6]\"\n       >\n           \u003C  ProgressSpinner   />\n       \u003C/  div  >\n   \u003C/  template  >\n  2. Ensure PrimeVue's ProgressSpinner is properly imported in your Nuxt configuration primevue plugin  Usage Examples     \u003C!-- pages/users.vue -->\n   \u003C  template  >\n     \u003C  div  >\n       \u003C  LoadingOverlay   v-if  =  \"  loading  \"   />\n       \u003C  div   class  =  \"users-content\"  >\n         \u003C!-- Your page content -->\n       \u003C/  div  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   const   loading   =   ref  (  true  );\n   \n   onMounted  (  async   ()   =>   {\n     try   {\n       await   fetchUsers  ();\n     }   finally   {\n       loading.value   =   false  ;\n     }\n   });\n   \u003C/  script  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":213,"path":214,"dir":141,"title":215,"description":7,"keywords":216,"body":218},"content:1.Nuxt3 Setup:5.Common Features:12.themes.md","/nuxt3-setup/common-features/themes","Themes",[217],"Theme","  Theme  This guide will help you implementthemeing in your Nuxt 3 project.\nWe'll use a combination of Tailwind CSS for styling and Vue's reactive system to toggle between light and dark modes.  Configure Tailwind CSS by editing the   tailwind.config.js  file:     module  .  exports   =   {\n     darkMode:   \"class\"  ,   // Enable dark mode support\n     content: [\n       \"./components/**/*.{js,vue,ts}\"  ,\n       \"./layouts/**/*.vue\"  ,\n       \"./pages/**/*.vue\"  ,\n       \"./plugins/**/*.{js,ts}\"  ,\n       \"./app.vue\"  ,\n       \"./error.vue\"  ,\n     ],\n     theme: {\n       extend: {\n         colors: {\n           primary: {\n             50  :   \"rgb(var(--primary-50) / \u003Calpha-value>)\"  ,\n             75  :   \"rgb(var(--primary-75) / \u003Calpha-value>)\"  ,\n             100  :   \"rgb(var(--primary-100) / \u003Calpha-value>)\"  ,\n             200  :   \"rgb(var(--primary-200) / \u003Calpha-value>)\"  ,\n             300  :   \"rgb(var(--primary-300) / \u003Calpha-value>)\"  ,\n             400  :   \"rgb(var(--primary-400) / \u003Calpha-value>)\"  ,\n             500  :   \"rgb(var(--primary-500) / \u003Calpha-value>)\"  ,\n           },\n           neutral: {\n             10  :   \"rgb(var(--neutral-10) / \u003Calpha-value>)\"  ,\n             20  :   \"rgb(var(--neutral-20) / \u003Calpha-value>)\"  ,\n             30  :   \"rgb(var(--neutral-30) / \u003Calpha-value>)\"  ,\n             50  :   \"rgb(var(--neutral-50) / \u003Calpha-value>)\"  ,\n             100  :   \"rgb(var(--neutral-100) / \u003Calpha-value>)\"  ,\n             200  :   \"rgb(var(--neutral-200) / \u003Calpha-value>)\"  ,\n             300  :   \"rgb(var(--neutral-300) / \u003Calpha-value>)\"  ,\n             500  :   \"rgb(var(--neutral-500) / \u003Calpha-value>)\"  ,\n           },\n           success: {\n             50  :   \"rgb(var(--success-50) / \u003Calpha-value>)\"  ,\n             75  :   \"rgb(var(--success-75) / \u003Calpha-value>)\"  ,\n             100  :   \"rgb(var(--success-100) / \u003Calpha-value>)\"  ,\n             200  :   \"rgb(var(--success-200) / \u003Calpha-value>)\"  ,\n             300  :   \"rgb(var(--success-300) / \u003Calpha-value>)\"  ,\n             400  :   \"rgb(var(--success-400) / \u003Calpha-value>)\"  ,\n             500  :   \"rgb(var(--success-500) / \u003Calpha-value>)\"  ,\n           },\n           danger: {\n             50  :   \"rgb(var(--danger-50) / \u003Calpha-value>)\"  ,\n             75  :   \"rgb(var(--danger-75) / \u003Calpha-value>)\"  ,\n             100  :   \"rgb(var(--danger-100) / \u003Calpha-value>)\"  ,\n             200  :   \"rgb(var(--danger-200) / \u003Calpha-value>)\"  ,\n             300  :   \"rgb(var(--danger-300) / \u003Calpha-value>)\"  ,\n             400  :   \"rgb(var(--danger-400) / \u003Calpha-value>)\"  ,\n             500  :   \"rgb(var(--danger-500) / \u003Calpha-value>)\"  ,\n           },\n           warning: {\n             50  :   \"rgb(var(--warning-50) / \u003Calpha-value>)\"  ,\n             75  :   \"rgb(var(--warning-75) / \u003Calpha-value>)\"  ,\n             100  :   \"rgb(var(--warning-100) / \u003Calpha-value>)\"  ,\n             200  :   \"rgb(var(--warning-200) / \u003Calpha-value>)\"  ,\n             300  :   \"rgb(var(--warning-300) / \u003Calpha-value>)\"  ,\n             400  :   \"rgb(var(--warning-400) / \u003Calpha-value>)\"  ,\n             500  :   \"rgb(var(--warning-500) / \u003Calpha-value>)\"  ,\n           },\n           info: {\n             50  :   \"rgb(var(--info-50) / \u003Calpha-value>)\"  ,\n             75  :   \"rgb(var(--info-75) / \u003Calpha-value>)\"  ,\n             100  :   \"rgb(var(--info-100) / \u003Calpha-value>)\"  ,\n             200  :   \"rgb(var(--info-200) / \u003Calpha-value>)\"  ,\n             300  :   \"rgb(var(--info-300) / \u003Calpha-value>)\"  ,\n             400  :   \"rgb(var(--info-400) / \u003Calpha-value>)\"  ,\n             500  :   \"rgb(var(--info-500) / \u003Calpha-value>)\"  ,\n           },\n         },\n       },\n     },\n     plugins: [],\n   };\n  Add this to   colors.css  file:       /* assets/css/colors.css */\n   \n   :root   {\n     /* Primary Colors */\n     --primary-50  :   253   248   233  ;    /* #FDF8E9 */\n     --primary-75  :   249   235   189  ;    /* #F9EBBD */\n     --primary-100  :   245   222   146  ;   /* #F5DE92 */\n     --primary-200  :   241   208   102  ;   /* #F1D066 */\n     --primary-300  :   235   188   36  ;    /* #EBBC24 */\n     --primary-400  :   188   150   29  ;    /* #BC961D */\n     --primary-500  :   141   113   22  ;    /* #8D7116 */\n   \n     /* Neutral Colors */\n     --neutral-10  :   255   255   255  ;    /* #FFFFFF */\n     --neutral-20  :   250   250   250  ;    /* #FAFAFA */\n     --neutral-30  :   245   245   245  ;    /* #F5F5F5 */\n     --neutral-50  :   232   233   233  ;    /* #E8E9E9 */\n     --neutral-100  :   225   225   225  ;   /* #E1E1E1 */\n     --neutral-200  :   151   152   154  ;   /* #97989A */\n     --neutral-300  :   58   58   58  ;      /* #3A3A3A */\n     --neutral-500  :   18   18   18  ;      /* #121212 */\n   \n     /* Success Colors */\n     --success-50  :   233   248   238  ;    /* #E9F8EE */\n     --success-75  :   164   226   187  ;    /* #A4E2BB */\n     --success-100  :   126   214   158  ;   /* #7ED69E */\n     --success-200  :   70   196   116  ;    /* #46C474 */\n     --success-300  :   32   184   88  ;     /* #20B858 */\n     --success-400  :   22   129   62  ;     /* #16813E */\n     --success-500  :   20   112   54  ;     /* #147036 */\n   \n     /* Danger Colors */\n     --danger-50  :   253   231   231  ;     /* #FDE7E7 */\n     --danger-75  :   248   158   158  ;     /* #F89E9E */\n     --danger-100  :   246   118   118  ;    /* #F67676 */\n     --danger-200  :   242   58   58  ;      /* #F23A3A */\n     --danger-300  :   239   18   18  ;      /* #EF1212 */\n     --danger-400  :   167   13   13  ;      /* #A70D0D */\n     --danger-500  :   146   11   11  ;      /* #920B0B */\n   \n     /* Warning Colors */\n     --warning-50  :   255   249   230  ;    /* #FFF9E6 */\n     --warning-75  :   255   229   151  ;    /* #FFE597 */\n     --warning-100  :   255   218   108  ;   /* #FFDA6C */\n     --warning-200  :   255   203   44  ;    /* #FFCB2C */\n     --warning-300  :   255   192   1  ;     /* #FFC001 */\n     --warning-400  :   179   134   1  ;     /* #B38601 */\n     --warning-500  :   156   117   1  ;     /* #9C7501 */\n   \n     /* Info Colors */\n     --info-50  :   231   246   253  ;      /* #E7F6FD */\n     --info-75  :   156   218   246  ;      /* #9CDAF6 */\n     --info-100  :   115   203   242  ;     /* #73CBF2 */\n     --info-200  :   55   180   237  ;      /* #37B4ED */\n     --info-300  :   14   165   233  ;      /* #0EA5E9 */\n     --info-400  :   10   115   163  ;      /* #0A73A3 */\n     --info-500  :   9   101   142  ;       /* #09658E */\n   }\n   \n   /* Dark mode overrides */\n   .dark   {\n     /* Primary Colors (Dark Mode) */\n     --primary-50  :   141   113   22  ;     /* #8D7116 - Darkest yellow */\n     --primary-75  :   188   150   29  ;     /* #BC961D */\n     --primary-100  :   235   188   36  ;    /* #EBBC24 */\n     --primary-200  :   241   208   102  ;   /* #F1D066 */\n     --primary-300  :   235   188   36  ;    /* #EBBC24 */\n     --primary-400  :   249   235   189  ;   /* #F9EBBD */\n     --primary-500  :   253   248   233  ;   /* #FDF8E9 - Lightest yellow */\n     \n     /* Neutral Colors (Dark Mode) */\n     --neutral-10  :   18   18   18  ;       /* #121212 - Darkest gray */\n     --neutral-20  :   58   58   58  ;       /* #3A3A3A */\n     --neutral-30  :   151   152   154  ;    /* #97989A */\n     --neutral-50  :   225   225   225  ;    /* #E1E1E1 */\n     --neutral-100  :   232   233   233  ;   /* #E8E9E9 */\n     --neutral-200  :   245   245   245  ;   /* #F5F5F5 */\n     --neutral-300  :   250   250   250  ;   /* #FAFAFA */\n     --neutral-500  :   255   255   255  ;   /* #FFFFFF - White */\n   \n     /* Success, Danger, Warning, and Info colors can stay the same or be slightly adjusted */\n   }\n  Create Theme Toggle  To enable light and dark mode switching in your Nuxt 3 project, update   index.vue  to include a toggle switch.  This will allow users to seamlessly switch between themes.     \u003C  template  >\n     \u003C  div   class  =  \" bg-neutral-10 h-screen\"  >\n       \u003C  h1   class  =  \"text-3xl font-bold underline text-red-500\"  >Hello world!\u003C/  h1  >\n       \u003C  div   class  =  \"p-4 flex items-center\"  >\n             \u003C  InputSwitch   v-model  =  \"  checked  \"   class  =  \"\"   @  change  =  \"  themeChange  \"   />\n             \u003C  p   class  =  \"ml-3 text-[#676A6C] dark:text-[#E8E9E9]\"  >Light Mode\u003C/  p  >\n       \u003C/  div  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   const   checked   =   ref  (  false  );\n   \n   const   themeChange   =   ()   =>   {\n     if   (localStorage.  getItem  (  \"color-theme\"  )) {\n       if   (localStorage.  getItem  (  \"color-theme\"  )   ===   \"light\"  ) {\n         document.documentElement.classList.  add  (  \"dark\"  );\n         localStorage.  setItem  (  \"color-theme\"  ,   \"dark\"  );\n       }   else   {\n         document.documentElement.classList.  remove  (  \"dark\"  );\n         localStorage.  setItem  (  \"color-theme\"  ,   \"light\"  );\n       }\n     }   else   {\n       if   (document.documentElement.classList.  contains  (  \"dark\"  )) {\n         document.documentElement.classList.  remove  (  \"dark\"  );\n         localStorage.  setItem  (  \"color-theme\"  ,   \"light\"  );\n       }   else   {\n         document.documentElement.classList.  add  (  \"dark\"  );\n         localStorage.  setItem  (  \"color-theme\"  ,   \"dark\"  );\n       }\n     }\n   };\n   \u003C/  script  >\n  Retain User Preference  To ensure the theme preference persists across the entire Nuxt 3 application, update app.vue.  This ensures a seamless user experience, even after page reloads.     \u003C  script  >\n   export   default   defineNuxtComponent  ({\n     setup  () {\n       const   config   =   useRuntimeConfig  ();\n       const   isProduction   =   config.public.env   ===   \"production\"  ;\n   \n       onBeforeMount  (  async   ()   =>   {\n   \n       if   (\n       localStorage.  getItem  (  'color-theme'  )   ===   'dark'   ||\n       (  !  (  'color-theme'   in   localStorage)   &&\n         window.  matchMedia  (  '(prefers-color-scheme: dark)'  ).matches)\n       ) {\n       document.documentElement.classList.  add  (  'dark'  );\n       }   else   {\n       document.documentElement.classList.  remove  (  'dark'  );\n       }\n   \n     });\n   \n       useHead  ({\n         script: isProduction\n           ?   [\n               {\n                 src:   \"/newRelic.js\"  ,\n                 async:   true  ,\n                 defer:   true  ,\n               },\n             ]\n           :   [],\n       });\n     },\n   });\n   \u003C/  script  >\n  Add this also to   app.vue     // app.vue\n   \u003C  style  >\n   @import   './assets/css/colors.css'  ;\n   \u003C/  style  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":220,"path":221,"dir":141,"title":222,"description":7,"keywords":223,"body":225},"content:1.Nuxt3 Setup:5.Common Features:13.OTPInput.md","/nuxt3-setup/common-features/otpinput","OTPInput",[224],"OTP Input Component","  OTP Input Component  Features\nCustomizable OTP length (length prop)  Fully controlled input via v-model (modelValue)  Auto-focus on next/previous inputs  Smart paste support  Only numeric input allowed  Focus styling and input clearing with backspace     \u003C  template  >\n       \u003C  div   class  =  \"otp-input-container\"  >\n         \u003C  div   v-for  =  \"  (digit, index)   in   otpArray  \"   :  key  =  \"  index  \"   class  =  \"otp-digit-container\"  >\n           \u003C  input\n             ref  =  \"otpInputs\"\n             type  =  \"tel\"\n             maxlength  =  \"1\"\n             pattern  =  \"[0-9]*\"\n             inputmode  =  \"numeric\"\n             v-model  =  \"  otpArray[index]  \"\n             class  =  \"otp-digit-input\"\n             :  data-index  =  \"  index  \"\n             placeholder  =  \"-\"\n             @  input  =  \"  handleInput  (index)  \"\n             @  keydown  =  \"  handleKeyDown  ($event, index)  \"\n             @  paste  =  \"  handlePaste  \"\n             @  focus  =  \"  handleFocus  \"\n           />\n         \u003C/  div  >\n       \u003C/  div  >\n     \u003C/  template  >\n     \n     \u003C  script   setup  >\n     import   { ref, computed, watch, onMounted }   from   'vue'  ;\n     \n     const   props   =   defineProps  ({\n       length: {\n         type: Number,\n         default:   4\n       },\n       modelValue: {\n         type: String,\n         default:   ''\n       }\n     });\n     \n     const   emit   =   defineEmits  ([  'update:modelValue'  ]);\n     \n     const   otpInputs   =   ref  ([]);\n     const   otpArray   =   ref  (  Array  (props.  length  ).  fill  (  ''  ));\n     \n     // Watch for external modelValue changes\n     watch  (()   =>   props.modelValue, (  newValue  )   =>   {\n       if   (newValue) {\n         const   valueArray   =   newValue.  toString  ().  split  (  ''  );\n         otpArray.value   =   Array  (props.  length  ).  fill  (  ''  ).  map  ((  _  ,   i  )   =>   valueArray[i]   ||   ''  );\n       }   else   {\n         otpArray.value   =   Array  (props.  length  ).  fill  (  ''  );\n       }\n     }, { immediate:   true   });\n     \n     // Watch internal array for changes to emit\n     watch  (otpArray, (  newArray  )   =>   {\n       const   joinedValue   =   newArray.  join  (  ''  );\n       emit  (  'update:modelValue'  , joinedValue);\n     }, { deep:   true   });\n     \n     // Computed property to check if OTP is completed\n     const   isCompleted   =   computed  (()   =>   {\n       return   otpArray.value.  every  (  digit   =>   digit   !==   ''  )   &&   otpArray.value.  length   ===   props.  length  ;\n     });\n     \n     // Handle input in a field\n     const   handleInput   =   (  index  )   =>   {\n       // Only allow numbers\n       otpArray.value[index]   =   otpArray.value[index].  replace  (  /  [  ^  0-9]  /  g  ,   ''  );\n       \n       // Move to next input if current one has a value\n       if   (otpArray.value[index]   !==   ''   &&   index   \u003C   props.  length   -   1  ) {\n         otpInputs.value[index   +   1  ].  focus  ();\n       }\n     };\n     \n     // Handle keydown events\n     const   handleKeyDown   =   (  event  ,   index  )   =>   {\n       // Handle backspace\n       if   (event.key   ===   'Backspace'  ) {\n         if   (otpArray.value[index]   ===   ''  ) {\n           // Current field is empty, move to previous field and select its content\n           if   (index   >   0  ) {\n             event.  preventDefault  ();\n             otpInputs.value[index   -   1  ].  focus  ();\n             otpInputs.value[index   -   1  ].  select  ();\n           }\n         }\n       } \n       // Handle left arrow key\n       else   if   (event.key   ===   'ArrowLeft'  ) {\n         if   (index   >   0  ) {\n           event.  preventDefault  ();\n           otpInputs.value[index   -   1  ].  focus  ();\n           otpInputs.value[index   -   1  ].  select  ();\n         }\n       } \n       // Handle right arrow key\n       else   if   (event.key   ===   'ArrowRight'  ) {\n         if   (index   \u003C   props.  length   -   1  ) {\n           event.  preventDefault  ();\n           otpInputs.value[index   +   1  ].  focus  ();\n           otpInputs.value[index   +   1  ].  select  ();\n         }\n       }\n     };\n     \n     // Handle paste event\n     const   handlePaste   =   (  event  )   =>   {\n       event.  preventDefault  ();\n       const   pastedData   =   event.clipboardData.  getData  (  'text'  );\n       const   pastedDigits   =   pastedData.  replace  (  /  \\D  /  g  ,   ''  ).  split  (  ''  );\n       \n       for   (  let   i   =   0  ; i   \u003C   props.  length   &&   i   \u003C   pastedDigits.  length  ; i  ++  ) {\n         otpArray.value[i]   =   pastedDigits[i];\n       }\n       \n       // Focus on the next empty input or the last one\n       const   nextEmptyIndex   =   otpArray.value.  findIndex  (  digit   =>   digit   ===   ''  );\n       if   (nextEmptyIndex   !==   -  1  ) {\n         otpInputs.value[nextEmptyIndex].  focus  ();\n       }   else   {\n         otpInputs.value[props.  length   -   1  ].  focus  ();\n       }\n     };\n     \n     // Handle focus event\n     const   handleFocus   =   (  event  )   =>   {\n       // Select the content when focused\n       event.target.  select  ();\n     };\n     \n     // Focus on first input when mounted\n     onMounted  (()   =>   {\n       if   (otpInputs.value.  length   &&   otpArray.value[  0  ]   ===   ''  ) {\n         otpInputs.value[  0  ].  focus  ();\n       }\n     });\n     \u003C/  script  >\n     .otp-input-container   {\n     @  apply   flex   items-center   justify-between   sm  :gap-4 gap-2;\n   }\n     \n     .otp-digit-container   {\n       flex  :   1  ;\n     }\n     \n     .otp-digit-input   {\n       width  :   100  %  ;\n       height  :   40  px  ;\n       text-align  :   center  ;\n       font-size  :   24  px  ;\n       border  :   1  px   solid   #E1E1E1  ;\n       border-radius  :   8  px  ;\n       background-color  :   transparent  ;\n       -moz-appearance  : textfield;\n       box-sizing  :   border-box  ;\n     }\n     \n     .otp-digit-input:focus   {\n       border-color  :   #EBBC24  ;\n       outline  :   none  ;\n     }\n     \n     .otp-digit-input::-webkit-inner-spin-button  ,\n     .otp-digit-input::-webkit-outer-spin-button   {\n       -webkit-appearance  :   none  ;\n       margin  :   0  ;\n     }\n  Usage         \u003C  div   class  =  \"card gap-4 w-full mb-8\"  >\n         \u003COtpInput v-model=\"otpCode\" :length=\"4\" />\n       \u003C/  div  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":227,"path":228,"dir":141,"title":229,"description":7,"keywords":230,"body":232},"content:1.Nuxt3 Setup:5.Common Features:14.filter.md","/nuxt3-setup/common-features/filter","Filter",[231],"Filter Modal","  Filter Modal  The Filter Component is a reusable modal that provides a menu with customizable filter options. It allows users to filter data based on different criteria and apply those filters to the parent component.  Features   Popup overlay menu with filter options  Support for dropdown select filters  Filter clearing functionality  Reset all filters option  Apply filters button  Usage    ModalFilterMenu.vue  - This is the main filter menu component that renders a popup overlay with filter options.     \n   \u003C  template  >\n     \u003C  OverlayPanel\n       ref  =  \"op\"\n       id  =  \"overlay_menu\"\n       :popup  =  \"true\"\n       class  =  \"w-[240px] rounded-lg\"\n     >\n       \u003C!  --   Modal   Header   --  >\n       \u003C  div  >\n         \u003C  div\n           class  =  \"flex items-center justify-between px-4 py-[10px] bg-neutral-20\"\n         >\n           \u003C  div   class=\"flex items-center gap-3\"  >\n             \u003C  h5   class=\"body-normal font-medium text-neutral-500\"  >  Filter  \u003C  /h  5>\n           \u003C  /div  >\n           \u003C  button   @click=\"toggle\"  >\n             \u003C  i\n               class  =  \"pi pi-times text-neutral-500 text-xs hover:bg-primary-50 p-2 hover:rounded-full\"\n             /  >\n           \u003C  /button  >\n         \u003C  /div  >\n       \u003C  /div  >\n       \u003C  div   class=\"p-4\"  >\n         \u003C  div   v-for=\"(item, index) in items\"   :key=\"index\"   class=\"mb-4\"  >\n           \u003C  div   class=\"mb-2 flex justify-between items-center\"  >\n             \u003C  label   class=\"body-small\"  >  {{   item.label   }}   \u003C  /labe  l  >\n             \u003C  p\n               @click  =  \"handleClear(index)\"\n               class  =  \"body-small text-primary-500 cursor-pointer\"\n             >\n               Clear\n             \u003C  /p  >\n           \u003C  /div  >\n           \u003C  FormSelect\n             v-if  =  \"item.field === 'Select'\"\n             v-model  =  \"selectedValues[index]\"\n             optionLabel  =  \"name\"\n             item-value  =  \"value\"\n             placeholder  =  \"All\"\n             required\n             class  =  \"h-[36px]\"\n             :options  =  \"item.options\"\n             :value  =  \"selectedValues[index]\"\n             name  =  \"field\"\n             @change  =  \"handleSelectChange(index)\"\n           /  >\n         \u003C  /div  >\n   \n         \u003C!  --   Modal   Footer   --  >\n         \u003C  div   class=\"flex items-center gap-4 pt-4 border-t border-neutral-100\"  >\n           \u003C  div   class=\"w-full\"  >\n             \u003C  CommonButton\n               title  =  \"Reset\"\n               bgColor  =  \"bg-neutral-30\"\n               textColor  =  \"text-neutral-500 font-semibold text-sm h-8\"\n               type  =  \"button\"\n               @click  =  \"resetModal\"\n             /  >\n           \u003C  /div  >\n   \n           \u003C  div   class=\"w-full\"  >\n             \u003C  CommonButton\n               title  =  \"Apply\"\n               bgColor  =  \"bg-primary-300 text-neutral-500 h-8\"\n               textColor  =  \"font-semibold text-sm\"\n               type  =  \"submit\"\n               :loading  =  \"isLoading\"\n               @click  =  \"onPrimaryAction\"\n             /  >\n           \u003C  /div  >\n         \u003C  /div  >\n       \u003C  /div  >\n     \u003C  /OverlayPanel  >\n   \u003C  /template  >\n   \n   \u003C  script setup  >\n   import   {   ref   }   from   \"vue\"  ;\n   import   FormSelect   from   \"~/components/common/input/FormSelect.vue\"  ;\n   \n   const   op   =   ref  (  null  );\n   const   selectedValues   =   ref  ([]);   //   Store   selected   values   for   each   item\n   const   isLoading   =   ref  (  false  );\n   \n   //   Define   props   for   the   component\n   const   props   =   defineProps  ({\n     items:   {\n       type  :   Array,\n       required:   true  ,\n     },\n   });\n   \n   //   Emit   events   for   toggling   the   menu   and   reset\n   const   emit   =   defineEmits  ([  \"toggle\"  ,   \"reset\"  ]);\n   \n   //   Define   the   toggle   function\n   const   toggle   =   (event) =  >   {\n     op.value.toggle(event  );\n     emit(  \"toggle\"  ,   event  );\n   };\n   \n   //   Handle   select   change\n   const   handleSelectChange   =   (index) =  >   {\n     console.log(  \"Selected value:\"  ,   selectedValues.value  );\n   };\n   \n   //   Handle   clear   button   click\n   const   handleClear   =   (index) =  >   {\n     selectedValues.value[index]   =   null  ;   //   Reset   the   selected   value\n   };\n   \n   //   Reset   all   filters\n   const   resetModal   =   () => {\n     selectedValues.value   =   [];   //   Reset   all   selected   values\n     emit(  \"reset\"  );   //   Emit   reset   event\n     op.value.hide  ();   //   Hide   the   menu   after   reset\n   };\n   \n   //   Apply   filters\n   const   onPrimaryAction   =   () => {\n     const   filteredValues   =   [...selectedValues.value];\n     emit(  \"toggle\"  ,   filteredValues  );\n     op.value.hide  ();   //   Hide   menu   after   applying\n   };\n   \n   //   Expose   the   toggle   function   to   the   parent   component\n   defineExpose(  {\n     toggle,\n   });\n   \u003C  /script  >\n  Basic Implementation     \u003C  template  >\n     \u003C!-- Filter Button -->\n     \u003C  button\n       class  =  \"h-[48px] px-5 rounded-[8px] flex justify-center items-center bg-none border border-neutral-100 text-neutral-200 font-normal text-sm hover:bg-primary-75 hover:border-primary-75\"\n       @  click  =  \"  toggle  \"\n       aria-haspopup  =  \"true\"\n       aria-controls  =  \"overlay_menu\"\n     >\n       \u003C  span   class  =  \"mr-2\"  >\n         \u003C  BaseCustomIcon   name  =  \"filter\"   />\n       \u003C/  span  >\n       \u003C  p  >Filter\u003C/  p  >\n     \u003C/  button  >\n   \n     \u003C!-- Filter Menu Component -->\n     \u003C  ModalFilterMenu\n       ref  =  \"reusableMenu\"\n       :  items  =  \"  menuItems  \"\n       @  toggle  =  \"  handleMenuToggle  \"\n     />\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   { ref }   from   \"vue\"  ;\n   import   ModalFilterMenu   from   \"~/components/ModalFilterMenu.vue\"  ;\n   \n   // Reference to the filter menu\n   const   reusableMenu   =   ref  ();\n   \n   // Define menu items\n   const   menuItems   =   ref  ([\n     {\n       label:   \"Staff\"  ,\n       field:   \"Select\"  ,\n       options: [\n         { name:   \"Pending\"  , value:   \"Pending\"   },\n         { name:   \"Completed\"  , value:   \"Completed\"   },\n       ],\n     },\n     {\n       label:   \"Feature\"  ,\n       field:   \"Select\"  ,\n       options: [\n         { name:   \"Credit\"  , value:   \"Credit\"   },\n         { name:   \"Debit\"  , value:   \"Debit\"   },\n       ],\n     },\n   ]);\n   \n   // Function to toggle the menu\n   const   toggle   =   (  event  )   =>   {\n     reusableMenu.value.  toggle  (event);\n   };\n   \n   // Handle menu toggle event\n   const   handleMenuToggle   =   (  event  )   =>   {\n     console.  log  (  \"Menu toggled\"  , event);\n   };\n   \u003C/  script  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":234,"path":235,"dir":141,"title":236,"description":7,"keywords":237,"body":239},"content:1.Nuxt3 Setup:5.Common Features:15.dropdown-menu.md","/nuxt3-setup/common-features/dropdown-menu","Dropdown Menu",[236,238],"Component Structure","  Dropdown Menu  This component implements a reusable, customizable dropdown menu that can be positioned anywhere in the application. It uses PrimeVue's Menu component with enhanced functionality for flexible application across different use cases.  Component Structure  The component consists of:   A PrimeVue   Menu  component with popup functionality  Custom templates for rendering menu items with icons  Toggle logic for controlling menu visibility  Menu Component     \u003C  Menu\n     ref  =  \"op\"\n     id  =  \"overlay_menu\"\n     :popup  =  \"true\"\n     :model  =  \"items\"\n     :pt  =  \"{ root: { style: 'right: 0px; left: auto; top:56px; position:fixed ' } }\"\n   >\n   \n   \u003C  template   #item=\"{ item, props }\">\n     \u003C  NuxtLink\n       v-if  =  \"item.route\"\n       :to  =  \"item.route\"\n       v-bind  =  \"props.action\"\n       class  =  \"flex items-center\"\n       @click  =  \"closeAllNavs\"\n     >\n       \u003C  CustomIcon   v-if=\"item.icon\"   :name=\"item.icon\"   /  >\n       \u003C  span   class=\"ml-2\"  >  {{   item.label   }}  \u003C  /spa  n  >\n     \u003C  /NuxtLink  >\n     \u003C  a\n       v-else\n       :href  =  \"item.url\"\n       :target  =  \"item.target\"\n       v-bind  =  \"props.action\"\n       class  =  \"flex items-center\"\n       @click  =  \"closeAllNavs\"\n     >\n       \u003C  CustomIcon   v-if=\"item.icon\"   :name=\"item.icon\"   /  >\n       \u003C  span   class=\"ml-2\"  >  {{   item.label   }}  \u003C  /spa  n  >\n     \u003C  /a  >\n   \u003C  /template  >\n   \u003C  /Menu  >\n     \n   \u003C  script  >\n   const   op   =   ref  (  null  );   //   Reference   to   the   menu   component\n   \n   const   toggle   =   (event) =  >   {\n     closeAllNavs  ();   //   Close   any   other   open   navigation   elements\n     onBtnDirection.value   =   !onBtnDirection.value  ;   //   Toggle   direction   indicator\n     op.value.toggle(event  );   //   Show/hide   the   menu\n   };\n   \n   \n   \n   const   menuItems   =   ref  ([\n     { label:   \"View\"  , icon:   \"eye\"  , route:   \"/view\"   },\n     { label:   \"Edit\"  , icon:   \"pencil\"  , route:   \"/edit\"   },\n     { label:   \"Delete\"  , icon:   \"trash\"  , command: ()   =>   confirmDelete() },\n   ]);\n   \n   //   Reference   to   menu   component\n   const   menuRef   =   ref  (  null  );\n   \n   //   Toggle   function\n   const   toggleMenu   =   (event)   =  >   {\n     menuRef.value.toggle(event  );\n   };\n   \u003C  /script  >\n  Menu Items Configuration  Items are defined in an array with the following structure:     const   items   =   ref  ([\n     {\n       label:   'Item Text'  ,       // Text to display\n       icon:   'icon_name'  ,        // Optional icon to display\n       route:   '/route/path'  ,     // For internal routing (uses NuxtLink)\n       url:   'https://...'  ,       // For external links (uses anchor tag)\n       target:   '_blank'  ,         // Target for external links\n       command  : ()   =>   {  ...  }      // Function to execute when clicked\n     }\n   ])\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":241,"path":242,"dir":141,"title":243,"description":7,"keywords":244,"body":246},"content:1.Nuxt3 Setup:5.Common Features:16.vueLottie.md","/nuxt3-setup/common-features/vuelottie","VueLottie",[245],"Lottie","  Lottie  A reusable Lottie animation wrapper component built with vue3-lottie, ready for drop-in use in any Nuxt 3 + Composition API project. It supports looping, autoplay, and full customization through props.     npm   install   vue3-lottie\n   Plugin Setup  plugins/vue3-lottie.client.ts  This plugin registers vue3-lottie globally in your Nuxt 3 app so that it can be used in any component without additional imports.     // plugins/vue3-lottie.client.ts\n   import   Vue3Lottie   from   'vue3-lottie'\n   \n   export   default   defineNuxtPlugin  ((  nuxtApp  )   =>   {\n     nuxtApp.vueApp.  use  (Vue3Lottie)\n   })\n  🧭 How to Get a Lottie Animation from LottieFiles  If you want to use custom animations in your Nuxt app with vue3-lottie, follow these simple steps:   1. Visit LottieFiles  Head over to   https://lottiefiles.com/  in your browser.   2. Search for an Animation  In the search bar, type in a keyword that describes the animation you want.\nFor example, to show a “Success” message or state, search for:\n👉 success   3. Choose and Download the JSON  Browse through the available animations.  Once you find one you like, click on it.  Hit the Download button and hit the Lottie JSON button (you might need to log in or sign up).   4. Add the JSON to Your Project  Move the downloaded .json file into your project folder, preferably:\n/assets/animations/success.json   5. Use It in Your Component  Here’s a working example of how to use the success animation in your Vue component:         \u003C  template  >\n         \u003C  client-only  >\n             \u003C  Vue3Lottie\n             :  height  =  \"  112  \"\n             :  width  =  \"  112  \"\n             :  animationData  =  \"  animationData  \"\n           />\n           \u003C/  client-only  >\n       \u003C/  template  >\n   \n   \u003C  script   setup  >\n   \n   import   animationData   from   \"@/assets/animations/success.json\"  ;\n   \n   \n   \u003C/  script  >\n  💡 Tip: You can replace success.json with any other animation file you downloaded.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":248,"path":249,"dir":141,"title":250,"description":7,"keywords":251,"body":252},"content:1.Nuxt3 Setup:5.Common Features:18.Drawer.md","/nuxt3-setup/common-features/drawer","Drawer",[250],"  Drawer  This drawer uses PrimeVue's Sidebar component to create a right-aligned modal for adding a new team member.  It is styled to resemble a drawer with a custom header and body content.  🔧 Component: Sidebar (PrimeVue)  Usage Summary  Triggered by the reactive variable: showModal  Appears from the right side of the screen  Custom close button and header section  Contains a    component         \u003C  Sidebar\n         v-model  :  visible  =  \"  showModal  \"\n         position  =  \"right\"\n         :  style  =  \"  { maxWidth:   '400px'  , width:   '100%'   }  \"\n         modal\n         class  =  \"custom-modal-drawer rounded-tl-lg rounded-bl-lg\"\n         :  showCloseIcon  =  \"  false  \"\n         :  show-header  =  \"  false  \"\n       >\n         \u003Cdiv class=\"flex items-center justify-between px-6 py-3 bg-neutral-20\">\n           \u003Cdiv class=\"flex items-center gap-4\">\n             \u003CBaseCustomIcon name=\"teams\" />\n             \u003Ch5 class=\"text-neutral-500 body-large\">Add New Team Member\u003C/h5>\n           \u003C/div>\n           \u003Cbutton @click=\"showModal = false\">\n             \u003Ci\n               class=\"pi pi-times text-neutral-500 text-base hover:bg-primary-50 p-3 hover:rounded-full\"\n             />\n           \u003C/button>\n         \u003C/div>\n         \u003Cdiv class=\"\">\n           \u003CTeamsAddTeam />\n         \u003C/div>\n       \u003C/  Sidebar  >\n       \n       \u003C  script   setup  >\n       const   showModal   =   ref  (  false  )\n       \u003C/  script  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":254,"path":255,"dir":256,"title":257,"description":7,"keywords":258,"body":260},"content:2.Features:1.Charts:bar chart.md","/features/charts/bar-chart","charts","Bar Chart",[259],"Bar Charts","  Bar Charts  This guide, will walk you through integrating charts into your Nuxt 3 project using a popular charting library, chart.js, along with primevue chart to integrate it seamlessly into your Vue components.    Install Required Packages  First, you need to install chart.js and primevue chart. Run the following command in your terminal:     npm   install   chart.js\n  Create a Chart Component  Create a reusable chart component to render charts anywhere in your project.\nthe component code for all type of charts can be gotten on primevue documentation. eg barchart.vue     \u003C  template  >\n     \u003C  div  >\n       \u003C  Chart\n         type  =  \"bar\"\n         :  data  =  \"  chartData  \"\n         :  options  =  \"  chartOptions  \"\n         class  =  \"w-full\"\n       />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   \n   const   props   =   defineProps  ({\n     chartData: {\n       type: Object,\n       required:   true  ,\n     },\n     chartOptions: {\n       type: Object,\n       required:   true  ,\n     },\n     labels: {\n       type: Array,\n       required:   true  ,\n     },\n     colors: {\n       type: Array,\n       required:   true  ,\n     },\n   });\n   \n   // Local refs to handle prop changes\n   const   localChartData   =   ref  (props.chartData);\n   const   localChartOptions   =   ref  (props.chartOptions);\n   \n   // Watch for prop changes and update local refs\n   watch  (\n     ()   =>   props.chartData,\n     (  newData  )   =>   {\n       localChartData.value   =   newData;\n     }\n   );\n   \n   watch  (\n     ()   =>   props.chartOptions,\n     (  newOptions  )   =>   {\n       localChartOptions.value   =   newOptions;\n     }\n   );\n   \u003C/  script  >\n  Using the Chart Component in a Page  Now, let's use the barChart component inside a page, passing dynamic data and options.  Example in a Page (e.g., pages/index.vue):     \u003C  template  >\n     \u003C  div  >\n         \u003C  ChartBar   :  chartData  =  \"  chartDataBar  \"   :  chartOptions  =  \"  chartOptionsBar  \"   />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   \n   const   chartDataBar   =   ref  (  null  );\n   const   chartOptionsBar   =   ref  (  null  );\n   \n   const   setChartDataBar   =   ()   =>   {\n     return   {\n       labels: [  \"Jan\"  ,   \"Feb\"  ,   \"Mar\"  ,   \"Apr\"  ,   \"May\"  ,   \"Jun\"  ,   \"Jul\"  ,   \"Sept\"  ],\n       datasets: [\n         {\n           type:   \"bar\"  ,\n           label:   \"Count\"  ,\n           data: [  10  ,   5  ,   25  ,   90  ,   35  ,   75  ,   58  ,   16  ],\n           backgroundColor:   \"#5398BE\"  ,\n           borderColor:   \"#5398BE\"  ,\n           borderRadius: [  4  ,   4  ,   0  ,   0  ],   // Apply 4px radius to the top corners\n         },\n       ],\n     };\n   };\n   \n   const   setChartOptionsBar   =   ()   =>   {\n     // Set the textColor based on light/dark mode\n     const   lightTextColor   =   \"#333333\"  ;\n     const   darkTextColor   =   \"#FFFFFF\"  ;\n   \n     // Check if dark mode is enabled (using the `dark` class on the body or root)\n     const   isDarkMode   =   document.documentElement.classList.  contains  (  \"dark\"  );\n     const   textColor   =   isDarkMode   ?   darkTextColor   :   lightTextColor;\n   \n     return   {\n       // maintainAspectRatio: false,\n       aspectRatio:   2.5  ,\n       plugins: {\n         legend: {\n           display:   false  ,   // Set to true to show the legend\n           labels: {\n             color: textColor,\n           },\n         },\n       },\n       scales: {\n         x: {\n           ticks: {\n             color: textColor,\n           },\n           grid: {\n             display:   false  ,   // Remove grid lines for the x-axis\n           },\n         },\n         y: {\n           ticks: {\n             color: textColor,\n           },\n           grid: {\n             display:   false  ,   // Remove grid lines for the x-axis\n           },\n           afterFit  : (  scale  )   =>   {\n             // Set a fixed height for the bars\n             scale.height   =   38.17   *   scale.ticks.  length  ;   // Adjust height based on the number of bars\n           },\n         },\n       },\n       datasets: {\n         bar: {\n           borderRadius: [  4  ,   4  ,   0  ,   0  ],   // Add 4px radius to the top corners\n           barThickness:   38.17  ,   // Set a fixed height for all bars\n         },\n       },\n     };\n   };\n   \n   onMounted  (()   =>   {\n     fetchChart  ();\n     updateChartOptionsOnModeChange  ();\n   });\n   \n   const   fetchChart   =   ()   =>   {\n     chartDataBar.value   =   setChartDataBar  ();\n     chartOptionsBar.value   =   setChartOptionsBar  ();\n   };\n   \n   // Watch for dark mode changes and update the chart options\n   const   updateChartOptionsOnModeChange   =   ()   =>   {\n     const   observer   =   new   MutationObserver  (()   =>   {\n       chartOptionsBar.value   =   setChartOptionsBar  ();\n     });\n   \n     // Observe changes on the class attribute of the document element\n     observer.  observe  (document.documentElement, {\n       attributes:   true  ,\n       attributeFilter: [  \"class\"  ],\n     });\n   };\n   \u003C/  script  >\n  Customize Your Charts  You can customize your charts further by changing the options or using different chart types. Here are a few examples of common chart customizations:  Line Chart, Pie Chart, Doughnut Chart etc  Conclusion\nWith chart.js and primevue chart, you can create a wide variety of interactive and dynamic charts in your Nuxt 3 project. Whether you need simple bar charts or complex radar charts.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":262,"path":263,"dir":256,"title":264,"description":7,"keywords":265,"body":267},"content:2.Features:1.Charts:doughnut chart.md","/features/charts/doughnut-chart","Doughnut Chart",[266],"Doughnut Charts","  Doughnut Charts  This guide, will walk you through integrating charts into your Nuxt 3 project using a popular charting library, chart.js, along with primevue chart to integrate it seamlessly into your Vue components.    Install Required Packages  First, you need to install chart.js and primevue chart. Run the following command in your terminal:     npm   install   chart.js\n  Create a Chart Component  Create a reusable chart component to render charts anywhere in your project.\nthe component code for all type of charts can be gotten on primevue documentation. eg barchart.vue     \u003C  template  >\n     \u003C  div  >\n       \u003C  Chart\n         type  =  \"doughnut\"\n         :  data  =  \"  chartData  \"\n         :  options  =  \"  chartOptions  \"\n         class  =  \"w-full\"\n       />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   \n   const   props   =   defineProps  ({\n     chartData: {\n       type: Object,\n       required:   true  ,\n     },\n     chartOptions: {\n       type: Object,\n       required:   true  ,\n     },\n     labels: {\n       type: Array,\n       required:   true  ,\n     },\n     colors: {\n       type: Array,\n       required:   true  ,\n     },\n   });\n   \n   // Local refs to handle prop changes\n   const   localChartData   =   ref  (props.chartData);\n   const   localChartOptions   =   ref  (props.chartOptions);\n   \n   // Watch for prop changes and update local refs\n   watch  (\n     ()   =>   props.chartData,\n     (  newData  )   =>   {\n       localChartData.value   =   newData;\n     }\n   );\n   \n   watch  (\n     ()   =>   props.chartOptions,\n     (  newOptions  )   =>   {\n       localChartOptions.value   =   newOptions;\n     }\n   );\n   \u003C/  script  >\n  Using the Chart Component in a Page  Now, let's use the barChart component inside a page, passing dynamic data and options.  Example in a Page (e.g., pages/index.vue):     \u003C  template  >\n     \u003C  div  >\n           \u003C  ChartDoughnut\n             :  chartData  =  \"  chartDataDoughnut  \"\n             :  chartOptions  =  \"  chartOptionsDoughnut  \"\n           />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   \n   const   chartDataDoughnut   =   ref  (  null  );\n   const   chartOptionsDoughnut   =   ref  (  null  );\n   \n   const   setChartDataDoughnut   =   ()   =>   {\n     const   documentStyle   =   getComputedStyle  (document.body);\n   \n     return   {\n       labels: [\n         \"Airtime\"  ,\n         \"Electricity Bill\"  ,\n         \"Educational Bill\"  ,\n         \"Hotel Reservations\"  ,\n         \"Airtime-to-Cash\"  ,\n         \"Cable TV\"  ,\n         \"Data\"  ,\n         \"Giftcard Sales\"  ,\n         \"Giftcard Purchase\"  ,\n         \"Betting\"  ,\n         \"Virtual Cards\"  ,\n         \"Flight Booking\"  ,\n         \"SocialBoostPro\"  ,\n       ],\n       datasets: [\n         {\n           data: [  12  ,   15  ,   8  ,   10  ,   9  ,   7  ,   6  ,   14  ,   5  ,   11  ,   13  ,   9  ,   8  ],\n           backgroundColor: [\n             \"#4F416D\"  ,\n             \"#F95C7D\"  ,\n             \"#0066CC\"  ,\n             \"#66A6FF\"  ,\n             \"#FF6600\"  ,\n             \"#006633\"  ,\n             \"#A6CBA4\"  ,\n             \"#3C1D28\"  ,\n             \"#6B6E7E\"  ,\n             \"#E8D9E6\"  ,\n             \"#B89C3A\"  ,\n             \"#411E34\"  ,\n             \"#00F4FF\"  ,\n           ],\n           hoverBackgroundColor: [\n             \"#4F416D\"  ,\n             \"#F95C7D\"  ,\n             \"#0066CC\"  ,\n             \"#66A6FF\"  ,\n             \"#FF6600\"  ,\n             \"#006633\"  ,\n             \"#A6CBA4\"  ,\n             \"#3C1D28\"  ,\n             \"#6B6E7E\"  ,\n             \"#E8D9E6\"  ,\n             \"#B89C3A\"  ,\n             \"#411E34\"  ,\n             \"#00F4FF\"  ,\n           ],\n           borderWidth:   0  ,\n         },\n       ],\n     };\n   };\n   \n   const   setChartOptionsDoughnut   =   ()   =>   {\n     const   documentStyle   =   getComputedStyle  (document.documentElement);\n     const   textColor   =   documentStyle.  getPropertyValue  (  \"--text-color\"  );\n   \n     return   {\n       plugins: {\n         legend: {\n           display:   false  ,\n           labels: {\n             cutout:   \"50%\"  ,\n             color: textColor,\n           },\n         },\n       },\n       tooltip: {\n         callbacks: {\n           label  :   function   (  context  ) {\n             const   label   =   context.label   ||   \"\"  ;\n             const   value   =   context.raw   ||   0  ;\n             const   total   =   context.dataset.data.  reduce  (\n               (  acc  ,   data  )   =>   acc   +   data,\n               0\n             );\n             const   percentage   =   Math.  round  ((value   /   total)   *   100  );\n             return   `${  label  }: ${  percentage  }%`  ;\n           },\n         },\n       },\n     };\n   };\n   \n   onMounted  (()   =>   {\n     fetchChart  ();\n     updateChartOptionsOnModeChange  ();\n   });\n   \n   const   fetchChart   =   ()   =>   {\n     chartDataDoughnut.value   =   setChartDataDoughnut  ();\n     chartOptionsDoughnut.value   =   setChartOptionsDoughnut  ();\n   };\n   \n   // Watch for dark mode changes and update the chart options\n   const   updateChartOptionsOnModeChange   =   ()   =>   {\n     const   observer   =   new   MutationObserver  (()   =>   {\n       chartOptionsDoughnut.value   =   setChartOptionsDoughnut  ();\n     });\n   \n     // Observe changes on the class attribute of the document element\n     observer.  observe  (document.documentElement, {\n       attributes:   true  ,\n       attributeFilter: [  \"class\"  ],\n     });\n   };\n   \u003C/  script  >\n  Customize Your Charts  You can customize your charts further by changing the options or using different chart types. Here are a few examples of common chart customizations:  Line Chart, Pie Chart, Doughnut Chart etc  Conclusion\nWith chart.js and primevue chart, you can create a wide variety of interactive and dynamic charts in your Nuxt 3 project. Whether you need simple bar charts or complex radar charts.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":269,"path":270,"dir":256,"title":271,"description":7,"keywords":272,"body":274},"content:2.Features:1.Charts:line chart.md","/features/charts/line-chart","Line Chart",[273],"Line Charts","  Line Charts  This guide, will walk you through integrating charts into your Nuxt 3 project using a popular charting library, chart.js, along with primevue chart to integrate it seamlessly into your Vue components.    Install Required Packages  First, you need to install chart.js and primevue chart. Run the following command in your terminal:     npm   install   chart.js\n  Create a Chart Component  Create a reusable chart component to render charts anywhere in your project.\nthe component code for all type of charts can be gotten on primevue documentation. eg barchart.vue     \u003C  template  >\n     \u003C  div  >\n       \u003C  Chart\n         type  =  \"line\"\n         :  data  =  \"  chartData  \"\n         :  options  =  \"  chartOptions  \"\n         class  =  \"w-full\"\n       />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   \n   const   props   =   defineProps  ({\n     chartData: {\n       type: Object,\n       required:   true  ,\n     },\n     chartOptions: {\n       type: Object,\n       required:   true  ,\n     },\n     labels: {\n       type: Array,\n       required:   true  ,\n     },\n     colors: {\n       type: Array,\n       required:   true  ,\n     },\n   });\n   \n   // Local refs to handle prop changes\n   const   localChartData   =   ref  (props.chartData);\n   const   localChartOptions   =   ref  (props.chartOptions);\n   \n   // Watch for prop changes and update local refs\n   watch  (\n     ()   =>   props.chartData,\n     (  newData  )   =>   {\n       localChartData.value   =   newData;\n     }\n   );\n   \n   watch  (\n     ()   =>   props.chartOptions,\n     (  newOptions  )   =>   {\n       localChartOptions.value   =   newOptions;\n     }\n   );\n   \u003C/  script  >\n  Using the Chart Component in a Page  Now, let's use the barChart component inside a page, passing dynamic data and options.  Example in a Page (e.g., pages/index.vue):     \u003C  template  >\n     \u003C  div  >\n           \u003C  ChartLine\n               :  chartData  =  \"  chartDataLine  \"\n               :  chartOptions  =  \"  chartOptionsLine  \"\n             />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   \n   const   chartDataLine   =   ref  (  null  );\n   const   chartOptionsLine   =   ref  (  null  );\n   \n   const   setChartDataLine   =   ()   =>   {\n     return   {\n       labels: [\n         \"Jan\"  ,\n         \"Feb\"  ,\n         \"Mar\"  ,\n         \"Apr\"  ,\n         \"May\"  ,\n         \"Jun\"  ,\n         \"Jul\"  ,\n         \"Sep\"  ,\n         \"Oct\"  ,\n         \"Nov\"  ,\n         \"Dec\"  ,\n       ],\n       datasets: [\n         {\n           label:   \"\"  ,\n           data: [  10  ,   5  ,   25  ,   90  ,   35  ,   75  ,   58  ,   16  ,   8  ,   39  ,   24  ],\n           fill:   false  ,   // Remove background color\n           borderColor:   \"#FF6201\"  ,\n           tension:   0.4  ,   // Make the line curvy\n           borderWidth:   2  ,   // Line thickness\n           borderCapStyle:   \"round\"  ,   // Round the ends of the line\n           pointRadius:   0  ,   // Hide data points\n         },\n       ],\n     };\n   };\n   \n   const   setChartOptionsLine   =   ()   =>   {\n     // Set the textColor based on light/dark mode\n     const   lightTextColor   =   \"#333333\"  ;\n     const   darkTextColor   =   \"#FFFFFF\"  ;\n   \n     // Check if dark mode is enabled (using the `dark` class on the body or root)\n     const   isDarkMode   =   document.documentElement.classList.  contains  (  \"dark\"  );\n     const   textColor   =   isDarkMode   ?   darkTextColor   :   lightTextColor;\n   \n     return   {\n       aspectRatio:   2.5  ,\n       plugins: {\n         legend: {\n           display:   false  ,\n           labels: {\n             cutout:   \"50%\"  ,\n             color: textColor,\n           },\n         },\n       },\n       scales: {\n         x: {\n           ticks: {\n             color: textColor,\n           },\n           grid: {\n             display:   false  ,   // Remove grid lines for the x-axis\n           },\n         },\n         y: {\n           ticks: {\n             color: textColor,\n           },\n           grid: {\n             display:   false  ,   // Remove grid lines for the x-axis\n           },\n         },\n       },\n     };\n   };\n   \n   onMounted  (()   =>   {\n     fetchChart  ();\n     updateChartOptionsOnModeChange  ();\n   });\n   \n   const   fetchChart   =   ()   =>   {\n       chartOptionsLine.value   =   setChartOptionsLine  ();\n   };\n   \n   // Watch for dark mode changes and update the chart options\n   const   updateChartOptionsOnModeChange   =   ()   =>   {\n     const   observer   =   new   MutationObserver  (()   =>   {\n       chartOptionsBar.value   =   setChartOptionsBar  ();\n     });\n   \n     // Observe changes on the class attribute of the document element\n     observer.  observe  (document.documentElement, {\n       attributes:   true  ,\n       attributeFilter: [  \"class\"  ],\n     });\n   };\n   \u003C/  script  >\n  Customize Your Charts  You can customize your charts further by changing the options or using different chart types. Here are a few examples of common chart customizations:  Line Chart, Pie Chart, Doughnut Chart etc  Conclusion\nWith chart.js and primevue chart, you can create a wide variety of interactive and dynamic charts in your Nuxt 3 project. Whether you need simple bar charts or complex radar charts.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":276,"path":277,"dir":256,"title":278,"description":7,"keywords":279,"body":281},"content:2.Features:1.Charts:pie chart.md","/features/charts/pie-chart","Pie Chart",[280],"Pie Charts","  Pie Charts  This guide, will walk you through integrating charts into your Nuxt 3 project using a popular charting library, chart.js, along with primevue chart to integrate it seamlessly into your Vue components.    Install Required Packages  First, you need to install chart.js and primevue chart. Run the following command in your terminal:     npm   install   chart.js\n  Create a Chart Component  Create a reusable chart component to render charts anywhere in your project.\nthe component code for all type of charts can be gotten on primevue documentation. eg barchart.vue     \u003C  template  >\n     \u003C  div  >\n       \u003C  Chart\n         type  =  \"pie\"\n         :  data  =  \"  chartData  \"\n         :  options  =  \"  chartOptions  \"\n         class  =  \"w-full\"\n       />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   \n   const   props   =   defineProps  ({\n     chartData: {\n       type: Object,\n       required:   true  ,\n     },\n     chartOptions: {\n       type: Object,\n       required:   true  ,\n     },\n     labels: {\n       type: Array,\n       required:   true  ,\n     },\n     colors: {\n       type: Array,\n       required:   true  ,\n     },\n   });\n   \n   // Local refs to handle prop changes\n   const   localChartData   =   ref  (props.chartData);\n   const   localChartOptions   =   ref  (props.chartOptions);\n   \n   // Watch for prop changes and update local refs\n   watch  (\n     ()   =>   props.chartData,\n     (  newData  )   =>   {\n       localChartData.value   =   newData;\n     }\n   );\n   \n   watch  (\n     ()   =>   props.chartOptions,\n     (  newOptions  )   =>   {\n       localChartOptions.value   =   newOptions;\n     }\n   );\n   \u003C/  script  >\n  Using the Chart Component in a Page  Now, let's use the barChart component inside a page, passing dynamic data and options.  Example in a Page (e.g., pages/index.vue):     \u003C  template  >\n     \u003C  div  >\n         \u003C  ChartPie   :  chartData  =  \"  chartDataPie  \"   :  chartOptions  =  \"  chartOptionsPie  \"   />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   \n   const   chartDataPie   =   ref  (  null  );\n   const   chartOptionsPie   =   ref  (  null  );\n   \n   const   setChartDataPie   =   ()   =>   {\n     const   documentStyle   =   getComputedStyle  (document.body);\n   \n     return   {\n       labels: [\n         \"Airtime\"  ,\n         \"Electricity Bill\"  ,\n         \"Educational Bill\"  ,\n         \"Hotel Reservations\"  ,\n         \"Airtime-to-Cash\"  ,\n         \"Cable TV\"  ,\n         \"Data\"  ,\n         \"Giftcard Sales\"  ,\n         \"Giftcard Purchase\"  ,\n         \"Betting\"  ,\n         \"Virtual Cards\"  ,\n         \"Flight Booking\"  ,\n         \"SocialBoostPro\"  ,\n       ],\n       datasets: [\n         {\n           data: [  12  ,   15  ,   8  ,   10  ,   9  ,   7  ,   6  ,   14  ,   5  ,   11  ,   13  ,   9  ,   8  ],\n           backgroundColor: [\n             \"#4F416D\"  ,\n             \"#F95C7D\"  ,\n             \"#0066CC\"  ,\n             \"#66A6FF\"  ,\n             \"#FF6600\"  ,\n             \"#006633\"  ,\n             \"#A6CBA4\"  ,\n             \"#3C1D28\"  ,\n             \"#6B6E7E\"  ,\n             \"#E8D9E6\"  ,\n             \"#B89C3A\"  ,\n             \"#411E34\"  ,\n             \"#00F4FF\"  ,\n           ],\n           hoverBackgroundColor: [\n             \"#4F416D\"  ,\n             \"#F95C7D\"  ,\n             \"#0066CC\"  ,\n             \"#66A6FF\"  ,\n             \"#FF6600\"  ,\n             \"#006633\"  ,\n             \"#A6CBA4\"  ,\n             \"#3C1D28\"  ,\n             \"#6B6E7E\"  ,\n             \"#E8D9E6\"  ,\n             \"#B89C3A\"  ,\n             \"#411E34\"  ,\n             \"#00F4FF\"  ,\n           ],\n           borderWidth:   0  ,\n         },\n       ],\n     };\n   };\n   \n   const   setChartOptionsPie   =   ()   =>   {\n     const   documentStyle   =   getComputedStyle  (document.documentElement);\n     const   textColor   =   documentStyle.  getPropertyValue  (  \"--text-color\"  );\n   \n     return   {\n       plugins: {\n         legend: {\n           display:   false  ,\n           labels: {\n             cutout:   \"50%\"  ,\n             color: textColor,\n           },\n         },\n       },\n       tooltip: {\n         callbacks: {\n           label  :   function   (  context  ) {\n             const   label   =   context.label   ||   \"\"  ;\n             const   value   =   context.raw   ||   0  ;\n             const   total   =   context.dataset.data.  reduce  (\n               (  acc  ,   data  )   =>   acc   +   data,\n               0\n             );\n             const   percentage   =   Math.  round  ((value   /   total)   *   100  );\n             return   `${  label  }: ${  percentage  }%`  ;\n           },\n         },\n       },\n     };\n   };\n   \n   onMounted  (()   =>   {\n     fetchChart  ();\n     updateChartOptionsOnModeChange  ();\n   });\n   \n   const   fetchChart   =   ()   =>   {\n     chartDataPie.value   =   setChartDataPie  ();\n     chartOptionsPie.value   =   setChartOptionsPie  ();\n   };\n   \n   // Watch for dark mode changes and update the chart options\n   const   updateChartOptionsOnModeChange   =   ()   =>   {\n     const   observer   =   new   MutationObserver  (()   =>   {\n       chartOptionsPie.value   =   setChartOptionsPie  ();\n     });\n   \n     // Observe changes on the class attribute of the document element\n     observer.  observe  (document.documentElement, {\n       attributes:   true  ,\n       attributeFilter: [  \"class\"  ],\n     });\n   };\n   \u003C/  script  >\n  Customize Your Charts  You can customize your charts further by changing the options or using different chart types. Here are a few examples of common chart customizations:  Line Chart, Pie Chart, Doughnut Chart etc  Conclusion\nWith chart.js and primevue chart, you can create a wide variety of interactive and dynamic charts in your Nuxt 3 project. Whether you need simple bar charts or complex radar charts.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":283,"path":284,"dir":285,"title":286,"description":7,"keywords":287,"body":288},"content:2.Features:2.Layouts:auth layout.md","/features/layouts/auth-layout","layouts","Auth Layout",[286],"  Auth Layout  This layout is designed to provide a clean, responsive, and visually appealing structure for authentication-related pages such as login and signup.    Features  Split screen layout with an image and message panel on large screens  Fully responsive: stacks vertically on small devices  Uses custom utility classes for consistent design  Slot-based content injection for reuse across auth pages     \u003C  template  >\n     \u003C  div   class  =  \"w-full bg-neutral-30 min-h-screen text-neutral-500 sm:py-[50px] sm:px-[82px] p-3\"  >\n       \u003C  div   class  =  \"flex rounded-xl\"  >\n         \u003C  div\n           class  =  \"hidden lg:block w-6/12 py-[72px] px-[45px] h-[85vh] bg-primary-300 relative overflow-hidden rounded-l-xl\"\n         >\n           \u003C  h1   class  =  \"text-neutral-10 text-center mb-3\"  >Powerful Admin Control at Your Fingertips\u003C/  h1  >\n           \u003C  p   class  =  \"body-regular text-center text-neutral-10 max-w-[381px] mx-auto\"  >\n             Manage vendors, track revenue, and optimise operations and more with ease.\n           \u003C/  p  >\n   \n           \u003C  div   class  =  \"absolute left-0 -bottom-20\"  >\n             \u003C  img   src  =  \"@/assets/images/authBG.png\"   alt  =  \"background image\"   class  =  \"w-screen\"   />\n           \u003C/  div  >\n         \u003C/  div  >\n         \u003C  div\n           class  =  \"sm:py-[80px] xl:px-[145px] lg:px-[60px] sm:px-[96px] px-4 py-8 bg-neutral-10 lg:w-6/12 w-full lg:rounded-r-xl lg:rounded-none rounded-xl lg:overflow-hidden lg:h-[85vh]\"\n         >\n           \u003C  BaseCustomIcon   name  =  \"logo\"   class  =  \"mb-6\"   />\n           \u003C  slot   /  >\n         \u003C/  div  >\n       \u003C/  div  >\n     \u003C/  div  >\n   \u003C/  template  >\n  Admin Login Form Component  This form allows admin users to securely log in to the application. It includes input validation, error messaging, form state management, and integrates with your store and routing logic.  Features  Form Validation using Joi  Error Handling for each field  Loading and Disable States during submission  Session Expiry Toast Notification  Responsive layout and reusable UI components  Template Structure  pages/login.vue     \u003C  template  >\n     \u003C  div  >\n       \u003C  div   class  =  \"mb-8\"  >\n         \u003C  h3  >Admin Login\u003C/  h3  >\n         \u003C  p   class  =  \"body-small text-neutral-200\"  >\n           Securely log in to manage users, services, and more.\n         \u003C/  p  >\n       \u003C/  div  >\n       \u003C  form   @  submit  .  prevent  =  \"  onSubmit  \"   class  =  \" \"  >\n         \u003C  div   class  =  \"flex flex-col\"  >\n           \u003C  div  >\n             \u003C  FormText\n               label  =  \"Email Address\"\n               required\n               v-model  =  \"  userEmail  \"\n               placeholder  =  \"Enter your email address\"\n               @  input  =  \"  validateField  (  'userEmail'  )  \"\n             >\u003C/  FormText  >\n             \u003C  span   v-if  =  \"  errors.userEmail  \"   class  =  \"text-danger-300 mt-8 text-xs\"  >\n               {{ errors.userEmail }}\n             \u003C/  span  >\n           \u003C/  div  >\n           \u003C  div   class  =  \"mt-5 mb-2\"  >\n             \u003C  FormText\n               label  =  \"Password\"\n               v-model  =  \"  userPassword  \"\n               type  =  \"password\"\n               placeholder  =  \"Enter your password\"\n               @  input  =  \"  validateField  (  'userPassword'  )  \"\n             />\n             \u003C  div   v-if  =  \"  errors.userPassword  \"   class  =  \"text-danger-300 text-xs\"  >\n               {{ errors.userPassword }}\n             \u003C/  div  >\n           \u003C/  div  >\n         \u003C/  div  >\n   \n         \u003C  div   class  =  \"flex items-center justify-between mb-6\"  >\n           \u003C  div   class  =  \"flex items-center\"  >\u003C/  div  >\n           \u003C  NuxtLink\n             to  =  \"/forgot-password\"\n             class  =  \"no-underline ml-2 label text-primary-200 text-right cursor-pointer\"\n             >Forgot password?\u003C/  NuxtLink\n           >\n         \u003C/  div  >\n   \n         \u003C  NuxtLink   to  =  \"/\"  >\n           \u003C  CommonButton\n             title  =  \"Log In\"\n             bgColor  =  \"bg-secondary-300\"\n             textColor  =  \"text-primary-300 font-semibold text-sm\"\n             type  =  \"submit\"\n             :  loading  =  \"  isLoading  \"\n             :  disabled  =  \"  isLoading   ||   !  isFormValid  \"\n           />\n         \u003C/  NuxtLink  >\n       \u003C/  form  >\n     \u003C/  div  >\n   \u003C/  template  >\n  Script Setup     \u003C  script   setup  >\n   import   Joi   from   'joi'\n   import   { useToast }   from   'primevue/usetoast'\n   import   FormText   from   '~/components/common/input/FormText.vue'\n   import   { useRoute, useRouter }   from   'vue-router'\n   \n   definePageMeta  ({\n     layout:   'auth'   // Specify the layout to use\n   })\n   \n   useHead  ({\n     title:   'Login | Attafly Admin'\n   })\n   \n   const   toast   =   useToast  ()\n   // Get the current route\n   const   route   =   useRoute  ()\n   const   router   =   useRouter  ()\n   // Access the query parameters\n   const   query   =   route.query\n   const   isLoading   =   ref  (  false  )\n   const   errors   =   ref  ({})\n   const   userEmail   =   ref  ()\n   const   userPassword   =   ref  ()\n   \n   const   isFormValid   =   computed  (()   =>   {\n     return   (\n       userEmail.value   &&   userPassword.value   &&   !  errors.value.userEmail   &&   !  errors.value.userPassword\n     )\n   })\n   \n   const   validationSchema   =   {\n     userEmail: Joi.  alternatives  ()\n       .  try  (\n         Joi.  string  ()\n           .  email  ({ tlds: { allow:   false   } })\n           .  messages  ({\n             'string.email'  :   'Enter a valid email address'\n           })\n       )\n       .  required  ()\n       .  messages  ({\n         'alternatives.match'  :   'Enter a valid email address'  ,\n         'any.required'  :   'Email is required'  ,\n         'string.empty'  :   'Email cannot be empty'\n       }),\n     userPassword: Joi.  string  ().  min  (  8  ).  required  ().  messages  ({\n       'any.required'  :   'Password is required'  ,\n       'string.empty'  :   'Password is required'  ,\n       'string.min'  :   'Password must be at least 8 characters'\n     })\n   }\n   \n   // Field validation function\n   const   validateField   =   (  field  )   =>   {\n     const   value   =   field   ===   'userEmail'   ?   userEmail.value   :   userPassword.value\n   \n     const   {   error   }   =   validationSchema[field].  validate  (value)\n   \n     if   (error) {\n       errors.value[field]   =   error.details[  0  ].message\n     }   else   {\n       delete   errors.value[field]\n     }\n   }\n   \n   // Form submission handler\n   const   onSubmit   =   async   ()   =>   {\n     Object.  keys  (validationSchema).  forEach  ((  field  )   =>   validateField  (field))\n     if   (isFormValid.value) {\n       // await signInUser();\n     }\n   }\n   \n   onMounted  (()   =>   {\n     if   (query.toast   ===   'Session Expired'  ) {\n       toast.  add  ({\n         severity:   'info'  ,\n         summary:   ''  ,\n         detail:   'Session Expired'  ,\n         life:   5000  ,\n         closable:   false\n       })\n       removeTypeQuery  ()\n     }\n   })\n   \n   const   removeTypeQuery   =   ()   =>   {\n     // Navigate to the same route with the updated query\n     router.  push  ({ path: route.path })\n   }\n   \u003C/  script  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":290,"path":291,"dir":285,"title":292,"description":7,"keywords":293,"body":295},"content:2.Features:2.Layouts:sidebar layout 1.md","/features/layouts/sidebar-layout-1","Sidebar Layout 1",[294],"Layout Component","  Layout Component  The Layout Component in Nuxt 3 provides a structured way to maintain consistent UI elements across different pages. It helps define reusable sections such as headers, sidebars, and navigation bars, ensuring a uniform design throughout the application. Layouts enable better organization, reduce code duplication, and enhance maintainability in large projects.  Dynamic Template     1. Header :\nCreate TheHeader.vue inside the components/partials/ directory to manage the user actions.     // components/partials/TheHeader.vue\n   \u003C  template  >\n     \u003C  div   class  =  \"fixed w-full z-40\"  >\n       \u003C!-- Header -->\n       \u003C  div\n         class  =  \"h-[70px] flex justify-between items-center px-8 bg-neutral-10 border-b border-neutral-100 dark:bg-neutral-10 relative lg:static\"\n       >\n         \u003C!-- Sidebar Toggle Button (Mobile) -->\n         \u003C  a\n           class  =  \"cursor-pointer block lg:hidden text-surface-700 dark:text-surface-100 mr-4 mt-1\"\n           @  click  =  \"  toggleSidebar  \"\n         >\n           \u003C  i   class  =  \"pi pi-bars text-2xl\"   /  >\n         \u003C/  a  >\n   \n         \u003C!-- Notification and User Greeting (Mobile) -->\n         \u003C  a   class  =  \"cursor-pointer block lg:hidden text-surface-700 dark:text-surface-100\"  >\n           \u003C  ul   class  =  \"flex\"  >\n             \u003C  div   class  =  \"flex items-center ml-auto\"  >\n               \u003C  i\n                 class  =  \"pi pi-bell text-base lg:!text-xl leading-none mr-2 cursor-pointer\"\n                 @  click  =  \"  viewNotification   =   true  \"\n               /  >\n               \u003C  p   class  =  \"mr-1\"  >\n                 \u003C  span   class  =  \"font-bold text-base\"  >Hello\u003C/  span  > Amaka,\n               \u003C/  p  >\n               \u003C  div  >👋\u003C/  div  >\n             \u003C/  div  >\n           \u003C/  ul  >\n         \u003C/  a  >\n   \n         \u003C!-- Navigation Breadcrumbs and User Menu (Desktop) -->\n         \u003C  ul\n           class  =  \"list-none p-0 m-0 hidden lg:flex lg:items-center select-none lg:flex-row w-auto lg:w-full border lg:border-0 border-surface bg-surface-0 dark:bg-surface-950 right-0 top-full z-10 shadow lg:shadow-none absolute lg:static\"\n         >\n           \u003C!-- Breadcrumbs -->\n           \u003C  h4   class  =  \"font-semibold text-2xl ml-5 capitalize\"  >\n             \u003C  NuxtLink\n               :  to  =  \"  prevNavLink   ?   `/${  prevNavLink  }`   :   `/${  prevNavProp  }`\"\n               v-if  =  \"  prevNavProp  \"\n               class  =  \"text-neutral-200\"\n             >\n               {{ prevNavProp }} /\n             \u003C/  NuxtLink  >\n             {{ customProp }}\n           \u003C/  h4  >\n   \n           \u003C!-- User Dropdown -->\n           \u003C  button\n             class  =  \"flex items-center border-t border-surface lg:border-t-0 ml-auto mr-2\"\n             @  click  =  \"  toggle  \"\n             aria-haspopup  =  \"true\"\n             aria-controls  =  \"overlay_menu\"\n           >\n             \u003C  p   class  =  \"mr-2 text-base font-normal text-neutral-200\"  >\n               \u003C  span   class  =  \"text-neutral-500\"  >Mayokun,\u003C/  span  > Admin 💼\n             \u003C/  p  >\n             \u003C  i\n               class  =  \"pi pi-chevron-down text-sm leading-none\"\n               :  class  =  \"  onBtnDirection   ?   'rotate-[180deg]'   :   ''\"\n             /  >\n           \u003C/  button  >\n   \n           \u003C!-- Dropdown Menu -->\n           \u003C  Menu   ref  =  \"op\"   id  =  \"overlay_menu\"   :  popup  =  \"  true  \"   :  model  =  \"  items  \"  >\n             \u003C  template   #  item  =  \"  { item, props }  \"  >\n               \u003C  router-link\n                 v-if  =  \"  item.route  \"\n                 v-slot  =  \"  { href, navigate }  \"\n                 :  to  =  \"  item.route  \"\n                 custom\n               >\n                 \u003C  a\n                   v-ripple\n                   :  href  =  \"  href  \"\n                   v-bind  =  \"  props.action  \"\n                   @  click  =  \"\n                     navigate;\n                     onBtnDirection   =   false  ;\n                   \"\n                 >\n                   \u003C  CustomIcon   :  name  =  \"  item.icon  \"   />\n                   \u003C  span   class  =  \"ml-2\"  >{{ item.label }}\u003C/  span  >\n                 \u003C/  a  >\n               \u003C/  router-link  >\n               \u003C  a\n                 v-else\n                 v-ripple\n                 :  href  =  \"  item.url  \"\n                 :  target  =  \"  item.target  \"\n                 v-bind  =  \"  props.action  \"\n               >\n                 \u003C  CustomIcon   :  name  =  \"  item.icon  \"   />\n                 \u003C  span   class  =  \"ml-2\"  >{{ item.label }}\u003C/  span  >\n               \u003C/  a  >\n             \u003C/  template  >\n           \u003C/  Menu  >\n         \u003C/  ul  >\n       \u003C/  div  >\n   \n       \u003C!-- Logout Confirmation Modal -->\n       \u003C  ModalConfirmation\n         title  =  \"Log Out\"\n         message  =  \"Are you sure you want to logout?\"\n         primaryButtonText  =  \"Log Out\"\n         :  showLockIcon  =  \"  true  \"\n         :  showBackButton  =  \"  true  \"\n         :  closable  =  \"  false  \"\n         @  primary-action  =  \"  handlePrimaryAction  \"\n         :  isVisible  =  \"  logoutModal  \"\n         @  close  =  \"  logoutModal   =   false  \"\n       />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   { ref }   from   \"vue\"  ;\n   \n   // Props\n   const   props   =   defineProps  ({\n     customProp: {\n       type: String,\n       required:   true  ,\n     },\n     prevNavProp: {\n       type: String,\n     },\n     prevNavLink: {\n       type: String,\n     },\n   });\n   \n   // Dropdown Menu Items\n   const   items   =   ref  ([\n     {\n       label:   \"Profile\"  ,\n       icon:   \"\"  ,\n       route:   \"/profile\"  ,\n     },\n     {\n       label:   \"Sign Out\"  ,\n       icon:   \"\"  ,\n       command  : ()   =>   {\n         logoutModal.value   =   true  ;\n       },\n     },\n   ]);\n   \n   // Refs\n   const   op   =   ref  ();\n   const   logoutModal   =   ref  (  false  );\n   const   onBtnDirection   =   ref  (  false  );\n   const   viewNotification   =   ref  (  false  );\n   \n   // Emit event to toggle sidebar\n   const   emit   =   defineEmits  ([  \"toggle-sidebar\"  ]);\n   \n   // Toggle Dropdown Menu\n   const   toggle   =   (  event  )   =>   {\n     onBtnDirection.value   =   !  onBtnDirection.value;\n     op.value.  toggle  (event);\n   };\n   \n   // Toggle Sidebar\n   const   toggleSidebar   =   ()   =>   {\n     emit  (  \"toggle-sidebar\"  );\n   };\n   \n   // Handle Logout Action\n   const   handlePrimaryAction   =   ()   =>   {\n     navigateTo  (  \"/login\"  );\n   };\n   \u003C/  script  >\n   2. Sidebar :\nCreate TheSidebar.vue inside the components/partials/ directory to handle the application's side navigation.  It typically includes links to different sections and can be collapsible for better usability.     // components/partials/TheSidebar.vue\n   \n   \u003C  template  >\n     \u003C  div   class  =  \"flex h-screen bg-primary-50\"  >\n       \u003C!-- Sidebar -->\n       \u003C  div\n         class  =  \"w-[18rem] border-r border-neutral-100 fixed h-full flex flex-col text-neutral-500 bg-primary-50 overflow-y-scroll lg:overflow-y-auto no-scrollbar transition-all duration-300 ease-in-out overflow-x-hidden\"\n       >\n         \u003C!-- Cancel Icon (Only for Mobile) -->\n         \u003C  button\n           class  =  \"absolute top-7 right-4 lg:hidden\"\n           @  click  =  \"  emit  (  'close-sidebar'  )  \"\n         >\n           \u003C  i\n             class  =  \"pi pi-times text-neutral-500 text-base border border-neutral-500 p-1 rounded-full\"\n           >\u003C/  i  >\n         \u003C/  button  >\n         \u003C!-- Sidebar Content -->\n         \u003C  a   class  =  \"inline-flex items-center gap-3 px-7 py-4 cursor-pointer\"  >\n           \u003C  BaseCustomIcon   name  =  \"logo\"   />\n         \u003C/  a  >\n         \u003C  div\n           class  =  \"w-[calc(100%-3rem)] mx-auto h-[1px] bg-surface-200 dark:bg-surface-700 px-6\"\n         /  >\n         \u003C  div   class  =  \"px-6 pt-6 flex-1\"  >\n           \u003C  ul   ref  =  \"outerDiv\"   class  =  \"flex flex-col gap-2 overflow-hidden\"  >\n             \u003C  template   v-for  =  \"  (item, index)   of   navs  \"   :  key  =  \"  index  \"  >\n               \u003C  li  >\n                 \u003C  NuxtLink\n                   :  to  =  \"  item.path  \"\n                   :  class  =  \"\n                     selectedNav   ===   item.label   ||   route.path   ===   item.path\n                       ?   'bg-primary-200 text-surface-900 shadow-sm'\n                       :   'border-transparent hover:border-surface-200 hover:bg-primary-75 text-surface-600'\n                   \"\n                   class  =  \"z-30 relative flex items-center gap-2 px-3 py-3 rounded-lg cursor-pointer transition-all\"\n                   @  click  =  \"  selectedNav   =   item.label  \"\n                 >\n                   \u003C  BaseCustomIcon   :  name  =  \"  item.icon  \"   />\n                   \u003C  span   class  =  \"flex-1 font-medium text-sm\"  >{{ item.label }}\u003C/  span  >\n                   \u003C  i\n                     v-if  =  \"  item?.subMenu  \"\n                     class  =  \"pi pi-chevron-down text-sm leading-none\"\n                   /  >\n                 \u003C/  NuxtLink  >\n                 \u003C  div\n                   v-if  =  \"  selectedNav   ===   item.label   &&   item?.subMenu  \"\n                   class  =  \"relative pl-1.5 flex flex-col transition-all duration-500 mt-2\"\n                   :  class  =  \"\n                     selectedNav   ===   item.label   &&   item?.subMenu\n                       ?   'opacity-100'\n                       :   'opacity-0'\n                   \"\n                 >\n                   \u003C  template   v-for  =  \"  (subItem, index)   of   item.subMenu  \"   :  key  =  \"  index  \"  >\n                     \u003C  div\n                       class  =  \"cursor-pointer relative px-3.5 py-2 flex items-center transition-all\"\n                       @  click  =  \"  selectedSubNav   =   subItem.label  \"\n                     >\n                       \u003C  svg\n                         width  =  \"18\"\n                         height  =  \"44\"\n                         viewBox  =  \"0 0 18 44\"\n                         fill  =  \"none\"\n                         xmlns  =  \"http://www.w3.org/2000/svg\"\n                         class  =  \"absolute left-4 -top-2\"\n                       >\n                         \u003C  path\n                           :  d  =  \"  getLinePath  (index, item.subMenu.  length  )  \"\n                           class  =  \"stroke-neutral-200 dark:stroke-surface-600\"\n                           stroke-width  =  \"1\"\n                         />\n                         \u003C  path\n                           d  =  \"M11.136 26.2862L11.1313 26.2863C11.1243 26.2863 11.1174 26.2849 11.1109 26.2823C11.1045 26.2796 11.0986 26.2756 11.0937 26.2707L11.0937 26.2707L11.0917 26.2687C11.0805 26.2575 11.0742 26.2422 11.0742 26.2263C11.0742 26.2105 11.0805 26.1953 11.0917 26.1841C11.0917 26.184 11.0917 26.184 11.0917 26.184L14.4286 22.8471L14.7822 22.4936L14.4286 22.14L11.1009 18.8123C11.0922 18.8014 11.0875 18.7878 11.0877 18.7737C11.088 18.7582 11.0943 18.7434 11.1052 18.7324C11.1162 18.7214 11.131 18.7151 11.1466 18.7149C11.1606 18.7146 11.1743 18.7193 11.1852 18.7281L14.9083 22.4512C14.9195 22.4625 14.9258 22.4777 14.9258 22.4936C14.9258 22.5095 14.9195 22.5247 14.9083 22.5359L11.1758 26.2685L11.1758 26.2685L11.1736 26.2707C11.1687 26.2756 11.1628 26.2796 11.1564 26.2823C11.1499 26.2849 11.143 26.2863 11.136 26.2862Z\"\n                           class  =  \"stroke-neutral-200 fill-neutral-200 dark:stroke-surface-600 dark:fill-surface-600\"\n                         />\n                         \u003C  path\n                           d  =  \"M1 14V17.5C1 20.2614 3.23858 22.5 6 22.5H15\"\n                           class  =  \"stroke-neutral-200 dark:stroke-surface-600\"\n                           stroke-width  =  \"1\"\n                         />\n                         \u003C  template   v-if  =  \"  index   ===   getSelectedIndex  ()  \"  >\n                           \u003C  path\n                             d  =  \"M11.136 26.2862L11.1313 26.2863C11.1243 26.2863 11.1174 26.2849 11.1109 26.2823C11.1045 26.2796 11.0986 26.2756 11.0937 26.2707L11.0937 26.2707L11.0917 26.2687C11.0805 26.2575 11.0742 26.2422 11.0742 26.2263C11.0742 26.2105 11.0805 26.1953 11.0917 26.1841C11.0917 26.184 11.0917 26.184 11.0917 26.184L14.4286 22.8471L14.7822 22.4936L14.4286 22.14L11.1009 18.8123C11.0922 18.8014 11.0875 18.7878 11.0877 18.7737C11.088 18.7582 11.0943 18.7434 11.1052 18.7324C11.1162 18.7214 11.131 18.7151 11.1466 18.7149C11.1606 18.7146 11.1743 18.7193 11.1852 18.7281L14.9083 22.4512C14.9195 22.4625 14.9258 22.4777 14.9258 22.4936C14.9258 22.5095 14.9195 22.5247 14.9083 22.5359L11.1758 26.2685L11.1758 26.2685L11.1736 26.2707C11.1687 26.2756 11.1628 26.2796 11.1564 26.2823C11.1499 26.2849 11.143 26.2863 11.136 26.2862Z\"\n                             class  =  \"stroke-neutral-500 fill-neutral-500 dark:stroke-surface-0 dark:fill-surface-0\"\n                           />\n                           \u003C  path\n                             d  =  \"M1 14V17.5C1 20.2614 3.23858 22.5 6 22.5H15\"\n                             class  =  \"stroke-neutral-500 dark:stroke-surface-0\"\n                             stroke-width  =  \"1\"\n                           />\n                         \u003C/  template  >\n                         \u003C  path\n                           v-if  =  \"  index   \u003C=   getSelectedIndex  ()  \"\n                           :  d  =  \"  getActiveLinePath  (index,   getSelectedIndex  ())  \"\n                           class  =  \"stroke-neutral-500 dark:stroke-surface-0\"\n                           stroke-width  =  \"1\"\n                         />\n                       \u003C/  svg  >\n                       \u003C  NuxtLink\n                         :  to  =  \"  subItem.path  \"\n                         class  =  \"leading-relaxed font-medium text-xs transition-all ml-8\"\n                         :  class  =  \"\n                           selectedSubNav   ===   subItem.label   ||\n                           route.path   ===   subItem.path\n                             ?   'text-neutral-500 dark:text-neutral-500'\n                             :   'text-neutral-200 dark:text-neutral-200 hover:text-primary-200 dark:hover:text-primary-200'\n                         \"\n                       >\n                         {{ subItem.label }}\n                       \u003C/  NuxtLink  >\n                     \u003C/  div  >\n                   \u003C/  template  >\n                 \u003C/  div  >\n               \u003C/  li  >\n             \u003C/  template  >\n           \u003C/  ul  >\n         \u003C/  div  >\n         \u003C  ul   class  =  \"flex flex-col gap-2 px-6 py-3\"  >\n           \u003C  template   v-for  =  \"  (item, index)   of   bottomNavs  \"   :  key  =  \"  index  \"  >\n             \u003C  li\n               :  class  =  \"\n                 selectedNav   ===   item.label   ||   route.path   ===   item.path\n                   ?   'bg-primary-200 text-surface-900 shadow-sm'\n                   :   'border-transparent hover:bg-primary-75 text-surface-600'\n               \"\n               class  =  \"flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition-all\"\n               @  click  =  \"  selectedNav   =   item.label  \"\n             >\n               \u003C  BaseCustomIcon   :  name  =  \"  item.icon  \"   />\n               \u003C  span   class  =  \"flex-1 font-medium\"  >{{ item.label }}\u003C/  span  >\n               \u003C  i\n                 v-if  =  \"  item?.subMenu  \"\n                 class  =  \"pi pi-chevron-down text-sm leading-none\"\n               /  >\n             \u003C/  li  >\n           \u003C/  template  >\n         \u003C/  ul  >\n         \u003C  div   class  =  \"bg-primary-50\"  >\n           \u003C  div   class  =  \"px-[35px] p-3 flex items-center switch pb-3\"  >\n             \u003C  InputSwitch   v-model  =  \"  checked  \"   class  =  \"\"   @  change  =  \"  themeChange  \"   />\n             \u003C  p   class  =  \"ml-3 text-[#676A6C] dark:text-[#E8E9E9]\"  >Light Mode\u003C/  p  >\n           \u003C/  div  >\n           \u003C  div\n             class  =  \"w-[calc(100%-3rem)] mx-auto h-[1px] bg-surface-200 dark:bg-surface-700 px-6 border-t border-neutral-50\"\n           /  >\n           \u003C  div\n             class  =  \"px-6 py-4 cursor-pointer bg-primary-50\"\n             @  click  =  \"  showModal   =   true  \"\n           >\n             \u003C  li\n               class  =  \"flex items-center gap-2 px-3 py-3 rounded-lg cursor-pointer transition-all border-transparent hover:bg-primary-75 text-surface-600\"\n             >\n               \u003C  BaseCustomIcon   name  =  \"logout\"   />\n               \u003C  span   class  =  \"flex-1 font-medium text-sm\"  >Sign Out\u003C/  span  >\n             \u003C/  li  >\n           \u003C/  div  >\n         \u003C/  div  >\n       \u003C/  div  >\n   \n       \u003C!-- Main Content -->\n       \u003C  div   class  =  \"flex-1\"   /  >\n       \u003C  ModalConfirmation\n         title  =  \"Log Out\"\n         message  =  \"Are you sure you want to logout?\"\n         primaryButtonText  =  \"Log Out\"\n         :  showLockIcon  =  \"  true  \"\n         :  showBackButton  =  \"  true  \"\n         :  closable  =  \"  false  \"\n         @  primary-action  =  \"  handlePrimaryAction  \"\n         :  isVisible  =  \"  showModal  \"\n         @  close  =  \"  showModal   =   false  \"\n       />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   { ref, onMounted, onUnmounted }   from   \"vue\"  ;\n   import   { useRoute }   from   \"#vue-router\"  ;\n   \n   const   route   =   useRoute  ();\n   const   selectedNav   =   ref  (  \"\"  );\n   const   selectedSubNav   =   ref  (  null  );\n   const   bottomNavs   =   ref  ([]);\n   const   navs   =   ref  ([\n     {\n       icon:   \"home\"  ,\n       label:   \"Dashboard\"  ,\n       path:   \"/\"  ,\n     },\n     {\n       icon:   \"globe\"  ,\n       label:   \"Services\"  ,\n       path:   \"/services\"  ,\n     },\n     {\n       icon:   \"person\"  ,\n       label:   \"Users\"  ,\n       path:   \"/users\"  ,\n     },\n     {\n       icon:   \"speaker\"  ,\n       label:   \"Referrals\"  ,\n       path:   \"/referrals\"  ,\n     },\n     {\n       icon:   \"gifts\"  ,\n       label:   \"Points\"  ,\n       path:   \"/points\"  ,\n     },\n     {\n       icon:   \"transaction\"  ,\n       label:   \"Transactions\"  ,\n       path:   \"/transactions\"  ,\n     },\n     {\n       icon:   \"wallet\"  ,\n       label:   \"Wallets\"  ,\n       path:   \"/wallets\"  ,\n     },\n     {\n       icon:   \"transition_slide\"  ,\n       label:   \"Banner\"  ,\n       path:   \"/banner\"  ,\n     },\n     {\n       icon:   \"teams\"  ,\n       label:   \"Teams\"  ,\n       subMenu: [\n         {\n           label:   \"Team Members\"  ,\n           path:   \"/teams\"  ,\n         },\n         {\n           label:   \"Audit\"  ,\n           path:   \"/teams/audit\"  ,\n         },\n       ],\n     },\n     {\n       icon:   \"settings\"  ,\n       label:   \"Settings\"  ,\n       path:   \"/settings\"  ,\n     },\n   ]);\n   \n   const   emit   =   defineEmits  ([  \"close-sidebar\"  ]);\n   \n   const   getLinePath   =   (  index  ,   totalItems  )   =>   {\n     if   (index   ===   0  ) {\n       return   `M1 0 V40`  ;\n     }   else   if   (index   ===   totalItems   -   1  ) {\n       return   `M1 -4 V14`  ;\n     }   else   {\n       return   `M1 -4 V40`  ;\n     }\n   };\n   \n   const   getActiveLinePath   =   (  index  ,   selectedIndex  )   =>   {\n     if   (index   ===   0  ) {\n       return   `M1 0 V${  index   ===   selectedIndex   ?   \"14\"   :   \"40\"}`  ;\n     }   else   if   (index   ===   selectedIndex) {\n       return   `M1 -4 V14`  ;\n     }   else   {\n       return   `M1 -4 V40`  ;\n     }\n   };\n   \n   const   getSelectedIndex   =   ()   =>   {\n     return   navs.value[  8  ].subMenu.  findIndex  (\n       (  subItem  )   =>   subItem.label   ===   selectedSubNav.value\n     );\n   };\n   \n   const   showModal   =   ref  (  false  );\n   \n   const   handlePrimaryAction   =   ()   =>   {\n     navigateTo  (  \"/login\"  );\n   };\n   \n   const   handleBack   =   ()   =>   {\n     console.  log  (  \"Back button clicked\"  );\n   };\n   \n   const   checked   =   ref  (  false  );\n   \n   const   themeChange   =   ()   =>   {\n     if   (localStorage.  getItem  (  \"color-theme\"  )) {\n       if   (localStorage.  getItem  (  \"color-theme\"  )   ===   \"light\"  ) {\n         document.documentElement.classList.  add  (  \"dark\"  );\n         localStorage.  setItem  (  \"color-theme\"  ,   \"dark\"  );\n       }   else   {\n         document.documentElement.classList.  remove  (  \"dark\"  );\n         localStorage.  setItem  (  \"color-theme\"  ,   \"light\"  );\n       }\n     }   else   {\n       if   (document.documentElement.classList.  contains  (  \"dark\"  )) {\n         document.documentElement.classList.  remove  (  \"dark\"  );\n         localStorage.  setItem  (  \"color-theme\"  ,   \"light\"  );\n       }   else   {\n         document.documentElement.classList.  add  (  \"dark\"  );\n         localStorage.  setItem  (  \"color-theme\"  ,   \"dark\"  );\n       }\n     }\n   };\n   \n   \u003C/  script  >\n   3. Default :\nThe main layout wrapper that includes the header, sidebar, and content area.     // layout/default.vue\n   \n   \u003C  template  >\n     \u003C  div   class  =  \"min-h-screen flex bg-neutral-20 text-neutral-500\"  >\n       \u003C!-- Sidebar -->\n       \u003C  div\n         id  =  \"app-sidebar\"\n         class  =  \"w-[18rem] bg-neutral-10 dark:bg-neutral-10 h-screen overflow-y-auto fixed lg:fixed top-0 left-0 z-50 lg:z-auto transition-transform duration-300 ease-in-out\"\n         :  class  =  \"\n           isSidebarOpen   ?   'translate-x-0'   :   '-translate-x-full lg:translate-x-0'\n         \"\n       >\n         \u003C  div   class  =  \"h-full\"  >\n           \u003C  PartialsTheSidebar   @  close-sidebar  =  \"  isSidebarOpen   =   false  \"   />\n         \u003C/  div  >\n       \u003C/  div  >\n   \n       \u003C!-- Main Content Area -->\n       \u003C  div   class  =  \"min-h-screen flex flex-col flex-auto relative lg:ml-[18rem]\"  >\n         \u003C!-- Header -->\n         \u003C  PartialsTheHeader\n           :  customProp  =  \"  customProp  \"\n           :  prevNavProp  =  \"  prevNavProp  \"\n           :  prevNavLink  =  \"  prevNavLink  \"\n           @  toggle-sidebar  =  \"  toggleSidebar  \"\n         />\n   \n         \u003C!-- Page Content -->\n         \u003C  div   class  =  \"py-4 sm:px-4 flex flex-col flex-auto text-neutral-500 mt-[70px]\"  >\n           \u003C  slot   /  >\n         \u003C/  div  >\n       \u003C/  div  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   { ref, watch }   from   \"vue\"  ;\n   import   { useRoute }   from   \"vue-router\"  ;\n   \n   const   route   =   useRoute  ();\n   const   isSidebarOpen   =   ref  (  false  );\n   \n   // Props from route meta\n   const   customProp   =   ref  (route.meta.customProp);\n   const   prevNavProp   =   ref  (route.meta.prevNavProp);\n   const   prevNavLink   =   ref  (route.meta.prevNavLink);\n   \n   // Watch for changes in route meta properties\n   watch  (\n     ()   =>   route.meta.customProp,\n     (  newValue  )   =>   {\n       customProp.value   =   newValue;\n     }\n   );\n   watch  (\n     ()   =>   route.meta.prevNavProp,\n     (  newValue  )   =>   {\n       prevNavProp.value   =   newValue;\n     }\n   );\n   watch  (\n     ()   =>   route.meta.prevNavLink,\n     (  newValue  )   =>   {\n       prevNavLink.value   =   newValue;\n     }\n   );\n   \n   // Toggle Sidebar\n   const   toggleSidebar   =   ()   =>   {\n     isSidebarOpen.value   =   !  isSidebarOpen.value;\n   };\n   \u003C/  script  >\n  Add to   app.vue     // app.vue\n   \u003C  style  >\n   @import   './assets/css/colors.css'  ;\n   \u003C/  style  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":297,"path":298,"dir":299,"title":300,"description":7,"keywords":301,"body":303},"content:2.Features:3.Notifications:1.Page notification 1.md","/features/notifications/page-notification-1","notifications","Page Notification 1",[302],"Notifications","  Notifications  This page displays a list of system-generated notifications such as content alerts,\nuser suspensions, or broadcast updates. It provides admins with a quick view of all recent activity that requires attention.  File Location: pages/notifications.vue  Features  ✅ Responsive layout with clear hierarchy  ✅ Notification badge showing unread status  ✅ Icon-based categorization of notifications  ✅ Timestamp formatting via Moment.js  Usage Example  The component renders a list of notifications using static sample data. Each item includes:  An icon (via BaseCustomIcon)  A title and message  A timestamp formatted with Moment.js  A red dot indicator if the notification is unread (status: false)     \u003C  template  >\n     \u003C  section   class  =  \"bg-neutral-10 p-6 rounded-lg min-h-[100%]\"  >\n       \u003C  div   class  =  \"mb-12\"  >\n         \u003C  div   class  =  \"sm:flex sm:items-center mb-1\"  >\n           \u003C  h4   class  =  \"font-semibold capitalize mb-2 sm:mb-0\"  >All Notifications\u003C/  h4  >\n           \u003C  div\n             class  =  \"flex items-center sm:ml-2 bg-neutral-20 border border-neutral-100 py-[1px] px-[6px] rounded-[6px] b-shadow w-fit\"\n           >\n             \u003C  div   class  =  \"w-[6px] h-[6px] rounded-full bg-[#367EE8] mr-[6px]\"  >\u003C/  div  >\n             \u003C  span   class  =  \"text-neutral-300 body-xsmall\"  >{{ notifications.  length   }} Notifications\u003C/  span  >\n           \u003C/  div  >\n         \u003C/  div  >\n         \u003C  p   class  =  \"body-regular text-neutral-l-600 mb-4\"  >\n           See all recent and past notifications received\n         \u003C/  p  >\n       \u003C/  div  >\n       \u003C  div\n         v-for  =  \"  (notification, index)   in   notifications  \"\n         :  key  =  \"  index  \"\n         class  =  \"flex justify-between pb-3 mb-6 border-b border-neutral-30 max-w-[712px]\"\n       >\n         \u003C  div   class  =  \"flex\"  >\n           \u003C  div   class  =  \"mr-3 p-2 rounded-full h-fit bg-neutral-30\"  >\n             \u003C  BaseCustomIcon   :  name  =  \"  notification.icon  \"   />\n           \u003C/  div  >\n           \u003C  div  >\n             \u003C  p   class  =  \"font-semibold text-sm text-neutral-500\"  >{{ notification.title }}\u003C/  p  >\n             \u003C  p   class  =  \"body-regular text-neutral-500 mb-2\"  >{{ notification.message }}\u003C/  p  >\n             \u003C  p   class  =  \"body-small text-neutral-200\"  >\n               {{   moment  (notification.date).  format  (  'DD MMM, YYYY . h:mm A'  ) }}\n             \u003C/  p  >\n           \u003C/  div  >\n         \u003C/  div  >\n         \u003C  div   v-if  =  \"  notification.status   ===   false  \"   class  =  \"bg-[#EF1212] w-2 h-2 rounded-full\"   /  >\n       \u003C/  div  >\n     \u003C/  section  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   moment   from   'moment'\n   \n   definePageMeta  ({\n     layout:   'default'  ,   // Specify the layout to use\n     customProp:   'Notifications'   // Define your custom prop\n   })\n   \n   useHead  ({\n     title:   'Notifications | Duduzili Admin'\n   })\n   \n   const   notifications   =   ref  ([\n     {\n       title:   'Reported Content Alert'  ,\n       message:   \"A post by @JaneDoe has been reported for 'Hate Speech.' Review now.\"  ,\n       date:   '30 Jan, 2025 . 01:05 PM'  ,\n       time:   '01:05 PM'  ,\n       status:   false  ,\n       icon:   'content'   // appropriate icon for reported content\n     },\n     {\n       title:   'User Account Suspended'  ,\n       message:   'User @ToxicUser has been suspended for violating community guidelines.'  ,\n       date:   '30 Jan, 2025 . 01:05 PM'  ,\n       time:   '01:05 PM'  ,\n       status:   false  ,\n       icon:   'users'   // suspended user icon\n     },\n     {\n       title:   'New Broadcast Sent'  ,\n       message:\n         \"Your scheduled broadcast 'New Feature Update' has been successfully sent to all users.\"  ,\n       date:   '30 Jan, 2025 . 01:05 PM'  ,\n       time:   '01:05 PM'  ,\n       status:   false  ,\n       icon:   'broadcasts'   // broadcast icon\n     },\n     {\n       title:   'New Broadcast Sent'  ,\n       message:\n         \"Your scheduled broadcast 'New Feature Update' has been successfully sent to all users.\"  ,\n       date:   '30 Jan, 2025 . 01:05 PM'  ,\n       time:   '01:05 PM'  ,\n       status:   true  ,\n       icon:   'broadcasts'   // broadcast icon\n     },\n     {\n       title:   'New Broadcast Sent'  ,\n       message:\n         \"Your scheduled broadcast 'New Feature Update' has been successfully sent to all users.\"  ,\n       date:   '30 Jan, 2025 . 01:05 PM'  ,\n       time:   '01:05 PM'  ,\n       status:   true  ,\n       icon:   'broadcasts'   // broadcast icon\n     },\n     {\n       title:   'New Broadcast Sent'  ,\n       message:\n         \"Your scheduled broadcast 'New Feature Update' has been successfully sent to all users.\"  ,\n       date:   '30 Jan, 2025 . 01:05 PM'  ,\n       time:   '01:05 PM'  ,\n       status:   true  ,\n       icon:   'broadcasts'   // broadcast icon\n     },\n     {\n       title:   'New Broadcast Sent'  ,\n       message:\n         \"Your scheduled broadcast 'New Feature Update' has been successfully sent to all users.\"  ,\n       date:   '30 Jan, 2025 . 01:05 PM'  ,\n       time:   '01:05 PM'  ,\n       status:   true  ,\n       icon:   'broadcasts'   // broadcast icon\n     }\n   ])\n   \u003C/  script  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":305,"path":306,"dir":307,"title":308,"description":7,"keywords":309,"body":311},"content:2.Features:4.Adverts:1.advert 1.md","/features/adverts/advert-1","adverts","Advert 1",[310],"Ad Banners/Advert","  Ad Banners/Advert  The Ad Banners page allows admins to view, search, and manage all advertisement banners displayed in the system. It includes support for adding new banners via a modal form and viewing banner details via a reusable component.  File Location: pages/advert.vue (or similar)  Features  ✅ Banner listing in a responsive grid  ✅ Search functionality with live input binding  ✅ Add New Banner modal form  ✅ Status indication for banners (e.g., checked/active)  ✅ Loading state via BasePageLoading  ✅ Modular component architecture using BannerAdvertBanner and BannerAddBanner     \u003C  template  >\n     \u003C  section   class  =  \"bg-neutral-10 p-6 rounded-lg min-h-[100%]\"  >\n       \u003C  div   class  =  \"\"  >\n         \u003C  BasePageLoading   v-if  =  \"  loading  \"   />\n   \n         \u003C!-- Page Header -->\n         \u003C  div   class  =  \"flex items-center mb-1\"  >\n           \u003C  h5   class  =  \"capitalize\"  >All Ad Banners\u003C/  h5  >\n           \u003C  div\n             class  =  \"flex items-center ml-2 bg-neutral-20 border border-[#D0D5DD] py-[1px] px-[6px] rounded-full b-shadow\"\n           >\n             \u003C  div   class  =  \"w-[6px] h-[6px] rounded-full bg-[#F2AE2A] mr-[6px]\"  >\u003C/  div  >\n             \u003C  span   class  =  \"text-neutral-300 body-xsmall\"  >{{ banners.  length   }} Banners\u003C/  span  >\n           \u003C/  div  >\n         \u003C/  div  >\n         \u003C  p   class  =  \"body-small text-neutral-200 mb-8\"  >Add and manage all advert banners\u003C/  p  >\n   \n         \u003C!-- Search and Add Button -->\n         \u003C  div   class  =  \"sm:flex justify-between items-center mb-4\"  >\n           \u003C  div   class  =  \"sm:w-[274px] w-full max-w-full sm:mb-0 mb-4\"  >\n             \u003C  IconField  >\n               \u003C  InputIcon   class  =  \"pi pi-search\"   />\n               \u003C  InputText   v-model  =  \"  search  \"   @  input  =  \"  onInput  \"   placeholder  =  \"Search\"   class  =  \"w-full\"   />\n             \u003C/  IconField  >\n           \u003C/  div  >\n           \u003C  CommonButton\n             title  =  \"Add New Banner\"\n             bgColor  =  \"bg-secondary-300 text-sm\"\n             textColor  =  \"text-primary-300 font-medium !h-[40px]\"\n             type  =  \"button\"\n             createIcon  =  \"plus\"\n             @  click  =  \"  addBanner   =   true  \"\n           />\n         \u003C/  div  >\n   \n         \u003C!-- Advert Banners Grid -->\n         \u003C  div   class  =  \"grid md:grid-cols-2 xl:grid-cols-3 gap-4\"  >\n           \u003C  BannerAdvertBanner\n             @  onView  =  \"  onViewDeatails  \"\n             v-for  =  \"  (banner, index)   in   banners  \"\n             :  key  =  \"  index  \"\n             :  banner  =  \"  banner  \"\n           />\n         \u003C/  div  >\n   \n         \u003C!-- Add Banner Dialog -->\n         \u003C  Dialog\n           v-model  :  visible  =  \"  addBanner  \"\n           modal\n           :  show-header  =  \"  false  \"\n           class  =  \"w-full max-w-md rounded-lg p-0 custom-modal\"\n         >\n           \u003C  div   class  =  \"flex items-center justify-between px-6 py-4 bg-neutral-20\"  >\n             \u003C  div   class  =  \"flex items-center gap-3\"  >\n               \u003C  div   class  =  \"\"  >\n                 \u003C  BaseCustomIcon   name  =  \"advert\"   />\n               \u003C/  div  >\n               \u003C  h5   class  =  \"text-base\"  >Add New Banner\u003C/  h5  >\n             \u003C/  div  >\n             \u003C  button   @  click  =  \"  addBanner   =   false  \"  >\n               \u003C  i\n                 class  =  \"pi pi-times text-neutral-500 text-base hover:bg-primary-50 p-3 hover:rounded-full\"\n               /  >\n             \u003C/  button  >\n           \u003C/  div  >\n           \u003C  BannerAddBanner   @  close  =  \"  addBanner   =   false  \"   @  proceed  =  \"  handleProceed  \"   />\n         \u003C/  Dialog  >\n   \n         \u003C!-- Add Banner Dialog -->\n         \u003C  Dialog\n           v-model  :  visible  =  \"  addBanner  \"\n           modal\n           :  show-header  =  \"  false  \"\n           class  =  \"w-full max-w-md rounded-lg p-0 custom-modal\"\n         >\n           \u003C  div   class  =  \"flex items-center justify-between px-6 py-4 bg-neutral-20\"  >\n             \u003C  div   class  =  \"flex items-center gap-3\"  >\n               \u003C  div   class  =  \"\"  >\n                 \u003C  BaseCustomIcon   name  =  \"advert\"   />\n               \u003C/  div  >\n               \u003C  h5   class  =  \"text-base\"  >Add New Banner\u003C/  h5  >\n             \u003C/  div  >\n             \u003C  button   @  click  =  \"  addBanner   =   false  \"  >\n               \u003C  i\n                 class  =  \"pi pi-times text-neutral-500 text-base hover:bg-primary-50 p-3 hover:rounded-full\"\n               /  >\n             \u003C/  button  >\n           \u003C/  div  >\n           \u003C  BannerAddBanner   @  close  =  \"  addBanner   =   false  \"   @  proceed  =  \"  handleProceed  \"   />\n         \u003C/  Dialog  >\n       \u003C/  div  >\n     \u003C/  section  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   { ref }   from   'vue'\n   \n   definePageMeta  ({\n     layout:   'default'  ,   // Specify the layout to use\n     customProp:   'Ad Banner'   // Define your custom prop\n   })\n   \n   useHead  ({\n     title:   'Ad Banner | Attafly Admin'\n   })\n   \n   const   addBanner   =   ref  (  false  )\n   const   search   =   ref  (  ''  )\n   const   loading   =   ref  (  false  )\n   \n   // Mock Data for Banners\n   const   banners   =   ref  ([\n     {\n       image:   'https://res.cloudinary.com/dlzc5sld6/image/upload/v1744122772/image_4_xv23ob.png'  ,\n       title:   'Sun King Solar Advert 2025'  ,\n       checked:   false  ,\n       date:   '23 Jan, 2025'\n     },\n     {\n       image:   'https://res.cloudinary.com/dlzc5sld6/image/upload/v1744122772/image_2_q8p7f3.png'  ,\n       title:   'TotalEnergy Solar Advert'  ,\n       checked:   true  ,\n       date:   '1 Feb, 2025'\n     },\n     {\n       image:   'https://res.cloudinary.com/dlzc5sld6/image/upload/v1744122772/image_3_qmzwk0.png'  ,\n       title:   'Solyn Energy Advert'  ,\n       checked:   false  ,\n       date:   '10 Feb, 2025'\n     }\n   ])\n   \n   const   onInput   =   ()   =>   {\n     console.  log  (  'Search input:'  , search.value)\n   }\n   \u003C/  script  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":313,"path":314,"dir":315,"title":316,"description":7,"keywords":317,"body":319},"content:2.Features:5.Dialog:1.Confirmation.md","/features/dialog/confirmation","dialog","Confirmation",[318],"Confirmation Dialog","  Confirmation Dialog  This component is a flexible, reusable confirmation dialog built with PrimeVue’s Dialog.  It supports optional input validation (reason field), customizable titles, icons, and action buttons.  It's useful for confirming user decisions such as deletions, submissions, or status changes.  🔧 Component: Dialog (PrimeVue)  Usage Summary  Controlled by prop: isOpen  Emits events: confirm and close  Optionally shows a reason textarea with validation     \u003C!-- components/confirmation.vue -->\n   \u003C  template  >\n       \u003C  Dialog\n         v-model  :  visible  =  \"  dialogVisible  \"\n         modal\n         :  show-header  =  \"  false  \"\n         class  =  \"w-full max-w-md rounded-lg p-0 custom-modal\"\n       >\n         \u003C!-- Modal Header -->\n         \u003C  div   class  =  \"flex items-center justify-between px-6 py-4 bg-neutral-20\"  >\n           \u003C  div   class  =  \"flex items-center gap-3\"  >\n             \u003C  div   v-if  =  \"  icon  \"   class  =  \"\"  >\n               \u003C  BaseCustomIcon   :  name  =  \"  icon  \"   />\n             \u003C/  div  >\n             \u003C  p   class  =  \"text-neutral-500 body-regular\"  >{{ title }}\u003C/  p  >\n           \u003C/  div  >\n           \u003C  button   @  click  =  \"  close  \"  >\n             \u003C  i\n               class  =  \"pi pi-times text-neutral-500 text-base hover:bg-primary-50 p-3 hover:rounded-full\"\n             /  >\n           \u003C/  button  >\n         \u003C/  div  >\n     \n         \u003C!-- Modal Body -->\n         \u003C  div   class  =  \"px-6 py-6\"  >\n           \u003C  div   class  =  \" mb-6 flex flex-col justify-center\"  >\n             \u003C  h4   class  =  \"text-neutral-500 pb-4\"  >{{ confirmationMessage }}\u003C/  h4  >\n             \u003C  p   class  =  \"body-small text-neutral-l-700\"  >\n               {{ informationText }}\n             \u003C/  p  >\n           \u003C/  div  >\n     \n           \u003C  div   v-if  =  \"  requireReason  \"   class  =  \"mt-4\"  >\n             \u003C  FormText\n               :  label  =  \"  reasonLabel  \"\n               required\n               v-model  =  \"  reason  \"\n               type  =  \"textarea\"\n               :  placeholder  =  \"  reasonPlaceholder  \"\n               @  input  =  \"  validateField  (  'reason'  )  \"\n             >\u003C/  FormText  >\n             \u003C  span   v-if  =  \"  errors.reason  \"   class  =  \"text-danger-300 mt-8 text-xs\"  >\n               {{ errors.reason }}\n             \u003C/  span  >\n           \u003C/  div  >\n         \u003C/  div  >\n     \n         \u003C!-- Modal Footer -->\n         \u003C  div   class  =  \"flex items-center gap-4 pt-4 pb-6 mx-6 border-t border-neutral-100\"  >\n           \u003C  div   class  =  \"w-full\"  >\n             \u003C  CommonButton\n               :  title  =  \"  cancelButtonText  \"\n               bgColor  =  \"bg-neutral-30\"\n               textColor  =  \"text-neutral-500 body-regular hover:bg-neutral-100 !h-10\"\n               type  =  \"button\"\n               @  click  =  \"  close  \"\n             />\n           \u003C/  div  >\n     \n           \u003C  div   class  =  \"w-full\"  >\n             \u003C  CommonButton\n               :  title  =  \"  actionButtonText  \"\n               :  bgColor  =  \"  actionButtonClass  \"\n               textColor  =  \"body-regular text-white !h-10\"\n               type  =  \"submit\"\n               :  createIcon  =  \"  btnIcon  \"\n               :  disabled  =  \"  requireReason   &&   !  reason.  trim  ()  \"\n               @  click  =  \"  confirm  \"\n             />\n           \u003C/  div  >\n         \u003C/  div  >\n       \u003C/  Dialog  >\n     \u003C/  template  >\n     \n     \u003C  script   setup  >\n     import   { ref, watch }   from   'vue'\n     import   FormText   from   '~/components/common/input/FormText.vue'\n     \n     const   props   =   defineProps  ({\n       isOpen: {\n         type: Boolean,\n         default:   false\n       },\n       // More flexible props for custom dialogs\n       title: {\n         type: String,\n         default:   'Confirmation'\n       },\n       confirmationMessage: {\n         type: String,\n         default:   'Are you sure you want to proceed with this action?'\n       },\n       informationText: {\n         type: String,\n         default:   'This action cannot be undone.'\n       },\n       icon: {\n         type: String,\n         default:   ''\n       },\n       btnIcon: {\n         type: String,\n         default:   ''\n       },\n       // Button configuration\n       actionButtonText: {\n         type: String,\n         default:   'Confirm'\n       },\n       cancelButtonText: {\n         type: String,\n         default:   'Cancel'\n       },\n       actionButtonClass: {\n         type: String,\n         default:   'bg-primary-300 hover:bg-primary-200'\n       },\n       // Reason field configuration\n       requireReason: {\n         type: Boolean,\n         default:   false\n       },\n       reasonLabel: {\n         type: String,\n         default:   'Give a reason'\n       },\n       reasonPlaceholder: {\n         type: String,\n         default:   'Enter reason'\n       },\n       // Optional - for backward compatibility\n       type: {\n         type: String,\n         default:   ''\n       },\n       entityType: {\n         type: String,\n         default:   ''\n       }\n     })\n     \n     const   emit   =   defineEmits  ([  'close'  ,   'confirm'  ])\n     \n     const   reason   =   ref  (  ''  )\n     const   dialogVisible   =   ref  (  false  )\n     const   errors   =   ref  ({\n       reason:   ''\n     })\n     \n     // Watch for changes in the isOpen prop\n     watch  (\n       ()   =>   props.isOpen,\n       (  newVal  )   =>   {\n         dialogVisible.value   =   newVal\n       }\n     )\n     \n     // Methods\n     const   close   =   ()   =>   {\n       reason.value   =   ''\n       errors.value   =   { reason:   ''   }\n       dialogVisible.value   =   false\n       emit  (  'close'  )\n     }\n     \n     const   confirm   =   ()   =>   {\n       emit  (  'confirm'  , {\n         type: props.type,\n         reason: reason.value,\n         entityType: props.entityType\n       })\n       reason.value   =   ''\n       dialogVisible.value   =   false\n     }\n     \n     const   validateField   =   (  field  )   =>   {\n       if   (field   ===   'reason'  ) {\n         errors.value.reason   =   !  reason.value.  trim  ()   ?   'Reason is required'   :   ''\n       }\n     }\n     \u003C/  script  >\n  How to use         \u003C  CommonConfirmation\n         :  isOpen  =  \"  isModalOpen  \"\n         :  title  =  \"  modalTitle  \"\n         :  confirmationMessage  =  \"  customMessage  \"\n         :  informationText  =  \"  customInfo  \"\n         :  actionButtonText  =  \"  modalActionText  \"\n         :  actionButtonClass  =  \"  modalActionClass  \"\n         :  requireReason  =  \"  requireReason  \"\n         :  btnIcon  =  \"  btnIcon  \"\n         @  close  =  \"  closeModal  \"\n         @  confirm  =  \"  handleConfirmation  \"\n       />\n     \u003C  script   setup  >\n   \n   // Modal configuration\n   const   isModalOpen   =   ref  (  false  )\n   const   modalTitle   =   ref  (  'Confirmation'  )\n   const   customMessage   =   ref  (  ''  )\n   const   customInfo   =   ref  (  ''  )\n   const   modalActionText   =   ref  (  'Confirm'  )\n   const   modalActionClass   =   ref  (  'bg-primary-300 hover:bg-primary-200'  )\n   const   requireReason   =   ref  (  false  )\n   const   btnIcon   =   ref  (  ''  )\n   // Open approve modal\n   \n   // Open activate modal\n   const   onActivate   =   ()   =>   {\n     modalTitle.value   =   'Reactivate Team Member'\n     modalActionText.value   =   'Reactivate'\n     modalActionClass.value   =   'bg-[#0DBF66] hover:bg-success-200'\n     requireReason.value   =   false\n     customMessage.value   =   'Are you sure you want to reactivate this team member?'\n     customInfo.value   =   \"This will give them access to the admin platform. You can suspend them at any time.\"\n     isModalOpen.value   =   true\n       btnIcon.value   =   'check'\n   }\n   \n   // Open suspend modal\n   const   onsuspend   =   ()   =>   {\n     modalTitle.value   =   'Suspend Team Member'\n     modalActionText.value   =   'Suspend'\n     modalActionClass.value   =   'bg-[#ED5556] hover:bg-danger-200'\n     requireReason.value   =   false\n     customMessage.value   =   'Are you sure you want to suspend this team member?'\n     customInfo.value   =\n       \"This will prevent them from accessing the admin platform. You can reactivate them at any time.\"\n     isModalOpen.value   =   true\n     btnIcon.value   =   'cancel'\n   }\n   \n   // Close modal\n   const   closeModal   =   ()   =>   {\n     isModalOpen.value   =   false\n   }\n   \n   // Handle confirmation\n   const   handleConfirmation   =   (  data  )   =>   {\n     console.  log  (  'Confirmation data:'  , data)\n     // Here you would handle the approve/reject action\n     // For example, make API calls based on data.type and data.reason\n     // Handle the action based on modalTitle.value or other contextual info\n     if   (modalTitle.value   ===   'Activate Member'  ) {\n       // Handle activation\n     }   else   if   (modalTitle.value   ===   'Suspend Member'  ) {\n       // Handle suspension\n     }\n     closeModal  ()\n   }\n   \u003C/  script  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":321,"path":322,"dir":323,"title":324,"description":7,"keywords":325,"body":327},"content:2.Features:tables.md","/features/tables","features","Tables",[326],"Table Component","  Table Component  The Dynamic Table component provides an efficient and flexible way to display tabular data in a Vue.js application. This component offers features such as sorting, filtering, pagination, and customizable headers. It can easily be integrated into any project requiring a data table with dynamic capabilities.  Dynamic Template    Create a   dynamicTable.vue  file in the components folder and add the code below     \u003C!-- components/Common/table/dynamicTable.vue -->\n   \u003C  template  >\n     \u003C  div   class  =  \"relative\"  >\n       \u003C  div   class  =  \" flex items-center mb-6\"  >\n         \u003C  h5   class  =  \" capitalize\"   v-if  =  \"  title  \"  >\n         {{ title }}\n       \u003C/  h5  >\n       \u003C  div\n         class  =  \"flex items-center ml-2 bg-neutral-20 border border-[#D0D5DD] py-[1px] px-[6px] rounded-full b-shadow\"\n       >\n         \u003C  div   class  =  \"w-[6px] h-[6px] rounded-full bg-[#F2AE2A] mr-[6px]\"  >\u003C/  div  >\n         \u003C  span   class  =  \"text-neutral-400 text-[12px] font-medium\"\n           >{{ row_count }} {{ count_label }}\u003C/  span  >\n       \u003C/  div  >\n       \u003C/  div  >\n        \u003C  p   v-if  =  \"  description  \"   class  =  \"sm:text-lg text-subtxt dark:text-white mb-10\"  >\n         {{ description }}\n       \u003C/  p  >\n   \n       \u003C  div   class  =  \"grid\"  >\n         \u003C  div   class  =  \"col-12 overflow-auto\"  >\n           \u003C  div   class  =  \"card text-sm font-normal capitalize\"  >\n             \u003C  DataTable\n               v-model  :  selection  =  \"  selectedProduct  \"\n               :  value  =  \"  mockData  \"\n               rowGroupMode  =  \"rowspan\"\n               sortMode  =  \"single\"\n               :  sortOrder  =  \"  1  \"\n               scrollable\n               responsiveLayout  =  \"scroll\"\n               class  =  \"mb-6\"\n               @  sort  =  \"  sort  \"\n               @  row-click  =  \"  view  \"\n             >\n               \u003C  slot   name  =  \"header\"  >\n                 \u003C  div\n                   :  class  =  \"\n                     plainInfo\n                       ?   'flex justify-between items-center overflow-auto table-header flex-wrap gap-2'\n                       :   'py-5 flex justify-between items-center overflow-auto table-header flex-wrap gap-2'\n                   \"\n                 >\n                   \u003C  div\n                     class  =  \"flex bg-transparent justify-start items-center flex-wrap gap-2\"\n                   >\n                     \u003C  div   class  =  \"text-left\"   v-if  =  \"  hasSearch  \"  >\n                       \u003C  div   class  =  \"sm:w-[274px] w-full max-w-full\"  >\n                         \u003C  IconField   class  =  \"\"  >\n                           \u003C  InputIcon   class  =  \"pi pi-search\"  > \u003C/  InputIcon  >\n                           \u003C  InputText\n                             v-model  =  \"  search  \"\n                             @  input  =  \"  onInput  \"\n                             placeholder  =  \"Search\"\n                             class  =  \"w-full\"\n                           />\n                         \u003C/  IconField  >\n                       \u003C/  div  >\n                     \u003C/  div  >\n                     \u003C  slot   name  =  \"dateFilter\"  >\u003C/  slot  >\n                   \u003C/  div  >\n   \n                   \u003C  div\n                     class  =  \"flex bg-transparent xl:justify-end items-center flex-wrap gap-2\"\n                   >\n                     \u003C  slot   name  =  \"filter\"  >\u003C/  slot  >\n                      \u003C  div   class  =  \"flex justify-end items-center\"   v-if  =  \"  hasLimit  \"  >\n                       \u003C  label   for  =  \"limit\"   class  =  \"text-sm text-[#7C7C7A] mr-2\"  >{{\n                         \"show\"\n                       }}\u003C/  label  >\n                       \u003C  FormSelect\n                         placeholder  =  \"10\"\n                         name  =  \"limit\"\n                         :  options  =  \"  limits  \"\n                         id  =  \"limit\"\n                         v-model  =  \"  limit  \"\n                         item-text  =  \"name\"\n                         item-value  =  \"value\"\n                         @  update  :  model-value  =  \"  onLimit  \"\n                         hideError\n                       />\n                     \u003C/  div  >\n                   \u003C/  div  >\n                 \u003C/  div  >\n               \u003C/  slot  >\n   \n               \u003C  slot   name  =  \"items\"  >\n                 \u003C  Column\n                   selectionMode  =  \"multiple\"\n                   headerStyle  =  \"width: 3rem\"\n                   v-if  =  \"  itemsBulkActions   &&   itemsBulkActions.  length   >   0  \"\n                 >\u003C/  Column  >\n                 \u003C  Column\n                   v-for  =  \"  (column, index)   in   selectedColumns  \"\n                   :  key  =  \"  index  \"\n                   :  sortable  =  \"  column.sortable  \"\n                   :  field  =  \"  column.field  \"\n                   :  header  =  \"  column.header  \"\n                   :  style  =  \"  column.style  \"\n                   :  frozen  =  \"  !!  column.frozen  \"\n                   :  class  =  \"  column.class  \"\n                   alignFrozen  =  \"right\"\n                   class  =  \"cursor-pointer body-normal text-neutral-500\"\n                 >\n                   \u003C  template   #  body  =  \"  slotProps  \"  >\n                     \u003C  slot\n                       :  name  =  \"  column.field  \"\n                       v-bind  =  \"  slotProps  \"\n                       v-if  =  \"  slotProps   &&   slotProps.data  \"\n                     >\n                       {{ slotProps.data[column.field] }}\n                     \u003C/  slot  >\n                   \u003C/  template  >\n                 \u003C/  Column  >\n               \u003C/  slot  >\n   \n               \u003C  template   #  footer   v-if  =  \"  !  mockData   ||   mockData.  length   \u003C   1  \"  >\n                 \u003C  div\n                   class  =  \"flex flex-col items-center justify-center gap-6 py-12\"\n                 >\n                   \u003C  svg\n                     width  =  \"72\"\n                     height  =  \"72\"\n                     viewBox  =  \"0 0 72 72\"\n                     fill  =  \"none\"\n                     xmlns  =  \"http://www.w3.org/2000/svg\"\n                   >\n                     \u003C  rect   width  =  \"72\"   height  =  \"72\"   rx  =  \"36\"   fill  =  \"#F5F5F5\"   />\n                     \u003C  mask\n                       id  =  \"mask0_788_10160\"\n                       style  =  \"  mask-type  :   alpha  \"\n                       maskUnits  =  \"userSpaceOnUse\"\n                       x  =  \"14\"\n                       y  =  \"14\"\n                       width  =  \"44\"\n                       height  =  \"44\"\n                     >\n                       \u003C  rect\n                         x  =  \"14.3999\"\n                         y  =  \"14.3999\"\n                         width  =  \"43.2\"\n                         height  =  \"43.2\"\n                         fill  =  \"#D9D9D9\"\n                       />\n                     \u003C/  mask  >\n                     \u003C  g   mask  =  \"url(#mask0_788_10160)\"  >\n                       \u003C  path\n                         d  =  \"M25.2 53.0999C23.9424 53.0999 22.878 52.6643 22.0068 51.7931C21.1356 50.9219 20.7 49.8575 20.7 48.5999V46.6613C20.7 45.7667 21.0186 45.0008 21.6558 44.3636C22.293 43.7264 23.059 43.4078 23.9539 43.4078H26.1V22.1539C26.1 21.259 26.4186 20.4929 27.0558 19.8557C27.693 19.2185 28.459 18.8999 29.3539 18.8999H48.046C48.9409 18.8999 49.707 19.2185 50.3442 19.8557C50.9814 20.4929 51.3 21.259 51.3 22.1539V48.5999C51.3 49.8575 50.8644 50.9219 49.9932 51.7931C49.122 52.6643 48.0576 53.0999 46.8 53.0999H25.2ZM46.8 50.3999C47.31 50.3999 47.7375 50.2274 48.0825 49.8824C48.4275 49.5374 48.6 49.1099 48.6 48.5999V22.1539C48.6 21.9922 48.5481 21.8594 48.4443 21.7556C48.3405 21.6518 48.2077 21.5999 48.046 21.5999H29.3539C29.1922 21.5999 29.0595 21.6518 28.9557 21.7556C28.8519 21.8594 28.8 21.9922 28.8 22.1539V43.4078H41.746C42.6409 43.4078 43.407 43.7264 44.0442 44.3636C44.6814 45.0008 45 45.7667 45 46.6613V48.5999C45 49.1099 45.1725 49.5374 45.5175 49.8824C45.8625 50.2274 46.29 50.3999 46.8 50.3999ZM32.296 30.046C31.9135 30.046 31.593 29.9165 31.3344 29.6576C31.0755 29.3987 30.946 29.078 30.946 28.6955C30.946 28.3127 31.0755 27.9922 31.3344 27.7339C31.593 27.4753 31.9135 27.346 32.296 27.346H45.1039C45.4864 27.346 45.807 27.4754 46.0656 27.7343C46.3245 27.9932 46.4539 28.3141 46.4539 28.6969C46.4539 29.0794 46.3245 29.3999 46.0656 29.6585C45.807 29.9168 45.4864 30.046 45.1039 30.046H32.296ZM32.296 35.2385C31.9135 35.2385 31.593 35.1091 31.3344 34.8502C31.0755 34.5913 30.946 34.2704 30.946 33.8876C30.946 33.5051 31.0755 33.1846 31.3344 32.926C31.593 32.6677 31.9135 32.5385 32.296 32.5385H45.1039C45.4864 32.5385 45.807 32.668 46.0656 32.9269C46.3245 33.1855 46.4539 33.5062 46.4539 33.889C46.4539 34.2718 46.3245 34.5923 46.0656 34.8506C45.807 35.1092 45.4864 35.2385 45.1039 35.2385H32.296ZM25.2 50.3999H42.3V46.6613C42.3 46.4999 42.2481 46.3673 42.1443 46.2635C42.0405 46.1594 41.9077 46.1074 41.746 46.1074H23.9539C23.7922 46.1074 23.6595 46.1594 23.5557 46.2635C23.4519 46.3673 23.4 46.4999 23.4 46.6613V48.5999C23.4 49.1099 23.5725 49.5374 23.9175 49.8824C24.2625 50.2274 24.69 50.3999 25.2 50.3999ZM25.2 50.3999H23.4H42.3H25.2Z\"\n                         fill  =  \"#121212\"\n                       />\n                     \u003C/  g  >\n                   \u003C/  svg  >\n   \n                                  \u003C  div   v-if  =  \"  loading  \"   class  =  \"flex items-center justify-center gap-2 py-20\"  >\n                     \u003C  p   class  =  \"body-small text-neutral-text_secondary\"  >Loading data...\u003C/  p  >\n                     \u003C  i   class  =  \"pi pi-spin pi-spinner text-2xl text-primary-300\"  >\u003C/  i  >\n                   \u003C/  div  >\n                   \u003C  div   v-else   class  =  \"text-center max-w-[406px]\"  >\n                     \u003C  h4   class  =  \"mb-2\"  >No Data to Show\u003C/  h4  >\n                     \u003C  p   class  =  \"body-normal text-neutral-text_secondary0\"  >\n                       Your information will be displayed here when available.\n                     \u003C/  p  >\n                   \u003C/  div  >\n                 \u003C/  div  >\n   \n               \u003C/  template  >\n             \u003C/  DataTable  >\n   \n             \u003C  div\n               class  =  \"sm:flex sm:justify-center sm:items-center\"\n               v-if  =  \"  mockData   &&   mockData.  length   >   0   &&   hasPagination  \"\n             >\n               \u003C!-- \u003Cdiv\n                 class=\"mb-6 sm:mb-0 text-[#5C5C5C] bg-primary-50 w-max px-5 py-2 rounded-full\"\n               >\n                 \u003Cp class=\"sm:text-base text-sm lowercase\">\n                   Showing {{ metadata.page }} of {{ metadata.pages }}\n                 \u003C/p>\n               \u003C/div> -->\n   \n               \u003C  Paginator\n                 v-if  =  \"  mockData   &&   mockData.  length   >   0   &&   hasPagination  \"\n                 v-model  =  \"  metadata.page  \"\n                 :  rows  =  \"  metadata.limit  \"\n                 :  totalRecords  =  \"  metadata.total  \"\n                 :  rowsPerPageOptions  =  \"  limits  \"\n                 @  page  =  \"  onPage  ($event)  \"\n                 @  update  :  rows  =  \"  onPageLimit  ($event)  \"\n               />\n             \u003C/  div  >\n           \u003C/  div  >\n         \u003C/  div  >\n       \u003C/  div  >\n   \n       \u003C  Toast   />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   FormSelect   from   \"~/components/common/input/FormSelect.vue\"  ;\n   \n   const   props   =   defineProps  ({\n     loading: {\n       type: Boolean,\n       default:   false\n     },\n     columns: {\n       type: Array,\n       required:   true  ,\n       default  : ()   =>   [],\n     },\n     mockData: {\n       type: Array,\n       required:   true  ,\n       default  : ()   =>   [],\n     },\n     otherFilter: {\n       type: Object,\n       default  : ()   =>   {},\n     },\n     url: {\n       type: String,\n       default:   \"\"  ,\n     },\n     subPath: {\n       type: String,\n       default:   \"\"  ,\n     },\n     title: {\n       type: String,\n       default:   \"\"  ,\n     },\n     count_label: {\n       type: String,\n       default:   \"\"  ,\n     },\n     row_count: {\n       type: Number,\n       default:   0  ,\n     },\n     description: {\n       type: String,\n       default:   \"\"  ,\n     },\n     dateFilter: {\n       type: Boolean,\n       default:   true  ,\n     },\n     hasSearch: {\n       type: Boolean,\n       default:   true  ,\n     },\n     hasLimit: {\n       type: Boolean,\n       default:   false  ,\n     },\n     hasPagination: {\n       type: Boolean,\n       default:   true  ,\n     },\n     plainInfo: {\n       type: Boolean,\n       default:   false  ,\n     },\n     itemsBulkActions: {\n       type: Array,\n       default  : ()   =>   [],\n     },\n     metadata: {\n       type: Array,\n       default  : ()   =>   [{ page:   1  , limit:   10  , total:   0  , pages:   1   }],\n     },\n   });\n   \n   const   first   =   ref  (  0  );\n   const   selectedProduct   =   ref  (  null  );\n   const   search   =   ref  (  \"\"  );\n   // const tableData = ref([]);\n   const   limits   =   [  10  ,   20  ,   30  ];\n   const   page   =   ref  (  1  );\n   const   limit   =   ref  (  10  );\n   const   pages   =   ref  (  1  );\n   const   total   =   ref  (  1  );\n   const   loading   =   ref  (  false  );\n   const   filter   =   ref  (  \"\"  );\n   const   order   =   ref  (  1  );\n   const   selectedColumns   =   ref  ([  ...  props.columns]);\n   const   emit   =   defineEmits  ([\n     \"bulkChange\"  ,\n     \"create\"  ,\n     \"onPagination\"  ,\n     \"onSearch\"  ,\n     \"onSort\"  ,\n     \"onLimit\"  ,\n     \"onReload\"  ,\n     \"onView\"  ,\n   ]);\n   const   toast   =   useToast  ();\n   \n   onMounted  (()   =>   {\n     onToggle  (selectedColumns.value);\n   });\n   onBeforeMount  (  async   ()   =>   {\n     reset  ();\n   });\n   \n   const   onToggle   =   (  val  )   =>   {\n     selectedColumns.value   =   props.columns.  filter  ((  col  )   =>   val.  includes  (col));\n   };\n   const   sort   =   (  e  )   =>   {\n     emit  (  \"onSort\"  ,   \"sort\"  , e.sortOrder, e.sortField);\n     order.value   =   e.sortOrder;\n   };\n   const   onPage   =   (  $event  )   =>   {\n     page.value   =   $event.page   +   1  ;\n     emit  (  \"onPagination\"  ,   \"page\"  , page.value);\n   };\n   const   onInput   =   ()   =>   {\n     emit  (  \"onSearch\"  ,   \"search\"  , search.value);\n   };\n   const   view   =   (  e  )   =>   {\n     emit  (  \"onView\"  , e.data);\n   };\n   const   onLimit   =   (  info  )   =>   {\n     emit  (  \"onLimit\"  ,   \"limit\"  , limit.value);\n   };\n   const   tableReload   =   (  info  )   =>   {\n     emit  (  \"onReload\"  ,   \"reload\"  );\n   };\n   const   reset   =   ()   =>   {\n     first.value   =   (page.value   -   1  )   *   limit.value;\n   };\n   \n   \u003C/  script  >\n  Usage Example     \u003C!-- pages/index.vue -->\n   \u003C  template  >\n     \u003C  div  >\n           \u003C  CommonTableDynamicTable\n         :  columns  =  \"  columns  \"\n         title  =  \"All Transactions\"\n         :  mock-data  =  \"  tableData  \"\n         @  onPagination  =  \"  updateStateAndFetch  \"\n         @  onSort  =  \"  updateStateAndFetch  \"\n         @  onSearch  =  \"  updateStateAndFetch  \"\n         @  onLimit  =  \"  updateStateAndFetch  \"\n         @  onView  =  \"  onViewDeatails  \"\n         :  metadata  =  \"  metadata  \"\n         :  row_count  =  \"  total  \"\n       >\n         \u003C  template   #  filter  >\n   \n           \u003C  CommonButton\n             title  =  \"Export\"\n             bgColor  =  \"bg-primary-300 border border-violet-90 dark:border-violet-60 body-regular !h-[40px]\"\n             textColor  =  \"text-neutral-500\"\n             type  =  \"button\"\n             createIcon  =  \"download\"\n           />\n           \u003C  CommonButton\n             title  =  \"Add New Broadcast\"\n             bgColor  =  \"bg-primary-300 body-regular !h-[40px]\"\n             textColor  =  \"text-neutral-500\"\n             type  =  \"button\"\n             createIcon  =  \"plus\"\n           />\n         \u003C/  template  >\n         \u003C  template   #  full_name  =  \"  slotProps  \"  >\n           \u003C  div   class  =  \"flex items-center gap-2\"  >\n             \u003C  div  >\n               \u003C  p   class  =  \"mb-1\"  >{{ slotProps.data.full_name }}\u003C/  p  >\n               \u003C  p   class  =  \"text-neutral-200 text-xs\"  >\n                 {{ slotProps.data.username }}\n               \u003C/  p  >\n             \u003C/  div  >\n           \u003C/  div  >\n         \u003C/  template  >\n         \u003C  template   #  date  =  \"  slotProps  \"  >\n           \u003C  div   class  =  \"flex items-center gap-2\"  >\n             \u003C  div  >\n               \u003C  p   class  =  \"mb-1 body-small text-neutral-300\"  >\n                 {{   moment  (slotProps.data.date).  format  (  'DD, MMM YYYY'  ) }}\n               \u003C/  p  >\n               \u003C  p   class  =  \"text-neutral-200 body-xsmall\"  >\n                 {{   moment  (slotProps.data.date).  format  (  'h:mm A'  ) }}\n               \u003C/  p  >\n             \u003C/  div  >\n           \u003C/  div  >\n         \u003C/  template  >\n         \u003C  template   #  type  =  \"  slotProps  \"  >\n           \u003C  div   class  =  \"\"  >\n             \u003C  CommonTag   :  info  =  \"  slotProps.data.type  \"   />\n           \u003C/  div  >\n         \u003C/  template  >\n         \u003C  template   #  status  =  \"  slotProps  \"  >\n           \u003C  div   class  =  \"\"  >\n             \u003C  CommonStatus   :  status  =  \"  slotProps.data.status  \"   />\n           \u003C/  div  >\n         \u003C/  template  >\n         \u003C  template   #  action  =  \"  slotProps  \"  >\n           \u003C  CommonActionMenu\n             :  items  =  \"  getMenuItems  (slotProps.data)  \"\n             :  data  =  \"  slotProps.data  \"\n             @  view  =  \"  onViewDeatails  (slotProps.data._id)  \"\n             @  activate  =  \"  onActivate  (slotProps.data._id)  \"\n             @  suspend  =  \"  onsuspend  (slotProps.data._id)  \"\n           />\n         \u003C/  template  >\n       \u003C/  CommonTableDynamicTable  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   moment   from   'moment'\n   \n   \n   const   columns   =   [\n     {\n       field:   'title'  ,\n       header:   'Title'  ,\n       sortable:   false\n     },\n     {\n       field:   'type'  ,\n       header:   'Type'  ,\n       sortable:   false\n     },\n     {\n       field:   'status'  ,\n       header:   'Status'  ,\n       sortable:   false\n     },\n     {\n       field:   'date'  ,\n       header:   'Created Date'  ,\n       sortable:   false\n     },\n     {\n       field:   'action'  ,\n       header:   ''  ,\n       sortable:   false\n     }\n   ]\n   \n   const   tableData   =   [\n     {\n       title:   'New Feature Update'  ,\n       type:   'Announcement'  ,\n       status:   'Sent'  ,\n       date:   '08, Mar 2025'  ,\n       time:   '12:05 PM'\n     },\n     {\n       title:   'System Maintenance'  ,\n       type:   'Alert'  ,\n       status:   'Sent'  ,\n       date:   '08, Mar 2025'  ,\n       time:   '12:05 PM'\n     },\n     {\n       title:   'Survey Invitation'  ,\n       type:   'Engagement'  ,\n       status:   'Ended'  ,\n       date:   '08, Mar 2025'  ,\n       time:   '12:05 PM'\n     },\n     {\n       title:   'Security Update'  ,\n       type:   'Alert'  ,\n       status:   'In Progress'  ,\n       date:   '08, Mar 2025'  ,\n       time:   '12:05 PM'\n     },\n     {\n       title:   'Community Guidelines'  ,\n       type:   'Announcement'  ,\n       status:   'Sent'  ,\n       date:   '08, Mar 2025'  ,\n       time:   '12:05 PM'\n     }\n   ]\n   \n   const   metadata   =   ref  ([{ page:   1  , limit:   10  , total:   0  , pages:   1   }])\n   \n   function   getMenuItems  (  rowData  ) {\n     return   [\n       { label:   'View Broadcast'  , icon:   'broadcasts'  , emit:   'edit'   },\n       { label:   'End'  , icon:   'cancel-red'  , emit:   'suspend'   },\n       { label:   'Delete'  , icon:   'trash'  , emit:   'activate'   }\n     ]\n   }\n   \n   const   updateStateAndFetch   =   (  actionType  ,   value1  ,   value2   =   null  )   =>   {\n     if   (actionType   ===   'page'  ) {\n       page.value   =   value1\n     }   else   if   (actionType   ===   'search'  ) {\n       search.value   =   value1\n     }   else   if   (actionType   ===   'sort'  ) {\n       order.value   =   value1\n       // filter.value = value2;\n     }   else   if   (actionType   ===   'limit'  ) {\n       limit.value   =   value1\n       // filter.value = value2;\n     }   else   {\n       console.  log  (  'Unknown action type:'  , actionType)\n       return   // Exit if the action type is not recognized\n     }\n     FetchData  ()\n   }\n   \u003C/  script  >\n  A customizable tag component based on PrimeVue’s Tag that visually represents information like statuses, labels, or categories with optional styling for background and borders.     \u003C!-- /components/common/Tag.vue -->\n   \n   \u003C  template  >\n     \u003C  div  >\n       \u003C  Tag   :  value  =  \"  info  \"   :  style  =  \"  getTagStyle  (info)  \"   rounded   />\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   Tag   from   \"primevue/tag\"  ;\n   \n   const   props   =   defineProps  ({\n     info: {\n       type: String,\n     },\n     back_g: {\n       type: Boolean,\n       default:   true  ,\n     },\n     border: {\n       type: Boolean,\n       default:   false  ,\n     },\n   });\n   \n   // Example function to determine tag style based on feature\n   const   getTagStyle   =   (  feature  )   =>   {\n     switch   (feature) {\n       case   \"Estimate Request\"  :\n         return   {\n           backgroundColor: props.back_g   ?   \"#F7EEFC\"   :   \"transparent\"  ,\n           color:   \"#AF52DE\"  ,\n           borderColor:   \"#F7EEFC\"  ,\n         };\n       default  :\n         return   {\n           backgroundColor: props.back_g   ?   \"#FCFCFD\"   :   \"transparent\"  ,\n           color:   \"#3A3A3A\"  ,\n           borderColor:   \"#D9D9DB\"  ,\n         };\n     }\n   };\n   \u003C/  script  >\n  A visual status indicator that displays a rounded badge with an icon and text. It adapts its color and icon based on the given status, using Tailwind CSS utility classes and custom icons.     \u003C!-- /components/common/Status.vue -->\n   \n   \u003C  template  >\n     \u003C  div   class  =  \" body-small\"  >\n       \u003C  button\n         class  =  \" text-success-300 dark:text-success-75 bg-success-50 dark:bg-success-500 py-[1px] rounded-[100px] pl-[4px] pr-2 flex items-center gap-[4px] capitalize\"\n         v-if  =  \"\n           status   ===   'Completed'   ||   status   ===   'Active'   ||   status   ===   'Paid'   ||   status   ===   'Sent'   ||   status   ===   'Resolved'\n         \"\n       >\n         \u003C  div  >\n           \u003C  BaseCustomIcon   name  =  \"check_circle\"   />\n         \u003C/  div  >\n         {{ status }}\n       \u003C/  button  >\n   \n       \u003C  button\n         class  =  \" text-warning-300 dark:text-warning-75 bg-warning-50 dark:bg-warning-500 py-[1px] rounded-[100px] pl-[4px] pr-2 flex items-center gap-[4px] capitalize\"\n         v-else-if  =  \"\n           status   ===   'Unverified'   ||   status   ===   'Archived'   ||   status   ===   'In Progress'   ||   status   ===   'Pending'\n         \"\n       >\n       \u003C  div  >\n           \u003C  BaseCustomIcon   name  =  \"not_disturb\"   />\n         \u003C/  div  >\n         {{ status }}\n       \u003C/  button  >\n       \u003C  button\n         class  =  \" text-danger-300 dark:text-danger-75 dark:bg-danger-500 bg-[#FDEEEE] py-[1px] rounded-[100px] pl-[4px] pr-2 flex items-center gap-[4px] capitalize\"\n         v-else-if  =  \"  status   ===   'Cancelled'   ||   status   ===   'Suspended'   ||   status   ===   'Rejected'   ||   status   ===   'Failed'   ||   status   ===   'Ended'   ||   status   ===   'Deleted'\"\n       >\n       \u003C  div  >\n         \u003C  BaseCustomIcon   name  =  \"suspend\"   />\n         \u003C/  div  >\n         {{ status }}\n       \u003C/  button  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   const   props   =   defineProps  ({\n     status: {\n       type: String,\n     },\n   });\n   \u003C/  script  >\n  A customizable dropdown menu built with PrimeVue’s Menu component. This menu allows you to attach actions to items, emit events dynamically, and trigger context-based operations using icons and labels.     \u003C!-- /components/common/ActionMenu.vue -->\n   \u003C  template  >\n     \u003C  div   class  =  \"card flex justify-end\"   v-if  =  \"  items   &&   items.  length   >   0  \"  >\n       \u003C  button   @  click  =  \"  toggle  \"   class  =  \"dark:text-[white]\"  >\n         \u003C  BaseCustomIcon   name  =  \"3dot\"   />\n       \u003C/  button  >\n       \u003C  Menu   ref  =  \"menu\"   :  model  =  \"  items  \"   :  popup  =  \"  true  \"   class  =  \"rounded-[8px] !min-w-[143px]\"  >\n         \u003C  template   #  item  =  \"  { item }  \"  >\n           \u003C  button\n             class  =  \"flex items-center justify-between gap-2 py-2 px-3 w-full\"\n             @  click  =  \"  $emit  (item.emit, data)  \"\n           >\n             \u003C  span   class  =  \"font-normal text-neutral-500 body-small text-nowrap\"  >{{ item.label }}\u003C/  span  >\n             \u003C  div   class  =  \"text-neutral-l-600\"  >\n               \u003C  BaseCustomIcon   :  name  =  \"  item.icon  \"   />\n             \u003C/  div  >\n           \u003C/  button  >\n         \u003C/  template  >\n       \u003C/  Menu  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   { ref, defineEmits }   from   'vue'\n   \n   const   menu   =   ref  ()\n   const   props   =   defineProps  ({\n     items: {\n       type: Array,\n       required:   true  ,\n       default  : ()   =>   []\n     },\n     data: {\n       type: Object,\n       default  : ()   =>   null\n     }\n   })\n   \n   const   toggle   =   (  event  )   =>   {\n     menu.value.  toggle  (event)\n   }\n   \u003C/  script  >\n  A versatile and fully customizable button component that supports loading state, icon placement, dynamic colors, and click events. Perfect for use across your application wherever buttons are needed with consistent styling and behavior.     \u003C!-- /components/common/button.vue -->\n   \u003C  template  >\n     \u003C  div   :  class  =  \"  buttonContainerClass  \"  >\n       \u003C  button\n         :  class  =  \"  [\n           'w-full h-[48px] px-5 rounded-[8px] flex justify-center items-center'  ,\n           borderClass,\n           bgClass,\n           textColorClass,\n           borderColor   !==   ''   ?   `border ${  borderColor  }`   :   ''  ,\n           {   'opacity-50 cursor-not-allowed'  : disabled   ||   loading } \n   \n         ]  \"\n         @  click  =  \"  handleClick  \"\n         :  disabled  =  \"  disabled   ||   loading  \"   \n         :  type  =  \"  type  \"\n       >\n         \u003C!-- Show spinner when loading -->\n         \u003C  span   v-if  =  \"  loading  \"  >\n           \u003C  i   class  =  \"pi pi-spin pi-spinner mr-2\"  >\u003C/  i  >\n         \u003C/  span  >\n   \n         \u003C!-- Show title and icon when not loading -->\n         \u003C  span   class  =  \"flex items-center justify-center\"  >\n           \u003C  div   v-if  =  \"  iconPosition   ===   'before'   &&   createIcon  \"   :  class  =  \"  title   ?   'mr-2'   :   ''\"  >\n             \u003C  BaseCustomIcon   :  name  =  \"  createIcon  \"   />\n           \u003C/  div  >\n   \n           {{ title }}\n   \n           \u003C  div   v-if  =  \"  iconPosition   ===   'after'   &&   createIcon  \"   class  =  \"ml-2\"  >\n             \u003C  BaseCustomIcon   :  name  =  \"  createIcon  \"   />\n           \u003C/  div  >\n         \u003C/  span  >\n       \u003C/  button  >\n     \u003C/  div  >\n   \u003C/  template  >\n   \n   \u003C  script   setup  >\n   import   { computed }   from   \"vue\"  ;\n   \n   // Define props\n   const   props   =   defineProps  ({\n     title: {\n       type: String,\n       default:   \"\"  ,\n     },\n     createIcon: {\n       type: String,\n       default:   \"\"  ,\n     },\n     iconPosition: {\n       type: String,\n       default:   \"before\"  ,   // can be 'before' or 'after'\n     },\n     bgColor: {\n       type: String,\n       default:   \"bg-blue-500\"  ,\n     },\n     textColor: {\n       type: String,\n       default:   \"text-white\"  ,\n     },\n     borderColor: {\n       type: String,\n       default:   \"\"  ,\n     },\n     buttonContainerClass: {\n       type: String,\n       default:   \"flex items-center gap-3\"  ,\n     },\n     loading: {\n       type: Boolean,\n       default:   false  ,\n     },\n     type: {\n       type: String,\n       default:   \"\"  ,\n     },\n     disabled: {\n     type: Boolean,\n     default:   false  ,\n   }\n   \n   });\n   \n   // Define emit\n   const   emit   =   defineEmits  ([  \"click\"  ]);\n   \n   // Compute classes\n   const   bgClass   =   computed  (()   =>   props.bgColor);\n   const   textColorClass   =   computed  (()   =>   props.textColor);\n   const   borderClass   =   computed  (()   =>   props.borderColor);\n   \n   // Handle click event\n   const   handleClick   =   ()   =>   {\n     if   (props.disabled   ||   props.loading)   return  ;   // Prevent clicking when disabled or loading\n     emit  (  \"click\"  );\n   };\n   \n   \u003C/  script  >\n   \n   \u003C  style   scoped  >\n   /* Style for the spinner is already defined in PrimeIcons */\n   \u003C/  style  >\n     /* global.css */\n   .own-filter   .p-select   {\n       height  :   48  px  ;\n       flex-direction  :   row-reverse  ;\n       box-shadow  :   0  px   1  px   2  px   0  px   rgba  (  16  ,   24  ,   40  ,   0.05  )   !important  ;\n       border-radius  :   8  px  ;\n       padding  :   0   3  px  ;\n     }\n     .own-filter   .p-select   .p-inputtext   {\n       line-height  :   1  rem  ;\n       border  :   none   !important  ;\n       background  :   none   !important  ;\n       font-size  :   14  px  ;\n     }\n     .own-filter   .p-select   .p-dropdown-trigger   {\n       width  :   16  px  ;\n     }\n     .own-filter   .p-select   .p-placeholder   {\n       @  apply   font-normal   text-neutral-  200   text-sm  ;\n     }\n     \n     .own-filter   .p-select-label   {\n       @  apply   !  pr-  [7  px  ];\n     }\n     \n     .p-popover-content   {\n       @  apply   !  p-  0;\n     }\n     .p-textarea   {\n       @  apply   border-none   bg-neutral-  30   text-neutral-  500 !  important  ;\n     }\n     \n     .p-tag   {\n       @  apply   !  border   !  rounded-  [100  px  ] !  text-xs   !  font-normal  ;\n     }\n     \n     @media   screen   and   (  min-width  :   640  px  ) {\n       .p-paginator-current   {\n         flex  :   auto  ;\n         margin  :   auto  ;\n         display  :   inline-flex  ;\n         justify-content  :   flex-start  ;\n       }\n     }\n     \n     .th-center   {\n       .  p-datatable-column-header-content   {\n         justify-content  :   center  ;\n       }\n     }\n     \n     .dark   {\n       .  p-datatable-thead   tr   th   {\n         background  :   #323942   !important  ;\n         color  :   white  ;\n       }\n     \n       .p-datatable-tbody   tr   {\n         background  :   transparent  ;\n         border-bottom  :   1  px   solid   #bfbfbf33   !important  ;\n         border-top  :   1  px   solid   #bfbfbf33   !important  ;\n     \n         &:hover {\n           background  :   #bfbfbf33   !important  ;\n         }\n       }\n     }\n     .p-select-label   {\n       margin-top  :   auto  ;\n       margin-bottom  :   auto  ;\n     }\n     \n     .p-placeholder   {\n       color  :   #97989A   !important  ;\n       font-size  :   12  px  ;\n       font-weight  :   400  ;\n     }\n     \n     .p-select   {\n       border-radius  :   8  px   !important  ;\n       border-color  :   #D9D9DB   !important  ;\n       background  :   transparent   !important  ;\n       box-shadow  :   none   !important  ;\n       font-size  :   12  px   !important  ;\n       .  p-select-label   {\n         padding  :   0   !important  ;\n         /* color: #121212 !important; */\n         font-weight  :   400  ;\n       }\n       &  ::placeholder   {\n         color  :   #97989A   !important  ;\n       }\n     }\n     \n     .dark   {\n       .  p-select   {\n         border-color  :   #494850   !important  ;\n         background  :   #05040F   !important  ;\n         color  :   #ffffff   !important  ;\n       }\n     }\n     \n     .p-select-list   {\n       font-size  :   12  px  ;\n     }\n     \n     .p-datepicker   .p-inputtext::placeholder   {\n       color  :   #97989a   !important  ;\n       font-size  :   14  px  ;\n     }\n     \n     .p-datatable-thead   tr   th   {\n       background  :   #fafafa   !important  ;\n       font-size  :   14  px  ;\n       font-weight  :   500  ;\n       padding  :   13  px   24  px   !important  ;\n       border-bottom  :   0.6  px   solid   #bfbfbf66  ;\n       text-wrap  :   nowrap  ;\n       color  :   #080a09  ;\n     }\n     \n     .p-datatable-thead   tr   {\n       border-bottom  :   1  px   solid   #eaecf0  ;\n     }\n     \n     .p-datatable-tbody   tr   {\n       border-bottom  :   1  px   solid   #eaecf0  ;\n       border-top  :   1  px   solid   #eaecf0  ;\n     \n       td   {\n         padding  :   13  px   24  px   !important  ;\n       }\n     \n       &  :hover   {\n         background  :   #f8f8fc  ;\n       }\n     }\n     \n     .p-datatable   .p-datatable-footer   {\n       border  :   none   !important  ;\n       background-color  :   white  ;\n       min-height  :   50  px  ;\n     }\n     \n     .p-datatable   .p-datatable-footer   {\n       @  apply   dark  :bg-neutral-10;\n     }\n     \n     .p-paginator-bottom   {\n       border  :   none  ;\n       margin-top  :   20  px  ;\n     }\n     \n     .p-paginator   {\n       background  :   transparent  ;\n     \n       border  :   none  ;\n     }\n  Note: The dynamic table component accepts various props such as columns, title, pagination, search, limit, and more, which can be used across all pages. Be sure to review your project's specific requirements to determine how these props should be configured and utilized.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":329,"path":330,"dir":7,"title":331,"description":7,"keywords":332,"body":333},"content:Guideline:0.index.md","/guideline","Home",[],"     The best place to start your documentation.   Write pages in   Markdown , use   Vue  components and enjoy the power of   Nuxt .      +50 Components  ready to build rich pages   Docs  and   Page  layouts  Start from a   README , scale to a framework documentation  Navigation and Table of Contents generation  Fully configurable design system  Leverages    Typography  and    Elements  Used on   Content Documentation      What's included      Nuxt Architecture   Harness the full power of   Nuxt 3  and its   modules  ecosystem.    Nuxt Studio ready   Edit your theme content and appearance with live-preview within   Nuxt Studio .    Vue Components   Use built-in components (or your own!) inside your content.    Write Markdown   Enjoy the ease and simplicity of Markdown and discover   MDC syntax .    Deploy anywhere   Zero config on   Vercel  or   Netlify . Choose between static generation, on-demand rendering (Node) or edge-side rendering on   CloudFlare workers .    Extensible.   Customize the whole design, or add components using slots - you can make Docus your own.",{"id":335,"path":336,"dir":337,"title":338,"description":339,"keywords":340,"body":343},"content:Guideline:1.introduction:1.getting-started.md","/guideline/introduction/getting-started","introduction","Getting Started","From your Markdown files to a deployed website in few minutes.",[341,342],"Play online","Create a new project","  Getting Started  From your Markdown files to a deployed website in few minutes.  Play online  You can start playing with Docus in your browser using Stackblitz:  Play on StackBlitz  Create a new project   Start a fresh Docus project with:     npx   nuxi@latest   init   docs   -t   themes/docus\n   Install the dependencies in the   docs  folder:      npm   install\n     yarn   install\n     pnpm   install   --shamefully-hoist\n   Run the   dev  command to start Docus in development mode:      npm   run   dev\n     yarn   dev\n     pnpm   run   dev\n   ✨ Well done! A browser window should automatically open for   http://localhost:3000  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":345,"path":346,"dir":337,"title":44,"description":347,"keywords":348,"body":350},"content:Guideline:1.introduction:2.project-structure.md","/guideline/introduction/project-structure","Docus is a Nuxt theme that provides a ready-to-use documentation website, if you are familiar with Nuxt, you will feel right at home.",[349],"Directory Structure","  Project Structure  Docus is a Nuxt theme that provides a ready-to-use documentation website, if you are familiar with Nuxt, you will feel right at home.  Directory Structure  This is the minimal directory structure to get an up and running Docus website.     content/\n     index.md\n   app.config.ts\n   nuxt.config.ts\n  The   content/  directory is where you   write Markdown pages .  The   app.config.ts  is where you   configure Docus  to fit your branding and design.  The   nuxt.config.ts  is your   Nuxt configuration .  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":352,"path":353,"dir":337,"title":354,"description":355,"keywords":356,"body":358},"content:Guideline:1.introduction:3.writing-pages.md","/guideline/introduction/writing-pages","Writing Pages","Docus is made to let you write all your content in Markdown and Vue components with the MDC syntax.",[357],"Frontmatter","  Writing Pages  Docus is made to let you write all your content in Markdown and Vue components with the MDC syntax.  Each Markdown page in the   content/  folder will be mapped to a route.     File  Generated route     index.md   /    about.md   /about    blog/index.md   /blog    blog/hello.md   /blog/hello    1.guide/2.installation   /guide/installation  Frontmatter  Docus supports multiple Front-matter attributes for pages.     ---\n   title: \"Get Started\"\n   description: \"Let's learn how to use my amazing module.\"\n   ---\n      Key   Type   Default   Description     layout   string   default  Use any layout name like you would in   definePageMeta()    title   string   Defines the page title and H1 in docs pages    description   string   Defines the page description and excerpt in docs pages    redirect   string   A route path to redirect    image   object   OpenGraph cover image    Docs layout options       aside   boolean   Toggles the visibility of aside navigation    toc   boolean   Toggles the visibility of table of contents    header   boolean   Toggles the visibility of the page header    bottom   boolean   Toggles the visibility of page bottom section    Navigation options       navigation   boolean   Toggles the visibility of the page or directory in navigation    navigation.title   string   Changes the name of the page or directory in navigation    navigation.icon   string   Changes the icon of the page or directory in navigation  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":360,"path":361,"dir":337,"title":362,"description":363,"keywords":364,"body":366},"content:Guideline:1.introduction:4.configuration.md","/guideline/introduction/configuration","Configuration","Learn how to configure Docus.",[365],"Customizing the logo","  Configuration  Learn how to configure Docus.      export   default   defineAppConfig  ({\n     docus: {\n       title:   'Docus'  ,\n       description:   'My Docus Project'  ,\n       url:   'http://docus.dev'\n     }\n   })\n     export   default   defineAppConfig  ({\n     docus: {\n       title:   'Docus'  ,\n       description:   'My Docus Project'  ,\n       url:   'http://docus.dev'  ,\n       image:   '/social-card-preview.png'  ,\n       socials: {\n         twitter:   '@nuxt_js'  ,\n         github:   'nuxt-themes/docus'  ,\n       },\n       github: {\n         root:   'content'  ,\n         edit:   true  ,\n         contributors:   false\n       },\n       layout:   'default'  ,\n       aside: {\n         level:   1  ,\n         filter: [],\n       },\n       header: {\n         title:   false  ,\n         logo:   true  ,\n         showLinkIcon:   false\n       },\n       footer: {\n         credits: {\n           icon:   'IconDocus'  ,\n           text:   'Powered by Docus'  ,\n           href:   'https://docus.dev'  ,\n         },\n         textLinks: [\n           {\n             text:   'Nuxt'  ,\n             href:   'https://nuxt.com'  ,\n             target:   '_blank'  ,\n             rel:   'noopener'\n           }\n         ],\n         iconLinks: [\n           {\n             label:   'NuxtJS'  ,\n             href:   'https://nuxtjs.org'  ,\n             component:   'IconNuxtLabs'  ,\n           },\n           {\n             label:   'Vue Telescope'  ,\n             href:   'https://vuetelescope.com'  ,\n             component:   'IconVueTelescope'  ,\n           },\n         ],\n       }\n     }\n   })\n      Key   Type   Default   Description     title   string  Docus  Website title    titleTemplate   string  Docus  Website title template    description   string  My Docus Project  Website description    url   string   Website URL    layout   string  default  Fallback layout to use (supports   default  or   page )    Socials       socials   object   {}  Social links    socials.github   string   The repository to use on GitHub links    socials.twitter   string   The account to use on Twitter links    socials.youtube   string   The channel to use on Youtube links    socials.instagram   string   The account to use on Instagram links    socials.facebook   string   The account to use on Facebook links    socials.medium   string   The account to use on Medium links    socials.[social]   object   Override social or display custom one    socials.[social].label   string   A label to use for the social    socials.[social].icon   string   A icon to use for the social    socials.[social].href   string   A link to use for the social    socials.[social].rel   string   noopener noreferrer  A space-separated list of   link types    Header       header   object   Header configuration    header.logo   boolean   Whether or not to use   Logo.vue  as the header logo    header.title   string   If set to a string, will be used in the header    header.showLinkIcon   boolean   If set to   true  links icons will show in the header    header.exclude   string[]   An array of path to exclude out from the header navigation    header.fluid   boolean   true  Make header   Container  fluid    Main       main   object   Main configuration    main.fluid   boolean   true  Make main content   Container  fluid    main.padded   boolean   true  Make main content   Container  padded    Aside       aside   object   Aside configuration    aside.level   string  0  Aside base level of nesting    aside.collapsed   boolean   Will be used as default value for collapsible navigation categories    aside.exclude   string[]   An array of path to exclude out from the aside navigation    Footer       footer   object   Footer configuration    footer.credits   object   An object defining the bottom left credits    footer.credits.icon   object   The icon to use for the credits    footer.credits.text   object   The text to use for the credits    footer.textLinks   array   []  An array of texts to display at the center of footer    footer.textLinks[0].text   string   The text to display    footer.textLinks[0].href   string   A link to use for the text    footer.textLinks[0].target   string   _self  Where to display the linked URL, as the name for a browsing context    footer.textLinks[0].rel   string   noopener noreferrer  A space-separated list of   link types    footer.iconLinks   array   []  An array of icons to display in the footer    footer.iconLinks[0].label   string   A label to use for the icon    footer.iconLinks[0].href   string   A link to use for the icon    footer.iconLinks[0].icon   string   The icon to use (can be a component name)    footer.iconLinks[0].rel   string   noopener noreferrer  A space-separated list of   link types    footer.fluid   boolean   true  Make footer   Container  fluid    GitHub       github   object   false  GitHub integration configuration    github.dir   string   Directory containing the files to be edited    github.branch   string   Branch to start editing    github.repo   string   Name of the GitHub repo to edit files    github.owner   string   Owner of the repo    github.edit   boolean   Toggle \"Edit this page on Github\" component on documentation pages    Search       fuse   object   useFuse   options  Customizing the logo  To update the logo in the header, create a component in   components/Logo.vue  with your own logo.  In this example, the image is located at   /public/img .     \u003C  template  >\n     \u003C  img   width  =  \"120\"   src  =  \"/img/YOURLOGO.png\"  />\n   \u003C/  template  >\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":368,"path":369,"dir":370,"title":371,"description":372,"keywords":373,"body":389},"content:Guideline:2.api:1.components.md","/guideline/api/components","api","Components","Discover every component you can use in your content.",[374,375,376,377,378,379,380,381,382,383,384,385,386,387,388],"\u003CAlert />","\u003CBadge />","\u003CBlockHero />","\u003CButtonLink />","\u003CCallout />","\u003CCard />","\u003CCardGrid />","\u003CCodeGroup />","\u003CCodeBlock />","\u003CCopyButton />","\u003CIcon />","\u003CList />","\u003CSandbox />","\u003CTerminal />","\u003CVideoPlayer />","  Components  Discover every component you can use in your content.   \u003CAlert />     Check out an   info  alert with   code  and a   link .   Check out a   success  alert with   code  and a   link .   Check out a   warning  alert with   code  and a   link .   Check out a   danger  alert with   code  and a   link .     ::alert{type=\"info\"}\n   Check out an   **info**   alert with   `code`   and a [  link  ](  /  ).\n   ::\n   \n   ::alert{type=\"success\"}\n   Check out a   **success**   alert with   `code`   and a [  link  ](  /  ).\n   ::\n   \n   ::alert{type=\"warning\"}\n   Check out a   **warning**   alert with   `code`   and a [  link  ](  /  ).\n   ::\n   \n   ::alert{type=\"danger\"}\n   Check out a   **danger**   alert with   `code`   and a [  link  ](  /  ).\n   ::\n     \u003CBadge />   \u003CBadge />  support same types as   \u003CAlert /> .     v1.2  Deprecated   Not found!     :badge[  v1.2  ]\n   \n   :badge[  Deprecated  ]{type=\"warning\"}\n   \n   ::badge{type=\"danger\"}\n   Not found!\n   ::\n     \u003CBlockHero />      Document-driven framework   Docus reconciles content creators and developers by offering to both the best tools to create and scale content-based websites.     ::block-hero\n   ---\n   cta:\n     -   Get started\n     -   /get-started\n   secondary:\n     -   Open on GitHub →\n     -   https://github.com/nuxtlabs/docus\n   snippet: npx nuxi@latest init docus-app -t nuxtlabs/docus-starter\n   ---\n   #title\n   Document-driven framework\n   \n   #description\n   Docus reconciles content creators and developers by offering to both the best tools to create and scale content-based websites.\n   ::\n     \u003CButtonLink />    Play on StackBlitz     :button-link[Play on StackBlitz]{icon=\"IconStackBlitz\" href=\"https://stackblitz.com/github/nuxtlabs/docus-starter\" blank}\n     \u003CCallout />   \u003CCallout />  support same types as   \u003CAlert /> .      This is a callout! Click me to open.   This is the content of the callout.    This is a callout! Click me to open.   This is the content of the callout.     ::callout\n   #summary\n   This is a callout! Click me to open.\n   \n   #content\n   This is the content of the callout.\n   ::\n    \n   ::callout{type=\"warning\"}\n   #summary\n   This is a callout! Click me to open.\n   \n   #content\n   This is the content of the callout.\n   ::\n     \u003CCard />      Nuxt Architecture.   Based on   Nuxt 3  and   Nuxt Content .   \nUse Nuxt to build a static site, or a serverless app.      ::card{icon=\"logos:nuxt-icon\"}\n    #title\n    Nuxt Architecture.\n    #description\n    Based on   **Nuxt 3**   and   **Nuxt Content**  . :br\n    Use Nuxt to build a static site, or a serverless app.\n    ::\n     \u003CCardGrid />      What's included?      Nuxt Architecture.   Harness the full power of Nuxt and the Nuxt ecosystem.    Vue Components.   Use built-in components (or your own!) inside your content.    Write Markdown.   Enjoy the ease and simplicity of Markdown and discover MDC syntax.     ::card-grid\n   #title\n   What's included\n   \n   #root\n   :ellipsis\n   \n   #default\n     ::card\n     #title\n     Nuxt Architecture.\n     #description\n     Harness the full power of Nuxt and the Nuxt ecosystem.\n     ::\n     ::card\n     #title\n     Vue Components.\n     #description\n     Use built-in components (or your own!) inside your content.\n     ::\n     ::card\n     #title\n     Write Markdown.\n     #description\n     Enjoy the ease and simplicity of Markdown and discover MDC syntax.\n     ::\n   ::\n     \u003CCodeGroup />  This component uses   slots  to create a tab panel of your code examples or preview.        yarn   add   docus\n     npm   install   docus\n     ::code-group\n     ```bash [Yarn]\n     yarn   add   docus\n     ```\n     ```bash [NPM]\n     npm   install   docus\n     ```\n   ::\n     \u003CCodeBlock />  To be used inside a   \u003CCodeGroup />  component to display a preview of some rendered code.     Hello World!     /* Added as a child of   `\u003CCodeGroup />`   */\n   \n   ::code-block{label=\"Preview\" preview}\n     ::badge\n     Hello World!\n     ::\n   ::\n     \u003CCopyButton />        :copy-button{content=\"hey!\"}\n     \u003CIcon />  Icon component gives you access to all   100,000+  icons from   icones.js.org .          :icon{name=\"logos:nuxt-icon\"}\n   :icon{name=\"logos:vue\"}\n   :icon{name=\"logos:nuxt-icon\"}\n     \u003CList />       Important  Always    Amazing  Congrats    Do you know?  You can also do this    Be careful  Use with precautions    Drinking too much  Driving drunk     ::list{type=\"primary\"}\n   -   **Important**\n   -   Always\n   ::\n   \n   ::list{type=\"success\"}\n   -   Amazing\n   -   Congrats\n   ::\n   \n   ::list{type=\"info\"}\n   -   Do you know?\n   -   You can also do this\n   ::\n   \n   ::list{type=\"warning\"}\n   -   Be careful\n   -   Use with precautions\n   ::\n   \n   ::list{type=\"danger\"}\n   -   Drinking too much\n   -   Driving drunk\n   ::\n    \u003CSandbox />  Embed CodeSandbox/StackBlitz easily in your documentation with great performances.  Using the   IntersectionObserver  to load when visible in the viewport.        :sandbox{src=\"https://codesandbox.io/embed/nuxt-content-l164h?hidenavigation=1&theme=dark\"}\n     \u003CTerminal />        :terminal{content=\"nuxi build\"}\n     \u003CVideoPlayer />         ::div\n     :video-player{src=\"https://www.youtube.com/watch?v=o9e12WbKrd8\"}\n   ::\n   html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":391,"path":392,"dir":370,"title":393,"description":394,"keywords":395,"body":399},"content:Guideline:2.api:2.composables.md","/guideline/api/composables","Composables","Discover the Docus composables to use in your custom Vue components and pages.",[396,397,398],"useDocus()","useMenu()","useScrollspy()","  Composables  Discover the Docus composables to use in your custom Vue components and pages.   useDocus()    useDocus  ()  gives access to docus runtime config, all default values and your custom config from   app.config.ts    config  refers to the merged config of the current page.   main ,   header ,   aside ,   footer  and   titleTemplate  can be set from   _dir.yml  and any   page.md  file.  The configs in   app.config  file will be used as defaults.     \u003C  script   setup  >\n   const   {   config   }   =   useDocus  ()\n   \u003C/  script  >\n   \n   \u003C  template  >\n     \u003C  div  >\n       \u003C  h1  >{{ config.title }}\u003C/  h1  >\n       \u003C  p  >{{ config.description }}\u003C/  p  >\n     \u003C/  div  >\n   \u003C/  template  >\n    tree  refers to the current navigation tree that is displayed in the   aside  component.     \u003C  script   setup  >\n   const   {   tree   }   =   useDocus  ()\n   \u003C/  script  >\n   \n   \u003C  template  >\n     \u003C  DocsAsideTree   :links  =  \"tree\"   />\n   \u003C/  template  >\n    useMenu()   useMenu()  gives access to   $menu  plugin controlling mobile navigation globally.     const   {\n     // Is menu visible\n     visible  ,\n     // Close menu function\n     close  ,\n     // Open menu function\n     open  ,\n     // Toggle menu function\n     toggle\n   }   =   useMenu  ()\n    useScrollspy()   useScrollspy()  is used in   docs  layout to make the ToC display the currently visible headings.     const   {\n     // Headings on the page\n     visibleHeadings  ,\n     // Active headings (for the current page)\n     activeHeadings  ,\n     // Update headings (an array of DOM nodes)\n     updateHeadings\n   }   =   useScrollspy  ()\n   html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":401,"path":402,"dir":370,"title":403,"description":404,"keywords":405,"body":408},"content:Guideline:2.api:3.layouts.md","/guideline/api/layouts","Layouts","Docus provides multiple built-in layouts for displaying your Markdown pages.",[406,407],"default","page","  Layouts  Docus provides multiple built-in layouts for displaying your Markdown pages.   default  The default layout for every page created in the project. This layout renders multiple section alongside the content:   Aside navigation menu (togglable with   aside: false/true )  Page bottom section (togglable with   bottom: false/true )  Table of content (togglable with   toc: false/true )     ---\n   aside: true\n   bottom: true\n   toc: false\n   ---\n   \n   Your awesome content\n  Current page is live sample of default layout.   page   page  layout is content focused layout. This layout does not render aside menu of table of contents.  This layout accept some configuration from content front-matter.    fluid : By setting   fluid: true  in content front-matter the content will be rendered in full width.   constrainedClass : Using this option you can modify layout container look. Like constraining layout width of changing the background.   padded : Setting   padded: true  in front-matter will add horizontal padding in the layout.     ---\n   title: Home\n   layout: page\n   fluid: true\n   ---\n  Check   Home page  as live sample of page layout  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",1761136242722]