diff --git a/package-lock.json b/package-lock.json
index 671b1384fac341a78c5aacd043a28bde7cb447ed..802c2332f59df2fd4b6353ace61ec7e7e98fc455 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,10 +13,15 @@
         "@testing-library/user-event": "^13.5.0",
         "class-variance-authority": "^0.7.0",
         "clsx": "^2.1.1",
+        "firebase": "^11.0.2",
         "react": "^18.3.1",
         "react-dom": "^18.3.1",
+        "react-icons": "^5.4.0",
+        "react-modal": "^3.16.1",
         "react-router-dom": "^6.28.0",
         "react-scripts": "5.0.1",
+        "styled-components": "^6.1.13",
+        "sweetalert2": "^11.14.5",
         "tailwind-merge": "^2.5.4",
         "web-vitals": "^2.1.4",
         "workbox-background-sync": "^6.6.0",
@@ -2248,6 +2253,27 @@
         "postcss-selector-parser": "^6.0.10"
       }
     },
+    "node_modules/@emotion/is-prop-valid": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
+      "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
+      "license": "MIT",
+      "dependencies": {
+        "@emotion/memoize": "^0.8.1"
+      }
+    },
+    "node_modules/@emotion/memoize": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
+      "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
+      "license": "MIT"
+    },
+    "node_modules/@emotion/unitless": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
+      "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
+      "license": "MIT"
+    },
     "node_modules/@eslint-community/eslint-utils": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
@@ -2344,6 +2370,684 @@
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       }
     },
+    "node_modules/@firebase/analytics": {
+      "version": "0.10.10",
+      "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.10.tgz",
+      "integrity": "sha512-Psdo7c9g2SLAYh6u1XRA+RZ7ab2JfBVuAt/kLzXkhKZL/gS2cQUCMsOW5p0RIlDPRKqpdNSmvujd2TeRWLKOkQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/installations": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/analytics-compat": {
+      "version": "0.2.16",
+      "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.16.tgz",
+      "integrity": "sha512-Q/s+u/TEMSb2EDJFQMGsOzpSosybBl8HuoSEMyGZ99+0Pu7SIR9MPDGUjc8PKiCFQWDJ3QXxgqh1d/rujyAMbA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/analytics": "0.10.10",
+        "@firebase/analytics-types": "0.8.3",
+        "@firebase/component": "0.6.11",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/analytics-types": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz",
+      "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@firebase/app": {
+      "version": "0.10.16",
+      "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.16.tgz",
+      "integrity": "sha512-SUati2qH48gvVGnSsqMkZr1Iq7No52a3tJQ4itboSTM89Erezmw3v1RsfVymrDze9+KiOLmBpvLNKSvheITFjg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "idb": "7.1.1",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@firebase/app-check": {
+      "version": "0.8.10",
+      "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.10.tgz",
+      "integrity": "sha512-DWFfxxif/t+Ow4MmRUevDX+A3hVxm1rUf6y5ZP4sIomfnVCO1NNahqtsv9rb1/tKGkTeoVT40weiTS/WjQG1mA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/app-check-compat": {
+      "version": "0.3.17",
+      "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.17.tgz",
+      "integrity": "sha512-a/eadrGsY0MVCBPhrNbKUhoYpms4UKTYLKO7nswwSFVsm3Rw6NslQQCNLfvljcDqP4E7alQDRGJXjkxd/5gJ+Q==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/app-check": "0.8.10",
+        "@firebase/app-check-types": "0.5.3",
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/app-check-interop-types": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz",
+      "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@firebase/app-check-types": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz",
+      "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@firebase/app-compat": {
+      "version": "0.2.46",
+      "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.46.tgz",
+      "integrity": "sha512-9hSHWE5LMqtKIm13CnH5OZeMPbkVV3y5vgNZ5EMFHcG2ceRrncyNjG9No5XfWQw8JponZdGs4HlE4aMD/jxcFA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/app": "0.10.16",
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@firebase/app-types": {
+      "version": "0.9.3",
+      "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz",
+      "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@firebase/auth": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.1.tgz",
+      "integrity": "sha512-LX9N/Cf5Z35r5yqm2+5M3+2bRRe/+RFaa/+u4HDni7TA27C/Xm4XHLKcWcLg1BzjrS4zngSaBEOSODvp6RFOqQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x",
+        "@react-native-async-storage/async-storage": "^1.18.1"
+      },
+      "peerDependenciesMeta": {
+        "@react-native-async-storage/async-storage": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@firebase/auth-compat": {
+      "version": "0.5.16",
+      "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.16.tgz",
+      "integrity": "sha512-YlYwJMBqAyv0ESy3jDUyshMhZlbUiwAm6B6+uUmigNDHU+uq7j4SFiDJEZlFFIz397yBzKn06SUdqutdQzGnCA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/auth": "1.8.1",
+        "@firebase/auth-types": "0.12.3",
+        "@firebase/component": "0.6.11",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/auth-interop-types": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz",
+      "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@firebase/auth-types": {
+      "version": "0.12.3",
+      "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.3.tgz",
+      "integrity": "sha512-Zq9zI0o5hqXDtKg6yDkSnvMCMuLU6qAVS51PANQx+ZZX5xnzyNLEBO3GZgBUPsV5qIMFhjhqmLDxUqCbnAYy2A==",
+      "license": "Apache-2.0",
+      "peerDependencies": {
+        "@firebase/app-types": "0.x",
+        "@firebase/util": "1.x"
+      }
+    },
+    "node_modules/@firebase/component": {
+      "version": "0.6.11",
+      "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz",
+      "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@firebase/data-connect": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.1.2.tgz",
+      "integrity": "sha512-Bcf29mntFCt5V7aceMe36wnkHrG7cwbMlUVbDHOlh2foQKx9VtSXEONw9r6FtL1sFobHVYOM5L6umX35f59m5g==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/auth-interop-types": "0.2.4",
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/database": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.10.tgz",
+      "integrity": "sha512-sWp2g92u7xT4BojGbTXZ80iaSIaL6GAL0pwvM0CO/hb0nHSnABAqsH7AhnWGsGvXuEvbPr7blZylPaR9J+GSuQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/app-check-interop-types": "0.3.3",
+        "@firebase/auth-interop-types": "0.2.4",
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "faye-websocket": "0.11.4",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@firebase/database-compat": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.1.tgz",
+      "integrity": "sha512-IsFivOjdE1GrjTeKoBU/ZMenESKDXidFDzZzHBPQ/4P20ptGdrl3oLlWrV/QJqJ9lND4IidE3z4Xr5JyfUW1vg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/database": "1.0.10",
+        "@firebase/database-types": "1.0.7",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@firebase/database-types": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.7.tgz",
+      "integrity": "sha512-I7zcLfJXrM0WM+ksFmFdAMdlq/DFmpeMNa+/GNsLyFo5u/lX5zzkPzGe3srVWqaBQBY5KprylDGxOsP6ETfL0A==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/app-types": "0.9.3",
+        "@firebase/util": "1.10.2"
+      }
+    },
+    "node_modules/@firebase/firestore": {
+      "version": "4.7.5",
+      "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.5.tgz",
+      "integrity": "sha512-OO3rHvjC07jL2ITN255xH/UzCVSvh6xG8oTzQdFScQvFbcm1fjCL1hgAdpDZcx3vVcKMV+6ktr8wbllkB8r+FQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "@firebase/webchannel-wrapper": "1.0.3",
+        "@grpc/grpc-js": "~1.9.0",
+        "@grpc/proto-loader": "^0.7.8",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/firestore-compat": {
+      "version": "0.3.40",
+      "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.40.tgz",
+      "integrity": "sha512-18HopMN811KYBc9Ptpr1Rewwio0XF09FF3jc5wtV6rGyAs815SlFFw5vW7ZeLd43zv9tlEc2FzM0H+5Vr9ZRxw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/firestore": "4.7.5",
+        "@firebase/firestore-types": "3.0.3",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/firestore-types": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz",
+      "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==",
+      "license": "Apache-2.0",
+      "peerDependencies": {
+        "@firebase/app-types": "0.x",
+        "@firebase/util": "1.x"
+      }
+    },
+    "node_modules/@firebase/functions": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.10.tgz",
+      "integrity": "sha512-TP+Dzebazhw6+GduBdWn1kOJRFH84G2z+BW3pNVfkpFRkc//+uT1Uw2+dLpMGSSBRG7FrcDG91vcPnOFCzr15w==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/app-check-interop-types": "0.3.3",
+        "@firebase/auth-interop-types": "0.2.4",
+        "@firebase/component": "0.6.11",
+        "@firebase/messaging-interop-types": "0.2.3",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/functions-compat": {
+      "version": "0.3.16",
+      "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.16.tgz",
+      "integrity": "sha512-FL7EXehiiBisNIR7mlb0i+moyWKLVfcEJgh/Wq6ZV6BdrCObpCTz7w5EvuRIEFX5e9cNL2oWInKg8S5X4HtINg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/functions": "0.11.10",
+        "@firebase/functions-types": "0.6.3",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/functions-types": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz",
+      "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@firebase/installations": {
+      "version": "0.6.11",
+      "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.11.tgz",
+      "integrity": "sha512-w8fY8mw6fxJzsZM2ufmTtomopXl1+bn/syYon+Gpn+0p0nO1cIUEVEFrFazTLaaL9q1CaVhc3HmseRTsI3igAA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/util": "1.10.2",
+        "idb": "7.1.1",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/installations-compat": {
+      "version": "0.2.11",
+      "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.11.tgz",
+      "integrity": "sha512-SHRgw5LTa6v8LubmJZxcOCwEd1MfWQPUtKdiuCx2VMWnapX54skZd1PkQg0K4l3k+4ujbI2cn7FE6Li9hbChBw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/installations": "0.6.11",
+        "@firebase/installations-types": "0.5.3",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/installations-types": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz",
+      "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==",
+      "license": "Apache-2.0",
+      "peerDependencies": {
+        "@firebase/app-types": "0.x"
+      }
+    },
+    "node_modules/@firebase/logger": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz",
+      "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@firebase/messaging": {
+      "version": "0.12.14",
+      "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.14.tgz",
+      "integrity": "sha512-cSGP34jJswFvME8tdMDkvJvW6T1jEekyMSyq84AMBZ0KEpJbDWuC9n4wKT2lxUm1jaL651iZnn6g51yCl77ICg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/installations": "0.6.11",
+        "@firebase/messaging-interop-types": "0.2.3",
+        "@firebase/util": "1.10.2",
+        "idb": "7.1.1",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/messaging-compat": {
+      "version": "0.2.14",
+      "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.14.tgz",
+      "integrity": "sha512-r9weK8jTEA2aGiwy0IbMQPnzuJ0DHkOQaMxGJOlU2QZ1a7fh6RHpNtaoM+LKnn6u1NQgmAOWYNr9vezVQEm9zw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/messaging": "0.12.14",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/messaging-interop-types": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz",
+      "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@firebase/performance": {
+      "version": "0.6.11",
+      "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.11.tgz",
+      "integrity": "sha512-FlkJFeqLlIeh5T4Am3uE38HVzggliDIEFy/fErEc1faINOUFCb6vQBEoNZGaXvRnTR8lh3X/hP7tv37C7BsK9g==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/installations": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/performance-compat": {
+      "version": "0.2.11",
+      "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.11.tgz",
+      "integrity": "sha512-DqeNBy51W2xzlklyC7Ht9JQ94HhTA08PCcM4MDeyG/ol3fqum/+YgtHWQ2IQuduqH9afETthZqLwCZiSgY7hiA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/performance": "0.6.11",
+        "@firebase/performance-types": "0.2.3",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/performance-types": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz",
+      "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@firebase/remote-config": {
+      "version": "0.4.11",
+      "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.11.tgz",
+      "integrity": "sha512-9z0rgKuws2nj+7cdiqF+NY1QR4na6KnuOvP+jQvgilDOhGtKOcCMq5XHiu66i73A9kFhyU6QQ2pHXxcmaq1pBw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/installations": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/remote-config-compat": {
+      "version": "0.2.11",
+      "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.11.tgz",
+      "integrity": "sha512-zfIjpwPrGuIOZDmduukN086qjhZ1LnbJi/iYzgua+2qeTlO0XdlE1v66gJPwygGB3TOhT0yb9EiUZ3nBNttMqg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/remote-config": "0.4.11",
+        "@firebase/remote-config-types": "0.3.3",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/remote-config-types": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.3.tgz",
+      "integrity": "sha512-YlRI9CHxrk3lpQuFup9N1eohpwdWayKZUNZ/YeQ0PZoncJ66P32UsKUKqVXOaieTjJIOh7yH8JEzRdht5s+d6g==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@firebase/storage": {
+      "version": "0.13.4",
+      "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.4.tgz",
+      "integrity": "sha512-b1KaTTRiMupFurIhpGIbReaWev0k5O3ouTHkAPcEssT+FvU3q/1JwzvkX4+ZdB60Fc43Mbp8qQ1gWfT0Z2FP9Q==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x"
+      }
+    },
+    "node_modules/@firebase/storage-compat": {
+      "version": "0.3.14",
+      "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.14.tgz",
+      "integrity": "sha512-Ok5FmXJiapaNAOQ8W8qppnfwgP8540jw2B8M0c4TFZqF4BD+CoKBxW0dRtOuLNGadLhzqqkDZZZtkexxrveQqA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/component": "0.6.11",
+        "@firebase/storage": "0.13.4",
+        "@firebase/storage-types": "0.8.3",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app-compat": "0.x"
+      }
+    },
+    "node_modules/@firebase/storage-types": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz",
+      "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==",
+      "license": "Apache-2.0",
+      "peerDependencies": {
+        "@firebase/app-types": "0.x",
+        "@firebase/util": "1.x"
+      }
+    },
+    "node_modules/@firebase/util": {
+      "version": "1.10.2",
+      "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz",
+      "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@firebase/vertexai": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@firebase/vertexai/-/vertexai-1.0.1.tgz",
+      "integrity": "sha512-f48MGSofhaS05ebpN7zMIv4tBqYf19pXr5/4njKtNZVLbjxUswDma0SuFDoO+IwgbdkhFxgtNctM+C1zfI/O1Q==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/app-check-interop-types": "0.3.3",
+        "@firebase/component": "0.6.11",
+        "@firebase/logger": "0.4.4",
+        "@firebase/util": "1.10.2",
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@firebase/app": "0.x",
+        "@firebase/app-types": "0.x"
+      }
+    },
+    "node_modules/@firebase/webchannel-wrapper": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz",
+      "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@grpc/grpc-js": {
+      "version": "1.9.15",
+      "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz",
+      "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@grpc/proto-loader": "^0.7.8",
+        "@types/node": ">=12.12.47"
+      },
+      "engines": {
+        "node": "^8.13.0 || >=10.10.0"
+      }
+    },
+    "node_modules/@grpc/proto-loader": {
+      "version": "0.7.13",
+      "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz",
+      "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "lodash.camelcase": "^4.3.0",
+        "long": "^5.0.0",
+        "protobufjs": "^7.2.5",
+        "yargs": "^17.7.2"
+      },
+      "bin": {
+        "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@grpc/proto-loader/node_modules/cliui": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+      "license": "ISC",
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.1",
+        "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@grpc/proto-loader/node_modules/yargs": {
+      "version": "17.7.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+      "license": "MIT",
+      "dependencies": {
+        "cliui": "^8.0.1",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.3",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^21.1.1"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@grpc/proto-loader/node_modules/yargs-parser": {
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/@humanwhocodes/config-array": {
       "version": "0.13.0",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
@@ -2952,6 +3656,70 @@
         }
       }
     },
+    "node_modules/@protobufjs/aspromise": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+      "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@protobufjs/base64": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+      "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@protobufjs/codegen": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+      "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@protobufjs/eventemitter": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+      "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@protobufjs/fetch": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+      "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "@protobufjs/aspromise": "^1.1.1",
+        "@protobufjs/inquire": "^1.1.0"
+      }
+    },
+    "node_modules/@protobufjs/float": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+      "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@protobufjs/inquire": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+      "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@protobufjs/path": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+      "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@protobufjs/pool": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+      "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@protobufjs/utf8": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+      "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
+      "license": "BSD-3-Clause"
+    },
     "node_modules/@remix-run/router": {
       "version": "1.21.0",
       "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz",
@@ -3905,6 +4673,12 @@
       "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
       "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="
     },
