+
- {loading ? (
-
- {Array.from({ length: 8 }).map((_, i) => (
-
- ))}
-
- ) : products.length === 0 ? (
-
-
-
- No products found
-
-
- Try adjusting your search or filters
-
-
- ) : (
- <>
-
- {products.map((product) => (
-
- ))}
+
+
+
+ Discover Amazing Products
+
+
+ {total} products available
+
- {totalPages > 1 && (
-
-
- {Array.from({ length: totalPages }, (_, i) => i + 1).map((p) => (
-
+
+
+ {loading ? (
+
+ {Array.from({ length: 6 }).map((_, i) => (
+
))}
-
+ ) : products.length === 0 ? (
+
+
+
+ No products found
+
+
+ Try adjusting your search or filters
+
+ ) : (
+ <>
+
+ {products.map((product) => (
+
+ ))}
+
+
+ {totalPages > 1 && (
+
+
+ {Array.from({ length: totalPages }, (_, i) => i + 1).map((p) => (
+
+ ))}
+
+
+ )}
+ >
)}
- >
- )}
+
+
);
}
diff --git a/shopping-app/src/components/Sidebar.tsx b/shopping-app/src/components/Sidebar.tsx
new file mode 100644
index 00000000000000..d8c427f045d126
--- /dev/null
+++ b/shopping-app/src/components/Sidebar.tsx
@@ -0,0 +1,295 @@
+"use client";
+
+import Link from "next/link";
+import { useRouter } from "next/navigation";
+import { useState } from "react";
+import { useAuthStore } from "@/store/auth";
+import { useCartStore } from "@/store/cart";
+import { api } from "@/lib/api";
+
+interface SidebarProps {
+ categories: string[];
+ activeCategory: string;
+ onCategoryChange: (category: string) => void;
+}
+
+export default function Sidebar({
+ categories,
+ activeCategory,
+ onCategoryChange,
+}: SidebarProps) {
+ const { user, token, logout, loadFromStorage } = useAuthStore();
+ const { items } = useCartStore();
+ const router = useRouter();
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const [loginError, setLoginError] = useState("");
+ const [loginLoading, setLoginLoading] = useState(false);
+
+ const cartCount = items.reduce((sum, item) => sum + item.quantity, 0);
+ const cartTotal = items.reduce(
+ (sum, item) => sum + item.price * item.quantity,
+ 0
+ );
+
+ const handleLogin = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setLoginError("");
+ setLoginLoading(true);
+
+ const res = await api.auth.login(email, password);
+ if (res.success && res.data) {
+ useAuthStore.getState().setAuth(res.data.user, res.data.token);
+ setEmail("");
+ setPassword("");
+ } else {
+ setLoginError(res.error || "Login failed");
+ }
+ setLoginLoading(false);
+ };
+
+ const handleLogout = () => {
+ logout();
+ router.refresh();
+ };
+
+ return (
+
+ );
+}
From ae0c0418f4c9567b429b1c51321bfc5ef4109ebf Mon Sep 17 00:00:00 2001
From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Date: Sat, 14 Mar 2026 13:37:45 +0000
Subject: [PATCH 3/3] feat: branded FSFT Shopping login page, sidebar only
after login
---
shopping-app/src/app/layout.tsx | 4 +-
shopping-app/src/app/login/page.tsx | 179 +++++++++++++-------
shopping-app/src/app/page.tsx | 14 +-
shopping-app/src/components/Navbar.tsx | 2 +-
shopping-app/src/components/Sidebar.tsx | 206 ++++++++----------------
5 files changed, 203 insertions(+), 202 deletions(-)
diff --git a/shopping-app/src/app/layout.tsx b/shopping-app/src/app/layout.tsx
index 6f067732d5e671..2940563c6f4baf 100644
--- a/shopping-app/src/app/layout.tsx
+++ b/shopping-app/src/app/layout.tsx
@@ -6,7 +6,7 @@ import Navbar from "@/components/Navbar";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
- title: "ShopHub - Your One-Stop Shopping Destination",
+ title: "FSFT Shopping - Your One-Stop Shopping Destination",
description: "Browse and shop from our wide selection of products",
};
@@ -23,7 +23,7 @@ export default function RootLayout({
diff --git a/shopping-app/src/app/login/page.tsx b/shopping-app/src/app/login/page.tsx
index 1c0d3e53e96df1..534a3b0273551a 100644
--- a/shopping-app/src/app/login/page.tsx
+++ b/shopping-app/src/app/login/page.tsx
@@ -38,71 +38,136 @@ export default function LoginPage() {
};
return (
-