diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index da2f963..79ac845 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -44,7 +44,6 @@
         "@types/jest": "^29.5.12",
         "axios": "^1.7.2",
         "babel-eslint": "*",
-        "bootstrap": "^5.3.3",
         "eslint": "^8.0.0",
         "eslint-config-prettier": "*",
         "eslint-import-resolver-typescript": "*",
@@ -56,7 +55,6 @@
         "nodemon": "^3.1.0",
         "prettier": "^3.2.5",
         "prettier-plugin-organize-imports": "^3.2.4",
-        "react-bootstrap": "^2.10.2",
         "react-router-dom": "^6.23.1",
         "tailwindcss": "^3.4.10",
         "ts-jest": "^29.2.5",
@@ -3602,31 +3600,6 @@
         "node": ">= 8"
       }
     },
-    "node_modules/@popperjs/core": {
-      "version": "2.11.8",
-      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
-      "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/popperjs"
-      }
-    },
-    "node_modules/@react-aria/ssr": {
-      "version": "3.9.5",
-      "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.5.tgz",
-      "integrity": "sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==",
-      "dev": true,
-      "dependencies": {
-        "@swc/helpers": "^0.5.0"
-      },
-      "engines": {
-        "node": ">= 12"
-      },
-      "peerDependencies": {
-        "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
-      }
-    },
     "node_modules/@react-oauth/google": {
       "version": "0.12.1",
       "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.12.1.tgz",
@@ -3646,48 +3619,6 @@
         "node": ">=14.0.0"
       }
     },
-    "node_modules/@restart/hooks": {
-      "version": "0.4.16",
-      "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
-      "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==",
-      "dev": true,
-      "dependencies": {
-        "dequal": "^2.0.3"
-      },
-      "peerDependencies": {
-        "react": ">=16.8.0"
-      }
-    },
-    "node_modules/@restart/ui": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.8.0.tgz",
-      "integrity": "sha512-xJEOXUOTmT4FngTmhdjKFRrVVF0hwCLNPdatLCHkyS4dkiSK12cEu1Y0fjxktjJrdst9jJIc5J6ihMJCoWEN/g==",
-      "dev": true,
-      "dependencies": {
-        "@babel/runtime": "^7.21.0",
-        "@popperjs/core": "^2.11.6",
-        "@react-aria/ssr": "^3.5.0",
-        "@restart/hooks": "^0.4.9",
-        "@types/warning": "^3.0.0",
-        "dequal": "^2.0.3",
-        "dom-helpers": "^5.2.0",
-        "uncontrollable": "^8.0.1",
-        "warning": "^4.0.3"
-      },
-      "peerDependencies": {
-        "react": ">=16.14.0",
-        "react-dom": ">=16.14.0"
-      }
-    },
-    "node_modules/@restart/ui/node_modules/uncontrollable": {
-      "version": "8.0.4",
-      "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz",
-      "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==",
-      "dev": true,
-      "peerDependencies": {
-        "react": ">=16.14.0"
-      }
-    },
     "node_modules/@rollup/plugin-babel": {
       "version": "5.3.1",
       "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@@ -4055,15 +3986,6 @@
         "url": "https://github.com/sponsors/gregberge"
       }
     },
-    "node_modules/@swc/helpers": {
-      "version": "0.5.13",
-      "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz",
-      "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==",
-      "dev": true,
-      "dependencies": {
-        "tslib": "^2.4.0"
-      }
-    },
     "node_modules/@testing-library/dom": {
       "version": "10.4.0",
       "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
@@ -4645,15 +4567,6 @@
         "@types/react": "*"
       }
     },
-    "node_modules/@types/react-transition-group": {
-      "version": "4.4.11",
-      "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz",
-      "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==",
-      "dev": true,
-      "dependencies": {
-        "@types/react": "*"
-      }
-    },
     "node_modules/@types/resolve": {
       "version": "1.17.1",
       "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -4725,12 +4638,6 @@
       "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
       "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="
     },
-    "node_modules/@types/warning": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz",
-      "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==",
-      "dev": true
-    },
     "node_modules/@types/ws": {
       "version": "8.5.12",
       "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz",
@@ -6142,25 +6049,6 @@
       "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
       "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
     },
-    "node_modules/bootstrap": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
-      "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/twbs"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/bootstrap"
-        }
-      ],
-      "peerDependencies": {
-        "@popperjs/core": "^2.11.8"
-      }
-    },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -6437,12 +6325,6 @@
       "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz",
       "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA=="
     },
-    "node_modules/classnames": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
-      "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
-      "dev": true
-    },
     "node_modules/clean-css": {
       "version": "5.3.3",
       "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
@@ -7542,16 +7424,6 @@
         "utila": "~0.4"
       }
     },
-    "node_modules/dom-helpers": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
-      "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
-      "dev": true,
-      "dependencies": {
-        "@babel/runtime": "^7.8.7",
-        "csstype": "^3.0.2"
-      }
-    },
     "node_modules/dom-serializer": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
@@ -16049,25 +15921,6 @@
         "react-is": "^16.13.1"
       }
     },
-    "node_modules/prop-types-extra": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
-      "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
-      "dev": true,
-      "dependencies": {
-        "react-is": "^16.3.2",
-        "warning": "^4.0.0"
-      },
-      "peerDependencies": {
-        "react": ">=0.14.0"
-      }
-    },
-    "node_modules/prop-types-extra/node_modules/react-is": {
-      "version": "16.13.1",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
-      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
-      "dev": true
-    },
     "node_modules/prop-types/node_modules/react-is": {
       "version": "16.13.1",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -16359,36 +16212,6 @@
         "uuid": "bin/uuid"
       }
     },
-    "node_modules/react-bootstrap": {
-      "version": "2.10.4",
-      "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.4.tgz",
-      "integrity": "sha512-W3398nBM2CBfmGP2evneEO3ZZwEMPtHs72q++eNw60uDGDAdiGn0f9yNys91eo7/y8CTF5Ke1C0QO8JFVPU40Q==",
-      "dev": true,
-      "dependencies": {
-        "@babel/runtime": "^7.24.7",
-        "@restart/hooks": "^0.4.9",
-        "@restart/ui": "^1.6.9",
-        "@types/react-transition-group": "^4.4.6",
-        "classnames": "^2.3.2",
-        "dom-helpers": "^5.2.1",
-        "invariant": "^2.2.4",
-        "prop-types": "^15.8.1",
-        "prop-types-extra": "^1.1.0",
-        "react-transition-group": "^4.4.5",
-        "uncontrollable": "^7.2.1",
-        "warning": "^4.0.3"
-      },
-      "peerDependencies": {
-        "@types/react": ">=16.14.8",
-        "react": ">=16.14.0",
-        "react-dom": ">=16.14.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/react-bootstrap-icons": {
       "version": "1.11.4",
       "resolved": "https://registry.npmjs.org/react-bootstrap-icons/-/react-bootstrap-icons-1.11.4.tgz",
@@ -17988,22 +17811,6 @@
         "node": ">=10"
       }
     },
-    "node_modules/react-transition-group": {
-      "version": "4.4.5",
-      "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
-      "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
-      "dev": true,
-      "dependencies": {
-        "@babel/runtime": "^7.5.5",
-        "dom-helpers": "^5.0.1",
-        "loose-envify": "^1.4.0",
-        "prop-types": "^15.6.2"
-      },
-      "peerDependencies": {
-        "react": ">=16.6.0",
-        "react-dom": ">=16.6.0"
-      }
-    },
     "node_modules/read-cache": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -20494,21 +20301,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/uncontrollable": {
-      "version": "7.2.1",
-      "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",
-      "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==",
-      "dev": true,
-      "dependencies": {
-        "@babel/runtime": "^7.6.3",
-        "@types/react": ">=16.9.11",
-        "invariant": "^2.2.4",
-        "react-lifecycles-compat": "^3.0.4"
-      },
-      "peerDependencies": {
-        "react": ">=15.0.0"
-      }
-    },
     "node_modules/undefsafe": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
@@ -20734,15 +20526,6 @@
         "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==",
-      "dev": true,
-      "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/frontend/package.json b/frontend/package.json
index 1b0c51a..5cb1a8d 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -61,7 +61,6 @@
     "@types/jest": "^29.5.12",
     "axios": "^1.7.2",
     "babel-eslint": "*",
-    "bootstrap": "^5.3.3",
     "eslint": "^8.0.0",
     "eslint-config-prettier": "*",
     "eslint-import-resolver-typescript": "*",
@@ -73,7 +72,6 @@
     "nodemon": "^3.1.0",
     "prettier": "^3.2.5",
     "prettier-plugin-organize-imports": "^3.2.4",
-    "react-bootstrap": "^2.10.2",
     "react-router-dom": "^6.23.1",
     "tailwindcss": "^3.4.10",
     "ts-jest": "^29.2.5",
diff --git a/frontend/src/App.css b/frontend/src/App.css
index 56f0752..43ca4da 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -4,5 +4,93 @@
 @tailwind utilities;
 
 body {
-  font-family: "Noto Serif SC", serif; /* Use Noto Serif Simplified Chinese font */
+  font-family: "Noto Serif SC", serif;
+  /* Use Noto Serif Simplified Chinese font */
+}
+
+.perspective {
+  perspective: 1000px;
+}
+
+.transform-style-preserve-3d {
+  transform-style: preserve-3d;
+}
+
+.backface-hidden {
+  backface-visibility: hidden;
+}
+
+.group-hover\:rotate-y-30:hover,
+.rotate-y-30 {
+  transform: rotateY(-30deg);
+  /* Rotate the element on hover */
+}
+
+.rotate-y-90 {
+  transform: rotateY(-90deg) !important;
+}
+
+.rotate-y-180 {
+  transform: rotateY(180deg);
+}
+
+.rotate-left {
+  transform-origin: left;
+  /* Set transform origin to the left edge */
+}
+
+@layer base {
+  @layer base {
+    /* Global input customization */
+    input,
+    textarea,
+    select {
+      @apply border border-gray-300 rounded-lg px-4 py-2 bg-white text-black placeholder-gray-400 transition duration-200 ease-in-out;
+    }
+
+    /* Hover and focus states for inputs */
+    input:hover,
+    textarea:hover,
+    select:hover {
+      @apply border-gray-400;
+    }
+
+    input:focus,
+    textarea:focus,
+    select:focus {
+      @apply border-blue-500 ring ring-blue-200 outline-none;
+    }
+
+    /* Disabled input */
+    input:disabled,
+    textarea:disabled,
+    select:disabled {
+      @apply bg-gray-200 cursor-not-allowed opacity-50;
+    }
+
+    /* Additional customization for textareas */
+    textarea {
+      @apply resize-none;
+      /* Prevents resizing */
+    }
+
+    /* Button styling */
+    button {
+      @apply bg-blue-500 text-white px-6 py-2 rounded-lg transition duration-200 ease-in-out;
+    }
+
+    /* Hover and focus states for buttons */
+    button:hover {
+      @apply bg-blue-600;
+    }
+
+    button:focus {
+      @apply ring ring-blue-300 outline-none;
+    }
+
+    /* Disabled button */
+    button:disabled {
+      @apply bg-gray-500 cursor-not-allowed opacity-50;
+    }
+  }
 }
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index d5175f8..b9cbbfe 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,6 +1,6 @@
-import "bootstrap/dist/css/bootstrap.min.css";
+import Content from "components/HOC/Content";
 import LoadingMask from "components/LoadingMask";
-import TopNavbar from "components/nav/TopNavbar";
+import Navbar from "components/nav/Navbar";
 import NotFoundRedirect from "components/NotFoundRedirect";
 import { AuthProvider } from "contexts/AuthContext";
 import { LoadingProvider } from "contexts/LoadingContext";
@@ -14,7 +14,6 @@ import NotFound from "pages/NotFound";
 import SubscriptionTypePage from "pages/SubscriptioinType";
 import SubscriptionCancelPage from "pages/Subscription";
 import PrivateRoute from "ProtectedRoute";
-import { Container } from "react-bootstrap";
 import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
 import "./App.css";
 