+    "node_modules/@types/stylis": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
+      "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==",
+      "license": "MIT"
+    },
     "node_modules/@types/testing-library__jest-dom": {
       "version": "5.14.9",
       "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz",
@@ -5302,6 +6076,15 @@
         "node": ">= 6"
       }
     },
+    "node_modules/camelize": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
+      "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/caniuse-api": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@@ -5820,6 +6603,15 @@
         "postcss": "^8.4"
       }
     },
+    "node_modules/css-color-keywords": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+      "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/css-declaration-sorter": {
       "version": "6.4.1",
       "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz",
@@ -5961,6 +6753,17 @@
       "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
       "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w=="
     },
+    "node_modules/css-to-react-native": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
+      "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
+      "license": "MIT",
+      "dependencies": {
+        "camelize": "^1.0.0",
+        "css-color-keywords": "^1.0.0",
+        "postcss-value-parser": "^4.0.2"
+      }
+    },
     "node_modules/css-tree": {
       "version": "1.0.0-alpha.37",
       "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
@@ -7544,6 +8347,12 @@
         "url": "https://github.com/sindresorhus/execa?sponsor=1"
       }
     },
+    "node_modules/exenv": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
+      "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==",
+      "license": "BSD-3-Clause"
+    },
     "node_modules/exit": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
@@ -7844,6 +8653,42 @@
         "node": ">=8"
       }
     },
+    "node_modules/firebase": {
+      "version": "11.0.2",
+      "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.0.2.tgz",
+      "integrity": "sha512-w4T8BSJpzdZA25QRch5ahLsgB6uRvg1LEic4BaC5rTD1YygroI1AXp+W+rbMnr8d8EjfAv6t4k8doULIjc1P8Q==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@firebase/analytics": "0.10.10",
+        "@firebase/analytics-compat": "0.2.16",
+        "@firebase/app": "0.10.16",
+        "@firebase/app-check": "0.8.10",
+        "@firebase/app-check-compat": "0.3.17",
+        "@firebase/app-compat": "0.2.46",
+        "@firebase/app-types": "0.9.3",
+        "@firebase/auth": "1.8.1",
+        "@firebase/auth-compat": "0.5.16",
+        "@firebase/data-connect": "0.1.2",
+        "@firebase/database": "1.0.10",
+        "@firebase/database-compat": "2.0.1",
+        "@firebase/firestore": "4.7.5",
+        "@firebase/firestore-compat": "0.3.40",
+        "@firebase/functions": "0.11.10",
+        "@firebase/functions-compat": "0.3.16",
+        "@firebase/installations": "0.6.11",
+        "@firebase/installations-compat": "0.2.11",
+        "@firebase/messaging": "0.12.14",
+        "@firebase/messaging-compat": "0.2.14",
+        "@firebase/performance": "0.6.11",
+        "@firebase/performance-compat": "0.2.11",
+        "@firebase/remote-config": "0.4.11",
+        "@firebase/remote-config-compat": "0.2.11",
+        "@firebase/storage": "0.13.4",
+        "@firebase/storage-compat": "0.3.14",
+        "@firebase/util": "1.10.2",
+        "@firebase/vertexai": "1.0.1"
+      }
+    },
     "node_modules/flat-cache": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
@@ -10576,6 +11421,12 @@
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
     },
+    "node_modules/lodash.camelcase": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+      "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
+      "license": "MIT"
+    },
     "node_modules/lodash.debounce": {
       "version": "4.0.8",
       "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -10601,6 +11452,12 @@
       "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
       "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="
     },
+    "node_modules/long": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
+      "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==",
+      "license": "Apache-2.0"
+    },
     "node_modules/loose-envify": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -12820,6 +13677,30 @@
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
       "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
     },
