[
  {
    "path": "FirstSpring/.gitignore",
    "content": "HELP.md\ntarget/\n!.mvn/wrapper/maven-wrapper.jar\n!**/src/main/**/target/\n!**/src/test/**/target/\n\n### STS ###\n.apt_generated\n.classpath\n.factorypath\n.project\n.settings\n.springBeans\n.sts4-cache\n\n### IntelliJ IDEA ###\n.idea\n*.iws\n*.iml\n*.ipr\n\n### NetBeans ###\n/nbproject/private/\n/nbbuild/\n/dist/\n/nbdist/\n/.nb-gradle/\nbuild/\n!**/src/main/**/build/\n!**/src/test/**/build/\n\n### VS Code ###\n.vscode/\n"
  },
  {
    "path": "FirstSpring/mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Apache Maven Wrapper startup batch script, version 3.2.0\n#\n# Required ENV vars:\n# ------------------\n#   JAVA_HOME - location of a JDK home dir\n#\n# Optional ENV vars\n# -----------------\n#   MAVEN_OPTS - parameters passed to the Java VM when running Maven\n#     e.g. to debug Maven itself, use\n#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n# ----------------------------------------------------------------------------\n\nif [ -z \"$MAVEN_SKIP_RC\" ] ; then\n\n  if [ -f /usr/local/etc/mavenrc ] ; then\n    . /usr/local/etc/mavenrc\n  fi\n\n  if [ -f /etc/mavenrc ] ; then\n    . /etc/mavenrc\n  fi\n\n  if [ -f \"$HOME/.mavenrc\" ] ; then\n    . \"$HOME/.mavenrc\"\n  fi\n\nfi\n\n# OS specific support.  $var _must_ be set to either true or false.\ncygwin=false;\ndarwin=false;\nmingw=false\ncase \"$(uname)\" in\n  CYGWIN*) cygwin=true ;;\n  MINGW*) mingw=true;;\n  Darwin*) darwin=true\n    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home\n    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html\n    if [ -z \"$JAVA_HOME\" ]; then\n      if [ -x \"/usr/libexec/java_home\" ]; then\n        JAVA_HOME=\"$(/usr/libexec/java_home)\"; export JAVA_HOME\n      else\n        JAVA_HOME=\"/Library/Java/Home\"; export JAVA_HOME\n      fi\n    fi\n    ;;\nesac\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  if [ -r /etc/gentoo-release ] ; then\n    JAVA_HOME=$(java-config --jre-home)\n  fi\nfi\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched\nif $cygwin ; then\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=$(cygpath --unix \"$JAVA_HOME\")\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=$(cygpath --path --unix \"$CLASSPATH\")\nfi\n\n# For Mingw, ensure paths are in UNIX format before anything is touched\nif $mingw ; then\n  [ -n \"$JAVA_HOME\" ] && [ -d \"$JAVA_HOME\" ] &&\n    JAVA_HOME=\"$(cd \"$JAVA_HOME\" || (echo \"cannot cd into $JAVA_HOME.\"; exit 1); pwd)\"\nfi\n\nif [ -z \"$JAVA_HOME\" ]; then\n  javaExecutable=\"$(which javac)\"\n  if [ -n \"$javaExecutable\" ] && ! [ \"$(expr \"\\\"$javaExecutable\\\"\" : '\\([^ ]*\\)')\" = \"no\" ]; then\n    # readlink(1) is not available as standard on Solaris 10.\n    readLink=$(which readlink)\n    if [ ! \"$(expr \"$readLink\" : '\\([^ ]*\\)')\" = \"no\" ]; then\n      if $darwin ; then\n        javaHome=\"$(dirname \"\\\"$javaExecutable\\\"\")\"\n        javaExecutable=\"$(cd \"\\\"$javaHome\\\"\" && pwd -P)/javac\"\n      else\n        javaExecutable=\"$(readlink -f \"\\\"$javaExecutable\\\"\")\"\n      fi\n      javaHome=\"$(dirname \"\\\"$javaExecutable\\\"\")\"\n      javaHome=$(expr \"$javaHome\" : '\\(.*\\)/bin')\n      JAVA_HOME=\"$javaHome\"\n      export JAVA_HOME\n    fi\n  fi\nfi\n\nif [ -z \"$JAVACMD\" ] ; then\n  if [ -n \"$JAVA_HOME\"  ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n  else\n    JAVACMD=\"$(\\unset -f command 2>/dev/null; \\command -v java)\"\n  fi\nfi\n\nif [ ! -x \"$JAVACMD\" ] ; then\n  echo \"Error: JAVA_HOME is not defined correctly.\" >&2\n  echo \"  We cannot execute $JAVACMD\" >&2\n  exit 1\nfi\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  echo \"Warning: JAVA_HOME environment variable is not set.\"\nfi\n\n# traverses directory structure from process work directory to filesystem root\n# first directory with .mvn subdirectory is considered project base directory\nfind_maven_basedir() {\n  if [ -z \"$1\" ]\n  then\n    echo \"Path not specified to find_maven_basedir\"\n    return 1\n  fi\n\n  basedir=\"$1\"\n  wdir=\"$1\"\n  while [ \"$wdir\" != '/' ] ; do\n    if [ -d \"$wdir\"/.mvn ] ; then\n      basedir=$wdir\n      break\n    fi\n    # workaround for JBEAP-8937 (on Solaris 10/Sparc)\n    if [ -d \"${wdir}\" ]; then\n      wdir=$(cd \"$wdir/..\" || exit 1; pwd)\n    fi\n    # end of workaround\n  done\n  printf '%s' \"$(cd \"$basedir\" || exit 1; pwd)\"\n}\n\n# concatenates all lines of a file\nconcat_lines() {\n  if [ -f \"$1\" ]; then\n    # Remove \\r in case we run on Windows within Git Bash\n    # and check out the repository with auto CRLF management\n    # enabled. Otherwise, we may read lines that are delimited with\n    # \\r\\n and produce $'-Xarg\\r' rather than -Xarg due to word\n    # splitting rules.\n    tr -s '\\r\\n' ' ' < \"$1\"\n  fi\n}\n\nlog() {\n  if [ \"$MVNW_VERBOSE\" = true ]; then\n    printf '%s\\n' \"$1\"\n  fi\n}\n\nBASE_DIR=$(find_maven_basedir \"$(dirname \"$0\")\")\nif [ -z \"$BASE_DIR\" ]; then\n  exit 1;\nfi\n\nMAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-\"$BASE_DIR\"}; export MAVEN_PROJECTBASEDIR\nlog \"$MAVEN_PROJECTBASEDIR\"\n\n##########################################################################################\n# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n# This allows using the maven wrapper in projects that prohibit checking in binary data.\n##########################################################################################\nwrapperJarPath=\"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\"\nif [ -r \"$wrapperJarPath\" ]; then\n    log \"Found $wrapperJarPath\"\nelse\n    log \"Couldn't find $wrapperJarPath, downloading it ...\"\n\n    if [ -n \"$MVNW_REPOURL\" ]; then\n      wrapperUrl=\"$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n    else\n      wrapperUrl=\"https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n    fi\n    while IFS=\"=\" read -r key value; do\n      # Remove '\\r' from value to allow usage on windows as IFS does not consider '\\r' as a separator ( considers space, tab, new line ('\\n'), and custom '=' )\n      safeValue=$(echo \"$value\" | tr -d '\\r')\n      case \"$key\" in (wrapperUrl) wrapperUrl=\"$safeValue\"; break ;;\n      esac\n    done < \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties\"\n    log \"Downloading from: $wrapperUrl\"\n\n    if $cygwin; then\n      wrapperJarPath=$(cygpath --path --windows \"$wrapperJarPath\")\n    fi\n\n    if command -v wget > /dev/null; then\n        log \"Found wget ... using wget\"\n        [ \"$MVNW_VERBOSE\" = true ] && QUIET=\"\" || QUIET=\"--quiet\"\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            wget $QUIET \"$wrapperUrl\" -O \"$wrapperJarPath\" || rm -f \"$wrapperJarPath\"\n        else\n            wget $QUIET --http-user=\"$MVNW_USERNAME\" --http-password=\"$MVNW_PASSWORD\" \"$wrapperUrl\" -O \"$wrapperJarPath\" || rm -f \"$wrapperJarPath\"\n        fi\n    elif command -v curl > /dev/null; then\n        log \"Found curl ... using curl\"\n        [ \"$MVNW_VERBOSE\" = true ] && QUIET=\"\" || QUIET=\"--silent\"\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            curl $QUIET -o \"$wrapperJarPath\" \"$wrapperUrl\" -f -L || rm -f \"$wrapperJarPath\"\n        else\n            curl $QUIET --user \"$MVNW_USERNAME:$MVNW_PASSWORD\" -o \"$wrapperJarPath\" \"$wrapperUrl\" -f -L || rm -f \"$wrapperJarPath\"\n        fi\n    else\n        log \"Falling back to using Java to download\"\n        javaSource=\"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java\"\n        javaClass=\"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class\"\n        # For Cygwin, switch paths to Windows format before running javac\n        if $cygwin; then\n          javaSource=$(cygpath --path --windows \"$javaSource\")\n          javaClass=$(cygpath --path --windows \"$javaClass\")\n        fi\n        if [ -e \"$javaSource\" ]; then\n            if [ ! -e \"$javaClass\" ]; then\n                log \" - Compiling MavenWrapperDownloader.java ...\"\n                (\"$JAVA_HOME/bin/javac\" \"$javaSource\")\n            fi\n            if [ -e \"$javaClass\" ]; then\n                log \" - Running MavenWrapperDownloader.java ...\"\n                (\"$JAVA_HOME/bin/java\" -cp .mvn/wrapper MavenWrapperDownloader \"$wrapperUrl\" \"$wrapperJarPath\") || rm -f \"$wrapperJarPath\"\n            fi\n        fi\n    fi\nfi\n##########################################################################################\n# End of extension\n##########################################################################################\n\n# If specified, validate the SHA-256 sum of the Maven wrapper jar file\nwrapperSha256Sum=\"\"\nwhile IFS=\"=\" read -r key value; do\n  case \"$key\" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;\n  esac\ndone < \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties\"\nif [ -n \"$wrapperSha256Sum\" ]; then\n  wrapperSha256Result=false\n  if command -v sha256sum > /dev/null; then\n    if echo \"$wrapperSha256Sum  $wrapperJarPath\" | sha256sum -c > /dev/null 2>&1; then\n      wrapperSha256Result=true\n    fi\n  elif command -v shasum > /dev/null; then\n    if echo \"$wrapperSha256Sum  $wrapperJarPath\" | shasum -a 256 -c > /dev/null 2>&1; then\n      wrapperSha256Result=true\n    fi\n  else\n    echo \"Checksum validation was requested but neither 'sha256sum' or 'shasum' are available.\"\n    echo \"Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties.\"\n    exit 1\n  fi\n  if [ $wrapperSha256Result = false ]; then\n    echo \"Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.\" >&2\n    echo \"Investigate or delete $wrapperJarPath to attempt a clean download.\" >&2\n    echo \"If you updated your Maven version, you need to update the specified wrapperSha256Sum property.\" >&2\n    exit 1\n  fi\nfi\n\nMAVEN_OPTS=\"$(concat_lines \"$MAVEN_PROJECTBASEDIR/.mvn/jvm.config\") $MAVEN_OPTS\"\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin; then\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=$(cygpath --path --windows \"$JAVA_HOME\")\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=$(cygpath --path --windows \"$CLASSPATH\")\n  [ -n \"$MAVEN_PROJECTBASEDIR\" ] &&\n    MAVEN_PROJECTBASEDIR=$(cygpath --path --windows \"$MAVEN_PROJECTBASEDIR\")\nfi\n\n# Provide a \"standardized\" way to retrieve the CLI args that will\n# work with both Windows and non-Windows executions.\nMAVEN_CMD_LINE_ARGS=\"$MAVEN_CONFIG $*\"\nexport MAVEN_CMD_LINE_ARGS\n\nWRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\n# shellcheck disable=SC2086 # safe args\nexec \"$JAVACMD\" \\\n  $MAVEN_OPTS \\\n  $MAVEN_DEBUG_OPTS \\\n  -classpath \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\" \\\n  \"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}\" \\\n  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG \"$@\"\n"
  },
  {
    "path": "FirstSpring/mvnw.cmd",
    "content": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software Foundation (ASF) under one\n@REM or more contributor license agreements.  See the NOTICE file\n@REM distributed with this work for additional information\n@REM regarding copyright ownership.  The ASF licenses this file\n@REM to you under the Apache License, Version 2.0 (the\n@REM \"License\"); you may not use this file except in compliance\n@REM with the License.  You may obtain a copy of the License at\n@REM\n@REM    https://www.apache.org/licenses/LICENSE-2.0\n@REM\n@REM Unless required by applicable law or agreed to in writing,\n@REM software distributed under the License is distributed on an\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n@REM KIND, either express or implied.  See the License for the\n@REM specific language governing permissions and limitations\n@REM under the License.\n@REM ----------------------------------------------------------------------------\n\n@REM ----------------------------------------------------------------------------\n@REM Apache Maven Wrapper startup batch script, version 3.2.0\n@REM\n@REM Required ENV vars:\n@REM JAVA_HOME - location of a JDK home dir\n@REM\n@REM Optional ENV vars\n@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands\n@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending\n@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven\n@REM     e.g. to debug Maven itself, use\n@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n@REM ----------------------------------------------------------------------------\n\n@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'\n@echo off\n@REM set title of command window\ntitle %0\n@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'\n@if \"%MAVEN_BATCH_ECHO%\" == \"on\"  echo %MAVEN_BATCH_ECHO%\n\n@REM set %HOME% to equivalent of $HOME\nif \"%HOME%\" == \"\" (set \"HOME=%HOMEDRIVE%%HOMEPATH%\")\n\n@REM Execute a user defined script before this one\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPre\n@REM check for pre script, once with legacy .bat ending and once with .cmd ending\nif exist \"%USERPROFILE%\\mavenrc_pre.bat\" call \"%USERPROFILE%\\mavenrc_pre.bat\" %*\nif exist \"%USERPROFILE%\\mavenrc_pre.cmd\" call \"%USERPROFILE%\\mavenrc_pre.cmd\" %*\n:skipRcPre\n\n@setlocal\n\nset ERROR_CODE=0\n\n@REM To isolate internal variables from possible post scripts, we use another setlocal\n@setlocal\n\n@REM ==== START VALIDATION ====\nif not \"%JAVA_HOME%\" == \"\" goto OkJHome\n\necho.\necho Error: JAVA_HOME not found in your environment. >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n:OkJHome\nif exist \"%JAVA_HOME%\\bin\\java.exe\" goto init\n\necho.\necho Error: JAVA_HOME is set to an invalid directory. >&2\necho JAVA_HOME = \"%JAVA_HOME%\" >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n@REM ==== END VALIDATION ====\n\n:init\n\n@REM Find the project base dir, i.e. the directory that contains the folder \".mvn\".\n@REM Fallback to current working directory if not found.\n\nset MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%\nIF NOT \"%MAVEN_PROJECTBASEDIR%\"==\"\" goto endDetectBaseDir\n\nset EXEC_DIR=%CD%\nset WDIR=%EXEC_DIR%\n:findBaseDir\nIF EXIST \"%WDIR%\"\\.mvn goto baseDirFound\ncd ..\nIF \"%WDIR%\"==\"%CD%\" goto baseDirNotFound\nset WDIR=%CD%\ngoto findBaseDir\n\n:baseDirFound\nset MAVEN_PROJECTBASEDIR=%WDIR%\ncd \"%EXEC_DIR%\"\ngoto endDetectBaseDir\n\n:baseDirNotFound\nset MAVEN_PROJECTBASEDIR=%EXEC_DIR%\ncd \"%EXEC_DIR%\"\n\n:endDetectBaseDir\n\nIF NOT EXIST \"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\" goto endReadAdditionalConfig\n\n@setlocal EnableExtensions EnableDelayedExpansion\nfor /F \"usebackq delims=\" %%a in (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a\n@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%\n\n:endReadAdditionalConfig\n\nSET MAVEN_JAVA_EXE=\"%JAVA_HOME%\\bin\\java.exe\"\nset WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.jar\"\nset WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nset WRAPPER_URL=\"https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n\nFOR /F \"usebackq tokens=1,2 delims==\" %%A IN (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.properties\") DO (\n    IF \"%%A\"==\"wrapperUrl\" SET WRAPPER_URL=%%B\n)\n\n@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n@REM This allows using the maven wrapper in projects that prohibit checking in binary data.\nif exist %WRAPPER_JAR% (\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Found %WRAPPER_JAR%\n    )\n) else (\n    if not \"%MVNW_REPOURL%\" == \"\" (\n        SET WRAPPER_URL=\"%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n    )\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Couldn't find %WRAPPER_JAR%, downloading it ...\n        echo Downloading from: %WRAPPER_URL%\n    )\n\n    powershell -Command \"&{\"^\n\t\t\"$webclient = new-object System.Net.WebClient;\"^\n\t\t\"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {\"^\n\t\t\"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');\"^\n\t\t\"}\"^\n\t\t\"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')\"^\n\t\t\"}\"\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Finished downloading %WRAPPER_JAR%\n    )\n)\n@REM End of extension\n\n@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file\nSET WRAPPER_SHA_256_SUM=\"\"\nFOR /F \"usebackq tokens=1,2 delims==\" %%A IN (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.properties\") DO (\n    IF \"%%A\"==\"wrapperSha256Sum\" SET WRAPPER_SHA_256_SUM=%%B\n)\nIF NOT %WRAPPER_SHA_256_SUM%==\"\" (\n    powershell -Command \"&{\"^\n       \"$hash = (Get-FileHash \\\"%WRAPPER_JAR%\\\" -Algorithm SHA256).Hash.ToLower();\"^\n       \"If('%WRAPPER_SHA_256_SUM%' -ne $hash){\"^\n       \"  Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';\"^\n       \"  Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';\"^\n       \"  Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';\"^\n       \"  exit 1;\"^\n       \"}\"^\n       \"}\"\n    if ERRORLEVEL 1 goto error\n)\n\n@REM Provide a \"standardized\" way to retrieve the CLI args that will\n@REM work with both Windows and non-Windows executions.\nset MAVEN_CMD_LINE_ARGS=%*\n\n%MAVEN_JAVA_EXE% ^\n  %JVM_CONFIG_MAVEN_PROPS% ^\n  %MAVEN_OPTS% ^\n  %MAVEN_DEBUG_OPTS% ^\n  -classpath %WRAPPER_JAR% ^\n  \"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%\" ^\n  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*\nif ERRORLEVEL 1 goto error\ngoto end\n\n:error\nset ERROR_CODE=1\n\n:end\n@endlocal & set ERROR_CODE=%ERROR_CODE%\n\nif not \"%MAVEN_SKIP_RC%\"==\"\" goto skipRcPost\n@REM check for post script, once with legacy .bat ending and once with .cmd ending\nif exist \"%USERPROFILE%\\mavenrc_post.bat\" call \"%USERPROFILE%\\mavenrc_post.bat\"\nif exist \"%USERPROFILE%\\mavenrc_post.cmd\" call \"%USERPROFILE%\\mavenrc_post.cmd\"\n:skipRcPost\n\n@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'\nif \"%MAVEN_BATCH_PAUSE%\"==\"on\" pause\n\nif \"%MAVEN_TERMINATE_CMD%\"==\"on\" exit %ERROR_CODE%\n\ncmd /C exit /B %ERROR_CODE%\n"
  },
  {
    "path": "FirstSpring/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>org.springframework.boot</groupId>\n\t\t<artifactId>spring-boot-starter-parent</artifactId>\n\t\t<version>4.0.1</version>\n\t\t<relativePath/> <!-- lookup parent from repository -->\n\t</parent>\n\t<groupId>com.embarkx</groupId>\n\t<artifactId>FirstSpring</artifactId>\n\t<version>0.0.1-SNAPSHOT</version>\n\t<name>FirstSpring</name>\n\t<description>First project for Spring Boot</description>\n\t<properties>\n\t\t<java.version>24</java.version>\n\t</properties>\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-webmvc</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-test</artifactId>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t\t<artifactId>spring-boot-maven-plugin</artifactId>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n</project>\n"
  },
  {
    "path": "FirstSpring/src/main/java/com/embarkx/FirstSpring/FirstSpringApplication.java",
    "content": "package com.embarkx.FirstSpring;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\n\n@SpringBootApplication\npublic class FirstSpringApplication {\n\n\n    public static void main(String[] args) {\n        SpringApplication.run(FirstSpringApplication.class, args);\n    }\n\n}\n"
  },
  {
    "path": "FirstSpring/src/main/java/com/embarkx/FirstSpring/HelloController.java",
    "content": "package com.embarkx.FirstSpring;\n\nimport org.springframework.web.bind.annotation.*;\n\n@RestController\npublic class HelloController {\n\n    @GetMapping(\"/hello/{name}\")\n    public HelloResponse helloParam(@PathVariable String name) {\n        return new HelloResponse(\"Hello, \" + name);\n    }\n\n    @GetMapping(\"/hello\")\n    public HelloResponse hello() {\n        return new HelloResponse(\"Hello, World!\");\n    }\n\n    @PostMapping(\"/hello\")\n    public HelloResponse helloPost(@RequestBody String name) {\n        return new HelloResponse(\"Hello, \" + name + \"!\");\n    }\n}\n"
  },
  {
    "path": "FirstSpring/src/main/java/com/embarkx/FirstSpring/HelloResponse.java",
    "content": "package com.embarkx.FirstSpring;\n\npublic class HelloResponse {\n    private String message;\n\n    public HelloResponse(String message) {\n        this.message = message;\n    }\n\n    public String getMessage() {\n        return message;\n    }\n\n    public void setMessage(String message) {\n        this.message = message;\n    }\n}\n"
  },
  {
    "path": "FirstSpring/src/main/resources/application.properties",
    "content": "server.port=8080"
  },
  {
    "path": "FirstSpring/src/test/java/com/embarkx/FirstSpring/FirstSpringApplicationTests.java",
    "content": "package com.embarkx.FirstSpring;\n\nimport org.junit.jupiter.api.Test;\nimport org.springframework.boot.test.context.SpringBootTest;\n\n@SpringBootTest\nclass FirstSpringApplicationTests {\n\n\t@Test\n\tvoid contextLoads() {\n\t}\n\n}\n"
  },
  {
    "path": "Java Spring Boot- Professional eCommerce Project Masterclass.postman_collection.json",
    "content": "{\n\t\"info\": {\n\t\t\"_postman_id\": \"e901da3d-88dd-479e-a9f9-2a1a38b6282b\",\n\t\t\"name\": \"Java Spring Boot: Professional eCommerce Project Masterclass\",\n\t\t\"schema\": \"https://schema.getpostman.com/json/collection/v2.1.0/collection.json\",\n\t\t\"_exporter_id\": \"28392683\"\n\t},\n\t\"item\": [\n\t\t{\n\t\t\t\"name\": \"SocialMedia APIs\",\n\t\t\t\"item\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"GetUsers\",\n\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/social/users\",\n\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\"social\",\n\t\t\t\t\t\t\t\t\"users\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"response\": []\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"GetUsers\",\n\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/social/users/1\",\n\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\"social\",\n\t\t\t\t\t\t\t\t\"users\",\n\t\t\t\t\t\t\t\t\"1\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"response\": []\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"DeleteUsers\",\n\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/social/users/4\",\n\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\"social\",\n\t\t\t\t\t\t\t\t\"users\",\n\t\t\t\t\t\t\t\t\"4\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"response\": []\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"SaveUsers\",\n\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\"raw\": \"{\\r\\n        \\\"id\\\": 10,\\r\\n        \\\"socialProfile\\\": {\\r\\n            \\\"id\\\": 10,\\r\\n            \\\"description\\\":\\\"Test 4\\\"\\r\\n        }\\r\\n}\",\n\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/social/users\",\n\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\"social\",\n\t\t\t\t\t\t\t\t\"users\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"response\": []\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Hello World App\",\n\t\t\t\"item\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"http://localhost:8080/hello\",\n\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\"raw\": \"Spring Boot\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/hello\",\n\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\"hello\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"response\": []\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"http://localhost:8080/hello\",\n\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/hello\",\n\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\"hello\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"response\": []\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Spring Boot Ecommerce\",\n\t\t\t\"item\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"Product\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Add Product\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n    \\\"productName\\\": \\\"Adjustable dumbbell set for home workouts | Premium Quality\\\",\\r\\n    \\\"description\\\": \\\"Adjustable dumbbell set for home workouts, can be used indoors, outdoors, at your personal gym. This is available at lowest possible rates.\\\",\\r\\n    \\\"quantity\\\": 90,\\r\\n    \\\"price\\\": 90,\\r\\n    \\\"discount\\\": 10\\r\\n}\\r\\n\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/admin/categories/6/product\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"admin\",\n\t\t\t\t\t\t\t\t\t\t\"categories\",\n\t\t\t\t\t\t\t\t\t\t\"6\",\n\t\t\t\t\t\t\t\t\t\t\"product\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Update Product\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n    \\\"productName\\\": \\\"Adjustable dumbbell set for home workouts | Premium Quality\\\",\\r\\n    \\\"description\\\": \\\"Adjustable dumbbell set for home workouts, can be used indoors, outdoors, at your personal gym. This is available at lowest possible rates.\\\",\\r\\n    \\\"quantity\\\": 0,\\r\\n    \\\"price\\\": 90,\\r\\n    \\\"discount\\\": 10\\r\\n}\\r\\n\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/admin/products/157\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"admin\",\n\t\t\t\t\t\t\t\t\t\t\"products\",\n\t\t\t\t\t\t\t\t\t\t\"157\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Update Product Image\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"formdata\",\n\t\t\t\t\t\t\t\t\t\"formdata\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"image\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\"src\": \"/C:/Users/FAISAL/Downloads/placeholder.png\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/products/202/image\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"products\",\n\t\t\t\t\t\t\t\t\t\t\"202\",\n\t\t\t\t\t\t\t\t\t\t\"image\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Delete Product\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/admin/products/1\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"admin\",\n\t\t\t\t\t\t\t\t\t\t\"products\",\n\t\t\t\t\t\t\t\t\t\t\"1\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Get All Products\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMSIsImlhdCI6MTcxNTE4MzY0OSwiZXhwIjoxNzE1MTg2NjQ5fQ.XS0-JKPhMJMrULRonqYLQzhJFTFOXGxkeuFj4q4mxeE\",\n\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/public/products?sortBy=price&sortOrder=desc&pageSize=20\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"public\",\n\t\t\t\t\t\t\t\t\t\t\"products\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"pageNumber\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"1\",\n\t\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"sortBy\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"price\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"sortOrder\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"desc\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"keyword\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"blender\",\n\t\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"category\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"Electronics\",\n\t\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"pageSize\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"20\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Get Products By Keyword\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/public/products/keyword/rob?pageNumber=0&pageSize=10&sortBy=productName&sortOrder=desc\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"public\",\n\t\t\t\t\t\t\t\t\t\t\"products\",\n\t\t\t\t\t\t\t\t\t\t\"keyword\",\n\t\t\t\t\t\t\t\t\t\t\"rob\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"pageNumber\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"0\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"pageSize\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"10\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"sortBy\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"productName\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"sortOrder\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"desc\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Get Products By Category\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/public/categories/1/products?pageNumber=0&pageSize=10&sortBy=productId&sortOrder=desc\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"public\",\n\t\t\t\t\t\t\t\t\t\t\"categories\",\n\t\t\t\t\t\t\t\t\t\t\"1\",\n\t\t\t\t\t\t\t\t\t\t\"products\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"pageNumber\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"0\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"pageSize\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"10\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"sortBy\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"productId\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"sortOrder\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"desc\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"Category\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Get All Categories\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/public/categories\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"public\",\n\t\t\t\t\t\t\t\t\t\t\"categories\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"pageNumber\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"0\",\n\t\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"pageSize\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"10\",\n\t\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"sortBy\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"categoryName\",\n\t\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"sortOrder\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"desc\",\n\t\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"DELETE Category\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/admin/categories/4\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"admin\",\n\t\t\t\t\t\t\t\t\t\t\"categories\",\n\t\t\t\t\t\t\t\t\t\t\"4\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Create new Category\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n    \\\"categoryName\\\":\\\"Sports & Fitness\\\"\\r\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/public/categories\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"public\",\n\t\t\t\t\t\t\t\t\t\t\"categories\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Update Category\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n    \\\"categoryName\\\":\\\"Travel Updated\\\"\\r\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/public/categories/1\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"public\",\n\t\t\t\t\t\t\t\t\t\t\"categories\",\n\t\t\t\t\t\t\t\t\t\t\"1\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"Authentication\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Sign in\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n    \\\"username\\\":\\\"user1\\\",\\r\\n    \\\"password\\\":\\\"password1\\\"\\r\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/auth/signin\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"auth\",\n\t\t\t\t\t\t\t\t\t\t\"signin\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"GetUserName\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/auth/username\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"auth\",\n\t\t\t\t\t\t\t\t\t\t\"username\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"GetUser\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/auth/user\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"auth\",\n\t\t\t\t\t\t\t\t\t\t\"user\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Sign Out\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/auth/signout\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"auth\",\n\t\t\t\t\t\t\t\t\t\t\"signout\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Sign up\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n    \\\"username\\\":\\\"user3\\\",\\r\\n    \\\"email\\\":\\\"user3email@gmail.com\\\",\\r\\n    \\\"password\\\":\\\"password3\\\",\\r\\n    \\\"role\\\":[\\\"admin\\\"]\\r\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/auth/signup\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"auth\",\n\t\t\t\t\t\t\t\t\t\t\"signup\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"Cart\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Add product to cart\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/carts/products/1/quantity/1\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"carts\",\n\t\t\t\t\t\t\t\t\t\t\"products\",\n\t\t\t\t\t\t\t\t\t\t\"1\",\n\t\t\t\t\t\t\t\t\t\t\"quantity\",\n\t\t\t\t\t\t\t\t\t\t\"1\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Get all carts\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/carts\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"carts\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Get User Cart\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/carts/users/cart\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"carts\",\n\t\t\t\t\t\t\t\t\t\t\"users\",\n\t\t\t\t\t\t\t\t\t\t\"cart\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Update quantity of product in Cart\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/cart/products/1/quantity/delete\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"cart\",\n\t\t\t\t\t\t\t\t\t\t\"products\",\n\t\t\t\t\t\t\t\t\t\t\"1\",\n\t\t\t\t\t\t\t\t\t\t\"quantity\",\n\t\t\t\t\t\t\t\t\t\t\"delete\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Delete product from cart\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/carts/1/product/1\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"carts\",\n\t\t\t\t\t\t\t\t\t\t\"1\",\n\t\t\t\t\t\t\t\t\t\t\"product\",\n\t\t\t\t\t\t\t\t\t\t\"1\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"Addresses\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Create Address\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n    \\\"country\\\": \\\"USA\\\",\\r\\n    \\\"city\\\": \\\"San Francisco\\\",\\r\\n    \\\"street\\\": \\\"Market Street\\\",\\r\\n    \\\"pincode\\\": \\\"94103\\\",\\r\\n    \\\"buildingName\\\": \\\"Bay Apartments\\\",\\r\\n    \\\"state\\\": \\\"California\\\"\\r\\n}\\r\\n\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/addresses\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"addresses\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Update Address\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n    \\\"country\\\": \\\"USA\\\",\\r\\n    \\\"city\\\": \\\"San Francisco\\\",\\r\\n    \\\"street\\\": \\\"Market Street\\\",\\r\\n    \\\"pincode\\\": \\\"94103\\\",\\r\\n    \\\"buildingName\\\": \\\"Bay Apartments Updated\\\",\\r\\n    \\\"state\\\": \\\"California\\\"\\r\\n}\\r\\n\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/addresses/1\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"addresses\",\n\t\t\t\t\t\t\t\t\t\t\"1\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Get Addresses\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/addresses\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"addresses\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Get Address By Id\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/addresses/1\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"addresses\",\n\t\t\t\t\t\t\t\t\t\t\"1\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Delete Address\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/addresses/2\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"addresses\",\n\t\t\t\t\t\t\t\t\t\t\"2\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Get User Addresses\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"noauth\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/users/addresses\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"users\",\n\t\t\t\t\t\t\t\t\t\t\"addresses\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"Orders\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"Place Order\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n  \\\"addressId\\\": 1,\\r\\n  \\\"pgName\\\": \\\"Stripe\\\",\\r\\n  \\\"pgPaymentId\\\": \\\"pi_1FHEhK2eZvKYlo2CcK4UJNdW\\\",\\r\\n  \\\"pgStatus\\\": \\\"succeeded\\\",\\r\\n  \\\"pgResponseMessage\\\": \\\"Payment successful\\\"\\r\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/order/users/payments/CARD\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"order\",\n\t\t\t\t\t\t\t\t\t\t\"users\",\n\t\t\t\t\t\t\t\t\t\t\"payments\",\n\t\t\t\t\t\t\t\t\t\t\"CARD\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"StripeClientSecret\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\r\\n  \\\"amount\\\": 2000,\\r\\n  \\\"currency\\\": \\\"usd\\\"\\r\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"http://localhost:8080/api/order/stripe-client-secret\",\n\t\t\t\t\t\t\t\t\t\"protocol\": \"http\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"localhost\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"port\": \"8080\",\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\"order\",\n\t\t\t\t\t\t\t\t\t\t\"stripe-client-secret\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": []\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}"
  },
  {
    "path": "README.md",
    "content": "This is the Official repository of **Java Spring Boot: Professional eCommerce Project Masterclass** on Udemy\r\n\r\n# The Ultimate Java and Spring Boot Mastery Roadmap\r\n\r\nWelcome to your one-stop-shop for mastering Java and Spring Boot! This repository offers a comprehensive learning experience with high-quality resources and community support. Dive into over 150+ hours of premium content, with everything you need to excel at Java and Spring Boot development.\r\n\r\n## 🎓 Learning Roadmap\r\n\r\nMost of the courses below are available in **Udemy For Business**, so if you have subscription - you can get FREE access.\r\nHere’s a structured path to enhance your skills with detailed courses available:\r\n\r\n1. **[Spring Boot By Building Complex Projects Step by Step](https://link.embarkx.com/spring-boot) (90+ Hours of Content)**\r\n2. **[Master Spring Boot Microservices by Building eCommerce Project](https://link.embarkx.com/microservices) (55+ Hours of Content)**\r\n3. **[Full Stack AI DevOps for Software Developers (AWS, Azure, GCP)](https://link.embarkx.com/devops) (20+ Hours of Content)**\r\n4. **[Learn Java with 60+ Hours of Content](http://link.embarkx.com/java) (60+ Hours of Content)**\r\n5. **[Master Spring Security with React JS + OAuth2](https://link.embarkx.com/spring-security) (34+ Hours of Content)**\r\n6. **[Master IntelliJ IDEA](http://link.embarkx.com/intellij) (3+ Hours of Content)**\r\n\r\n\r\n## 🌟 With All Our Courses You Gain Access To\r\n\r\n- 📝 **Notes:** Detailed and downloadable notes to accompany each lesson.\r\n- 💻 **Source Code:** Full access to the source code used in the tutorials.\r\n- 🤔 **Doubt Solving:** Responsive instructor and community support.\r\n- 🎥 **High-Quality HD Videos:** Easy to understand, high-definition video tutorials.\r\n- 🔄 **Free Lifetime Updates:** Continuous updates to course content at no extra cost.\r\n\r\n## 📚 Why Choose This Mastery Series?\r\n\r\nWith this series, you're not just learning; you're preparing to dominate the field of Java and Spring Boot development. Our structured learning path ensures that you build your skills progressively, with each course designed to build on the knowledge gained from the previous one.\r\n\r\n### Join Us Now!\r\n\r\nStart your journey today to become a master at Java and Spring Boot. Our community and expert instructors are here to support your learning every step of the way. **Enroll and start building your future, today!**\r\n\r\n\r\n\r\n\r\n\r\n# Usage Policy for Course Materials\r\n\r\n## Instructor Information\r\n\r\n**Instructor:** Faisal Memon  \r\n**Company:** [EmbarkX.com](http://www.embarkx.com)\r\n\r\n## Policy Overview\r\n\r\nThis document outlines the guidelines and restrictions concerning the use of course materials provided by EmbarkX, including but not limited to PDF presentations, code samples, and video tutorials.\r\n\r\n### 1. Personal Use Only\r\n\r\nThe materials provided in this course are intended for **your personal use only**. They are to be used solely for the purpose of learning and completing this course.\r\n\r\n### 2. No Unauthorized Sharing or Distribution\r\n\r\nYou are **not permitted** to share, distribute, or publicly post any course materials on any websites, social media platforms, or other public forums without prior written consent from the instructor.\r\n\r\n### 3. Intellectual Property\r\n\r\nAll course materials are protected by copyright laws and are the intellectual property of Faisal Memon and EmbarkX. Unauthorized use, reproduction, or distribution of these materials is **strictly prohibited**.\r\n\r\n### 4. Reporting Violations\r\n\r\nIf you become aware of any unauthorized sharing or distribution of course materials, please report it immediately to [embarkxofficial@gmail.com](mailto:embarkxofficial@gmail.com).\r\n\r\n### 5. Legal Action\r\n\r\nWe reserve the right to take legal action against individuals or entities found to be violating this usage policy.\r\n\r\n## Thank You\r\n\r\nThank you for respecting these guidelines and helping us maintain the integrity of our course materials.\r\n\r\n## Contact Information\r\n\r\n- **Email:** [embarkxofficial@gmail.com](mailto:embarkxofficial@gmail.com)\r\n- **Website:** [www.embarkx.com](http://www.embarkx.com)\r\n\r\n\r\n"
  },
  {
    "path": "SpringExample/.gitignore",
    "content": "target/\n!.mvn/wrapper/maven-wrapper.jar\n!**/src/main/**/target/\n!**/src/test/**/target/\n\n### IntelliJ IDEA ###\n.idea/modules.xml\n.idea/jarRepositories.xml\n.idea/compiler.xml\n.idea/libraries/\n*.iws\n*.iml\n*.ipr\n\n### Eclipse ###\n.apt_generated\n.classpath\n.factorypath\n.project\n.settings\n.springBeans\n.sts4-cache\n\n### NetBeans ###\n/nbproject/private/\n/nbbuild/\n/dist/\n/nbdist/\n/.nb-gradle/\nbuild/\n!**/src/main/**/build/\n!**/src/test/**/build/\n\n### VS Code ###\n.vscode/\n\n### Mac OS ###\n.DS_Store"
  },
  {
    "path": "SpringExample/.idea/.gitignore",
    "content": "# Default ignored files\n/shelf/\n/workspace.xml\n"
  },
  {
    "path": "SpringExample/.idea/encodings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Encoding\">\n    <file url=\"file://$PROJECT_DIR$/src/main/java\" charset=\"UTF-8\" />\n    <file url=\"file://$PROJECT_DIR$/src/main/resources\" charset=\"UTF-8\" />\n  </component>\n</project>"
  },
  {
    "path": "SpringExample/.idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ExternalStorageConfigurationManager\" enabled=\"true\" />\n  <component name=\"MavenProjectsManager\">\n    <option name=\"originalFiles\">\n      <list>\n        <option value=\"$PROJECT_DIR$/pom.xml\" />\n      </list>\n    </option>\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_21\" default=\"true\" project-jdk-name=\"21\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/out\" />\n  </component>\n</project>"
  },
  {
    "path": "SpringExample/.idea/uiDesigner.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Palette2\">\n    <group name=\"Swing\">\n      <item class=\"com.intellij.uiDesigner.HSpacer\" tooltip-text=\"Horizontal Spacer\" icon=\"/com/intellij/uiDesigner/icons/hspacer.svg\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"1\" hsize-policy=\"6\" anchor=\"0\" fill=\"1\" />\n      </item>\n      <item class=\"com.intellij.uiDesigner.VSpacer\" tooltip-text=\"Vertical Spacer\" icon=\"/com/intellij/uiDesigner/icons/vspacer.svg\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"1\" anchor=\"0\" fill=\"2\" />\n      </item>\n      <item class=\"javax.swing.JPanel\" icon=\"/com/intellij/uiDesigner/icons/panel.svg\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" />\n      </item>\n      <item class=\"javax.swing.JScrollPane\" icon=\"/com/intellij/uiDesigner/icons/scrollPane.svg\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"7\" hsize-policy=\"7\" anchor=\"0\" fill=\"3\" />\n      </item>\n      <item class=\"javax.swing.JButton\" icon=\"/com/intellij/uiDesigner/icons/button.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"0\" fill=\"1\" />\n        <initial-values>\n          <property name=\"text\" value=\"Button\" />\n        </initial-values>\n      </item>\n      <item class=\"javax.swing.JRadioButton\" icon=\"/com/intellij/uiDesigner/icons/radioButton.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"8\" fill=\"0\" />\n        <initial-values>\n          <property name=\"text\" value=\"RadioButton\" />\n        </initial-values>\n      </item>\n      <item class=\"javax.swing.JCheckBox\" icon=\"/com/intellij/uiDesigner/icons/checkBox.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"3\" anchor=\"8\" fill=\"0\" />\n        <initial-values>\n          <property name=\"text\" value=\"CheckBox\" />\n        </initial-values>\n      </item>\n      <item class=\"javax.swing.JLabel\" icon=\"/com/intellij/uiDesigner/icons/label.svg\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" />\n        <initial-values>\n          <property name=\"text\" value=\"Label\" />\n        </initial-values>\n      </item>\n      <item class=\"javax.swing.JTextField\" icon=\"/com/intellij/uiDesigner/icons/textField.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\">\n          <preferred-size width=\"150\" height=\"-1\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JPasswordField\" icon=\"/com/intellij/uiDesigner/icons/passwordField.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\">\n          <preferred-size width=\"150\" height=\"-1\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JFormattedTextField\" icon=\"/com/intellij/uiDesigner/icons/formattedTextField.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\">\n          <preferred-size width=\"150\" height=\"-1\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JTextArea\" icon=\"/com/intellij/uiDesigner/icons/textArea.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JTextPane\" icon=\"/com/intellij/uiDesigner/icons/textPane.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JEditorPane\" icon=\"/com/intellij/uiDesigner/icons/editorPane.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JComboBox\" icon=\"/com/intellij/uiDesigner/icons/comboBox.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"2\" anchor=\"8\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JTable\" icon=\"/com/intellij/uiDesigner/icons/table.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JList\" icon=\"/com/intellij/uiDesigner/icons/list.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"2\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JTree\" icon=\"/com/intellij/uiDesigner/icons/tree.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"150\" height=\"50\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JTabbedPane\" icon=\"/com/intellij/uiDesigner/icons/tabbedPane.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"200\" height=\"200\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JSplitPane\" icon=\"/com/intellij/uiDesigner/icons/splitPane.svg\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\">\n          <preferred-size width=\"200\" height=\"200\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JSpinner\" icon=\"/com/intellij/uiDesigner/icons/spinner.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"true\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JSlider\" icon=\"/com/intellij/uiDesigner/icons/slider.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JSeparator\" icon=\"/com/intellij/uiDesigner/icons/separator.svg\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"6\" anchor=\"0\" fill=\"3\" />\n      </item>\n      <item class=\"javax.swing.JProgressBar\" icon=\"/com/intellij/uiDesigner/icons/progressbar.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"0\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JToolBar\" icon=\"/com/intellij/uiDesigner/icons/toolbar.svg\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"0\" fill=\"1\">\n          <preferred-size width=\"-1\" height=\"20\" />\n        </default-constraints>\n      </item>\n      <item class=\"javax.swing.JToolBar$Separator\" icon=\"/com/intellij/uiDesigner/icons/toolbarSeparator.svg\" removable=\"false\" auto-create-binding=\"false\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"0\" fill=\"1\" />\n      </item>\n      <item class=\"javax.swing.JScrollBar\" icon=\"/com/intellij/uiDesigner/icons/scrollbar.svg\" removable=\"false\" auto-create-binding=\"true\" can-attach-label=\"false\">\n        <default-constraints vsize-policy=\"6\" hsize-policy=\"0\" anchor=\"0\" fill=\"2\" />\n      </item>\n    </group>\n  </component>\n</project>"
  },
  {
    "path": "SpringExample/.idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"$PROJECT_DIR$/..\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "SpringExample/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.example</groupId>\n    <artifactId>SpringExample</artifactId>\n    <version>1.0-SNAPSHOT</version>\n\n    <properties>\n        <maven.compiler.source>21</maven.compiler.source>\n        <maven.compiler.target>21</maven.compiler.target>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n    </properties>\n\n\n    <dependencies>\n        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-core</artifactId>\n            <version>6.1.6</version>\n        </dependency>\n\n        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-context</artifactId>\n            <version>6.1.6</version>\n        </dependency>\n\n    </dependencies>\n</project>"
  },
  {
    "path": "SpringExample/src/main/java/car/example/bean/App.java",
    "content": "package car.example.bean;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\n\npublic class App {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new ClassPathXmlApplicationContext(\"applicationBeanContext.xml\");\n\n        MyBean myBean = (MyBean) context.getBean(\"myBean\");\n        System.out.println(myBean);\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/car/example/bean/MyBean.java",
    "content": "package car.example.bean;\n\npublic class MyBean {\n    private String message;\n\n    public void setMessage(String message) {\n        this.message = message;\n    }\n\n    public void showMessage(){\n        System.out.println(\"Message: \" + message);\n    }\n\n    @Override\n    public String toString() {\n        return \"MyBean{\" +\n                \"message='\" + message + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/car/example/constructor/injection/App.java",
    "content": "package car.example.constructor.injection;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\n\npublic class App {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new ClassPathXmlApplicationContext(\"applicationConstructorInjection.xml\");\n        Car myCar = (Car) context.getBean(\"myCar\");\n        myCar.displayDetails();\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/car/example/constructor/injection/Car.java",
    "content": "package car.example.constructor.injection;\n\npublic class Car {\n    private Specification specification;\n\n    public Car(Specification specification) {\n        this.specification = specification;\n    }\n\n    public void displayDetails(){\n        System.out.println(\"Car Details: \" + specification.toString());\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/car/example/constructor/injection/Specification.java",
    "content": "package car.example.constructor.injection;\n\npublic class Specification {\n    private String make;\n    private String model;\n\n    public String getMake() {\n        return make;\n    }\n\n    public void setMake(String make) {\n        this.make = make;\n    }\n\n    public String getModel() {\n        return model;\n    }\n\n    public void setModel(String model) {\n        this.model = model;\n    }\n\n    @Override\n    public String toString() {\n        return \"Specification{\" +\n                \"make='\" + make + '\\'' +\n                \", model='\" + model + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/car/example/setter/injection/App.java",
    "content": "package car.example.setter.injection;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\n\npublic class App {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new ClassPathXmlApplicationContext(\"applicationSetterInjection.xml\");\n        Car myCar = (Car) context.getBean(\"myCar\");\n        myCar.displayDetails();\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/car/example/setter/injection/Car.java",
    "content": "package car.example.setter.injection;\n\npublic class Car {\n    private Specification specification;\n\n    public void setSpecification(Specification specification) {\n        this.specification = specification;\n    }\n\n    public void displayDetails(){\n        System.out.println(\"Car Details: \" + specification.toString());\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/car/example/setter/injection/Specification.java",
    "content": "package car.example.setter.injection;\n\npublic class Specification {\n    private String make;\n    private String model;\n\n    public String getMake() {\n        return make;\n    }\n\n    public void setMake(String make) {\n        this.make = make;\n    }\n\n    public String getModel() {\n        return model;\n    }\n\n    public void setModel(String model) {\n        this.model = model;\n    }\n\n    @Override\n    public String toString() {\n        return \"Specification{\" +\n                \"make='\" + make + '\\'' +\n                \", model='\" + model + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowire/constructor/App.java",
    "content": "package com.example.autowire.constructor;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\n\npublic class App {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new ClassPathXmlApplicationContext(\"autowireByConstructor.xml\");\n        Car myCar = (Car) context.getBean(\"myCar\");\n        myCar.displayDetails();\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowire/constructor/Car.java",
    "content": "package com.example.autowire.constructor;\n\npublic class Car {\n    private Specification specification;\n\n    public Car(Specification specification) {\n        this.specification = specification;\n    }\n\n//    public void setSpecification(Specification specification) {\n//        this.specification = specification;\n//    }\n\n    public void displayDetails(){\n        System.out.println(\"Car Details: \" + specification.toString());\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowire/constructor/Specification.java",
    "content": "package com.example.autowire.constructor;\n\npublic class Specification {\n    private String make;\n    private String model;\n\n    public String getMake() {\n        return make;\n    }\n\n    public void setMake(String make) {\n        this.make = make;\n    }\n\n    public String getModel() {\n        return model;\n    }\n\n    public void setModel(String model) {\n        this.model = model;\n    }\n\n    @Override\n    public String toString() {\n        return \"Specification{\" +\n                \"make='\" + make + '\\'' +\n                \", model='\" + model + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowire/name/App.java",
    "content": "package com.example.autowire.name;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\n\npublic class App {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new ClassPathXmlApplicationContext(\"autowireByName.xml\");\n        Car myCar = (Car) context.getBean(\"myCar\");\n        myCar.displayDetails();\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowire/name/Car.java",
    "content": "package com.example.autowire.name;\n\npublic class Car {\n    private Specification specification;\n\n    public void setSpecification(Specification specification) {\n        this.specification = specification;\n    }\n\n    public void displayDetails(){\n        System.out.println(\"Car Details: \" + specification.toString());\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowire/name/Specification.java",
    "content": "package com.example.autowire.name;\n\npublic class Specification {\n    private String make;\n    private String model;\n\n    public String getMake() {\n        return make;\n    }\n\n    public void setMake(String make) {\n        this.make = make;\n    }\n\n    public String getModel() {\n        return model;\n    }\n\n    public void setModel(String model) {\n        this.model = model;\n    }\n\n    @Override\n    public String toString() {\n        return \"Specification{\" +\n                \"make='\" + make + '\\'' +\n                \", model='\" + model + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowire/type/App.java",
    "content": "package com.example.autowire.type;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\n\npublic class App {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new ClassPathXmlApplicationContext(\"autowireByType.xml\");\n        Car myCar = (Car) context.getBean(\"myCar\");\n        myCar.displayDetails();\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowire/type/Car.java",
    "content": "package com.example.autowire.type;\n\npublic class Car {\n    private Specification specification;\n\n    public void setSpecification(Specification specification) {\n        this.specification = specification;\n    }\n\n    public void displayDetails(){\n        System.out.println(\"Car Details: \" + specification.toString());\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowire/type/Specification.java",
    "content": "package com.example.autowire.type;\n\npublic class Specification {\n    private String make;\n    private String model;\n\n    public String getMake() {\n        return make;\n    }\n\n    public void setMake(String make) {\n        this.make = make;\n    }\n\n    public String getModel() {\n        return model;\n    }\n\n    public void setModel(String model) {\n        this.model = model;\n    }\n\n    @Override\n    public String toString() {\n        return \"Specification{\" +\n                \"make='\" + make + '\\'' +\n                \", model='\" + model + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowired/annotation/App.java",
    "content": "package com.example.autowired.annotation;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.AnnotationConfigApplicationContext;\n\npublic class App {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new AnnotationConfigApplicationContext(AppConfig.class);\n        Employee employee = context.getBean(\"employee\", Employee.class);\n        System.out.println(employee.toString());\n\n\n        Manager manager = context.getBean(\"manager\", Manager.class);\n        System.out.println(manager.toString());\n    }\n}\n\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowired/annotation/AppConfig.java",
    "content": "package com.example.autowired.annotation;\n\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@ComponentScan(basePackages = \"com.example.autowired.annotation\")\npublic class AppConfig {\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowired/annotation/Employee.java",
    "content": "package com.example.autowired.annotation;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.stereotype.Component;\n\n@Component(\"employee\")\npublic class Employee {\n    private int employeeId;\n\n    @Value(\"Hello\")\n    private String firstName;\n\n    @Value(\"${java.home}\")\n    private String lastName;\n\n    @Value(\"#{4*4}\")\n    private double salary;\n\n    public int getEmployeeId() {\n        return employeeId;\n    }\n\n    public void setEmployeeId(int employeeId) {\n        this.employeeId = employeeId;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public double getSalary() {\n        return salary;\n    }\n\n    public void setSalary(double salary) {\n        this.salary = salary;\n    }\n\n    @Override\n    public String toString() {\n        return \"Employee{\" +\n                \"employeeId=\" + employeeId +\n                \", firstName='\" + firstName + '\\'' +\n                \", lastName='\" + lastName + '\\'' +\n                \", salary=\" + salary +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/autowired/annotation/Manager.java",
    "content": "package com.example.autowired.annotation;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class Manager {\n    @Autowired\n    @Qualifier(\"employee\")\n    private Employee employee;\n\n    /*@Autowired\n    public Manager(Employee employee) {\n        this.employee = employee;\n    }*/\n\n    @Override\n    public String toString() {\n        return \"Manager{\" +\n                \"employee=\" + employee +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/componentscan/App.java",
    "content": "package com.example.componentscan;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\n\npublic class App {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new ClassPathXmlApplicationContext(\"componentScanDemo.xml\");\n        Employee employee = context.getBean(\"employee\", Employee.class);\n        System.out.println(employee.toString());\n    }\n}\n\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/componentscan/Employee.java",
    "content": "package com.example.componentscan;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.stereotype.Component;\n\n@Component(\"employee\")\npublic class Employee {\n    private int employeeId;\n\n    @Value(\"Hello\")\n    private String firstName;\n\n    @Value(\"${java.home}\")\n    private String lastName;\n\n    @Value(\"#{4*4}\")\n    private double salary;\n\n    public int getEmployeeId() {\n        return employeeId;\n    }\n\n    public void setEmployeeId(int employeeId) {\n        this.employeeId = employeeId;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public double getSalary() {\n        return salary;\n    }\n\n    public void setSalary(double salary) {\n        this.salary = salary;\n    }\n\n    @Override\n    public String toString() {\n        return \"Employee{\" +\n                \"employeeId=\" + employeeId +\n                \", firstName='\" + firstName + '\\'' +\n                \", lastName='\" + lastName + '\\'' +\n                \", salary=\" + salary +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/componentscan/annotation/App.java",
    "content": "package com.example.componentscan.annotation;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.AnnotationConfigApplicationContext;\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\n\npublic class App {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new AnnotationConfigApplicationContext(AppConfig.class);\n        Employee employee = context.getBean(\"employee\", Employee.class);\n        System.out.println(employee.toString());\n    }\n}\n\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/componentscan/annotation/AppConfig.java",
    "content": "package com.example.componentscan.annotation;\n\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@ComponentScan(basePackages = \"com.example.componentscan.annotation\")\npublic class AppConfig {\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/example/componentscan/annotation/Employee.java",
    "content": "package com.example.componentscan.annotation;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.stereotype.Component;\n\n@Component(\"employee\")\npublic class Employee {\n    private int employeeId;\n\n    @Value(\"Hello\")\n    private String firstName;\n\n    @Value(\"${java.home}\")\n    private String lastName;\n\n    @Value(\"#{4*4}\")\n    private double salary;\n\n    public int getEmployeeId() {\n        return employeeId;\n    }\n\n    public void setEmployeeId(int employeeId) {\n        this.employeeId = employeeId;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public double getSalary() {\n        return salary;\n    }\n\n    public void setSalary(double salary) {\n        this.salary = salary;\n    }\n\n    @Override\n    public String toString() {\n        return \"Employee{\" +\n                \"employeeId=\" + employeeId +\n                \", firstName='\" + firstName + '\\'' +\n                \", lastName='\" + lastName + '\\'' +\n                \", salary=\" + salary +\n                '}';\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/ioc/coupling/IOCExample.java",
    "content": "package com.ioc.coupling;\n\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\n\npublic class IOCExample {\n    public static void main(String[] args) {\n        ApplicationContext context\n                = new ClassPathXmlApplicationContext(\"applicationIoCLooseCouplingExample.xml\");\n\n        UserManager userManagerWithDB =\n                (UserManager) context.getBean(\"userManagerWithUserDataProvider\");\n        System.out.println(userManagerWithDB.getUserInfo());\n\n       UserManager userManagerWithWS =\n                (UserManager) context.getBean(\"userManagerWithWebServiceProvider\");\n        System.out.println(userManagerWithWS.getUserInfo());\n\n      UserManager userManagerWithNewDB =\n                (UserManager) context.getBean(\"userManagerWithNewDatabaseProvider\");\n        System.out.println(userManagerWithNewDB.getUserInfo());\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/ioc/coupling/NewDatabaseProvider.java",
    "content": "package com.ioc.coupling;\n\npublic class NewDatabaseProvider implements UserDataProvider {\n    @Override\n    public String getUserDetails() {\n        return \"New Database in action\";\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/ioc/coupling/UserDataProvider.java",
    "content": "package com.ioc.coupling;\n\npublic interface UserDataProvider {\n    String getUserDetails();\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/ioc/coupling/UserDatabaseProvider.java",
    "content": "package com.ioc.coupling;\n\n// A - MySQL, PostgreSQL\n// B - Web Service, MongoDB\n\npublic class UserDatabaseProvider implements UserDataProvider {\n    @Override\n    public String getUserDetails(){\n        // Directly access database here\n        return \"User Details From Database\";\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/ioc/coupling/UserManager.java",
    "content": "package com.ioc.coupling;\n\npublic class UserManager {\n    private UserDataProvider userDataProvider;\n\n    public UserManager(UserDataProvider userDataProvider) {\n        this.userDataProvider = userDataProvider;\n    }\n\n    public String getUserInfo(){\n        return userDataProvider.getUserDetails();\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/ioc/coupling/WebServiceDataProvider.java",
    "content": "package com.ioc.coupling;\n\npublic class WebServiceDataProvider implements UserDataProvider {\n\n    @Override\n    public String getUserDetails() {\n        return \"Fetching Data From WebService\";\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/loose/coupling/LooseCouplingExample.java",
    "content": "package com.loose.coupling;\n\npublic class LooseCouplingExample {\n    public static void main(String[] args) {\n        UserDataProvider databaseProvider = new UserDatabaseProvider();\n        UserManager userManagerWithDB = new UserManager(databaseProvider);\n        System.out.println(userManagerWithDB.getUserInfo());\n\n        UserDataProvider webServiceProvider = new WebServiceDataProvider();\n        UserManager userManagerWithWS = new UserManager(webServiceProvider);\n        System.out.println(userManagerWithWS.getUserInfo());\n\n        UserDataProvider newDatabaseProvider = new NewDatabaseProvider();\n        UserManager userManagerWithNewDB = new UserManager(newDatabaseProvider);\n        System.out.println(userManagerWithNewDB.getUserInfo());\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/loose/coupling/NewDatabaseProvider.java",
    "content": "package com.loose.coupling;\n\npublic class NewDatabaseProvider implements UserDataProvider{\n    @Override\n    public String getUserDetails() {\n        return \"New Database in action\";\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/loose/coupling/UserDataProvider.java",
    "content": "package com.loose.coupling;\n\npublic interface UserDataProvider {\n    String getUserDetails();\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/loose/coupling/UserDatabaseProvider.java",
    "content": "package com.loose.coupling;\n\n// A - MySQL, PostgreSQL\n// B - Web Service, MongoDB\n\npublic class UserDatabaseProvider implements UserDataProvider {\n    @Override\n    public String getUserDetails(){\n        // Directly access database here\n        return \"User Details From Database\";\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/loose/coupling/UserManager.java",
    "content": "package com.loose.coupling;\n\npublic class UserManager {\n    private UserDataProvider userDataProvider;\n\n    public UserManager(UserDataProvider userDataProvider) {\n        this.userDataProvider = userDataProvider;\n    }\n\n    public String getUserInfo(){\n        return userDataProvider.getUserDetails();\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/loose/coupling/WebServiceDataProvider.java",
    "content": "package com.loose.coupling;\n\npublic class WebServiceDataProvider implements UserDataProvider{\n\n    @Override\n    public String getUserDetails() {\n        return \"Fetching Data From WebService\";\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/tight/coupling/TightCouplingExample.java",
    "content": "package com.tight.coupling;\n\npublic class TightCouplingExample {\n    public static void main(String[] args) {\n        UserManager userManager = new UserManager();\n        System.out.println(userManager.getUserInfo());\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/tight/coupling/UserDatabase.java",
    "content": "package com.tight.coupling;\n\n// A - MySQL, PostgreSQL\n// B - Web Service, MongoDB\n\npublic class UserDatabase {\n    public String getUserDetails(){\n        // Directly access database here\n        return \"User Details From Database\";\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/java/com/tight/coupling/UserManager.java",
    "content": "package com.tight.coupling;\n\npublic class UserManager {\n    private UserDatabase userDatabase = new UserDatabase();\n\n    public String getUserInfo(){\n        return userDatabase.getUserDetails();\n    }\n}\n"
  },
  {
    "path": "SpringExample/src/main/resources/applicationBeanContext.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"\n        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\">\n\n    <!-- bean definitions here -->\n    <bean id=\"myBean\" class=\"car.example.bean.MyBean\">\n        <property name=\"message\" value=\"I am a first bean\"/>\n    </bean>\n\n</beans>"
  },
  {
    "path": "SpringExample/src/main/resources/applicationConstructorInjection.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"\n        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\">\n\n    <!-- bean definitions here -->\n    <bean id=\"carSpecification\" class=\"car.example.constructor.injection.Specification\">\n        <property name=\"make\" value=\"Toyota\"/>\n        <property name=\"model\" value=\"Corolla\"/>\n    </bean>\n\n    <bean id=\"myCar\" class=\"car.example.constructor.injection.Car\">\n        <constructor-arg ref=\"carSpecification\"/>\n    </bean>\n\n</beans>"
  },
  {
    "path": "SpringExample/src/main/resources/applicationIoCLooseCouplingExample.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"\n        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\">\n\n    <!-- bean definitions here -->\n    <bean id=\"userDataProvider\"\n          class=\"com.ioc.coupling.UserDatabaseProvider\"/>\n\n    <bean id=\"newDatabaseProvider\"\n          class=\"com.ioc.coupling.NewDatabaseProvider\"/>\n\n    <bean id=\"webServiceDataProvider\"\n          class=\"com.ioc.coupling.WebServiceDataProvider\"/>\n\n    <bean id=\"userManagerWithUserDataProvider\" class=\"com.ioc.coupling.UserManager\">\n        <constructor-arg ref=\"userDataProvider\"/>\n    </bean>\n\n    <bean id=\"userManagerWithNewDatabaseProvider\" class=\"com.ioc.coupling.UserManager\">\n        <constructor-arg ref=\"newDatabaseProvider\"/>\n    </bean>\n\n    <bean id=\"userManagerWithWebServiceProvider\" class=\"com.ioc.coupling.UserManager\">\n        <constructor-arg ref=\"webServiceDataProvider\"/>\n    </bean>\n\n</beans>"
  },
  {
    "path": "SpringExample/src/main/resources/applicationSetterInjection.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"\n        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\">\n\n    <!-- bean definitions here -->\n    <bean id=\"carSpecification\" class=\"car.example.setter.injection.Specification\">\n        <property name=\"make\" value=\"Toyota\"/>\n        <property name=\"model\" value=\"Corolla\"/>\n    </bean>\n\n    <bean id=\"myCar\" class=\"car.example.setter.injection.Car\">\n        <property name=\"specification\" ref=\"carSpecification\"/>\n    </bean>\n\n</beans>"
  },
  {
    "path": "SpringExample/src/main/resources/autowireByConstructor.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"\n        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\">\n\n    <!-- bean definitions here -->\n    <bean id=\"specification1\" class=\"com.example.autowire.constructor.Specification\">\n        <property name=\"make\" value=\"Toyota\"/>\n        <property name=\"model\" value=\"Corolla\"/>\n    </bean>\n\n<!--    <bean id=\"specification\" class=\"com.example.autowire.constructor.Specification\">-->\n<!--        <property name=\"make\" value=\"Toyota1\"/>-->\n<!--        <property name=\"model\" value=\"Corolla1\"/>-->\n<!--    </bean>-->\n\n    <bean id=\"myCar\" class=\"com.example.autowire.constructor.Car\" autowire=\"constructor\"/>\n\n</beans>"
  },
  {
    "path": "SpringExample/src/main/resources/autowireByName.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"\n        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\">\n\n    <!-- bean definitions here -->\n    <bean id=\"specification\" class=\"com.example.autowire.name.Specification\">\n        <property name=\"make\" value=\"Toyota\"/>\n        <property name=\"model\" value=\"Corolla\"/>\n    </bean>\n\n    <bean id=\"specification1\" class=\"com.example.autowire.name.Specification\">\n        <property name=\"make\" value=\"Toyota1\"/>\n        <property name=\"model\" value=\"Corolla1\"/>\n    </bean>\n\n    <bean id=\"myCar\" class=\"com.example.autowire.name.Car\" autowire=\"byName\"/>\n\n</beans>"
  },
  {
    "path": "SpringExample/src/main/resources/autowireByType.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"\n        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\">\n\n    <!-- bean definitions here -->\n    <bean id=\"specification1\" class=\"com.example.autowire.type.Specification\">\n        <property name=\"make\" value=\"Toyota\"/>\n        <property name=\"model\" value=\"Corolla\"/>\n    </bean>\n\n<!--    <bean id=\"specification1\" class=\"com.example.autowire.type.Specification\">-->\n<!--        <property name=\"make\" value=\"Toyota1\"/>-->\n<!--        <property name=\"model\" value=\"Corolla1\"/>-->\n<!--    </bean>-->\n\n    <bean id=\"myCar\" class=\"com.example.autowire.type.Car\" autowire=\"byType\"/>\n\n</beans>"
  },
  {
    "path": "SpringExample/src/main/resources/componentScanDemo.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xmlns:context=\"http://www.springframework.org/schema/context\"\n       xsi:schemaLocation=\"http://www.springframework.org/schema/beans\n\t\thttps://www.springframework.org/schema/beans/spring-beans.xsd\n\t\thttp://www.springframework.org/schema/context\n\t\thttps://www.springframework.org/schema/context/spring-context.xsd\">\n\n    <context:component-scan base-package=\"com.example.componentscan\"/>\n\n</beans>"
  },
  {
    "path": "ecom-frontend/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndist-ssr\n*.local\n\n# Editor directories and files\n.vscode/*\n!.vscode/extensions.json\n.idea\n.DS_Store\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n\n.env"
  },
  {
    "path": "ecom-frontend/README.md",
    "content": "# React + Vite\n\nThis template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.\n\nCurrently, two official plugins are available:\n\n- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh\n- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh\n"
  },
  {
    "path": "ecom-frontend/eslint.config.js",
    "content": "import js from '@eslint/js'\nimport globals from 'globals'\nimport react from 'eslint-plugin-react'\nimport reactHooks from 'eslint-plugin-react-hooks'\nimport reactRefresh from 'eslint-plugin-react-refresh'\n\nexport default [\n  { ignores: ['dist'] },\n  {\n    files: ['**/*.{js,jsx}'],\n    languageOptions: {\n      ecmaVersion: 2020,\n      globals: globals.browser,\n      parserOptions: {\n        ecmaVersion: 'latest',\n        ecmaFeatures: { jsx: true },\n        sourceType: 'module',\n      },\n    },\n    settings: { react: { version: '18.3' } },\n    plugins: {\n      react,\n      'react-hooks': reactHooks,\n      'react-refresh': reactRefresh,\n    },\n    rules: {\n      ...js.configs.recommended.rules,\n      ...react.configs.recommended.rules,\n      ...react.configs['jsx-runtime'].rules,\n      ...reactHooks.configs.recommended.rules,\n      'react/jsx-no-target-blank': 'off',\n      'react-refresh/only-export-components': [\n        'warn',\n        { allowConstantExport: true },\n      ],\n    },\n  },\n]\n"
  },
  {
    "path": "ecom-frontend/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <link rel=\"icon\" type=\"image/svg+xml\" href=\"/vite.svg\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Vite + React</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.jsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "ecom-frontend/package.json",
    "content": "{\n  \"name\": \"ecom-frontend\",\n  \"private\": true,\n  \"version\": \"0.0.0\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"lint\": \"eslint .\",\n    \"preview\": \"vite preview\"\n  },\n  \"dependencies\": {\n    \"@emotion/react\": \"^11.14.0\",\n    \"@emotion/styled\": \"^11.14.1\",\n    \"@headlessui/react\": \"^2.2.9\",\n    \"@mui/material\": \"^7.3.7\",\n    \"@mui/x-data-grid\": \"^8.25.0\",\n    \"@reduxjs/toolkit\": \"^2.11.2\",\n    \"@stripe/react-stripe-js\": \"^5.4.1\",\n    \"@stripe/stripe-js\": \"^8.6.3\",\n    \"axios\": \"^1.13.2\",\n    \"classnames\": \"^2.5.1\",\n    \"react\": \"^19.2.3\",\n    \"react-dom\": \"^19.2.3\",\n    \"react-hook-form\": \"^7.71.1\",\n    \"react-hot-toast\": \"^2.6.0\",\n    \"react-icons\": \"^5.5.0\",\n    \"react-loader-spinner\": \"^8.0.2\",\n    \"react-redux\": \"^9.2.0\",\n    \"react-router-dom\": \"^7.12.0\",\n    \"swiper\": \"^12.0.3\"\n  },\n  \"devDependencies\": {\n    \"@eslint/js\": \"^9.39.2\",\n    \"@tailwindcss/postcss\": \"^4.1.18\",\n    \"@types/react\": \"^19.2.9\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@vitejs/plugin-react\": \"^5.1.2\",\n    \"eslint\": \"^9.39.2\",\n    \"eslint-plugin-react\": \"^7.37.5\",\n    \"eslint-plugin-react-hooks\": \"^7.0.1\",\n    \"eslint-plugin-react-refresh\": \"^0.4.26\",\n    \"globals\": \"^17.0.0\",\n    \"postcss\": \"^8.5.6\",\n    \"tailwindcss\": \"^4.1.18\",\n    \"vite\": \"^7.3.1\"\n  }\n}\n"
  },
  {
    "path": "ecom-frontend/postcss.config.js",
    "content": "export default {\n  plugins: {\n    '@tailwindcss/postcss': {},\n  },\n}\n"
  },
  {
    "path": "ecom-frontend/src/App.css",
    "content": ""
  },
  {
    "path": "ecom-frontend/src/App.jsx",
    "content": "import React, { useState } from 'react'\nimport './App.css'\nimport Products from './components/products/Products'\nimport { BrowserRouter as Router, Routes, Route } from 'react-router-dom'\nimport Home from './components/home/Home'\nimport Navbar from './components/shared/Navbar'\nimport About from './components/About'\nimport Contact from './components/Contact'\nimport { Toaster } from 'react-hot-toast'\nimport Cart from './components/cart/Cart'\nimport LogIn from './components/auth/LogIn'\nimport PrivateRoute from './components/PrivateRoute'\nimport Register from './components/auth/Register'\nimport Checkout from './components/checkout/Checkout'\nimport PaymentConfirmation from './components/checkout/PaymentConfirmation'\nimport AdminLayout from './components/admin/AdminLayout'\nimport Dashboard from './components/admin/dashboard/Dashboard'\nimport AdminProducts from './components/admin/products/AdminProducts'\nimport Sellers from './components/admin/sellers/Sellers'\nimport Category from './components/admin/categories/Category'\nimport Orders from './components/admin/orders/Orders'\n\nfunction App() {\n  return (\n    <React.Fragment>\n      <Router>\n        <Navbar />\n        <Routes>\n          <Route path='/' element={ <Home />}/>\n          <Route path='/products' element={ <Products />}/>\n          <Route path='/about' element={ <About />}/>\n          <Route path='/contact' element={ <Contact />}/>\n          <Route path='/cart' element={ <Cart />}/>\n        \n          <Route path='/' element={<PrivateRoute />}>\n            <Route path='/checkout' element={ <Checkout />}/>\n            <Route path='/order-confirm' element={ <PaymentConfirmation />}/>\n          </Route>\n\n          <Route path='/' element={<PrivateRoute publicPage />}>\n            <Route path='/login' element={ <LogIn />}/>\n            <Route path='/register' element={ <Register />}/>\n          </Route>\n\n           <Route path='/' element={<PrivateRoute adminOnly />}>\n            <Route path='/admin' element={ <AdminLayout />}>\n              <Route path='' element={<Dashboard />} />\n              <Route path='products' element={<AdminProducts />} />\n              <Route path='sellers' element={<Sellers />} />\n              <Route path='orders' element={<Orders />} />\n              <Route path='categories' element={<Category />} />\n            </Route>\n          </Route>\n        </Routes>\n      </Router>\n      <Toaster position='bottom-center'/>\n    </React.Fragment>\n  )\n}\n\nexport default App\n"
  },
  {
    "path": "ecom-frontend/src/api/api.js",
    "content": "import axios from \"axios\";\n\nconst api = axios.create({\n    baseURL: `${import.meta.env.VITE_BACK_END_URL}/api`,\n    withCredentials: true,\n});\n\nexport default api;"
  },
  {
    "path": "ecom-frontend/src/components/About.jsx",
    "content": "import ProductCard from \"./shared/ProductCard\";\n\nconst products = [\n    {\n        image: \"https://embarkx.com/sample/placeholder.png\",\n        productName: \"iPhone 13 Pro Max\",\n        description:\n          \"The iPhone 13 Pro Max offers exceptional performance with its A15 Bionic chip, stunning Super Retina XDR display, and advanced camera features for breathtaking photos.\",\n        specialPrice: 720,\n        price: 780,\n      },\n      {\n        image: \"https://embarkx.com/sample/placeholder.png\",\n        productName: \"Samsung Galaxy S21\",\n        description:\n          \"Experience the brilliance of the Samsung Galaxy S21 with its vibrant AMOLED display, powerful camera, and sleek design that fits perfectly in your hand.\",\n        specialPrice: 699,\n        price: 799,\n      },\n      {\n        image: \"https://embarkx.com/sample/placeholder.png\",\n        productName: \"Google Pixel 6\",\n        description:\n          \"The Google Pixel 6 boasts cutting-edge AI features, exceptional photo quality, and a stunning display, making it a perfect choice for Android enthusiasts.\",\n        price: 599,\n        specialPrice: 400,\n      }\n];\n\nconst About = () => {\n    return (\n        <div className=\"max-w-7xl mx-auto px-4 py-8\">\n            <h1 className=\"text-slate-800 text-4xl font-bold text-center mb-12\">\n                About Us\n            </h1>\n           <div className=\"flex flex-col lg:flex-row justify-between items-center mb-12\">\n                <div className=\"w-full md:w-1/2 text-center md:text-left\">\n                    <p className=\"text-lg mb-4\">\n                        Welcome to our e-commerce store! We are dedicated to providing the\n                        best products and services to our customers. Our mission is to offer\n                        a seamless shopping experience while ensuring the highest quality of\n                        our offerings.\n                    </p>\n                </div>\n\n                <div className=\"w-full md:w-1/2 mb-6 md:mb-0\">\n                    <img\n                        src=\"https://embarkx.com/sample/placeholder.png\"\n                        alt=\"About Us\"\n                        className=\"w-full h-auto rounded-lg shadow-lg transform transition-transform duration-300 hover:scale-105\"></img>\n                </div>\n           </div>\n\n\n           <div className=\"py-7 space-y-8\">\n            <h1 className=\"text-slate-800 text-4xl font-bold text-center\">\n                Our Products\n            </h1>\n            <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n               {products.map((product, index) => (\n                <ProductCard \n                    key={index}\n                    image={product.image}\n                    productName={product.productName}\n                    description={product.description}\n                    specialPrice={product.specialPrice}\n                    price={product.price}\n                    about\n                />\n               ))\n               }\n                \n\n            </div>\n           </div>\n        </div>\n    );\n}\n\nexport default About;"
  },
  {
    "path": "ecom-frontend/src/components/BackDrop.jsx",
    "content": "import React from 'react'\n\nconst BackDrop = ({ data }) => {\n  return (\n    <div\n        className={`z-20 transition-all duration-200 opacity-50 w-screen h-screen bg-slate-300 fixed ${data ? \"top-16\" : \"top-0\"} left-0`}\n    ></div>\n  )\n}\n\nexport default BackDrop"
  },
  {
    "path": "ecom-frontend/src/components/Contact.jsx",
    "content": "import { FaEnvelope, FaMapMarkedAlt, FaPhone } from \"react-icons/fa\";\n\nconst Contact = () => {\n    return(\n        <div\n            className=\"flex flex-col items-center justify-center min-h-screen py-12 bg-cover bg-center\"\n            style={{backgroundImage: \"url('')\"}}>\n            \n            <div className=\"bg-white shadow-lg rounded-lg p-8 w-full max-w-lg\">\n                <h1 className=\"text-4xl font-bold text-center mb-6\">Contact us</h1>\n                <p className=\"text-gray-600 text-center mb-4\">\n                    We would love to hear from you! Please fill out the form below or contact us directly\n                </p>\n\n                <form className=\"space-y-4\">\n                    <div>\n                        <label className=\"block text-sm font-medium text-gray-700\">\n                            Name\n                        </label>\n                        <input \n                            type=\"text\"\n                            required\n                            className=\"mt-1 block w-full border border-gray-300 rounded-lg p-2 focus:outline-hidden focus:ring-2 focus: ring-blue-500\"/>\n                    </div>\n\n\n                    <div>\n                        <label className=\"block text-sm font-medium text-gray-700\">\n                            Email\n                        </label>\n                        <input \n                            type=\"email\"\n                            required\n                            className=\"mt-1 block w-full border border-gray-300 rounded-lg p-2 focus:outline-hidden focus:ring-2 focus: ring-blue-500\"/>\n                    </div>\n\n                    <div>\n                        <label className=\"block text-sm font-medium text-gray-700\">\n                            Message\n                        </label>\n                        <textarea \n                            rows=\"4\"\n                            required\n                            className=\"mt-1 block w-full border border-gray-300 rounded-lg p-2 focus:outline-hidden focus:ring-2 focus: ring-blue-500\"/>\n                    </div>\n\n                    <button className=\"w-full bg-blue-500 text-white py-2 rounded-lg hover:bg-blue-600 transition duration-300\">\n                        Send Message\n                    </button>\n                </form>\n\n                <div className=\"mt-8 text-center\">\n                    <h2 className=\"text-lg font-semibold\">Contact Information</h2>\n                    <div className=\"flex flex-col items-center space-y-2 mt-4\">\n                        <div className=\"flex items-center\">\n                            <FaPhone className=\"text-blue-500 mr-2\"/>\n                            <span className=\"text-gray-600\">+4 8961 944 149</span>\n                        </div>\n\n                        <div className=\"flex items-center\">\n                            <FaEnvelope className=\"text-blue-500 mr-2\"/>\n                            <span className=\"text-gray-600\">embarkxofficial@gmail.com</span>\n                        </div>\n\n                        <div className=\"flex items-center\">\n                            <FaMapMarkedAlt className=\"text-blue-500 mr-2\"/>\n                            <span className=\"text-gray-600\">123 Main, Town, USA</span>\n                        </div>\n                    </div>\n                </div>\n            </div>\n            \n        </div>\n    );\n}\n\nexport default Contact;"
  },
  {
    "path": "ecom-frontend/src/components/PrivateRoute.jsx",
    "content": "import React from 'react'\nimport { useSelector } from 'react-redux'\nimport { Navigate, Outlet, useLocation } from 'react-router-dom';\n\nconst PrivateRoute = ({ publicPage = false, adminOnly = false }) => {\n    const { user } = useSelector((state) => state.auth);\n    const isAdmin = user && user?.roles?.includes(\"ROLE_ADMIN\");\n    const isSeller = user && user?.roles.includes(\"ROLE_SELLER\");\n    const location = useLocation();\n\n    if (publicPage) {\n        return user ? <Navigate to=\"/\" /> : <Outlet />\n    }\n\n    if (adminOnly) {\n        if (isSeller && !isAdmin) {\n            const sellerAllowedPaths = [\"/admin/orders\", \"/admin/products\"];\n            const sellerAllowed = sellerAllowedPaths.some(path => \n                location.pathname.startsWith(path)\n            );\n            if (!sellerAllowed) {\n                return <Navigate to=\"/\" replace />\n            }\n        }\n    }\n\n    if (!isAdmin && !isSeller) {\n        return <Navigate to=\"/\"/>\n    }\n    \n    return user ? <Outlet /> : <Navigate to=\"/login\" />;\n}\n\nexport default PrivateRoute"
  },
  {
    "path": "ecom-frontend/src/components/UserMenu.jsx",
    "content": "import { Avatar, Button, Menu, MenuItem } from '@mui/material';\nimport React from 'react'\nimport { BiUser } from 'react-icons/bi';\nimport { FaShoppingCart, FaUserShield } from 'react-icons/fa';\nimport { IoExitOutline } from 'react-icons/io5';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Link, useNavigate } from 'react-router-dom';\nimport BackDrop from './BackDrop';\nimport { logOutUser } from '../store/actions';\n\nconst UserMenu = () => {\n    const [anchorEl, setAnchorEl] = React.useState(null);\n    const open = Boolean(anchorEl);\n    const { user } = useSelector((state) => state.auth);\n    const dispatch = useDispatch();\n    const navigate = useNavigate();\n\n    const isAdmin = user && user?.roles.includes(\"ROLE_ADMIN\");\n    const isSeller = user && user?.roles.includes(\"ROLE_SELLER\");\n\n    const handleClick = (event) => {\n      setAnchorEl(event.currentTarget);\n    };\n    const handleClose = () => {\n      setAnchorEl(null);\n    };\n\n    const logOutHandler = () => {\n        dispatch(logOutUser(navigate));\n      };\n  \n    return (\n      <div className='relative z-30'>\n        <div\n        className='sm:border sm:border-slate-400 flex flex-row items-center gap-1 rounded-full cursor-pointer hover:shadow-md transition text-slate-700'\n          onClick={handleClick}\n        >\n          <Avatar alt='Menu' src=''/>\n        </div>\n        <Menu\n          sx={{ width:\"400px\" }}\n          id=\"basic-menu\"\n          anchorEl={anchorEl}\n          open={open}\n          onClose={handleClose}\n          MenuListProps={{\n            'aria-labelledby': 'basic-button',\n            sx: {width: 160},\n          }}\n        >\n\n          <Link to=\"/profile\">\n            <MenuItem className=\"flex gap-2\" \n                onClick={handleClose}>\n                    <BiUser className='text-xl'/>\n                    <span className='font-bold text-[16px] mt-1'>\n                        {user?.username}\n                    </span>\n            </MenuItem>\n          </Link>\n\n          <Link to=\"/profile/orders\">\n            <MenuItem className=\"flex gap-2\" \n                onClick={handleClose}>\n                    <FaShoppingCart className='text-xl'/>\n                    <span className='font-semibold'>\n                        Order\n                    </span>\n            </MenuItem>\n          </Link>\n\n          { (isAdmin || isSeller) && (\n          <Link to={isAdmin ? \"/admin\" : \"/admin/orders\"}>\n            <MenuItem className=\"flex gap-2\" \n                onClick={handleClose}>\n                    <FaUserShield className='text-xl'/>\n                    <span className='font-semibold'>\n                        {isAdmin ? \"Admin Panel\" : \"Seller Panel\"}\n                    </span>\n            </MenuItem>\n          </Link> )}\n\n            <MenuItem className=\"flex gap-2\" \n                onClick={logOutHandler}>\n                    <div className='font-semibold w-full flex gap-2 items-center bg-button-gradient px-4 py-1 text-white rounded-xs'>\n                    <IoExitOutline className='text-xl'/>\n                    <span className='font-bold text-[16px] mt-1'>\n                        LogOut\n                    </span>\n                    </div>\n            </MenuItem>\n\n        </Menu>\n\n        {open && <BackDrop />}\n      </div>\n    );\n}\n\nexport default UserMenu"
  },
  {
    "path": "ecom-frontend/src/components/admin/AdminLayout.jsx",
    "content": "import React, { useState } from 'react'\nimport Sidebar from '../shared/Sidebar'\nimport { Outlet } from 'react-router-dom'\nimport { Description, Dialog, DialogBackdrop, DialogPanel, DialogTitle, TransitionChild } from '@headlessui/react';\nimport { RxCross1 } from 'react-icons/rx';\nimport { FaBars } from 'react-icons/fa';\n\nconst AdminLayout = () => {\n    let [sidebarOpen, setSidebarOpen] = useState(false);\n  return (\n    <div>\n        <Dialog \n            open={sidebarOpen} \n            onClose={() => setSidebarOpen(false)} \n            className=\"relative z-50 xl:hidden\">\n        \n        <DialogBackdrop \n        transition\n        className=\"fixed inset-0 bg-gray-900/80 transition-opacity duration-300 ease-linear data-closed:opacity-0\" />\n\n        <div className=\"fixed inset-0 flex\">\n          <DialogPanel \n            transition\n            className=\"relative mr-16 flex w-full max-w-xs flex-1 transform transition duration-300 ease-in-out data-closed:-translate-x-full\">\n                \n           <TransitionChild>\n            <div className='absolute left-full top-0 flex w-16 justify-center pt-5 duration-300 ease-in-out data-closed:opacity-0'>\n                <button type='button'\n                 onClick={() => setSidebarOpen(false)}\n                 className='-m-2.5 p-2.5'>\n                    <span className='sr-only'> Close Sidebar</span>\n                    <RxCross1 className='text-white text-2xl'/>\n                </button>\n            </div>\n           </TransitionChild>\n           <Sidebar />\n          </DialogPanel>\n        </div>\n      </Dialog>\n\n\n\n\n        <div className='hidden xl:fixed xl:inset-y-0 xl:z-50 xl:flex xl:w-72 xl:flex-col'>\n            <Sidebar />\n        </div>\n\n        <div className='xl:pl-72'>\n            <button\n                type='button'\n                onClick={() => setSidebarOpen(true)}\n                className='-m-2.5 text-gray-700 xl:hidden p-4'>\n                    <span className='sr-only'> Open Sidebar</span>\n                    <FaBars className='text-slate-800 text-2xl'/>\n            </button>\n\n            <main className=''>\n                <div className='p-4 sm:p-6 xl:p-8'>\n                    <Outlet />\n                </div>\n                \n            </main>\n        </div>\n    </div>\n  )\n}\n\nexport default AdminLayout"
  },
  {
    "path": "ecom-frontend/src/components/admin/categories/AddCategoryForm.jsx",
    "content": "import React, { useEffect } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { useDispatch } from \"react-redux\";\nimport toast from \"react-hot-toast\";\n\nimport {\n  createCategoryDashboardAction,\n  updateCategoryDashboardAction,\n} from \"../../../store/actions\";\nimport InputField from \"../../shared/InputField\";\n\nconst AddCategoryForm = ({ setOpen, open, category, update = false }) => {\n  const dispatch = useDispatch();\n\n  const {\n    register,\n    handleSubmit,\n    reset,\n    setValue,\n    formState: { errors },\n  } = useForm({\n    mode: \"onTouched\",\n  });\n\n  const addNewCategoryHandler = (data) => {\n    if (!update) {\n      //dispatch createCategoryDashboardAction\n      dispatch(createCategoryDashboardAction(data, setOpen, reset, toast));\n    } else {\n      //dispatch updateCategoryDashboardAction\n      dispatch(\n        updateCategoryDashboardAction(data, setOpen, category.id, reset, toast)\n      );\n    }\n  };\n  useEffect(() => {\n    if (update && category) {\n      setValue(\"categoryName\", category?.categoryName);\n    }\n  }, [update, category]);\n\n  return (\n    <div className=\"py-5 relative h-full \">\n      <form\n        className=\"space-y-4 \"\n        onSubmit={handleSubmit(addNewCategoryHandler)}\n      >\n        <div className=\"flex md:flex-row flex-col gap-4 w-full \">\n          <InputField\n            label=\"Category Name\"\n            required\n            id=\"categoryName\"\n            type=\"text\"\n            message=\"This field is required*\"\n            placeholder=\"Category Name\"\n            register={register}\n            errors={errors}\n          />\n        </div>\n\n        <div className=\"flex  w-full justify-between items-center absolute bottom-14\">\n          <button\n            disabled={open}\n            onClick={() => setOpen(false)}\n            type=\"button\"\n            className={`border border-borderColor rounded-[5px] font-metropolis  text-textColor py-[10px] px-4 text-sm font-medium`}\n          >\n            Cancel\n          </button>\n          <button\n            disabled={open}\n            type=\"submit\"\n            className={`font-metropolis rounded-[5px]  bg-custom-blue hover:bg-blue-800 text-white  py-[10px] px-4 text-sm font-medium`}\n          >\n            {open ? \"Loading..\" : update ? \"Update\" : \"Save\"}\n          </button>\n        </div>\n      </form>\n    </div>\n  );\n};\n\nexport default AddCategoryForm;"
  },
  {
    "path": "ecom-frontend/src/components/admin/categories/Category.jsx",
    "content": "import React, { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useLocation, useNavigate, useSearchParams } from \"react-router-dom\";\nimport { DataGrid } from \"@mui/x-data-grid\";\nimport { FaFolderOpen, FaThList } from \"react-icons/fa\";\nimport toast from \"react-hot-toast\";\n\nimport Modal from \"../../shared/Modal\";\nimport AddCategoryForm from \"./AddCategoryForm\";\nimport Loader from \"../../shared/Loader\";\nimport { DeleteModal } from \"../../../components/shared/DeleteModal\";\nimport useCategoryFilter from \"../../../hooks/useCategoryFilter\";\nimport ErrorPage from \"../../shared/ErrorPage\";\nimport { deleteCategoryDashboardAction } from \"../../../store/actions\";\nimport { categoryTableColumns } from \"../../helper/tableColumn\";\n\nconst Category = () => {\n  const [searchParams] = useSearchParams();\n  const pathname = useLocation().pathname;\n  const params = new URLSearchParams(searchParams);\n  const navigate = useNavigate();\n\n  const dispatch = useDispatch();\n  const [openModal, setOpenModal] = useState(false);\n  const [openUpdateModal, setOpenUpdateModal] = useState(false);\n  const [openDeleteModal, setOpenDeleteModal] = useState(false);\n  const [selectedCategory, setSelectedCategory] = useState(null);\n\n  const { categoryLoader, errorMessage } = useSelector((state) => state.errors);\n  const { categories, pagination } = useSelector((state) => state.products);\n  const [currentPage, setCurrentPage] = useState(\n    pagination?.pageNumber + 1 || 1\n  );\n\n  // Calling the `useCategoryFilter` custom hook to handle category fetching and pagination based on the current URL parameters.\n  useCategoryFilter();\n\n  const tableRecords = categories?.map((item) => ({\n    id: item.categoryId,\n    categoryName: item.categoryName,\n    version: item.version,\n  }));\n\n  const handleEdit = (category) => {\n    setOpenUpdateModal(true);\n    setSelectedCategory(category);\n  };\n\n  const handleDelete = (category) => {\n    setSelectedCategory(category);\n    setOpenDeleteModal(true);\n  };\n\n  const onDeleteHandler = () => {\n    dispatch(\n      deleteCategoryDashboardAction(setOpenDeleteModal, selectedCategory?.id, toast)\n    );\n  };\n\n  const handlePaginationChange = (paginationModel) => {\n    const page = paginationModel.page + 1; // Adjust to 1-based index\n    setCurrentPage(page);\n\n    params.set(\"page\", page.toString());\n    navigate(`${pathname}?${params}`);\n  };\n\n  const emptyCategories = !categories || categories?.length === 0;\n\n  if (errorMessage) return <ErrorPage message={errorMessage} />;\n\n  return (\n    <div>\n      <div className=\"pt-6 pb-10 flex justify-end\">\n        <button\n          onClick={() => setOpenModal(true)}\n          className=\"bg-custom-blue hover:bg-blue-800 text-white font-semibold py-2 px-4 flex items-center gap-2 rounded-md shadow-md transition-colors hover:text-slate-300 duration-300\"\n        >\n          <FaThList className=\"text-xl\" />\n          Add Category\n        </button>\n      </div>\n      {!emptyCategories && (\n        <h1 className=\"text-slate-800 text-3xl text-center font-bold pb-6 uppercase\">\n          All Categories\n        </h1>\n      )}\n\n      {categoryLoader ? (\n        <Loader />\n      ) : (\n        <>\n          {emptyCategories ? (\n            <div className=\"flex flex-col items-center justify-center text-gray-600 py-10\">\n              <FaFolderOpen size={50} className=\"mb-3\" />\n              <h2 className=\"text-2xl font-semibold\">\n                No Categories Created Yet\n              </h2>\n            </div>\n          ) : (\n            <div className=\"max-w-fit mx-auto\">\n              <DataGrid\n                className=\"w-full\"\n                rows={tableRecords}\n                columns={categoryTableColumns(handleEdit, handleDelete)}\n                paginationMode=\"server\"\n                rowCount={pagination?.totalElements || 0}\n                initialState={{\n                  pagination: {\n                    paginationModel: {\n                      pageSize: pagination?.pageSize || 10,\n                      page: currentPage - 1,\n                    },\n                  },\n                }}\n                onPaginationModelChange={handlePaginationChange}\n                disableRowSelectionOnClick\n                disableColumnResize\n                pageSizeOptions={[pagination?.pageSize || 10]}\n                pagination\n                paginationOptions={{\n                  showFirstButton: true,\n                  showLastButton: true,\n                  hideNextButton: currentPage === pagination?.totalPages,\n                }}\n              />\n            </div>\n          )}\n        </>\n      )}\n\n      <Modal\n        open={openUpdateModal || openModal}\n        setOpen={openUpdateModal ? setOpenUpdateModal : setOpenModal}\n        title={openUpdateModal ? \"Update Category\" : \"Add Category\"}\n      >\n        <AddCategoryForm\n          setOpen={openUpdateModal ? setOpenUpdateModal : setOpenModal}\n          open={categoryLoader}\n          category={selectedCategory}\n          update={openUpdateModal}\n        />\n      </Modal>\n\n      <DeleteModal\n        open={openDeleteModal}\n        loader={categoryLoader}\n        setOpen={setOpenDeleteModal}\n        title=\"Are you want to delete this category\"\n        onDeleteHandler={onDeleteHandler}\n      />\n    </div>\n  );\n};\n\nexport default Category;"
  },
  {
    "path": "ecom-frontend/src/components/admin/dashboard/Dashboard.jsx",
    "content": "import React, { useEffect } from 'react'\nimport DashboardOverview from './DashboardOverview'\nimport { FaBoxOpen, FaDollarSign, FaShoppingCart } from 'react-icons/fa';\nimport { MdAttachMoney } from 'react-icons/md';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { analyticsAction } from '../../../store/actions';\nimport Loader from '../../shared/Loader';\nimport ErrorPage from '../../shared/ErrorPage';\n\nconst Dashboard = () => {\n  const dispatch = useDispatch();\n  const {isLoading, errorMessage} = useSelector((state) => state.errors);\n  const { \n    analytics: { productCount, totalRevenue, totalOrders },\n   } = useSelector((state) => state.admin);\n\n   useEffect(() => {\n    dispatch(analyticsAction());\n   }, [dispatch]);\n\n   if (isLoading) {\n    return <Loader />\n   }\n\n   if (errorMessage) {\n    return <ErrorPage message={errorMessage}/>;\n   }\n  \n  return (\n    <div>\n      <div className='flex md:flex-row mt-8 flex-col lg:justify-between \n          border border-slate-400 rounded-lg bg-linear-to-r\n           from-blue-50 to-blue-100 shadow-lg'>\n            <DashboardOverview \n              title=\"Total Products\"\n              amount={productCount}\n              Icon={FaBoxOpen}\n            />\n\n            <DashboardOverview \n              title=\"Total Orders\"\n              amount={totalOrders}\n              Icon={FaShoppingCart}\n            />\n\n            <DashboardOverview \n              title=\"Total Revenue\"\n              amount={totalRevenue}\n              Icon={FaDollarSign}\n              revenue\n            />\n      </div>\n    </div>\n  )\n}\n\nexport default Dashboard"
  },
  {
    "path": "ecom-frontend/src/components/admin/dashboard/DashboardOverview.jsx",
    "content": "import { Icon } from '@mui/material';\nimport React from 'react'\nimport { formatRevenue } from '../../../utils/formatPrice';\n\nconst DashboardOverview = ({ title, amount, Icon, revenue = false }) => {\n  \n  const convertedAmount = revenue ? Number(amount).toFixed(2) : amount;\n\n    return (\n    <>\n    <div className='xl:w-80 w-full space-y-4 text-center md:text-start px-5 py-8'>\n        <div className='flex md:justify-start justify-center items-center gap-2'>\n            <h3 className='uppercase text-2xl text-slate-700 font-semibold'>{title}</h3>\n            <Icon className='text-slate-800 text-2xl' />\n        </div>\n\n        <h1 className='font-bold text-slate-800 text-3xl'>\n            {revenue ? \"$\" : null}\n            {revenue ? formatRevenue(convertedAmount) : convertedAmount}\n        </h1>\n    </div>\n    </>\n  )\n}\n\nexport default DashboardOverview"
  },
  {
    "path": "ecom-frontend/src/components/admin/orders/OrderTable.jsx",
    "content": "import { DataGrid } from '@mui/x-data-grid'\nimport { adminOrderTableColumn } from '../../helper/tableColumn';\nimport { useState } from 'react';\nimport { useLocation, useNavigate, useSearchParams } from 'react-router-dom';\nimport Modal from '../../shared/Modal';\nimport UpdateOrderForm from './UpdateOrderForm';\n\nconst OrderTable = ({ adminOrder, pagination}) => {\n  const [updateOpenModal, setUpdateOpenModal] = useState(false);\n  const [selectedItem, setSelectedItem] = useState(\"\");\n  const [loader, setLoader] = useState(false);\n  const navigate = useNavigate();\n  const [currentPage, setCurrentPage] = useState(\n    pagination?.pageNumber + 1 || 1\n  );\n\n  const [searchParams] = useSearchParams();\n  const params = new URLSearchParams(searchParams);\n  const pathname = useLocation().pathname;\n\nconst tableRecords = adminOrder?.map((item) => {\n  return {\n    id: item.orderId,\n    email: item.email,\n    totalAmount: item.totalAmount,\n    status: item.orderStatus,\n    date: item.orderDate,\n  }\n});\n\nconst handlePaginationChange = (paginationModel) => {\n  const page = paginationModel.page + 1;\n  setCurrentPage(page);\n  params.set(\"page\", page.toString());\n  navigate(`${pathname}?${params}`)\n}\n\nconst handleEdit = (order) => {\n  setSelectedItem(order);\n  setUpdateOpenModal(true);\n}\n\n  return (\n    <div>\n      <h1 className='text-slate-800 text-3xl text-center font-bold pb-6 uppercase'>\n        All Orders\n      </h1>\n\n      <div>\n         <DataGrid\n         className='w-full'\n            rows={tableRecords}\n            columns={adminOrderTableColumn(handleEdit)}\n            paginationMode='server'\n            rowCount={pagination?.totalElements || 0}\n            initialState={{\n              pagination: {\n                paginationModel: {\n                  pageSize: pagination?.pageSize || 10,\n                  page: currentPage - 1,\n                },\n              },\n            }}\n            onPaginationModelChange={handlePaginationChange}\n            disableRowSelectionOnClick\n            disableColumnResize\n            pageSizeOptions={[pagination?.pageSize || 10]}\n            pagination\n            paginationOptions={{\n              showFirstButton: true,\n              showLastButton: true,\n              hideNextButton: currentPage === pagination?.totalPages,\n            }}\n          />\n      </div>\n\n      <Modal\n        open={updateOpenModal}\n        setOpen={setUpdateOpenModal}\n        title='Update Order Status'>\n          <UpdateOrderForm\n            setOpen={setUpdateOpenModal}\n            open={updateOpenModal}\n            loader={loader}\n            setLoader={setLoader}\n            selectedId={selectedItem.id}\n            selectedItem={selectedItem}\n            />\n      </Modal>\n    </div>\n  )\n}\n\nexport default OrderTable"
  },
  {
    "path": "ecom-frontend/src/components/admin/orders/Orders.jsx",
    "content": "import React from 'react'\nimport { FaShoppingCart } from 'react-icons/fa';\nimport OrderTable from './OrderTable';\nimport { useSelector } from 'react-redux';\nimport useOrderFilter from '../../../hooks/useOrderFilter';\n\nconst Orders = () => {\n  // const adminOrder = [ { \"orderId\": 17, \"email\": \"user1@example.com\", \"orderItems\": [ { \"orderItemId\": 7, \"product\": { \"productId\": 153, \"productName\": \"Running Shoes\", \"image\": \"0abca637-0c4e-4054-ae03-bdfc51cb3396.png\", \"description\": \"Comfortable and lightweight running shoes for daily fitness\", \"quantity\": 49, \"price\": 80, \"discount\": 10, \"specialPrice\": 72 }, \"quantity\": 1, \"discount\": 10, \"orderedProductPrice\": 72 } ], \"orderDate\": \"2025-02-15\", \"payment\": { \"paymentId\": 17, \"paymentMethod\": \"online\", \"pgPaymentId\": \"pi_3QsfCYLK9jOar8Y81NsK7PXG\", \"pgStatus\": \"succeeded\", \"pgResponseMessage\": \"Payment successful\", \"pgName\": \"Stripe\" }, \"totalAmount\": 72, \"orderStatus\": \"Order Accepted !\", \"addressId\": 1 }, { \"orderId\": 18, \"email\": \"user1@example.com\", \"orderItems\": [ { \"orderItemId\": 8, \"product\": { \"productId\": 102, \"productName\": \"Blender\", \"image\": \"39356dd0-6682-4821-adc8-b198ee85b358.png\", \"description\": \"High-performance Blender having powerful features for modern family\", \"quantity\": 28, \"price\": 500, \"discount\": 19, \"specialPrice\": 405 }, \"quantity\": 1, \"discount\": 19, \"orderedProductPrice\": 405 } ], \"orderDate\": \"2025-07-18\", \"payment\": { \"paymentId\": 18, \"paymentMethod\": \"online\", \"pgPaymentId\": \"pi_3Rm6zYLK9jOar8Y81iyMdnMg\", \"pgStatus\": \"succeeded\", \"pgResponseMessage\": \"Payment successful\", \"pgName\": \"Stripe\" }, \"totalAmount\": 405, \"orderStatus\": \"Order Accepted !\", \"addressId\": 5 } ];\n  // const pagination = { pageNumber: 0, pageSize: 50, totalElements: 11, totalPages: 1, lastPage: true };\n  \n  const {adminOrder, pagination} = useSelector((state) => state.order);\n\n  useOrderFilter();\n\n  const emptyOrder = !adminOrder || adminOrder?.length ===0;\n  return (\n    <div className='pb-6 pt-20'>\n        {emptyOrder ? (\n            <div className='flex flex-col items-center justify-center text-gray-600 py-10'>\n                <FaShoppingCart size={50} className='mb-3'/>\n                <h2 className='text-2xl font-semibold'>No Orders Placed Yet</h2>\n            </div>\n        ) : (\n           <OrderTable adminOrder={adminOrder} pagination={pagination}/>\n        )}\n    </div>\n  )\n}\n\nexport default Orders"
  },
  {
    "path": "ecom-frontend/src/components/admin/orders/UpdateOrderForm.jsx",
    "content": "import { Button, FormControl, FormHelperText, InputLabel, MenuItem, Select } from '@mui/material'\nimport React, { useState } from 'react'\nimport { FaSpinner } from 'react-icons/fa';\nimport Spinners from '../../shared/Spinners';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { updateOrderStatusFromDashboard } from '../../../store/actions';\nimport toast from 'react-hot-toast';\n\nconst ORDER_STATUSES = [\n    \"Pending\",\n    \"Processing\",\n    \"Shipped\",\n    \"Delivered\",\n    \"Cancelled\",\n    \"Accepted\",\n];\n\nconst UpdateOrderForm = ({ setOpen, selectedId, selectedItem, loader, setLoader}) => {\n    const [orderStatus, setOrderStatus] = useState(selectedItem?.status || 'Accepted');\n    const [error, setError] = useState(\"\");\n    const dispatch = useDispatch();\n\n    const { user } = useSelector((state) => state.auth);\n    const isAdmin = user && user?.roles?.includes(\"ROLE_ADMIN\");\n\n    const updateOrderStatus = (e) => {\n        e.preventDefault();\n        if (!orderStatus) {\n            setError(\"Order status is required\");\n            return;\n        }\n        dispatch(updateOrderStatusFromDashboard(\n            selectedId,\n            orderStatus,\n            toast,\n            setLoader,\n            isAdmin\n        ));\n    };\n\n  return (\n    <div className='py-5 relative h-full'>\n        <form className='space-y-4' onSubmit={updateOrderStatus}>\n            <FormControl fullWidth variant='outlined' error={!!error}>\n                <InputLabel id=\"order-status-label\">Order Status</InputLabel>\n                <Select\n                    labelId='order-status-label'\n                    label='Order Status'\n                    value={orderStatus}\n                    onChange={(e) => {\n                        setOrderStatus(e.target.value);\n                        setError(\"\");\n                    }}>\n                    \n                    {\n                        ORDER_STATUSES.map((status) => (\n                            <MenuItem key={status} value={status}>\n                                {status}\n                            </MenuItem>\n                        ))\n                    }\n\n                </Select>\n\n                {error && <FormHelperText>{error}</FormHelperText>}\n            </FormControl>\n\n            <div className='flex w-full justify-between items-center absolute bottom-14'>\n                <Button disabled={loader}\n                        onClick={() => setOpen(false)}\n                        variant='outlined'\n                        className='text-white py-[10px] px-4 text-sm font-medium'>\n                    Cancel\n                </Button>\n\n                <Button\n                    disabled={loader}\n                    type='submit'\n                    variant='contained'\n                    color='primary'\n                    className='bg-custom-blue text-white  py-[10px] px-4 text-sm font-medium'>\n                    {loader ? (\n                        <div className='flex gap-2 items-center'>\n                            <Spinners /> Loading...\n                        </div>\n                    ) : (\n                        \"Update\"\n                    )}\n                </Button>\n            </div>\n        </form>\n\n    </div>\n  )\n}\n\nexport default UpdateOrderForm"
  },
  {
    "path": "ecom-frontend/src/components/admin/products/AddProductForm.jsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { useForm } from 'react-hook-form'\nimport InputField from '../../shared/InputField';\nimport { Button } from '@mui/material';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { addNewProductFromDashboard, fetchCategories, updateProductFromDashboard } from '../../../store/actions';\nimport toast from 'react-hot-toast';\nimport Spinners from '../../shared/Spinners';\nimport SelectTextField from '../../shared/SelectTextField';\nimport Skeleton from '../../shared/Skeleton';\nimport ErrorPage from '../../shared/ErrorPage';\n\nconst AddProductForm = ({ setOpen, product, update=false}) => {\nconst [loader, setLoader] = useState(false);\nconst [selectedCategory, setSelectedCategory] = useState();\nconst { categories } = useSelector((state) => state.products);\nconst { categoryLoader, errorMessage } = useSelector((state) => state.errors);\nconst { user } = useSelector((state) => state.auth);\nconst isAdmin = user && user?.roles?.includes(\"ROLE_ADMIN\");\n\nconst dispatch = useDispatch();\n    const {\n        register,\n        handleSubmit,\n        reset,\n        setValue,\n        formState: { errors }\n    } = useForm({\n        mode: \"onTouched\"\n    });\n\n    const saveProductHandler = (data) => {\n        if(!update) {\n            // create new product logic\n            const sendData = {\n                ...data,\n                categoryId: selectedCategory.categoryId,\n            };\n            dispatch(addNewProductFromDashboard(\n                sendData, toast, reset, setLoader, setOpen, isAdmin\n            ));\n        } else {\n            const sendData = {\n                ...data,\n                id: product.id,\n            };\n            dispatch(updateProductFromDashboard(sendData, toast, reset, setLoader, setOpen, isAdmin));\n        }\n    };\n\n\n    useEffect(() => {\n        if (update && product) {\n            setValue(\"productName\", product?.productName);\n            setValue(\"price\", product?.price);\n            setValue(\"quantity\", product?.quantity);\n            setValue(\"discount\", product?.discount);\n            setValue(\"specialPrice\", product?.specialPrice);\n            setValue(\"description\", product?.description);\n        }\n    }, [update, product]);\n\n\n    useEffect(() => {\n        if (!update) {\n            dispatch(fetchCategories());\n        }\n    }, [dispatch, update]);\n\n    useEffect(() => {\n        if (!categoryLoader && categories) {\n            setSelectedCategory(categories[0]);\n        }\n    }, [categories, categoryLoader]);\n\n    if (categoryLoader) return <Skeleton />\n    if (errorMessage) return <ErrorPage message={errorMessage} />\n\n  return (\n    <div className='py-5 relative h-full'>\n        <form className='space-y-4'\n            onSubmit={handleSubmit(saveProductHandler)}>\n            <div className='flex md:flex-row flex-col gap-4 w-full'>\n                <InputField \n                    label=\"Product Name\"\n                    required\n                    id=\"productName\"\n                    type=\"text\"\n                    message=\"This field is required*\"\n                    register={register}\n                    placeholder=\"Product Name\"\n                    errors={errors}\n                    />\n\n                {!update && (\n                    <SelectTextField\n                        label=\"Select Categories\"\n                        select={selectedCategory}\n                        setSelect={setSelectedCategory}\n                        lists={categories}\n                    />\n                )}\n            </div>\n\n            <div className='flex md:flex-row flex-col gap-4 w-full'>\n                <InputField \n                    label=\"Price\"\n                    required\n                    id=\"price\"\n                    type=\"number\"\n                    message=\"This field is required*\"\n                    placeholder=\"Product Price\"\n                    register={register}\n                    errors={errors}\n                    />\n\n                    <InputField \n                    label=\"Quantity\"\n                    required\n                    id=\"quantity\"\n                    type=\"number\"\n                    message=\"This field is required*\"\n                    register={register}\n                    placeholder=\"Product Quantity\"\n                    errors={errors}\n                    />\n            </div>\n        <div className=\"flex md:flex-row flex-col gap-4 w-full\">\n          <InputField\n            label=\"Discount\"\n            id=\"discount\"\n            type=\"number\"\n            message=\"This field is required*\"\n            placeholder=\"Product Discount\"\n            register={register}\n            errors={errors}\n          />\n          <InputField\n            label=\"Special Price\"\n            id=\"specialPrice\"\n            type=\"number\"\n            message=\"This field is required*\"\n            placeholder=\"Product Discount\"\n            register={register}\n            errors={errors}\n          />\n        </div>\n\n        <div className=\"flex flex-col gap-2 w-full\">\n            <label htmlFor='desc'\n              className='font-semibold text-sm text-slate-800'>\n                Description\n            </label>\n\n            <textarea\n                rows={5}\n                placeholder=\"Add product description....\"\n                className={`px-4 py-2 w-full border outline-hidden bg-transparent text-slate-800 rounded-md ${\n                    errors[\"description\"]?.message ? \"border-red-500\" : \"border-slate-700\" \n                }`}\n                maxLength={255}\n                {...register(\"description\", {\n                    required: {value: true, message:\"Description is required\"},\n                })}\n                />\n\n                {errors[\"description\"]?.message && (\n                    <p className=\"text-sm font-semibold text-red-600 mt-0\">\n                        {errors[\"description\"]?.message}\n                    </p>\n                )}\n        </div>\n\n        <div className='flex w-full justify-between items-center absolute bottom-14'>\n            <Button disabled={loader}\n                    onClick={() => setOpen(false)}\n                    variant='outlined'\n                    className='text-white py-[10px] px-4 text-sm font-medium'>\n                Cancel\n            </Button>\n\n            <Button\n                disabled={loader}\n                type='submit'\n                variant='contained'\n                color='primary'\n                className='bg-custom-blue text-white  py-[10px] px-4 text-sm font-medium'>\n                {loader ? (\n                    <div className='flex gap-2 items-center'>\n                        <Spinners /> Loading...\n                    </div>\n                ) : (\n                    \"Save\"\n                )}\n            </Button>\n        </div>\n        </form>\n    </div>\n  )\n}\n\nexport default AddProductForm"
  },
  {
    "path": "ecom-frontend/src/components/admin/products/AdminProducts.jsx",
    "content": "import React, { useState } from 'react'\nimport { MdAddShoppingCart } from 'react-icons/md';\nimport { useDispatch, useSelector } from 'react-redux';\nimport Loader from '../../shared/Loader';\nimport { FaBoxOpen } from 'react-icons/fa';\nimport { DataGrid } from '@mui/x-data-grid';\nimport { adminProductTableColumn } from '../../helper/tableColumn';\nimport { useDashboardProductFilter } from '../../../hooks/useProductFilter';\nimport Modal from '../../shared/Modal';\nimport AddProductForm from './AddProductForm';\nimport DeleteModal from '../../shared/DeleteModal';\nimport { deleteProduct } from '../../../store/actions';\nimport toast from 'react-hot-toast';\nimport ImageUploadForm from './ImageUploadForm';\nimport ProductViewModal from '../../shared/ProductViewModal';\nimport { useLocation, useNavigate, useSearchParams } from 'react-router-dom';\n\nconst AdminProducts = () => {\n  // const products = [{ \"productId\": 52, \"productName\": \"iPad Pro\", \"image\": \"http://localhost:8080/images/7a7b38c4-2342-4d10-89e9-2c5b3c4fdb44.png\", \"description\": \"High-performance Tablet with a 4K display and powerful camera\", \"quantity\": 30, \"price\": 1800.0, \"discount\": 43.0, \"specialPrice\": 1026.0 }, { \"productId\": 2, \"productName\": \"iPhone 16 Pro Max\", \"image\": \"http://localhost:8080/images/22185fd1-024a-4708-9a10-832b8a50bfde.png\", \"description\": \"High-performance phone with a 4K display and powerful camera\", \"quantity\": 19, \"price\": 1400.0, \"discount\": 23.0, \"specialPrice\": 1078.0 }];\n  // const pagination = { pageNumber: 0, pageSize: 50, totalElements: 11, totalPages: 1, lastPage: true };\n  \n  const {products, pagination} = useSelector((state) => state.products);\n  const { isLoading, errorMessage } = useSelector((state) => state.errors);\n  const [currentPage, setCurrentPage] = useState(\n      pagination?.pageNumber + 1 || 1\n    );\n\n  const dispatch = useDispatch();\n  \n  const [selectedProduct, setSelectedProduct] = useState('');\n  const [openUpdateModal, setOpenUpdateModal] = useState(false);\n  const [openAddModal, setOpenAddModal] = useState(false);\n  const [openDeleteModal, setOpenDeleteModal] = useState(false);\n  const [openProductViewModal, setOpenProductViewModal] = useState(false);\n  const [openImageUploadModal, setOpenImageUploadModal] = useState(false);\n\n  const [loader, setLoader] = useState(false);\n\n  const navigate = useNavigate();\n  const [searchParams] = useSearchParams();\n  const params = new URLSearchParams(searchParams);\n  const pathname = useLocation().pathname;\n\n  const { user } = useSelector((state) => state.auth);\n  const isAdmin = user && user?.roles?.includes(\"ROLE_ADMIN\");\n\n  useDashboardProductFilter();\n\n  const tableRecords = products?.map((item) => {\n  return {\n    id: item.productId,\n    productName: item.productName,\n    description: item.description,\n    discount: item.discount,\n    image: item.image,\n    price: item.price,\n    quantity: item.quantity,\n    specialPrice: item.specialPrice,\n  }\n});\n\nconst handleEdit = (product) => {\n  setSelectedProduct(product);\n  setOpenUpdateModal(true);\n};\n\nconst handleDelete = (product) => {\n  setSelectedProduct(product);\n  setOpenDeleteModal(true);\n};\n\nconst handleImageUpload = (product) => {\n  setSelectedProduct(product);\n  setOpenImageUploadModal(true);\n};\n\nconst handleProductView = (product) => {\n  setSelectedProduct(product);\n  setOpenProductViewModal(true);\n};\n\n\nconst handlePaginationChange = (paginationModel) => {\n  const page = paginationModel.page + 1;\n  setCurrentPage(page);\n  params.set(\"page\", page.toString());\n  navigate(`${pathname}?${params}`)\n};\n\n\nconst onDeleteHandler = () => {\n  dispatch(deleteProduct(setLoader, selectedProduct?.id, toast, setOpenDeleteModal, isAdmin));\n};\n\n  const emptyProduct = !products || products?.length ===0;\n  return (\n    <div>\n      <div className='pt-6 pb-10 flex justify-end'>\n        <button\n          onClick={() => setOpenAddModal(true)}\n          className='bg-custom-blue hover:bg-blue-800 text-white font-semibold py-2 px-4 flex items-center gap-2 rounded-md shadow-md transition-colors hover:text-slate-300 duration-300'>\n          <MdAddShoppingCart className='text-xl' />\n          Add Product\n        </button>\n      </div>\n\n\n    {!emptyProduct && (\n      <h1 className='text-slate-800 text-3xl text-center font-bold pb-6 uppercase'>\n        All Products</h1>\n    )}\n    {isLoading ? (\n      <Loader />\n    ) : (\n      <>\n      {emptyProduct ? (\n        <div className='flex flex-col items-center justify-center text-gray-600 py-10'>\n          <FaBoxOpen size={50} className='mb-3'/>\n          <h2 className='text-2xl font-semibold'>\n            No products created yet  \n          </h2>\n        </div>\n      ) : (\n        <div className='max-w-full'>\n          <DataGrid\n            className='w-full'\n            rows={tableRecords}\n            columns={adminProductTableColumn(\n              handleEdit,\n              handleDelete,\n              handleImageUpload,\n              handleProductView)}\n            paginationMode='server'\n            rowCount={pagination?.totalElements || 0}\n            initialState={{\n              pagination: {\n                paginationModel: {\n                  pageSize: pagination?.pageSize || 10,\n                  page: currentPage - 1,\n                },\n              },\n            }}\n            onPaginationModelChange={handlePaginationChange}\n            disableRowSelectionOnClick\n            disableColumnResize\n            pageSizeOptions={[pagination?.pageSize || 10]}\n            pagination\n            paginationOptions={{\n              showFirstButton: true,\n              showLastButton: true,\n              hideNextButton: currentPage === pagination?.totalPages,\n            }}\n            />\n        </div>\n      )}\n      </>\n    )}\n\n    <Modal\n      open={openUpdateModal || openAddModal}\n      setOpen={openUpdateModal ? setOpenUpdateModal : setOpenAddModal}\n      title={openUpdateModal ? \"Update Product\" : \"Add Product\"}>\n        <AddProductForm \n          setOpen={openUpdateModal ? setOpenUpdateModal : setOpenAddModal}\n          product={selectedProduct}\n          update={openUpdateModal}\n          />\n    </Modal>\n\n\n    <Modal\n      open={openImageUploadModal}\n      setOpen={setOpenImageUploadModal}\n      title=\"Add Product Image\">\n        <ImageUploadForm \n          setOpen={setOpenImageUploadModal}\n          product={selectedProduct}\n          />\n    </Modal>\n\n\n    <DeleteModal\n      open={openDeleteModal}\n      setOpen={setOpenDeleteModal}\n      loader={loader}\n      title=\"Delete Product\"\n      onDeleteHandler={onDeleteHandler} />\n\n      <ProductViewModal \n        open={openProductViewModal}\n        setOpen={setOpenProductViewModal}\n        product={selectedProduct}\n      />\n    </div>\n  )\n}\n\nexport default AdminProducts"
  },
  {
    "path": "ecom-frontend/src/components/admin/products/ImageUploadForm.jsx",
    "content": "import React, { useRef, useState } from 'react'\nimport { FaCloudUploadAlt } from 'react-icons/fa'\nimport Spinners from '../../shared/Spinners';\nimport { Button } from '@mui/material';\nimport toast from 'react-hot-toast';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { updateProductImageFromDashboard } from '../../../store/actions';\n\nconst ImageUploadForm = ({ setOpen, product }) => {\n    const [loader, setLoader] = useState(false);\n    const fileInputRef = useRef();\n    const [previewImage, setPreviewImage] = useState(null);\n    const [selectedFile, setSelectedFile] = useState(null);\n    const dispatch = useDispatch();\n\n    const { user } = useSelector((state) => state.auth);\n    const isAdmin = user && user?.roles?.includes(\"ROLE_ADMIN\");\n\n    const onHandleImageChange = (e) => {\n        const file = e.target.files[0];\n        if (file && [\"image/jpeg\", \"image/jpg\", \"image/png\"].includes(file.type)) {\n            const reader = new FileReader();\n            reader.onloadend = () => {\n                setPreviewImage(reader.result);\n            };\n            reader.readAsDataURL(file);\n            setSelectedFile(file);\n        } else {\n            toast.error(\"Please select a valid image file (.jpeg, .jpg, .png)\");\n            setPreviewImage(null);\n            setSelectedFile(null);\n        }\n\n    };\n\n    const addNewImageHandler = async (event) => {\n        event.preventDefault();\n        if (!selectedFile) {\n            toast.error(\"Please select an image before saving.\");\n            return;\n        }\n\n        const formData = new FormData();\n        formData.append(\"image\", selectedFile);\n\n        dispatch(updateProductImageFromDashboard(formData, product.id, toast, setLoader, setOpen, isAdmin));\n    };\n\n    const handleClearImage = () => {\n        setPreviewImage(null);\n        setSelectedFile(null);\n        fileInputRef.current.value = null;\n    };\n\n  return (\n    <div className='py-5 relative h-full'>\n        <form className='space-y-4' onSubmit={addNewImageHandler}>\n            <div className='flex flex-col gap-4 w-full'>\n                <label className='flex items-center gap-2 cursor-pointer text-custom-blue border border-dashed border-custom-blue rounded-md p-3 w-full justify-center'>\n                    <FaCloudUploadAlt size={24}/>\n                    <span>Upload Product Image</span>\n                    <input \n                        type='file'\n                        ref={fileInputRef}\n                        onChange={onHandleImageChange}\n                        className='hidden'\n                        accept='.jpeg, .jpg, .png'/>\n                </label>\n\n                {previewImage && (\n                    <div>\n                        <img\n                            src={previewImage}\n                            alt='Image Preview'\n                            className='h-60 rounded-md mb-2'/>\n\n                        <button\n                            type='button'\n                            onClick={handleClearImage}\n                            className='bg-rose-600 text-white px-2 py-1 rounded-md'>Clear Image</button>\n                    </div>\n                )}\n            </div>\n\n            <div className='flex w-full justify-between items-center absolute bottom-14'>\n            <Button disabled={loader}\n                    onClick={() => setOpen(false)}\n                    variant='outlined'\n                    className='text-white py-[10px] px-4 text-sm font-medium'>\n                Cancel\n            </Button>\n\n            <Button\n                disabled={loader}\n                type='submit'\n                variant='contained'\n                color='primary'\n                className='bg-custom-blue text-white  py-[10px] px-4 text-sm font-medium'>\n                {loader ? (\n                    <div className='flex gap-2 items-center'>\n                        <Spinners /> Loading...\n                    </div>\n                ) : (\n                    \"Update\"\n                )}\n            </Button>\n        </div>\n        </form>\n    </div>\n  )\n}\n\nexport default ImageUploadForm"
  },
  {
    "path": "ecom-frontend/src/components/admin/sellers/AddSellerForm.jsx",
    "content": "import React, { useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { useForm } from \"react-hook-form\";\nimport toast from \"react-hot-toast\";\nimport { addNewDashboardSeller } from \"../../../store/actions\";\nimport InputField from \"../../shared/InputField\";\nimport Spinners from \"../../shared/Spinners\";\n\nconst AddSellerForm = ({ setOpen }) => {\n  const dispatch = useDispatch();\n  const [loader, setLoader] = useState(false);\n\n  const {\n    register,\n    handleSubmit,\n    reset,\n    formState: { errors },\n  } = useForm({\n    mode: \"onTouched\",\n  });\n\n  const addSellerHandler = (data) => {\n    const sendData = {\n      ...data,\n      role: [\"seller\"],\n    };\n\n    dispatch(addNewDashboardSeller(sendData, toast, reset, setOpen, setLoader));\n  };\n\n  return (\n    <div className=\"py-5 relative h-full \">\n      <form className=\"space-y-4 \" onSubmit={handleSubmit(addSellerHandler)}>\n        <div className=\"flex  flex-col gap-4 w-full\">\n          <InputField\n            label=\"UserName\"\n            required\n            id=\"username\"\n            type=\"text\"\n            message=\"*UserName is required\"\n            placeholder=\"Enter your username\"\n            register={register}\n            errors={errors}\n          />\n          <InputField\n            label=\"Email\"\n            required\n            id=\"email\"\n            type=\"email\"\n            message=\"*Email is required\"\n            placeholder=\"Enter your email\"\n            register={register}\n            errors={errors}\n          />\n          <InputField\n            label=\"Password\"\n            required\n            id=\"password\"\n            type=\"password\"\n            message=\"*Password is required\"\n            placeholder=\"Enter your password\"\n            register={register}\n            errors={errors}\n          />\n        </div>\n\n        <div className=\"flex  w-full justify-between items-center absolute bottom-14\">\n          <button\n            disabled={loader}\n            onClick={() => setOpen(false)}\n            type=\"button\"\n            className={`border border-blue-500 rounded-[5px] font-metropolis  text-textColor py-[10px] px-4 text-sm font-medium`}\n          >\n            Cancel\n          </button>\n          <button\n            disabled={loader}\n            type=\"submit\"\n            className={`font-metropolis rounded-[5px]  bg-custom-blue hover:bg-blue-800 text-white  py-[10px] px-4 text-sm font-medium`}\n          >\n            {loader ? (\n              <div className=\"flex gap-2 items-center\">\n                <Spinners /> Loading..\n              </div>\n            ) : (\n              \"Add New Seller\"\n            )}\n          </button>\n        </div>\n      </form>\n    </div>\n  );\n};\n\nexport default AddSellerForm;"
  },
  {
    "path": "ecom-frontend/src/components/admin/sellers/SellerTable.jsx",
    "content": "import React, { useState } from \"react\";\nimport { useLocation, useNavigate, useSearchParams } from \"react-router-dom\";\nimport { DataGrid } from \"@mui/x-data-grid\";\nimport { sellerTableColumns } from \"../../helper/tableColumn\";\n\nconst SellerTable = ({ sellers, pagination }) => {\n  const navigate = useNavigate();\n  const [searchParams] = useSearchParams();\n  const pathname = useLocation().pathname;\n  const params = new URLSearchParams(searchParams);\n  const [currentPage, setCurrentPage] = useState(pagination?.pageNumber || 1);\n\n  const tableRecords = sellers?.map((item) => {\n    return {\n      id: item.userId,\n      username: item.username,\n      email: item.email,\n    };\n  });\n\n  const handlePaginationChange = (paginationModel) => {\n    const page = paginationModel.page + 1;\n    setCurrentPage(page);\n\n    params.set(\"page\", page.toString());\n    navigate(`${pathname}?${params}`);\n  };\n\n  return (\n    <div>\n      <div className=\"max-w-fit mx-auto\">\n        <DataGrid\n          className=\"w-full\"\n          rows={tableRecords}\n          paginationMode=\"server\"\n          rowCount={pagination?.totalElements || 0}\n          columns={sellerTableColumns}\n          initialState={{\n            pagination: {\n              paginationModel: {\n                pageSize: pagination?.pageSize || 10,\n                page: currentPage - 1,\n              },\n            },\n          }}\n          onPaginationModelChange={handlePaginationChange}\n          disableRowSelectionOnClick\n          disableColumnResize\n          pagination\n          pageSizeOptions={[pagination?.pageSize || 10]}\n          paginationOptions={{\n            showFirstButton: true,\n            showLastButton: true,\n            hideNextButton: currentPage === pagination?.totalPages,\n          }}\n        />\n      </div>\n    </div>\n  );\n};\n\nexport default SellerTable;"
  },
  {
    "path": "ecom-frontend/src/components/admin/sellers/Sellers.jsx",
    "content": "import React, { useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { MdPersonAdd } from \"react-icons/md\";\n\nimport SellerTable from \"./SellerTable\";\nimport ErrorPage from \"../../shared/ErrorPage\";\nimport Loader from \"../../shared/Loader\";\nimport Modal from \"../../shared/Modal\";\nimport AddSellerForm from \"./AddSellerForm\";\nimport useSellerFilter from \"./useSellerFilter\";\n\nconst Sellers = () => {\n  const [openModal, setOpenModal] = useState(false);\n  const { sellers, pagination } = useSelector((state) => state.seller);\n  const { isLoading, errorMessage } = useSelector((state) => state.errors);\n\n  // Calling the `useSellerFilter` custom hook to fetch sellers and pagination based on the current URL parameters.\n  useSellerFilter();\n\n  const emptySellers = !sellers || sellers?.length === 0;\n\n  if (errorMessage) {\n    return <ErrorPage message={errorMessage} />;\n  }\n\n  return (\n    <React.Fragment>\n      <div className=\"pt-6 pb-10 flex justify-end\">\n        <button\n          onClick={() => setOpenModal(true)}\n          className=\"bg-custom-blue hover:bg-blue-800 text-white font-semibold py-2 px-4 flex items-center gap-2 rounded-md shadow-md transition-colors hover:text-slate-300 duration-300\"\n        >\n          <MdPersonAdd className=\"text-xl\" />\n          Add Seller\n        </button>\n      </div>\n\n      {!emptySellers && (\n        <h1 className=\"text-slate-800 text-3xl text-center font-bold pb-6 uppercase\">\n          All Sellers\n        </h1>\n      )}\n\n      {isLoading ? (\n        <Loader />\n      ) : (\n        <>\n          {emptySellers ? (\n            <>\n              <div className=\"flex flex-col items-center justify-center text-gray-600 py-10\">\n                <h2 className=\"text-2xl font-semibold\">\n                  No Seller Created Yet\n                </h2>\n              </div>\n            </>\n          ) : (\n            <SellerTable sellers={sellers} pagination={pagination} />\n          )}\n        </>\n      )}\n\n      <Modal open={openModal} setOpen={setOpenModal} title=\"Add New Seller\">\n        <AddSellerForm setOpen={setOpenModal} />\n      </Modal>\n    </React.Fragment>\n  );\n};\n\nexport default Sellers;"
  },
  {
    "path": "ecom-frontend/src/components/admin/sellers/useSellerFilter.jsx",
    "content": "import { useEffect } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport { useDispatch } from \"react-redux\";\n\nimport { getAllSellersDashboard } from \"../../../store/actions\";\n\nconst useSellerFilter = () => {\n  const [searchParams] = useSearchParams(); // Access search params from the URL\n  const dispatch = useDispatch(); // Get the dispatch function to call actions\n\n  useEffect(() => {\n    const params = new URLSearchParams(); // Create new URLSearchParams object\n\n    // Get current page from URL search params, defaulting to 1 if not present\n    const currentPage = searchParams.get(\"page\")\n      ? Number(searchParams.get(\"page\"))\n      : 1;\n    params.set(\"pageNumber\", currentPage - 1); // Pagination starts from 0 for API\n\n    // Convert params to a query string\n    const queryString = params.toString();\n\n    // Dispatch action to fetch all seller using the constructed query string\n    dispatch(getAllSellersDashboard(queryString));\n  }, [dispatch, searchParams]);\n};\n\nexport default useSellerFilter;"
  },
  {
    "path": "ecom-frontend/src/components/auth/LogIn.jsx",
    "content": "import { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { AiOutlineLogin } from \"react-icons/ai\";\nimport { Link, useNavigate } from \"react-router-dom\";\nimport InputField from \"../shared/InputField\";\nimport { useDispatch } from \"react-redux\";\nimport { authenticateSignInUser } from \"../../store/actions\";\nimport toast from \"react-hot-toast\";\nimport Spinners from \"../shared/Spinners\";\n\nconst LogIn = () => {\n    const navigate = useNavigate();\n    const dispatch = useDispatch();\n    const [loader, setLoader] = useState(false);\n\n    const {\n        register,\n        handleSubmit,\n        reset,\n        formState: {errors},\n    } = useForm({\n        mode: \"onTouched\",\n    });\n\n    const loginHandler = async (data) => {\n        console.log(\"Login Click\");\n        dispatch(authenticateSignInUser(data, toast, reset, navigate, setLoader));\n    };\n\n    return (\n        <div className=\"min-h-[calc(100vh-64px)] flex justify-center items-center\">\n            <form\n                onSubmit={handleSubmit(loginHandler)}\n                className=\"sm:w-[450px] w-[360px] shadow-custom py-8 sm:px-8 px-4 rounded-md\">\n                    <div className=\"flex flex-col items-center justify-center space-y-4\">\n                        <AiOutlineLogin className=\"text-slate-800 text-5xl\"/>\n                        <h1 className=\"text-slate-800 text-center font-montserrat lg:text-3xl text-2xl font-bold\">\n                            Login Here\n                        </h1>\n                    </div>\n            <hr className=\"mt-2 mb-5 text-black\" />\n            <div className=\"flex flex-col gap-3\">\n                <InputField\n                    label=\"UserName\"\n                    required\n                    id=\"username\"\n                    type=\"text\"\n                    message=\"*UserName is required\"\n                    placeholder=\"Enter your username\"\n                    register={register}\n                    errors={errors}\n                    />\n\n                <InputField\n                    label=\"Password\"\n                    required\n                    id=\"password\"\n                    type=\"password\"\n                    message=\"*Password is required\"\n                    placeholder=\"Enter your password\"\n                    register={register}\n                    errors={errors}\n                    />\n            </div>\n\n            <button\n                disabled={loader}\n                className=\"bg-button-gradient flex gap-2 items-center justify-center font-semibold text-white w-full py-2 hover:text-slate-400 transition-colors duration-100 rounded-xs my-3\"\n                type=\"submit\">\n                {loader ? (\n                    <>\n                    <Spinners /> Loading...\n                    </>\n                ) : (\n                    <>Login</>\n                )}\n            </button>\n\n            <p className=\"text-center text-sm text-slate-700 mt-6\">\n              Don't have an account?\n              <Link\n                className=\"font-semibold underline hover:text-black\"\n                to=\"/register\">\n              <span> SignUp</span></Link>  \n            </p>\n            </form>\n        </div>\n    );\n}\n\nexport default LogIn;"
  },
  {
    "path": "ecom-frontend/src/components/auth/Register.jsx",
    "content": "import React, { useState } from 'react'\nimport { useForm } from 'react-hook-form';\nimport { FaUserPlus } from 'react-icons/fa';\nimport { Link, useNavigate } from 'react-router-dom';\nimport InputField from '../shared/InputField';\nimport { useDispatch } from 'react-redux';\nimport { registerNewUser } from '../../store/actions';\nimport toast from 'react-hot-toast';\nimport Spinners from '../shared/Spinners';\n\nconst Register = () => {\n    const navigate = useNavigate();\n    const dispatch = useDispatch();\n    const [loader, setLoader] = useState(false);\n\n    const {\n        register,\n        handleSubmit,\n        reset,\n        formState: {errors},\n    } = useForm({\n        mode: \"onTouched\",\n    });\n\n    const registerHandler = async (data) => {\n        console.log(\"Register Click\");\n        dispatch(registerNewUser(data, toast, reset, navigate, setLoader));\n     };\n\n    return (\n        <div className=\"min-h-[calc(100vh-64px)] flex justify-center items-center\">\n            <form\n                onSubmit={handleSubmit(registerHandler)}\n                className=\"sm:w-[450px] w-[360px] shadow-custom py-8 sm:px-8 px-4 rounded-md\">\n                    <div className=\"flex flex-col items-center justify-center space-y-4\">\n                        <FaUserPlus className=\"text-slate-800 text-5xl\"/>\n                        <h1 className=\"text-slate-800 text-center font-montserrat lg:text-3xl text-2xl font-bold\">\n                            Register Here\n                        </h1>\n                    </div>\n            <hr className=\"mt-2 mb-5 text-black\" />\n            <div className=\"flex flex-col gap-3\">\n                <InputField\n                    label=\"UserName\"\n                    required\n                    id=\"username\"\n                    type=\"text\"\n                    message=\"*UserName is required\"\n                    placeholder=\"Enter your username\"\n                    register={register}\n                    errors={errors}\n                    />\n\n                <InputField\n                    label=\"Email\"\n                    required\n                    id=\"email\"\n                    type=\"email\"\n                    message=\"*Email is required\"\n                    placeholder=\"Enter your email\"\n                    register={register}\n                    errors={errors}\n                    />\n\n                <InputField\n                    label=\"Password\"\n                    required\n                    id=\"password\"\n                    min={6}\n                    type=\"password\"\n                    message=\"*Password is required\"\n                    placeholder=\"Enter your password\"\n                    register={register}\n                    errors={errors}\n                    />\n            </div>\n\n            <button\n                disabled={loader}\n                className=\"bg-button-gradient flex gap-2 items-center justify-center font-semibold text-white w-full py-2 hover:text-slate-400 transition-colors duration-100 rounded-xs my-3\"\n                type=\"submit\">\n                {loader ? (\n                    <>\n                    <Spinners /> Loading...\n                    </>\n                ) : (\n                    <>Register</>\n                )}\n            </button>\n\n            <p className=\"text-center text-sm text-slate-700 mt-6\">\n              Already have an account?\n              <Link\n                className=\"font-semibold underline hover:text-black\"\n                to=\"/login\">\n              <span> Login</span></Link>  \n            </p>\n            </form>\n        </div>\n    );\n}\n\nexport default Register"
  },
  {
    "path": "ecom-frontend/src/components/cart/Cart.jsx",
    "content": "import { MdArrowBack, MdShoppingCart } from \"react-icons/md\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\nimport ItemContent from \"./ItemContent\";\nimport CartEmpty from \"./CartEmpty\";\nimport { formatPrice } from \"../../utils/formatPrice\";\n\nconst Cart = () => {\n    const dispatch = useDispatch();\n    const { cart } = useSelector((state) => state.carts);\n    const newCart = { ...cart };\n\n    newCart.totalPrice = cart?.reduce(\n        (acc, cur) => acc + Number(cur?.specialPrice) * Number(cur?.quantity), 0\n    );\n\n    if (!cart || cart.length === 0) return <CartEmpty />;\n\n    return (\n        <div className=\"lg:px-14 sm:px-8 px-4 py-10\">\n            <div className=\"flex flex-col items-center mb-12\">\n                <h1 className=\"text-4xl font-bold text-gray-900 flex items-center gap-3\">\n                  <MdShoppingCart size={36} className=\"text-gray-700\" />\n                    Your Cart\n                </h1>\n                <p className=\"text-lg text-gray-600 mt-2\">All your selected items</p>\n            </div>\n\n            <div className=\"grid md:grid-cols-5 grid-cols-4 gap-4 pb-2 font-semibold items-center\">\n                <div className=\"md:col-span-2 justify-self-start text-lg text-slate-800 lg:ps-4\">\n                    Product\n                </div>\n\n                <div className=\"justify-self-center text-lg text-slate-800\">\n                    Price\n                </div>\n\n                <div className=\"justify-self-center text-lg text-slate-800\">\n                    Quantity\n                </div>\n\n                <div className=\"justify-self-center text-lg text-slate-800\">\n                    Total\n                </div>\n            </div>\n\n            <div>\n                {cart && cart.length > 0 &&\n                    cart.map((item, i) => <ItemContent key={i} {...item}/>)}\n            </div>\n\n            <div className=\"border-t-[1.5px] border-slate-200 py-4 flex sm:flex-row sm:px-0 px-2 flex-col sm:justify-between gap-4\">\n                <div></div>\n                <div className=\"flex text-sm gap-1 flex-col\">\n                    <div className=\"flex justify-between w-full md:text-lg text-sm font-semibold\">\n                        <span>Subtotal</span>\n                        <span>{formatPrice(newCart?.totalPrice)}</span>\n                    </div>\n\n                    <p className=\"text-slate-500\">\n                        Taxes and shipping calculated at checkout\n                    </p>\n\n                    <Link className=\"w-full flex justify-end\" to=\"/checkout\">\n                    <button\n                        onClick={() => {}}\n                        className=\"font-semibold w-[300px] py-2 px-4 rounded-xs bg-custom-blue text-white flex items-center justify-center gap-2 hover:text-gray-300 transition duration-500\">\n                        <MdShoppingCart size={20} />\n                        Checkout\n                    </button>\n                    </Link>\n\n                    <Link className=\"flex gap-2 items-center mt-2 text-slate-500\" to=\"/products\">\n                        <MdArrowBack />\n                        <span>Continue Shopping</span>\n                    </Link>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default Cart;"
  },
  {
    "path": "ecom-frontend/src/components/cart/CartEmpty.jsx",
    "content": "import { MdArrowBack, MdShoppingCart } from \"react-icons/md\";\nimport { Link } from \"react-router-dom\";\n\nconst CartEmpty = () => {\n return (\n    <div className=\"min-h-[800px] flex flex-col items-center justify-center\">\n        <div className=\"flex flex-col items-center\">\n            <MdShoppingCart size={80} className=\"mb-4 text-slate-500\"/>\n            <div className=\"text-3xl font-bold text-slate-700\">\n                Your cart is empty\n            </div>\n            <div className=\"text-lg text-slate-500 mt-2\">\n                Add some products to get started\n            </div>\n        </div>\n        <div className=\"mt-6\">\n            <Link\n                to=\"/\"\n                className=\"flex gap-2 items-center text-blue-500 hover:text-blue-600 transition\">\n                    <MdArrowBack size={24} />\n                    <span className=\"font-medium\">Start Shopping</span>\n                </Link>\n        </div>\n    </div>\n )   \n}\n\nexport default CartEmpty;"
  },
  {
    "path": "ecom-frontend/src/components/cart/ItemContent.jsx",
    "content": "import { useState } from \"react\";\nimport { HiOutlineTrash } from \"react-icons/hi\";\nimport SetQuantity from \"./SetQuantity\";\nimport { useDispatch } from \"react-redux\";\nimport { decreaseCartQuantity, increaseCartQuantity, removeFromCart } from \"../../store/actions\";\nimport toast from \"react-hot-toast\";\nimport { formatPrice } from \"../../utils/formatPrice\";\nimport truncateText from \"../../utils/truncateText\";\n\nconst ItemContent = ({\n    productId,\n    productName,\n    image,\n    description,\n    quantity,\n    price,\n    discount,\n    specialPrice,\n    cartId,\n  }) => {\n    const [currentQuantity, setCurrentQuantity] = useState(quantity);\n    const dispatch = useDispatch();\n\n    const handleQtyIncrease = (cartItems) => {\n        dispatch(increaseCartQuantity(\n            cartItems,\n            toast,\n            currentQuantity,\n            setCurrentQuantity\n        ));\n    };\n\n    const handleQtyDecrease = (cartItems) => {\n        if (currentQuantity > 1) {\n            const newQuantity = currentQuantity - 1;\n            setCurrentQuantity(newQuantity);\n            dispatch(decreaseCartQuantity(cartItems, newQuantity));\n        }\n    };\n\n    const removeItemFromCart = (cartItems) => {\n        dispatch(removeFromCart(cartItems, toast));\n    };\n    \n    return (\n        <div className=\"grid md:grid-cols-5 grid-cols-4 md:text-md text-sm gap-4   items-center  border border-slate-200  rounded-md  lg:px-4  py-4 p-2\">\n            <div className=\"md:col-span-2 justify-self-start flex  flex-col gap-2 \">\n                <div className=\"flex md:flex-row flex-col lg:gap-4 sm:gap-3 gap-0 items-start \">\n                   <h3 className=\"lg:text-[17px] text-sm font-semibold text-slate-600\">\n                    {truncateText(productName)}\n                   </h3>\n                </div>\n\n                <div className=\"md:w-36 sm:w-24 w-12\">\n                    <img \n                        src={`${import.meta.env.VITE_BACK_END_URL}/images/${image}`}\n                        alt={productName}\n                        className=\"md:h-36 sm:h-24 h-12 w-full object-cover rounded-md\"/>\n                \n\n                <div className=\"flex items-start gap-5 mt-3\">\n                    <button\n                        onClick={() => removeItemFromCart({\n                            image,\n                            productName,\n                            description,\n                            specialPrice,\n                            price,\n                            productId,\n                            quantity,\n                        })}\n                        className=\"flex items-center font-semibold space-x-2 px-4 py-1 text-xs border border-rose-600 text-rose-600 rounded-md hover:bg-red-50 transition-colors duration-200\">\n                        <HiOutlineTrash size={16} className=\"text-rose-600\"/>\n                        Remove\n                    </button>\n                    </div>\n                </div>\n            </div>\n\n            <div className=\"justify-self-center lg:text-[17px] text-sm text-slate-600 font-semibold\">\n                {formatPrice(Number(specialPrice))}\n            </div>\n\n            <div className=\"justify-self-center\">\n                <SetQuantity \n                    quantity={currentQuantity}\n                    cardCounter={true}\n                    handeQtyIncrease={() => handleQtyIncrease({\n                        image,\n                        productName,\n                        description,\n                        specialPrice,\n                        price,\n                        productId,\n                        quantity,\n                    })}\n                    handleQtyDecrease={() => {handleQtyDecrease({\n                        image,\n                        productName,\n                        description,\n                        specialPrice,\n                        price,\n                        productId,\n                        quantity,\n                    })}}/>\n            </div>\n\n            <div className=\"justify-self-center lg:text-[17px] text-sm text-slate-600 font-semibold\">\n                {formatPrice(Number(currentQuantity) * Number(specialPrice))}\n            </div>\n        </div>\n    )\n};\n\nexport default ItemContent;"
  },
  {
    "path": "ecom-frontend/src/components/cart/SetQuantity.jsx",
    "content": "\nconst btnStyles = \"border-[1.2px] border-slate-800 px-3 py-1 rounded-sm\";\nconst SetQuantity = ({\n    quantity,\n    cardCounter,\n    handeQtyIncrease,\n    handleQtyDecrease,\n}) => {\n   return (\n   <div className=\"flex gap-8 items-center\">\n        {cardCounter ? null : <div className=\"font-semibold\">QUANTITY</div>}\n        <div className=\"flex md:flex-row flex-col gap-4 items-center lg:text-[22px] text-sm\">\n            <button\n                disabled={quantity<=1}\n                className={btnStyles}\n                onClick={handleQtyDecrease}>\n                -\n            </button>\n                <div className=\"text-red-500\">{quantity}</div>\n            <button\n                className={btnStyles}\n                onClick={handeQtyIncrease}>\n                +\n            </button>\n        </div>\n    </div>\n   );\n};\n\nexport default SetQuantity;"
  },
  {
    "path": "ecom-frontend/src/components/checkout/AddAddressForm.jsx",
    "content": "import React, { useEffect } from 'react'\nimport InputField from '../shared/InputField'\nimport { useForm } from 'react-hook-form';\nimport { FaAddressCard } from 'react-icons/fa';\nimport { useDispatch, useSelector } from 'react-redux';\nimport Spinners from '../shared/Spinners';\nimport toast from 'react-hot-toast';\nimport { addUpdateUserAddress } from '../../store/actions';\n\nconst AddAddressForm = ({ address, setOpenAddressModal }) => {\n    const dispatch = useDispatch();\n    const { btnLoader } = useSelector((state) => state.errors);\n    const {\n            register,\n            handleSubmit,\n            reset,\n            setValue,\n            formState: {errors},\n        } = useForm({\n            mode: \"onTouched\",\n        });\n\n        const onSaveAddressHandler = async (data) => {\n            dispatch(addUpdateUserAddress(\n                data,\n                toast,\n                address?.addressId,\n                setOpenAddressModal\n            ));\n        };\n\n\n        useEffect(() => {\n            if (address?.addressId) {\n                setValue(\"buildingName\", address?.buildingName);\n                setValue(\"city\", address?.city);\n                setValue(\"street\", address?.street);\n                setValue(\"state\", address?.state);\n                setValue(\"pincode\", address?.pincode);\n                setValue(\"country\", address?.country);\n            }\n        }, [address]);\n\n  return (\n    <div className=\"\">\n            <form\n                onSubmit={handleSubmit(onSaveAddressHandler)}\n                className=\"\">\n                    <div className=\"flex justify-center items-center mb-4 font-semibold text-2xl text-slate-800 py-2 px-4\">\n                        <FaAddressCard className=\"mr-2 text-2xl\"/>\n                        {!address?.addressId ? \n                        \"Add Address\" :\n                        \"Update Address\"\n                        }\n                        \n                    </div>\n            <div className=\"flex flex-col gap-4\">\n                <InputField\n                    label=\"Building Name\"\n                    required\n                    id=\"buildingName\"\n                    type=\"text\"\n                    message=\"*Building Name is required\"\n                    placeholder=\"Enter Building Name\"\n                    register={register}\n                    errors={errors}\n                    />\n\n                <InputField\n                    label=\"City\"\n                    required\n                    id=\"city\"\n                    type=\"text\"\n                    message=\"*City is required\"\n                    placeholder=\"Enter City\"\n                    register={register}\n                    errors={errors}\n                    />\n\n                <InputField\n                    label=\"State\"\n                    required\n                    id=\"state\"\n                    type=\"text\"\n                    message=\"*State is required\"\n                    placeholder=\"Enter State\"\n                    register={register}\n                    errors={errors}\n                    />\n\n                <InputField\n                    label=\"Pincode\"\n                    required\n                    id=\"pincode\"\n                    type=\"text\"\n                    message=\"*Pincode is required\"\n                    placeholder=\"Enter Pincode\"\n                    register={register}\n                    errors={errors}\n                    />    \n                <InputField\n                    label=\"Street\"\n                    required\n                    id=\"street\"\n                    type=\"text\"\n                    message=\"*Street is required\"\n                    placeholder=\"Enter Street\"\n                    register={register}\n                    errors={errors}\n                    />   \n\n                <InputField\n                    label=\"Country\"\n                    required\n                    id=\"country\"\n                    type=\"text\"\n                    message=\"*Country is required\"\n                    placeholder=\"Enter Country\"\n                    register={register}\n                    errors={errors}\n                    />        \n            </div>\n\n            <button\n                disabled={btnLoader}\n                className=\"text-white bg-custom-blue px-4 py-2 rounded-md mt-4\"\n                type=\"submit\">\n                {btnLoader ? (\n                    <>\n                    <Spinners /> Loading...\n                    </>\n                ) : (\n                    <>Save</>\n                )}\n            </button>\n            </form>\n        </div>\n  )\n}\n\nexport default AddAddressForm"
  },
  {
    "path": "ecom-frontend/src/components/checkout/AddressInfo.jsx",
    "content": "\nimport React, { useState } from 'react'\nimport Skeleton from '../shared/Skeleton';\nimport { FaAddressBook } from 'react-icons/fa';\nimport AddressInfoModal from './AddressInfoModal';\nimport AddAddressForm from './AddAddressForm';\nimport { useDispatch, useSelector } from 'react-redux';\nimport AddressList from './AddressList';\nimport { DeleteModal } from './DeleteModal';\nimport toast from 'react-hot-toast';\nimport { deleteUserAddress } from '../../store/actions';\n\nconst AddressInfo = ({ address }) => {\n    const [openAddressModal, setOpenAddressModal] = useState(false);\n    const [openDeleteModal, setOpenDeleteModal] = useState(false);\n    const [selectedAddress, setSelectedAddress] = useState(\"\");\n    const addNewAddressHandler = () => {\n        setSelectedAddress(\"\");\n        setOpenAddressModal(true);\n    };\n\n    const dispatch = useDispatch();\n\n    const deleteAddressHandler = () => {\n        dispatch(deleteUserAddress(\n            toast,\n            selectedAddress?.addressId,\n            setOpenDeleteModal\n        ))\n    };\n\n    const noAddressExist = !address || address.length === 0;\n    const { isLoading, btnLoader } = useSelector((state) => state.errors);\n  return (\n    <div className='pt-4'>\n        {noAddressExist ? (\n            <div className='p-6 rounded-lg max-w-md mx-auto flex flex-col items-center justify-center'>\n                <FaAddressBook size={50} className='text-gray-500 mb-4' />\n                <h1 className='mb-2 text-slate-900 text-center font-semibold text-2xl'>\n                    No Address Added Yet\n                </h1>\n                <p className='mb-6 text-slate-800 text-center'>\n                    Please add your address to complete purchase\n                </p>\n\n                <button\n                    onClick={addNewAddressHandler}\n                    className='px-4 py-2 bg-blue-600 text-white font-medium rounded-sm hover:bg-blue-700 transition-all'>\n                    Add Address\n                </button>\n            </div>\n        ) : (\n            <div className='relative p-6 rounded-lg max-w-md mx-auto'>\n                <h1 className='text-slate-800 text-center font-bold text-2xl'>\n                    Select Address\n                </h1>\n            \n            {isLoading ? (\n                <div className='py-4 px-8'>\n                    <Skeleton />\n                </div>\n            ) : (\n                <>\n                <div className='space-y-4 pt-6'>\n                    <AddressList \n                        addresses={address}\n                        setSelectedAddress={setSelectedAddress}\n                        setOpenAddressModal={setOpenAddressModal}\n                        setOpenDeleteModal={setOpenDeleteModal}\n                        />\n                </div>\n\n                {address.length > 0 && (\n                    <div className='mt-4'>\n                        <button \n                            onClick={addNewAddressHandler}\n                            className='px-4 py-2 bg-blue-600 text-white font-medium rounded-sm hover:bg-blue-700 transition-all'>\n                                Add More\n                        </button>\n                    </div>\n                )}\n                </>\n            )}\n            </div>\n        )}\n\n\n        <AddressInfoModal\n            open={openAddressModal}\n            setOpen={setOpenAddressModal}>\n                <AddAddressForm \n                    address={selectedAddress}\n                    setOpenAddressModal={setOpenAddressModal}/>\n        </AddressInfoModal>\n\n        <DeleteModal \n            open={openDeleteModal}\n            loader={btnLoader}\n            setOpen={setOpenDeleteModal}\n            title=\"Delete Address\"\n            onDeleteHandler={deleteAddressHandler}\n        />\n    </div>\n  )\n}\n\nexport default AddressInfo"
  },
  {
    "path": "ecom-frontend/src/components/checkout/AddressInfoModal.jsx",
    "content": "import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react';\nimport React from 'react'\nimport { FaTimes } from 'react-icons/fa';\n\nconst AddressInfoModal = ({ open, setOpen, children }) => {\n  return (\n    <Dialog open={open} onClose={() => setOpen(false)} className=\"relative z-50\">\n        {/* The backdrop, rendered as a fixed sibling to the panel container */}\n        <DialogBackdrop className=\"fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity\" />\n\n        {/* Full-screen container to center the panel */}\n        <div className=\"fixed inset-0 flex w-screen items-center justify-center p-4\">\n          {/* The actual dialog panel  */}\n          <DialogPanel className=\"relative w-full max-w-md mx-auto transform overflow-hidden bg-white rounded-lg shadow-xl transition-all\">\n            <div className='px-6 py-6'>\n                {children}\n            </div>\n            <div className='flex justify-end gap-4 absolute right-4 top-2'>\n                <button onClick={() => setOpen(false)} type='button'>\n                    <FaTimes className='text-slate-700' size={25} />\n                </button>\n            </div>\n          </DialogPanel>\n        </div>\n      </Dialog>\n  );\n}\n\nexport default AddressInfoModal"
  },
  {
    "path": "ecom-frontend/src/components/checkout/AddressList.jsx",
    "content": "import React from 'react'\nimport { FaBuilding, FaCheckCircle, FaEdit, FaStreetView, FaTrash } from 'react-icons/fa';\nimport { MdLocationCity, MdPinDrop, MdPublic } from \"react-icons/md\";\nimport { useDispatch, useSelector } from 'react-redux'\nimport { selectUserCheckoutAddress } from '../../store/actions';\n\nconst AddressList = ({ addresses, setSelectedAddress, setOpenAddressModal, setOpenDeleteModal }) => {\n    const dispatch = useDispatch();\n    const { selectedUserCheckoutAddress } = useSelector((state) => state.auth);\n\n    const onEditButtonHandler = (addresses) => {\n        setSelectedAddress(addresses);\n        setOpenAddressModal(true);\n    };\n\n    const onDeleteButtonHandler = (addresses) => {\n        setSelectedAddress(addresses);\n        setOpenDeleteModal(true);\n    };\n\n    const handleAddressSelection = (addresses) => {\n        dispatch(selectUserCheckoutAddress(addresses));\n    };\n\n  return (\n    <div className='space-y-4'>\n        {addresses.map((address) => (\n            <div\n                key={address.addressId}\n                onClick={() => handleAddressSelection(address)}\n                className={`p-4 border rounded-md cursor-pointer relative ${\n                    selectedUserCheckoutAddress?.addressId === address.addressId\n                    ? \"bg-green-100\"\n                    : \"bg-white\"\n                }`}>\n                <div className=\"flex items-start\">\n                    <div className=\"space-y-1\">\n                        <div className=\"flex items-center \">\n                            <FaBuilding size={14} className='mr-2 text-gray-600' />\n                            <p className='font-semibold'>{address.buildingName}</p>\n                            {selectedUserCheckoutAddress?.addressId === address.addressId && (\n                                <FaCheckCircle className='text-green-500 ml-2' />\n                            )}\n                        </div>\n\n                        <div className=\"flex items-center \">\n                            <FaStreetView size={17} className='mr-2 text-gray-600' />\n                            <p>{address.street}</p>\n                        </div>\n\n                        <div className=\"flex items-center \">\n                            <MdLocationCity size={17} className='mr-2 text-gray-600' />\n                            <p>{address.city}, {address.state}</p>\n                        </div>\n\n                        <div className=\"flex items-center \">\n                            <MdPinDrop size={17} className='mr-2 text-gray-600' />\n                            <p>{address.pincode}</p>\n                        </div>\n\n                        <div className=\"flex items-center \">\n                            <MdPublic size={17} className='mr-2 text-gray-600' />\n                            <p>{address.country}</p>\n                        </div>\n                    </div>\n                </div>\n\n\n                <div className=\"flex gap-3 absolute top-4 right-2\">\n                    <button onClick={() => onEditButtonHandler(address)}>\n                        <FaEdit size={18} className=\"text-teal-700\" />\n                    </button>\n                    <button onClick={() => onDeleteButtonHandler(address)}>\n                        <FaTrash size={17} className=\"text-rose-600\" />\n                    </button>\n                </div>\n            </div>\n        ))}\n    </div>\n  )\n}\n\nexport default AddressList"
  },
  {
    "path": "ecom-frontend/src/components/checkout/Checkout.jsx",
    "content": "import { Button, Step, StepLabel, Stepper } from '@mui/material';\nimport React, { useEffect, useState } from 'react'\nimport AddressInfo from './AddressInfo';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { getUserAddresses } from '../../store/actions';\nimport toast from 'react-hot-toast';\nimport Skeleton from '../shared/Skeleton';\nimport ErrorPage from '../shared/ErrorPage';\nimport PaymentMethod from './PaymentMethod';\nimport OrderSummary from './OrderSummary';\nimport StripePayment from './StripePayment';\nimport PaypalPayment from './PaypalPayment';\n\nconst Checkout = () => {\n    const [activeStep, setActiveStep] = useState(0);\n    const dispatch = useDispatch();\n    const { isLoading, errorMessage } = useSelector((state) => state.errors);\n    const { cart, totalPrice } = useSelector((state) => state.carts);\n    const { address, selectedUserCheckoutAddress } = useSelector(\n        (state) => state.auth\n    )\n    const { paymentMethod } = useSelector((state) => state.payment);\n\n    const handleBack = () => {\n        setActiveStep((prevStep) => prevStep - 1);\n    };\n\n    const handleNext = () => {\n        if(activeStep === 0 && !selectedUserCheckoutAddress) {\n            toast.error(\"Please select checkout address before proceeding.\");\n            return;\n        }\n\n        if(activeStep === 1 && (!selectedUserCheckoutAddress || !paymentMethod)) {\n            toast.error(\"Please select payment address before proceeding.\");\n            return;\n        }\n        \n        setActiveStep((prevStep) => prevStep + 1);\n    };\n\n    const steps = [\n        \"Address\",\n        \"Payment Method\",\n        \"Order Summary\",\n        \"Payment\",\n    ];\n    \n    useEffect(() => {\n        dispatch(getUserAddresses());\n    }, [dispatch]);\n\n  return (\n    <div className='py-14 min-h-[calc(100vh-100px)]'>\n        <Stepper activeStep={activeStep} alternativeLabel>\n            {steps.map((label, index) => (\n                <Step key={index}>\n                    <StepLabel>{label}</StepLabel>\n                </Step>\n            ))}\n        </Stepper>\n\n        {isLoading ? (\n            <div className='lg:w-[80%] mx-auto py-5'>\n                <Skeleton />\n            </div>\n        ) : (\n            <div className='mt-5'>\n                {activeStep === 0 && <AddressInfo address={address} />}\n                {activeStep === 1 && <PaymentMethod />}\n                {activeStep === 2 && <OrderSummary \n                                        totalPrice={totalPrice}\n                                        cart={cart}\n                                        address={selectedUserCheckoutAddress}\n                                        paymentMethod={paymentMethod}/>}\n                {activeStep === 3 && \n                    <>\n                        {paymentMethod === \"Stripe\" ? (\n                            <StripePayment />\n                        ) : (\n                            <PaypalPayment />\n                        )}\n                    </>}\n            </div>\n        )}\n        \n\n        <div\n            className='flex justify-between items-center px-4 fixed z-50 h-24 bottom-0 bg-white left-0 w-full py-4 border-slate-200'\n            style={{ boxShadow: \"0 -2px 4px rgba(100, 100, 100, 0.15)\" }}>\n            <Button\n                variant='outlined'\n                disabled={activeStep === 0}\n                onClick={handleBack}>\n                    Back\n            </Button>\n\n            {activeStep !== steps.length - 1 && (\n                <button\n                    disabled={\n                        errorMessage || (\n                            (activeStep === 0 ? !selectedUserCheckoutAddress\n                                : activeStep === 1 ? !paymentMethod\n                                : false\n                            )\n                        )\n                    }\n                    className={`bg-custom-blue font-semibold px-6 h-10 rounded-md text-white\n                       ${\n                        errorMessage ||\n                        (activeStep === 0 && !selectedUserCheckoutAddress) ||\n                        (activeStep === 1 && !paymentMethod)\n                        ? \"opacity-60\"\n                        : \"\"\n                       }`}\n                       onClick={handleNext}>\n                    Proceed\n                </button>\n            )} \n        </div>\n        \n        {errorMessage && <ErrorPage message={errorMessage} />}\n    </div>\n  );\n}\n\nexport default Checkout;"
  },
  {
    "path": "ecom-frontend/src/components/checkout/DeleteModal.jsx",
    "content": "import React from \"react\";\nimport { FaExclamationTriangle } from \"react-icons/fa\";\nimport { FaTimes } from \"react-icons/fa\";\nimport {\n  Dialog,\n  DialogBackdrop,\n  DialogPanel,\n  DialogTitle,\n} from \"@headlessui/react\";\n\nexport const DeleteModal = ({\n  open,\n  setOpen,\n  title,\n  onDeleteHandler,\n  loader,\n}) => {\n  return (\n    <Dialog open={open} onClose={setOpen} className=\"relative z-50\">\n      <DialogBackdrop\n        transition\n        className=\"fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity data-closed:opacity-0 data-enter:duration-300 data-leave:duration-200 data-enter:ease-out data-leave:ease-in\"\n      />\n      <div className=\"fixed inset-0 z-10 w-screen overflow-y-auto\">\n        <div className=\"flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0\">\n          <DialogPanel\n            transition\n            className=\"relative transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left shadow-xl transition-all data-closed:translate-y-4 data-closed:opacity-0 data-enter:duration-300 data-leave:duration-200 data-enter:ease-out data-leave:ease-in sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:data-closed:translate-y-0 sm:data-closed:scale-95\"\n          >\n            <div className=\"absolute right-0 top-0 hidden pr-4 pt-4 sm:block\">\n              <button\n                disabled={loader}\n                type=\"button\"\n                onClick={() => setOpen(false)}\n                className=\"rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-hidden focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2\"\n              >\n                <span className=\"sr-only\">Close</span>\n                <FaTimes className=\"h-6 w-6\" />\n              </button>\n            </div>\n            <div className=\"sm:flex sm:items-start\">\n              <div className=\"mx-auto flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10\">\n                <FaExclamationTriangle className=\" text-red-600\" />\n              </div>\n              <div className=\"mt-3 text-center sm:ml-4 sm:mt-0 sm:text-left\">\n                <DialogTitle\n                  as=\"h3\"\n                  className=\"text-base font-semibold font-metropolis leading-6 text-textColor\"\n                >\n                  {title}\n                </DialogTitle>\n                <div className=\"mt-2\">\n                  <p className=\"text-sm text-textColor2 font-metropolis\">\n                    Are you sure you want to delete?\n                  </p>\n                </div>\n              </div>\n            </div>\n            <div className=\"mt-5 sm:mt-4 sm:flex sm:flex-row-reverse\">\n              <button\n                disabled={loader}\n                type=\"button\"\n                onClick={onDeleteHandler}\n                className=\"inline-flex w-full bg-customRed justify-center rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-red-500 sm:ml-3 sm:w-auto\"\n              >\n                {loader ? \"Loading...\" : \"Delete\"}\n              </button>\n              <button\n                disabled={loader}\n                type=\"button\"\n                onClick={() => setOpen(false)}\n                className=\"mt-3 inline-flex w-full justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-xs ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:mt-0 sm:w-auto\"\n              >\n                Cancel\n              </button>\n            </div>\n          </DialogPanel>\n        </div>\n      </div>\n    </Dialog>\n  );\n};"
  },
  {
    "path": "ecom-frontend/src/components/checkout/OrderSummary.jsx",
    "content": "import React from 'react'\nimport { formatPriceCalculation } from '../../utils/formatPrice'\n\nconst OrderSummary = ({ totalPrice, cart, address, paymentMethod}) => {\n  return (\n    <div className=\"container mx-auto px-4 mb-8\">\n     <div className=\"flex flex-wrap\">\n      <div className=\"w-full lg:w-8/12 pr-4\">\n       <div className=\"space-y-4\">\n        <div className=\"p-4 border rounded-lg shadow-xs\">\n            <h2 className='text-2xl font-semibold mb-2'>Billing Address</h2>\n            <p>\n                <strong>Building Name: </strong>\n                {address?.buildingName}\n            </p>\n            <p>\n                <strong>City: </strong>\n                {address?.city}\n            </p>\n            <p>\n                <strong>Street: </strong>\n                {address?.street}\n            </p>\n            <p>\n                <strong>State: </strong>\n                {address?.state}\n            </p>\n            <p>\n                <strong>Pincode: </strong>\n                {address?.pincode}\n            </p>\n            <p>\n                <strong>Country: </strong>\n                {address?.country}\n            </p>\n        </div>\n        <div className='p-4 border rounded-lg shadow-xs'>\n            <h2 className='text-2xl font-semibold mb-2'>\n                Payment Method\n            </h2>\n            <p>\n                <strong>Method: </strong>\n                {paymentMethod}\n            </p>\n        </div>\n\n        <div className='pb-4 border rounded-lg shadow-xs mb-6'>\n            <h2 className='text-2xl font-semibold mb-2'>Order Items</h2>\n            <div className='space-y-2'>\n                {cart?.map((item) => (\n                    <div key={item?.productId} className='flex items-center'>\n                        <img src={`${import.meta.env.VITE_BACK_END_URL}/images/${\n                            item?.image\n                        }`}\n                        alt='Product'\n                        className='w-12 h-12 rounded-sm'></img>\n                    <div className='text-gray-500'>\n                        <p>{item?.productName}</p>\n                        <p>\n                {item?.quantity} x ${item?.specialPrice} = ${\n                    formatPriceCalculation(item?.quantity, item?.specialPrice)\n                }\n                        </p>\n                    </div>\n                    </div>\n                ))}\n            </div>\n        </div>\n       </div>\n      </div>\n\n\n      <div className=\"w-full lg:w-4/12 mt-4 lg:mt-0\">\n          <div className=\"border rounded-lg shadow-xs p-4 space-y-4\">\n            <h2 className=\"text-2xl font-semibold mb-2\">Order Summary</h2>\n\n            <div className=\"space-y-2\">\n              <div className=\"flex justify-between\">\n                <span>Products</span>\n                <span>${formatPriceCalculation(totalPrice, 1)}</span>\n              </div>\n              <div className=\"flex justify-between\">\n                <span>Tax (0%)</span>\n                <span>$0.00</span>\n              </div>\n              <div className=\"flex justify-between font-semibold\">\n                <span>SubTotal</span>\n                <span>${formatPriceCalculation(totalPrice, 1)}</span>\n              </div>\n            </div>\n        </div>\n        </div>\n    </div>\n\n    </div>\n  )\n}\n\nexport default OrderSummary"
  },
  {
    "path": "ecom-frontend/src/components/checkout/PaymentConfirmation.jsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { FaCheckCircle } from 'react-icons/fa';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useLocation } from 'react-router-dom'\nimport { stripePaymentConfirmation } from '../../store/actions';\nimport toast from 'react-hot-toast';\n\nconst PaymentConfirmation = () => {\n    const location = useLocation();\n    const searchParams = new URLSearchParams(location.search);\n    const dispatch = useDispatch();\n    const  [errorMessage, setErrorMessage ] = useState(\"\");\n    const { cart } = useSelector((state) => state.carts);\n    const [ loading, setLoading] = useState(false);\n\n    const paymentIntent = searchParams.get(\"payment_intent\");\n    const clientSecret = searchParams.get(\"payment_intent_client_secret\");\n    const redirectStatus = searchParams.get(\"redirect_status\");\n    const selectedUserCheckoutAddress = localStorage.getItem(\"CHECKOUT_ADDRESS\")\n        ? JSON.parse(localStorage.getItem(\"CHECKOUT_ADDRESS\"))\n        : [];\n\n    useEffect(() => {\n        if (paymentIntent &&\n            clientSecret &&\n            redirectStatus &&\n            cart &&\n            cart?.length > 0\n        ) { \n            console.log(selectedUserCheckoutAddress);\n            const sendData = {\n                addressId: selectedUserCheckoutAddress.addressId,\n                pgName: \"Stripe\",\n                pgPaymentId: paymentIntent,\n                pgStatus: \"succeeded\",\n                pgResponseMessage: \"Payment successful\"\n              };\n              console.log(sendData);\n            dispatch(stripePaymentConfirmation(sendData, setErrorMessage, setLoading, toast));\n        }\n    }, [paymentIntent, clientSecret, redirectStatus, cart]);\n\n  return (\n    <div className='min-h-screen flex items-center justify-center'>\n        {loading ? (\n            <div className='max-w-xl mx-auto'>\n                <Skeleton />\n          </div>\n        ) : (\n            <div className=\"p-8 rounded-lg shadow-lg text-center max-w-md mx-auto border border-gray-200\">\n                <div className=\"text-green-500 mb-4 flex  justify-center\">    \n                    <FaCheckCircle size={64} />\n                </div>\n                <h2 className='text-3xl font-bold text-gray-800 mb-2'>Payment Successful!</h2>\n                <p className=\"text-gray-600 mb-6\">\n                    Thank you for your purchase! Your payment was successful, and we’re\n                    processing your order.\n                </p>\n            </div>\n        )}\n    </div>\n  )\n}\n\nexport default PaymentConfirmation"
  },
  {
    "path": "ecom-frontend/src/components/checkout/PaymentForm.jsx",
    "content": "import { Skeleton } from '@mui/material';\nimport { PaymentElement, useElements, useStripe } from '@stripe/react-stripe-js'\nimport React from 'react'\nimport { useState } from 'react';\n\nconst PaymentForm = ({ clientSecret, totalPrice }) => {\n    const stripe = useStripe();\n    const elements = useElements();\n    const [errorMessage, setErrorMessage] = useState(\"\");\n\n    const handleSubmit = async (e) => {\n        e.preventDefault();\n        if (!stripe || !elements) {\n            return;\n        }\n\n        const { error: submitError } = await elements.submit();\n\n        const { error } = await stripe.confirmPayment({\n            elements,\n            clientSecret,\n            confirmParams: {\n                return_url: `${import.meta.env.VITE_FRONTEND_URL}/order-confirm`,\n            },\n        });\n\n        if (error) {\n            setErrorMessage(error.message);\n            return false;\n        }\n    };\n\n    const paymentElementOptions = {\n        layout: \"tabs\",\n    }\n\n    const isLoading = !clientSecret || !stripe || !elements;\n\n  return (\n    <form onSubmit={handleSubmit} className='max-w-lg mx-auto p-4'>\n        <h2 className='text-xl font-semibold mb-4'>Payment Information</h2>\n        {isLoading ? (\n            <Skeleton />\n        ) : (\n            <>\n            {clientSecret && <PaymentElement  options={paymentElementOptions}/> }\n            {errorMessage && (\n                <div className='text-red-500 mt-2'>{errorMessage}</div>\n            )}\n\n            <button\n                className='text-white w-full px-5 py-[10px] bg-black mt-2 rounded-md font-bold disabled:opacity-50 disabled:animate-pulse'\n                disabled={!stripe || isLoading}>\n                    {!isLoading ? `Pay $${Number(totalPrice).toFixed(2)}`\n                            : \"Processing\"}\n            </button>\n            </>\n        )}\n    </form>\n  )\n}\n\nexport default PaymentForm"
  },
  {
    "path": "ecom-frontend/src/components/checkout/PaymentMethod.jsx",
    "content": "import { FormControl, FormControlLabel, Radio, RadioGroup } from '@mui/material'\nimport React, { useEffect } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { addPaymentMethod, createUserCart } from '../../store/actions';\n\nconst PaymentMethod = () => {\n    const dispatch = useDispatch();\n    const { paymentMethod } = useSelector((state) => state.payment);\n    const { cart, cartId } = useSelector((state) => state.carts);\n    const { isLoading, errorMessage } = useSelector((state) => state.errors);\n\n    useEffect(() => {\n        if (cart.length > 0 && !cartId && !errorMessage) {\n            const sendCartItems = cart.map((item) => {\n                return {\n                    productId: item.productId,\n                    quantity: item.quantity,\n                };\n            });\n            \n            dispatch(createUserCart(sendCartItems));\n        }\n    }, [dispatch, cartId]);\n\n    const paymentMethodHandler = (method) => {\n        dispatch(addPaymentMethod(method));\n    }\n  return (\n    <div className='max-w-md mx-auto p-5 bg-white shadow-md rounded-lg mt-16 border'>\n        <h1 className='text-2xl font-semibold mb-4'>Select Payment Method</h1>\n        <FormControl>\n            <RadioGroup\n                aria-label=\"payment method\"\n                name=\"paymentMethod\"\n                value={paymentMethod}\n                onChange={(e) => paymentMethodHandler(e.target.value)}\n            >\n                <FormControlLabel \n                    value=\"Stripe\" \n                    control={<Radio color='primary' />} \n                    label=\"Stripe\" \n                    className='text-gray-700'/>\n\n                <FormControlLabel \n                    value=\"Paypal\" \n                    control={<Radio color='primary' />} \n                    label=\"Paypal\" \n                    className='text-gray-700'/>\n            </RadioGroup>\n        </FormControl>\n    </div>\n  )\n}\n\nexport default PaymentMethod"
  },
  {
    "path": "ecom-frontend/src/components/checkout/PaypalPayment.jsx",
    "content": "import { Alert, AlertTitle } from '@mui/material'\nimport React from 'react'\n\nconst PaypalPayment = () => {\n  return (\n    <div className='h-96 flex justify-center items-center'>\n        <Alert severity=\"warning\" variant='filled' style={{ maxWidth: \"400px\" }}>\n            <AlertTitle>Paypal Unavailable</AlertTitle>\n            Paypal payment is unavailable. Please use another payment method.\n        </Alert>\n    </div>\n  )\n}\n\nexport default PaypalPayment"
  },
  {
    "path": "ecom-frontend/src/components/checkout/StripePayment.jsx",
    "content": "import { Alert, AlertTitle, Skeleton } from '@mui/material'\nimport { Elements } from '@stripe/react-stripe-js';\nimport { loadStripe } from '@stripe/stripe-js';\nimport React, { useEffect } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport PaymentForm from './PaymentForm';\nimport { createStripePaymentSecret } from '../../store/actions';\n\nconst stripePromise = loadStripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY);\n\nconst StripePayment = () => {\n  const dispatch = useDispatch();\n  const { clientSecret } = useSelector((state) => state.auth);\n  const { totalPrice } = useSelector((state) => state.carts);\n  const { isLoading, errorMessage } = useSelector((state) => state.errors);\n  const { user, selectedUserCheckoutAddress } = useSelector((state) => state.auth);\n\n  useEffect(() => {\n    if (!clientSecret) {\n    const sendData = {\n      amount: Number(totalPrice) * 100,\n      currency: \"usd\",\n      email: user.email,\n      name: `${user.username}`,\n      address: selectedUserCheckoutAddress,\n      description: `Order for ${user.email}`,\n      metadata: {\n        test: \"1\"\n      }\n    };\n      dispatch(createStripePaymentSecret(sendData));\n    }\n  }, [clientSecret]);\n\n  if (isLoading) {\n    return (\n      <div className='max-w-lg mx-auto'>\n        <Skeleton />\n      </div>\n    )\n  }\n\n\n  return (\n    <>\n      {clientSecret && (\n        <Elements stripe={stripePromise} options={{ clientSecret }}>\n          <PaymentForm clientSecret={clientSecret} totalPrice={totalPrice} />\n        </Elements>\n      )}\n    </>\n  )\n}\n\nexport default StripePayment"
  },
  {
    "path": "ecom-frontend/src/components/helper/tableColumn.jsx",
    "content": "import { FaEdit, FaEye, FaImage, FaTrashAlt } from \"react-icons/fa\";\nimport { MdOutlineEmail } from \"react-icons/md\";\n\nexport const adminProductTableColumn = (\n  handleEdit,\n  handleDelete,\n  handleImageUpload,\n  handleProductView\n) => [\n  {\n    disableColumnMenu: true,\n    sortable: false,\n    field: \"id\",\n    headerName: \"ID\",\n    minWidth: 200,\n    headerAlign: \"center\",\n    align: \"center\",\n    editable: false,\n    headerClassName: \"text-black font-semibold border\",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => <span className=\"text-center\">ProductID</span>,\n  },\n  {\n    disableColumnMenu: true,\n    field: \"productName\",\n    headerName: \"Product Name\",\n    align: \"center\",\n    width: 260,\n    editable: false,\n    sortable: false,\n    headerAlign: \"center\",\n    headerClassName: \"text-black font-semibold text-center border \",\n    cellClassName: \"text-slate-700 font-normal border text-center\",\n    renderHeader: (params) => <span>Product Name</span>,\n  },\n\n  {\n    disableColumnMenu: true,\n    field: \"price\",\n    headerName: \"Price\",\n    minWidth: 200,\n    headerAlign: \"center\",\n    align: \"center\",\n    editable: false,\n    headerClassName: \"text-black font-semibold border\",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => <span className=\"text-center\">Price</span>,\n  },\n  {\n    disableColumnMenu: true,\n    field: \"quantity\",\n    headerName: \"Quantity\",\n    minWidth: 200,\n    headerAlign: \"center\",\n    align: \"center\",\n    editable: false,\n    headerClassName: \"text-black font-semibold border\",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => <span className=\"text-center\">Quantity</span>,\n  },\n  {\n    disableColumnMenu: true,\n    field: \"specialPrice\",\n    headerName: \"Price\",\n    minWidth: 200,\n    headerAlign: \"center\",\n    align: \"center\",\n    editable: false,\n    headerClassName: \"text-black font-semibold border\",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => (\n      <span className=\"text-center\">Special Price</span>\n    ),\n  },\n  {\n    sortable: false,\n    field: \"description\",\n    headerName: \"Image\",\n    headerAlign: \"center\",\n    align: \"center\",\n    width: 200,\n    editable: false,\n    disableColumnMenu: true,\n    headerClassName: \"text-black font-semibold border \",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => <span className=\"ps-10\">Description</span>,\n  },\n  {\n    sortable: false,\n    field: \"image\",\n    headerName: \"Image\",\n    headerAlign: \"center\",\n    align: \"center\",\n    width: 200,\n    editable: false,\n    disableColumnMenu: true,\n    headerClassName: \"text-black font-semibold border \",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => <span className=\"ps-10\">Image</span>,\n  },\n\n  {\n    field: \"action\",\n    headerName: \"Action\",\n    headerAlign: \"center\",\n    editable: false,\n    headerClassName: \"text-black font-semibold text-center\",\n    cellClassName: \"text-slate-700 font-normal\",\n    sortable: false,\n    width: 400,\n    renderHeader: (params) => <span>Action</span>,\n    renderCell: (params) => {\n      return (\n        <div className=\"flex justify-center items-center space-x-2 h-full pt-2\">\n          <button\n            onClick={() => handleImageUpload(params.row)}\n            className=\"flex items-center bg-green-500 hover:bg-green-600 text-white px-4 h-9 rounded-md\"\n          >\n            <FaImage className=\"mr-2\" />\n            Image\n          </button>\n          <button\n            onClick={() => handleEdit(params.row)}\n            className=\"flex items-center bg-blue-500 text-white px-4 h-9 rounded-md \"\n          >\n            <FaEdit className=\"mr-2\" />\n            Edit\n          </button>\n\n          <button\n            onClick={() => handleDelete(params.row)}\n            className=\"flex items-center bg-red-500 text-white px-4   h-9 rounded-md\"\n          >\n            <FaTrashAlt className=\"mr-2\" />\n            Delete\n          </button>\n          <button\n            onClick={() => handleProductView(params.row)}\n            className=\"flex items-center bg-slate-800 text-white px-4   h-9 rounded-md\"\n          >\n            <FaEye className=\"mr-2\" />\n            View\n          </button>\n        </div>\n      );\n    },\n  },\n];\n\n\nexport const adminOrderTableColumn = (handleEdit) => [\n  { \n    sortable: false,\n    disableColumnMenu: true,\n    field: \"id\",\n    headerName: \"orderId\",\n    minWidth: 180,\n    headerAlign: \"center\",\n    editable: false,\n    headerClassName: \"text-black font-semibold border\",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => <span className='text-center'>Order ID</span>\n   },\n  {\n    // Column for customer email.\n    disableColumnMenu: true,\n    field: \"email\",\n    headerName: \"Email\",\n    align: \"center\",\n    width: 250,\n    editable: false,\n    sortable: false,\n    headerAlign: \"center\",\n    headerClassName: \"text-black font-semibold text-center border \",\n    cellClassName: \"text-slate-700 font-normal border text-center\",\n    renderHeader: (params) => <span>Email</span>,\n  },\n  {\n    // Column for showing total amount of the order.\n    disableColumnMenu: true,\n    field: \"totalAmount\",\n    headerName: \"Total Amount\",\n    align: \"center\",\n    width: 200,\n    editable: false,\n    sortable: true,\n    headerAlign: \"center\",\n    headerClassName: \"text-black font-semibold text-center border \",\n    cellClassName: \"text-slate-700 font-normal border text-center\",\n    renderHeader: (params) => <span>Total Amount</span>,\n  },\n  {\n    // Column to display order status (e.g., Pending, Shipped).\n    disableColumnMenu: true,\n    field: \"status\",\n    headerName: \"Status\",\n    align: \"center\",\n    width: 200,\n    editable: false,\n    sortable: false,\n    headerAlign: \"center\",\n    headerClassName: \"text-black font-semibold text-center border \",\n    cellClassName: \"text-slate-700 font-normal border text-center\",\n    renderHeader: (params) => <span>Status</span>,\n  },\n  {\n    // Column for order creation date.\n    disableColumnMenu: true,\n    field: \"date\",\n    headerName: \"Order Date\",\n    align: \"center\",\n    width: 200,\n    editable: false,\n    sortable: false,\n    headerAlign: \"center\",\n    headerClassName: \"text-black font-semibold text-center border \",\n    cellClassName: \"text-slate-700 font-normal border text-center\",\n    renderHeader: (params) => <span>Order Date</span>,\n  },\n  {\n    // Custom action column with an \"Edit\" button.\n    field: \"action\",\n    headerName: \"Action\",\n    headerAlign: \"center\",\n    editable: false,\n    headerClassName: \"text-black font-semibold text-center\",\n    cellClassName: \"text-slate-700 font-normal\",\n    sortable: false,\n    width: 250,\n    renderHeader: (params) => <span>Action</span>,\n    renderCell: (params) => {\n      return (\n        <div className='flex justify-center items-center space-x-2 h-full pt-2'>\n          <button\n            onClick={() => handleEdit(params.row)}\n            className='flex items-center bg-blue-500 text-white px-4 h-9 rounded-md'>\n              <FaEdit className='mr-2'/>\n              Edit\n          </button>\n        </div>\n      );\n    },\n  },\n];\n\n\n//table column for categories in admin panel\nexport const categoryTableColumns = (handleEdit, handleDelete) => [\n  {\n    sortable: false,\n    disableColumnMenu: true,\n    field: \"id\",\n    headerName: \"CategoryId\",\n    minWidth: 300,\n    headerAlign: \"center\",\n    align: \"center\",\n    editable: false,\n    headerClassName: \"text-black font-semibold border\",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => <span className=\"text-center\">CategoryId</span>,\n  },\n  {\n    disableColumnMenu: true,\n    field: \"categoryName\",\n    headerName: \"Category Name\",\n    align: \"center\",\n    width: 400,\n    editable: false,\n    sortable: false,\n    headerAlign: \"center\",\n    headerClassName: \"text-black font-semibold text-center border \",\n    cellClassName: \"text-slate-700 font-normal border text-center\",\n    renderHeader: (params) => <span>Category Name</span>,\n  },\n\n  {\n    field: \"action\",\n    headerName: \"Action\",\n    headerAlign: \"center\",\n    editable: false,\n    headerClassName: \"text-black font-semibold text-center\",\n    cellClassName: \"text-slate-700 font-normal\",\n    sortable: false,\n    width: 400,\n    renderHeader: (params) => <span>Action</span>,\n    renderCell: (params) => {\n      return (\n        <div className=\"flex justify-center space-x-2 h-full pt-2\">\n          <button\n            onClick={() => handleEdit(params.row)}\n            className=\"flex items-center bg-blue-500 text-white px-4 h-9 rounded-md \"\n          >\n            <FaEdit className=\"mr-2\" />\n            Edit\n          </button>\n\n          {/* Delete Button */}\n          <button\n            onClick={() => handleDelete(params.row)}\n            className=\"flex items-center bg-red-500 text-white px-4   h-9 rounded-md\"\n          >\n            <FaTrashAlt className=\"mr-2\" />\n            Delete\n          </button>\n        </div>\n      );\n    },\n  },\n];\n\n\n//table column for seller in admin panel\nexport const sellerTableColumns = [\n  {\n    disableColumnMenu: true,\n    field: \"id\",\n    headerName: \"ID\",\n    minWidth: 400,\n    headerAlign: \"center\",\n    align: \"center\",\n    editable: false,\n\n    headerClassName: \"text-black font-semibold border\",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => <span className=\"text-center\">SellerID</span>,\n  },\n  {\n    disableColumnMenu: true,\n    field: \"username\",\n    headerName: \"UserName\",\n    minWidth: 400,\n    headerAlign: \"center\",\n    align: \"center\",\n    editable: false,\n    sortable: false,\n    headerClassName: \"text-black font-semibold border\",\n    cellClassName: \"text-slate-700 font-normal border\",\n    renderHeader: (params) => <span className=\"text-center\">UserName</span>,\n  },\n  {\n    disableColumnMenu: true,\n    field: \"email\",\n    headerName: \"Email\",\n    align: \"center\",\n    width: 400,\n    editable: false,\n    sortable: false,\n    headerAlign: \"center\",\n    headerClassName: \"text-black font-semibold text-center border \",\n    cellClassName: \"text-slate-700 font-normal border text-center\",\n    renderHeader: (params) => <span>Email</span>,\n    renderCell: (params) => {\n      return (\n        <div className=\"flex items-center justify-center gap-1\">\n          <span>\n            <MdOutlineEmail className=\"text-slate-700 text-lg\" />\n          </span>\n          <span>{params?.row?.email}</span>\n        </div>\n      );\n    },\n  },\n];"
  },
  {
    "path": "ecom-frontend/src/components/home/HeroBanner.jsx",
    "content": "// Import Swiper React components\nimport { Swiper, SwiperSlide } from 'swiper/react';\nimport 'swiper/css/navigation';\nimport 'swiper/css/pagination';\nimport 'swiper/css/scrollbar';\nimport 'swiper/css/effect-fade';\nimport 'swiper/css/autoplay';\n\n// Import Swiper styles\nimport 'swiper/css';\nimport { Autoplay, Pagination, EffectFade, Navigation } from 'swiper/modules';\n\nimport { bannerLists } from '../../utils';\nimport { Link } from 'react-router-dom';\n\nconst colors = [\"bg-banner-color1\", \"bg-banner-color2\", \"bg-banner-color3\"];\n\nconst HeroBanner = () => {\n    return (\n        <div className='py-2 rounded-md'>\n            <Swiper\n                grabCursor = {true}\n                autoplay = {{\n                    delay:4000,\n                    disableOnInteraction: false,\n                }}\n                navigation\n                modules={[Pagination, EffectFade, Navigation, Autoplay]}\n                pagination={{clickable: true}}\n                scrollbar={{ draggable: true}}\n                slidesPerView={1}>\n\n                    {bannerLists.map((item, i) => (\n                        <SwiperSlide key={item.id}>\n                            <div className={`carousel-item rounded-md sm:h-[500px] h-96 ${colors[i]}`}>\n                                <div className='flex items-center justify-center'>\n                                    <div className='hidden lg:flex justify-center w-1/2 p-8'>\n                                    <div className='text-center'>\n                                        <h3 className='text-3xl text-white font-bold'>\n                                            {item.title}\n                                        </h3>\n                                        <h1 className='text-5xl text-white font-bold mt-2'>\n                                            {item.subtitle}\n                                        </h1>\n                                        <p className='text-white font-bold mt-4'>\n                                            {item.description}\n                                        </p>\n                                        <Link \n                                            className='mt-6 inline-block bg-black text-white py-2 px-4 rounded-sm hover:bg-gray-800'\n                                            to=\"/products\">\n                                        Shop\n                                        </Link>\n                                    </div>\n                                </div>\n                                <div className='w-full flex justify-center lg:w-1/2 p-4'>\n                                    <img src={item?.image}></img>\n                                </div>\n                                </div>\n                            </div>\n                        </SwiperSlide>\n                    ))}\n            </Swiper>\n        </div>\n    );\n}\n\n\nexport default HeroBanner;"
  },
  {
    "path": "ecom-frontend/src/components/home/Home.jsx",
    "content": "import { useDispatch, useSelector } from \"react-redux\";\nimport HeroBanner from \"./HeroBanner\";\nimport { useEffect } from \"react\";\nimport { fetchProducts } from \"../../store/actions\";\nimport ProductCard from \"../shared/ProductCard\";\nimport Loader from \"../shared/Loader\";\nimport { FaExclamationTriangle } from \"react-icons/fa\";\n\nconst Home = () => {\n    const dispatch = useDispatch();\n    const {products} = useSelector((state) => state.products);\n    const { isLoading, errorMessage } = useSelector(\n        (state) => state.errors\n    );\n    useEffect(() => {\n        dispatch(fetchProducts());\n    }, [dispatch]);\n    return (\n        <div className=\"lg:px-14 sm:px-8 px-4\">\n            <div className=\"py-6\">\n                <HeroBanner />\n            </div>\n            \n            <div className=\"py-5\">\n                <div className=\"flex flex-col justify-center items-center space-y-2\">\n                    <h1 className=\"text-slate-800 text-4xl font-bold\"> Products</h1>\n                        <span className=\"text-slate-700\">\n                            Discover our handpicked selection of top-rated items just for you!\n                        </span>\n                    \n                </div>\n\n                {isLoading ? (\n                    <Loader />\n                ) : errorMessage ? (\n                    <div className=\"flex justify-center items-center h-[200px]\">\n                        <FaExclamationTriangle className=\"text-slate-800 text-3xl mr-2\"/>\n                        <span className=\"text-slate-800 text-lg font-medium\">\n                            {errorMessage}\n                        </span>\n                    </div>\n                ) : (\n            <div className=\"pb-6 pt-14 grid 2xl:grid-cols-4 lg:grid-cols-3 sm:grid-cols-2 gap-y-6 gap-x-6\">\n                       {products && \n                       products?.slice(0,4)\n                                .map((item, i) => <ProductCard key={i} {...item} />\n                        )}\n                    </div>\n                    )}\n            </div>\n        </div>\n    )\n}\n\nexport default Home;"
  },
  {
    "path": "ecom-frontend/src/components/products/Filter.jsx",
    "content": "import { Button, FormControl, InputLabel, MenuItem, Select, Tooltip } from \"@mui/material\";\nimport { useEffect, useState } from \"react\";\nimport { FiArrowDown, FiArrowUp, FiRefreshCw, FiSearch } from \"react-icons/fi\";\nimport { useLocation, useNavigate, useSearchParams } from \"react-router-dom\";\n\nconst Filter = ({ categories }) => {\n    const [searchParams] = useSearchParams();\n    const params = new URLSearchParams(searchParams);\n    const pathname = useLocation().pathname;\n    const navigate = useNavigate();\n    \n    const [category, setCategory] = useState(\"all\");\n    const [sortOrder, setSortOrder] = useState(\"asc\");\n    const [searchTerm, setSearchTerm] = useState(\"\");\n\n    useEffect(() => {\n        const currentCategory = searchParams.get(\"category\") || \"all\";\n        const currentSortOrder = searchParams.get(\"sortby\") || \"asc\";\n        const currentSearchTerm = searchParams.get(\"keyword\") || \"\";\n\n        setCategory(currentCategory);\n        setSortOrder(currentSortOrder);\n        setSearchTerm(currentSearchTerm);\n    }, [searchParams]);\n\n    useEffect(() => { \n        const handler = setTimeout(() => {\n            if (searchTerm) {\n                searchParams.set(\"keyword\", searchTerm);\n            } else {\n                searchParams.delete(\"keyword\");\n            }\n            navigate(`${pathname}?${searchParams.toString()}`);\n        }, 700);\n\n        return () => {\n            clearTimeout(handler);\n        };\n    }, [searchParams, searchTerm, navigate, pathname]);\n\n    const handleCategoryChange = (event) => {\n        const selectedCategory = event.target.value;\n\n        if (selectedCategory === \"all\") {\n            params.delete(\"category\");\n        } else {\n            params.set(\"category\", selectedCategory);\n        }\n        navigate(`${pathname}?${params}`);\n        setCategory(event.target.value);\n    };\n\n    const toggleSortOrder = () => {\n        setSortOrder((prevOrder) => {\n            const newOrder = (prevOrder === \"asc\") ?  \"desc\" : \"asc\";\n            params.set(\"sortby\", newOrder);\n            navigate(`${pathname}?${params}`);\n            return newOrder;\n        })\n    };\n\n    const handleClearFilters = () => {\n        navigate({ pathname : window.location.pathname });\n    };\n\n    return (\n        <div className=\"flex lg:flex-row flex-col-reverse lg:justify-between justify-center items-center gap-4\">\n            {/* SEARCH BAR */}\n            <div className=\"relative flex items-center 2xl:w-[450px] sm:w-[420px] w-full\">\n                <input \n                    type=\"text\"\n                    placeholder=\"Search Products\"\n                    value={searchTerm}\n                    onChange={(e) => setSearchTerm(e.target.value)}\n                    className=\"border border-gray-400 text-slate-800 rounded-md py-2 pl-10 pr-4 w-full focus:outline-hidden focus:ring-2 focus:ring-[#1976d2]\"/>\n                <FiSearch className=\"absolute left-3 text-slate-800 size={20}\"/>\n            </div>\n\n            {/* CATEGORY SELECTION */}\n            <div className=\"flex sm:flex-row flex-col gap-4 items-center\">\n                <FormControl\n                    className=\"text-slate-800 border-slate-700\"\n                    variant=\"outlined\"\n                    size=\"small\">\n                        <InputLabel id=\"category-select-label\">Category</InputLabel>\n                        <Select\n                            labelId=\"category-select-label\"\n                            value={category}\n                            onChange={handleCategoryChange}\n                            label=\"Category\"\n                            className=\"min-w-[120px] text-slate-800 border-slate-700\"\n                         >\n                            <MenuItem value=\"all\">All</MenuItem>\n                            {categories.map((item) => (\n                                <MenuItem key={item.categoryId} value={item.categoryName}>\n                                    {item.categoryName}\n                                </MenuItem>\n                            ))}\n                         </Select>\n                </FormControl>\n\n                {/* SORT BUTTON & CLEAR FILTER */}\n                <Tooltip title=\"Sorted by price: asc\">\n                    <Button variant=\"contained\" \n                        onClick={toggleSortOrder}\n                        color=\"primary\" \n                        className=\"flex items-center gap-2 h-10\">\n                        Sort By\n                        {sortOrder === \"asc\" ? (\n                            <FiArrowUp size={20} />\n                        ) : (\n                            <FiArrowDown size={20} />\n                        )}\n                        \n                    </Button>\n                </Tooltip>\n                <button \n                className=\"flex items-center gap-2 bg-rose-900 text-white px-3 py-2 rounded-md transition duration-300 ease-in shadow-md focus:outline-hidden\"\n                onClick={handleClearFilters}\n                >\n                    <FiRefreshCw className=\"font-semibold\" size={16}/>\n                    <span className=\"font-semibold\">Clear Filter</span>\n                </button>\n            </div>\n        </div>\n    );\n}\n\nexport default Filter;"
  },
  {
    "path": "ecom-frontend/src/components/products/Products.jsx",
    "content": "import { FaExclamationTriangle } from \"react-icons/fa\";\nimport ProductCard from \"../shared/ProductCard\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useEffect } from \"react\";\nimport { fetchCategories } from \"../../store/actions\";\nimport Filter from \"./Filter\";\nimport useProductFilter from \"../../hooks/useProductFilter\";\nimport Loader from \"../shared/Loader\";\nimport Paginations from \"../shared/Paginations\";\n\nconst Products = () => {\n    const { isLoading, errorMessage } = useSelector(\n        (state) => state.errors\n    );\n    const {products, categories, pagination} = useSelector(\n        (state) => state.products\n    )\n    const dispatch = useDispatch();\n    useProductFilter();\n\n    useEffect(() => {\n        dispatch(fetchCategories());\n    }, [dispatch]);\n\n    return (\n        <div className=\"lg:px-14 sm:px-8 px-4 py-14 2xl:w-[90%] 2xl:mx-auto\">\n            <Filter categories={categories ? categories : []}/>\n            {isLoading ? (\n                <Loader />\n            ) : errorMessage ? (\n                <div className=\"flex justify-center items-center h-[200px]\">\n                    <FaExclamationTriangle className=\"text-slate-800 text-3xl mr-2\"/>\n                    <span className=\"text-slate-800 text-lg font-medium\">\n                        {errorMessage}\n                    </span>\n                </div>\n            ) : (\n                <div className=\"min-h-[700px]\">\n                    <div className=\"pb-6 pt-14 grid 2xl:grid-cols-4 lg:grid-cols-3 sm:grid-cols-2 gap-y-6 gap-x-6\">\n                       {products && \n                        products.map((item, i) => <ProductCard key={i} {...item} />\n                        )}\n                    </div>\n                    <div className=\"flex justify-center pt-10\">\n                        <Paginations \n                            numberOfPage = {pagination?.totalPages}\n                            totalProducts = {pagination?.totalElements}/>\n                    </div>\n                </div>\n            )}\n        </div>\n    )\n}\n\nexport default Products;"
  },
  {
    "path": "ecom-frontend/src/components/shared/DeleteModal.jsx",
    "content": "import React from \"react\";\nimport { FaExclamationTriangle } from \"react-icons/fa\";\nimport { FaTimes } from \"react-icons/fa\";\nimport {\n  Dialog,\n  DialogBackdrop,\n  DialogPanel,\n  DialogTitle,\n} from \"@headlessui/react\";\n\nexport const DeleteModal = ({\n  open,\n  setOpen,\n  title,\n  onDeleteHandler,\n  loader,\n}) => {\n  return (\n    <Dialog open={open} onClose={setOpen} className=\"relative z-50\">\n      <DialogBackdrop\n        transition\n        className=\"fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity data-[closed]:opacity-0 data-[enter]:duration-300 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in\"\n      />\n\n      <div className=\"fixed inset-0 z-10 w-screen overflow-y-auto\">\n        <div className=\"flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0\">\n          <DialogPanel\n            transition\n            className=\"relative transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left shadow-xl transition-all data-[closed]:translate-y-4 data-[closed]:opacity-0 data-[enter]:duration-300 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in sm:my-8 sm:w-full sm:max-w-lg sm:p-6 data-[closed]:sm:translate-y-0 data-[closed]:sm:scale-95\"\n          >\n            <div className=\"absolute right-0 top-0 hidden pr-4 pt-4 sm:block\">\n              <button\n                disabled={loader}\n                type=\"button\"\n                onClick={() => setOpen(false)}\n                className=\"rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2\"\n              >\n                <span className=\"sr-only\">Close</span>\n                <FaTimes className=\"h-6 w-6\" />\n              </button>\n            </div>\n            <div className=\"sm:flex sm:items-start\">\n              <div className=\"mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10\">\n                <FaExclamationTriangle className=\" text-red-600\" />\n              </div>\n              <div className=\"mt-3 text-center sm:ml-4 sm:mt-0 sm:text-left\">\n                <DialogTitle\n                  as=\"h3\"\n                  className=\"text-base font-semibold font-metropolis leading-6 text-textColor\"\n                >\n                  {title}\n                </DialogTitle>\n                <div className=\"mt-2\">\n                  <p className=\"text-sm text-textColor2 font-metropolis\">\n                    Are you sure you want to delete?\n                  </p>\n                </div>\n              </div>\n            </div>\n            <div className=\"mt-5 sm:mt-4 sm:flex sm:flex-row-reverse\">\n              <button\n                disabled={loader}\n                type=\"button\"\n                onClick={onDeleteHandler}\n                className=\"inline-flex w-full bg-customRed justify-center rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 sm:ml-3 sm:w-auto\"\n              >\n                {loader ? \"Loading...\" : \"Delete\"}\n              </button>\n              <button\n                disabled={loader}\n                type=\"button\"\n                onClick={() => setOpen(false)}\n                className=\"mt-3 inline-flex w-full justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:mt-0 sm:w-auto\"\n              >\n                Cancel\n              </button>\n            </div>\n          </DialogPanel>\n        </div>\n      </div>\n    </Dialog>\n  );\n};\n\nexport default DeleteModal;"
  },
  {
    "path": "ecom-frontend/src/components/shared/ErrorPage.jsx",
    "content": "import React from 'react'\nimport { FaExclamationTriangle } from 'react-icons/fa'\n\nconst ErrorPage = ({ message}) => {\n  return (\n    <div className='flex flex-col items-center justify-center px-6 py-14'>\n        <FaExclamationTriangle className='text-red-500 text-6xl mb-4' />\n        <p className='text-gray-600 mb-6 text-center'>\n            {message ? message : \"An unexpected error has occured\"}\n        </p>\n    </div>\n    \n  )\n}\n\nexport default ErrorPage"
  },
  {
    "path": "ecom-frontend/src/components/shared/InputField.jsx",
    "content": "const InputField = ({\n    label,\n    id,\n    type,\n    errors,\n    register,\n    required,\n    message,\n    className,\n    min,\n    value,\n    placeholder,\n}) => {\n    return (\n        <div className=\"flex flex-col gap-1 w-full\">\n            <label\n                htmlFor=\"id\"\n                className={`${\n                    className ? className : \"\"\n                } font-semibold text-sm text-slate-800`}>\n                {label}\n            </label>\n            <input\n                type={type}\n                id={id}\n                placeholder={placeholder}\n                className={`${\n                    className ? className : \"\"\n                } px-2 py-2 border outline-hidden bg-transparent text-slate-800 rounded-md ${\n                    errors[id]?.message ? \"border-red-500\" : \"border-slate-700\" \n                }`}\n                {...register(id, {\n                    required: {value: required, message},\n                    minLength: min\n                        ? { value: min, message: `Minimum ${min} character is required`}\n                        : null,\n                    pattern:\n                        type === \"email\"\n                            ? {\n                                value: /^[a-zA-Z0-9]+@(?:[a-zA-Z0-9]+\\.)+com+$/,\n                                message: \"Invalid email\"\n                            }\n                            : type === \"url\"\n                            ? {\n                                value: /^(https?:\\/\\/)?(([a-zA-Z0-9\\u00a1-\\uffff-]+\\.)+[a-zA-Z\\u00a1-\\uffff]{2,})(:\\d{2,5})?(\\/[^\\s]*)?$/,\n                                message: \"Please enter a valid url\"\n                            }\n                            : null,\n\n                })}\n                />\n\n                {errors[id]?.message && (\n                    <p className=\"text-sm font-semibold text-red-600 mt-0\">\n                        {errors[id]?.message}\n                    </p>\n                )}\n        </div>\n    );\n};\n\nexport default InputField;"
  },
  {
    "path": "ecom-frontend/src/components/shared/Loader.jsx",
    "content": "import { RotatingLines } from \"react-loader-spinner\";\n\nconst Loader = ({ text }) => {\n    return (\n        <div className=\"flex justify-center items-center w-full h-[450px]\">\n            <div className=\"flex flex-col items-center gap-1\">\n            <RotatingLines\n                    visible={true}\n                    height=\"96\"\n                    width=\"96\"\n                    color=\"red\"\n                    strokeWidth=\"5\"\n                    animationDuration=\"0.75\"\n                    ariaLabel=\"rotating-lines-loading\"\n                    wrapperStyle={{}}\n                    wrapperClass=\"\"\n                    />\n                    <p className=\"text-slate-800\">\n                        {text ? text : \"Please wait....\" }\n                    </p>\n            </div>\n        </div>\n    );\n}\n\nexport default Loader;"
  },
  {
    "path": "ecom-frontend/src/components/shared/Modal.jsx",
    "content": "import { Description, Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react'\nimport { RxCross1 } from 'react-icons/rx';\n\nfunction Modal({ open, setOpen, children, title = \"\"}) {\n  return (\n    <>\n      <Dialog open={open} onClose={() => setOpen(false)} className=\"relative z-10\">\n        <DialogBackdrop className=\"fixed inset-0 bg-gray-500/75 transition-opacity duration-500 ease-in-out data-closed:opacity-0\" />\n        \n        <div className=\"fixed inset-0 overflow-hidden\">\n            <div className='absolute inset-0 overflow-hidden'>\n                <div className='pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10'>\n                    <DialogPanel transition\n                        className='pointer-events-auto relative w-screen max-w-[800px] transform transition duration-500 ease-in-out data-closed:translate-x-full sm:duration-700'>\n                            <div className='flex h-full flex-col overflow-y-scroll bg-white shadow-xl'>\n                                <div className='px-4 sm:px-6'>\n                                    <DialogTitle className='text-base font-semibold leading-6 text-gray-900'>\n                                        Panel Title\n                                    </DialogTitle>\n                                </div>\n\n                                <div className='relative mt-6 flex-1 p-8'>\n                                    <div className='border-b pb-8 flex justify-between'>\n                                        <h1 className='font-montserrat font-bold text-slate-800 text-2xl pt-4'>{title}</h1>\n                                        <button onClick={() => setOpen(false)}>\n                                            <RxCross1 className='text-slate-800 text-2xl'/>\n                                        </button>\n                                    </div>    \n                                    {children}                                \n                                </div>\n                            </div>\n                    </DialogPanel>\n                </div>\n            </div>\n        </div>\n      </Dialog>\n    </>\n  )\n}\n\n\nexport default Modal;"
  },
  {
    "path": "ecom-frontend/src/components/shared/Navbar.jsx",
    "content": "import { Badge } from \"@mui/material\";\nimport { useState } from \"react\";\nimport { FaShoppingCart, FaSignInAlt, FaStore } from \"react-icons/fa\";\nimport { IoIosMenu } from \"react-icons/io\";\nimport { RxCross2 } from \"react-icons/rx\";\nimport { useSelector } from \"react-redux\";\nimport { Link, useLocation } from \"react-router-dom\";\nimport UserMenu from \"../UserMenu\";\n\nconst Navbar = () => {\n    const path = useLocation().pathname;\n    const [navbarOpen, setNavbarOpen] = useState(false);\n    const { cart } = useSelector((state) => state.carts);\n    const { user } = useSelector((state) => state.auth);\n    \n    return (\n        <div className=\"h-[70px] bg-custom-gradient text-white z-50 flex items-center sticky top-0\">\n            <div className=\"lg:px-14 sm:px-8 px-4 w-full flex justify-between\">\n                <Link to=\"/\" className=\"flex items-center text-2xl font-bold\">\n                    <FaStore className=\"mr-2 text-3xl\" />\n                    <span className=\"font-[Poppins]\">E-Shop</span>\n                </Link>\n\n            <ul className={`flex sm:gap-10 gap-4 sm:items-center  text-slate-800 sm:static absolute left-0 top-[70px] sm:shadow-none shadow-md ${\n            navbarOpen ? \"h-fit sm:pb-0 pb-5\" : \"h-0 overflow-hidden\"\n          }  transition-all duration-100 sm:h-fit sm:bg-none bg-custom-gradient   text-white sm:w-fit w-full sm:flex-row flex-col px-4 sm:px-0`}>\n                <li className=\"font-medium transition-all duration-150\">\n                   <Link className={`${\n                    path === \"/\" ? \"text-white font-semibold\" : \"text-gray-200\"\n                   }`}\n                    to=\"/\">\n                        Home\n                   </Link> \n                </li>\n\n                <li className=\"font-medium transition-all duration-150\">\n                   <Link className={`${\n                    path === \"/products\" ? \"text-white font-semibold\" : \"text-gray-200\"\n                   }`}\n                    to=\"/products\">\n                        Products\n                   </Link> \n                </li>\n\n\n                <li className=\"font-medium transition-all duration-150\">\n                   <Link className={`${\n                    path === \"/about\" ? \"text-white font-semibold\" : \"text-gray-200\"\n                   }`}\n                    to=\"/about\">\n                        About\n                   </Link> \n                </li>\n\n                <li className=\"font-medium transition-all duration-150\">\n                   <Link className={`${\n                    path === \"/contact\" ? \"text-white font-semibold\" : \"text-gray-200\"\n                   }`}\n                    to=\"/contact\">\n                        Contact\n                   </Link> \n                </li>\n\n                <li className=\"font-medium transition-all duration-150\">\n                   <Link className={`${\n                    path === \"/cart\" ? \"text-white font-semibold\" : \"text-gray-200\"\n                   }`}\n                    to=\"/cart\">\n                        <Badge\n                            showZero\n                            badgeContent={cart?.length || 0}\n                            color=\"primary\"\n                            overlap=\"circular\"\n                            anchorOrigin={{ vertical: 'top', horizontal: 'right', }}>\n                                <FaShoppingCart size={25} />\n                        </Badge>\n                   </Link> \n                </li>\n\n                {(user && user.id) ? (\n                    <li className=\"font-medium transition-all duration-150\">\n                        <UserMenu />\n                    </li>\n                ) : (\n                <li className=\"font-medium transition-all duration-150\">\n                   <Link className=\"flex items-center space-x-2 px-4 py-[6px] \n                            bg-linear-to-r from-purple-600 to-red-500 \n                            text-white font-semibold rounded-md shadow-lg \n                            hover:from-purple-500 hover:to-red-400 transition \n                            duration-300 ease-in-out transform \"\n                    to=\"/login\">\n                        <FaSignInAlt />\n                        <span>Login</span>\n                   </Link> \n                </li>\n                )}\n            </ul>\n\n            <button\n                onClick={() => setNavbarOpen(!navbarOpen)}\n                className=\"sm:hidden flex items-center sm:mt-0 mt-2\">\n                    {navbarOpen ? (\n                        <RxCross2 className=\"text-white text-3xl\" />\n                    ) : (\n                        <IoIosMenu className=\"text-white text-3xl\" />\n                    )}\n            </button>\n            </div>\n        </div>\n    )\n}\n\nexport default Navbar;"
  },
  {
    "path": "ecom-frontend/src/components/shared/Paginations.jsx",
    "content": "import { Pagination } from \"@mui/material\";\nimport { useLocation, useNavigate, useSearchParams } from \"react-router-dom\";\n\nconst Paginations = ({ numberOfPage, totalProducts }) => {\n    const [searchParams] = useSearchParams();\n    const pathname = useLocation().pathname;\n    const params = new URLSearchParams(searchParams);\n    const navigate = useNavigate();\n    const paramValue = searchParams.get(\"page\")\n                ? Number(searchParams.get(\"page\"))\n                : 1;\n\n    const onChangeHandler = (event, value) => {\n        params.set(\"page\", value.toString());\n        navigate(`${pathname}?${params}`);\n    };\n\n    return(\n        <Pagination \n            count={numberOfPage} \n            page={paramValue}\n            defaultPage={1} \n            siblingCount={0} \n            boundaryCount={2} \n            shape=\"rounded\" \n            onChange = {onChangeHandler}\n            />\n    )\n};\n\nexport default Paginations;"
  },
  {
    "path": "ecom-frontend/src/components/shared/ProductCard.jsx",
    "content": "import { useState } from \"react\";\nimport { FaShoppingCart } from \"react-icons/fa\";\nimport ProductViewModal from \"./ProductViewModal\";\nimport truncateText from \"../../utils/truncateText\";\nimport { useDispatch } from \"react-redux\";\nimport { addToCart } from \"../../store/actions\";\nimport toast from \"react-hot-toast\";\n\nconst ProductCard = ({\n        productId,\n        productName,\n        image,\n        description,\n        quantity,\n        price,\n        discount,\n        specialPrice,\n        about = false,\n}) => {\n    const [openProductViewModal, setOpenProductViewModal] = useState(false);\n    const btnLoader = false;\n    const [selectedViewProduct, setSelectedViewProduct] = useState(\"\");\n    const isAvailable = quantity && Number(quantity) > 0;\n    const dispatch = useDispatch();\n\n    const handleProductView = (product) => {\n        if (!about) {\n            setSelectedViewProduct(product);\n            setOpenProductViewModal(true);\n        }\n    };\n\n    const addToCartHandler = (cartItems) => {\n        dispatch(addToCart(cartItems, 1, toast));\n    };\n\n    return (\n        <div className=\"border rounded-lg shadow-xl overflow-hidden transition-shadow duration-300\">\n            <div onClick={() => {\n                handleProductView({\n                    id: productId,\n                    productName,\n                    image,\n                    description,\n                    quantity,\n                    price,\n                    discount,\n                    specialPrice,\n                })\n            }} \n                    className=\"w-full overflow-hidden aspect-3/2\">\n                <img \n                className=\"w-full h-full cursor-pointer transition-transform duration-300 transform hover:scale-105\"\n                src={image}\n                alt={productName}>\n                </img>\n            </div>\n            <div className=\"p-4\">\n                <h2 onClick={() => {\n                handleProductView({\n                    id: productId,\n                    productName,\n                    image,\n                    description,\n                    quantity,\n                    price,\n                    discount,\n                    specialPrice,\n                })\n            }}\n                    className=\"text-lg font-semibold mb-2 cursor-pointer\">\n                    {truncateText(productName, 50)}\n                </h2>\n                \n                <div className=\"min-h-20 max-h-20\">\n                    <p className=\"text-gray-600 text-sm\">\n                        {truncateText(description, 80)}\n                    </p>\n                </div>\n\n            { !about && (\n                <div className=\"flex items-center justify-between\">\n                {specialPrice ? (\n                    <div className=\"flex flex-col\">\n                        <span className=\"text-gray-400 line-through\">\n                            ${Number(price).toFixed(2)}\n                        </span>\n                        <span className=\"text-xl font-bold text-slate-700\">\n                            ${Number(specialPrice).toFixed(2)}\n                        </span>\n                    </div>\n                ) : (\n                    <span className=\"text-xl font-bold text-slate-700\">\n                        {\"  \"}\n                        ${Number(price).toFixed(2)}\n                    </span>\n                )}\n\n                <button\n                    disabled={!isAvailable || btnLoader}\n                    onClick={() => addToCartHandler({\n                        image,\n                        productName,\n                        description,\n                        specialPrice,\n                        price,\n                        productId,\n                        quantity,\n                    })}\n                    className={`bg-blue-500 ${isAvailable ? \"opacity-100 hover:bg-blue-600\" : \"opacity-70\"}\n                        text-white py-2 px-3 rounded-lg items-center transition-colors duration-300 w-36 flex justify-center`}>\n                    <FaShoppingCart className=\"mr-2\"/>\n                    {isAvailable ? \"Add to Cart\" : \"Stock Out\"}\n                </button>\n                </div>\n            )}\n                \n            </div>\n            <ProductViewModal \n                open={openProductViewModal}\n                setOpen={setOpenProductViewModal}\n                product={selectedViewProduct}\n                isAvailable={isAvailable}\n            />\n        </div>\n    )\n}\n\nexport default ProductCard;"
  },
  {
    "path": "ecom-frontend/src/components/shared/ProductViewModal.jsx",
    "content": "import { Button, Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react'\nimport { Divider } from '@mui/material';\nimport { useState } from 'react'\nimport Status from './Status';\nimport { MdClose, MdDone } from 'react-icons/md';\n\nfunction ProductViewModal({open, setOpen, product, isAvailable}) {\n  \n  const {id, productName, image, description, quantity, price, discount, specialPrice} = product;\n  const handleClickOpen = () => {\n    setOpen(true);\n  }\n\n  return (\n    <>\n      <Dialog open={open} as=\"div\" className=\"relative z-10\" onClose={close}>\n      <DialogBackdrop className=\"fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity\" />\n        <div className=\"fixed inset-0 z-10 w-screen overflow-y-auto\">\n          <div className=\"flex min-h-full items-center justify-center p-4\">\n            <DialogPanel\n              transition\n              className=\"relative transform overflow-hidden rounded-lg bg-white shadow-xl transition-all md:max-w-[620px] md:min-w-[620px] w-full\"\n            >\n                {image && (\n                    <div className='flex justify-center aspect-3/2'>\n                    <img \n                    src={image}\n                    alt={productName} />\n                    </div>\n                )}\n\n\n\n                <div className='px-6 pt-10 pb-2'>\n                <DialogTitle as=\"h1\" className=\"lg:text-3xl sm:text-2xl text-xl font-semibold leading-6 text-gray-800 mb-4\">\n                {productName}\n              </DialogTitle>\n\n\n              <div className=\"space-y-2 text-gray-700 pb-4\">\n                <div className=\"flex items-center justify-between gap-2\">\n                  {specialPrice ? (\n                    <div className=\"flex items-center gap-2\">\n                      <span className=\"text-gray-400 line-through\">\n                        ${Number(price).toFixed(2)}\n                      </span>\n                      <span className=\"sm:text-xl font-semibold text-slate-700\">\n                        ${Number(specialPrice).toFixed(2)}\n                      </span>\n                    </div>\n                  ) : (\n                    <span className=\"text-xl font-bold\">\n                      {\" \"}\n                      ${Number(price).toFixed(2)}\n                    </span>\n                  )}\n\n                  {isAvailable ? (\n                    <Status\n                      text=\"In Stock\"\n                      icon={MdDone}\n                      bg=\"bg-teal-200\"\n                      color=\"text-teal-900\"\n                    />\n                  ) : (\n                    <Status\n                      text=\"Out-Of-Stock\"\n                      icon={MdClose}\n                      bg=\"bg-rose-200\"\n                      color=\"text-rose-700\"\n                    />\n                  )}\n                </div>\n\n                <Divider />\n\n                <p>{description}</p>\n              </div>\n                </div>\n\n\n            <div className=\"px-6 py-4 flex justify-end gap-4\">\n              <button\n                onClick={() => setOpen(false)}\n                type=\"button\"\n                className=\"px-4 py-2 text-sm font-semibold text-slate-700 border border-slate-700 hover:text-slate-800 hover:border-slate-800 rounded-md \"\n              >\n                Close\n              </button>\n            </div>\n            </DialogPanel>\n          </div>\n        </div>\n      </Dialog>\n    </>\n  )\n}\n\nexport default ProductViewModal;"
  },
  {
    "path": "ecom-frontend/src/components/shared/SelectTextField.jsx",
    "content": "import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from \"@headlessui/react\";\nimport { FaCheck } from \"react-icons/fa\";\n\nconst SelectTextField = ({\n    label,\n    select,\n    setSelect,\n    lists\n}) => {\n    return (\n        <Listbox value={select} onChange={setSelect}>\n        <div className=\"flex flex-col gap-2 w-full\">\n            <label\n                htmlFor=\"id\"\n                className=\"font-semibold text-sm text-slate-800\">\n                {label}\n            </label>\n        \n            <div className=\"relative\">\n                <ListboxButton \n                className={`relative text-sm py-2 rounded-md border border-slate-700  w-full cursor-default  bg-white  text-left text-gray-600 sm:text-sm sm:leading-6`}>\n                    <span className=\"block truncate ps-2\">{select?.categoryName}</span>\n                </ListboxButton>\n                <ListboxOptions\n                    transition\n                    className=\"absolute z-10 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-opacity-5 ring-black focus:outline-hidden\">\n                    {lists?.map((category) => (\n                    <ListboxOption key={category.categoryId} value={category} \n                    className=\"group relative cursor-default py-2 pl-3 pr-9 text-gray-900 data-focus:bg-indigo-600 data-focus:text-white\">\n                        <span className=\"block truncate font-semibold group-data-selected:font-semibold\">\n                            {category.categoryName}\n                        </span>\n\n                        <span className=\"absolute inset-y-0 right-0 flex items-center pr-4 text-indigo-600 group-data-focus:text-white [.group:not([data-selected])_&]:hidden\">\n                            <FaCheck className=\"text-xl\"/>\n                        </span>\n                        \n                    </ListboxOption>\n                    ))}\n                </ListboxOptions>\n            </div>\n        </div>\n        </Listbox>\n    );\n};\n\nexport default SelectTextField;"
  },
  {
    "path": "ecom-frontend/src/components/shared/Sidebar.jsx",
    "content": "import React from 'react'\nimport { FaTachometerAlt } from 'react-icons/fa';\nimport { useSelector } from 'react-redux';\nimport { Link, useLocation } from 'react-router-dom'\nimport { adminNavigation, sellerNavigation } from '../../utils';\nimport classNames from 'classnames';\n\nconst Sidebar = ({isProfileLayout = false}) => {\n    const pathName = useLocation().pathname;\n    const { user } = useSelector((state) => state.auth);\n\n    const isAdmin = user && user?.roles?.includes(\"ROLE_ADMIN\");\n\n    const sideBarLayout = isAdmin ? adminNavigation : sellerNavigation;\n    \n  return (\n    <div className='flex grow flex-col gap-y-7 overflow-y-auto bg-custom-gradient px-6 pb-4'>\n        <div className='flex h-16 shrink-0 gap-x-3 pt-2'>\n            <FaTachometerAlt className='h-8 w-8 text-indigo-500'/>\n            <h1 className='text-white text-xl font-bold'>\n                {isAdmin ? \"Admin Panel\" : \"Seller Panel\"}\n            </h1>\n        </div>\n        <nav className='flex flex-1 flex-col'>\n            <ul role='list' className='flex flex-1 flex-col gap-y-7'>\n                <li>\n                    <ul role='list' className='-mx-2 space-y-4'>\n                        {sideBarLayout.map((item) => (\n                            <li key={item.name}>\n                                <Link\n                                    to={item.href}\n                                    className={classNames(\n                                        pathName === item.href\n                                            ? \"bg-custom-blue text-white\"\n                                            : \"text-gray-400 hover:bg-gray-800 hover:text-white\",\n                                        \"group flex gap-x-3 rounded-md p-2 text-sm font-semibold leading-6\"\n                                    )}>\n\n                                        <item.icon className='text-2xl'/>\n                                        {item.name}\n                                </Link>\n                            </li>\n                        ))}\n                    </ul>\n                </li>\n            </ul>\n        </nav>\n    </div>\n  )\n}\n\nexport default Sidebar"
  },
  {
    "path": "ecom-frontend/src/components/shared/Skeleton.jsx",
    "content": "import React from \"react\";\n\nconst Skeleton = () => {\n  return (\n    <div role=\"status\" className=\"space-y-2.5 animate-pulse w-full\">\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 w-32\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-24\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-24\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-200 rounded-full dark:bg-gray-700 w-80\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 ms-2 bg-gray-200 rounded-full dark:bg-gray-700 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-24\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-32\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-24\" />\n        <div className=\"h-2.5 ms-2 bg-gray-200 rounded-full dark:bg-gray-700 flex-1\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-200 rounded-full dark:bg-gray-700 w-80\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 w-32\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-24\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-24\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-200 rounded-full dark:bg-gray-700 w-80\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 ms-2 bg-gray-200 rounded-full dark:bg-gray-700 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-24\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-32\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 w-24\" />\n        <div className=\"h-2.5 ms-2 bg-gray-200 rounded-full dark:bg-gray-700 flex-1\" />\n      </div>\n      <div className=\"flex items-center w-full\">\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n        <div className=\"h-2.5 ms-2 bg-gray-200 rounded-full dark:bg-gray-700 w-80\" />\n        <div className=\"h-2.5 ms-2 bg-gray-300 rounded-full dark:bg-gray-600 flex-1\" />\n      </div>\n    </div>\n  );\n};\n\nexport default Skeleton;"
  },
  {
    "path": "ecom-frontend/src/components/shared/Spinners.jsx",
    "content": "import React from 'react'\n\nconst Spinners = () => {\n  return (\n<div role=\"status\">\n    <svg aria-hidden=\"true\" class=\"w-5 h-5 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600\" viewBox=\"0 0 100 101\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n        <path d=\"M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z\" fill=\"currentColor\"/>\n        <path d=\"M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z\" fill=\"currentFill\"/>\n    </svg>\n</div>\n\n  )\n}\n\nexport default Spinners;"
  },
  {
    "path": "ecom-frontend/src/components/shared/Status.jsx",
    "content": "const Status = ({text, icon:Icon, bg, color}) => {\n    return (\n        <div\n            className={`${bg} ${color} px-2 py-2 font-medium rounded-sm flex items-center gap-1`}>\n            {text} <Icon size={15} />\n        </div>\n    )\n};\n\nexport default Status;"
  },
  {
    "path": "ecom-frontend/src/hooks/useCategoryFilter.js",
    "content": "import { useEffect } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport { useDispatch } from \"react-redux\";\n\nimport { fetchCategories } from \"../store/actions\";\n\nconst useCategoryFilter = () => {\n  const [searchParams] = useSearchParams(); // Access search params from the URL\n  const dispatch = useDispatch(); // Get the dispatch function to call actions\n\n  useEffect(() => {\n    const params = new URLSearchParams(); // Create new URLSearchParams object\n\n    // Get current page from URL search params, defaulting to 1 if not present\n    const currentPage = searchParams.get(\"page\")\n      ? Number(searchParams.get(\"page\"))\n      : 1;\n    params.set(\"pageNumber\", currentPage - 1); // Pagination starts from 0 for API\n\n    // Convert params to a query string\n    const queryString = params.toString();\n\n    // Dispatch action to fetch categories using the constructed query string\n    dispatch(fetchCategories(queryString));\n  }, [dispatch, searchParams]);\n};\n\nexport default useCategoryFilter;"
  },
  {
    "path": "ecom-frontend/src/hooks/useOrderFilter.js",
    "content": "import { useEffect } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useSearchParams } from \"react-router-dom\";\nimport { getOrdersForDashboard } from \"../store/actions\";\n\nconst useOrderFilter = () => {\n    const [searchParams] = useSearchParams();\n    const dispatch = useDispatch();\n\n    const { user } = useSelector((state) => state.auth);\n    const isAdmin = user && user?.roles?.includes(\"ROLE_ADMIN\");\n\n    useEffect(() => {\n        const params = new URLSearchParams();\n\n        const currentPage = searchParams.get(\"page\")\n            ? Number(searchParams.get(\"page\"))\n            : 1;\n\n        params.set(\"pageNumber\", currentPage - 1);\n\n        const queryString = params.toString();\n        console.log(\"QUERY STRING\", queryString);\n        \n        dispatch(getOrdersForDashboard(queryString, isAdmin));\n\n    }, [dispatch, searchParams]);\n};\n\nexport default useOrderFilter;"
  },
  {
    "path": "ecom-frontend/src/hooks/useProductFilter.js",
    "content": "import { useEffect } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useSearchParams } from \"react-router-dom\";\nimport { dashboardProductsAction, fetchProducts } from \"../store/actions\";\n\nconst useProductFilter = () => {\n    const [searchParams] = useSearchParams();\n    const dispatch = useDispatch();\n\n    useEffect(() => {\n        const params = new URLSearchParams();\n\n        const currentPage = searchParams.get(\"page\")\n            ? Number(searchParams.get(\"page\"))\n            : 1;\n\n        params.set(\"pageNumber\", currentPage - 1);\n\n        const sortOrder = searchParams.get(\"sortby\") || \"asc\";\n        const categoryParams = searchParams.get(\"category\") || null;\n        const keyword = searchParams.get(\"keyword\") || null;\n        params.set(\"sortBy\",\"price\");\n        params.set(\"sortOrder\", sortOrder);\n\n        if (categoryParams) {\n            params.set(\"category\", categoryParams);\n        }\n\n        if (keyword) {\n            params.set(\"keyword\", keyword);\n        }\n\n        const queryString = params.toString();\n        console.log(\"QUERY STRING\", queryString);\n        \n        dispatch(fetchProducts(queryString));\n\n    }, [dispatch, searchParams]);\n};\n\n\nexport const useDashboardProductFilter = () => {\n\n    const { user } = useSelector((state) => state.auth);\n    const isAdmin = user && user?.roles?.includes(\"ROLE_ADMIN\");\n\n    const [searchParams] = useSearchParams();\n    const dispatch = useDispatch();\n\n    useEffect(() => {\n        const params = new URLSearchParams();\n\n        const currentPage = searchParams.get(\"page\")\n            ? Number(searchParams.get(\"page\"))\n            : 1;\n\n        params.set(\"pageNumber\", currentPage - 1);\n\n        const queryString = params.toString();\n        dispatch(dashboardProductsAction(queryString, isAdmin));\n\n    }, [dispatch, searchParams]);\n};\n\nexport default useProductFilter;"
  },
  {
    "path": "ecom-frontend/src/index.css",
    "content": "@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap')\nlayer(base);\n\n@import 'tailwindcss';\n\n@theme {\n  --font-montserrat: Montserrat, sans-serif;\n\n  --shadow-custom: 0 0 15px rgba(0, 0, 0, 0.3);\n  --shadow-right: 10px 0px 10px -5px rgba(0, 0, 0, 0.3);\n\n  --color-custom-blue: rgba(28, 100, 242, 1);\n\n  --color-banner-color1: #fdc200;\n  --color-banner-color2: #ff2c2c;\n  --color-banner-color3: #21ad61;\n  --color-banner-color4: #723da6;\n\n  --background-image-custom-gradient: linear-gradient(\n    to right,\n    #111827,\n    #1f2937\n  );\n  --background-image-button-gradient: linear-gradient(\n    to right,\n    #7e22ce,\n    #ef4444\n  );\n  --background-image-custom-gradient2: linear-gradient(\n    135deg,\n    #f5f5f5,\n    #eae7dc\n  );\n}\n\n/*\n  The default border color has changed to `currentcolor` in Tailwind CSS v4,\n  so we've added these compatibility styles to make sure everything still\n  looks the same as it did with Tailwind CSS v3.\n\n  If we ever want to remove these styles, we need to add an explicit border\n  color utility to any element that depends on these defaults.\n*/\n@layer base {\n  *,\n  ::after,\n  ::before,\n  ::backdrop,\n  ::file-selector-button {\n    border-color: var(--color-gray-200, currentcolor);\n  }\n}"
  },
  {
    "path": "ecom-frontend/src/main.jsx",
    "content": "import { StrictMode } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport './index.css'\nimport App from './App.jsx'\nimport { Provider } from 'react-redux'\nimport store from './store/reducers/store.js'\n\ncreateRoot(document.getElementById('root')).render(\n  <Provider store={store}>\n        <App />\n  </Provider>,\n)\n"
  },
  {
    "path": "ecom-frontend/src/store/actions/index.js",
    "content": "import api from \"../../api/api\"\n\nexport const fetchProducts = (queryString) => async (dispatch) => {\n    try {\n        dispatch({ type: \"IS_FETCHING\" });\n        const { data } = await api.get(`/public/products?${queryString}`);\n        dispatch({\n            type: \"FETCH_PRODUCTS\",\n            payload: data.content,\n            pageNumber: data.pageNumber,\n            pageSize: data.pageSize,\n            totalElements: data.totalElements,\n            totalPages: data.totalPages,\n            lastPage: data.lastPage,\n        });\n        dispatch({ type: \"IS_SUCCESS\" });\n    } catch (error) {\n        console.log(error);\n        dispatch({ \n            type: \"IS_ERROR\",\n            payload: error?.response?.data?.message || \"Failed to fetch products\",\n         });\n    }\n};\n\n\nexport const fetchCategories = () => async (dispatch) => {\n    try {\n        dispatch({ type: \"CATEGORY_LOADER\" });\n        const { data } = await api.get(`/public/categories`);\n        dispatch({\n            type: \"FETCH_CATEGORIES\",\n            payload: data.content,\n            pageNumber: data.pageNumber,\n            pageSize: data.pageSize,\n            totalElements: data.totalElements,\n            totalPages: data.totalPages,\n            lastPage: data.lastPage,\n        });\n        dispatch({ type: \"IS_ERROR\" });\n    } catch (error) {\n        console.log(error);\n        dispatch({ \n            type: \"IS_ERROR\",\n            payload: error?.response?.data?.message || \"Failed to fetch categories\",\n         });\n    }\n};\n\n\nexport const addToCart = (data, qty = 1, toast) => \n    (dispatch, getState) => {\n        // Find the product\n        const { products } = getState().products;\n        const getProduct = products.find(\n            (item) => item.productId === data.productId\n        );\n\n        // Check for stocks\n        const isQuantityExist = getProduct.quantity >= qty;\n\n        // If in stock -> add\n        if (isQuantityExist) {\n            dispatch({ type: \"ADD_CART\", payload: {...data, quantity: qty}});\n            toast.success(`${data?.productName} added to the cart`);\n            localStorage.setItem(\"cartItems\", JSON.stringify(getState().carts.cart));\n        } else {\n            // error\n            toast.error(\"Out of stock\");\n        }\n};\n\n\nexport const increaseCartQuantity = \n    (data, toast, currentQuantity, setCurrentQuantity) =>\n    (dispatch, getState) => {\n        // Find the product\n        const { products } = getState().products;\n        \n        const getProduct = products.find(\n            (item) => item.productId === data.productId\n        );\n\n        const isQuantityExist = getProduct.quantity >= currentQuantity + 1;\n\n        if (isQuantityExist) {\n            const newQuantity = currentQuantity + 1;\n            setCurrentQuantity(newQuantity);\n\n            dispatch({\n                type: \"ADD_CART\",\n                payload: {...data, quantity: newQuantity + 1 },\n            });\n            localStorage.setItem(\"cartItems\", JSON.stringify(getState().carts.cart));\n        } else {\n            toast.error(\"Quantity Reached to Limit\");\n        }\n\n    };\n\n\n\nexport const decreaseCartQuantity = \n    (data, newQuantity) => (dispatch, getState) => {\n        dispatch({\n            type: \"ADD_CART\",\n            payload: {...data, quantity: newQuantity},\n        });\n        localStorage.setItem(\"cartItems\", JSON.stringify(getState().carts.cart));\n    }\n\nexport const removeFromCart =  (data, toast) => (dispatch, getState) => {\n    dispatch({type: \"REMOVE_CART\", payload: data });\n    toast.success(`${data.productName} removed from cart`);\n    localStorage.setItem(\"cartItems\", JSON.stringify(getState().carts.cart));\n}\n\n\n\nexport const authenticateSignInUser \n    = (sendData, toast, reset, navigate, setLoader) => async (dispatch) => {\n        try {\n            setLoader(true);\n            const { data } = await api.post(\"/auth/signin\", sendData);\n            dispatch({ type: \"LOGIN_USER\", payload: data });\n            localStorage.setItem(\"auth\", JSON.stringify(data));\n            reset();\n            toast.success(\"Login Success\");\n            navigate(\"/\");\n        } catch (error) {\n            console.log(error);\n            toast.error(error?.response?.data?.message || \"Internal Server Error\");\n        } finally {\n            setLoader(false);\n        }\n}\n\n\nexport const registerNewUser \n    = (sendData, toast, reset, navigate, setLoader) => async (dispatch) => {\n        try {\n            setLoader(true);\n            const { data } = await api.post(\"/auth/signup\", sendData);\n            reset();\n            toast.success(data?.message || \"User Registered Successfully\");\n            navigate(\"/login\");\n        } catch (error) {\n            console.log(error);\n            toast.error(error?.response?.data?.message || error?.response?.data?.password || \"Internal Server Error\");\n        } finally {\n            setLoader(false);\n        }\n};\n\n\nexport const logOutUser = (navigate) => (dispatch) => {\n    dispatch({ type:\"LOG_OUT\" });\n    localStorage.removeItem(\"auth\");\n    navigate(\"/login\");\n};\n\nexport const addUpdateUserAddress =\n     (sendData, toast, addressId, setOpenAddressModal) => async (dispatch, getState) => {\n    /*\n    const { user } = getState().auth;\n    await api.post(`/addresses`, sendData, {\n          headers: { Authorization: \"Bearer \" + user.jwtToken },\n        });\n    */\n    dispatch({ type:\"BUTTON_LOADER\" });\n    try {\n        if (!addressId) {\n            const { data } = await api.post(\"/addresses\", sendData);\n        } else {\n            await api.put(`/addresses/${addressId}`, sendData);\n        }\n        dispatch(getUserAddresses());\n        toast.success(\"Address saved successfully\");\n        dispatch({ type:\"IS_SUCCESS\" });\n    } catch (error) {\n        console.log(error);\n        toast.error(error?.response?.data?.message || \"Internal Server Error\");\n        dispatch({ type:\"IS_ERROR\", payload: null });\n    } finally {\n        setOpenAddressModal(false);\n    }\n};\n\n\nexport const deleteUserAddress = \n    (toast, addressId, setOpenDeleteModal) => async (dispatch, getState) => {\n    try {\n        dispatch({ type: \"BUTTON_LOADER\" });\n        await api.delete(`/addresses/${addressId}`);\n        dispatch({ type: \"IS_SUCCESS\" });\n        dispatch(getUserAddresses());\n        dispatch(clearCheckoutAddress());\n        toast.success(\"Address deleted successfully\");\n    } catch (error) {\n        console.log(error);\n        dispatch({ \n            type: \"IS_ERROR\",\n            payload: error?.response?.data?.message || \"Some Error Occured\",\n         });\n    } finally {\n        setOpenDeleteModal(false);\n    }\n};\n\nexport const clearCheckoutAddress = () => {\n    return {\n        type: \"REMOVE_CHECKOUT_ADDRESS\",\n    }\n};\n\nexport const getUserAddresses = () => async (dispatch, getState) => {\n    try {\n        dispatch({ type: \"IS_FETCHING\" });\n        const { data } = await api.get(`/addresses`);\n        dispatch({type: \"USER_ADDRESS\", payload: data});\n        dispatch({ type: \"IS_SUCCESS\" });\n    } catch (error) {\n        console.log(error);\n        dispatch({ \n            type: \"IS_ERROR\",\n            payload: error?.response?.data?.message || \"Failed to fetch user addresses\",\n         });\n    }\n};\n\nexport const selectUserCheckoutAddress = (address) => {\n    localStorage.setItem(\"CHECKOUT_ADDRESS\", JSON.stringify(address));\n    \n    return {\n        type: \"SELECT_CHECKOUT_ADDRESS\",\n        payload: address,\n    }\n};\n\n\nexport const addPaymentMethod = (method) => {\n    return {\n        type: \"ADD_PAYMENT_METHOD\",\n        payload: method,\n    }\n};\n\n\nexport const createUserCart = (sendCartItems) => async (dispatch, getState) => {\n    try {\n        dispatch({ type: \"IS_FETCHING\" });\n        await api.post('/cart/create', sendCartItems);\n        await dispatch(getUserCart());\n    } catch (error) {\n        console.log(error);\n        dispatch({ \n            type: \"IS_ERROR\",\n            payload: error?.response?.data?.message || \"Failed to create cart items\",\n         });\n    }\n};\n\n\nexport const getUserCart = () => async (dispatch, getState) => {\n    try {\n        dispatch({ type: \"IS_FETCHING\" });\n        const { data } = await api.get('/carts/users/cart');\n        \n        dispatch({\n            type: \"GET_USER_CART_PRODUCTS\",\n            payload: data.products,\n            totalPrice: data.totalPrice,\n            cartId: data.cartId\n        })\n        localStorage.setItem(\"cartItems\", JSON.stringify(getState().carts.cart));\n        dispatch({ type: \"IS_SUCCESS\" });\n    } catch (error) {\n        console.log(error);\n        dispatch({ \n            type: \"IS_ERROR\",\n            payload: error?.response?.data?.message || \"Failed to fetch cart items\",\n         });\n    }\n};\n\n\nexport const createStripePaymentSecret \n    = (sendData) => async (dispatch, getState) => {\n        try {\n            dispatch({ type: \"IS_FETCHING\" });\n            const { data } = await api.post(\"/order/stripe-client-secret\", sendData);\n            dispatch({ type: \"CLIENT_SECRET\", payload: data });\n              localStorage.setItem(\"client-secret\", JSON.stringify(data));\n              dispatch({ type: \"IS_SUCCESS\" });\n        } catch (error) {\n            console.log(error);\n            toast.error(error?.response?.data?.message || \"Failed to create client secret\");\n        }\n};\n\n\nexport const stripePaymentConfirmation \n    = (sendData, setErrorMesssage, setLoadng, toast) => async (dispatch, getState) => {\n        try {\n            const response  = await api.post(\"/order/users/payments/online\", sendData);\n            if (response.data) {\n                localStorage.removeItem(\"CHECKOUT_ADDRESS\");\n                localStorage.removeItem(\"cartItems\");\n                localStorage.removeItem(\"client-secret\");\n                dispatch({ type: \"REMOVE_CLIENT_SECRET_ADDRESS\"});\n                dispatch({ type: \"CLEAR_CART\"});\n                toast.success(\"Order Accepted\");\n              } else {\n                setErrorMesssage(\"Payment Failed. Please try again.\");\n              }\n        } catch (error) {\n            setErrorMesssage(\"Payment Failed. Please try again.\");\n        }\n};\n\nexport const analyticsAction = () => async (dispatch, getState) => {\n        try {\n            dispatch({ type: \"IS_FETCHING\"});\n            const { data } = await api.get('/admin/app/analytics');\n            dispatch({\n                type: \"FETCH_ANALYTICS\",\n                payload: data,\n            })\n            dispatch({ type: \"IS_SUCCESS\"});\n        } catch (error) {\n            dispatch({ \n                type: \"IS_ERROR\",\n                payload: error?.response?.data?.message || \"Failed to fetch analytics data\",\n            });\n        }\n};\n\nexport const getOrdersForDashboard = (queryString, isAdmin) => async (dispatch) => {\n    try {\n        dispatch({ type: \"IS_FETCHING\" });\n        const endpoint = isAdmin ? \"/admin/orders\" : \"/seller/orders\";\n        const { data } = await api.get(`${endpoint}?${queryString}`);\n        dispatch({\n            type: \"GET_ADMIN_ORDERS\",\n            payload: data.content,\n            pageNumber: data.pageNumber,\n            pageSize: data.pageSize,\n            totalElements: data.totalElements,\n            totalPages: data.totalPages,\n            lastPage: data.lastPage,\n        });\n        dispatch({ type: \"IS_SUCCESS\" });\n    } catch (error) {\n        console.log(error);\n        dispatch({ \n            type: \"IS_ERROR\",\n            payload: error?.response?.data?.message || \"Failed to fetch orders data\",\n         });\n    }\n};\n\n\n\nexport const updateOrderStatusFromDashboard =\n     (orderId, orderStatus, toast, setLoader, isAdmin) => async (dispatch, getState) => {\n    try {\n        setLoader(true);\n        const endpoint = isAdmin ? \"/admin/orders/\" : \"/seller/orders/\";\n        const { data } = await api.put(`${endpoint}${orderId}/status`, { status: orderStatus});\n        toast.success(data.message || \"Order updated successfully\");\n        await dispatch(getOrdersForDashboard());\n    } catch (error) {\n        console.log(error);\n        toast.error(error?.response?.data?.message || \"Internal Server Error\");\n    } finally {\n        setLoader(false)\n    }\n};\n\n\nexport const dashboardProductsAction = (queryString, isAdmin) => async (dispatch) => {\n    try {\n        dispatch({ type: \"IS_FETCHING\" });\n        const endpoint = isAdmin ? \"/admin/products\" : \"/seller/products\";\n        const { data } = await api.get(`${endpoint}?${queryString}`);\n        dispatch({\n            type: \"FETCH_PRODUCTS\",\n            payload: data.content,\n            pageNumber: data.pageNumber,\n            pageSize: data.pageSize,\n            totalElements: data.totalElements,\n            totalPages: data.totalPages,\n            lastPage: data.lastPage,\n        });\n        dispatch({ type: \"IS_SUCCESS\" });\n    } catch (error) {\n        console.log(error);\n        dispatch({ \n            type: \"IS_ERROR\",\n            payload: error?.response?.data?.message || \"Failed to fetch dashboard products\",\n         });\n    }\n};\n\n\nexport const updateProductFromDashboard = \n    (sendData, toast, reset, setLoader, setOpen, isAdmin) => async (dispatch) => {\n    try {\n        setLoader(true);\n        const endpoint = isAdmin ? \"/admin/products/\" : \"/seller/products/\";\n        await api.put(`${endpoint}${sendData.id}`, sendData);\n        toast.success(\"Product update successful\");\n        reset();\n        setLoader(false);\n        setOpen(false);\n        await dispatch(dashboardProductsAction());\n    } catch (error) {\n        toast.error(error?.response?.data?.description || \"Product update failed\");\n     \n    }\n};\n\n\n\nexport const addNewProductFromDashboard = \n    (sendData, toast, reset, setLoader, setOpen, isAdmin) => async(dispatch, getState) => {\n        try {\n            setLoader(true);\n            const endpoint = isAdmin ? \"/admin/categories/\" : \"/seller/categories/\";\n            await api.post(`${endpoint}${sendData.categoryId}/product`,\n                sendData\n            );\n            toast.success(\"Product created successfully\");\n            reset();\n            setOpen(false);\n            await dispatch(dashboardProductsAction());\n        } catch (error) {\n            console.error(err);\n            toast.error(err?.response?.data?.description || \"Product creation failed\");\n        } finally {\n            setLoader(false);\n        }\n    }\n\nexport const deleteProduct = \n    (setLoader, productId, toast, setOpenDeleteModal, isAdmin) => async (dispatch, getState) => {\n    try {\n        setLoader(true)\n        const endpoint = isAdmin ? \"/admin/products/\" : \"/seller/products/\";\n        await api.delete(`${endpoint}${productId}`);\n        toast.success(\"Product deleted successfully\");\n        setLoader(false);\n        setOpenDeleteModal(false);\n        await dispatch(dashboardProductsAction());\n    } catch (error) {\n        console.log(error);\n        toast.error(\n            error?.response?.data?.message || \"Some Error Occured\"\n        )\n    }\n};\n\n\nexport const updateProductImageFromDashboard = \n    (formData, productId, toast, setLoader, setOpen, isAdmin) => async (dispatch) => {\n    try {\n        setLoader(true);\n        const endpoint = isAdmin ? \"/admin/products/\" : \"/seller/products/\";\n        await api.put(`${endpoint}${productId}/image`, formData);\n        toast.success(\"Image upload successful\");\n        setLoader(false);\n        setOpen(false);\n        await dispatch(dashboardProductsAction());\n    } catch (error) {\n        toast.error(error?.response?.data?.description || \"Product Image upload failed\");\n     \n    }\n};\n\nexport const getAllCategoriesDashboard = (queryString) => async (dispatch) => {\n  dispatch({ type: \"CATEGORY_LOADER\" });\n  try {\n    const { data } = await api.get(`/public/categories?${queryString}`);\n    dispatch({\n      type: \"FETCH_CATEGORIES\",\n      payload: data[\"content\"],\n      pageNumber: data[\"pageNumber\"],\n      pageSize: data[\"pageSize\"],\n      totalElements: data[\"totalElements\"],\n      totalPages: data[\"totalPages\"],\n      lastPage: data[\"lastPage\"],\n    });\n\n    dispatch({ type: \"CATEGORY_SUCCESS\" });\n  } catch (err) {\n    console.log(err);\n\n    dispatch({\n      type: \"IS_ERROR\",\n      payload: err?.response?.data?.message || \"Failed to fetch categories\",\n    });\n  }\n};\n\nexport const createCategoryDashboardAction =\n  (sendData, setOpen, reset, toast) => async (dispatch, getState) => {\n    try {\n      dispatch({ type: \"CATEGORY_LOADER\" });\n      await api.post(\"/admin/categories\", sendData);\n      dispatch({ type: \"CATEGORY_SUCCESS\" });\n      reset();\n      toast.success(\"Category Created Successful\");\n      setOpen(false);\n      await dispatch(getAllCategoriesDashboard());\n    } catch (err) {\n      console.log(err);\n      toast.error(\n        err?.response?.data?.categoryName || \"Failed to create new category\"\n      );\n\n      dispatch({\n        type: \"IS_ERROR\",\n        payload: err?.response?.data?.message || \"Internal Server Error\",\n      });\n    }\n  };\n\nexport const updateCategoryDashboardAction =\n  (sendData, setOpen, categoryID, reset, toast) =>\n  async (dispatch, getState) => {\n    try {\n      dispatch({ type: \"CATEGORY_LOADER\" });\n\n      await api.put(`/admin/categories/${categoryID}`, sendData);\n\n      dispatch({ type: \"CATEGORY_SUCCESS\" });\n\n      reset();\n      toast.success(\"Category Update Successful\");\n      setOpen(false);\n      await dispatch(getAllCategoriesDashboard());\n    } catch (err) {\n      console.log(err);\n      toast.error(\n        err?.response?.data?.categoryName || \"Failed to update category\"\n      );\n\n      dispatch({\n        type: \"IS_ERROR\",\n        payload: err?.response?.data?.message || \"Internal Server Error\",\n      });\n    }\n  };\n\nexport const deleteCategoryDashboardAction =\n  (setOpen, categoryID, toast) => async (dispatch, getState) => {\n    try {\n      dispatch({ type: \"CATEGORY_LOADER\" });\n\n      await api.delete(`/admin/categories/${categoryID}`);\n\n      dispatch({ type: \"CATEGORY_SUCCESS\" });\n\n      toast.success(\"Category Delete Successful\");\n      setOpen(false);\n      await dispatch(getAllCategoriesDashboard());\n    } catch (err) {\n      console.log(err);\n      toast.error(err?.response?.data?.message || \"Failed to delete category\");\n      dispatch({\n        type: \"IS_ERROR\",\n        payload: err?.response?.data?.message || \"Internal Server Error\",\n      });\n    }\n  };\n\n\n  export const getAllSellersDashboard =\n  (queryString) => async (dispatch, getState) => {\n    const { user } = getState().auth;\n    try {\n      dispatch({ type: \"IS_FETCHING\" });\n      const { data } = await api.get(`/auth/sellers?${queryString}`);\n      dispatch({\n        type: \"GET_SELLERS\",\n        payload: data[\"content\"],\n        pageNumber: data[\"pageNumber\"],\n        pageSize: data[\"pageSize\"],\n        totalElements: data[\"totalElements\"],\n        totalPages: data[\"totalPages\"],\n        lastPage: data[\"lastPage\"],\n      });\n\n      dispatch({ type: \"IS_SUCCESS\" });\n    } catch (err) {\n      console.log(err);\n      dispatch({\n        type: \"IS_ERROR\",\n        payload: err?.response?.data?.message || \"Failed to fetch sellers data\",\n      });\n    }\n  };\n\nexport const addNewDashboardSeller =\n  (sendData, toast, reset, setOpen, setLoader) => async (dispatch) => {\n    try {\n      setLoader(true);\n      await api.post(\"/auth/signup\", sendData);\n      reset();\n      toast.success(\"Seller registered successfully!\");\n\n      await dispatch(getAllSellersDashboard());\n    } catch (err) {\n      console.log(err);\n      toast.error(\n        err?.response?.data?.message ||\n          err?.response?.data?.password ||\n          \"Internal Server Error\"\n      );\n    } finally {\n      setLoader(false);\n      setOpen(false);\n    }\n  };"
  },
  {
    "path": "ecom-frontend/src/store/reducers/ProductReducer.js",
    "content": "const initialState = {\n    products: null,\n    categories: null,\n    pagination: {},\n};\n\nexport const productReducer = (state = initialState, action) => {\n    switch (action.type) {\n        case \"FETCH_PRODUCTS\":\n            return {\n                ...state,\n                products: action.payload,\n                pagination: {\n                    ...state.pagination,\n                    pageNumber: action.pageNumber,\n                    pageSize: action.pageSize,\n                    totalElements: action.totalElements,\n                    totalPages: action.totalPages,\n                    lastPage: action.lastPage,\n                },\n            };\n\n        case \"FETCH_PRODUCTS\":\n            return {\n                ...state,\n                products: action.payload,\n                pagination: {\n                    ...state.pagination,\n                    pageNumber: action.pageNumber,\n                    pageSize: action.pageSize,\n                    totalElements: action.totalElements,\n                    totalPages: action.totalPages,\n                    lastPage: action.lastPage,\n                },\n            };\n    \n        case \"FETCH_CATEGORIES\":\n            return {\n                ...state,\n                categories: action.payload,\n                pagination: {\n                    ...state.pagination,\n                    pageNumber: action.pageNumber,\n                    pageSize: action.pageSize,\n                    totalElements: action.totalElements,\n                    totalPages: action.totalPages,\n                    lastPage: action.lastPage,\n                },\n            };\n        \n    \n        default:\n            return state;\n    }\n};"
  },
  {
    "path": "ecom-frontend/src/store/reducers/adminReducer.js",
    "content": "const initialState = {\n    analytics: {},\n};\n\nexport const adminReducer = (state = initialState, action) => {\n    switch (action.type) {\n        case \"FETCH_ANALYTICS\":\n            return {\n                ...state,\n                analytics: action.payload,\n            };\n            \n        default:\n            return state;\n    }\n};\n\n"
  },
  {
    "path": "ecom-frontend/src/store/reducers/authReducer.js",
    "content": "const initialState = {\n    user: null,\n    address: [],\n    clientSecret: null,\n    selectedUserCheckoutAddress: null,\n}\n\nexport const authReducer = (state = initialState, action) => {\n    switch (action.type) {\n        case \"LOGIN_USER\":\n            return { ...state, user: action.payload };\n        case \"USER_ADDRESS\":\n            return { ...state, address: action.payload };\n        case \"SELECT_CHECKOUT_ADDRESS\":\n            return { ...state, selectedUserCheckoutAddress: action.payload };\n        case \"REMOVE_CHECKOUT_ADDRESS\":\n            return { ...state, selectedUserCheckoutAddress: null };\n        case \"CLIENT_SECRET\":\n            return { ...state, clientSecret: action.payload };\n        case \"REMOVE_CLIENT_SECRET_ADDRESS\":\n            return { ...state, clientSecret: null, selectedUserCheckoutAddress: null };\n        case \"LOG_OUT\":\n            return { \n                user: null,\n                address: null,\n             };\n             \n        default:\n            return state;\n    }\n};"
  },
  {
    "path": "ecom-frontend/src/store/reducers/cartReducer.js",
    "content": "const initialState = {\n    cart: [],\n    totalPrice: 0,\n    cartId: null,\n}\n\nexport const cartReducer = (state = initialState, action) => {\n    switch (action.type) {\n        case \"ADD_CART\":\n            const productToAdd = action.payload;\n            const existingProduct = state.cart.find(\n                (item) => item.productId === productToAdd.productId\n            );\n\n            if(existingProduct) {\n                const updatedCart = state.cart.map((item) => {\n                    if (item.productId === productToAdd.productId) {\n                        return productToAdd;\n                    } else {\n                        return item;\n                    }\n                });\n\n                return {\n                    ...state,\n                    cart: updatedCart,\n                };\n            } else {\n                const newCart = [...state.cart, productToAdd];\n                return {\n                    ...state,\n                    cart: newCart,\n                };\n            }\n        case \"REMOVE_CART\":\n            return {\n                ...state,\n                cart: state.cart.filter(\n                    (item) => item.productId !== action.payload.productId\n                ),\n            };\n        case \"GET_USER_CART_PRODUCTS\":\n            return {\n                ...state,\n                cart: action.payload,\n                totalPrice: action.totalPrice,\n                cartId: action.cartId,\n            };\n        case \"CLEAR_CART\":\n            return { cart:[], totalPrice: 0, cartId: null};\n        default:\n            return state;\n    }\n    return state;\n}"
  },
  {
    "path": "ecom-frontend/src/store/reducers/errorReducer.js",
    "content": "const initialState = {\n    isLoading: false,\n    errorMessage: null,\n    categoryLoader: false,\n    categoryError: null,\n    btnLoader: false,\n};\n\nexport const errorReducer = (state = initialState, action) => {\n    switch (action.type) {\n        case \"IS_FETCHING\":\n            return {\n                ...state,\n                isLoading: true,\n                errorMessage: null,\n            };\n        case \"BUTTON_LOADER\":\n            return {\n                    ...state,\n                    btnLoader: true,\n                    errorMessage: null,\n                    categoryError: null,\n                };\n        case \"IS_SUCCESS\":\n            return {\n                ...state,\n                isLoading: false,\n                errorMessage: null,\n                btnLoader: false,\n                categoryError: null,\n                categoryLoader: false,\n            };\n        case \"IS_ERROR\":\n            return {\n                ...state,\n                isLoading: false,\n                errorMessage: action.payload,\n                btnLoader: false,\n                categoryLoader: false,\n            }\n        case \"CATEGORY_SUCCESS\":\n            return {\n                ...state,\n                categoryLoader: false,\n                categoryError: null,\n            };\n        case \"CATEGORY_LOADER\":\n            return {\n                ...state,\n                categoryLoader: true,\n                categoryError: null,\n                errorMessage: null,\n            }\n\n        default:\n            return state;\n    }  \n};"
  },
  {
    "path": "ecom-frontend/src/store/reducers/orderReducer.js",
    "content": "const initialState = {\n    adminOrder: null,\n    pagination: {},\n};\n\nexport const orderReducer = (state = initialState, action) => {\n    switch (action.type) {\n        case \"GET_ADMIN_ORDERS\":\n            return {\n                ...state,\n                adminOrder: action.payload,\n                pagination: {\n                    ...state.pagination,\n                    pageNumber: action.pageNumber,\n                    pageSize: action.pageSize,\n                    totalElements: action.totalElements,\n                    totalPages: action.totalPages,\n                    lastPage: action.lastPage,\n                },\n            };\n        default:\n            return state;\n    }\n};"
  },
  {
    "path": "ecom-frontend/src/store/reducers/paymentMethodReducer.js",
    "content": "const initialState = {\n    paymentMethod: null,\n};\n\nexport const paymentMethodReducer = (state = initialState, action) => {\n    switch (action.type) {\n        case \"ADD_PAYMENT_METHOD\":\n            return {\n                ...state,\n                paymentMethod: action.payload,\n            };\n        default:\n            return state;\n    }\n};"
  },
  {
    "path": "ecom-frontend/src/store/reducers/sellerReducer.js",
    "content": "const initialState = {\n  sellers: null,\n  pagination: {},\n};\n\nexport const sellerReducer = (state = initialState, action) => {\n  switch (action.type) {\n    case \"GET_SELLERS\":\n      return {\n        ...state,\n        sellers: action.payload,\n        pagination: {\n          ...state.pagination,\n          pageNumber: action.pageNumber,\n          pageSize: action.pageSize,\n          totalElements: action.totalElements,\n          totalPages: action.totalPages,\n          lastPage: action.lastPage,\n        },\n      };\n    default:\n      return state;\n  }\n};"
  },
  {
    "path": "ecom-frontend/src/store/reducers/store.js",
    "content": "import { configureStore } from \"@reduxjs/toolkit\";\nimport { productReducer } from \"./ProductReducer\";\nimport { errorReducer } from \"./errorReducer\";\nimport { cartReducer } from \"./cartReducer\";\nimport { authReducer } from \"./authReducer\";\nimport { paymentMethodReducer } from \"./paymentMethodReducer\";\nimport { adminReducer } from \"./adminReducer\";\nimport { orderReducer } from \"./orderReducer\";\nimport { sellerReducer } from \"./sellerReducer\";\n\nconst user = localStorage.getItem(\"auth\")\n    ? JSON.parse(localStorage.getItem(\"auth\"))\n    : null;\n\nconst cartItems = localStorage.getItem(\"cartItems\")\n    ? JSON.parse(localStorage.getItem(\"cartItems\"))\n    : [];\n\nconst selectUserCheckoutAddress = localStorage.getItem(\"CHECKOUT_ADDRESS\")\n    ? JSON.parse(localStorage.getItem(\"CHECKOUT_ADDRESS\"))\n    : [];\n\nconst initialState = {\n    auth: { user: user, selectUserCheckoutAddress },\n    carts: { cart: cartItems },\n};\n\nexport const store = configureStore({\n    reducer: {\n        products: productReducer,\n        errors: errorReducer,\n        carts: cartReducer,\n        auth: authReducer,\n        payment: paymentMethodReducer,\n        admin: adminReducer,\n        order: orderReducer,\n        seller: sellerReducer,\n    },\n    preloadedState: initialState,\n});\n\nexport default store;"
  },
  {
    "path": "ecom-frontend/src/utils/constant.js",
    "content": "import bannerImageOne from \"../assets/sliders/s_1.webp\";\nimport bannerImageTwo from \"../assets/sliders/s_2.webp\";\nimport bannerImageThree from \"../assets/sliders/s_3.webp\";\n\nexport {\n    bannerImageOne,\n    bannerImageTwo,\n    bannerImageThree\n}"
  },
  {
    "path": "ecom-frontend/src/utils/formatPrice.js",
    "content": "export const formatPrice = (amount) => {\n return new Intl.NumberFormat(\"en-US\", {\n    style: \"currency\",\n    currency: \"USD\",\n }).format(amount);\n}\n\n\nexport const formatPriceCalculation = (quantity, price) => {\n   return (Number(quantity) * Number(price)).toFixed(2);\n  }\n\n\nexport const formatRevenue = (value) => {\n   if (value >= 1e9) {\n      return (value / 1e9).toFixed(1) + \"B\";\n   } else if (value >= 1e6) {\n      return (value / 1e6).toFixed(1) + \"M\";\n   } else if (value >= 1e3) {\n      return (value / 1e3).toFixed(1) + \"K\";\n   } else {\n      return value;\n   }\n};"
  },
  {
    "path": "ecom-frontend/src/utils/index.js",
    "content": "import { FaBoxOpen, FaHome, FaShoppingCart, FaStore, FaThList } from \"react-icons/fa\";\nimport { bannerImageOne, bannerImageThree, bannerImageTwo } from \"./constant\";\n\nexport const bannerLists = [\n    {\n        id: 1,\n        image: bannerImageOne,\n        title: \"Home Comfort\",\n        subtitle: \"Living Room\",\n        description: \"Upgrade your space with cozy and stylish sofas\",\n      },\n      {\n        id: 2,\n        image: bannerImageTwo,\n        title: \"Entertainment Hub\",\n        subtitle: \"Smart TV\",\n        description: \"Experience the latest in home entertainment\",\n      },\n      {\n        id: 3,\n        image: bannerImageThree,\n        title: \"Playful Picks\",\n        subtitle: \"Kids' Clothing\",\n        description: \"Bright and fun styles for kids, up to 20% off\",\n    }\n];\n\n\nexport const adminNavigation = [\n  {\n    name: \"Dashboard\", \n    href: \"/admin\", \n    icon: FaHome, \n    current: true \n  }, {\n    name: \"Orders\", \n    href: \"/admin/orders\", \n    icon: FaShoppingCart\n  }, {\n    name: \"Products\", \n    href: \"/admin/products\", \n    icon: FaBoxOpen\n  }, {\n    name: \"Categories\", \n    href: \"/admin/categories\", \n    icon: FaThList\n  }, {\n    name: \"Sellers\", \n    href: \"/admin/sellers\", \n    icon: FaStore \n  }\n];\n\n\nexport const sellerNavigation = [\n  {\n    name: \"Orders\", \n    href: \"/admin/orders\", \n    icon: FaShoppingCart,\n    current: true \n  }, {\n    name: \"Products\", \n    href: \"/admin/products\", \n    icon: FaBoxOpen\n  }\n];"
  },
  {
    "path": "ecom-frontend/src/utils/truncateText.js",
    "content": "const truncateText = (text, charLimit = 90) => {\n    if (text?.length > charLimit) {\n        return text.slice(0, charLimit) + \"...\";\n    }\n    return text;\n};\n\nexport default truncateText;"
  },
  {
    "path": "ecom-frontend/vite.config.js",
    "content": "import { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\n\n// https://vite.dev/config/\nexport default defineConfig({\n  plugins: [react()],\n})\n"
  },
  {
    "path": "media/.gitignore",
    "content": "HELP.md\ntarget/\n!.mvn/wrapper/maven-wrapper.jar\n!**/src/main/**/target/\n!**/src/test/**/target/\n\n### STS ###\n.apt_generated\n.classpath\n.factorypath\n.project\n.settings\n.springBeans\n.sts4-cache\n\n### IntelliJ IDEA ###\n.idea\n*.iws\n*.iml\n*.ipr\n\n### NetBeans ###\n/nbproject/private/\n/nbbuild/\n/dist/\n/nbdist/\n/.nb-gradle/\nbuild/\n!**/src/main/**/build/\n!**/src/test/**/build/\n\n### VS Code ###\n.vscode/\n"
  },
  {
    "path": "media/.mvn/wrapper/maven-wrapper.properties",
    "content": "distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip\nwrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\n"
  },
  {
    "path": "media/mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Apache Maven Wrapper startup batch script, version 3.2.0\n#\n# Required ENV vars:\n# ------------------\n#   JAVA_HOME - location of a JDK home dir\n#\n# Optional ENV vars\n# -----------------\n#   MAVEN_OPTS - parameters passed to the Java VM when running Maven\n#     e.g. to debug Maven itself, use\n#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n# ----------------------------------------------------------------------------\n\nif [ -z \"$MAVEN_SKIP_RC\" ] ; then\n\n  if [ -f /usr/local/etc/mavenrc ] ; then\n    . /usr/local/etc/mavenrc\n  fi\n\n  if [ -f /etc/mavenrc ] ; then\n    . /etc/mavenrc\n  fi\n\n  if [ -f \"$HOME/.mavenrc\" ] ; then\n    . \"$HOME/.mavenrc\"\n  fi\n\nfi\n\n# OS specific support.  $var _must_ be set to either true or false.\ncygwin=false;\ndarwin=false;\nmingw=false\ncase \"$(uname)\" in\n  CYGWIN*) cygwin=true ;;\n  MINGW*) mingw=true;;\n  Darwin*) darwin=true\n    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home\n    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html\n    if [ -z \"$JAVA_HOME\" ]; then\n      if [ -x \"/usr/libexec/java_home\" ]; then\n        JAVA_HOME=\"$(/usr/libexec/java_home)\"; export JAVA_HOME\n      else\n        JAVA_HOME=\"/Library/Java/Home\"; export JAVA_HOME\n      fi\n    fi\n    ;;\nesac\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  if [ -r /etc/gentoo-release ] ; then\n    JAVA_HOME=$(java-config --jre-home)\n  fi\nfi\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched\nif $cygwin ; then\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=$(cygpath --unix \"$JAVA_HOME\")\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=$(cygpath --path --unix \"$CLASSPATH\")\nfi\n\n# For Mingw, ensure paths are in UNIX format before anything is touched\nif $mingw ; then\n  [ -n \"$JAVA_HOME\" ] && [ -d \"$JAVA_HOME\" ] &&\n    JAVA_HOME=\"$(cd \"$JAVA_HOME\" || (echo \"cannot cd into $JAVA_HOME.\"; exit 1); pwd)\"\nfi\n\nif [ -z \"$JAVA_HOME\" ]; then\n  javaExecutable=\"$(which javac)\"\n  if [ -n \"$javaExecutable\" ] && ! [ \"$(expr \"\\\"$javaExecutable\\\"\" : '\\([^ ]*\\)')\" = \"no\" ]; then\n    # readlink(1) is not available as standard on Solaris 10.\n    readLink=$(which readlink)\n    if [ ! \"$(expr \"$readLink\" : '\\([^ ]*\\)')\" = \"no\" ]; then\n      if $darwin ; then\n        javaHome=\"$(dirname \"\\\"$javaExecutable\\\"\")\"\n        javaExecutable=\"$(cd \"\\\"$javaHome\\\"\" && pwd -P)/javac\"\n      else\n        javaExecutable=\"$(readlink -f \"\\\"$javaExecutable\\\"\")\"\n      fi\n      javaHome=\"$(dirname \"\\\"$javaExecutable\\\"\")\"\n      javaHome=$(expr \"$javaHome\" : '\\(.*\\)/bin')\n      JAVA_HOME=\"$javaHome\"\n      export JAVA_HOME\n    fi\n  fi\nfi\n\nif [ -z \"$JAVACMD\" ] ; then\n  if [ -n \"$JAVA_HOME\"  ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n  else\n    JAVACMD=\"$(\\unset -f command 2>/dev/null; \\command -v java)\"\n  fi\nfi\n\nif [ ! -x \"$JAVACMD\" ] ; then\n  echo \"Error: JAVA_HOME is not defined correctly.\" >&2\n  echo \"  We cannot execute $JAVACMD\" >&2\n  exit 1\nfi\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  echo \"Warning: JAVA_HOME environment variable is not set.\"\nfi\n\n# traverses directory structure from process work directory to filesystem root\n# first directory with .mvn subdirectory is considered project base directory\nfind_maven_basedir() {\n  if [ -z \"$1\" ]\n  then\n    echo \"Path not specified to find_maven_basedir\"\n    return 1\n  fi\n\n  basedir=\"$1\"\n  wdir=\"$1\"\n  while [ \"$wdir\" != '/' ] ; do\n    if [ -d \"$wdir\"/.mvn ] ; then\n      basedir=$wdir\n      break\n    fi\n    # workaround for JBEAP-8937 (on Solaris 10/Sparc)\n    if [ -d \"${wdir}\" ]; then\n      wdir=$(cd \"$wdir/..\" || exit 1; pwd)\n    fi\n    # end of workaround\n  done\n  printf '%s' \"$(cd \"$basedir\" || exit 1; pwd)\"\n}\n\n# concatenates all lines of a file\nconcat_lines() {\n  if [ -f \"$1\" ]; then\n    # Remove \\r in case we run on Windows within Git Bash\n    # and check out the repository with auto CRLF management\n    # enabled. Otherwise, we may read lines that are delimited with\n    # \\r\\n and produce $'-Xarg\\r' rather than -Xarg due to word\n    # splitting rules.\n    tr -s '\\r\\n' ' ' < \"$1\"\n  fi\n}\n\nlog() {\n  if [ \"$MVNW_VERBOSE\" = true ]; then\n    printf '%s\\n' \"$1\"\n  fi\n}\n\nBASE_DIR=$(find_maven_basedir \"$(dirname \"$0\")\")\nif [ -z \"$BASE_DIR\" ]; then\n  exit 1;\nfi\n\nMAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-\"$BASE_DIR\"}; export MAVEN_PROJECTBASEDIR\nlog \"$MAVEN_PROJECTBASEDIR\"\n\n##########################################################################################\n# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n# This allows using the maven wrapper in projects that prohibit checking in binary data.\n##########################################################################################\nwrapperJarPath=\"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\"\nif [ -r \"$wrapperJarPath\" ]; then\n    log \"Found $wrapperJarPath\"\nelse\n    log \"Couldn't find $wrapperJarPath, downloading it ...\"\n\n    if [ -n \"$MVNW_REPOURL\" ]; then\n      wrapperUrl=\"$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n    else\n      wrapperUrl=\"https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n    fi\n    while IFS=\"=\" read -r key value; do\n      # Remove '\\r' from value to allow usage on windows as IFS does not consider '\\r' as a separator ( considers space, tab, new line ('\\n'), and custom '=' )\n      safeValue=$(echo \"$value\" | tr -d '\\r')\n      case \"$key\" in (wrapperUrl) wrapperUrl=\"$safeValue\"; break ;;\n      esac\n    done < \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties\"\n    log \"Downloading from: $wrapperUrl\"\n\n    if $cygwin; then\n      wrapperJarPath=$(cygpath --path --windows \"$wrapperJarPath\")\n    fi\n\n    if command -v wget > /dev/null; then\n        log \"Found wget ... using wget\"\n        [ \"$MVNW_VERBOSE\" = true ] && QUIET=\"\" || QUIET=\"--quiet\"\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            wget $QUIET \"$wrapperUrl\" -O \"$wrapperJarPath\" || rm -f \"$wrapperJarPath\"\n        else\n            wget $QUIET --http-user=\"$MVNW_USERNAME\" --http-password=\"$MVNW_PASSWORD\" \"$wrapperUrl\" -O \"$wrapperJarPath\" || rm -f \"$wrapperJarPath\"\n        fi\n    elif command -v curl > /dev/null; then\n        log \"Found curl ... using curl\"\n        [ \"$MVNW_VERBOSE\" = true ] && QUIET=\"\" || QUIET=\"--silent\"\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            curl $QUIET -o \"$wrapperJarPath\" \"$wrapperUrl\" -f -L || rm -f \"$wrapperJarPath\"\n        else\n            curl $QUIET --user \"$MVNW_USERNAME:$MVNW_PASSWORD\" -o \"$wrapperJarPath\" \"$wrapperUrl\" -f -L || rm -f \"$wrapperJarPath\"\n        fi\n    else\n        log \"Falling back to using Java to download\"\n        javaSource=\"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java\"\n        javaClass=\"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class\"\n        # For Cygwin, switch paths to Windows format before running javac\n        if $cygwin; then\n          javaSource=$(cygpath --path --windows \"$javaSource\")\n          javaClass=$(cygpath --path --windows \"$javaClass\")\n        fi\n        if [ -e \"$javaSource\" ]; then\n            if [ ! -e \"$javaClass\" ]; then\n                log \" - Compiling MavenWrapperDownloader.java ...\"\n                (\"$JAVA_HOME/bin/javac\" \"$javaSource\")\n            fi\n            if [ -e \"$javaClass\" ]; then\n                log \" - Running MavenWrapperDownloader.java ...\"\n                (\"$JAVA_HOME/bin/java\" -cp .mvn/wrapper MavenWrapperDownloader \"$wrapperUrl\" \"$wrapperJarPath\") || rm -f \"$wrapperJarPath\"\n            fi\n        fi\n    fi\nfi\n##########################################################################################\n# End of extension\n##########################################################################################\n\n# If specified, validate the SHA-256 sum of the Maven wrapper jar file\nwrapperSha256Sum=\"\"\nwhile IFS=\"=\" read -r key value; do\n  case \"$key\" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;\n  esac\ndone < \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties\"\nif [ -n \"$wrapperSha256Sum\" ]; then\n  wrapperSha256Result=false\n  if command -v sha256sum > /dev/null; then\n    if echo \"$wrapperSha256Sum  $wrapperJarPath\" | sha256sum -c > /dev/null 2>&1; then\n      wrapperSha256Result=true\n    fi\n  elif command -v shasum > /dev/null; then\n    if echo \"$wrapperSha256Sum  $wrapperJarPath\" | shasum -a 256 -c > /dev/null 2>&1; then\n      wrapperSha256Result=true\n    fi\n  else\n    echo \"Checksum validation was requested but neither 'sha256sum' or 'shasum' are available.\"\n    echo \"Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties.\"\n    exit 1\n  fi\n  if [ $wrapperSha256Result = false ]; then\n    echo \"Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.\" >&2\n    echo \"Investigate or delete $wrapperJarPath to attempt a clean download.\" >&2\n    echo \"If you updated your Maven version, you need to update the specified wrapperSha256Sum property.\" >&2\n    exit 1\n  fi\nfi\n\nMAVEN_OPTS=\"$(concat_lines \"$MAVEN_PROJECTBASEDIR/.mvn/jvm.config\") $MAVEN_OPTS\"\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin; then\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=$(cygpath --path --windows \"$JAVA_HOME\")\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=$(cygpath --path --windows \"$CLASSPATH\")\n  [ -n \"$MAVEN_PROJECTBASEDIR\" ] &&\n    MAVEN_PROJECTBASEDIR=$(cygpath --path --windows \"$MAVEN_PROJECTBASEDIR\")\nfi\n\n# Provide a \"standardized\" way to retrieve the CLI args that will\n# work with both Windows and non-Windows executions.\nMAVEN_CMD_LINE_ARGS=\"$MAVEN_CONFIG $*\"\nexport MAVEN_CMD_LINE_ARGS\n\nWRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\n# shellcheck disable=SC2086 # safe args\nexec \"$JAVACMD\" \\\n  $MAVEN_OPTS \\\n  $MAVEN_DEBUG_OPTS \\\n  -classpath \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\" \\\n  \"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}\" \\\n  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG \"$@\"\n"
  },
  {
    "path": "media/mvnw.cmd",
    "content": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software Foundation (ASF) under one\n@REM or more contributor license agreements.  See the NOTICE file\n@REM distributed with this work for additional information\n@REM regarding copyright ownership.  The ASF licenses this file\n@REM to you under the Apache License, Version 2.0 (the\n@REM \"License\"); you may not use this file except in compliance\n@REM with the License.  You may obtain a copy of the License at\n@REM\n@REM    https://www.apache.org/licenses/LICENSE-2.0\n@REM\n@REM Unless required by applicable law or agreed to in writing,\n@REM software distributed under the License is distributed on an\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n@REM KIND, either express or implied.  See the License for the\n@REM specific language governing permissions and limitations\n@REM under the License.\n@REM ----------------------------------------------------------------------------\n\n@REM ----------------------------------------------------------------------------\n@REM Apache Maven Wrapper startup batch script, version 3.2.0\n@REM\n@REM Required ENV vars:\n@REM JAVA_HOME - location of a JDK home dir\n@REM\n@REM Optional ENV vars\n@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands\n@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending\n@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven\n@REM     e.g. to debug Maven itself, use\n@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n@REM ----------------------------------------------------------------------------\n\n@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'\n@echo off\n@REM set title of command window\ntitle %0\n@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'\n@if \"%MAVEN_BATCH_ECHO%\" == \"on\"  echo %MAVEN_BATCH_ECHO%\n\n@REM set %HOME% to equivalent of $HOME\nif \"%HOME%\" == \"\" (set \"HOME=%HOMEDRIVE%%HOMEPATH%\")\n\n@REM Execute a user defined script before this one\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPre\n@REM check for pre script, once with legacy .bat ending and once with .cmd ending\nif exist \"%USERPROFILE%\\mavenrc_pre.bat\" call \"%USERPROFILE%\\mavenrc_pre.bat\" %*\nif exist \"%USERPROFILE%\\mavenrc_pre.cmd\" call \"%USERPROFILE%\\mavenrc_pre.cmd\" %*\n:skipRcPre\n\n@setlocal\n\nset ERROR_CODE=0\n\n@REM To isolate internal variables from possible post scripts, we use another setlocal\n@setlocal\n\n@REM ==== START VALIDATION ====\nif not \"%JAVA_HOME%\" == \"\" goto OkJHome\n\necho.\necho Error: JAVA_HOME not found in your environment. >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n:OkJHome\nif exist \"%JAVA_HOME%\\bin\\java.exe\" goto init\n\necho.\necho Error: JAVA_HOME is set to an invalid directory. >&2\necho JAVA_HOME = \"%JAVA_HOME%\" >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n@REM ==== END VALIDATION ====\n\n:init\n\n@REM Find the project base dir, i.e. the directory that contains the folder \".mvn\".\n@REM Fallback to current working directory if not found.\n\nset MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%\nIF NOT \"%MAVEN_PROJECTBASEDIR%\"==\"\" goto endDetectBaseDir\n\nset EXEC_DIR=%CD%\nset WDIR=%EXEC_DIR%\n:findBaseDir\nIF EXIST \"%WDIR%\"\\.mvn goto baseDirFound\ncd ..\nIF \"%WDIR%\"==\"%CD%\" goto baseDirNotFound\nset WDIR=%CD%\ngoto findBaseDir\n\n:baseDirFound\nset MAVEN_PROJECTBASEDIR=%WDIR%\ncd \"%EXEC_DIR%\"\ngoto endDetectBaseDir\n\n:baseDirNotFound\nset MAVEN_PROJECTBASEDIR=%EXEC_DIR%\ncd \"%EXEC_DIR%\"\n\n:endDetectBaseDir\n\nIF NOT EXIST \"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\" goto endReadAdditionalConfig\n\n@setlocal EnableExtensions EnableDelayedExpansion\nfor /F \"usebackq delims=\" %%a in (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a\n@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%\n\n:endReadAdditionalConfig\n\nSET MAVEN_JAVA_EXE=\"%JAVA_HOME%\\bin\\java.exe\"\nset WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.jar\"\nset WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nset WRAPPER_URL=\"https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n\nFOR /F \"usebackq tokens=1,2 delims==\" %%A IN (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.properties\") DO (\n    IF \"%%A\"==\"wrapperUrl\" SET WRAPPER_URL=%%B\n)\n\n@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n@REM This allows using the maven wrapper in projects that prohibit checking in binary data.\nif exist %WRAPPER_JAR% (\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Found %WRAPPER_JAR%\n    )\n) else (\n    if not \"%MVNW_REPOURL%\" == \"\" (\n        SET WRAPPER_URL=\"%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n    )\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Couldn't find %WRAPPER_JAR%, downloading it ...\n        echo Downloading from: %WRAPPER_URL%\n    )\n\n    powershell -Command \"&{\"^\n\t\t\"$webclient = new-object System.Net.WebClient;\"^\n\t\t\"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {\"^\n\t\t\"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');\"^\n\t\t\"}\"^\n\t\t\"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')\"^\n\t\t\"}\"\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Finished downloading %WRAPPER_JAR%\n    )\n)\n@REM End of extension\n\n@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file\nSET WRAPPER_SHA_256_SUM=\"\"\nFOR /F \"usebackq tokens=1,2 delims==\" %%A IN (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.properties\") DO (\n    IF \"%%A\"==\"wrapperSha256Sum\" SET WRAPPER_SHA_256_SUM=%%B\n)\nIF NOT %WRAPPER_SHA_256_SUM%==\"\" (\n    powershell -Command \"&{\"^\n       \"$hash = (Get-FileHash \\\"%WRAPPER_JAR%\\\" -Algorithm SHA256).Hash.ToLower();\"^\n       \"If('%WRAPPER_SHA_256_SUM%' -ne $hash){\"^\n       \"  Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';\"^\n       \"  Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';\"^\n       \"  Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';\"^\n       \"  exit 1;\"^\n       \"}\"^\n       \"}\"\n    if ERRORLEVEL 1 goto error\n)\n\n@REM Provide a \"standardized\" way to retrieve the CLI args that will\n@REM work with both Windows and non-Windows executions.\nset MAVEN_CMD_LINE_ARGS=%*\n\n%MAVEN_JAVA_EXE% ^\n  %JVM_CONFIG_MAVEN_PROPS% ^\n  %MAVEN_OPTS% ^\n  %MAVEN_DEBUG_OPTS% ^\n  -classpath %WRAPPER_JAR% ^\n  \"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%\" ^\n  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*\nif ERRORLEVEL 1 goto error\ngoto end\n\n:error\nset ERROR_CODE=1\n\n:end\n@endlocal & set ERROR_CODE=%ERROR_CODE%\n\nif not \"%MAVEN_SKIP_RC%\"==\"\" goto skipRcPost\n@REM check for post script, once with legacy .bat ending and once with .cmd ending\nif exist \"%USERPROFILE%\\mavenrc_post.bat\" call \"%USERPROFILE%\\mavenrc_post.bat\"\nif exist \"%USERPROFILE%\\mavenrc_post.cmd\" call \"%USERPROFILE%\\mavenrc_post.cmd\"\n:skipRcPost\n\n@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'\nif \"%MAVEN_BATCH_PAUSE%\"==\"on\" pause\n\nif \"%MAVEN_TERMINATE_CMD%\"==\"on\" exit %ERROR_CODE%\n\ncmd /C exit /B %ERROR_CODE%\n"
  },
  {
    "path": "media/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>org.springframework.boot</groupId>\n\t\t<artifactId>spring-boot-starter-parent</artifactId>\n\t\t<version>4.0.1</version>\n\t\t<relativePath/> <!-- lookup parent from repository -->\n\t</parent>\n\t<groupId>com.social</groupId>\n\t<artifactId>media</artifactId>\n\t<version>0.0.1-SNAPSHOT</version>\n\t<name>media</name>\n\t<description>Demo project for Spring Boot</description>\n\t<properties>\n\t\t<java.version>24</java.version>\n\t</properties>\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-data-jpa</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-webmvc</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.h2database</groupId>\n\t\t\t<artifactId>h2</artifactId>\n\t\t\t<scope>runtime</scope>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-test</artifactId>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.projectlombok</groupId>\n\t\t\t<artifactId>lombok</artifactId>\n\t\t\t<optional>true</optional>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t\t<artifactId>spring-boot-maven-plugin</artifactId>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n</project>\n"
  },
  {
    "path": "media/src/main/java/com/social/media/DataInitializer.java",
    "content": "package com.social.media;\n\nimport com.social.media.repositories.PostRepository;\nimport com.social.media.repositories.SocialProfileRepository;\nimport org.springframework.boot.CommandLineRunner;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\nimport com.social.media.models.Post;\nimport com.social.media.models.SocialGroup;\nimport com.social.media.models.SocialProfile;\nimport com.social.media.models.SocialUser;\nimport com.social.media.repositories.SocialGroupRepository;\nimport com.social.media.repositories.SocialUserRepository;\n\n@Configuration\npublic class DataInitializer {\n\n    private final SocialUserRepository userRepository;\n    private final SocialGroupRepository groupRepository;\n    private final SocialProfileRepository socialProfileRepository;\n    private final PostRepository postRepository;\n\n    public DataInitializer(SocialUserRepository userRepository, SocialGroupRepository groupRepository, SocialProfileRepository socialProfileRepository, PostRepository postRepository) {\n        this.userRepository = userRepository;\n        this.groupRepository = groupRepository;\n        this.socialProfileRepository = socialProfileRepository;\n        this.postRepository = postRepository;\n    }\n\n    @Bean\n    public CommandLineRunner initializeData() {\n        return args -> {\n            // Create some users\n            SocialUser user1 = new SocialUser();\n            SocialUser user2 = new SocialUser();\n            SocialUser user3 = new SocialUser();\n\n            // Save users to the database\n            userRepository.save(user1);\n            userRepository.save(user2);\n            userRepository.save(user3);\n\n            // Create some groups\n            SocialGroup group1 = new SocialGroup();\n            SocialGroup group2 = new SocialGroup();\n\n            // Add users to groups\n            group1.getSocialUsers().add(user1);\n            group1.getSocialUsers().add(user2);\n\n            group2.getSocialUsers().add(user2);\n            group2.getSocialUsers().add(user3);\n\n            // Save groups to the database\n            groupRepository.save(group1);\n            groupRepository.save(group2);\n\n            // Associate users with groups\n            user1.getGroups().add(group1);\n            user2.getGroups().add(group1);\n            user2.getGroups().add(group2);\n            user3.getGroups().add(group2);\n\n            // Save users back to database to update associations\n            userRepository.save(user1);\n            userRepository.save(user2);\n            userRepository.save(user3);\n\n\n            // Create some posts\n            Post post1 = new Post();\n            Post post2 = new Post();\n            Post post3 = new Post();\n\n            // Associate posts with users\n            post1.setSocialUser(user1);\n            post2.setSocialUser(user2);\n            post3.setSocialUser(user3);\n\n            // Save posts to the database (assuming you have a PostRepository)\n             postRepository.save(post1);\n             postRepository.save(post2);\n             postRepository.save(post3);\n\n            // Create some social profiles\n            SocialProfile profile1 = new SocialProfile();\n            SocialProfile profile2 = new SocialProfile();\n            SocialProfile profile3 = new SocialProfile();\n\n            // Associate profiles with users\n            profile1.setUser(user1);\n            profile2.setUser(user2);\n            profile3.setUser(user3);\n\n            // Save profiles to the database (assuming you have a SocialProfileRepository)\n            socialProfileRepository.save(profile1);\n            socialProfileRepository.save(profile2);\n            socialProfileRepository.save(profile3);\n\n\n            // FETCH TYPES\n            System.out.println(\"FETCHING SOCIAL USER\");\n            userRepository.findById(1L);\n        };\n    }\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/MediaApplication.java",
    "content": "package com.social.media;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\n\n@SpringBootApplication\npublic class MediaApplication {\n\n\tpublic static void main(String[] args) {\n\t\tSpringApplication.run(MediaApplication.class, args);\n\t}\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/controllers/SocialController.java",
    "content": "package com.social.media.controllers;\n\nimport com.social.media.models.SocialUser;\nimport com.social.media.services.SocialService;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n\n@RestController\npublic class SocialController {\n    @Autowired\n    private SocialService socialService;\n\n    @GetMapping(\"/social/users\")\n    public ResponseEntity<List<SocialUser>> getUsers(){\n        return new ResponseEntity<>(socialService.getAllUsers(), HttpStatus.OK);\n    }\n\n    @PostMapping(\"/social/users\")\n    public ResponseEntity<SocialUser> saveUser(@RequestBody SocialUser socialUser){\n        return new ResponseEntity<>(socialService.saveUser(socialUser), HttpStatus.CREATED);\n    }\n\n    @DeleteMapping(\"/social/users/{userId}\")\n    public ResponseEntity<String> deleteUser(@PathVariable Long userId){\n        socialService.deleteUser(userId);\n        return new ResponseEntity<>(\"Deleted Successfully\", HttpStatus.OK);\n    }\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/models/Post.java",
    "content": "package com.social.media.models;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport jakarta.persistence.*;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Entity\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class Post {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n\n    @ManyToOne\n    @JoinColumn(name = \"user_id\")\n    @JsonIgnore\n    private SocialUser socialUser;\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/models/SocialGroup.java",
    "content": "package com.social.media.models;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport jakarta.persistence.*;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.HashSet;\nimport java.util.Objects;\nimport java.util.Set;\n\n@Entity\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class SocialGroup {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n\n    @ManyToMany(mappedBy = \"groups\")\n    @JsonIgnore\n    private Set<SocialUser> socialUsers = new HashSet<>();\n\n    @Override\n    public int hashCode(){\n        return Objects.hash(id);\n    }\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/models/SocialProfile.java",
    "content": "package com.social.media.models;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport jakarta.persistence.*;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Entity\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class SocialProfile {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n\n    @OneToOne\n    @JoinColumn(name = \"social_user\")\n    @JsonIgnore\n    private SocialUser user;\n\n    private String description;\n\n    public void setSocialUser(SocialUser socialUser){\n        this.user = socialUser;\n        if (user.getSocialProfile() != this)\n            user.setSocialProfile(this);\n    }\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/models/SocialUser.java",
    "content": "package com.social.media.models;\n\nimport jakarta.persistence.*;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.*;\n\n\n@Entity\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class SocialUser {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n\n    @OneToOne(mappedBy = \"user\",\n            cascade = {CascadeType.REMOVE, CascadeType.PERSIST, CascadeType.MERGE})\n    //@JoinColumn(name = \"social_profile_id\")\n    private SocialProfile socialProfile;\n\n    @OneToMany(mappedBy = \"socialUser\", cascade = {CascadeType.PERSIST, CascadeType.MERGE})\n    private List<Post> posts = new ArrayList<>();\n\n    @ManyToMany(fetch = FetchType.LAZY)\n    @JoinTable(\n            name = \"user_group\",\n            joinColumns = @JoinColumn(name = \"user_id\"),\n            inverseJoinColumns = @JoinColumn(name = \"group_id\")\n    )\n    private Set<SocialGroup> groups = new HashSet<>();\n\n    @Override\n    public int hashCode(){\n        return Objects.hash(id);\n    }\n\n    public void setSocialProfile(SocialProfile socialProfile){\n        socialProfile.setUser(this);\n        this.socialProfile = socialProfile;\n    }\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/repositories/PostRepository.java",
    "content": "package com.social.media.repositories;\n\nimport com.social.media.models.Post;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\npublic interface PostRepository extends JpaRepository<Post, Long> {\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/repositories/SocialGroupRepository.java",
    "content": "package com.social.media.repositories;\n\nimport com.social.media.models.SocialGroup;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\npublic interface SocialGroupRepository extends JpaRepository<SocialGroup, Long> {\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/repositories/SocialProfileRepository.java",
    "content": "package com.social.media.repositories;\n\nimport com.social.media.models.SocialProfile;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\npublic interface SocialProfileRepository extends JpaRepository<SocialProfile, Long> {\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/repositories/SocialUserRepository.java",
    "content": "package com.social.media.repositories;\n\nimport com.social.media.models.SocialUser;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\npublic interface SocialUserRepository extends JpaRepository<SocialUser,Long> {\n}\n"
  },
  {
    "path": "media/src/main/java/com/social/media/services/SocialService.java",
    "content": "package com.social.media.services;\n\nimport com.social.media.models.SocialUser;\nimport com.social.media.repositories.SocialUserRepository;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\n\nimport java.util.List;\n\n@Service\npublic class SocialService {\n    @Autowired\n    SocialUserRepository socialUserRepository;\n\n    public List<SocialUser> getAllUsers() {\n        return socialUserRepository.findAll();\n    }\n\n    public SocialUser saveUser(SocialUser socialUser) {\n        return socialUserRepository.save(socialUser);\n    }\n\n    public SocialUser deleteUser(Long id) {\n        SocialUser socialUser = socialUserRepository.findById(id)\n                .orElseThrow(() -> new RuntimeException(\"User not found\"));\n        socialUserRepository.delete(socialUser);\n        return socialUser;\n    }\n}\n"
  },
  {
    "path": "media/src/main/resources/application.properties",
    "content": "spring.application.name=media\nspring.h2.console.enabled=true\nspring.datasource.url=jdbc:h2:mem:test\n\nspring.jpa.show-sql=true\nspring.jpa.properties.hibernate.format_sql=true"
  },
  {
    "path": "media/src/test/java/com/social/media/MediaApplicationTests.java",
    "content": "package com.social.media;\n\nimport org.junit.jupiter.api.Test;\nimport org.springframework.boot.test.context.SpringBootTest;\n\n@SpringBootTest\nclass MediaApplicationTests {\n\n\t@Test\n\tvoid contextLoads() {\n\t}\n\n}\n"
  },
  {
    "path": "sb-ecom/.gitignore",
    "content": "HELP.md\ntarget/\n!.mvn/wrapper/maven-wrapper.jar\n!**/src/main/**/target/\n!**/src/test/**/target/\n\n### STS ###\n.apt_generated\n.classpath\n.factorypath\n.project\n.settings\n.springBeans\n.sts4-cache\n\n# Ignore the images folder\nimages/\n\n\n### IntelliJ IDEA ###\n.idea\n*.iws\n*.iml\n*.ipr\n\n### NetBeans ###\n/nbproject/private/\n/nbbuild/\n/dist/\n/nbdist/\n/.nb-gradle/\nbuild/\n!**/src/main/**/build/\n!**/src/test/**/build/\n\n### VS Code ###\n.vscode/\n"
  },
  {
    "path": "sb-ecom/.mvn/wrapper/maven-wrapper.properties",
    "content": "distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip\nwrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\n"
  },
  {
    "path": "sb-ecom/mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Apache Maven Wrapper startup batch script, version 3.2.0\n#\n# Required ENV vars:\n# ------------------\n#   JAVA_HOME - location of a JDK home dir\n#\n# Optional ENV vars\n# -----------------\n#   MAVEN_OPTS - parameters passed to the Java VM when running Maven\n#     e.g. to debug Maven itself, use\n#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n# ----------------------------------------------------------------------------\n\nif [ -z \"$MAVEN_SKIP_RC\" ] ; then\n\n  if [ -f /usr/local/etc/mavenrc ] ; then\n    . /usr/local/etc/mavenrc\n  fi\n\n  if [ -f /etc/mavenrc ] ; then\n    . /etc/mavenrc\n  fi\n\n  if [ -f \"$HOME/.mavenrc\" ] ; then\n    . \"$HOME/.mavenrc\"\n  fi\n\nfi\n\n# OS specific support.  $var _must_ be set to either true or false.\ncygwin=false;\ndarwin=false;\nmingw=false\ncase \"$(uname)\" in\n  CYGWIN*) cygwin=true ;;\n  MINGW*) mingw=true;;\n  Darwin*) darwin=true\n    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home\n    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html\n    if [ -z \"$JAVA_HOME\" ]; then\n      if [ -x \"/usr/libexec/java_home\" ]; then\n        JAVA_HOME=\"$(/usr/libexec/java_home)\"; export JAVA_HOME\n      else\n        JAVA_HOME=\"/Library/Java/Home\"; export JAVA_HOME\n      fi\n    fi\n    ;;\nesac\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  if [ -r /etc/gentoo-release ] ; then\n    JAVA_HOME=$(java-config --jre-home)\n  fi\nfi\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched\nif $cygwin ; then\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=$(cygpath --unix \"$JAVA_HOME\")\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=$(cygpath --path --unix \"$CLASSPATH\")\nfi\n\n# For Mingw, ensure paths are in UNIX format before anything is touched\nif $mingw ; then\n  [ -n \"$JAVA_HOME\" ] && [ -d \"$JAVA_HOME\" ] &&\n    JAVA_HOME=\"$(cd \"$JAVA_HOME\" || (echo \"cannot cd into $JAVA_HOME.\"; exit 1); pwd)\"\nfi\n\nif [ -z \"$JAVA_HOME\" ]; then\n  javaExecutable=\"$(which javac)\"\n  if [ -n \"$javaExecutable\" ] && ! [ \"$(expr \"\\\"$javaExecutable\\\"\" : '\\([^ ]*\\)')\" = \"no\" ]; then\n    # readlink(1) is not available as standard on Solaris 10.\n    readLink=$(which readlink)\n    if [ ! \"$(expr \"$readLink\" : '\\([^ ]*\\)')\" = \"no\" ]; then\n      if $darwin ; then\n        javaHome=\"$(dirname \"\\\"$javaExecutable\\\"\")\"\n        javaExecutable=\"$(cd \"\\\"$javaHome\\\"\" && pwd -P)/javac\"\n      else\n        javaExecutable=\"$(readlink -f \"\\\"$javaExecutable\\\"\")\"\n      fi\n      javaHome=\"$(dirname \"\\\"$javaExecutable\\\"\")\"\n      javaHome=$(expr \"$javaHome\" : '\\(.*\\)/bin')\n      JAVA_HOME=\"$javaHome\"\n      export JAVA_HOME\n    fi\n  fi\nfi\n\nif [ -z \"$JAVACMD\" ] ; then\n  if [ -n \"$JAVA_HOME\"  ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n  else\n    JAVACMD=\"$(\\unset -f command 2>/dev/null; \\command -v java)\"\n  fi\nfi\n\nif [ ! -x \"$JAVACMD\" ] ; then\n  echo \"Error: JAVA_HOME is not defined correctly.\" >&2\n  echo \"  We cannot execute $JAVACMD\" >&2\n  exit 1\nfi\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  echo \"Warning: JAVA_HOME environment variable is not set.\"\nfi\n\n# traverses directory structure from process work directory to filesystem root\n# first directory with .mvn subdirectory is considered project base directory\nfind_maven_basedir() {\n  if [ -z \"$1\" ]\n  then\n    echo \"Path not specified to find_maven_basedir\"\n    return 1\n  fi\n\n  basedir=\"$1\"\n  wdir=\"$1\"\n  while [ \"$wdir\" != '/' ] ; do\n    if [ -d \"$wdir\"/.mvn ] ; then\n      basedir=$wdir\n      break\n    fi\n    # workaround for JBEAP-8937 (on Solaris 10/Sparc)\n    if [ -d \"${wdir}\" ]; then\n      wdir=$(cd \"$wdir/..\" || exit 1; pwd)\n    fi\n    # end of workaround\n  done\n  printf '%s' \"$(cd \"$basedir\" || exit 1; pwd)\"\n}\n\n# concatenates all lines of a file\nconcat_lines() {\n  if [ -f \"$1\" ]; then\n    # Remove \\r in case we run on Windows within Git Bash\n    # and check out the repository with auto CRLF management\n    # enabled. Otherwise, we may read lines that are delimited with\n    # \\r\\n and produce $'-Xarg\\r' rather than -Xarg due to word\n    # splitting rules.\n    tr -s '\\r\\n' ' ' < \"$1\"\n  fi\n}\n\nlog() {\n  if [ \"$MVNW_VERBOSE\" = true ]; then\n    printf '%s\\n' \"$1\"\n  fi\n}\n\nBASE_DIR=$(find_maven_basedir \"$(dirname \"$0\")\")\nif [ -z \"$BASE_DIR\" ]; then\n  exit 1;\nfi\n\nMAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-\"$BASE_DIR\"}; export MAVEN_PROJECTBASEDIR\nlog \"$MAVEN_PROJECTBASEDIR\"\n\n##########################################################################################\n# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n# This allows using the maven wrapper in projects that prohibit checking in binary data.\n##########################################################################################\nwrapperJarPath=\"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\"\nif [ -r \"$wrapperJarPath\" ]; then\n    log \"Found $wrapperJarPath\"\nelse\n    log \"Couldn't find $wrapperJarPath, downloading it ...\"\n\n    if [ -n \"$MVNW_REPOURL\" ]; then\n      wrapperUrl=\"$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n    else\n      wrapperUrl=\"https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n    fi\n    while IFS=\"=\" read -r key value; do\n      # Remove '\\r' from value to allow usage on windows as IFS does not consider '\\r' as a separator ( considers space, tab, new line ('\\n'), and custom '=' )\n      safeValue=$(echo \"$value\" | tr -d '\\r')\n      case \"$key\" in (wrapperUrl) wrapperUrl=\"$safeValue\"; break ;;\n      esac\n    done < \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties\"\n    log \"Downloading from: $wrapperUrl\"\n\n    if $cygwin; then\n      wrapperJarPath=$(cygpath --path --windows \"$wrapperJarPath\")\n    fi\n\n    if command -v wget > /dev/null; then\n        log \"Found wget ... using wget\"\n        [ \"$MVNW_VERBOSE\" = true ] && QUIET=\"\" || QUIET=\"--quiet\"\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            wget $QUIET \"$wrapperUrl\" -O \"$wrapperJarPath\" || rm -f \"$wrapperJarPath\"\n        else\n            wget $QUIET --http-user=\"$MVNW_USERNAME\" --http-password=\"$MVNW_PASSWORD\" \"$wrapperUrl\" -O \"$wrapperJarPath\" || rm -f \"$wrapperJarPath\"\n        fi\n    elif command -v curl > /dev/null; then\n        log \"Found curl ... using curl\"\n        [ \"$MVNW_VERBOSE\" = true ] && QUIET=\"\" || QUIET=\"--silent\"\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            curl $QUIET -o \"$wrapperJarPath\" \"$wrapperUrl\" -f -L || rm -f \"$wrapperJarPath\"\n        else\n            curl $QUIET --user \"$MVNW_USERNAME:$MVNW_PASSWORD\" -o \"$wrapperJarPath\" \"$wrapperUrl\" -f -L || rm -f \"$wrapperJarPath\"\n        fi\n    else\n        log \"Falling back to using Java to download\"\n        javaSource=\"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java\"\n        javaClass=\"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class\"\n        # For Cygwin, switch paths to Windows format before running javac\n        if $cygwin; then\n          javaSource=$(cygpath --path --windows \"$javaSource\")\n          javaClass=$(cygpath --path --windows \"$javaClass\")\n        fi\n        if [ -e \"$javaSource\" ]; then\n            if [ ! -e \"$javaClass\" ]; then\n                log \" - Compiling MavenWrapperDownloader.java ...\"\n                (\"$JAVA_HOME/bin/javac\" \"$javaSource\")\n            fi\n            if [ -e \"$javaClass\" ]; then\n                log \" - Running MavenWrapperDownloader.java ...\"\n                (\"$JAVA_HOME/bin/java\" -cp .mvn/wrapper MavenWrapperDownloader \"$wrapperUrl\" \"$wrapperJarPath\") || rm -f \"$wrapperJarPath\"\n            fi\n        fi\n    fi\nfi\n##########################################################################################\n# End of extension\n##########################################################################################\n\n# If specified, validate the SHA-256 sum of the Maven wrapper jar file\nwrapperSha256Sum=\"\"\nwhile IFS=\"=\" read -r key value; do\n  case \"$key\" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;\n  esac\ndone < \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties\"\nif [ -n \"$wrapperSha256Sum\" ]; then\n  wrapperSha256Result=false\n  if command -v sha256sum > /dev/null; then\n    if echo \"$wrapperSha256Sum  $wrapperJarPath\" | sha256sum -c > /dev/null 2>&1; then\n      wrapperSha256Result=true\n    fi\n  elif command -v shasum > /dev/null; then\n    if echo \"$wrapperSha256Sum  $wrapperJarPath\" | shasum -a 256 -c > /dev/null 2>&1; then\n      wrapperSha256Result=true\n    fi\n  else\n    echo \"Checksum validation was requested but neither 'sha256sum' or 'shasum' are available.\"\n    echo \"Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties.\"\n    exit 1\n  fi\n  if [ $wrapperSha256Result = false ]; then\n    echo \"Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.\" >&2\n    echo \"Investigate or delete $wrapperJarPath to attempt a clean download.\" >&2\n    echo \"If you updated your Maven version, you need to update the specified wrapperSha256Sum property.\" >&2\n    exit 1\n  fi\nfi\n\nMAVEN_OPTS=\"$(concat_lines \"$MAVEN_PROJECTBASEDIR/.mvn/jvm.config\") $MAVEN_OPTS\"\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin; then\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=$(cygpath --path --windows \"$JAVA_HOME\")\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=$(cygpath --path --windows \"$CLASSPATH\")\n  [ -n \"$MAVEN_PROJECTBASEDIR\" ] &&\n    MAVEN_PROJECTBASEDIR=$(cygpath --path --windows \"$MAVEN_PROJECTBASEDIR\")\nfi\n\n# Provide a \"standardized\" way to retrieve the CLI args that will\n# work with both Windows and non-Windows executions.\nMAVEN_CMD_LINE_ARGS=\"$MAVEN_CONFIG $*\"\nexport MAVEN_CMD_LINE_ARGS\n\nWRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\n# shellcheck disable=SC2086 # safe args\nexec \"$JAVACMD\" \\\n  $MAVEN_OPTS \\\n  $MAVEN_DEBUG_OPTS \\\n  -classpath \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\" \\\n  \"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}\" \\\n  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG \"$@\"\n"
  },
  {
    "path": "sb-ecom/mvnw.cmd",
    "content": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software Foundation (ASF) under one\n@REM or more contributor license agreements.  See the NOTICE file\n@REM distributed with this work for additional information\n@REM regarding copyright ownership.  The ASF licenses this file\n@REM to you under the Apache License, Version 2.0 (the\n@REM \"License\"); you may not use this file except in compliance\n@REM with the License.  You may obtain a copy of the License at\n@REM\n@REM    https://www.apache.org/licenses/LICENSE-2.0\n@REM\n@REM Unless required by applicable law or agreed to in writing,\n@REM software distributed under the License is distributed on an\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n@REM KIND, either express or implied.  See the License for the\n@REM specific language governing permissions and limitations\n@REM under the License.\n@REM ----------------------------------------------------------------------------\n\n@REM ----------------------------------------------------------------------------\n@REM Apache Maven Wrapper startup batch script, version 3.2.0\n@REM\n@REM Required ENV vars:\n@REM JAVA_HOME - location of a JDK home dir\n@REM\n@REM Optional ENV vars\n@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands\n@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending\n@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven\n@REM     e.g. to debug Maven itself, use\n@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n@REM ----------------------------------------------------------------------------\n\n@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'\n@echo off\n@REM set title of command window\ntitle %0\n@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'\n@if \"%MAVEN_BATCH_ECHO%\" == \"on\"  echo %MAVEN_BATCH_ECHO%\n\n@REM set %HOME% to equivalent of $HOME\nif \"%HOME%\" == \"\" (set \"HOME=%HOMEDRIVE%%HOMEPATH%\")\n\n@REM Execute a user defined script before this one\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPre\n@REM check for pre script, once with legacy .bat ending and once with .cmd ending\nif exist \"%USERPROFILE%\\mavenrc_pre.bat\" call \"%USERPROFILE%\\mavenrc_pre.bat\" %*\nif exist \"%USERPROFILE%\\mavenrc_pre.cmd\" call \"%USERPROFILE%\\mavenrc_pre.cmd\" %*\n:skipRcPre\n\n@setlocal\n\nset ERROR_CODE=0\n\n@REM To isolate internal variables from possible post scripts, we use another setlocal\n@setlocal\n\n@REM ==== START VALIDATION ====\nif not \"%JAVA_HOME%\" == \"\" goto OkJHome\n\necho.\necho Error: JAVA_HOME not found in your environment. >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n:OkJHome\nif exist \"%JAVA_HOME%\\bin\\java.exe\" goto init\n\necho.\necho Error: JAVA_HOME is set to an invalid directory. >&2\necho JAVA_HOME = \"%JAVA_HOME%\" >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n@REM ==== END VALIDATION ====\n\n:init\n\n@REM Find the project base dir, i.e. the directory that contains the folder \".mvn\".\n@REM Fallback to current working directory if not found.\n\nset MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%\nIF NOT \"%MAVEN_PROJECTBASEDIR%\"==\"\" goto endDetectBaseDir\n\nset EXEC_DIR=%CD%\nset WDIR=%EXEC_DIR%\n:findBaseDir\nIF EXIST \"%WDIR%\"\\.mvn goto baseDirFound\ncd ..\nIF \"%WDIR%\"==\"%CD%\" goto baseDirNotFound\nset WDIR=%CD%\ngoto findBaseDir\n\n:baseDirFound\nset MAVEN_PROJECTBASEDIR=%WDIR%\ncd \"%EXEC_DIR%\"\ngoto endDetectBaseDir\n\n:baseDirNotFound\nset MAVEN_PROJECTBASEDIR=%EXEC_DIR%\ncd \"%EXEC_DIR%\"\n\n:endDetectBaseDir\n\nIF NOT EXIST \"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\" goto endReadAdditionalConfig\n\n@setlocal EnableExtensions EnableDelayedExpansion\nfor /F \"usebackq delims=\" %%a in (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a\n@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%\n\n:endReadAdditionalConfig\n\nSET MAVEN_JAVA_EXE=\"%JAVA_HOME%\\bin\\java.exe\"\nset WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.jar\"\nset WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nset WRAPPER_URL=\"https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n\nFOR /F \"usebackq tokens=1,2 delims==\" %%A IN (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.properties\") DO (\n    IF \"%%A\"==\"wrapperUrl\" SET WRAPPER_URL=%%B\n)\n\n@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n@REM This allows using the maven wrapper in projects that prohibit checking in binary data.\nif exist %WRAPPER_JAR% (\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Found %WRAPPER_JAR%\n    )\n) else (\n    if not \"%MVNW_REPOURL%\" == \"\" (\n        SET WRAPPER_URL=\"%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar\"\n    )\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Couldn't find %WRAPPER_JAR%, downloading it ...\n        echo Downloading from: %WRAPPER_URL%\n    )\n\n    powershell -Command \"&{\"^\n\t\t\"$webclient = new-object System.Net.WebClient;\"^\n\t\t\"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {\"^\n\t\t\"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');\"^\n\t\t\"}\"^\n\t\t\"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')\"^\n\t\t\"}\"\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Finished downloading %WRAPPER_JAR%\n    )\n)\n@REM End of extension\n\n@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file\nSET WRAPPER_SHA_256_SUM=\"\"\nFOR /F \"usebackq tokens=1,2 delims==\" %%A IN (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.properties\") DO (\n    IF \"%%A\"==\"wrapperSha256Sum\" SET WRAPPER_SHA_256_SUM=%%B\n)\nIF NOT %WRAPPER_SHA_256_SUM%==\"\" (\n    powershell -Command \"&{\"^\n       \"$hash = (Get-FileHash \\\"%WRAPPER_JAR%\\\" -Algorithm SHA256).Hash.ToLower();\"^\n       \"If('%WRAPPER_SHA_256_SUM%' -ne $hash){\"^\n       \"  Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';\"^\n       \"  Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';\"^\n       \"  Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';\"^\n       \"  exit 1;\"^\n       \"}\"^\n       \"}\"\n    if ERRORLEVEL 1 goto error\n)\n\n@REM Provide a \"standardized\" way to retrieve the CLI args that will\n@REM work with both Windows and non-Windows executions.\nset MAVEN_CMD_LINE_ARGS=%*\n\n%MAVEN_JAVA_EXE% ^\n  %JVM_CONFIG_MAVEN_PROPS% ^\n  %MAVEN_OPTS% ^\n  %MAVEN_DEBUG_OPTS% ^\n  -classpath %WRAPPER_JAR% ^\n  \"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%\" ^\n  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*\nif ERRORLEVEL 1 goto error\ngoto end\n\n:error\nset ERROR_CODE=1\n\n:end\n@endlocal & set ERROR_CODE=%ERROR_CODE%\n\nif not \"%MAVEN_SKIP_RC%\"==\"\" goto skipRcPost\n@REM check for post script, once with legacy .bat ending and once with .cmd ending\nif exist \"%USERPROFILE%\\mavenrc_post.bat\" call \"%USERPROFILE%\\mavenrc_post.bat\"\nif exist \"%USERPROFILE%\\mavenrc_post.cmd\" call \"%USERPROFILE%\\mavenrc_post.cmd\"\n:skipRcPost\n\n@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'\nif \"%MAVEN_BATCH_PAUSE%\"==\"on\" pause\n\nif \"%MAVEN_TERMINATE_CMD%\"==\"on\" exit %ERROR_CODE%\n\ncmd /C exit /B %ERROR_CODE%\n"
  },
  {
    "path": "sb-ecom/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>org.springframework.boot</groupId>\n\t\t<artifactId>spring-boot-starter-parent</artifactId>\n\t\t<version>4.0.1</version>\n\t\t<relativePath/> <!-- lookup parent from repository -->\n\t</parent>\n\t<groupId>com.ecommerce</groupId>\n\t<artifactId>sb-ecom</artifactId>\n\t<version>0.0.1-SNAPSHOT</version>\n\t<name>sb-ecom</name>\n\t<description>Spring Boot Ecommerce Project</description>\n\t<properties>\n\t\t<java.version>24</java.version>\n\t</properties>\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-webmvc</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-data-jpa</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springdoc</groupId>\n\t\t\t<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>\n\t\t\t<version>3.0.0</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.stripe</groupId>\n\t\t\t<artifactId>stripe-java</artifactId>\n\t\t\t<version>29.3.0</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.postgresql</groupId>\n\t\t\t<artifactId>postgresql</artifactId>\n\t\t\t<scope>runtime</scope>\n\t\t</dependency>\n\n<!--\t\t<dependency>-->\n<!--\t\t\t<groupId>com.h2database</groupId>-->\n<!--\t\t\t<artifactId>h2</artifactId>-->\n<!--\t\t\t<scope>runtime</scope>-->\n<!--\t\t</dependency>-->\n\n\t\t<dependency>\n\t\t\t<groupId>org.projectlombok</groupId>\n\t\t\t<artifactId>lombok</artifactId>\n\t\t\t<optional>true</optional>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-validation</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-test</artifactId>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.modelmapper</groupId>\n\t\t\t<artifactId>modelmapper</artifactId>\n\t\t\t<version>3.0.0</version>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-security</artifactId>\n\t\t</dependency>\n\n\n\t\t<dependency>\n\t\t\t<groupId>io.jsonwebtoken</groupId>\n\t\t\t<artifactId>jjwt-api</artifactId>\n\t\t\t<version>0.13.0</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>io.jsonwebtoken</groupId>\n\t\t\t<artifactId>jjwt-impl</artifactId>\n\t\t\t<version>0.13.0</version>\n\t\t\t<scope>runtime</scope>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>io.jsonwebtoken</groupId>\n\t\t\t<artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->\n\t\t\t<version>0.13.0</version>\n\t\t\t<scope>runtime</scope>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.security</groupId>\n\t\t\t<artifactId>spring-security-test</artifactId>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t\t<artifactId>spring-boot-maven-plugin</artifactId>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n</project>\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/SbEcomApplication.java",
    "content": "package com.ecommerce.project;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\n\n@SpringBootApplication\npublic class SbEcomApplication {\n\n\tpublic static void main(String[] args) {\n\t\tSpringApplication.run(SbEcomApplication.class, args);\n\t}\n\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/config/AppConfig.java",
    "content": "package com.ecommerce.project.config;\n\nimport org.modelmapper.ModelMapper;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class AppConfig {\n\n    @Bean\n    public ModelMapper modelMapper(){\n        return new ModelMapper();\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/config/AppConstants.java",
    "content": "package com.ecommerce.project.config;\n\npublic class AppConstants {\n    public static final String PAGE_NUMBER = \"0\";\n    public static final String PAGE_SIZE = \"10\";\n    public static final String SORT_CATEGORIES_BY = \"categoryId\";\n    public static final String SORT_PRODUCTS_BY = \"productId\";\n    public static final String SORT_DIR = \"asc\";\n    public static final String SORT_ORDERS_BY = \"totalAmount\";\n    public static final String SORT_USERS_BY = \"userId\";\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/config/SwaggerConfig.java",
    "content": "package com.ecommerce.project.config;\n\nimport io.swagger.v3.oas.models.Components;\nimport io.swagger.v3.oas.models.ExternalDocumentation;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.info.Contact;\nimport io.swagger.v3.oas.models.info.Info;\nimport io.swagger.v3.oas.models.info.License;\nimport io.swagger.v3.oas.models.security.SecurityRequirement;\nimport io.swagger.v3.oas.models.security.SecurityScheme;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class SwaggerConfig {\n\n    @Bean\n    public OpenAPI customOpenAPI() {\n        SecurityScheme bearerScheme = new SecurityScheme()\n                .type(SecurityScheme.Type.HTTP)\n                .scheme(\"bearer\")\n                .bearerFormat(\"JWT\")\n                .description(\"JWT Bearer Token\");\n\n        SecurityRequirement bearerRequirement = new SecurityRequirement()\n                .addList(\"Bearer Authentication\");\n\n        return new OpenAPI()\n                .info(new Info()\n                        .title(\"Spring Boot eCommerce API\")\n                        .version(\"1.0\")\n                        .description(\"This is a Spring Boot Project for eCommerce\")\n                        .license(new License().name(\"Our License Link\").url(\"http://embarkx.com\"))\n                        .contact(new Contact()\n                                .name(\"Faisal Memon\")\n                                .email(\"faisal@embarkx.com\")\n                                .url(\"https://github.com/EmbarkxOfficial\")))\n                .externalDocs(new ExternalDocumentation()\n                        .description(\"Project Documentation\")\n                        .url(\"http://embarkx.com\"))\n                .components(new Components()\n                        .addSecuritySchemes(\"Bearer Authentication\", bearerScheme))\n                .addSecurityItem(bearerRequirement);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/config/WebMvcConfig.java",
    "content": "package com.ecommerce.project.config;\n\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;\nimport org.springframework.web.servlet.config.annotation.WebMvcConfigurer;\n\n@Configuration\npublic class WebMvcConfig implements WebMvcConfigurer {\n    @Override\n    public void addResourceHandlers(ResourceHandlerRegistry registry) {\n        registry.addResourceHandler(\"/images/**\").addResourceLocations(\"file:images/\");\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/controller/AddressController.java",
    "content": "package com.ecommerce.project.controller;\n\nimport com.ecommerce.project.model.User;\nimport com.ecommerce.project.payload.AddressDTO;\nimport com.ecommerce.project.service.AddressService;\nimport com.ecommerce.project.util.AuthUtil;\nimport jakarta.validation.Valid;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n\n@RestController\n@RequestMapping(\"/api\")\npublic class AddressController {\n\n    @Autowired\n    AuthUtil authUtil;\n\n    @Autowired\n    AddressService addressService;\n\n    @PostMapping(\"/addresses\")\n    public ResponseEntity<AddressDTO> createAddress(@Valid @RequestBody AddressDTO addressDTO){\n        User user = authUtil.loggedInUser();\n        AddressDTO savedAddressDTO = addressService.createAddress(addressDTO, user);\n        return new ResponseEntity<>(savedAddressDTO, HttpStatus.CREATED);\n    }\n\n    @GetMapping(\"/addresses\")\n    public ResponseEntity<List<AddressDTO>> getAddresses(){\n        List<AddressDTO> addressList = addressService.getAddresses();\n        return new ResponseEntity<>(addressList, HttpStatus.OK);\n    }\n\n    @GetMapping(\"/addresses/{addressId}\")\n    public ResponseEntity<AddressDTO> getAddressById(@PathVariable Long addressId){\n        AddressDTO addressDTO = addressService.getAddressesById(addressId);\n        return new ResponseEntity<>(addressDTO, HttpStatus.OK);\n    }\n\n\n    @GetMapping(\"/users/addresses\")\n    public ResponseEntity<List<AddressDTO>> getUserAddresses(){\n        User user = authUtil.loggedInUser();\n        List<AddressDTO> addressList = addressService.getUserAddresses(user);\n        return new ResponseEntity<>(addressList, HttpStatus.OK);\n    }\n\n    @PutMapping(\"/addresses/{addressId}\")\n    public ResponseEntity<AddressDTO> updateAddress(@PathVariable Long addressId\n            , @RequestBody AddressDTO addressDTO){\n        AddressDTO updatedAddress = addressService.updateAddress(addressId, addressDTO);\n        return new ResponseEntity<>(updatedAddress, HttpStatus.OK);\n    }\n\n    @DeleteMapping(\"/addresses/{addressId}\")\n    public ResponseEntity<String> updateAddress(@PathVariable Long addressId){\n        String status = addressService.deleteAddress(addressId);\n        return new ResponseEntity<>(status, HttpStatus.OK);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/controller/AnalyticsController.java",
    "content": "package com.ecommerce.project.controller;\n\nimport com.ecommerce.project.payload.AnalyticsResponse;\nimport com.ecommerce.project.service.AnalyticsService;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RestController;\n\n@RestController\n@RequestMapping(\"/api\")\npublic class AnalyticsController {\n\n    @Autowired\n    private AnalyticsService analyticsService;\n\n    @GetMapping(\"/admin/app/analytics\")\n    public ResponseEntity<AnalyticsResponse> getAnalytics() {\n        AnalyticsResponse response = analyticsService.getAnalyticsData();\n        return new ResponseEntity<AnalyticsResponse>(response, HttpStatus.OK);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/controller/AuthController.java",
    "content": "package com.ecommerce.project.controller;\n\nimport com.ecommerce.project.config.AppConstants;\nimport com.ecommerce.project.payload.AuthenticationResult;\nimport com.ecommerce.project.security.request.LoginRequest;\nimport com.ecommerce.project.security.request.SignupRequest;\nimport com.ecommerce.project.security.response.MessageResponse;\nimport com.ecommerce.project.service.AuthService;\nimport jakarta.validation.Valid;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.data.domain.PageRequest;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.domain.Sort;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.ResponseCookie;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.web.bind.annotation.*;\n\n@RestController\n@RequestMapping(\"/api/auth\")\npublic class AuthController {\n\n    @Autowired\n    AuthService authService;\n\n    @PostMapping(\"/signin\")\n    public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {\n        AuthenticationResult result = authService.login(loginRequest);\n        return ResponseEntity.ok().header(HttpHeaders.SET_COOKIE,\n                result.getJwtCookie().toString())\n                .body(result.getResponse());\n    }\n\n    @PostMapping(\"/signup\")\n    public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {\n        return authService.register(signUpRequest);\n    }\n\n    @GetMapping(\"/username\")\n    public String currentUserName(Authentication authentication){\n        if (authentication != null)\n            return authentication.getName();\n        else\n            return \"\";\n    }\n\n\n    @GetMapping(\"/user\")\n    public ResponseEntity<?> getUserDetails(Authentication authentication){\n        return ResponseEntity.ok().body(authService.getCurrentUserDetails(authentication));\n    }\n\n    @PostMapping(\"/signout\")\n    public ResponseEntity<?> signoutUser(){\n        ResponseCookie cookie = authService.logoutUser();\n        return ResponseEntity.ok().header(HttpHeaders.SET_COOKIE,\n                        cookie.toString())\n                .body(new MessageResponse(\"You've been signed out!\"));\n    }\n\n    @GetMapping(\"/sellers\")\n    public ResponseEntity<?> getAllSellers(\n            @RequestParam(name = \"pageNumber\", defaultValue = AppConstants.PAGE_NUMBER, required = false) Integer pageNumber) {\n\n        Sort sortByAndOrder = Sort.by(AppConstants.SORT_USERS_BY).descending();\n        Pageable pageDetails = PageRequest.of(pageNumber ,\n                Integer.parseInt(AppConstants.PAGE_SIZE), sortByAndOrder);\n\n        return ResponseEntity.ok(authService.getAllSellers(pageDetails));\n    }\n\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/controller/CartController.java",
    "content": "package com.ecommerce.project.controller;\n\nimport com.ecommerce.project.model.Cart;\nimport com.ecommerce.project.payload.CartDTO;\nimport com.ecommerce.project.payload.CartItemDTO;\nimport com.ecommerce.project.repositories.CartRepository;\nimport com.ecommerce.project.service.CartService;\nimport com.ecommerce.project.util.AuthUtil;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n\n@RestController\n@RequestMapping(\"/api\")\npublic class CartController {\n\n    @Autowired\n    private CartRepository cartRepository;\n\n    @Autowired\n    private AuthUtil authUtil;\n\n    @Autowired\n    private CartService cartService;\n\n    @PostMapping(\"/cart/create\")\n    public ResponseEntity<String> createOrUpdateCart(@RequestBody List<CartItemDTO> cartItems){\n        String response = cartService.createOrUpdateCartWithItems(cartItems);\n        return new ResponseEntity<>(response, HttpStatus.CREATED);\n    }\n\n    @PostMapping(\"/carts/products/{productId}/quantity/{quantity}\")\n    public ResponseEntity<CartDTO> addProductToCart(@PathVariable Long productId,\n                                                    @PathVariable Integer quantity){\n        CartDTO cartDTO = cartService.addProductToCart(productId, quantity);\n        return new ResponseEntity<CartDTO>(cartDTO, HttpStatus.CREATED);\n    }\n\n    @GetMapping(\"/carts\")\n    public ResponseEntity<List<CartDTO>> getCarts() {\n        List<CartDTO> cartDTOs = cartService.getAllCarts();\n        return new ResponseEntity<List<CartDTO>>(cartDTOs, HttpStatus.FOUND);\n    }\n\n    @GetMapping(\"/carts/users/cart\")\n    public ResponseEntity<CartDTO> getCartById(){\n        String emailId = authUtil.loggedInEmail();\n        Cart cart = cartRepository.findCartByEmail(emailId);\n        Long cartId = cart.getCartId();\n        CartDTO cartDTO = cartService.getCart(emailId, cartId);\n        return new ResponseEntity<CartDTO>(cartDTO, HttpStatus.OK);\n    }\n\n    @PutMapping(\"/cart/products/{productId}/quantity/{operation}\")\n    public ResponseEntity<CartDTO> updateCartProduct(@PathVariable Long productId,\n                                                     @PathVariable String operation) {\n\n        CartDTO cartDTO = cartService.updateProductQuantityInCart(productId,\n                operation.equalsIgnoreCase(\"delete\") ? -1 : 1);\n\n        return new ResponseEntity<CartDTO>(cartDTO, HttpStatus.OK);\n    }\n\n    @DeleteMapping(\"/carts/{cartId}/product/{productId}\")\n    public ResponseEntity<String> deleteProductFromCart(@PathVariable Long cartId,\n                                                        @PathVariable Long productId) {\n        String status = cartService.deleteProductFromCart(cartId, productId);\n\n        return new ResponseEntity<String>(status, HttpStatus.OK);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/controller/CategoryController.java",
    "content": "package com.ecommerce.project.controller;\n\nimport com.ecommerce.project.config.AppConstants;\nimport com.ecommerce.project.payload.CategoryDTO;\nimport com.ecommerce.project.payload.CategoryResponse;\nimport com.ecommerce.project.service.CategoryService;\nimport jakarta.validation.Valid;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.*;\n\n@RestController\n@RequestMapping(\"/api\")\npublic class CategoryController {\n\n    @Autowired\n    private CategoryService categoryService;\n\n    @GetMapping(\"/public/categories\")\n    public ResponseEntity<CategoryResponse> getAllCategories(\n            @RequestParam(name = \"pageNumber\", defaultValue = AppConstants.PAGE_NUMBER, required = false) Integer pageNumber,\n            @RequestParam(name = \"pageSize\", defaultValue = AppConstants.PAGE_SIZE, required = false) Integer pageSize,\n            @RequestParam(name = \"sortBy\", defaultValue = AppConstants.SORT_CATEGORIES_BY, required = false) String sortBy,\n            @RequestParam(name = \"sortOrder\", defaultValue = AppConstants.SORT_DIR, required = false) String sortOrder) {\n        CategoryResponse categoryResponse = categoryService.getAllCategories(pageNumber, pageSize, sortBy, sortOrder);\n        return new ResponseEntity<>(categoryResponse, HttpStatus.OK);\n    }\n\n    @PostMapping(\"/admin/categories\")\n    public ResponseEntity<CategoryDTO> createCategory(@Valid @RequestBody CategoryDTO categoryDTO){\n        CategoryDTO savedCategoryDTO = categoryService.createCategory(categoryDTO);\n        return new ResponseEntity<>(savedCategoryDTO, HttpStatus.CREATED);\n    }\n\n    @DeleteMapping(\"/admin/categories/{categoryId}\")\n    public ResponseEntity<CategoryDTO> deleteCategory(@PathVariable Long categoryId){\n            CategoryDTO deletedCategory = categoryService.deleteCategory(categoryId);\n            return new ResponseEntity<>(deletedCategory, HttpStatus.OK);\n    }\n\n\n    @PutMapping(\"/admin/categories/{categoryId}\")\n    public ResponseEntity<CategoryDTO> updateCategory(@Valid @RequestBody CategoryDTO categoryDTO,\n                                                 @PathVariable Long categoryId){\n            CategoryDTO savedCategoryDTO = categoryService.updateCategory(categoryDTO, categoryId);\n            return new ResponseEntity<>(savedCategoryDTO, HttpStatus.OK);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/controller/OrderController.java",
    "content": "package com.ecommerce.project.controller;\n\nimport com.ecommerce.project.config.AppConstants;\nimport com.ecommerce.project.payload.*;\nimport com.ecommerce.project.security.services.UserDetailsImpl;\nimport com.ecommerce.project.service.OrderService;\nimport com.ecommerce.project.service.StripeService;\nimport com.ecommerce.project.util.AuthUtil;\nimport com.stripe.exception.StripeException;\nimport com.stripe.model.PaymentIntent;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.web.bind.annotation.*;\n\n@RestController\n@RequestMapping(\"/api\")\npublic class OrderController {\n\n    @Autowired\n    private OrderService orderService;\n\n    @Autowired\n    private AuthUtil authUtil;\n\n    @Autowired\n    private StripeService stripeService;\n\n    @PostMapping(\"/order/users/payments/{paymentMethod}\")\n    public ResponseEntity<OrderDTO> orderProducts(@PathVariable String paymentMethod, @RequestBody OrderRequestDTO orderRequestDTO) {\n        String emailId = authUtil.loggedInEmail();\n        System.out.println(\"orderRequestDTO DATA: \" + orderRequestDTO);\n        OrderDTO order = orderService.placeOrder(\n                emailId,\n                orderRequestDTO.getAddressId(),\n                paymentMethod,\n                orderRequestDTO.getPgName(),\n                orderRequestDTO.getPgPaymentId(),\n                orderRequestDTO.getPgStatus(),\n                orderRequestDTO.getPgResponseMessage()\n        );\n        return new ResponseEntity<>(order, HttpStatus.CREATED);\n    }\n\n    @PostMapping(\"/order/stripe-client-secret\")\n    public ResponseEntity<String> createStripeClientSecret(@RequestBody StripePaymentDto stripePaymentDto) throws StripeException {\n        System.out.println(\"StripePaymentDTO Received \" + stripePaymentDto);\n        PaymentIntent paymentIntent = stripeService.paymentIntent(stripePaymentDto);\n        return new ResponseEntity<>(paymentIntent.getClientSecret(), HttpStatus.CREATED);\n    }\n\n    @GetMapping(\"/admin/orders\")\n    public ResponseEntity<OrderResponse> getAllOrders(\n            @RequestParam(name = \"pageNumber\", defaultValue = AppConstants.PAGE_NUMBER, required = false) Integer pageNumber,\n            @RequestParam(name = \"pageSize\", defaultValue = AppConstants.PAGE_SIZE, required = false) Integer pageSize,\n            @RequestParam(name = \"sortBy\", defaultValue = AppConstants.SORT_ORDERS_BY, required = false) String sortBy,\n            @RequestParam(name = \"sortOrder\", defaultValue = AppConstants.SORT_DIR, required = false) String sortOrder\n    ) {\n        OrderResponse orderResponse = orderService.getAllOrders(pageNumber, pageSize, sortBy, sortOrder);\n        return new ResponseEntity<OrderResponse>(orderResponse, HttpStatus.OK);\n    }\n\n    @GetMapping(\"/seller/orders\")\n    public ResponseEntity<OrderResponse> getAllSellerOrders(\n            @RequestParam(name = \"pageNumber\", defaultValue = AppConstants.PAGE_NUMBER, required = false) Integer pageNumber,\n            @RequestParam(name = \"pageSize\", defaultValue = AppConstants.PAGE_SIZE, required = false) Integer pageSize,\n            @RequestParam(name = \"sortBy\", defaultValue = AppConstants.SORT_ORDERS_BY, required = false) String sortBy,\n            @RequestParam(name = \"sortOrder\", defaultValue = AppConstants.SORT_DIR, required = false) String sortOrder\n    ) {\n        OrderResponse orderResponse = orderService.getAllSellerOrders(pageNumber, pageSize, sortBy, sortOrder);\n        return new ResponseEntity<OrderResponse>(orderResponse, HttpStatus.OK);\n    }\n\n    @PutMapping(\"/admin/orders/{orderId}/status\")\n    public ResponseEntity<OrderDTO> updateOrderStatus(@PathVariable Long orderId,\n                                                      @RequestBody OrderStatusUpdateDto orderStatusUpdateDto) {\n        OrderDTO order = orderService.updateOrder(orderId, orderStatusUpdateDto.getStatus());\n        return new ResponseEntity<OrderDTO>(order, HttpStatus.OK);\n    }\n\n    @PutMapping(\"/seller/orders/{orderId}/status\")\n    public ResponseEntity<OrderDTO> updateOrderStatusSeller(@PathVariable Long orderId,\n                                                      @RequestBody OrderStatusUpdateDto orderStatusUpdateDto) {\n        OrderDTO order = orderService.updateOrder(orderId, orderStatusUpdateDto.getStatus());\n        return new ResponseEntity<OrderDTO>(order, HttpStatus.OK);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/controller/ProductController.java",
    "content": "package com.ecommerce.project.controller;\n\nimport com.ecommerce.project.config.AppConstants;\nimport com.ecommerce.project.payload.ProductDTO;\nimport com.ecommerce.project.payload.ProductResponse;\nimport com.ecommerce.project.service.ProductService;\nimport jakarta.validation.Valid;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.*;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport java.io.IOException;\n\n@RestController\n@RequestMapping(\"/api\")\npublic class ProductController {\n\n    @Autowired\n    ProductService productService;\n\n    @PostMapping(\"/admin/categories/{categoryId}/product\")\n    public ResponseEntity<ProductDTO> addProduct(@Valid @RequestBody ProductDTO productDTO,\n                                                 @PathVariable Long categoryId){\n        ProductDTO savedProductDTO = productService.addProduct(categoryId, productDTO);\n        return new ResponseEntity<>(savedProductDTO, HttpStatus.CREATED);\n    }\n\n    @PostMapping(\"/seller/categories/{categoryId}/product\")\n    public ResponseEntity<ProductDTO> addProductSeller(@Valid @RequestBody ProductDTO productDTO,\n                                                 @PathVariable Long categoryId){\n        ProductDTO savedProductDTO = productService.addProduct(categoryId, productDTO);\n        return new ResponseEntity<>(savedProductDTO, HttpStatus.CREATED);\n    }\n\n    @GetMapping(\"/public/products\")\n    public ResponseEntity<ProductResponse> getAllProducts(\n            @RequestParam(name = \"keyword\", required = false) String keyword,\n            @RequestParam(name = \"category\", required = false) String category,\n            @RequestParam(name = \"pageNumber\", defaultValue = AppConstants.PAGE_NUMBER, required = false) Integer pageNumber,\n            @RequestParam(name = \"pageSize\", defaultValue = AppConstants.PAGE_SIZE, required = false) Integer pageSize,\n            @RequestParam(name = \"sortBy\", defaultValue = AppConstants.SORT_PRODUCTS_BY, required = false) String sortBy,\n            @RequestParam(name = \"sortOrder\", defaultValue = AppConstants.SORT_DIR, required = false) String sortOrder\n    ){\n        ProductResponse productResponse = productService.getAllProducts(pageNumber, pageSize, sortBy, sortOrder, keyword, category);\n        return new ResponseEntity<>(productResponse,HttpStatus.OK);\n    }\n\n    @GetMapping(\"/public/categories/{categoryId}/products\")\n    public ResponseEntity<ProductResponse> getProductsByCategory(@PathVariable Long categoryId,\n                                                                 @RequestParam(name = \"pageNumber\", defaultValue = AppConstants.PAGE_NUMBER, required = false) Integer pageNumber,\n                                                                 @RequestParam(name = \"pageSize\", defaultValue = AppConstants.PAGE_SIZE, required = false) Integer pageSize,\n                                                                 @RequestParam(name = \"sortBy\", defaultValue = AppConstants.SORT_PRODUCTS_BY, required = false) String sortBy,\n                                                                 @RequestParam(name = \"sortOrder\", defaultValue = AppConstants.SORT_DIR, required = false) String sortOrder){\n        ProductResponse productResponse = productService.searchByCategory(categoryId, pageNumber, pageSize, sortBy, sortOrder);\n        return new ResponseEntity<>(productResponse, HttpStatus.OK);\n    }\n\n    @GetMapping(\"/public/products/keyword/{keyword}\")\n    public ResponseEntity<ProductResponse> getProductsByKeyword(@PathVariable String keyword,\n                                                                @RequestParam(name = \"pageNumber\", defaultValue = AppConstants.PAGE_NUMBER, required = false) Integer pageNumber,\n                                                                @RequestParam(name = \"pageSize\", defaultValue = AppConstants.PAGE_SIZE, required = false) Integer pageSize,\n                                                                @RequestParam(name = \"sortBy\", defaultValue = AppConstants.SORT_PRODUCTS_BY, required = false) String sortBy,\n                                                                @RequestParam(name = \"sortOrder\", defaultValue = AppConstants.SORT_DIR, required = false) String sortOrder){\n        ProductResponse productResponse = productService.searchProductByKeyword(keyword, pageNumber, pageSize, sortBy, sortOrder);\n        return new ResponseEntity<>(productResponse, HttpStatus.FOUND);\n    }\n\n    @PutMapping(\"/admin/products/{productId}\")\n    public ResponseEntity<ProductDTO> updateProduct(@Valid @RequestBody ProductDTO productDTO,\n                                                    @PathVariable Long productId){\n        ProductDTO updatedProductDTO = productService.updateProduct(productId, productDTO);\n        return new ResponseEntity<>(updatedProductDTO, HttpStatus.OK);\n    }\n\n    @DeleteMapping(\"/admin/products/{productId}\")\n    public ResponseEntity<ProductDTO> deleteProduct(@PathVariable Long productId){\n        ProductDTO deletedProduct = productService.deleteProduct(productId);\n        return new ResponseEntity<>(deletedProduct, HttpStatus.OK);\n    }\n\n    @PutMapping(\"/admin/products/{productId}/image\")\n    public ResponseEntity<ProductDTO> updateProductImage(@PathVariable Long productId,\n                                                         @RequestParam(\"image\")MultipartFile image) throws IOException {\n        ProductDTO updatedProduct = productService.updateProductImage(productId, image);\n        return new ResponseEntity<>(updatedProduct, HttpStatus.OK);\n    }\n\n\n    @GetMapping(\"/admin/products\")\n    public ResponseEntity<ProductResponse> getAllProductsForAdmin(\n            @RequestParam(name = \"pageNumber\", defaultValue = AppConstants.PAGE_NUMBER, required = false) Integer pageNumber,\n            @RequestParam(name = \"pageSize\", defaultValue = AppConstants.PAGE_SIZE, required = false) Integer pageSize,\n            @RequestParam(name = \"sortBy\", defaultValue = AppConstants.SORT_PRODUCTS_BY, required = false) String sortBy,\n            @RequestParam(name = \"sortOrder\", defaultValue = AppConstants.SORT_DIR, required = false) String sortOrder\n    ){\n        ProductResponse productResponse = productService.getAllProductsForAdmin(pageNumber, pageSize, sortBy, sortOrder);\n        return new ResponseEntity<>(productResponse,HttpStatus.OK);\n    }\n\n\n    @GetMapping(\"/seller/products\")\n    public ResponseEntity<ProductResponse> getAllProductsForSeller(\n            @RequestParam(name = \"pageNumber\", defaultValue = AppConstants.PAGE_NUMBER, required = false) Integer pageNumber,\n            @RequestParam(name = \"pageSize\", defaultValue = AppConstants.PAGE_SIZE, required = false) Integer pageSize,\n            @RequestParam(name = \"sortBy\", defaultValue = AppConstants.SORT_PRODUCTS_BY, required = false) String sortBy,\n            @RequestParam(name = \"sortOrder\", defaultValue = AppConstants.SORT_DIR, required = false) String sortOrder\n    ){\n        ProductResponse productResponse = productService.getAllProductsForSeller(pageNumber, pageSize, sortBy, sortOrder);\n        return new ResponseEntity<>(productResponse,HttpStatus.OK);\n    }\n\n    @PutMapping(\"/seller/products/{productId}\")\n    public ResponseEntity<ProductDTO> updateProductSeller(@Valid @RequestBody ProductDTO productDTO,\n                                                    @PathVariable Long productId){\n        ProductDTO updatedProductDTO = productService.updateProduct(productId, productDTO);\n        return new ResponseEntity<>(updatedProductDTO, HttpStatus.OK);\n    }\n\n    @DeleteMapping(\"/seller/products/{productId}\")\n    public ResponseEntity<ProductDTO> deleteProductSeller(@PathVariable Long productId){\n        ProductDTO deletedProduct = productService.deleteProduct(productId);\n        return new ResponseEntity<>(deletedProduct, HttpStatus.OK);\n    }\n\n    @PutMapping(\"/seller/products/{productId}/image\")\n    public ResponseEntity<ProductDTO> updateProductImageSeller(@PathVariable Long productId,\n                                                         @RequestParam(\"image\")MultipartFile image) throws IOException {\n        ProductDTO updatedProduct = productService.updateProductImage(productId, image);\n        return new ResponseEntity<>(updatedProduct, HttpStatus.OK);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/exceptions/APIException.java",
    "content": "package com.ecommerce.project.exceptions;\n\npublic class APIException extends RuntimeException {\n    private static final long serialVersionUID = 1L;\n\n    public APIException() {\n    }\n\n    public APIException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/exceptions/MyGlobalExceptionHandler.java",
    "content": "package com.ecommerce.project.exceptions;\n\n\nimport com.ecommerce.project.payload.APIResponse;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.validation.FieldError;\nimport org.springframework.web.bind.MethodArgumentNotValidException;\nimport org.springframework.web.bind.annotation.ExceptionHandler;\nimport org.springframework.web.bind.annotation.RestControllerAdvice;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n@RestControllerAdvice\npublic class MyGlobalExceptionHandler {\n\n    @ExceptionHandler(MethodArgumentNotValidException.class)\n    public ResponseEntity<Map<String, String>> myMethodArgumentNotValidException(MethodArgumentNotValidException e) {\n        Map<String, String> response = new HashMap<>();\n        e.getBindingResult().getAllErrors().forEach(err -> {\n            String fieldName = ((FieldError) err).getField();\n            String message = err.getDefaultMessage();\n            response.put(fieldName, message);\n        });\n        return new ResponseEntity<Map<String, String>>(response,\n                HttpStatus.BAD_REQUEST);\n    }\n\n    @ExceptionHandler(ResourceNotFoundException.class)\n    public ResponseEntity<APIResponse> myResourceNotFoundException(ResourceNotFoundException e) {\n        String message = e.getMessage();\n        APIResponse apiResponse = new APIResponse(message, false);\n        return new ResponseEntity<>(apiResponse, HttpStatus.NOT_FOUND);\n    }\n\n    @ExceptionHandler(APIException.class)\n    public ResponseEntity<APIResponse> myAPIException(APIException e) {\n        String message = e.getMessage();\n        APIResponse apiResponse = new APIResponse(message, false);\n        return new ResponseEntity<>(apiResponse, HttpStatus.BAD_REQUEST);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/exceptions/ResourceNotFoundException.java",
    "content": "package com.ecommerce.project.exceptions;\n\npublic class ResourceNotFoundException extends RuntimeException {\n    String resourceName;\n    String field;\n    String fieldName;\n    Long fieldId;\n\n    public ResourceNotFoundException() {\n    }\n\n    public ResourceNotFoundException(String resourceName, String field, String fieldName) {\n        super(String.format(\"%s not found with %s: %s\", resourceName, field, fieldName));\n        this.resourceName = resourceName;\n        this.field = field;\n        this.fieldName = fieldName;\n    }\n\n    public ResourceNotFoundException(String resourceName, String field, Long fieldId) {\n        super(String.format(\"%s not found with %s: %d\", resourceName, field, fieldId));\n        this.resourceName = resourceName;\n        this.field = field;\n        this.fieldId = fieldId;\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/Address.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport jakarta.validation.constraints.NotBlank;\nimport jakarta.validation.constraints.Size;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\nimport lombok.ToString;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n@Entity\n@Table(name = \"addresses\")\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class Address {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long addressId;\n\n    @NotBlank\n    @Size(min = 5, message = \"Street name must be atleast 5 characters\")\n    private String street;\n\n    @NotBlank\n    @Size(min = 5, message = \"Building name must be atleast 5 characters\")\n    private String buildingName;\n\n    @NotBlank\n    @Size(min = 4, message = \"City name must be atleast 4 characters\")\n    private String city;\n\n    @NotBlank\n    @Size(min = 2, message = \"State name must be atleast 2 characters\")\n    private String state;\n\n    @NotBlank\n    @Size(min = 2, message = \"Country name must be atleast 2 characters\")\n    private String country;\n\n    @NotBlank\n    @Size(min = 5, message = \"Pincode must be atleast 5 characters\")\n    private String pincode;\n\n    @ManyToOne\n    @JoinColumn(name = \"user_id\")\n    private User user;\n\n    public Address(String street, String buildingName, String city, String state, String country, String pincode) {\n        this.street = street;\n        this.buildingName = buildingName;\n        this.city = city;\n        this.state = state;\n        this.country = country;\n        this.pincode = pincode;\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/AppRole.java",
    "content": "package com.ecommerce.project.model;\n\npublic enum AppRole {\n    ROLE_USER,\n    ROLE_SELLER,\n    ROLE_ADMIN\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/Cart.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n@Entity\n@Data\n@Table(name = \"carts\")\n@NoArgsConstructor\n@AllArgsConstructor\npublic class Cart {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long cartId;\n\n    @OneToOne\n    @JoinColumn(name = \"user_id\")\n    private User user;\n\n    @OneToMany(mappedBy = \"cart\", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, orphanRemoval = true)\n    private List<CartItem> cartItems = new ArrayList<>();\n\n    private Double totalPrice = 0.0;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/CartItem.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Entity\n@Data\n@Table(name = \"cart_items\")\n@NoArgsConstructor\n@AllArgsConstructor\npublic class CartItem {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long cartItemId;\n\n    @ManyToOne\n    @JoinColumn(name = \"cart_id\")\n    private Cart cart;\n\n    @ManyToOne\n    @JoinColumn(name = \"product_id\")\n    private Product product;\n\n    private Integer quantity;\n    private double discount;\n    private double productPrice;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/Category.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport jakarta.validation.constraints.NotBlank;\nimport jakarta.validation.constraints.Size;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.List;\n\n@Entity(name = \"categories\")\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class Category {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long categoryId;\n\n    @NotBlank\n    @Size(min = 5, message = \"Category name must contain atleast 5 characters\")\n    private String categoryName;\n\n    @OneToMany(mappedBy = \"category\", cascade = CascadeType.ALL)\n    private List<Product> products;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/Order.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport jakarta.validation.constraints.Email;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@Entity\n@Table(name = \"orders\")\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class Order {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long orderId;\n\n    @Email\n    @Column(nullable = false)\n    private String email;\n\n    @OneToMany(mappedBy = \"order\", cascade = { CascadeType.PERSIST, CascadeType.MERGE })\n    private List<OrderItem> orderItems = new ArrayList<>();\n\n    private LocalDate orderDate;\n\n    @OneToOne\n    @JoinColumn(name = \"payment_id\")\n    private Payment payment;\n\n    private Double totalAmount;\n    private String orderStatus;\n\n    // Reference to Address\n    @ManyToOne\n    @JoinColumn(name = \"address_id\")\n    private Address address;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/OrderItem.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Entity\n@Data\n@Table(name = \"order_items\")\n@AllArgsConstructor\n@NoArgsConstructor\npublic class OrderItem {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long orderItemId;\n\n    @ManyToOne\n    @JoinColumn(name = \"product_id\")\n    private Product product;\n\n    @ManyToOne\n    @JoinColumn(name = \"order_id\")\n    private Order order;\n\n    private Integer quantity;\n    private double discount;\n    private double orderedProductPrice;\n\n}"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/Payment.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport jakarta.validation.constraints.NotBlank;\nimport jakarta.validation.constraints.Size;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Entity\n@Table(name = \"payments\")\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class Payment {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long paymentId;\n\n    @OneToOne(mappedBy = \"payment\", cascade = { CascadeType.PERSIST, CascadeType.MERGE })\n    private Order order;\n\n    @NotBlank\n    @Size(min = 4, message = \"Payment method must contain at least 4 characters\")\n    private String paymentMethod;\n\t\n    private String pgPaymentId;\n    private String pgStatus;\n    private String pgResponseMessage;\n\n    private String pgName;\n\n\n    public Payment(String paymentMethod, String pgPaymentId, String pgStatus,\n                   String pgResponseMessage, String pgName) {\n        this.paymentMethod = paymentMethod;\n        this.pgPaymentId = pgPaymentId;\n        this.pgStatus = pgStatus;\n        this.pgResponseMessage = pgResponseMessage;\n        this.pgName = pgName;\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/Product.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport jakarta.validation.constraints.NotBlank;\nimport jakarta.validation.constraints.Size;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\nimport lombok.ToString;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n@Entity\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\n@Table(name = \"products\")\n@ToString\npublic class Product {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.AUTO)\n    private Long productId;\n\n    @NotBlank\n    @Size(min = 3, message = \"Product name must contain atleast 3 characters\")\n    private String productName;\n    private String image;\n\n    @NotBlank\n    @Size(min = 6, message = \"Product description must contain atleast 6 characters\")\n    private String description;\n    private Integer quantity;\n    private double price;\n    private double discount;\n    private double specialPrice;\n\n    @ManyToOne\n    @JoinColumn(name = \"category_id\")\n    private Category category;\n\n    @ManyToOne\n    @JoinColumn(name = \"seller_id\")\n    private User user;\n\n    @OneToMany(mappedBy = \"product\", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)\n    private List<CartItem> products = new ArrayList<>();\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/Role.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\nimport lombok.ToString;\n\n@Entity\n@NoArgsConstructor\n@AllArgsConstructor\n@Data\n@Table(name = \"roles\")\npublic class Role {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    @Column(name = \"role_id\")\n    private Integer roleId;\n\n    @ToString.Exclude\n    @Enumerated(EnumType.STRING)\n    @Column(length = 20, name = \"role_name\")\n    private AppRole roleName;\n\n    public Role(AppRole roleName) {\n        this.roleName = roleName;\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/model/User.java",
    "content": "package com.ecommerce.project.model;\n\nimport jakarta.persistence.*;\nimport jakarta.validation.constraints.Email;\nimport jakarta.validation.constraints.NotBlank;\nimport jakarta.validation.constraints.Size;\nimport lombok.*;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n@Entity\n@Getter\n@Setter\n@NoArgsConstructor\n@Table(name = \"users\",\n        uniqueConstraints = {\n        @UniqueConstraint(columnNames = \"username\"),\n        @UniqueConstraint(columnNames = \"email\")\n        })\npublic class User {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    @Column(name = \"user_id\")\n    private Long userId;\n\n    @NotBlank\n    @Size(max = 20)\n    @Column(name = \"username\")\n    private String userName;\n\n    @NotBlank\n    @Size(max = 50)\n    @Email\n    @Column(name = \"email\")\n    private String email;\n\n    @NotBlank\n    @Size(max = 120)\n    @Column(name = \"password\")\n    private String password;\n\n    public User(String userName, String email, String password) {\n        this.userName = userName;\n        this.email = email;\n        this.password = password;\n    }\n\n    @Setter\n    @Getter\n    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE},\n                fetch = FetchType.EAGER)\n    @JoinTable(name = \"user_role\",\n                joinColumns = @JoinColumn(name = \"user_id\"),\n                inverseJoinColumns = @JoinColumn(name = \"role_id\"))\n    private Set<Role> roles = new HashSet<>();\n\n    @Getter\n    @Setter\n    @OneToMany(mappedBy = \"user\", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval = true)\n//    @JoinTable(name = \"user_address\",\n//                joinColumns = @JoinColumn(name = \"user_id\"),\n//                inverseJoinColumns = @JoinColumn(name = \"address_id\"))\n    private List<Address> addresses = new ArrayList<>();\n\n    @ToString.Exclude\n    @OneToOne(mappedBy = \"user\", cascade = { CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval = true)\n    private Cart cart;\n\n    @ToString.Exclude\n    @OneToMany(mappedBy = \"user\",\n            cascade = {CascadeType.PERSIST, CascadeType.MERGE},\n            orphanRemoval = true)\n    private Set<Product> products;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/APIResponse.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class APIResponse {\n    public String message;\n    private boolean status;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/AddressDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class AddressDTO {\n    private Long addressId;\n    private String street;\n    private String buildingName;\n    private String city;\n    private String state;\n    private String country;\n    private String pincode;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/AnalyticsResponse.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class AnalyticsResponse {\n    private String productCount;\n    private String totalRevenue;\n    private String totalOrders;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/AuthenticationResult.java",
    "content": "package com.ecommerce.project.payload;\n\nimport com.ecommerce.project.security.response.UserInfoResponse;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport org.springframework.http.ResponseCookie;\n\n@Data\n@AllArgsConstructor\npublic class AuthenticationResult {\n    private final UserInfoResponse response;\n    private final ResponseCookie jwtCookie;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/CartDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class CartDTO {\n    private Long cartId;\n    private Double totalPrice = 0.0;\n    private List<ProductDTO> products = new ArrayList<>();\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/CartItemDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class CartItemDTO {\n    private Long productId;\n    private Integer quantity;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/CategoryDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class CategoryDTO {\n    private Long categoryId;\n    private String categoryName;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/CategoryResponse.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.List;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class CategoryResponse {\n    private List<CategoryDTO> content;\n    private Integer pageNumber;\n    private Integer pageSize;\n    private Long totalElements;\n    private Integer totalPages;\n    private boolean lastPage;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/OrderDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.time.LocalDate;\nimport java.util.List;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class OrderDTO {\n    private Long orderId;\n    private String email;\n    private List<OrderItemDTO> orderItems;\n    private LocalDate orderDate;\n    private PaymentDTO payment;\n    private Double totalAmount;\n    private String orderStatus;\n    private Long addressId;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/OrderItemDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class OrderItemDTO {\n    private Long orderItemId;\n    private ProductDTO product;\n    private Integer quantity;\n    private double discount;\n    private double orderedProductPrice;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/OrderRequestDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class OrderRequestDTO {\n    private Long addressId;\n    private String paymentMethod;\n    private String pgName;\n    private String pgPaymentId;\n    private String pgStatus;\n    private String pgResponseMessage;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/OrderResponse.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.List;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class OrderResponse {\n    private List<OrderDTO> content;\n    private Integer pageNumber;\n    private Integer pageSize;\n    private Long totalElements;\n    private Integer totalPages;\n    private boolean lastPage;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/OrderStatusUpdateDto.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.Data;\n\n@Data\npublic class OrderStatusUpdateDto {\n    private String status;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/PaymentDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class PaymentDTO {\n    private Long paymentId;\n    private String paymentMethod;\n    private String pgPaymentId;\n    private String pgStatus;\n    private String pgResponseMessage;\n    private String pgName;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/ProductDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class ProductDTO {\n    private Long productId;\n    private String productName;\n    private String image;\n    private String description;\n    private Integer quantity;\n    private double price;\n    private double discount;\n    private double specialPrice;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/ProductResponse.java",
    "content": "package com.ecommerce.project.payload;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.List;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class ProductResponse {\n    private List<ProductDTO> content;\n    private Integer pageNumber;\n    private Integer pageSize;\n    private Long totalElements;\n    private Integer totalPages;\n    private boolean lastPage;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/StripePaymentDto.java",
    "content": "package com.ecommerce.project.payload;\n\nimport com.ecommerce.project.model.Address;\nimport lombok.Data;\n\nimport java.util.Map;\n\n@Data\npublic class StripePaymentDto {\n    private Long amount;\n    private String currency;\n    private String email;\n    private String name;\n    private Address address;\n    private String description;\n    private Map<String, String> metadata;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/UserDTO.java",
    "content": "package com.ecommerce.project.payload;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\nimport com.ecommerce.project.model.Role;\n\nimport com.ecommerce.project.model.Role;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class UserDTO {\n\t\n\tprivate Long userId;\n\tprivate String username;\n\tprivate String email;\n\tprivate String password;\n\tprivate Set<Role> roles = new HashSet<>();\n\tprivate AddressDTO address;\n\tprivate CartDTO cart;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/payload/UserResponse.java",
    "content": "package com.ecommerce.project.payload;\n\nimport java.util.List;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class UserResponse {\n\t\n\tprivate List<UserDTO> content;\n\tprivate Integer pageNumber;\n\tprivate Integer pageSize;\n\tprivate Long totalElements;\n\tprivate Integer totalPages;\n\tprivate boolean lastPage;\n\t\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/AddressRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\nimport com.ecommerce.project.model.Address;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\npublic interface AddressRepository extends JpaRepository<Address, Long> {\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/CartItemRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\nimport com.ecommerce.project.model.CartItem;\nimport org.springframework.data.jpa.repository.JpaRepository;\nimport org.springframework.data.jpa.repository.Modifying;\nimport org.springframework.data.jpa.repository.Query;\n\npublic interface CartItemRepository extends JpaRepository<CartItem, Long> {\n    @Query(\"SELECT ci FROM CartItem ci WHERE ci.cart.id = ?1 AND ci.product.id = ?2\")\n    CartItem findCartItemByProductIdAndCartId(Long cartId, Long productId);\n\n    @Modifying\n    @Query(\"DELETE FROM CartItem ci WHERE ci.cart.id = ?1 AND ci.product.id = ?2\")\n    void deleteCartItemByProductIdAndCartId(Long cartId, Long productId);\n\n    @Modifying\n    @Query(\"DELETE FROM CartItem ci WHERE ci.cart.id = ?1\")\n    void deleteAllByCartId(Long cartId);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/CartRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\nimport com.ecommerce.project.model.Cart;\nimport org.springframework.data.jpa.repository.JpaRepository;\nimport org.springframework.data.jpa.repository.Query;\n\nimport java.util.List;\n\npublic interface CartRepository extends JpaRepository<Cart, Long> {\n    @Query(\"SELECT c FROM Cart c WHERE c.user.email = ?1\")\n    Cart findCartByEmail(String email);\n\n    @Query(\"SELECT c FROM Cart c WHERE c.user.email = ?1 AND c.id = ?2\")\n    Cart findCartByEmailAndCartId(String emailId, Long cartId);\n\n    @Query(\"SELECT c FROM Cart c JOIN FETCH c.cartItems ci JOIN FETCH ci.product p WHERE p.id = ?1\")\n    List<Cart> findCartsByProductId(Long productId);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/CategoryRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\nimport com.ecommerce.project.model.Category;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\npublic interface CategoryRepository extends JpaRepository<Category,Long> {\n    Category findByCategoryName(String categoryName);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/OrderItemRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\n\nimport org.springframework.data.jpa.repository.JpaRepository;\nimport org.springframework.stereotype.Repository;\n\nimport com.ecommerce.project.model.OrderItem;\n\n@Repository\npublic interface OrderItemRepository extends JpaRepository<OrderItem, Long> {\n\n}"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/OrderRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\n\nimport org.springframework.data.jpa.repository.JpaRepository;\nimport org.springframework.data.jpa.repository.Query;\nimport org.springframework.stereotype.Repository;\n\nimport com.ecommerce.project.model.Order;\n\n@Repository\npublic interface OrderRepository extends JpaRepository<Order, Long> {\n\n    @Query(\"SELECT COALESCE(SUM(o.totalAmount), 0) FROM Order o\")\n    Double getTotalRevenue();\n}"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/PaymentRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\n\nimport org.springframework.data.jpa.repository.JpaRepository;\nimport org.springframework.stereotype.Repository;\n\nimport com.ecommerce.project.model.Payment;\n\n@Repository\npublic interface PaymentRepository extends JpaRepository<Payment, Long>{\n\n}"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/ProductRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\nimport com.ecommerce.project.model.Category;\nimport com.ecommerce.project.model.Product;\nimport com.ecommerce.project.model.User;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.jpa.repository.JpaRepository;\nimport org.springframework.data.jpa.repository.JpaSpecificationExecutor;\nimport org.springframework.stereotype.Repository;\n\n@Repository\npublic interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {\n    Page<Product> findByCategoryOrderByPriceAsc(Category category, Pageable pageDetails);\n\n    Page<Product> findByProductNameLikeIgnoreCase(String keyword, Pageable pageDetails);\n\n    Page<Product> findByUser(User user, Pageable pageDetails);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/RoleRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\nimport com.ecommerce.project.model.AppRole;\nimport com.ecommerce.project.model.Role;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\nimport java.util.Optional;\n\npublic interface RoleRepository extends JpaRepository<Role, Long> {\n    Optional<Role> findByRoleName(AppRole appRole);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/repositories/UserRepository.java",
    "content": "package com.ecommerce.project.repositories;\n\nimport com.ecommerce.project.model.AppRole;\nimport com.ecommerce.project.model.User;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.jpa.repository.JpaRepository;\nimport org.springframework.data.jpa.repository.Query;\nimport org.springframework.data.repository.query.Param;\nimport org.springframework.stereotype.Repository;\n\nimport java.util.Optional;\n\n@Repository\npublic interface UserRepository extends JpaRepository<User, Long> {\n\n    Optional<User> findByUserName(String username);\n\n    Boolean existsByUserName(String username);\n\n    Boolean existsByEmail(String email);\n\n    @Query(\"SELECT u FROM User u JOIN u.roles r WHERE r.roleName = :role\")\n    Page<User> findByRoleName(@Param(\"role\") AppRole role, Pageable pageable);\n\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/WebConfig.java",
    "content": "package com.ecommerce.project.security;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.web.servlet.config.annotation.CorsRegistry;\nimport org.springframework.web.servlet.config.annotation.WebMvcConfigurer;\n\n@Configuration\npublic class WebConfig implements WebMvcConfigurer {\n\n    @Value(\"${frontend.url}\")\n    String frontEndUrl;\n\n    @Override\n    public void addCorsMappings(CorsRegistry registry) {\n        registry.addMapping(\"/**\")\n                .allowedOrigins(\"http://localhost:3000\", frontEndUrl)\n                .allowedMethods(\"GET\",\"POST\",\"PUT\",\"DELETE\",\"OPTIONS\")\n                .allowedHeaders(\"*\")\n                .allowCredentials(true);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/WebSecurityConfig.java",
    "content": "package com.ecommerce.project.security;\n\nimport com.ecommerce.project.model.AppRole;\nimport com.ecommerce.project.model.Role;\nimport com.ecommerce.project.model.User;\nimport com.ecommerce.project.repositories.RoleRepository;\nimport com.ecommerce.project.repositories.UserRepository;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.CommandLineRunner;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.security.authentication.AuthenticationManager;\nimport org.springframework.security.authentication.dao.DaoAuthenticationProvider;\n//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;\nimport org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;\nimport org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;\nimport org.springframework.security.config.annotation.web.builders.HttpSecurity;\n//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;\n//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;\nimport org.springframework.security.config.annotation.web.builders.WebSecurity;\nimport org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;\nimport org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;\nimport org.springframework.security.config.http.SessionCreationPolicy;\nimport org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;\nimport org.springframework.security.crypto.password.PasswordEncoder;\nimport org.springframework.security.web.SecurityFilterChain;\nimport org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;\n\nimport com.ecommerce.project.security.jwt.AuthEntryPointJwt;\nimport com.ecommerce.project.security.jwt.AuthTokenFilter;\nimport com.ecommerce.project.security.services.UserDetailsServiceImpl;\n\nimport java.util.Set;\n\n@Configuration\n@EnableWebSecurity\n//@EnableMethodSecurity\npublic class WebSecurityConfig {\n    @Autowired\n    UserDetailsServiceImpl userDetailsService;\n\n    @Autowired\n    private AuthEntryPointJwt unauthorizedHandler;\n\n    @Bean\n    public AuthTokenFilter authenticationJwtTokenFilter() {\n        return new AuthTokenFilter();\n    }\n\n\n    @Bean\n    public DaoAuthenticationProvider authenticationProvider() {\n        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(userDetailsService);\n\n//        authProvider.setUserDetailsService(userDetailsService);\n        authProvider.setPasswordEncoder(passwordEncoder());\n\n        return authProvider;\n    }\n\n\n    @Bean\n    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {\n        return authConfig.getAuthenticationManager();\n    }\n\n    @Bean\n    public PasswordEncoder passwordEncoder() {\n        return new BCryptPasswordEncoder();\n    }\n\n\n\n    @Bean\n    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {\n        http.csrf(csrf -> csrf.disable())\n                .cors(cors -> {})\n                .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))\n                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))\n                .authorizeHttpRequests(auth ->\n                        auth.requestMatchers(\"/api/auth/**\").permitAll()\n                                .requestMatchers(\"/v3/api-docs/**\").permitAll()\n                                .requestMatchers(\"/h2-console/**\").permitAll()\n                                .requestMatchers(\"/api/admin/**\").hasRole(\"ADMIN\")\n                                .requestMatchers(\"/api/seller/**\").hasAnyRole(\"ADMIN\",\"SELLER\")\n                                //.requestMatchers(\"/api/admin/**\").permitAll()\n                                .requestMatchers(\"/api/public/**\").permitAll()\n                                .requestMatchers(\"/swagger-ui/**\").permitAll()\n                                .requestMatchers(\"/api/test/**\").permitAll()\n                                .requestMatchers(\"/images/**\").permitAll()\n                                .requestMatchers(HttpMethod.OPTIONS, \"/**\").permitAll()\n                                .anyRequest().authenticated()\n                );\n\n        http.authenticationProvider(authenticationProvider());\n\n        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);\n        http.headers(headers -> headers.frameOptions(\n                frameOptions -> frameOptions.sameOrigin()));\n\n        return http.build();\n    }\n\n    @Bean\n    public WebSecurityCustomizer webSecurityCustomizer() {\n        return (web -> web.ignoring().requestMatchers(\"/v2/api-docs\",\n                \"/configuration/ui\",\n                \"/swagger-resources/**\",\n                \"/configuration/security\",\n                \"/swagger-ui.html\",\n                \"/webjars/**\"));\n    }\n\n\n    @Bean\n    public CommandLineRunner initData(RoleRepository roleRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) {\n        return args -> {\n            // Retrieve or create roles\n            Role userRole = roleRepository.findByRoleName(AppRole.ROLE_USER)\n                    .orElseGet(() -> {\n                        Role newUserRole = new Role(AppRole.ROLE_USER);\n                        return roleRepository.save(newUserRole);\n                    });\n\n            Role sellerRole = roleRepository.findByRoleName(AppRole.ROLE_SELLER)\n                    .orElseGet(() -> {\n                        Role newSellerRole = new Role(AppRole.ROLE_SELLER);\n                        return roleRepository.save(newSellerRole);\n                    });\n\n            Role adminRole = roleRepository.findByRoleName(AppRole.ROLE_ADMIN)\n                    .orElseGet(() -> {\n                        Role newAdminRole = new Role(AppRole.ROLE_ADMIN);\n                        return roleRepository.save(newAdminRole);\n                    });\n\n            Set<Role> userRoles = Set.of(userRole);\n            Set<Role> sellerRoles = Set.of(sellerRole);\n            Set<Role> adminRoles = Set.of(userRole, sellerRole, adminRole);\n\n\n            // Create users if not already present\n            if (!userRepository.existsByUserName(\"user1\")) {\n                User user1 = new User(\"user1\", \"user1@example.com\", passwordEncoder.encode(\"password1\"));\n                userRepository.save(user1);\n            }\n\n            if (!userRepository.existsByUserName(\"seller1\")) {\n                User seller1 = new User(\"seller1\", \"seller1@example.com\", passwordEncoder.encode(\"password2\"));\n                userRepository.save(seller1);\n            }\n\n            if (!userRepository.existsByUserName(\"admin\")) {\n                User admin = new User(\"admin\", \"admin@example.com\", passwordEncoder.encode(\"adminPass\"));\n                userRepository.save(admin);\n            }\n\n            // Update roles for existing users\n            userRepository.findByUserName(\"user1\").ifPresent(user -> {\n                user.setRoles(userRoles);\n                userRepository.save(user);\n            });\n\n            userRepository.findByUserName(\"seller1\").ifPresent(seller -> {\n                seller.setRoles(sellerRoles);\n                userRepository.save(seller);\n            });\n\n            userRepository.findByUserName(\"admin\").ifPresent(admin -> {\n                admin.setRoles(adminRoles);\n                userRepository.save(admin);\n            });\n        };\n    }\n\n}"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/jwt/AuthEntryPointJwt.java",
    "content": "package com.ecommerce.project.security.jwt;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.http.MediaType;\nimport org.springframework.security.core.AuthenticationException;\nimport org.springframework.security.web.AuthenticationEntryPoint;\nimport org.springframework.stereotype.Component;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\n@Component\npublic class AuthEntryPointJwt implements AuthenticationEntryPoint {\n\n    private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);\n\n    @Override\n    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)\n            throws IOException, ServletException {\n        logger.error(\"Unauthorized error: {}\", authException.getMessage());\n\n        response.setContentType(MediaType.APPLICATION_JSON_VALUE);\n        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);\n\n        final Map<String, Object> body = new HashMap<>();\n        body.put(\"status\", HttpServletResponse.SC_UNAUTHORIZED);\n        body.put(\"error\", \"Unauthorized\");\n        body.put(\"message\", authException.getMessage());\n        body.put(\"path\", request.getServletPath());\n\n        final ObjectMapper mapper = new ObjectMapper();\n        mapper.writeValue(response.getOutputStream(), body);\n    }\n\n}\n\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/jwt/AuthTokenFilter.java",
    "content": "package com.ecommerce.project.security.jwt;\n\nimport com.ecommerce.project.security.services.UserDetailsServiceImpl;\nimport jakarta.servlet.FilterChain;\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\nimport org.springframework.security.core.context.SecurityContextHolder;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.web.authentication.WebAuthenticationDetailsSource;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.filter.OncePerRequestFilter;\n\nimport java.io.IOException;\n\n@Component\npublic class AuthTokenFilter extends OncePerRequestFilter {\n    @Autowired\n    private JwtUtils jwtUtils;\n\n    @Autowired\n    private UserDetailsServiceImpl userDetailsService;\n\n    private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);\n\n    @Override\n    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)\n            throws ServletException, IOException {\n        logger.debug(\"AuthTokenFilter called for URI: {}\", request.getRequestURI());\n        try {\n            String jwt = parseJwt(request);\n            if (jwt != null && jwtUtils.validateJwtToken(jwt)) {\n                String username = jwtUtils.getUserNameFromJwtToken(jwt);\n\n                UserDetails userDetails = userDetailsService.loadUserByUsername(username);\n\n                UsernamePasswordAuthenticationToken authentication =\n                        new UsernamePasswordAuthenticationToken(userDetails,\n                                null,\n                                userDetails.getAuthorities());\n                logger.debug(\"Roles from JWT: {}\", userDetails.getAuthorities());\n\n                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));\n\n                SecurityContextHolder.getContext().setAuthentication(authentication);\n            }\n        } catch (Exception e) {\n            logger.error(\"Cannot set user authentication: {}\", e);\n        }\n\n        filterChain.doFilter(request, response);\n    }\n\n//    private String parseJwt(HttpServletRequest request) {\n//        String jwt = jwtUtils.getJwtFromCookies(request);\n//        logger.debug(\"AuthTokenFilter.java: {}\", jwt);\n//        return jwt;\n//    }\n\n    private String parseJwt(HttpServletRequest request) {\n        String jwtFromCookie = jwtUtils.getJwtFromCookies(request);\n        if (jwtFromCookie != null) {\n            return jwtFromCookie;\n        }\n\n        String jwtFromHeader = jwtUtils.getJwtFromHeader(request);\n        if (jwtFromHeader != null) {\n            return jwtFromHeader;\n        }\n\n        return null;\n    }\n}\n\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/jwt/JwtUtils.java",
    "content": "package com.ecommerce.project.security.jwt;\n\nimport com.ecommerce.project.security.services.UserDetailsImpl;\nimport io.jsonwebtoken.*;\nimport io.jsonwebtoken.io.Decoders;\nimport io.jsonwebtoken.security.Keys;\nimport jakarta.servlet.http.Cookie;\nimport jakarta.servlet.http.HttpServletRequest;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.http.ResponseCookie;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.util.WebUtils;\n\nimport javax.crypto.SecretKey;\nimport java.security.Key;\nimport java.util.Date;\n\n@Component\npublic class JwtUtils {\n    private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);\n\n    @Value(\"${spring.app.jwtSecret}\")\n    private String jwtSecret;\n\n    @Value(\"${spring.app.jwtExpirationMs}\")\n    private int jwtExpirationMs;\n\n    @Value(\"${spring.ecom.app.jwtCookieName}\")\n    private String jwtCookie;\n\n    public String getJwtFromCookies(HttpServletRequest request) {\n        Cookie cookie = WebUtils.getCookie(request, jwtCookie);\n        if (cookie != null) {\n            return cookie.getValue();\n        } else {\n            return null;\n        }\n    }\n\n    public String getJwtFromHeader(HttpServletRequest request) {\n        String bearerToken = request.getHeader(\"Authorization\");\n        if (bearerToken != null && bearerToken.startsWith(\"Bearer \")) {\n            return bearerToken.substring(7);\n        }\n        return null;\n    }\n\n    public ResponseCookie generateJwtCookie(UserDetailsImpl userPrincipal) {\n        String jwt = generateTokenFromUsername(userPrincipal.getUsername());\n        ResponseCookie cookie = ResponseCookie.from(jwtCookie, jwt)\n                .path(\"/api\")\n                .maxAge(24 * 60 * 60)\n                .httpOnly(false)\n                .secure(false)\n                .build();\n        return cookie;\n    }\n\n    public ResponseCookie getCleanJwtCookie() {\n        ResponseCookie cookie = ResponseCookie.from(jwtCookie, null)\n                .path(\"/api\")\n                .build();\n        return cookie;\n    }\n\n    public String generateTokenFromUsername(String username) {\n        return Jwts.builder()\n                .subject(username)\n                .issuedAt(new Date())\n                .expiration(new Date((new Date()).getTime() + jwtExpirationMs))\n                .signWith(key())\n                .compact();\n    }\n\n    public String getUserNameFromJwtToken(String token) {\n        return Jwts.parser()\n                        .verifyWith((SecretKey) key())\n                .build().parseSignedClaims(token)\n                .getPayload().getSubject();\n    }\n\n    private Key key() {\n        return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret));\n    }\n\n    public boolean validateJwtToken(String authToken) {\n        try {\n            Jwts.parser().verifyWith((SecretKey) key()).build().parseSignedClaims(authToken);\n            return true;\n        } catch (MalformedJwtException e) {\n            logger.error(\"Invalid JWT token: {}\", e.getMessage());\n        } catch (ExpiredJwtException e) {\n            logger.error(\"JWT token is expired: {}\", e.getMessage());\n        } catch (UnsupportedJwtException e) {\n            logger.error(\"JWT token is unsupported: {}\", e.getMessage());\n        } catch (IllegalArgumentException e) {\n            logger.error(\"JWT claims string is empty: {}\", e.getMessage());\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/request/LoginRequest.java",
    "content": "package com.ecommerce.project.security.request;\n\nimport jakarta.validation.constraints.NotBlank;\n\npublic class LoginRequest {\n    @NotBlank\n    private String username;\n\n    @NotBlank\n    private String password;\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public String getPassword() {\n        return password;\n    }\n\n    public void setPassword(String password) {\n        this.password = password;\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/request/SignupRequest.java",
    "content": "package com.ecommerce.project.security.request;\n\nimport java.util.Set;\n\nimport jakarta.validation.constraints.*;\nimport lombok.Data;\n\n@Data\npublic class SignupRequest {\n    @NotBlank\n    @Size(min = 3, max = 20)\n    private String username;\n\n    @NotBlank\n    @Size(max = 50)\n    @Email\n    private String email;\n\n    private Set<String> role;\n\n    @NotBlank\n    @Size(min = 6, max = 40)\n    private String password;\n\n    public Set<String> getRole() {\n        return this.role;\n    }\n\n    public void setRole(Set<String> role) {\n        this.role = role;\n    }\n}"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/response/MessageResponse.java",
    "content": "package com.ecommerce.project.security.response;\n\npublic class MessageResponse {\n    private String message;\n\n    public MessageResponse(String message) {\n        this.message = message;\n    }\n\n    public String getMessage() {\n        return message;\n    }\n\n    public void setMessage(String message) {\n        this.message = message;\n    }\n}"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/response/UserInfoResponse.java",
    "content": "package com.ecommerce.project.security.response;\n\nimport java.util.List;\n\npublic class UserInfoResponse {\n    private Long id;\n    private String jwtToken;\n    private String username;\n    private String email;\n    private List<String> roles;\n\n    public UserInfoResponse(Long id, String username, List<String> roles, String email, String jwtToken) {\n        this.id = id;\n        this.username = username;\n        this.roles = roles;\n        this.email = email;\n        this.jwtToken = jwtToken;\n    }\n\n    public UserInfoResponse(Long id, String username, List<String> roles) {\n        this.id = id;\n        this.username = username;\n        this.roles = roles;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public String getJwtToken() {\n        return jwtToken;\n    }\n\n    public void setJwtToken(String jwtToken) {\n        this.jwtToken = jwtToken;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public List<String> getRoles() {\n        return roles;\n    }\n\n    public void setRoles(List<String> roles) {\n        this.roles = roles;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n}\n\n\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/services/UserDetailsImpl.java",
    "content": "package com.ecommerce.project.security.services;\n\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.stream.Collectors;\n\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\nimport org.springframework.security.core.GrantedAuthority;\nimport org.springframework.security.core.authority.SimpleGrantedAuthority;\nimport org.springframework.security.core.userdetails.UserDetails;\n\nimport com.ecommerce.project.model.User;\nimport com.fasterxml.jackson.annotation.JsonIgnore;\n\n@NoArgsConstructor\n@Data\npublic class UserDetailsImpl implements UserDetails {\n    private static final long serialVersionUID = 1L;\n\n    private Long id;\n\n    private String username;\n\n    private String email;\n\n    @JsonIgnore\n    private String password;\n\n    private Collection<? extends GrantedAuthority> authorities;\n\n    public UserDetailsImpl(Long id, String username, String email, String password,\n                           Collection<? extends GrantedAuthority> authorities) {\n        this.id = id;\n        this.username = username;\n        this.email = email;\n        this.password = password;\n        this.authorities = authorities;\n    }\n\n    public static UserDetailsImpl build(User user) {\n        List<GrantedAuthority> authorities = user.getRoles().stream()\n                .map(role -> new SimpleGrantedAuthority(role.getRoleName().name()))\n                .collect(Collectors.toList());\n\n        return new UserDetailsImpl(\n                user.getUserId(),\n                user.getUserName(),\n                user.getEmail(),\n                user.getPassword(),\n                authorities);\n    }\n\n    @Override\n    public Collection<? extends GrantedAuthority> getAuthorities() {\n        return authorities;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    @Override\n    public String getPassword() {\n        return password;\n    }\n\n    @Override\n    public String getUsername() {\n        return username;\n    }\n\n    @Override\n    public boolean isAccountNonExpired() {\n        return true;\n    }\n\n    @Override\n    public boolean isAccountNonLocked() {\n        return true;\n    }\n\n    @Override\n    public boolean isCredentialsNonExpired() {\n        return true;\n    }\n\n    @Override\n    public boolean isEnabled() {\n        return true;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o)\n            return true;\n        if (o == null || getClass() != o.getClass())\n            return false;\n        UserDetailsImpl user = (UserDetailsImpl) o;\n        return Objects.equals(id, user.id);\n    }\n\n}"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/security/services/UserDetailsServiceImpl.java",
    "content": "package com.ecommerce.project.security.services;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.core.context.SecurityContextHolder;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.core.userdetails.UserDetailsService;\nimport org.springframework.security.core.userdetails.UsernameNotFoundException;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\nimport com.ecommerce.project.model.User;\nimport com.ecommerce.project.repositories.UserRepository;\n\n@Service\npublic class UserDetailsServiceImpl implements UserDetailsService {\n    @Autowired\n    UserRepository userRepository;\n\n    @Override\n    @Transactional\n    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {\n        User user = userRepository.findByUserName(username)\n                .orElseThrow(() -> new UsernameNotFoundException(\"User Not Found with username: \" + username));\n\n        return UserDetailsImpl.build(user);\n    }\n\n\n}"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/AddressService.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.model.User;\nimport com.ecommerce.project.payload.AddressDTO;\n\nimport java.util.List;\n\npublic interface AddressService {\n    AddressDTO createAddress(AddressDTO addressDTO, User user);\n\n    List<AddressDTO> getAddresses();\n\n    AddressDTO getAddressesById(Long addressId);\n\n    List<AddressDTO> getUserAddresses(User user);\n\n    AddressDTO updateAddress(Long addressId, AddressDTO addressDTO);\n\n    String deleteAddress(Long addressId);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/AddressServiceImpl.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.exceptions.ResourceNotFoundException;\nimport com.ecommerce.project.model.Address;\nimport com.ecommerce.project.model.User;\nimport com.ecommerce.project.payload.AddressDTO;\nimport com.ecommerce.project.repositories.AddressRepository;\nimport com.ecommerce.project.repositories.UserRepository;\nimport org.modelmapper.ModelMapper;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\n\nimport java.util.List;\n\n@Service\npublic class AddressServiceImpl implements AddressService{\n    @Autowired\n    private AddressRepository addressRepository;\n\n    @Autowired\n    private ModelMapper modelMapper;\n\n    @Autowired\n    UserRepository userRepository;\n\n    @Override\n    public AddressDTO createAddress(AddressDTO addressDTO, User user) {\n        Address address = modelMapper.map(addressDTO, Address.class);\n        address.setUser(user);\n        List<Address> addressesList = user.getAddresses();\n        addressesList.add(address);\n        user.setAddresses(addressesList);\n        Address savedAddress = addressRepository.save(address);\n        return modelMapper.map(savedAddress, AddressDTO.class);\n    }\n\n    @Override\n    public List<AddressDTO> getAddresses() {\n        List<Address> addresses = addressRepository.findAll();\n        return addresses.stream()\n                .map(address -> modelMapper.map(address, AddressDTO.class))\n                .toList();\n    }\n\n    @Override\n    public AddressDTO getAddressesById(Long addressId) {\n        Address address = addressRepository.findById(addressId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Address\", \"addressId\", addressId));\n        return modelMapper.map(address, AddressDTO.class);\n    }\n\n    @Override\n    public List<AddressDTO> getUserAddresses(User user) {\n        List<Address> addresses = user.getAddresses();\n        return addresses.stream()\n                .map(address -> modelMapper.map(address, AddressDTO.class))\n                .toList();\n    }\n\n    @Override\n    public AddressDTO updateAddress(Long addressId, AddressDTO addressDTO) {\n        Address addressFromDatabase = addressRepository.findById(addressId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Address\", \"addressId\", addressId));\n\n        addressFromDatabase.setCity(addressDTO.getCity());\n        addressFromDatabase.setPincode(addressDTO.getPincode());\n        addressFromDatabase.setState(addressDTO.getState());\n        addressFromDatabase.setCountry(addressDTO.getCountry());\n        addressFromDatabase.setStreet(addressDTO.getStreet());\n        addressFromDatabase.setBuildingName(addressDTO.getBuildingName());\n\n        Address updatedAddress = addressRepository.save(addressFromDatabase);\n\n        User user = addressFromDatabase.getUser();\n        user.getAddresses().removeIf(address -> address.getAddressId().equals(addressId));\n        user.getAddresses().add(updatedAddress);\n        userRepository.save(user);\n\n        return modelMapper.map(updatedAddress, AddressDTO.class);\n    }\n\n    @Override\n    public String deleteAddress(Long addressId) {\n        Address addressFromDatabase = addressRepository.findById(addressId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Address\", \"addressId\", addressId));\n\n        User user = addressFromDatabase.getUser();\n        user.getAddresses().removeIf(address -> address.getAddressId().equals(addressId));\n        userRepository.save(user);\n\n        addressRepository.delete(addressFromDatabase);\n\n        return \"Address deleted successfully with addressId: \" + addressId;\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/AnalyticsService.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.payload.AnalyticsResponse;\n\npublic interface AnalyticsService {\n    AnalyticsResponse getAnalyticsData();\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/AnalyticsServiceImpl.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.payload.AnalyticsResponse;\nimport com.ecommerce.project.repositories.OrderRepository;\nimport com.ecommerce.project.repositories.ProductRepository;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class AnalyticsServiceImpl implements AnalyticsService{\n\n    @Autowired\n    private ProductRepository productRepository;\n\n    @Autowired\n    private OrderRepository orderRepository;\n\n    @Override\n    public AnalyticsResponse getAnalyticsData() {\n        AnalyticsResponse response = new AnalyticsResponse();\n\n        long productCount = productRepository.count();\n        long totalOrders = orderRepository.count();;\n        Double totalRevenue = orderRepository.getTotalRevenue();\n\n        response.setProductCount(String.valueOf(productCount));\n        response.setTotalOrders(String.valueOf(totalOrders));\n        response.setTotalRevenue(String.valueOf(totalRevenue != null ? totalRevenue : 0));\n        return response;\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/AuthService.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.payload.AuthenticationResult;\nimport com.ecommerce.project.payload.UserResponse;\nimport com.ecommerce.project.security.request.LoginRequest;\nimport com.ecommerce.project.security.request.SignupRequest;\nimport com.ecommerce.project.security.response.MessageResponse;\nimport com.ecommerce.project.security.response.UserInfoResponse;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.http.ResponseCookie;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.security.core.Authentication;\n\npublic interface AuthService {\n\n    AuthenticationResult login(LoginRequest loginRequest);\n\n    ResponseEntity<MessageResponse> register(SignupRequest signUpRequest);\n\n    UserInfoResponse getCurrentUserDetails(Authentication authentication);\n\n    ResponseCookie logoutUser();\n\n    UserResponse getAllSellers(Pageable pageable);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/AuthServiceImpl.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.model.AppRole;\nimport com.ecommerce.project.model.Role;\nimport com.ecommerce.project.model.User;\nimport com.ecommerce.project.payload.AuthenticationResult;\nimport com.ecommerce.project.payload.UserDTO;\nimport com.ecommerce.project.payload.UserResponse;\nimport com.ecommerce.project.repositories.RoleRepository;\nimport com.ecommerce.project.repositories.UserRepository;\nimport com.ecommerce.project.security.jwt.JwtUtils;\nimport com.ecommerce.project.security.request.LoginRequest;\nimport com.ecommerce.project.security.request.SignupRequest;\nimport com.ecommerce.project.security.response.MessageResponse;\nimport com.ecommerce.project.security.response.UserInfoResponse;\nimport com.ecommerce.project.security.services.UserDetailsImpl;\nimport jakarta.transaction.Transactional;\nimport org.modelmapper.ModelMapper;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.http.ResponseCookie;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.security.authentication.AuthenticationManager;\nimport org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.core.context.SecurityContextHolder;\nimport org.springframework.security.crypto.password.PasswordEncoder;\nimport org.springframework.stereotype.Service;\n\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.stream.Collectors;\n\n@Service\n@Transactional\npublic class AuthServiceImpl implements AuthService {\n\n    @Autowired\n    private AuthenticationManager authenticationManager;\n\n    @Autowired\n    private JwtUtils jwtUtils;\n\n    @Autowired\n    UserRepository userRepository;\n\n    @Autowired\n    RoleRepository roleRepository;\n\n    @Autowired\n    PasswordEncoder encoder;\n\n    @Autowired\n    ModelMapper modelMapper;\n\n    @Override\n    public AuthenticationResult login(LoginRequest loginRequest) {\n        Authentication authentication = authenticationManager\n                    .authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));\n\n        SecurityContextHolder.getContext().setAuthentication(authentication);\n\n        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();\n\n        ResponseCookie jwtCookie = jwtUtils.generateJwtCookie(userDetails);\n\n        List<String> roles = userDetails.getAuthorities().stream()\n                .map(item -> item.getAuthority())\n                .collect(Collectors.toList());\n\n        UserInfoResponse response = new UserInfoResponse(userDetails.getId(),\n                userDetails.getUsername(), roles, userDetails.getEmail(), jwtCookie.toString());\n\n        return new AuthenticationResult(response, jwtCookie);\n    }\n\n    @Override\n    public ResponseEntity<MessageResponse> register(SignupRequest signUpRequest) {\n        if (userRepository.existsByUserName(signUpRequest.getUsername())) {\n            return ResponseEntity.badRequest().body(new MessageResponse(\"Error: Username is already taken!\"));\n        }\n\n        if (userRepository.existsByEmail(signUpRequest.getEmail())) {\n            return ResponseEntity.badRequest().body(new MessageResponse(\"Error: Email is already in use!\"));\n        }\n\n        // Create new user's account\n        User user = new User(signUpRequest.getUsername(),\n                signUpRequest.getEmail(),\n                encoder.encode(signUpRequest.getPassword()));\n\n        Set<String> strRoles = signUpRequest.getRole();\n        Set<Role> roles = new HashSet<>();\n\n        if (strRoles == null) {\n            Role userRole = roleRepository.findByRoleName(AppRole.ROLE_USER)\n                    .orElseThrow(() -> new RuntimeException(\"Error: Role is not found.\"));\n            roles.add(userRole);\n        } else {\n            strRoles.forEach(role -> {\n                switch (role) {\n                    case \"admin\":\n                        Role adminRole = roleRepository.findByRoleName(AppRole.ROLE_ADMIN)\n                                .orElseThrow(() -> new RuntimeException(\"Error: Role is not found.\"));\n                        roles.add(adminRole);\n\n                        break;\n                    case \"seller\":\n                        Role modRole = roleRepository.findByRoleName(AppRole.ROLE_SELLER)\n                                .orElseThrow(() -> new RuntimeException(\"Error: Role is not found.\"));\n                        roles.add(modRole);\n\n                        break;\n                    default:\n                        Role userRole = roleRepository.findByRoleName(AppRole.ROLE_USER)\n                                .orElseThrow(() -> new RuntimeException(\"Error: Role is not found.\"));\n                        roles.add(userRole);\n                }\n            });\n        }\n\n        user.setRoles(roles);\n        userRepository.save(user);\n        return ResponseEntity.ok(new MessageResponse(\"User registered successfully!\"));\n    }\n\n    @Override\n    public UserInfoResponse getCurrentUserDetails(Authentication authentication) {\n        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();\n\n        List<String> roles = userDetails.getAuthorities().stream()\n                .map(item -> item.getAuthority())\n                .collect(Collectors.toList());\n\n        UserInfoResponse response = new UserInfoResponse(userDetails.getId(),\n                userDetails.getUsername(), roles);\n\n        return response;\n    }\n\n    @Override\n    public ResponseCookie logoutUser() {\n        return jwtUtils.getCleanJwtCookie();\n    }\n\n    @Override\n    public UserResponse getAllSellers(Pageable pageable) {\n        Page<User> allUsers = userRepository.findByRoleName(AppRole.ROLE_SELLER, pageable);\n        List<UserDTO> userDtos = allUsers.getContent()\n                .stream()\n                .map(p -> modelMapper.map(p, UserDTO.class))\n                .collect(Collectors.toList());\n\n        UserResponse response = new UserResponse();\n        response.setContent(userDtos);\n        response.setPageNumber(allUsers.getNumber());\n        response.setPageSize(allUsers.getSize());\n        response.setTotalElements(allUsers.getTotalElements());\n        response.setTotalPages(allUsers.getTotalPages());\n        response.setLastPage(allUsers.isLast());\n        return response;\n    }\n\n\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/CartService.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.payload.CartDTO;\nimport com.ecommerce.project.payload.CartItemDTO;\nimport jakarta.transaction.Transactional;\n\nimport java.util.List;\n\npublic interface CartService {\n    CartDTO addProductToCart(Long productId, Integer quantity);\n\n    List<CartDTO> getAllCarts();\n\n    CartDTO getCart(String emailId, Long cartId);\n\n    @Transactional\n    CartDTO updateProductQuantityInCart(Long productId, Integer quantity);\n\n    String deleteProductFromCart(Long cartId, Long productId);\n\n    void updateProductInCarts(Long cartId, Long productId);\n\n    String createOrUpdateCartWithItems(List<CartItemDTO> cartItems);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/CartServiceImpl.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.exceptions.APIException;\nimport com.ecommerce.project.exceptions.ResourceNotFoundException;\nimport com.ecommerce.project.model.Cart;\nimport com.ecommerce.project.model.CartItem;\nimport com.ecommerce.project.model.Product;\nimport com.ecommerce.project.payload.CartDTO;\nimport com.ecommerce.project.payload.CartItemDTO;\nimport com.ecommerce.project.payload.ProductDTO;\nimport com.ecommerce.project.repositories.CartItemRepository;\nimport com.ecommerce.project.repositories.CartRepository;\nimport com.ecommerce.project.repositories.ProductRepository;\nimport com.ecommerce.project.util.AuthUtil;\nimport jakarta.transaction.Transactional;\nimport org.modelmapper.ModelMapper;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\n@Service\npublic class CartServiceImpl implements CartService{\n    @Autowired\n    private CartRepository cartRepository;\n\n    @Autowired\n    private AuthUtil authUtil;\n\n    @Autowired\n    ProductRepository productRepository;\n\n    @Autowired\n    CartItemRepository cartItemRepository;\n\n    @Autowired\n    ModelMapper modelMapper;\n\n    @Override\n    public CartDTO addProductToCart(Long productId, Integer quantity) {\n        Cart cart  = createCart();\n\n        Product product = productRepository.findById(productId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Product\", \"productId\", productId));\n\n        CartItem cartItem = cartItemRepository.findCartItemByProductIdAndCartId(cart.getCartId(), productId);\n\n        if (cartItem != null) {\n            throw new APIException(\"Product \" + product.getProductName() + \" already exists in the cart\");\n        }\n\n        if (product.getQuantity() == 0) {\n            throw new APIException(product.getProductName() + \" is not available\");\n        }\n\n        if (product.getQuantity() < quantity) {\n            throw new APIException(\"Please, make an order of the \" + product.getProductName()\n                    + \" less than or equal to the quantity \" + product.getQuantity() + \".\");\n        }\n\n        CartItem newCartItem = new CartItem();\n\n        newCartItem.setProduct(product);\n        newCartItem.setCart(cart);\n        newCartItem.setQuantity(quantity);\n        newCartItem.setDiscount(product.getDiscount());\n        newCartItem.setProductPrice(product.getSpecialPrice());\n\n        cartItemRepository.save(newCartItem);\n\n        product.setQuantity(product.getQuantity());\n\n        cart.setTotalPrice(cart.getTotalPrice() + (product.getSpecialPrice() * quantity));\n\n        cartRepository.save(cart);\n\n        CartDTO cartDTO = modelMapper.map(cart, CartDTO.class);\n\n        List<CartItem> cartItems = cart.getCartItems();\n\n        Stream<ProductDTO> productStream = cartItems.stream().map(item -> {\n            ProductDTO map = modelMapper.map(item.getProduct(), ProductDTO.class);\n            map.setQuantity(item.getQuantity());\n            return map;\n        });\n\n        cartDTO.setProducts(productStream.toList());\n\n        return cartDTO;\n    }\n\n    @Override\n    public List<CartDTO> getAllCarts() {\n        List<Cart> carts = cartRepository.findAll();\n\n        if (carts.size() == 0) {\n            throw new APIException(\"No cart exists\");\n        }\n\n        List<CartDTO> cartDTOs = carts.stream().map(cart -> {\n            CartDTO cartDTO = modelMapper.map(cart, CartDTO.class);\n\n            List<ProductDTO> products = cart.getCartItems().stream().map(cartItem -> {\n                ProductDTO productDTO = modelMapper.map(cartItem.getProduct(), ProductDTO.class);\n                productDTO.setQuantity(cartItem.getQuantity()); // Set the quantity from CartItem\n                return productDTO;\n            }).collect(Collectors.toList());\n\n\n            cartDTO.setProducts(products);\n\n            return cartDTO;\n\n        }).collect(Collectors.toList());\n\n        return cartDTOs;\n    }\n\n    @Override\n    public CartDTO getCart(String emailId, Long cartId) {\n        Cart cart = cartRepository.findCartByEmailAndCartId(emailId, cartId);\n        if (cart == null){\n            throw new ResourceNotFoundException(\"Cart\", \"cartId\", cartId);\n        }\n        CartDTO cartDTO = modelMapper.map(cart, CartDTO.class);\n        cart.getCartItems().forEach(c ->\n                c.getProduct().setQuantity(c.getQuantity()));\n        List<ProductDTO> products = cart.getCartItems().stream()\n                .map(p -> modelMapper.map(p.getProduct(), ProductDTO.class))\n                .toList();\n        cartDTO.setProducts(products);\n        return cartDTO;\n    }\n\n    @Transactional\n    @Override\n    public CartDTO updateProductQuantityInCart(Long productId, Integer quantity) {\n\n        String emailId = authUtil.loggedInEmail();\n        Cart userCart = cartRepository.findCartByEmail(emailId);\n        Long cartId  = userCart.getCartId();\n\n        Cart cart = cartRepository.findById(cartId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Cart\", \"cartId\", cartId));\n\n        Product product = productRepository.findById(productId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Product\", \"productId\", productId));\n\n        if (product.getQuantity() == 0) {\n            throw new APIException(product.getProductName() + \" is not available\");\n        }\n\n        if (product.getQuantity() < quantity) {\n            throw new APIException(\"Please, make an order of the \" + product.getProductName()\n                    + \" less than or equal to the quantity \" + product.getQuantity() + \".\");\n        }\n\n        CartItem cartItem = cartItemRepository.findCartItemByProductIdAndCartId(cartId, productId);\n\n        if (cartItem == null) {\n            throw new APIException(\"Product \" + product.getProductName() + \" not available in the cart!!!\");\n        }\n\n        // Calculate new quantity\n        int newQuantity = cartItem.getQuantity() + quantity;\n\n        // Validation to prevent negative quantities\n        if (newQuantity < 0) {\n            throw new APIException(\"The resulting quantity cannot be negative.\");\n        }\n\n        if (newQuantity == 0){\n            deleteProductFromCart(cartId, productId);\n        } else {\n            cartItem.setProductPrice(product.getSpecialPrice());\n            cartItem.setQuantity(cartItem.getQuantity() + quantity);\n            cartItem.setDiscount(product.getDiscount());\n            cart.setTotalPrice(cart.getTotalPrice() + (cartItem.getProductPrice() * quantity));\n            cartRepository.save(cart);\n        }\n\n        CartItem updatedItem = cartItemRepository.save(cartItem);\n        if(updatedItem.getQuantity() == 0){\n            cartItemRepository.deleteById(updatedItem.getCartItemId());\n        }\n\n\n        CartDTO cartDTO = modelMapper.map(cart, CartDTO.class);\n\n        List<CartItem> cartItems = cart.getCartItems();\n\n        Stream<ProductDTO> productStream = cartItems.stream().map(item -> {\n            ProductDTO prd = modelMapper.map(item.getProduct(), ProductDTO.class);\n            prd.setQuantity(item.getQuantity());\n            return prd;\n        });\n\n\n        cartDTO.setProducts(productStream.toList());\n\n        return cartDTO;\n    }\n\n\n    private Cart createCart() {\n        Cart userCart  = cartRepository.findCartByEmail(authUtil.loggedInEmail());\n        if(userCart != null){\n            return userCart;\n        }\n\n        Cart cart = new Cart();\n        cart.setTotalPrice(0.00);\n        cart.setUser(authUtil.loggedInUser());\n        Cart newCart =  cartRepository.save(cart);\n\n        return newCart;\n    }\n\n\n    @Transactional\n    @Override\n    public String deleteProductFromCart(Long cartId, Long productId) {\n        Cart cart = cartRepository.findById(cartId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Cart\", \"cartId\", cartId));\n\n        CartItem cartItem = cartItemRepository.findCartItemByProductIdAndCartId(cartId, productId);\n\n        if (cartItem == null) {\n            throw new ResourceNotFoundException(\"Product\", \"productId\", productId);\n        }\n\n        cart.setTotalPrice(cart.getTotalPrice() -\n                (cartItem.getProductPrice() * cartItem.getQuantity()));\n\n        cartItemRepository.deleteCartItemByProductIdAndCartId(cartId, productId);\n\n        return \"Product \" + cartItem.getProduct().getProductName() + \" removed from the cart !!!\";\n    }\n\n\n    @Override\n    public void updateProductInCarts(Long cartId, Long productId) {\n        Cart cart = cartRepository.findById(cartId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Cart\", \"cartId\", cartId));\n\n        Product product = productRepository.findById(productId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Product\", \"productId\", productId));\n\n        CartItem cartItem = cartItemRepository.findCartItemByProductIdAndCartId(cartId, productId);\n\n        if (cartItem == null) {\n            throw new APIException(\"Product \" + product.getProductName() + \" not available in the cart!!!\");\n        }\n\n        double cartPrice = cart.getTotalPrice()\n                - (cartItem.getProductPrice() * cartItem.getQuantity());\n\n        cartItem.setProductPrice(product.getSpecialPrice());\n\n        cart.setTotalPrice(cartPrice\n                + (cartItem.getProductPrice() * cartItem.getQuantity()));\n\n        cartItem = cartItemRepository.save(cartItem);\n    }\n\n    @Transactional\n    @Override\n    public String createOrUpdateCartWithItems(List<CartItemDTO> cartItems) {\n        // Get user's email\n        String emailId = authUtil.loggedInEmail();\n\n        // Check if an existing cart is available or create a new one\n        Cart existingCart = cartRepository.findCartByEmail(emailId);\n        if (existingCart == null) {\n            existingCart = new Cart();\n            existingCart.setTotalPrice(0.00);\n            existingCart.setUser(authUtil.loggedInUser());\n            existingCart = cartRepository.save(existingCart);\n        } else {\n            // Clear all current items in the existing cart\n            cartItemRepository.deleteAllByCartId(existingCart.getCartId());\n        }\n\n        double totalPrice = 0.00;\n\n        // Process each item in the request to add to the cart\n        for (CartItemDTO cartItemDTO : cartItems) {\n            Long productId = cartItemDTO.getProductId();\n            Integer quantity = cartItemDTO.getQuantity();\n\n            // Find the product by ID\n            Product product = productRepository.findById(productId)\n                    .orElseThrow(() -> new ResourceNotFoundException(\"Product\", \"productId\", productId));\n\n            // Directly update product stock and total price\n            // product.setQuantity(product.getQuantity() - quantity);\n            totalPrice += product.getSpecialPrice() * quantity;\n\n            // Create and save cart item\n            CartItem cartItem = new CartItem();\n            cartItem.setProduct(product);\n            cartItem.setCart(existingCart);\n            cartItem.setQuantity(quantity);\n            cartItem.setProductPrice(product.getSpecialPrice());\n            cartItem.setDiscount(product.getDiscount());\n            cartItemRepository.save(cartItem);\n        }\n\n        // Update the cart's total price and save\n        existingCart.setTotalPrice(totalPrice);\n        cartRepository.save(existingCart);\n        return \"Cart created/updated with the new items successfully\";\n    }\n\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/CategoryService.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.model.Category;\nimport com.ecommerce.project.payload.CategoryDTO;\nimport com.ecommerce.project.payload.CategoryResponse;\n\npublic interface CategoryService {\n    CategoryResponse getAllCategories(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder);\n    CategoryDTO createCategory(CategoryDTO categoryDTO);\n\n    CategoryDTO deleteCategory(Long categoryId);\n\n    CategoryDTO updateCategory(CategoryDTO categoryDTO, Long categoryId);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/CategoryServiceImpl.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.exceptions.APIException;\nimport com.ecommerce.project.exceptions.ResourceNotFoundException;\nimport com.ecommerce.project.model.Category;\nimport com.ecommerce.project.payload.CategoryDTO;\nimport com.ecommerce.project.payload.CategoryResponse;\nimport com.ecommerce.project.repositories.CategoryRepository;\nimport org.modelmapper.ModelMapper;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.PageRequest;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.domain.Sort;\nimport org.springframework.stereotype.Service;\n\nimport java.util.List;\n\n@Service\npublic class CategoryServiceImpl implements CategoryService{\n\n    @Autowired\n    private CategoryRepository categoryRepository;\n\n    @Autowired\n    private ModelMapper modelMapper;\n\n    @Override\n    public CategoryResponse getAllCategories(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder) {\n        Sort sortByAndOrder = sortOrder.equalsIgnoreCase(\"asc\")\n                ? Sort.by(sortBy).ascending()\n                : Sort.by(sortBy).descending();\n\n        Pageable pageDetails = PageRequest.of(pageNumber, pageSize, sortByAndOrder);\n        Page<Category> categoryPage = categoryRepository.findAll(pageDetails);\n\n        List<Category> categories = categoryPage.getContent();\n        if (categories.isEmpty())\n            throw new APIException(\"No category created till now.\");\n\n        List<CategoryDTO> categoryDTOS = categories.stream()\n                .map(category -> modelMapper.map(category, CategoryDTO.class))\n                .toList();\n\n        CategoryResponse categoryResponse = new CategoryResponse();\n        categoryResponse.setContent(categoryDTOS);\n        categoryResponse.setPageNumber(categoryPage.getNumber());\n        categoryResponse.setPageSize(categoryPage.getSize());\n        categoryResponse.setTotalElements(categoryPage.getTotalElements());\n        categoryResponse.setTotalPages(categoryPage.getTotalPages());\n        categoryResponse.setLastPage(categoryPage.isLast());\n        return categoryResponse;\n    }\n\n    @Override\n    public CategoryDTO createCategory(CategoryDTO categoryDTO) {\n        Category category = modelMapper.map(categoryDTO, Category.class);\n        Category categoryFromDb = categoryRepository.findByCategoryName(category.getCategoryName());\n        if (categoryFromDb != null)\n            throw new APIException(\"Category with the name \" + category.getCategoryName() + \" already exists !!!\");\n        Category savedCategory = categoryRepository.save(category);\n        return modelMapper.map(savedCategory, CategoryDTO.class);\n    }\n\n    @Override\n    public CategoryDTO deleteCategory(Long categoryId) {\n        Category category = categoryRepository.findById(categoryId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Category\",\"categoryId\",categoryId));\n\n        categoryRepository.delete(category);\n        return modelMapper.map(category, CategoryDTO.class);\n    }\n\n    @Override\n    public CategoryDTO updateCategory(CategoryDTO categoryDTO, Long categoryId) {\n        Category savedCategory = categoryRepository.findById(categoryId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Category\",\"categoryId\",categoryId));\n\n        Category category = modelMapper.map(categoryDTO, Category.class);\n        category.setCategoryId(categoryId);\n        savedCategory = categoryRepository.save(category);\n        return modelMapper.map(savedCategory, CategoryDTO.class);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/FileService.java",
    "content": "package com.ecommerce.project.service;\n\nimport org.springframework.web.multipart.MultipartFile;\n\nimport java.io.IOException;\n\npublic interface FileService {\n    String uploadImage(String path, MultipartFile file) throws IOException;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/FileServiceImpl.java",
    "content": "package com.ecommerce.project.service;\n\nimport org.springframework.stereotype.Service;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\nimport java.util.UUID;\n\n@Service\npublic class FileServiceImpl implements FileService {\n\n    @Override\n    public String uploadImage(String path, MultipartFile file) throws IOException {\n        String originalFileName = file.getOriginalFilename();\n        String randomId = UUID.randomUUID().toString();\n        String fileName = randomId.concat(originalFileName.substring(originalFileName.lastIndexOf('.')));\n        String filePath = path + File.separator + fileName;\n\n        File folder = new File(path);\n        if (!folder.exists())\n            folder.mkdir();\n\n        Files.copy(file.getInputStream(), Paths.get(filePath));\n        return fileName;\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/OrderService.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.payload.OrderDTO;\nimport com.ecommerce.project.payload.OrderResponse;\nimport jakarta.transaction.Transactional;\n\npublic interface OrderService {\n    @Transactional\n    OrderDTO placeOrder(String emailId, Long addressId, String paymentMethod, String pgName, String pgPaymentId, String pgStatus, String pgResponseMessage);\n\n    OrderResponse getAllOrders(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder);\n\n    OrderDTO updateOrder(Long orderId, String status);\n\n    OrderResponse getAllSellerOrders(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/OrderServiceImpl.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.exceptions.APIException;\nimport com.ecommerce.project.exceptions.ResourceNotFoundException;\nimport com.ecommerce.project.model.*;\nimport com.ecommerce.project.payload.OrderDTO;\nimport com.ecommerce.project.payload.OrderItemDTO;\nimport com.ecommerce.project.payload.OrderResponse;\nimport com.ecommerce.project.repositories.*;\nimport com.ecommerce.project.util.AuthUtil;\nimport jakarta.transaction.Transactional;\nimport org.modelmapper.ModelMapper;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.PageRequest;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.domain.Sort;\nimport org.springframework.stereotype.Service;\n\nimport java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\n@Service\npublic class OrderServiceImpl implements OrderService {\n\n    @Autowired\n    CartRepository cartRepository;\n\n    @Autowired\n    AddressRepository addressRepository;\n\n    @Autowired\n    OrderItemRepository orderItemRepository;\n\n    @Autowired\n    OrderRepository orderRepository;\n\n    @Autowired\n    PaymentRepository paymentRepository;\n\n    @Autowired\n    CartService cartService;\n\n    @Autowired\n    ModelMapper modelMapper;\n\n    @Autowired\n    ProductRepository productRepository;\n\n    @Autowired\n    AuthUtil authUtil;\n\n    @Override\n    @Transactional\n    public OrderDTO placeOrder(String emailId, Long addressId, String paymentMethod, String pgName, String pgPaymentId, String pgStatus, String pgResponseMessage) {\n        Cart cart = cartRepository.findCartByEmail(emailId);\n        if (cart == null) {\n            throw new ResourceNotFoundException(\"Cart\", \"email\", emailId);\n        }\n\n        Address address = addressRepository.findById(addressId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Address\", \"addressId\", addressId));\n\n        Order order = new Order();\n        order.setEmail(emailId);\n        order.setOrderDate(LocalDate.now());\n        order.setTotalAmount(cart.getTotalPrice());\n        order.setOrderStatus(\"Accepted\");\n        order.setAddress(address);\n\n        Payment payment = new Payment(paymentMethod, pgPaymentId, pgStatus, pgResponseMessage, pgName);\n        payment.setOrder(order);\n        payment = paymentRepository.save(payment);\n        order.setPayment(payment);\n\n        Order savedOrder = orderRepository.save(order);\n\n        List<CartItem> cartItems = cart.getCartItems();\n        if (cartItems.isEmpty()) {\n            throw new APIException(\"Cart is empty\");\n        }\n\n        List<OrderItem> orderItems = new ArrayList<>();\n        for (CartItem cartItem : cartItems) {\n            OrderItem orderItem = new OrderItem();\n            orderItem.setProduct(cartItem.getProduct());\n            orderItem.setQuantity(cartItem.getQuantity());\n            orderItem.setDiscount(cartItem.getDiscount());\n            orderItem.setOrderedProductPrice(cartItem.getProductPrice());\n            orderItem.setOrder(savedOrder);\n            orderItems.add(orderItem);\n        }\n\n        orderItems = orderItemRepository.saveAll(orderItems);\n\n        cart.getCartItems().forEach(item -> {\n            int quantity = item.getQuantity();\n            Product product = item.getProduct();\n\n            // Reduce stock quantity\n            product.setQuantity(product.getQuantity() - quantity);\n\n            // Save product back to the database\n            productRepository.save(product);\n\n            // Remove items from cart\n            cartService.deleteProductFromCart(cart.getCartId(), item.getProduct().getProductId());\n        });\n\n        OrderDTO orderDTO = modelMapper.map(savedOrder, OrderDTO.class);\n        orderItems.forEach(item -> orderDTO.getOrderItems().add(modelMapper.map(item, OrderItemDTO.class)));\n\n        orderDTO.setAddressId(addressId);\n\n        return orderDTO;\n    }\n\n    @Override\n    public OrderResponse getAllOrders(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder) {\n        Sort sortByAndOrder = sortOrder.equalsIgnoreCase(\"asc\")\n                ? Sort.by(sortBy).ascending()\n                : Sort.by(sortBy).descending();\n        Pageable pageDetails = PageRequest.of(pageNumber, pageSize, sortByAndOrder);\n        Page<Order> pageOrders = orderRepository.findAll(pageDetails);\n        List<Order> orders = pageOrders.getContent();\n        List<OrderDTO> orderDTOs = orders.stream()\n                .map(order -> modelMapper.map(order, OrderDTO.class))\n                .toList();\n        OrderResponse orderResponse = new OrderResponse();\n        orderResponse.setContent(orderDTOs);\n        orderResponse.setPageNumber(pageOrders.getNumber());\n        orderResponse.setPageSize(pageOrders.getSize());\n        orderResponse.setTotalElements(pageOrders.getTotalElements());\n        orderResponse.setTotalPages(pageOrders.getTotalPages());\n        orderResponse.setLastPage(pageOrders.isLast());\n        return orderResponse;\n    }\n\n    @Override\n    public OrderDTO updateOrder(Long orderId, String status) {\n        Order order = orderRepository.findById(orderId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Order\",\"orderId\",orderId));\n        order.setOrderStatus(status);\n        orderRepository.save(order);\n        return modelMapper.map(order, OrderDTO.class);\n    }\n\n    @Override\n    public OrderResponse getAllSellerOrders(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder) {\n        Sort sortByAndOrder = sortOrder.equalsIgnoreCase(\"asc\")\n                ? Sort.by(sortBy).ascending()\n                : Sort.by(sortBy).descending();\n        Pageable pageDetails = PageRequest.of(pageNumber, pageSize, sortByAndOrder);\n\n        User seller = authUtil.loggedInUser();\n\n        Page<Order> pageOrders = orderRepository.findAll(pageDetails);\n\n        List<Order> sellerOrders = pageOrders.getContent().stream()\n                .filter(order -> order.getOrderItems().stream()\n                        .anyMatch(orderItem -> {\n                            var product = orderItem.getProduct();\n                            if (product == null || product.getUser() == null) {\n                                return false;\n                            }\n                            return product.getUser().getUserId().equals(\n                                    seller.getUserId());\n                        }))\n                .toList();\n\n        List<OrderDTO> orderDTOs = sellerOrders.stream()\n                .map(order -> modelMapper.map(order, OrderDTO.class))\n                .toList();\n        OrderResponse orderResponse = new OrderResponse();\n        orderResponse.setContent(orderDTOs);\n        orderResponse.setPageNumber(pageOrders.getNumber());\n        orderResponse.setPageSize(pageOrders.getSize());\n        orderResponse.setTotalElements(pageOrders.getTotalElements());\n        orderResponse.setTotalPages(pageOrders.getTotalPages());\n        orderResponse.setLastPage(pageOrders.isLast());\n        return orderResponse;\n    }\n\n\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/ProductService.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.payload.ProductDTO;\nimport com.ecommerce.project.payload.ProductResponse;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport java.io.IOException;\n\npublic interface ProductService {\n    ProductDTO addProduct(Long categoryId, ProductDTO product);\n\n    ProductResponse getAllProducts(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder, String keyword, String category);\n\n    ProductResponse searchByCategory(Long categoryId, Integer pageNumber, Integer pageSize, String sortBy, String sortOrder);\n\n    ProductResponse searchProductByKeyword(String keyword, Integer pageNumber, Integer pageSize, String sortBy, String sortOrder);\n\n    ProductDTO updateProduct(Long productId, ProductDTO product);\n\n    ProductDTO deleteProduct(Long productId);\n\n    ProductDTO updateProductImage(Long productId, MultipartFile image) throws IOException;\n\n    ProductResponse getAllProductsForAdmin(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder);\n\n    ProductResponse getAllProductsForSeller(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder);\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/ProductServiceImpl.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.exceptions.APIException;\nimport com.ecommerce.project.exceptions.ResourceNotFoundException;\nimport com.ecommerce.project.model.Cart;\nimport com.ecommerce.project.model.Category;\nimport com.ecommerce.project.model.Product;\nimport com.ecommerce.project.model.User;\nimport com.ecommerce.project.payload.CartDTO;\nimport com.ecommerce.project.payload.ProductDTO;\nimport com.ecommerce.project.payload.ProductResponse;\nimport com.ecommerce.project.repositories.CartRepository;\nimport com.ecommerce.project.repositories.CategoryRepository;\nimport com.ecommerce.project.repositories.ProductRepository;\nimport com.ecommerce.project.util.AuthUtil;\nimport org.modelmapper.ModelMapper;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.PageRequest;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.domain.Sort;\nimport org.springframework.data.jpa.domain.Specification;\nimport org.springframework.stereotype.Service;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport java.io.IOException;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\n@Service\npublic class ProductServiceImpl implements ProductService {\n    @Autowired\n    private CartRepository cartRepository;\n\n    @Autowired\n    private CartService cartService;\n\n    @Autowired\n    private ProductRepository productRepository;\n\n    @Autowired\n    private CategoryRepository categoryRepository;\n\n    @Autowired\n    private ModelMapper modelMapper;\n\n    @Autowired\n    private FileService fileService;\n\n    @Autowired\n    AuthUtil authUtil;\n\n    @Value(\"${project.image}\")\n    private String path;\n\n    @Value(\"${image.base.url}\")\n    private String imageBaseUrl;\n\n    @Override\n    public ProductDTO addProduct(Long categoryId, ProductDTO productDTO) {\n        Category category = categoryRepository.findById(categoryId)\n                .orElseThrow(() ->\n                        new ResourceNotFoundException(\"Category\", \"categoryId\", categoryId));\n\n        boolean isProductNotPresent = true;\n\n        List<Product> products = category.getProducts();\n        for (Product value : products) {\n            if (value.getProductName().equals(productDTO.getProductName())) {\n                isProductNotPresent = false;\n                break;\n            }\n        }\n\n        if (isProductNotPresent) {\n            Product product = modelMapper.map(productDTO, Product.class);\n            product.setImage(\"default.png\");\n            product.setCategory(category);\n            product.setUser(authUtil.loggedInUser());\n            double specialPrice = product.getPrice() -\n                    ((product.getDiscount() * 0.01) * product.getPrice());\n            product.setSpecialPrice(specialPrice);\n            Product savedProduct = productRepository.save(product);\n            return modelMapper.map(savedProduct, ProductDTO.class);\n        } else {\n            throw new APIException(\"Product already exist!!\");\n        }\n    }\n\n    @Override\n    public ProductResponse getAllProducts(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder, String keyword, String category) {\n        Sort sortByAndOrder = sortOrder.equalsIgnoreCase(\"asc\")\n                ? Sort.by(sortBy).ascending()\n                : Sort.by(sortBy).descending();\n\n        Pageable pageDetails = PageRequest.of(pageNumber, pageSize, sortByAndOrder);\n        Specification<Product> spec = (root, query, cb) -> cb.conjunction();\n        if (keyword != null && !keyword.isEmpty()) {\n            spec = spec.and((root, query, criteriaBuilder) ->\n                    criteriaBuilder.like(criteriaBuilder.lower(root.get(\"productName\")), \"%\" + keyword.toLowerCase() + \"%\"));\n        }\n\n        if (category != null && !category.isEmpty()) {\n            spec = spec.and((root, query, criteriaBuilder) ->\n                    criteriaBuilder.like(root.get(\"category\").get(\"categoryName\"), category));\n        }\n\n        Page<Product> pageProducts = productRepository.findAll(spec, pageDetails);\n\n        List<Product> products = pageProducts.getContent();\n\n        List<ProductDTO> productDTOS = products.stream()\n                .map(product -> {\n                    ProductDTO productDTO = modelMapper.map(product, ProductDTO.class);\n                    productDTO.setImage(constructImageUrl(product.getImage()));\n                    return productDTO;\n                })\n                .toList();\n\n        ProductResponse productResponse = new ProductResponse();\n        productResponse.setContent(productDTOS);\n        productResponse.setPageNumber(pageProducts.getNumber());\n        productResponse.setPageSize(pageProducts.getSize());\n        productResponse.setTotalElements(pageProducts.getTotalElements());\n        productResponse.setTotalPages(pageProducts.getTotalPages());\n        productResponse.setLastPage(pageProducts.isLast());\n        return productResponse;\n    }\n\n\n    @Override\n    public ProductResponse getAllProductsForAdmin(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder) {\n        Sort sortByAndOrder = sortOrder.equalsIgnoreCase(\"asc\")\n                ? Sort.by(sortBy).ascending()\n                : Sort.by(sortBy).descending();\n\n        Pageable pageDetails = PageRequest.of(pageNumber, pageSize, sortByAndOrder);\n        Page<Product> pageProducts = productRepository.findAll(pageDetails);\n\n        List<Product> products = pageProducts.getContent();\n\n        List<ProductDTO> productDTOS = products.stream()\n                .map(product -> {\n                    ProductDTO productDTO = modelMapper.map(product, ProductDTO.class);\n                    productDTO.setImage(constructImageUrl(product.getImage()));\n                    return productDTO;\n                })\n                .toList();\n\n        ProductResponse productResponse = new ProductResponse();\n        productResponse.setContent(productDTOS);\n        productResponse.setPageNumber(pageProducts.getNumber());\n        productResponse.setPageSize(pageProducts.getSize());\n        productResponse.setTotalElements(pageProducts.getTotalElements());\n        productResponse.setTotalPages(pageProducts.getTotalPages());\n        productResponse.setLastPage(pageProducts.isLast());\n        return productResponse;\n    }\n\n    @Override\n    public ProductResponse getAllProductsForSeller(Integer pageNumber, Integer pageSize, String sortBy, String sortOrder) {\n        Sort sortByAndOrder = sortOrder.equalsIgnoreCase(\"asc\")\n                ? Sort.by(sortBy).ascending()\n                : Sort.by(sortBy).descending();\n\n        Pageable pageDetails = PageRequest.of(pageNumber, pageSize, sortByAndOrder);\n\n        User user = authUtil.loggedInUser();\n        Page<Product> pageProducts = productRepository.findByUser(user, pageDetails);\n\n        List<Product> products = pageProducts.getContent();\n\n        List<ProductDTO> productDTOS = products.stream()\n                .map(product -> {\n                    ProductDTO productDTO = modelMapper.map(product, ProductDTO.class);\n                    productDTO.setImage(constructImageUrl(product.getImage()));\n                    return productDTO;\n                })\n                .toList();\n\n        ProductResponse productResponse = new ProductResponse();\n        productResponse.setContent(productDTOS);\n        productResponse.setPageNumber(pageProducts.getNumber());\n        productResponse.setPageSize(pageProducts.getSize());\n        productResponse.setTotalElements(pageProducts.getTotalElements());\n        productResponse.setTotalPages(pageProducts.getTotalPages());\n        productResponse.setLastPage(pageProducts.isLast());\n        return productResponse;\n    }\n\n    private String constructImageUrl(String imageName) {\n        return imageBaseUrl.endsWith(\"/\") ? imageBaseUrl + imageName : imageBaseUrl + \"/\" + imageName;\n    }\n\n    @Override\n    public ProductResponse searchByCategory(Long categoryId, Integer pageNumber, Integer pageSize, String sortBy, String sortOrder) {\n        Category category = categoryRepository.findById(categoryId)\n                .orElseThrow(() ->\n                        new ResourceNotFoundException(\"Category\", \"categoryId\", categoryId));\n\n        Sort sortByAndOrder = sortOrder.equalsIgnoreCase(\"asc\")\n                ? Sort.by(sortBy).ascending()\n                : Sort.by(sortBy).descending();\n\n        Pageable pageDetails = PageRequest.of(pageNumber, pageSize, sortByAndOrder);\n        Page<Product> pageProducts = productRepository.findByCategoryOrderByPriceAsc(category, pageDetails);\n\n        List<Product> products = pageProducts.getContent();\n\n        if(products.isEmpty()){\n            throw new APIException(category.getCategoryName() + \" category does not have any products\");\n        }\n\n        List<ProductDTO> productDTOS = products.stream()\n                .map(product -> modelMapper.map(product, ProductDTO.class))\n                .toList();\n\n        ProductResponse productResponse = new ProductResponse();\n        productResponse.setContent(productDTOS);\n        productResponse.setPageNumber(pageProducts.getNumber());\n        productResponse.setPageSize(pageProducts.getSize());\n        productResponse.setTotalElements(pageProducts.getTotalElements());\n        productResponse.setTotalPages(pageProducts.getTotalPages());\n        productResponse.setLastPage(pageProducts.isLast());\n        return productResponse;\n    }\n\n    @Override\n    public ProductResponse searchProductByKeyword(String keyword, Integer pageNumber, Integer pageSize, String sortBy, String sortOrder) {\n        Sort sortByAndOrder = sortOrder.equalsIgnoreCase(\"asc\")\n                ? Sort.by(sortBy).ascending()\n                : Sort.by(sortBy).descending();\n\n        Pageable pageDetails = PageRequest.of(pageNumber, pageSize, sortByAndOrder);\n        Page<Product> pageProducts = productRepository.findByProductNameLikeIgnoreCase('%' + keyword + '%', pageDetails);\n\n        List<Product> products = pageProducts.getContent();\n        List<ProductDTO> productDTOS = products.stream()\n                .map(product -> modelMapper.map(product, ProductDTO.class))\n                .toList();\n\n        if(products.isEmpty()){\n            throw new APIException(\"Products not found with keyword: \" + keyword);\n        }\n\n        ProductResponse productResponse = new ProductResponse();\n        productResponse.setContent(productDTOS);\n        productResponse.setPageNumber(pageProducts.getNumber());\n        productResponse.setPageSize(pageProducts.getSize());\n        productResponse.setTotalElements(pageProducts.getTotalElements());\n        productResponse.setTotalPages(pageProducts.getTotalPages());\n        productResponse.setLastPage(pageProducts.isLast());\n        return productResponse;\n    }\n\n    @Override\n    public ProductDTO updateProduct(Long productId, ProductDTO productDTO) {\n        Product productFromDb = productRepository.findById(productId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Product\", \"productId\", productId));\n\n        Product product = modelMapper.map(productDTO, Product.class);\n\n        productFromDb.setProductName(product.getProductName());\n        productFromDb.setDescription(product.getDescription());\n        productFromDb.setQuantity(product.getQuantity());\n        productFromDb.setDiscount(product.getDiscount());\n        productFromDb.setPrice(product.getPrice());\n        productFromDb.setSpecialPrice(product.getSpecialPrice());\n\n        Product savedProduct = productRepository.save(productFromDb);\n\n        List<Cart> carts = cartRepository.findCartsByProductId(productId);\n\n        List<CartDTO> cartDTOs = carts.stream().map(cart -> {\n            CartDTO cartDTO = modelMapper.map(cart, CartDTO.class);\n\n            List<ProductDTO> products = cart.getCartItems().stream()\n                    .map(p -> modelMapper.map(p.getProduct(), ProductDTO.class)).collect(Collectors.toList());\n\n            cartDTO.setProducts(products);\n\n            return cartDTO;\n\n        }).collect(Collectors.toList());\n\n        cartDTOs.forEach(cart -> cartService.updateProductInCarts(cart.getCartId(), productId));\n\n        return modelMapper.map(savedProduct, ProductDTO.class);\n    }\n\n    @Override\n    public ProductDTO deleteProduct(Long productId) {\n        Product product = productRepository.findById(productId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Product\", \"productId\", productId));\n\n        // DELETE\n        List<Cart> carts = cartRepository.findCartsByProductId(productId);\n        carts.forEach(cart -> cartService.deleteProductFromCart(cart.getCartId(), productId));\n\n        productRepository.delete(product);\n        return modelMapper.map(product, ProductDTO.class);\n    }\n\n    @Override\n    public ProductDTO updateProductImage(Long productId, MultipartFile image) throws IOException {\n        Product productFromDb = productRepository.findById(productId)\n                .orElseThrow(() -> new ResourceNotFoundException(\"Product\", \"productId\", productId));\n\n        String fileName = fileService.uploadImage(path, image);\n        productFromDb.setImage(fileName);\n\n        Product updatedProduct = productRepository.save(productFromDb);\n        return modelMapper.map(updatedProduct, ProductDTO.class);\n    }\n\n\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/StripeService.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.payload.StripePaymentDto;\nimport com.stripe.exception.StripeException;\nimport com.stripe.model.PaymentIntent;\n\npublic interface StripeService {\n\n    PaymentIntent paymentIntent(StripePaymentDto stripePaymentDto) throws StripeException;\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/service/StripeServiceImpl.java",
    "content": "package com.ecommerce.project.service;\n\nimport com.ecommerce.project.payload.StripePaymentDto;\nimport com.stripe.Stripe;\nimport com.stripe.exception.StripeException;\nimport com.stripe.model.Customer;\nimport com.stripe.model.CustomerSearchResult;\nimport com.stripe.model.PaymentIntent;\nimport com.stripe.param.CustomerCreateParams;\nimport com.stripe.param.CustomerSearchParams;\nimport com.stripe.param.PaymentIntentCreateParams;\nimport jakarta.annotation.PostConstruct;\nimport jakarta.transaction.Transactional;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.stereotype.Service;\n\n@Service\n@Transactional\npublic class StripeServiceImpl implements StripeService {\n\n    @Value(\"${stripe.secret.key}\")\n    private String stripeApiKey;\n\n    @PostConstruct\n    public void init(){\n        Stripe.apiKey = stripeApiKey;\n    }\n\n    @Override\n    public PaymentIntent paymentIntent(StripePaymentDto stripePaymentDto) throws StripeException {\n        Customer customer;\n        // Retrieve and check if customer exist\n        CustomerSearchParams searchParams =\n                CustomerSearchParams.builder()\n                        .setQuery(\"email:'\" + stripePaymentDto.getEmail() + \"'\")\n                        .build();\n        CustomerSearchResult customers = Customer.search(searchParams);\n        if (customers.getData().isEmpty()) {\n            // Create new customer\n            CustomerCreateParams customerParams = CustomerCreateParams.builder()\n                    .setEmail(stripePaymentDto.getEmail())\n                    .setName(stripePaymentDto.getName())\n                    .setAddress(\n                            CustomerCreateParams.Address.builder()\n                                    .setLine1(stripePaymentDto.getAddress().getStreet())\n                                    .setCity(stripePaymentDto.getAddress().getCity())\n                                    .setState(stripePaymentDto.getAddress().getState())\n                                    .setPostalCode(stripePaymentDto.getAddress().getPincode())\n                                    .setCountry(stripePaymentDto.getAddress().getCountry())\n                                    .build()\n                    )\n                    .build();\n\n            customer = Customer.create(customerParams);\n        } else {\n            // Fetch the customer that exist\n            customer = customers.getData().get(0);\n        }\n\n        PaymentIntentCreateParams params =\n                PaymentIntentCreateParams.builder()\n                        .setAmount(stripePaymentDto.getAmount())\n                        .setCurrency(stripePaymentDto.getCurrency())\n                        .setCustomer(customer.getId())\n                        .setDescription(stripePaymentDto.getDescription())\n                        .setAutomaticPaymentMethods(\n                                PaymentIntentCreateParams.AutomaticPaymentMethods.builder()\n                                        .setEnabled(true)\n                                        .build()\n                        )\n                        .build();\n\n        return PaymentIntent.create(params);\n    }\n}\n"
  },
  {
    "path": "sb-ecom/src/main/java/com/ecommerce/project/util/AuthUtil.java",
    "content": "package com.ecommerce.project.util;\n\nimport com.ecommerce.project.model.User;\nimport com.ecommerce.project.repositories.UserRepository;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.core.context.SecurityContextHolder;\nimport org.springframework.security.core.userdetails.UsernameNotFoundException;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class AuthUtil {\n\n    @Autowired\n    UserRepository userRepository;\n\n    public String loggedInEmail(){\n        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();\n        User user = userRepository.findByUserName(authentication.getName())\n                .orElseThrow(() -> new UsernameNotFoundException(\"User Not Found with username: \" + authentication.getName()));\n\n        return user.getEmail();\n    }\n\n    public Long loggedInUserId(){\n        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();\n        User user = userRepository.findByUserName(authentication.getName())\n                .orElseThrow(() -> new UsernameNotFoundException(\"User Not Found with username: \" + authentication.getName()));\n\n        return user.getUserId();\n    }\n\n    public User loggedInUser(){\n        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();\n\n        User user = userRepository.findByUserName(authentication.getName())\n                .orElseThrow(() -> new UsernameNotFoundException(\"User Not Found with username: \" + authentication.getName()));\n        return user;\n\n    }\n\n\n}"
  },
  {
    "path": "sb-ecom/src/main/resources/application.properties",
    "content": "spring.application.name=sb-ecom\n\nspring.datasource.url=jdbc:postgresql://localhost:5432/ecommerce\nspring.datasource.username=postgres\nspring.datasource.password=admin@123\n\nspring.jpa.hibernate.ddl-auto=update\nspring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect\n\n#spring.h2.console.enabled=true\n#spring.datasource.url=jdbc:h2:mem:test\n\nproject.image=images/\n\n#spring.jpa.show-sql=true\n#spring.jpa.properties.hibernate.format_sql=true\n\n\nspring.app.jwtSecret=mySecretKey123912738aopsgjnspkmndfsopkvajoirjg94gf2opfng2moknm\nspring.app.jwtExpirationMs=300000000\nspring.ecom.app.jwtCookieName=springBootEcom\n\n\n\n#logging.level.org.springframework=DEBUG\n#logging.level.org.hibernate.SQL=DEBUG\n#logging.level.org.springframework.security=DEBUG\n#logging.level.com.ecommerce.project=DEBUG\n\n\n# Needed if you are using elastic beanstalk\n#server.port=5000\nfrontend.url=http://localhost:5173/\nimage.base.url=http://localhost:8080/images\n\n#STRIPE KEY\nstripe.secret.key=${STRIPE_SECRET_KEY}\n"
  },
  {
    "path": "sb-ecom/src/test/java/com/ecommerce/project/SbEcomApplicationTests.java",
    "content": "package com.ecommerce.project;\n\nimport org.junit.jupiter.api.Test;\nimport org.springframework.boot.test.context.SpringBootTest;\n\n@SpringBootTest\nclass SbEcomApplicationTests {\n\n\t@Test\n\tvoid contextLoads() {\n\t}\n\n}\n"
  }
]