@@ -26,7 +25,7 @@ const App = () => {
           <AuthProvider>
             <AlertQueueProvider>
               <AlertQueue>
-                <Container>
+                <Content>
                   <Routes>
                     <Route path="/" element={<Home />} />
                     <Route path="/404" element={<NotFound />} />
@@ -82,8 +81,9 @@ const App = () => {
                     />
                     <Route path="*" element={<NotFoundRedirect />} />
                   </Routes>
-                </Container>
-                <TopNavbar />
+                </Content>
+                <Navbar />
+                {/* <TopNavbar /> */}
               </AlertQueue>
             </AlertQueueProvider>
           </AuthProvider>
diff --git a/frontend/src/ProtectedRoute.tsx b/frontend/src/ProtectedRoute.tsx
index 438242c..42bfee8 100644
--- a/frontend/src/ProtectedRoute.tsx
+++ b/frontend/src/ProtectedRoute.tsx
@@ -11,20 +11,19 @@ const PrivateRoute: React.FC<PrivateRouteProps> = ({
   element,
   requiredSubscription = false,
 }) => {
-  const { auth } = useAuth();
+  const { auth, is_auth } = useAuth();
   const location = useLocation();
   const navigate = useNavigate();
 
   useEffect(() => {
-    if (auth)
-      if (!auth?.is_auth) {
-        // Redirect to login if not authenticated
-        navigate("/login", { replace: true, state: { from: location } });
-      } else if (requiredSubscription && !auth?.is_subscription) {
-        // Redirect to subscription page if subscription is required and not active
-        navigate("/subscription_type", { replace: true });
-      }
-  }, [auth, requiredSubscription, navigate, location]);
+    if (!is_auth) {
+      // Redirect to login if not authenticated
+      navigate("/login", { replace: true, state: { from: location } });
+    } else if (auth && requiredSubscription && !auth?.is_subscription) {
+      // Redirect to subscription page if subscription is required and not active
+      navigate("/subscription_type", { replace: true });
+    }
+  }, [auth, is_auth, requiredSubscription, navigate, location]);
 
   if (!auth?.is_auth || (requiredSubscription && !auth?.is_subscription)) {
     // Render nothing while redirecting
diff --git a/frontend/src/components/Audio.tsx b/frontend/src/components/Audio.tsx
index 5dea933..9d92b1f 100644
--- a/frontend/src/components/Audio.tsx
+++ b/frontend/src/components/Audio.tsx
@@ -1,4 +1,5 @@
 import React, { useEffect, useRef, useState } from "react";
+import { CaretLeft, CaretRight } from "react-bootstrap-icons";
 import {
   FaPause,
   FaPlay,
@@ -9,15 +10,22 @@ import {
 import { Image } from "types/model";
 
 interface AudioPlayerProps {
-  currentImage: Image;
-  index: number;
+  currentImage: Image; // current image
+  index: number; // current transcription index
+  handleTranscriptionNext: () => void; //next transcript
+  handleTranscriptionPrev: () => void; //prev transcript
 }
 
-const AudioPlayer: React.FC<AudioPlayerProps> = ({ currentImage, index }) => {
-  const audioRef = useRef<HTMLAudioElement>(null);
+const AudioPlayer: React.FC<AudioPlayerProps> = ({
+  currentImage,
+  index,
+  handleTranscriptionNext,
+  handleTranscriptionPrev,
+}) => {
+  const audioRef = useRef<HTMLAudioElement>(null); //audio
   const [isPlaying, setIsPlaying] = useState(false);
-  const [playbackRate, setPlaybackRate] = useState(1);
-  const [volume, setVolume] = useState(1);
+  const [playbackRate, setPlaybackRate] = useState(1); //speed
+  const [volume, setVolume] = useState(1); // volumn size
   const [currentTime, setCurrentTime] = useState(0);
   const [duration, setDuration] = useState(0);
 
@@ -82,13 +90,15 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({ currentImage, index }) => {
         setCurrentTime(0); // Reset current time to 0
       });
 
+      audio.addEventListener("ended", handleTranscriptionNext);
+
       // Clean up the event listeners on component unmount
       return () => {
         audio.removeEventListener("timeupdate", () => {});
         audio.removeEventListener("ended", () => {});
       };
     }
-  }, []);
+  }, [handleTranscriptionNext]);
 
   useEffect(() => {
     if (audioRef.current) {
@@ -98,7 +108,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({ currentImage, index }) => {
   }, [currentImage, index]);
 
   return (
-    <div className="mt-4 w-full text-center bg-gray-200 dark:bg-gray-600 px-4 py-1 rounded-md">
+    <div className="mt-2 w-full text-center bg-gray-12 px-4 py-1 rounded-md">
       <audio ref={audioRef}>
         <source
           src={currentImage.transcriptions[index].audio_url}
@@ -110,6 +120,17 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({ currentImage, index }) => {
       {/* Custom Controls */}
       <div className="flex items-center justify-center mt-4 space-x-6">
         <div className="flex gap-3">
+          <button
+            className={`flex-1 flex justify-center p-2 rounded-full ${
+              index === 0
+                ? "bg-gray-300 text-gray-600 cursor-not-allowed"
+                : "bg-gray-500 text-white hover:bg-gray-400"
+            }`}
+            onClick={handleTranscriptionPrev}
+            disabled={index === 0}
+          >
+            <CaretLeft />
+          </button>
           <button
             onClick={togglePlayPause}
             className="p-2 bg-blue-500 text-white rounded-full hover:bg-blue-600"
@@ -123,6 +144,21 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({ currentImage, index }) => {
           >
             <FaStop />
           </button>
+          <button
+            className={`flex justify-center p-2 rounded-full ${
+              index === currentImage.transcriptions.length - 1 ||
+              currentImage.transcriptions.length === 0
+                ? "bg-gray-300 text-gray-600 cursor-not-allowed"
+                : "bg-gray-500 text-white hover:bg-gray-400"
+            }`}
+            onClick={handleTranscriptionNext}
+            disabled={
+              index === currentImage.transcriptions.length - 1 ||
+              currentImage.transcriptions.length === 0
+            }
+          >
+            <CaretRight />
+          </button>
         </div>
         <div className="flex items-center">
           <label htmlFor="speed" className="mr-2">
diff --git a/frontend/src/components/Book.tsx b/frontend/src/components/Book.tsx
new file mode 100644
index 0000000..0c6cf8d
--- /dev/null
+++ b/frontend/src/components/Book.tsx
@@ -0,0 +1,91 @@
+import bookplaceholder from "images/bookplaceholder.png";
+import React, { useState } from "react";
+import { useNavigate } from "react-router-dom";
+
+type BookProps = {
+  id: string;
+  title: string;
+  description: string;
+  featured_image: string;
+  is_editable?: boolean;
+  onDelete?: (id: string) => void;
+};
+
+const Book: React.FC<BookProps> = ({
+  id,
+  title,
+  description,
+  featured_image,
+  onDelete,
+  is_editable,
+}) => {
+  const [isOpen, setIsOpen] = useState<boolean>(false);
+  const navigate = useNavigate();
+  const toggleOpen = () => setIsOpen(!isOpen);
+  const handleOpen = () => {
+    navigate(`/collection/${id}`);
+  };
+  const handleEdit = () => {
+    navigate(`/collection/${id}?Action=edit`);
+  };
+  const handleDelete = () => {
+    if (onDelete) onDelete(id);
+  };
+  return (
+    <div
+      className="relative group perspective w-48 h-64 relative cursor-pointer shadow-xl"
+      onClick={toggleOpen}
+    >
+      {/* Second page */}
+      <div className="absolute top-0 w-full h-full bg-gray-100 shadow-lg rounded-sm">
+        <div className="p-4 flex flex-col justify-between items-center text-gray-700 text-center h-full">
+          <div>
+            <h2 className="text-lg font-bold mb-2">{title}</h2>
+            <p className="text-sm line-clamp-5">{description}</p>
+          </div>
+          {is_editable ? (
+            <div className="flex flex-col gap-2">
+              <span className="hover:text-blue-700" onClick={handleOpen}>
+                Open
+              </span>
+              <span className="hover:text-blue-700" onClick={handleEdit}>
+                Edit
+              </span>
+              <span className="hover:text-red-700" onClick={handleDelete}>
+                Delete
+              </span>
+            </div>
+          ) : (
+            <span className="hover:text-blue-700" onClick={handleOpen}>
+              Open
+            </span>
+          )}
+        </div>
+      </div>
+      {/* Book Wrapper */}
+      <div
+        className={`relative w-full h-full transform-style-preserve-3d transition-transform duration-700 group-hover:rotate-y-30 rotate-left rounded-sm ${isOpen ? "rotate-y-90" : ""}`}
+      >
+        {/* Front Cover */}
+        <div className="absolute w-full h-full bg-gray-800 text-white shadow-lg backface-hidden rounded-sm">
+          <div className="h-full flex flex-col items-center justify-center relative">
+            <img
+              src={featured_image || bookplaceholder}
+              alt={title}
+              className="object-cover w-full h-full rounded-sm"
+            />
+            <div className="absolute top-4 bg-gray-12/70 mt-7 mx-5 p-2 max-h-52 overflow-hidden">
+              <h2 className="text-md text-center">{title}</h2>
+            </div>
+          </div>
+        </div>
+        {/* Back Cover */}
+        <div className="absolute w-full h-full bg-gray-800 shadow-lg rotate-y-180 backface-hidden"></div>
+        {/* Spine of the Book */}
+        <div className="absolute h-full w-4 bg-gray-700/30 left-0 top-0 rounded-l-sm shadow-md"></div>
+      </div>
+    </div>
+  );
+};
+
+export default Book;
diff --git a/frontend/src/components/BookSkeleton.tsx b/frontend/src/components/BookSkeleton.tsx
new file mode 100644
index 0000000..daec755
--- /dev/null
+++ b/frontend/src/components/BookSkeleton.tsx
@@ -0,0 +1,40 @@
+type BookSkeletonProps = {
+  is_light: boolean;
+};
+const BookSkeleton: React.FC<BookSkeletonProps> = ({ is_light }) => {
+  const items = Array(5).fill(null);
+  return (
+    <>
+      {is_light
+        ? items.map((_, index) => {
+            return (
+              <div
+                className="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/5 2xl:w-1/6"
+                key={index}
+              >
+                <div className="bg-gray-5 w-48 h-64 rounded-lg animate-pulse p-8">
+                  <div className="bg-gray-8 w-full h-4 rounded-lg animate-pulse" />
+                  <div className="bg-gray-8 w-full h-4 rounded-lg animate-pulse mt-8" />
+                  <div className="bg-gray-8 w-full h-4 rounded-lg animate-pulse mt-2" />
+                </div>
+              </div>
+            );
+          })
+        : items.map((_, index) => {
+            return (
+              <div
+                className="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/5 2xl:w-1/6"
+                key={index}
+              >
+                <div className="bg-gray-11 w-48 h-64 rounded-lg animate-pulse p-8">
+                  <div className="bg-gray-12 w-full h-4 rounded-lg animate-pulse" />
+                  <div className="bg-gray-12 w-full h-4 rounded-lg animate-pulse mt-8" />
+                  <div className="bg-gray-12 w-full h-4 rounded-lg animate-pulse mt-2" />
+                </div>
+              </div>
+            );
+          })}
+    </>
+  );
+};
+export default BookSkeleton;
diff --git a/frontend/src/components/HOC/Container.tsx b/frontend/src/components/HOC/Container.tsx
new file mode 100644
index 0000000..af3213a
--- /dev/null
+++ b/frontend/src/components/HOC/Container.tsx
@@ -0,0 +1,10 @@
+import React, { ReactNode } from "react";
+interface ContainerProps {
+  children: ReactNode;
+}
+const Container: React.FC<ContainerProps> = ({ children }) => {
+  return (
+    <div className="mx-4 sm:mx-6 md:mx-10 xl:mx-16 relative">{children}</div>
+  );
+};
+export default Container;
diff --git a/frontend/src/components/HOC/Content.tsx b/frontend/src/components/HOC/Content.tsx
new file mode 100644
index 0000000..5be80f9
--- /dev/null
+++ b/frontend/src/components/HOC/Content.tsx
@@ -0,0 +1,15 @@
+import React, { ReactNode } from "react";
+interface ContentProps {
+  children: ReactNode;
+}
+const Content: React.FC<ContentProps> = ({ children }) => {
+  return (
+    <div
+      className="h-screen mx-4 sm:mx-6 md:mx-10 xl:mx-16 pb-4"
+      style={{ paddingTop: "68px" }}
+    >
+      {children}
+    </div>
+  );
+};
+export default Content;
diff --git a/frontend/src/components/HOC/DraggableWrapper.tsx b/frontend/src/components/HOC/DraggableWrapper.tsx
new file mode 100644
index 0000000..984349a
--- /dev/null
+++ b/frontend/src/components/HOC/DraggableWrapper.tsx
@@ -0,0 +1,78 @@
+import React, { ReactNode, useEffect, useRef, useState } from "react";
+
+interface DraggableWrapperProps {
+  children: ReactNode;
+  handleSelector: string; // Selector for the draggable handle
+}
+
+const DraggableWrapper: React.FC<DraggableWrapperProps> = ({
+  children,
+  handleSelector,
+}) => {
+  const [position, setPosition] = useState({ x: 50, y: 150 });
+  const [isDragging, setIsDragging] = useState(false);
+  const [offset, setOffset] = useState({ x: 0, y: 0 });
+  const ref = useRef<HTMLDivElement>(null);
+  const animationFrameRef = useRef<number | null>(null);
+
+  const onMouseDown = (e: React.MouseEvent) => {
+    const handleElement = (e.target as HTMLElement).closest(handleSelector);
+
+    if (handleElement) {
+      const element = ref.current;
+
+      if (element) {
+        const rect = element.getBoundingClientRect();
+        // Calculate the offset between the cursor and the element's top-left corner
+        setOffset({ x: e.clientX - rect.left, y: e.clientY - rect.top });
+        setIsDragging(true);
+      }
+    }
+  };
+
+  const onMouseMove = (e: MouseEvent) => {
+    if (isDragging && animationFrameRef.current === null) {
+      // Throttle with requestAnimationFrame for better performance
+      animationFrameRef.current = requestAnimationFrame(() => {
+        setPosition({ x: e.clientX - offset.x, y: e.clientY - offset.y });
+        animationFrameRef.current = null;
+      });
+    }
+  };
+
+  const onMouseUp = () => {
+    setIsDragging(false);
+    if (animationFrameRef.current) {
+      cancelAnimationFrame(animationFrameRef.current);
+      animationFrameRef.current = null;
+    }
+  };
+
+  useEffect(() => {
+    if (isDragging) {
+      window.addEventListener("mousemove", onMouseMove);
+      window.addEventListener("mouseup", onMouseUp);
+    } else {
+      window.removeEventListener("mousemove", onMouseMove);
+      window.removeEventListener("mouseup", onMouseUp);
+    }
+
+    return () => {
+      window.removeEventListener("mousemove", onMouseMove);
+      window.removeEventListener("mouseup", onMouseUp);
+    };
+  }, [isDragging, offset]);
+
+  return (
+    <div
+      ref={ref}
+      className="fixed shadow-xl"
+      style={{ top: `${position.y}px`, left: `${position.x}px` }}
+      onMouseDown={onMouseDown}
+    >
+      {children}
+    </div>
+  );
+};
+
+export default DraggableWrapper;
diff --git a/frontend/src/components/Logo.tsx b/frontend/src/components/Logo.tsx
new file mode 100644
index 0000000..ac42f30
--- /dev/null
+++ b/frontend/src/components/Logo.tsx
@@ -0,0 +1,14 @@
+import smallLogo from "images/small-logo.png";
+
+const Logo = () => {
+  return (
+    <div className="flex items-center space-x-2 select-none">
+      <img src={smallLogo} alt="K Scale Logo" className="h-6 invert" />
+      <span className="text-lg font-bold text-gray-1 font-orbitron tracking-wider">
+        Linguaphoto
+      </span>
+    </div>
+  );
+};
+
+export default Logo;
diff --git a/frontend/src/components/UploadContent.tsx b/frontend/src/components/UploadContent.tsx
index 7dfd505..d0b1cfb 100644
--- a/frontend/src/components/UploadContent.tsx
+++ b/frontend/src/components/UploadContent.tsx
@@ -80,12 +80,12 @@ const UploadContent: FC<UploadContentProps> = ({ onUpload }) => {
                       alt=""
                       className="w-full h-32 object-cover rounded-lg border border-gray-300 dark:border-gray-700"
                     />
-                    <button
-                      className="absolute top-2 right-2 text-red-500 hover:text-red-600 dark:text-red-400 dark:hover:text-red-300 transition-colors duration-200"
+                    <span
+                      className="absolute top-2 right-2 text-red-500 hover:text-red-600 dark:text-red-400 dark:hover:text-red-300 transition-colors duration-200 cursor-pointer"
                       onClick={() => onImageRemove(index)}
                     >
                       <XCircleFill size={24} />
-                    </button>
+                    </span>
                   </div>
                 ))
               ) : (
diff --git a/frontend/src/components/auth/GoogleAuthComponent.tsx b/frontend/src/components/auth/GoogleAuthComponent.tsx
deleted file mode 100644
index de010f7..0000000
--- a/frontend/src/components/auth/GoogleAuthComponent.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import { faGoogle } from "@fortawesome/free-brands-svg-icons";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { GoogleOAuthProvider, useGoogleLogin } from "@react-oauth/google";
-import { humanReadableError } from "constants/backend";
-import { useAlertQueue } from "hooks/alerts";
-import { useAuthentication } from "hooks/auth";
-import { useEffect, useState } from "react";
-import { Button } from "react-bootstrap";
-
-const GOOGLE_CLIENT_ID = process.env.REACT_APP_GOOGLE_CLIENT_ID;
-
-interface UserLoginResponse {
-  token: string;
-  token_type: string;
-}
-
-const GoogleAuthComponentInner = () => {
-  const [credential, setCredential] = useState<string | null>(null);
-  const [disableButton, setDisableButton] = useState(false);
-
-  const { setApiKey, api } = useAuthentication();
-  const { addAlert } = useAlertQueue();
-
-  useEffect(() => {
-    (async () => {
-      if (credential !== null) {
-        try {
-          const response = await api.post<UserLoginResponse>("/users/google", {
-            token: credential,
-          });
-          setApiKey(response.data.token);
-        } catch (error) {
-          addAlert(humanReadableError(error), "error");
-        } finally {
-          setCredential(null);
-          setDisableButton(false);
-        }
-      }
-    })();
-  }, [credential, setApiKey, api, addAlert]);
-
-  const login = useGoogleLogin({
-    onSuccess: (tokenResponse) => {
-      const returnedCredential = tokenResponse.access_token;
-      if (returnedCredential) {
-        setCredential(returnedCredential);
-      } else {
-        addAlert("Failed to login using Google OAuth.", "error");
-      }
-    },
-    onError: () => {
-      addAlert("Failed to login using Google OAuth.", "error");
-      setDisableButton(false);
-    },
-    onNonOAuthError: () => {
-      addAlert("Failed to login using Google OAuth.", "error");
-      setDisableButton(false);
-    },
-  });
-
-  return (
-    <Button
-      onClick={() => {
-        setDisableButton(true);
-        login();
-      }}
-      disabled={disableButton || credential !== null}
-      variant="primary"
-    >
-      Sign In with Google
-      <FontAwesomeIcon icon={faGoogle} style={{ marginLeft: 10 }} />
-    </Button>
-  );
-};
-
-const GoogleAuthComponent = () => {
-  // Fatal error if GOOGLE_CLIENT_ID is not set
-  if (GOOGLE_CLIENT_ID === undefined) {
-    throw new Error(`REACT_APP_GOOGLE_CLIENT_ID is ${GOOGLE_CLIENT_ID}.`);
-  }
-
-  return (
-    <GoogleOAuthProvider clientId={GOOGLE_CLIENT_ID}>
-      <GoogleAuthComponentInner />
-    </GoogleOAuthProvider>
-  );
-};
-
-export default GoogleAuthComponent;
diff --git a/frontend/src/components/auth/RequireAuthentication.tsx b/frontend/src/components/auth/RequireAuthentication.tsx
deleted file mode 100644
index d51a6ca..0000000
--- a/frontend/src/components/auth/RequireAuthentication.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { useAuthentication } from "hooks/auth";
-import React from "react";
-import { useNavigate } from "react-router-dom";
-
-interface Props {
-  children: React.ReactNode;
-}
-
-const RequireAuthentication = (props: Props) => {
-  const { children } = props;
-  const { isAuthenticated } = useAuthentication();
-
-  const navigate = useNavigate();
-
-  if (!isAuthenticated) {
-    navigate("/");
-  }
-
-  return children;
-};
-
-export default RequireAuthentication;
diff --git a/frontend/src/components/card.tsx b/frontend/src/components/card.tsx
index dd4e07d..02d4ba3 100644
--- a/frontend/src/components/card.tsx
+++ b/frontend/src/components/card.tsx
@@ -45,7 +45,7 @@ const CardItem: React.FC<CardItemProps> = (cardprops) => {
               Edit
             </button>
             <button
-              className="bg-red-700 text-white flex justify-content-center items-center w-8 h-8 rounded"
+              className="bg-red-700 text-white flex justify-center items-center w-8 h-8 rounded"
               onClick={handleDelete}
             >
               <TrashFill size={18} />
diff --git a/frontend/src/components/collection/Edit.tsx b/frontend/src/components/collection/Edit.tsx
new file mode 100644
index 0000000..c9448e7
--- /dev/null
+++ b/frontend/src/components/collection/Edit.tsx
@@ -0,0 +1,350 @@
+import { Api } from "api/api";
+import axios, { AxiosInstance } from "axios";
+import Book from "components/Book";
+import ImageComponent from "components/image";
+import Modal from "components/modal";
+import UploadContent from "components/UploadContent";
+import { useAuth } from "contexts/AuthContext";
+import { useLoading } from "contexts/LoadingContext";
+import { useAlertQueue } from "hooks/alerts";
+import { useEffect, useMemo, useState } from "react";
+import { ListManager } from "react-beautiful-dnd-grid";
+import { Collection, Image } from "types/model";
+type CollectionEditProps = {
+  collection: Collection;
+  setCollection: React.Dispatch<React.SetStateAction<Collection | undefined>>;
+};
+const CollectionEdit: React.FC<CollectionEditProps> = ({
+  collection,
+  setCollection,
+}) => {
+  const [featured_image, setFeaturedImage] = useState<string>("");
+  const [title, setTitle] = useState<string>("");
+  const [description, setDescription] = useState<string>("");
+  const { auth, client } = useAuth();
+  const { startLoading, stopLoading } = useLoading();
+  const [showUploadModal, setShowUploadModal] = useState(false);
+  const [showDeleteImageModal, setShowDeleteImageModal] = useState(false);
+  const [images, setImages] = useState<Array<Image> | undefined>([]);
+  const [reorderImageIds, setReorderImageIds] = useState<Array<string> | null>(
+    [],
+  );
+  const { addAlert } = useAlertQueue();
+  const [deleteImageId, setDeleteImageId] = useState<string>("");
+  useEffect(() => {
+    if (collection) {
+      setTitle(collection.title);
+      setDescription(collection.description);
+      setFeaturedImage(collection.featured_image);
+      setReorderImageIds([...collection.images]);
+      const asyncfunction = async () => {
+        const { data: images, error } = await client.GET("/get_images", {
+          params: { query: { collection_id: collection.id } },
+        });
+        if (error) addAlert(error.detail?.toString(), "error");
+        else setImages(images);
+      };
+      asyncfunction();
+    }
+  }, [collection.id]);
+  useEffect(() => {}, [collection.images]);
+  const apiClient: AxiosInstance = useMemo(
+    () =>
+      axios.create({
+        baseURL: process.env.REACT_APP_BACKEND_URL, // Base URL for all requests
+        timeout: 10000, // Request timeout (in milliseconds)
+        headers: {
+          "Content-Type": "application/json",
+          Authorization: `Bearer ${auth?.token}`, // Add any default headers you need
+        },
+      }),
+    [auth?.token],
+  );
+  const apiClient1: AxiosInstance = useMemo(
+    () =>
+      axios.create({
+        baseURL: process.env.REACT_APP_BACKEND_URL,
+        timeout: 1000000,
+        headers: {
+          "Content-Type": "multipart/form-data",
+          Authorization: `Bearer ${auth?.token}`,
+        },
+      }),
+    [auth?.token],
+  );
+  const API = useMemo(() => new Api(apiClient), [apiClient]);
+  const API_Uploader = useMemo(() => new Api(apiClient1), [apiClient1]);
+  const handleSave = async (e: React.FormEvent) => {
+    e.preventDefault();
+    // Use e.nativeEvent to access the native event
+    const target = e.nativeEvent as SubmitEvent;
+    const submitButton = target.submitter as HTMLButtonElement;
+    // Check if the submitButton exists and get its value
+    const action = submitButton ? submitButton.value : "";
+    switch (action) {
+      case "save":
+        if (collection && reorderImageIds) {
+          const asyncfunction = async () => {
+            startLoading();
+            collection.images = reorderImageIds;
+            const { error } = await client.POST("/edit_collection", {
+              body: { ...collection, featured_image, title, description },
+            });
+            if (error) addAlert(error.detail?.toString(), "error");
+            else {
+              setCollection({
+                ...collection,
+                featured_image,
+                title,
+                description,
+              });
+              addAlert(
+                "The collection has been updated successfully!",
+                "success",
+              );
+            }
+            stopLoading();
+          };
+          asyncfunction();
+        }
+        break;
+      case "publish":
+        if (collection) {
+          const { error } = await client.POST("/publish_collection", {
+            body: { id: collection.id, flag: !collection.publish_flag },
+          });
+          if (error) addAlert(error.detail?.toString(), "error");
+          else {
+            setCollection({
+              ...collection,
+              publish_flag: !collection.publish_flag,
+            });
+            addAlert(
+              "The collection has been updated successfully!",
+              "success",
+            );
+          }
+        }
+        break;
+    }
+  };
+  const onShowDeleteImageModal = (id: string) => {
+    setDeleteImageId(id);
+    setShowDeleteImageModal(true);
+  };
+  const handleUpload = async (file: File) => {
+    if (collection) {
+      startLoading();
+      const new_image = await API_Uploader.uploadImage(file, collection?.id);
+      stopLoading();
+      if (new_image) {
+        if (collection.images.length == 0 || images == undefined) {
+          // no images
+          setImages([new_image]);
+          setFeaturedImage(new_image.image_url);
+        } else {
+          // images exist
+          images.push(new_image);
+          setImages([...images]);
+        }
+        collection.images.push(new_image.id);
+        setReorderImageIds([...collection.images]);
+        setCollection({ ...collection });
+      }
+    }
+  };
+  const handleTranslateOneImage = async (image_id: string) => {
+    if (images) {
+      startLoading();
+      addAlert(
+        "The image is being tranlated. Please wait a moment.",
+        "primary",
+      );
+      const image_response = await API.translateImages([image_id]);
+      const i = images?.findIndex((image) => image.id == image_id);
+      images[i] = image_response[0];
+      setImages([...images]);
+      addAlert("The image has been tranlated!", "success");
+      stopLoading();
+    }
+  };
+  const onDeleteImage = async () => {
+    if (deleteImageId) {
+      startLoading();
+      const { error } = await client.GET("/delete_image", {
+        params: { query: { id: deleteImageId } },
+      });
+      if (error) addAlert(error.detail?.toString(), "error");
+      else if (images) {
+        const new_images_ID = collection.images.filter(
+          (image) => image !== deleteImageId,
+        );
+        collection.images = new_images_ID;
+        const new_images = images.filter((image) => image.id !== deleteImageId);
+        setImages(new_images);
+        setReorderImageIds([...collection.images]);
+        setCollection({ ...collection });
+        addAlert("The image has been deleted!", "success");
+      }
+      setShowDeleteImageModal(false);
+      stopLoading();
+    }
+  };
+  // Inside your CollectionPage component
+  /* eslint-disable */
+  const handleDragEnd = (sourceIndex: number, destinationIndex: number) => {
+    /* eslint-enable */
+    if (!reorderImageIds) return;
+    const [removed] = reorderImageIds.splice(sourceIndex, 1);
+    reorderImageIds.splice(destinationIndex, 0, removed);
+    setReorderImageIds([...reorderImageIds]);
+    //featured image
+    const image = images?.find((img) => img.id == reorderImageIds[0]);
+    if (image) setFeaturedImage(image?.image_url);
+    // Optionally, you can save the new order to your backend here
+  };
+  return (
+    <div className="flex flex-col rounded-md min-h-full bg-gray-3 p-24 gap-8">
+      <h1 className="text-3xl text-gray-900">Edit Collection </h1>
+      <form
+        className="flex flex-col items-center gap-4 w-full"
+        onSubmit={handleSave}
+      >
+        <div className="flex flex-wrap w-full gap-4">
+          <div className="flex flex-col flex-1 gap-3 h-64">
+            <input
+              className="border p-2 w-full"
+              type="text"
+              placeholder="Title"
+              value={title}
+              onChange={(e) => setTitle(e.target.value)}
+              required
+            />
+            <textarea
+              className="flex-1 border p-2 w-full"
+              placeholder="Description"
+              value={description}
+              onChange={(e) => setDescription(e.target.value)}
+              required
+            />
+          </div>
+          <Book
+            title={title}
+            description={description}
+            id={collection.id}
+            featured_image={featured_image}
+          />
+        </div>
+        <div className="flex justify-content-end w-full gap-2">
+          <button
+            className="bg-blue-500 text-white w-35 p-2 rounded hover:bg-blue-600"
+            onClick={() => setShowUploadModal(true)}
+          >
+            Add Images
+          </button>
+          <button
+            className="bg-blue-500 text-white w-30 p-2 rounded hover:bg-blue-600"
+            disabled={
+              collection.images.join() == reorderImageIds?.join() &&
+              collection.title == title &&
+              collection.description == description
+            }
+            type="submit"
+            name="action"
+            value="save"
+          >
+            Save Changes
+          </button>
+          <button
+            className="bg-blue-500 text-white w-30 p-2 rounded hover:bg-blue-600"
+            type="submit"
+            name="action"
+            value="publish"
+          >
+            {collection.publish_flag ? "Unpublish" : "Publish"}
+          </button>
+        </div>
+      </form>
+      {/* <div className="flex gap-4">
+          <button
+            className="bg-blue-500 text-white w-35 p-2 rounded hover:bg-blue-600 disabled:bg-gray-600"
+            onClick={(e) => handleSave(e)}
+            disabled={reorderImageIds?.join() === collection.images.join()}
+            value="save"
+          >
+            Order Save
+          </button>
+        </div> */}
+      {/* reordering part */}
+      <div className="flex flex-wrap justify-start w-full">
+        {reorderImageIds && images && (
+          <ListManager
+            items={reorderImageIds}
+            direction="horizontal"
+            maxItems={3}
+            onDragEnd={handleDragEnd}
+            render={(id) => {
+              const image = images.find((item) => item.id === id);
+              return (
+                <div className="w-full md:w-1/2 lg:w-1/3">
+                  {image ? (
+                    <ImageComponent
+                      {...image}
+                      handleTranslateOneImage={handleTranslateOneImage}
+                      showDeleteModal={onShowDeleteImageModal}
+                    />
+                  ) : (
+                    <ImageComponent
+                      {...{
+                        id,
+                        is_translated: false,
+                        image_url: "",
+                        transcriptions: [],
+                        collection: collection.id,
+                      }}
+                      handleTranslateOneImage={handleTranslateOneImage}
+                      showDeleteModal={onShowDeleteImageModal}
+                    />
+                  )}
+                </div>
+              );
+            }}
+          />
+        )}
+      </div>
+      {/* Upload Modal */}
+      <Modal isOpen={showUploadModal} onClose={() => setShowUploadModal(false)}>
+        <UploadContent onUpload={handleUpload} />
+        <div className="mt-5 flex justify-end space-x-2">
+          <button
+            className="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400"
+            onClick={() => setShowUploadModal(false)}
+          >
+            Close
+          </button>
+        </div>
+      </Modal>
+      <Modal
+        isOpen={showDeleteImageModal}
+        onClose={() => setShowDeleteImageModal(false)}
+      >
+        <div className="mt-5 flex justify-end space-x-2 gap-4 items-center">
+          <span>Are you sure you want to delete the collection?</span>
+          <button
+            className="px-4 py-2 bg-red-700 text-gray-300 rounded hover:bg-red-800"
+            onClick={onDeleteImage}
+          >
+            Delete
+          </button>
+          <button
+            className="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400"
+            onClick={() => setShowDeleteImageModal(false)}
+          >
+            Cancel
+          </button>
+        </div>
+      </Modal>
+    </div>
+  );
+};
+export default CollectionEdit;
diff --git a/frontend/src/components/collection/New.tsx b/frontend/src/components/collection/New.tsx
new file mode 100644
index 0000000..4ff6bc9
--- /dev/null
+++ b/frontend/src/components/collection/New.tsx
@@ -0,0 +1,62 @@
+import { useAuth } from "contexts/AuthContext";
+import { useLoading } from "contexts/LoadingContext";
+import { useAlertQueue } from "hooks/alerts";
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+
+const CollectionNew: React.FC = () => {
+  const navigate = useNavigate();
+  const { client } = useAuth();
+  const { startLoading, stopLoading } = useLoading();
+  const { addAlert } = useAlertQueue();
+  const [title, setTitle] = useState<string>("");
+  const [description, setDescription] = useState<string>("");
+
+  const handleCreate = async (e: React.FormEvent) => {
+    e.preventDefault();
+    startLoading();
+    const { data: collection, error } = await client.POST(
+      "/create_collection",
+      { body: { title, description } },
+    );
+    if (error) addAlert(error.detail?.toString(), "error");
+    else if (collection != null) {
+      navigate(`/collection/${collection.id}?Action=edit`);
+      addAlert("New collection has been created successfully!", "success");
+    } else addAlert("The process has gone wrong!", "error");
+    stopLoading();
+  };
+
+  return (
+    <div className="flex flex-col rounded-md h-full bg-gray-3 p-24 gap-8">
+      <h1 className="text-3xl text-gray-900">New Collection</h1>
+      <form
+        className="flex flex-col items-end gap-4 w-full"
+        onSubmit={handleCreate}
+      >
+        <input
+          className="border p-2 w-full"
+          type="text"
+          placeholder="Title"
+          value={title}
+          onChange={(e) => setTitle(e.target.value)}
+          required
+        />
+        <textarea
+          className="border p-2 w-full h-32"
+          placeholder="Description"
+          value={description}
+          onChange={(e) => setDescription(e.target.value)}
+          required
+        />
+        <button
+          className="bg-blue-500 w-32 text-white p-2 rounded hover:bg-blue-600"
+          type="submit"
+        >
+          Create
+        </button>
+      </form>
+    </div>
+  );
+};
+export default CollectionNew;
diff --git a/frontend/src/components/collection/View.tsx b/frontend/src/components/collection/View.tsx
new file mode 100644
index 0000000..603d3c3
--- /dev/null
+++ b/frontend/src/components/collection/View.tsx
@@ -0,0 +1,170 @@
+import AudioPlayer from "components/Audio";
+import Container from "components/HOC/Container";
+import { useAuth } from "contexts/AuthContext";
+import { useAlertQueue } from "hooks/alerts";
+import { useEffect, useMemo, useState } from "react";
+import { Collection, Image } from "types/model";
+type CollectionViewProps = {
+  collection: Collection;
+};
+const CollectionView: React.FC<CollectionViewProps> = ({ collection }) => {
+  const [currentImageIndex, setCurrentImageIndex] = useState(0);
+  const [currentTranscriptionIndex, setCurrentTranscriptionIndex] = useState(0);
+  const [currentImage, setCurrentImage] = useState<Image | null>(null);
+  const [isLoading, setIsLoading] = useState<boolean>(true);
+  const { client } = useAuth();
+  const { addAlert } = useAlertQueue();
+  const [images, setImages] = useState<Array<Image> | undefined>([]);
+  // Get translated images
+  const translatedImages = useMemo(() => {
+    if (images) {
+      // Get translated images
+      const filter = images.filter((img) => img.is_translated);
+      const final_filter = collection.images
+        ?.map((img) => {
+          const foundItem = filter.find((item) => item.id == img);
+          return foundItem ? foundItem : null; // Return `null` or skip
+        })
+        .filter(Boolean); // Filters out `null` or `undefined`
+      if (final_filter) return final_filter;
+    }
+    return [];
+  }, [images]);
+
+  useEffect(() => {
+    if (translatedImages.length > 0) {
+      setCurrentImage(translatedImages[currentImageIndex]);
+    }
+  }, [currentImageIndex, translatedImages]);
+
+  useEffect(() => {
+    if (collection) {
+      const asyncfunction = async () => {
+        const { data: images, error } = await client.GET("/get_images", {
+          params: { query: { collection_id: collection.id } },
+        });
+        if (error) addAlert(error.detail?.toString(), "error");
+        else setImages(images);
+        setIsLoading(false);
+      };
+      asyncfunction();
+    }
+  }, [collection?.id]);
+
+  // Navigate between images
+  const handleNext = () => {
+    if (currentImageIndex < translatedImages.length - 1) {
+      setCurrentImageIndex(currentImageIndex + 1);
+      setCurrentTranscriptionIndex(0);
+      window.scrollTo(0, 0); // This instantly jumps the viewport to the top
+    }
+  };
+
+  const handlePrev = () => {
+    if (currentImageIndex > 0) {
+      setCurrentImageIndex(currentImageIndex - 1);
+      setCurrentTranscriptionIndex(0);
+      window.scrollTo(0, 0); // This instantly jumps the viewport to the top
+    }
+  };
+
+  // Navigate transcriptions
+  const handleTranscriptionNext = () => {
+    if (
+      currentImage?.transcriptions &&
+      currentTranscriptionIndex < currentImage?.transcriptions.length - 1
+    ) {
+      setCurrentTranscriptionIndex(currentTranscriptionIndex + 1);
+    }
+  };
+
+  const handleTranscriptionPrev = () => {
+    if (currentTranscriptionIndex > 0) {
+      setCurrentTranscriptionIndex(currentTranscriptionIndex - 1);
+    }
+  };
+  const handlePhotoClick = (e: React.MouseEvent<HTMLDivElement>) => {
+    // Calculate the click position relative to the component
+    const { clientX, currentTarget } = e;
+    const { left, right } = currentTarget.getBoundingClientRect();
+    const width = right - left;
+
+    // Determine if the click was on the left or right side
+    if (clientX < left + width / 2) {
+      handlePrev(); // Clicked on the left side
+    } else {
+      handleNext(); // Clicked on the right side
+    }
+  };
+  return (
+    <div className="flex flex-col rounded-md h-full items-center bg-gray-0 gap-4 w-full">
+      {isLoading ? (
+        <div className="flex flex-col h-full w-full gap-4">
+          <div className="bg-gray-3 w-full rounded-lg h-3/4 animate-pulse" />
+          <div className="bg-gray-3 w-full rounded-lg h-1/4 animate-pulse" />
+        </div>
+      ) : currentImage ? (
+        <div className="flex flex-col align-items-center w-full">
+          <div className="w-full absolute left-0">
+            <img
+              draggable="false"
+              src={currentImage.image_url}
+              alt="Collection Image"
+              className="w-full select-none"
+              style={{ marginBottom: "230px" }}
+              onClick={handlePhotoClick}
+            />
+          </div>
+          <div className="fixed bottom-0 left-0 w-full px-4 py-1 text-center bg-gray-1/30 backdrop-blur-lg">
+            <Container>
+              {/* transcription */}
+              <div className="rounded-md bg-gray-12 p-2">
+                <p className="mt-2 px-12">
+                  {currentImage.transcriptions.map((transcription, index) => {
+                    return (
+                      <span
+                        key={index}
+                        className={
+                          index == currentTranscriptionIndex
+                            ? ""
+                            : "text-gray-400"
+                        }
+                      >
+                        {transcription.text}
+                      </span>
+                    );
+                  })}
+                </p>
+                <p className="mt-2">
+                  {
+                    currentImage.transcriptions[currentTranscriptionIndex]
+                      .pinyin
+                  }
+                </p>
+                <p className="mt-2">
+                  {
+                    currentImage.transcriptions[currentTranscriptionIndex]
+                      .translation
+                  }
+                </p>
+                <AudioPlayer
+                  currentImage={currentImage}
+                  index={currentTranscriptionIndex}
+                  handleTranscriptionNext={handleTranscriptionNext}
+                  handleTranscriptionPrev={handleTranscriptionPrev}
+                />
+              </div>
+            </Container>
+          </div>
+        </div>
+      ) : (
+        <div className="p-24 flex h-full items-center">
+          <h1 className="text-3xl text-gray-900">
+            No translated images available.
+          </h1>
+        </div>
+      )}
+    </div>
+  );
+};
+export default CollectionView;
diff --git a/frontend/src/components/image.tsx b/frontend/src/components/image.tsx
index a28aacd..7f1f2b4 100644
--- a/frontend/src/components/image.tsx
+++ b/frontend/src/components/image.tsx
@@ -15,7 +15,6 @@ const ImageComponent: React.FC<ImageWithFunction> = ({
   id,
   is_translated,
   image_url,
-  transcriptions,
   handleTranslateOneImage,
   showDeleteModal,
 }) => {
@@ -31,11 +30,6 @@ const ImageComponent: React.FC<ImageWithFunction> = ({
               <CheckCircleFill size={15} className="mr-2" />
               <span>The image has been translated</span>
             </div>
-            <div className="absolute bottom-2 text-white bg-gray-800 py-1 px-3 mx-2 rounded">
-              {transcriptions.map((transcription, index) => (
-                <span key={index}>{transcription.text}&nbsp;&nbsp;</span>
-              ))}
-            </div>
           </>
         ) : (
           <>
diff --git a/frontend/src/components/modal.tsx b/frontend/src/components/modal.tsx
index d5ef647..2622bb6 100644
--- a/frontend/src/components/modal.tsx
+++ b/frontend/src/components/modal.tsx
@@ -15,13 +15,13 @@ const Modal: FC<ModalProps> = ({ isOpen, onClose, children }) => {
       {/* Modal container */}
       <div className="bg-white p-8 rounded-2xl shadow-xl max-w-3xl w-full relative border border-gray-200 dark:bg-gray-800 dark:border-gray-700 dark:text-white">
         {/* Close button in the top right corner */}
-        <button
-          className="absolute top-4 right-4 text-gray-600 hover:text-red-600 dark:text-gray-400 dark:hover:text-red-400 transition-colors duration-200"
+        <div
+          className="absolute hover:bg-transparent top-6 right-8 text-gray-400 hover:text-red-400 transition-colors duration-200"
           onClick={onClose}
           aria-label="Close Modal"
         >
           <X size={28} /> {/* Close icon from react-bootstrap-icons */}
-        </button>
+        </div>
 
         {/* Modal content */}
         <div className="p-6">{children}</div>
diff --git a/frontend/src/components/nav/Navbar.tsx b/frontend/src/components/nav/Navbar.tsx
new file mode 100644
index 0000000..b0beaca
--- /dev/null
+++ b/frontend/src/components/nav/Navbar.tsx
@@ -0,0 +1,107 @@
+import { useState } from "react";
+import { FaBars } from "react-icons/fa";
+import { Link, useLocation } from "react-router-dom";
+
+import Container from "components/HOC/Container";
+import Logo from "components/Logo";
+import Sidebar from "components/nav/Sidebar";
+import { useAuth } from "contexts/AuthContext";
+const Navbar = () => {
+  const { auth, signout } = useAuth();
+  const [showSidebar, setShowSidebar] = useState<boolean>(false);
+  const location = useLocation();
+
+  const navItems = [
+    { name: "Home", path: "/", isExternal: false },
+    { name: "My Collections", path: "/collections", isExternal: false },
+    { name: "Subscription", path: "/subscription", isExternal: false },
+  ];
+
+  return (
+    <>
+      {
+        <nav className="fixed w-full z-30 top-0 start-0 bg-gray-1/30 backdrop-blur-lg">
+          <Container>
+            <div className="flex items-center justify-between py-2 font-medium">
+              <Link
+                to="/"
+                className="flex items-center space-x-2 bg-gray-12 p-3 rounded-lg hover:bg-primary-9 transition-all duration-300"
+              >
+                <Logo />
+              </Link>
+              <div className="hidden lg:flex items-center flex-grow justify-between ml-4">
+                <div className="flex space-x-3 bg-gray-12 rounded-lg p-2 flex-grow justify-center">
+                  {navItems.map((item) =>
+                    item.isExternal ? (
+                      <a
+                        key={item.name}
+                        href={item.path}
+                        className={`px-2 xl:px-3 py-2 rounded-md text-sm tracking-wide xl:tracking-widest text-gray-1 hover:bg-primary-9`}
+                        target="_blank"
+                        rel="noopener noreferrer"
+                      >
+                        {item.name}
+                      </a>
+                    ) : (
+                      <Link
+                        key={item.name}
+                        to={item.path}
+                        className={`px-2 xl:px-3 py-2 rounded-md text-sm tracking-widest ${
+                          location.pathname === item.path
+                            ? "bg-gray-11 text-gray-1"
+                            : "text-gray-1 hover:bg-gray-1 hover:text-primary-9"
+                        }`}
+                      >
+                        {item.name}
+                      </Link>
+                    ),
+                  )}
+                </div>
+                <div className="flex items-center space-x-2 text-gray-1 bg-gray-12 rounded-lg p-2 ml-4 text-sm tracking-widest">
+                  {auth?.is_auth ? (
+                    <>
+                      {/* <Link
+                    to="/account"
+                    className={`px-3 py-2 rounded-md hover:bg-gray-1 hover:text-primary-9 ${location.pathname === "/account"
+                      ? "bg-gray-11 text-gray-1"
+                      : ""
+                      }`}
+                  >
+                    Account
+                  </Link> */}
+                      <Link
+                        to="/login"
+                        className="px-3 py-2 rounded-md hover:bg-primary-9"
+                        onClick={signout}
+                      >
+                        Logout
+                      </Link>
+                    </>
+                  ) : (
+                    <>
+                      <Link
+                        to="/login"
+                        className="px-3 py-2 rounded-md hover:bg-gray-1 hover:text-primary-9"
+                      >
+                        Sign In
+                      </Link>
+                    </>
+                  )}
+                </div>
+              </div>
+              <button
+                onClick={() => setShowSidebar(true)}
+                className="lg:hidden text-gray-300 hover:bg-gray-700 bg-gray-12 hover:text-white p-4 rounded-md text-sm"
+              >
+                <FaBars size={20} />
+              </button>
+            </div>
+          </Container>
+        </nav>
+      }
+      <Sidebar show={showSidebar} onClose={() => setShowSidebar(false)} />
+    </>
+  );
+};
+
+export default Navbar;
diff --git a/frontend/src/components/nav/TopNavbar.tsx b/frontend/src/components/nav/TopNavbar.tsx
deleted file mode 100644
index 4f04e4f..0000000
--- a/frontend/src/components/nav/TopNavbar.tsx
+++ /dev/null
@@ -1,123 +0,0 @@
-import { useAuth } from "contexts/AuthContext";
-import { useTheme } from "hooks/theme";
-import { useState } from "react";
-import { Container, Nav, Navbar } from "react-bootstrap";
-import { MoonFill, SunFill } from "react-bootstrap-icons";
-import {
-  FaBars,
-  FaLock,
-  FaSignInAlt,
-  FaSignOutAlt,
-  FaThList,
-} from "react-icons/fa";
-import { Link, useLocation } from "react-router-dom";
-import Sidebar from "./Sidebar";
-
-const TopNavbar = () => {
-  const [showSidebar, setShowSidebar] = useState<boolean>(false);
-  const { theme, setTheme } = useTheme();
-  const location = useLocation(); // To determine the active link
-  const { auth, signout } = useAuth();
-  return (
-    <>
-      <Navbar
-        className="fixed w-full top-0 z-50 bg-gray-100 dark:bg-gray-800 justify-content-between shadow-lg"
-        expand="lg"
-        style={{ height: "60px" }} // Set navbar height
-      >
-        <Container className="flex justify-between items-center h-full">
-          <Navbar.Brand
-            as={Link}
-            to="/"
-            className="text-xl text-gray-900 dark:text-white" // Reduced font size
-          >
-            LinguaPhoto
-          </Navbar.Brand>
-
-          <div className="flex gap-6 items-center">
-            {/* Main Navigation Links */}
-            <div className="hidden sm:flex gap-6">
-              {" "}
-              {/* Hidden on small screens */}
-              {auth?.is_auth ? (
-                <>
-                  <Nav.Link
-                    as={Link}
-                    to="/collections"
-                    className={`flex items-center gap-2 px-3 py-2 text-sm transition-colors rounded-md ${
-                      location.pathname === "/collections"
-                        ? "text-blue-600 dark:text-blue-400 font-semibold"
-                        : "text-gray-800 dark:text-gray-300"
-                    } hover:text-blue-500 dark:hover:text-blue-300`}
-                  >
-                    <FaThList /> <span>Collections</span>
-                  </Nav.Link>
-
-                  <Nav.Link
-                    as={Link}
-                    to="/subscription"
-                    className={`flex items-center gap-2 px-3 py-2 text-sm transition-colors rounded-md ${
-                      location.pathname === "/subscription"
-                        ? "text-blue-600 dark:text-blue-400 font-semibold"
-                        : "text-gray-800 dark:text-gray-300"
-                    } hover:text-blue-500 dark:hover:text-blue-300`}
-                  >
-                    <FaLock /> <span>Subscription</span>
-                  </Nav.Link>
-                  <Nav.Link
-                    as={Link}
-                    to="/login"
-                    className="flex items-center gap-2 px-3 py-2 text-sm transition-colors rounded-md hover:text-blue-500 dark:hover:text-blue-300"
-                    onClick={() => {
-                      // Handle logout logic here
-                      signout();
-                    }}
-                  >
-                    <FaSignOutAlt /> <span>Logout</span>
-                  </Nav.Link>
-                </>
-              ) : (
-                <Nav.Link
-                  as={Link}
-                  to="/login"
-                  className={`flex items-center gap-2 px-3 py-2 text-sm transition-colors rounded-md ${
-                    location.pathname === "/login"
-                      ? "text-blue-600 dark:text-blue-400 font-semibold"
-                      : "text-gray-800 dark:text-gray-300"
-                  } hover:text-blue-500 dark:hover:text-blue-300`}
-                  onClick={() => {
-                    // Handle logout logic here
-                    signout();
-                  }}
-                >
-                  <FaSignInAlt /> <span>Login / Sign Up</span>
-                </Nav.Link>
-              )}
-            </div>
-
-            {/* Theme Toggle and Sidebar */}
-            <div className="flex items-center gap-3">
-              <Nav.Link
-                onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
-                className="flex items-center text-lg text-gray-800 dark:text-gray-300"
-              >
-                {theme === "dark" ? <SunFill /> : <MoonFill />}
-              </Nav.Link>
-
-              <Nav.Link
-                onClick={() => setShowSidebar(true)}
-                className="flex items-center text-lg text-gray-800 dark:text-gray-300 hover:text-blue-500 dark:hover:text-blue-300 lg:hidden" // Show only on small screens
-              >
-                <FaBars /> {/* Hamburger Button */}
-              </Nav.Link>
-            </div>
-          </div>
-        </Container>
-      </Navbar>
-
-      <Sidebar show={showSidebar} onClose={() => setShowSidebar(false)} />
-    </>
-  );
-};
-
-export default TopNavbar;
diff --git a/frontend/src/components/new_card.tsx b/frontend/src/components/new_card.tsx
index 04876b5..d6a7b4f 100644
--- a/frontend/src/components/new_card.tsx
+++ b/frontend/src/components/new_card.tsx
@@ -3,19 +3,14 @@ import { Link } from "react-router-dom";
 
 const NewCardItem: React.FC = () => {
   return (
-    <div className="relative m-4">
-      <div className="relative z-10 w-52 h-72 p-3 bg-blue-200 dark:bg-gray-900 border flex flex-col gap-2 opacity-95">
-        <h3 className="text-lg font-bold">New Collection</h3>
-        <p className="text-sm text-gray-900 dark:text-gray-100">
-          Please add new collections
-        </p>
-        <div className="mt-3 flex gap-2 justify-center items-center grow">
-          <Link to="/collection/new">
-            <PlusCircleFill size={50} color="white" />
-          </Link>
-        </div>
+    <div className="w-52 h-64 p-3 bg-blue-200 dark:bg-gray-1 border flex flex-col gap-2 text-gray-900">
+      <h3 className="text-lg font-bold">New Collection</h3>
+      <p className="text-sm">Please add new collections</p>
+      <div className="mt-3 flex gap-2 justify-center items-center grow">
+        <Link to="/collection/new">
+          <PlusCircleFill size={50} color="orange" />
+        </Link>
       </div>
-      <div className="absolute top-5 left-5 w-52 h-72 bg-slate-300 shadow-sm"></div>
     </div>
   );
 };
diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx
index cdbd4ac..9d2b3be 100644
--- a/frontend/src/contexts/AuthContext.tsx
+++ b/frontend/src/contexts/AuthContext.tsx
@@ -17,6 +17,7 @@ interface AuthContextType {
       components["schemas"]["UserInfoResponseItem"] | undefined
     >
   >;
+  is_auth: boolean;
   setApiKeyId: React.Dispatch<React.SetStateAction<string | null>>;
   signout: () => void;
   apiKeyId: string | null;
@@ -40,6 +41,7 @@ const AuthProvider = ({ children }: { children: ReactNode }) => {
   const [auth, setAuth] = useState<
     components["schemas"]["UserInfoResponseItem"] | undefined
   >(undefined);
+  const [is_auth, setIsAuth] = useState<boolean>(true);
   const [apiKeyId, setApiKeyId] = useState<string | null>(
     getLocalStorageAuth(),
   );
@@ -47,6 +49,7 @@ const AuthProvider = ({ children }: { children: ReactNode }) => {
     localStorage.removeItem("token");
     setAuth(undefined);
     setApiKeyId("");
+    setIsAuth(false);
   };
   const client = useMemo(
     () =>
@@ -74,8 +77,9 @@ const AuthProvider = ({ children }: { children: ReactNode }) => {
       const fetch_data = async () => {
         const { data, error } = await client.GET("/me");
         if (error) {
-          console.error("Failed to fetch current user", error);
+          signout();
         } else {
+          setIsAuth(true);
           setAuth(data);
           setApiKeyId(data.token);
         }
@@ -101,6 +105,7 @@ const AuthProvider = ({ children }: { children: ReactNode }) => {
     <AuthContext.Provider
       value={{
         auth,
+        is_auth,
         setAuth,
         signout,
         client,
diff --git a/frontend/src/contexts/api.tsx b/frontend/src/contexts/api.tsx
index 5385fcf..1297056 100644
--- a/frontend/src/contexts/api.tsx
+++ b/frontend/src/contexts/api.tsx
@@ -7,22 +7,4 @@ export default class api {
   constructor(client: Client<paths>) {
     this.client = client;
   }
-
-  public async upload(files: File[], listing_id: string) {
-    return await this.client.POST("/artifacts/upload/{listing_id}", {
-      body: {
-        files: [],
-      },
-      params: {
-        path: {
-          listing_id,
-        },
-      },
-      bodySerializer() {
-        const fd = new FormData();
-        files.forEach((file) => fd.append("files", file));
-        return fd;
-      },
-    });
-  }
 }
diff --git a/frontend/src/gen/api.ts b/frontend/src/gen/api.ts
index 4d505c4..750a8c7 100644
--- a/frontend/src/gen/api.ts
+++ b/frontend/src/gen/api.ts
@@ -4,125 +4,6 @@
  */
 import { Collection, Image } from "types/model";
 export interface paths {
-  "/": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Read Root */
-    get: operations["read_root__get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/artifacts/url/{artifact_type}/{listing_id}/{name}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Artifact Url */
-    get: operations["artifact_url_artifacts_url__artifact_type___listing_id___name__get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/artifacts/info/{artifact_id}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Get Artifact Info */
-    get: operations["get_artifact_info_artifacts_info__artifact_id__get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/artifacts/list/{listing_id}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** List Artifacts */
-    get: operations["list_artifacts_artifacts_list__listing_id__get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/artifacts/upload/{listing_id}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    /** Upload */
-    post: operations["upload_artifacts_upload__listing_id__post"];
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/artifacts/edit/{artifact_id}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    /** Edit Artifact */
-    put: operations["edit_artifact_artifacts_edit__artifact_id__put"];
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/artifacts/delete/{artifact_id}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    post?: never;
-    /** Delete Artifact */
-    delete: operations["delete_artifact_artifacts_delete__artifact_id__delete"];
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
   "/translate": {
     parameters: {
       query?: never;
@@ -132,341 +13,49 @@ export interface paths {
     };
     get?: never;
     put?: never;
-    post: operations["translate"];
-    /** Delete Artifact */
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/get_images": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get: operations["get_images"];
-    put?: never;
-    post?: never;
-    /** Delete Artifact */
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/delete_image": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get: operations["delete_image"];
-    put?: never;
-    post?: never;
-    /** Delete Artifact */
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/create_collection": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    post: operations["create_collection"];
-    /** Delete Artifact */
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/edit_collection": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    post: operations["edit_collection"];
-    /** Delete Artifact */
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/get_collection": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get: operations["get_collection"];
-    put?: never;
-    post?: never;
-    /** Delete Artifact */
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/get_collections": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get: operations["get_collections"];
-    put?: never;
-    post?: never;
-    /** Delete Artifact */
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/delete_collection": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get: operations["delete_collections"];
-    put?: never;
-    post?: never;
-    /** Delete Artifact */
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/create_subscription": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    post: operations["create_subscription"];
-    /** Delete Artifact */
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/email/signup/create": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    /**
-     * Create Signup Token
-     * @description Creates a signup token and emails it to the user.
-     */
-    post: operations["create_signup_token_email_signup_create_post"];
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/email/signup/get/{id}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Get Signup Token */
-    get: operations["get_signup_token_email_signup_get__id__get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/email/signup/delete/{id}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    post?: never;
-    /** Delete Signup Token */
-    delete: operations["delete_signup_token_email_signup_delete__id__delete"];
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/keys/new": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    /** New Key */
-    post: operations["new_key_keys_new_post"];
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/keys/list": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** List Keys */
-    get: operations["list_keys_keys_list_get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/keys/delete/{key}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    post?: never;
-    /** Delete Key */
-    delete: operations["delete_key_keys_delete__key__delete"];
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/listings/search": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** List Listings */
-    get: operations["list_listings_listings_search_get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/listings/batch": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Get Batch Listing Info */
-    get: operations["get_batch_listing_info_listings_batch_get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/listings/dump": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Dump Listings */
-    get: operations["dump_listings_listings_dump_get"];
-    put?: never;
-    post?: never;
+    post: operations["translate"];
+    /** Delete Artifact */
     delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/listings/user/{id}": {
+  "/get_images": {
     parameters: {
       query?: never;
       header?: never;
       path?: never;
       cookie?: never;
     };
-    /** List User Listings */
-    get: operations["list_user_listings_listings_user__id__get"];
+    get: operations["get_images"];
     put?: never;
     post?: never;
+    /** Delete Artifact */
     delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/listings/me": {
+  "/delete_image": {
     parameters: {
       query?: never;
       header?: never;
       path?: never;
       cookie?: never;
     };
-    /** List My Listings */
-    get: operations["list_my_listings_listings_me_get"];
+    get: operations["delete_image"];
     put?: never;
     post?: never;
+    /** Delete Artifact */
     delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/listings/add": {
+  "/create_collection": {
     parameters: {
       query?: never;
       header?: never;
@@ -475,15 +64,15 @@ export interface paths {
     };
     get?: never;
     put?: never;
-    /** Add Listing */
-    post: operations["add_listing_listings_add_post"];
+    post: operations["create_collection"];
+    /** Delete Artifact */
     delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/listings/delete/{listing_id}": {
+  "/edit_collection": {
     parameters: {
       query?: never;
       header?: never;
@@ -492,66 +81,66 @@ export interface paths {
     };
     get?: never;
     put?: never;
-    post?: never;
-    /** Delete Listing */
-    delete: operations["delete_listing_listings_delete__listing_id__delete"];
+    post: operations["edit_collection"];
+    /** Delete Artifact */
+    delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/listings/edit/{id}": {
+  "/get_collection": {
     parameters: {
       query?: never;
       header?: never;
       path?: never;
       cookie?: never;
     };
-    get?: never;
-    /** Edit Listing */
-    put: operations["edit_listing_listings_edit__id__put"];
+    get: operations["get_collection"];
+    put?: never;
     post?: never;
+    /** Delete Artifact */
     delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/listings/{id}": {
+  "/get_collections": {
     parameters: {
       query?: never;
       header?: never;
       path?: never;
       cookie?: never;
     };
-    /** Get Listing */
-    get: operations["get_listing_listings__id__get"];
+    get: operations["get_collections"];
     put?: never;
     post?: never;
+    /** Delete Artifact */
     delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/listings/{id}/view": {
+  "/delete_collection": {
     parameters: {
       query?: never;
       header?: never;
       path?: never;
       cookie?: never;
     };
-    get?: never;
+    get: operations["delete_collections"];
     put?: never;
-    /** Increment View Count */
-    post: operations["increment_view_count_listings__id__view_post"];
+    post?: never;
+    /** Delete Artifact */
     delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/listings/{id}/vote": {
+  "/publish_collection": {
     parameters: {
       query?: never;
       header?: never;
@@ -560,43 +149,40 @@ export interface paths {
     };
     get?: never;
     put?: never;
-    /** Vote Listing */
-    post: operations["vote_listing_listings__id__vote_post"];
-    /** Remove Vote */
-    delete: operations["remove_vote_listings__id__vote_delete"];
+    post: operations["publish_collection"];
+    delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/onshape/set/{listing_id}": {
+  "/public_collections": {
     parameters: {
       query?: never;
       header?: never;
       path?: never;
       cookie?: never;
     };
-    get?: never;
+    get: operations["public_collections"];
     put?: never;
-    /** Set Onshape Document */
-    post: operations["set_onshape_document_onshape_set__listing_id__post"];
+    post?: never;
     delete?: never;
     options?: never;
     head?: never;
     patch?: never;
     trace?: never;
   };
-  "/onshape/pull/{listing_id}": {
+  "/create_subscription": {
     parameters: {
       query?: never;
       header?: never;
       path?: never;
       cookie?: never;
     };
-    /** Pull Onshape Document */
-    get: operations["pull_onshape_document_onshape_pull__listing_id__get"];
+    get?: never;
     put?: never;
-    post?: never;
+    post: operations["create_subscription"];
+    /** Delete Artifact */
     delete?: never;
     options?: never;
     head?: never;
@@ -673,204 +259,6 @@ export interface paths {
     patch?: never;
     trace?: never;
   };
-  "/users/batch": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Get Users Batch Endpoint */
-    get: operations["get_users_batch_endpoint_users_batch_get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/public/batch": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Get Users Public Batch Endpoint */
-    get: operations["get_users_public_batch_endpoint_users_public_batch_get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/{id}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Get User Info By Id Endpoint */
-    get: operations["get_user_info_by_id_endpoint_users__id__get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/public/me": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Get My Public User Info Endpoint */
-    get: operations["get_my_public_user_info_endpoint_users_public_me_get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/public/{id}": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Get Public User Info By Id Endpoint */
-    get: operations["get_public_user_info_by_id_endpoint_users_public__id__get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/validate-api-key": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Validate Api Key Endpoint */
-    get: operations["validate_api_key_endpoint_users_validate_api_key_get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/github/client-id": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Github Client Id Endpoint */
-    get: operations["github_client_id_endpoint_users_github_client_id_get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/github/code": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    /**
-     * Github Code
-     * @description Gives the user a session token upon successful github authentication and creation of user.
-     *
-     *     Args:
-     *         data: The request body, containing the code from the OAuth redirect.
-     *         crud: The CRUD object.
-     *         response: The response object.
-     *
-     *     Returns:
-     *         UserInfoResponse.
-     */
-    post: operations["github_code_users_github_code_post"];
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/google/client-id": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    /** Google Client Id Endpoint */
-    get: operations["google_client_id_endpoint_users_google_client_id_get"];
-    put?: never;
-    post?: never;
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/google/login": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    /** Google Login Endpoint */
-    post: operations["google_login_endpoint_users_google_login_post"];
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
-  "/users/set-moderator": {
-    parameters: {
-      query?: never;
-      header?: never;
-      path?: never;
-      cookie?: never;
-    };
-    get?: never;
-    put?: never;
-    /** Set Moderator */
-    post: operations["set_moderator_users_set_moderator_post"];
-    delete?: never;
-    options?: never;
-    head?: never;
-    patch?: never;
-    trace?: never;
-  };
 }
 export type webhooks = Record<string, never>;
 export interface components {
@@ -983,6 +371,10 @@ export interface components {
       title: string;
       description: string;
     };
+    CollectionPublishRequest: {
+      id: string;
+      flag: boolean;
+    };
     SubscriptionRequest: {
       payment_method_id: string;
       email: string;
@@ -1742,6 +1134,68 @@ export interface operations {
       };
     };
   };
+  publish_collection: {
+    parameters: {
+      query?: never;
+      header?: never;
+      path?: never;
+      cookie?: never;
+    };
+    requestBody: {
+      content: {
+        "application/json": components["schemas"]["CollectionPublishRequest"];
+      };
+    };
+    responses: {
+      /** @description Successful Response */
+      200: {
+        headers: {
+          [name: string]: unknown;
+        };
+        content: {
+          "application/json": never;
+        };
+      };
+      /** @description Validation Error */
+      422: {
+        headers: {
+          [name: string]: unknown;
+        };
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  public_collections: {
+    parameters: {
+      query?: never;
+      header?: never;
+      path?: never;
+      cookie?: never;
+    };
+    requestBody?: never;
+    responses: {
+      /** @description Successful Response */
+      200: {
+        headers: {
+          [name: string]: unknown;
+        };
+        content: {
+          "application/json": Array<Collection>;
+        };
+      };
+      /** @description Validation Error */
+      422: {
+        headers: {
+          [name: string]: unknown;
+        };
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
   translate: {
     parameters: {
       query?: never;
diff --git a/frontend/src/hooks/alerts.tsx b/frontend/src/hooks/alerts.tsx
index 84e8ec1..596d7b8 100644
--- a/frontend/src/hooks/alerts.tsx
+++ b/frontend/src/hooks/alerts.tsx
@@ -5,7 +5,6 @@ import {
   useContext,
   useState,
 } from "react";
-import { Toast, ToastContainer } from "react-bootstrap";
 
 const DELAY = 5000;
 const MAX_ERRORS = 10;
@@ -15,13 +14,15 @@ type AlertType = "error" | "success" | "primary" | "info";
 const alertTypeToBg = (kind: AlertType) => {
   switch (kind) {
     case "error":
-      return "danger";
+      return "bg-red-500 text-white"; // Tailwind-style classes
     case "success":
-      return "success";
+      return "bg-green-500 text-white";
     case "primary":
-      return "primary";
+      return "bg-blue-500 text-white";
     case "info":
-      return "secondary";
+      return "bg-gray-500 text-white";
+    default:
+      return "bg-gray-500 text-white";
   }
 };
 
@@ -52,9 +53,9 @@ export const AlertQueueProvider = (props: AlertQueueProviderProps) => {
 
   const addAlert = useCallback(
     (alert: string | ReactNode, kind: AlertType) => {
+      const alertId = generateAlertId();
       setAlerts((prev) => {
         const newAlerts = new Map(prev);
-        const alertId = generateAlertId();
         newAlerts.set(alertId, [alert, kind]);
 
         // Ensure the map doesn't exceed MAX_ERRORS
@@ -65,6 +66,10 @@ export const AlertQueueProvider = (props: AlertQueueProviderProps) => {
 
         return newAlerts;
       });
+      // Automatically remove the alert after DELAY
+      setTimeout(() => {
+        removeAlert(alertId);
+      }, DELAY);
     },
     [generateAlertId],
   );
@@ -93,7 +98,7 @@ export const AlertQueueProvider = (props: AlertQueueProviderProps) => {
 export const useAlertQueue = () => {
   const context = useContext(AlertQueueContext);
   if (context === undefined) {
-    throw new Error("useAlertQueue must be used within a ErrorQueueProvider");
+    throw new Error("useAlertQueue must be used within an AlertQueueProvider");
   }
   return context;
 };
@@ -109,31 +114,45 @@ export const AlertQueue = (props: AlertQueueProps) => {
   return (
     <>
       {children}
-      <ToastContainer
-        className="p-3 mb-8"
-        position="bottom-center"
-        style={{ zIndex: 1000, position: "fixed" }}
+      <div
+        className="fixed bottom-0 left-0 right-0 flex flex-col items-center space-y-2 p-4"
+        style={{ zIndex: 1000 }}
       >
-        {Array.from(alerts).map(([alertId, [alert, kind]]) => {
-          return (
-            <Toast
-              key={alertId}
-              bg={alertTypeToBg(kind)}
-              autohide
-              delay={DELAY}
-              onClose={() => removeAlert(alertId)}
-              animation={true}
-            >
-              <Toast.Header>
-                <strong className="me-auto">
-                  {kind.charAt(0).toUpperCase() + kind.slice(1)}
-                </strong>
-              </Toast.Header>
-              <Toast.Body>{alert}</Toast.Body>
-            </Toast>
-          );
-        })}
-      </ToastContainer>
+        {Array.from(alerts).map(([alertId, [alert, kind]]) => (
+          <div
+            key={alertId}
+            className={`w-full max-w-xs p-4 rounded shadow-lg ${alertTypeToBg(
+              kind,
+            )}`}
+            style={{ animation: "fadeIn 0.5s ease-in-out" }}
+          >
+            <div className="flex justify-between items-center">
+              <strong className="capitalize">{kind}</strong>
+              <div
+                onClick={() => removeAlert(alertId)}
+                className="ml-2 text-white hover:text-gray-200 cursor-pointer"
+              >
+                &times;
+              </div>
+            </div>
+            <div className="mt-2">{alert}</div>
+          </div>
+        ))}
+      </div>
+
+      {/* Remove the jsx attribute */}
+      <style>{`
+        @keyframes fadeIn {
+          from {
+            opacity: 0;
+            transform: translateY(20px);
+          }
+          to {
+            opacity: 1;
+            transform: translateY(0);
+          }
+        }
+      `}</style>
     </>
   );
 };
diff --git a/frontend/src/hooks/auth.tsx b/frontend/src/hooks/auth.tsx
deleted file mode 100644
index e07ea68..0000000
--- a/frontend/src/hooks/auth.tsx
+++ /dev/null
@@ -1,144 +0,0 @@
-import axios, { AxiosInstance } from "axios";
-import { BACKEND_URL } from "constants/backend";
-import {
-  createContext,
-  ReactNode,
-  useCallback,
-  useContext,
-  useEffect,
-  useState,
-} from "react";
-import { useNavigate, useSearchParams } from "react-router-dom";
-
-const API_KEY_ID = "__API_KEY";
-
-const getLocalStorageApiKey = (): string | null => {
-  return localStorage.getItem(API_KEY_ID);
-};
-
-const setLocalStorageApiKey = (token: string) => {
-  localStorage.setItem(API_KEY_ID, token);
-};
-
-const deleteLocalStorageApiKey = () => {
-  localStorage.removeItem(API_KEY_ID);
-};
-
-interface AuthenticationContextProps {
-  apiKey: string | null;
-  setApiKey: (token: string) => void;
-  logout: () => void;
-  isAuthenticated: boolean;
-  api: AxiosInstance;
-}
-
-const AuthenticationContext = createContext<
-  AuthenticationContextProps | undefined
->(undefined);
-
-interface AuthenticationProviderProps {
-  children: ReactNode;
-}
-
-export const AuthenticationProvider = (props: AuthenticationProviderProps) => {
-  const { children } = props;
-
-  const [apiKey, setApiKey] = useState<string | null>(getLocalStorageApiKey());
-
-  const navigate = useNavigate();
-
-  const isAuthenticated = apiKey !== null;
-
-  const api = axios.create({
-    baseURL: BACKEND_URL,
-    withCredentials: true,
-  });
-
-  if (apiKey !== null) {
-    // Adds the API key to the request header since it is set.
-    api.interceptors.request.use(
-      (config) => {
-        config.headers.Authorization = `Bearer ${apiKey}`;
-        return config;
-      },
-      (error) => {
-        return Promise.reject(error);
-      },
-    );
-  }
-
-  useEffect(() => {
-    if (apiKey === null) {
-      deleteLocalStorageApiKey();
-    } else {
-      setLocalStorageApiKey(apiKey);
-    }
-  }, [apiKey]);
-
-  const logout = useCallback(() => {
-    (async () => {
-      await api.delete<boolean>("/users/logout");
-      setApiKey(null);
-      navigate("/");
-    })();
-  }, [navigate]);
-
-  return (
-    <AuthenticationContext.Provider
-      value={{
-        apiKey,
-        setApiKey,
-        logout,
-        isAuthenticated,
-        api,
-      }}
-    >
-      {children}
-    </AuthenticationContext.Provider>
-  );
-};
-
-export const useAuthentication = (): AuthenticationContextProps => {
-  const context = useContext(AuthenticationContext);
-  if (!context) {
-    throw new Error(
-      "useAuthentication must be used within a AuthenticationProvider",
-    );
-  }
-  return context;
-};
-
-interface OneTimePasswordWrapperProps {
-  children: ReactNode;
-}
-
-interface UserLoginResponse {
-  api_key: string;
-}
-
-export const OneTimePasswordWrapper = ({
-  children,
-}: OneTimePasswordWrapperProps) => {
-  const [searchParams] = useSearchParams();
-  const navigate = useNavigate();
-  const { setApiKey, api } = useAuthentication();
-
-  useEffect(() => {
-    (async () => {
-      const payload = searchParams.get("otp");
-      if (payload !== null) {
-        try {
-          const response = await api.post<UserLoginResponse>("/users/otp", {
-            payload,
-          });
-          setApiKey(response.data.api_key);
-          navigate("/");
-        } finally {
-          searchParams.delete("otp");
-        }
-      }
-    })();
-  }, []);
-
-  return <>{children}</>;
-};
diff --git a/frontend/src/hooks/theme.tsx b/frontend/src/hooks/theme.tsx
index d62eb6b..ad19870 100644
--- a/frontend/src/hooks/theme.tsx
+++ b/frontend/src/hooks/theme.tsx
@@ -21,7 +21,7 @@ const COLORS: { [key in Theme]: ThemeColors } = {
     color: "#201a42",
   },
   dark: {
-    backgroundColor: "#000000",
+    backgroundColor: "#ffffff",
     color: "#f5f2ef",
   },
 };
diff --git a/frontend/src/images/KScaleASCII.png b/frontend/src/images/KScaleASCII.png
new file mode 100644
index 0000000..1deb260
Binary files /dev/null and b/frontend/src/images/KScaleASCII.png differ
diff --git a/frontend/src/images/KScaleASCIIMobile.png b/frontend/src/images/KScaleASCIIMobile.png
new file mode 100644
index 0000000..d8e832c
Binary files /dev/null and b/frontend/src/images/KScaleASCIIMobile.png differ
diff --git a/frontend/src/images/bookplaceholder.png b/frontend/src/images/bookplaceholder.png
new file mode 100644
index 0000000..ebe352d
Binary files /dev/null and b/frontend/src/images/bookplaceholder.png differ
diff --git a/frontend/src/images/small-logo.png b/frontend/src/images/small-logo.png
new file mode 100644
index 0000000..487ff9a
Binary files /dev/null and b/frontend/src/images/small-logo.png differ
diff --git a/frontend/src/pages/Collection.tsx b/frontend/src/pages/Collection.tsx
index a7ca922..6b92adb 100644
--- a/frontend/src/pages/Collection.tsx
+++ b/frontend/src/pages/Collection.tsx
@@ -1,104 +1,30 @@
-import { Api } from "api/api";
-import axios, { AxiosInstance } from "axios";
-import AudioPlayer from "components/Audio";
-import ImageComponent from "components/image";
-import Modal from "components/modal";
-import UploadContent from "components/UploadContent";
+import CollectionEdit from "components/collection/Edit";
+import CollectionNew from "components/collection/New";
+import CollectionView from "components/collection/View";
 import { useAuth } from "contexts/AuthContext";
-import { useLoading } from "contexts/LoadingContext";
 import { useAlertQueue } from "hooks/alerts";
 import React, { useEffect, useMemo, useState } from "react";
-import { ListManager } from "react-beautiful-dnd-grid";
-import { Col } from "react-bootstrap";
-import {
-  ArrowLeft,
-  CaretLeft,
-  CaretRight,
-  SkipBackward,
-  SkipForward,
-} from "react-bootstrap-icons";
-import { useLocation, useNavigate, useParams } from "react-router-dom";
-import { Collection, Image } from "types/model";
+import { useLocation, useParams } from "react-router-dom";
+import { Collection } from "types/model";
 
 const CollectionPage: React.FC = () => {
   const { id } = useParams<{ id?: string }>();
   const location = useLocation();
-  const navigate = useNavigate();
-  const [title, setTitle] = useState("");
-  const [description, setDescription] = useState("");
-  const [currentImageIndex, setCurrentImageIndex] = useState(0);
-  const [currentTranscriptionIndex, setCurrentTranscriptionIndex] = useState(0);
-  const [currentImage, setCurrentImage] = useState<Image | null>(null);
   const [collection, setCollection] = useState<Collection | undefined>(
     undefined,
   );
   const { auth, client } = useAuth();
-  const { startLoading, stopLoading } = useLoading();
-  const [showUploadModal, setShowUploadModal] = useState(false);
-  const [showDeleteImageModal, setShowDeleteImageModal] = useState(false);
-  const [images, setImages] = useState<Array<Image> | undefined>([]);
-  const [reorderImageIds, setReorderImageIds] = useState<Array<string> | null>(
-    [],
-  );
   const { addAlert } = useAlertQueue();
-  const [deleteImageId, setDeleteImageId] = useState<string>("");
-  const apiClient: AxiosInstance = useMemo(
-    () =>
-      axios.create({
-        baseURL: process.env.REACT_APP_BACKEND_URL, // Base URL for all requests
-        timeout: 10000, // Request timeout (in milliseconds)
-        headers: {
-          "Content-Type": "application/json",
-          Authorization: `Bearer ${auth?.token}`, // Add any default headers you need
-        },
-      }),
-    [auth?.token],
-  );
-  useEffect(() => {
-    if (collection && collection.images) {
-      setReorderImageIds([...collection.images]);
-    }
-  }, [collection]);
-  const apiClient1: AxiosInstance = useMemo(
-    () =>
-      axios.create({
-        baseURL: process.env.REACT_APP_BACKEND_URL,
-        timeout: 1000000,
-        headers: {
-          "Content-Type": "multipart/form-data",
-          Authorization: `Bearer ${auth?.token}`,
-        },
-      }),
-    [auth?.token],
-  );
-  const API = useMemo(() => new Api(apiClient), [apiClient]);
-  const API_Uploader = useMemo(() => new Api(apiClient1), [apiClient1]);
+
   // Helper to check if it's an edit action
   const isEditAction = useMemo(
     () => location.search.includes("Action=edit"),
     [location.search],
   );
 
-  // Get translated images
-  const translatedImages = useMemo(() => {
-    // Get translated images
-    if (images) {
-      const filter = images.filter((img) => img.is_translated);
-      const final_filter = reorderImageIds
-        ?.map((img) => {
-          const foundItem = filter.find((item) => item.id == img);
-          return foundItem ? foundItem : null; // Return `null` or skip
-        })
-        .filter(Boolean); // Filters out `null` or `undefined`
-      if (final_filter) return final_filter;
-    }
-    return [];
-  }, [images]);
-
   // Simulate fetching data for the edit page (mocking API call)
   useEffect(() => {
     if (id && auth?.is_auth) {
-      startLoading();
       const asyncfunction = async () => {
         const { data: collection, error } = await client.GET(
           "/get_collection",
@@ -106,436 +32,67 @@ const CollectionPage: React.FC = () => {
         );
         if (error) addAlert(error.detail?.toString(), "error");
         else setCollection(collection);
-        stopLoading();
       };
       asyncfunction();
     }
   }, [id, auth]);
 
-  useEffect(() => {
-    if (translatedImages.length > 0) {
-      setCurrentImage(translatedImages[currentImageIndex]);
-    }
-  }, [currentImageIndex, translatedImages]);
-
-  useEffect(() => {
-    if (collection) {
-      const asyncfunction = async () => {
-        startLoading();
-        const { data: images, error } = await client.GET("/get_images", {
-          params: { query: { collection_id: collection.id } },
-        });
-        if (error) addAlert(error.detail?.toString(), "error");
-        else setImages(images);
-        stopLoading();
-      };
-      asyncfunction();
-    }
-  }, [collection?.id]);
-
-  const handleCreate = async (e: React.FormEvent) => {
-    e.preventDefault();
-    startLoading();
-    const { data: collection, error } = await client.POST(
-      "/create_collection",
-      { body: { title, description } },
-    );
-    if (error) addAlert(error.detail?.toString(), "error");
-    else if (collection != null) {
-      navigate(`/collection/${collection.id}?Action=edit`);
-      addAlert("New collection has been created successfully!", "success");
-    } else addAlert("The process has gone wrong!", "error");
-    stopLoading();
-  };
-  // Navigate between images
-  const handleNext = () => {
-    if (currentImageIndex < translatedImages.length - 1) {
-      setCurrentImageIndex(currentImageIndex + 1);
-      setCurrentTranscriptionIndex(0);
-    }
-  };
-
-  const handlePrev = () => {
-    if (currentImageIndex > 0) {
-      setCurrentImageIndex(currentImageIndex - 1);
-      setCurrentTranscriptionIndex(0);
-    }
-  };
-  // Navigate transcriptions
-  const handleTranscriptionNext = () => {
-    if (
-      currentImage?.transcriptions &&
-      currentTranscriptionIndex < currentImage?.transcriptions.length - 1
-    ) {
-      setCurrentTranscriptionIndex(currentTranscriptionIndex + 1);
-    }
-  };
-
-  const handleTranscriptionPrev = () => {
-    if (currentTranscriptionIndex > 0) {
-      setCurrentTranscriptionIndex(currentTranscriptionIndex - 1);
-    }
-  };
   // Return button handler
-  const handleReturn = () => {
-    navigate("/collections");
-  };
-
-  const handleSave = (e: React.FormEvent) => {
-    e.preventDefault();
-    if (collection && reorderImageIds) {
-      const asyncfunction = async () => {
-        startLoading();
-        collection.images = reorderImageIds;
-        const { error } = await client.POST("/edit_collection", {
-          body: collection,
-        });
-        if (error) addAlert(error.detail?.toString(), "error");
-        else {
-          setCollection({ ...collection });
-          addAlert("The collection has been updated successfully!", "success");
-        }
-        stopLoading();
-      };
-      asyncfunction();
-    }
-  };
-  const handleUpload = async (file: File) => {
-    if (collection) {
-      startLoading();
-      const Image = await API_Uploader.uploadImage(file, collection?.id);
-      stopLoading();
-      if (Image) {
-        const new_images: Array<Image> | undefined = images;
-        new_images?.push(Image);
-        if (new_images != undefined) {
-          setImages(new_images);
-          collection.images.push(Image.id);
-          setCollection({ ...collection });
-        }
-      }
-    }
-  };
-  const handleTranslateOneImage = async (image_id: string) => {
-    if (images) {
-      startLoading();
-      addAlert(
-        "The image is being tranlated. Please wait a moment.",
-        "primary",
-      );
-      const image_response = await API.translateImages([image_id]);
-      const i = images?.findIndex((image) => image.id == image_id);
-      images[i] = image_response[0];
-      setImages([...images]);
-      addAlert("The image has been tranlated!", "success");
-      stopLoading();
-    }
-  };
-  // Inside your CollectionPage component
-  /* eslint-disable */
-  const handleDragEnd = (sourceIndex: number, destinationIndex: number) => {
-    /* eslint-enable */
-    if (!reorderImageIds) return;
-    const [removed] = reorderImageIds.splice(sourceIndex, 1);
-    reorderImageIds.splice(destinationIndex, 0, removed);
-    setReorderImageIds([...reorderImageIds]);
-    // Optionally, you can save the new order to your backend here
-  };
-
-  const onShowDeleteImageModal = (id: string) => {
-    setDeleteImageId(id);
-    setShowDeleteImageModal(true);
-  };
-  const onDeleteImage = async () => {
-    if (deleteImageId) {
-      startLoading();
-      const { error } = await client.GET("/delete_image", {
-        params: { query: { id: deleteImageId } },
-      });
-      if (error) addAlert(error.detail?.toString(), "error");
-      else if (images) {
-        const filter = images.filter((image) => image.id !== deleteImageId);
-        setImages(filter);
-        const filteredId = collection?.images.filter(
-          (image) => image !== deleteImageId,
-        );
-        if (filteredId) setReorderImageIds(filteredId);
-        else setReorderImageIds([]);
-        addAlert("The image has been deleted!", "success");
-      }
-      setShowDeleteImageModal(false);
-      stopLoading();
-    }
-  };
+  // const handleReturn = () => {
+  //   navigate("/collections");
+  // };
+
+  // Navigate View Page
+  // const handlePreview = () => {
+  //   navigate("/collection/" + collection?.id);
+  // };
   // Custom Return Button (fixed top-left with border)
-  const ReturnButton = () => (
-    <button
-      className="fixed top-16 left-4 p-2 border-2 border-gray-400 rounded-sm dark:bg-gray-800 shadow-sm"
-      onClick={handleReturn}
-    >
-      <ArrowLeft size={24} />
-    </button>
-  );
+  // const ReturnButton = () => (
+  //   <div className="fixed left-0 mx-4 sm:mx-6 md:mx-10 xl:mx-16">
+  //     <div className="w-full p-2">
+  //       <button
+  //         className="p-2 border-2 bg-gray-12 rounded-md shadow-sm w-full"
+  //         onClick={handleReturn}
+  //       >
+  //         <ArrowLeft size={24} />
+  //       </button>
+  //     </div>
+  //   </div>
+  // );
+  // Custom Return Button (fixed top-left with border)
+  // const PreviewButton = () => (
+  //   <div className="fixed right-0 mx-4 sm:mx-6 md:mx-10 xl:mx-16">
+  //     <div className="w-full p-2">
+  //       <button
+  //         className="p-2 border-2 bg-gray-12 rounded-md shadow-sm w-full"
+  //         onClick={handlePreview}
+  //       >
+  //         <Eye size={24} />
+  //       </button>
+  //     </div>
+  //   </div>
+  // );
 
   // Rendering New Collection Page
   if (!id) {
-    return (
-      <div className="flex flex-col items-center pt-20 gap-8">
-        <h1>New Collection</h1>
-        <form
-          className="flex flex-col items-end gap-4 w-full"
-          onSubmit={handleCreate}
-        >
-          <input
-            className="border p-2 w-full"
-            type="text"
-            placeholder="Title"
-            value={title}
-            onChange={(e) => setTitle(e.target.value)}
-            required
-          />
-          <textarea
-            className="border p-2 w-full h-32"
-            placeholder="Description"
-            value={description}
-            onChange={(e) => setDescription(e.target.value)}
-            required
-          />
-          <button
-            className="bg-blue-500 w-32 text-white p-2 rounded hover:bg-blue-600"
-            type="submit"
-          >
-            Create
-          </button>
-        </form>
-        <ReturnButton />
-      </div>
-    );
+    return <CollectionNew />;
   }
-
   // Rendering Edit Collection Page
   if (id && isEditAction && collection) {
     return (
-      <div className="flex flex-col items-center pt-20 gap-4">
-        <h1>Edit Collection </h1>
-        <form
-          className="flex flex-col items-center gap-4 w-full"
-          onSubmit={handleSave}
-        >
-          <div className="mt-4 w-full">
-            <input
-              className="border p-2 w-full"
-              type="text"
-              placeholder="Title"
-              value={collection.title}
-              onChange={(e) =>
-                setCollection({ ...collection, title: e.target.value })
-              }
-              required
-            />
-          </div>
-          <div className="mt-4 w-full">
-            <textarea
-              className="border p-2 h-32 w-full"
-              placeholder="Description"
-              value={collection.description}
-              onChange={(e) =>
-                setCollection({ ...collection, description: e.target.value })
-              }
-              required
-            />
-          </div>
-          <div className="mt-4 flex justify-content-end w-full gap-2">
-            <button
-              className="bg-blue-500 text-white w-30 p-2 rounded hover:bg-blue-600"
-              type="submit"
-            >
-              Save Changes
-            </button>
-          </div>
-        </form>
-        <div className="flex gap-4">
-          <button
-            className="bg-blue-500 text-white w-35 p-2 rounded hover:bg-blue-600"
-            onClick={() => setShowUploadModal(true)}
-          >
-            Add Images
-          </button>
-          <button
-            className="bg-blue-500 text-white w-35 p-2 rounded hover:bg-blue-600 disabled:bg-gray-600"
-            onClick={(e) => handleSave(e)}
-            disabled={reorderImageIds?.join() === collection.images.join()}
-          >
-            Order Save
-          </button>
-        </div>
-        {/* Upload Modal */}
-        <Modal
-          isOpen={showUploadModal}
-          onClose={() => setShowUploadModal(false)}
-        >
-          <UploadContent onUpload={handleUpload} />
-          <div className="mt-5 flex justify-end space-x-2">
-            <button
-              className="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400"
-              onClick={() => setShowUploadModal(false)}
-            >
-              Close
-            </button>
-          </div>
-        </Modal>
-        <Modal
-          isOpen={showDeleteImageModal}
-          onClose={() => setShowDeleteImageModal(false)}
-        >
-          <div className="mt-5 flex justify-end space-x-2 gap-4 items-center">
-            <span>Are you sure you want to delete the collection?</span>
-            <button
-              className="px-4 py-2 bg-red-700 text-gray-300 rounded hover:bg-red-800"
-              onClick={onDeleteImage}
-            >
-              Delete
-            </button>
-            <button
-              className="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400"
-              onClick={() => setShowDeleteImageModal(false)}
-            >
-              Cancel
-            </button>
-          </div>
-        </Modal>
-
-        {reorderImageIds && (
-          <ListManager
-            items={reorderImageIds}
-            direction="horizontal"
-            maxItems={3}
-            onDragEnd={handleDragEnd}
-            render={(id) => {
-              const image = images?.find((item) => item.id === id);
-              return (
-                <Col lg={4} md={6} sm={12} className="p-0">
-                  {image ? (
-                    <ImageComponent
-                      {...image}
-                      handleTranslateOneImage={handleTranslateOneImage}
-                      showDeleteModal={onShowDeleteImageModal}
-                    />
-                  ) : (
-                    <ImageComponent
-                      {...{
-                        id,
-                        is_translated: false,
-                        image_url: "",
-                        transcriptions: [],
-                        collection: collection.id,
-                      }}
-                      handleTranslateOneImage={handleTranslateOneImage}
-                      showDeleteModal={onShowDeleteImageModal}
-                    />
-                  )}
-                </Col>
-              );
-            }}
-          />
-        )}
-        <ReturnButton key={id} />
-      </div>
+      <CollectionEdit collection={collection} setCollection={setCollection} />
     );
   }
-
   // Rendering Collection Detail Page
   if (id && !isEditAction && collection) {
-    return (
-      <div className="flex flex-col items-center pt-20 gap-4">
-        <h1 className="text-xl font-bold mb-4">{collection.title}</h1>
-        <p className="text-md mb-4">{collection.description}</p>
-        {currentImage ? (
-          <div className="flex flex-col align-items-center">
-            <img
-              src={currentImage.image_url}
-              alt="Collection Image"
-              className="max-h-96 h-auto mx-auto mb-4"
-            />
-            <p className="mt-2">
-              {currentImage.transcriptions[currentTranscriptionIndex].text}
-            </p>
-            <p className="mt-2">
-              {currentImage.transcriptions[currentTranscriptionIndex].pinyin}
-            </p>
-            <p className="mt-2">
-              {
-                currentImage.transcriptions[currentTranscriptionIndex]
-                  .translation
-              }
-            </p>
-            <AudioPlayer
-              currentImage={currentImage}
-              index={currentTranscriptionIndex}
-            />
-
-            {/* Navigation Buttons */}
-            <div className="flex justify-content-center mt-4 w-40 gap-4">
-              <button
-                className={`px-5 py-3 rounded ${
-                  currentImageIndex === 0
-                    ? "bg-gray-300 text-gray-600 cursor-not-allowed"
-                    : "bg-gray-500 text-white hover:bg-gray-600"
-                }`}
-                onClick={handlePrev}
-                disabled={currentImageIndex === 0}
-              >
-                <SkipBackward size={22} />
-              </button>
-              <button
-                className={`px-5 py-3 rounded ${
-                  currentTranscriptionIndex === 0
-                    ? "bg-gray-300 text-gray-600 cursor-not-allowed"
-                    : "bg-gray-500 text-white hover:bg-gray-600"
-                }`}
-                onClick={handleTranscriptionPrev}
-                disabled={currentTranscriptionIndex === 0}
-              >
-                <CaretLeft size={22} />
-              </button>
-              <button
-                className={`px-5 py-3 rounded ${
-                  currentTranscriptionIndex ===
-                    currentImage.transcriptions.length - 1 ||
-                  currentImage.transcriptions.length === 0
-                    ? "bg-gray-300 text-gray-600 cursor-not-allowed"
-                    : "bg-gray-500 text-white hover:bg-gray-600"
-                }`}
-                onClick={handleTranscriptionNext}
-                disabled={
-                  currentTranscriptionIndex ===
-                    currentImage.transcriptions.length - 1 ||
-                  currentImage.transcriptions.length === 0
-                }
-              >
-                <CaretRight size={22} />
-              </button>
-              <button
-                className={`px-5 py-3 rounded ${
-                  currentImageIndex === translatedImages.length - 1
-                    ? "bg-gray-300 text-gray-600 cursor-not-allowed"
-                    : "bg-gray-500 text-white hover:bg-gray-600"
-                }`}
-                onClick={handleNext}
-                disabled={currentImageIndex === translatedImages.length - 1}
-              >
-                <SkipForward size={22} />
-              </button>
-            </div>
-          </div>
-        ) : (
-          <div>No translated images available.</div>
-        )}
-        <ReturnButton />
-      </div>
-    );
+    return <CollectionView collection={collection} />;
   }
-  return <></>;
+  //skeleton
+  return (
+    <div className="flex flex-col h-full w-full gap-4">
+      <div className="bg-gray-3 w-full rounded-lg h-3/4 animate-pulse" />
+      <div className="bg-gray-3 w-full rounded-lg h-1/4 animate-pulse" />
+    </div>
+  );
 };
-
 export default CollectionPage;
diff --git a/frontend/src/pages/Collections.tsx b/frontend/src/pages/Collections.tsx
index 6570e2c..99acabd 100644
--- a/frontend/src/pages/Collections.tsx
+++ b/frontend/src/pages/Collections.tsx
@@ -1,11 +1,11 @@
-import CardItem from "components/card";
+import Book from "components/Book";
+import BookSkeleton from "components/BookSkeleton";
 import Modal from "components/modal";
 import NewCardItem from "components/new_card";
 import { useAuth } from "contexts/AuthContext";
 import { useLoading } from "contexts/LoadingContext";
 import { useAlertQueue } from "hooks/alerts";
 import { useEffect, useState } from "react";
-import { Col, Row } from "react-bootstrap";
 import { Collection } from "types/model";
 
 const Collections = () => {
@@ -15,6 +15,7 @@ const Collections = () => {
   const { startLoading, stopLoading } = useLoading();
   const [delete_ID, setDeleteID] = useState(String);
   const { addAlert } = useAlertQueue();
+  const [is_loading, setIsLoading] = useState<boolean>(true);
   const onDeleteModalShow = (id: string) => {
     setDeleteID(id);
     setShowModal(true);
@@ -41,32 +42,51 @@ const Collections = () => {
   useEffect(() => {
     if (auth?.is_auth) {
       const asyncfunction = async () => {
-        startLoading();
         const { data: collections, error } =
           await client.GET("/get_collections");
         if (error) addAlert(error.detail?.toString(), "error");
         else setCollection(collections);
-        stopLoading();
+        setIsLoading(false);
       };
       asyncfunction();
     }
   }, [auth]);
 
   return (
-    <div className="flex-column pt-20 gap-4 d-flex justify-content-center">
-      <h1>My Collections</h1>
-      <Row className="align-items-center">
-        <Col lg={3} md={4} sm={12}>
-          <NewCardItem />
-        </Col>
-        {collections?.map((collection) => {
-          return (
-            <Col lg={3} md={4} sm={12} key={collection.id}>
-              <CardItem {...collection} onDelete={onDeleteModalShow} />
-            </Col>
-          );
-        })}
-      </Row>
+    <div className="flex-column rounded-md min-h-full items-center bg-gray-3 p-3">
+      {auth?.is_auth ? (
+        <div className="flex flex-col rounded-md items-start p-24 gap-8">
+          <h1 className="text-3xl text-gray-900">My Collections</h1>
+          <div className="w-full flex flex-wrap gap-8">
+            <div className="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/5 2xl:w-1/6">
+              <NewCardItem />
+            </div>
+            {is_loading ? (
+              <BookSkeleton is_light={true} />
+            ) : (
+              collections?.map((collection) => {
+                return (
+                  <div
+                    key={collection.id}
+                    className="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/5 2xl:w-1/6"
+                  >
+                    <Book
+                      title={collection.title}
+                      description={collection.title}
+                      id={collection.id}
+                      featured_image={collection.featured_image}
+                      is_editable={true}
+                      onDelete={onDeleteModalShow}
+                    />
+                  </div>
+                );
+              })
+            )}
+          </div>
+        </div>
+      ) : (
+        <></>
+      )}
       {/* Delete Modal */}
       <Modal isOpen={showModal} onClose={() => setShowModal(false)}>
         <div className="mt-5 flex justify-end space-x-2 gap-4 items-center">
diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx
index 1c83be4..b6ea186 100644
--- a/frontend/src/pages/Home.tsx
+++ b/frontend/src/pages/Home.tsx
@@ -1,45 +1,103 @@
-import avatar from "assets/avatar.png";
-import { Col, Container, Row } from "react-bootstrap";
+import Book from "components/Book";
+import BookSkeleton from "components/BookSkeleton";
+import { useAuth } from "contexts/AuthContext";
+import { useEffect, useState } from "react";
+import { Collection } from "types/model";
 
 const Home = () => {
+  const [public_collections, setPublicCollections] = useState<
+    Array<Collection> | undefined
+  >([]);
+  const [collections, setCollections] = useState<Array<Collection> | undefined>(
+    [],
+  );
+  const { auth, client } = useAuth();
+  const [is_collection_roading, setIsCollectionRoading] =
+    useState<boolean>(true);
+  const [is_public_collection_roading, setIsPublicCollectionRoading] =
+    useState<boolean>(true);
+  useEffect(() => {
+    (async () => {
+      const { data } = await client.GET("/public_collections");
+      setPublicCollections(data);
+      setIsPublicCollectionRoading(false);
+    })();
+  }, [client]);
+  useEffect(() => {
+    if (auth?.is_auth)
+      (async () => {
+        const { data } = await client.GET("/get_collections");
+        setCollections(data);
+        setIsCollectionRoading(false);
+      })();
+  }, [client, auth]);
   return (
-    <Container
-      fluid
-      className="d-flex flex-column justify-content-center align-items-center min-vh-100"
-    >
-      <Row className="align-items-center w-100">
+    <div className="flex flex-col gap-2 h-full">
+      <div className="flex flex-wrap rounded-md items-center bg-gray-12 px-4">
         {/* Text Section */}
-        <Col
-          lg={4}
-          md={8}
-          sm={12}
-          className="text-center text-md-start d-flex flex-column justify-content-center"
-        >
-          <h1 className="display-4">LinguaPhoto</h1>
-          <p className="lead">Visual language learning for everyone!</p>
-          <Row className="mt-3">{/* GoogleAuthComponent placeholder */}</Row>
-        </Col>
-
-        {/* Image Section */}
-        <Col
-          lg={8}
-          md={8}
-          sm={12}
-          className="d-flex justify-content-center align-items-center"
-        >
-          <img
-            src={avatar}
-            alt="Avatar"
-            className="img-fluid"
-            style={{
-              maxHeight: "80vh", // Keeps image height responsive
-              maxWidth: "100%",
-              objectFit: "contain", // Prevents overflow
-            }}
-          />
-        </Col>
-      </Row>
-    </Container>
+        <div className="flex flex-col justify-center items-center text-md-start h-72 text-3xl w-full">
+          <h1>LinguaPhoto</h1>
+          <p>Visual language learning for everyone!</p>
+          <div className="flex felx-wrap mt-3">
+            {/* GoogleAuthComponent placeholder */}
+          </div>
+        </div>
+      </div>
+      <div className="flex flex-col rounded-md items-start bg-gray-3 p-24 gap-8">
+        <h1 className="text-3xl text-gray-900">Public Collections</h1>
+        <div className="w-full flex flex-wrap gap-8">
+          {is_public_collection_roading ? (
+            // skeleton for public collections
+            <BookSkeleton is_light={true} />
+          ) : (
+            public_collections?.map((collection) => {
+              return (
+                <div
+                  key={collection.id}
+                  className="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/5 2xl:w-1/6"
+                >
+                  <Book
+                    title={collection.title}
+                    description={collection.title}
+                    id={collection.id}
+                    featured_image={collection.featured_image}
+                  />
+                </div>
+              );
+            })
+          )}
+        </div>
+      </div>
+      {auth?.is_auth ? (
+        <div className="flex flex-col rounded-md items-start bg-gray-12 p-24 gap-8">
+          <h1 className="text-3xl">My Collections</h1>
+          <div className="w-full flex flex-wrap gap-8">
+            {is_collection_roading ? (
+              // skeleton for my collections
+              <BookSkeleton is_light={false} />
+            ) : (
+              collections?.map((collection) => {
+                return (
+                  <div
+                    key={collection.id}
+                    className="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/5 2xl:w-1/6"
+                  >
+                    <Book
+                      title={collection.title}
+                      description={collection.title}
+                      id={collection.id}
+                      featured_image={collection.featured_image}
+                    />
+                  </div>
+                );
+              })
+            )}
+          </div>
+        </div>
+      ) : (
+        <></>
+      )}
+    </div>
   );
 };
 
diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx
index d74f61a..a302bcd 100644
--- a/frontend/src/pages/Login.tsx
+++ b/frontend/src/pages/Login.tsx
@@ -10,12 +10,12 @@ const LoginPage: React.FC = () => {
   const [password, setPassword] = useState("");
   const [username, setName] = useState("");
   const { startLoading, stopLoading } = useLoading();
-  const { auth, setAuth, client, setApiKeyId } = useAuth();
+  const { auth, is_auth, setAuth, client, setApiKeyId } = useAuth();
   const navigate = useNavigate();
   const { addAlert } = useAlertQueue();
   useEffect(() => {
-    if (auth?.is_auth) navigate("/collections");
-  }, [auth]);
+    if (is_auth && auth?.is_auth) navigate("/collections");
+  }, [is_auth, auth?.is_auth]);
   // Toggle between login and signup forms
   const handleSwitch = () => {
     setIsSignup(!isSignup);
@@ -58,9 +58,9 @@ const LoginPage: React.FC = () => {
   };
 
   return (
-    <div className="flex items-center justify-center h-screen">
-      <div className="border rounded-lg shadow-md p-6 w-full max-w-md">
-        <h2 className="text-2xl font-bold mb-4 text-center">
+    <div className="flex flex-wrap rounded-md h-full items-center justify-center bg-gray-3">
+      <div className="border border-gray-600 rounded-lg shadow-md p-6 w-full max-w-md">
+        <h2 className="text-2xl font-bold text-gray-700 mb-4 text-center">
           {isSignup ? "Sign Up" : "Login"}
         </h2>
         <form className="space-y-4" onSubmit={handleSubmit}>
@@ -128,7 +128,7 @@ const LoginPage: React.FC = () => {
           <hr className="flex-grow border-t border-gray-300" />
         </div>
 
-        <button className="bg-gray-800 text-white p-2 rounded w-full flex items-center justify-center hover:bg-gray-900">
+        <button className="bg-gray-11 text-white p-2 rounded w-full hover:bg-gray-10 flex flex-wrap items-center justify-center">
           <Google className="mr-2" size={20} />
           {isSignup ? "Sign Up with Google" : "Login with Google"}
         </button>
@@ -137,22 +137,22 @@ const LoginPage: React.FC = () => {
           {isSignup ? (
             <>
               Already have an account?{" "}
-              <button
+              <span
                 onClick={handleSwitch}
-                className="text-blue-500 hover:underline"
+                className="text-blue-500 hover:underline cursor-pointer"
               >
                 Login here
-              </button>
+              </span>
             </>
           ) : (
             <>
               Don&apos;t have an account?{" "}
-              <button
+              <span
                 onClick={handleSwitch}
-                className="text-blue-500 hover:underline"
+                className="text-blue-500 hover:underline cursor-pointer"
               >
                 Create a new account
-              </button>
+              </span>
             </>
           )}
         </p>
diff --git a/frontend/src/pages/NotFound.tsx b/frontend/src/pages/NotFound.tsx
index 9b39a7c..dc5ec1d 100644
--- a/frontend/src/pages/NotFound.tsx
+++ b/frontend/src/pages/NotFound.tsx
@@ -1,14 +1,12 @@
-import { Col, Row } from "react-bootstrap";
-
 const NotFound = () => {
   return (
     <div className="pt-5 rounded-lg flex items-center justify-center h-screen">
-      <Row>
-        <Col>
+      <div className="flex flex-wrap">
+        <div className="w-full">
           <h1 className="display-4">404 Not Found</h1>
           <p className="lead">The page you are looking for does not exist</p>
-        </Col>
-      </Row>
+        </div>
+      </div>
     </div>
   );
 };
diff --git a/frontend/src/pages/Subscription.tsx b/frontend/src/pages/Subscription.tsx
index 44390b9..b7c0eb3 100644
--- a/frontend/src/pages/Subscription.tsx
+++ b/frontend/src/pages/Subscription.tsx
@@ -2,22 +2,17 @@ import React from "react";
 
 const SubscriptionCancelPage: React.FC = () => {
   return (
-    <div className="flex flex-column gap-8 justify-center items-center min-h-screen">
+    <div className="flex flex-col rounded-md h-full items-center justify-center bg-gray-3 p-24 gap-12 text-gray-900">
       <h1 className="text-3xl">
         This page is on developing. will be updated soon
       </h1>
-      <div className="w-full max-w-md p-6 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg shadow">
+      <div className="w-full max-w-md p-6 border border-gray-300 bg-white rounded-lg shadow">
         {/* Current Plan Section */}
         <div className="mb-6">
-          <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100">
-            Current Plan
-          </h2>
-          <p className="text-gray-700 dark:text-gray-300 mt-2">
+          <h2 className="text-gray-700 text-lg font-semibold">Current Plan</h2>
+          <p className="mt-2">
             You have been subscribed to the{" "}
-            <span className="font-semibold text-green-600 dark:text-green-400">
-              Premium Plan
-            </span>
-            .
+            <span className="font-semibold text-green-700">Premium Plan</span>.
           </p>
           <button className="mt-4 px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-md w-full">
             Cancel Subscription
@@ -26,12 +21,8 @@ const SubscriptionCancelPage: React.FC = () => {
 
         {/* Billing Cycle Section */}
         <div>
-          <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100">
-            Current Billing Cycle
-          </h2>
-          <p className="text-gray-700 dark:text-gray-300 mt-2">
-            2023.05.05 - 2023.06.05
-          </p>
+          <h2 className="text-lg font-semibold">Current Billing Cycle</h2>
+          <p className="text-gray-700 mt-2">2023.05.05 - 2023.06.05</p>
         </div>
       </div>
     </div>
diff --git a/frontend/src/types/model.ts b/frontend/src/types/model.ts
index a648b88..4770409 100644
--- a/frontend/src/types/model.ts
+++ b/frontend/src/types/model.ts
@@ -3,6 +3,9 @@ export interface Collection {
   title: string;
   description: string;
   images: Array<string>;
+  user: string;
+  featured_image: string;
+  publish_flag: boolean;
 }
 
 interface Transcription {
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js
index 70b003e..da17d57 100644
--- a/frontend/tailwind.config.js
+++ b/frontend/tailwind.config.js
@@ -3,9 +3,47 @@ export default {
   content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
   darkMode: "class",
   theme: {
-    extend: {},
-  },
-  plugins: [],
-  important: true
-}
-
+    extend: {
+      fontFamily: {
+        sans: ["Inter", "sans-serif"],
+        orbitron: ["Orbitron", "sans-serif"],
+      },
+      colors: {
+        // compliments international orange primary color palette
+        gray: {
+          1: "#fcfcfd",
+          2: "#f9f9fb",
+          3: "#eff0f3",
+          4: "#e7e8ec",
+          5: "#e0e1e6",
+          6: "#d8d9e0",
+          7: "#cdced7",
+          8: "#b9bbc6",
+          9: "#8b8d98",
+          10: "#80828d",
+          11: "#62636c",
+          12: "#1e1f24",
+        },
+        // Radix UI International Orange Colorscale 1-12 (light)
+        primary: {
+          1: "#fefcfb",
+          2: "#fff5f1",
+          3: "#ffe8de",
+          4: "#ffd7c7",
+          5: "#ffc9b4",
+          6: "#ffb89f",
+          7: "#ffa284",
+          8: "#fb8765",
+          9: "#ff4f00",
+          10: "#f14000",
+          11: "#de3500",
+          12: "#5d291a",
+          DEFAULT: "#ff4f00",
+          foreground: "#5d291a",
+        },
+      },
+    },
+    plugins: [],
+    important: true
+  }
+}
\ No newline at end of file
diff --git a/linguaphoto/api/collection.py b/linguaphoto/api/collection.py
index b7bc7f7..a8c0ce8 100644
--- a/linguaphoto/api/collection.py
+++ b/linguaphoto/api/collection.py
@@ -10,6 +10,7 @@
 from linguaphoto.schemas.collection import (
     CollectionCreateFragment,
     CollectionEditFragment,
+    CollectionPublishFragment,
 )
 from linguaphoto.utils.auth import get_current_user_id
 
@@ -64,7 +65,12 @@ async def editcollection(
     async with collection_crud:
         await collection_crud.edit_collection(
             collection.id,
-            updates={"title": collection.title, "description": collection.description, "images": collection.images},
+            updates={
+                "title": collection.title,
+                "description": collection.description,
+                "images": collection.images,
+                "featured_image": collection.featured_image,
+            },
         )
         return
 
@@ -78,3 +84,23 @@ async def deletecollection(
     async with collection_crud:
         await collection_crud.delete_collection(collection_id=id)
         return
+
+
+@router.post("/publish_collection")
+async def publishcollection(
+    data: CollectionPublishFragment,
+    user_id: str = Depends(get_current_user_id),
+    collection_crud: CollectionCrud = Depends(),
+) -> None:
+    async with collection_crud:
+        await collection_crud.edit_collection(data.id, updates={"publish_flag": data.flag})
+        return
+
+
+@router.get("/public_collections")
+async def publiccoleections(
+    collection_crud: CollectionCrud = Depends(),
+) -> List[Collection]:
+    async with collection_crud:
+        collections = await collection_crud.get_public_collections()
+        return collections
diff --git a/linguaphoto/crud/base.py b/linguaphoto/crud/base.py
index c3cbdf0..676d609 100644
--- a/linguaphoto/crud/base.py
+++ b/linguaphoto/crud/base.py
@@ -255,7 +255,7 @@ async def _list_items(
         table = await self.db.Table(TABLE_NAME)
 
         query_params = {
-            "IndexName": "type_index",
+            "IndexName": "type-index",
             "KeyConditionExpression": Key("type").eq(item_class.__name__),
             "Limit": limit,
         }
diff --git a/linguaphoto/crud/collection.py b/linguaphoto/crud/collection.py
index 32e11e2..5ce56e7 100644
--- a/linguaphoto/crud/collection.py
+++ b/linguaphoto/crud/collection.py
@@ -25,3 +25,12 @@ async def edit_collection(self, collection_id: str, updates: dict) -> None:
 
     async def delete_collection(self, collection_id: str) -> None:
         await self._delete_item(collection_id)
+
+    async def get_public_collections(self) -> List[Collection]:
+        collections = await self._list_items(
+            item_class=Collection,
+            filter_expression="#flag=:flag",
+            expression_attribute_names={"#flag": "publish_flag"},
+            expression_attribute_values={":flag": True},
+        )
+        return collections
diff --git a/linguaphoto/models.py b/linguaphoto/models.py
index 15baa57..4d2693c 100644
--- a/linguaphoto/models.py
+++ b/linguaphoto/models.py
@@ -58,6 +58,8 @@ class Collection(LinguaBaseModel):
     description: str
     images: List[str] = []
     user: str
+    featured_image: str = ""
+    publish_flag: bool = False
 
     @classmethod
     def create(cls, title: str, description: str, user_id: str) -> Self:
diff --git a/linguaphoto/schemas/collection.py b/linguaphoto/schemas/collection.py
index 897b3b3..bb65524 100644
--- a/linguaphoto/schemas/collection.py
+++ b/linguaphoto/schemas/collection.py
@@ -15,3 +15,9 @@ class CollectionEditFragment(BaseModel):
     title: Optional[str]
     description: Optional[str]
     images: Optional[List[str]]
+    featured_image: Optional[str]
+
+
+class CollectionPublishFragment(BaseModel):
+    id: str
+    flag: bool