+    "node_modules/protobufjs": {
+      "version": "7.4.0",
+      "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz",
+      "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
+      "hasInstallScript": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "@protobufjs/aspromise": "^1.1.2",
+        "@protobufjs/base64": "^1.1.2",
+        "@protobufjs/codegen": "^2.0.4",
+        "@protobufjs/eventemitter": "^1.1.0",
+        "@protobufjs/fetch": "^1.1.0",
+        "@protobufjs/float": "^1.0.2",
+        "@protobufjs/inquire": "^1.1.0",
+        "@protobufjs/path": "^1.1.2",
+        "@protobufjs/pool": "^1.1.0",
+        "@protobufjs/utf8": "^1.1.0",
+        "@types/node": ">=13.7.0",
+        "long": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
     "node_modules/proxy-addr": {
       "version": "2.0.7",
       "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -13101,11 +13982,45 @@
       "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
       "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
     },
+    "node_modules/react-icons": {
+      "version": "5.4.0",
+      "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz",
+      "integrity": "sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react": "*"
+      }
+    },
     "node_modules/react-is": {
       "version": "17.0.2",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
       "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
     },
+    "node_modules/react-lifecycles-compat": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
+      "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==",
+      "license": "MIT"
+    },
+    "node_modules/react-modal": {
+      "version": "3.16.1",
+      "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.1.tgz",
+      "integrity": "sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==",
+      "license": "MIT",
+      "dependencies": {
+        "exenv": "^1.2.0",
+        "prop-types": "^15.7.2",
+        "react-lifecycles-compat": "^3.0.0",
+        "warning": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "peerDependencies": {
+        "react": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18",
+        "react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18"
+      }
+    },
     "node_modules/react-refresh": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -13994,6 +14909,12 @@
       "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
       "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
     },
+    "node_modules/shallowequal": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+      "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
+      "license": "MIT"
+    },
     "node_modules/shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -14557,6 +15478,68 @@
         "webpack": "^5.0.0"
       }
     },
+    "node_modules/styled-components": {
+      "version": "6.1.13",
+      "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz",
+      "integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==",
+      "license": "MIT",
+      "dependencies": {
+        "@emotion/is-prop-valid": "1.2.2",
+        "@emotion/unitless": "0.8.1",
+        "@types/stylis": "4.2.5",
+        "css-to-react-native": "3.2.0",
+        "csstype": "3.1.3",
+        "postcss": "8.4.38",
+        "shallowequal": "1.1.0",
+        "stylis": "4.3.2",
+        "tslib": "2.6.2"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/styled-components"
+      },
+      "peerDependencies": {
+        "react": ">= 16.8.0",
+        "react-dom": ">= 16.8.0"
+      }
+    },
+    "node_modules/styled-components/node_modules/postcss": {
+      "version": "8.4.38",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+      "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.7",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/styled-components/node_modules/tslib": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+      "license": "0BSD"
+    },
     "node_modules/stylehacks": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
@@ -14572,6 +15555,12 @@
         "postcss": "^8.2.15"
       }
     },
+    "node_modules/stylis": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
+      "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==",
+      "license": "MIT"
+    },
     "node_modules/sucrase": {
       "version": "3.35.0",
       "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
@@ -14825,6 +15814,16 @@
         "node": ">=4"
       }
     },
+    "node_modules/sweetalert2": {
+      "version": "11.14.5",
+      "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.14.5.tgz",
+      "integrity": "sha512-8MWk5uc/r6bWhiJWkUXyEuApfXAhSCZT8FFX7pZXL7YwaPxq+9Ynhi2dUzWkOFn9jvLjKj22CXuccZ+IHcnjvQ==",
+      "license": "MIT",
+      "funding": {
+        "type": "individual",
+        "url": "https://github.com/sponsors/limonte"
+      }
+    },
     "node_modules/symbol-tree": {
       "version": "3.2.4",
       "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -15547,6 +16546,15 @@
         "makeerror": "1.0.12"
       }
     },
+    "node_modules/warning": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+      "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+      "license": "MIT",
+      "dependencies": {
+        "loose-envify": "^1.0.0"
+      }
+    },
     "node_modules/watchpack": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
diff --git a/package.json b/package.json
index a8aeba3db90e6f50697070e77ecf07e48459d6c1..9794b7a42808c520486595e401f3cb9faf266c11 100644
--- a/package.json
+++ b/package.json
@@ -8,10 +8,15 @@
     "@testing-library/user-event": "^13.5.0",
     "class-variance-authority": "^0.7.0",
     "clsx": "^2.1.1",
+    "firebase": "^11.0.2",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
+    "react-icons": "^5.4.0",
+    "react-modal": "^3.16.1",
     "react-router-dom": "^6.28.0",
     "react-scripts": "5.0.1",
+    "styled-components": "^6.1.13",
+    "sweetalert2": "^11.14.5",
     "tailwind-merge": "^2.5.4",
     "web-vitals": "^2.1.4",
     "workbox-background-sync": "^6.6.0",
diff --git a/src/App.js b/src/App.js
index af5e2cb370603b0c49f90b34f74755dacf59d445..ef2b121afbb5396d732cfb4fcee62e0eeee9575a 100644
--- a/src/App.js
+++ b/src/App.js
@@ -4,6 +4,7 @@ import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
 import LoginPage from "./pages/LoginPage";
 import HomePage from "./pages/HomePage";
 import ChattingListPage from "./pages/Chatting/ChattingListPage";
+import ChattingDetailPage from "./pages/Chatting/ChattingDetailPage";
 import MyPage from "./pages/Mypage";
 import HeaderNav from "./components/layout/HeaderNav";
 import Footer from "./components/layout/Footer";
@@ -22,6 +23,7 @@ const App = () => {
             <Route path="/" element={<HomePage />} />
             <Route path="/timetable" element={<SchedulePage />} />
             <Route path="/chattinglist" element={<ChattingListPage />} />
+            <Route path="/chat/chatRoom/:chatRoomId" element={<ChattingDetailPage />} />
             <Route path="/mypage" element={<MyPage />} />
             <Route path="/login" element={<LoginPage />} />
           </Routes>
diff --git a/src/components/ChattingDetail.css b/src/components/ChattingDetail.css
new file mode 100644
index 0000000000000000000000000000000000000000..17942aca2836e4b6ff9e03833f3644385510cdf3
--- /dev/null
+++ b/src/components/ChattingDetail.css
@@ -0,0 +1,96 @@
+/* ChattingDetail.css */
+.chatting-detail-container {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: center;
+  background-color: #ffffff;
+  min-height: 100vh;
+  padding: 1rem;
+  box-sizing: border-box;
+}
+
+.chatting-header {
+  width: 100%;
+  background-color: #f8f9fa;
+  padding: 0.5rem 1rem;
+  display: flex;
+  align-items: center;
+  border-bottom: 1px solid #e9ecef;
+}
+
+.chatting-header h1 {
+  font-size: 1.25rem;
+  font-weight: bold;
+  margin-left: 0.5rem;
+  color: #343a40;
+}
+
+.chatting-messages {
+  flex: 1;
+  width: 100%;
+  overflow-y: auto;
+  padding: 1rem;
+  box-sizing: border-box;
+  background-color: #f1f3f5;
+  border-radius: 0.5rem;
+}
+
+.chatting-message {
+  display: flex;
+  align-items: flex-start;
+  margin-bottom: 0.75rem;
+}
+
+.chatting-message img {
+  width: 36px;
+  height: 36px;
+  border-radius: 50%;
+  margin-right: 0.5rem;
+}
+
+.chatting-message .message-content {
+  background-color: #ffffff;
+  padding: 0.75rem 1rem;
+  border-radius: 0.5rem;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+  max-width: 70%;
+}
+
+.chatting-message.own .message-content {
+  background-color: #e0f7fa;
+  margin-left: auto;
+}
+
+.chatting-input-container {
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding: 0.5rem;
+  background-color: #ffffff;
+  border-top: 1px solid #e9ecef;
+}
+
+.chatting-input-container input {
+  flex: 1;
+  padding: 0.75rem;
+  font-size: 1rem;
+  border: 1px solid #ced4da;
+  border-radius: 0.5rem;
+  margin-right: 0.5rem;
+  outline: none;
+}
+
+.chatting-input-container button {
+  background-color: #007bff;
+  color: #ffffff;
+  border: none;
+  padding: 0.75rem 1rem;
+  border-radius: 0.5rem;
+  font-size: 1rem;
+  cursor: pointer;
+}
+
+.chatting-input-container button:hover {
+  background-color: #0056b3;
+}
\ No newline at end of file
diff --git a/src/components/ChattingDetail.jsx b/src/components/ChattingDetail.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..5f82d0200d484816229d3f2eec3b18418e82cc37
--- /dev/null
+++ b/src/components/ChattingDetail.jsx
@@ -0,0 +1,942 @@
+import { useParams, useLocation } from 'react-router-dom';
+import { useEffect, useState, useRef, useCallback, useMemo } from 'react';
+import './ChattingDetail.css';
+import styled, { keyframes } from 'styled-components';
+import { FaSearch, FaArrowUp, FaArrowDown } from 'react-icons/fa';
+import Button from "../components/Button";
+import ChattingNoticeDetailModal from '../components/ChattingNoticeDetailModal';
+import ChattingNoticeListModal from '../components/ChattingNoticeListModal';
+
+// 흔들리는 애니메이션을 위한 keyframes 정의
+const shakeAnimation = keyframes`
+  0% { transform: translateY(0); }
+  25% { transform: translateY(-5px); }
+  50% { transform: translateY(0); }
+  75% { transform: translateY(5px); }
+  100% { transform: translateY(0); }
+`;
+
+const ChatRoomContainer = styled.div`
+  display: flex;
+  flex-direction: column;
+  height: 100vh; /* 전체 화면 높이 */
+  width: 100%;
+  overflow: hidden; /* 부모 요소의 스크롤 제거 */
+`;
+
+const ChatRoomHeader = styled.div`
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 10px;
+  border-bottom: 1px solid #ddd;
+`;
+
+const SearchBar = styled.div`
+  display: flex;
+  align-items: center;
+  padding: 10px;
+  border-bottom: 1px solid #ddd;
+
+  input {
+    width: 100%;
+    padding: 10px;
+    border-radius: 5px;
+    border: 1px solid #ddd;
+  }
+
+  .arrow-buttons {
+    display: flex;
+    align-items: center;
+    margin-left: 10px;
+
+    svg {
+      cursor: pointer;
+      margin-left: 5px;
+    }
+  }
+`;
+
+const ChatRoomMessages = styled.div`
+  flex: 1;
+  overflow-y: auto; /* 메시지 영역만 스크롤 가능 */
+  padding: 10px;
+  margin-top: 10px; /* 검색 바와 메시지 사이 여백 */
+`;
+
+const MessageContainer = styled.div`
+  display: flex;
+  justify-content: ${(props) => (props.isMine ? 'flex-end' : 'flex-start')};
+  margin-bottom: 10px;
+  padding: 10px;
+  border-radius: 5px;
+  border: ${(props) => (props.highlighted ? '2px solid blue' : 'none')};
+  transition: background-color 0.3s ease, border 0.3s ease;
+  animation: ${(props) => (props.highlighted ? shakeAnimation : 'none')} 0.5s ease;
+`;
+
+const MessageBubble = styled.div`
+  max-width: 60%;
+  padding: 10px;
+  border-radius: 10px;
+  background-color: ${(props) => (props.isMine ? '#dcf8c6' : '#f9f9f9')};
+  text-align: ${(props) => (props.isMine ? 'right' : 'left')};
+  border: ${(props) => (props.highlighted ? '2px solid blue' : 'none')};
+  word-wrap: break-word;
+  transition: background-color 0.3s ease, border 0.3s ease;
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1);
+  animation: ${(props) => (props.highlighted ? shakeAnimation : 'none')} 0.5s ease;
+`;
+
+const CenteredMessage = styled.div`
+  text-align: center;
+  font-size: 0.9em;
+  color: #888;
+  margin: 20px 0;
+  background-color: #f0f0f0;
+  padding: 10px;
+  border-radius: 10px;
+  max-width: 50%;
+  margin-left: auto;
+  margin-right: auto;
+`;
+
+const MessageTimestamp = styled.div`
+  font-size: 0.8em;
+  color: #888;
+  text-align: ${(props) => (props.isMine ? 'right' : 'left')};
+`;
+
+const ChatRoomInput = styled.div`
+  display: flex;
+  padding: 10px;
+  border-top: 1px solid #ddd;
+
+  input {
+    flex: 1;
+    padding: 10px;
+    border-radius: 5px;
+    border: 1px solid #ddd;
+    margin-right: 10px;
+  }
+
+  button {
+    padding: 10px;
+    border-radius: 5px;
+    background-color: #007bff;
+    color: white;
+    border: none;
+    cursor: pointer;
+  }
+
+  button:hover {
+    background-color: #0056b3;
+  }
+`;
+
+const FixedSearchBar = styled(SearchBar)`
+  position: sticky;
+  top: 0; /* 화면 상단에 고정 */
+  z-index: 10; /* 다른 요소 위에 표시 */
+  background-color: white; /* 배경색 지정 */
+  border-bottom: 1px solid #ddd;
+`;
+
+const NoticeContainer = styled.div`
+  background-color: ${({ isCollapsed }) => (isCollapsed ? "transparent" : "#f8f9fa")};
+  padding: ${({ isCollapsed }) => (isCollapsed ? "0" : "10px")};
+  border-bottom: ${({ isCollapsed }) => (isCollapsed ? "none" : "1px solid #ddd")};
+  position: relative; /* 확성기 위치 조정을 위해 사용 */
+`;
+
+const NoticeMessage = styled.div`
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 3; /* 최대 3줄까지만 표시 */
+  white-space: normal;
+  height: calc(1.3em * 3); /* 3줄 높이로 제한 */
+  cursor: pointer;
+  margin-bottom: -30px; /* 메시지와 작성자 사이 간격 */
+`;
+
+const NoticeSender = styled.div`
+  font-size: 0.875rem;
+  color: #888;
+  text-align: left;
+`;
+
+const NoticeActions = styled.div`
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 10px;
+  gap: 10px;
+
+  button {
+    padding: 5px 10px;
+    border: none;
+    background-color: #e7e7e7;
+    color: #555;
+    border-radius: 5px;
+    cursor: pointer;
+    font-size: 0.9em;
+  }
+
+  button:hover {
+    background-color: #d6d6d6;
+  }
+`;
+
+function ChattingDetail() {
+  const { chatRoomId } = useParams();
+  const location = useLocation();
+  const { nickname, chatRoomName } = location.state;
+
+  // const [notice, setNotice] = useState(null); // 공지 메시지  
+  const [messages, setMessages] = useState([]);
+  const [input, setInput] = useState('');
+  const [searchTerm, setSearchTerm] = useState('');
+  const [searchResults, setSearchResults] = useState([]);
+  const [currentSearchIndex, setCurrentSearchIndex] = useState(0);
+  const [isSearching, setIsSearching] = useState(false);
+  const [loggedInUser, setLoggedInUser] = useState(nickname);
+  const [chatUnread, setChatUnread] = useState({});
+  // const [isScrolledToBottom, setIsScrolledToBottom] = useState(true);
+  const [notice, setNotice] = useState(null); // 공지 메시지  
+  const [isNoticeVisible, setIsNoticeVisible] = useState(true); // 공지 표시 여부
+  const [isNoticeCollapsed, setIsNoticeCollapsed] = useState(false); // 공지 접힘 여부
+  const [isNoticeModalOpen, setIsNoticeModalOpen] = useState(false);
+  const [isNoticeDetailModalOpen, setIsNoticeDetailModalOpen] = useState(false); // 공지 상세 모달 상태
+  const [selectedNotice, setSelectedNotice] = useState(null); // 선택된 공지
+  const [notices, setNotices] = useState([]); // 공지사항 목록
+
+  // const chatRoomMessagesRef = useRef(null); // 메시지 컨테이너 참조
+  const ws = useRef(null);
+  const messagesEndRef = useRef(null);
+  const searchInputRef = useRef(null);
+  const highlightedMessageRef = useRef(null);
+  const isTabActiveRef = useRef(true); // useRef로 상태 초기화
+  
+  let reconnectAttempts = 0;
+  const MAX_RECONNECT_ATTEMPTS = 5;
+  // let isTabActive = true; // 브라우저 탭 상태를 저장
+
+  const lastReadLogIdRef = useRef(null);
+
+  const chatUnreadSortArray = useMemo(() => {
+    return Object.entries(chatUnread).sort(([key1], [key2]) => {
+      return key1.localeCompare(key2);
+    });
+  }, [chatUnread]);
+
+  const toggleSearchBar = () => {
+    setIsSearching((prevState) => !prevState);
+  };
+
+  const unreadCount = useCallback(
+    (logId) => {
+      if (chatUnreadSortArray.length === 0) {
+        return 0;
+      } 
+
+      for (let i = 0; i < chatUnreadSortArray.length; i++) {
+        if (logId <= chatUnreadSortArray[i][1]) {
+          return i === 0 ? 0 : Number(chatUnreadSortArray[i - 1][0]);
+        }
+      }
+
+      return Number(chatUnreadSortArray[chatUnreadSortArray.length - 1][0]);
+    },
+    [chatUnreadSortArray]
+  );
+
+  const handleNoticeClick = () => {
+    setSelectedNotice(notice); // 현재 공지사항을 선택
+    setIsNoticeDetailModalOpen(true); // 상세 모달 열기
+  };
+
+  const closeNoticeDetailModal = () => {
+    setIsNoticeDetailModalOpen(false); // 상세 모달 닫기
+  };
+
+  const handleNoticeCollapse = () => {
+    setIsNoticeCollapsed(true); // 공지를 접음
+  };
+
+  const handleMegaphoneClick = () => {
+    setIsNoticeCollapsed(false); // 공지를 펼침
+  };
+
+  const handleDismissNotice = () => {
+    const dismissedNotices = JSON.parse(localStorage.getItem('dismissedNotices')) || [];
+    
+    // 현재 공지사항이 로컬 스토리지에 추가되도록 처리
+    if (notice && !dismissedNotices.includes(notice.message)) {
+      dismissedNotices.push(notice.message);
+      localStorage.setItem('dismissedNotices', JSON.stringify(dismissedNotices));
+    }
+
+    setIsNoticeVisible(false); // 공지를 숨김
+  };
+
+  const fetchUnreadCounts = async () => {
+    try {
+      const response = await fetch(`http://localhost:8080/api/chat/unread-count/${chatRoomId}`);
+      if (response.ok) {
+        const data = await response.json();
+        setChatUnread(data);
+      } else {
+        console.error('Failed to fetch unread counts');
+      }
+    } catch (error) {
+      console.error('Error fetching unread counts:', error);
+    }
+  };
+
+  /// 합친 코드
+  const updateUserStatusAndLogId = async (status) => {
+    let logId = null;
+    // isOnline이 false일 경우 마지막 메시지의 logId를 가져옴
+    // isOnline이 false로 전환될 때 마지막 메시지가 없으면 가장 최근 메시지의 logId를 설정
+    if (!status) {
+      if (messages.length > 0) {
+        logId = messages[messages.length - 1]._id;  // 가장 최근 메시지의 logId로 설정
+      } else {
+        logId = lastReadLogIdRef.current;  // 마지막 읽은 logId를 그대로 유지
+      }
+    }
+
+    try {
+      const response = await fetch('http://localhost:8080/api/chat/update-status-and-logid', {
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json',
+        },
+        body: JSON.stringify({
+          chatRoomId,
+          nickname,
+          isOnline: status,
+          logId: logId,  // 상태에 따라 logId도 함께 보냄
+        }),
+      });
+
+      if (!response.ok) {
+        throw new Error('Failed to update status and logId');
+      }
+
+      console.log(`${nickname} : 상태업데이트 to ${status}, logId updated to ${logId} for `);
+    } catch (err) {
+      console.error('Error updating status and logId:', err);
+    }
+  };
+
+  const handleRightClick = async (e, messageData) => {
+    e.preventDefault();
+    if (window.confirm("이 메시지를 공지로 설정하시겠습니까?")) {
+      try {
+
+        const noticeMessage = {
+          type: 'notice',          // 메시지 유형: 공지사항 설정
+          chatRoomId: chatRoomId, // 현재 채팅방 ID
+          nickname: loggedInUser,     // 공지 설정한 사용자 닉네임
+          text: messageData.message,          // 공지 내용
+        };
+
+        // WebSocket을 통해 서버로 메시지 전송
+        ws.current.send(JSON.stringify(noticeMessage));
+        console.log('공지사항 설정 메시지 전송:', noticeMessage);
+
+
+        const response = await fetch(
+          `http://localhost:8080/api/chat/${chatRoomId}/notices`,
+          {
+            method: 'POST',
+            headers: {
+              'Content-Type': 'application/json',
+            },
+            body: JSON.stringify({
+              sender: messageData.sender,
+              message: messageData.message,
+            }),
+          }
+        );
+
+        if (response.ok) {
+          const newNotice = await response.json();
+          setNotice(newNotice); // 공지를 로컬 상태로 업데이트
+        } else {
+          console.error('Failed to set notice');
+        }
+      } catch (error) {
+        console.error('Error setting notice:', error);
+      }
+    }
+  };
+
+  // // 새로운 메시지가 왔을 때만 스크롤
+  // useEffect(() => {
+  //   if (messages.length > 0) {
+  //     const lastMessage = messages[messages.length - 1];
+  //     if (lastMessage.type === 'message') {
+  //       scrollToBottom();
+  //     }
+  //   }
+  // }, [messages]); // messages가 변경될 때만 실행
+
+  // const scrollToBottom = () => {
+  //   console.log("바닥 스크롤")
+  //   if (messagesEndRef.current) {
+  //     messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
+  //   }
+  // };
+
+  const fetchLatestNotice = async () => {
+    try {
+      const response = await fetch(`http://localhost:8080/api/chat/${chatRoomId}/notices/latest`);
+      if (response.ok) {
+        const latestNotice = await response.json();
+
+        const dismissedNotices = JSON.parse(localStorage.getItem('dismissedNotices')) || [];
+        const isDismissed = dismissedNotices.includes(latestNotice.message);
+
+        // 새로운 공지라면 표시하고, 숨겨진 공지가 아니라면 표시
+        setNotice(latestNotice);
+        setIsNoticeVisible(!isDismissed);
+      } else if (response.status === 404) {
+        // 공지가 없는 경우 처리
+        setNotice(null);
+        setIsNoticeVisible(false);
+      } else {
+        console.error('Failed to fetch latest notice');
+      }
+    } catch (error) {
+      console.error('Error fetching latest notice:', error);
+    }
+  };
+
+  const scrollToHighlightedMessage = () => {
+    if (highlightedMessageRef.current) {
+      highlightedMessageRef.current.scrollIntoView({ 
+        behavior: 'smooth', 
+        block: 'center' 
+      });
+    }
+  };
+
+  const joinRoom = () => {
+    if (ws.current) {
+      ws.current.close(); // 기존 WebSocket 연결 종료
+    }
+
+    ws.current = new WebSocket('ws://localhost:8081');
+    ws.current.onopen = () => {
+      if (ws.current.isTimedOut) {
+        console.log(`타임아웃된 클라이언트의 재연결을 차단: ${nickname}`);
+        ws.current.close();
+        return;
+      }
+      
+      reconnectAttempts = 0; // 재연결 성공 시 시도 횟수 초기화
+      const joinMessage = JSON.stringify({
+        type: 'join',
+        chatRoomId,
+        nickname,
+      });
+      ws.current.send(joinMessage);
+      console.log(`(클라이언트) WebSocket 연결 완료 - 채팅방: ${chatRoomId}, 닉네임: ${nickname}`);
+    };
+
+    ws.current.onmessage = (event) => {
+      const messageData = JSON.parse(event.data);
+      console.log("받은 메시지", messageData);
+
+      if (messageData.type === 'status') {
+        const { nickname, isOnline } = messageData;
+        if (!isOnline) {
+          console.log(`${nickname}님이 오프라인 상태로 전환되었습니다.`);
+        }
+        fetchUnreadCounts();
+        return;
+      }
+
+      if (messageData.type === 'notice') {
+        // 공지사항 변경 이벤트 처리
+        console.log('새 공지사항 알림 수신:', messageData);
+        setNotice({
+          sender: messageData.sender,
+          message: messageData.message,
+        });
+        setIsNoticeVisible(true); // 공지를 표시하도록 설정
+        fetchLatestNotice(); // 최신 공지사항 업데이트
+      } else if (messageData.type === 'previousMessages') {
+        // setMessages((prevMessages) => [...prevMessages, ...messageData.messages]);
+        setMessages((prevMessages) => {
+          const messageIds = new Set(prevMessages.map((msg) => msg._id)); // 기존 메시지의 ID 저장
+          const newMessages = messageData.messages.filter((msg) => !messageIds.has(msg._id)); // 중복 제거
+          return [...prevMessages, ...newMessages];
+        });
+      } else {
+        // setMessages((prevMessages) => [...prevMessages, messageData]);
+        setMessages((prevMessages) => {
+          const messageIds = new Set(prevMessages.map((msg) => msg._id)); // 기존 메시지의 ID 저장
+          if (!messageIds.has(messageData._id)) { // 새 메시지가 중복되지 않으면 추가
+            return [...prevMessages, messageData];
+          }
+          return prevMessages;
+        });
+
+        lastReadLogIdRef.current = messageData._id;
+        // messages 배열에 메시지가 추가된 후에 logId를 업데이트
+        const lastMessage = messageData;  // 새로 받은 메시지
+        lastReadLogIdRef.current = lastMessage._id;
+
+        console.log('Received message logId:', lastReadLogIdRef.current);
+        if (!chatUnreadSortArray.length || chatUnreadSortArray[chatUnreadSortArray.length - 1][1] <= messageData._id) {
+          fetchUnreadCounts(chatRoomId);
+        }
+      }
+      updateLastReadAt();
+    };
+
+    ws.current.onclose = async (event) => {
+      console.warn('(클라이언트)WebSocket 연결이 종료되었습니다.', event);
+
+      // 탭이 활성화된 상태에서만 재연결 시도
+      if (isTabActiveRef.current && reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
+        setTimeout(() => {
+          console.log(`WebSocket 재연결 시도 (${reconnectAttempts + 1}/${MAX_RECONNECT_ATTEMPTS})`);
+          reconnectAttempts++;
+          joinRoom(); // 재연결 시도
+        }, 2000); // 2초 후 재연결
+      } else if (!isTabActiveRef.current) {
+        console.log('브라우저 탭이 비활성화 상태입니다. WebSocket 재연결을 시도하지 않습니다.');
+      } else {
+        console.error('WebSocket 재연결 실패: 최대 시도 횟수를 초과했습니다.');
+      }
+    };
+
+    ws.current.onerror = (error) => {
+      console.error('WebSocket 오류:', error);
+    };
+  };
+
+  const updateLastReadAt = async () => {
+    try {
+      const response = await fetch('http://localhost:8080/api/chat/update-read-status', {
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json',
+        },
+        body: JSON.stringify({ chatRoomId, nickname }),
+      });
+
+      if (!response.ok) {
+        throw new Error('Failed to update lastReadAt');
+      }
+
+      console.log('lastReadAt updated for', nickname);
+    } catch (err) {
+      console.error('Error updating lastReadAt:', err);
+    }
+    
+  };
+
+  // // 채팅방에서 퇴장
+  // const leaveRoom = () => {
+  //   const leaveMessage = JSON.stringify({
+  //     type: 'leave',
+  //     chatRoomId,
+  //     nickname,
+  //   });
+  //   try {
+  //     ws.current.send(leaveMessage);  // 서버로 퇴장 메시지 전송
+  //     console.log('퇴장 메시지 전송:', leaveMessage);
+  //     ws.current.close();  // 웹소켓 연결 종료
+  //   } catch (error) {
+  //     console.error('퇴장 메시지 전송 오류:', error);
+  //   } 
+  // };
+
+  const handleSearch = (e) => {
+    if (e.key === 'Enter') {
+      const results = messages.filter((message) => message.message.includes(searchTerm));
+      setSearchResults(results);
+      setCurrentSearchIndex(results.length > 0 ? results.length - 1 : -1);
+      setIsSearching(true);
+      setTimeout(() => {
+        scrollToHighlightedMessage();
+      }, 100);
+    }
+  };
+
+  const handleArrowDown = () => {
+    if (searchResults.length > 0 && currentSearchIndex < searchResults.length - 1) {
+      setCurrentSearchIndex((prevIndex) => prevIndex + 1);
+      setTimeout(() => {
+        scrollToHighlightedMessage();
+      }, 0);
+    } else {
+      alert('더 이상 검색결과가 없습니다.');
+    }
+  };
+
+  const handleArrowUp = () => {
+    if (searchResults.length > 0 && currentSearchIndex > 0) {
+      setCurrentSearchIndex((prevIndex) => prevIndex - 1);
+      setTimeout(() => {
+        scrollToHighlightedMessage();
+      }, 0);
+    } else {
+      alert('더 이상 검색결과가 없습니다.');
+    }
+  };
+
+  const sendMessage = () => {
+    if (input.trim()) {
+      const message = JSON.stringify({
+        type: 'message',
+        chatRoomId,
+        sender: loggedInUser,
+        nickname,
+        text: input,
+      });
+
+      try {
+        ws.current.send(message);
+        console.log('전송한 메시지:', message);
+        updateLastReadAt();
+      } catch (error) {
+        console.error('메시지 전송 오류:', error);
+      }
+
+      setInput('');
+    } else {
+      alert('메시지를 입력하세요.');
+    }
+  };
+
+  useEffect(() => {
+    if (isSearching && searchInputRef.current) {
+      searchInputRef.current.focus();
+    }
+  }, [isSearching]);
+
+  useEffect(() => {
+    let heartbeatInterval;
+
+    const sendHeartbeat = () => {
+      if (ws.current && ws.current.readyState === WebSocket.OPEN) {
+        const heartbeatMessage = JSON.stringify({
+          type: 'heartbeat',
+          chatRoomId,
+          nickname,
+        });
+        ws.current.send(heartbeatMessage);
+        // console.log('Heartbeat sent:', heartbeatMessage);
+      }
+    };
+
+    const startHeartbeat = () => {
+      // 5초 간격으로 Heartbeat 전송
+      heartbeatInterval = setInterval(sendHeartbeat, 5000);
+    };
+
+    const stopHeartbeat = () => {
+      clearInterval(heartbeatInterval);
+    };
+
+    joinRoom();
+    // WebSocket 연결 시 Heartbeat 시작
+    startHeartbeat();
+
+    updateLastReadAt();
+
+      // 탭 상태가 변경되면 Heartbeat 중단/재개
+    document.addEventListener('visibilitychange', () => {
+      if (document.visibilityState === 'hidden') {
+        stopHeartbeat();
+      } else if (document.visibilityState === 'visible') {
+        startHeartbeat();
+      }
+    });
+
+    return () => {
+      if (ws.current) ws.current.close();
+    };
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [chatRoomId]);
+
+  useEffect(() => {
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+    const handleVisibilityChange = () => {
+      if (document.visibilityState === 'hidden') { // 브라우저 탭이 비활성화되었을 때
+        // isTabActive = false; // 탭 비활성화 상태로 설정
+        isTabActiveRef.current = false; // 탭 비활성화 상태로 설정
+        updateUserStatusAndLogId(false);
+        if (ws.current) {
+          ws.current.close(); // WebSocket 연결 종료
+          console.log('브라우저 탭 비활성화: WebSocket 연결 종료');
+        }
+      } else if (document.visibilityState === 'visible') { // 브라우저 탭이 다시 활성화되었을 때
+        // isTabActive = true; // 탭 활성화 상태로 설정
+        isTabActiveRef.current = false; // 탭 비활성화 상태로 설정
+        updateUserStatusAndLogId(true);
+        if (!ws.current || ws.current.readyState === WebSocket.CLOSED) {
+          console.log('브라우저 탭 활성화: WebSocket 연결 재시작');
+          joinRoom(); // WebSocket 재연결 시도
+        }
+      }
+    };
+
+    document.addEventListener("visibilitychange", handleVisibilityChange);
+
+    return () => {
+      document.removeEventListener("visibilitychange", handleVisibilityChange);
+    };
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [chatRoomId]);
+
+  useEffect(() => {
+    if (searchResults.length > 0) {
+      scrollToHighlightedMessage();
+    }
+  }, [currentSearchIndex, searchResults.length]);
+
+  useEffect(() => {
+    console.log('chatRoomId:', chatRoomId);
+    console.log('nickname:', nickname);
+    setLoggedInUser(nickname);
+  }, [chatRoomId, nickname]);
+
+  useEffect(() => {
+    fetchLatestNotice();
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [chatRoomId]); // 채팅방 ID가 변경될 때마다 공지사항 업데이트
+
+  useEffect(() => {
+    // 공지사항 목록 가져오기
+    const fetchNotices = async () => {
+      try {
+        const response = await fetch(`http://localhost:8080/api/chat/${chatRoomId}/notices`);
+        if (response.ok) {
+          const data = await response.json();
+          setNotices(data); // 공지사항 목록 업데이트
+        } else {
+          console.error('Failed to fetch notices');
+        }
+      } catch (error) {
+        console.error('Error fetching notices:', error);
+      }
+    };
+    fetchNotices();
+  }, [chatRoomId]);
+
+  useEffect(() => {
+    // 공지가 변경되면 렌더링
+    console.log('공지사항 업데이트:', notice);
+  }, [notice]);
+
+  useEffect(() => {
+    const handleBeforeUnload = () => {
+      updateUserStatusAndLogId(false);
+      if (ws.current) {
+        ws.current.close(); // WebSocket 연결 종료
+      }
+    };
+
+    window.addEventListener('beforeunload', handleBeforeUnload); // 브라우저 종료/새로고침 이벤트 리스너 추가
+
+    return () => {
+      console.log("페이지 이동시 상태 업데이트");
+      updateUserStatusAndLogId(false); // 페이지 이동 시 상태 업데이트
+      window.removeEventListener('beforeunload', handleBeforeUnload); // 컴포넌트 언마운트 시 이벤트 리스너 제거
+      if (ws.current) {
+        ws.current.close(); // WebSocket 연결 종료
+      }
+    };
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [chatRoomId]); // chatRoomId 변경 또는 컴포넌트 언마운트 시 실행
+
+  const highlightSearchTerm = (message) => {
+    if (!searchTerm) return message;
+
+    const regex = new RegExp(`(${searchTerm})`, 'gi');
+    const parts = message.split(regex);
+
+    return parts.map((part, index) =>
+      part.toLowerCase() === searchTerm.toLowerCase() ? (
+        <span key={index} style={{ backgroundColor: 'yellow', fontWeight: 'bold' }}>
+          {part}
+        </span>
+      ) : (
+        part
+      )
+    );
+  };
+
+  return (
+    <ChatRoomContainer>
+      <ChatRoomHeader>
+        <h1 className="heading-1 text-gray-800">{chatRoomName}</h1>
+        {/* 검색 버튼 */}
+        <Button
+          size="lg"
+          theme="pink"
+          icon={<FaSearch />} 
+          onClick={toggleSearchBar}
+        >
+          
+        </Button>
+      </ChatRoomHeader>
+
+      {/* 공지사항 */}
+      {isNoticeVisible && notice && (
+        <NoticeContainer isCollapsed={isNoticeCollapsed}>
+          {!isNoticeCollapsed ? (
+            <>
+              <NoticeMessage isCollapsed={isNoticeCollapsed} onClick={handleNoticeClick}>
+                📢 {notice?.message}
+              </NoticeMessage>
+              <NoticeSender>
+                {notice?.sender}
+              </NoticeSender>
+              <NoticeActions>
+                <button onClick={handleNoticeCollapse}>접어두기</button>
+                <button onClick={handleDismissNotice}>다시 열지 않음</button>
+              </NoticeActions>
+            </>
+          ) : (
+            <Button
+              size="lg"
+              theme="mix"
+              onClick={handleMegaphoneClick}
+              style={{
+                position: "absolute",
+                bottom: "-100px",
+                right: "30px",
+                zIndex: "20",
+              }}
+            >
+              📢
+            </Button>
+          )}
+        </NoticeContainer>
+      )}
+
+      {/* 공지사항 상세 모달 */}
+      {isNoticeDetailModalOpen && (
+        <ChattingNoticeDetailModal
+          initialNotice={selectedNotice} // 처음 표시할 공지사항
+          notices={notices}
+          onClose={closeNoticeDetailModal}
+          onSelectNotice={(notice) => setSelectedNotice(notice)}
+        />
+      )}
+
+      {/* 공지사항 목록 모달 */}
+      {isNoticeModalOpen && (
+        <ChattingNoticeListModal
+          notices={notices}
+          onClose={() => setIsNoticeModalOpen(false)}
+          onNoticeClick={(notice) => {
+            setSelectedNotice(notice);
+            setIsNoticeDetailModalOpen(true);
+          }}
+        />
+      )}
+
+      {isSearching && (
+      <FixedSearchBar>
+        <input
+          ref={searchInputRef}
+          type="text"
+          value={searchTerm}
+          onChange={(e) => setSearchTerm(e.target.value)}
+          onKeyPress={handleSearch}
+          placeholder="대화 내용 검색"
+        />
+        <div className="arrow-buttons">
+          <FaArrowUp
+            onClick={handleArrowUp}
+            size={20}
+            style={{ pointerEvents: currentSearchIndex > 0 ? 'auto' : 'none', opacity: currentSearchIndex > 0 ? 1 : 0.5 }}
+          />
+          <FaArrowDown
+            onClick={handleArrowDown}
+            size={20}
+            style={{
+              pointerEvents: currentSearchIndex < searchResults.length - 1 ? 'auto' : 'none',
+              opacity: currentSearchIndex < searchResults.length - 1 ? 1 : 0.5,
+            }}
+          />
+        </div>
+        {searchResults.length === 0 && (
+          <p style={{ color: 'gray', fontSize: '0.9em', textAlign: 'center', marginTop: '10px' }}>
+            더 이상 검색 결과가 없습니다.
+          </p>
+        )}
+      </FixedSearchBar>
+    )}
+
+      <ChatRoomMessages>
+        {messages.length === 0 ? (
+          <p>메시지가 없습니다.</p>
+        ) : (
+          messages.map((messageData, index) => {
+            if (messageData.type === "join" || messageData.type === "leave") {
+              return (
+                <CenteredMessage key={index}>{messageData.message}</CenteredMessage>
+              );
+            }
+
+            return (
+              <MessageContainer
+                key={index}
+                isMine={messageData.sender === loggedInUser}
+                highlighted={searchResults[currentSearchIndex] === messageData}
+                ref={
+                  searchResults[currentSearchIndex] === messageData
+                    ? highlightedMessageRef
+                    : null
+                }
+              >
+                <MessageBubble 
+                  isMine={messageData.sender === loggedInUser}
+                  onContextMenu={(e) => handleRightClick(e, messageData)}  
+                > 
+                  <div>
+                    {messageData.sender !== loggedInUser && (
+                      <strong>{messageData.sender}</strong>
+                    )}
+                    {highlightSearchTerm(messageData.message)}
+                  </div>
+                  <MessageTimestamp isMine={messageData.sender === loggedInUser}>
+                    {new Date(messageData.timestamp).toLocaleTimeString()}
+                    <span>{` (${unreadCount(
+                      messageData._id
+                    )}명이 읽지 않음)`}</span>
+                  </MessageTimestamp>
+                </MessageBubble>
+              </MessageContainer>
+            );
+          })
+        )}
+        <div ref={messagesEndRef}></div>
+      </ChatRoomMessages>
+
+      <ChatRoomInput>
+        <input
+          type="text"
+          value={input}
+          onChange={(e) => setInput(e.target.value)}
+          placeholder="메시지를 입력하세요"
+          onKeyPress={(e) => e.key === "Enter" && sendMessage()}
+        />
+        <button onClick={sendMessage}>전송</button>
+      </ChatRoomInput>
+    </ChatRoomContainer>
+  );
+}
+
+export default ChattingDetail;
\ No newline at end of file
diff --git a/src/components/ChattingList.jsx b/src/components/ChattingList.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..4a2b3a0bd5d3cb87472135148f89d2819df7aff3
--- /dev/null
+++ b/src/components/ChattingList.jsx
@@ -0,0 +1,176 @@
+import React, { useState, useEffect, useRef, useCallback } from "react";
+import { useNavigate } from "react-router-dom";
+
+function ChattingList() {
+  const [rooms, setRooms] = useState([]);
+  const [joinedRooms, setJoinedRooms] = useState([]);
+  const [unreadCounts, setUnreadCounts] = useState({});
+  const [nickname] = useState(localStorage.getItem("nickname") || "");
+  const navigate = useNavigate();
+  const ws = useRef(null);
+
+  // WebSocket 연결 및 실시간 업데이트
+  const setupWebSocket = () => {
+    ws.current = new WebSocket('ws://localhost:8081'); // WebSocket 연결
+
+    ws.current.onopen = () => {
+      console.log('WebSocket 연결 성공');
+    };
+
+    ws.current.onmessage = (event) => {
+      try {
+        const messageData = JSON.parse(event.data);
+
+        if (messageData.type === 'message') {
+          const { chatRoomId, sender, message, timestamp } = messageData;
+
+          // 마지막 메시지 업데이트
+          setRooms((prevRooms) =>
+            prevRooms.map((room) =>
+              room.chatRoomId === chatRoomId
+                ? {
+                    ...room,
+                    lastMessage: { sender, message, timestamp },
+                  }
+                : room
+            )
+          );
+
+          // 읽지 않은 메시지 개수 업데이트
+          setUnreadCounts((prevUnreadCounts) => ({
+            ...prevUnreadCounts,
+            [chatRoomId]: (prevUnreadCounts[chatRoomId] || 0) + 1,
+          }));
+        }
+      } catch (error) {
+        console.error('Error parsing WebSocket message:', error);
+      }
+    };
+
+    ws.current.onclose = () => {
+      console.log('("채팅 목록) WebSocket 연결이 종료되었습니다.');
+    };
+
+    ws.current.onerror = (error) => {
+      console.error('WebSocket 오류:', error);
+    };
+  };
+
+  const fetchRooms = async () => {
+    try {
+      const response = await fetch("http://localhost:8080/api/chat/rooms");
+      if (!response.ok) throw new Error("Failed to fetch rooms");
+      const data = await response.json();
+      setRooms(data);
+    } catch (err) {
+      console.error("Error fetching rooms:", err);
+    }
+  };
+
+  // const fetchUnreadMessages = async () => {
+  //   try {
+  //     const response = await fetch(`http://localhost:8080/api/chat/unread-messages/${nickname}`);
+  //     if (!response.ok) throw new Error("Failed to fetch unread messages");
+  //     const data = await response.json();
+  //     const joinedChatRoomIds = data.map((chatRoom) => chatRoom.chatRoomId);
+  //     const unreadCountsMap = data.reduce((acc, chatRoom) => {
+  //       acc[chatRoom.chatRoomId] = chatRoom.unreadCount;
+  //       return acc;
+  //     }, {});
+  //     setJoinedRooms(joinedChatRoomIds);
+  //     setUnreadCounts(unreadCountsMap);
+  //   } catch (err) {
+  //     console.error("Error fetching unread messages:", err);
+  //   }
+  // };
+  const fetchUnreadMessages = useCallback(async () => {
+    try {
+      const response = await fetch(`http://localhost:8080/api/chat/unread-messages/${nickname}`);
+      if (!response.ok) throw new Error("Failed to fetch unread messages");
+      const data = await response.json();
+      const joinedChatRoomIds = data.map((chatRoom) => chatRoom.chatRoomId);
+      const unreadCountsMap = data.reduce((acc, chatRoom) => {
+        acc[chatRoom.chatRoomId] = chatRoom.unreadCount;
+        return acc;
+      }, {});
+      setJoinedRooms(joinedChatRoomIds);
+      setUnreadCounts(unreadCountsMap);
+    } catch (err) {
+      console.error("Error fetching unread messages:", err);
+    }
+  }, [nickname]);
+
+  const joinRoom = (chatRoomId, chatRoomName) => {
+    if (!nickname.trim()) {
+      alert("닉네임을 입력하세요.");
+      return;
+    }
+    setUnreadCounts((prevUnreadCounts) => ({
+      ...prevUnreadCounts,
+      [chatRoomId]: 0,
+    }));
+    navigate(`/chat/chatRoom/${chatRoomId}`, { state: { nickname, chatRoomId, chatRoomName } });
+  };
+
+  useEffect(() => {
+    console.log("Unread counts updated:", unreadCounts);
+  }, [unreadCounts]);
+
+  useEffect(() => {
+    fetchRooms();
+    if (nickname) {
+      fetchUnreadMessages();
+    }
+    setupWebSocket(); // WebSocket 연결 설정
+    return () => {
+      if (ws.current) ws.current.close();
+    };
+  }, [nickname, fetchUnreadMessages]);
+
+  return (
+    <div className="max-w-6xl mx-auto p-6 font-sans">
+      <h1 className="text-3xl font-bold mb-6">번개 채팅방 목록</h1>
+      <div className="flex justify-start mb-4">
+      </div>
+      <div className="bg-white shadow-lg rounded-lg overflow-hidden">
+        {rooms.length === 0 ? (
+          <p className="text-gray-500 p-6 text-center">생성된 채팅방이 없습니다.</p>
+        ) : (
+          <ul className="divide-y divide-gray-200">
+            {rooms.map((chatRoom) => (
+              <li
+                key={chatRoom.chatRoomId}
+                className="flex items-center justify-between w-full p-4 hover:bg-gray-50 cursor-pointer"
+                onClick={() => joinRoom(chatRoom.chatRoomId, chatRoom.chatRoomName)} // 클릭하면 상세 페이지로 이동
+              >
+                <div className="flex items-center w-full">
+                  <div className="w-14 h-14 rounded-full bg-gray-300 overflow-hidden mr-4">
+                    <img
+                      src="https://via.placeholder.com/50"
+                      alt="프로필"
+                      className="w-full h-full object-cover"
+                    />
+                  </div>
+                  <div className="flex-grow">
+                    <div className="font-semibold text-gray-800">{chatRoom.chatRoomName}</div>
+                    <div className="text-sm text-gray-600">
+                      <strong>{chatRoom.lastMessage?.sender || "없음"}:</strong>{" "}
+                      {chatRoom.lastMessage?.message || "메시지 없음"}
+                    </div>
+                  </div>
+                  {joinedRooms.includes(chatRoom.chatRoomId) && (
+                    <div className="bg-red-500 text-white text-xs px-2 py-1 rounded-full">
+                      {unreadCounts[chatRoom.chatRoomId] || 0}
+                    </div>
+                  )}
+                </div>
+              </li>
+            ))}
+          </ul>
+        )}
+      </div>
+    </div>
+  );
+}
+
+export default ChattingList;
\ No newline at end of file
diff --git a/src/components/ChattingNoticeDetailModal.jsx b/src/components/ChattingNoticeDetailModal.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..05424ef51b9eabed2ee1ef3454514faba919c847
--- /dev/null
+++ b/src/components/ChattingNoticeDetailModal.jsx
@@ -0,0 +1,217 @@
+import React, { useState, useEffect } from "react";
+import styled from "styled-components";
+import Button from "./Button.jsx";
+
+const ModalContainer = styled.div`
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 1000;
+`;
+
+const ModalContent = styled.div`
+  background: white;
+  width: 90%;
+  max-width: 600px;
+  padding: 20px;
+  border-radius: 10px;
+  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
+  overflow-y: auto;
+`;
+
+const Header = styled.div`
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 20px;
+
+  .title {
+    font-size: 1.5rem;
+    font-weight: bold;
+  }
+`;
+
+const NoticeHeader = styled.div`
+  display: flex;
+  align-items: center;
+  margin-bottom: 20px;
+
+  .profile {
+    width: 50px;
+    height: 50px;
+    border-radius: 50%;
+    background-color: #f0f0f0;
+    margin-right: 15px;
+  }
+
+  .info {
+    display: flex;
+    flex-direction: column;
+
+    .author {
+      font-size: 1rem;
+      font-weight: bold;
+      color: #333;
+    }
+
+    .timestamp {
+      font-size: 0.875rem;
+      color: #888;
+    }
+  }
+`;
+
+const NoticeContent = styled.div`
+  margin-bottom: 20px;
+  font-size: 1rem;
+  line-height: 1.5;
+  white-space: pre-wrap;
+
+  .section-title {
+    font-weight: bold;
+    margin-top: 10px;
+    margin-bottom: 5px;
+  }
+
+  .section-content {
+    margin-bottom: 10px;
+  }
+`;
+
+const NoticeListContainer = styled.ul`
+  list-style: none;
+  padding: 0;
+  margin: 0;
+  max-height: 400px;
+  overflow-y: auto;
+
+  li {
+    display: flex;
+    flex-direction: column;
+    padding: 15px;
+    border-bottom: 1px solid #ddd;
+    cursor: pointer;
+    transition: background 0.3s ease;
+
+    &:hover {
+      background: #f9f9f9;
+    }
+
+    .message {
+      font-size: 1rem;
+      font-weight: bold;
+      color: #333;
+      margin-bottom: 5px;
+    }
+
+    .meta {
+      font-size: 0.875rem;
+      color: #555;
+      display: flex;
+      justify-content: space-between;
+
+      .timestamp {
+        color: #888;
+      }
+
+      .sender {
+        color: #555;
+        font-weight: 500;
+      }
+    }
+  }
+`;
+
+export default function ChattingNoticeDetailModal({
+  initialNotice,
+  notices,
+  onClose,
+}) {
+  const [currentView, setCurrentView] = useState("detail"); // 'detail' or 'list'
+  const [selectedNotice, setSelectedNotice] = useState(initialNotice);
+  const [sortedNotices, setSortedNotices] = useState([]);
+
+  useEffect(() => {
+    // 최신 공지가 상단에 오도록 정렬
+    const sorted = [...notices].sort(
+      (a, b) => new Date(b.timestamp) - new Date(a.timestamp)
+    );
+    setSortedNotices(sorted);
+  }, [notices]);
+
+  const handleSelectNotice = (notice) => {
+    setSelectedNotice(notice);
+    setCurrentView("detail");
+  };
+
+  const formatTimestamp = (timestamp) => {
+    const date = new Date(timestamp);
+    const options = {
+      year: "numeric",
+      month: "long",
+      day: "numeric",
+      hour: "2-digit",
+      minute: "2-digit",
+    };
+    return date.toLocaleDateString("ko-KR", options);
+  };
+
+  return (
+    <ModalContainer>
+      <ModalContent>
+        {currentView === "detail" ? (
+          <>
+            <Header>
+              <Button
+                size="sm"
+                theme="pink"
+                onClick={() => setCurrentView("list")}
+              >
+                ← 공지사항 목록
+              </Button>
+              <Button onClick={onClose}>닫기</Button>
+            </Header>
+            <NoticeHeader>
+              <div className="profile" />
+              <div className="info">
+                <span className="author">{selectedNotice.sender}</span>
+                <span className="timestamp">
+                  {formatTimestamp(selectedNotice.timestamp)}
+                </span>
+              </div>
+            </NoticeHeader>
+            <NoticeContent>
+              <div className="section-content">{selectedNotice.message}</div>
+            </NoticeContent>
+          </>
+        ) : (
+          <>
+            <Header>
+              <div className="title">공지사항 목록</div>
+              <Button onClick={onClose}>닫기</Button>
+            </Header>
+            <NoticeListContainer>
+              {sortedNotices.map((item, index) => (
+                <li key={index} onClick={() => handleSelectNotice(item)}>
+                  <div className="message">{item.message}</div>
+                  <div className="meta">
+                    <span className="timestamp">
+                      {formatTimestamp(item.timestamp)}
+                    </span>
+                    <span className="sender">{item.sender}</span>
+                  </div>
+                </li>
+              ))}
+            </NoticeListContainer>
+          </>
+        )}
+      </ModalContent>
+    </ModalContainer>
+  );
+}
\ No newline at end of file
diff --git a/src/components/ChattingNoticeListModal.jsx b/src/components/ChattingNoticeListModal.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..67e19804a642f8687a4f468d48a6bb33e0cf10aa
--- /dev/null
+++ b/src/components/ChattingNoticeListModal.jsx
@@ -0,0 +1,72 @@
+import React from 'react';
+import styled from 'styled-components';
+
+const ModalContainer = styled.div`
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 1000;
+`;
+
+const ModalContent = styled.div`
+  background: white;
+  width: 80%;
+  max-width: 600px;
+  padding: 20px;
+  border-radius: 10px;
+  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
+`;
+
+const NoticeList = styled.ul`
+  list-style: none;
+  padding: 0;
+  margin: 0;
+
+  li {
+    padding: 10px;
+    border-bottom: 1px solid #ddd;
+    cursor: pointer;
+
+    &:hover {
+      background: #f0f0f0;
+    }
+  }
+`;
+
+const CloseButton = styled.button`
+  margin-top: 20px;
+  padding: 10px 20px;
+  background: #007bff;
+  color: white;
+  border: none;
+  border-radius: 5px;
+  cursor: pointer;
+
+  &:hover {
+    background: #0056b3;
+  }
+`;
+
+export default function ChattingNoticeListModal({ notices, onClose, onNoticeClick }) {
+  return (
+    <ModalContainer>
+      <ModalContent>
+        <h2>공지사항 목록</h2>
+        <NoticeList>
+          {notices.map((notice, index) => (
+            <li key={index} onClick={() => onNoticeClick(notice)}>
+              {notice.message} (작성자: {notice.sender})
+            </li>
+          ))}
+        </NoticeList>
+        <CloseButton onClick={onClose}>닫기</CloseButton>
+      </ModalContent>
+    </ModalContainer>
+  );
+}
\ No newline at end of file
diff --git a/src/fcm/AddServiceWorker.jsx b/src/fcm/AddServiceWorker.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..6a2159f29b4eaafb31d7ac7335757fb83d155a05
--- /dev/null
+++ b/src/fcm/AddServiceWorker.jsx
@@ -0,0 +1,26 @@
+import { firebaseApp } from "./firebase";
+import {
+  getMessaging,
+  onMessage,
+  onBackgroundMessage,
+} from "firebase/messaging";
+
+const messaging = getMessaging(firebaseApp);
+
+onMessage(messaging, (payload) => {
+  console.log("Message received. ", payload);
+});
+
+onBackgroundMessage(messaging, (payload) => {
+  console.log(
+    "[firebase-messaging-sw.js] Received background message ",
+    payload
+  );
+  const notificationTitle = "Background Message Title";
+  const notificationOptions = {
+    body: "Background Message body.",
+    icon: "/firebase-logo.png",
+  };
+
+  self.registration.showNotification(notificationTitle, notificationOptions);
+});
diff --git a/src/fcm/GetFCMToken.jsx b/src/fcm/GetFCMToken.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..826c164693d44bca20d81ca71a087d67943e9281
--- /dev/null
+++ b/src/fcm/GetFCMToken.jsx
@@ -0,0 +1,35 @@
+import { firebaseApp } from "./firebase";
+import { getMessaging, getToken } from "firebase/messaging";
+
+const GetFCMToken = async () => {
+  try {
+    const messagingPromise = new Promise((resolve, reject) => {
+      const messaging = getMessaging(firebaseApp);
+      if (messaging) {
+        resolve(messaging);
+      } else {
+        reject(new Error("Messaging object is not available"));
+      }
+    });
+
+    const messaging = await messagingPromise;
+    const currentToken = await getToken(messaging, {
+      vapidKey: process.env.REACT_APP_VAPID_KEY,
+    });
+
+    if (currentToken) {
+      localStorage.setItem("fcmToken", currentToken);
+    } else {
+      console.log(
+        "No registration token available. Request permission to generate one."
+      );
+    }
+  } catch (error) {
+    console.error(
+      "An error occurred while sending the token to the server:",
+      error
+    );
+  }
+};
+
+export default GetFCMToken;
diff --git a/src/fcm/GetUserPermission.jsx b/src/fcm/GetUserPermission.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..621f1a7b4d218c69bb678ab436e340f60889696c
--- /dev/null
+++ b/src/fcm/GetUserPermission.jsx
@@ -0,0 +1,85 @@
+import GetFCMToken from "./GetFCMToken";
+import { registerServiceWorker } from "../serviceWorkerRegistration";
+import Swal from "sweetalert2";
+
+const Toast = Swal.mixin({
+  toast: true,
+  position: "center-center",
+  showConfirmButton: false,
+  timer: 1000,
+  timerProgressBar: true,
+  didOpen: (toast) => {
+    toast.addEventListener("mouseenter", Swal.stopTimer);
+    toast.addEventListener("mouseleave", Swal.resumeTimer);
+  },
+});
+
+const GetUserPermission = async (setIsLoading) => {
+  try {
+    //서비스워커 추가
+    // await navigator.serviceWorker.register("firebase-messaging-sw.js");
+
+    // const registrations = await navigator.serviceWorker.getRegistrations();
+    // if (registrations.length === 0) {
+    //   setIsLoading(true);
+    //   await registerServiceWorker();
+    //   setIsLoading(false);
+    // }
+
+    if (!("Notification" in window)) {
+      alert(
+        "알림 서비스를 원활하게 사용하시려면 바탕화면에 바로가기 추가 후, 홈페이지에 종모양아이콘 클릭하여 알림 허용을 해주세요."
+      );
+      return;
+    }
+
+    console.log("Checking notification permission...");
+
+    const permission = await Notification.requestPermission();
+    if (permission === "granted") {
+      try {
+        console.log("Notification permission granted. Ready to send token...");
+        setIsLoading(true);
+        await GetFCMToken();
+        setIsLoading(false);
+        let isFCMToken = localStorage.getItem("fcmToken");
+        if (!isFCMToken) {
+          setIsLoading(true);
+          await GetFCMToken();
+          setIsLoading(false);
+          Toast.fire({
+            icon: "error",
+            title: `알림 토큰 저장 실패`,
+          });
+        } else {
+          console.log("token setting complete");
+        }
+      } catch {
+        Toast.fire({
+          icon: "error",
+          title: `알림 토큰 요청 실패`,
+        });
+      }
+    } else if (permission === "denied") {
+      // alert("알림권한이 허용되어 있지않습니다. 권한을 허용해 주십시오.");
+      console.log(
+        "Notification permission not granted. Requesting permission..."
+      );
+    } else {
+      // Toast.fire({
+      //   icon: "warning",
+      //   title: `알림 설정 안함`,
+      //   text: "알림 설정 요청을 원하시면 종아이콘을 클릭해주세요.",
+      // });
+    }
+  } catch (error) {
+    Toast.fire({
+      icon: "error",
+      title: `알림 설정 요청 실패`,
+    });
+    console.error("Failed to check or request notification permission:", error);
+    setIsLoading(false);
+  }
+};
+
+export default GetUserPermission;
diff --git a/src/fcm/firebase.js b/src/fcm/firebase.js
new file mode 100644
index 0000000000000000000000000000000000000000..10fd4e0ed2041d46bf2d18b9df3d4d8b92ae4a3b
--- /dev/null
+++ b/src/fcm/firebase.js
@@ -0,0 +1,14 @@
+import { initializeApp } from "firebase/app";
+
+const firebaseConfig = {
+  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
+  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
+  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
+  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
+  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
+  appId: process.env.REACT_APP_FIREBASE_APP_ID,
+  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
+};
+
+const firebaseApp = initializeApp(firebaseConfig);
+export { firebaseApp };
diff --git a/src/pages/Chatting/ChattingDetail.jsx b/src/pages/Chatting/ChattingDetail.jsx
deleted file mode 100644
index 2b1bf0202cad968f338b8648c2076978b2bc5b69..0000000000000000000000000000000000000000
--- a/src/pages/Chatting/ChattingDetail.jsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import React from "react";
-
-const ChattingDetail = () => {
-  return <></>;
-};
-
-export default ChattingDetail;
diff --git a/src/pages/Chatting/ChattingDetailPage.jsx b/src/pages/Chatting/ChattingDetailPage.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..2bcc7767c338deb64a9ba85e2105a48f93d38ba9
--- /dev/null
+++ b/src/pages/Chatting/ChattingDetailPage.jsx
@@ -0,0 +1,10 @@
+import React from "react";
+import ChattingDetail from "../../components/ChattingDetail";
+
+export default function ChattingDetailPage() {
+  return (
+    <div className="flex flex-col items-center justify-center bg-white min-h-screen overflow-hidden">
+      <ChattingDetail />
+    </div>
+  );
+}
\ No newline at end of file
diff --git a/src/pages/Chatting/ChattingListPage.jsx b/src/pages/Chatting/ChattingListPage.jsx
index e77427b1e3fe8b5c192d03dfb5abb063468d3562..67a44e69630c9eb7a35cc0fdaa5f10978c665fa2 100644
--- a/src/pages/Chatting/ChattingListPage.jsx
+++ b/src/pages/Chatting/ChattingListPage.jsx
@@ -1,7 +1,10 @@
 import React from "react";
+import ChattingList from "../../components/ChattingList";
 
-const ChattingList = () => {
-  return <></>;
-};
-
-export default ChattingList;
+export default function ChattingListPage() {
+  return (
+    <div className="flex flex-col items-center justify-center bg-white min-h-screen overflow-hidden">
+      <ChattingList />
+    </div>
+  );
+}
\ No newline at end of file